diff --git a/Components/MyGUIScreenMedicalsPatch.cs b/Components/MyGUIScreenMedicalsPatch.cs index cc01c8b..977e0f1 100644 --- a/Components/MyGUIScreenMedicalsPatch.cs +++ b/Components/MyGUIScreenMedicalsPatch.cs @@ -39,6 +39,10 @@ namespace SeamlessClient.Components return; MyGuiControlTable myGuiControlTable = (MyGuiControlTable)typeof(MyGuiScreenMedicals).GetField("m_respawnsTable", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).GetValue(__instance); + if (myGuiControlTable == null) + return; + + string s = MyTexts.GetString(MySpaceTexts.SpawnInSpaceSuit); foreach (var item in myGuiControlTable.Rows) { diff --git a/Components/ServerSwitcherComponent.cs b/Components/ServerSwitcherComponent.cs index 2f18618..2e0a88f 100644 --- a/Components/ServerSwitcherComponent.cs +++ b/Components/ServerSwitcherComponent.cs @@ -180,13 +180,14 @@ namespace SeamlessClient.ServerSwitching } SendPlayerData.Invoke(MyMultiplayer.Static, new object[] { MyGameService.OnlineName }); + isSwitch = false; } } public static bool LoadClientsFromWorld(ref List clients) { - if(clients == null || clients.Count == 0) - return false; + if(!isSwitch || clients == null || clients.Count == 0) + return true; //Dictionary @@ -209,13 +210,16 @@ namespace SeamlessClient.ServerSwitching } - return true; + return false; } private static bool ProcessAllMembersData(ref AllMembersDataMsg msg) { + if(!isSwitch) + return true; + Sync.Players.ClearIdentities(); if (msg.Identities != null) @@ -610,11 +614,6 @@ namespace SeamlessClient.ServerSwitching PauseClient.Invoke(MyMultiplayer.Static, new object[] { false }); MySandboxGame.PausePop(); MyHud.Notifications.Remove(MyNotificationSingletons.ConnectionProblem); - - - - - isSwitch = false; } diff --git a/Components/ServerSwitcherComponentOLD.cs b/Components/ServerSwitcherComponentOLD.cs index 2b9f664..f47514c 100644 --- a/Components/ServerSwitcherComponentOLD.cs +++ b/Components/ServerSwitcherComponentOLD.cs @@ -27,12 +27,19 @@ using Sandbox.Game; using VRage.Game.ModAPI; using VRage.Utils; using SeamlessClient.ServerSwitching; +using Sandbox.Game.Entities.Character; +using VRage.Game.Utils; +using VRage; +using Sandbox.Game.GameSystems.CoordinateSystem; namespace SeamlessClient.Components { public class ServerSwitcherComponentOLD : ComponentBase { - private static bool isSeamlessSwitching = false; + private static bool isSeamlessSwitching { get; set; } = false; + private static bool WaitingForClientCheck { get; set; } = false; + + private static ConstructorInfo TransportLayerConstructor; private static ConstructorInfo SyncLayerConstructor; private static ConstructorInfo ClientConstructor; @@ -53,9 +60,28 @@ namespace SeamlessClient.Components private string OldArmorSkin { get; set; } = string.Empty; public ServerSwitcherComponentOLD() { Instance = this; } + public static string SwitchingText = string.Empty; + public override void Update() + { + //Toggle waiting for client check + if (WaitingForClientCheck == false && isSeamlessSwitching) + WaitingForClientCheck = true; + if(WaitingForClientCheck && MySession.Static.LocalHumanPlayer != null) + WaitingForClientCheck = false; + + if (isSeamlessSwitching || WaitingForClientCheck) + { + //SeamlessClient.TryShow("Switching Servers!"); + MyRenderProxy.DebugDrawText2D(new VRageMath.Vector2(MySandboxGame.ScreenViewport.Width/2, MySandboxGame.ScreenViewport.Height - 150), SwitchingText, VRageMath.Color.AliceBlue, 1f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); + MyRenderProxy.DebugDrawText2D(new VRageMath.Vector2(MySandboxGame.ScreenViewport.Width / 2, MySandboxGame.ScreenViewport.Height - 200), $"Transferring to {TargetServer.Name}", VRageMath.Color.Yellow, 1.5f, MyGuiDrawAlignEnum.HORISONTAL_CENTER_AND_VERTICAL_CENTER); + + + MyRenderProxy.DebugDrawLine2D(new VRageMath.Vector2((MySandboxGame.ScreenViewport.Width / 2) - 250, MySandboxGame.ScreenViewport.Height - 170), new VRageMath.Vector2((MySandboxGame.ScreenViewport.Width / 2)+250, MySandboxGame.ScreenViewport.Height - 170), VRageMath.Color.Blue, VRageMath.Color.Green); + } + } public override void Patch(Harmony patcher) @@ -85,13 +111,28 @@ namespace SeamlessClient.Components //SeamlessClient.TryShow("User Joined! Result: " + msg.JoinResult.ToString()); //Invoke the switch event + SwitchingText = "Server Responded! Removing Old Entities and forcing client connection!"; + RemoveOldEntities(); ForceClientConnection(); + + //Fix any character issues + if (MySession.Static.LocalCharacter != null) + MySession.Static.LocalHumanPlayer.SpawnIntoCharacter(MySession.Static.LocalCharacter); + isSeamlessSwitching = false; } } public void StartBackendSwitch(MyGameServerItem _TargetServer, MyObjectBuilder_World _TargetWorld) { + + if(MySession.Static.LocalCharacter != null) + { + var viewMatrix = MySession.Static.LocalCharacter.GetViewMatrix(); + MySpectator.Static.SetViewMatrix(viewMatrix); + } + + SwitchingText = "Starting Seamless Switch... Please wait!"; isSeamlessSwitching = true; OldArmorSkin = MySession.Static.LocalHumanPlayer.BuildArmorSkin; TargetServer = _TargetServer; @@ -104,8 +145,8 @@ namespace SeamlessClient.Components UnloadCurrentServer(); SetNewMultiplayerClient(); //SeamlessClient.IsSwitching = false; - + SwitchingText = "Waiting for server response..."; }, "SeamlessClient"); } @@ -129,12 +170,13 @@ namespace SeamlessClient.Components // Set the new SyncLayer to the MySession.Static.SyncLayer MySessionLayer.SetValue(MySession.Static, MyMultiplayer.Static.SyncLayer); + SwitchingText = "New Multiplayer Session Set"; Seamless.TryShow("Successfully set MyMultiplayer.Static"); Sync.Clients.SetLocalSteamId(Sync.MyId, false, MyGameService.UserName); Sync.Players.RegisterEvents(); - + SwitchingText = "Registering Player Events"; } @@ -147,7 +189,7 @@ namespace SeamlessClient.Components //Load force load any connected players LoadConnectedClients(); - + SwitchingText = "Loaded Connected Clients"; MySector.InitEnvironmentSettings(TargetWorld.Sector.Environment); @@ -159,10 +201,8 @@ namespace SeamlessClient.Components MyModAPIHelper.Initialize(); MySession.Static.LoadDataComponents(); - - //MySession.Static.LoadObjectBuildersComponents(TargetWorld.Checkpoint.SessionComponents); MyModAPIHelper.Initialize(); - // MySession.Static.LoadObjectBuildersComponents(TargetWorld.Checkpoint.SessionComponents); + //MethodInfo A = typeof(MySession).GetMethod("LoadGameDefinition", BindingFlags.Instance | BindingFlags.NonPublic); @@ -171,7 +211,7 @@ namespace SeamlessClient.Components MyMultiplayer.Static.OnSessionReady(); - + SwitchingText = "Session Ready"; UpdateWorldGenerator(); @@ -180,13 +220,14 @@ namespace SeamlessClient.Components MyHud.Chat.RegisterChat(MyMultiplayer.Static); GpsRegisterChat.Invoke(MySession.Static.Gpss, new object[] { MyMultiplayer.Static }); - + SwitchingText = "Registered Chat"; // Allow the game to start proccessing incoming messages in the buffer MyMultiplayer.Static.StartProcessingClientMessages(); //Recreate all controls... Will fix weird gui/paint/crap MyGuiScreenHudSpace.Static.RecreateControls(true); + SwitchingText = "Client Registered. Waiting for entities from server..."; //MySession.Static.LocalHumanPlayer.BuildArmorSkin = OldArmorSkin; } @@ -441,8 +482,7 @@ namespace SeamlessClient.Components throw new Exception("MyMultiplayer.Static is null on unloading? dafuq?"); - RemoveOldEntities(); - + SwitchingText = "Unloading Local Server Components"; //Try and close the quest log MySessionComponentIngameHelp component = MySession.Static.GetComponent(); component?.TryCancelObjective(); @@ -463,6 +503,10 @@ namespace SeamlessClient.Components MyMultiplayer.Static.ReplicationLayer.Dispose(); MyMultiplayer.Static.Dispose(); MyMultiplayer.Static = null; + SwitchingText = "Local Multiplayer Disposed"; + + //Clear grid coord systems + ResetCoordinateSystems(); //Close any respawn screens that are open MyGuiScreenMedicals.Close(); @@ -471,7 +515,7 @@ namespace SeamlessClient.Components } - private void RemoveOldEntities() + private static void RemoveOldEntities() { foreach (var ent in MyEntities.GetEntities()) { @@ -482,6 +526,11 @@ namespace SeamlessClient.Components } } + private static void ResetCoordinateSystems() + { + AccessTools.Field(typeof(MyCoordinateSystem), "m_lastCoordSysId").SetValue(MyCoordinateSystem.Static, 1L); + AccessTools.Field(typeof(MyCoordinateSystem), "m_localCoordSystems").SetValue(MyCoordinateSystem.Static, new Dictionary()); + } diff --git a/Messages/WorldRequestData.cs b/Messages/WorldRequestData.cs index 678b2ac..106b450 100644 --- a/Messages/WorldRequestData.cs +++ b/Messages/WorldRequestData.cs @@ -24,7 +24,7 @@ namespace SeamlessClient.Messages [ProtoMember(3)] public string PlayerName; [ProtoMember(4)] public byte[] WorldData; - [ProtoMember(5)] public MyObjectBuilder_Gps GpsCollection; + [ProtoMember(5)] public MyObjectBuilder_Gps GpsCollection { get; set; } public WorldRequest() { diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 8dd9d50..6ef9a1b 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -33,5 +33,5 @@ using System.Runtime.InteropServices; // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.0.0.6")] //Set these both to the same -[assembly: AssemblyFileVersion("2.0.0.6")] +[assembly: AssemblyVersion("3.0.0.6")] //Set these both to the same +[assembly: AssemblyFileVersion("3.0.0.6")] diff --git a/Seamless.cs b/Seamless.cs index c6bcb55..f38070a 100644 --- a/Seamless.cs +++ b/Seamless.cs @@ -34,12 +34,12 @@ namespace SeamlessClient public static ushort SeamlessClientNetId = 2936; private List allComps = new List(); + private Assembly thisAssembly => typeof(Seamless).Assembly; private bool Initilized = false; public static bool isSeamlessServer { get; private set; } = false; public static bool isDebug = false; public static bool UseNewVersion = false; - - + public void Init(object gameInstance) @@ -47,19 +47,19 @@ namespace SeamlessClient TryShow($"Running Seamless Client Plugin v[{SeamlessVersion}]"); SeamlessPatcher = new Harmony("SeamlessClientPatcher"); GetComponents(); - PatchComponents(SeamlessPatcher); } + + private void GetComponents() { int failedCount = 0; foreach (Type type in IntrospectionContext.Global.CollectDerivedTypes(typeof(Seamless).Module)) { - try { ComponentBase s = (ComponentBase)Activator.CreateInstance(type); @@ -109,7 +109,6 @@ namespace SeamlessClient } } - private static void MessageHandler(ushort packetID, byte[] data, ulong sender, bool fromServer) { //Ignore anything except dedicated server @@ -144,6 +143,9 @@ namespace SeamlessClient } } + + + public static void SendSeamlessVersion() { ClientMessage response = new ClientMessage(SeamlessVersion.ToString()); @@ -159,6 +161,10 @@ namespace SeamlessClient } public void Update() { + + + + allComps.ForEach(x => x.Update()); if (MyAPIGateway.Multiplayer == null) @@ -214,8 +220,6 @@ namespace SeamlessClient - - public static void TryShow(string message) { if (MySession.Static?.LocalHumanPlayer != null && isDebug) diff --git a/SeamlessClient.csproj b/SeamlessClient.csproj index 9ea35ec..e93c1bf 100644 --- a/SeamlessClient.csproj +++ b/SeamlessClient.csproj @@ -1,7 +1,7 @@  - net8.0-windows + net9.0-windows win-x64 disable true diff --git a/global.json b/global.json index da113e4..90b3042 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.0", + "version": "9.0.0", "rollForward": "latestFeature", "allowPrerelease": false }