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 REPOPatch v1.0.0
off_grid.REPOPatch.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using REPOPatch.Features; using REPOPatch.Patches; using REPOPatch.Services; using UnityEngine; [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("off_grid.REPOPatch")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("REPOPatch")] [assembly: AssemblyTitle("off_grid.REPOPatch")] [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 REPOPatch { [BepInPlugin("off_grid.REPOPatch", "REPOPatch", "1.0.0")] public class REPOPatch : BaseUnityPlugin { internal static Harmony Harmony = new Harmony("off_grid.REPOPatch"); internal static bool Patch_SendBufferFull = true; internal static int SBF_MaxQueuedStatUpdates = 2000; internal static int SBF_MaxSendsPerFlush = 25; internal static float SBF_FlushInterval = 0.08f; internal static bool SBF_DropWhenFull = true; public ConfigFile config; public static REPOPatch Instance { get; private set; } = null; internal static ManualLogSource Logger { get; private set; } = null; private void Setup() { if (Patch_SendBufferFull) { PunManagerPatch.EnablePatch(); } Logger.LogInfo((object)"<--- Setup Finished --->"); } private void NetworkSetup() { Logger.LogInfo((object)"<--- Network Finished --->"); } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; FileManager.InitializeConfig(); Setup(); NetworkSetup(); Harmony.PatchAll(); Logger.LogInfo((object)"off_grid.REPOPatch v1.0.0 has fully loaded!"); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "off_grid.REPOPatch"; public const string PLUGIN_NAME = "REPOPatch"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace REPOPatch.Services { internal class Networking { } internal static class PhotonViewCache { private static readonly Dictionary<int, PhotonView> s_cache = new Dictionary<int, PhotonView>(1024); private static readonly object s_lock = new object(); public static bool TryGet(int viewID, out PhotonView? pv) { lock (s_lock) { if (s_cache.TryGetValue(viewID, out pv)) { if ((Object)(object)pv == (Object)null) { s_cache.Remove(viewID); pv = null; return false; } return true; } } pv = null; return false; } public static void Store(int viewID, PhotonView pv) { if ((Object)(object)pv == (Object)null) { return; } lock (s_lock) { s_cache[viewID] = pv; } } public static void Invalidate(int viewID) { lock (s_lock) { s_cache.Remove(viewID); } } public static void Clear() { lock (s_lock) { s_cache.Clear(); } } } internal static class ListPool<T> { private const int MaxPoolSize = 256; private static readonly Stack<List<T>> s_pool = new Stack<List<T>>(64); private static readonly object s_lock = new object(); public static List<T> Get(int capacity = 0) { lock (s_lock) { if (s_pool.Count > 0) { List<T> list = s_pool.Pop(); if (capacity > list.Capacity) { list.Capacity = capacity; } list.Clear(); return list; } } if (capacity <= 0) { return new List<T>(); } return new List<T>(capacity); } public static void Release(List<T> list) { if (list == null) { return; } list.Clear(); lock (s_lock) { if (s_pool.Count < 256) { s_pool.Push(list); } } } public static void ReleaseRange(IEnumerable<List<T>> lists) { if (lists == null) { return; } lock (s_lock) { foreach (List<T> list in lists) { if (list != null) { list.Clear(); if (s_pool.Count < 256) { s_pool.Push(list); } } } } } } internal static class DictionaryPool<TKey, TValue> { private const int MaxPoolSize = 128; private static readonly Stack<Dictionary<TKey, TValue>> s_pool = new Stack<Dictionary<TKey, TValue>>(32); private static readonly object s_lock = new object(); public static Dictionary<TKey, TValue> Get(int capacity = 0) { lock (s_lock) { if (s_pool.Count > 0) { Dictionary<TKey, TValue> dictionary = s_pool.Pop(); dictionary.Clear(); return dictionary; } } if (capacity <= 0) { return new Dictionary<TKey, TValue>(); } return new Dictionary<TKey, TValue>(capacity); } public static void Release(Dictionary<TKey, TValue> d) { if (d == null) { return; } d.Clear(); lock (s_lock) { if (s_pool.Count < 128) { s_pool.Push(d); } } } public static void ReleaseRange(IEnumerable<Dictionary<TKey, TValue>> items) { if (items == null) { return; } lock (s_lock) { foreach (Dictionary<TKey, TValue> item in items) { if (item != null) { item.Clear(); if (s_pool.Count < 128) { s_pool.Push(item); } } } } } } internal static class PhotonHashtablePool { private const int MaxPoolSize = 256; private static readonly Stack<Hashtable> s_pool = new Stack<Hashtable>(64); private static readonly object s_lock = new object(); public static Hashtable Get(int capacity = 0) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown lock (s_lock) { if (s_pool.Count > 0) { Hashtable val = s_pool.Pop(); ((Dictionary<object, object>)(object)val).Clear(); return val; } } return new Hashtable(); } public static void Release(Hashtable ht) { if (ht == null) { return; } ((Dictionary<object, object>)(object)ht).Clear(); lock (s_lock) { if (s_pool.Count < 256) { s_pool.Push(ht); } } } public static void ReleaseRange(IEnumerable<Hashtable> items) { if (items == null) { return; } lock (s_lock) { foreach (Hashtable item in items) { if (item != null) { ((Dictionary<object, object>)(object)item).Clear(); if (s_pool.Count < 256) { s_pool.Push(item); } } } } } } public class StatThrottler : MonoBehaviour { private struct Pending { public PunManager manager; public string dict; public string key; public int val; public Pending(PunManager m, string d, string k, int v) { manager = m; dict = d; key = k; val = v; } } [CompilerGenerated] private sealed class <FlushLoop>d__11 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public StatThrottler <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <FlushLoop>d__11(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; StatThrottler statThrottler = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; break; case 1: <>1__state = -1; break; } if (statThrottler.queue.Count > 0) { for (int i = 0; i < Math.Min(REPOPatch.SBF_MaxSendsPerFlush, statThrottler.queue.Count); i++) { Pending pending = statThrottler.queue.Dequeue(); try { pending.manager.UpdateStatRPC(pending.dict, pending.key, pending.val, default(PhotonMessageInfo)); if (!statThrottler.lastSent.TryGetValue(pending.dict, out Dictionary<string, int> value)) { value = new Dictionary<string, int>(); statThrottler.lastSent[pending.dict] = value; } value[pending.key] = pending.val; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> StatThrottler send failed: {arg}"); } } <>2__current = (object)new WaitForSeconds(REPOPatch.SBF_FlushInterval); <>1__state = 1; return true; } statThrottler.flushRoutine = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private readonly Queue<Pending> queue = new Queue<Pending>(); private readonly Dictionary<string, Dictionary<string, int>> lastSent = new Dictionary<string, Dictionary<string, int>>(); private Coroutine? flushRoutine; public static StatThrottler? Instance { get; private set; } public static StatThrottler CreateOrGet() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown if ((Object)(object)Instance != (Object)null) { return Instance; } Instance = Object.FindObjectOfType<StatThrottler>(); if ((Object)(object)Instance != (Object)null) { return Instance; } GameObject val = new GameObject("StatThrottler"); Object.DontDestroyOnLoad((Object)(object)val); Instance = val.AddComponent<StatThrottler>(); return Instance; } private void Awake() { if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } Instance = this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); } public void Enqueue(PunManager manager, string dict, string key, int value) { if ((Object)(object)manager == (Object)null || (lastSent.TryGetValue(dict, out Dictionary<string, int> value2) && value2.TryGetValue(key, out var value3) && value3 == value)) { return; } if (queue.Count >= REPOPatch.SBF_MaxQueuedStatUpdates) { if (REPOPatch.SBF_DropWhenFull) { return; } queue.Dequeue(); } queue.Enqueue(new Pending(manager, dict, key, value)); if (flushRoutine == null) { flushRoutine = ((MonoBehaviour)this).StartCoroutine(FlushLoop()); } } [IteratorStateMachine(typeof(<FlushLoop>d__11))] private IEnumerator FlushLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <FlushLoop>d__11(0) { <>4__this = this }; } public void FlushAllNow() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) while (queue.Count > 0) { Pending pending = queue.Dequeue(); try { pending.manager.UpdateStatRPC(pending.dict, pending.key, pending.val, default(PhotonMessageInfo)); } catch { } } } } } namespace REPOPatch.Patches { [HarmonyPatch] internal static class PhotonAndCanvasPatches { private static readonly Dictionary<int, MaterialPropertyBlock> s_rendererBlocks = new Dictionary<int, MaterialPropertyBlock>(); private static readonly object s_lock = new object(); private static readonly ConditionalWeakTable<object, Coroutine> s_wiggleCoroutines = new ConditionalWeakTable<object, Coroutine>(); [HarmonyPatch(typeof(PhotonView), "OnDestroy")] [HarmonyPostfix] private static void PhotonView_OnDestroy_Postfix(PhotonView __instance) { try { if ((Object)(object)__instance == (Object)null) { return; } int num = 0; try { num = __instance.ViewID; } catch { PropertyInfo property = typeof(PhotonView).GetProperty("ViewID", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { num = (int)property.GetValue(__instance); } } if (num > 0) { PhotonViewCache.Invalidate(num); } } catch { } } [HarmonyPatch(typeof(CanvasHandler), "SetMaterialAlpha")] [HarmonyPrefix] private static bool CanvasHandler_SetMaterialAlpha_Prefix(MeshRenderer renderer, float alpha) { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)renderer == (Object)null) { return false; } int num = Shader.PropertyToID("_Color"); int instanceID = ((Object)renderer).GetInstanceID(); MaterialPropertyBlock value; lock (s_lock) { if (!s_rendererBlocks.TryGetValue(instanceID, out value)) { value = new MaterialPropertyBlock(); s_rendererBlocks[instanceID] = value; } } Color val = Color.white; try { Material sharedMaterial = ((Renderer)renderer).sharedMaterial; if ((Object)(object)sharedMaterial != (Object)null) { val = sharedMaterial.color; } } catch { } val.a = Mathf.Clamp01(alpha); value.SetColor(num, val); ((Renderer)renderer).SetPropertyBlock(value); return false; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> CanvasHandler SetMaterialAlpha exception: {arg}"); return true; } } [HarmonyPatch(typeof(CanvasHandler), "StartWiggle")] [HarmonyPrefix] private static bool StartWiggle_Prefix(object __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown try { Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "DustParticles"); ParticleSystem val = (ParticleSystem)fieldInfo.GetValue(__instance); float num = (float)AccessTools.Field(type, "wiggleAmount").GetValue(__instance); FieldInfo fieldInfo2 = AccessTools.Field(type, "currentWiggleAmount"); FieldInfo fieldInfo3 = AccessTools.Field(type, "isWiggling"); if (s_wiggleCoroutines.TryGetValue(__instance, out Coroutine value) && value != null) { try { object obj = ((__instance is MonoBehaviour) ? __instance : null); if (obj != null) { ((MonoBehaviour)obj).StopCoroutine(value); } } catch { } try { s_wiggleCoroutines.Remove(__instance); } catch { } } fieldInfo3.SetValue(__instance, true); try { if ((Object)(object)val != (Object)null && !val.isPlaying) { val.Play(); } } catch { } fieldInfo2.SetValue(__instance, num); MethodInfo methodInfo = AccessTools.Method(type, "WiggleCoroutine", (Type[])null, (Type[])null); if (methodInfo != null) { IEnumerator enumerator = (IEnumerator)methodInfo.Invoke(__instance, null); if (enumerator != null) { object obj5 = ((__instance is MonoBehaviour) ? __instance : null); Coroutine val2 = ((obj5 != null) ? ((MonoBehaviour)obj5).StartCoroutine(enumerator) : null); if (val2 != null) { try { s_wiggleCoroutines.Add(__instance, val2); } catch { try { s_wiggleCoroutines.Remove(__instance); s_wiggleCoroutines.Add(__instance, val2); } catch { } } } } } return false; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> CanvasHandler StartWiggle prefix exception: {arg}"); return true; } } [HarmonyPatch(typeof(CanvasHandler), "StopWiggle")] [HarmonyPrefix] private static bool StopWiggle_Prefix(object __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown try { Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "DustParticles"); ParticleSystem val = (ParticleSystem)fieldInfo.GetValue(__instance); FieldInfo fieldInfo2 = AccessTools.Field(type, "isWiggling"); try { if ((Object)(object)val != (Object)null && val.isPlaying) { val.Stop(); } } catch { } fieldInfo2.SetValue(__instance, false); if (s_wiggleCoroutines.TryGetValue(__instance, out Coroutine value) && value != null) { try { object obj2 = ((__instance is MonoBehaviour) ? __instance : null); if (obj2 != null) { ((MonoBehaviour)obj2).StopCoroutine(value); } } catch { } try { s_wiggleCoroutines.Remove(__instance); } catch { } } return false; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> CanvasHandler StopWiggle prefix exception: {arg}"); return true; } } } [HarmonyPatch] public static class RenderTextureMain_Optimizations { [HarmonyPatch(typeof(RenderTextureMain), "SetRenderTexture")] [HarmonyPrefix] private static bool SetRenderTexture_Prefix(object __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Expected O, but got Unknown try { Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "renderTexture"); RenderTexture val = (RenderTexture)fieldInfo.GetValue(__instance); float num = (float)AccessTools.Field(type, "textureWidth").GetValue(__instance); float num2 = (float)AccessTools.Field(type, "textureHeight").GetValue(__instance); int num3 = (int)num; int num4 = (int)num2; if (((Texture)val).width != num3 || ((Texture)val).height != num4 || !val.IsCreated()) { try { if (val.IsCreated()) { val.Release(); } ((Texture)val).width = num3; ((Texture)val).height = num4; val.Create(); } catch (Exception arg) { REPOPatch.Logger.LogError((object)$"> Error resetting RenderTexture: {arg}"); return true; } } else { REPOPatch.Logger.LogInfo((object)"> RenderTexture already has correct dimensions and is created."); } FieldInfo fieldInfo2 = AccessTools.Field(type, "cameras"); if (fieldInfo2.GetValue(__instance) is IList list) { foreach (Camera item in list) { Camera val2 = item; try { val2.targetTexture = val; ((Behaviour)val2).enabled = false; ((Behaviour)val2).enabled = true; } catch (Exception arg2) { REPOPatch.Logger.LogError((object)$"> Error updating camera target texture: {arg2}"); } } } return false; } catch (Exception arg3) { REPOPatch.Logger.LogWarning((object)$"> SetRenderTexture prefix exception: {arg3}"); return true; } } } [HarmonyPatch] internal static class PunManagerAdvancedPatches { [HarmonyPatch(typeof(PunManager), "ConvertToHashtable")] [HarmonyPrefix] private static bool ConvertToHashtable_Prefix(object __instance, Dictionary<string, int> dictionary, ref Hashtable? __result) { try { if (dictionary == null) { __result = null; return false; } Hashtable val = PhotonHashtablePool.Get(dictionary.Count); foreach (KeyValuePair<string, int> item in dictionary) { ((Dictionary<object, object>)(object)val).Add((object)item.Key, (object)item.Value); } __result = val; return false; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> ConvertToHashtable prefix exception: {arg}"); return true; } } [HarmonyPatch(typeof(PunManager), "SyncAllDictionaries")] [HarmonyPrefix] private static bool SyncAllDictionaries_Prefix(object __instance) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown try { Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "statsManager"); FieldInfo fieldInfo2 = AccessTools.Field(type, "syncData"); FieldInfo fieldInfo3 = AccessTools.Field(type, "photonView"); object value = fieldInfo.GetValue(__instance); List<Hashtable> list = (List<Hashtable>)fieldInfo2.GetValue(__instance); PhotonView val = (PhotonView)fieldInfo3.GetValue(__instance); Type type2 = value.GetType(); FieldInfo fieldInfo4 = AccessTools.Field(type2, "statsSynced"); if (fieldInfo4 != null) { fieldInfo4.SetValue(value, true); } if (!SemiFunc.IsMultiplayer() || !PhotonNetwork.IsMasterClient) { REPOPatch.Logger.LogWarning((object)"> SyncAllDictionaries patch failed: Not in multiplayer, so not point in patching..."); return false; } list.Clear(); FieldInfo fieldInfo5 = AccessTools.Field(type2, "dictionaryOfDictionaries"); Dictionary<string, Dictionary<string, int>> dictionary = (Dictionary<string, Dictionary<string, int>>)fieldInfo5.GetValue(value); if (dictionary == null || dictionary.Count == 0) { REPOPatch.Logger.LogError((object)"> SyncAllDictionaries patch failed: DAa!2"); return false; } Hashtable val2 = PhotonHashtablePool.Get(); int num = 0; int num2 = 0; int count = dictionary.Count; MethodInfo methodInfo = AccessTools.Method(__instance.GetType(), "ConvertToHashtable", new Type[1] { typeof(Dictionary<string, int>) }, (Type[])null); foreach (KeyValuePair<string, Dictionary<string, int>> item in dictionary) { Hashtable value2 = (Hashtable)methodInfo.Invoke(__instance, new object[1] { item.Value }); ((Dictionary<object, object>)(object)val2).Add((object)item.Key, (object)value2); num++; num2++; if (num > 3 || num2 == count) { list.Add(val2); val2 = PhotonHashtablePool.Get(); num = 0; } } if (val2 != null && ((Dictionary<object, object>)(object)val2).Count == 0) { PhotonHashtablePool.Release(val2); } for (int i = 0; i < list.Count; i++) { bool flag = i == list.Count - 1; Hashtable val3 = list[i]; try { val.RPC("ReceiveSyncData", (RpcTarget)1, new object[2] { val3, flag }); } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> SyncAllDictionaries RPC send failed: {arg}"); } } foreach (Hashtable item2 in list) { if (item2 == null) { continue; } List<Hashtable> list2 = ListPool<Hashtable>.Get(((Dictionary<object, object>)(object)item2).Count); DictionaryEntryEnumerator enumerator3 = item2.GetEnumerator(); try { while (((DictionaryEntryEnumerator)(ref enumerator3)).MoveNext()) { object? value3 = ((DictionaryEntryEnumerator)(ref enumerator3)).Current.Value; Hashtable val4 = (Hashtable)((value3 is Hashtable) ? value3 : null); if (val4 != null) { list2.Add(val4); } } } finally { ((IDisposable)(DictionaryEntryEnumerator)(ref enumerator3)).Dispose(); } foreach (Hashtable item3 in list2) { PhotonHashtablePool.Release(item3); } ListPool<Hashtable>.Release(list2); PhotonHashtablePool.Release(item2); } list.Clear(); return false; } catch (Exception arg2) { REPOPatch.Logger.LogWarning((object)$"> SyncAllDictionaries prefix exception: {arg2}"); return true; } } [HarmonyPatch(typeof(PunManager), "TruckPopulateItemVolumes")] [HarmonyPrefix] private static bool TruckPopulateItemVolumes_Prefix(object __instance) { try { Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "itemManager"); object value = fieldInfo.GetValue(__instance); if (value == null) { REPOPatch.Logger.LogError((object)"> TruckPopulateItemVolumes patch failed: DAa!1"); return true; } if (AccessTools.Field(value.GetType(), "spawnedItems")?.GetValue(value) is IList list) { list.Clear(); } MethodInfo method = typeof(SemiFunc).GetMethod("IsNotMasterClient", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (method != null && (bool)method.Invoke(null, null)) { REPOPatch.Logger.LogError((object)"> TruckPopulateItemVolumes patch failed: DAa!2"); return false; } FieldInfo fieldInfo2 = AccessTools.Field(value.GetType(), "itemVolumes"); FieldInfo fieldInfo3 = AccessTools.Field(value.GetType(), "purchasedItems"); List<object> list2 = fieldInfo2.GetValue(value) as List<object>; List<object> list3 = fieldInfo3.GetValue(value) as List<object>; int capacity = list2?.Count ?? 0; int capacity2 = list3?.Count ?? 0; List<object> list4 = ListPool<object>.Get(capacity); List<object> list5 = ListPool<object>.Get(capacity2); try { if (list2 != null) { list4.AddRange(list2); } if (list3 != null) { list5.AddRange(list3); } while (list4.Count > 0 && list5.Count > 0) { bool flag = false; for (int i = 0; i < list5.Count; i++) { object obj = list5[i]; object obj2 = null; foreach (object item in list4) { try { Type type2 = item.GetType(); FieldInfo field = type2.GetField("itemVolume", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); Type type3 = obj.GetType(); FieldInfo field2 = type3.GetField("itemVolume", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); object obj3 = ((field != null) ? field.GetValue(item) : null); object obj4 = ((field2 != null) ? field2.GetValue(obj) : null); if (obj3 != null && obj4 != null && obj3.Equals(obj4)) { obj2 = item; break; } } catch { } } if (obj2 != null) { MethodInfo method2 = type.GetMethod("SpawnItem", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method2 != null) { method2.Invoke(__instance, new object[2] { obj, obj2 }); } list4.Remove(obj2); list5.RemoveAt(i); flag = true; break; } } if (!flag) { break; } } if (list2 != null) { foreach (object item2 in list2) { if (item2 == null) { continue; } try { FieldInfo field3 = item2.GetType().GetField("gameObject", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field3 != null) { object? value2 = field3.GetValue(item2); GameObject val = (GameObject)((value2 is GameObject) ? value2 : null); if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } } catch { } } } } finally { ListPool<object>.Release(list4); ListPool<object>.Release(list5); } return false; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> TruckPopulateItemVolumes pooled prefix exception: {arg}"); return true; } } } [HarmonyPatch(typeof(PunManager), "UpdateStat", new Type[] { typeof(string), typeof(string), typeof(int) })] internal static class PunManagerPatch { private static volatile bool _enabled; public static void EnablePatch() { _enabled = true; StatThrottler.CreateOrGet(); REPOPatch.Logger.LogInfo((object)"> PunManagerPatch enabled."); } public static void DisablePatch() { _enabled = false; REPOPatch.Logger.LogInfo((object)"> PunManagerPatch disabled."); } public static bool IsEnabled() { return _enabled; } private static bool Prefix(PunManager __instance, string dictionaryName, string key, int value) { if (!_enabled) { return true; } try { StatThrottler statThrottler = StatThrottler.CreateOrGet(); statThrottler.Enqueue(__instance, dictionaryName, key, value); return false; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> PunManagerPatch Prefix exception: {arg}"); return true; } } } [HarmonyPatch] internal static class PunManagerPoolsAndPhotonFindPatches { [HarmonyPatch(typeof(PhotonView), "Find", new Type[] { typeof(int) })] [HarmonyPrefix] private static bool PhotonView_Find_Prefix(int viewID, ref PhotonView __result) { if (viewID <= 0) { return true; } if (PhotonViewCache.TryGet(viewID, out PhotonView pv)) { __result = pv; return false; } return true; } [HarmonyPatch(typeof(PhotonView), "Find", new Type[] { typeof(int) })] [HarmonyPostfix] private static void PhotonView_Find_Postfix(int viewID, PhotonView __result) { if ((Object)(object)__result != (Object)null && viewID > 0) { PhotonViewCache.Store(viewID, __result); } } [HarmonyPatch(typeof(PunManager), "ReceiveSyncData")] [HarmonyPrefix] private static bool ReceiveSyncData_Prefix(object __instance, Hashtable data, bool finalChunk, PhotonMessageInfo _info = default(PhotonMessageInfo)) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) try { MethodInfo methodInfo = AccessTools.Method(typeof(SemiFunc), "MasterOnlyRPC", (Type[])null, (Type[])null); if (methodInfo != null && !(bool)methodInfo.Invoke(null, new object[1] { _info })) { REPOPatch.Logger.LogError((object)"> ReceiveSyncData patch failed: DAa!1"); return false; } if (data == null || ((Dictionary<object, object>)(object)data).Count == 0) { REPOPatch.Logger.LogError((object)"> ReceiveSyncData patch failed: DAa!2"); return false; } Type type = __instance.GetType(); FieldInfo fieldInfo = AccessTools.Field(type, "statsManager"); if (fieldInfo == null) { REPOPatch.Logger.LogError((object)"> ReceiveSyncData patch failed: DAa!3"); return true; } object value = fieldInfo.GetValue(__instance); if (value == null) { REPOPatch.Logger.LogError((object)"> ReceiveSyncData patch failed: DAa!4"); return true; } Type type2 = value.GetType(); FieldInfo fieldInfo2 = AccessTools.Field(type2, "dictionaryOfDictionaries"); if (fieldInfo2 == null) { REPOPatch.Logger.LogError((object)"> ReceiveSyncData patch failed: DAa!4"); return true; } if (!(fieldInfo2.GetValue(value) is Dictionary<string, Dictionary<string, int>> dictionary)) { REPOPatch.Logger.LogError((object)"> ReceiveSyncData patch failed: DAa!5"); return true; } DictionaryEntryEnumerator enumerator = data.GetEnumerator(); try { while (((DictionaryEntryEnumerator)(ref enumerator)).MoveNext()) { DictionaryEntry current = ((DictionaryEntryEnumerator)(ref enumerator)).Current; if (!(current.Key is string key) || !dictionary.TryGetValue(key, out var value2) || value2 == null) { continue; } object? value3 = current.Value; Hashtable val = (Hashtable)((value3 is Hashtable) ? value3 : null); if (val == null) { continue; } DictionaryEntryEnumerator enumerator2 = val.GetEnumerator(); try { while (((DictionaryEntryEnumerator)(ref enumerator2)).MoveNext()) { DictionaryEntry current2 = ((DictionaryEntryEnumerator)(ref enumerator2)).Current; if (current2.Key is string key2 && current2.Value is int value4) { value2[key2] = value4; } } } finally { ((IDisposable)(DictionaryEntryEnumerator)(ref enumerator2)).Dispose(); } } } finally { ((IDisposable)(DictionaryEntryEnumerator)(ref enumerator)).Dispose(); } if (finalChunk) { AccessTools.Field(type2, "statsSynced")?.SetValue(value, true); } return false; } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> ReceiveSyncData prefix exception: {arg}"); return true; } } [HarmonyPatch(typeof(PunManager), "ShopUpdateCost")] [HarmonyPrefix] private static bool ShopUpdateCost_Prefix(PunManager __instance) { //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) try { ShopManager instance = ShopManager.instance; FieldInfo fieldInfo = AccessTools.Field(((object)instance).GetType(), "shoppingList"); if (fieldInfo == null) { REPOPatch.Logger.LogError((object)"> ShopUpdateCost patch failed: DAa!1"); return true; } if (!(fieldInfo.GetValue(instance) is IList list)) { REPOPatch.Logger.LogError((object)"> ShopUpdateCost patch failed: DAa!2"); return true; } object? obj = AccessTools.Field(typeof(PunManager), "photonView")?.GetValue(__instance); PhotonView val = (PhotonView)((obj is PhotonView) ? obj : null); Type typeFromHandle = typeof(ItemAttributes); FieldInfo fieldInfo2 = AccessTools.Field(typeFromHandle, "roomVolumeCheck"); FieldInfo fieldInfo3 = AccessTools.Field(typeFromHandle, "value"); if (fieldInfo2 == null || fieldInfo3 == null) { REPOPatch.Logger.LogError((object)"> ShopUpdateCost patch failed: DAa!3"); return true; } Type fieldType = fieldInfo2.FieldType; MethodInfo methodInfo = AccessTools.Method(fieldType, "CheckSet", (Type[])null, (Type[])null); FieldInfo fieldInfo4 = AccessTools.Field(fieldType, "inExtractionPoint"); if (fieldInfo4 == null) { REPOPatch.Logger.LogError((object)"> ShopUpdateCost patch failed: DAa!4"); return true; } List<ItemAttributes> list2 = ListPool<ItemAttributes>.Get(); try { int num = 0; foreach (object item in list) { ItemAttributes val2 = (ItemAttributes)((item is ItemAttributes) ? item : null); if ((Object)(object)val2 != (Object)null) { object value = fieldInfo2.GetValue(val2); methodInfo?.Invoke(value, null); if (!(bool)fieldInfo4.GetValue(value)) { list2.Add(val2); continue; } int num2 = (int)fieldInfo3.GetValue(val2); num += num2; } else { list2.Add(val2); } } foreach (ItemAttributes item2 in list2) { list.Remove(item2); } if (SemiFunc.IsMasterClientOrSingleplayer()) { if (SemiFunc.IsMultiplayer() && (Object)(object)val != (Object)null) { val.RPC("UpdateShoppingCostRPC", (RpcTarget)0, new object[1] { num }); } else { __instance.UpdateShoppingCostRPC(num, default(PhotonMessageInfo)); } } return false; } finally { ListPool<ItemAttributes>.Release(list2); } } catch (Exception arg) { REPOPatch.Logger.LogWarning((object)$"> ShopUpdateCost pool prefix exception: {arg}"); return true; } } } } namespace REPOPatch.Modules { public static class Helper { } } namespace REPOPatch.Features { public static class Additions { } public static class FileManager { internal static ConfigEntry<T> BindConfig<T>(string Header, string Features, T Value, string? Info = "") { return REPOPatch.Instance.config.Bind<T>(Header, Features, Value, Info); } internal static void InitializeConfig() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown string text = Path.Combine(Paths.ConfigPath, "DAa Mods/REPOPatch"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } REPOPatch.Instance.config = new ConfigFile(Path.Combine(text, "config.cfg"), true); if (BindConfig("Version", "Current Version", "").Value != "1.0.0") { REPOPatch.Instance.config.Clear(); } DefineConfig(); REPOPatch.Logger.LogWarning((object)"< Config initialized >"); } internal static void DefineConfig() { BindConfig("Version", "Current Version", "1.0.0", "Autoupdates the config / lets the mod know what version of config it is."); REPOPatch.Patch_SendBufferFull = BindConfig("BufferThrottler", "SendBufferFull", Value: true, "Patches SendBufferFull error.").Value; REPOPatch.SBF_MaxQueuedStatUpdates = BindConfig("BufferThrottler", "MaxQueuedStatUpdates", 2000, "Maximum queued stat updates before drops/eviction occur.").Value; REPOPatch.SBF_MaxSendsPerFlush = BindConfig("BufferThrottler", "MaxSendsPerFlush", 25, "How many stat updates to send per flush batch.").Value; REPOPatch.SBF_FlushInterval = BindConfig("BufferThrottler", "FlushInterval", 0.08f, "Seconds to wait between flush batches.").Value; REPOPatch.SBF_DropWhenFull = BindConfig("BufferThrottler", "DropWhenFull", Value: true, "If true, drop new updates when queue is full; if false, oldest updates are evicted.").Value; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }