Decompiled source of HookDOTS API v1.0.0

HookDOTS.API.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using HookDOTS;
using HookDOTS.API.Attributes;
using HookDOTS.API.Spec.Language;
using HookDOTS.HookRegistration;
using HookDOTS.Hooks;
using HookDOTS.Patches;
using HookDOTS.Utilities;
using Il2CppInterop.Runtime;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Unity.Entities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("Nicholas Toby")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyCopyright("Copyright (c) Nicholas Toby 2025")]
[assembly: AssemblyDescription("BepInEx plugin providing an API to hook Unity DOTS systems, for il2cpp builds")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+fdbd63077a834d9666bad5a36c008b1d62d19d31")]
[assembly: AssemblyProduct("HookDOTS.API")]
[assembly: AssemblyTitle("HookDOTS.API")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/cheesasaurus/HookDOTS")]
[assembly: AssemblyMetadata("Reloadable", "True")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

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

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ExamplePlugin.Patches
{
	[HarmonyPatch]
	internal class WorldReadinessPatches
	{
		[HarmonyPatch(typeof(ScriptBehaviourUpdateOrder), "AppendWorldToCurrentPlayerLoop")]
		[HarmonyPostfix]
		private static void WorldAppendedToCurrentPlayerLoop(World world)
		{
			Bus.Instance.TriggerEventWorldsMayHaveChanged();
		}

		[HarmonyPatch(typeof(ScriptBehaviourUpdateOrder), "AppendWorldToPlayerLoop")]
		[HarmonyPostfix]
		private static void WorldAppendedToSpecificPlayerLoop(World world)
		{
			Bus.Instance.TriggerEventWorldsMayHaveChanged();
		}
	}
}
namespace HookDOTS
{
	public class Bus
	{
		public static readonly Bus Instance = new Bus();

		public event Action EventGameReadyForHooking;

		public event Action EventWorldsMayHaveChanged;

		public event Action CommandRunHooks_WorldsCreated;

		public void TriggerEventGameReadyForHooking()
		{
			this.EventGameReadyForHooking?.Invoke();
		}

		public void TriggerEventWorldsMayHaveChanged()
		{
			this.EventWorldsMayHaveChanged?.Invoke();
		}

		public void TriggerCommandRunHooks_WorldsCreated()
		{
			this.CommandRunHooks_WorldsCreated?.Invoke();
		}
	}
	internal static class HookManager
	{
		private static Bus _bus = Bus.Instance;

		private static bool _initialized = false;

		private static bool _isGameReadyForRegistration = false;

		private static HookRegistry _hookRegistry;

		private static Executor_System_OnUpdate _executor_System_OnUpdate;

		private static Executor_WhenCreatedWorldsContain _executor_WhenCreatedWorldsContain;

		internal static void Initialize()
		{
			if (!_initialized)
			{
				_hookRegistry = new HookRegistry();
				_executor_System_OnUpdate = new Executor_System_OnUpdate(_hookRegistry.SubRegistry_System_OnUpdate_Prefix, _hookRegistry.SubRegistry_System_OnUpdate_Postfix);
				_executor_WhenCreatedWorldsContain = new Executor_WhenCreatedWorldsContain(_hookRegistry.SubRegistry_WhenCreatedWorldsContainAny, _hookRegistry.SubRegistry_WhenCreatedWorldsContainAll, new WorldWatcher());
				_bus.EventGameReadyForHooking += HandleGameReadyForRegistration;
				_bus.EventWorldsMayHaveChanged += HandleWorldsMayHaveChanged;
				_bus.CommandRunHooks_WorldsCreated += HandlerCommandRunHooks_WorldsCreated;
				_initialized = true;
			}
		}

		internal static void UnInitialize()
		{
			if (_initialized)
			{
				_bus.EventGameReadyForHooking -= HandleGameReadyForRegistration;
				_bus.EventWorldsMayHaveChanged -= HandleWorldsMayHaveChanged;
				_bus.CommandRunHooks_WorldsCreated -= HandlerCommandRunHooks_WorldsCreated;
				_hookRegistry = null;
				_executor_System_OnUpdate = null;
				_executor_WhenCreatedWorldsContain = null;
				_isGameReadyForRegistration = false;
				_initialized = false;
			}
		}

		private static void HandleGameReadyForRegistration()
		{
			_isGameReadyForRegistration = true;
		}

		internal unsafe static void HandleSystemUpdatePrefix(SystemState* systemState)
		{
			_executor_System_OnUpdate.ExecutePrefixHooks(systemState);
		}

		internal unsafe static void HandleSystemUpdatePostfix(SystemState* systemState)
		{
			_executor_System_OnUpdate.ExecutePostfixHooks(systemState);
		}

		internal static void HandleWorldsMayHaveChanged()
		{
			_executor_WhenCreatedWorldsContain.ExecuteAndRemoveHooks();
		}

		internal static void HandlerCommandRunHooks_WorldsCreated()
		{
			_executor_WhenCreatedWorldsContain.ExecuteAndRemoveHooks();
		}

		internal static HookRegistrar NewHookRegistrar(string id, ManualLogSource log)
		{
			HookRegistryStaging hookRegistryStaging = new HookRegistryStaging(id, _hookRegistry, _bus, _isGameReadyForRegistration, log);
			return new HookRegistrar(id, hookRegistryStaging, log);
		}
	}
	public class Throttle
	{
		private TimeSpan _interval;

		private DateTime _blockUntilTime = DateTime.MinValue;

		public Throttle(TimeSpan interval)
		{
			_interval = interval;
		}

		public Throttle(int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0)
		{
			_interval = new TimeSpan(days, hours, minutes, seconds, milliseconds);
		}

		public bool CheckAndTrigger()
		{
			if (DateTime.Now < _blockUntilTime)
			{
				return true;
			}
			_blockUntilTime = DateTime.Now.Add(_interval);
			return false;
		}
	}
	internal interface IWorldWatcher
	{
		void Update();

		bool AreAllWorldsCreated(ISet<string> worldNames);

		bool AreAnyWorldsCreated(ISet<string> worldNames);

		IEnumerable<World> GetMatchingWorldsCreated(ISet<string> worldNames);
	}
	internal class WorldWatcher : IWorldWatcher
	{
		private HashSet<string> _createdWorldNames = new HashSet<string>();

		private Dictionary<string, World> _createdWorlds = new Dictionary<string, World>();

		public void Update()
		{
			Enumerator<World> enumerator = World.All.GetEnumerator();
			while (enumerator.MoveNext())
			{
				World current = enumerator.Current;
				if (current.IsCreated)
				{
					_createdWorldNames.Add(current.Name);
					_createdWorlds.TryAdd(current.Name, current);
				}
			}
		}

		public bool AreAllWorldsCreated(ISet<string> worldNames)
		{
			return _createdWorldNames.IsSupersetOf(worldNames);
		}

		public bool AreAnyWorldsCreated(ISet<string> worldNames)
		{
			return _createdWorldNames.Overlaps(worldNames);
		}

		public IEnumerable<World> GetMatchingWorldsCreated(ISet<string> worldNames)
		{
			return from worldName in worldNames.Where(_createdWorlds.ContainsKey)
				select _createdWorlds[worldName];
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "HookDOTS.API";

		public const string PLUGIN_NAME = "HookDOTS.API";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace HookDOTS.Utilities
{
	internal static class LogUtil
	{
		public static ManualLogSource Logger;

		public static void Init(ManualLogSource logger)
		{
			Logger = logger;
		}

		public static void LogMessage(object data)
		{
			Logger.LogMessage(data);
		}

		public static void LogInfo(object data)
		{
			Logger.LogInfo(data);
		}

		public static void LogDebug(object data)
		{
			Logger.LogDebug(data);
		}

		public static void LogWarning(object data)
		{
			Logger.LogWarning(data);
		}

		public static void LogError(object data)
		{
			Logger.LogError(data);
		}
	}
	internal static class StringUtil
	{
		public static string StringifyEnumerableOfStrings(IEnumerable<string> strings)
		{
			IEnumerable<string> values = strings.Select((string str) => "\"" + str + "\"");
			return string.Join(", ", values);
		}
	}
}
namespace HookDOTS.Patches
{
	[HarmonyPatch]
	internal class PerformanceRecorderSystemPatch
	{
		private static bool _initialized;

		private static bool _wasStaticRecordingEnabled;

		internal static void UnInitialize()
		{
			if (_initialized)
			{
				PerformanceRecorderSystem.StaticRecordingEnabled = _wasStaticRecordingEnabled;
				_wasStaticRecordingEnabled = false;
				_initialized = false;
			}
		}

		[HarmonyPatch(typeof(PerformanceRecorderSystem), "OnUpdate")]
		[HarmonyPrefix]
		internal static bool PerformanceRecorderSystem_OnUpdate_Prefix(PerformanceRecorderSystem __instance)
		{
			if (_initialized)
			{
				return _wasStaticRecordingEnabled;
			}
			_wasStaticRecordingEnabled = PerformanceRecorderSystem.StaticRecordingEnabled;
			PerformanceRecorderSystem.StaticRecordingEnabled = true;
			_initialized = true;
			return _wasStaticRecordingEnabled;
		}

		[HarmonyPatch(typeof(PerformanceRecorderSystem), "StartSystem")]
		[HarmonyPrefix]
		internal unsafe static void PerformanceRecorderSystem_StartSystem_Prefix(SystemState* systemState)
		{
			HookManager.HandleSystemUpdatePrefix(systemState);
		}

		[HarmonyPatch(typeof(PerformanceRecorderSystem), "EndSystem")]
		[HarmonyPostfix]
		internal unsafe static void PerformanceRecorderSystem_EndSystem_Postfix(SystemState* systemState)
		{
			HookManager.HandleSystemUpdatePostfix(systemState);
		}
	}
}
namespace HookDOTS.Hooks
{
	public static class System_OnUpdate_Postfix
	{
		public unsafe delegate void HookFunction(SystemState* systemState);

		public delegate void HookFunctionVariant1();

		public class Hook
		{
			public HookFunction Func { get; }

			public MethodInfo UnwrappedMethodInfo { get; }

			public Hook(HookFunction func, MethodInfo unwrappedMethodInfo)
			{
				Func = func;
				UnwrappedMethodInfo = unwrappedMethodInfo;
				base..ctor();
			}

			public unsafe void Invoke(SystemState* systemState)
			{
				Func(systemState);
			}

			public string FullName()
			{
				string text = UnwrappedMethodInfo?.DeclaringType?.FullName;
				string text2 = UnwrappedMethodInfo?.Name;
				return text + "." + text2;
			}
		}

		public class Options
		{
			public bool OnlyWhenSystemRuns;

			public Throttle? Throttle;

			public static Options Default => new Options();

			public Options(bool onlyWhenSystemRuns = true, Throttle? throttle = null)
			{
				OnlyWhenSystemRuns = onlyWhenSystemRuns;
				Throttle = throttle;
				base..ctor();
			}
		}

		internal static class HookFunctionAdapter
		{
			public unsafe static HookFunction Adapt(MethodInfo methodInfo)
			{
				dynamic val = null;
				int num = methodInfo.GetParameters().Length;
				Type type = methodInfo.GetParameters().ElementAtOrDefault(0)?.ParameterType;
				if (num <= 1 && methodInfo.ReturnType == typeof(void))
				{
					if (type == typeof(SystemState*))
					{
						val = methodInfo.CreateDelegate<HookFunction>();
					}
					else if (type == null)
					{
						val = methodInfo.CreateDelegate<HookFunctionVariant1>();
					}
				}
				if (val == null)
				{
					throw new Exception("Invalid hook format on " + methodInfo.DeclaringType?.FullName + "." + methodInfo.Name);
				}
				return HookFunctionAdapter.Adapt(val);
			}

			internal static HookFunction Adapt(HookFunction suppliedHook)
			{
				return suppliedHook;
			}

			internal static HookFunction Adapt(HookFunctionVariant1 suppliedHook)
			{
				HookFunctionVariant1 suppliedHook2 = suppliedHook;
				return delegate
				{
					suppliedHook2();
				};
			}
		}

		public static Hook CreateHook(MethodInfo methodInfo)
		{
			HookFunction func = HookFunctionAdapter.Adapt(methodInfo);
			return new Hook(func, methodInfo);
		}

		public static Hook CreateHook(HookFunction hookFunc)
		{
			return new Hook(hookFunc, hookFunc.Method);
		}

		public static Hook CreateHook(HookFunctionVariant1 hookFunc)
		{
			HookFunction func = HookFunctionAdapter.Adapt(hookFunc);
			return new Hook(func, hookFunc.Method);
		}
	}
	public static class System_OnUpdate_Prefix
	{
		public unsafe delegate bool HookFunction(SystemState* systemState);

		public delegate bool HookFunctionVariant1();

		public unsafe delegate void HookFunctionVariant2(SystemState* systemState);

		public delegate void HookFunctionVariant3();

		public class Hook
		{
			public HookFunction Func { get; }

			public MethodInfo UnwrappedMethodInfo { get; }

			public Hook(HookFunction func, MethodInfo unwrappedMethodInfo)
			{
				Func = func;
				UnwrappedMethodInfo = unwrappedMethodInfo;
				base..ctor();
			}

			public unsafe bool Invoke(SystemState* systemState)
			{
				return Func(systemState);
			}

			public string FullName()
			{
				string text = UnwrappedMethodInfo?.DeclaringType?.FullName;
				string text2 = UnwrappedMethodInfo?.Name;
				return text + "." + text2;
			}
		}

		public class Options
		{
			public bool OnlyWhenSystemRuns;

			public Throttle? Throttle;

			public static Options Default => new Options();

			public Options(bool onlyWhenSystemRuns = true, Throttle? throttle = null)
			{
				OnlyWhenSystemRuns = onlyWhenSystemRuns;
				Throttle = throttle;
				base..ctor();
			}
		}

		internal static class HookFunctionAdapter
		{
			public unsafe static HookFunction Adapt(MethodInfo methodInfo)
			{
				dynamic val = null;
				int num = methodInfo.GetParameters().Length;
				Type type = methodInfo.GetParameters().ElementAtOrDefault(0)?.ParameterType;
				if (num <= 1)
				{
					if (methodInfo.ReturnType == typeof(bool))
					{
						if (type == typeof(SystemState*))
						{
							val = methodInfo.CreateDelegate<HookFunction>();
						}
						else if (type == null)
						{
							val = methodInfo.CreateDelegate<HookFunctionVariant1>();
						}
					}
					else if (methodInfo.ReturnType == typeof(void))
					{
						if (type == typeof(SystemState*))
						{
							val = methodInfo.CreateDelegate<HookFunctionVariant2>();
						}
						else if (type == null)
						{
							val = methodInfo.CreateDelegate<HookFunctionVariant3>();
						}
					}
				}
				if (val == null)
				{
					throw new Exception("Invalid hook format on " + methodInfo.DeclaringType?.FullName + "." + methodInfo.Name);
				}
				return HookFunctionAdapter.Adapt(val);
			}

			internal static HookFunction Adapt(HookFunction suppliedHook)
			{
				return suppliedHook;
			}

			internal unsafe static HookFunction Adapt(HookFunctionVariant1 suppliedHook)
			{
				HookFunctionVariant1 suppliedHook2 = suppliedHook;
				return (SystemState* systemState) => suppliedHook2();
			}

			internal unsafe static HookFunction Adapt(HookFunctionVariant2 suppliedHook)
			{
				HookFunctionVariant2 suppliedHook2 = suppliedHook;
				return delegate(SystemState* systemState)
				{
					suppliedHook2(systemState);
					return true;
				};
			}

			internal static HookFunction Adapt(HookFunctionVariant3 suppliedHook)
			{
				HookFunctionVariant3 suppliedHook2 = suppliedHook;
				return delegate
				{
					suppliedHook2();
					return true;
				};
			}
		}

		public static Hook CreateHook(MethodInfo methodInfo)
		{
			HookFunction func = HookFunctionAdapter.Adapt(methodInfo);
			return new Hook(func, methodInfo);
		}

		public static Hook CreateHook(HookFunction hookFunc)
		{
			return new Hook(hookFunc, hookFunc.Method);
		}

		public static Hook CreateHook(HookFunctionVariant1 hookFunc)
		{
			HookFunction func = HookFunctionAdapter.Adapt(hookFunc);
			return new Hook(func, hookFunc.Method);
		}

		public static Hook CreateHook(HookFunctionVariant2 hookFunc)
		{
			HookFunction func = HookFunctionAdapter.Adapt(hookFunc);
			return new Hook(func, hookFunc.Method);
		}

		public static Hook CreateHook(HookFunctionVariant3 hookFunc)
		{
			HookFunction func = HookFunctionAdapter.Adapt(hookFunc);
			return new Hook(func, hookFunc.Method);
		}
	}
	public static class WhenCreatedWorldsContainAll
	{
		public delegate void HookFunction(IEnumerable<World> worlds);

		public delegate void HookFunctionVariant1();

		public class Hook
		{
			public HookFunction Func { get; }

			public MethodInfo UnwrappedMethodInfo { get; }

			public Hook(HookFunction func, MethodInfo unwrappedMethodInfo)
			{
				Func = func;
				UnwrappedMethodInfo = unwrappedMethodInfo;
				base..ctor();
			}

			public void Invoke(IEnumerable<World> worlds)
			{
				Func(worlds);
			}

			public string FullName()
			{
				string text = UnwrappedMethodInfo?.DeclaringType?.FullName;
				string text2 = UnwrappedMethodInfo?.Name;
				return text + "." + text2;
			}
		}

		internal static class HookFunctionAdapter
		{
			public static HookFunction Adapt(MethodInfo methodInfo)
			{
				dynamic val = null;
				int num = methodInfo.GetParameters().Length;
				Type type = methodInfo.GetParameters().ElementAtOrDefault(0)?.ParameterType;
				if (num <= 1 && methodInfo.ReturnType == typeof(void))
				{
					if ((object)type != null && type.IsAssignableFrom(typeof(IEnumerable<World>)))
					{
						val = methodInfo.CreateDelegate<HookFunction>();
					}
					else if (type == null)
					{
						val = methodInfo.CreateDelegate<HookFunctionVariant1>();
					}
				}
				if (val == null)
				{
					throw new Exception("Invalid hook format on " + methodInfo.DeclaringType?.FullName + "." + methodInfo.Name);
				}
				return HookFunctionAdapter.Adapt(val);
			}

			internal static HookFunction Adapt(HookFunction suppliedHook)
			{
				return suppliedHook;
			}

			internal static HookFunction Adapt(HookFunctionVariant1 suppliedHook)
			{
				return delegate
				{
					suppliedHook();
				};
			}
		}

		public static Hook CreateHook(MethodInfo methodInfo)
		{
			HookFunction func = HookFunctionAdapter.Adapt(methodInfo);
			return new Hook(func, methodInfo);
		}

		public static Hook CreateHook(HookFunction hookFunc)
		{
			return new Hook(hookFunc, hookFunc.Method);
		}

		public static Hook CreateHook(HookFunctionVariant1 hookFunc)
		{
			HookFunction func = HookFunctionAdapter.Adapt(hookFunc);
			return new Hook(func, hookFunc.Method);
		}
	}
	public static class WhenCreatedWorldsContainAny
	{
		public delegate void HookFunction(IEnumerable<World> worlds);

		public delegate void HookFunctionVariant1();

		public class Hook
		{
			public HookFunction Func { get; }

			public MethodInfo UnwrappedMethodInfo { get; }

			public Hook(HookFunction func, MethodInfo unwrappedMethodInfo)
			{
				Func = func;
				UnwrappedMethodInfo = unwrappedMethodInfo;
				base..ctor();
			}

			public void Invoke(IEnumerable<World> worlds)
			{
				Func(worlds);
			}

			public string FullName()
			{
				string text = UnwrappedMethodInfo?.DeclaringType?.FullName;
				string text2 = UnwrappedMethodInfo?.Name;
				return text + "." + text2;
			}
		}

		internal static class HookFunctionAdapter
		{
			public static HookFunction Adapt(MethodInfo methodInfo)
			{
				dynamic val = null;
				int num = methodInfo.GetParameters().Length;
				Type type = methodInfo.GetParameters().ElementAtOrDefault(0)?.ParameterType;
				if (num <= 1 && methodInfo.ReturnType == typeof(void))
				{
					if ((object)type != null && type.IsAssignableFrom(typeof(IEnumerable<World>)))
					{
						val = methodInfo.CreateDelegate<HookFunction>();
					}
					else if (type == null)
					{
						val = methodInfo.CreateDelegate<HookFunctionVariant1>();
					}
				}
				if (val == null)
				{
					throw new Exception("Invalid hook format on " + methodInfo.DeclaringType?.FullName + "." + methodInfo.Name);
				}
				return HookFunctionAdapter.Adapt(val);
			}

			internal static HookFunction Adapt(HookFunction suppliedHook)
			{
				return suppliedHook;
			}

			internal static HookFunction Adapt(HookFunctionVariant1 suppliedHook)
			{
				return delegate
				{
					suppliedHook();
				};
			}
		}

		public static Hook CreateHook(MethodInfo methodInfo)
		{
			HookFunction func = HookFunctionAdapter.Adapt(methodInfo);
			return new Hook(func, methodInfo);
		}

		public static Hook CreateHook(HookFunction hookFunc)
		{
			return new Hook(hookFunc, hookFunc.Method);
		}

		public static Hook CreateHook(HookFunctionVariant1 hookFunc)
		{
			HookFunction func = HookFunctionAdapter.Adapt(hookFunc);
			return new Hook(func, hookFunc.Method);
		}
	}
}
namespace HookDOTS.HookRegistration
{
	internal class Executor_System_OnUpdate
	{
		private class WorldboundExecutor
		{
			private World _world;

			private SubRegistry_System_OnUpdate_Prefix _prefixSubRegistry;

			private SubRegistry_System_OnUpdate_Postfix _postfixSubRegistry;

			private static Dictionary<SystemTypeIndex, bool> _restoreEnabledAfterPrefixSkip_System_OnUpdate = new Dictionary<SystemTypeIndex, bool>();

			private static Dictionary<SystemTypeIndex, bool> _didPrefixExpectSystemToRun = new Dictionary<SystemTypeIndex, bool>();

			public WorldboundExecutor(World world, SubRegistry_System_OnUpdate_Prefix prefixSubRegistry, SubRegistry_System_OnUpdate_Postfix postfixSubRegistry)
			{
				_world = world;
				_prefixSubRegistry = prefixSubRegistry;
				_postfixSubRegistry = postfixSubRegistry;
			}

			internal unsafe void ExecutePrefixHooks(SystemState* systemState)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_0023: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
				SystemTypeIndex systemTypeIndex = ((SystemState)systemState).m_SystemTypeIndex;
				bool flag = ((SystemState)systemState).Enabled && ((SystemState)systemState).ShouldRunSystem();
				bool flag2 = false;
				foreach (RegistryEntries.System_OnUpdate_Prefix item in _prefixSubRegistry.GetEntriesInRegistrationOrder(systemTypeIndex))
				{
					try
					{
						if (flag || !item.Options.OnlyWhenSystemRuns)
						{
							Throttle? throttle = item.Options.Throttle;
							if ((throttle == null || !throttle.CheckAndTrigger()) && !item.Hook.Invoke(systemState))
							{
								flag2 = true;
							}
						}
					}
					catch (Exception ex)
					{
						item.Log.LogError((object)ex);
					}
				}
				if (flag2)
				{
					_restoreEnabledAfterPrefixSkip_System_OnUpdate[systemTypeIndex] = ((SystemState)systemState).Enabled;
					((SystemState)systemState).Enabled = false;
				}
				_didPrefixExpectSystemToRun[systemTypeIndex] = flag && !flag2;
			}

			internal unsafe void ExecutePostfixHooks(SystemState* systemState)
			{
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_0007: Unknown result type (might be due to invalid IL or missing references)
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_004a: Unknown result type (might be due to invalid IL or missing references)
				//IL_001e: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				SystemTypeIndex systemTypeIndex = ((SystemState)systemState).m_SystemTypeIndex;
				if (_restoreEnabledAfterPrefixSkip_System_OnUpdate.ContainsKey(systemTypeIndex))
				{
					((SystemState)systemState).Enabled = _restoreEnabledAfterPrefixSkip_System_OnUpdate[systemTypeIndex];
					_restoreEnabledAfterPrefixSkip_System_OnUpdate.Remove(systemTypeIndex);
				}
				bool flag = _didPrefixExpectSystemToRun[systemTypeIndex];
				foreach (RegistryEntries.System_OnUpdate_Postfix item in _postfixSubRegistry.GetEntriesInRegistrationOrder(systemTypeIndex))
				{
					try
					{
						if (flag || !item.Options.OnlyWhenSystemRuns)
						{
							Throttle? throttle = item.Options.Throttle;
							if (throttle == null || !throttle.CheckAndTrigger())
							{
								item.Hook.Invoke(systemState);
							}
						}
					}
					catch (Exception ex)
					{
						item.Log.LogError((object)ex);
					}
				}
			}
		}

		private SubRegistry_System_OnUpdate_Prefix _prefixSubRegistry;

		private SubRegistry_System_OnUpdate_Postfix _postfixSubRegistry;

		private Dictionary<World, WorldboundExecutor> _worldboundExecutors = new Dictionary<World, WorldboundExecutor>();

		public Executor_System_OnUpdate(SubRegistry_System_OnUpdate_Prefix prefixSubRegistry, SubRegistry_System_OnUpdate_Postfix postfixSubRegistry)
		{
			_prefixSubRegistry = prefixSubRegistry;
			_postfixSubRegistry = postfixSubRegistry;
		}

		private WorldboundExecutor GetOrCreateWorldboundExecutor(World world)
		{
			if (_worldboundExecutors.ContainsKey(world))
			{
				return _worldboundExecutors[world];
			}
			WorldboundExecutor worldboundExecutor = new WorldboundExecutor(world, _prefixSubRegistry, _postfixSubRegistry);
			_worldboundExecutors.Add(world, worldboundExecutor);
			return worldboundExecutor;
		}

		internal unsafe void ExecutePrefixHooks(SystemState* systemState)
		{
			WorldboundExecutor orCreateWorldboundExecutor = GetOrCreateWorldboundExecutor(((SystemState)systemState).World);
			orCreateWorldboundExecutor.ExecutePrefixHooks(systemState);
		}

		internal unsafe void ExecutePostfixHooks(SystemState* systemState)
		{
			WorldboundExecutor orCreateWorldboundExecutor = GetOrCreateWorldboundExecutor(((SystemState)systemState).World);
			orCreateWorldboundExecutor.ExecutePostfixHooks(systemState);
		}
	}
	internal class Executor_WhenCreatedWorldsContain
	{
		private IWorldWatcher _worldWatcher;

		private SubRegistry_WhenCreatedWorldsContainAny _subRegistryAny;

		private SubRegistry_WhenCreatedWorldsContainAll _subRegistryAll;

		internal Executor_WhenCreatedWorldsContain(SubRegistry_WhenCreatedWorldsContainAny subRegistryAny, SubRegistry_WhenCreatedWorldsContainAll subRegistryAll, IWorldWatcher worldWatcher)
		{
			_subRegistryAny = subRegistryAny;
			_subRegistryAll = subRegistryAll;
			_worldWatcher = worldWatcher;
		}

		public void ExecuteAndRemoveHooks()
		{
			_worldWatcher.Update();
			ExecuteAndRemoveHooks_AllWorlds();
			ExecuteAndRemoveHooks_AnyWorlds();
		}

		private void ExecuteAndRemoveHooks_AnyWorlds()
		{
			IEnumerable<RegistryEntries.WhenCreatedWorldsContainAny> enumerable = _subRegistryAny.ExtractMatchesInRegistrationOrder(_worldWatcher);
			foreach (RegistryEntries.WhenCreatedWorldsContainAny item in enumerable)
			{
				try
				{
					IEnumerable<World> matchingWorldsCreated = _worldWatcher.GetMatchingWorldsCreated(item.WorldNames);
					item.Hook.Invoke(matchingWorldsCreated);
				}
				catch (Exception ex)
				{
					item.Log.LogError((object)ex);
				}
			}
		}

		private void ExecuteAndRemoveHooks_AllWorlds()
		{
			IEnumerable<RegistryEntries.WhenCreatedWorldsContainAll> enumerable = _subRegistryAll.ExtractMatchesInRegistrationOrder(_worldWatcher);
			foreach (RegistryEntries.WhenCreatedWorldsContainAll item in enumerable)
			{
				try
				{
					IEnumerable<World> matchingWorldsCreated = _worldWatcher.GetMatchingWorldsCreated(item.WorldNames);
					item.Hook.Invoke(matchingWorldsCreated);
				}
				catch (Exception ex)
				{
					item.Log.LogError((object)ex);
				}
			}
		}
	}
	internal struct HookHandle
	{
		public int Value;

		public HookType HookType;

		public SystemTypeIndex SystemTypeIndex;
	}
	public class HookRegistrar
	{
		private string _id;

		private HookRegistryStaging _hookRegistryStaging;

		private ManualLogSource _log;

		internal HookRegistrar(string registrarId, HookRegistryStaging hookRegistryStaging, ManualLogSource log)
		{
			_id = registrarId;
			_hookRegistryStaging = hookRegistryStaging;
			_log = log;
		}

		public void Dispose()
		{
			_hookRegistryStaging.Dispose();
		}

		public void UnregisterHooks()
		{
			_hookRegistryStaging.CancelPendingRegistrations();
			_hookRegistryStaging.UnregisterRegisteredHooks();
		}

		public void RegisterHook_System_OnUpdate_Prefix<TSystemType>(System_OnUpdate_Prefix.Hook hook)
		{
			System_OnUpdate_Prefix.Options @default = System_OnUpdate_Prefix.Options.Default;
			RegisterHook_System_OnUpdate_Prefix<TSystemType>(hook, @default);
		}

		public void RegisterHook_System_OnUpdate_Prefix<TSystemType>(System_OnUpdate_Prefix.Hook hook, System_OnUpdate_Prefix.Options options)
		{
			RegisterHook_System_OnUpdate_Prefix(hook, Il2CppType.Of<TSystemType>(), options);
		}

		public void RegisterHook_System_OnUpdate_Prefix(System_OnUpdate_Prefix.Hook hook, Type systemType)
		{
			System_OnUpdate_Prefix.Options @default = System_OnUpdate_Prefix.Options.Default;
			RegisterHook_System_OnUpdate_Prefix(hook, systemType, @default);
		}

		public void RegisterHook_System_OnUpdate_Prefix(System_OnUpdate_Prefix.Hook hook, Type systemType, System_OnUpdate_Prefix.Options options)
		{
			RegisterHook_System_OnUpdate_Prefix(hook, Il2CppType.From(systemType), options);
		}

		public void RegisterHook_System_OnUpdate_Prefix(System_OnUpdate_Prefix.Hook hook, Type systemType)
		{
			System_OnUpdate_Prefix.Options @default = System_OnUpdate_Prefix.Options.Default;
			RegisterHook_System_OnUpdate_Prefix(hook, systemType, @default);
		}

		public void RegisterHook_System_OnUpdate_Prefix(System_OnUpdate_Prefix.Hook hook, Type systemType, System_OnUpdate_Prefix.Options options)
		{
			_hookRegistryStaging.RegisterHook_System_OnUpdate_Prefix(hook, systemType, options);
		}

		public void RegisterHook_System_OnUpdate_Postfix<TSystemType>(System_OnUpdate_Postfix.Hook hook)
		{
			System_OnUpdate_Postfix.Options @default = System_OnUpdate_Postfix.Options.Default;
			RegisterHook_System_OnUpdate_Postfix<TSystemType>(hook, @default);
		}

		public void RegisterHook_System_OnUpdate_Postfix<TSystemType>(System_OnUpdate_Postfix.Hook hook, System_OnUpdate_Postfix.Options options)
		{
			RegisterHook_System_OnUpdate_Postfix(hook, Il2CppType.Of<TSystemType>(), options);
		}

		public void RegisterHook_System_OnUpdate_Postfix(System_OnUpdate_Postfix.Hook hook, Type systemType)
		{
			System_OnUpdate_Postfix.Options @default = System_OnUpdate_Postfix.Options.Default;
			RegisterHook_System_OnUpdate_Postfix(hook, systemType, @default);
		}

		public void RegisterHook_System_OnUpdate_Postfix(System_OnUpdate_Postfix.Hook hook, Type systemType, System_OnUpdate_Postfix.Options options)
		{
			RegisterHook_System_OnUpdate_Postfix(hook, Il2CppType.From(systemType), options);
		}

		public void RegisterHook_System_OnUpdate_Postfix(System_OnUpdate_Postfix.Hook hook, Type systemType)
		{
			System_OnUpdate_Postfix.Options @default = System_OnUpdate_Postfix.Options.Default;
			RegisterHook_System_OnUpdate_Postfix(hook, systemType, @default);
		}

		public void RegisterHook_System_OnUpdate_Postfix(System_OnUpdate_Postfix.Hook hook, Type systemType, System_OnUpdate_Postfix.Options options)
		{
			_hookRegistryStaging.RegisterHook_System_OnUpdate_Postfix(hook, systemType, options);
		}

		public void RegisterHook_WhenCreatedWorldsContainAny(HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook hook, IEnumerable<string> worldNames)
		{
			if (!worldNames.Any())
			{
				throw new ArgumentException("worldNames must not be empty");
			}
			_hookRegistryStaging.RegisterHook_WhenCreatedWorldsContainAny(hook, worldNames.ToHashSet());
		}

		public void RegisterHook_WhenCreatedWorldsContainAll(HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook hook, IEnumerable<string> worldNames)
		{
			if (!worldNames.Any())
			{
				throw new ArgumentException("worldNames must not be empty");
			}
			_hookRegistryStaging.RegisterHook_WhenCreatedWorldsContainAll(hook, worldNames.ToHashSet());
		}
	}
	internal class HookRegistry
	{
		private IdGenerator _idGenerator;

		internal SubRegistry_System_OnUpdate_Prefix SubRegistry_System_OnUpdate_Prefix { get; }

		internal SubRegistry_System_OnUpdate_Postfix SubRegistry_System_OnUpdate_Postfix { get; }

		internal SubRegistry_WhenCreatedWorldsContainAny SubRegistry_WhenCreatedWorldsContainAny { get; }

		internal SubRegistry_WhenCreatedWorldsContainAll SubRegistry_WhenCreatedWorldsContainAll { get; }

		internal HookRegistry()
		{
			_idGenerator = new IdGeneratorAutoIncrement();
			SubRegistry_System_OnUpdate_Prefix = new SubRegistry_System_OnUpdate_Prefix(_idGenerator);
			SubRegistry_System_OnUpdate_Postfix = new SubRegistry_System_OnUpdate_Postfix(_idGenerator);
			SubRegistry_WhenCreatedWorldsContainAny = new SubRegistry_WhenCreatedWorldsContainAny(_idGenerator);
			SubRegistry_WhenCreatedWorldsContainAll = new SubRegistry_WhenCreatedWorldsContainAll(_idGenerator);
		}

		internal void UnregisterHook(HookHandle hookHandle)
		{
			switch (hookHandle.HookType)
			{
			case HookType.System_OnUpdate_Prefix:
				SubRegistry_System_OnUpdate_Prefix.UnregisterHook(hookHandle);
				break;
			case HookType.System_OnUpdate_Postfix:
				SubRegistry_System_OnUpdate_Postfix.UnregisterHook(hookHandle);
				break;
			case HookType.WhenCreatedWorldsContainAny:
				SubRegistry_WhenCreatedWorldsContainAny.UnregisterHook(hookHandle);
				break;
			case HookType.WhenCreatedWorldsContainAll:
				SubRegistry_WhenCreatedWorldsContainAll.UnregisterHook(hookHandle);
				break;
			}
		}
	}
	internal class HookRegistryStaging
	{
		private string _id;

		private HookRegistry _hookRegistry;

		private Bus _bus;

		private ManualLogSource _log;

		private bool _canRegister = false;

		private List<HookHandle> _registeredHookHandles = new List<HookHandle>();

		private Queue<RegistryEntries.System_OnUpdate_Prefix> _pendingRegistrations_System_OnUpdate_Prefix = new Queue<RegistryEntries.System_OnUpdate_Prefix>();

		private Queue<RegistryEntries.System_OnUpdate_Postfix> _pendingRegistrations_System_OnUpdate_Postfix = new Queue<RegistryEntries.System_OnUpdate_Postfix>();

		private Queue<RegistryEntries.WhenCreatedWorldsContainAny> _pendingRegistrations_WhenCreatedWorldsContainAny = new Queue<RegistryEntries.WhenCreatedWorldsContainAny>();

		private Queue<RegistryEntries.WhenCreatedWorldsContainAll> _pendingRegistrations_WhenCreatedWorldsContainAll = new Queue<RegistryEntries.WhenCreatedWorldsContainAll>();

		internal HookRegistryStaging(string id, HookRegistry hookRegistry, Bus bus, bool isGameReadyForRegistration, ManualLogSource log)
		{
			_id = id;
			_hookRegistry = hookRegistry;
			_canRegister = isGameReadyForRegistration;
			_bus = bus;
			_log = log;
			_bus.EventGameReadyForHooking += HandleGameReadyForRegistration;
		}

		public void Dispose()
		{
			_bus.EventGameReadyForHooking -= HandleGameReadyForRegistration;
			UnregisterRegisteredHooks();
			CancelPendingRegistrations();
		}

		internal void UnregisterRegisteredHooks()
		{
			foreach (HookHandle registeredHookHandle in _registeredHookHandles)
			{
				_hookRegistry.UnregisterHook(registeredHookHandle);
			}
			_registeredHookHandles.Clear();
		}

		internal void CancelPendingRegistrations()
		{
			_pendingRegistrations_System_OnUpdate_Prefix.Clear();
			_pendingRegistrations_System_OnUpdate_Postfix.Clear();
			_pendingRegistrations_WhenCreatedWorldsContainAny.Clear();
			_pendingRegistrations_WhenCreatedWorldsContainAll.Clear();
		}

		internal void HandleGameReadyForRegistration()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			_canRegister = true;
			ManualLogSource log = _log;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(52, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HookDOTS: processing pending hook registrations for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_id);
			}
			log.LogDebug(val);
			ProcessPendingRegistrations_System_OnUpdate_Prefix();
			ProcessPendingRegistrations_System_OnUpdate_Postfix();
			ProcessPendingRegistrations_WhenCreatedWorldsContainAny();
			ProcessPendingRegistrations_WhenCreatedWorldsContainAll();
			_bus.TriggerCommandRunHooks_WorldsCreated();
		}

		internal void ProcessPendingRegistrations_System_OnUpdate_Prefix()
		{
			while (_pendingRegistrations_System_OnUpdate_Prefix.Count != 0)
			{
				RegistryEntries.System_OnUpdate_Prefix entry = _pendingRegistrations_System_OnUpdate_Prefix.Dequeue();
				try
				{
					RegisterHook_System_OnUpdate_Prefix(entry);
				}
				catch (Exception ex)
				{
					_log.LogError((object)ex);
				}
			}
		}

		internal void ProcessPendingRegistrations_System_OnUpdate_Postfix()
		{
			while (_pendingRegistrations_System_OnUpdate_Postfix.Count != 0)
			{
				RegistryEntries.System_OnUpdate_Postfix entry = _pendingRegistrations_System_OnUpdate_Postfix.Dequeue();
				try
				{
					RegisterHook_System_OnUpdate_Postfix(entry);
				}
				catch (Exception ex)
				{
					_log.LogError((object)ex);
				}
			}
		}

		internal void ProcessPendingRegistrations_WhenCreatedWorldsContainAny()
		{
			while (_pendingRegistrations_WhenCreatedWorldsContainAny.Count != 0)
			{
				RegistryEntries.WhenCreatedWorldsContainAny entry = _pendingRegistrations_WhenCreatedWorldsContainAny.Dequeue();
				try
				{
					RegisterHook_WhenCreatedWorldsContainAny(entry);
				}
				catch (Exception ex)
				{
					_log.LogError((object)ex);
				}
			}
		}

		internal void ProcessPendingRegistrations_WhenCreatedWorldsContainAll()
		{
			while (_pendingRegistrations_WhenCreatedWorldsContainAll.Count != 0)
			{
				RegistryEntries.WhenCreatedWorldsContainAll entry = _pendingRegistrations_WhenCreatedWorldsContainAll.Dequeue();
				try
				{
					RegisterHook_WhenCreatedWorldsContainAll(entry);
				}
				catch (Exception ex)
				{
					_log.LogError((object)ex);
				}
			}
		}

		internal void RegisterHook_System_OnUpdate_Prefix(System_OnUpdate_Prefix.Hook hook, Type systemType, System_OnUpdate_Prefix.Options options)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			RegistryEntries.System_OnUpdate_Prefix system_OnUpdate_Prefix = new RegistryEntries.System_OnUpdate_Prefix(hook, systemType, options, _log, _id);
			if (_canRegister)
			{
				RegisterHook_System_OnUpdate_Prefix(system_OnUpdate_Prefix);
				return;
			}
			ManualLogSource log = _log;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(48, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HookDOTS: added a pending hook registration for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_id);
			}
			log.LogDebug(val);
			_pendingRegistrations_System_OnUpdate_Prefix.Enqueue(system_OnUpdate_Prefix);
		}

		private void RegisterHook_System_OnUpdate_Prefix(RegistryEntries.System_OnUpdate_Prefix entry)
		{
			HookHandle item = _hookRegistry.SubRegistry_System_OnUpdate_Prefix.RegisterHook(entry);
			_registeredHookHandles.Add(item);
		}

		internal void RegisterHook_System_OnUpdate_Postfix(System_OnUpdate_Postfix.Hook hook, Type systemType, System_OnUpdate_Postfix.Options options)
		{
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			RegistryEntries.System_OnUpdate_Postfix system_OnUpdate_Postfix = new RegistryEntries.System_OnUpdate_Postfix(hook, systemType, options, _log, _id);
			if (_canRegister)
			{
				RegisterHook_System_OnUpdate_Postfix(system_OnUpdate_Postfix);
				return;
			}
			ManualLogSource log = _log;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(48, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HookDOTS: added a pending hook registration for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_id);
			}
			log.LogDebug(val);
			_pendingRegistrations_System_OnUpdate_Postfix.Enqueue(system_OnUpdate_Postfix);
		}

		private void RegisterHook_System_OnUpdate_Postfix(RegistryEntries.System_OnUpdate_Postfix entry)
		{
			HookHandle item = _hookRegistry.SubRegistry_System_OnUpdate_Postfix.RegisterHook(entry);
			_registeredHookHandles.Add(item);
		}

		internal void RegisterHook_WhenCreatedWorldsContainAny(HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook hook, ISet<string> worldNames)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			RegistryEntries.WhenCreatedWorldsContainAny whenCreatedWorldsContainAny = new RegistryEntries.WhenCreatedWorldsContainAny(hook, worldNames, _log, _id);
			if (_canRegister)
			{
				RegisterHook_WhenCreatedWorldsContainAny(whenCreatedWorldsContainAny);
				_bus.TriggerCommandRunHooks_WorldsCreated();
				return;
			}
			ManualLogSource log = _log;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(48, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HookDOTS: added a pending hook registration for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_id);
			}
			log.LogDebug(val);
			_pendingRegistrations_WhenCreatedWorldsContainAny.Enqueue(whenCreatedWorldsContainAny);
		}

		private void RegisterHook_WhenCreatedWorldsContainAny(RegistryEntries.WhenCreatedWorldsContainAny entry)
		{
			HookHandle item = _hookRegistry.SubRegistry_WhenCreatedWorldsContainAny.RegisterHook(entry);
			_registeredHookHandles.Add(item);
		}

		internal void RegisterHook_WhenCreatedWorldsContainAll(HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook hook, ISet<string> worldNames)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			RegistryEntries.WhenCreatedWorldsContainAll whenCreatedWorldsContainAll = new RegistryEntries.WhenCreatedWorldsContainAll(hook, worldNames, _log, _id);
			if (_canRegister)
			{
				RegisterHook_WhenCreatedWorldsContainAll(whenCreatedWorldsContainAll);
				_bus.TriggerCommandRunHooks_WorldsCreated();
				return;
			}
			ManualLogSource log = _log;
			bool flag = default(bool);
			BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(48, 1, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("HookDOTS: added a pending hook registration for ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_id);
			}
			log.LogDebug(val);
			_pendingRegistrations_WhenCreatedWorldsContainAll.Enqueue(whenCreatedWorldsContainAll);
		}

		private void RegisterHook_WhenCreatedWorldsContainAll(RegistryEntries.WhenCreatedWorldsContainAll entry)
		{
			HookHandle item = _hookRegistry.SubRegistry_WhenCreatedWorldsContainAll.RegisterHook(entry);
			_registeredHookHandles.Add(item);
		}
	}
	internal enum HookType
	{
		System_OnUpdate_Prefix,
		System_OnUpdate_Postfix,
		WhenCreatedWorldsContainAny,
		WhenCreatedWorldsContainAll
	}
	internal interface IdGenerator
	{
		int NextId();
	}
	internal class IdGeneratorAutoIncrement : IdGenerator
	{
		private int _autoIncrement = 0;

		public int NextId()
		{
			return ++_autoIncrement;
		}
	}
	internal static class RegistryEntries
	{
		internal record System_OnUpdate_Prefix(HookDOTS.Hooks.System_OnUpdate_Prefix.Hook Hook, Type SystemType, HookDOTS.Hooks.System_OnUpdate_Prefix.Options Options, ManualLogSource Log, string RegistrantId);

		internal record System_OnUpdate_Postfix(HookDOTS.Hooks.System_OnUpdate_Postfix.Hook Hook, Type SystemType, HookDOTS.Hooks.System_OnUpdate_Postfix.Options Options, ManualLogSource Log, string RegistrantId);

		internal record WhenCreatedWorldsContainAny(HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook Hook, ISet<string> WorldNames, ManualLogSource Log, string RegistrantId);

		internal record WhenCreatedWorldsContainAll(HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook Hook, ISet<string> WorldNames, ManualLogSource Log, string RegistrantId);
	}
	internal abstract class SubRegistry_System<TRegistryEntry>
	{
		protected Dictionary<SystemTypeIndex, Dictionary<HookHandle, TRegistryEntry>> _hooksBySystem = new Dictionary<SystemTypeIndex, Dictionary<HookHandle, TRegistryEntry>>();

		protected ICollection<TRegistryEntry> _emptyCollection = Array.Empty<TRegistryEntry>();

		internal abstract HookHandle RegisterHook(TRegistryEntry registryEntry);

		internal void UnregisterHook(HookHandle hookHandle)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			_hooksBySystem[hookHandle.SystemTypeIndex].Remove(hookHandle);
		}

		internal IEnumerable<TRegistryEntry> GetEntriesInRegistrationOrder(SystemTypeIndex systemTypeIndex)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			if (!_hooksBySystem.ContainsKey(systemTypeIndex))
			{
				return _emptyCollection;
			}
			return _hooksBySystem[systemTypeIndex].Values;
		}

		protected HookHandle RegisterHook(SystemTypeIndex systemTypeIndex, HookHandle handle, TRegistryEntry registryEntry)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<HookHandle, TRegistryEntry> dictionary;
			if (_hooksBySystem.ContainsKey(systemTypeIndex))
			{
				dictionary = _hooksBySystem[systemTypeIndex];
			}
			else
			{
				dictionary = new Dictionary<HookHandle, TRegistryEntry>();
				_hooksBySystem.Add(systemTypeIndex, dictionary);
			}
			dictionary.Add(handle, registryEntry);
			return handle;
		}
	}
	internal class SubRegistry_System_OnUpdate_Postfix : SubRegistry_System<RegistryEntries.System_OnUpdate_Postfix>
	{
		private IdGenerator _idGenerator;

		internal SubRegistry_System_OnUpdate_Postfix(IdGenerator idGenerator)
		{
			_idGenerator = idGenerator;
		}

		internal override HookHandle RegisterHook(RegistryEntries.System_OnUpdate_Postfix registryEntry)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Type systemType = registryEntry.SystemType;
			SystemTypeIndex systemTypeIndex = TypeManager.GetSystemTypeIndex(systemType);
			if (((SystemTypeIndex)(ref systemTypeIndex)).Equals(SystemTypeIndex.Null))
			{
				throw new Exception("null SystemTypeIndex for " + systemType.FullName);
			}
			HookHandle hookHandle = default(HookHandle);
			hookHandle.Value = _idGenerator.NextId();
			hookHandle.HookType = HookType.System_OnUpdate_Postfix;
			hookHandle.SystemTypeIndex = systemTypeIndex;
			HookHandle hookHandle2 = hookHandle;
			RegisterHook(systemTypeIndex, hookHandle2, registryEntry);
			string fullName = TypeManager.GetSystemType(systemTypeIndex).FullName;
			LogUtil.LogDebug(MultiLineRegistrationLogEntry(registryEntry, hookHandle2, fullName));
			return hookHandle2;
		}

		protected string MultiLineRegistrationLogEntry(RegistryEntries.System_OnUpdate_Postfix registryEntry, HookHandle handle, string confirmedSystemName)
		{
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(25, 1, stringBuilder2);
			handler.AppendLiteral("HookDOTS registered hook#");
			handler.AppendFormatted(handle.Value);
			stringBuilder3.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2);
			handler.AppendLiteral("    registrant: ");
			handler.AppendFormatted(registryEntry.RegistrantId);
			stringBuilder4.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(25, 1, stringBuilder2);
			handler.AppendLiteral("    target:     ");
			handler.AppendFormatted(confirmedSystemName);
			handler.AppendLiteral(".OnUpdate");
			stringBuilder5.AppendLine(ref handler);
			stringBuilder.AppendLine("    precedence: POSTFIX");
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(13, 1, stringBuilder2);
			handler.AppendLiteral("    invoke:  ");
			handler.AppendFormatted(registryEntry.Hook.FullName());
			stringBuilder6.Append(ref handler);
			return stringBuilder.ToString();
		}
	}
	internal class SubRegistry_System_OnUpdate_Prefix : SubRegistry_System<RegistryEntries.System_OnUpdate_Prefix>
	{
		private IdGenerator _idGenerator;

		internal SubRegistry_System_OnUpdate_Prefix(IdGenerator idGenerator)
		{
			_idGenerator = idGenerator;
		}

		internal override HookHandle RegisterHook(RegistryEntries.System_OnUpdate_Prefix registryEntry)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			Type systemType = registryEntry.SystemType;
			SystemTypeIndex systemTypeIndex = TypeManager.GetSystemTypeIndex(systemType);
			if (((SystemTypeIndex)(ref systemTypeIndex)).Equals(SystemTypeIndex.Null))
			{
				throw new Exception("null SystemTypeIndex for " + systemType.FullName);
			}
			HookHandle hookHandle = default(HookHandle);
			hookHandle.Value = _idGenerator.NextId();
			hookHandle.HookType = HookType.System_OnUpdate_Prefix;
			hookHandle.SystemTypeIndex = systemTypeIndex;
			HookHandle hookHandle2 = hookHandle;
			RegisterHook(systemTypeIndex, hookHandle2, registryEntry);
			string fullName = TypeManager.GetSystemType(systemTypeIndex).FullName;
			LogUtil.LogDebug(MultiLineRegistrationLogEntry(registryEntry, hookHandle2, fullName));
			return hookHandle2;
		}

		protected string MultiLineRegistrationLogEntry(RegistryEntries.System_OnUpdate_Prefix registryEntry, HookHandle handle, string confirmedSystemName)
		{
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(26, 1, stringBuilder2);
			handler.AppendLiteral("HookDOTS registered hook#");
			handler.AppendFormatted(handle.Value);
			handler.AppendLiteral(".");
			stringBuilder3.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2);
			handler.AppendLiteral("    registrant: ");
			handler.AppendFormatted(registryEntry.RegistrantId);
			stringBuilder4.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(25, 1, stringBuilder2);
			handler.AppendLiteral("    target:     ");
			handler.AppendFormatted(confirmedSystemName);
			handler.AppendLiteral(".OnUpdate");
			stringBuilder5.AppendLine(ref handler);
			stringBuilder.AppendLine("    precedence: PREFIX");
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2);
			handler.AppendLiteral("    detour to:  ");
			handler.AppendFormatted(registryEntry.Hook.FullName());
			stringBuilder6.Append(ref handler);
			return stringBuilder.ToString();
		}
	}
	internal class SubRegistry_WhenCreatedWorldsContainAll : SubRegistry_WhenCreatedWorldsContain<RegistryEntries.WhenCreatedWorldsContainAll>
	{
		private IdGenerator _idGenerator;

		internal SubRegistry_WhenCreatedWorldsContainAll(IdGenerator idGenerator)
		{
			_idGenerator = idGenerator;
		}

		internal IEnumerable<RegistryEntries.WhenCreatedWorldsContainAll> ExtractMatchesInRegistrationOrder(IWorldWatcher worldWatcher)
		{
			IEnumerable<HookHandle> enumerable = _hooks.Keys.Where((HookHandle k) => worldWatcher.AreAllWorldsCreated(_hooks[k].WorldNames));
			List<RegistryEntries.WhenCreatedWorldsContainAll> result = enumerable.Select(((IReadOnlyDictionary<HookHandle, RegistryEntries.WhenCreatedWorldsContainAll>)_hooks).GetValueOrDefault<HookHandle, RegistryEntries.WhenCreatedWorldsContainAll>).ToList();
			foreach (HookHandle item in enumerable)
			{
				_hooks.Remove(item);
			}
			return result;
		}

		internal override HookHandle RegisterHook(RegistryEntries.WhenCreatedWorldsContainAll registryEntry)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			HookHandle hookHandle = default(HookHandle);
			hookHandle.Value = _idGenerator.NextId();
			hookHandle.HookType = HookType.WhenCreatedWorldsContainAll;
			hookHandle.SystemTypeIndex = SystemTypeIndex.Null;
			HookHandle hookHandle2 = hookHandle;
			RegisterHook(hookHandle2, registryEntry);
			LogUtil.LogDebug(MultiLineRegistrationLogEntry(registryEntry, hookHandle2));
			return hookHandle2;
		}

		protected string MultiLineRegistrationLogEntry(RegistryEntries.WhenCreatedWorldsContainAll registryEntry, HookHandle handle)
		{
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(25, 1, stringBuilder2);
			handler.AppendLiteral("HookDOTS registered hook#");
			handler.AppendFormatted(handle.Value);
			stringBuilder3.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2);
			handler.AppendLiteral("    registrant: ");
			handler.AppendFormatted(registryEntry.RegistrantId);
			stringBuilder4.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(47, 1, stringBuilder2);
			handler.AppendLiteral("    target:     WhenCreatedWorldsContainAll([");
			handler.AppendFormatted(FormattedWorldNames(registryEntry.WorldNames));
			handler.AppendLiteral(")]");
			stringBuilder5.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2);
			handler.AppendLiteral("    invoke:     ");
			handler.AppendFormatted(registryEntry.Hook.FullName());
			stringBuilder6.Append(ref handler);
			return stringBuilder.ToString();
		}
	}
	internal class SubRegistry_WhenCreatedWorldsContainAny : SubRegistry_WhenCreatedWorldsContain<RegistryEntries.WhenCreatedWorldsContainAny>
	{
		private IdGenerator _idGenerator;

		internal SubRegistry_WhenCreatedWorldsContainAny(IdGenerator idGenerator)
		{
			_idGenerator = idGenerator;
		}

		internal IEnumerable<RegistryEntries.WhenCreatedWorldsContainAny> ExtractMatchesInRegistrationOrder(IWorldWatcher worldWatcher)
		{
			IEnumerable<HookHandle> enumerable = _hooks.Keys.Where((HookHandle k) => worldWatcher.AreAnyWorldsCreated(_hooks[k].WorldNames));
			List<RegistryEntries.WhenCreatedWorldsContainAny> result = enumerable.Select(((IReadOnlyDictionary<HookHandle, RegistryEntries.WhenCreatedWorldsContainAny>)_hooks).GetValueOrDefault<HookHandle, RegistryEntries.WhenCreatedWorldsContainAny>).ToList();
			foreach (HookHandle item in enumerable)
			{
				_hooks.Remove(item);
			}
			return result;
		}

		internal override HookHandle RegisterHook(RegistryEntries.WhenCreatedWorldsContainAny registryEntry)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			HookHandle hookHandle = default(HookHandle);
			hookHandle.Value = _idGenerator.NextId();
			hookHandle.HookType = HookType.WhenCreatedWorldsContainAny;
			hookHandle.SystemTypeIndex = SystemTypeIndex.Null;
			HookHandle hookHandle2 = hookHandle;
			RegisterHook(hookHandle2, registryEntry);
			LogUtil.LogDebug(MultiLineRegistrationLogEntry(registryEntry, hookHandle2));
			return hookHandle2;
		}

		protected string MultiLineRegistrationLogEntry(RegistryEntries.WhenCreatedWorldsContainAny registryEntry, HookHandle handle)
		{
			StringBuilder stringBuilder = new StringBuilder();
			StringBuilder stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder3 = stringBuilder2;
			StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(25, 1, stringBuilder2);
			handler.AppendLiteral("HookDOTS registered hook#");
			handler.AppendFormatted(handle.Value);
			stringBuilder3.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder4 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2);
			handler.AppendLiteral("    registrant: ");
			handler.AppendFormatted(registryEntry.RegistrantId);
			stringBuilder4.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder5 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(47, 1, stringBuilder2);
			handler.AppendLiteral("    target:     WhenCreatedWorldsContainAny([");
			handler.AppendFormatted(FormattedWorldNames(registryEntry.WorldNames));
			handler.AppendLiteral("])");
			stringBuilder5.AppendLine(ref handler);
			stringBuilder2 = stringBuilder;
			StringBuilder stringBuilder6 = stringBuilder2;
			handler = new StringBuilder.AppendInterpolatedStringHandler(16, 1, stringBuilder2);
			handler.AppendLiteral("    invoke:     ");
			handler.AppendFormatted(registryEntry.Hook.FullName());
			stringBuilder6.Append(ref handler);
			return stringBuilder.ToString();
		}
	}
	internal abstract class SubRegistry_WhenCreatedWorldsContain<TRegistryEntry>
	{
		protected Dictionary<HookHandle, TRegistryEntry> _hooks = new Dictionary<HookHandle, TRegistryEntry>();

		internal abstract HookHandle RegisterHook(TRegistryEntry registryEntry);

		internal void UnregisterHook(HookHandle hookHandle)
		{
			_hooks.Remove(hookHandle);
		}

		protected HookHandle RegisterHook(HookHandle handle, TRegistryEntry registryEntry)
		{
			_hooks.Add(handle, registryEntry);
			return handle;
		}

		protected string FormattedWorldNames(ISet<string> worldNames)
		{
			return StringUtil.StringifyEnumerableOfStrings(worldNames);
		}
	}
}
namespace HookDOTS.API
{
	[BepInPlugin("HookDOTS.API", "HookDOTS.API", "1.0.0")]
	public class ApiPlugin : BasePlugin
	{
		private Harmony _harmony;

