Decompiled source of Less Zdo Corruption v1.0.1

LessZdoCorruption.dll

Decompiled 6 months ago
using 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.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LessZdoCorruption.Extensions;
using LessZdoCorruption.Fixes;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("LessZdoCorruption")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+586617223bad1f4a448b6763881dd6db8ae38a63")]
[assembly: AssemblyProduct("LessZdoCorruption")]
[assembly: AssemblyTitle("LessZdoCorruption")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.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 LessZdoCorruption
{
	internal static class Config
	{
		private static ConfigFile? File { get; set; }

		public static ConfigEntry<bool> RandEvent_Cleanup { get; set; }

		public static ConfigEntry<bool> Zdo_BlockOverflow { get; set; }

		public static ConfigEntry<bool> ZnetScene_RemoveObject_Cleanup { get; set; }

		public static ConfigEntry<bool> ZnetScene_RemoveObject_Verbose { get; set; }

		internal static void Init(ConfigFile file)
		{
			File = file;
			RandEvent_Cleanup = file.Bind<bool>("RandEventSystem - Cleanup", "Enabled", true, "Toggles fix for events (eg., raids and boss fights) that tells the\ncurrent zone-owner to clean up the data stored in the zone about that raid\nwhen that raid ends.\nIntended for avoiding storage of too many timestamps of things spawned.\nRestart required to take effect.");
			Zdo_BlockOverflow = file.Bind<bool>("Zdo - Block Overflow", "Enabled", true, "Toggles blocking of adding too much data to ZDO's.\nFor instance, if you had 400 creatures attempting to spawn, this would\ncurrently cause world corruption. This fix denies the game from storing\ndata in ZDO's when above 255 entries.\nNote that this probably has a performance cost, and the blocking\nitself might cause unknown side-effects due to entries not being stored.\nRestart required to take effect.");
			ZnetScene_RemoveObject_Cleanup = file.Bind<bool>("ZNetScene.RemoveObjects", "Enabled", true, "Toggles cleanup code for the dreaded \"ZNetScene.RemoveObjects\" error.\nThis fix will attempt to identify and handle the error so that it doesn't\nend up spamming endlessly in the logs.\nRestart required to take effect.");
			ZnetScene_RemoveObject_Verbose = file.Bind<bool>("ZNetScene.RemoveObjects", "Verbose", true, "Toggles logging of debugging info when problems are detected.\nAttempts will be made to help identify the cause.\nRestart not necessary.");
		}
	}
	internal class Log
	{
		internal static ManualLogSource? Logger;

		[Conditional("Debug")]
		public static void DevConditionally(bool condition, string message)
		{
		}

		[Conditional("Debug")]
		public static void DevConditionally(Func<bool> condition, string message)
		{
			condition();
		}

		[Conditional("Debug")]
		public static void DevelopmentOnly(string message)
		{
			Logger.LogWarning((object)(message ?? ""));
		}

		public static void Debug(string message)
		{
			Logger.LogInfo((object)(message ?? ""));
		}

		public static void Trace(string message)
		{
			Logger.LogDebug((object)(message ?? ""));
		}

		public static void Info(string message)
		{
			Logger.LogMessage((object)(message ?? ""));
		}

		public static void Warning(string message)
		{
			Logger.LogWarning((object)(message ?? ""));
		}

		public static void Warning(string message, Exception e)
		{
			Logger.LogWarning((object)$"{message}\n{e}");
		}

		public static void Error(string message)
		{
			Logger.LogError((object)(message ?? ""));
		}

		public static void Error(string message, Exception e)
		{
			Logger.LogError((object)$"{message}\n{e}");
		}
	}
	[BepInPlugin("LessZdoCorruption", "Less ZDO Corruption", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModId = "LessZdoCorruption";

		public const string PluginName = "Less ZDO Corruption";

		public const string Version = "1.0.1";

		private void Awake()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			Log.Logger = ((BaseUnityPlugin)this).Logger;
			Config.Init(((BaseUnityPlugin)this).Config);
			Harmony harmony = new Harmony("LessZdoCorruption");
			Toggle(Config.RandEvent_Cleanup, RandEventSpawnSystemCleanup.Enable, "RandEventSpawnSystemCleanup");
			Toggle(Config.Zdo_BlockOverflow, ZdoBlockOverflow.Enable, "ZdoBlockOverflow");
			Toggle(Config.ZnetScene_RemoveObject_Cleanup, ZNetSceneRemoveObjectsCleanup.Enable, "ZNetSceneRemoveObjectsCleanup");
			void Toggle(ConfigEntry<bool> cfg, Action<Harmony> fix, string name)
			{
				if (cfg.Value)
				{
					try
					{
						fix(harmony);
					}
					catch (Exception e)
					{
						Log.Warning("Failed to apply fix '" + name + "'. Skipping fix.", e);
					}
				}
			}
		}
	}
}
namespace LessZdoCorruption.Fixes
{
	[Obsolete("Deprecated. Feature is too simple and ends up causing more spawn chance checks than expected.")]
	internal static class LessSpawnSystemRecords
	{
		private static MethodInfo Method_ZDO_Set_IntLong = AccessTools.Method(typeof(ZDO), "Set", new Type[2]
		{
			typeof(int),
			typeof(long)
		}, (Type[])null);

		private static MethodInfo Method_SpawnSystem_FindBaseSpawnPoint = AccessTools.Method(typeof(SpawnSystem), "FindBaseSpawnPoint", (Type[])null, (Type[])null);

		private static MethodInfo Method_SpawnSystem_UpdateSpawnList = AccessTools.Method(typeof(SpawnSystem), "UpdateSpawnList", (Type[])null, (Type[])null);

		private static MethodInfo Method_GetStableHash = AccessTools.Method(typeof(StringExtensionMethods), "GetStableHashCode", (Type[])null, (Type[])null);

		private static MethodInfo Method_LessSpawnSystemRecords_MoveSpawnTimeCode = AccessTools.Method(typeof(LessSpawnSystemRecords), "MoveSpawnTimeCode", (Type[])null, (Type[])null);

		private static MethodInfo Method_LessSpawnSystemRecords_SetTimestamp = AccessTools.Method(typeof(LessSpawnSystemRecords), "SetTimestamp", (Type[])null, (Type[])null);

		private static SpawnSystem? CurrentInstance { get; set; }

		private static DateTime? CurrentTime { get; set; }

		internal static void Enable(Harmony harmony)
		{
		}

		private static void Init(SpawnSystem __instance, DateTime currentTime)
		{
			CurrentInstance = __instance;
			CurrentTime = currentTime;
		}

		private static IEnumerable<CodeInstruction> MoveSpawnTimeCode(this IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected O, but got Unknown
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Expected O, but got Unknown
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Expected O, but got Unknown
			CodeInstruction instruction;
			return new CodeMatcher(instructions, generator).MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)Method_GetStableHash, (string)null),
				new CodeMatch((OpCode?)OpCodes.Stloc_S, (object)null, (string)null)
			}).GetInstruction(out instruction).MatchForward(true, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Ldarga_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Call, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Callvirt, (object)Method_ZDO_Set_IntLong, (string)null)
			})
				.RemoveInstruction()
				.InsertAndAdvance(OpCodes.Pop)
				.InsertAndAdvance(OpCodes.Pop)
				.InsertAndAdvance(OpCodes.Pop)
				.MatchForward(true, (CodeMatch[])(object)new CodeMatch[1]
				{
					new CodeMatch((OpCode?)OpCodes.Call, (object)Method_SpawnSystem_FindBaseSpawnPoint, (string)null)
				})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { instruction.GetLdlocFromStLoc() })
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { Transpilers.EmitDelegate<Action<int>>((Action<int>)SetTimestamp) })
				.InstructionEnumeration();
		}

		private static void SetTimestamp(int stableHashCode)
		{
			try
			{
				if (Object.op_Implicit((Object)(object)CurrentInstance) && (Object)(object)CurrentInstance != (Object)null && CurrentTime.HasValue)
				{
					CurrentInstance.m_nview.GetZDO().Set(stableHashCode, CurrentTime.Value.Ticks);
				}
			}
			catch (Exception e)
			{
				Log.Error("Error while attempting to record time that entity spawned.", e);
			}
		}
	}
	internal static class RandEventSpawnSystemCleanup
	{
		internal static void Enable(Harmony harmony)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			MethodInfo methodInfo = AccessTools.Method(typeof(RandomEvent), "OnDeactivate", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(RandEventSpawnSystemCleanup), "CleanupSpawnSystemRecords", (Type[])null, (Type[])null);
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void CleanupSpawnSystemRecords(RandomEvent __instance, bool end)
		{
			try
			{
				if (!end)
				{
					return;
				}
				foreach (SpawnSystem instance in SpawnSystem.m_instances)
				{
					if (instance.m_nview.IsOwner())
					{
						Cleanup(instance, __instance);
					}
				}
			}
			catch (Exception e)
			{
				Log.Warning("Error while attempting to clean up the raid entries added to SpawnSystem ZDO's.", e);
			}
		}

		private static void Cleanup(SpawnSystem spawnSystem, RandomEvent randEvent)
		{
			if (randEvent.m_spawn == null || randEvent.m_spawn.Count == 0)
			{
				return;
			}
			ZNetView nview = spawnSystem.m_nview;
			if (!Object.op_Implicit((Object)(object)nview) || (Object)(object)nview == (Object)null)
			{
				return;
			}
			ZDO zDO = nview.GetZDO();
			if (zDO == null)
			{
				return;
			}
			for (int i = 0; i < randEvent.m_spawn.Count; i++)
			{
				SpawnData val = randEvent.m_spawn[i];
				if (val != null && Object.op_Implicit((Object)(object)val.m_prefab) && !((Object)(object)val.m_prefab == (Object)null))
				{
					int stableHashCode = StringExtensionMethods.GetStableHashCode($"e_{((Object)val.m_prefab).name}{i + 1}");
					if (zDO.GetLong(stableHashCode, 0L) != 0L)
					{
						zDO.RemoveLong(stableHashCode);
					}
				}
			}
		}
	}
	internal static class ZdoBlockOverflow
	{
		public static void Enable(Harmony harmony)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Expected O, but got Unknown
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Expected O, but got Unknown
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a3: Expected O, but got Unknown
			//IL_02f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Expected O, but got Unknown
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0361: Expected O, but got Unknown
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Expected O, but got Unknown
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_041f: Expected O, but got Unknown
			//IL_0470: Unknown result type (might be due to invalid IL or missing references)
			//IL_047e: Expected O, but got Unknown
			//IL_04cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Expected O, but got Unknown
			//IL_052e: Unknown result type (might be due to invalid IL or missing references)
			//IL_053c: Expected O, but got Unknown
			//IL_058d: Unknown result type (might be due to invalid IL or missing references)
			//IL_059b: Expected O, but got Unknown
			Type typeFromHandle = typeof(ZDOExtraData);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Update", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(Vector3)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Vector3", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Add", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(float)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Float", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Add", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(string)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_String", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Add", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(Vector3)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Vector3", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Add", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(Quaternion)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Quaternion", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Add", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(int)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Int", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Add", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(long)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Long", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Add", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(byte[])
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_ByteArray", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Set", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(float)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Float", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Set", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(string)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_String", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Set", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(Vector3)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Vector3", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Set", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(Quaternion)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Quaternion", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Set", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(int)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Int", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Set", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(long)
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_Long", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			harmony.Patch((MethodBase)AccessTools.Method(typeFromHandle, "Set", new Type[3]
			{
				typeof(ZDOID),
				typeof(int),
				typeof(byte[])
			}, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZdoBlockOverflow), "BlockOverflow_Int_ByteArray", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static bool CheckSpace<T, K>(Dictionary<ZDOID, BinarySearchDictionary<T, K>> storage, ZDOID zid) where T : IComparable<T>
		{
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			if (storage == null)
			{
				return true;
			}
			if (storage.TryGetValue(zid, out BinarySearchDictionary<T, K> value) && value.Count >= 255)
			{
				try
				{
					ZDO zDO = ZDOMan.instance.GetZDO(zid);
					if (zDO != null)
					{
						GameObject prefab = ZNetScene.instance.GetPrefab(zDO.m_prefab);
						if (Object.op_Implicit((Object)(object)prefab))
						{
							Log.Error("[ZdoBlockOverflow]: Attempted to add too much '" + typeof(K).Name + "' data to ZDO '" + ((Object)prefab).name + "'. Blocking data from being stored.");
						}
						else
						{
							PrintFallbackError(zid);
						}
					}
					else
					{
						PrintFallbackError(zid);
					}
				}
				catch
				{
					PrintFallbackError(zid);
				}
				return false;
			}
			return true;
			static void PrintFallbackError(ZDOID zid)
			{
				Log.Error($"[ZdoBlockOverflow]: Attempted to add too much '{typeof(K).Name}' data to ZDOID '{((ZDOID)(ref zid)).ID}'. Blocking data from being stored.");
			}
		}

		private static bool BlockOverflow_Int_Float(ZDOID zid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CheckSpace(ZDOExtraData.s_floats, zid);
		}

		private static bool BlockOverflow_Int_String(ZDOID zid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CheckSpace(ZDOExtraData.s_strings, zid);
		}

		private static bool BlockOverflow_Int_Vector3(ZDOID zid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CheckSpace(ZDOExtraData.s_vec3, zid);
		}

		private static bool BlockOverflow_Int_Quaternion(ZDOID zid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CheckSpace(ZDOExtraData.s_quats, zid);
		}

		private static bool BlockOverflow_Int_Int(ZDOID zid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CheckSpace(ZDOExtraData.s_ints, zid);
		}

		private static bool BlockOverflow_Int_Long(ZDOID zid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CheckSpace(ZDOExtraData.s_longs, zid);
		}

		private static bool BlockOverflow_Int_ByteArray(ZDOID zid)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			return CheckSpace(ZDOExtraData.s_byteArrays, zid);
		}
	}
	internal static class ZNetSceneRemoveObjectsCleanup
	{
		public static void Enable(Harmony harmony)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Expected O, but got Unknown
			harmony.Patch((MethodBase)AccessTools.Method(typeof(ZNetScene), "RemoveObjects", (Type[])null, (Type[])null), new HarmonyMethod(AccessTools.Method(typeof(ZNetSceneRemoveObjectsCleanup), "VerifyAndCleanInput", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void Log(string message)
		{
			if (Config.ZnetScene_RemoveObject_Verbose.Value)
			{
				LessZdoCorruption.Log.Warning("[ZnetScene RemoveObjects] " + message);
			}
		}

		public static void VerifyAndCleanInput(ZNetScene __instance, ref List<ZDO> currentNearObjects, ref List<ZDO> currentDistantObjects)
		{
			//IL_02e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0312: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			if (currentNearObjects == null)
			{
				Log("'currentNearObjects' input is null. Fixing.");
				currentNearObjects = new List<ZDO>(0);
			}
			else
			{
				int num = 0;
				for (int i = 0; i < currentNearObjects.Count; i++)
				{
					if (currentNearObjects[i] == null)
					{
						num++;
						currentNearObjects.RemoveAt(i);
						i--;
					}
				}
				if (num > 0)
				{
					Log(string.Format("null values in '{0}'. Cleaning {1} nulls.", "currentNearObjects", num));
				}
			}
			if (currentDistantObjects == null)
			{
				Log("'currentDistantObjects' input as null. Fixing.");
				currentDistantObjects = new List<ZDO>(0);
			}
			else
			{
				int num2 = 0;
				for (int j = 0; j < currentDistantObjects.Count; j++)
				{
					if (currentDistantObjects[j] == null)
					{
						num2++;
						currentDistantObjects.RemoveAt(j);
						j--;
					}
				}
				if (num2 > 0)
				{
					Log(string.Format("null values in '{0}'. Cleaning {1} nulls.", "currentDistantObjects", num2));
				}
			}
			List<ZDO> list = new List<ZDO>();
			List<KeyValuePair<ZDO, ZNetView>> list2 = new List<KeyValuePair<ZDO, ZNetView>>();
			foreach (KeyValuePair<ZDO, ZNetView> instance in __instance.m_instances)
			{
				if (instance.Value == null)
				{
					list.Add(instance.Key);
				}
				else if (instance.Value.GetZDO() == null)
				{
					list2.Add(instance);
				}
			}
			if (list.Count > 0)
			{
				Log($"ZNetScene.m_instances had '{list.Count}' zdo keys with null ZNetView values. Removing keys (Prefab, Pos):");
				_ = from x in list
					group x by x.GetPrefab();
				foreach (ZDO item in list)
				{
					try
					{
						GameObject prefab = ZNetScene.instance.GetPrefab(item.GetPrefab());
						if (!Object.op_Implicit((Object)(object)prefab) || prefab == null)
						{
							Log($"\t({item.GetPrefab()}, {item.GetPosition()})");
						}
						else
						{
							Log($"\t({((Object)prefab).name}, {item.GetPosition()})");
						}
					}
					catch (Exception ex)
					{
						Log($"\t{item.GetPrefab()}: Error during identification of broken prefab. Key will still be removed: " + ex);
					}
					__instance.m_instances.Remove(item);
				}
			}
			if (list2.Count <= 0)
			{
				return;
			}
			Log($"ZNetScene.m_instances had {list2.Count} zdo keys with znetviews that had null ZDO. Removing keys (Prefab, Pos):");
			foreach (KeyValuePair<ZDO, ZNetView> item2 in list2)
			{
				try
				{
					GameObject prefab2 = ZNetScene.instance.GetPrefab(item2.Key.GetPrefab());
					if (!Object.op_Implicit((Object)(object)prefab2) || prefab2 == null)
					{
						Log($"\t({item2.Key.GetPrefab()}, {item2.Key.GetPosition()}");
					}
					else
					{
						Log($"\t({((Object)prefab2).name}, {item2.Key.GetPosition()}");
					}
				}
				catch
				{
				}
				__instance.m_instances.Remove(item2.Key);
			}
		}
	}
}
namespace LessZdoCorruption.Extensions
{
	internal static class CodeInstructionExtensions
	{
		public static CodeInstruction GetLdlocFromStLoc(this CodeInstruction instruction)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			if (instruction.opcode == OpCodes.Stloc_0)
			{
				return new CodeInstruction(OpCodes.Ldloc_0, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_1)
			{
				return new CodeInstruction(OpCodes.Ldloc_1, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_2)
			{
				return new CodeInstruction(OpCodes.Ldloc_2, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_3)
			{
				return new CodeInstruction(OpCodes.Ldloc_3, (object)null);
			}
			if (instruction.opcode == OpCodes.Stloc_S)
			{
				return new CodeInstruction(OpCodes.Ldloc_S, instruction.operand);
			}
			if (instruction.opcode == OpCodes.Stloc)
			{
				return new CodeInstruction(OpCodes.Ldloc, instruction.operand);
			}
			throw new ArgumentException($"Unexpected instruction '{instruction}' encountered. Expected an {OpCodes.Stloc}.");
		}

		public static CodeInstruction GetStlocFromLdloc(this CodeInstruction instruction)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected O, but got Unknown
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Expected O, but got Unknown
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Expected O, but got Unknown
			if (instruction.opcode == OpCodes.Ldloc_0)
			{
				return new CodeInstruction(OpCodes.Stloc_0, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloc_1)
			{
				return new CodeInstruction(OpCodes.Stloc_1, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloc_2)
			{
				return new CodeInstruction(OpCodes.Stloc_2, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloc_3)
			{
				return new CodeInstruction(OpCodes.Stloc_3, (object)null);
			}
			if (instruction.opcode == OpCodes.Ldloc_S)
			{
				return new CodeInstruction(OpCodes.Stloc_S, instruction.operand);
			}
			if (instruction.opcode == OpCodes.Ldloc)
			{
				return new CodeInstruction(OpCodes.Stloc, instruction.operand);
			}
			throw new ArgumentException($"Unexpected instruction '{instruction}' encountered. Expected an {OpCodes.Ldloc}.");
		}
	}
	internal static class CodeMatcherExtensions
	{
		public static CodeMatcher InsertAndAdvance(this CodeMatcher matcher, OpCode code)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			return matcher.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(code, (object)null)
			});
		}

		public static CodeMatcher MatchForward(this CodeMatcher matcher, bool useEnd, params OpCode[] matches)
		{
			return matcher.MatchForward(useEnd, ((IEnumerable<OpCode>)matches).Select((Func<OpCode, CodeMatch>)((OpCode x) => new CodeMatch((OpCode?)x, (object)null, (string)null))).ToArray());
		}

		public static CodeMatcher GetOpcode(this CodeMatcher codeMatcher, out OpCode opcode)
		{
			opcode = codeMatcher.Opcode;
			return codeMatcher;
		}

		public static CodeMatcher GetInstruction(this CodeMatcher codeMatcher, out CodeInstruction instruction)
		{
			instruction = codeMatcher.Instruction;
			return codeMatcher;
		}

		public static CodeMatcher GetOperand(this CodeMatcher codeMatcher, out object operand)
		{
			operand = codeMatcher.Operand;
			return codeMatcher;
		}

		public static CodeMatcher Print(this CodeMatcher codeMatcher, int before, int after)
		{
			return codeMatcher;
		}
	}
}