Decompiled source of DropNSpawn v1.3.6

DropNSpawn.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using Data;
using ExpandWorldData;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
using YamlDotNet.Core;
using YamlDotNet.Core.Events;
using YamlDotNet.Core.ObjectPool;
using YamlDotNet.Core.Tokens;
using YamlDotNet.Helpers;
using YamlDotNet.RepresentationModel;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.BufferedDeserialization;
using YamlDotNet.Serialization.BufferedDeserialization.TypeDiscriminators;
using YamlDotNet.Serialization.Callbacks;
using YamlDotNet.Serialization.Converters;
using YamlDotNet.Serialization.EventEmitters;
using YamlDotNet.Serialization.NamingConventions;
using YamlDotNet.Serialization.NodeDeserializers;
using YamlDotNet.Serialization.NodeTypeResolvers;
using YamlDotNet.Serialization.ObjectFactories;
using YamlDotNet.Serialization.ObjectGraphTraversalStrategies;
using YamlDotNet.Serialization.ObjectGraphVisitors;
using YamlDotNet.Serialization.Schemas;
using YamlDotNet.Serialization.TypeInspectors;
using YamlDotNet.Serialization.TypeResolvers;
using YamlDotNet.Serialization.Utilities;
using YamlDotNet.Serialization.ValueDeserializers;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DropNSpawn")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("sighsorry")]
[assembly: AssemblyProduct("DropNSpawn")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("4358610B-F3F4-4843-B7AF-98B7BC60DCDE")]
[assembly: AssemblyFileVersion("1.3.6")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.6.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class ExtensionMarkerAttribute : Attribute
	{
		private readonly string <Name>k__BackingField;

		public string Name => <Name>k__BackingField;

		public ExtensionMarkerAttribute(string name)
		{
			<Name>k__BackingField = name;
		}
	}
}
namespace LocalizationManager
{
	[PublicAPI]
	public class Localizer
	{
		private static readonly Dictionary<string, Dictionary<string, Func<string>>> PlaceholderProcessors;

		private static readonly Dictionary<string, Dictionary<string, string>> loadedTexts;

		private static readonly ConditionalWeakTable<Localization, string> localizationLanguage;

		private static readonly List<WeakReference<Localization>> localizationObjects;

		private static BaseUnityPlugin? _plugin;

		private static readonly List<string> fileExtensions;