		public override void Load()
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Expected O, but got Unknown
			LogUtil.Init(((BasePlugin)this).Log);
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(27, 2, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("HookDOTS.API");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" version ");
				((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
			}
			log.LogInfo(val);
			_harmony = new Harmony("HookDOTS.API");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			HookManager.Initialize();
			TypeManager.Initialize();
			Bus.Instance.TriggerEventGameReadyForHooking();
		}

		public override bool Unload()
		{
			HookManager.UnInitialize();
			PerformanceRecorderSystemPatch.UnInitialize();
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			return true;
		}
	}
	public class HookDOTS
	{
		private ManualLogSource _log;

		public string Id { get; }

		public HookRegistrar HookRegistrar { get; }

		public HookDOTS(string id, ManualLogSource log)
		{
			if (string.IsNullOrEmpty(id))
			{
				throw new ArgumentException("id cannot be null or empty");
			}
			Id = id;
			_log = log;
			HookRegistrar = HookManager.NewHookRegistrar(id, _log);
		}

		public void Dispose()
		{
			HookRegistrar.Dispose();
		}

		public SetupHooks SetupHooks()
		{
			SpecificationContext context = new SpecificationContext(HookRegistrar);
			Specification spec = new Specification(context);
			return new SetupHooks(spec);
		}

