Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of TimeoutLimit v0.2.0
TimeoutLimit.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("TimeoutLimit")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("TimeoutLimit")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("FE8B42E3-7082-4DFF-A5CC-6B62B0315ACA")] [assembly: AssemblyFileVersion("0.2.0")] [assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.2.0.0")] [module: UnverifiableCode] namespace TimeoutLimit; public static class CodeMatcherExtensions { public static CodeMatcher GetPosition(this CodeMatcher codeMatcher, out int position) { position = codeMatcher.Pos; return codeMatcher; } public static CodeMatcher AddLabel(this CodeMatcher codeMatcher, out Label label) { label = default(Label); codeMatcher.AddLabels((IEnumerable<Label>)new Label[1] { label }); return codeMatcher; } public static CodeMatcher GetLabels(this CodeMatcher codeMatcher, out List<Label> label) { label = codeMatcher.Labels; return codeMatcher; } public static CodeMatcher GetOperand(this CodeMatcher codeMatcher, out object operand) { operand = codeMatcher.Operand; return codeMatcher; } internal static CodeMatcher Print(this CodeMatcher codeMatcher, string message) { Debug.Log((object)message); return codeMatcher; } internal static CodeMatcher Print(this CodeMatcher codeMatcher, int before, int after) { for (int i = -before; i <= after; i++) { int num = i; int num2 = codeMatcher.Pos + num; if (num2 > 0) { if (num2 >= codeMatcher.Length) { break; } try { CodeInstruction val = codeMatcher.InstructionAt(num); Debug.Log((object)($"[{num}] " + ((object)val).ToString())); } catch (Exception ex) { Debug.Log((object)ex.Message); } } } return codeMatcher; } public static bool IsVirtCall(this CodeInstruction i, string declaringType, string name) { return i.opcode == OpCodes.Callvirt && i.operand is MethodInfo methodInfo && methodInfo.DeclaringType?.Name == declaringType && methodInfo.Name == name; } } [BepInPlugin("com.maxsch.valheim.TimeoutLimit", "TimeoutLimit", "0.2.0")] [HarmonyPatch] public class Plugin : BaseUnityPlugin { public const string ModName = "TimeoutLimit"; public const string ModGuid = "com.maxsch.valheim.TimeoutLimit"; public const string ModVersion = "0.2.0"; public static Harmony harmony; public static HashSet<Assembly> patchedAssemblies = new HashSet<Assembly>(); public static CodeInstruction[] loadTimeout = (CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Call, (object)AccessTools.PropertyGetter(typeof(Plugin), "Timeout")), new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.PropertyGetter(typeof(ConfigEntry<float>), "Value")) }; public static MethodInfo getTime = AccessTools.PropertyGetter(typeof(Time), "time"); public static ConfigEntry<float> Timeout { get; set; } public void Awake() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown Timeout = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Timeout", 90f, "Timeout in seconds"); Timeout.SettingChanged += delegate { if (Chainloader.PluginInfos.TryGetValue("com.jotunn.jotunn", out var value)) { SetJotunnTimeout(value); } }; harmony = new Harmony("com.maxsch.valheim.TimeoutLimit"); harmony.PatchAll(); } public void Start() { //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0473: Expected O, but got Unknown //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Expected O, but got Unknown foreach (PluginInfo value in Chainloader.PluginInfos.Values) { if (value == null || !Object.op_Implicit((Object)(object)value.Instance) || value.Metadata.GUID == "com.maxsch.valheim.TimeoutLimit") { continue; } if (value.Metadata.GUID == "com.jotunn.jotunn") { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Patching " + value.Metadata.Name + " [" + value.Metadata.GUID + "]")); SetJotunnTimeout(value); continue; } Assembly assembly = ((object)value.Instance).GetType().Assembly; if (!patchedAssemblies.Add(assembly)) { continue; } List<Type> source = (from t in assembly.GetTypes() where t.IsClass && (t.Name == "ConfigSync" || t.Name == "ServerSync") select t).ToList(); List<Type> list = (from t in source.SelectMany((Type t) => t.GetNestedTypes(BindingFlags.Instance | BindingFlags.NonPublic)).SelectMany((Type t) => t.GetNestedTypes(BindingFlags.Instance | BindingFlags.NonPublic)) where t.IsClass && t.Name.Contains("waitForQueue") select t).ToList(); bool flag = false; if (value.Metadata.GUID == "Azumatt.AzuAntiCheat" && list.Count == 0) { list = (from m in assembly.GetTypes().SelectMany((Type t) => t.GetNestedTypes(BindingFlags.Instance | BindingFlags.NonPublic)).SelectMany((Type t) => t.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)) where m.Name.Contains("waitForQueue") select m).SelectMany((MethodInfo m) => m.DeclaringType?.GetNestedTypes(BindingFlags.Instance | BindingFlags.NonPublic)).ToList(); flag = list.Count == 1; } List<MethodInfo> list2 = (from m in list.SelectMany((Type t) => t.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)) where m.Name == "MoveNext" select m).ToList(); if (list2.Count > 0) { if (value.Metadata.GUID == "Azumatt.AzuAntiCheat") { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Patching " + value.Metadata.Name + " [" + value.Metadata.GUID + "] (special case: " + (flag ? "yes" : "no") + ")")); } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Patching " + value.Metadata.Name + " [" + value.Metadata.GUID + "]")); } } else { ((BaseUnityPlugin)this).Logger.LogInfo((object)("Skipping " + value.Metadata.Name + " [" + value.Metadata.GUID + "]")); } foreach (MethodInfo item in list2) { try { if (flag) { harmony.Patch((MethodBase)item, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin).GetMethod("AzuAntiCheatTranspiler")), (HarmonyMethod)null, (HarmonyMethod)null); } else { harmony.Patch((MethodBase)item, (HarmonyMethod)null, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin).GetMethod("ServerSyncTranspiler")), (HarmonyMethod)null, (HarmonyMethod)null); } } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to patch {item?.DeclaringType?.FullName}.{item?.Name}: {arg}"); } } } } public void SetJotunnTimeout(PluginInfo plugin) { if (plugin != null && (Object)(object)plugin.Instance != (Object)null && plugin.Metadata.GUID == "com.jotunn.jotunn" && plugin.Metadata.Version >= new Version("2.24.0")) { Type type = AccessTools.TypeByName("Jotunn.Entities.CustomRPC, Jotunn"); AccessTools.Field(type, "Timeout").SetValue(null, Timeout.Value); } } [HarmonyPatch(typeof(ZRpc), "SetLongTimeout")] [HarmonyTranspiler] public static IEnumerable<CodeInstruction> SetLongTimeoutTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) CodeMatch[] array = (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Stsfld, (object)null, (string)null) }; List<Label> label; return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, array).RemoveInstructions(1).InsertAndAdvance(loadTimeout) .MatchForward(false, array) .GetLabels(out label) .RemoveInstructions(1) .Insert(loadTimeout) .AddLabels((IEnumerable<Label>)label) .InstructionEnumeration(); } [HarmonyPatch(typeof(Debug), "Log", new Type[] { typeof(object) })] [HarmonyPrefix] public static bool DebugContext(object message) { if (message is string text && text.Contains("seconds config sending timeout") && !text.StartsWith("[")) { Assembly assembly; try { assembly = (new StackTrace().GetFrames() ?? Array.Empty<StackFrame>()).First((StackFrame x) => x.GetMethod().ReflectedType?.Assembly != typeof(Plugin).Assembly && x.GetMethod().ReflectedType?.Assembly != typeof(Debug).Assembly).GetMethod().ReflectedType?.Assembly; } catch (Exception) { return true; } if (assembly != null) { Debug.Log((object)$"[{assembly.GetName().Name}] {message}"); return false; } } return true; } public static IEnumerable<CodeInstruction> ServerSyncTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Expected O, but got Unknown //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.Calls(i, getTime)), (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null) }).ThrowIfNotMatch("Failed to match timeout calculation", Array.Empty<CodeMatch>()).Advance(1) .RemoveInstructions(1) .InsertAndAdvance(loadTimeout) .MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"Disconnecting {0} after 30 seconds config sending timeout", (string)null) }) .ThrowIfNotMatch("Failed to match disconnect message", Array.Empty<CodeMatch>()) .RemoveInstructions(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldstr, (object)"Disconnecting {0} after {1} seconds config sending timeout") }) .MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && i.operand is MethodInfo methodInfo && methodInfo.Name == "Format"), (string)null) }) .ThrowIfNotMatch("Failed to match string.Format", Array.Empty<CodeMatch>()) .RemoveInstructions(1) .InsertAndAdvance(loadTimeout) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Box, (object)typeof(float)) }) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(string), "Format", new Type[3] { typeof(string), typeof(object), typeof(object) }, (Type[])null)) }) .InstructionEnumeration(); } public static IEnumerable<CodeInstruction> AzuAntiCheatTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Expected O, but got Unknown //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[3] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.Calls(i, getTime)), (string)null), new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)null, (string)null), new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null) }).ThrowIfNotMatch("Failed to match timeout calculation", Array.Empty<CodeMatch>()) .Advance(1) .RemoveInstructions(1) .InsertAndAdvance(loadTimeout) .Start() .MatchForward(true, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Call && i.operand is MethodInfo methodInfo && methodInfo.Name == "Format"), (string)null) }) .ThrowIfNotMatch("Failed to match string.Format", Array.Empty<CodeMatch>()) .Advance(1) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[6] { new CodeInstruction(OpCodes.Pop, (object)null), new CodeInstruction(OpCodes.Ldstr, (object)"Disconnecting peer after {0} seconds config sending timeout"), new CodeInstruction(OpCodes.Call, (object)AccessTools.PropertyGetter(typeof(Plugin), "Timeout")), new CodeInstruction(OpCodes.Callvirt, (object)AccessTools.PropertyGetter(typeof(ConfigEntry<float>), "Value")), new CodeInstruction(OpCodes.Box, (object)typeof(float)), new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(string), "Format", new Type[2] { typeof(string), typeof(object) }, (Type[])null)) }) .InstructionEnumeration(); } }