Decompiled source of AdvancedWardenObjective v2.2.6
AdvancedWardenObjective.dll
Decompiled a month ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using AIGraph; using AK; using AWO.CustomFields; using AWO.Jsons; using AWO.Modules.TSL; using AWO.Modules.WEE; using AWO.Modules.WEE.Detours; using AWO.Modules.WEE.Events; using AWO.Modules.WEE.JsonInjects; using AWO.Modules.WEE.Replicators; using AWO.Modules.WOE; using AWO.Networking; using AWO.Networking.Patches; using AWO.Sessions; using AWO.Utils; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using BepInEx.Unity.IL2CPP.Utils; using BepInEx.Unity.IL2CPP.Utils.Collections; using CellMenu; using ChainedPuzzles; using Enemies; using Expedition; using FluffyUnderware.Curvy.Utils; using GTFO.API; using GTFO.API.Extensions; using GameData; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.Runtime; using Il2CppJsonNet; using Il2CppJsonNet.Linq; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using InjectLib.FieldInjection; using InjectLib.JsonNETInjection; using InjectLib.JsonNETInjection.Converter; using InjectLib.JsonNETInjection.Handler; using InjectLib.JsonNETInjection.Supports; using LevelGeneration; using Localization; using MTFO.Ext.PartialData; using Microsoft.CodeAnalysis; using Player; using PlayerCoverage; using SNetwork; using SemanticVersioning; using TMPro; using UnityEngine; using UnityEngine.UI; [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("AdvancedWardenObjective")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("2.2.5")] [assembly: AssemblyInformationalVersion("2.2.5+gite0422a3-dirty-master.e0422a380c662016852b4a4545800532010373b5")] [assembly: AssemblyProduct("AdvancedWardenObjective")] [assembly: AssemblyTitle("AdvancedWardenObjective")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.5.0")] [module: UnverifiableCode] 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; } } } namespace AWO { internal static class Configuration { public static bool VerboseEnabled { get; private set; } public static void Init() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown BindAll(new ConfigFile(Path.Combine(Paths.ConfigPath, "AWO.cfg"), true)); bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Verbose logging is enabled: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(VerboseEnabled); } Logger.Debug(val); } private static void BindAll(ConfigFile config) { string text = "General Settings"; string text2 = "Enable Verbose Debug Logging"; string text3 = "Prints some additional logs to the console, which may be useful for rundown devs"; VerboseEnabled = config.Bind<bool>(text, text2, false, text3).Value; } } [BepInPlugin("GTFO.AWO", "AWO", "2.2.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class EntryPoint : BasePlugin { [StructLayout(LayoutKind.Sequential, Size = 1)] public struct Coroutines { public static float CountdownStarted { get; set; } } [StructLayout(LayoutKind.Sequential, Size = 1)] public struct TimerMods { public static float TimeModifier { get; set; } public static Color TimerColor { get; set; } public static float SpeedModifier { get; set; } public static LocaleText TimerTitleText { get; set; } public static LocaleText TimerBodyText { get; set; } } public static bool PartialDataIsLoaded { get; private set; } = false; public static BlackoutState BlackoutState { get; private set; } = new BlackoutState(); public static SessionRandReplicator SessionRand { get; private set; } = new SessionRandReplicator(); public override void Load() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) if (((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value) && value.Metadata.Version.CompareTo(new Version(1, 5, 2, (string)null, (string)null)) >= 0) { Logger.Debug("Flowaria's PartialData v1.5.2(+) support found"); PartialDataIsLoaded = true; } Configuration.Init(); WardenEventExt.Initialize(); new Harmony("AWO.Harmony").PatchAll(); AssetAPI.OnStartupAssetsLoaded += delegate { LevelFailUpdateState.AssetLoaded(); }; LevelAPI.OnBuildDone += OnBuildDone; LevelAPI.OnLevelCleanup += OnLevelCleanup; WOEventDataFields.Init(); SerialLookupManager.Init(); Logger.Info("AWO is done loading!"); } private void OnBuildDone() { BlackoutState.Setup(); SessionRand.Setup(1u, RundownManager.GetActiveExpeditionData().sessionSeed); } private void OnLevelCleanup() { _ = WardenObjectiveManager.m_exitEventsTriggered; WardenObjectiveManager.m_exitEventsTriggered = false; BlackoutState.Cleanup(); SessionRand.Cleanup(); } } internal static class Logger { private static readonly ManualLogSource MLS; private const string Dev = "Dev"; static Logger() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown MLS = new ManualLogSource("AWO"); Logger.Sources.Add((ILogSource)(object)MLS); } private static string Format(string module, object msg) { return $"[{module}] {msg}"; } public static void Info(BepInExInfoLogInterpolatedStringHandler handler) { MLS.LogInfo(handler); } public static void Info(string str) { MLS.LogMessage((object)str); } public static void Info(string module, object data) { MLS.LogMessage((object)Format(module, data)); } public static void Debug(BepInExDebugLogInterpolatedStringHandler handler) { MLS.LogDebug(handler); } public static void Debug(string str) { MLS.LogDebug((object)str); } public static void Debug(string module, object data) { MLS.LogDebug((object)Format(module, data)); } public static void Error(BepInExErrorLogInterpolatedStringHandler handler) { MLS.LogError(handler); } public static void Error(string str) { MLS.LogError((object)str); } public static void Error(string module, object data) { MLS.LogError((object)Format(module, data)); } public static void Warn(BepInExWarningLogInterpolatedStringHandler handler) { MLS.LogWarning(handler); } public static void Warn(string str) { MLS.LogWarning((object)str); } public static void Warn(string module, object data) { MLS.LogWarning((object)Format(module, data)); } public static void Verbose(LogLevel level, string data) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Invalid comparison between Unknown and I4 //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if (!Configuration.VerboseEnabled) { return; } if ((int)level <= 4) { if ((int)level != 2) { if ((int)level == 4) { Warn("Dev", data); } } else { Error("Dev", data); } } else if ((int)level != 16) { if ((int)level == 32) { Debug("Dev", data); } } else { Info("Dev", data); } } } [GeneratedCode("VersionInfoGenerator", "2.0.0+git50a4b1a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "AWO"; public const string Version = "2.2.5"; public const string VersionPrerelease = null; public const string VersionMetadata = "gite0422a3-dirty-master"; public const string SemVer = "2.2.5+gite0422a3-dirty-master"; public const string GitRevShort = "e0422a3-dirty"; public const string GitRevLong = "e0422a380c662016852b4a4545800532010373b5-dirty"; public const string GitBranch = "master"; public const string GitTag = null; public const bool GitIsDirty = true; } } namespace AWO.Utils { public static class DictionaryExtensions { public static TValue GetOrAddNew<TKey, TValue>(this IDictionary<TKey, TValue> dict, TKey key) where TValue : new() { if (!dict.TryGetValue(key, out TValue value)) { value = (dict[key] = new TValue()); } return value; } public static void ForEachValue<TKey, TValue>(this Dictionary<TKey, TValue> dict, Action<TValue> action) where TKey : notnull { foreach (TValue value in dict.Values) { action(value); } } public static void ForEachValue<TKey, TValue>(this ConcurrentDictionary<TKey, TValue> dict, Action<TValue> action) where TKey : notnull { foreach (TValue value in dict.Values) { action(value); } } } public static class GameObjectExtensions { public static bool TryAndGetComponent<T>(this GameObject go, out T component) { component = go.GetComponent<T>(); return component != null; } public static T AddOrGetComponent<T>(this GameObject go) where T : Component { if (!go.TryAndGetComponent<T>(out var component)) { return go.AddComponent<T>(); } return component; } public static string GetFullPath(this GameObject go) { StringBuilder stringBuilder = new StringBuilder(((Object)go).name); Transform parent = go.transform.parent; while ((Object)(object)parent != (Object)null) { stringBuilder.Insert(0, ((Object)parent).name + "/"); parent = parent.parent; } return stringBuilder.ToString(); } } public static class LocalizedTextExtensions { public static string ToText(this LocalizedText text) { return text.HasTranslation ? Text.Get(text.Id) : text.UntranslatedText; } } public static class NumberExtension { public static bool IsPrime(this int num) { if (num < 2) { return false; } if (num % 2 == 0) { return num == 2; } int num2 = (int)Math.Sqrt(num); for (int i = 3; i <= num2; i += 2) { if (num % i == 0) { return false; } } return true; } } public static class RandomExtensions { public static bool MeetProbability(this Random rand, float prob) { if (prob >= 1f) { return true; } if (prob <= 0f) { return false; } return prob >= rand.NextFloat(); } public static float NextRange(this Random rand, float min, float max) { return rand.NextFloat() * (max - min) + min; } public static float NextFloat(this Random rand) { return (float)rand.NextDouble(); } } public static class Vector3Extensions { public static bool IsWithinSqrDistance(this Vector3 a, Vector3 b, float threshold, out float sqrDistance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Vector3 val = a - b; sqrDistance = ((Vector3)(ref val)).sqrMagnitude; return sqrDistance < threshold * threshold; } public static bool IsApproximatelySqrDistance(this Vector3 a, Vector3 b, float threshold, out float sqrDistance) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) Vector3 val = a - b; sqrDistance = ((Vector3)(ref val)).sqrMagnitude; return CurvyUtility.Approximately(sqrDistance, threshold * threshold); } } } namespace AWO.Sessions { internal struct BlackoutStatus { public bool blackoutEnabled; } internal sealed class BlackoutState : IStateReplicatorHolder<BlackoutStatus> { public StateReplicator<BlackoutStatus>? Replicator { get; private set; } public bool BlackoutEnabled { get; private set; } public void Setup() { BlackoutEnabled = false; Replicator = StateReplicator<BlackoutStatus>.Create(1u, new BlackoutStatus { blackoutEnabled = false }, LifeTimeType.Session, this); } public void Cleanup() { BlackoutEnabled = false; Replicator?.Unload(); } public void SetEnabled(bool enabled) { Replicator?.SetState(new BlackoutStatus { blackoutEnabled = enabled }); } public void OnStateChange(BlackoutStatus oldState, BlackoutStatus state, bool isRecall) { //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Invalid comparison between Unknown and I4 //IL_031f: Unknown result type (might be due to invalid IL or missing references) //IL_0324: Unknown result type (might be due to invalid IL or missing references) //IL_032a: Invalid comparison between Unknown and I4 bool flag = !state.blackoutEnabled; foreach (LG_LabDisplay item in LG_Objects.TrackedList<LG_LabDisplay>()) { if ((Object)(object)((item != null) ? item.m_Text : null) != (Object)null) { ((Behaviour)item.m_Text).enabled = flag; } } foreach (LG_ComputerTerminal item2 in LG_Objects.TrackedList<LG_ComputerTerminal>()) { if ((Object)(object)item2 == (Object)null) { continue; } item2.OnProximityExit(); Interact_ComputerTerminal componentInChildren = ((Component)item2).GetComponentInChildren<Interact_ComputerTerminal>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = flag; ((Interact_Base)componentInChildren).SetActive(flag); } if (((Component)item2).gameObject.TryAndGetComponent<GUIX_VirtualSceneLink>(out var component) && (Object)(object)component.m_virtualScene != (Object)null) { GUIX_VirtualCamera virtualCamera = component.m_virtualScene.virtualCamera; float num = (flag ? 0.3f : 0f); float num2 = (flag ? 1000f : 0f); virtualCamera.SetFovAndClip(virtualCamera.paramCamera.fieldOfView, num, num2); } if ((Object)(object)item2.m_text != (Object)null) { ((Behaviour)item2.m_text).enabled = flag; } if (!flag) { PlayerAgent localInteractionSource = item2.m_localInteractionSource; if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger) { item2.ExitFPSView(); } } } foreach (LG_DoorButton item3 in LG_Objects.TrackedList<LG_DoorButton>()) { if ((Object)(object)item3 == (Object)null) { continue; } ((Component)item3.m_anim).gameObject.SetActive(flag); item3.m_enabled = flag; if (flag) { LG_WeakLock componentInChildren2 = ((Component)item3).GetComponentInChildren<LG_WeakLock>(); if ((Object)(object)componentInChildren2 != (Object)null && (int)componentInChildren2.Status != 3) { item3.m_enabled = false; } } } foreach (LG_WeakLock item4 in LG_Objects.TrackedList<LG_WeakLock>()) { if (!((Object)(object)item4 == (Object)null)) { ((Interact_Base)item4.m_intHack).m_isActive = flag; Transform val = ((Component)item4).transform.FindChild("HackableLock/SecurityLock/g_WeakLock/Security_Display_Locked") ?? ((Component)item4).transform.FindChild("HackableLock/Security_Display_Locked"); if ((Object)(object)val != (Object)null) { ((Component)val).gameObject.active = flag; } } } foreach (LG_HSUActivator_Core item5 in LG_Objects.TrackedList<LG_HSUActivator_Core>()) { if ((Object)(object)item5 == (Object)null || !item5.m_isWardenObjective || (int)item5.m_stateReplicator.State.status != 0) { continue; } item5.m_insertHSUInteraction.SetActive(flag); foreach (GameObject item6 in (Il2CppArrayBase<GameObject>)(object)item5.m_activateWhenActive) { item6.SetActive(flag); } } BlackoutEnabled = state.blackoutEnabled; } } internal enum LevelFailMode { Default, Never, AnyPlayerDown } internal struct LevelFailCheck { public LevelFailMode mode; } internal sealed class LevelFailUpdateState { public static StateReplicator<LevelFailCheck>? Replicator; public static bool LevelFailAllowed { get; private set; } = true; public static bool LevelFailWhenAnyPlayerDown { get; private set; } = false; internal static void AssetLoaded() { Replicator = StateReplicator<LevelFailCheck>.Create(1u, new LevelFailCheck { mode = LevelFailMode.Default }, LifeTimeType.Permanent); LG_Factory.OnFactoryBuildStart += Action.op_Implicit((Action)delegate { Replicator.ClearAllRecallSnapshot(); Replicator.SetState(new LevelFailCheck { mode = LevelFailMode.Default }); }); Replicator.OnStateChanged += OnStateChanged; LevelAPI.OnLevelCleanup += LevelCleanup; } private static void LevelCleanup() { SetFailAllowed(allowed: true); } public static void SetFailAllowed(bool allowed) { Replicator?.SetState(new LevelFailCheck { mode = ((!allowed) ? LevelFailMode.Never : LevelFailMode.Default) }); } public static void SetFailWhenAnyPlayerDown(bool enabled) { Replicator?.SetState(new LevelFailCheck { mode = (enabled ? LevelFailMode.AnyPlayerDown : LevelFailMode.Default) }); } private static void OnStateChanged(LevelFailCheck _, LevelFailCheck state, bool __) { switch (state.mode) { case LevelFailMode.Default: LevelFailAllowed = true; LevelFailWhenAnyPlayerDown = false; break; case LevelFailMode.Never: LevelFailAllowed = false; LevelFailWhenAnyPlayerDown = false; break; case LevelFailMode.AnyPlayerDown: LevelFailAllowed = true; LevelFailWhenAnyPlayerDown = true; break; } } } public static class LG_Objects { public static Dictionary<Type, HashSet<Component>> TrackedTypes { get; private set; } static LG_Objects() { TrackedTypes = new Dictionary<Type, HashSet<Component>> { { typeof(LG_ComputerTerminal), new HashSet<Component>() }, { typeof(LG_DoorButton), new HashSet<Component>() }, { typeof(LG_HSUActivator_Core), new HashSet<Component>() }, { typeof(LG_LabDisplay), new HashSet<Component>() }, { typeof(LG_WeakLock), new HashSet<Component>() } }; LevelAPI.OnLevelCleanup += Clear; } private static void Clear() { TrackedTypes.ForEachValue<Type, HashSet<Component>>(delegate(HashSet<Component> set) { set.Clear(); }); } public static IEnumerable<T> TrackedList<T>() where T : Component { if (TrackedTypes.TryGetValue(typeof(T), out HashSet<Component> value)) { return value.Cast<T>(); } return Enumerable.Empty<T>(); } public static void AddToTrackedList(Component itemToAdd) { if (TrackedTypes.TryGetValue(((object)itemToAdd).GetType(), out HashSet<Component> value)) { value.Add(itemToAdd); } } public static void RemoveFromTrackedList(Component itemToRemove) { if (TrackedTypes.TryGetValue(((object)itemToRemove).GetType(), out HashSet<Component> value)) { value.Remove(itemToRemove); } } } public struct SessionRandState { public uint currentStep; } public sealed class SessionRandReplicator : IStateReplicatorHolder<SessionRandState> { public StateReplicator<SessionRandState>? Replicator { get; private set; } public int Seed { get; private set; } public uint Step { get; private set; } public uint State { get; private set; } public void Setup(uint id, int seed) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown Seed = seed; Step = 0u; State = (uint)Seed; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(12, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SessionSeed "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(Seed); } Logger.Info(val); Replicator = StateReplicator<SessionRandState>.Create(id, new SessionRandState { currentStep = Step }, LifeTimeType.Session, this); } public void Cleanup() { Step = 0u; Replicator?.Unload(); } public void SyncStep() { Replicator?.SetState(new SessionRandState { currentStep = Step }); } public void OnStateChange(SessionRandState oldState, SessionRandState state, bool isRecall) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (state.currentStep != Step) { bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(47, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Jumping ahead from local step "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(Step); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" to session step "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(state.currentStep); } Logger.Debug(val); Step = state.currentStep; Jump(Step); } else { Logger.Verbose((LogLevel)32, "No change in SessionRand step from received state"); } } public uint Next() { Replicator?.SetStateUnsynced(new SessionRandState { currentStep = ++Step }); uint num = (State += 2654435769u); num ^= num >> 16; num *= 569420461; num ^= num >> 15; num *= 1935289751; return num ^ (num >> 15); } public void Jump(ulong steps) { if (steps != 0) { State += (uint)(int)(steps * 2654435769u); } } public int NextInt() { return (int)(Next() & 0x7FFFFFFF); } public int NextInt(int max) { if (max <= 0) { throw new ArgumentOutOfRangeException("max", "max must be positive."); } return (int)(NextFloat() * (float)max); } public int NextInt(int min, int max) { if (min > max) { throw new ArgumentOutOfRangeException("min", "min must be less than or equal to max."); } return min + NextInt(max - min); } public float NextFloat() { return (float)Next() * 2.3283064E-10f; } } } namespace AWO.Sessions.Patches { [HarmonyPatch] internal static class Patch_InteractionOnBlackout { [HarmonyPatch(typeof(LG_ComputerTerminal), "OnProximityEnter")] [HarmonyPatch(typeof(LG_ComputerTerminal), "OnProximityExit")] [HarmonyPatch(typeof(LG_DoorButton), "OnWeakLockUnlocked")] [HarmonyPrefix] private static bool Pre_ToggleInteraction() { return !EntryPoint.BlackoutState.BlackoutEnabled; } } [HarmonyPatch] internal static class Patch_LevelFailCheck { [HarmonyPatch(typeof(WardenObjectiveManager), "CheckExpeditionFailed")] [HarmonyPostfix] [HarmonyAfter(new string[] { })] private static void Post_CheckLevelFail(ref bool __result) { if (!LevelFailUpdateState.LevelFailAllowed) { __result = false; } else if (LevelFailUpdateState.LevelFailWhenAnyPlayerDown && HasAnyDownedPlayer()) { __result = true; } } private static bool HasAnyDownedPlayer() { Enumerator<PlayerAgent> enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!((Agent)current).Alive) { return true; } } return false; } } [HarmonyPatch] internal static class Patch_LG_ObjectsTrack { [CompilerGenerated] private sealed class <TargetMethods>d__0 : IEnumerable<MethodBase>, IEnumerable, IEnumerator<MethodBase>, IDisposable, IEnumerator { private int <>1__state; private MethodBase <>2__current; private int <>l__initialThreadId; MethodBase IEnumerator<MethodBase>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <TargetMethods>d__0(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = AccessTools.Method(typeof(LG_ComputerTerminal), "Setup", (Type[])null, (Type[])null); <>1__state = 1; return true; case 1: <>1__state = -1; <>2__current = AccessTools.Method(typeof(LG_DoorButton), "Setup", (Type[])null, (Type[])null); <>1__state = 2; return true; case 2: <>1__state = -1; <>2__current = AccessTools.Method(typeof(LG_HSUActivator_Core), "Start", (Type[])null, (Type[])null); <>1__state = 3; return true; case 3: <>1__state = -1; <>2__current = AccessTools.Method(typeof(LG_LabDisplay), "GenerateText", new Type[2] { typeof(int), typeof(SubComplex) }, (Type[])null); <>1__state = 4; return true; case 4: <>1__state = -1; <>2__current = AccessTools.Method(typeof(LG_WeakLock), "Setup", (Type[])null, (Type[])null); <>1__state = 5; return true; case 5: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<MethodBase> IEnumerable<MethodBase>.GetEnumerator() { if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; return this; } return new <TargetMethods>d__0(0); } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<MethodBase>)this).GetEnumerator(); } } [IteratorStateMachine(typeof(<TargetMethods>d__0))] [HarmonyTargetMethods] private static IEnumerable<MethodBase> TargetMethods() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <TargetMethods>d__0(-2); } [HarmonyPostfix] private static void Post_TrackObject(Component __instance) { LG_Objects.AddToTrackedList(__instance); } } } namespace AWO.Networking { public interface IStateReplicatorHolder<S> where S : struct { StateReplicator<S>? Replicator { get; } void OnStateChange(S oldState, S state, bool isRecall); } public sealed class ReplicatorHandshake { public delegate void ClientRequestedSyncDel(SNet_Player requestedPlayer); public struct Packet { public uint replicatorID; public PacketAction action; } public enum PacketAction : byte { Created, Destroyed, SyncRequest } public sealed class Data { public bool SetupOnHost = false; public bool SetupOnClient = false; } private readonly Dictionary<uint, Data> _Lookup = new Dictionary<uint, Data>(); public string EventName { get; private set; } public bool IsReadyToSync { get; private set; } public event ClientRequestedSyncDel OnClientSyncRequested; public static ReplicatorHandshake Create(string guid) { if (string.IsNullOrWhiteSpace(guid)) { return null; } string text = "RHs" + guid; return NetworkAPI.IsEventRegistered(text) ? null : new ReplicatorHandshake(text); } private ReplicatorHandshake(string eventName) { EventName = eventName; NetworkAPI.RegisterEvent<Packet>(eventName, (Action<ulong, Packet>)OnSyncAction); Patch_OnRecallDone.OnRecallDone += delegate { Logger.Warn("ReplicatorHandshake: Client sending sync request"); ClientSyncRequest(); }; } private void ClientSyncRequest() { if (SNet.IsMaster) { return; } foreach (uint key in _Lookup.Keys) { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = key, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); } } public void Reset() { _Lookup.Clear(); } private void OnSyncAction(ulong sender, Packet packet) { //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Expected O, but got Unknown if (!SNet.IsMaster && sender == SNet.Master.Lookup) { if (packet.action == PacketAction.Created) { SetHostState(packet.replicatorID, isSetup: true); } else if (packet.action == PacketAction.Destroyed) { SetHostState(packet.replicatorID, isSetup: false); } } else { if (!SNet.IsMaster) { return; } if (packet.action == PacketAction.Created) { SetClientState(packet.replicatorID, isSetup: true); } else if (packet.action == PacketAction.Destroyed) { SetClientState(packet.replicatorID, isSetup: false); } else { if (packet.action != PacketAction.SyncRequest) { return; } SNet_Player requestedPlayer = default(SNet_Player); if (!SNet.TryGetPlayer(sender, ref requestedPlayer)) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cannot find player from sender: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(sender); } Logger.Error(val); } else { this.OnClientSyncRequested?.Invoke(requestedPlayer); } } } } public void UpdateCreated(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, (SNet_ChannelType)2); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, SNet.Master, (SNet_ChannelType)2); } else { Logger.Error("Handshake::MASTER is NULL in lobby; This should NOT happen!!!!!!!!!!!!"); } } else { Logger.Error("Handshake::Session Type StateReplicator cannot be created without lobby!"); } } public void UpdateDestroyed(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, (SNet_ChannelType)2); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, SNet.Master, (SNet_ChannelType)2); } else { Logger.Error("Handshake::MASTER is NULL in lobby; This should NOT happen!!!!!!!!!!!!"); } } else { Logger.Error("Handshake::Session Type StateReplicator cannot be created without lobby!"); } } private void SetHostState(uint id, bool isSetup) { if (_Lookup.TryGetValue(id, out Data value)) { value.SetupOnHost = isSetup; } else { _Lookup[id] = new Data { SetupOnHost = isSetup }; } UpdateSyncState(id); } private void SetClientState(uint id, bool isSetup) { if (_Lookup.TryGetValue(id, out Data value)) { value.SetupOnClient = isSetup; } else { _Lookup[id] = new Data { SetupOnClient = isSetup }; } UpdateSyncState(id); } private void UpdateSyncState(uint id) { bool isReadyToSync = IsReadyToSync; if (_Lookup.TryGetValue(id, out Data value)) { IsReadyToSync = value.SetupOnHost && value.SetupOnClient; } else { IsReadyToSync = false; } if (IsReadyToSync && isReadyToSync != IsReadyToSync && SNet.HasMaster && !SNet.IsMaster) { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); } } } public delegate void OnReceiveDel<S>(ulong sender, uint replicatorID, S newState) where S : struct; public static class StatePayloads { public enum Size { State4Byte = 4, State8Byte = 8, State16Byte = 16, State32Byte = 32, State48Byte = 48, State64Byte = 64, State80Byte = 80, State96Byte = 96, State128Byte = 128, State196Byte = 196, State256Byte = 256 } public static Size GetSizeType(int size) { Size size2 = Size.State8Byte; foreach (object value in Enum.GetValues(typeof(Size))) { if (size <= (int)value && (int)size2 < (int)value) { size2 = (Size)value; break; } } return size2; } public static IReplicatorEvent<S> CreateEvent<S>(Size size, string eventName, OnReceiveDel<S> onReceiveCallback) where S : struct { return size switch { Size.State4Byte => ReplicatorPayloadWrapper<S, StatePayload4Byte>.Create(eventName, onReceiveCallback), Size.State8Byte => ReplicatorPayloadWrapper<S, StatePayload8Byte>.Create(eventName, onReceiveCallback), Size.State16Byte => ReplicatorPayloadWrapper<S, StatePayload16Byte>.Create(eventName, onReceiveCallback), Size.State32Byte => ReplicatorPayloadWrapper<S, StatePayload32Byte>.Create(eventName, onReceiveCallback), Size.State48Byte => ReplicatorPayloadWrapper<S, StatePayload48Byte>.Create(eventName, onReceiveCallback), Size.State64Byte => ReplicatorPayloadWrapper<S, StatePayload64Byte>.Create(eventName, onReceiveCallback), Size.State80Byte => ReplicatorPayloadWrapper<S, StatePayload80Byte>.Create(eventName, onReceiveCallback), Size.State96Byte => ReplicatorPayloadWrapper<S, StatePayload96Byte>.Create(eventName, onReceiveCallback), Size.State128Byte => ReplicatorPayloadWrapper<S, StatePayload128Byte>.Create(eventName, onReceiveCallback), Size.State196Byte => ReplicatorPayloadWrapper<S, StatePayload196Byte>.Create(eventName, onReceiveCallback), Size.State256Byte => ReplicatorPayloadWrapper<S, StatePayload256Byte>.Create(eventName, onReceiveCallback), _ => null, }; } public static S Get<S>(byte[] bytes, int bytesLength) where S : struct { int num = Marshal.SizeOf(typeof(S)); if (num > bytesLength) { throw new ArgumentException($"StateData Exceed size of {bytesLength} : Unable to Deserialize", "S"); } IntPtr intPtr = Marshal.AllocHGlobal(num); Marshal.Copy(bytes, 0, intPtr, num); S result = (S)Marshal.PtrToStructure(intPtr, typeof(S)); Marshal.FreeHGlobal(intPtr); return result; } public static void Set<S>(S stateData, int size, ref byte[] payloadBytes) where S : struct { int num = Marshal.SizeOf(stateData); if (num > size) { throw new ArgumentException($"StateData Exceed size of {size} : Unable to Serialize", "S"); } byte[] array = new byte[size]; IntPtr intPtr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(stateData, intPtr, fDeleteOld: false); Marshal.Copy(intPtr, array, 0, size); Marshal.FreeHGlobal(intPtr); payloadBytes = array; } } public interface IReplicatorEvent<S> where S : struct { string Name { get; } bool IsRegistered { get; } void Invoke(uint replicatorID, S data); void Invoke(uint replicatorID, S data, SNet_ChannelType channelType); void Invoke(uint replicatorID, S data, SNet_Player target); void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType); } public class ReplicatorPayloadWrapper<S, P> : IReplicatorEvent<S> where S : struct where P : struct, IStatePayload { public string Name { get; private set; } public bool IsRegistered { get; private set; } = false; public static IReplicatorEvent<S> Create(string eventName, OnReceiveDel<S> onReceiveCallback) { ReplicatorPayloadWrapper<S, P> replicatorPayloadWrapper = new ReplicatorPayloadWrapper<S, P>(); replicatorPayloadWrapper.Register(eventName, onReceiveCallback); object result; if (!replicatorPayloadWrapper.IsRegistered) { result = null; } else { IReplicatorEvent<S> replicatorEvent = replicatorPayloadWrapper; result = replicatorEvent; } return (IReplicatorEvent<S>)result; } public void Register(string eventName, OnReceiveDel<S> onReceiveCallback) { OnReceiveDel<S> onReceiveCallback2 = onReceiveCallback; if (!IsRegistered && !NetworkAPI.IsEventRegistered(eventName)) { NetworkAPI.RegisterEvent<P>(eventName, (Action<ulong, P>)delegate(ulong sender, P payload) { onReceiveCallback2?.Invoke(sender, payload.ID, payload.Get<S>()); }); IsRegistered = true; Name = eventName; } } public void Invoke(uint replicatorID, S data) { P val = new P { ID = replicatorID }; val.Set(data); NetworkAPI.InvokeEvent<P>(Name, val, (SNet_ChannelType)2); } public void Invoke(uint replicatorID, S data, SNet_ChannelType channelType) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) P val = new P { ID = replicatorID }; val.Set(data); NetworkAPI.InvokeEvent<P>(Name, val, channelType); } public void Invoke(uint replicatorID, S data, SNet_Player target) { P val = new P { ID = replicatorID }; val.Set(data); NetworkAPI.InvokeEvent<P>(Name, val, target, (SNet_ChannelType)2); } public void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) P val = new P { ID = replicatorID }; val.Set(data); NetworkAPI.InvokeEvent<P>(Name, val, target, channelType); } } public interface IStatePayload { uint ID { get; set; } S Get<S>() where S : struct; void Set<S>(S stateData) where S : struct; } public struct StatePayload4Byte : IStatePayload { public const int Size = 4; private uint id; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] PayloadBytes; public uint ID { get { return id; } set { id = value; } } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 4); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 4, ref PayloadBytes); } } public struct StatePayload8Byte : IStatePayload { public const int Size = 8; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 8); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 8, ref PayloadBytes); } } public struct StatePayload16Byte : IStatePayload { public const int Size = 16; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 16); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 16, ref PayloadBytes); } } public struct StatePayload32Byte : IStatePayload { public const int Size = 32; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 32); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 32, ref PayloadBytes); } } public struct StatePayload48Byte : IStatePayload { public const int Size = 48; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 48); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 48, ref PayloadBytes); } } public struct StatePayload64Byte : IStatePayload { public const int Size = 64; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 64); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 64, ref PayloadBytes); } } public struct StatePayload80Byte : IStatePayload { public const int Size = 80; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 80); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 80, ref PayloadBytes); } } public struct StatePayload96Byte : IStatePayload { public const int Size = 96; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 96); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 96, ref PayloadBytes); } } public struct StatePayload128Byte : IStatePayload { public const int Size = 128; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 128); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 128, ref PayloadBytes); } } public struct StatePayload196Byte : IStatePayload { public const int Size = 196; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 196); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 196, ref PayloadBytes); } } public struct StatePayload256Byte : IStatePayload { public const int Size = 256; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 256); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 256, ref PayloadBytes); } } public enum LifeTimeType { Permanent, Session } public sealed class StateReplicator<S> where S : struct { private readonly Dictionary<eBufferType, S> _RecallStateSnapshots = new Dictionary<eBufferType, S>(); public static readonly string Name; public static readonly string HashName; public static readonly string ClientRequestEventName; public static readonly string HostSetStateEventName; public static readonly string HostSetRecallStateEventName; public static readonly int StateSize; public static readonly StatePayloads.Size StateSizeType; private static readonly IReplicatorEvent<S> _C_RequestEvent; private static readonly IReplicatorEvent<S> _H_SetStateEvent; private static readonly IReplicatorEvent<S> _H_SetRecallStateEvent; private static readonly ReplicatorHandshake _Handshake; private static readonly Dictionary<uint, StateReplicator<S>> _Replicators; public bool IsValid => ID != 0; public bool IsInvalid => ID == 0; public uint ID { get; private set; } public LifeTimeType LifeTime { get; private set; } public IStateReplicatorHolder<S> Holder { get; private set; } public S State { get; private set; } public bool ClientSendStateAllowed { get; set; } = true; public bool CanSendToClient => SNet.IsInLobby && SNet.IsMaster; public bool CanSendToHost => SNet.IsInLobby && !SNet.IsMaster && SNet.HasMaster && ClientSendStateAllowed; public event Action<S, S, bool> OnStateChanged; public void SetState(S state) { if (!IsInvalid) { DoSync(state); } } public void SetStateUnsynced(S state) { if (!IsInvalid) { State = state; } } public void Unload() { if (IsValid) { _Replicators.Remove(ID); _RecallStateSnapshots.Clear(); _Handshake.UpdateDestroyed(ID); ID = 0u; } } private void DoSync(S newState) { if (!IsInvalid) { if (CanSendToClient) { _H_SetStateEvent.Invoke(ID, newState); Internal_ChangeState(newState, isRecall: false); } else if (CanSendToHost) { _C_RequestEvent.Invoke(ID, newState, SNet.Master); } } } private void Internal_ChangeState(S state, bool isRecall) { if (!IsInvalid) { S state2 = State; State = state; this.OnStateChanged?.Invoke(state2, state, isRecall); Holder?.OnStateChange(state2, state, isRecall); } } private void SendDropInState(SNet_Player target) { if (!IsInvalid) { if ((Object)(object)target == (Object)null) { Logger.Error("SendDropInState::Target was null??"); } else { _H_SetRecallStateEvent.Invoke(ID, State, target); } } } public void ClearAllRecallSnapshot() { if (!IsInvalid) { _RecallStateSnapshots.Clear(); } } private void SaveSnapshot(eBufferType type) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!IsInvalid) { _RecallStateSnapshots[type] = State; } } private void RestoreSnapshot(eBufferType type) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) if (IsInvalid || !CanSendToClient) { return; } if (_RecallStateSnapshots.TryGetValue(type, out var value)) { _H_SetRecallStateEvent.Invoke(ID, value); Internal_ChangeState(value, isRecall: true); return; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RestoreSnapshot"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("::There was no snapshot for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eBufferType>(type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("?"); } Logger.Error(val); } static StateReplicator() { _Replicators = new Dictionary<uint, StateReplicator<S>>(); Name = typeof(S).Name; StateSize = Marshal.SizeOf(typeof(S)); StateSizeType = StatePayloads.GetSizeType(StateSize); using MD5 mD = MD5.Create(); byte[] inArray = mD.ComputeHash(Encoding.UTF8.GetBytes(typeof(S).FullName)); HashName = Convert.ToBase64String(inArray); ClientRequestEventName = "SRs" + Name + "-" + HashName; HostSetStateEventName = "SRr" + Name + "-" + HashName; HostSetRecallStateEventName = "SRre" + Name + "-" + HashName; _C_RequestEvent = StatePayloads.CreateEvent<S>(StateSizeType, ClientRequestEventName, ClientRequestEventCallback); _H_SetStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetStateEventName, HostSetStateEventCallback); _H_SetRecallStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetRecallStateEventName, HostSetRecallStateEventCallback); _Handshake = ReplicatorHandshake.Create(Name + "-" + HashName); _Handshake.OnClientSyncRequested += ClientSyncRequested; Patch_SNet_Capture.OnBufferCapture += BufferStored; Patch_SNet_Capture.OnBufferRecalled += BufferRecalled; LevelAPI.OnLevelCleanup += LevelCleanedUp; } private static void ClientSyncRequested(SNet_Player requestedPlayer) { foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.SendDropInState(requestedPlayer); } } } private static void BufferStored(eBufferType type) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.SaveSnapshot(type); } } } private static void BufferRecalled(eBufferType type) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.RestoreSnapshot(type); } } } private static void LevelCleanedUp() { UnloadSessionReplicator(); } private StateReplicator() { } public static StateReplicator<S> Create(uint replicatorID, S startState, LifeTimeType lifeTime, IStateReplicatorHolder<S> holder = null) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown if (replicatorID == 0) { Logger.Error("Replicator ID 0 is reserved for empty!"); return null; } if (_Replicators.ContainsKey(replicatorID)) { Logger.Error("Replicator ID has already assigned!"); return null; } StateReplicator<S> stateReplicator = new StateReplicator<S> { ID = replicatorID, LifeTime = lifeTime, Holder = holder, State = startState }; switch (lifeTime) { case LifeTimeType.Permanent: Logger.Debug("LifeTime is Permanent :: Handshaking is disabled!"); break; case LifeTimeType.Session: _Handshake.UpdateCreated(replicatorID); break; default: { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LifeTime is invalid!: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LifeTimeType>(lifeTime); } Logger.Error(val); return null; } } _Replicators[replicatorID] = stateReplicator; return stateReplicator; } public static void UnloadSessionReplicator() { List<uint> list = new List<uint>(); foreach (StateReplicator<S> value in _Replicators.Values) { if (value.LifeTime == LifeTimeType.Session) { list.Add(value.ID); value.Unload(); } } foreach (uint item in list) { _Replicators.Remove(item); } _Handshake.Reset(); } private static void ClientRequestEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.IsMaster && _Replicators.TryGetValue(replicatorID, out StateReplicator<S> value)) { value.SetState(newState); } } private static void HostSetStateEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out StateReplicator<S> value)) { value.Internal_ChangeState(newState, isRecall: false); } } private static void HostSetRecallStateEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out StateReplicator<S> value)) { value.Internal_ChangeState(newState, isRecall: true); } } } } namespace AWO.Networking.Patches { [HarmonyPatch(typeof(SNet_Capture))] internal static class Patch_OnRecallDone { public static event Action? OnRecallDone; [HarmonyPostfix] [HarmonyPatch(typeof(SNet_SyncManager), "OnRecallDone")] private static void Post_OnRecallDone() { Patch_OnRecallDone.OnRecallDone?.Invoke(); } } [HarmonyPatch(typeof(SNet_Capture))] internal static class Patch_SNet_Capture { public static event Action<eBufferType>? OnBufferCapture; public static event Action<eBufferType>? OnBufferRecalled; [HarmonyPatch("TriggerCapture")] [HarmonyPrefix] [HarmonyWrapSafe] private static void Pre_TriggerCapture(SNet_Capture __instance) { //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_0013: Unknown result type (might be due to invalid IL or missing references) eBufferType primedBufferType = __instance.PrimedBufferType; Patch_SNet_Capture.OnBufferCapture?.Invoke(primedBufferType); } [HarmonyPatch("RecallBuffer")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_RecallBuffer(SNet_Capture __instance, eBufferType bufferType) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (!__instance.IsRecalling) { Patch_SNet_Capture.OnBufferRecalled?.Invoke(bufferType); } } } } namespace AWO.Modules.WOE { [Obsolete] public static class WardenObjectiveExt { private static readonly Dictionary<eWardenObjectiveType, Type> _DTOTypes; private static readonly List<WOE_ContextBase> _ActiveContexts; static WardenObjectiveExt() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown _DTOTypes = new Dictionary<eWardenObjectiveType, Type>(); _ActiveContexts = new List<WOE_ContextBase>(); IEnumerable<Type> enumerable = from x in typeof(WOE_ContextBase).Assembly.GetTypes() where !x.IsAbstract where x.IsAssignableTo(typeof(WOE_ContextBase)) select x; bool flag = default(bool); foreach (Type item in enumerable) { WOE_ContextBase wOE_ContextBase = (WOE_ContextBase)Activator.CreateInstance(item); if (_DTOTypes.TryGetValue(wOE_ContextBase.TargetType, out Type _)) { Logger.Error("Duplicate TargetType Detected!"); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(14, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("With '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' and '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(wOE_ContextBase.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); } Logger.Error(val); } else if (!wOE_ContextBase.DataType.IsAssignableTo(typeof(WOE_DataBase))) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" does not have valid "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("DataType"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (not derived from "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("WOE_DataBase"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } Logger.Error(val); } else { _DTOTypes[wOE_ContextBase.TargetType] = item; } } WOEvents.OnSetup += ObjectiveSetup; LevelAPI.OnLevelCleanup += LevelCleanup; } internal static void Initialize() { } private static void ObjectiveSetup(LG_LayerType layer, int chainIndex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_0083: 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) WardenObjectiveDataBlock val = default(WardenObjectiveDataBlock); Type value; if (!WardenObjectiveManager.TryGetWardenObjectiveDataForLayer(layer, chainIndex, ref val)) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(44, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<LG_LayerType>(layer); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Layer (CI: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(chainIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(") does not have ObjectiveData!!!"); } Logger.Error(val2); } else if (_DTOTypes.TryGetValue(val.Type, out value)) { WOE_ContextBase wOE_ContextBase = (WOE_ContextBase)Activator.CreateInstance(value); wOE_ContextBase.Setup(layer, chainIndex); _ActiveContexts.Add(wOE_ContextBase); } } private static void LevelCleanup() { foreach (WOE_ContextBase activeContext in _ActiveContexts) { activeContext.OnLevelCleanup(); } _ActiveContexts.Clear(); } } public delegate void SetupObjectiveDel(LG_LayerType layer, int chainIndex); [Obsolete] internal static class WOEvents { public static event SetupObjectiveDel? OnSetup; internal static void Invoke_OnSetup(LG_LayerType layer, int chainIndex) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) WOEvents.OnSetup?.Invoke(layer, chainIndex); } } [Obsolete] internal abstract class WOE_ContextBase { public abstract eWardenObjectiveType TargetType { get; } public abstract Type DataType { get; } protected WOE_DataBase? Data { get; private set; } protected LG_LayerType Layer { get; private set; } protected int ChainIndex { get; private set; } public void Setup(LG_LayerType layer, int chainIndex) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Layer = layer; ChainIndex = chainIndex; } public virtual void OnSetup() { } public virtual void OnBuildDone() { } public virtual void OnBuildDoneLate() { } public virtual void OnLevelCleanup() { } } [Obsolete] internal abstract class WOE_DataBase { public uint ObjectiveID { get; set; } public WardenObjectiveDataBlock? GameData { get; set; } } } namespace AWO.Modules.WOE.Objectives.Uplinks { [Obsolete] internal sealed class WOE_UplinkContext : WOE_ContextBase { public override eWardenObjectiveType TargetType => (eWardenObjectiveType)8; public override Type DataType => typeof(WOE_UplinkData); } [Obsolete] internal sealed class WOE_UplinkData : WOE_DataBase { public UplinkCodeBehaviour[] CodeBehaviours { get; set; } = Array.Empty<UplinkCodeBehaviour>(); } internal sealed class UplinkCodeBehaviour { public bool ShowCodesOnTerminal { get; set; } = false; public bool ShowCodesOnHUD { get; set; } = true; public bool ShowCodeToOtherTerminal { get; set; } = true; public TerminalZoneSelectionData TerminalZone { get; set; } = new TerminalZoneSelectionData(); public TerminalOutput[] StartOutputs { get; set; } = Array.Empty<TerminalOutput>(); public TerminalOutput[] EndOutputs { get; set; } = Array.Empty<TerminalOutput>(); public WardenObjectiveEventData[] EventsOnStart { get; set; } = Array.Empty<WardenObjectiveEventData>(); public WardenObjectiveEventData[] EventsOnEnd { get; set; } = Array.Empty<WardenObjectiveEventData>(); } } namespace AWO.Modules.WOE.Objectives.ReactorStartups { [Obsolete] internal sealed class WOE_ReactorStartupContext : WOE_ContextBase { public override eWardenObjectiveType TargetType => (eWardenObjectiveType)1; public override Type DataType => typeof(WOE_ReactorStartupData); } internal enum ReactorWavePuzzleType { Default, CustomLock, UseCommand_OnMainTerminal, UseCommand_InZone, PowerGenerator_InZone } [Obsolete] internal sealed class WOE_ReactorStartupData : WOE_DataBase { public bool RemoveMainStartupCommand { get; set; } = false; public bool RemoveMainVerifyCommand { get; set; } = false; public ScriptedWaveData[] WaveDatas { get; set; } = Array.Empty<ScriptedWaveData>(); public ReactorWavePuzzleData[] WavePuzzles { get; set; } = Array.Empty<ReactorWavePuzzleData>(); } internal enum SettingWarpMode { Clamped, Repeat, PingPong } internal sealed class ScriptedWaveData { public float[] IntroDuration { get; set; } = Array.Empty<float>(); public SettingWarpMode IntroDurationWarpMode { get; set; } = SettingWarpMode.Clamped; public float[] WaveDuration { get; set; } = Array.Empty<float>(); public SettingWarpMode WaveDurationWarpMode { get; set; } = SettingWarpMode.Clamped; public string[][] WaveInstructions { get; set; } = Array.Empty<string[]>(); public SettingWarpMode WaveInstructionsWarpMode { get; set; } = SettingWarpMode.Clamped; } internal sealed class ReactorWavePuzzleData { public ReactorWavePuzzleType Type { get; set; } = ReactorWavePuzzleType.Default; public bool ShowBeacon { get; set; } = false; public string BeaconText { get; set; } = "Auxiliary Terminal"; public Color BeaconColor { get; set; } = Color.magenta; public string Command { get; set; } = "REACTOR_CONTINUE"; public string CommandDescription { get; set; } = "CONTINUE REACTOR STARTUP PROCESS"; public bool ForceJumpWaveWhenSolved { get; set; } = true; } } namespace AWO.Modules.WOE.Objectives.GenClusters { [Obsolete] internal sealed class WOE_GenClusterContext : WOE_ContextBase { public override eWardenObjectiveType TargetType => (eWardenObjectiveType)9; public override Type DataType => typeof(int); } } namespace AWO.Modules.WOE.JsonInjects { [Obsolete] internal class ObjectiveDataHandler : Il2CppJsonReferenceTypeHandler<WardenObjectiveDataBlock> { public override void OnRead(in Object result, in JToken jToken) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 if ((int)jToken.Type == 1) { JObject val = (JObject)jToken; JToken val2 = default(JToken); if (val.TryGetValue("woeEnabled", ref val2) && (int)val2.Type == 9 && (bool)val2) { WardenObjectiveDataBlock val3 = ((Il2CppObjectBase)result).Cast<WardenObjectiveDataBlock>(); } } } } } namespace AWO.Modules.WEE { internal static class VanillaEventOvr { [CompilerGenerated] private sealed class <Handle>d__2 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public eWardenObjectiveEventType type; public WardenObjectiveEventData e; public float currentDuration; private float <delay>5__1; private eWardenObjectiveEventType <>s__2; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Handle>d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Expected I4, but got Unknown //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Invalid comparison between Unknown and I4 switch (<>1__state) { default: return false; case 0: <>1__state = -1; <delay>5__1 = Mathf.Max(e.Delay - currentDuration, 0f); if (<delay>5__1 > 0f) { <>2__current = (object)new WaitForSeconds(<delay>5__1); <>1__state = 1; return true; } break; case 1: <>1__state = -1; break; } if (WorldEventManager.GetCondition(e.Condition.ConditionIndex) != e.Condition.IsTrue) { Logger.Verbose((LogLevel)32, $"Condition {e.Condition.ConditionIndex} is not met"); return false; } WardenObjectiveManager.DisplayWardenIntel(e.Layer, e.WardenIntel); if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { PlaySound(e); } if (SNet.IsMaster) { eWardenObjectiveEventType val = type; <>s__2 = val; eWardenObjectiveEventType val2 = <>s__2; switch (val2 - 3) { default: if ((int)val2 == 16) { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(SpawnEnemyOnPoint(e)), (Action)null); } break; case 1: ToggleDimensionLights(mode: true, e.DimensionIndex); break; case 0: ToggleDimensionLights(mode: false, e.DimensionIndex); break; case 2: break; } } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnEnemyOnPoint>d__6 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public WardenObjectiveEventData e; private int <count>5__1; private Vector3 <pos>5__2; private LG_WorldEventObject <weObject>5__3; private AIG_CourseNode <courseNode>5__4; private AgentMode <mode>5__5; private WaitForSeconds <spawnInterval>5__6; private bool <>s__7; private int <i>5__8; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnEnemyOnPoint>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <weObject>5__3 = null; <courseNode>5__4 = null; <spawnInterval>5__6 = null; <>1__state = -2; } private bool MoveNext() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: { <>1__state = -1; <count>5__1 = ((e.Count < 2) ? 1 : e.Count); <pos>5__2 = (WorldEventUtils.TryGetRandomWorldEventObjectFromFilter(e.WorldEventObjectFilter, (uint)Builder.SessionSeedRandom.Seed, ref <weObject>5__3) ? ((Component)<weObject>5__3).gameObject.transform.position : e.Position); if (!Dimension.TryGetCourseNodeFromPos(<pos>5__2, ref <courseNode>5__4)) { Logger.Error("SpawnEnemyOnPoint", "Failed to find valid CourseNode from Position!"); return false; } <>s__7 = e.Enabled; AgentMode val = ((!<>s__7) ? ((e.EnemyID != 20) ? ((AgentMode)4) : ((AgentMode)3)) : ((AgentMode)1)); <mode>5__5 = val; <spawnInterval>5__6 = new WaitForSeconds(2f / (float)<count>5__1); <i>5__8 = 0; break; } case 1: <>1__state = -1; <i>5__8++; break; } if (<i>5__8 < <count>5__1) { EnemyAgent.SpawnEnemy(e.EnemyID, <pos>5__2, <courseNode>5__4, <mode>5__5); <>2__current = <spawnInterval>5__6; <>1__state = 1; return true; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static bool HasOverride(eWardenObjectiveEventType type, WardenObjectiveEventData e) { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Invalid comparison between Unknown and I4 bool flag = e.Position != Vector3.zero; if (type - 3 > 1) { if ((int)type != 5) { if ((int)type == 16) { return flag || e.Count > 0; } return false; } return flag; } return (int)e.DimensionIndex > 0; } internal static void HandleEvent(eWardenObjectiveEventType type, WardenObjectiveEventData e, float currentDuration) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Handle(type, e, currentDuration)), (Action)null); } [IteratorStateMachine(typeof(<Handle>d__2))] private static IEnumerator Handle(eWardenObjectiveEventType type, WardenObjectiveEventData e, float currentDuration) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Handle>d__2(0) { type = type, e = e, currentDuration = currentDuration }; } private static void PlaySound(WardenObjectiveEventData e) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) if ((int)e.Type != 5) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); } else { CellSoundPlayer val = new CellSoundPlayer(); val.Post(e.SoundID, e.Position, 1u, EventCallback.op_Implicit((Action<Object, AkCallbackType, AkCallbackInfo>)SoundDoneCallback), (Object)(object)val); } string text = ((Object)e.SoundSubtitle).ToString(); if (!string.IsNullOrWhiteSpace(text)) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(text); } } private static void SoundDoneCallback(Object in_cookie, AkCallbackType in_type, AkCallbackInfo callbackInfo) { CellSoundPlayer val = ((Il2CppObjectBase)in_cookie).Cast<CellSoundPlayer>(); if (val != null) { val.Recycle(); } } private static void ToggleDimensionLights(bool mode, eDimensionIndex dimension) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) pEnvironmentInteraction val = default(pEnvironmentInteraction); val.EnvironmentStateChangeType = (EnvironmentStateChangeType)1; val.LightsEnabled = mode; val.DimensionIndex = dimension; pEnvironmentInteraction val2 = val; EnvironmentStateManager.LogEnvironmentState("VEO SetLightMode Attempt"); EnvironmentStateManager.Current.AttemptInteract(val2); } [IteratorStateMachine(typeof(<SpawnEnemyOnPoint>d__6))] private static IEnumerator SpawnEnemyOnPoint(WardenObjectiveEventData e) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SpawnEnemyOnPoint>d__6(0) { e = e }; } } internal static class WardenEventExt { [CompilerGenerated] private sealed class <Handle>d__4 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public WEE_Type type; public WEE_EventData e; public float currentDuration; private float <delay>5__1; private BaseEvent <eventInstance>5__2; private string <line>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Handle>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <eventInstance>5__2 = null; <line>5__3 = null; <>1__state = -2; } private bool MoveNext() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <delay>5__1 = Mathf.Max(e.Delay - currentDuration, 0f); if (<delay>5__1 > 0f) { <>2__current = (object)new WaitForSeconds(<delay>5__1); <>1__state = 1; return true; } break; case 1: <>1__state = -1; break; } if (WorldEventManager.GetCondition(e.Condition.ConditionIndex) != e.Condition.IsTrue) { Logger.Verbose((LogLevel)32, $"Condition {e.Condition.ConditionIndex} is not met"); return false; } WardenObjectiveManager.DisplayWardenIntel(e.Layer, (LocalizedText)e.WardenIntel); if (e.Type != WEE_Type.ForcePlayPlayerDialogue) { if (e.DialogueID != 0) { PlayerDialogManager.WantToStartDialog(e.DialogueID, -1, false, false); } if (e.SoundID != 0) { WardenObjectiveManager.Current.m_sound.Post(e.SoundID, true); <line>5__3 = e.SoundSubtitle; if (!string.IsNullOrWhiteSpace(<line>5__3) && e.Type != WEE_Type.PlaySubtitles) { GuiManager.PlayerLayer.ShowMultiLineSubtitle(<line>5__3); } <line>5__3 = null; } } if (e.SubObjective.DoUpdate && e.Type != WEE_Type.MultiProgression) { WardenObjectiveManager.UpdateSyncCustomSubObjective((LocalizedText)e.SubObjective.CustomSubObjectiveHeader, (LocalizedText)e.SubObjective.CustomSubObjective); } if (e.Fog.DoUpdate) { EnvironmentStateManager.AttemptStartFogTransition(e.Fog.FogSetting, e.Fog.FogTransitionDuration, e.DimensionIndex); } if (_EventsToTrigger.TryGetValue(type, out <eventInstance>5__2)) { <eventInstance>5__2.Trigger(e); } else { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(26, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<WEE_Type>(type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" does not exist in lookup!"); } Logger.Error(val); } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } internal static readonly Dictionary<WEE_Type, BaseEvent> _EventsToTrigger; static WardenEventExt() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown _EventsToTrigger = new Dictionary<WEE_Type, BaseEvent>(); IEnumerable<Type> enumerable = from x in typeof(BaseEvent).Assembly.GetTypes() where !x.IsAbstract where x.IsAssignableTo(typeof(BaseEvent)) select x; bool flag = default(bool); foreach (Type item in enumerable) { BaseEvent baseEvent = (BaseEvent)Activator.CreateInstance(item); if (_EventsToTrigger.TryGetValue(baseEvent.EventType, out BaseEvent value)) { Logger.Error("Duplicate EventType detected!"); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(14, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("With '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(value.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' and '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(baseEvent.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); } Logger.Error(val); } else { baseEvent.Setup(); _EventsToTrigger[baseEvent.EventType] = baseEvent; } } } internal static void Initialize() { ClassInjector.RegisterTypeInIl2Cpp<ScanPositionReplicator>(); ClassInjector.RegisterTypeInIl2Cpp<ZoneLightReplicator>(); JsonInjector.SetConverter<eWardenObjectiveEventType>((Il2CppJsonUnmanagedTypeConverter<eWardenObjectiveEventType>)new EventTypeConverter()); JsonInjector.AddHandler<WardenObjectiveEventData>((Il2CppJsonReferenceTypeHandler<WardenObjectiveEventData>)(object)new EventDataHandler()); JsonInjector.AddHandler<WorldEventFromSourceData>((Il2CppJsonReferenceTypeHandler<WorldEventFromSourceData>)(object)new TriggerDataHandler()); WEE_EnumInjector.Inject(); Detour_ExecuteEvent.Patch(); } internal static void HandleEvent(WEE_Type type, WardenObjectiveEventData e, float currentDuration) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown WEE_EventData wEEData = e.GetWEEData(); if (wEEData != null) { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Handle(type, wEEData, currentDuration)), (Action)null); return; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(72, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("WardenEvent Type is Extension ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<WEE_Type>(type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("), but it's not registered to dataholder!"); } Logger.Error(val); } [IteratorStateMachine(typeof(<Handle>d__4))] private static IEnumerator Handle(WEE_Type type, WEE_EventData e, float currentDuration) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Handle>d__4(0) { type = type, e = e, currentDuration = currentDuration }; } } internal static class WEE_EnumInjector { public const int ExtendedIndex = 10000; private static readonly Dictionary<string, object> _EventTypes; private static int _CurrentIndex; static WEE_EnumInjector() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown _EventTypes = new Dictionary<string, object>(); _CurrentIndex = 0; WEE_Type[] values = Enum.GetValues<WEE_Type>(); bool flag = default(bool); for (int i = 0; i < values.Length; i++) { WEE_Type wEE_Type = values[i]; string text = wEE_Type.ToString(); AddEvent(text); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Injecting EWOEvent: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'"); } Logger.Debug(val); } } private static void AddEvent(string name) { _EventTypes[name] = _CurrentIndex + 10000; _CurrentIndex++; } internal static void Inject() { EnumInjector.InjectEnumValues<eWardenObjectiveEventType>(_EventTypes); } } public sealed class WEE_EventData { public WEE_Type Type { get; set; } public WorldEventConditionPair Condition { get; set; } = new WorldEventConditionPair { ConditionIndex = -1, IsTrue = false }; public eWardenObjectiveEventTrigger Trigger { get; set; } = (eWardenObjectiveEventTrigger)0; public uint ChainPuzzle { get; set; } = 0u; public bool UseStaticBioscanPoints { get; set; } = false; public eDimensionIndex DimensionIndex { get; set; } = (eDimensionIndex)0; public LG_LayerType Layer { get; set; } = (LG_LayerType)0; public eLocalZoneIndex LocalIndex { get; set; } = (eLocalZoneIndex)0; public Vector3 Position { get; set; } = Vector3.zero; public float Delay { get; set; } = 0f; public float Duration { get; set; } = 0f; public LocaleText WardenIntel { get; set; } = LocaleText.Empty; public uint SoundID { get; set; } = 0u; public LocaleText SoundSubtitle { get; set; } = LocaleText.Empty; public uint DialogueID { get; set; } = 0u; public int Count { get; set; } = 0; public bool Enabled { get; set; } = true; public bool SpecialBool { get; set; } = false; public int SpecialNumber { get; set; } = -1; public LocaleText SpecialText { get; set; } = LocaleText.Empty; public string WorldEventObjectFilter { get { return SpecialText; } set { SpecialText = new LocaleText(value); } } public WEE_SubObjectiveData SubObjective { get; set; } = new WEE_SubObjectiveData(); public WEE_UpdateFogData Fog { get; set; } = new WEE_UpdateFogData(); public bool CleanUpEnemiesBehind { get; set; } = true; public WEE_ReactorEventData Reactor { get; set; } = new WEE_ReactorEventData(); public WEE_CountdownData Countdown { get; set; } = new WEE_CountdownData(); public WEE_ZoneLightData SetZoneLight { get; set; } = new WEE_ZoneLightData(); public WEE_CleanupEnemiesData CleanupEnemies { get; set; } = new WEE_CleanupEnemiesData(); public WEE_SpawnHibernateData SpawnHibernates { get; set; } = new WEE_SpawnHibernateData(); public WEE_SpawnScoutData SpawnScouts { get; set; } = new WEE_SpawnScoutData(); public WEE_AddTerminalCommand AddTerminalCommand { get; set; } = new WEE_AddTerminalCommand(); public WEE_AddTerminalCommand AddCommand { get { return AddTerminalCommand; } set { AddTerminalCommand = value; } } public WEE_HideTerminalCommand HideTerminalCommand { get; set; } = new WEE_HideTerminalCommand(); public WEE_HideTerminalCommand HideCommand { get { return HideTerminalCommand; } set { HideTerminalCommand = value; } } public WEE_UnhideTerminalCommand UnhideTerminalCommand { get; set; } = new WEE_UnhideTerminalCommand(); public WEE_UnhideTerminalCommand UnhideCommand { get { return UnhideTerminalCommand; } set { UnhideTerminalCommand = value; } } public WEE_NestedEvent NestedEvent { get; set; } = new WEE_NestedEvent(); public WEE_StartEventLoop StartEventLoop { get; set; } = new WEE_StartEventLoop(); public WEE_StartEventLoop EventLoop { get { return StartEventLoop; } set { StartEventLoop = value; } } public WEE_TeleportPlayer TeleportPlayer { get; set; } = new WEE_TeleportPlayer(); public WEE_InfectPlayer InfectPlayer { get; set; } = new WEE_InfectPlayer(); public WEE_DamagePlayer DamagePlayer { get; set; } = new WEE_DamagePlayer(); public WEE_RevivePlayer RevivePlayer { get; set; } = new WEE_RevivePlayer(); public WEE_AdjustTimer AdjustTimer { get; set; } = new WEE_AdjustTimer(); public WEE_CountupData Countup { get; set; } = new WEE_CountupData(); public WEE_NavMarkerData NavMarker { get; set; } = new WEE_NavMarkerData(); public WEE_ShakeScreen CameraShake { get; set; } = new WEE_ShakeScreen(); public WEE_StartPortalMachine Portal { get; set; } = new WEE_StartPortalMachine(); public WEE_SetSuccessScreen SuccessScreen { get; set; } = new WEE_SetSuccessScreen(); public List<WEE_SubObjectiveData> MultiProgression { get; set; } = new List<WEE_SubObjectiveData>(); public WEE_PlayWaveDistantRoar WaveRoarSound { get; set; } = new WEE_PlayWaveDistantRoar(); public WEE_CustomHudText CustomHudText { get; set; } = new WEE_CustomHudText(); public WEE_CustomHudText CustomHud { get { return CustomHudText; } set { CustomHudText = value; } } public WEE_SpecialHudTimer SpecialHudTimer { get; set; } = new WEE_SpecialHudTimer(); public WEE_SpecialHudTimer SpecialHud { get { return SpecialHudTimer; } set { SpecialHudTimer = value; } } public WEE_ForcePlayerDialogue PlayerDialogue { get; set; } = new WEE_ForcePlayerDialogue(); public WEE_SetTerminalLog SetTerminalLog { get; set; } = new WEE_SetTerminalLog(); public WEE_SetTerminalLog TerminalLog { get { return SetTerminalLog; } set { SetTerminalLog = value; } } public List<WEE_SetPocketItem> ObjectiveItems { get; set; } = new List<WEE_SetPocketItem>(); } public sealed class WEE_SubObjectiveData { public bool DoUpdate { get; set; } = false; public LocaleText CustomSubObjectiveHeader { get; set; } = LocaleText.Empty; public LocaleText CustomSubObjective { get; set; } = LocaleText.Empty; public uint Index { get; set; } = 0u; public int Priority { get; set; } = 1; public LG_LayerType Layer { get; set; } = (LG_LayerType)0; public bool IsLayerIndependent { get; set; } = true; public LocaleText OverrideTag { get; set; } = LocaleText.Empty; } public sealed class WEE_UpdateFogData { public bool DoUpdate { get; set; } = false; public uint FogSetting { get; set; } = 0u; public float FogTransitionDuration { get; set; } = 0f; } public sealed class WEE_ReactorEventData { public enum WaveState { Intro, Wave, Verify, Idle } public WaveState State { get; set; } = WaveState.Intro; public int Wave { get; set; } = 1; public float Progress { get; set; } = 0f; } public sealed class WEE_CountdownData { public float Duration { get; set; } = 0f; public bool CanShowHours { get; set; } = true; public LocaleText TimerText { get; set; } = LocaleText.Empty; public LocaleText TitleText { get { return TimerText; } set { TimerText = value; } } public Color TimerColor { get; set; } = Color.red; public List<EventsOnTimerProgress> EventsOnProgress { get; set; } = new List<EventsOnTimerProgress>(); public List<WardenObjectiveEventData> EventsOnDone { get; set; } = new List<WardenObjectiveEventData>(); } public sealed class WEE_CleanupEnemiesData { public enum CleanUpType { Kill, Despawn } public CleanUpType Type { get; set; } = CleanUpType.Despawn; public int AreaIndex { get; set; } = -1; public bool IncludeHibernate { get; set; } = true; public bool IncludeAggressive { get; set; } = true; public bool IncludeScout { get; set; } = true; public uint[] ExcludeEnemyID { get; set; } = Array.Empty<uint>(); public uint[] IncludeOnlyID { get; set; } = Array.Empty<uint>(); public void DoClear(AIG_CourseNode node) { //IL_0045: 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_004c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected I4, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) if (!SNet.IsMaster || node == null || node.m_enemiesInNode == null) { return; } foreach (EnemyAgent item in node.m_enemiesInNode.ToArray()) { AgentMode mode = ((AgentAI)item.AI).Mode; if ((mode - 1) switch { 0 => IncludeAggressive, 2 => IncludeScout, 3 => IncludeHibernate, _ => true, } && !ExcludeEnemyID.Contains(item.EnemyDataID) && (IncludeOnlyID.Length == 0 || IncludeOnlyID.Contains(item.EnemyDataID))) { switch (Type) { case CleanUpType.Despawn: ((Agent)item).m_replicator.Despawn(); break; case CleanUpType.Kill: item.Damage.IsImortal = false; item.Damage.BulletDamage(((Dam_SyncedDamageBase)item.Damage).DamageMax, (Agent)null, default(Vector3), default(Vector3), default(Vector3), false, 0, 1f, 1f, 0u); break; } } } } } public sealed class WEE_ZoneLightData { public enum ModifierType : byte { RevertToOriginal, SetZoneLightData } public ModifierType Type { get; set; } = ModifierType.RevertToOriginal; public uint LightDataID { get; set; } = 0u; public float TransitionDuration { get; set; } = 0.5f; public int Seed { get; set; } = 0; public bool UseRandomSeed => Seed == 0; } public sealed class WEE_SpawnHibernateData { public int AreaIndex { get; set; } = -1; public int[] AreaBlacklist { get; set; } = Array.Empty<int>(); public uint EnemyID { get; set; } = 0u; public int Count { get; set; } = 0; public Vector3 Position { get; set; } = Vector3.zero; public Vector3 Rotation { get; set; } = Vector3.zero; } public sealed class WEE_SpawnScoutData { public int AreaIndex { get; set; } = -1; public int[] AreaBlacklist { get; set; } = Array.Empty<int>(); public eEnemyGroupType GroupType { get; set; } public eEnemyRoleDifficulty Difficulty { get; set; } public int Count { get; set; } = 0; } public sealed class WEE_AddTerminalCommand { public struct LocaleTerminalOutput { public TerminalLineType LineType { get; set; } public LocaleText Output { get; set; } public float Time { get; set; } public readonly TerminalOutput ToTerminalOutput() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown return new TerminalOutput { LineType = LineType, Output = SerialLookupManager.ParseLocaleText(Output), Time = Time }; } } public int TerminalIndex { get; set; } = 0; public int CommandNumber { get; set; } = 6; public string Command { get; set; } = string.Empty; public LocaleText CommandDesc { get; set; } = LocaleText.Empty; public bool AutoIndentCommandDesc { get; set; } = false; public List<LocaleTerminalOutput> PostCommandOutputs { get; set; } = new List<LocaleTerminalOutput>(); public List<WardenObjectiveEventData> CommandEvents { get; set; } = new List<WardenObjectiveEventData>(); public bool ProgressWaitBeforeEvents { get; set; } = false; public TERM_CommandRule SpecialCommandRule { get; set; } = (TERM_CommandRule)0; } public sealed class WEE_HideTerminalCommand { public int TerminalIndex { get; set; } = 0; public TERM_Command CommandEnum { get; set; } = (TERM_Command)0; public int CommandNumber { get; set; } = 0; public bool DeleteCommand { get; set; } = false; } public sealed class WEE_UnhideTerminalCommand { public int TerminalIndex { get; set; } = 0; public TERM_Command CommandEnum { get; set; } = (TERM_Command)0; public int CommandNumber { get; set; } = 0; } public sealed class WEE_NestedEvent { public enum NestedMode : byte { ActivateAll, RandomAny, RandomWeighted } public struct EventsOnRandomWeight { public string DebugName { get; set; } public float Weight { get; set; } public int RepeatCount { get; set; } public bool IsInfinite { get; set; } public List<WardenObjectiveEventData> Events { get; set; } } public NestedMode Type { get; set; } = NestedMode.ActivateAll; public int MaxRandomEvents { get; set; } = -1; public bool AllowRepeatsInRandom { get; set; } = false; public List<WardenObjectiveEventData> EventsToActivate { get; set; } = new List<WardenObjectiveEventData>(); public List<EventsOnRandomWeight> WheelOfEvents { get; set; } = new List<EventsOnRandomWeight>(); } public sealed class WEE_StartEventLoop { public int LoopIndex { get; set; } = 0; public float LoopDelay { get; set; } = 1f; public int LoopCount { get; set; } = -1; public List<WardenObjectiveEventData> EventsToActivate { get; set; } = new List<WardenObjectiveEventData>(); } public enum PlayerIndex : byte { P0, P1, P2, P3 } public sealed class WEE_TeleportPlayer { public struct TeleportData { public PlayerIndex PlayerIndex { get; set; } [JsonPropertyName("DimensionIndex")] public eDimensionIndex Dimension { get; set; } public Vector3 Position { get; set; } public string WorldEventObjectFilter { get; set; } [JsonPropertyName("LookDirection")] public int LookDir { get; set; } [JsonPropertyName("LookDirectionV3")] public Vector3 LookDirV3 { get; set; } public bool PlayWarpAnimation { get; set; } [JsonPropertyName("FlashDuration")] public float Duration { get; set; } [JsonIgnore] public PlayerAgent Player { get; set; } [JsonIgnore] public eDimensionIndex LastDimension { get; set; } [JsonIgnore] public Vector3 LastPosition { get; set; } [JsonIgnore] public Vector3 LastLookDirV3 { get; set; } [JsonIgnore] public List<IWarpableObject> ItemsToWarp { get; set; } } public HashSet<PlayerIndex> PlayerFilter { get; set; } = new HashSet<PlayerIndex>(); public bool PlayWarpAnimation { get; set; } = true; public bool SendBPUsToHost { get; set; } = false; public Vector3 Player0Position { get; set; } = Vector3.zero; public int P0LookDir { get; set; } = 0; public Vector3 Player1Position { get; set; } = Vector3.zero; public int P1LookDir { get; set; } = 0; public Vector3 Player2Position { get; set; } = Vector3.zero; public int P2LookDir { get; set; } = 0;