		public void RegisterAnnotatedHooks()
		{
			RegisterHooks(Assembly.GetCallingAssembly());
		}

		public void UnregisterHooks()
		{
			HookRegistrar.UnregisterHooks();
		}

		public void RegisterHooks(Assembly assembly)
		{
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				RegisterHooks(type);
			}
		}

		internal void RegisterHooks(Type type)
		{
			MethodInfo[] methods = type.GetMethods();
			foreach (MethodInfo methodInfo in methods)
			{
				RegisterHooks(methodInfo);
			}
		}

		internal void RegisterHooks(MethodInfo methodInfo)
		{
			RegisterEcsSystemUpdatePrefix(methodInfo);
			RegisterEcsSystemUpdatePostfix(methodInfo);
			RegisterWhenCreatedWorldsContainAny(methodInfo);
			RegisterWhenCreatedWorldsContainAll(methodInfo);
		}

		internal bool RegisterEcsSystemUpdatePrefix(MethodInfo methodInfo)
		{
			if (!methodInfo.IsStatic)
			{
				return false;
			}
			EcsSystemUpdatePrefixAttribute customAttribute = methodInfo.GetCustomAttribute<EcsSystemUpdatePrefixAttribute>();
			if (customAttribute == null)
			{
				return false;
			}
			try
			{
				System_OnUpdate_Prefix.Hook hook = System_OnUpdate_Prefix.CreateHook(methodInfo);
				System_OnUpdate_Prefix.Options options = new System_OnUpdate_Prefix.Options(customAttribute.OnlyWhenSystemRuns, methodInfo.GetCustomAttribute<ThrottleAttribute>()?.CreateThrottle());
				HookRegistrar.RegisterHook_System_OnUpdate_Prefix(hook, customAttribute.SystemType, options);
				return true;
			}
			catch (Exception ex)
			{
				_log.LogError((object)ex);
				return false;
			}
		}