		private static BaseUnityPlugin plugin
		{
			get
			{
				//IL_009b: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a5: Expected O, but got Unknown
				if (_plugin == null)
				{
					IEnumerable<TypeInfo> source;
					try
					{
						source = Assembly.GetExecutingAssembly().DefinedTypes.ToList();
					}
					catch (ReflectionTypeLoadException ex)
					{
						source = from t in ex.Types
							where t != null
							select t.GetTypeInfo();
					}
					_plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t)));
				}
				return _plugin;
			}
		}

		public static event Action? OnLocalizationComplete;

		private static void UpdatePlaceholderText(Localization localization, string key)
		{
			localizationLanguage.TryGetValue(localization, out string value);
			string text = loadedTexts[value][key];
			if (PlaceholderProcessors.TryGetValue(key, out Dictionary<string, Func<string>> value2))
			{
				text = value2.Aggregate(text, (string current, KeyValuePair<string, Func<string>> kv) => current.Replace("{" + kv.Key + "}", kv.Value()));
			}
			localization.AddWord(key, text);
		}

		public static void AddPlaceholder<T>(string key, string placeholder, ConfigEntry<T> config, Func<T, string>? convertConfigValue = null) where T : notnull
		{
			if (convertConfigValue == null)
			{
				convertConfigValue = (T val) => val.ToString();
			}
			if (!PlaceholderProcessors.ContainsKey(key))
			{
				PlaceholderProcessors[key] = new Dictionary<string, Func<string>>();
			}
			config.SettingChanged += delegate
			{
				UpdatePlaceholder();
			};
			if (loadedTexts.ContainsKey(Localization.instance.GetSelectedLanguage()))
			{
				UpdatePlaceholder();
			}
			void UpdatePlaceholder()
			{
				PlaceholderProcessors[key][placeholder] = () => convertConfigValue(config.Value);
				UpdatePlaceholderText(Localization.instance, key);
			}
		}

		public static void AddText(string key, string text)
		{
			List<WeakReference<Localization>> list = new List<WeakReference<Localization>>();
			foreach (WeakReference<Localization> localizationObject in localizationObjects)
			{
				if (localizationObject.TryGetTarget(out var target))
				{
					Dictionary<string, string> dictionary = loadedTexts[localizationLanguage.GetOrCreateValue(target)];
					if (!target.m_translations.ContainsKey(key))
					{
						dictionary[key] = text;
						target.AddWord(key, text);
					}
				}
				else
				{
					list.Add(localizationObject);
				}
			}
			foreach (WeakReference<Localization> item in list)
			{
				localizationObjects.Remove(item);
			}
		}

		public static void Load()
		{
			_ = plugin;
		}

		public static void LoadLocalizationLater(Localization __instance)
		{
			LoadLocalization(Localization.instance, __instance.GetSelectedLanguage());
		}

		public static void SafeCallLocalizeComplete()
		{
			Localizer.OnLocalizationComplete?.Invoke();
		}

		private static void LoadLocalization(Localization __instance, string language)
		{
			if (!localizationLanguage.Remove(__instance))
			{
				localizationObjects.Add(new WeakReference<Localization>(__instance));
			}
			localizationLanguage.Add(__instance, language);
			Dictionary<string, string> dictionary = new Dictionary<string, string>();
			foreach (string item in from f in Directory.GetFiles(Path.GetDirectoryName(Paths.PluginPath), plugin.Info.Metadata.Name + ".*", SearchOption.AllDirectories)
				where fileExtensions.IndexOf(Path.GetExtension(f)) >= 0
				select f)
			{
				string[] array = Path.GetFileNameWithoutExtension(item).Split('.');
				if (array.Length >= 2)
				{
					string text = array[1];
					if (dictionary.ContainsKey(text))
					{
						Debug.LogWarning((object)("Duplicate key " + text + " found for " + plugin.Info.Metadata.Name + ". The duplicate file found at " + item + " will be skipped."));
					}
					else
					{
						dictionary[text] = item;
					}
				}
			}
			byte[] array2 = LoadTranslationFromAssembly("English");
			if (array2 == null)
			{
				throw new Exception("Found no English localizations in mod " + plugin.Info.Metadata.Name + ". Expected an embedded resource translations/English.json or translations/English.yml.");
			}
			Dictionary<string, string> dictionary2 = new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(Encoding.UTF8.GetString(array2));
			if (dictionary2 == null)
			{
				throw new Exception("Localization for mod " + plugin.Info.Metadata.Name + " failed: Localization file was empty.");
			}
			string text2 = null;
			if (language != "English")
			{
				if (dictionary.TryGetValue(language, out var value))
				{
					text2 = File.ReadAllText(value);
				}
				else
				{
					byte[] array3 = LoadTranslationFromAssembly(language);
					if (array3 != null)
					{
						text2 = Encoding.UTF8.GetString(array3);
					}
				}
			}
			if (text2 == null && dictionary.TryGetValue("English", out var value2))
			{
				text2 = File.ReadAllText(value2);
			}
			if (text2 != null)
			{
				foreach (KeyValuePair<string, string> item2 in new DeserializerBuilder().IgnoreFields().Build().Deserialize<Dictionary<string, string>>(text2) ?? new Dictionary<string, string>())
				{
					dictionary2[item2.Key] = item2.Value;
				}
			}
			loadedTexts[language] = dictionary2;
			foreach (KeyValuePair<string, string> item3 in dictionary2)
			{
				UpdatePlaceholderText(__instance, item3.Key);
			}
		}

		static Localizer()
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Expected O, but got Unknown
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Expected O, but got Unknown
			PlaceholderProcessors = new Dictionary<string, Dictionary<string, Func<string>>>();
			loadedTexts = new Dictionary<string, Dictionary<string, string>>();
			localizationLanguage = new ConditionalWeakTable<Localization, string>();
			localizationObjects = new List<WeakReference<Localization>>();
			fileExtensions = new List<string>(2) { ".json", ".yml" };
			Harmony val = new Harmony("org.bepinex.helpers.LocalizationManager");
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(Localization), "SetupLanguage", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalization", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "SetupGui", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "LoadLocalizationLater", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			val.Patch((MethodBase)AccessTools.DeclaredMethod(typeof(FejdStartup), "Start", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(AccessTools.DeclaredMethod(typeof(Localizer), "SafeCallLocalizeComplete", (Type[])null, (Type[])null)), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static byte[]? LoadTranslationFromAssembly(string language)
		{
			foreach (string fileExtension in fileExtensions)
			{
				byte[] array = ReadEmbeddedFileBytes("translations." + language + fileExtension);
				if (array != null)
				{
					return array;
				}
			}
			return null;
		}

		public static byte[]? ReadEmbeddedFileBytes(string resourceFileName, Assembly? containingAssembly = null)
		{
			using MemoryStream memoryStream = new MemoryStream();
			if ((object)containingAssembly == null)
			{
				containingAssembly = Assembly.GetCallingAssembly();
			}
			string text = containingAssembly.GetManifestResourceNames().FirstOrDefault((string str) => str.EndsWith(resourceFileName, StringComparison.Ordinal));
			if (text != null)
			{
				containingAssembly.GetManifestResourceStream(text)?.CopyTo(memoryStream);
			}
			return (memoryStream.Length == 0L) ? null : memoryStream.ToArray();
		}
	}
	public static class LocalizationManagerVersion
	{
		public const string Version = "1.4.1";
	}
}
namespace DropNSpawn
{
	[HarmonyPatch(typeof(ZNetScene), "Awake")]
	internal static class ZNetSceneAwakePatch
	{
		private static void Postfix()
		{
			DropNSpawnPlugin.QueueGameDataRefresh(DropNSpawnPlugin.ReloadDomain.All, "ZNetScene.Awake");
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "Awake")]
	internal static class ObjectDBAwakePatch
	{
		private static void Postfix()
		{
			DropNSpawnPlugin.QueueGameDataRefresh(DropNSpawnPlugin.ReloadDomain.All, "ObjectDB.Awake");
		}
	}
	[HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")]
	internal static class ObjectDBCopyOtherDBPatch
	{
		private static void Postfix()
		{
			DropNSpawnPlugin.QueueGameDataRefresh(DropNSpawnPlugin.ReloadDomain.All, "ObjectDB.CopyOtherDB");
		}
	}
	[HarmonyPatch(typeof(ZNet), "Shutdown")]
	internal static class ZNetShutdownPatch
	{
		private static void Prefix()
		{
			CharacterDropManager.ResetWorldRuntimeState();
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "Start")]
	internal static class ZoneSystemStartPatch
	{
		private static void Postfix()
		{
			DropNSpawnPlugin.QueueGameDataRefresh(DropNSpawnPlugin.ReloadDomain.SpawnSystem, "ZoneSystem.Start");
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "Awake")]
	internal static class RandEventSystemAwakePatch
	{
		private static void Postfix()
		{
			EventManager.ApplyGlobalEventSettings();
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "Start")]
	internal static class RandEventSystemStartPatch
	{
		private static void Postfix()
		{
			EventManager.ApplyGlobalEventSettings();
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "Start")]
	internal static class ZoneSystemStartEventPatch
	{
		[HarmonyPriority(0)]
		private static void Postfix()
		{
			EventManager.NotifyGameDataReady("ZoneSystem.Start");
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "OnDestroy")]
	internal static class RandEventSystemOnDestroyPatch
	{
		private static void Prefix()
		{
			EventManager.OnRandEventSystemDestroyed();
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "FixedUpdate")]
	internal static class RandEventSystemFixedUpdatePatch
	{
		private static bool Prefix(RandEventSystem __instance)
		{
			return !EventManager.TryRunMultipleEventsFixedUpdate(__instance);
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "SetRandomEvent")]
	internal static class RandEventSystemSetRandomEventPatch
	{
		private static bool Prefix(RandEventSystem __instance, RandomEvent ev, Vector3 pos)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			return !EventManager.TryHandleMultipleSetRandomEvent(__instance, ev, pos);
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "SendCurrentRandomEvent")]
	internal static class RandEventSystemSendCurrentRandomEventPatch
	{
		private static bool Prefix(RandEventSystem __instance)
		{
			return !EventManager.TrySendMultipleCurrentRandomEvent(__instance);
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "UpdateRandomEvent")]
	internal static class RandEventSystemUpdateRandomEventPatch
	{
		private static bool Prefix(RandEventSystem __instance, float dt)
		{
			return !EventManager.TryRunCheckPerPlayerRandomUpdate(__instance, dt);
		}
	}
	[HarmonyPatch(typeof(RandomEvent), "Clone")]
	internal static class RandomEventClonePatch
	{
		private static void Postfix(RandomEvent __instance, RandomEvent __result)
		{
			EventManager.CopySpawnPayloads(__instance, __result);
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "CheckBase")]
	internal static class RandEventSystemCheckBasePatch
	{
		private static bool Prefix(RandomEvent ev, PlayerEventData player, ref bool __result)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if (!EventManager.TryCheckBase(ev, player, out var result))
			{
				return true;
			}
			__result = result;
			return false;
		}
	}
	[HarmonyPatch(typeof(RandEventSystem), "InValidBiome")]
	internal static class RandEventSystemInValidBiomePatch
	{
		private static void Postfix(RandomEvent ev, Vector3 point, ref bool __result)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			__result = EventManager.PassesExtraChecks(ev, point, __result);
		}
	}
	[HarmonyPatch(typeof(RandomEvent), "OnStart")]
	internal static class RandomEventOnStartPatch
	{
		private static void Postfix(RandomEvent __instance)
		{
			EventManager.RunStartCommands(__instance);
		}
	}
	[HarmonyPatch(typeof(RandomEvent), "OnStop")]
	internal static class RandomEventOnStopPatch
	{
		private static void Postfix(RandomEvent __instance)
		{
			EventManager.RunEndCommands(__instance);
		}
	}
	[HarmonyPatch(typeof(Location), "OnDestroy")]
	internal static class LocationOnDestroyPatch
	{
		private static void Prefix(Location __instance)
		{
			SpawnerManager.UntrackLocationInstanceProvenance(__instance);
		}
	}
	[HarmonyPatch(typeof(LocationProxy), "SpawnLocation")]
	internal static class LocationProxySpawnLocationPatch
	{
		private static readonly FieldRef<LocationProxy, GameObject> InstanceRef = AccessTools.FieldRefAccess<LocationProxy, GameObject>("m_instance");

		private static void Postfix(LocationProxy __instance, bool __result)
		{
			if (__result && PluginSettingsFacade.IsSpawnerDomainEnabled() && !DropNSpawnPlugin.IsGameDataRefreshDeferred(DropNSpawnPlugin.ReloadDomain.Spawner))
			{
				GameObject spawnedRoot = (((Object)(object)__instance != (Object)null) ? InstanceRef.Invoke(__instance) : null);
				SpawnerManager.RecordSpawnedLocationProxyProvenance(__instance, spawnedRoot);
			}
		}
	}
	internal readonly struct TemporaryFieldOverrideState<T> where T : class
	{
		internal bool Applied { get; }

		internal T? Previous { get; }

		internal TemporaryFieldOverrideState(T? previous)
		{
			Applied = true;
			Previous = previous;
		}
	}
	[HarmonyPatch(typeof(Piece), "Awake")]
	internal static class PieceAwakePatch
	{
		private static void Postfix(Piece __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.Piece);
		}
	}
	[HarmonyPatch(typeof(Piece), "SetCreator")]
	internal static class PieceSetCreatorPatch
	{
		private static void Postfix(Piece __instance)
		{
			if (PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.ReconcilePieceInstance(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Piece), "OnDestroy")]
	internal static class PieceOnDestroyPatch
	{
		private static void Prefix(Piece __instance)
		{
			ObjectDropManager.UntrackObjectInstance(((Component)__instance).gameObject);
		}
	}
	[HarmonyPatch(typeof(ZNetView), "OnDestroy")]
	internal static class ZNetViewOnDestroyPatch
	{
		private static void Prefix(ZNetView __instance)
		{
			ObjectDropManager.UntrackObjectInstance(((Component)__instance).gameObject);
			SpawnArea component = ((Component)__instance).GetComponent<SpawnArea>();
			if ((Object)(object)component != (Object)null)
			{
				SpawnerManager.UntrackSpawnAreaInstance(component);
			}
		}
	}
	[HarmonyPatch(typeof(Destructible), "Awake")]
	internal static class DestructibleAwakePatch
	{
		private static void Postfix(Destructible __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.Destructible);
		}
	}
	[HarmonyPatch(typeof(Destructible), "GetDestructibleType")]
	internal static class DestructibleGetDestructibleTypePatch
	{
		private static void Prefix(Destructible __instance)
		{
			if (PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.ApplyLazyDestructibleTypeIfNeeded(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Destructible), "RPC_Damage")]
	internal static class DestructibleDamagePatch
	{
		private static void Prefix(Destructible __instance)
		{
			if (PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.ApplyLazyDestructibleScalarsIfNeeded(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Destructible), "Destroy")]
	internal static class DestructibleDestroyPatch
	{
		private static void Prefix(Destructible __instance, out TemporaryFieldOverrideState<GameObject> __state)
		{
			__state = default(TemporaryFieldOverrideState<GameObject>);
			if (PluginSettingsFacade.IsObjectDomainEnabled() && ObjectDropManager.TryOverrideConditionalDestructibleSpawnWhenDestroyed(__instance, out GameObject previous))
			{
				__state = new TemporaryFieldOverrideState<GameObject>(previous);
			}
		}

		private static void Postfix(Destructible __instance, TemporaryFieldOverrideState<GameObject> __state)
		{
			if (__state.Applied)
			{
				__instance.m_spawnWhenDestroyed = __state.Previous;
			}
		}

		private static Exception? Finalizer(Destructible __instance, TemporaryFieldOverrideState<GameObject> __state, Exception? __exception)
		{
			if (__exception != null && __state.Applied)
			{
				__instance.m_spawnWhenDestroyed = __state.Previous;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(DropOnDestroyed), "Awake")]
	internal static class DropOnDestroyedAwakePatch
	{
		private static void Postfix(DropOnDestroyed __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.DropOnDestroyed);
		}
	}
	[HarmonyPatch(typeof(Container), "Awake")]
	internal static class ContainerAwakePatch
	{
		private static void Postfix(Container __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.Container);
		}
	}
	[HarmonyPatch(typeof(Pickable), "Awake")]
	internal static class PickableAwakePatch
	{
		private static void Postfix(Pickable __instance)
		{
			if (!PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.TrackObjectInstance(((Component)__instance).gameObject);
			}
			else
			{
				ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.Pickable);
			}
		}
	}
	[HarmonyPatch(typeof(PickableItem), "Awake")]
	internal static class PickableItemAwakePatch
	{
		private static void Postfix(PickableItem __instance)
		{
			if (!PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.TrackObjectInstance(((Component)__instance).gameObject);
			}
			else
			{
				ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.PickableItem);
			}
		}
	}
	[HarmonyPatch(typeof(Fish), "Awake")]
	internal static class FishAwakePatch
	{
		private static void Postfix(Fish __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.Fish);
		}
	}
	[HarmonyPatch(typeof(Container), "AddDefaultItems")]
	internal static class ContainerAddDefaultItemsPatch
	{
		private static void Prefix(Container __instance, out TemporaryFieldOverrideState<DropTable> __state)
		{
			__state = default(TemporaryFieldOverrideState<DropTable>);
			if (PluginSettingsFacade.IsObjectDomainEnabled() && ObjectDropManager.TryOverrideContainerDrops(__instance, out DropTable previous))
			{
				__state = new TemporaryFieldOverrideState<DropTable>(previous);
			}
		}

		private static void Postfix(Container __instance, TemporaryFieldOverrideState<DropTable> __state)
		{
			if (__state.Applied)
			{
				__instance.m_defaultItems = __state.Previous;
			}
		}

		private static Exception? Finalizer(Container __instance, TemporaryFieldOverrideState<DropTable> __state, Exception? __exception)
		{
			if (__exception != null && __state.Applied)
			{
				__instance.m_defaultItems = __state.Previous;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(DropOnDestroyed), "OnDestroyed")]
	internal static class DropOnDestroyedPatch
	{
		private static void Prefix(DropOnDestroyed __instance, out TemporaryFieldOverrideState<DropTable> __state)
		{
			__state = default(TemporaryFieldOverrideState<DropTable>);
			if (PluginSettingsFacade.IsObjectDomainEnabled() && ObjectDropManager.TryOverrideConditionalDropOnDestroyed(__instance, out DropTable previous))
			{
				__state = new TemporaryFieldOverrideState<DropTable>(previous);
			}
		}

		private static void Postfix(DropOnDestroyed __instance, TemporaryFieldOverrideState<DropTable> __state)
		{
			if (__state.Applied)
			{
				__instance.m_dropWhenDestroyed = __state.Previous;
			}
		}

		private static Exception? Finalizer(DropOnDestroyed __instance, TemporaryFieldOverrideState<DropTable> __state, Exception? __exception)
		{
			if (__exception != null && __state.Applied)
			{
				__instance.m_dropWhenDestroyed = __state.Previous;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(MineRock), "RPC_Hit")]
	internal static class MineRockHitPatch
	{
		private static void Prefix(MineRock __instance, out TemporaryFieldOverrideState<DropTable> __state)
		{
			__state = default(TemporaryFieldOverrideState<DropTable>);
			if (PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.ApplyLazyMineRockScalarsIfNeeded(__instance);
				if (ObjectDropManager.TryOverrideConditionalMineRockDrops(__instance, out DropTable previous))
				{
					__state = new TemporaryFieldOverrideState<DropTable>(previous);
				}
			}
		}

		private static void Postfix(MineRock __instance, TemporaryFieldOverrideState<DropTable> __state)
		{
			if (__state.Applied)
			{
				__instance.m_dropItems = __state.Previous;
			}
		}

		private static Exception? Finalizer(MineRock __instance, TemporaryFieldOverrideState<DropTable> __state, Exception? __exception)
		{
			if (__exception != null && __state.Applied)
			{
				__instance.m_dropItems = __state.Previous;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(MineRock), "Start")]
	internal static class MineRockStartPatch
	{
		private static void Postfix(MineRock __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.MineRock);
		}
	}
	[HarmonyPatch(typeof(MineRock5), "RPC_Damage")]
	internal static class MineRock5DamagePatch
	{
		private static void Prefix(MineRock5 __instance, out TemporaryFieldOverrideState<DropTable> __state)
		{
			__state = default(TemporaryFieldOverrideState<DropTable>);
			if (PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.ApplyLazyMineRock5ScalarsIfNeeded(__instance);
				if (ObjectDropManager.TryOverrideConditionalMineRock5Drops(__instance, out DropTable previous))
				{
					__state = new TemporaryFieldOverrideState<DropTable>(previous);
				}
			}
		}

		private static void Postfix(MineRock5 __instance, TemporaryFieldOverrideState<DropTable> __state)
		{
			if (__state.Applied)
			{
				__instance.m_dropItems = __state.Previous;
			}
		}

		private static Exception? Finalizer(MineRock5 __instance, TemporaryFieldOverrideState<DropTable> __state, Exception? __exception)
		{
			if (__exception != null && __state.Applied)
			{
				__instance.m_dropItems = __state.Previous;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(MineRock5), "Awake")]
	internal static class MineRock5AwakePatch
	{
		private static void Postfix(MineRock5 __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.MineRock5);
		}
	}
	[HarmonyPatch(typeof(TreeBase), "RPC_Damage")]
	internal static class TreeBaseDamagePatch
	{
		private static void Prefix(TreeBase __instance, out TemporaryFieldOverrideState<DropTable> __state)
		{
			__state = default(TemporaryFieldOverrideState<DropTable>);
			if (PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.ApplyLazyTreeBaseScalarsIfNeeded(__instance);
				if (ObjectDropManager.TryOverrideConditionalTreeBaseDrops(__instance, out DropTable previous))
				{
					__state = new TemporaryFieldOverrideState<DropTable>(previous);
				}
			}
		}

		private static void Postfix(TreeBase __instance, TemporaryFieldOverrideState<DropTable> __state)
		{
			if (__state.Applied)
			{
				__instance.m_dropWhenDestroyed = __state.Previous;
			}
		}

		private static Exception? Finalizer(TreeBase __instance, TemporaryFieldOverrideState<DropTable> __state, Exception? __exception)
		{
			if (__exception != null && __state.Applied)
			{
				__instance.m_dropWhenDestroyed = __state.Previous;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(TreeBase), "Awake")]
	internal static class TreeBaseAwakePatch
	{
		private static void Postfix(TreeBase __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.TreeBase);
		}
	}
	[HarmonyPatch(typeof(TreeLog), "Destroy")]
	internal static class TreeLogDestroyPatch
	{
		private static void Prefix(TreeLog __instance, out TemporaryFieldOverrideState<DropTable> __state)
		{
			__state = default(TemporaryFieldOverrideState<DropTable>);
			if (PluginSettingsFacade.IsObjectDomainEnabled() && ObjectDropManager.TryOverrideConditionalTreeLogDrops(__instance, out DropTable previous))
			{
				__state = new TemporaryFieldOverrideState<DropTable>(previous);
			}
		}

		private static void Postfix(TreeLog __instance, TemporaryFieldOverrideState<DropTable> __state)
		{
			if (__state.Applied)
			{
				__instance.m_dropWhenDestroyed = __state.Previous;
			}
		}

		private static Exception? Finalizer(TreeLog __instance, TemporaryFieldOverrideState<DropTable> __state, Exception? __exception)
		{
			if (__exception != null && __state.Applied)
			{
				__instance.m_dropWhenDestroyed = __state.Previous;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(TreeLog), "RPC_Damage")]
	internal static class TreeLogDamagePatch
	{
		private static void Prefix(TreeLog __instance)
		{
			if (PluginSettingsFacade.IsObjectDomainEnabled())
			{
				ObjectDropManager.ApplyLazyTreeLogScalarsIfNeeded(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(TreeLog), "Awake")]
	internal static class TreeLogAwakePatch
	{
		private static void Postfix(TreeLog __instance)
		{
			ObjectDropManager.QueueObjectInstanceReconcile(((Component)__instance).gameObject, ObjectDropManager.LiveObjectComponentKind.TreeLog);
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")]
	internal static class CharacterDropGenerateDropListPatch
	{
		private readonly struct State
		{
			internal List<Drop>? PreviousDrops { get; }

			internal bool HasOnePerPlayerScope { get; }

			internal IReadOnlyList<Drop>? AmountSourceDrops { get; }

			internal State(List<Drop>? previousDrops, bool hasOnePerPlayerScope, IReadOnlyList<Drop>? amountSourceDrops)
			{
				PreviousDrops = previousDrops;
				HasOnePerPlayerScope = hasOnePerPlayerScope;
				AmountSourceDrops = amountSourceDrops;
			}
		}

		private static void Prefix(CharacterDrop __instance, out State __state)
		{
			__state = new State(null, hasOnePerPlayerScope: false, null);
			bool flag = PluginSettingsFacade.IsCharacterDomainEnabled();
			if (flag || CharacterDropManager.IsGlobalCharacterLootLevelScalingEnabled())
			{
				List<Drop> list = (flag ? CharacterDropManager.OverrideConditionalDrops(__instance) : null);
				__state = new State(list, hasOnePerPlayerScope: false, null);
				IReadOnlyList<Drop> sourceDrops;
				List<Drop> list2 = CharacterDropManager.SuppressGlobalCharacterLootLevelMultiplierDrops(__instance, out sourceDrops);
				if (list == null)
				{
					list = list2;
				}
				__state = new State(list, hasOnePerPlayerScope: false, sourceDrops);
				bool hasOnePerPlayerScope = flag && CharacterDropManager.BeginOnePerPlayerNearbyPlayerScope(__instance);
				__state = new State(list, hasOnePerPlayerScope, sourceDrops);
			}
		}

		[HarmonyPriority(0)]
		private static void Postfix(CharacterDrop __instance, List<KeyValuePair<GameObject, int>> __result, State __state)
		{
			CharacterDropManager.ApplyGlobalCharacterLootLevelMultiplier(__instance, __result, __state.AmountSourceDrops);
			if (__state.PreviousDrops != null)
			{
				__instance.m_drops = __state.PreviousDrops;
			}
		}

		private static Exception? Finalizer(CharacterDrop __instance, State __state, Exception? __exception)
		{
			if (__state.PreviousDrops != null)
			{
				__instance.m_drops = __state.PreviousDrops;
			}
			if (__state.HasOnePerPlayerScope)
			{
				CharacterDropManager.EndOnePerPlayerNearbyPlayerScope();
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(ZNet), "GetNrOfPlayers")]
	internal static class ZNetGetNrOfPlayersPatch
	{
		private static bool Prefix(ref int __result)
		{
			if (!PluginSettingsFacade.IsCharacterDomainEnabled())
			{
				return true;
			}
			if (!CharacterDropManager.TryGetScopedOnePerPlayerNearbyPlayerCount(out var playerCount))
			{
				return true;
			}
			__result = playerCount;
			return false;
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "Start")]
	internal static class CharacterDropStartPatch
	{
		private static void Postfix(CharacterDrop __instance)
		{
			if (PluginSettingsFacade.IsCharacterDomainEnabled())
			{
				CharacterDropManager.TrackCharacterDropInstance(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Character), "OnDestroy")]
	internal static class CharacterOnDestroyCharacterDropPatch
	{
		private static void Postfix(Character __instance)
		{
			CharacterDrop characterDrop = default(CharacterDrop);
			if ((Object)(object)__instance != (Object)null && ((Component)__instance).TryGetComponent<CharacterDrop>(ref characterDrop))
			{
				CharacterDropManager.UntrackCharacterDropInstance(characterDrop);
			}
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "OnDeath")]
	internal static class CharacterDropOnDeathPatch
	{
		private static bool Prefix(CharacterDrop __instance)
		{
			if (!PluginSettingsFacade.IsCharacterDomainEnabled())
			{
				return true;
			}
			return !CharacterDropManager.TryHandleConfiguredDeath(__instance);
		}
	}
	[HarmonyPatch(typeof(CharacterDrop), "DropItems")]
	internal static class CharacterDropDropItemsPatch
	{
		private static void Prefix(ref List<KeyValuePair<GameObject, int>> drops, Vector3 centerPos, float dropArea)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			if (PluginSettingsFacade.IsCharacterDomainEnabled())
			{
				CharacterDropManager.ApplyGlobalDropInStack(ref drops, centerPos, dropArea);
			}
		}
	}
	[HarmonyPatch(typeof(Ragdoll), "Setup")]
	internal static class RagdollSetupMonsterInstantLootDropPatch
	{
		private static void Postfix(Ragdoll __instance, CharacterDrop characterDrop)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginSettingsFacade.IsMonsterInstantLootDropEnabled() || (Object)(object)characterDrop == (Object)null || !__instance.m_dropItems)
			{
				return;
			}
			ZNetView nview = __instance.m_nview;
			if ((Object)(object)nview == (Object)null || !nview.IsValid() || !nview.IsOwner())
			{
				return;
			}
			ZDO zDO = nview.GetZDO();
			if (zDO.GetInt(ZDOVars.s_drops, 0) > 0)
			{
				Vector3 val = __instance.GetAverageBodyPosition();
				if ((Object)(object)__instance.m_lootSpawnJoint != (Object)null)
				{
					val = __instance.m_lootSpawnJoint.transform.position;
				}
				__instance.SpawnLoot(val);
				zDO.Set(ZDOVars.s_drops, 0, false);
			}
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "SpawnLocation", new Type[]
	{
		typeof(ZoneLocation),
		typeof(int),
		typeof(Vector3),
		typeof(Quaternion),
		typeof(SpawnMode),
		typeof(List<GameObject>)
	})]
	[HarmonyAfter(new string[] { "expand_world_data" })]
	internal static class ZoneSystemSpawnLocationContextPatch
	{
		private sealed class SpawnLocationContextState
		{
			public bool HasContext { get; set; }
		}

		private static void Prefix(ZoneLocation location, ref SpawnLocationContextState? __state)
		{
			__state = null;
			if (PluginSettingsFacade.IsSpawnerDomainEnabled() && !DropNSpawnPlugin.IsGameDataRefreshDeferred(DropNSpawnPlugin.ReloadDomain.Spawner))
			{
				SpawnerManager.BeginLocationSpawnContext(location);
				__state = new SpawnLocationContextState
				{
					HasContext = true
				};
			}
		}

		private static void Postfix(GameObject __result, SpawnLocationContextState? __state)
		{
			if (__state != null && __state.HasContext)
			{
				SpawnerManager.RecordSpawnedLocationRootProvenance(__result);
			}
		}

		private static void Finalizer(SpawnLocationContextState? __state)
		{
			if (__state != null && __state.HasContext)
			{
				SpawnerManager.EndLocationSpawnContext();
			}
		}
	}
	[HarmonyPatch(typeof(DungeonGenerator), "Generate", new Type[] { typeof(SpawnMode) })]
	internal static class DungeonGeneratorGenerateContextPatch
	{
		private static void Prefix(DungeonGenerator __instance, ref bool __state)
		{
			__state = false;
			if (PluginSettingsFacade.IsSpawnerDomainEnabled() && !DropNSpawnPlugin.IsGameDataRefreshDeferred(DropNSpawnPlugin.ReloadDomain.Spawner))
			{
				__state = SpawnerManager.TryBeginDerivedLocationSpawnContext(__instance);
			}
		}

		private static void Finalizer(bool __state)
		{
			if (__state)
			{
				SpawnerManager.EndLocationSpawnContext();
			}
		}
	}
	[HarmonyPatch(typeof(DungeonGenerator), "Spawn")]
	internal static class DungeonGeneratorSpawnContextPatch
	{
		private static void Prefix(DungeonGenerator __instance, ref bool __state)
		{
			__state = false;
			if (PluginSettingsFacade.IsSpawnerDomainEnabled() && !DropNSpawnPlugin.IsGameDataRefreshDeferred(DropNSpawnPlugin.ReloadDomain.Spawner))
			{
				__state = SpawnerManager.TryBeginDerivedLocationSpawnContext(__instance);
			}
		}

		private static void Finalizer(bool __state)
		{
			if (__state)
			{
				SpawnerManager.EndLocationSpawnContext();
			}
		}
	}
	[HarmonyPatch(typeof(SpawnArea), "Awake")]
	internal static class SpawnAreaAwakePatch
	{
		private static void Postfix(SpawnArea __instance)
		{
			SpawnerManager.HandleSpawnAreaInstanceAwake(__instance);
		}
	}
	[HarmonyPatch(typeof(SpawnArea), "UpdateSpawn")]
	internal static class SpawnAreaUpdateSpawnPatch
	{
		private static bool Prefix(SpawnArea __instance)
		{
			if (!PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				return true;
			}
			if (SpawnerManager.ShouldBlockClientSpawnerUpdate())
			{
				return false;
			}
			return SpawnerManager.PrepareSpawnAreaForUpdate(__instance);
		}
	}
	[HarmonyPatch(typeof(SpawnArea), "SelectWeightedPrefab")]
	internal static class SpawnAreaSelectWeightedPrefabPatch
	{
		private static void Postfix(SpawnArea __instance, SpawnData __result)
		{
			if (PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				SpawnerManager.RecordSelectedSpawnAreaPrefab(__instance, __result);
			}
		}
	}
	[HarmonyPatch(typeof(SpawnArea), "FindSpawnPoint")]
	internal static class SpawnAreaFindSpawnPointPatch
	{
		private static void Postfix(SpawnArea __instance, GameObject prefab, ref Vector3 point, bool __result)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			if (PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				SpawnerManager.RecordSpawnAreaSpawnPoint(__instance, __result, point);
				if (__result)
				{
					SpawnerManager.InitializeSpawnAreaSpawnData(__instance, prefab, point);
				}
			}
		}
	}
	[HarmonyPatch(typeof(SpawnArea), "SpawnOne")]
	internal static class SpawnAreaSpawnOnePatch
	{
		private static readonly MethodInfo InstantiateGameObjectMethod = (from method in typeof(Object).GetMethods(BindingFlags.Static | BindingFlags.Public)
			where method.Name == "Instantiate" && method.IsGenericMethodDefinition
			select method).First(delegate(MethodInfo method)
		{
			ParameterInfo[] parameters = method.GetParameters();
			return parameters.Length == 3 && parameters[2].ParameterType == typeof(Quaternion);
		}).MakeGenericMethod(typeof(GameObject));

		private static void Prefix(SpawnArea __instance)
		{
			if (PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				SpawnerManager.BeginSpawnAreaSpawnAttempt(__instance);
			}
		}

		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.MatchForward(false, (CodeMatch[])(object)new CodeMatch[1]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)InstantiateGameObjectMethod, (string)null)
			});
			if (!val.IsValid)
			{
				DropNSpawnPlugin.DropNSpawnLogger.LogError((object)"Failed to locate SpawnArea.SpawnOne instantiate call for faction tracking.");
				return instructions;
			}
			return val.Advance(1).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Dup, (object)null)
			}).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
			{
				new CodeInstruction(OpCodes.Ldarg_0, (object)null)
			})
				.InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1]
				{
					new CodeInstruction(OpCodes.Call, Transpilers.EmitDelegate<Action<GameObject, SpawnArea>>((Action<GameObject, SpawnArea>)RecordSpawnedObject).operand)
				})
				.InstructionEnumeration();
		}

		private static void Postfix(SpawnArea __instance, bool __result)
		{
			if (PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				SpawnerManager.FinalizeSpawnAreaSpawnAttempt(__instance, __result);
			}
		}

		private static void RecordSpawnedObject(GameObject spawnedObject, SpawnArea spawnArea)
		{
			SpawnerManager.RecordDirectSpawnAreaSpawnedObject(spawnArea, spawnedObject);
		}
	}
	[HarmonyPatch(typeof(CreatureSpawner), "Awake")]
	internal static class CreatureSpawnerAwakePatch
	{
		private static void Postfix(CreatureSpawner __instance)
		{
			SpawnerManager.HandleCreatureSpawnerInstanceAwake(__instance);
		}
	}
	[HarmonyPatch(typeof(CreatureSpawner), "OnDestroy")]
	internal static class CreatureSpawnerOnDestroyPatch
	{
		private static void Prefix(CreatureSpawner __instance)
		{
			SpawnerManager.UntrackCreatureSpawnerInstance(__instance);
		}
	}
	[HarmonyPatch(typeof(CreatureSpawner), "UpdateSpawner")]
	internal static class CreatureSpawnerUpdateSpawnerPatch
	{
		private static bool Prefix(CreatureSpawner __instance)
		{
			if (!PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				return true;
			}
			if (SpawnerManager.ShouldBlockClientSpawnerUpdate())
			{
				return false;
			}
			return SpawnerManager.PrepareCreatureSpawnerForUpdate(__instance);
		}
	}
	[HarmonyPatch(typeof(CreatureSpawner), "Spawn")]
	internal static class CreatureSpawnerSpawnPatch
	{
		private static void Prefix(CreatureSpawner __instance)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			if (PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				Vector3 position = ((Component)__instance).transform.position;
				float y = default(float);
				if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.FindFloor(position, ref y))
				{
					position.y = y;
				}
				SpawnerManager.InitializeCreatureSpawnerSpawnData(__instance, __instance.m_creaturePrefab, position);
			}
		}

		private static void Postfix(CreatureSpawner __instance, ZNetView __result)
		{
			if (PluginSettingsFacade.IsSpawnerDomainEnabled())
			{
				SpawnerManager.ApplyCreatureSpawnerSpawnOverrides(__instance, __result);
			}
		}
	}
	[HarmonyPatch(typeof(BaseAI), "Awake")]
	internal static class BaseAIAwakeFactionPatch
	{
		private static void Postfix(BaseAI __instance)
		{
			FactionIntegration.ApplyFromZdo(__instance);
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "Awake")]
	[HarmonyPriority(0)]
	internal static class SpawnSystemAwakePatch
	{
		private static void Prefix(SpawnSystem __instance)
		{
			SpawnSystemManager.PreAttachCompiledTableToAwakeningSystem(__instance);
		}

		private static void Postfix(SpawnSystem __instance)
		{
			SpawnSystemManager.OnSpawnSystemAwake(__instance);
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "OnDestroy")]
	internal static class SpawnSystemOnDestroyPatch
	{
		private static void Prefix(SpawnSystem __instance)
		{
			SpawnSystemManager.UntrackLiveSystem(__instance);
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "UpdateSpawning")]
	internal static class SpawnSystemUpdateSpawningRequiredGlobalKeyPatch
	{
		private static bool Prefix(SpawnSystem __instance, out bool __state)
		{
			__state = false;
			if (!PluginSettingsFacade.IsSpawnSystemDomainEnabled())
			{
				return true;
			}
			if (SpawnSystemManager.ShouldBlockClientSpawnSystemUpdate(__instance))
			{
				return false;
			}
			SpawnSystemManager.RefreshRuntimeTimeOfDayState();
			__state = true;
			SpawnSystemManager.EnterRequiredGlobalKeyEvaluation();
			return true;
		}

		private static Exception? Finalizer(bool __state, Exception? __exception)
		{
			if (__state)
			{
				SpawnSystemManager.ExitRequiredGlobalKeyEvaluation();
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "GetGlobalKey", new Type[] { typeof(string) })]
	internal static class ZoneSystemGetGlobalKeyStringPatch
	{
		private static bool Prefix(ZoneSystem __instance, string name, ref bool __result)
		{
			if (!PluginSettingsFacade.IsSpawnSystemDomainEnabled())
			{
				return true;
			}
			if (!SpawnSystemManager.TryEvaluateExtendedRequiredGlobalKey(__instance, name, out var result))
			{
				return true;
			}
			__result = result;
			return false;
		}
	}
	[HarmonyPatch(typeof(ZoneSystem), "RPC_SetGlobalKey")]
	internal static class ZoneSystemRpcSetGlobalKeyPatch
	{
		private static void Prefix(ZoneSystem __instance, ref string name)
		{
			if (DropNSpawnPlugin.IsSourceOfTruth && PluginSettingsFacade.IsSpawnSystemDomainEnabled() && SpawnSystemManager.TryRewriteExtendedGlobalKeyMutation(__instance, name, out string rewrittenValue))
			{
				name = rewrittenValue;
			}
		}
	}
	[HarmonyPatch(typeof(SpawnSystem), "Spawn")]
	internal static class SpawnSystemSpawnPatch
	{
		private static void Prefix(SpawnData critter, Vector3 spawnPoint, out bool __state)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			__state = false;
			if (PluginSettingsFacade.IsSpawnSystemDomainEnabled() || SpawnSystemCustomDataSupport.HasPreparedPayload(critter))
			{
				__state = true;
				SpawnSystemCustomDataSupport.InitializeSpawn(critter, spawnPoint);
			}
		}

		private static void Postfix(SpawnData critter, Vector3 spawnPoint, bool __state)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			if (__state)
			{
				SpawnSystemManager.ConsumeExtendedRequiredGlobalKeyAfterSpawn(critter);
				SpawnSystemCustomDataSupport.SpawnObjects(critter, spawnPoint);
			}
		}

		private static Exception? Finalizer(SpawnData critter, bool __state, Exception? __exception)
		{
			return __exception;
		}
	}
	internal static class GeneratedFileWriter
	{
		internal static bool WriteAllTextIfChanged(string path, string content)
		{
			if (path == null)
			{
				throw new ArgumentNullException("path");
			}
			if (content == null)
			{
				content = "";
			}
			string directoryName = Path.GetDirectoryName(path);
			if (!string.IsNullOrEmpty(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			if (File.Exists(path) && string.Equals(File.ReadAllText(path), content, StringComparison.Ordinal))
			{
				return false;
			}
			File.WriteAllText(path, content);
			return true;
		}
	}
	internal static class GeneratedArtifactWriter
	{
		internal static bool WriteText(string path, string content, string? logMessage = null, bool logOnlyWhenChanged = false)
		{
			bool flag = GeneratedFileWriter.WriteAllTextIfChanged(path, content);
			if (!string.IsNullOrWhiteSpace(logMessage) && (!logOnlyWhenChanged || flag))
			{
				DropNSpawnPlugin.DropNSpawnLogger.LogInfo((object)logMessage);
			}
			return flag;
		}

		internal static void WriteTextAlways(string path, string content, string? logMessage = null)
		{
			string directoryName = Path.GetDirectoryName(path);
			if (!string.IsNullOrWhiteSpace(directoryName))
			{
				Directory.CreateDirectory(directoryName);
			}
			File.WriteAllText(path, content ?? "");
			if (!string.IsNullOrWhiteSpace(logMessage))
			{
				DropNSpawnPlugin.DropNSpawnLogger.LogInfo((object)logMessage);
			}
		}
	}
	internal static class ReferenceRefreshSupport
	{
		internal const string CurrentReferenceLogicVersion = "2026-03-26-full-rewrite-v1";

		internal static string ComputeStableHashForKeys(IEnumerable<string?> keys)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (string item in (from key in (keys ?? Enumerable.Empty<string>()).Select(NormalizeKey)
				where key.Length > 0
				select key).OrderBy<string, string>((string key) => key, StringComparer.OrdinalIgnoreCase))
			{
				stringBuilder.AppendLine(item);
			}
			return ComputeStableHash(stringBuilder.ToString());
		}

		internal static string SerializeReferenceSections<T>(IEnumerable<T> entries, Func<T, string> getPrefabName, ISerializer serializer)
		{
			return PrefabOutputSections.SerializeReferenceSections(PrefabOutputSections.BuildSections(entries ?? Enumerable.Empty<T>(), getPrefabName), serializer);
		}

		internal static HashSet<string> ToNormalizedKeySet(IEnumerable<string?> keys)
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			foreach (string item in keys ?? Enumerable.Empty<string>())
			{
				string text = NormalizeKey(item);
				if (text.Length > 0)
				{
					hashSet.Add(text);
				}
			}
			return hashSet;
		}

		internal static string NormalizeKey(string? key)
		{
			return (key ?? "").Trim();
		}

		internal static bool ShouldSkipAutoUpdate(string stateKey, string referencePath, string sourceSignature, string? logicVersion = null)
		{
			if (string.IsNullOrWhiteSpace(stateKey) || string.IsNullOrWhiteSpace(referencePath) || string.IsNullOrWhiteSpace(sourceSignature) || !File.Exists(referencePath))
			{
				return false;
			}
			string autoUpdateStatePath = GetAutoUpdateStatePath(stateKey);
			if (!File.Exists(autoUpdateStatePath))
			{
				return false;
			}
			try
			{
				string text = (logicVersion ?? "").Trim();
				string[] array = File.ReadAllLines(autoUpdateStatePath);
				if (array.Length < 2)
				{
					return false;
				}
				string a = (array[0] ?? "").Trim();
				string a2 = (array[1] ?? "").Trim();
				string a3 = ((array.Length >= 4) ? (array[3] ?? "").Trim() : "");
				if (text.Length > 0 && !string.Equals(a3, text, StringComparison.Ordinal))
				{
					return false;
				}
				return string.Equals(a, sourceSignature, StringComparison.Ordinal) && string.Equals(a2, BuildReferenceFileStamp(referencePath), StringComparison.Ordinal);
			}
			catch
			{
				return false;
			}
		}

		internal static void RecordAutoUpdateState(string stateKey, string referencePath, string sourceSignature, string? precheckSignature = null, string? logicVersion = null)
		{
			if (!string.IsNullOrWhiteSpace(stateKey) && !string.IsNullOrWhiteSpace(referencePath) && !string.IsNullOrWhiteSpace(sourceSignature) && File.Exists(referencePath))
			{
				string autoUpdateStatePath = GetAutoUpdateStatePath(stateKey);
				string content = sourceSignature.Trim() + Environment.NewLine + BuildReferenceFileStamp(referencePath) + Environment.NewLine + (precheckSignature ?? "").Trim() + Environment.NewLine + (logicVersion ?? "").Trim() + Environment.NewLine;
				GeneratedFileWriter.WriteAllTextIfChanged(autoUpdateStatePath, content);
			}
		}

		internal static string ComputeStableHash(string? value)
		{
			using SHA256 sHA = SHA256.Create();
			byte[] bytes = Encoding.UTF8.GetBytes(value ?? "");
			byte[] array = sHA.ComputeHash(bytes);
			StringBuilder stringBuilder = new StringBuilder(array.Length * 2);
			byte[] array2 = array;
			foreach (byte b in array2)
			{
				stringBuilder.Append(b.ToString("x2"));
			}
			return stringBuilder.ToString();
		}

		private static string GetAutoUpdateStatePath(string stateKey)
		{
			string text = SanitizeFileName(stateKey);
			return Path.Combine(GetAutoUpdateStateDirectoryPath(), ".reference-state." + text + ".txt");
		}

		private static string GetAutoUpdateStateDirectoryPath()
		{
			return Path.Combine(DropNSpawnPlugin.YamlConfigDirectoryPath, "cache");
		}

		private static string BuildReferenceFileStamp(string referencePath)
		{
			FileInfo fileInfo = new FileInfo(referencePath);
			return $"{fileInfo.Length}:{fileInfo.LastWriteTimeUtc.Ticks}";
		}

		private static string SanitizeFileName(string value)
		{
			StringBuilder stringBuilder = new StringBuilder(value.Length);
			HashSet<char> hashSet = Path.GetInvalidFileNameChars().ToHashSet();
			foreach (char c in value)
			{
				stringBuilder.Append(hashSet.Contains(c) ? '_' : c);
			}
			return stringBuilder.ToString();
		}
	}
	internal enum ReferenceArtifactUpdateKind
	{
		None,
		Created,
		Updated
	}
	internal static class ReferenceArtifactLifecycle
	{
		internal static bool TryPlanUpdate(string stateKey, string referencePath, string sourceSignature, out ReferenceArtifactUpdateKind updateKind)
		{
			updateKind = ReferenceArtifactUpdateKind.None;
			if (!File.Exists(referencePath))
			{
				updateKind = ReferenceArtifactUpdateKind.Created;
				return true;
			}
			if (ReferenceRefreshSupport.ShouldSkipAutoUpdate(stateKey, referencePath, sourceSignature, "2026-03-26-full-rewrite-v1"))
			{
				return false;
			}
			updateKind = ReferenceArtifactUpdateKind.Updated;
			return true;
		}

		internal static void RecordUpdate(string stateKey, string referencePath, string sourceSignature)
		{
			ReferenceRefreshSupport.RecordAutoUpdateState(stateKey, referencePath, sourceSignature, null, "2026-03-26-full-rewrite-v1");
		}

		internal static string FormatAction(ReferenceArtifactUpdateKind updateKind)
		{
			if (updateKind != ReferenceArtifactUpdateKind.Created)
			{
				return "Updated";
			}
			return "Created";
		}
	}
	internal sealed class CharacterDropPrefabEntry
	{
		[YamlMember(Order = 1)]
		public string Prefab { get; set; } = "";

		[YamlMember(Order = 2)]
		public bool Enabled { get; set; } = true;

		[YamlMember(Order = 3)]
		public ConditionsDefinition? Conditions { get; set; }

		[YamlMember(Order = 4)]
		public CharacterDropDefinition? CharacterDrop { get; set; }

		[YamlIgnore]
		public string RuleId { get; set; } = "";

		[YamlIgnore]
		public string? SourcePath { get; set; }

		[YamlIgnore]
		public int SourceLine { get; set; }

		[YamlIgnore]
		public int SourceColumn { get; set; }
	}
	internal sealed class CharacterDropReferenceEntry
	{
		[YamlMember(Order = 1)]
		public string Prefab { get; set; } = "";

		[YamlMember(Order = 2)]
		public CharacterDropDefinition? CharacterDrop { get; set; }
	}
	internal sealed class CharacterDropDefinition
	{
		[YamlMember(Order = 1)]
		public List<CharacterDropEntryDefinition>? Drops { get; set; }
	}
	internal sealed class CharacterDropEntryDefinition
	{
		[YamlMember(Order = 1)]
		public string Item { get; set; } = "";

		[YamlMember(Order = 2)]
		public IntRangeDefinition? Amount { get; set; }

		[YamlIgnore]
		public int? AmountMin { get; set; }

		[YamlIgnore]
		public int? AmountMax { get; set; }

		[YamlMember(Order = 3)]
		public float? Chance { get; set; }

		[YamlMember(Order = 4)]
		public bool? DontScale { get; set; }

		[YamlMember(Order = 5)]
		public bool? LevelMultiplier { get; set; }

		[YamlMember(Order = 6)]
		public bool? OnePerPlayer { get; set; }

		[YamlMember(Order = 7)]
		public int? AmountLimit { get; set; }

		[YamlMember(Order = 8)]
		public bool? DropInStack { get; set; }
	}
	internal sealed class CompiledCharacterDropDefinition
	{
		public string Fingerprint { get; set; } = "";

		public GameObject Prefab { get; set; }

		public int AmountMin { get; set; }

		public int AmountMax { get; set; }

		public float Chance { get; set; }

		public bool DontScale { get; set; }

		public bool LevelMultiplier { get; set; }

		public bool OnePerPlayer { get; set; }

		public int? AmountLimit { get; set; }

		public bool DropInStack { get; set; }
	}
	internal sealed class CompiledCharacterDropRule
	{
		public CharacterDropPrefabEntry Entry { get; set; }

		public List<CompiledCharacterDropDefinition> Drops { get; } = new List<CompiledCharacterDropDefinition>();
	}
	internal sealed class CachedCharacterRuntimeDropResolution
	{
		public bool HasMatchedRuntimeRule { get; set; }

		public CompiledCharacterDropDefinition[] Definitions { get; set; } = Array.Empty<CompiledCharacterDropDefinition>();

		public List<Drop>? OverrideDrops { get; set; }

		public bool HasCustomDropHandling { get; set; }
	}
	internal sealed class CharacterRuntimeDropCacheState
	{
		public bool IsCacheable { get; set; } = true;

		public bool UsesLevel { get; set; }

		public bool UsesFaction { get; set; }

		public bool UsesState { get; set; }

		public bool UsesTimeOfDay { get; set; }

		public bool UsesRequiredEnvironments { get; set; }

		public bool UsesInsidePlayerBase { get; set; }

		public string[] RequiredGlobalKeys { get; set; } = Array.Empty<string>();

		public string[] ForbiddenGlobalKeys { get; set; } = Array.Empty<string>();

		public Dictionary<int, CachedCharacterRuntimeDropResolution> ResolutionsBySignature { get; } = new Dictionary<int, CachedCharacterRuntimeDropResolution>();
	}
	internal sealed class CharacterCompiledState
	{
		public static CharacterCompiledState Empty { get; } = new CharacterCompiledState();

		public Dictionary<string, List<CompiledCharacterDropRule>> RuntimeRulesByPrefab { get; } = new Dictionary<string, List<CompiledCharacterDropRule>>(StringComparer.OrdinalIgnoreCase);

		public Dictionary<string, CharacterRuntimeDropCacheState> RuntimeDropCachesByPrefab { get; } = new Dictionary<string, CharacterRuntimeDropCacheState>(StringComparer.OrdinalIgnoreCase);

		public Dictionary<string, List<CompiledCharacterDropDefinition>> StaticDropsByPrefab { get; } = new Dictionary<string, List<CompiledCharacterDropDefinition>>(StringComparer.OrdinalIgnoreCase);

		public Dictionary<string, List<Drop>> StaticBuiltDropsByPrefab { get; } = new Dictionary<string, List<Drop>>(StringComparer.OrdinalIgnoreCase);
	}
	internal sealed class CharacterDropItemSnapshot
	{
		public GameObject? ItemPrefab { get; set; }

		public int AmountMin { get; set; }

		public int AmountMax { get; set; }

		public float Chance { get; set; }

		public bool OnePerPlayer { get; set; }

		public bool LevelMultiplier { get; set; }

		public bool DontScale { get; set; }
	}
	internal sealed class CharacterDropSnapshot
	{
		public GameObject Prefab { get; set; }

		public List<CharacterDropItemSnapshot> Drops { get; set; } = new List<CharacterDropItemSnapshot>();

		public List<Drop> BuiltDrops { get; set; } = new List<Drop>();
	}
	internal sealed class PendingCharacterDropSnapshotBuildState
	{
		public int GameDataSignature { get; set; }

		public int SnapshotSignature { get; set; }

		public string Source { get; set; } = "";

		public List<GameObject> Prefabs { get; } = new List<GameObject>();

		public List<CharacterDropSnapshot> Snapshots { get; } = new List<CharacterDropSnapshot>();

		public Dictionary<string, CharacterDropSnapshot> SnapshotsByPrefab { get; } = new Dictionary<string, CharacterDropSnapshot>(StringComparer.OrdinalIgnoreCase);

		public int NextIndex { get; set; }
	}
	internal static class CharacterDropRuntime
	{
		private static readonly List<CharacterDropSnapshot> Snapshots = new List<CharacterDropSnapshot>();

		private static readonly Dictionary<string, CharacterDropSnapshot> SnapshotsByPrefab = new Dictionary<string, CharacterDropSnapshot>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<string, HashSet<CharacterDrop>> LiveCharacterDropsByPrefab = new Dictionary<string, HashSet<CharacterDrop>>(StringComparer.OrdinalIgnoreCase);

		private static readonly Dictionary<CharacterDrop, string> LiveCharacterDropPrefabsByInstance = new Dictionary<CharacterDrop, string>();

		private static int? _lastProcessedSnapshotSignature;

		private static int? _lastProcessedGameDataSignature;

		private static int? _lastBootstrappedLiveObjectsSceneSignature;

		private static PendingCharacterDropSnapshotBuildState? _pendingSnapshotBuild;

		internal static void Reset()
		{
			Snapshots.Clear();
			SnapshotsByPrefab.Clear();
			LiveCharacterDropsByPrefab.Clear();
			LiveCharacterDropPrefabsByInstance.Clear();
			_lastProcessedSnapshotSignature = null;
			_lastProcessedGameDataSignature = null;
			_lastBootstrappedLiveObjectsSceneSignature = null;
			_pendingSnapshotBuild = null;
		}

		internal static bool HasSnapshots()
		{
			return Snapshots.Count > 0;
		}

		internal static IReadOnlyList<CharacterDropSnapshot> GetSnapshots()
		{
			return Snapshots;
		}

		internal static bool HasSnapshot(string prefabName)
		{
			if (!string.IsNullOrWhiteSpace(prefabName))
			{
				return SnapshotsByPrefab.ContainsKey(prefabName);
			}
			return false;
		}

		internal static bool TryGetSnapshot(string prefabName, out CharacterDropSnapshot? snapshot)
		{
			return SnapshotsByPrefab.TryGetValue(prefabName ?? "", out snapshot);
		}

		internal static bool IsGameDataAlreadyProcessed(int gameDataSignature)
		{
			return _lastProcessedGameDataSignature == gameDataSignature;
		}

		internal static bool NeedsSnapshotBuild(int snapshotSignature)
		{
			if (_lastProcessedSnapshotSignature == snapshotSignature)
			{
				return Snapshots.Count == 0;
			}
			return true;
		}

		internal static void ScheduleSnapshotBuild(string source, int gameDataSignature, int snapshotSignature, IEnumerable<GameObject> prefabs)
		{
			if (_pendingSnapshotBuild == null || _pendingSnapshotBuild.GameDataSignature != gameDataSignature || _pendingSnapshotBuild.SnapshotSignature != snapshotSignature)
			{
				PendingCharacterDropSnapshotBuildState pendingCharacterDropSnapshotBuildState = new PendingCharacterDropSnapshotBuildState();
				pendingCharacterDropSnapshotBuildState.GameDataSignature = gameDataSignature;
				pendingCharacterDropSnapshotBuildState.SnapshotSignature = snapshotSignature;
				pendingCharacterDropSnapshotBuildState.Source = source;
				pendingCharacterDropSnapshotBuildState.Prefabs.AddRange(prefabs);
				_pendingSnapshotBuild = pendingCharacterDropSnapshotBuildState;
			}
		}

		internal static bool HasPendingSnapshotBuildWork()
		{
			return _pendingSnapshotBuild != null;
		}

		internal static bool ProcessPendingSnapshotBuildStep(double deadline, Func<GameObject, CharacterDropSnapshot?> captureSnapshot, Action<string, int, int> onCompleted)
		{
			PendingCharacterDropSnapshotBuildState pendingSnapshotBuild = _pendingSnapshotBuild;
			if (pendingSnapshotBuild == null)
			{
				return false;
			}
			if (pendingSnapshotBuild.NextIndex >= pendingSnapshotBuild.Prefabs.Count)
			{
				CompletePendingSnapshotBuild(pendingSnapshotBuild, onCompleted);
				return true;
			}
			GameObject val = pendingSnapshotBuild.Prefabs[pendingSnapshotBuild.NextIndex];
			pendingSnapshotBuild.NextIndex++;
			CharacterDropSnapshot characterDropSnapshot = (((Object)(object)val != (Object)null) ? captureSnapshot(val) : null);
			if (_pendingSnapshotBuild == null || _pendingSnapshotBuild != pendingSnapshotBuild)
			{
				return true;
			}
			if (characterDropSnapshot != null)
			{
				pendingSnapshotBuild.Snapshots.Add(characterDropSnapshot);
				if (!pendingSnapshotBuild.SnapshotsByPrefab.ContainsKey(((Object)characterDropSnapshot.Prefab).name))
				{
					pendingSnapshotBuild.SnapshotsByPrefab.Add(((Object)characterDropSnapshot.Prefab).name, characterDropSnapshot);
				}
			}
			if (pendingSnapshotBuild.NextIndex >= pendingSnapshotBuild.Prefabs.Count && Time.realtimeSinceStartupAsDouble <= deadline)
			{
				CompletePendingSnapshotBuild(pendingSnapshotBuild, onCompleted);
			}
			return true;
		}

		internal static void CaptureSnapshotsIfNeeded(IEnumerable<GameObject> prefabs, Func<GameObject, CharacterDropSnapshot?> captureSnapshot)
		{
			if (Snapshots.Count > 0)
			{
				return;
			}
			foreach (GameObject prefab in prefabs)
			{
				CharacterDropSnapshot characterDropSnapshot = captureSnapshot(prefab);
				if (characterDropSnapshot != null)
				{
					Snapshots.Add(characterDropSnapshot);
					if (!SnapshotsByPrefab.ContainsKey(((Object)characterDropSnapshot.Prefab).name))
					{
						SnapshotsByPrefab.Add(((Object)characterDropSnapshot.Prefab).name, characterDropSnapshot);
					}
				}
			}
		}

		internal static void RegisterLiveCharacterDrop(CharacterDrop characterDrop, string prefabName)
		{
			if ((Object)(object)characterDrop == (Object)null || string.IsNullOrWhiteSpace(prefabName))
			{
				return;
			}
			if (LiveCharacterDropPrefabsByInstance.TryGetValue(characterDrop, out string value))
			{
				if (string.Equals(value, prefabName, StringComparison.OrdinalIgnoreCase))
				{
					return;
				}
				UnregisterLiveCharacterDrop(characterDrop, value);
			}
			LiveCharacterDropPrefabsByInstance[characterDrop] = prefabName;
			if (!LiveCharacterDropsByPrefab.TryGetValue(prefabName, out HashSet<CharacterDrop> value2))
			{
				value2 = new HashSet<CharacterDrop>();
				LiveCharacterDropsByPrefab[prefabName] = value2;
			}
			value2.Add(characterDrop);
		}

		internal static bool TryGetRegisteredPrefabName(CharacterDrop characterDrop, out string prefabName)
		{
			return LiveCharacterDropPrefabsByInstance.TryGetValue(characterDrop, out prefabName);
		}

		internal static void UnregisterLiveCharacterDrop(CharacterDrop characterDrop, string prefabName)
		{
			LiveCharacterDropPrefabsByInstance.Remove(characterDrop);
			if (LiveCharacterDropsByPrefab.TryGetValue(prefabName, out HashSet<CharacterDrop> value))
			{
				value.Remove(characterDrop);
				if (value.Count == 0)
				{
					LiveCharacterDropsByPrefab.Remove(prefabName);
				}
			}
		}

		internal static void BootstrapRegisteredCharacterDropsIfNeeded(int sceneSignature, IEnumerable<CharacterDrop> liveCharacterDrops, Func<CharacterDrop, string> getPrefabName, Func<string, bool> shouldRegisterPrefab, ISet<string>? additionalPrefabs = null, bool forceRescan = false)
		{
			if (!forceRescan && _lastBootstrappedLiveObjectsSceneSignature == sceneSignature)
			{
				return;
			}
			CleanupRegisteredCharacterDrops();
			foreach (CharacterDrop liveCharacterDrop in liveCharacterDrops)
			{
				if (!((Object)(object)liveCharacterDrop == (Object)null) && !((Object)(object)((Component)liveCharacterDrop).gameObject == (Object)null))
				{
					string text = getPrefabName(liveCharacterDrop);
					if (text.Length != 0 && (shouldRegisterPrefab(text) || (additionalPrefabs != null && additionalPrefabs.Contains(text))))
					{
						RegisterLiveCharacterDrop(liveCharacterDrop, text);
					}
				}
			}
			_lastBootstrappedLiveObjectsSceneSignature = sceneSignature;
		}

		internal static IReadOnlyList<CharacterDrop> GetRegisteredCharacterDrops(HashSet<string>? dirtyPrefabs = null)
		{
			CleanupRegisteredCharacterDrops();
			HashSet<CharacterDrop> visited = new HashSet<CharacterDrop>();
			List<CharacterDrop> list = new List<CharacterDrop>();
			if (dirtyPrefabs == null)
			{
				foreach (HashSet<CharacterDrop> value2 in LiveCharacterDropsByPrefab.Values)
				{
					AddRegisteredCharacterDrops(value2, visited, list);
				}
				return list;
			}
			foreach (string dirtyPrefab in dirtyPrefabs)
			{
				if (LiveCharacterDropsByPrefab.TryGetValue(dirtyPrefab, out HashSet<CharacterDrop> value))
				{
					AddRegisteredCharacterDrops(value, visited, list);
				}
			}
			return list;
		}

		private static void AddRegisteredCharacterDrops(IEnumerable<CharacterDrop> characterDrops, ISet<CharacterDrop> visited, ICollection<CharacterDrop> registered)
		{
			foreach (CharacterDrop item in characterDrops ?? Enumerable.Empty<CharacterDrop>())
			{
				if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null && visited.Add(item))
				{
					registered.Add(item);
				}
			}
		}

		private static void CleanupRegisteredCharacterDrops()
		{
			List<CharacterDrop> list = null;
			foreach (CharacterDrop item in LiveCharacterDropPrefabsByInstance.Keys.ToList())
			{
				if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null)
				{
					if (list == null)
					{
						list = new List<CharacterDrop>();
					}
					list.Add(item);
				}
			}
			if (list == null)
			{
				return;
			}
			foreach (CharacterDrop item2 in list)
			{
				if (LiveCharacterDropPrefabsByInstance.TryGetValue(item2, out string value))
				{
					UnregisterLiveCharacterDrop(item2, value);
				}
			}
		}

		private static void CompletePendingSnapshotBuild(PendingCharacterDropSnapshotBuildState buildState, Action<string, int, int> onCompleted)
		{
			if (_pendingSnapshotBuild == null || _pendingSnapshotBuild != buildState)
			{
				return;
			}
			Snapshots.Clear();
			Snapshots.AddRange(buildState.Snapshots);
			SnapshotsByPrefab.Clear();
			foreach (var (key, value) in buildState.SnapshotsByPrefab)
			{
				SnapshotsByPrefab[key] = value;
			}
			_lastBootstrappedLiveObjectsSceneSignature = null;
			_pendingSnapshotBuild = null;
			_lastProcessedSnapshotSignature = buildState.SnapshotSignature;
			_lastProcessedGameDataSignature = buildState.GameDataSignature;
			onCompleted(buildState.Source, buildState.GameDataSignature, buildState.SnapshotSignature);
		}
	}
	internal static class CharacterDropManager
	{
		private sealed class ResolvedConfiguredDrop
		{
			public GameObject Prefab { get; set; }

			public int Amount { get; set; }

			public bool DropInStack { get; set; }
		}

		private sealed class CharacterConfigurationState
		{
			public List<CharacterDropPrefabEntry> Configuration { get; } = new List<CharacterDropPrefabEntry>();

			public Dictionary<string, List<CharacterDropPrefabEntry>> ActiveEntriesByPrefab { get; } = new Dictionary<string, List<CharacterDropPrefabEntry>>(StringComparer.OrdinalIgnoreCase);

			public HashSet<string> PrefabsWithCharacterDropOverrides { get; } = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

			public Dictionary<string, string> CurrentEntrySignaturesByPrefab { get; set; } = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

			public string ConfigurationSignature { get; set; } = "";
		}

		private sealed class CharacterRuntimeContextSnapshot
		{
			public int Frame { get; set; }

			public int TimeOfDayPhaseMarker { get; set; }

			public string EnvironmentName { get; set; } = "";

			public Dictionary<string, bool> GlobalKeyStates { get; } = new Dictionary<string, bool>(StringComparer.Ordinal);
		}

		private sealed class CharacterApplyOperations : StandardBaselineDesiredStateOperations<CharacterDesiredState>
		{
			public static CharacterApplyOperations Instance { get; } = new CharacterApplyOperations();

			public override string DomainKey => "character";

			public override BaselineDesiredStateCapabilities Capabilities => BaselineDesiredStateCapabilities.Validation | BaselineDesiredStateCapabilities.StaticBaseline | BaselineDesiredStateCapabilities.StaticApply | BaselineDesiredStateCapabilities.LiveApply | BaselineDesiredStateCapabilities.StaticRollback;

			public override void Validate(CharacterDesiredState desiredState)
			{
				ValidateCharacterDesiredState(desiredState);
			}

			public override void RestoreStaticBaseline(CharacterDesiredState desiredState)
			{
				RestoreCharacterStaticBaseline(desiredState);
			}

			public override void ApplyDesiredStateToStaticBaseline(CharacterDesiredState desiredState)
			{
				ApplyCharacterDesiredStateToStaticBaseline(desiredState);
			}

			public override void ApplyDesiredStateToLive(CharacterDesiredState desiredState)
			{
				ApplyCharacterDesiredStateToLive(desiredState);
			}

			public override void Commit(CharacterDesiredState desiredState)
			{
				RecordAppliedState(desiredState.GameDataSignature, desiredState.DomainEnabled, desiredState.CurrentEntrySignatures, desiredState.EffectiveConfigurationSignature);
			}
		}

		private sealed class CharacterDesiredState
		{
			public StandardDomainApplyPlan ApplyPlan { get; set; }

			public CharacterCompiledState CompiledState { get; set; } = CharacterCompiledState.Empty;

			public int GameDataSignature { get; set; }

			public string EffectiveConfigurationSignature { get; set; } = "";

			public Dictionary<string, string> CurrentEntrySignatures { get; set; } = EmptyEntrySignatures;

			public bool DomainEnabled { get; set; }
		}

		private const string ReferenceAutoUpdateStateKey = "character";

		internal static readonly DomainModuleDefinition<CharacterDropPrefabEntry> Module = new DomainModuleDefinition<CharacterDropPrefabEntry>(new DomainModuleOptions<CharacterDropPrefabEntry>
		{
			DomainKey = "character",
			ReloadDomain = DropNSpawnPlugin.ReloadDomain.Character,
			ManifestSettingKey = "character_yaml",
			ManifestPriority = 99,
			ShouldReloadForPath = ShouldReloadForPath,
			Reload = ReloadConfiguration,
			InitializeRuntime = Initialize,
			OnGameDataReady = OnGameDataReady,
			HandleExpandWorldDataReady = HandleExpandWorldDataReady,
			DtoVersion = 10,
			TransportProfile = DomainTransportProfile.SmallConfig,
			DisplayName = "character",
			CacheDirectoryName = "character",
			ClientRequestPriority = 10,
			KeySelector = (CharacterDropPrefabEntry entry) => entry.RuleId,
			ApplyPayloadAction = ApplySyncedPayload,
			HasPendingSnapshotBuildWork = HasPendingSnapshotBuildWork,
			ProcessPendingSnapshotBuildStep = ProcessPendingSnapshotBuildStep,
			BeforeClientManifestChanged = MarkSyncedPayloadPending,
			OnClientAuthorityCutover = EnterPendingSyncedPayloadState
		});

		private static readonly object Sync = new object();

		private static readonly IDeserializer Deserializer = new DeserializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).Build();

		private static readonly ISerializer Serializer = new SerializerBuilder().WithNamingConvention(CamelCaseNamingConvention.Instance).ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull | DefaultValuesHandling.OmitDefaults).Build();

		private static CharacterConfigurationState RuntimeState = new CharacterConfigurationState();

		private static readonly InvalidEntryDiagnostics InvalidEntryWarnings = new InvalidEntryDiagnostics();

		private static readonly FieldInfo? DropsEnabledField = AccessTools.Field(typeof(CharacterDrop), "m_dropsEnabled");

		[ThreadStatic]
		private static CharacterDrop? OnePerPlayerScopeCharacterDrop;

		[ThreadStatic]
		private static int OnePerPlayerScopeDepth;

		private static bool _initialized;

		private static CharacterCompiledState _compiledState = CharacterCompiledState.Empty;

		private static string _compiledStateConfigurationSignature = "";

		private static int? _compiledStateGameDataSignature;

		private static bool _referenceArtifactsAutoRefreshConsumed;

		private static readonly Dictionary<string, string> _lastAppliedEntrySignaturesByPrefab = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		private static string _lastAppliedConfigurationSignature = "";

		private static int? _lastAppliedGameDataSignature;

		private static bool? _lastAppliedDomainEnabled;

		private static bool _lastAppliedSynchronizedPayloadReady;

		private static bool _synchronizedPayloadReady;

		private static int? _lastCommittedAuthorityEpoch;

		private static CharacterRuntimeContextSnapshot? _runtimeContextSnapshot;

		private static int _cachedFrameGameDataSignatureFrame = -1;

		private static int _cachedFrameGameDataSignatureValue;

		private const string MockPrefabPrefix = "JVLmock_";

		private const float ConfiguredDropGroundOffset = 0.2f;

		private const int MaxCachedRuntimeDropResolutionsPerPrefab = 32;

		private static readonly DomainConfigurationRuntime<CharacterDropPrefabEntry, CharacterConfigurationState> ConfigurationRuntime = new DomainConfigurationRuntime<CharacterDropPrefabEntry, CharacterConfigurationState>(new DomainLoadHooks<CharacterDropPrefabEntry, CharacterConfigurationState>(ParseLocalConfigurationDocuments, BuildSyncedConfigurationState, CommitSyncedConfigurationState, RejectLocalConfigurationPayload, (CharacterConfigurationState state) => state.Configuration.Count, LogPartiallyAcceptedLocalConfiguration, LogLocalConfigurationLoaded, OnSourceOfTruthPayloadUnchanged, delegate
		{
			ConfigurationDomainHost.PublishSyncedPayload(DropNSpawnPlugin.IsSourceOfTruth, Descriptor, RuntimeState.Configuration, RuntimeState.ConfigurationSignature);
		}), new DomainSyncHooks<CharacterDropPrefabEntry, CharacterConfigurationState>(delegate(out List<CharacterDropPrefabEntry> configuration, out string payloadToken)
		{
			return ConfigurationDomainHost.TryGetSyncedEntries(Descriptor, out configuration, out payloadToken);
		}, (string payloadToken) => ConfigurationDomainHost.ShouldSkipSyncedPayload(LoadState, payloadToken, Volatile.Read(in _synchronizedPayloadReady)), BuildSyncedConfigurationState, CommitSyncedConfigurationState, (CharacterConfigurationState state) => state.ActiveEntriesByPrefab.Count, "ServerSync:DropNSpawnCharacter", MarkSyncedPayloadPending, LogSyncedCharacterConfigurationLoaded, LogSyncedCharacterConfigurationFailure));

		private static readonly Dictionary<string, string> EmptyEntrySignatures = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);

		internal static DomainDescriptor<CharacterDropPrefabEntry> Descriptor => Module.DescriptorTyped;

		internal static DomainTransportMetadata<CharacterDropPrefabEntry> TransportMetadata => Module.TransportMetadataTyped;

		private static DomainLoadState LoadState => ConfigurationRuntime.LoadState;

		private static string ReferenceConfigurationPath => Path.Combine(DropNSpawnPlugin.YamlConfigDirectoryPath, PluginSettingsFacade.GetYamlDomainFilePrefix("character") + ".reference.yml");

		private static string PrimaryOverrideConfigurationPathYml => Path.Combine(DropNSpawnPlugin.YamlConfigDirectoryPath, PluginSettingsFacade.GetYamlDomainFilePrefix("character") + ".yml");

		private static string PrimaryOverrideConfigurationPathYaml => Path.Combine(DropNSpawnPlugin.YamlConfigDirectoryPath, PluginSettingsFacade.GetYamlDomainFilePrefix("character") + ".yaml");

		private static string FullScaffoldConfigurationPath => Path.Combine(DropNSpawnPlugin.YamlConfigDirectoryPath, PluginSettingsFacade.GetYamlDomainFilePrefix("character") + ".full.yml");

		internal static bool ShouldReloadForPath(string? path)
		{
			if (PluginSettingsFacade.IsEligibleOverrideConfigurationPath(path))
			{
				return IsOverrideConfigurationFileName(Path.GetFileName(path ?? ""));
			}
			return false;
		}

		private static bool ShouldApplyLocally()
		{
			return PluginSettingsFacade.IsCharacterDomainEnabled();
		}

		internal static void Initialize()
		{
			lock (Sync)
			{
				if (!_initialized)
				{
					LoadConfiguration();
					_initialized = true;
				}
			}
		}

		internal static void ReloadConfiguration()
		{
			lock (Sync)
			{
				LoadConfiguration();
				ApplyIfReady();
			}
		}

		internal static void MarkSyncedPayloadPending()
		{
			lock (Sync)
			{
				ConfigurationRuntime.MarkSyncedPayloadPending(DropNSpawnPlugin.IsSourceOfTruth, delegate
				{
					Volatile.Write(ref _synchronizedPayloadReady, value: false);
				});
			}
		}

		internal static void EnterPendingSyncedPayloadState()
		{
			lock (Sync)
			{
				Dictionary<string, string> previousEntrySignatures = CloneCurrentEntrySignaturesByPrefab();
				HashSet<string> previouslyAppliedPrefabs = BuildLastAppliedPrefabs();
				ConfigurationRuntime.EnterPendingSyncedPayloadState(DropNSpawnPlugin.IsSourceOfTruth, ResetLoadedConfigurationState, delegate
				{
					RuntimeState.ConfigurationSignature = "";
					_lastAppliedSynchronizedPayloadReady = false;
					RestoreSnapshots(previouslyAppliedPrefabs);
					RestoreTrackedCharacterDrops(previouslyAppliedPrefabs);
					RefreshVneiCompatibility(previousEntrySignatures);
				});
			}
		}

		private static bool CanUseCurrentRuntimeState()
		{
			if (!DropNSpawnPlugin.IsSourceOfTruth && !Volatile.Read(in _synchronizedPayloadReady))
			{
				return _lastCommittedAuthorityEpoch == NetworkPayloadSyncSupport.CurrentAuthorityEpoch;
			}
			return true;
		}

		private static HashSet<string> BuildLastAppliedPrefabs()
		{
			HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			if (_lastAppliedDomainEnabled != true)
			{
				return hashSet;
			}
			foreach (string key in _lastAppliedEntrySignaturesByPrefab.Keys)
			{
				hashSet.Add(key);
			}
			return hashSet;
		}

		internal static bool HandleExpandWorldDataReady()
		{
			lock (Sync)
			{
				if (!DropNSpawnPlugin.IsSourceOfTruth)
				{
					return false;
				}
				string text = NetworkPayloadSyncSupport.ComputeCharacterConfigurationSignature(RuntimeState.Configuration);
				if (string.Equals(text, RuntimeState.ConfigurationSignature, StringComparison.Ordinal))
				{
					return false;
				}
				RuntimeState.ConfigurationSignature = text;
				ConfigurationDomainHost.PublishSyncedPayload(DropNSpawnPlugin.IsSourceOfTruth, Descriptor, RuntimeState.Configuration, RuntimeState.ConfigurationSignature);
				ApplyIfReady();
				return true;
			}
		}

		internal static void ApplySyncedPayload()
		{
			lock (Sync)
			{
				Dictionary<string, string> previousEntrySignatures = CloneCurrentEntrySignaturesByPrefab();
				ConfigurationRuntime.ApplySyncedPayload(delegate
				{
					RefreshVneiCompatibility(previousEntrySignatures, CloneCurrentEntrySignaturesByPrefab());
					ApplyIfReady();
				});
			}
		}

		internal static void OnGameDataReady(string source)
		{
			lock (Sync)
			{
				if (!_initialized)
				{
					Initialize();
				}
				if (!IsGameDataReady())
				{
					return;
				}
				int gameDataSignature = ComputeGameDataSignature();
				if (!CharacterDropRuntime.IsGameDataAlreadyProcessed(gameDataSignature))
				{
					int snapshotSignature = ComputeSnapshotSignature();
					if (CharacterDropRuntime.NeedsSnapshotBuild(snapshotSignature))
					{
						CharacterDropRuntime.ScheduleSnapshotBuild(source, gameDataSignature, snapshotSignature, EnumerateRelevantPrefabs());
					}
					else
					{
						CompleteGameDataReadyLocked(source, gameDataSignature, snapshotSignature);
					}
				}
			}
		}

		internal static bool HasPendingSnapshotBuildWork()
		{
			lock (Sync)
			{
				return CharacterDropRuntime.HasPendingSnapshotBuildWork();
			}
		}

		internal static bool ProcessPendingSnapshotBuildStep(double deadline)
		{
			lock (Sync)
			{
				return CharacterDropRuntime.ProcessPendingSnapshotBuildStep(deadline, CaptureSnapshot, CompleteGameDataReadyLocked);
			}
		}

		private static bool IsGameDataReady()
		{
			if ((Object)(object)ZNetScene.instance != (Object)null)
			{
				return (Object)(object)ObjectDB.instance != (Object)null;
			}
			return false;
		}

		private static bool EnsurePrimaryOverrideConfigurationFileExists()
		{
			if (DomainConfigurationFileSupport.HasAnyOverrideConfigurationFile("character", PrimaryOverrideConfigurationPathYml, PrimaryOverrideConfigurationPathYaml))
			{
				return false;
			}
			if (!IsGameDataReady() || !CharacterDropRuntime.HasSnapshots())
			{
				return false;
			}
			GeneratedArtifactWriter.WriteTextAlways(PrimaryOverrideConfigurationPathYml, BuildPrimaryOverrideConfigurationTemplate(), "Created character override configuration at " + PrimaryOverrideConfigurationPathYml + ".");
			return true;
		}

		private static void LoadConfiguration()
		{
			Dictionary<string, string> previousEntrySignatures = CloneCurrentEntrySignaturesByPrefab();
			if (DropNSpawnPlugin.IsSourceOfTruth)
			{
				EnsurePrimaryOverrideConfigurationFileExists();
				if (ConfigurationRuntime.ReloadSourceOfTruth(EnumerateOverrideConfigurationPaths().ToList()) == DomainReloadOutcome.Loaded)
				{
					RefreshVneiCompatibility(previousEntrySignatures);
				}
			}
			else if (ConfigurationRuntime.ReloadSynced() == DomainReloadOutcome.Loaded)
			{
				RefreshVneiCompatibility(previousEntrySignatures, CloneCurrentEntrySignaturesByPrefab());
			}
		}

		private static void CompleteGameDataReadyLocked(string source, int gameDataSignature, int snapshotSignature)
		{
			if (DropNSpawnPlugin.IsSourceOfTruth && !_referenceArtifactsAutoRefreshConsumed)
			{
				EnsureReferenceArtifactsUpToDate();
				_referenceArtifactsAutoRefreshConsumed = true;
			}
			if (DropNSpawnPlugin.IsSourceOfTruth && EnsurePrimaryOverrideConfigurationFileExists())
			{
				LoadConfiguration();
			}
			ApplyIfReady();
		}

		private static void ResetLoadedConfigurationState()
		{
			RuntimeState = new CharacterConfigurationState();
			InvalidEntryWarnings.Clear();
			_compiledState = CharacterCompiledState.Empty;
			_compiledStateConfigurationSignature = "";
			_compiledStateGameDataSignature = null;
			_cachedFrameGameDataSignatureFrame = -1;
			_cachedFrameGameDataSignatureValue = 0;
			Volatile.Write(ref _synchronizedPayloadReady, value: false);
		}

		internal static void ResetWorldRuntimeState()
		{
			lock (Sync)
			{
				HashSet<string> hashSet = BuildLastAppliedPrefabs();
				RestoreSnapshots(hashSet);
				RestoreTrackedCharacterDrops(hashSet);
				CharacterDropRuntime.Reset();
				_compiledState = CharacterCompiledState.Empty;
				_compiledStateConfigurationSignature = "";
				_compiledStateGameDataSignature = null;
				_lastAppliedEntrySignaturesByPrefab.Clear();
				_lastAppliedConfigurationSignature = "";
				_lastAppliedGameDataSignature = null;
				_lastAppliedDomainEnabled = null;
				_lastAppliedSynchronizedPayloadReady = false;
				_runtimeContextSnapshot = null;
				_cachedFrameGameDataSignatureFrame = -1;
				_cachedFrameGameDataSignatureValue = 0;
				OnePerPlayerScopeCharacterDrop = null;
				OnePerPlayerScopeDepth = 0;
			}
		}

		private static List<CharacterDropPrefabEntry> CloneAndNormalizeConfigurationEntries(List<CharacterDropPrefabEntry>? configuration, string sourceName)
		{
			List<CharacterDropPrefabEntry> list = NetworkPayloadSyncSupport.CloneEntries(Descriptor, configuration);
			foreach (CharacterDropPrefabEntry item in list)
			{
				NormalizeEntry(item);
				item.SourcePath = (string.IsNullOrWhiteSpace(item.SourcePath) ? sourceName : item.SourcePath);
			}
			return list;
		}

		private static List<CharacterDropPrefabEntry> PrepareLocalConfigurationEntries(List<CharacterDropPrefabEntry>? configuration, string sourceName, List<string> warnings)
		{
			List<CharacterDropPrefabEntry> list = CloneAndNormalizeConfigurationEntries(configuration, sourceName);
			List<CharacterDropPrefabEntry> list2 = new List<CharacterDropPrefabEntry>();
			foreach (CharacterDropPrefabEntry item in list)
			{
				if (TryAcceptLocalConfigurationEntry(item, warnings))
				{
					list2.Add(item);
				}
			}
			return list2;
		}

		private static bool TryAcceptLocalConfigurationEntry(CharacterDropPrefabEntry entry, List<string> warnings)
		{
			if (!entry.Enabled)
			{
				return true;
			}
			string text = CreateConfigurationContext(entry);
			bool flag = entry.CharacterDrop != null;
			if (string.IsNullOrWhiteSpace(entry.Prefab))
			{
				warnings.Add("Entry '" + text + "' is missing required prefab.");
				return false;
			}
			if (!flag)
			{
				warnings.Add("Entry '" + text + "' does not define characterDrop.");
				return false;
			}
			if (!TryResolveConfiguredCharacterPrefab(entry.Prefab, out var hasCharacterComponent, out var hasCharacterDropComponent))
			{
				warnings.Add("Entry '" + text + "' references unknown character prefab '" + entry.Prefab + "'.");
				return false;
			}
			if (!hasCharacterComponent)
			{
				warnings.Add("Entry '" + text + "' references '" + entry.Prefab + "', but it is not a Character prefab.");
				return false;
			}
			if (flag && !hasCharacterDropComponent)
			{
				warnings.Add("Entry '" + text + "' references '" + entry.Prefab + "', but it is not a CharacterDrop prefab.");
				return false;
			}
			return true;
		}

		private static bool TryResolveConfiguredCharacterPrefab(string prefabName, out bool hasCharacterComponent, out bool hasCharacterDropComponent)
		{
			hasCharacterComponent = true;
			hasCharacterDropComponent = true;
			if ((Object)(object)ZNetScene.instance == (Object)null || string.IsNullOrWhiteSpace(prefabName))
			{
				return true;
			}
			GameObject prefab = ZNetScene.instance.GetPrefab(prefabName.Trim());
			if ((Object)(object)prefab == (Object)null)
			{
				hasCharacterComponent = false;
				hasCharacterDropComponent = false;
				return false;
			}
			hasCharacterComponent = (Object)(object)prefab.GetComponent<Character>() != (Object)null;
			hasCharacterDropComponent = (Object)(object)prefab.GetComponent<CharacterDrop>() != (Object)null;
			return true;
		}

		private static CharacterConfigurationState BuildSyncedConfigurationState(List<CharacterDropPrefabEntry> configuration, string sourceName)
		{
			using (BeginInvalidEntryWarningSuppressionForSyncedClientBuild(sourceName))
			{
				CharacterConfigurationState characterConfigurationState = new CharacterConfigurationState();
				foreach (CharacterDropPrefabEntry item in CloneAndNormalizeConfigurationEntries(configuration, sourceName))
				{
					if (!string.IsNullOrWhiteSpace(item.Prefab))
					{
						RemoveEffectiveConfigurationEntry(characterConfigurationState.Configuration, characterConfigurationState.ActiveEntriesByPrefab, item.Prefab, item.RuleId);
						if (item.Enabled)
						{
							characterConfigurationState.Configuration.Add(item);
							GetOrCreateActiveEntries(characterConfigurationState.ActiveEntriesByPrefab, item.Prefab).Add(item);
						}
					}
				}
				RebuildCharacterDropOverridePrefabSet(characterConfigurationState.ActiveEntriesByPrefab, characterConfigurationState.PrefabsWithCharacterDropOverrides);
				characterConfigurationState.ConfigurationSignature = NetworkPayloadSyncSupport.ComputeCharacterConfigurationSignature(characterConfigurationState.Configuration);
				characterConfigurationState.CurrentEntrySignaturesByPrefab = BuildActiveEntrySignaturesByPrefab(characterConfigurationState.ActiveEntriesByPrefab);
				return characterConfigurationState;
			}
		}

		private static void CommitSyncedConfigurationState(CharacterConfigurationState state, string payloadToken)
		{
			ResetLoadedConfigurationState();
			RuntimeState = state;
			LoadState.LastLoadedPayload = payloadToken;
			LoadState.LastRejectedPayload = "";
			LoadState.PendingStrictPayload = "";
			LoadState.LastRejectedValidationKey = "";
			Volatile.Write(ref _synchronizedPayloadReady, value: true);
			_lastCommittedAuthorityEpoch = (DropNSpawnPlugin.IsSourceOfTruth ? ((int?)null) : new int?(NetworkPayloadSyncSupport.CurrentAuthorityEpoch));
		}

		private static LocalLoadResult<CharacterDropPrefabEntry> ParseLocalConfigurationDocuments(List<ConfigurationLoadSupport.LocalYamlDocument> documents)
		{
			return ConfigurationLoadSupport.ParseLocalConfigurationDocuments(documents, ParseConfiguration, PrepareLocalConfigurationEntries, FormatYamlExceptionLocation, "Character override YAML must start with a root list like '- prefab: ...'.");
		}

		private static void RejectLocalConfigurationPayload(string payload, IEnumerable<string> errors)
		{
			ConfigurationDomainHost.RejectLocalConfigurationPayload(LoadState, payload, errors, "character");
		}

		private static void RebuildCharacterDropOverridePrefabSet(Dictionary<string, List<CharacterDropPrefabEntry>> activeEntriesByPrefab, HashSet<string> target)
		{
			target.Clear();
			foreach (var (item, source) in activeEntriesByPrefab)
			{
				if (source.Any((CharacterDropPrefabEntry entry) => entry.CharacterDrop != null))
				{
					target.Add(item);
				}
			}
		}

		private static bool RemoveEffectiveConfigurationEntry(List<CharacterDropPrefabEntry> configuration, Dictionary<string, List<CharacterDropPrefabEntry>> activeEntriesByPrefab, string prefabName, string ruleId)
		{
			bool result = false;
			for (int num = configuration.Count - 1; num >= 0; num--)
			{
				CharacterDropPrefabEntry characterDropPrefabEntry = configuration[num];
				if (string.Equals(characterDropPrefabEntry.Prefab, prefabName, StringComparison.OrdinalIgnoreCase) && string.Equals(characterDropPrefabEntry.RuleId, ruleId, StringComparison.Ordinal))
				{
					configuration.RemoveAt(num);
					result = true;
				}
			}
			if (activeEntriesByPrefab.TryGetValue(prefabName, out List<CharacterDropPrefabEntry> value))
			{
				for (int num2 = value.Count - 1; num2 >= 0; num2--)
				{
					if (string.Equals(value[num2].RuleId, ruleId, StringComparison.Ordinal))
					{
						value.RemoveAt(num2);
						result = true;
					}
				}
				if (value.Count == 0)
				{
					activeEntriesByPrefab.Remove(prefabName);
				}
			}
			return result;
		}

		private static ConfigurationLoadSupport.ParsedLocalConfiguration<CharacterDropPrefabEntry> ParseConfiguration(string yaml, string? sourcePath)
		{
			ConfigurationLoadSupport.ParsedLocalConfiguration<CharacterDropPrefabEntry> parsedLocalConfiguration = new ConfigurationLoadSupport.ParsedLocalConfiguration<CharacterDropPrefabEntry>();
			if (string.IsNullOrWhiteSpace(yaml))
			{
				return parsedLocalConfiguration;
			}
			checked
			{
				using StringReader input = new StringReader(yaml);
				YamlStream yamlStream = new YamlStream();
				yamlStream.Load(input);
				if (yamlStream.Documents.Count == 0)
				{
					return parsedLocalConfiguration;
				}
				foreach (YamlNode child in ((yamlStream.Documents[0].RootNode as YamlSequenceNode) ?? throw new YamlException(yamlStream.Documents[0].RootNode.Start, yamlStream.Documents[0].RootNode.End, "Character override YAML root must be a sequence.")).Children)
				{
					if (!(child is YamlMappingNode yamlMappingNode))
					{
						parsedLocalConfiguration.Warnings.Add("Skipped character YAML node at " + FormatYamlNodeLocation(sourcePath, child.Start) + ". Expected a list item object like '- prefab: Fox' but found " + DescribeYamlNode(child) + ".");
						continue;
					}
					try
					{
						string input2 = SerializeYamlNode(yamlMappingNode);
						CharacterDropPrefabEntry characterDropPrefabEntry = Deserializer.Deserialize<CharacterDropPrefabEntry>(input2) ?? new CharacterDropPrefabEntry();
						characterDropPrefabEntry.SourceLine = (int)yamlMappingNode.Start.Line;
						characterDropPrefabEntry.SourceColumn = (int)yamlMappingNode.Start.Column;
						parsedLocalConfiguration.Configuration.Add(characterDropPrefabEntry);
					}
					catch (Exception ex)
					{
						parsedLocalConfiguration.Warnings.Add("Skipped invalid character entry at " + FormatYamlNodeLocation(sourcePath, yamlMappingNode.Start) + ". " + FormatEntryParseFailure(ex));
					}
				}
				return parsedLocalConfiguration;
			}
		}

		private static string SerializeYamlNode(YamlNode node)
		{
			YamlStream yamlStream = new YamlStream(new YamlDocument(node));
			using StringWriter stringWriter = new StringWriter(CultureInfo.InvariantCulture);
			yamlStream.Save(stringWriter, assignAnchors: false);
			return stringWriter.ToString();
		}

		private static string DescribeYamlNode(YamlNode node)
		{
			if (node is YamlScalarNode yamlScalarNode)
			{
				string text = yamlScalarNode.Value ?? "";
				if (text.Length != 0)
				{
					return "scalar '" + text + "'";
				}
				return "an empty scalar";
			}
			if (node is YamlSequenceNode)
			{
				return "a nested sequence";
			}
			if (node is YamlMappingNode)
			{
				return "a mapping";
			}
			return "an unknown YAML node";
		}

		private static string FormatYamlNodeLocation(string? sourcePath, Mark mark)
		{
			string text = (string.IsNullOrWhiteSpace(sourcePath) ? "inline YAML" : Path.GetFileName(sourcePath));
			if (mark.Line > 0)
			{
				text = text + ":" + mark.Line.ToString(CultureInfo.InvariantCulture);
			}
			return text;
		}

		private static string FormatEntryParseFailure(Exception ex)
		{
			if (ex is YamlException ex2)
			{
				return ex2.Message;
			}
			return ex.Message;
		}

		private static void NormalizeEntry(CharacterDropPrefabEntry entry)
		{
			entry.Prefab = (entry.Prefab ?? "").Trim();
			if (entry.CharacterDrop != null)
			{
				CharacterDropDefinition characterDrop = entry.CharacterDrop;
				if (characterDrop.Drops == null)
				{
					List<CharacterDropEntryDefinition> list = (characterDrop.Drops = new List<CharacterDropEntryDefinition>());
				}
				foreach (CharacterDropEntryDefinition drop in entry.CharacterDrop.Drops)
				{
					drop.Item = (drop.Item ?? "").Trim();
					IntRangeDefinition? amount = drop.Amount;
					if (amount != null && amount.HasValues())
					{
						drop.AmountMin = RangeFormatting.GetMin(drop.Amount, drop.AmountMin);
						drop.AmountMax = RangeFormatting.GetMax(drop.Amount, drop.AmountMin, drop.AmountMax);
					}
				}
			}
			entry.RuleId = NormalizeOptionalRuleId(entry.RuleId) ?? BuildRuleId(entry);
		}

		private static string BuildRuleId(CharacterDropPrefabEntry entry)
		{
			CharacterDropPrefabEntry entry2 = new CharacterDropPrefabEntry
			{
				Prefab = entry.Prefab,
				Enabled = true,
				Conditions = entry.Conditions,
				CharacterDrop = entry.CharacterDrop
			};
			return entry.Prefab + ":" + NetworkPayloadSyncSupport.ComputeCharacterEntryIdentitySignature(entry2);
		}

		private static string? NormalizeOptionalRuleId(string? ruleId)
		{
			if (ruleId == null)
			{
				return null;
			}
			string text = ruleId.Trim();
			if (text.Length != 0)
			{
				return text;
			}
			return null;
		}

		private static bool HasCustomDropHandling(IReadOnlyList<CompiledCharacterDropDefinition>? drops)
		{
			return drops?.Any((CompiledCharacterDropDefinition drop) => (drop.AmountLimit.HasValue && drop.AmountLimit.Value >= 0) || drop.DropInStack) ?? false;
		}

		internal static void ApplyGlobalDropInStack(ref List<KeyValuePair<GameObject, int>> drops, Vector3 centerPos, float dropArea)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (!PluginSettingsFacade.IsGlobalCharacterDropInStackEnabled() || drops.Count == 0)
			{
				return;
			}
			List<KeyValuePair<GameObject, int>> list = new List<KeyValuePair<GameObject, int>>(drops.Count);
			bool flag = false;
			foreach (KeyValuePair<GameObject, int> drop in drops)
			{
				if (!ShouldDropInStack(drop.Key, drop.Value, explicitDropInStack: false))
				{
					list.Add(drop);
					continue;
				}
				SpawnStackedDrops(drop.Key, drop.Value, centerPos, dropArea);
				flag = true;
			}
			if (flag)
			{
				drops = list;
			}
		}

		internal static bool IsGlobalCharacterLootLevelScalingEnabled()
		{
			if (PluginSettingsFacade.ShouldDisableCharacterLootScalingForCreatureLevelControl())
			{
				return false;
			}
			if (!PluginSettingsFacade.IsCharacterDropCalculateChanceLootSystemEnabled())
			{
				return PluginSettingsFacade.IsGlobalCharacterDropTrophyLevelMultiplierEnabled();
			}
			return true;
		}

		internal static List<Drop>? SuppressGlobalCharacterLootLevelMultiplierDrops(CharacterDrop characterDrop, out IReadOnlyList<Drop>? sourceDrops)
		{
			sourceDrops = null;
			if (!IsGlobalCharacterLootLevelScalingEnabled() || (Object)(object)characterDrop == (Object)null || characterDrop.m_drops == null || characterDrop.m_drops.Count == 0)
			{
				return null;
			}
			List<Drop> list = (List<Drop>)(sourceDrops = characterDrop.m_drops);
			List<Drop> list2 = null;
			for (int