From 849360629856c27dbd4c1643e8f543dfc105b3bc Mon Sep 17 00:00:00 2001 From: StalkR Date: Wed, 27 Dec 2023 23:14:31 +0100 Subject: [PATCH] timeoutfix: original source and diff from reddit from: https://www.reddit.com/r/spaceengineers/comments/f7ul3s/fix_for_server_is_not_responding_error/ by rexxar --- TimeoutFix.cs | 130 ++++++++++++++++++++++++++++++++++++++++++++++++++ joinfix.diff | 46 ++++++++++++++++++ 2 files changed, 176 insertions(+) create mode 100644 TimeoutFix.cs create mode 100644 joinfix.diff diff --git a/TimeoutFix.cs b/TimeoutFix.cs new file mode 100644 index 0000000..a332b15 --- /dev/null +++ b/TimeoutFix.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using VRage.Plugins; +using System.Threading.Tasks; +using ClientPlugin; +using Sandbox.Engine.Multiplayer; +using Sandbox.Engine.Networking; +using Sandbox.Game; +using Sandbox.Game.Gui; +using Sandbox.Graphics.GUI; +using VRage; +using VRage.GameServices; +using VRage.Utils; + +namespace TimeoutFixPlugin +{ + public class TimeoutFix : IPlugin + { + public void Dispose() + { + + } + + private static MethodInfo _target = typeof(MyJoinGameHelper).GetMethod("DownloadWorld", BindingFlags.NonPublic | BindingFlags.Static); + private static MethodInfo _patch = typeof(TimeoutFix).GetMethod(nameof(DownloadWorld), BindingFlags.NonPublic | BindingFlags.Static); + + private static FieldInfo _downloadField = typeof(MyWorkshop).GetField("m_downloadScreen", BindingFlags.NonPublic | BindingFlags.Static); + + private static MyGuiScreenMessageBox DownloadScreen => (MyGuiScreenMessageBox)_downloadField.GetValue(null); + + private static bool DownloadVisible => DownloadScreen?.Visible ?? false; + + public void Init(object gameInstance) + { + MethodUtil.ReplaceMethod(_patch, _target); + } + + public void Update() + { + } + + private static void DownloadWorld(MyGuiScreenProgress progress, MyMultiplayerBase multiplayer) + { + if (progress.Text != null) + { + progress.Text.Clear(); + progress.Text.Append(MyTexts.Get(MyCommonTexts.MultiplayerStateConnectingToServer)); + } + + MyLog.Default.WriteLine("World requested"); + + const float worldRequestTimeout = 40; // in seconds + Stopwatch worldRequestTime = Stopwatch.StartNew(); + + ulong serverId = multiplayer.GetOwner(); + bool connected = false; + progress.Tick += () => + { + MyP2PSessionState state = default(MyP2PSessionState); + MyGameService.Peer2Peer.GetSessionState(multiplayer.ServerId, ref state); + + if (!connected && state.ConnectionActive) + { + MyLog.Default.WriteLine("World requested - connection alive"); + connected = true; + if (progress.Text != null) + { + progress.Text.Clear(); + progress.Text.AppendLine("Using Rexxar's fixed join code! :D"); + progress.Text.Append(MyTexts.Get(MyCommonTexts.MultiplayerStateWaitingForServer)); + } + } + + bool isTop = MyScreenManager.IsScreenOnTop(progress); + //progress.Text.Clear(); + //progress.Text.AppendLine($"Elapsed: {worldRequestTime.ElapsedMilliseconds}"); + //progress.Text.AppendLine($"Download Status: {DownloadScreen?.Visible.ToString() ?? "Not open"} : {DownloadVisible}"); + //progress.Text.AppendLine("Connecting: " + state.Connecting); + //progress.Text.AppendLine("ConnectionActive: " + state.ConnectionActive); + //progress.Text.AppendLine("Relayed: " + state.UsingRelay); + //progress.Text.AppendLine("Bytes queued: " + state.BytesQueuedForSend); + //progress.Text.AppendLine("Packets queued: " + state.PacketsQueuedForSend); + //progress.Text.AppendLine("Last session error: " + state.LastSessionError); + //progress.Text.AppendLine("Original server: " + serverId); + ////progress.Text.AppendLine("Current server: " + multiplayer.Lobby.GetOwner()); + //progress.Text.AppendLine("Game version: " + multiplayer.AppVersion); + //progress.Text.Append($"IsTop: {isTop}"); + + if (serverId != multiplayer.GetOwner()) + { + MyLog.Default.WriteLine("World requested - failed, server changed"); + progress.Cancel(); + MyGuiSandbox.Show(MyCommonTexts.MultiplayerErrorServerHasLeft); + multiplayer.Dispose(); + } + + bool visible = DownloadVisible; + + if (!visible && isTop && !worldRequestTime.IsRunning) + { + worldRequestTime.Start(); + } + else if (visible || !isTop && worldRequestTime.IsRunning) + { + worldRequestTime.Stop(); + } + + if (visible && progress.Visible) + progress.HideScreen(); + else if (!visible && !progress.Visible) + progress.UnhideScreen(); + + + if (worldRequestTime.IsRunning && worldRequestTime.Elapsed.TotalSeconds > worldRequestTimeout) + { + MyLog.Default.WriteLine("World requested - failed, server changed"); + progress.Cancel(); + MyGuiSandbox.Show(MyCommonTexts.MultiplaterJoin_ServerIsNotResponding); + multiplayer.Dispose(); + } + }; + + multiplayer.DownloadWorld(); + } + } +} diff --git a/joinfix.diff b/joinfix.diff new file mode 100644 index 0000000..f996cca --- /dev/null +++ b/joinfix.diff @@ -0,0 +1,46 @@ +Index: Sources/Sandbox.Game/Engine/Networking/MyWorkshop.cs +=================================================================== +--- Sources/Sandbox.Game/Engine/Networking/MyWorkshop.cs (revision 124917) ++++ Sources/Sandbox.Game/Engine/Networking/MyWorkshop.cs (working copy) +@@ -196,6 +196,11 @@ + } + } + ++ public static bool DownloadScreenVisible ++ { ++ get { return m_downloadScreen?.Visible ?? false; } ++ } ++ + private static MyGuiScreenMessageBox m_downloadScreen; + private static DownloadModsResult m_downloadResult; + +Index: Sources/Sandbox.Game/Game/Screens/MyJoinGameHelper.cs +=================================================================== +--- Sources/Sandbox.Game/Game/Screens/MyJoinGameHelper.cs (revision 124917) ++++ Sources/Sandbox.Game/Game/Screens/MyJoinGameHelper.cs (working copy) +@@ -247,16 +247,23 @@ + } + + bool isTop = MyScreenManager.IsScreenOnTop(progress); +- if (isTop && !worldRequestTime.IsRunning) ++ bool visible = MyWorkshop.DownloadScreenVisible; ++ ++ if (!visible && isTop && !worldRequestTime.IsRunning) + { + worldRequestTime.Start(); + } +- else if (!isTop && worldRequestTime.IsRunning) ++ else if (visible || !isTop && worldRequestTime.IsRunning) + { + worldRequestTime.Stop(); + } + ++ if (visible && progress.Visible) ++ progress.HideScreen(); ++ else if (!visible && !progress.Visible) ++ progress.UnhideScreen(); + ++ + if (worldRequestTime.IsRunning && worldRequestTime.Elapsed.TotalSeconds > worldRequestTimeout) + { + MyLog.Default.WriteLine("World requested - failed, server changed");