		internal bool RegisterEcsSystemUpdatePostfix(MethodInfo methodInfo)
		{
			if (!methodInfo.IsStatic)
			{
				return false;
			}
			EcsSystemUpdatePostfixAttribute customAttribute = methodInfo.GetCustomAttribute<EcsSystemUpdatePostfixAttribute>();
			if (customAttribute == null)
			{
				return false;
			}
			try
			{
				System_OnUpdate_Postfix.Hook hook = System_OnUpdate_Postfix.CreateHook(methodInfo);
				System_OnUpdate_Postfix.Options options = new System_OnUpdate_Postfix.Options(customAttribute.OnlyWhenSystemRuns, methodInfo.GetCustomAttribute<ThrottleAttribute>()?.CreateThrottle());
				HookRegistrar.RegisterHook_System_OnUpdate_Postfix(hook, customAttribute.SystemType, options);
				return true;
			}
			catch (Exception ex)
			{
				_log.LogError((object)ex);
				return false;
			}
		}

		internal bool RegisterWhenCreatedWorldsContainAny(MethodInfo methodInfo)
		{
			if (!methodInfo.IsStatic)
			{
				return false;
			}
			WhenCreatedWorldsContainAnyAttribute customAttribute = methodInfo.GetCustomAttribute<WhenCreatedWorldsContainAnyAttribute>();
			if (customAttribute == null)
			{
				return false;
			}
			try
			{
				global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook hook = global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.CreateHook(methodInfo);
				HookRegistrar.RegisterHook_WhenCreatedWorldsContainAny(hook, customAttribute.WorldNames);
				return true;
			}
			catch (Exception ex)
			{
				_log.LogError((object)ex);
				return false;
			}
		}

