Fixed online players bug

This commit is contained in:
Bob Da Ross
2021-05-10 03:28:29 -05:00
parent ae3cc2003d
commit 21377bee24
4 changed files with 153 additions and 59 deletions

View File

@@ -214,6 +214,7 @@ namespace SeamlessClientPlugin
TransferMessage.PingServerAndBeginRedirect(); TransferMessage.PingServerAndBeginRedirect();
RanJoin = false; RanJoin = false;
MySession.Static.SetCameraController(VRage.Game.MyCameraControllerEnum.SpectatorFixed); MySession.Static.SetCameraController(VRage.Game.MyCameraControllerEnum.SpectatorFixed);
//DisposeInitilizations(); //DisposeInitilizations();
} }
} }

View File

@@ -27,8 +27,8 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Reflection.Emit; using System.Reflection.Emit;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Timers;
using VRage; using VRage;
using VRage.FileSystem; using VRage.FileSystem;
using VRage.Game; using VRage.Game;
@@ -54,6 +54,8 @@ namespace SeamlessClientPlugin.SeamlessTransfer
private static readonly Type MySessionType = Type.GetType("Sandbox.Game.World.MySession, Sandbox.Game"); private static readonly Type MySessionType = Type.GetType("Sandbox.Game.World.MySession, Sandbox.Game");
private static readonly Type VirtualClientsType = Type.GetType("Sandbox.Engine.Multiplayer.MyVirtualClients, Sandbox.Game"); private static readonly Type VirtualClientsType = Type.GetType("Sandbox.Engine.Multiplayer.MyVirtualClients, Sandbox.Game");
private static readonly Type GUIScreenChat = Type.GetType("Sandbox.Game.Gui.MyGuiScreenChat, Sandbox.Game"); private static readonly Type GUIScreenChat = Type.GetType("Sandbox.Game.Gui.MyGuiScreenChat, Sandbox.Game");
private static readonly Type MyMultiplayerClientBase = Type.GetType("Sandbox.Engine.Multiplayer.MyMultiplayerClientBase, Sandbox.Game");
private static Harmony Patcher = new Harmony("SeamlessClientReUnload"); private static Harmony Patcher = new Harmony("SeamlessClientReUnload");
@@ -68,6 +70,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
public static ConstructorInfo SyncLayerConstructor; public static ConstructorInfo SyncLayerConstructor;
public static ConstructorInfo TransportLayerConstructor; public static ConstructorInfo TransportLayerConstructor;
public static ConstructorInfo MySessionConstructor; public static ConstructorInfo MySessionConstructor;
public static ConstructorInfo MyMultiplayerClientBaseConstructor;
//Reflected Methods //Reflected Methods
public static FieldInfo VirtualClients; public static FieldInfo VirtualClients;
@@ -80,20 +83,18 @@ namespace SeamlessClientPlugin.SeamlessTransfer
public static MethodInfo LoadPlayerInternal; public static MethodInfo LoadPlayerInternal;
public static MethodInfo LoadMembersFromWorld; public static MethodInfo LoadMembersFromWorld;
public static FieldInfo DisconnectedClients;
public static FieldInfo MClients;
public static PropertyInfo MySessionLayer;
public static MethodInfo LoadMultiplayer; public static MethodInfo LoadMultiplayer;
private static ulong LocalSteamID;
public LoadServer() public LoadServer()
{ {
InitiatePatches(); InitiatePatches();
//TargetWorld = World;
//Server = e;
} }
@@ -109,6 +110,22 @@ namespace SeamlessClientPlugin.SeamlessTransfer
SyncLayerConstructor = SyncLayerType?.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { MyTransportLayerType }, null); SyncLayerConstructor = SyncLayerType?.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { MyTransportLayerType }, null);
TransportLayerConstructor = MyTransportLayerType?.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null); TransportLayerConstructor = MyTransportLayerType?.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null, new Type[1] { typeof(int) }, null);
MySessionConstructor = MySessionType?.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2] { typeof(MySyncLayer), typeof(bool) }, null); MySessionConstructor = MySessionType?.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[2] { typeof(MySyncLayer), typeof(bool) }, null);
MyMultiplayerClientBaseConstructor = MyMultiplayerClientBase?.GetConstructor(BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[] { typeof(MySyncLayer) }, null);
MethodInfo ClientJoined = ClientType.GetMethod("OnClientConnected", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo ClientLeft = SyncLayerType?.GetMethod("OnClientLeft", BindingFlags.Instance | BindingFlags.NonPublic);
Timer ClientChecker = new Timer(5000);
ClientChecker.Elapsed += ClientChecker_Elapsed;
ClientChecker.Start();
//Patcher.Patch(ClientJoined, prefix: new HarmonyMethod(GetPatchMethod(nameof(OnClientJoined))));
Patcher.Patch(ClientLeft, prefix: new HarmonyMethod(GetPatchMethod(nameof(OnClientLeft))));
if (ClientConstructor == null) if (ClientConstructor == null)
{ {
@@ -131,6 +148,15 @@ namespace SeamlessClientPlugin.SeamlessTransfer
} }
RemovePlayerFromDictionary = typeof(MyPlayerCollection).GetMethod("RemovePlayerFromDictionary", BindingFlags.Instance | BindingFlags.NonPublic); RemovePlayerFromDictionary = typeof(MyPlayerCollection).GetMethod("RemovePlayerFromDictionary", BindingFlags.Instance | BindingFlags.NonPublic);
DisconnectedClients = typeof(MyClientCollection).GetField("m_disconnectedClients", BindingFlags.Instance | BindingFlags.NonPublic);
MClients = typeof(MyClientCollection).GetField("m_clients", BindingFlags.Instance | BindingFlags.NonPublic);
MySessionLayer = typeof(MySession).GetProperty("SyncLayer", BindingFlags.Instance | BindingFlags.Public);
VirtualClients = typeof(MySession).GetField("VirtualClients", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); VirtualClients = typeof(MySession).GetField("VirtualClients", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
InitVirtualClients = VirtualClientsType.GetMethod("Init", BindingFlags.Instance | BindingFlags.Public); InitVirtualClients = VirtualClientsType.GetMethod("Init", BindingFlags.Instance | BindingFlags.Public);
LoadPlayerInternal = typeof(MyPlayerCollection).GetMethod("LoadPlayerInternal", BindingFlags.Instance | BindingFlags.NonPublic); LoadPlayerInternal = typeof(MyPlayerCollection).GetMethod("LoadPlayerInternal", BindingFlags.Instance | BindingFlags.NonPublic);
@@ -141,11 +167,10 @@ namespace SeamlessClientPlugin.SeamlessTransfer
LoadMultiplayer = typeof(MySession).GetMethod("LoadMultiplayer", BindingFlags.Static | BindingFlags.NonPublic); LoadMultiplayer = typeof(MySession).GetMethod("LoadMultiplayer", BindingFlags.Static | BindingFlags.NonPublic);
MethodInfo LoadingAction = typeof(MySessionLoader).GetMethod("LoadMultiplayerSession", BindingFlags.Public | BindingFlags.Static); MethodInfo LoadingAction = typeof(MySessionLoader).GetMethod("LoadMultiplayerSession", BindingFlags.Public | BindingFlags.Static);
Patcher.Patch(LoadingAction, prefix: new HarmonyMethod(GetPatchMethod(nameof(LoadMultiplayerSession)))); Patcher.Patch(LoadingAction, prefix: new HarmonyMethod(GetPatchMethod(nameof(LoadMultiplayerSession))));
} }
@@ -183,7 +208,8 @@ namespace SeamlessClientPlugin.SeamlessTransfer
} }
} }
}catch(Exception ex) }
catch (Exception ex)
{ {
SeamlessClient.TryShow(ex.ToString()); SeamlessClient.TryShow(ex.ToString());
} }
@@ -259,15 +285,68 @@ namespace SeamlessClientPlugin.SeamlessTransfer
if (SeamlessClient.IsSwitching && msg.JoinResult == JoinResult.OK) if (SeamlessClient.IsSwitching && msg.JoinResult == JoinResult.OK)
{ {
SeamlessClient.TryShow("User Joined! Result: " + msg.JoinResult.ToString()); SeamlessClient.TryShow("User Joined! Result: " + msg.JoinResult.ToString());
if(MySessionLayer == null)
{
SeamlessClient.TryShow("Null SessionLayer FieldInfo");
}
if (MySession.Static == null)
{
SeamlessClient.TryShow("Null MySession.Static");
}
if (MyMultiplayer.Static.SyncLayer == null)
{
SeamlessClient.TryShow("Null MyMultiplayer.Static.SyncLayer");
}
MySessionLayer.SetValue(MySession.Static , MyMultiplayer.Static.SyncLayer);
ForceClientConnection(); ForceClientConnection();
}else if (SeamlessClient.IsSwitching && msg.JoinResult != JoinResult.OK) MyMultiplayer.Static.StartProcessingClientMessages();
}
else if (SeamlessClient.IsSwitching && msg.JoinResult != JoinResult.OK)
{ {
SeamlessClient.TryShow("Failed to join server! Reason: " + msg.JoinResult.ToString()); SeamlessClient.TryShow("Failed to join server! Reason: " + msg.JoinResult.ToString());
MySession.Static.Unload(); MySession.Static?.Unload();
} }
} }
private static void OnClientJoined(MyPacket packet)
{
ConnectedClientDataMsg msg = MySerializer.CreateAndRead<ConnectedClientDataMsg>(packet.BitStream);
SeamlessClient.TryShow($"Client: {msg.ClientId} Name: {msg.Name} PacketSender: {packet.Sender.Id.Value}");
}
private static void OnClientLeft(ulong steamUserId, MyChatMemberStateChangeEnum leaveReason)
{
SeamlessClient.TryShow($"Client {steamUserId} left!");
}
private static void ClientChecker_Elapsed(object sender, ElapsedEventArgs e)
{
var Clients = Sync.Clients.GetClients();
SeamlessClient.TryShow("---------------------");
foreach (var client in Clients)
{
SeamlessClient.TryShow($"{client.DisplayName}:{client.SteamUserId}");
}
SeamlessClient.TryShow("---------------------");
}
public static void LoadWorldData(MyGameServerItem TargetServer, MyObjectBuilder_World TargetWorld) public static void LoadWorldData(MyGameServerItem TargetServer, MyObjectBuilder_World TargetWorld)
{ {
@@ -281,32 +360,39 @@ namespace SeamlessClientPlugin.SeamlessTransfer
try try
{ {
//m_memberData
MySandboxGame.Static.SessionCompatHelper.FixSessionComponentObjectBuilders(World.Checkpoint, World.Sector); MySandboxGame.Static.SessionCompatHelper.FixSessionComponentObjectBuilders(World.Checkpoint, World.Sector);
var LayerInstance = TransportLayerConstructor.Invoke(new object[] { 2 }); var LayerInstance = TransportLayerConstructor.Invoke(new object[] { 2 });
var SyncInstance = SyncLayerConstructor.Invoke(new object[] { LayerInstance }); var SyncInstance = SyncLayerConstructor.Invoke(new object[] { LayerInstance });
var instance = ClientConstructor.Invoke(new object[] { Server, SyncInstance }); var instance = ClientConstructor.Invoke(new object[] { Server, SyncInstance });
MyMulitplayerClient = instance; MyMulitplayerClient = instance;
MyMultiplayer.Static = Utility.CastToReflected(instance, ClientType);
MyMultiplayer.Static.ExperimentalMode = true;
MyMultiplayer.Static = (MyMultiplayerBase)instance;
MyMultiplayer.Static.ExperimentalMode = MySandboxGame.Config.ExperimentalMode;
SeamlessClient.TryShow("Successfully set MyMultiplayer.Static"); SeamlessClient.TryShow("Successfully set MyMultiplayer.Static");
//var m = ClientType.GetMethod("SendPlayerData", BindingFlags.Public | BindingFlags.Instance); //var m = ClientType.GetMethod("SendPlayerData", BindingFlags.Public | BindingFlags.Instance);
//m.Invoke(MyMultiplayer.Static, new object[] { MyGameService.UserName }); //m.Invoke(MyMultiplayer.Static, new object[] { MyGameService.UserName });
Server.GetGameTagByPrefix("gamemode"); Server.GetGameTagByPrefix("gamemode");
//typeof(MySession).GetMethod("LoadMembersFromWorld", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(MySession.Static, new object[] { LoadServer.TargetWorld, MyMultiplayer.Static }); //typeof(MySession).GetMethod("LoadMembersFromWorld", BindingFlags.NonPublic | BindingFlags.Instance).Invoke(MySession.Static, new object[] { LoadServer.TargetWorld, MyMultiplayer.Static });
//MyMultiplayer.Static.ClientJoined += Static_ClientJoined;
//MyScreenManager.CloseScreen(GUIScreenChat); //MyScreenManager.CloseScreen(GUIScreenChat);
MyHud.Chat.RegisterChat(MyMultiplayer.Static); MyHud.Chat.RegisterChat(MyMultiplayer.Static);
//MySession.SetSpectatorPositionFromServer(SeamlessClient.PreviousPosition ?? Vector3D.Zero); //MySession.SetSpectatorPositionFromServer(SeamlessClient.PreviousPosition ?? Vector3D.Zero);
MySession.Static.SetCameraController(MyCameraControllerEnum.SpectatorFixed); MySession.Static.SetCameraController(MyCameraControllerEnum.SpectatorFixed);
Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName);
Sync.Players.RegisterEvents();
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -314,6 +400,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
} }
} }
public static void LoadMP(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession) public static void LoadMP(MyObjectBuilder_World world, MyMultiplayerBase multiplayerSession)
{ {
SeamlessClient.TryShow("Starting LoadMP!"); SeamlessClient.TryShow("Starting LoadMP!");
@@ -449,11 +536,6 @@ namespace SeamlessClientPlugin.SeamlessTransfer
} }
private static void ForceClientConnection() private static void ForceClientConnection()
{ {
SeamlessClient.IsSwitching = false; SeamlessClient.IsSwitching = false;
@@ -474,7 +556,8 @@ namespace SeamlessClientPlugin.SeamlessTransfer
LoadMP(World, MyMultiplayer.Static); LoadMP(World, MyMultiplayer.Static);
}catch(Exception ex) }
catch (Exception ex)
{ {
SeamlessClient.TryShow(ex.ToString()); SeamlessClient.TryShow(ex.ToString());
} }
@@ -490,10 +573,6 @@ namespace SeamlessClientPlugin.SeamlessTransfer
MyPlayerCollection.RequestLocalRespawn(); MyPlayerCollection.RequestLocalRespawn();
} }
//typeof(MyGuiScreenTerminal).GetMethod("CreateTabs") //typeof(MyGuiScreenTerminal).GetMethod("CreateTabs")
MyMultiplayer.Static.OnSessionReady(); MyMultiplayer.Static.OnSessionReady();
MySession.Static.LoadDataComponents(); MySession.Static.LoadDataComponents();
@@ -505,7 +584,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
SeamlessClient.TryShow("OnlinePlayers: " + MySession.Static.Players.GetOnlinePlayers().Count); SeamlessClient.TryShow("OnlinePlayers: " + MySession.Static.Players.GetOnlinePlayers().Count);
SeamlessClient.TryShow("Loading Complete!"); SeamlessClient.TryShow("Loading Complete!");
MyMultiplayer.Static.OnSessionReady();
//Recreate all controls... Will fix weird gui/paint/crap //Recreate all controls... Will fix weird gui/paint/crap
MyGuiScreenHudSpace.Static.RecreateControls(true); MyGuiScreenHudSpace.Static.RecreateControls(true);
@@ -531,26 +610,27 @@ namespace SeamlessClientPlugin.SeamlessTransfer
try try
{ {
//Remove all old players
foreach (var Client in MySession.Static.Players.GetOnlinePlayers())
{
if (Client.Id.SteamId == Sync.MyId)
continue;
SeamlessClient.TryShow("Disconnecting: " + Client.DisplayName); //Reset Disconnected Clients
RemovePlayerFromDictionary.Invoke(MySession.Static.Players, new object[] { Client.Id });
}
//Clear all exsisting clients
foreach (var Client in Sync.Clients.GetClients().ToList()) foreach (var Client in Sync.Clients.GetClients().ToList())
{ {
if (Client.SteamUserId == Sync.MyId) if (Client.SteamUserId == Sync.MyId)
continue; {
break;
}
Sync.Clients.RemoveClient(Client.SteamUserId); Sync.Clients.RemoveClient(Client.SteamUserId);
} }
//Remove all old players
//Sync.Clients.Clear();
//Add server client
Sync.Clients.AddClient(Sync.ServerId, "Good.bot");
//Sync.Clients.AddClient(Sync.MyId, Sync.MyName);
object VirtualClientsValue = VirtualClients.GetValue(MySession.Static); object VirtualClientsValue = VirtualClients.GetValue(MySession.Static);
//Re-Initilize Virtual clients //Re-Initilize Virtual clients
@@ -560,7 +640,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
//Load Members from world //Load Members from world
SeamlessClient.TryShow("Loading Members From World!"); SeamlessClient.TryShow("Loading Members From World!");
LoadMembersFromWorld.Invoke(MySession.Static, new object[] { World, MyMulitplayerClient }); //LoadMembersFromWorld.Invoke(MySession.Static, new object[] { World, MyMulitplayerClient });
foreach (var Client in World.Checkpoint.Clients) foreach (var Client in World.Checkpoint.Clients)
{ {
SeamlessClient.TryShow("Adding New Client: " + Client.Name); SeamlessClient.TryShow("Adding New Client: " + Client.Name);
@@ -602,10 +682,11 @@ namespace SeamlessClientPlugin.SeamlessTransfer
foreach (KeyValuePair<MyObjectBuilder_Checkpoint.PlayerId, MyObjectBuilder_Player> item3 in checkpoint.AllPlayersData.Dictionary) foreach (KeyValuePair<MyObjectBuilder_Checkpoint.PlayerId, MyObjectBuilder_Player> item3 in checkpoint.AllPlayersData.Dictionary)
{ {
MyPlayer.PlayerId playerId5 = new MyPlayer.PlayerId(item3.Key.GetClientId(), item3.Key.SerialId); MyPlayer.PlayerId playerId5 = new MyPlayer.PlayerId(item3.Key.GetClientId(), item3.Key.SerialId);
SeamlessClient.TryShow($"ConnectedPlayer: {playerId5.ToString()}");
if (savingPlayerId.HasValue && playerId5.SteamId == savingPlayerId.Value.SteamId) if (savingPlayerId.HasValue && playerId5.SteamId == savingPlayerId.Value.SteamId)
{ {
playerId5 = new MyPlayer.PlayerId(Sync.MyId, playerId5.SerialId); playerId5 = new MyPlayer.PlayerId(Sync.MyId, playerId5.SerialId);
} }
LoadPlayerInternal.Invoke(MySession.Static.Players, new object[] { playerId5, item3.Value, false }); LoadPlayerInternal.Invoke(MySession.Static.Players, new object[] { playerId5, item3.Value, false });
@@ -632,6 +713,7 @@ namespace SeamlessClientPlugin.SeamlessTransfer
} }
} }

View File

@@ -129,6 +129,9 @@ namespace SeamlessClientPlugin.SeamlessTransfer
{ {
if (MyMultiplayer.Static != null) if (MyMultiplayer.Static != null)
{ {
Sync.Clients.Clear();
Sync.Players.ClearPlayers();
MyHud.Chat.UnregisterChat(MyMultiplayer.Static); MyHud.Chat.UnregisterChat(MyMultiplayer.Static);
//OnPlayerCreated //OnPlayerCreated
//OnConnectedClient //OnConnectedClient

View File

@@ -1,4 +1,5 @@
using ProtoBuf; using HarmonyLib;
using ProtoBuf;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@@ -34,5 +35,12 @@ namespace SeamlessClientPlugin.Utilities
return Serializer.Deserialize<T>(m); return Serializer.Deserialize<T>(m);
} }
} }
public static dynamic CastToReflected(this object o, Type type)
{
return Convert.ChangeType(o, type);
}
} }
} }