Decompiled source of DisableClientSideTimeout v1.0.0

com.chouja.DisableClientSideTimeout.dll

Decompiled 3 days 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.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("com.chouja.DisableClientSideTimeout")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fb6d09862f1bf05d7bb1d8c483a6747d66347675")]
[assembly: AssemblyProduct("com.chouja.DisableClientSideTimeout")]
[assembly: AssemblyTitle("DisableClientSideTimeout")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BepInEx
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class BepInAutoPluginAttribute : Attribute
	{
		public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace BepInEx.Preloader.Core.Patching
{
	[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
	[Conditional("CodeGeneration")]
	internal sealed class PatcherAutoPluginAttribute : Attribute
	{
		public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null)
		{
		}
	}
}
namespace DisableClientSideTimeout
{
	[BepInPlugin("com.chouja.DisableClientSideTimeout", "DisableClientSideTimeout", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Id = "com.chouja.DisableClientSideTimeout";

		internal static ManualLogSource Log { get; private set; }

		public static string Name => "DisableClientSideTimeout";

		public static string Version => "1.0.0";

		private void Awake()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			Log.LogInfo((object)("Plugin " + Name + " is loaded!"));
			Harmony val = new Harmony("com.chouja.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
				{
					val.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
				{
					val.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(methodInfo4), (HarmonyMethod)null, (HarmonyMethod)null);
				}
				Log.LogInfo((object)"Successfully applied timeout patches.");
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Error applying patches: {arg}");
			}
		}
	}
	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;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}