		internal bool RegisterWhenCreatedWorldsContainAll(MethodInfo methodInfo)
		{
			if (!methodInfo.IsStatic)
			{
				return false;
			}
			WhenCreatedWorldsContainAllAttribute customAttribute = methodInfo.GetCustomAttribute<WhenCreatedWorldsContainAllAttribute>();
			if (customAttribute == null)
			{
				return false;
			}
			try
			{
				global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook hook = global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.CreateHook(methodInfo);
				HookRegistrar.RegisterHook_WhenCreatedWorldsContainAll(hook, customAttribute.WorldNames);
				return true;
			}
			catch (Exception ex)
			{
				_log.LogError((object)ex);
				return false;
			}
		}
	}
}
namespace HookDOTS.API.Spec.Language
{
	internal interface IRule
	{
		internal void Apply(SpecificationContext context);
	}
	public class AfterSystemUpdates
	{
		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		internal AfterSystemUpdates(Specification spec, Type systemType, bool onlyWhenSystemRuns)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
		}

		public AfterSystemUpdatesExecuteAction ExecuteAction(System_OnUpdate_Postfix.HookFunction action)
		{
			System_OnUpdate_Postfix.Hook hook = System_OnUpdate_Postfix.CreateHook(action);
			return new AfterSystemUpdatesExecuteAction(_spec, _systemType, _onlyWhenSystemRuns, hook);
		}

