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;
}
}
}