v2.2 as decompiled
This commit is contained in:
173
ClientPlugin.cs
Normal file
173
ClientPlugin.cs
Normal file
@@ -0,0 +1,173 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace ClientPlugin
|
||||
{
|
||||
public static class MethodUtil
|
||||
{
|
||||
public static void SwapMethod(MethodBase source, MethodBase dest)
|
||||
{
|
||||
bool flag = !MethodUtil.MethodSignaturesEqual(source, dest);
|
||||
if (flag)
|
||||
{
|
||||
throw new ArgumentException("The method signatures are not the same.", "source");
|
||||
}
|
||||
MethodUtil.SwapMethod(MethodUtil.GetMethodAddress(source), dest);
|
||||
}
|
||||
|
||||
public unsafe static void SwapMethod(IntPtr srcAdr, MethodBase dest)
|
||||
{
|
||||
IntPtr methodAddress = MethodUtil.GetMethodAddress(dest);
|
||||
bool flag = IntPtr.Size == 8;
|
||||
if (flag)
|
||||
{
|
||||
ulong* ptr = (ulong*)srcAdr.ToPointer();
|
||||
ulong* ptr2 = (ulong*)methodAddress.ToPointer();
|
||||
ulong num = *ptr;
|
||||
*ptr = *ptr2;
|
||||
*ptr2 = num;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint* ptr3 = (uint*)methodAddress.ToPointer();
|
||||
uint* ptr4 = (uint*)srcAdr.ToPointer();
|
||||
uint num2 = *ptr4;
|
||||
*ptr4 = *ptr3;
|
||||
*ptr3 = num2;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReplaceMethod(MethodBase source, MethodBase dest)
|
||||
{
|
||||
bool flag = !MethodUtil.MethodSignaturesEqual(source, dest);
|
||||
if (flag)
|
||||
{
|
||||
throw new ArgumentException("The method signatures are not the same.", "source");
|
||||
}
|
||||
MethodUtil.ReplaceMethod(MethodUtil.GetMethodAddress(source), dest);
|
||||
}
|
||||
|
||||
public unsafe static void ReplaceMethod(IntPtr srcAdr, MethodBase dest)
|
||||
{
|
||||
IntPtr methodAddress = MethodUtil.GetMethodAddress(dest);
|
||||
bool flag = IntPtr.Size == 8;
|
||||
if (flag)
|
||||
{
|
||||
ulong* ptr = (ulong*)methodAddress.ToPointer();
|
||||
*ptr = (ulong)(*(long*)srcAdr.ToPointer());
|
||||
}
|
||||
else
|
||||
{
|
||||
uint* ptr2 = (uint*)methodAddress.ToPointer();
|
||||
*ptr2 = *(uint*)srcAdr.ToPointer();
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe static IntPtr GetMethodAddress(MethodBase method)
|
||||
{
|
||||
bool flag = method is DynamicMethod;
|
||||
IntPtr intPtr;
|
||||
if (flag)
|
||||
{
|
||||
intPtr = MethodUtil.GetDynamicMethodAddress(method);
|
||||
}
|
||||
else
|
||||
{
|
||||
RuntimeHelpers.PrepareMethod(method.MethodHandle);
|
||||
intPtr = new IntPtr((void*)((byte*)method.MethodHandle.Value.ToPointer() + 8L));
|
||||
}
|
||||
return intPtr;
|
||||
}
|
||||
|
||||
private unsafe static IntPtr GetDynamicMethodAddress(MethodBase method)
|
||||
{
|
||||
byte* ptr = (byte*)MethodUtil.GetDynamicMethodRuntimeHandle(method).Value.ToPointer();
|
||||
bool flag = IntPtr.Size == 8;
|
||||
IntPtr intPtr;
|
||||
if (flag)
|
||||
{
|
||||
ulong* ptr2 = (ulong*)ptr;
|
||||
ptr2 += 6;
|
||||
intPtr = new IntPtr((void*)ptr2);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint* ptr3 = (uint*)ptr;
|
||||
ptr3 += 6;
|
||||
intPtr = new IntPtr((void*)ptr3);
|
||||
}
|
||||
return intPtr;
|
||||
}
|
||||
|
||||
private static RuntimeMethodHandle GetDynamicMethodRuntimeHandle(MethodBase method)
|
||||
{
|
||||
bool flag = method is DynamicMethod;
|
||||
if (flag)
|
||||
{
|
||||
FieldInfo field = typeof(DynamicMethod).GetField("m_method", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
bool flag2 = field != null;
|
||||
if (flag2)
|
||||
{
|
||||
return (RuntimeMethodHandle)field.GetValue(method);
|
||||
}
|
||||
}
|
||||
return method.MethodHandle;
|
||||
}
|
||||
|
||||
private static bool MethodSignaturesEqual(MethodBase x, MethodBase y)
|
||||
{
|
||||
bool flag = x.CallingConvention != y.CallingConvention;
|
||||
bool flag2;
|
||||
if (flag)
|
||||
{
|
||||
flag2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type methodReturnType = MethodUtil.GetMethodReturnType(x);
|
||||
Type methodReturnType2 = MethodUtil.GetMethodReturnType(y);
|
||||
bool flag3 = methodReturnType != methodReturnType2;
|
||||
if (flag3)
|
||||
{
|
||||
flag2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
ParameterInfo[] parameters = x.GetParameters();
|
||||
ParameterInfo[] parameters2 = y.GetParameters();
|
||||
bool flag4 = parameters.Length != parameters2.Length;
|
||||
if (flag4)
|
||||
{
|
||||
flag2 = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < parameters.Length; i++)
|
||||
{
|
||||
bool flag5 = parameters[i].ParameterType != parameters2[i].ParameterType;
|
||||
if (flag5)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
flag2 = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag2;
|
||||
}
|
||||
|
||||
private static Type GetMethodReturnType(MethodBase method)
|
||||
{
|
||||
MethodInfo methodInfo = method as MethodInfo;
|
||||
bool flag = methodInfo == null;
|
||||
if (flag)
|
||||
{
|
||||
throw new ArgumentException("Unsupported MethodBase : " + method.GetType().Name, "method");
|
||||
}
|
||||
return methodInfo.ReturnType;
|
||||
}
|
||||
}
|
||||
}
|
210
TimeoutFix.cs
210
TimeoutFix.cs
@@ -1,37 +1,46 @@
|
||||
using System.Diagnostics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using VRage.Plugins;
|
||||
using System.Text;
|
||||
using ClientPlugin;
|
||||
using Sandbox;
|
||||
using Sandbox.Engine.Multiplayer;
|
||||
using Sandbox.Engine.Networking;
|
||||
using Sandbox.Game;
|
||||
using Sandbox.Game.Gui;
|
||||
using Sandbox.Game.Screens;
|
||||
using Sandbox.Game.World;
|
||||
using Sandbox.Graphics.GUI;
|
||||
using VRage;
|
||||
using VRage.Game;
|
||||
using VRage.GameServices;
|
||||
using VRage.Plugins;
|
||||
using VRage.Utils;
|
||||
|
||||
namespace TimeoutFixPlugin
|
||||
{
|
||||
public class TimeoutFix : IPlugin
|
||||
public class TimeoutFix : IPlugin, IDisposable
|
||||
{
|
||||
public void Dispose()
|
||||
private static MyGuiScreenProgressBase m_progress
|
||||
{
|
||||
|
||||
get
|
||||
{
|
||||
return (MyGuiScreenProgressBase)((MyGuiScreenProgressBase)TimeoutFix._progressField.GetValue(null));
|
||||
}
|
||||
set
|
||||
{
|
||||
TimeoutFix._progressField.SetValue(null, value);
|
||||
}
|
||||
}
|
||||
|
||||
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 Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public void Init(object gameInstance)
|
||||
{
|
||||
// source for MethodUtil not given on the reddit post
|
||||
//MethodUtil.ReplaceMethod(_patch, _target);
|
||||
MethodUtil.ReplaceMethod(TimeoutFix._patch, TimeoutFix._target);
|
||||
MethodUtil.ReplaceMethod(TimeoutFix._receivePatch, TimeoutFix._receiveTarget);
|
||||
}
|
||||
|
||||
public void Update()
|
||||
@@ -40,86 +49,157 @@ namespace TimeoutFixPlugin
|
||||
|
||||
private static void DownloadWorld(MyGuiScreenProgress progress, MyMultiplayerBase multiplayer)
|
||||
{
|
||||
if (progress.Text != null)
|
||||
TimeoutFix._worldReceived = false;
|
||||
bool flag = progress.Text != null;
|
||||
if (flag)
|
||||
{
|
||||
progress.Text.Clear();
|
||||
progress.Text.Append(MyTexts.Get(MyCommonTexts.MultiplayerStateConnectingToServer));
|
||||
}
|
||||
|
||||
MyLog.Default.WriteLine("World requested");
|
||||
|
||||
const float worldRequestTimeout = 40; // in seconds
|
||||
MyLog.Default.WriteLine("World requested: Timeout fix v2.2");
|
||||
Stopwatch worldRequestTime = Stopwatch.StartNew();
|
||||
|
||||
ulong serverId = multiplayer.GetOwner();
|
||||
bool connected = false;
|
||||
progress.Tick += () =>
|
||||
progress.Tick += delegate
|
||||
{
|
||||
MyP2PSessionState state = default(MyP2PSessionState);
|
||||
MyGameService.Peer2Peer.GetSessionState(multiplayer.ServerId, ref state);
|
||||
|
||||
if (!connected && state.ConnectionActive)
|
||||
MyP2PSessionState myP2PSessionState = default(MyP2PSessionState);
|
||||
MyGameService.Peer2Peer.GetSessionState(multiplayer.ServerId, ref myP2PSessionState);
|
||||
bool flag2 = !connected && myP2PSessionState.ConnectionActive;
|
||||
if (flag2)
|
||||
{
|
||||
MyLog.Default.WriteLine("World requested - connection alive");
|
||||
connected = true;
|
||||
if (progress.Text != null)
|
||||
bool flag3 = progress.Text != null;
|
||||
if (flag3)
|
||||
{
|
||||
progress.Text.Clear();
|
||||
progress.Text.AppendLine("Using Rexxar's fixed join code! :D");
|
||||
progress.Text.AppendLine("Using Rexxar's fixed join code v2.2! :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())
|
||||
bool flag4 = connected && !myP2PSessionState.ConnectionActive;
|
||||
if (flag4)
|
||||
{
|
||||
MyLog.Default.WriteLine("World requested - failed, server changed");
|
||||
MyLog.Default.WriteLine("World request - connection dropped");
|
||||
progress.Cancel();
|
||||
MyGuiSandbox.Show(MyCommonTexts.MultiplayerErrorServerHasLeft);
|
||||
MyGuiSandbox.Show(MyCommonTexts.MultiplaterJoin_ServerIsNotResponding, default(MyStringId), MyMessageBoxStyleEnum.Error);
|
||||
MySessionLoader.UnloadAndExitToMenu();
|
||||
}
|
||||
bool flag5 = MyScreenManager.IsScreenOnTop((MyGuiScreenBase)progress);
|
||||
bool flag6 = serverId != multiplayer.GetOwner();
|
||||
if (flag6)
|
||||
{
|
||||
MyLog.Default.WriteLine(string.Format("World requested - failed, server changed: Expected {0} got {1}", serverId, multiplayer.GetOwner()));
|
||||
progress.Cancel();
|
||||
MyGuiSandbox.Show(MyCommonTexts.MultiplayerErrorServerHasLeft, default(MyStringId), MyMessageBoxStyleEnum.Error);
|
||||
multiplayer.Dispose();
|
||||
}
|
||||
|
||||
bool visible = DownloadVisible;
|
||||
|
||||
if (!visible && isTop && !worldRequestTime.IsRunning)
|
||||
bool flag7 = MyScreenManager.IsScreenOfTypeOpen(typeof(MyGuiScreenDownloadMods));
|
||||
bool flag8 = !flag7 && flag5 && !worldRequestTime.IsRunning;
|
||||
if (flag8)
|
||||
{
|
||||
worldRequestTime.Start();
|
||||
}
|
||||
else if (visible || !isTop && worldRequestTime.IsRunning)
|
||||
else
|
||||
{
|
||||
bool flag9 = flag7 || (!flag5 && worldRequestTime.IsRunning);
|
||||
if (flag9)
|
||||
{
|
||||
worldRequestTime.Stop();
|
||||
}
|
||||
|
||||
if (visible && progress.Visible)
|
||||
progress.HideScreen();
|
||||
else if (!visible && !progress.Visible)
|
||||
progress.UnhideScreen();
|
||||
|
||||
|
||||
if (worldRequestTime.IsRunning && worldRequestTime.Elapsed.TotalSeconds > worldRequestTimeout)
|
||||
}
|
||||
bool flag10 = flag7 && progress.Visible;
|
||||
if (flag10)
|
||||
{
|
||||
MyLog.Default.WriteLine("World requested - failed, server changed");
|
||||
progress.HideScreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
bool flag11 = !flag7 && !progress.Visible;
|
||||
if (flag11)
|
||||
{
|
||||
progress.UnhideScreen();
|
||||
}
|
||||
}
|
||||
bool flag12 = !TimeoutFix._worldReceived && worldRequestTime.IsRunning && (float)(worldRequestTime.ElapsedTicks / Stopwatch.Frequency) > 120f;
|
||||
if (flag12)
|
||||
{
|
||||
MyLog.Default.WriteLine("World requested - failed, timeout reached");
|
||||
MyLog.Default.WriteLine(string.Format("Elapsed : {0:N2}", worldRequestTime.ElapsedTicks / Stopwatch.Frequency));
|
||||
progress.Cancel();
|
||||
MyGuiSandbox.Show(MyCommonTexts.MultiplaterJoin_ServerIsNotResponding);
|
||||
multiplayer.Dispose();
|
||||
MyGuiSandbox.Show(MyCommonTexts.MultiplaterJoin_ServerIsNotResponding, default(MyStringId), MyMessageBoxStyleEnum.Error);
|
||||
MySessionLoader.UnloadAndExitToMenu();
|
||||
}
|
||||
};
|
||||
|
||||
multiplayer.DownloadWorld(0);
|
||||
multiplayer.DownloadWorld(MyFinalBuildConstants.APP_VERSION.Version);
|
||||
}
|
||||
|
||||
private static void CheckDx11AndJoin(MyObjectBuilder_World world, MyMultiplayerBase multiplayer)
|
||||
{
|
||||
bool scenario = multiplayer.Scenario;
|
||||
if (scenario)
|
||||
{
|
||||
MySessionLoader.LoadMultiplayerScenarioWorld(world, multiplayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
MySessionLoader.LoadMultiplayerSession(world, multiplayer);
|
||||
}
|
||||
}
|
||||
|
||||
private static void WorldReceived(MyObjectBuilder_World world, MyMultiplayerBase multiplayer)
|
||||
{
|
||||
bool flag = world == null;
|
||||
if (flag)
|
||||
{
|
||||
MyLog.Default.WriteLine("World requested - failed, version mismatch");
|
||||
TimeoutFix.m_progress.Cancel();
|
||||
TimeoutFix.m_progress = null;
|
||||
MyGuiSandbox.Show(MyCommonTexts.MultiplayerErrorAppVersionMismatch, default(MyStringId), MyMessageBoxStyleEnum.Error);
|
||||
multiplayer.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeoutFix._worldReceived = true;
|
||||
MyLog.Default.WriteLine("World requested - world data received");
|
||||
bool flag2;
|
||||
if (world == null)
|
||||
{
|
||||
flag2 = null != null;
|
||||
}
|
||||
else
|
||||
{
|
||||
MyObjectBuilder_Checkpoint checkpoint = world.Checkpoint;
|
||||
flag2 = ((checkpoint != null) ? checkpoint.Settings : null) != null;
|
||||
}
|
||||
bool flag3 = flag2 && !MySandboxGame.Config.ExperimentalMode;
|
||||
if (flag3)
|
||||
{
|
||||
MySessionLoader.UnloadAndExitToMenu();
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.AppendFormat(MyCommonTexts.DialogTextJoinWorldFailed, MyTexts.GetString(MyCommonTexts.MultiplayerErrorExperimental));
|
||||
MyGuiSandbox.AddScreen((MyGuiScreenBase)MyGuiSandbox.CreateMessageBox(MyMessageBoxStyleEnum.Error, MyMessageBoxButtonsType.OK, stringBuilder, MyTexts.Get(MyCommonTexts.MessageBoxCaptionError), null, null, null, null, null, 0, MyGuiScreenMessageBox.ResultEnum.YES, true, null, true, null, true, false, null));
|
||||
}
|
||||
else
|
||||
{
|
||||
TimeoutFix.m_progress = null;
|
||||
TimeoutFix.CheckDx11AndJoin(world, multiplayer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static MethodInfo _target = typeof(MyJoinGameHelper).GetMethod("DownloadWorld", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
private static MethodInfo _patch = typeof(TimeoutFix).GetMethod("DownloadWorld", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
private static MethodInfo _receiveTarget = typeof(MyJoinGameHelper).GetMethod("WorldReceived", BindingFlags.Static | BindingFlags.Public);
|
||||
|
||||
private static MethodInfo _receivePatch = typeof(TimeoutFix).GetMethod("WorldReceived", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
private static bool _worldReceived;
|
||||
|
||||
private static readonly FieldInfo _progressField = typeof(MyJoinGameHelper).GetField("m_progress", BindingFlags.Static | BindingFlags.NonPublic);
|
||||
|
||||
private const string VERSION = "v2.2";
|
||||
}
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
@@ -32,8 +33,10 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PdbPath>none</PdbPath>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ClientPlugin.cs" />
|
||||
<Compile Include="TimeoutFix.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
@@ -45,6 +48,7 @@
|
||||
<HintPath>GameBinaries\Sandbox.Graphics.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="VRage">
|
||||
<HintPath>GameBinaries\VRage.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -54,6 +58,9 @@
|
||||
<Reference Include="VRage.Library">
|
||||
<HintPath>GameBinaries\VRage.Library.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="VRage.Math">
|
||||
<HintPath>GameBinaries\VRage.Math.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
Reference in New Issue
Block a user