		public AfterSystemUpdatesExecuteAction ExecuteAction(System_OnUpdate_Postfix.HookFunctionVariant1 action)
		{
			System_OnUpdate_Postfix.Hook hook = System_OnUpdate_Postfix.CreateHook(action);
			return new AfterSystemUpdatesExecuteAction(_spec, _systemType, _onlyWhenSystemRuns, hook);
		}

		public AfterSystemUpdatesExecuteAction ExecuteAction(System_OnUpdate_Postfix.Hook action)
		{
			return new AfterSystemUpdatesExecuteAction(_spec, _systemType, _onlyWhenSystemRuns, action);
		}
	}
	public class AfterSystemUpdatesExecuteAction
	{
		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		private System_OnUpdate_Postfix.Hook _hook;

		internal AfterSystemUpdatesExecuteAction(Specification spec, Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Postfix.Hook hook)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
			_hook = hook;
		}

		public AfterSystemUpdatesExecuteActionAlways Always()
		{
			return new AfterSystemUpdatesExecuteActionAlways(_spec, _systemType, _onlyWhenSystemRuns, _hook);
		}

		public AfterSystemUpdatesExecuteActionThrottled Throttled(int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0)
		{
			return new AfterSystemUpdatesExecuteActionThrottled(throttleInterval: new TimeSpan(days, hours, minutes, seconds, milliseconds), spec: _spec, systemType: _systemType, onlyWhenSystemRuns: _onlyWhenSystemRuns, hook: _hook);
		}
	}
	public class AfterSystemUpdatesExecuteActionAlways : IEndpoint
	{
		private class Rule : IRule
		{
			private Type _systemType;

			private bool _onlyWhenSystemRuns;

			private System_OnUpdate_Postfix.Hook _hook;

			internal Rule(Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Postfix.Hook hook)
			{
				_systemType = systemType;
				_onlyWhenSystemRuns = onlyWhenSystemRuns;
				_hook = hook;
			}

			void IRule.Apply(SpecificationContext context)
			{
				System_OnUpdate_Postfix.Options options = new System_OnUpdate_Postfix.Options
				{
					OnlyWhenSystemRuns = _onlyWhenSystemRuns,
					Throttle = null
				};
				context.Registrar.RegisterHook_System_OnUpdate_Postfix(_hook, _systemType, options);
			}
		}

		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		private System_OnUpdate_Postfix.Hook _hook;

		internal AfterSystemUpdatesExecuteActionAlways(Specification spec, Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Postfix.Hook hook)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
			_hook = hook;
		}

		public AfterSystemUpdates And()
		{
			AddRuleToSpec();
			return new AfterSystemUpdates(_spec, _systemType, _onlyWhenSystemRuns);
		}

		public SetupHooks Also()
		{
			AddRuleToSpec();
			return new SetupHooks(_spec);
		}

		public void RegisterChain()
		{
			AddRuleToSpec();
			_spec.Apply();
		}

		private void AddRuleToSpec()
		{
			_spec.AddRule(CreateRule());
		}

		private IRule CreateRule()
		{
			return new Rule(_systemType, _onlyWhenSystemRuns, _hook);
		}
	}
	public class AfterSystemUpdatesExecuteActionThrottled : IEndpoint
	{
		private class Rule : IRule
		{
			private Type _systemType;

			private System_OnUpdate_Postfix.Hook _hook;

			private bool _onlyWhenSystemRuns;

			private TimeSpan _throttleInterval;

			internal Rule(Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Postfix.Hook hook, TimeSpan throttleInterval)
			{
				_systemType = systemType;
				_onlyWhenSystemRuns = onlyWhenSystemRuns;
				_hook = hook;
				_throttleInterval = throttleInterval;
			}

			void IRule.Apply(SpecificationContext context)
			{
				System_OnUpdate_Postfix.Options options = new System_OnUpdate_Postfix.Options
				{
					OnlyWhenSystemRuns = _onlyWhenSystemRuns,
					Throttle = new Throttle(_throttleInterval)
				};
				context.Registrar.RegisterHook_System_OnUpdate_Postfix(_hook, _systemType, options);
			}
		}

		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		private System_OnUpdate_Postfix.Hook _hook;

		private TimeSpan _throttleInterval;

		internal AfterSystemUpdatesExecuteActionThrottled(Specification spec, Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Postfix.Hook hook, TimeSpan throttleInterval)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
			_hook = hook;
			_throttleInterval = throttleInterval;
		}

		public AfterSystemUpdates And()
		{
			AddRuleToSpec();
			return new AfterSystemUpdates(_spec, _systemType, _onlyWhenSystemRuns);
		}

		public SetupHooks Also()
		{
			AddRuleToSpec();
			return new SetupHooks(_spec);
		}

		public void RegisterChain()
		{
			AddRuleToSpec();
			_spec.Apply();
		}

		private void AddRuleToSpec()
		{
			_spec.AddRule(CreateRule());
		}

		private IRule CreateRule()
		{
			return new Rule(_systemType, _onlyWhenSystemRuns, _hook, _throttleInterval);
		}
	}
	public class BeforeSystemUpdates
	{
		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		internal BeforeSystemUpdates(Specification spec, Type systemType, bool onlyWhenSystemRuns)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
		}

		public BeforeSystemUpdatesExecuteDetour ExecuteDetour(System_OnUpdate_Prefix.HookFunction detour)
		{
			System_OnUpdate_Prefix.Hook detour2 = System_OnUpdate_Prefix.CreateHook(detour);
			return ExecuteDetour(detour2);
		}

		public BeforeSystemUpdatesExecuteDetour ExecuteDetour(System_OnUpdate_Prefix.HookFunctionVariant1 detour)
		{
			System_OnUpdate_Prefix.Hook detour2 = System_OnUpdate_Prefix.CreateHook(detour);
			return ExecuteDetour(detour2);
		}

		public BeforeSystemUpdatesExecuteDetour ExecuteDetour(System_OnUpdate_Prefix.HookFunctionVariant2 detour)
		{
			System_OnUpdate_Prefix.Hook detour2 = System_OnUpdate_Prefix.CreateHook(detour);
			return ExecuteDetour(detour2);
		}

		public BeforeSystemUpdatesExecuteDetour ExecuteDetour(System_OnUpdate_Prefix.HookFunctionVariant3 detour)
		{
			System_OnUpdate_Prefix.Hook detour2 = System_OnUpdate_Prefix.CreateHook(detour);
			return ExecuteDetour(detour2);
		}

		public BeforeSystemUpdatesExecuteDetour ExecuteDetour(System_OnUpdate_Prefix.Hook detour)
		{
			return new BeforeSystemUpdatesExecuteDetour(_spec, _systemType, _onlyWhenSystemRuns, detour);
		}
	}
	public class BeforeSystemUpdatesExecuteDetour
	{
		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		private System_OnUpdate_Prefix.Hook _hook;

		internal BeforeSystemUpdatesExecuteDetour(Specification spec, Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Prefix.Hook hook)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
			_hook = hook;
		}

		public BeforeSystemUpdatesExecuteDetourAlways Always()
		{
			return new BeforeSystemUpdatesExecuteDetourAlways(_spec, _systemType, _onlyWhenSystemRuns, _hook);
		}

		public BeforeSystemUpdatesExecuteDetourThrottled Throttled(int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0)
		{
			return new BeforeSystemUpdatesExecuteDetourThrottled(throttleInterval: new TimeSpan(days, hours, minutes, seconds, milliseconds), spec: _spec, systemType: _systemType, onlyWhenSystemRuns: _onlyWhenSystemRuns, hook: _hook);
		}
	}
	public class BeforeSystemUpdatesExecuteDetourAlways : IEndpoint
	{
		private class Rule : IRule
		{
			private Type _systemType;

			private bool _onlyWhenSystemRuns;

			private System_OnUpdate_Prefix.Hook _hook;

			internal Rule(Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Prefix.Hook hook)
			{
				_systemType = systemType;
				_onlyWhenSystemRuns = onlyWhenSystemRuns;
				_hook = hook;
			}

			void IRule.Apply(SpecificationContext context)
			{
				System_OnUpdate_Prefix.Options options = new System_OnUpdate_Prefix.Options
				{
					OnlyWhenSystemRuns = _onlyWhenSystemRuns,
					Throttle = null
				};
				context.Registrar.RegisterHook_System_OnUpdate_Prefix(_hook, _systemType, options);
			}
		}

		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		private System_OnUpdate_Prefix.Hook _hook;

		internal BeforeSystemUpdatesExecuteDetourAlways(Specification spec, Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Prefix.Hook hook)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
			_hook = hook;
		}

		public BeforeSystemUpdates And()
		{
			AddRuleToSpec();
			return new BeforeSystemUpdates(_spec, _systemType, _onlyWhenSystemRuns);
		}

		public SetupHooks Also()
		{
			AddRuleToSpec();
			return new SetupHooks(_spec);
		}

		public void RegisterChain()
		{
			AddRuleToSpec();
			_spec.Apply();
		}

		private void AddRuleToSpec()
		{
			_spec.AddRule(CreateRule());
		}

		private IRule CreateRule()
		{
			return new Rule(_systemType, _onlyWhenSystemRuns, _hook);
		}
	}
	public class BeforeSystemUpdatesExecuteDetourThrottled : IEndpoint
	{
		private class Rule : IRule
		{
			private Type _systemType;

			private bool _onlyWhenSystemRuns;

			private System_OnUpdate_Prefix.Hook _hook;

			private TimeSpan _throttleInterval;

			internal Rule(Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Prefix.Hook hook, TimeSpan throttleInterval)
			{
				_systemType = systemType;
				_onlyWhenSystemRuns = onlyWhenSystemRuns;
				_hook = hook;
				_throttleInterval = throttleInterval;
			}

			void IRule.Apply(SpecificationContext context)
			{
				System_OnUpdate_Prefix.Options options = new System_OnUpdate_Prefix.Options
				{
					OnlyWhenSystemRuns = _onlyWhenSystemRuns,
					Throttle = new Throttle(_throttleInterval)
				};
				context.Registrar.RegisterHook_System_OnUpdate_Prefix(_hook, _systemType, options);
			}
		}

		private Specification _spec;

		private Type _systemType;

		private bool _onlyWhenSystemRuns;

		private System_OnUpdate_Prefix.Hook _hook;

		private TimeSpan _throttleInterval;

		internal BeforeSystemUpdatesExecuteDetourThrottled(Specification spec, Type systemType, bool onlyWhenSystemRuns, System_OnUpdate_Prefix.Hook hook, TimeSpan throttleInterval)
		{
			_spec = spec;
			_systemType = systemType;
			_onlyWhenSystemRuns = onlyWhenSystemRuns;
			_hook = hook;
			_throttleInterval = throttleInterval;
		}

		public BeforeSystemUpdates And()
		{
			AddRuleToSpec();
			return new BeforeSystemUpdates(_spec, _systemType, _onlyWhenSystemRuns);
		}

		public SetupHooks Also()
		{
			AddRuleToSpec();
			return new SetupHooks(_spec);
		}

		public void RegisterChain()
		{
			AddRuleToSpec();
			_spec.Apply();
		}

		private void AddRuleToSpec()
		{
			_spec.AddRule(CreateRule());
		}

		private IRule CreateRule()
		{
			return new Rule(_systemType, _onlyWhenSystemRuns, _hook, _throttleInterval);
		}
	}
	internal interface IEndpoint
	{
		SetupHooks Also();

		void RegisterChain();
	}
	public class SetupHooks
	{
		private Specification _spec;

		internal SetupHooks(Specification spec)
		{
			_spec = spec;
		}

		public BeforeSystemUpdates BeforeSystemUpdates<TSystemType>(bool onlyWhenSystemRuns = true)
		{
			return new BeforeSystemUpdates(_spec, typeof(TSystemType), onlyWhenSystemRuns);
		}

		public AfterSystemUpdates AfterSystemUpdates<TSystemType>(bool onlyWhenSystemRuns = true)
		{
			return new AfterSystemUpdates(_spec, typeof(TSystemType), onlyWhenSystemRuns);
		}

		public WhenCreatedWorldsContainAny WhenCreatedWorldsContainAny(IEnumerable<string> worldNames)
		{
			return new WhenCreatedWorldsContainAny(_spec, worldNames);
		}

		public WhenCreatedWorldsContainAll WhenCreatedWorldsContainAll(IEnumerable<string> worldNames)
		{
			return new WhenCreatedWorldsContainAll(_spec, worldNames);
		}
	}
	public class WhenCreatedWorldsContainAll
	{
		private Specification _spec;

		private IEnumerable<string> _worldNames;

		internal WhenCreatedWorldsContainAll(Specification spec, IEnumerable<string> worldNames)
		{
			_spec = spec;
			_worldNames = worldNames;
		}

		public WhenCreatedWorldsContainAllExecuteActionOnce ExecuteActionOnce(global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.HookFunction action)
		{
			global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook hook = global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.CreateHook(action);
			return new WhenCreatedWorldsContainAllExecuteActionOnce(_spec, _worldNames, hook);
		}

		public WhenCreatedWorldsContainAllExecuteActionOnce ExecuteActionOnce(global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.HookFunctionVariant1 action)
		{
			global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook hook = global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.CreateHook(action);
			return new WhenCreatedWorldsContainAllExecuteActionOnce(_spec, _worldNames, hook);
		}

		public WhenCreatedWorldsContainAllExecuteActionOnce ExecuteActionOnce(global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook action)
		{
			return new WhenCreatedWorldsContainAllExecuteActionOnce(_spec, _worldNames, action);
		}
	}
	public class WhenCreatedWorldsContainAllExecuteActionOnce : IEndpoint
	{
		private class Rule : IRule
		{
			private IEnumerable<string> _worldNames;

			private global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook _hook;

			internal Rule(IEnumerable<string> worldNames, global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook hook)
			{
				_worldNames = worldNames;
				_hook = hook;
			}

			void IRule.Apply(SpecificationContext context)
			{
				context.Registrar.RegisterHook_WhenCreatedWorldsContainAll(_hook, _worldNames);
			}
		}

		private Specification _spec;

		private IEnumerable<string> _worldNames;

		private global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook _hook;

		internal WhenCreatedWorldsContainAllExecuteActionOnce(Specification spec, IEnumerable<string> worldNames, global::HookDOTS.Hooks.WhenCreatedWorldsContainAll.Hook hook)
		{
			_spec = spec;
			_worldNames = worldNames;
			_hook = hook;
		}

		public WhenCreatedWorldsContainAll And()
		{
			AddRuleToSpec();
			return new WhenCreatedWorldsContainAll(_spec, _worldNames);
		}

		public SetupHooks Also()
		{
			AddRuleToSpec();
			return new SetupHooks(_spec);
		}

		public void RegisterChain()
		{
			AddRuleToSpec();
			_spec.Apply();
		}

		private void AddRuleToSpec()
		{
			_spec.AddRule(CreateRule());
		}

		private IRule CreateRule()
		{
			return new Rule(_worldNames, _hook);
		}
	}
	public class WhenCreatedWorldsContainAny
	{
		private Specification _spec;

		private IEnumerable<string> _worldNames;

		internal WhenCreatedWorldsContainAny(Specification spec, IEnumerable<string> worldNames)
		{
			_spec = spec;
			_worldNames = worldNames;
		}

		public WhenCreatedWorldsContainAnyExecuteActionOnce ExecuteActionOnce(global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.HookFunction action)
		{
			global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook hook = global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.CreateHook(action);
			return new WhenCreatedWorldsContainAnyExecuteActionOnce(_spec, _worldNames, hook);
		}

		public WhenCreatedWorldsContainAnyExecuteActionOnce ExecuteActionOnce(global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.HookFunctionVariant1 action)
		{
			global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook hook = global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.CreateHook(action);
			return new WhenCreatedWorldsContainAnyExecuteActionOnce(_spec, _worldNames, hook);
		}

		public WhenCreatedWorldsContainAnyExecuteActionOnce ExecuteActionOnce(global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook action)
		{
			return new WhenCreatedWorldsContainAnyExecuteActionOnce(_spec, _worldNames, action);
		}
	}
	public class WhenCreatedWorldsContainAnyExecuteActionOnce
	{
		private class Rule : IRule
		{
			private IEnumerable<string> _worldNames;

			private global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook _hook;

			internal Rule(IEnumerable<string> worldNames, global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook hook)
			{
				_worldNames = worldNames;
				_hook = hook;
			}

			void IRule.Apply(SpecificationContext context)
			{
				context.Registrar.RegisterHook_WhenCreatedWorldsContainAny(_hook, _worldNames);
			}
		}

		private Specification _spec;

		private IEnumerable<string> _worldNames;

		private global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook _hook;

		internal WhenCreatedWorldsContainAnyExecuteActionOnce(Specification spec, IEnumerable<string> worldNames, global::HookDOTS.Hooks.WhenCreatedWorldsContainAny.Hook hook)
		{
			_spec = spec;
			_worldNames = worldNames;
			_hook = hook;
		}

		public WhenCreatedWorldsContainAny And()
		{
			AddRuleToSpec();
			return new WhenCreatedWorldsContainAny(_spec, _worldNames);
		}

		public SetupHooks Also()
		{
			AddRuleToSpec();
			return new SetupHooks(_spec);
		}

		public void RegisterChain()
		{
			AddRuleToSpec();
			_spec.Apply();
		}

		private void AddRuleToSpec()
		{
			_spec.AddRule(CreateRule());
		}

		private IRule CreateRule()
		{
			return new Rule(_worldNames, _hook);
		}
	}
	internal class Specification
	{
		internal SpecificationContext Context;

		private List<IRule> _rules = new List<IRule>();

		private List<List<IRule>> _history = new List<List<IRule>>();

		internal Specification(SpecificationContext context)
		{
			Context = context;
		}

		internal Specification AddRule(IRule rule)
		{
			_rules.Add(rule);
			return this;
		}

		internal void Apply()
		{
			foreach (IRule rule in _rules)
			{
				rule.Apply(Context);
			}
			_history.Add(_rules);
			_rules = new List<IRule>();
		}
	}
	internal class SpecificationContext
	{
		public HookRegistrar Registrar;

		internal SpecificationContext(HookRegistrar registrar)
		{
			Registrar = registrar;
		}
	}
}
namespace HookDOTS.API.Attributes
{
	[AttributeUsage(AttributeTargets.Method)]
	public class EcsSystemUpdatePostfixAttribute : Attribute
	{
		public Type SystemType { get; }

