Decompiled source of DisableClientsideTimeout v1.1.0

DisableClientsideTimeout.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DisableClientsideTimeout")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Disables Photon Timeout Disconnect checks")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+68679422f3642459482829ae3ca2b9d381bc7bff")]
[assembly: AssemblyProduct("DisableClientsideTimeout")]
[assembly: AssemblyTitle("DisableClientsideTimeout")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.0.0")]
[module: UnverifiableCode]
namespace DisableClientsideTimeout;

[BepInPlugin("DisableClientsideTimeout", "DisableClientsideTimeout", "1.1.0")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	private Harmony harmony;

	private static ConfigEntry<bool> enablePatch;

	private void Awake()
	{
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0068: Expected O, but got Unknown
		//IL_0129: Unknown result type (might be due to invalid IL or missing references)
		//IL_0135: Expected O, but got Unknown
		//IL_015b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		enablePatch = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enable Patch (Restart Required)", true, "Enable this to disable the Photon TimeoutDisconnect check. Disable if you experience severe lag/desync on very poor connections.");
		Log.LogInfo((object)"Plugin DisableClientsideTimeout is loaded!");
		if (enablePatch.Value)
		{
			Log.LogInfo((object)"Patch is enabled via config. Applying Harmony patches...");
			harmony = new Harmony("DisableClientsideTimeout");
			try
			{
				Type type = AccessTools.TypeByName("ExitGames.Client.Photon.EnetPeer");
				Type type2 = AccessTools.TypeByName("ExitGames.Client.Photon.TPeer");
				if (type == null)
				{
					Log.LogError((object)"Failed to find EnetPeer type!");
					return;
				}
				if (type2 == null)
				{
					Log.LogError((object)"Failed to find TPeer type!");
					return;
				}
				MethodInfo methodInfo = AccessTools.Method(type, "SendOutgoingCommands", (Type[])null, (Type[])null);
				MethodInfo methodInfo2 = AccessTools.Method(type2, "DispatchIncomingCommands", (Type[])null, (Type[])null);
				MethodInfo methodInfo3 = AccessTools.Method(typeof(TimeoutDisconnectPatch), "TranspilerEnetPeer", (Type[])null, (Type[])null);
				MethodInfo methodInfo4 = AccessTools.Method(typeof(TimeoutDisconnectPatch), "TranspilerTPeer", (Type[])null, (Type[])null);
				if (methodInfo == null)
				{
					Log.LogError((object)"Failed to find EnetPeer.SendOutgoingCommands method!");
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null);
				}
				if (methodInfo2 == null)
				{
					Log.LogError((object)"Failed to find TPeer.DispatchIncomingCommands method!");
				}
				else
				{
					harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null);
				}
				Log.LogInfo((object)"Successfully applied timeout patches.");
				return;
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Error applying patches: {arg}");
				return;
			}
		}
		Log.LogInfo((object)"Patch is disabled via config. Skipping Harmony patches.");
	}
}
internal static class TimeoutDisconnectPatch
{
	private static readonly Type PeerBaseType = AccessTools.TypeByName("ExitGames.Client.Photon.PeerBase");

	private static readonly MethodInfo debugOut = AccessTools.PropertyGetter(PeerBaseType, "debugOut");

	private static readonly MethodInfo EnqueueStatusCallback = AccessTools.Method(PeerBaseType, "EnqueueStatusCallback", (Type[])null, (Type[])null);

	internal static IEnumerable<CodeInstruction> TranspilerEnetPeer(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
	{
		List<CodeInstruction> list = new List<CodeInstruction>(instructions);
		bool flag = false;
		MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("ExitGames.Client.Photon.PeerBase"), "EnqueueStatusCallback", (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogError((object)"TranspilerEnetPeer: Could not find PeerBase.EnqueueStatusCallback!");
			}
			return instructions;
		}
		for (int i = 0; i < list.Count - 1; i++)
		{
			if (list[i].opcode == OpCodes.Ldc_I4 && list[i].operand is int num && num == 1040 && list[i + 1].opcode == OpCodes.Call && list[i + 1].operand is MethodInfo methodInfo2 && methodInfo2 == methodInfo)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"Patching EnetPeer.SendOutgoingCommands: Found TimeoutDisconnect call. Replacing with NOPs.");
				}
				list[i].opcode = OpCodes.Nop;
				list[i].operand = null;
				list[i + 1].opcode = OpCodes.Nop;
				list[i + 1].operand = null;
				flag = true;
				break;
			}
		}
		if (!flag)
		{
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogWarning((object)"Could not find patch location in EnetPeer.SendOutgoingCommands");
			}
		}
		return list;
	}

	internal static IEnumerable<CodeInstruction> TranspilerTPeer(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
	{
		List<CodeInstruction> list = new List<CodeInstruction>(instructions);
		bool flag = false;
		MethodInfo methodInfo = AccessTools.Method(AccessTools.TypeByName("ExitGames.Client.Photon.PeerBase"), "EnqueueStatusCallback", (Type[])null, (Type[])null);
		if (methodInfo == null)
		{
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogError((object)"TranspilerTPeer: Could not find PeerBase.EnqueueStatusCallback!");
			}
			return instructions;
		}
		for (int i = 0; i < list.Count - 1; i++)
		{
			if (list[i].opcode == OpCodes.Ldc_I4 && list[i].operand is int num && num == 1040 && list[i + 1].opcode == OpCodes.Call && list[i + 1].operand is MethodInfo methodInfo2 && methodInfo2 == methodInfo)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"Patching TPeer.DispatchIncomingCommands: Found TimeoutDisconnect call. Replacing with NOPs.");
				}
				list[i].opcode = OpCodes.Nop;
				list[i].operand = null;
				list[i + 1].opcode = OpCodes.Nop;
				list[i + 1].operand = null;
				flag = true;
				break;
			}
		}
		if (!flag)
		{
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogWarning((object)"Could not find patch location in TPeer.DispatchIncomingCommands");
			}
		}
		return list;
	}
}
public static class PluginInfo
{
	public const string PLUGIN_GUID = "DisableClientsideTimeout";

	public const string PLUGIN_NAME = "DisableClientsideTimeout";

	public const string PLUGIN_VERSION = "1.1.0";
}