		public bool OnlyWhenSystemRuns { get; }

		public EcsSystemUpdatePostfixAttribute(Type systemType, bool onlyWhenSystemRuns = true)
		{
			SystemType = systemType;
			OnlyWhenSystemRuns = onlyWhenSystemRuns;
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class EcsSystemUpdatePrefixAttribute : Attribute
	{
		public Type SystemType { get; }

		public bool OnlyWhenSystemRuns { get; }

		public EcsSystemUpdatePrefixAttribute(Type systemType, bool onlyWhenSystemRuns = true)
		{
			SystemType = systemType;
			OnlyWhenSystemRuns = onlyWhenSystemRuns;
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class ThrottleAttribute : Attribute
	{
		public TimeSpan Interval;

		public ThrottleAttribute(int days = 0, int hours = 0, int minutes = 0, int seconds = 0, int milliseconds = 0)
		{
			Interval = new TimeSpan(days, hours, minutes, seconds, milliseconds);
		}

		public Throttle CreateThrottle()
		{
			return new Throttle(Interval);
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class WhenCreatedWorldsContainAllAttribute : Attribute
	{
		public IEnumerable<string> WorldNames;

		public WhenCreatedWorldsContainAllAttribute(params string[] worldNames)
		{
			WorldNames = worldNames;
		}
	}
	[AttributeUsage(AttributeTargets.Method)]
	public class WhenCreatedWorldsContainAnyAttribute : Attribute
	{
		public IEnumerable<string> WorldNames;

		public WhenCreatedWorldsContainAnyAttribute(params string[] worldNames)
		{
			WorldNames = worldNames;
		}
	}
}