using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; 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.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Nodes; using System.Text.Json.Serialization; using System.Text.RegularExpressions; using System.Threading; using AIGraph; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using CellMenu; using ChainedPuzzles; using EOSExt.TacticalBigPickup.Definitions.Generic.BigPickup.Definition; using EOSExt.TacticalBigPickup.FogBeacon.Generic; using EOSExt.TacticalBigPickup.Functions.FogBeacon.BigPickup; using EOSExt.TacticalBigPickup.Functions.FogBeacon.LevelSpawned; using EOSExt.TacticalBigPickup.Functions.Generic.BigPickup; using EOSExt.TacticalBigPickup.Functions.Generic.BigPickup.Definition; using EOSExt.TacticalBigPickup.Impl; using EOSExt.TacticalBigPickup.Impl.FogBeacon.LeveSpawned; using EOSExt.TacticalBigPickup.Managers; using Enemies; using ExtraObjectiveSetup; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.JSON; using ExtraObjectiveSetup.Utils; using FloLib.Networks.Replications; using GTFO.API; using GTFO.API.Extensions; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using Microsoft.CodeAnalysis; using Player; using SNetwork; using ScanPosOverride.Managers; using StateMachines; using TMPro; using TOA_Heavy_Industries; using UnityEngine; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("TOA_Heavy_Industries")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.2.0.0")] [assembly: AssemblyInformationalVersion("2.2.0")] [assembly: AssemblyProduct("TOA_Heavy_Industries")] [assembly: AssemblyTitle("TOA_Heavy_Industries")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.0.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace EOSExt.TacticalBigPickup.Patches { [HarmonyPatch] internal static class FixLevelSpawnedFogBeaconRange { [HarmonyPostfix] [HarmonyPatch(typeof(HeavyFogRepellerGlobalState), "AttemptInteract")] private static void Post_HeavyFogRepellerGlobalState_AttemptInteract(HeavyFogRepellerGlobalState __instance) { LevelSpawnedFogBeaconSettings lSFBDef = LevelSpawnedFogBeaconSettingManager.Current.GetLSFBDef(__instance); if (lSFBDef != null) { __instance.m_repellerSphere.Range = lSFBDef.Range; } } } [HarmonyPatch] public static class SetupBigPickupItemWithItemId { public const string BIG_PICKUP_FOG_BEACON_NAME = "Carry_FogBeacon - ConstantFog"; public const string BIG_PICKUP_OBSERVER_NAME = "Carry_Observer"; [HarmonyPostfix] [HarmonyPatch(typeof(LG_PickupItem), "SetupBigPickupItemWithItemId")] private static void Post_Setup(LG_PickupItem __instance, uint itemId) { BigPickupItemManager.Current.Register(__instance); } } } namespace EOSExt.TacticalBigPickup.FogBeacon.Generic { public abstract class TOAGenericDefinitionManager where T : new() { protected readonly Dictionary> definitions = new Dictionary>(); protected abstract string DEFINITION_NAME { get; } protected string DEFINITION_PATH { get; } protected TOAGenericDefinitionManager() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown DEFINITION_PATH = Path.Combine(TOAConfigPaths.GetCustomPath(), "TOA_Heavy_Industries", "FogBeacon", DEFINITION_NAME); Directory.CreateDirectory(DEFINITION_PATH); EnsureTemplate(); LoadDefinitions(); LiveEdit.CreateListener(DEFINITION_PATH, "*.json", true).FileChanged += new LiveEditEventHandler(FileChanged); } private void EnsureTemplate() { string path = Path.Combine(DEFINITION_PATH, "Template.json"); if (!File.Exists(path)) { File.WriteAllText(path, EOSJson.Serialize>(new GenericDefinition())); } } private void LoadDefinitions() { foreach (string item in Directory.EnumerateFiles(DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { try { AddDefinitions(EOSJson.Deserialize>(File.ReadAllText(item))); } catch (Exception value) { EOSLogger.Error($"TOA Fog Beacon definition load failed for '{item}': {value}"); } } } private void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { AddDefinitions(EOSJson.Deserialize>(content)); }); } private void AddDefinitions(GenericDefinition definition) { if (definition != null) { definitions[definition.ID] = definition; } } public GenericDefinition GetDefinition(uint id) { if (!definitions.TryGetValue(id, out GenericDefinition value)) { return null; } return value; } public virtual void Init() { } } public abstract class TOAExpeditionDefinitionManager where T : new() { protected readonly Dictionary> definitions = new Dictionary>(); protected abstract string DEFINITION_NAME { get; } protected string DEFINITION_PATH { get; } protected TOAExpeditionDefinitionManager() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown DEFINITION_PATH = Path.Combine(TOAConfigPaths.GetCustomPath(), "TOA_Heavy_Industries", "FogBeacon", DEFINITION_NAME); Directory.CreateDirectory(DEFINITION_PATH); EnsureTemplate(); LoadDefinitions(); LiveEdit.CreateListener(DEFINITION_PATH, "*.json", true).FileChanged += new LiveEditEventHandler(FileChanged); } private void EnsureTemplate() { string path = Path.Combine(DEFINITION_PATH, "Template.json"); if (!File.Exists(path)) { File.WriteAllText(path, EOSJson.Serialize>(new GenericExpeditionDefinition())); } } private void LoadDefinitions() { foreach (string item in Directory.EnumerateFiles(DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { try { AddDefinitions(EOSJson.Deserialize>(File.ReadAllText(item))); } catch (Exception value) { EOSLogger.Error($"TOA Fog Beacon definition load failed for '{item}': {value}"); } } } private void FileChanged(LiveEditEventArgs e) { EOSLogger.Warning("LiveEdit File Changed: " + e.FullPath); LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { AddDefinitions(EOSJson.Deserialize>(content)); }); } private void AddDefinitions(GenericExpeditionDefinition definition) { if (definition != null) { definitions[definition.MainLevelLayout] = definition; } } public GenericExpeditionDefinition GetDefinition(uint levelLayout) { if (!definitions.TryGetValue(levelLayout, out GenericExpeditionDefinition value)) { return null; } return value; } public virtual void Init() { } } } namespace EOSExt.TacticalBigPickup.Definitions.Generic.BigPickup.Definition { public class BigPickupFunction { public string Type { get; set; } = string.Empty; public uint SettingID { get; set; } } } namespace EOSExt.TacticalBigPickup.Managers { public class BigPickupItemManager : PickupItemManager { public static BigPickupItemManager Current { get; } private BigPickupItemManager() { } static BigPickupItemManager() { Current = new BigPickupItemManager(); } } internal static class ItemInLevelUtils { internal static (eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex) GetGlobalZoneIndex(this ItemInLevel item) { //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_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) pItemData pItemData = ((Item)item).pItemData; AIG_CourseNode val = default(AIG_CourseNode); if (((pCourseNode)(ref pItemData.originCourseNode)).TryGet(ref val)) { return (dim: val.m_dimension.DimensionIndex, layer: val.LayerType, localIndex: val.m_zone.LocalIndex); } throw new NullReferenceException("originCourseNode is null"); } internal static LG_PickupItem GetLGPickupItem(this ItemInLevel item) { return ((Component)item).GetComponentInParent(); } } public abstract class PickupItemManager where T : ItemInLevel { protected Dictionary> RegisteredItems { get; private set; } = new Dictionary>(); public virtual void Register(LG_PickupItem item) { T componentInChildren = ((Component)item.m_root).GetComponentInChildren(); Register(componentInChildren); } public virtual void Register(T item) { ItemDataBlock itemDataBlock = ((Item)(object)item).ItemDataBlock; if (!RegisteredItems.TryGetValue(((GameDataBlockBase)(object)itemDataBlock).persistentID, out List value)) { value = new List(); RegisteredItems[((GameDataBlockBase)(object)itemDataBlock).persistentID] = value; } value.Add(item); } public virtual Dictionary<(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex), List> GetItemsOf(uint itemId) { if (!RegisteredItems.TryGetValue(itemId, out List value)) { return null; } return (from item in value group item by ((ItemInLevel)(object)item).GetGlobalZoneIndex()).ToDictionary((IGrouping<(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex), T> g) => g.Key, (IGrouping<(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex), T> g) => g.ToList()); } protected virtual void OnBuildDone() { } protected virtual void Clear() { RegisteredItems.Clear(); } protected PickupItemManager() { LevelAPI.OnBuildDone += OnBuildDone; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } static PickupItemManager() { } } } namespace EOSExt.TacticalBigPickup.Functions.Generic.BigPickup { public class BigPickupCustomHelper : MonoBehaviour { private Dictionary> eventsOnState = new Dictionary>(); public ItemInLevel Item { get; private set; } private void Setup(ItemInLevel item) { Item = item; item.GetSyncComponent().OnSyncStateChange += Action.op_Implicit((Action)OnSyncStateChange); } public bool TryGetEvents(ePickupItemStatus state, out List events) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return eventsOnState.TryGetValue(state, out events); } private void OnSyncStateChange(ePickupItemStatus state, pPickupPlacement placement, PlayerAgent player, bool isRecall) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (!isRecall && SNet.IsMaster && TryGetEvents(state, out List events)) { EOSLogger.Log($"item {((Item)Item).PublicName} on state {state}, executing {events.Count} events"); WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp(events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray)null); } } private void OnDestroy() { eventsOnState.Clear(); eventsOnState = null; } private BigPickupCustomHelper() { } public static void Setup(ItemInLevel item, BigPickupCustomization states) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) BigPickupCustomHelper bigPickupCustomHelper = ((Component)item).gameObject.GetComponent(); if ((Object)(object)bigPickupCustomHelper == (Object)null) { bigPickupCustomHelper = ((Component)item).gameObject.AddComponent(); bigPickupCustomHelper.Setup(item); } foreach (BigPickupStateEvent item2 in states.OnState) { if (!bigPickupCustomHelper.eventsOnState.TryGetValue(item2.State, out List value)) { value = new List(); bigPickupCustomHelper.eventsOnState[item2.State] = value; } value.AddRange(item2.EventsOnState); } } static BigPickupCustomHelper() { ClassInjector.RegisterTypeInIl2Cpp(); } } public class BigPickupCustomizationManager : TOAExpeditionDefinitionManager { public static BigPickupCustomizationManager Current { get; } = new BigPickupCustomizationManager(); protected override string DEFINITION_NAME => "BigPickupCustomization"; private void Build(BigPickups def) { Dictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex), List> itemsOf = BigPickupItemManager.Current.GetItemsOf(def.ItemId); foreach (BigPickupCustomization bigPickupItem in def.BigPickupItems) { if (!itemsOf.TryGetValue(((GlobalZoneIndex)bigPickupItem).GlobalZoneIndexTuple(), out var value)) { EOSLogger.Error($"EventsOnBigPickup: zone not found {((GlobalZoneIndex)bigPickupItem).GlobalZoneIndexTuple()}"); } else if (bigPickupItem.Index < 0 || bigPickupItem.Index >= value.Count) { EOSLogger.Error($"EventsOnBigPickup: itemID {def.ItemId}, index {bigPickupItem.Index} is invalid - there're {value.Count} items in {((GlobalZoneIndex)bigPickupItem).GlobalZoneIndexTuple()} - valid value falls in range [0, {value.Count - 1})"); } else { CarryItemPickup_Core item = value[bigPickupItem.Index]; BigPickupCustomHelper.Setup((ItemInLevel)(object)item, bigPickupItem); CustomBigPickupFunctionImplementor.SetupCustomBigPickupFunctions(((ItemInLevel)(object)item).GetLGPickupItem(), bigPickupItem.Functions); } } } private void Build() { if (definitions.TryGetValue(RundownManager.ActiveExpedition.LevelLayoutData, out GenericExpeditionDefinition value)) { value.Definitions.ForEach(Build); } } public BigPickupCustomizationManager() { LevelAPI.OnBuildDone += Build; } } } namespace EOSExt.TacticalBigPickup.Functions.Generic.BigPickup.Definition { public class BigPickupCustomization : GlobalZoneIndex { public int Index { get; set; } public List Functions { get; set; } = new List { new BigPickupFunction() }; public List OnState { get; set; } = new List { new BigPickupStateEvent() }; } public class BigPickups { public uint ItemId { get; set; } public List BigPickupItems { get; set; } = new List { new BigPickupCustomization() }; } public class BigPickupStateEvent { public ePickupItemStatus State { get; set; } public List EventsOnState { get; set; } = new List(); } } namespace EOSExt.TacticalBigPickup.Functions.FogBeacon.LevelSpawned { public class LevelSpawnedFogBeaconSettings { public int AreaIndex { get; set; } public float GrowDuration { get; set; } = 10f; public float ShrinkDuration { get; set; } = 10f; public float Range { get; set; } = 11f; public string WorldEventObjectFilter { get; set; } = string.Empty; public Vec3 Position { get; set; } = new Vec3(); } public class LevelSpawnedFogBeaconDefinition : GlobalZoneIndex { public List SpawnedBeaconsInZone { get; set; } = new List { new LevelSpawnedFogBeaconSettings() }; } public class LevelSpawnedFogBeaconSettingManager : TOAExpeditionDefinitionManager { public enum LSFBEvent { ToggleLevelSpawnedFogBeaconState = 922 } private Dictionary LSFBGlobalStatesSet = new Dictionary(); public static LevelSpawnedFogBeaconSettingManager Current { get; } protected override string DEFINITION_NAME => "LevelSpawnedFogBeacon_EOS"; private Dictionary LevelSpawnedFogBeacons { get; } = new Dictionary(); private void Build(LevelSpawnedFogBeaconDefinition def) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) foreach (LevelSpawnedFogBeaconSettings item in def.SpawnedBeaconsInZone) { if (item.WorldEventObjectFilter == null || item.WorldEventObjectFilter == string.Empty || LevelSpawnedFogBeacons.ContainsKey(item.WorldEventObjectFilter)) { EOSLogger.Error("LevelSpawnedFogBeaconManager: WorldEventObjectFilter '" + item.WorldEventObjectFilter + "' is either unassigned or has already been assigned."); continue; } LevelSpawnedFogBeacon levelSpawnedFogBeacon = LevelSpawnedFogBeacon.Instantiate(((GlobalZoneIndex)def).DimensionIndex, ((GlobalZoneIndex)def).LayerType, ((GlobalZoneIndex)def).LocalIndex, item); if (levelSpawnedFogBeacon != null) { LevelSpawnedFogBeacons[item.WorldEventObjectFilter] = levelSpawnedFogBeacon; LSFBGlobalStatesSet[((Il2CppObjectBase)levelSpawnedFogBeacon.GlobalState).Pointer] = item; EOSLogger.Debug($"LevelSpawnedFogBeaconManager: spawned '{item.WorldEventObjectFilter}' in {((GlobalZoneIndex)def).GlobalZoneIndexTuple()}, Area_{(ushort)(65 + item.AreaIndex)}"); } } } public LevelSpawnedFogBeaconSettings GetLSFBDef(HeavyFogRepellerGlobalState h) { if (!LSFBGlobalStatesSet.TryGetValue(((Il2CppObjectBase)h).Pointer, out LevelSpawnedFogBeaconSettings value)) { return null; } return value; } public void ToggleLSFBState(string worldEventgObjectFilter, bool enable) { //IL_0035: 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_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) if (!LevelSpawnedFogBeacons.TryGetValue(worldEventgObjectFilter, out LevelSpawnedFogBeacon value)) { EOSLogger.Error("ToggleLSFBState: '" + worldEventgObjectFilter + "' is not defined"); } else if (SNet.IsMaster) { value.GlobalState.AttemptInteract(new pCarryItemWithGlobalState_Interaction { type = ((!enable) ? ((byte)1) : ((byte)0)), owner = (eCarryItemWithGlobalStateOwner)2, staticPosition = value.Position }); } } private void Clear() { foreach (LevelSpawnedFogBeacon value in LevelSpawnedFogBeacons.Values) { value.Destroy(); } LSFBGlobalStatesSet.Clear(); LevelSpawnedFogBeacons.Clear(); } private void BuildLevelSpawnedFogBeacons() { if (definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions.ForEach(Build); } } private LevelSpawnedFogBeaconSettingManager() { LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; LevelAPI.OnBuildDone += BuildLevelSpawnedFogBeacons; EOSWardenEventManager.Current.AddEventDefinition(LSFBEvent.ToggleLevelSpawnedFogBeaconState.ToString(), 922u, (Action)ToggleLevelSpawnedFogBeaconState); } static LevelSpawnedFogBeaconSettingManager() { Current = new LevelSpawnedFogBeaconSettingManager(); } private static void ToggleLevelSpawnedFogBeaconState(WardenObjectiveEventData e) { Current.ToggleLSFBState(e.WorldEventObjectFilter, e.Enabled); } } } namespace EOSExt.TacticalBigPickup.Functions.FogBeacon.BigPickup { public class RepellerSphereSetting { public bool InfiniteDuration { get; set; } public float GrowDuration { get; set; } = 10f; public float ShrinkDuration { get; set; } = 10f; public float Range { get; set; } = 11f; } public class BigPickupFogBeaconSetting { public float TimeToPickup { get; set; } = 1f; public float TimeToPlace { get; set; } = 1f; public RepellerSphereSetting RSHold { get; set; } = new RepellerSphereSetting(); public RepellerSphereSetting RSPlaced { get; set; } = new RepellerSphereSetting(); } internal class BigPickupFogBeaconSettingManager : TOAGenericDefinitionManager { public static BigPickupFogBeaconSettingManager Current { get; private set; } protected override string DEFINITION_NAME => "BigPickupFogBeacon_EOS"; public override void Init() { } private BigPickupFogBeaconSettingManager() { } static BigPickupFogBeaconSettingManager() { Current = new BigPickupFogBeaconSettingManager(); } } } namespace EOSExt.TacticalBigPickup.Impl { public abstract class CustomBigPickupFunctionImplementor { private static Dictionary s_implementors; protected abstract string FunctionName { get; } public static void SetupCustomBigPickupFunctions(LG_PickupItem item, List functions) { foreach (BigPickupFunction function in functions) { if (s_implementors.TryGetValue(function.Type, out CustomBigPickupFunctionImplementor value)) { value.SetupCustomBigPickupFunction(item, function.SettingID); EOSLogger.Log("ICustomBigPickupFunctionImplementor: function '" + function.Type + "' applied to " + ((Object)item).name); } else { EOSLogger.Error("ICustomBigPickupFunctionImplementor: function '" + function.Type + "' not found"); } } } static CustomBigPickupFunctionImplementor() { s_implementors = new Dictionary(); foreach (Type item in from x in typeof(CustomBigPickupFunctionImplementor).Assembly.GetTypes() where !x.IsAbstract where x.IsAssignableTo(typeof(CustomBigPickupFunctionImplementor)) select x) { CustomBigPickupFunctionImplementor customBigPickupFunctionImplementor = (CustomBigPickupFunctionImplementor)Activator.CreateInstance(item, nonPublic: true); if (s_implementors.TryGetValue(customBigPickupFunctionImplementor.FunctionName, out CustomBigPickupFunctionImplementor _)) { EOSLogger.Error("CustomBigPickupFunctionImplementor: Duplicate " + customBigPickupFunctionImplementor.FunctionName + "!"); continue; } EOSLogger.Log("CustomBigPickupFunctionImplementor: registered " + customBigPickupFunctionImplementor.FunctionName + "!"); s_implementors[customBigPickupFunctionImplementor.FunctionName] = customBigPickupFunctionImplementor; } } public abstract void SetupCustomBigPickupFunction(LG_PickupItem item, uint settingID); } } namespace EOSExt.TacticalBigPickup.Impl.FogBeacon.LeveSpawned { public class LevelSpawnedFogBeacon { public static uint LSFB_ITEM_DB_ID { get; private set; } public static bool HasFogBeaconItemDBDefinition => LSFB_ITEM_DB_ID != 0; public string WorldEventObjectFilter => def?.WorldEventObjectFilter ?? string.Empty; public LevelSpawnedFogBeaconSettings def { get; private set; } public HeavyFogRepellerGlobalState GlobalState { get; private set; } public LG_PickupItem LG_PickupItem { get; private set; } public NavMarker NavMarker { get; private set; } public Vector3 Position { get { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) LG_PickupItem lG_PickupItem = LG_PickupItem; if (lG_PickupItem == null) { return Vector3.zero; } return ((Component)lG_PickupItem).transform.position; } } public Color NAV_MARKER_COLOR { get; } = new Color(1f, 0.75686276f, 0.14509805f); public static LevelSpawnedFogBeacon Instantiate(eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, LevelSpawnedFogBeaconSettings def) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) if (!HasFogBeaconItemDBDefinition) { EOSLogger.Error("LevelSpawnedFogBeaconManager: ItemDatablock Definition of vanilla Fog Repeller Turbine is not found..."); return null; } LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layer, localIndex, ref val) || (Object)(object)val == (Object)null || def.AreaIndex < 0 || def.AreaIndex >= val.m_areas.Count) { EOSLogger.Error($"LevelSpawnedFogBeacon: cannot find {(dimensionIndex, layer, localIndex)}, Area_{(ushort)(65 + def.AreaIndex)}"); return null; } AIG_CourseNode courseNode = val.m_areas[def.AreaIndex].m_courseNode; return new LevelSpawnedFogBeacon(def, courseNode) { def = def }; } internal void Destroy() { Object.Destroy((Object)(object)((Component)LG_PickupItem.m_root).gameObject); GlobalState = null; LG_PickupItem = null; def = null; } private LevelSpawnedFogBeacon(LevelSpawnedFogBeaconSettings def, AIG_CourseNode node) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: 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_0074: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) this.def = def; GameObject val = new GameObject($"LSBF_{def.WorldEventObjectFilter}-Area_{(ushort)(65 + def.AreaIndex)}"); val.transform.SetPositionAndRotation(def.Position.ToVector3(), Quaternion.identity); LG_PickupItem = LG_PickupItem.SpawnGenericPickupItem(val.transform); LG_PickupItem.SpawnNode = node; int count = ((Il2CppArrayBase>)(object)CarryItemWithGlobalStateManager.Current.m_carryItemGlobalStatesInstancesPerType)[0].Count; LG_PickupItem.SetupAsBigPickupItem(1, LSFB_ITEM_DB_ID, false, -1); CarryItemPickup_Core componentInChildren = ((Component)LG_PickupItem.m_root).GetComponentInChildren(); LG_PickupItem_Sync val2 = ((Il2CppObjectBase)componentInChildren.m_sync).Cast(); if ((Object)(object)val2 != (Object)null) { pPickupItemState state = val2.m_stateReplicator.State; ((pCourseNode)(ref state.placement.node)).Set(LG_PickupItem.SpawnNode); } ((Component)((Il2CppObjectBase)componentInChildren.m_interact).Cast()).gameObject.SetActive(false); iTerminalItem componentInChildren2 = ((Component)LG_PickupItem).GetComponentInChildren(); if (componentInChildren2 != null) { LG_LevelInteractionManager.DeregisterTerminalItem(componentInChildren2); } NavMarker = GuiManager.NavMarkerLayer.PrepareGenericMarker(((Component)LG_PickupItem).gameObject); if ((Object)(object)NavMarker != (Object)null) { NavMarker.SetColor(NAV_MARKER_COLOR); NavMarker.SetStyle((eNavMarkerStyle)14); NavMarker.SetVisible(false); } iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState); if (!CarryItemWithGlobalStateManager.TryGetItemInstance((eCarryItemWithGlobalStateType)0, (byte)count, ref val3)) { EOSLogger.Error("LevelSpawnedFogBeaconManager: Didn't find GlobalState of '" + def.WorldEventObjectFilter + "'"); return; } GlobalState = ((Il2CppObjectBase)val3).Cast(); FogRepeller_Sphere repellerSphere = GlobalState.m_repellerSphere; repellerSphere.GrowDuration = def.GrowDuration; repellerSphere.ShrinkDuration = def.ShrinkDuration; repellerSphere.Range = def.Range; HeavyFogRepellerGlobalState globalState = GlobalState; globalState.CallbackOnStateChange += Action.op_Implicit((Action)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall) { //IL_0000: 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_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected I4, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown eHeavyFogRepellerStatus val4 = (eHeavyFogRepellerStatus)newState.status; switch ((int)val4) { case 0: case 2: NavMarker.SetVisible(false); break; case 1: NavMarker.SetVisible(true); if (isRecall) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)922, WorldEventObjectFilter = WorldEventObjectFilter, Enabled = true, Delay = 1.1f }, (eWardenObjectiveEventTrigger)0, true, 0f); } break; } }); } private static void FindFogTurbineItemDBID() { if (!HasFogBeaconItemDBDefinition) { LSFB_ITEM_DB_ID = ((GameDataBlockBase)(object)GameDataBlockBase.GetBlock("Carry_HeavyFogRepeller"))?.persistentID ?? 0; if (LSFB_ITEM_DB_ID == 0) { EOSLogger.Error("LevelSpawnedFogBeaconManager: ItemDatablock Definition of vanilla Fog Repeller Turbine is not found..."); } } } static LevelSpawnedFogBeacon() { FindFogTurbineItemDBID(); LevelAPI.OnBuildStart += FindFogTurbineItemDBID; } } } namespace EOSExt.TacticalBigPickup.Impl.FogBeacon.BigPickup { internal class BigPickupFogBeaconImplementor : CustomBigPickupFunctionImplementor { protected override string FunctionName => "FogBeacon"; public override void SetupCustomBigPickupFunction(LG_PickupItem item, uint settingID) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Expected O, but got Unknown //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) GenericDefinition definition = BigPickupFogBeaconSettingManager.Current.GetDefinition(settingID); if (definition == null || definition.Definition == null) { EOSLogger.Error($"BigPickupFogBeacon: setting ID {settingID} not found"); return; } BigPickupFogBeaconSetting setting = definition.Definition; FogRepeller_Sphere val = new GameObject("FogInstance_Beacon_Fake").AddComponent(); val.InfiniteDuration = false; val.LifeDuration = 99999f; val.GrowDuration = 99999f; val.ShrinkDuration = 99999f; val.Range = 1f; FogRepeller_Sphere fogRepHold = new GameObject("FogInstance_Beacon_SmallLayer").AddComponent(); fogRepHold.InfiniteDuration = setting.RSHold.InfiniteDuration; fogRepHold.GrowDuration = setting.RSHold.GrowDuration; fogRepHold.ShrinkDuration = setting.RSHold.ShrinkDuration; fogRepHold.Range = setting.RSHold.Range; fogRepHold.Offset = Vector3.zero; FogRepeller_Sphere fogRepPlaced = new GameObject("FogInstance_Beacon_BigLayer").AddComponent(); fogRepPlaced.InfiniteDuration = setting.RSPlaced.InfiniteDuration; fogRepPlaced.GrowDuration = setting.RSPlaced.GrowDuration; fogRepPlaced.ShrinkDuration = setting.RSPlaced.ShrinkDuration; fogRepPlaced.Range = setting.RSPlaced.Range; fogRepPlaced.Offset = Vector3.zero; CarryItemPickup_Core componentInChildren = ((Component)item.m_root).GetComponentInChildren(); HeavyFogRepellerPickup val2 = ((Il2CppObjectBase)componentInChildren).Cast(); iCarryItemWithGlobalState val3 = default(iCarryItemWithGlobalState); byte byteId = default(byte); if (CarryItemWithGlobalStateManager.TryCreateItemInstance((eCarryItemWithGlobalStateType)0, item.m_root, ref val3, ref byteId)) { pItemData_Custom customData = ((Item)val2).GetCustomData(); customData.byteId = byteId; pItemData_Custom val4 = customData; ((Item)val2).SetCustomData(val4, true); } HeavyFogRepellerGlobalState val5 = ((Il2CppObjectBase)val3).Cast(); ((Component)fogRepHold).transform.SetParent(((Component)val5).transform, false); ((Component)fogRepPlaced).transform.SetParent(((Component)val5).transform, false); val5.m_repellerSphere = val; fogRepHold.m_sphereAllocator = new FogSphereAllocator(); fogRepPlaced.m_sphereAllocator = new FogSphereAllocator(); Interact_Pickup_PickupItem interact = ((Il2CppObjectBase)componentInChildren.m_interact).Cast(); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; val5.CallbackOnStateChange += Action.op_Implicit((Action)delegate(pCarryItemWithGlobalState_State oldState, pCarryItemWithGlobalState_State newState, bool isRecall) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0046: Unknown result type (might be due to invalid IL or missing references) if (isRecall) { FogRepeller_Sphere obj = fogRepHold; if (obj != null) { obj.KillRepellerInstantly(); } FogRepeller_Sphere obj2 = fogRepPlaced; if (obj2 != null) { obj2.KillRepellerInstantly(); } } else { eHeavyFogRepellerStatus val6 = (eHeavyFogRepellerStatus)newState.status; if ((int)val6 != 1) { if ((int)val6 == 2) { FogRepeller_Sphere obj3 = fogRepHold; if (obj3 != null) { obj3.StopRepelling(); } FogRepeller_Sphere obj4 = fogRepPlaced; if (obj4 != null) { obj4.StartRepelling(); } ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; } } else { FogRepeller_Sphere obj5 = fogRepHold; if (obj5 != null) { obj5.StartRepelling(); } if (oldState.status != 0) { FogRepeller_Sphere obj6 = fogRepPlaced; if (obj6 != null) { obj6.StopRepelling(); } } ((Interact_Timed)interact).InteractDuration = setting.TimeToPlace; } } }); } internal BigPickupFogBeaconImplementor() { } } } namespace TOA_Heavy_Industries { internal static class MTFOPartialDataIdResolver { private const string PartialDataPluginGuid = "MTFO.Extension.PartialBlocks"; private const string IdFileName = "_persistentID.json"; private static readonly object Sync = new object(); private static Dictionary? _guidToId; private static bool _loadAttempted; internal static bool TryResolve(string guid, out uint id) { id = 0u; if (string.IsNullOrWhiteSpace(guid)) { return false; } EnsureLoaded(); lock (Sync) { return _guidToId != null && _guidToId.TryGetValue(guid.Trim(), out id); } } private static void EnsureLoaded() { lock (Sync) { if (_loadAttempted) { return; } _loadAttempted = true; try { string text = TryGetPartialDataPathFromPlugin(); if (string.IsNullOrWhiteSpace(text)) { return; } string text2 = Path.Combine(text, "_persistentID.json"); if (File.Exists(text2)) { Dictionary dictionary = ReadPersistentIdFile(text2); if (dictionary.Count > 0) { _guidToId = dictionary; } } } catch (Exception ex) { TOARuntime.LogThrottled("MTFO PartialData persistentID resolver failed: " + ex.Message); } } } private static string TryGetPartialDataPathFromPlugin() { try { if (((BaseChainloader)(object)IL2CPPChainloader.Instance).Plugins.TryGetValue("MTFO.Extension.PartialBlocks", out var value)) { Assembly assembly = ((value == null) ? null : value.Instance?.GetType()?.Assembly); if (assembly != null && (assembly.GetTypes().FirstOrDefault((Type t) => string.Equals(t.Name, "PartialDataManager", StringComparison.Ordinal))?.GetProperty("PartialDataPath", BindingFlags.Static | BindingFlags.Public))?.GetValue(null) is string text && !string.IsNullOrWhiteSpace(text)) { return text; } } } catch { } return DiscoverPartialDataPathFromFileSystem(); } private static string DiscoverPartialDataPathFromFileSystem() { try { foreach (string item in Directory.EnumerateFiles(Paths.PluginPath, "_persistentID.json", SearchOption.AllDirectories)) { string directoryName = Path.GetDirectoryName(item); if (!string.IsNullOrWhiteSpace(directoryName)) { return directoryName; } } } catch { } return string.Empty; } private static Dictionary ReadPersistentIdFile(string idFilePath) { Dictionary dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); string text = File.ReadAllText(idFilePath); try { using JsonDocument jsonDocument = JsonDocument.Parse(text, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }); if (jsonDocument.RootElement.ValueKind == JsonValueKind.Array) { foreach (JsonElement item in jsonDocument.RootElement.EnumerateArray()) { if (TryReadGuidEntry(item, out string guid, out uint id)) { dictionary[guid] = id; } } } else if (jsonDocument.RootElement.ValueKind == JsonValueKind.Object) { foreach (JsonProperty item2 in jsonDocument.RootElement.EnumerateObject()) { if (TryReadUIntElement(item2.Value, out var id2) && !string.IsNullOrWhiteSpace(item2.Name)) { dictionary[item2.Name.Trim()] = id2; } } } } catch { foreach (Match item3 in Regex.Matches(text, "\\{[^{}]*\\\"GUID\\\"\\s*:\\s*\\\"(?(?:\\\\.|[^\\\"])*)\\\"[^{}]*\\\"ID\\\"\\s*:\\s*(?\\d+)[^{}]*\\}", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.CultureInvariant)) { string text2 = TOAJsonConfig.UnescapeJsonStringForRuntime(item3.Groups["guid"].Value).Trim(); if (!string.IsNullOrWhiteSpace(text2) && uint.TryParse(item3.Groups["id"].Value, out var result)) { dictionary[text2] = result; } } } return dictionary; } private static bool TryReadGuidEntry(JsonElement entry, out string guid, out uint id) { guid = string.Empty; id = 0u; if (entry.ValueKind != JsonValueKind.Object) { return false; } foreach (JsonProperty item in entry.EnumerateObject()) { if (string.Equals(item.Name, "GUID", StringComparison.OrdinalIgnoreCase) || string.Equals(item.Name, "Guid", StringComparison.OrdinalIgnoreCase) || string.Equals(item.Name, "persistentID", StringComparison.OrdinalIgnoreCase)) { guid = ((item.Value.ValueKind == JsonValueKind.String) ? (item.Value.GetString() ?? string.Empty).Trim() : item.Value.ToString().Trim()); } else if (string.Equals(item.Name, "ID", StringComparison.OrdinalIgnoreCase) || string.Equals(item.Name, "Id", StringComparison.OrdinalIgnoreCase)) { TryReadUIntElement(item.Value, out id); } } if (!string.IsNullOrWhiteSpace(guid)) { return id != 0; } return false; } private static bool TryReadUIntElement(JsonElement element, out uint id) { id = 0u; if (element.ValueKind == JsonValueKind.Number && element.TryGetUInt32(out var value)) { id = value; return true; } if (element.ValueKind == JsonValueKind.String && uint.TryParse(element.GetString(), out var result)) { id = result; return true; } return false; } } internal static class TOAConfigPaths { internal const string CustomRootFolderName = "TOA_Heavy_Industries"; internal static string GetFeaturePath(string featureName) { return Path.Combine(GetCustomPath(), "TOA_Heavy_Industries", featureName); } internal static string GetCustomPath() { if (TryGetMTFOCustomPath(out string customPath)) { return customPath; } return Path.Combine(Paths.BepInExRootPath, "Custom"); } private static bool TryGetMTFOCustomPath(out string customPath) { customPath = string.Empty; try { Type type = FindLoadedType("MTFO.API.MTFOPathAPI"); if (type == null) { return false; } if (type.GetProperty("CustomPath", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(null) is string text && !string.IsNullOrWhiteSpace(text)) { customPath = Path.GetFullPath(text); return true; } } catch (Exception ex) { TOARuntime.LogThrottled("Could not read MTFOPathAPI.CustomPath, falling back to BepInEx/Custom: " + ex.Message); } return false; } private static Type? FindLoadedType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false, ignoreCase: false); if (type != null) { return type; } } return null; } } internal sealed class TOALevelRule { internal string Name = string.Empty; internal string ButtonText = string.Empty; internal readonly HashSet OfflineIDs = new HashSet(); internal readonly HashSet LevelLayoutIDStrings = new HashSet(StringComparer.OrdinalIgnoreCase); internal bool HasAnySelector { get { if (OfflineIDs.Count <= 0) { return LevelLayoutIDStrings.Count > 0; } return true; } } } internal sealed class TOAConfigDocument { internal string FilePath = string.Empty; internal bool Enabled = true; internal bool EnableInstantReload; internal readonly List Levels = new List(); } internal static class TOAJsonConfig { internal const string ConfigFolderName = "TOA_Heavy_Industries"; internal const string GearSwapFeatureFolderName = "GearSwap"; internal const string ConfigFileName = "GearSwap.json"; internal const string ConfigSearchPattern = "*.json"; private static readonly object _sync = new object(); private static readonly List _configs = new List(); private static readonly List _configPaths = new List(); private static readonly List _watchers = new List(); private static string _lastConfigStamp = string.Empty; private static long _reloadPending; private static float _nextFallbackFileCheckTime; internal static string ConfigPathSummary { get { lock (_sync) { return (_configPaths.Count == 0) ? "" : string.Join(" | ", _configPaths); } } } internal static IReadOnlyList Configs { get { lock (_sync) { return _configs.ToArray(); } } } internal static bool IsInstantReloadEnabled { get { lock (_sync) { return _configs.Any((TOAConfigDocument c) => c.Enabled && c.EnableInstantReload); } } } internal static void LoadOrCreate(ManualLogSource? log, bool force = false) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Expected O, but got Unknown bool flag = default(bool); try { List list = DiscoverExistingConfigPaths().ToList(); if (list.Count == 0) { list = CreateDefaultConfigsInCandidateRundownFolders(log).ToList(); } string text = BuildConfigStamp(list); if (!force && text == _lastConfigStamp) { return; } List list2 = new List(); foreach (string item in list) { try { list2.Add(LoadConfigFile(item)); } catch (Exception ex) { ManualLogSource val = log; if (val != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(46, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to read TOA_Heavy_Industries JSON at "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex); } val.LogError(val2); } } } lock (_sync) { _configs.Clear(); _configs.AddRange(list2); _configPaths.Clear(); _configPaths.AddRange(list); _lastConfigStamp = text; } Interlocked.Exchange(ref _reloadPending, 0L); ApplyInstantReloadMode(log); } catch (Exception ex2) { ManualLogSource val = log; if (val != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(52, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Failed to load TOA_Heavy_Industries JSON config(s): "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2); } val.LogError(val2); } } } internal static void ApplyInstantReloadMode(ManualLogSource? log) { if (IsInstantReloadEnabled) { RestartWatchers(log); } else { StopWatchers(); } } internal static void ReloadIfChanged(ManualLogSource? log) { if (IsInstantReloadEnabled) { bool flag = Interlocked.Read(in _reloadPending) != 0; bool flag2 = Time.realtimeSinceStartup >= _nextFallbackFileCheckTime; if (flag || flag2) { _nextFallbackFileCheckTime = Time.realtimeSinceStartup + 5f; LoadOrCreate(log, flag); } } } private static TOAConfigDocument LoadConfigFile(string configPath) { string json = StripJsonLineComments(File.ReadAllText(configPath)); TOAConfigDocument tOAConfigDocument = new TOAConfigDocument { FilePath = configPath, Enabled = ReadBool(json, "Enabled", defaultValue: true), EnableInstantReload = ReadBool(json, "EnableInstantReload", defaultValue: false) }; TOALevelRule tOALevelRule = new TOALevelRule { Name = "MainLevelLayoutIDs", ButtonText = "Switch Gear" }; AddUIntOrStringValue(json, "MainLevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings); if (tOALevelRule.HasAnySelector) { tOAConfigDocument.Levels.Add(tOALevelRule); } return tOAConfigDocument; } private static IEnumerable ReadLevelRules(string json) { List list = new List(); string[] array = new string[6] { "Levels", "LevelLayouts", "Rundowns", "Entries", "Groups", "AllowedLevels" }; foreach (string propertyName in array) { string text = ExtractNamedArrayContent(json, propertyName); if (!string.IsNullOrWhiteSpace(text)) { list.AddRange(ExtractTopLevelObjectBlocksFromArray(text)); } } if (list.Count == 0 && json.TrimStart().StartsWith("[", StringComparison.Ordinal)) { list.AddRange(ExtractTopLevelObjectBlocksFromArray(json)); } foreach (string item in list) { TOALevelRule tOALevelRule = new TOALevelRule { Name = ReadString(item, "Name", string.Empty), ButtonText = ReadString(item, "ButtonText", "Switch Gear") }; AddUIntArray(item, "OfflineIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings); AddUIntArray(item, "LevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings); AddUIntArray(item, "AllowedLevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings); AddUIntOrStringValue(item, "MainLevelLayoutIDs", tOALevelRule.OfflineIDs, tOALevelRule.LevelLayoutIDStrings); AddStringArray(item, "PartialDataIDs", tOALevelRule.LevelLayoutIDStrings); AddStringArray(item, "PartialDataLevelLayoutIDs", tOALevelRule.LevelLayoutIDStrings); AddStringArray(item, "LevelLayoutIDStrings", tOALevelRule.LevelLayoutIDStrings); AddStringArray(item, "AllowedLevelLayoutIDStrings", tOALevelRule.LevelLayoutIDStrings); AddStringArray(item, "AllowedPartialDataLevelLayoutIDs", tOALevelRule.LevelLayoutIDStrings); AddStringArray(item, "BlockNames", tOALevelRule.LevelLayoutIDStrings); AddStringArray(item, "LevelLayoutNames", tOALevelRule.LevelLayoutIDStrings); if (tOALevelRule.HasAnySelector) { yield return tOALevelRule; } } } private static void RestartWatchers(ManualLogSource? log) { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Expected O, but got Unknown try { StopWatchers(); lock (_sync) { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (string configPath in _configPaths) { string directoryName = Path.GetDirectoryName(configPath); if (!string.IsNullOrWhiteSpace(directoryName) && Directory.Exists(directoryName)) { hashSet.Add(directoryName); } } using HashSet.Enumerator enumerator2 = hashSet.GetEnumerator(); while (enumerator2.MoveNext()) { FileSystemWatcher fileSystemWatcher = new FileSystemWatcher(enumerator2.Current, "*.json") { NotifyFilter = (NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite | NotifyFilters.CreationTime), IncludeSubdirectories = false, EnableRaisingEvents = true }; fileSystemWatcher.Changed += delegate { MarkReloadPending(); }; fileSystemWatcher.Created += delegate { MarkReloadPending(); }; fileSystemWatcher.Renamed += delegate { MarkReloadPending(); }; fileSystemWatcher.Deleted += delegate { MarkReloadPending(); }; _watchers.Add(fileSystemWatcher); } } } catch (Exception ex) { if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(84, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Could not start instant JSON reload watcher. Falling back to passive file checks. "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } private static void StopWatchers() { lock (_sync) { foreach (FileSystemWatcher watcher in _watchers) { try { watcher.Dispose(); } catch { } } _watchers.Clear(); } } private static void MarkReloadPending() { Interlocked.Exchange(ref _reloadPending, 1L); } private static IEnumerable DiscoverExistingConfigPaths() { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (string item in EnumerateFilesSafe(TOAConfigPaths.GetFeaturePath("GearSwap"), "*.json", SearchOption.TopDirectoryOnly)) { hashSet.Add(Path.GetFullPath(item)); } return hashSet.OrderBy((string p) => p, StringComparer.OrdinalIgnoreCase); } private static IEnumerable CreateDefaultConfigsInCandidateRundownFolders(ManualLogSource? log) { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); hashSet.Add(TOAConfigPaths.GetFeaturePath("GearSwap")); foreach (string item in hashSet.OrderBy((string p) => p, StringComparer.OrdinalIgnoreCase)) { Directory.CreateDirectory(item); string path = Path.Combine(item, "GearSwap.json"); if (!File.Exists(path)) { File.WriteAllText(path, CreateDefaultJson()); } yield return Path.GetFullPath(path); } } private static IEnumerable DiscoverRundownCustomRoots() { HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (string item in EnumerateDirectoriesSafe(Paths.PluginPath, "Custom", SearchOption.AllDirectories)) { string fullPath = Path.GetFullPath(item); if (fullPath.IndexOf(Path.DirectorySeparatorChar + "TOA_Heavy_Industries" + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase) < 0) { hashSet.Add(fullPath); } } return hashSet.OrderBy((string p) => p, StringComparer.OrdinalIgnoreCase); } private static IEnumerable EnumerateDirectoriesSafe(string root, string searchPattern, SearchOption option) { if (!Directory.Exists(root)) { return Array.Empty(); } try { return Directory.EnumerateDirectories(root, searchPattern, option).ToArray(); } catch { return Array.Empty(); } } private static IEnumerable EnumerateFilesSafe(string root, string searchPattern, SearchOption option) { if (!Directory.Exists(root)) { return Array.Empty(); } try { return (from path in Directory.EnumerateFiles(root, searchPattern, option) where !ShouldIgnoreConfigFile(path) select path).ToArray(); } catch { return Array.Empty(); } } private static bool ShouldIgnoreConfigFile(string path) { string fileName = Path.GetFileName(path); if (!fileName.StartsWith("Template", StringComparison.OrdinalIgnoreCase) && !fileName.StartsWith("README", StringComparison.OrdinalIgnoreCase)) { return fileName.StartsWith("Example", StringComparison.OrdinalIgnoreCase); } return true; } private static string GetPluginAssemblyDirectory() { try { string location = Assembly.GetExecutingAssembly().Location; string text = (string.IsNullOrWhiteSpace(location) ? null : Path.GetDirectoryName(location)); if (!string.IsNullOrWhiteSpace(text)) { return text; } } catch { } return Paths.PluginPath; } private static string BuildConfigStamp(IEnumerable configPaths) { StringBuilder stringBuilder = new StringBuilder(); foreach (string item in configPaths.OrderBy((string p) => p, StringComparer.OrdinalIgnoreCase)) { DateTime dateTime = (File.Exists(item) ? File.GetLastWriteTimeUtc(item) : DateTime.MinValue); long value = (File.Exists(item) ? new FileInfo(item).Length : (-1)); stringBuilder.Append(item).Append('|').Append(dateTime.Ticks) .Append('|') .Append(value) .Append('\n'); } return stringBuilder.ToString(); } private static bool ReadBool(string json, string propertyName, bool defaultValue) { Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:\\s*(true|false)", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); if (!match.Success) { return defaultValue; } return string.Equals(match.Groups[1].Value, "true", StringComparison.OrdinalIgnoreCase); } private static string ReadString(string json, string propertyName, string defaultValue) { Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:\\s*\\\"(?(?:\\\\.|[^\\\"])*)\\\"", RegexOptions.Singleline | RegexOptions.CultureInvariant); if (!match.Success) { return defaultValue; } string text = UnescapeJsonString(match.Groups["value"].Value).Trim(); if (!string.IsNullOrWhiteSpace(text)) { return text; } return defaultValue; } private static void AddUIntOrStringValue(string json, string propertyName, HashSet numericTarget, HashSet stringTarget) { if (!TryReadScalarValue(json, propertyName, out string value)) { return; } string text = value.Trim(); if (!string.IsNullOrWhiteSpace(text)) { if (uint.TryParse(text, out var result)) { numericTarget.Add(result); } else { stringTarget.Add(text); } } } private static bool TryReadScalarValue(string json, string propertyName, out string value) { value = string.Empty; Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); if (!match.Success) { return false; } int i; for (i = match.Index + match.Length; i < json.Length && char.IsWhiteSpace(json[i]); i++) { } if (i >= json.Length) { return false; } if (json[i] == '[' || json[i] == '{') { return false; } if (json[i] == '"') { StringBuilder stringBuilder = new StringBuilder(); bool flag = false; for (i++; i < json.Length; i++) { char c = json[i]; if (flag) { stringBuilder.Append('\\').Append(c); flag = false; continue; } switch (c) { case '\\': flag = true; break; case '"': value = UnescapeJsonString(stringBuilder.ToString()); return true; default: stringBuilder.Append(c); break; } } return false; } int num = i; for (; i < json.Length && !char.IsWhiteSpace(json[i]) && json[i] != ',' && json[i] != '}' && json[i] != ']'; i++) { } value = json.Substring(num, i - num).Trim(); return !string.IsNullOrWhiteSpace(value); } private static void AddUIntArray(string json, string propertyName, HashSet numericTarget, HashSet stringTarget) { string text = ExtractNamedArrayContent(json, propertyName); if (string.IsNullOrWhiteSpace(text)) { return; } foreach (string item in ReadTopLevelArrayScalarItems(text)) { string text2 = item.Trim(); if (uint.TryParse(text2, out var result)) { numericTarget.Add(result); } else if (!string.IsNullOrWhiteSpace(text2)) { stringTarget.Add(text2); } } } private static void AddStringArray(string json, string propertyName, HashSet target) { string text = ExtractNamedArrayContent(json, propertyName); if (string.IsNullOrWhiteSpace(text)) { return; } foreach (string item in ReadArrayStringItems(text)) { string text2 = item.Trim(); if (!string.IsNullOrWhiteSpace(text2)) { target.Add(text2); } } } private static IEnumerable ReadArrayStringItems(string arrayContent) { foreach (string item in ReadTopLevelArrayScalarItems(arrayContent)) { if (!uint.TryParse(item.Trim(), out var _)) { yield return item; } } } private static IEnumerable ReadTopLevelArrayScalarItems(string arrayContent) { string text = arrayContent.Trim(); if (text.StartsWith("[", StringComparison.Ordinal)) { int num = FindMatchingBracket(text, 0, '[', ']'); if (num > 0) { text = text.Substring(1, num - 1); } } bool inString = false; bool escaped = false; int objectDepth = 0; int arrayDepth = 0; int tokenStart = -1; StringBuilder stringBuilder = null; for (int i = 0; i <= text.Length; i++) { char c = ((i < text.Length) ? text[i] : ','); if (inString) { if (escaped) { stringBuilder?.Append('\\').Append(c); escaped = false; continue; } switch (c) { case '\\': escaped = true; break; case '"': inString = false; if (objectDepth == 0 && arrayDepth == 0 && stringBuilder != null) { yield return UnescapeJsonString(stringBuilder.ToString()); } stringBuilder = null; break; default: stringBuilder?.Append(c); break; } continue; } switch (c) { case '"': inString = true; escaped = false; stringBuilder = ((objectDepth == 0 && arrayDepth == 0) ? new StringBuilder() : null); tokenStart = -1; continue; case '{': objectDepth++; tokenStart = -1; continue; case '}': if (objectDepth > 0) { objectDepth--; } tokenStart = -1; continue; case '[': arrayDepth++; tokenStart = -1; continue; case ']': if (arrayDepth > 0) { arrayDepth--; } tokenStart = -1; continue; } if (objectDepth != 0 || arrayDepth != 0) { tokenStart = -1; } else if (char.IsWhiteSpace(c) || c == ',') { if (tokenStart >= 0) { string text2 = text.Substring(tokenStart, i - tokenStart).Trim(); if (!string.IsNullOrWhiteSpace(text2)) { yield return text2; } tokenStart = -1; } } else if (tokenStart < 0) { tokenStart = i; } } } private static string? ExtractNamedArrayContent(string json, string propertyName) { Match match = Regex.Match(json, "\\\"" + Regex.Escape(propertyName) + "\\\"\\s*:", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); if (!match.Success) { return null; } int num = json.IndexOf('[', match.Index + match.Length); if (num < 0) { return null; } int num2 = FindMatchingBracket(json, num, '[', ']'); if (num2 <= num) { return null; } return json.Substring(num + 1, num2 - num - 1); } private static IEnumerable ExtractTopLevelObjectBlocksFromArray(string arrayOrArrayContent) { string text = arrayOrArrayContent.Trim(); if (text.StartsWith("[", StringComparison.Ordinal)) { int num = FindMatchingBracket(text, 0, '[', ']'); if (num > 0) { text = text.Substring(1, num - 1); } } bool inString = false; bool escaped = false; int depth = 0; int num2 = -1; for (int i = 0; i < text.Length; i++) { char c = text[i]; if (inString) { if (escaped) { escaped = false; continue; } switch (c) { case '\\': escaped = true; break; case '"': inString = false; break; } continue; } switch (c) { case '"': inString = true; break; case '{': if (depth == 0) { num2 = i; } depth++; break; case '}': depth--; if (depth == 0 && num2 >= 0) { yield return text.Substring(num2, i - num2 + 1); num2 = -1; } break; } } } private static int FindMatchingBracket(string text, int openIndex, char openChar, char closeChar) { bool flag = false; bool flag2 = false; int num = 0; for (int i = openIndex; i < text.Length; i++) { char c = text[i]; if (flag) { if (flag2) { flag2 = false; continue; } switch (c) { case '\\': flag2 = true; break; case '"': flag = false; break; } } else if (c == '"') { flag = true; } else if (c == openChar) { num++; } else if (c == closeChar) { num--; if (num == 0) { return i; } } } return -1; } private static string StripJsonLineComments(string json) { StringBuilder stringBuilder = new StringBuilder(json.Length); bool flag = false; bool flag2 = false; for (int i = 0; i < json.Length; i++) { char c = json[i]; if (flag) { stringBuilder.Append(c); if (flag2) { flag2 = false; continue; } switch (c) { case '\\': flag2 = true; break; case '"': flag = false; break; } continue; } switch (c) { case '"': flag = true; stringBuilder.Append(c); continue; case '/': if (i + 1 < json.Length && json[i + 1] == '/') { for (; i < json.Length && json[i] != '\n'; i++) { } if (i < json.Length) { stringBuilder.Append(json[i]); } continue; } break; } stringBuilder.Append(c); } return stringBuilder.ToString(); } internal static string UnescapeJsonStringForRuntime(string value) { return UnescapeJsonString(value); } private static string UnescapeJsonString(string value) { return value.Replace("\\\"", "\"").Replace("\\\\", "\\").Replace("\\/", "/") .Replace("\\n", "\n") .Replace("\\r", "\r") .Replace("\\t", "\t"); } private static string CreateDefaultJson() { return "{\n \"Enabled\": true,\n \"EnableInstantReload\": false,\n \"MainLevelLayoutIDs\": \"Level_10_L1\"\n}\n"; } } internal static class TOATextResolver { internal static string Resolve(string text) { if (string.IsNullOrWhiteSpace(text)) { return string.Empty; } string text2 = text.Trim(); try { if (uint.TryParse(text2, out var result) && result != 0) { return Text.Get(result); } if (MTFOPartialDataIdResolver.TryResolve(text2, out var id) && id != 0) { return Text.Get(id); } } catch (Exception ex) { TOARuntime.LogThrottled("TOA text resolver failed for '" + text2 + "': " + ex.Message); } return text; } internal static string ResolveObject(object? value) { if (value == null) { return string.Empty; } try { uint num = ReadUInt(value, "Id"); if (num != 0) { string text = Text.Get(num); if (!string.IsNullOrWhiteSpace(text) && !text.Equals("Localization.LocalizedText", StringComparison.Ordinal)) { return text; } } string text2 = ReadMember(value, "UntranslatedText")?.ToString() ?? string.Empty; if (!string.IsNullOrWhiteSpace(text2)) { return text2; } string text3 = value.ToString() ?? string.Empty; return text3.Equals("Localization.LocalizedText", StringComparison.Ordinal) ? string.Empty : text3; } catch (Exception ex) { TOARuntime.LogThrottled("TOA localized object resolver failed: " + ex.Message); return string.Empty; } } private static uint ReadUInt(object value, string name) { object obj = ReadMember(value, name); if (obj != null) { return Convert.ToUInt32(obj); } return 0u; } private static object? ReadMember(object value, string name) { Type type = value.GetType(); object obj = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value); if (obj != null) { return obj; } return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(value); } } internal sealed class TOAEventScanComponent : MonoBehaviour { public const float UPDATE_INTERVAL = 0.3f; public const string VANILLA_CP_PREFAB_PATH = "Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab"; private GameObject _root; private GameObject _cylinder; private GameObject _visual; private GameObject _information; private readonly List _visualRenderers = new List(); private float time = float.NaN; private float m_colorLerpDelta; private const float LERP_DURATION = 0.5f; public GameObject Cylinder => _cylinder; public GameObject Visual => _visual; public GameObject Information => _information; public GameObject TextMeshProGO { get { if (Information.transform.childCount <= 0) { return Information; } return ((Component)Information.transform.GetChild(0)).gameObject; } } public Renderer VisualRenderer { get; private set; } public TextMeshPro DisplayText { get; private set; } private Vector3 Position => ((Component)this).gameObject.transform.position; public StateReplicator StateReplicator { get; private set; } public TOAEventScanDefinition def { get; internal set; } internal bool ExecuteEventsLocally { get; set; } = true; internal bool IsActive { get { if (StateReplicator != null) { return StateReplicator.State.Status == TOAEventScanState.Active; } return false; } } internal bool IsInactive { get { if (StateReplicator != null) { return StateReplicator.State.Status != TOAEventScanState.Active; } return false; } } public Color Color_Waiting { get; private set; } public Color Color_Active { get; private set; } private bool TryBindAssetHierarchy() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!TryBindLegacyHierarchy()) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(108, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' asset hierarchy mismatch. Expected TOA/Legacy shape root/Cylinder+Visual(+Information). Actual="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DescribeHierarchy(((Component)this).gameObject.transform, 4)); } log.LogError(val); } return false; } DisplayText = _information.GetComponentInChildren(true) ?? _root.GetComponentInChildren(true); _visualRenderers.Clear(); foreach (Renderer componentsInChild in _visual.GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild != (Object)null) { _visualRenderers.Add(componentsInChild); } } if (_visualRenderers.Count == 0) { foreach (Renderer componentsInChild2 in _root.GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild2 != (Object)null) { _visualRenderers.Add(componentsInChild2); } } } VisualRenderer = _visual.GetComponentInChildren(true); return _visualRenderers.Count > 0; } private bool TryBindLegacyHierarchy() { //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown if (((Component)this).gameObject.transform.childCount == 0) { return false; } _root = ((Component)((Component)this).gameObject.transform.GetChild(0)).gameObject; if (_root.transform.childCount >= 3) { _cylinder = ((Component)_root.transform.GetChild(0)).gameObject; _visual = ((Component)_root.transform.GetChild(1)).gameObject; _information = ((Component)_root.transform.GetChild(2)).gameObject; return true; } if (_root.transform.childCount >= 2) { _cylinder = ((Component)_root.transform.GetChild(0)).gameObject; _visual = ((Component)_root.transform.GetChild(1)).gameObject; _information = EnsureInformationObject(_root.transform); ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(123, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' asset has no Information child. A TOA Information container was created so the Legacy EventScan logic can run."); } log.LogWarning(val); } return true; } return false; } private static GameObject EnsureInformationObject(Transform root) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown for (int i = 0; i < root.childCount; i++) { Transform child = root.GetChild(i); if ((Object)(object)child != (Object)null && ((Object)child).name.IndexOf("Information", StringComparison.OrdinalIgnoreCase) >= 0) { return ((Component)child).gameObject; } } GameObject val = new GameObject("Information"); val.transform.SetParent(root, false); return val; } private static string DescribeHierarchy(Transform transform, int depth) { if (depth <= 0 || (Object)(object)transform == (Object)null) { return string.Empty; } StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append(((Object)transform).name); stringBuilder.Append('('); stringBuilder.Append(transform.childCount); stringBuilder.Append(')'); if (transform.childCount > 0) { stringBuilder.Append(": "); for (int i = 0; i < transform.childCount; i++) { if (i > 0) { stringBuilder.Append(", "); } stringBuilder.Append(DescribeHierarchy(transform.GetChild(i), depth - 1)); } } return stringBuilder.ToString(); } public void Setup() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_03a5: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Unknown result type (might be due to invalid IL or missing references) //IL_03f6: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0428: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Expected O, but got Unknown //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Expected O, but got Unknown if (def == null) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogError((object)"EventScan Setup: assign a EventScanDefinition before calling Setup()!"); } return; } ((Component)this).gameObject.transform.SetPositionAndRotation(def.Position.ToVector3(), Quaternion.identity); bool flag = default(bool); ManualLogSource log2; if (!TryBindAssetHierarchy()) { log2 = TOARuntime.Log; if (log2 != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(137, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' setup failed because the TOA EventScan AssetBundle prefab does not expose the required TOA/Legacy EventScan visual children."); } log2.LogError(val); } return; } ((Component)this).gameObject.SetActiveRecursively(true); if ((Object)(object)DisplayText == (Object)null && def.ShowDisplayText) { TryCreateDisplayTextFromVanillaCP(); } if ((Object)(object)DisplayText != (Object)null) { if (def.ShowDisplayText) { ((TMP_Text)DisplayText).SetText(LocalizedText.op_Implicit(def.DisplayText), true); ((TMP_Text)DisplayText).ForceMeshUpdate(false, false); Information.SetActive(true); ((Component)DisplayText).gameObject.SetActive(true); } else { foreach (TMP_Text componentsInChild in _root.GetComponentsInChildren(true)) { if ((Object)(object)componentsInChild != (Object)null) { componentsInChild.SetText(string.Empty, true); ((Component)componentsInChild).gameObject.SetActive(false); } } Information.SetActive(false); } } else if (def.ShowDisplayText) { log2 = TOARuntime.Log; if (log2 != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(122, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' has ShowDisplayText=true but neither TOA EventScan nor vanilla CP text could provide a TextMeshPro component."); } log2.LogWarning(val2); } } log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val3 = new BepInExMessageLogInterpolatedStringHandler(65, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': using TOA EventScan AssetBundle prefab at "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Component)this).gameObject.transform.position); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" radius="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(def.Radius); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); } log2.LogMessage(val3); } log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val3 = new BepInExMessageLogInterpolatedStringHandler(80, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': bound Root='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)_root).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Visual='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)_visual).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Cylinder='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)_cylinder).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Information='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(((Object)_information).name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Renderers="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(_visualRenderers.Count); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); } log2.LogMessage(val3); } TOAVec3 waiting = def.ColorSetting.Waiting; TOAVec3 active = def.ColorSetting.Active; Color_Waiting = new Color(waiting.x, waiting.y, waiting.z); Color_Active = new Color(active.x, active.y, active.z); float num = 0.16216217f; float num2 = Mathf.Max(0.01f, def.Radius); ((Component)this).gameObject.transform.localScale = new Vector3(num2, num2, num2); Transform transform = ((Component)this).gameObject.transform; transform.localPosition += Vector3.up * num; SetVisualColor(Color_Waiting); uint num3 = EOSNetworking.AllotReplicatorID(); if (num3 == 0) { TOANetworkStateAudit.Current.ReplicatorFailed("EventScan:" + def.WorldEventObjectFilter, "Replicator ID depleted"); ManualLogSource? log3 = TOARuntime.Log; if (log3 != null) { log3.LogError((object)"EventScan: Replicator ID depleted, cannot setup"); } return; } StateReplicator = TOAStateReplicatorCompat.Create(num3, new TOAEventScanStatus { Status = TOAEventScanState.Waiting }, (LifeTimeType)1, "EventScan:" + def.WorldEventObjectFilter); if (StateReplicator == null) { TOANetworkStateAudit.Current.ReplicatorFailed("EventScan:" + def.WorldEventObjectFilter, "StateReplicator creation failed"); log2 = TOARuntime.Log; if (log2 != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(57, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan:"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": StateReplicator creation failed, cannot setup"); } log2.LogError(val); } } else { StateReplicator.OnStateChanged += OnStateChange; TOANetworkStateAudit.Current.ReplicatorCreated("EventScan:" + def.WorldEventObjectFilter, num3, "Level"); } } private void TryCreateDisplayTextFromVanillaCP() { //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown bool flag = default(bool); try { GameObject loadedAsset = AssetAPI.GetLoadedAsset("Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab"); if ((Object)(object)loadedAsset == (Object)null || loadedAsset.transform.childCount == 0) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(83, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' could not clone display text because vanilla CP prefab was not loaded."); } log.LogWarning(val); } return; } Transform child = loadedAsset.transform.GetChild(0); if (child.childCount <= 1) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(92, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' could not clone display text because vanilla CP prefab hierarchy is unexpected."); } log.LogWarning(val); } } else { GameObject val2 = Object.Instantiate(((Component)child.GetChild(1)).gameObject); ((Object)val2).name = "TOA_EventScan_DisplayText"; val2.transform.SetParent(_information.transform, false); float num = Mathf.Max(0.01f, def.Radius); val2.transform.localScale = new Vector3(1f / num, 1f / num, 1f / num); DisplayText = val2.GetComponentInChildren(true); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(61, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' failed to clone display text from vanilla CP: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } private void SetVisualColor(Color color) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (_visualRenderers.Count == 0) { return; } foreach (Renderer visualRenderer in _visualRenderers) { if ((Object)(object)visualRenderer == (Object)null) { continue; } Material material = visualRenderer.material; if (!((Object)(object)material == (Object)null)) { if (material.HasProperty("_ColorA")) { material.SetColor("_ColorA", color); } if (material.HasProperty("_Color")) { material.SetColor("_Color", color); } material.color = color; } } } private void OnStateChange(TOAEventScanStatus oldState, TOAEventScanStatus newState, bool isRecall) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(15, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(oldState.Status); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" => "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(newState.Status); } log.LogWarning(val); } if (isRecall) { TOANetworkStateAudit.Current.StateRecall("EventScan:" + def.WorldEventObjectFilter, oldState.Status.ToString(), newState.Status.ToString()); } switch (newState.Status) { case TOAEventScanState.Disabled: { m_colorLerpDelta = 0f; TextMeshPro displayText3 = DisplayText; if (displayText3 != null) { ((Component)displayText3).gameObject.SetActive(false); } Information.SetActive(false); Cylinder.SetActive(false); CoroutineManager.BlinkOut(Visual, 0f); break; } case TOAEventScanState.Waiting: if (!Visual.active) { CoroutineManager.BlinkIn(Visual, 0f); Cylinder.SetActive(true); if (def.ShowDisplayText) { Information.SetActive(true); TextMeshPro displayText2 = DisplayText; if (displayText2 != null) { ((Component)displayText2).gameObject.SetActive(true); } } } if (!isRecall && ExecuteEventsLocally && oldState.Status == TOAEventScanState.Active) { using (TOAType2003TriggerScope.PushRadius("TOA_EventScan_Deactivate", Position, def.Radius)) { ExecuteConfiguredEvents(def.EventsOnDeactivate, "Deactivate"); } } break; case TOAEventScanState.Active: if (!Visual.active) { CoroutineManager.BlinkIn(Visual, 0f); Cylinder.SetActive(true); if (def.ShowDisplayText) { Information.SetActive(true); TextMeshPro displayText = DisplayText; if (displayText != null) { ((Component)displayText).gameObject.SetActive(true); } } } if (!isRecall && ExecuteEventsLocally && oldState.Status == TOAEventScanState.Waiting) { using (TOAType2003TriggerScope.PushRadius("TOA_EventScan_Activate", Position, def.Radius)) { ExecuteConfiguredEvents(def.EventsOnActivate, "Activate"); } } break; } TOAEventScanManager.Current.EvaluateIndexGroups(!isRecall); } private void ExecuteConfiguredEvents(List events, string transition) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown bool flag = default(bool); foreach (WardenObjectiveEventData @event in events) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(86, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(transition); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": dispatching configured vanilla/custom event. Filter='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(@event.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', Count="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(@event.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Duration="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(@event.Duration, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(@event, (eWardenObjectiveEventTrigger)0, true, 0f); } } public void ChangeToState(TOAEventScanState newState) { ChangedToStateUnsynced(newState); if (StateReplicator != null && TOANetworkStateAudit.Current.CanMasterWrite("EventScan:" + def.WorldEventObjectFilter, $"SetState:{newState}")) { StateReplicator.SetState(new TOAEventScanStatus { Status = newState }); } } private void ChangedToStateUnsynced(TOAEventScanState newState) { } private void Update() { //IL_0058: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012a: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0207: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Invalid comparison between Unknown and I4 //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Expected O, but got Unknown //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) if (StateReplicator == null) { return; } TOAEventScanState status = StateReplicator.State.Status; if (status == TOAEventScanState.Disabled) { return; } float num = Clock.Delta / 0.5f; if (status == TOAEventScanState.Waiting) { num = 0f - num; } float colorLerpDelta = m_colorLerpDelta; m_colorLerpDelta = Mathf.Clamp01(m_colorLerpDelta + num); if (!Mathf.Approximately(colorLerpDelta, m_colorLerpDelta)) { Color visualColor = Color.Lerp(Color_Waiting, Color_Active, Mathf.Pow(m_colorLerpDelta, 5f)); SetVisualColor(visualColor); } if (!float.IsNaN(time) && Clock.Time < time + 0.3f) { return; } time = Clock.Time + 0.3f; if (def.ActiveCondition.RequiredPlayerCount == 0 && def.ActiveCondition.RequiredBigPickupIndices.Count == 0) { return; } bool flag = false; bool flag2 = false; Vector3 val; if (def.ActiveCondition.RequiredPlayerCount > 0) { int num2 = 0; Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!((Object)(object)current != (Object)null) || !((Agent)current).Alive) { continue; } val = Position - ((Agent)current).Position; if (((Vector3)(ref val)).magnitude < def.Radius) { num2++; if (num2 >= def.ActiveCondition.RequiredPlayerCount) { flag = true; break; } } } } else { flag = true; } if (flag) { List requiredBigPickupIndices = def.ActiveCondition.RequiredBigPickupIndices; if (requiredBigPickupIndices.Count > 0) { int num3 = 0; bool flag3 = default(bool); foreach (int item in requiredBigPickupIndices) { CarryItemPickup_Core bigPickupItem = PuzzleReqItemManager.Current.GetBigPickupItem(item); if ((Object)(object)bigPickupItem == (Object)null) { num3++; continue; } pPickupItemState currentState = bigPickupItem.m_sync.GetCurrentState(); Vector3 zero = Vector3.zero; ePickupItemStatus status2 = currentState.status; if ((int)status2 != 0) { if ((int)status2 != 1) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("Item has invalid state: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(currentState.status); } log.LogError(val2); } continue; } zero = ((Component)bigPickupItem.PickedUpByPlayer).transform.position; } else { zero = ((Component)bigPickupItem).transform.position; } val = Position - zero; if (((Vector3)(ref val)).magnitude < def.Radius) { num3++; } } flag2 = num3 >= requiredBigPickupIndices.Count; } else { flag2 = true; } } switch (status) { case TOAEventScanState.Waiting: if (flag && flag2) { ChangeToState(TOAEventScanState.Active); } break; case TOAEventScanState.Active: if (!flag || !flag2) { ChangeToState(TOAEventScanState.Waiting); } break; } } private void OnDestroy() { def = null; VisualRenderer = null; DisplayText = null; StateReplicator = null; } static TOAEventScanComponent() { ClassInjector.RegisterTypeInIl2Cpp(); } } public class TOAEventScanColorSetting { public TOAVec3 Waiting { get; set; } = new TOAVec3 { x = 0.5294f, y = 0.8078f, z = 0.9215f }; public TOAVec3 Active { get; set; } = new TOAVec3 { x = 1f, y = 0.7529f, z = 0.145f }; } public class TOAEventScanActiveCondition { public int RequiredPlayerCount { get; set; } public List RequiredBigPickupIndices { get; set; } = new List(); } public class TOAEventScanDefinition { public string WorldEventObjectFilter { get; set; } = string.Empty; public int Index { get; set; } = -1; public List RequiredEventScanIndices { get; set; } = new List(); public bool UseRequiredEventScanIndicesEvents { get; set; } public TOAVec3 Position { get; set; } = new TOAVec3(); public float Radius { get; set; } = 3.2f; public bool ShowDisplayText { get; set; } public TOAEventScanColorSetting ColorSetting { get; set; } = new TOAEventScanColorSetting(); public LocalizedText DisplayText { get; set; } public TOAEventScanActiveCondition ActiveCondition { get; set; } = new TOAEventScanActiveCondition(); public List EventsOnActivate { get; set; } = new List(); public List EventsOnDeactivate { get; set; } = new List(); public List RequiredEventScanEventsOnActivate { get; set; } = new List(); public List RequiredEventScanEventsOnDeactivate { get; set; } = new List(); } public enum TOAEventScanState { Disabled, Waiting, Active } public struct TOAEventScanStatus { public TOAEventScanState Status; } internal static class TOAEventScanEvents { internal static void ToggleEventScanState(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.ToggleEventScanState, eventData)) { TOAEventScanManager.Current.ToggleEventScanState(eventData.WorldEventObjectFilter, eventData.Enabled); } } } internal sealed class TOAEventScanIndexGroup { private readonly TOAEventScanDefinition _definition; private readonly List _requiredIndices; private readonly Dictionary _eventScansByIndex; private bool _initialized; private bool _hasActivatedSinceFullInactive; internal TOAEventScanIndexGroup(TOAEventScanDefinition definition, List requiredIndices, Dictionary eventScansByIndex) { _definition = definition; _requiredIndices = requiredIndices; _eventScansByIndex = eventScansByIndex; } internal void Evaluate(bool executeEvents) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown TOAEventScanComponent value; bool flag = _requiredIndices.All((int index) => _eventScansByIndex.TryGetValue(index, out value) && value.IsActive); bool flag2 = _requiredIndices.All((int index) => _eventScansByIndex.TryGetValue(index, out value) && value.IsInactive); if (!_initialized) { _initialized = true; _hasActivatedSinceFullInactive = flag; } else { bool flag3 = default(bool); ManualLogSource log; if (flag) { _hasActivatedSinceFullInactive = true; log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(54, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan index group '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_definition.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(string.Join(",", _requiredIndices)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]: NotAllActive => AllActive"); } log.LogWarning(val); } if (!executeEvents || !_definition.UseRequiredEventScanIndicesEvents) { return; } { foreach (WardenObjectiveEventData item in _definition.RequiredEventScanEventsOnActivate) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(item, (eWardenObjectiveEventTrigger)0, true, 0f); } return; } } if (!flag2 || !_hasActivatedSinceFullInactive) { return; } _hasActivatedSinceFullInactive = false; log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(55, 2, ref flag3); if (flag3) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan index group '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_definition.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ["); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(string.Join(",", _requiredIndices)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("]: ActiveCycle => AllInactive"); } log.LogWarning(val); } if (!executeEvents || !_definition.UseRequiredEventScanIndicesEvents) { return; } foreach (WardenObjectiveEventData item2 in _definition.RequiredEventScanEventsOnDeactivate) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(item2, (eWardenObjectiveEventTrigger)0, true, 0f); } } } } internal sealed class TOAEventScanManager { private sealed class CachedEventScanDefinitionFile { internal readonly long LastWriteUtcTicks; internal readonly long Length; internal readonly GenericExpeditionDefinition Definition; internal CachedEventScanDefinitionFile(long lastWriteUtcTicks, long length, GenericExpeditionDefinition definition) { LastWriteUtcTicks = lastWriteUtcTicks; Length = length; Definition = definition; } } private const string DefinitionFolderName = "EventScan"; private readonly string _definitionPath = TOAConfigPaths.GetFeaturePath("EventScan"); private Dictionary> definitions = new Dictionary>(); private readonly Dictionary> _eventScans = new Dictionary>(); private readonly Dictionary _definitionCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _eventScanFiltersByHash = new Dictionary(); private readonly Dictionary _eventScansByIndex = new Dictionary(); private readonly List _indexGroups = new List(); private LiveEditListener? _liveEditListener; public static TOAEventScanManager Current { get; } = new TOAEventScanManager(); private TOAEventScanManager() { LevelAPI.OnBuildDone += Build; LevelAPI.OnLevelCleanup += Clear; } public void Init() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown bool flag = default(bool); try { EnsureDefinitionPath(); ReloadDefinitionsFromDisk(); if (_liveEditListener == null) { _liveEditListener = LiveEdit.CreateListener(_definitionPath, "*.json", true); _liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan definitions path: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_definitionPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan Init failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogError(val2); } } } private void EnsureDefinitionPath() { //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown Directory.CreateDirectory(_definitionPath); string text = Path.Combine(_definitionPath, "Template.json"); if (File.Exists(text)) { return; } GenericExpeditionDefinition val = new GenericExpeditionDefinition(); File.WriteAllText(text, EOSJson.Serialize>(val)); ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan template generated: '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } log.LogMessage(val2); } } private void BuildEventScan(TOAEventScanDefinition def) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Expected O, but got Unknown //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Expected O, but got Unknown bool flag = default(bool); try { ManualLogSource log; if (def.Position.ToVector3() == Vector3.zero) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(47, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' skipped because Position is 0,0,0."); } log.LogWarning(val); } return; } if ((Object)(object)TOAAssets.EventScan == (Object)null) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(63, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' skipped because TOA EventScan asset is not loaded."); } log.LogError(val2); } return; } string text = $"TOA_EventScan_{def.WorldEventObjectFilter}_{def.Index}"; GameObject val3 = TOAVisualObjectPool.Current.Rent(text, TOAAssets.EventScan, "EventScan"); ((Object)val3).name = text; TOAEventScanComponent tOAEventScanComponent = val3.AddComponent(); tOAEventScanComponent.def = def; tOAEventScanComponent.ExecuteEventsLocally = true; tOAEventScanComponent.Setup(); if (tOAEventScanComponent.StateReplicator == null) { TOAVisualObjectPool.Current.Return(val3); log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(63, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' was not registered because setup did not complete."); } log.LogError(val2); } return; } RegisterEventScan(def.WorldEventObjectFilter, tOAEventScanComponent); RegisterEventScanIndex(def, tOAEventScanComponent); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val4 = new BepInExMessageLogInterpolatedStringHandler(100, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("EventScan build '"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("': Index="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(def.Index); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(", RequiredEventScanIndices=["); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(string.Join(",", def.RequiredEventScanIndices)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("], Prefab='TOA EventScan AssetBundle', Radius="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(def.Radius); } log.LogMessage(val4); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(33, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan build failed for '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogError(val2); } } } private void RegisterEventScan(string worldEventObjectFilter, TOAEventScanComponent comp) { if (!_eventScans.TryGetValue(worldEventObjectFilter, out List value)) { value = new List(); _eventScans[worldEventObjectFilter] = value; } value.Add(comp); int num = TOANetworkEventProxy.StableHash(worldEventObjectFilter); if (num != 0 && !_eventScanFiltersByHash.ContainsKey(num)) { _eventScanFiltersByHash[num] = worldEventObjectFilter; } } private void RegisterEventScanIndex(TOAEventScanDefinition def, TOAEventScanComponent comp) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown bool flag = default(bool); if (def.Index < 0) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(77, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.Index); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; it cannot be referenced by RequiredEventScanIndices."); } log.LogWarning(val); } } else if (_eventScansByIndex.ContainsKey(def.Index)) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(107, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan index "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.Index); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is duplicated. RequiredEventScanIndices will use the first scan registered for this index."); } log.LogError(val2); } } else { _eventScansByIndex[def.Index] = comp; } } private void BuildIndexGroups(IEnumerable defs) { //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Expected O, but got Unknown //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown bool flag = default(bool); foreach (TOAEventScanDefinition def in defs) { List list = def.RequiredEventScanIndices ?? new List(); if (list.Count == 0) { continue; } List list2 = (from index in list.Where((int index) => index >= 0).Distinct() orderby index select index).ToList(); ManualLogSource log; if (list2.Count == 0) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(63, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan index group '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has no valid RequiredEventScanIndices."); } log.LogError(val); } continue; } TOAEventScanIndexGroup tOAEventScanIndexGroup = new TOAEventScanIndexGroup(def, list2, _eventScansByIndex); _indexGroups.Add(tOAEventScanIndexGroup); foreach (int item in list2) { if (_eventScansByIndex.ContainsKey(item)) { continue; } log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(49, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan index group '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' requires missing Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } } tOAEventScanIndexGroup.Evaluate(executeEvents: false); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(175, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan index group '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' registered RequiredEventScanIndices=["); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(string.Join(",", list2)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("], UseRequiredEventScanIndicesEvents="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.UseRequiredEventScanIndicesEvents); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". Normal EventsOnActivate/EventsOnDeactivate remain local to each EventScan."); } log.LogMessage(val2); } } } public void ToggleEventScanState(string worldEventObjectFilter, bool active = true) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (!_eventScans.ContainsKey(worldEventObjectFilter)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(62, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("ToggleEventScanState: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(worldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" does not correspond to any event scans!"); } log.LogError(val); } return; } foreach (TOAEventScanComponent item in _eventScans[worldEventObjectFilter]) { if (!active && item.StateReplicator.State.Status != TOAEventScanState.Disabled) { item.ChangeToState(TOAEventScanState.Disabled); } else if (active && item.StateReplicator.State.Status == TOAEventScanState.Disabled) { item.ChangeToState(TOAEventScanState.Waiting); } } } private void Build() { //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown bool flag = default(bool); try { ReloadDefinitionsFromDisk(); if (RundownManager.ActiveExpedition == null) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"EventScan Build skipped: ActiveExpedition is null."); } return; } uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; ManualLogSource log2; if (!definitions.ContainsKey(levelLayoutData)) { log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(63, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan Build: no EventScan definitions for LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(levelLayoutData); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log2.LogMessage(val); } return; } GenericExpeditionDefinition val2 = definitions[levelLayoutData]; if (val2.Definitions.Count == 0) { log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(60, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan Build: LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(levelLayoutData); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", no EventScan definitions."); } log2.LogMessage(val); } return; } if (!TOAAssets.EnsureEventScanLoaded()) { log2 = TOARuntime.Log; if (log2 != null) { BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(80, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EventScan Build skipped: TOA EventScan asset is not loaded for LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(levelLayoutData); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); } log2.LogError(val3); } return; } Clear(); log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(48, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan Build: LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(levelLayoutData); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(val2.Definitions.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log2.LogMessage(val); } val2.Definitions.ForEach(BuildEventScan); BuildIndexGroups(val2.Definitions); } catch (Exception ex) { ManualLogSource log2 = TOARuntime.Log; if (log2 != null) { BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(26, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EventScan Build failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log2.LogError(val3); } } } private void FileChanged(LiveEditEventArgs e) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan LiveEdit file changed: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(e.FullPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { if (TryLoadDefinitionContent(content, e.FullPath, out GenericExpeditionDefinition conf) && conf != null) { AddDefinitions(conf, e.FullPath); } }); } private void ReloadDefinitionsFromDisk() { //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Expected O, but got Unknown bool flag = default(bool); try { ManualLogSource log; if (string.IsNullOrWhiteSpace(_definitionPath) || !Directory.Exists(_definitionPath)) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan definitions path does not exist: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_definitionPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogWarning(val); } definitions.Clear(); return; } Dictionary> dictionary = new Dictionary>(); int num = 0; int num2 = 0; HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); foreach (string item in Directory.EnumerateFiles(_definitionPath, "*.json", SearchOption.AllDirectories)) { hashSet.Add(item); if (TryLoadDefinitionFile(item, out GenericExpeditionDefinition conf) && conf != null) { dictionary[conf.MainLevelLayout] = conf; num++; } else { num2++; } } PruneDefinitionCache(hashSet); definitions = dictionary; string text = ((dictionary.Count > 0) ? string.Join(",", dictionary.Keys.OrderBy((uint id) => id)) : ""); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(80, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan config reload complete. FilesLoaded="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", FilesFailed="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", MainLevelLayouts="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(34, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("EventScan config reload failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log.LogError(val3); } } } private bool TryLoadDefinitionFile(string file, out GenericExpeditionDefinition? conf) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown conf = null; try { FileInfo fileInfo = new FileInfo(file); if (_definitionCache.TryGetValue(file, out CachedEventScanDefinitionFile value) && value.LastWriteUtcTicks == fileInfo.LastWriteTimeUtc.Ticks && value.Length == fileInfo.Length) { conf = value.Definition; return conf != null; } string content = File.ReadAllText(file); if (!TryLoadDefinitionContent(content, file, out conf) || conf == null) { _definitionCache.Remove(file); return false; } _definitionCache[file] = new CachedEventScanDefinitionFile(fileInfo.LastWriteTimeUtc.Ticks, fileInfo.Length, conf); return true; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan config reload failed for '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } _definitionCache.Remove(file); return false; } } private bool TryLoadDefinitionContent(string content, string file, out GenericExpeditionDefinition? conf) { //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown conf = null; try { conf = EOSJson.Deserialize>(content); if (conf == null) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(57, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan config reload skipped null definition file: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogWarning(val); } return false; } TOAType2003SidecarStore.Capture(content, conf); TOAType2004SidecarStore.Capture(content, conf); TOAType2005SidecarStore.Capture(content, conf); return true; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag2 = default(bool); BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(41, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("EventScan config reload failed for '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogError(val2); } return false; } } private void AddDefinitions(GenericExpeditionDefinition conf, string file) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown TryRefreshDefinitionCache(file, conf); if (definitions.ContainsKey(conf.MainLevelLayout)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(63, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("EventScan config reload replaced MainLevelLayout "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(conf.MainLevelLayout); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" from file '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } definitions[conf.MainLevelLayout] = conf; } private void TryRefreshDefinitionCache(string file, GenericExpeditionDefinition conf) { try { FileInfo fileInfo = new FileInfo(file); _definitionCache[file] = new CachedEventScanDefinitionFile(fileInfo.LastWriteTimeUtc.Ticks, fileInfo.Length, conf); } catch { _definitionCache.Remove(file); } } private void PruneDefinitionCache(HashSet seenFiles) { List list = _definitionCache.Keys.Where((string file) => !seenFiles.Contains(file)).ToList(); for (int num = 0; num < list.Count; num++) { _definitionCache.Remove(list[num]); } } private void Clear() { foreach (List value in _eventScans.Values) { foreach (TOAEventScanComponent item in value) { Object.Destroy((Object)(object)item); TOAVisualObjectPool.Current.Return(((Component)item).gameObject); } } _eventScans.Clear(); _eventScanFiltersByHash.Clear(); _eventScansByIndex.Clear(); _indexGroups.Clear(); } internal bool TryGetWorldEventObjectFilterByHash(int hash, out string worldEventObjectFilter) { return _eventScanFiltersByHash.TryGetValue(hash, out worldEventObjectFilter); } internal void EvaluateIndexGroups(bool executeEvents) { foreach (TOAEventScanIndexGroup indexGroup in _indexGroups) { indexGroup.Evaluate(executeEvents); } } } internal sealed class TOAType2005EventData { internal int Count { get; set; } internal bool Enabled { get; set; } = true; internal bool HasEnabled { get; set; } internal Vector3 Position { get; set; } internal bool HasPosition { get; set; } internal float FogTransitionDuration { get; set; } internal bool HasFogTransitionDuration { get; set; } internal List Events { get; set; } = new List(); } internal readonly struct TOAType2005Signature : IEquatable { private readonly int _count; private readonly bool _enabled; private readonly int _radius1000; private readonly int _x1000; private readonly int _y1000; private readonly int _z1000; internal TOAType2005Signature(int count, bool enabled, float radius, Vector3 position) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) _count = count; _enabled = enabled; _radius1000 = Quantize(radius); _x1000 = Quantize(position.x); _y1000 = Quantize(position.y); _z1000 = Quantize(position.z); } internal static TOAType2005Signature FromEvent(WardenObjectiveEventData e) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) return new TOAType2005Signature(e.Count, e.Enabled, e.FogTransitionDuration, e.Position); } public bool Equals(TOAType2005Signature other) { if (_count == other._count && _enabled == other._enabled && _radius1000 == other._radius1000 && _x1000 == other._x1000 && _y1000 == other._y1000) { return _z1000 == other._z1000; } return false; } public override bool Equals(object? obj) { if (obj is TOAType2005Signature other) { return Equals(other); } return false; } public override int GetHashCode() { return HashCode.Combine(_count, _enabled, _radius1000, _x1000, _y1000, _z1000); } private static int Quantize(float value) { if (float.IsNaN(value) || float.IsInfinity(value)) { return 0; } return (int)Math.Round(value * 1000f); } } internal static class TOAType2005SidecarStore { private static readonly Dictionary ByEventPointer = new Dictionary(); private static readonly Dictionary> ByLooseSignature = new Dictionary>(); private static readonly List LooseFallback = new List(); private static readonly HashSet RegisteredLooseFingerprints = new HashSet(StringComparer.Ordinal); private static readonly HashSet AmbiguousWarningPrinted = new HashSet(); private static bool _isDeserializingSidecarEvents; private static bool _diskScanned; internal static bool TryGet(WardenObjectiveEventData eventData, out TOAType2005EventData data) { if (eventData != null && ByEventPointer.TryGetValue(((Il2CppObjectBase)eventData).Pointer, out data)) { return true; } if (eventData != null) { TOAType2005Signature tOAType2005Signature = TOAType2005Signature.FromEvent(eventData); if (ByLooseSignature.TryGetValue(tOAType2005Signature, out List value) && value.Count > 0) { data = value[0]; if (value.Count > 1 && AmbiguousWarningPrinted.Add(tOAType2005Signature)) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA Type 2005 sidecar fallback matched multiple definitions with the same vanilla signature. Using the first match. Make Count/Position/FogTransitionDuration/Enabled unique if this is not intended."); } } ByEventPointer[((Il2CppObjectBase)eventData).Pointer] = data; return true; } } if (LooseFallback.Count == 1) { data = LooseFallback[0]; if (eventData != null) { ByEventPointer[((Il2CppObjectBase)eventData).Pointer] = data; } return true; } data = null; return false; } internal static void ScanDiskForDefinitions() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown if (_diskScanned) { return; } _diskScanned = true; int num = 0; int num2 = 0; int num3 = 0; bool flag = default(bool); ManualLogSource log; try { foreach (string item in EnumerateCandidateJsonFiles()) { num++; string text; try { text = File.ReadAllText(item); } catch { continue; } if (text.IndexOf("2005", StringComparison.OrdinalIgnoreCase) >= 0) { List list = ParseType2005Nodes(text); if (list.Count != 0) { num2++; num3 += list.Count; RegisterLoose(list); } } } } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 disk sidecar scan failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } if (num3 > 0) { log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(90, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2005 disk sidecar scan complete. FilesScanned="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", FilesWithType2005="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } return; } log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val3 = new BepInExDebugLogInterpolatedStringHandler(71, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA Type 2005 disk sidecar scan complete. FilesScanned="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", Definitions=0."); } log.LogDebug(val3); } } internal static void Capture(string json, object? result) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Invalid comparison between Unknown and I4 if (_isDeserializingSidecarEvents || string.IsNullOrWhiteSpace(json) || json.IndexOf("2005", StringComparison.OrdinalIgnoreCase) < 0) { return; } List list = ParseType2005Nodes(json); if (list.Count == 0) { return; } RegisterLoose(list); if (result == null) { return; } List list2 = new List(); CollectEvents(result, list2, new HashSet(ReferenceEqualityComparer.Instance), 0); if (list2.Count == 0) { return; } Dictionary> dictionary = new Dictionary>(); foreach (TOAType2005EventData item in list) { TOAType2005Signature key = new TOAType2005Signature(item.Count, item.Enabled, item.FogTransitionDuration, item.Position); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new Queue()); } value.Enqueue(item); } Queue queue2 = new Queue(list); foreach (WardenObjectiveEventData item2 in list2) { if ((int)item2.Type == 2005) { TOAType2005EventData tOAType2005EventData = null; TOAType2005Signature key2 = TOAType2005Signature.FromEvent(item2); if (dictionary.TryGetValue(key2, out var value2) && value2.Count > 0) { tOAType2005EventData = value2.Dequeue(); } else if (queue2.Count > 0) { tOAType2005EventData = queue2.Dequeue(); } if (tOAType2005EventData != null) { ByEventPointer[((Il2CppObjectBase)item2).Pointer] = tOAType2005EventData; } } } } private static void RegisterLoose(IEnumerable parsed) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) foreach (TOAType2005EventData item in parsed) { string looseFingerprint = GetLooseFingerprint(item); if (RegisteredLooseFingerprints.Add(looseFingerprint)) { TOAType2005Signature key = new TOAType2005Signature(item.Count, item.Enabled, item.FogTransitionDuration, item.Position); if (!ByLooseSignature.TryGetValue(key, out List value)) { value = new List(1); ByLooseSignature[key] = value; } value.Add(item); LooseFallback.Add(item); } } } private static string GetLooseFingerprint(TOAType2005EventData data) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected I4, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) int num = 17; foreach (WardenObjectiveEventData @event in data.Events) { num = num * 31 + @event.Type; num = num * 31 + @event.Count; num = num * 31 + ((object)@event.LocalIndex/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + ((object)@event.Layer/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + ((object)@event.DimensionIndex/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + ((object)@event.Position/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + @event.FogTransitionDuration.GetHashCode(); } return string.Join("|", data.Count, data.Enabled, data.FogTransitionDuration, data.Position.x, data.Position.y, data.Position.z, data.Events.Count, num); } private static IEnumerable EnumerateCandidateJsonFiles() { HashSet roots = new HashSet(StringComparer.OrdinalIgnoreCase); AddRoot(Paths.PluginPath); AddRoot(Path.Combine(Paths.BepInExRootPath, "GameData")); AddRoot(Path.Combine(Paths.BepInExRootPath, "Custom")); foreach (string item in roots) { IEnumerable enumerable; try { enumerable = Directory.EnumerateFiles(item, "*.json", SearchOption.AllDirectories).ToArray(); } catch { continue; } foreach (string item2 in enumerable) { yield return item2; } } void AddRoot(string? root) { if (!string.IsNullOrWhiteSpace(root) && Directory.Exists(root)) { roots.Add(Path.GetFullPath(root)); } } } private static List ParseType2005Nodes(string json) { List list = new List(); try { JsonNode jsonNode = JsonNode.Parse(json, new JsonNodeOptions { PropertyNameCaseInsensitive = true }, new JsonDocumentOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip }); if (jsonNode != null) { TraverseJson(jsonNode, list); } } catch { } return list; } private static void TraverseJson(JsonNode node, List output) { if (node is JsonObject jsonObject) { if (IsType2005Object(jsonObject)) { output.Add(ParseEventData(jsonObject)); } { foreach (KeyValuePair item in jsonObject) { if (item.Value != null) { TraverseJson(item.Value, output); } } return; } } if (!(node is JsonArray jsonArray)) { return; } foreach (JsonNode item2 in jsonArray) { if (item2 != null) { TraverseJson(item2, output); } } } private static bool IsType2005Object(JsonObject obj) { if (!obj.TryGetPropertyValue("Type", out JsonNode jsonNode)) { return false; } if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value == 2005; } if (jsonValue.TryGetValue(out string value2)) { if (!string.Equals(value2, "2005", StringComparison.OrdinalIgnoreCase)) { return string.Equals(value2, "TOA_AddPlayersToAllDownEventGroup", StringComparison.OrdinalIgnoreCase); } return true; } } return false; } private static TOAType2005EventData ParseEventData(JsonObject obj) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) JsonNode jsonNode; TOAType2005EventData tOAType2005EventData = new TOAType2005EventData { Count = ReadInt(obj, "Count", 0), HasEnabled = obj.ContainsKey("Enabled"), Enabled = ReadBool(obj, "Enabled", fallback: true), HasPosition = obj.ContainsKey("Position"), Position = ReadVector3(obj.TryGetPropertyValue("Position", out jsonNode) ? jsonNode : null), HasFogTransitionDuration = obj.ContainsKey("FogTransitionDuration"), FogTransitionDuration = ReadFloat(obj, "FogTransitionDuration", 0f) }; if (obj.TryGetPropertyValue("Events", out JsonNode jsonNode2) && jsonNode2 != null) { tOAType2005EventData.Events = DeserializeEvents(jsonNode2.ToJsonString()); } return tOAType2005EventData; } private static List DeserializeEvents(string json) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown try { _isDeserializingSidecarEvents = true; return EOSJson.Deserialize>(json) ?? new List(); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(53, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 could not deserialize nested Events: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } return new List(); } finally { _isDeserializingSidecarEvents = false; } } private static void CollectEvents(object obj, List output, HashSet visited, int depth) { if (obj == null || depth > 12 || !visited.Add(obj)) { return; } WardenObjectiveEventData val = (WardenObjectiveEventData)((obj is WardenObjectiveEventData) ? obj : null); if (val != null) { output.Add(val); return; } if (obj is IEnumerable enumerable && !(obj is string)) { foreach (object item in enumerable) { if (item != null) { CollectEvents(item, output, visited, depth + 1); } } return; } Type type = obj.GetType(); if (type.IsPrimitive || type.IsEnum || type == typeof(string)) { return; } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.GetIndexParameters().Length != 0) { continue; } try { object value = propertyInfo.GetValue(obj); if (value != null) { CollectEvents(value, output, visited, depth + 1); } } catch { } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { try { object value2 = fieldInfo.GetValue(obj); if (value2 != null) { CollectEvents(value2, output, visited, depth + 1); } } catch { } } } private static int ReadInt(JsonObject node, string name, int fallback) { try { if (node.TryGetPropertyValue(name, out JsonNode jsonNode) && jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2) && int.TryParse(value2, out value)) { return value; } } } catch { } return fallback; } private static float ReadFloat(JsonObject node, string name, float fallback) { try { if (node.TryGetPropertyValue(name, out JsonNode jsonNode) && jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out var value2)) { return (float)value2; } if (jsonValue.TryGetValue(out string value3) && float.TryParse(value3, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { return value; } } } catch { } return fallback; } private static bool ReadBool(JsonObject node, string name, bool fallback) { try { if (node.TryGetPropertyValue(name, out JsonNode jsonNode) && jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2) && bool.TryParse(value2, out value)) { return value; } } } catch { } return fallback; } private static Vector3 ReadVector3(JsonNode? node) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!(node is JsonObject node2)) { return Vector3.zero; } return new Vector3(ReadFloat(node2, "x", 0f), ReadFloat(node2, "y", 0f), ReadFloat(node2, "z", 0f)); } } internal static class TOAAllDownEventGroupEvents { internal static void AddPlayersToAllDownEventGroup(WardenObjectiveEventData eventData) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.TOA_AddPlayersToAllDownEventGroup, eventData)) { return; } if (!TOAType2005SidecarStore.TryGet(eventData, out TOAType2005EventData data)) { data = new TOAType2005EventData { Count = eventData.Count, Enabled = eventData.Enabled, Position = eventData.Position, HasPosition = true, FogTransitionDuration = eventData.FogTransitionDuration, HasFogTransitionDuration = (eventData.FogTransitionDuration > 0f), Events = new List() }; } bool flag = default(bool); ManualLogSource log; if (!data.Enabled) { TOAAllDownEventGroupManager.Current.SetGroupEnabled(data.Count, enabled: false); log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(57, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 all-down event group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" disabled and cleared."); } log.LogDebug(val); } return; } List list = ResolvePlayers(eventData, data); int num = TOAAllDownEventGroupManager.Current.AddPlayersToGroup(data.Count, list, data.Events); log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(64, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 all-down event group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": added "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" player(s), Events="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Events.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); } } private static List ResolvePlayers(WardenObjectiveEventData eventData, TOAType2005EventData data) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) TOAType2003TriggerScope current = TOAType2003TriggerScope.Current; if (current != null) { List list = ResolvePlayersFromContext(current); if (list.Count > 0) { return list; } } float num = (data.HasFogTransitionDuration ? data.FogTransitionDuration : eventData.FogTransitionDuration); Vector3 origin = (data.HasPosition ? data.Position : eventData.Position); if (num > 0f) { return GetPlayersInRadius(origin, num); } return GetAllPlayers(); } private static List ResolvePlayersFromContext(TOAType2003TriggerScope context) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)context.Collider != (Object)null) { List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current == (Object)null || !((Agent)current).Alive) { continue; } try { if (LG_CollisionWorldEventTrigger.IsInside(context.Collider, ((Agent)current).Position)) { list.Add(current); } } catch { try { Bounds bounds = context.Collider.bounds; if (((Bounds)(ref bounds)).Contains(((Agent)current).Position)) { list.Add(current); } } catch { } } } return list; } if (context.HasRadius) { return GetPlayersInRadius(context.Position, context.Radius); } if ((Object)(object)context.TriggeringPlayer != (Object)null && ((Agent)context.TriggeringPlayer).Alive) { return new List { context.TriggeringPlayer }; } return new List(); } private static List GetPlayersInRadius(Vector3 origin, float radius) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) float num = radius * radius; List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!((Object)(object)current == (Object)null) && ((Agent)current).Alive) { Vector3 val = ((Agent)current).Position - origin; if (((Vector3)(ref val)).sqrMagnitude <= num) { list.Add(current); } } } return list; } private static List GetAllPlayers() { List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current != (Object)null && ((Agent)current).Alive) { list.Add(current); } } return list; } } public struct TOAAllDownEventGroupReplicationState { public bool enabled; public bool checkP1; public bool checkP2; public bool checkP3; public bool checkP4; } internal sealed class TOAAllDownEventGroup { internal const int MaxPlayers = 4; private readonly bool[] _slots = new bool[4]; private readonly bool[] _downSlots = new bool[4]; private readonly Dictionary _lastDeathFrameBySlot = new Dictionary(); private bool _hasTriggered; private StateReplicator? _stateReplicator; internal bool Enabled { get; private set; } internal List Events { get; set; } = new List(); internal int Count { get { int num = 0; for (int i = 0; i < _slots.Length; i++) { if (_slots[i]) { num++; } } return num; } } internal bool SetPlayerInGroup(int slot, bool inGroup) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!IsValidPlayerSlot(slot)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(57, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 invalid player slot index "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(slot); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; expected [0, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } log.LogError(val); } return false; } if (_slots[slot] == inGroup) { return false; } int count = Count; _slots[slot] = inGroup; _downSlots[slot] = false; _lastDeathFrameBySlot.Remove(slot); if (inGroup) { _hasTriggered = false; } int count2 = Count; if (count == 0 && count2 > 0) { Enabled = true; } else if (count > 0 && count2 == 0) { Enabled = false; } Sync(); return true; } internal void Toggle(bool enabled) { if (!enabled) { ClearAndDisable(); } else if (!Enabled) { Enabled = true; Sync(); } } internal void ClearAndDisable() { bool flag = Enabled || Count > 0 || Events.Count > 0 || _lastDeathFrameBySlot.Count > 0 || _hasTriggered; Enabled = false; for (int i = 0; i < _slots.Length; i++) { _slots[i] = false; _downSlots[i] = false; } _lastDeathFrameBySlot.Clear(); _hasTriggered = false; Events = new List(); if (flag) { Sync(); } } internal bool ContainsSlot(int slot) { if (IsValidPlayerSlot(slot)) { return _slots[slot]; } return false; } internal bool TryMarkPlayerDownAndCheckAll(int slot, int frame, out int markedCount, out int downCount) { markedCount = Count; downCount = GetDownCount(); if (!IsValidPlayerSlot(slot) || !_slots[slot] || _hasTriggered) { return false; } if (_lastDeathFrameBySlot.TryGetValue(slot, out var value) && value == frame) { return false; } _lastDeathFrameBySlot[slot] = frame; _downSlots[slot] = true; downCount = GetDownCount(); markedCount = Count; if (markedCount <= 0 || downCount < markedCount) { return false; } _hasTriggered = true; return true; } internal void Rearm(List events) { _hasTriggered = false; _lastDeathFrameBySlot.Clear(); for (int i = 0; i < _downSlots.Length; i++) { _downSlots[i] = false; } if (events.Count > 0) { Events = events; } } private int GetDownCount() { int num = 0; for (int i = 0; i < _slots.Length; i++) { if (_slots[i] && _downSlots[i]) { num++; } } return num; } internal void ResetSynced() { Reset(); Sync(); } internal void ResetUnsynced() { Reset(); _stateReplicator?.SetStateUnsynced(GetSyncState()); } private void Reset() { Enabled = false; for (int i = 0; i < _slots.Length; i++) { _slots[i] = false; _downSlots[i] = false; } _lastDeathFrameBySlot.Clear(); _hasTriggered = false; Events = new List(); } private void Sync() { if (!SNet.IsMaster) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA Type 2005 all-down event group sync blocked on client; state changes must be executed by host."); } } else { _stateReplicator?.SetState(GetSyncState()); } } private void OnStateChanged(TOAAllDownEventGroupReplicationState oldState, TOAAllDownEventGroupReplicationState newState, bool isRecall) { if (isRecall) { Enabled = newState.enabled; _slots[0] = newState.checkP1; _slots[1] = newState.checkP2; _slots[2] = newState.checkP3; _slots[3] = newState.checkP4; } } private TOAAllDownEventGroupReplicationState GetSyncState() { return new TOAAllDownEventGroupReplicationState { enabled = Enabled, checkP1 = _slots[0], checkP2 = _slots[1], checkP3 = _slots[2], checkP4 = _slots[3] }; } internal static TOAAllDownEventGroup? Instantiate() { if (!TOAStateReplicatorCompat.CanCreateReplicator("TOA Type 2005", logIfNotReady: false)) { return null; } uint num = EOSNetworking.AllotForeverReplicatorID(); if (num == 0) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogError((object)"TOA Type 2005 could not allocate a network replicator id."); } return null; } TOAAllDownEventGroup tOAAllDownEventGroup = new TOAAllDownEventGroup(); tOAAllDownEventGroup._stateReplicator = TOAStateReplicatorCompat.Create(num, default(TOAAllDownEventGroupReplicationState), (LifeTimeType)0, "TOA Type 2005"); if (tOAAllDownEventGroup._stateReplicator == null) { return null; } tOAAllDownEventGroup._stateReplicator.OnStateChanged += tOAAllDownEventGroup.OnStateChanged; tOAAllDownEventGroup.ResetUnsynced(); return tOAAllDownEventGroup; } private static bool IsValidPlayerSlot(int slot) { if (slot >= 0) { return slot < 4; } return false; } private TOAAllDownEventGroup() { } } internal sealed class TOAAllDownEventGroupManager { internal const int MaxGroups = 4; private readonly List _groups = new List(); private bool _initialized; private bool _delayedSetupLogged; internal static TOAAllDownEventGroupManager Current { get; } = new TOAAllDownEventGroupManager(); internal void Init() { if (!_initialized) { _initialized = true; EventAPI.OnManagersSetup += SetupGroups; LevelAPI.OnBuildStart += ResetUnsynced; LevelAPI.OnLevelCleanup += ResetUnsynced; LevelAPI.OnBuildDone += SetupGroups; } } internal int AddPlayersToGroup(int groupIndex, IEnumerable players, List events) { if (!TryGetGroup(groupIndex, out TOAAllDownEventGroup group)) { return 0; } group.Rearm(events); int num = 0; foreach (PlayerAgent player in players) { try { if (group.SetPlayerInGroup(player.PlayerSlotIndex, inGroup: true)) { num++; } } catch { } } return num; } internal void SetGroupEnabled(int groupIndex, bool enabled) { if (TryGetGroup(groupIndex, out TOAAllDownEventGroup group)) { group.Toggle(enabled); } } internal void ResetSynced() { foreach (TOAAllDownEventGroup group in _groups) { group.ResetSynced(); } } internal void ResetUnsynced() { foreach (TOAAllDownEventGroup group in _groups) { group.ResetUnsynced(); } } internal void OnPlayerDied(PlayerAgent? player) { //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Expected O, but got Unknown //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown EnsureGroups(); if ((Object)(object)player == (Object)null || !SNet.IsMaster) { return; } int playerSlotIndex; try { playerSlotIndex = player.PlayerSlotIndex; } catch { return; } int frameCount = Time.frameCount; bool flag = default(bool); for (int i = 0; i < _groups.Count; i++) { TOAAllDownEventGroup tOAAllDownEventGroup = _groups[i]; if (!tOAAllDownEventGroup.Enabled || !tOAAllDownEventGroup.ContainsSlot(playerSlotIndex)) { continue; } ManualLogSource log; if (!tOAAllDownEventGroup.TryMarkPlayerDownAndCheckAll(playerSlotIndex, frameCount, out var markedCount, out var downCount)) { log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(93, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 all-down event group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(i); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": player slot "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(playerSlotIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" downed ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(downCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(markedCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); waiting for all marked players."); } log.LogDebug(val); } continue; } log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(88, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 all-down event group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(i); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": all marked players downed ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(downCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(markedCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("); executing "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(tOAAllDownEventGroup.Events.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" event(s)."); } log.LogDebug(val); } foreach (WardenObjectiveEventData @event in tOAAllDownEventGroup.Events) { try { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(@event, (eWardenObjectiveEventTrigger)0, true, 0f); } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2005 nested event failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } } } } private void SetupGroups() { EnsureGroups(); } private bool EnsureGroups() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown if (_groups.Count >= 4) { return true; } bool flag = default(bool); if (!TOAStateReplicatorCompat.CanCreateReplicator("TOA Type 2005", logIfNotReady: false)) { if (!_delayedSetupLogged) { _delayedSetupLogged = true; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(102, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 all-down event group setup delayed until network state is ready. Current group count: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_groups.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); } } return false; } _delayedSetupLogged = false; while (_groups.Count < 4) { TOAAllDownEventGroup tOAAllDownEventGroup = TOAAllDownEventGroup.Instantiate(); if (tOAAllDownEventGroup == null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(113, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2005 all-down event group setup incomplete; instantiated "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_groups.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". It will retry when the group is next needed."); } log.LogWarning(val2); } return false; } _groups.Add(tOAAllDownEventGroup); } return true; } private bool TryGetGroup(int groupIndex, out TOAAllDownEventGroup? group) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown EnsureGroups(); bool flag = default(bool); if (groupIndex < 0 || groupIndex >= 4) { group = null; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(55, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2005 group index must be between 0 and "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; got "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(groupIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } return false; } if (groupIndex >= _groups.Count) { group = null; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(94, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2005 group "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(groupIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is not ready yet. Instantiated "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_groups.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; network state may still be unavailable."); } log.LogWarning(val2); } return false; } group = _groups[groupIndex]; return true; } private TOAAllDownEventGroupManager() { } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveSetDead")] internal static class TOAAllDownEvent_DamPlayerDamageBaseReceiveSetDeadPatch { private static void Postfix(Dam_PlayerDamageBase __instance) { TOAAllDownEventGroupManager.Current.OnPlayerDied(TryGetOwner(__instance)); } internal static PlayerAgent? TryGetOwner(Dam_PlayerDamageBase? damageBase) { if ((Object)(object)damageBase == (Object)null) { return null; } try { return damageBase.Owner; } catch { return null; } } } [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveSetDead")] internal static class TOAAllDownEvent_DamPlayerDamageLocalReceiveSetDeadPatch { private static void Postfix(Dam_PlayerDamageLocal __instance) { TOAAllDownEventGroupManager.Current.OnPlayerDied(TOAAllDownEvent_DamPlayerDamageBaseReceiveSetDeadPatch.TryGetOwner((Dam_PlayerDamageBase?)(object)__instance)); } } internal static class TOAAWOTimerEvents { private enum TimerMode { Unknown, Countdown, Countup } private static class AWOTimerBridge { private static bool _resolved; private static Type? _timerModsType; private static Type? _coroutinesType; private static PropertyInfo? _timeModifier; private static PropertyInfo? _speedModifier; private static PropertyInfo? _countdownStarted; private static Func? _getTimeModifier; private static Action? _setTimeModifier; private static Func? _getSpeedModifier; private static Action? _setSpeedModifier; private static Action? _setCountdownStarted; internal static bool IsAvailable { get { Resolve(); if (_timerModsType != null && CanReadWrite(_timeModifier, _getTimeModifier, _setTimeModifier)) { return CanReadWrite(_speedModifier, _getSpeedModifier, _setSpeedModifier); } return false; } } internal static float GetSpeedModifier() { Resolve(); return GetFloat(_speedModifier, _getSpeedModifier, 1f); } internal static void SetSpeedModifier(float value) { Resolve(); SetFloat(_speedModifier, _setSpeedModifier, value); } internal static void AddTimeModifier(float delta) { Resolve(); float num = GetFloat(_timeModifier, _getTimeModifier, 0f); SetFloat(_timeModifier, _setTimeModifier, num + delta); } internal static void ClearTimeModifier() { Resolve(); SetFloat(_timeModifier, _setTimeModifier, 0f); } internal static float GetTimeModifier() { Resolve(); return GetFloat(_timeModifier, _getTimeModifier, 0f); } internal static void ResetCountdownStarted() { Resolve(); SetFloat(_countdownStarted, _setCountdownStarted, Time.realtimeSinceStartup); } internal static string GetDetectedTimerMode() { return TimerModeToString(DetectTimerMode(GetHudTimerText())); } internal static TimerMode DetectTimerMode(string text) { if (string.IsNullOrWhiteSpace(text)) { return TimerMode.Unknown; } if (StripRichText(text).Contains(":")) { return TimerMode.Countdown; } return TimerMode.Countup; } internal static string TimerModeToString(TimerMode mode) { return mode switch { TimerMode.Countdown => "Countdown", TimerMode.Countup => "Countup", _ => "Unknown", }; } internal static string GetHudTimerText() { try { PlayerGuiLayer playerLayer = GuiManager.PlayerLayer; object obj; if (playerLayer == null) { obj = null; } else { PUI_ObjectiveTimer objectiveTimer = playerLayer.m_objectiveTimer; if (objectiveTimer == null) { obj = null; } else { TextMeshPro timerText = objectiveTimer.m_timerText; obj = ((timerText != null) ? ((TMP_Text)timerText).text : null); } } if (obj == null) { obj = string.Empty; } return (string)obj; } catch { return string.Empty; } } private static void Resolve() { if (!_resolved) { _resolved = true; Type type = FindType("AWO.EntryPoint"); if (!(type == null)) { _timerModsType = type.GetNestedType("TimerMods", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _coroutinesType = type.GetNestedType("Coroutines", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _timeModifier = _timerModsType?.GetProperty("TimeModifier", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _speedModifier = _timerModsType?.GetProperty("SpeedModifier", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _countdownStarted = _coroutinesType?.GetProperty("CountdownStarted", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); _getTimeModifier = CreateGetter(_timeModifier); _setTimeModifier = CreateSetter(_timeModifier); _getSpeedModifier = CreateGetter(_speedModifier); _setSpeedModifier = CreateSetter(_speedModifier); _setCountdownStarted = CreateSetter(_countdownStarted); } } } private static Type? FindType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(fullName, throwOnError: false); if (type != null) { return type; } } catch { } } return null; } private static bool CanReadWrite(PropertyInfo? property, Func? getter, Action? setter) { if (getter != null && setter != null) { return true; } if (property != null && property.CanRead) { return property.CanWrite; } return false; } private static Func? CreateGetter(PropertyInfo? property) { try { MethodInfo methodInfo = property?.GetGetMethod(nonPublic: true); if (methodInfo == null) { return null; } return (Func)Delegate.CreateDelegate(typeof(Func), methodInfo); } catch { return null; } } private static Action? CreateSetter(PropertyInfo? property) { try { MethodInfo methodInfo = property?.GetSetMethod(nonPublic: true); if (methodInfo == null) { return null; } return (Action)Delegate.CreateDelegate(typeof(Action), methodInfo); } catch { return null; } } private static float GetFloat(PropertyInfo? property, Func? getter, float fallback) { if (getter != null) { try { return getter(); } catch { } } if (property == null) { return fallback; } try { return (property.GetValue(null) is float num) ? num : fallback; } catch { return fallback; } } private static void SetFloat(PropertyInfo? property, Action? setter, float value) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown if (setter != null) { try { setter(value); return; } catch { } } if (property == null) { return; } try { property.SetValue(null, value); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(39, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA AWO timer bridge could not set "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(property.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } private static string StripRichText(string text) { if (string.IsNullOrEmpty(text)) { return string.Empty; } int num = 0; while (num++ < 32) { int num2 = text.IndexOf('<'); if (num2 < 0) { break; } int num3 = text.IndexOf('>', num2); if (num3 < 0) { break; } text = text.Remove(num2, num3 - num2 + 1); } return text; } } private const float DefaultResumeSpeed = 1f; private const float TimerModeProbeInterval = 0.25f; private static bool _pauseActive; private static bool _pausedByTOA; private static float _resumeSpeed = 1f; private static int _pauseGeneration; private static float _nextPauseTickLogTime; private static float _nextTimerModeProbeTime; private static TimerMode _pauseMode = TimerMode.Unknown; private static string _lastHudTimerText = string.Empty; internal static void Pause(WardenObjectiveEventData eventData) { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown if (!AWOTimerBridge.IsAvailable) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA_PauseAWOTimer ignored because AWO EntryPoint.TimerMods was not found."); } return; } if (_pauseActive) { ManualLogSource? log2 = TOARuntime.Log; if (log2 != null) { log2.LogDebug((object)"TOA_PauseAWOTimer ignored because AWO timer is already paused by TOA."); } return; } _resumeSpeed = AWOTimerBridge.GetSpeedModifier(); if (Mathf.Approximately(_resumeSpeed, 0f)) { _resumeSpeed = 1f; } _lastHudTimerText = AWOTimerBridge.GetHudTimerText(); _pauseMode = AWOTimerBridge.DetectTimerMode(_lastHudTimerText); _nextTimerModeProbeTime = Time.realtimeSinceStartup + 0.25f; _pauseActive = true; _pausedByTOA = true; _pauseGeneration++; _nextPauseTickLogTime = Time.realtimeSinceStartup + 1f; AWOTimerBridge.ClearTimeModifier(); AWOTimerBridge.SetSpeedModifier(0f); TOAAWOTimerPauseDriver.Ensure().BeginPause(_pauseGeneration); ManualLogSource log3 = TOARuntime.Log; if (log3 != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(82, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA_PauseAWOTimer paused AWO timer. StoredResumeSpeed="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_resumeSpeed, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", DetectedMode="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(AWOTimerBridge.TimerModeToString(_pauseMode)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", HudText='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_lastHudTimerText); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log3.LogMessage(val); } } internal static void Resume(WardenObjectiveEventData eventData) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown if (!AWOTimerBridge.IsAvailable) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA_ResumeAWOTimer ignored because AWO EntryPoint.TimerMods was not found."); } return; } if (!_pausedByTOA) { ManualLogSource? log2 = TOARuntime.Log; if (log2 != null) { log2.LogDebug((object)"TOA_ResumeAWOTimer ignored because TOA has not paused an AWO timer."); } return; } _pauseActive = false; _pausedByTOA = false; _pauseGeneration++; _pauseMode = TimerMode.Unknown; _lastHudTimerText = string.Empty; TOAAWOTimerPauseDriver.Ensure().EndPause(); AWOTimerBridge.ClearTimeModifier(); AWOTimerBridge.SetSpeedModifier(Mathf.Approximately(_resumeSpeed, 0f) ? 1f : _resumeSpeed); ManualLogSource log3 = TOARuntime.Log; if (log3 != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(51, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA_ResumeAWOTimer resumed AWO timer. ResumeSpeed="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(AWOTimerBridge.GetSpeedModifier(), "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log3.LogMessage(val); } } internal static void Stop(WardenObjectiveEventData eventData) { //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown _pauseActive = false; _pausedByTOA = false; _pauseGeneration++; _pauseMode = TimerMode.Unknown; _lastHudTimerText = string.Empty; TOAAWOTimerPauseDriver.Ensure().EndPause(); if (AWOTimerBridge.IsAvailable) { AWOTimerBridge.ClearTimeModifier(); AWOTimerBridge.SetSpeedModifier(1f); AWOTimerBridge.ResetCountdownStarted(); } try { GuiManager.PlayerLayer.m_objectiveTimer.SetTimerActive(false, true); GuiManager.PlayerLayer.m_objectiveTimer.SetTimerTextEnabled(false); ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogMessage((object)"TOA_StopAWOTimer stopped and hid the current AWO objective timer HUD."); } } catch (Exception ex) { ManualLogSource log2 = TOARuntime.Log; if (log2 != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(55, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA_StopAWOTimer could not hide objective timer HUD: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log2.LogWarning(val); } } } internal static void TickPausedCountdown(int generation, int reloadCount) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown if (!_pauseActive || generation != _pauseGeneration) { return; } if ((int)GameStateManager.CurrentStateName != 10 || reloadCount < CheckpointManager.CheckpointUsage) { _pauseActive = false; _pausedByTOA = false; _pauseMode = TimerMode.Unknown; _lastHudTimerText = string.Empty; TOAAWOTimerPauseDriver.Ensure().EndPause(); return; } AWOTimerBridge.SetSpeedModifier(0f); TimerMode currentPauseMode = GetCurrentPauseMode(); if (currentPauseMode == TimerMode.Countdown) { AWOTimerBridge.AddTimeModifier(Time.deltaTime); } else { AWOTimerBridge.ClearTimeModifier(); } if (!(Time.realtimeSinceStartup >= _nextPauseTickLogTime)) { return; } _nextPauseTickLogTime = Time.realtimeSinceStartup + 10f; ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(83, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA AWO timer pause tick. DetectedMode="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(AWOTimerBridge.TimerModeToString(currentPauseMode)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", SpeedModifier="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(AWOTimerBridge.GetSpeedModifier(), "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", TimeModifier="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(AWOTimerBridge.GetTimeModifier(), "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", HudText='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_lastHudTimerText); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogDebug(val); } } private static TimerMode GetCurrentPauseMode() { if (Time.realtimeSinceStartup < _nextTimerModeProbeTime) { return _pauseMode; } _nextTimerModeProbeTime = Time.realtimeSinceStartup + 0.25f; _lastHudTimerText = AWOTimerBridge.GetHudTimerText(); TimerMode timerMode = AWOTimerBridge.DetectTimerMode(_lastHudTimerText); if (timerMode != TimerMode.Unknown) { _pauseMode = timerMode; } return _pauseMode; } } internal sealed class TOAAWOTimerPauseDriver : MonoBehaviour { private static TOAAWOTimerPauseDriver? _instance; private int _generation; private int _reloadCount; internal static TOAAWOTimerPauseDriver Ensure() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if ((Object)(object)_instance != (Object)null) { return _instance; } GameObject val = new GameObject("TOA_AWOTimerPauseDriver") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); ((Behaviour)_instance).enabled = false; return _instance; } internal void BeginPause(int generation) { _generation = generation; _reloadCount = CheckpointManager.CheckpointUsage; ((Behaviour)this).enabled = true; } internal void EndPause() { ((Behaviour)this).enabled = false; } private void Update() { TOAAWOTimerEvents.TickPausedCountdown(_generation, _reloadCount); } static TOAAWOTimerPauseDriver() { ClassInjector.RegisterTypeInIl2Cpp(); } } internal delegate void TOACustomEventHandler(WardenObjectiveEventData eventData); internal enum TOACustomEventType { TOA_PauseAWOTimer = 2000, TOA_ResumeAWOTimer = 2001, TOA_StopAWOTimer = 2002, TOA_CheckPocketItemCarrierInScope = 2003, TOA_AddPlayersToDeathEventGroup = 2004, TOA_AddPlayersToAllDownEventGroup = 2005, TOA_ToggleTimedTerminalSequence = 2006, TOA_ResetTimedTerminalSequenceRound = 2007, TOA_CompleteTimedTerminalSequence = 2008, TOA_TimedTerminalSequenceCommand = 2009, ToggleLaserRoom = 2010, TOA_AdjustTimedTerminalSequenceTimer = 2011, TOA_TimedTerminalSequenceCustomValidation = 2012, FF_ToggleFFCheck = 210, FF_AddPlayersInRangeToCheck = 211, FF_AddPlayersOutOfRangeToCheck = 212, FF_ToggleCheckOnGroup = 213, FF_Reset = 214, FF_ResetGroup = 215, FF_SetExpeditionFailedText = 216, FF_ResetExpeditionFailedText = 217, ToggleEventScanState = 270 } internal abstract class TOABaseWardenEvent { public abstract TOACustomEventType EventType { get; } public string Name { get; private set; } = string.Empty; internal void Setup() { Name = GetType().Name; OnSetup(); } internal void Trigger(WardenObjectiveEventData eventData) { TriggerCommon(eventData); } protected virtual void OnSetup() { } protected abstract void TriggerCommon(WardenObjectiveEventData eventData); } internal sealed class TOACheckPocketItemCarrierInScopeEvent : TOABaseWardenEvent { public override TOACustomEventType EventType => TOACustomEventType.TOA_CheckPocketItemCarrierInScope; protected override void TriggerCommon(WardenObjectiveEventData eventData) { TOAPocketItemCarrierEvents.CheckCarrierInScope(eventData); } } internal static class TOACustomEventRegistry { private static bool _registered; private static readonly Dictionary Handlers = new Dictionary(); private static readonly Dictionary EventInstances = new Dictionary(); internal static void RegisterDefaults() { if (!_registered) { Register(TOACustomEventType.TOA_PauseAWOTimer, TOAAWOTimerEvents.Pause); Register(TOACustomEventType.TOA_ResumeAWOTimer, TOAAWOTimerEvents.Resume); Register(TOACustomEventType.TOA_StopAWOTimer, TOAAWOTimerEvents.Stop); RegisterEventClass(new TOACheckPocketItemCarrierInScopeEvent()); Register(TOACustomEventType.TOA_AddPlayersToDeathEventGroup, TOADeathEventGroupEvents.AddPlayersToDeathEventGroup); Register(TOACustomEventType.TOA_AddPlayersToAllDownEventGroup, TOAAllDownEventGroupEvents.AddPlayersToAllDownEventGroup); Register(TOACustomEventType.TOA_ToggleTimedTerminalSequence, TOATimedTerminalSequenceManager.Current.ToggleFromEvent); Register(TOACustomEventType.TOA_ResetTimedTerminalSequenceRound, TOATimedTerminalSequenceManager.Current.ResetRoundFromEvent); Register(TOACustomEventType.TOA_CompleteTimedTerminalSequence, TOATimedTerminalSequenceManager.Current.CompleteFromEvent); Register(TOACustomEventType.TOA_TimedTerminalSequenceCommand, TOATimedTerminalSequenceManager.Current.ExecuteCommandEvent); Register(TOACustomEventType.TOA_AdjustTimedTerminalSequenceTimer, TOATimedTerminalSequenceManager.Current.AdjustActiveTimerFromEvent); Register(TOACustomEventType.TOA_TimedTerminalSequenceCustomValidation, TOATimedTerminalSequenceManager.Current.ExecuteCustomValidationEvent); Register(TOACustomEventType.ToggleLaserRoom, TOALaserRoomEvents.ToggleLaserRoom); Register(TOACustomEventType.FF_ToggleFFCheck, TOAForceFailEvents.ToggleCheck); Register(TOACustomEventType.FF_AddPlayersInRangeToCheck, TOAForceFailEvents.AddPlayersInRangeToCheck); Register(TOACustomEventType.FF_AddPlayersOutOfRangeToCheck, TOAForceFailEvents.AddPlayersOutOfRangeToCheck); Register(TOACustomEventType.FF_ToggleCheckOnGroup, TOAForceFailEvents.ToggleCheckOnGroup); Register(TOACustomEventType.FF_Reset, TOAForceFailEvents.Reset); Register(TOACustomEventType.FF_ResetGroup, TOAForceFailEvents.ResetGroup); Register(TOACustomEventType.FF_SetExpeditionFailedText, TOAForceFailEvents.SetExpeditionFailedText); Register(TOACustomEventType.FF_ResetExpeditionFailedText, TOAForceFailEvents.ResetExpeditionFailedText); Register(TOACustomEventType.ToggleEventScanState, TOAEventScanEvents.ToggleEventScanState); _registered = true; ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogMessage((object)"TOA custom event registry initialized with AWO timer Type 2000-2002, PocketItem carrier scope check Type 2003, DeathEventGroup Type 2004, AllDownEventGroup Type 2005, TimedTerminalSequence Type 2006-2009 and 2011-2012, FF Type 210-217, EventScan Type 270 and LaserRoom Type 2010 events."); } } } private static void RegisterEventClass(TOABaseWardenEvent eventInstance) { eventInstance.Setup(); EventInstances[eventInstance.EventType] = eventInstance; Register(eventInstance.EventType, eventInstance.Trigger); } private static void Register(TOACustomEventType eventType, TOACustomEventHandler handler) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown Handlers[eventType] = handler; string text = eventType.ToString(); uint num = (uint)eventType; if (EOSWardenEventManager.Current.AddEventDefinition(text, num, (Action)delegate(WardenObjectiveEventData e) { handler(e); })) { return; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(107, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA custom event Type="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Name="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" could not be registered. Another plugin may already own this event name or id."); } log.LogWarning(val); } } internal static void Execute(TOACustomEventType eventType, WardenObjectiveEventData eventData) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (Handlers.TryGetValue(eventType, out TOACustomEventHandler value)) { value(eventData); return; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA custom event '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has no registered handler."); } log.LogWarning(val); } } } internal sealed class TOAType2004EventData { internal int Count { get; set; } internal bool Enabled { get; set; } = true; internal bool HasEnabled { get; set; } internal Vector3 Position { get; set; } internal bool HasPosition { get; set; } internal float FogTransitionDuration { get; set; } internal bool HasFogTransitionDuration { get; set; } internal List Events { get; set; } = new List(); } internal readonly struct TOAType2004Signature : IEquatable { private readonly int _count; private readonly bool _enabled; private readonly int _radius1000; private readonly int _x1000; private readonly int _y1000; private readonly int _z1000; internal TOAType2004Signature(int count, bool enabled, float radius, Vector3 position) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) _count = count; _enabled = enabled; _radius1000 = Quantize(radius); _x1000 = Quantize(position.x); _y1000 = Quantize(position.y); _z1000 = Quantize(position.z); } internal static TOAType2004Signature FromEvent(WardenObjectiveEventData e) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) return new TOAType2004Signature(e.Count, e.Enabled, e.FogTransitionDuration, e.Position); } public bool Equals(TOAType2004Signature other) { if (_count == other._count && _enabled == other._enabled && _radius1000 == other._radius1000 && _x1000 == other._x1000 && _y1000 == other._y1000) { return _z1000 == other._z1000; } return false; } public override bool Equals(object? obj) { if (obj is TOAType2004Signature other) { return Equals(other); } return false; } public override int GetHashCode() { return HashCode.Combine(_count, _enabled, _radius1000, _x1000, _y1000, _z1000); } private static int Quantize(float value) { if (float.IsNaN(value) || float.IsInfinity(value)) { return 0; } return (int)Math.Round(value * 1000f); } } internal static class TOAType2004SidecarStore { private static readonly Dictionary ByEventPointer = new Dictionary(); private static readonly Dictionary> ByLooseSignature = new Dictionary>(); private static readonly List LooseFallback = new List(); private static readonly HashSet RegisteredLooseFingerprints = new HashSet(StringComparer.Ordinal); private static readonly HashSet AmbiguousWarningPrinted = new HashSet(); private static bool _isDeserializingSidecarEvents; private static bool _diskScanned; internal static bool TryGet(WardenObjectiveEventData eventData, out TOAType2004EventData data) { if (eventData != null && ByEventPointer.TryGetValue(((Il2CppObjectBase)eventData).Pointer, out data)) { return true; } if (eventData != null) { TOAType2004Signature tOAType2004Signature = TOAType2004Signature.FromEvent(eventData); if (ByLooseSignature.TryGetValue(tOAType2004Signature, out List value) && value.Count > 0) { data = value[0]; if (value.Count > 1 && AmbiguousWarningPrinted.Add(tOAType2004Signature)) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA Type 2004 sidecar fallback matched multiple definitions with the same vanilla signature. Using the first match. Make Count/Position/FogTransitionDuration/Enabled unique if this is not intended."); } } ByEventPointer[((Il2CppObjectBase)eventData).Pointer] = data; return true; } } if (LooseFallback.Count == 1) { data = LooseFallback[0]; if (eventData != null) { ByEventPointer[((Il2CppObjectBase)eventData).Pointer] = data; } return true; } data = null; return false; } internal static void ScanDiskForDefinitions() { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown if (_diskScanned) { return; } _diskScanned = true; int num = 0; int num2 = 0; int num3 = 0; bool flag = default(bool); ManualLogSource log; try { foreach (string item in EnumerateCandidateJsonFiles()) { num++; string text; try { text = File.ReadAllText(item); } catch { continue; } if (text.IndexOf("2004", StringComparison.OrdinalIgnoreCase) >= 0) { List list = ParseType2004Nodes(text); if (list.Count != 0) { num2++; num3 += list.Count; RegisterLoose(list); } } } } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 disk sidecar scan failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } if (num3 > 0) { log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(90, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2004 disk sidecar scan complete. FilesScanned="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", FilesWithType2004="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } return; } log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val3 = new BepInExDebugLogInterpolatedStringHandler(71, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA Type 2004 disk sidecar scan complete. FilesScanned="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", Definitions=0."); } log.LogDebug(val3); } } internal static void Capture(string json, object? result) { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Invalid comparison between Unknown and I4 if (_isDeserializingSidecarEvents || string.IsNullOrWhiteSpace(json) || json.IndexOf("2004", StringComparison.OrdinalIgnoreCase) < 0) { return; } List list = ParseType2004Nodes(json); if (list.Count == 0) { return; } RegisterLoose(list); if (result == null) { return; } List list2 = new List(); CollectEvents(result, list2, new HashSet(ReferenceEqualityComparer.Instance), 0); if (list2.Count == 0) { return; } Dictionary> dictionary = new Dictionary>(); foreach (TOAType2004EventData item in list) { TOAType2004Signature key = new TOAType2004Signature(item.Count, item.Enabled, item.FogTransitionDuration, item.Position); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new Queue()); } value.Enqueue(item); } Queue queue2 = new Queue(list); foreach (WardenObjectiveEventData item2 in list2) { if ((int)item2.Type == 2004) { TOAType2004EventData tOAType2004EventData = null; TOAType2004Signature key2 = TOAType2004Signature.FromEvent(item2); if (dictionary.TryGetValue(key2, out var value2) && value2.Count > 0) { tOAType2004EventData = value2.Dequeue(); } else if (queue2.Count > 0) { tOAType2004EventData = queue2.Dequeue(); } if (tOAType2004EventData != null) { ByEventPointer[((Il2CppObjectBase)item2).Pointer] = tOAType2004EventData; } } } } private static void RegisterLoose(IEnumerable parsed) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) foreach (TOAType2004EventData item in parsed) { string looseFingerprint = GetLooseFingerprint(item); if (RegisteredLooseFingerprints.Add(looseFingerprint)) { TOAType2004Signature key = new TOAType2004Signature(item.Count, item.Enabled, item.FogTransitionDuration, item.Position); if (!ByLooseSignature.TryGetValue(key, out List value)) { value = new List(1); ByLooseSignature[key] = value; } value.Add(item); LooseFallback.Add(item); } } } private static string GetLooseFingerprint(TOAType2004EventData data) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected I4, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) int num = 17; foreach (WardenObjectiveEventData @event in data.Events) { num = num * 31 + @event.Type; num = num * 31 + @event.Count; num = num * 31 + ((object)@event.LocalIndex/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + ((object)@event.Layer/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + ((object)@event.DimensionIndex/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + ((object)@event.Position/*cast due to .constrained prefix*/).GetHashCode(); num = num * 31 + @event.FogTransitionDuration.GetHashCode(); } return string.Join("|", data.Count, data.Enabled, data.FogTransitionDuration, data.Position.x, data.Position.y, data.Position.z, data.Events.Count, num); } private static IEnumerable EnumerateCandidateJsonFiles() { HashSet roots = new HashSet(StringComparer.OrdinalIgnoreCase); AddRoot(Paths.PluginPath); AddRoot(Path.Combine(Paths.BepInExRootPath, "GameData")); AddRoot(Path.Combine(Paths.BepInExRootPath, "Custom")); foreach (string item in roots) { IEnumerable enumerable; try { enumerable = Directory.EnumerateFiles(item, "*.json", SearchOption.AllDirectories).ToArray(); } catch { continue; } foreach (string item2 in enumerable) { yield return item2; } } void AddRoot(string? root) { if (!string.IsNullOrWhiteSpace(root) && Directory.Exists(root)) { roots.Add(Path.GetFullPath(root)); } } } private static List ParseType2004Nodes(string json) { List list = new List(); try { JsonNode jsonNode = JsonNode.Parse(json, new JsonNodeOptions { PropertyNameCaseInsensitive = true }, new JsonDocumentOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip }); if (jsonNode != null) { TraverseJson(jsonNode, list); } } catch { } return list; } private static void TraverseJson(JsonNode node, List output) { if (node is JsonObject jsonObject) { if (IsType2004Object(jsonObject)) { output.Add(ParseEventData(jsonObject)); } { foreach (KeyValuePair item in jsonObject) { if (item.Value != null) { TraverseJson(item.Value, output); } } return; } } if (!(node is JsonArray jsonArray)) { return; } foreach (JsonNode item2 in jsonArray) { if (item2 != null) { TraverseJson(item2, output); } } } private static bool IsType2004Object(JsonObject obj) { if (!obj.TryGetPropertyValue("Type", out JsonNode jsonNode)) { return false; } if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value == 2004; } if (jsonValue.TryGetValue(out string value2)) { if (!string.Equals(value2, "2004", StringComparison.OrdinalIgnoreCase)) { return string.Equals(value2, "TOA_AddPlayersToDeathEventGroup", StringComparison.OrdinalIgnoreCase); } return true; } } return false; } private static TOAType2004EventData ParseEventData(JsonObject obj) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) JsonNode jsonNode; TOAType2004EventData tOAType2004EventData = new TOAType2004EventData { Count = ReadInt(obj, "Count", 0), HasEnabled = obj.ContainsKey("Enabled"), Enabled = ReadBool(obj, "Enabled", fallback: true), HasPosition = obj.ContainsKey("Position"), Position = ReadVector3(obj.TryGetPropertyValue("Position", out jsonNode) ? jsonNode : null), HasFogTransitionDuration = obj.ContainsKey("FogTransitionDuration"), FogTransitionDuration = ReadFloat(obj, "FogTransitionDuration", 0f) }; if (obj.TryGetPropertyValue("Events", out JsonNode jsonNode2) && jsonNode2 != null) { tOAType2004EventData.Events = DeserializeEvents(jsonNode2.ToJsonString()); } return tOAType2004EventData; } private static List DeserializeEvents(string json) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown try { _isDeserializingSidecarEvents = true; return EOSJson.Deserialize>(json) ?? new List(); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(53, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 could not deserialize nested Events: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } return new List(); } finally { _isDeserializingSidecarEvents = false; } } private static void CollectEvents(object obj, List output, HashSet visited, int depth) { if (obj == null || depth > 12 || !visited.Add(obj)) { return; } WardenObjectiveEventData val = (WardenObjectiveEventData)((obj is WardenObjectiveEventData) ? obj : null); if (val != null) { output.Add(val); return; } if (obj is IEnumerable enumerable && !(obj is string)) { foreach (object item in enumerable) { if (item != null) { CollectEvents(item, output, visited, depth + 1); } } return; } Type type = obj.GetType(); if (type.IsPrimitive || type.IsEnum || type == typeof(string)) { return; } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.GetIndexParameters().Length != 0) { continue; } try { object value = propertyInfo.GetValue(obj); if (value != null) { CollectEvents(value, output, visited, depth + 1); } } catch { } } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { try { object value2 = fieldInfo.GetValue(obj); if (value2 != null) { CollectEvents(value2, output, visited, depth + 1); } } catch { } } } private static int ReadInt(JsonObject node, string name, int fallback) { try { if (node.TryGetPropertyValue(name, out JsonNode jsonNode) && jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2) && int.TryParse(value2, out value)) { return value; } } } catch { } return fallback; } private static float ReadFloat(JsonObject node, string name, float fallback) { try { if (node.TryGetPropertyValue(name, out JsonNode jsonNode) && jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out var value2)) { return (float)value2; } if (jsonValue.TryGetValue(out string value3) && float.TryParse(value3, NumberStyles.Float, CultureInfo.InvariantCulture, out value)) { return value; } } } catch { } return fallback; } private static bool ReadBool(JsonObject node, string name, bool fallback) { try { if (node.TryGetPropertyValue(name, out JsonNode jsonNode) && jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2) && bool.TryParse(value2, out value)) { return value; } } } catch { } return fallback; } private static Vector3 ReadVector3(JsonNode? node) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!(node is JsonObject node2)) { return Vector3.zero; } return new Vector3(ReadFloat(node2, "x", 0f), ReadFloat(node2, "y", 0f), ReadFloat(node2, "z", 0f)); } } internal static class TOADeathEventGroupEvents { internal static void AddPlayersToDeathEventGroup(WardenObjectiveEventData eventData) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.TOA_AddPlayersToDeathEventGroup, eventData)) { return; } if (!TOAType2004SidecarStore.TryGet(eventData, out TOAType2004EventData data)) { data = new TOAType2004EventData { Count = eventData.Count, Enabled = eventData.Enabled, Position = eventData.Position, HasPosition = true, FogTransitionDuration = eventData.FogTransitionDuration, HasFogTransitionDuration = (eventData.FogTransitionDuration > 0f), Events = new List() }; } bool flag = default(bool); ManualLogSource log; if (!data.Enabled) { TOADeathEventGroupManager.Current.SetGroupEnabled(data.Count, enabled: false); log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(54, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 death event group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" disabled and cleared."); } log.LogDebug(val); } return; } List list = ResolvePlayers(eventData, data); int num = TOADeathEventGroupManager.Current.AddPlayersToGroup(data.Count, list, data.Events); log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(61, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 death event group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": added "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" player(s), Events="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Events.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); } } private static List ResolvePlayers(WardenObjectiveEventData eventData, TOAType2004EventData data) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) TOAType2003TriggerScope current = TOAType2003TriggerScope.Current; if (current != null) { List list = ResolvePlayersFromContext(current); if (list.Count > 0) { return list; } } float num = (data.HasFogTransitionDuration ? data.FogTransitionDuration : eventData.FogTransitionDuration); Vector3 origin = (data.HasPosition ? data.Position : eventData.Position); if (num > 0f) { return GetPlayersInRadius(origin, num); } return GetAllPlayers(); } private static List ResolvePlayersFromContext(TOAType2003TriggerScope context) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)context.Collider != (Object)null) { List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current == (Object)null || !((Agent)current).Alive) { continue; } try { if (LG_CollisionWorldEventTrigger.IsInside(context.Collider, ((Agent)current).Position)) { list.Add(current); } } catch { try { Bounds bounds = context.Collider.bounds; if (((Bounds)(ref bounds)).Contains(((Agent)current).Position)) { list.Add(current); } } catch { } } } return list; } if (context.HasRadius) { return GetPlayersInRadius(context.Position, context.Radius); } if ((Object)(object)context.TriggeringPlayer != (Object)null && ((Agent)context.TriggeringPlayer).Alive) { return new List { context.TriggeringPlayer }; } return new List(); } private static List GetPlayersInRadius(Vector3 origin, float radius) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) float num = radius * radius; List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if (!((Object)(object)current == (Object)null) && ((Agent)current).Alive) { Vector3 val = ((Agent)current).Position - origin; if (((Vector3)(ref val)).sqrMagnitude <= num) { list.Add(current); } } } return list; } private static List GetAllPlayers() { List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current != (Object)null && ((Agent)current).Alive) { list.Add(current); } } return list; } } public struct TOADeathEventGroupReplicationState { public bool enabled; public bool checkP1; public bool checkP2; public bool checkP3; public bool checkP4; } internal sealed class TOADeathEventGroup { internal const int MaxPlayers = 4; private readonly bool[] _slots = new bool[4]; private readonly Dictionary _lastDeathFrameBySlot = new Dictionary(); private StateReplicator? _stateReplicator; internal bool Enabled { get; private set; } internal List Events { get; set; } = new List(); internal int Count { get { int num = 0; for (int i = 0; i < _slots.Length; i++) { if (_slots[i]) { num++; } } return num; } } internal bool SetPlayerInGroup(int slot, bool inGroup) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!IsValidPlayerSlot(slot)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(57, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 invalid player slot index "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(slot); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; expected [0, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } log.LogError(val); } return false; } if (_slots[slot] == inGroup) { return false; } int count = Count; _slots[slot] = inGroup; if (inGroup) { _lastDeathFrameBySlot.Remove(slot); } int count2 = Count; if (count == 0 && count2 > 0) { Enabled = true; } else if (count > 0 && count2 == 0) { Enabled = false; } Sync(); return true; } internal void Toggle(bool enabled) { if (!enabled) { ClearAndDisable(); } else if (!Enabled) { Enabled = true; Sync(); } } internal void ClearAndDisable() { bool flag = Enabled || Count > 0 || Events.Count > 0 || _lastDeathFrameBySlot.Count > 0; Enabled = false; for (int i = 0; i < _slots.Length; i++) { _slots[i] = false; } _lastDeathFrameBySlot.Clear(); Events = new List(); if (flag) { Sync(); } } internal bool ContainsSlot(int slot) { if (IsValidPlayerSlot(slot)) { return _slots[slot]; } return false; } internal bool TryMarkDeathFrame(int slot, int frame) { if (_lastDeathFrameBySlot.TryGetValue(slot, out var value) && value == frame) { return false; } _lastDeathFrameBySlot[slot] = frame; return true; } internal void ResetSynced() { Reset(); Sync(); } internal void ResetUnsynced() { Reset(); _stateReplicator?.SetStateUnsynced(GetSyncState()); } private void Reset() { Enabled = false; for (int i = 0; i < _slots.Length; i++) { _slots[i] = false; } _lastDeathFrameBySlot.Clear(); Events = new List(); } private void Sync() { if (!SNet.IsMaster) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA Type 2004 death event group sync blocked on client; state changes must be executed by host."); } } else { _stateReplicator?.SetState(GetSyncState()); } } private void OnStateChanged(TOADeathEventGroupReplicationState oldState, TOADeathEventGroupReplicationState newState, bool isRecall) { if (isRecall) { Enabled = newState.enabled; _slots[0] = newState.checkP1; _slots[1] = newState.checkP2; _slots[2] = newState.checkP3; _slots[3] = newState.checkP4; } } private TOADeathEventGroupReplicationState GetSyncState() { return new TOADeathEventGroupReplicationState { enabled = Enabled, checkP1 = _slots[0], checkP2 = _slots[1], checkP3 = _slots[2], checkP4 = _slots[3] }; } internal static TOADeathEventGroup? Instantiate() { if (!TOAStateReplicatorCompat.CanCreateReplicator("TOA Type 2004", logIfNotReady: false)) { return null; } uint num = EOSNetworking.AllotForeverReplicatorID(); if (num == 0) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogError((object)"TOA Type 2004 could not allocate a network replicator id."); } return null; } TOADeathEventGroup tOADeathEventGroup = new TOADeathEventGroup(); tOADeathEventGroup._stateReplicator = TOAStateReplicatorCompat.Create(num, default(TOADeathEventGroupReplicationState), (LifeTimeType)0, "TOA Type 2004"); if (tOADeathEventGroup._stateReplicator == null) { return null; } tOADeathEventGroup._stateReplicator.OnStateChanged += tOADeathEventGroup.OnStateChanged; tOADeathEventGroup.ResetUnsynced(); return tOADeathEventGroup; } private static bool IsValidPlayerSlot(int slot) { if (slot >= 0) { return slot < 4; } return false; } private TOADeathEventGroup() { } } internal sealed class TOADeathEventGroupManager { internal const int MaxGroups = 4; private readonly List _groups = new List(); private bool _initialized; private bool _delayedSetupLogged; internal static TOADeathEventGroupManager Current { get; } = new TOADeathEventGroupManager(); internal void Init() { if (!_initialized) { _initialized = true; EventAPI.OnManagersSetup += SetupGroups; LevelAPI.OnBuildStart += ResetUnsynced; LevelAPI.OnLevelCleanup += ResetUnsynced; LevelAPI.OnBuildDone += SetupGroups; } } internal int AddPlayersToGroup(int groupIndex, IEnumerable players, List events) { if (!TryGetGroup(groupIndex, out TOADeathEventGroup group)) { return 0; } if (events.Count > 0) { group.Events = events; } int num = 0; foreach (PlayerAgent player in players) { try { if (group.SetPlayerInGroup(player.PlayerSlotIndex, inGroup: true)) { num++; } } catch { } } return num; } internal void SetGroupEnabled(int groupIndex, bool enabled) { if (TryGetGroup(groupIndex, out TOADeathEventGroup group)) { group.Toggle(enabled); } } internal void ResetSynced() { foreach (TOADeathEventGroup group in _groups) { group.ResetSynced(); } } internal void ResetUnsynced() { foreach (TOADeathEventGroup group in _groups) { group.ResetUnsynced(); } } internal void OnPlayerDied(PlayerAgent? player) { //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected O, but got Unknown EnsureGroups(); if ((Object)(object)player == (Object)null || !SNet.IsMaster) { return; } int playerSlotIndex; try { playerSlotIndex = player.PlayerSlotIndex; } catch { return; } int frameCount = Time.frameCount; bool flag = default(bool); for (int i = 0; i < _groups.Count; i++) { TOADeathEventGroup tOADeathEventGroup = _groups[i]; if (!tOADeathEventGroup.Enabled || !tOADeathEventGroup.ContainsSlot(playerSlotIndex) || !tOADeathEventGroup.TryMarkDeathFrame(playerSlotIndex, frameCount)) { continue; } ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(73, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 death event group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(i); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": player slot "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(playerSlotIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" died; executing "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(tOADeathEventGroup.Events.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" event(s)."); } log.LogDebug(val); } foreach (WardenObjectiveEventData @event in tOADeathEventGroup.Events) { try { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(@event, (eWardenObjectiveEventTrigger)0, true, 0f); } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2004 nested event failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } } } } private void SetupGroups() { EnsureGroups(); } private bool EnsureGroups() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown if (_groups.Count >= 4) { return true; } bool flag = default(bool); if (!TOAStateReplicatorCompat.CanCreateReplicator("TOA Type 2004", logIfNotReady: false)) { if (!_delayedSetupLogged) { _delayedSetupLogged = true; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(99, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 death event group setup delayed until network state is ready. Current group count: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_groups.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); } } return false; } _delayedSetupLogged = false; while (_groups.Count < 4) { TOADeathEventGroup tOADeathEventGroup = TOADeathEventGroup.Instantiate(); if (tOADeathEventGroup == null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(110, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2004 death event group setup incomplete; instantiated "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_groups.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". It will retry when the group is next needed."); } log.LogWarning(val2); } return false; } _groups.Add(tOADeathEventGroup); } return true; } private bool TryGetGroup(int groupIndex, out TOADeathEventGroup? group) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown EnsureGroups(); bool flag = default(bool); if (groupIndex < 0 || groupIndex >= 4) { group = null; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(55, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2004 group index must be between 0 and "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; got "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(groupIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } return false; } if (groupIndex >= _groups.Count) { group = null; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(94, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2004 group "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(groupIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is not ready yet. Instantiated "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_groups.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; network state may still be unavailable."); } log.LogWarning(val2); } return false; } group = _groups[groupIndex]; return true; } private TOADeathEventGroupManager() { } } [HarmonyPatch(typeof(Dam_PlayerDamageBase), "ReceiveSetDead")] internal static class TOADeathEvent_DamPlayerDamageBaseReceiveSetDeadPatch { private static void Postfix(Dam_PlayerDamageBase __instance) { TOADeathEventGroupManager.Current.OnPlayerDied(TryGetOwner(__instance)); } internal static PlayerAgent? TryGetOwner(Dam_PlayerDamageBase? damageBase) { if ((Object)(object)damageBase == (Object)null) { return null; } try { return damageBase.Owner; } catch { return null; } } } [HarmonyPatch(typeof(Dam_PlayerDamageLocal), "ReceiveSetDead")] internal static class TOADeathEvent_DamPlayerDamageLocalReceiveSetDeadPatch { private static void Postfix(Dam_PlayerDamageLocal __instance) { TOADeathEventGroupManager.Current.OnPlayerDied(TOADeathEvent_DamPlayerDamageBaseReceiveSetDeadPatch.TryGetOwner((Dam_PlayerDamageBase?)(object)__instance)); } } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct TOAEventRequestPacket { public int MessageId; public ulong TriggerId; public int EventType; public byte Enabled; public int Count; public float Duration; public float FogTransitionDuration; public float PosX; public float PosY; public float PosZ; public int WorldEventObjectFilterHash; public uint CustomSubObjectiveId; } [StructLayout(LayoutKind.Sequential, Pack = 1)] internal struct TOATimedTerminalSequenceConfirmPacket { public int RuntimeIndex; public int Round; public byte ActionKind; public int MessageId; public float HostClockTime; public float HostDeadline; } internal static class TOANetworkEventProxy { private const string EventName = "TOA.HeavyIndustries.EventRequest.v1"; private const string TimedTerminalConfirmEventName = "TOA.HeavyIndustries.TimedTerminalSequenceConfirm.v1"; private static bool _registered; private static bool _timedTerminalConfirmRegistered; private static bool _executingHostRequest; private static bool _registrationFailed; private static long _nextTriggerId = Environment.TickCount64; private static int _nextMessageId; private static readonly HashSet ProcessedTriggerIds = new HashSet(StringComparer.Ordinal); internal static void ResetProcessedTriggers() { ProcessedTriggerIds.Clear(); } internal static int NextMessageId() { int num = Interlocked.Increment(ref _nextMessageId); if (num == int.MaxValue) { Interlocked.Exchange(ref _nextMessageId, 1); num = 1; } return num; } internal static void Init() { //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown if (_registered) { return; } bool flag = default(bool); try { if (!NetworkAPI.IsEventRegistered("TOA.HeavyIndustries.EventRequest.v1")) { NetworkAPI.RegisterEvent("TOA.HeavyIndustries.EventRequest.v1", (Action)OnReceiveEventRequest); ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogMessage((object)"TOA network event proxy registered."); } } else { ManualLogSource log2 = TOARuntime.Log; if (log2 != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(55, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network event proxy event '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("TOA.HeavyIndustries.EventRequest.v1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is already registered."); } log2.LogWarning(val); } } if (!NetworkAPI.IsEventRegistered("TOA.HeavyIndustries.TimedTerminalSequenceConfirm.v1")) { NetworkAPI.RegisterEvent("TOA.HeavyIndustries.TimedTerminalSequenceConfirm.v1", (Action)OnReceiveTimedTerminalConfirm); ManualLogSource? log3 = TOARuntime.Log; if (log3 != null) { log3.LogMessage((object)"TOA TimedTerminalSequence confirm event registered."); } } _registered = true; _timedTerminalConfirmRegistered = true; _registrationFailed = false; LevelAPI.OnLevelCleanup -= ResetProcessedTriggers; LevelAPI.OnLevelCleanup += ResetProcessedTriggers; } catch (Exception ex) { _registered = false; _registrationFailed = true; ManualLogSource log2 = TOARuntime.Log; if (log2 != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(92, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network event proxy disabled because GTFO-API NetworkAPI is not ready or unavailable: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log2.LogWarning(val); } } } internal static void TickRegistration() { if (_registered && _timedTerminalConfirmRegistered) { return; } try { if (SNet.HasMaster || SNet.IsMaster || SNet.IsInLobby) { Init(); } } catch { } } internal static void BroadcastTimedTerminalSequenceConfirm(int runtimeIndex, int round, byte actionKind, float hostDeadline) { //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Expected O, but got Unknown bool flag = default(bool); if (!EnsureRegistered() || !_timedTerminalConfirmRegistered) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(110, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence confirm skipped because NetworkAPI registration is unavailable. Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(runtimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Round="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(round); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Action="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(actionKind); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogWarning(val); } return; } try { TOATimedTerminalSequenceConfirmPacket tOATimedTerminalSequenceConfirmPacket = new TOATimedTerminalSequenceConfirmPacket { RuntimeIndex = runtimeIndex, Round = round, ActionKind = actionKind, MessageId = Environment.TickCount, HostClockTime = Clock.Time, HostDeadline = hostDeadline }; NetworkAPI.InvokeEvent("TOA.HeavyIndustries.TimedTerminalSequenceConfirm.v1", tOATimedTerminalSequenceConfirmPacket, (SNet_ChannelType)2); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(65, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence confirm broadcast. Index="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(runtimeIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Round="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(round); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Action="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(actionKind); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(50, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TimedTerminalSequence confirm broadcast failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log.LogError(val3); } } } private static bool EnsureRegistered() { if (_registered && _timedTerminalConfirmRegistered) { return true; } Init(); if (_registered) { return _timedTerminalConfirmRegistered; } return false; } private static void OnReceiveTimedTerminalConfirm(ulong sender, TOATimedTerminalSequenceConfirmPacket packet) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (SNet.IsMaster) { return; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(73, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence confirm received. Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(packet.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Round="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(packet.Round); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Action="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(packet.ActionKind); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Sender="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(sender); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } TOATimedTerminalSequenceManager.Current.ReceiveClientConfirm(packet.RuntimeIndex, packet.Round, packet.ActionKind, packet.MessageId, packet.HostClockTime, packet.HostDeadline); } internal static bool EnsureHostExecution(TOACustomEventType eventType, WardenObjectiveEventData eventData) { //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Expected O, but got Unknown if (!_registered || !_timedTerminalConfirmRegistered) { Init(); } if (_executingHostRequest || SNet.IsMaster) { return true; } bool flag = default(bool); if (!SNet.HasMaster || (Object)(object)SNet.Master == (Object)null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(67, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA event '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' ignored on client because no SNet master is available."); } log.LogWarning(val); } return false; } if (!EnsureRegistered()) { string text = (_registrationFailed ? "network proxy registration is unavailable" : "network proxy is not registered"); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(48, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA event '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' was not forwarded to host because "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogWarning(val); } return false; } try { TOAEventRequestPacket tOAEventRequestPacket = BuildPacket(eventType, eventData); NetworkAPI.InvokeEvent("TOA.HeavyIndustries.EventRequest.v1", tOAEventRequestPacket, SNet.Master, (SNet_ChannelType)4); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(59, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA event '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' forwarded to host for authoritative execution."); } log.LogMessage(val2); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(36, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA event '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' host-forward failed: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log.LogError(val3); } } return false; } internal static int StableHash(string text) { if (string.IsNullOrWhiteSpace(text)) { return 0; } int num = -2128831035; for (int i = 0; i < text.Length; i++) { num ^= char.ToUpperInvariant(text[i]); num *= 16777619; } if (num != 0) { return num; } return 1; } private static TOAEventRequestPacket BuildPacket(TOACustomEventType eventType, WardenObjectiveEventData eventData) { //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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) Vector3 position = eventData.Position; uint customSubObjectiveId = 0u; try { customSubObjectiveId = eventData.CustomSubObjective.Id; } catch { } return new TOAEventRequestPacket { MessageId = NextMessageId(), TriggerId = (ulong)Interlocked.Increment(ref _nextTriggerId), EventType = (int)eventType, Enabled = (eventData.Enabled ? ((byte)1) : ((byte)0)), Count = eventData.Count, Duration = eventData.Duration, FogTransitionDuration = eventData.FogTransitionDuration, PosX = position.x, PosY = position.y, PosZ = position.z, WorldEventObjectFilterHash = StableHash(eventData.WorldEventObjectFilter), CustomSubObjectiveId = customSubObjectiveId }; } private static void OnReceiveEventRequest(ulong sender, TOAEventRequestPacket packet) { //IL_01d2: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Expected O, but got Unknown if (!SNet.IsMaster) { return; } bool flag = default(bool); if (!Enum.IsDefined(typeof(TOACustomEventType), packet.EventType)) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(65, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network event proxy ignored unknown event type "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(packet.EventType); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" from sender "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(sender); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogWarning(val); } return; } TOACustomEventType eventType = (TOACustomEventType)packet.EventType; string item = $"{sender}:{packet.MessageId}:{packet.TriggerId}"; if (!ProcessedTriggerIds.Add(item)) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(93, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network event proxy ignored duplicate trigger. Event='"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', Sender="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(sender); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", MessageId="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(packet.MessageId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", TriggerId="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(packet.TriggerId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogWarning(val); } return; } try { _executingHostRequest = true; WardenObjectiveEventData eventData = BuildEventData(packet); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(54, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA network event proxy executing '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' on host. Sender="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(sender); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } TOACustomEventRegistry.Execute(eventType, eventData); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(48, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA network event proxy failed to execute '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(eventType); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log.LogError(val3); } } finally { _executingHostRequest = false; } } private static WardenObjectiveEventData BuildEventData(TOAEventRequestPacket packet) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected O, but got Unknown WardenObjectiveEventData val = new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)packet.EventType, Enabled = (packet.Enabled != 0), Count = packet.Count, Duration = packet.Duration, FogTransitionDuration = packet.FogTransitionDuration, Position = new Vector3(packet.PosX, packet.PosY, packet.PosZ) }; if (packet.WorldEventObjectFilterHash != 0 && TOAEventScanManager.Current.TryGetWorldEventObjectFilterByHash(packet.WorldEventObjectFilterHash, out string worldEventObjectFilter)) { val.WorldEventObjectFilter = worldEventObjectFilter; } else if (packet.WorldEventObjectFilterHash != 0 && TOATimedTerminalSequenceManager.Current.TryGetWorldEventObjectFilterByHash(packet.WorldEventObjectFilterHash, out worldEventObjectFilter)) { val.WorldEventObjectFilter = worldEventObjectFilter; } if (packet.CustomSubObjectiveId != 0) { try { val.CustomSubObjective = new LocalizedText { Id = packet.CustomSubObjectiveId }; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(68, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA network event proxy could not rebuild CustomSubObjective id="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(packet.CustomSubObjectiveId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } } return val; } } internal sealed class TOAType2003EventData { internal int TargetItemIndex { get; set; } internal bool RequireAnyCarrier { get; set; } = true; internal bool HasLayer { get; set; } internal bool HasDimensionIndex { get; set; } internal bool HasLocalIndex { get; set; } internal bool HasCount { get; set; } internal LG_LayerType Layer { get; set; } internal eDimensionIndex DimensionIndex { get; set; } internal eLocalZoneIndex LocalIndex { get; set; } internal int Count { get; set; } internal List Events { get; set; } = new List(); internal bool HasExplicitScope { get { if (!HasLayer && !HasDimensionIndex && !HasLocalIndex) { return HasCount; } return true; } } } internal readonly struct TOAType2003Signature : IEquatable { private readonly int _layer; private readonly int _dimensionIndex; private readonly int _localIndex; private readonly int _count; private readonly int _enabled; private readonly string _filter; private readonly int _posX; private readonly int _posY; private readonly int _posZ; internal TOAType2003Signature(int layer, int dimensionIndex, int localIndex, int count, bool enabled, string? filter, Vector3 position) { //IL_003a: 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_006a: Unknown result type (might be due to invalid IL or missing references) _layer = layer; _dimensionIndex = dimensionIndex; _localIndex = localIndex; _count = count; _enabled = (enabled ? 1 : 0); _filter = filter ?? string.Empty; _posX = Mathf.RoundToInt(position.x * 100f); _posY = Mathf.RoundToInt(position.y * 100f); _posZ = Mathf.RoundToInt(position.z * 100f); } internal static TOAType2003Signature FromEvent(WardenObjectiveEventData e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected I4, but got Unknown //IL_002f: Expected I4, but got Unknown //IL_002f: Expected I4, but got Unknown return new TOAType2003Signature((int)e.Layer, (int)e.DimensionIndex, (int)e.LocalIndex, e.Count, e.Enabled, e.WorldEventObjectFilter, e.Position); } internal static TOAType2003Signature FromJson(JsonObject node) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) int layer = ReadInt(node, "Layer", 0); int dimensionIndex = ReadInt(node, "DimensionIndex", 0); int localIndex = ReadInt(node, "LocalIndex", 0); int count = ReadInt(node, "Count", 0); bool enabled = ReadBool(node, "Enabled", fallback: false); string filter = ReadString(node, "WorldEventObjectFilter", string.Empty); Vector3 position = ReadVector3(node["Position"]); return new TOAType2003Signature(layer, dimensionIndex, localIndex, count, enabled, filter, position); } public bool Equals(TOAType2003Signature other) { if (_layer == other._layer && _dimensionIndex == other._dimensionIndex && _localIndex == other._localIndex && _count == other._count && _enabled == other._enabled && string.Equals(_filter, other._filter, StringComparison.OrdinalIgnoreCase) && _posX == other._posX && _posY == other._posY) { return _posZ == other._posZ; } return false; } public override bool Equals(object? obj) { if (obj is TOAType2003Signature other) { return Equals(other); } return false; } public override int GetHashCode() { HashCode hashCode = default(HashCode); hashCode.Add(_layer); hashCode.Add(_dimensionIndex); hashCode.Add(_localIndex); hashCode.Add(_count); hashCode.Add(_enabled); hashCode.Add(_filter, StringComparer.OrdinalIgnoreCase); hashCode.Add(_posX); hashCode.Add(_posY); hashCode.Add(_posZ); return hashCode.ToHashCode(); } private static int ReadInt(JsonObject node, string name, int fallback) { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected I4, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected I4, but got Unknown //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected I4, but got Unknown if (!node.TryGetPropertyValue(name, out JsonNode jsonNode) || jsonNode == null) { return fallback; } try { if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2) && !string.IsNullOrWhiteSpace(value2)) { if (int.TryParse(value2, out var result)) { return result; } if (Enum.TryParse(value2, ignoreCase: true, out LG_LayerType result2)) { return (int)result2; } if (Enum.TryParse(value2, ignoreCase: true, out eDimensionIndex result3)) { return (int)result3; } if (Enum.TryParse(value2, ignoreCase: true, out eLocalZoneIndex result4)) { return (int)result4; } } } } catch { } return fallback; } private static bool ReadBool(JsonObject node, string name, bool fallback) { if (!node.TryGetPropertyValue(name, out JsonNode jsonNode) || jsonNode == null) { return fallback; } try { if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2) && bool.TryParse(value2, out var result)) { return result; } } } catch { } return fallback; } private static string ReadString(JsonObject node, string name, string fallback) { if (!node.TryGetPropertyValue(name, out JsonNode jsonNode) || jsonNode == null) { return fallback; } try { if (jsonNode is JsonValue jsonValue && jsonValue.TryGetValue(out string value)) { return value ?? fallback; } } catch { } return fallback; } private static Vector3 ReadVector3(JsonNode? node) { //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) if (!(node is JsonObject node2)) { return Vector3.zero; } float num = ReadFloat(node2, "x", ReadFloat(node2, "X", 0f)); float num2 = ReadFloat(node2, "y", ReadFloat(node2, "Y", 0f)); float num3 = ReadFloat(node2, "z", ReadFloat(node2, "Z", 0f)); return new Vector3(num, num2, num3); } private static float ReadFloat(JsonObject node, string name, float fallback) { if (!node.TryGetPropertyValue(name, out JsonNode jsonNode) || jsonNode == null) { return fallback; } try { if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out var value2)) { return (float)value2; } if (jsonValue.TryGetValue(out string value3) && float.TryParse(value3, out var result)) { return result; } } } catch { } return fallback; } } internal static class TOAType2003SidecarStore { private static readonly Dictionary ByEventPointer = new Dictionary(); private static readonly Dictionary> ByLooseSignature = new Dictionary>(); private static readonly List LooseFallback = new List(); private static readonly HashSet RegisteredLooseFingerprints = new HashSet(StringComparer.Ordinal); private static readonly HashSet AmbiguousWarningPrinted = new HashSet(); private static bool _isDeserializingSidecarEvents; private static bool _diskScanned; internal static bool TryGet(WardenObjectiveEventData eventData, out TOAType2003EventData data) { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if (eventData != null && ByEventPointer.TryGetValue(((Il2CppObjectBase)eventData).Pointer, out data)) { return true; } if (eventData != null) { TOAType2003Signature tOAType2003Signature = TOAType2003Signature.FromEvent(eventData); if (ByLooseSignature.TryGetValue(tOAType2003Signature, out List value) && value.Count > 0) { data = value[0]; if (value.Count > 1 && AmbiguousWarningPrinted.Add(tOAType2003Signature)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(209, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 sidecar fallback matched "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(value.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" definitions with the same vanilla signature. Using the first match. Add explicit Layer/DimensionIndex/LocalIndex/Count or make signatures unique if this is not intended."); } log.LogWarning(val); } } ByEventPointer[((Il2CppObjectBase)eventData).Pointer] = data; return true; } } if (LooseFallback.Count == 1) { data = LooseFallback[0]; if (eventData != null) { ByEventPointer[((Il2CppObjectBase)eventData).Pointer] = data; } return true; } data = null; return false; } internal static void ScanDiskForDefinitions() { //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Expected O, but got Unknown //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown if (_diskScanned) { return; } _diskScanned = true; int num = 0; int num2 = 0; int num3 = 0; bool flag = default(bool); ManualLogSource log; try { foreach (string item in EnumerateCandidateJsonFiles()) { num++; string text; try { text = File.ReadAllText(item); } catch { continue; } if (text.IndexOf("TargetItemIndex", StringComparison.OrdinalIgnoreCase) >= 0 && text.IndexOf("2003", StringComparison.OrdinalIgnoreCase) >= 0) { List list = ParseType2003Nodes(text); if (list.Count != 0) { num2++; num3 += list.Count; RegisterLoose(list); } } } } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(42, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 disk sidecar scan failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } if (num3 > 0) { log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(90, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA Type 2003 disk sidecar scan complete. FilesScanned="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", FilesWithType2003="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num3); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } return; } log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val3 = new BepInExDebugLogInterpolatedStringHandler(71, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA Type 2003 disk sidecar scan complete. FilesScanned="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", Definitions=0."); } log.LogDebug(val3); } } private static IEnumerable EnumerateCandidateJsonFiles() { HashSet roots = new HashSet(StringComparer.OrdinalIgnoreCase); try { AddRoot(Paths.PluginPath); } catch { } try { AddRoot(Path.Combine(Paths.GameRootPath, "BepInEx", "GameData")); } catch { } foreach (string item in roots) { IEnumerable enumerable; try { enumerable = Directory.EnumerateFiles(item, "*.json", SearchOption.AllDirectories); } catch { continue; } foreach (string item2 in enumerable) { yield return item2; } } void AddRoot(string? root) { if (!string.IsNullOrWhiteSpace(root) && Directory.Exists(root)) { roots.Add(Path.GetFullPath(root)); } } } private static void RegisterLoose(IEnumerable parsed) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected I4, but got Unknown //IL_004e: Expected I4, but got Unknown //IL_004e: Expected I4, but got Unknown foreach (TOAType2003EventData item in parsed) { string looseFingerprint = GetLooseFingerprint(item); if (RegisteredLooseFingerprints.Add(looseFingerprint)) { TOAType2003Signature key = new TOAType2003Signature((int)item.Layer, (int)item.DimensionIndex, (int)item.LocalIndex, item.Count, enabled: false, string.Empty, Vector3.zero); if (!ByLooseSignature.TryGetValue(key, out List value)) { value = new List(1); ByLooseSignature[key] = value; } value.Add(item); LooseFallback.Add(item); } } } private static string GetLooseFingerprint(TOAType2003EventData data) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected I4, but got Unknown //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected I4, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Expected I4, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected I4, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Expected I4, but got Unknown //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected I4, but got Unknown //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Expected I4, but got Unknown HashCode hashCode = default(HashCode); hashCode.Add(data.TargetItemIndex); hashCode.Add(data.RequireAnyCarrier); hashCode.Add(data.HasLayer); hashCode.Add(data.HasDimensionIndex); hashCode.Add(data.HasLocalIndex); hashCode.Add(data.HasCount); hashCode.Add((int)data.Layer); hashCode.Add((int)data.DimensionIndex); hashCode.Add((int)data.LocalIndex); hashCode.Add(data.Count); hashCode.Add(data.Events.Count); foreach (WardenObjectiveEventData @event in data.Events) { hashCode.Add((int)@event.Type); hashCode.Add((int)@event.Layer); hashCode.Add((int)@event.DimensionIndex); hashCode.Add((int)@event.LocalIndex); hashCode.Add(@event.Count); hashCode.Add(LocalizedText.op_Implicit(@event.WardenIntel), StringComparer.Ordinal); hashCode.Add(@event.WorldEventObjectFilter, StringComparer.Ordinal); } return hashCode.ToHashCode().ToString("X8"); } internal static void Capture(string json, object? result) { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected I4, but got Unknown //IL_0093: Expected I4, but got Unknown //IL_0093: Expected I4, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Invalid comparison between Unknown and I4 if (_isDeserializingSidecarEvents || string.IsNullOrWhiteSpace(json) || result == null) { return; } List list = ParseType2003Nodes(json); if (list.Count == 0) { return; } RegisterLoose(list); List list2 = new List(); HashSet visited = new HashSet(ReferenceEqualityComparer.Instance); CollectEvents(result, list2, visited, 0); if (list2.Count == 0) { return; } Dictionary> dictionary = new Dictionary>(); foreach (TOAType2003EventData item in list) { TOAType2003Signature key = new TOAType2003Signature((int)item.Layer, (int)item.DimensionIndex, (int)item.LocalIndex, item.Count, enabled: false, string.Empty, Vector3.zero); if (!dictionary.TryGetValue(key, out var value)) { value = (dictionary[key] = new Queue()); } value.Enqueue(item); } Queue queue2 = new Queue(list); foreach (WardenObjectiveEventData item2 in list2) { if ((int)item2.Type == 2003) { TOAType2003EventData tOAType2003EventData = null; TOAType2003Signature key2 = TOAType2003Signature.FromEvent(item2); if (dictionary.TryGetValue(key2, out var value2) && value2.Count > 0) { tOAType2003EventData = value2.Dequeue(); } else if (queue2.Count > 0) { tOAType2003EventData = queue2.Dequeue(); } if (tOAType2003EventData != null) { ByEventPointer[((Il2CppObjectBase)item2).Pointer] = tOAType2003EventData; } } } } private static List ParseType2003Nodes(string json) { //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown List list = new List(); try { JsonNode jsonNode = JsonNode.Parse(json, new JsonNodeOptions { PropertyNameCaseInsensitive = true }, new JsonDocumentOptions { AllowTrailingCommas = true, CommentHandling = JsonCommentHandling.Skip }); if (jsonNode != null) { TraverseJson(jsonNode, list); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(44, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 sidecar JSON parse skipped: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } return list; } private static void TraverseJson(JsonNode node, List output) { if (node is JsonObject jsonObject) { if (IsType2003Object(jsonObject)) { output.Add(ParseEventData(jsonObject)); } { foreach (KeyValuePair item in jsonObject) { if (item.Value != null) { TraverseJson(item.Value, output); } } return; } } if (!(node is JsonArray jsonArray)) { return; } foreach (JsonNode item2 in jsonArray) { if (item2 != null) { TraverseJson(item2, output); } } } private static bool IsType2003Object(JsonObject obj) { if (!obj.TryGetPropertyValue("Type", out JsonNode jsonNode) || jsonNode == null) { return false; } try { if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value == 2003; } if (jsonValue.TryGetValue(out string value2)) { return string.Equals(value2, "2003", StringComparison.OrdinalIgnoreCase) || string.Equals(value2, "TOA_CheckPocketItemCarrierInScope", StringComparison.OrdinalIgnoreCase) || string.Equals(value2, "TOA_CheckPocketItemCarrierInScope", StringComparison.OrdinalIgnoreCase); } } } catch { } return false; } private static TOAType2003EventData ParseEventData(JsonObject obj) { TOAType2003EventData tOAType2003EventData = new TOAType2003EventData { TargetItemIndex = ReadInt(obj, "TargetItemIndex", 0), RequireAnyCarrier = ReadBool(obj, "RequireAnyCarrier", fallback: true), HasLayer = obj.ContainsKey("Layer"), HasDimensionIndex = obj.ContainsKey("DimensionIndex"), HasLocalIndex = obj.ContainsKey("LocalIndex"), HasCount = obj.ContainsKey("Count"), Layer = (LG_LayerType)(byte)ReadInt(obj, "Layer", 0), DimensionIndex = (eDimensionIndex)ReadInt(obj, "DimensionIndex", 0), LocalIndex = (eLocalZoneIndex)ReadInt(obj, "LocalIndex", 0), Count = ReadInt(obj, "Count", 0) }; if (obj.TryGetPropertyValue("Events", out JsonNode jsonNode) && jsonNode is JsonArray jsonArray) { tOAType2003EventData.Events = DeserializeEvents(jsonArray.ToJsonString()); } return tOAType2003EventData; } private static List DeserializeEvents(string json) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown try { _isDeserializingSidecarEvents = true; return EOSJson.Deserialize>(json) ?? new List(); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(53, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 could not deserialize nested Events: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } return new List(); } finally { _isDeserializingSidecarEvents = false; } } private static void CollectEvents(object obj, List output, HashSet visited, int depth) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 if (depth > 12 || obj == null || obj is string) { return; } Type type = obj.GetType(); if (!type.IsValueType && !visited.Add(obj)) { return; } WardenObjectiveEventData val = (WardenObjectiveEventData)((obj is WardenObjectiveEventData) ? obj : null); if (val != null) { if ((int)val.Type == 2003) { output.Add(val); } return; } if (obj is IEnumerable enumerable) { int num = 0; { foreach (object item in enumerable) { if (item != null) { CollectEvents(item, output, visited, depth + 1); } if (++num > 20000) { break; } } return; } } if (type.Namespace != null && (type.Namespace.StartsWith("System", StringComparison.Ordinal) || type.Namespace.StartsWith("UnityEngine", StringComparison.Ordinal))) { return; } FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (fieldInfo.FieldType.IsPointer || fieldInfo.FieldType.IsPrimitive || fieldInfo.FieldType.IsEnum) { continue; } try { object value = fieldInfo.GetValue(obj); if (value != null) { CollectEvents(value, output, visited, depth + 1); } } catch { } } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (!propertyInfo.CanRead || propertyInfo.GetIndexParameters().Length != 0 || propertyInfo.PropertyType.IsPointer || propertyInfo.PropertyType.IsPrimitive || propertyInfo.PropertyType.IsEnum) { continue; } try { object value2 = propertyInfo.GetValue(obj); if (value2 != null) { CollectEvents(value2, output, visited, depth + 1); } } catch { } } } private static int ReadInt(JsonObject node, string name, int fallback) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected I4, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected I4, but got Unknown //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected I4, but got Unknown if (!node.TryGetPropertyValue(name, out JsonNode jsonNode) || jsonNode == null) { return fallback; } try { if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2)) { if (int.TryParse(value2, out var result)) { return result; } if (Enum.TryParse(value2, ignoreCase: true, out LG_LayerType result2)) { return (int)result2; } if (Enum.TryParse(value2, ignoreCase: true, out eDimensionIndex result3)) { return (int)result3; } if (Enum.TryParse(value2, ignoreCase: true, out eLocalZoneIndex result4)) { return (int)result4; } } } } catch { } return fallback; } private static bool ReadBool(JsonObject node, string name, bool fallback) { if (!node.TryGetPropertyValue(name, out JsonNode jsonNode) || jsonNode == null) { return fallback; } try { if (jsonNode is JsonValue jsonValue) { if (jsonValue.TryGetValue(out var value)) { return value; } if (jsonValue.TryGetValue(out string value2) && bool.TryParse(value2, out var result)) { return result; } } } catch { } return fallback; } } internal sealed class TOAType2003TriggerScope : IDisposable { private static readonly Stack Scopes = new Stack(); internal string Source { get; } internal PlayerAgent? TriggeringPlayer { get; } internal Collider? Collider { get; } internal Vector3 Position { get; } internal float Radius { get; } internal bool HasRadius { get; } internal static TOAType2003TriggerScope? Current { get { if (Scopes.Count <= 0) { return null; } return Scopes.Peek(); } } private TOAType2003TriggerScope(string source, PlayerAgent? player, Collider? collider, Vector3 position, float radius, bool hasRadius) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) Source = source; TriggeringPlayer = player; Collider = collider; Position = position; Radius = radius; HasRadius = hasRadius; } internal static TOAType2003TriggerScope PushPlayer(string source, PlayerAgent? player) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) TOAType2003TriggerScope tOAType2003TriggerScope = new TOAType2003TriggerScope(source, player, null, Vector3.zero, 0f, hasRadius: false); Scopes.Push(tOAType2003TriggerScope); return tOAType2003TriggerScope; } internal static TOAType2003TriggerScope PushCollider(string source, PlayerAgent? player, Collider? collider, Vector3 fallbackPosition) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) TOAType2003TriggerScope tOAType2003TriggerScope = new TOAType2003TriggerScope(source, player, collider, fallbackPosition, 0f, hasRadius: false); Scopes.Push(tOAType2003TriggerScope); return tOAType2003TriggerScope; } internal static TOAType2003TriggerScope PushRadius(string source, Vector3 position, float radius) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) TOAType2003TriggerScope tOAType2003TriggerScope = new TOAType2003TriggerScope(source, null, null, position, radius, hasRadius: true); Scopes.Push(tOAType2003TriggerScope); return tOAType2003TriggerScope; } public void Dispose() { if (Scopes.Count > 0 && Scopes.Peek() == this) { Scopes.Pop(); return; } Stack stack = new Stack(); while (Scopes.Count > 0) { TOAType2003TriggerScope tOAType2003TriggerScope = Scopes.Pop(); if (tOAType2003TriggerScope == this) { break; } stack.Push(tOAType2003TriggerScope); } while (stack.Count > 0) { Scopes.Push(stack.Pop()); } } } internal static class TOAPocketItemCarrierEvents { internal static void CheckCarrierInScope(WardenObjectiveEventData eventData) { //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown if (!TOAType2003SidecarStore.TryGet(eventData, out TOAType2003EventData data)) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA Type 2003 skipped because TargetItemIndex/Events sidecar data was not captured. This usually means the game is not running the TOA build that contains Type 2003, or the JSON was loaded before TOA could attach sidecar data. Install the latest DLL and keep the Type 2003 JSON in a scanned Custom/GameData JSON file."); } return; } List list = ResolvePlayers(eventData, data); bool flag = false; if (AWOPocketItemsBridge.TryGetPocketItemTag(data.TargetItemIndex, out string tag)) { foreach (PlayerAgent item in list) { if (IsCarrierWithTag(item, tag)) { flag = true; break; } } } bool flag2 = default(bool); ManualLogSource log2; if (flag != data.RequireAnyCarrier) { log2 = TOARuntime.Log; if (log2 != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(86, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 condition failed. TargetItemIndex="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.TargetItemIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", RequireAnyCarrier="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.RequireAnyCarrier); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", PlayersChecked="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log2.LogDebug(val); } return; } log2 = TOARuntime.Log; if (log2 != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(95, 4, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 condition passed. TargetItemIndex="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.TargetItemIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", RequireAnyCarrier="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.RequireAnyCarrier); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", PlayersChecked="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Events="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(data.Events.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log2.LogDebug(val); } foreach (WardenObjectiveEventData @event in data.Events) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(@event, (eWardenObjectiveEventTrigger)0, true, 0f); } } private static List ResolvePlayers(WardenObjectiveEventData eventData, TOAType2003EventData data) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) if (data.HasExplicitScope) { LG_LayerType layer = (data.HasLayer ? data.Layer : eventData.Layer); return GetPlayersInZoneArea(data.HasDimensionIndex ? data.DimensionIndex : eventData.DimensionIndex, zone: data.HasLocalIndex ? data.LocalIndex : eventData.LocalIndex, areaIndex: data.HasCount ? data.Count : eventData.Count, layer: layer, hasArea: data.HasCount); } TOAType2003TriggerScope current = TOAType2003TriggerScope.Current; if (current != null) { List list = ResolvePlayersFromContext(current); if (list.Count > 0) { return list; } } if (HasUsefulGenericZone(eventData)) { return GetPlayersInZoneArea(eventData.DimensionIndex, eventData.Layer, eventData.LocalIndex, eventData.Count != 0, eventData.Count); } return GetAllPlayers(); } private static List ResolvePlayersFromContext(TOAType2003TriggerScope context) { //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)context.Collider != (Object)null) { List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current == (Object)null || !((Agent)current).Alive) { continue; } try { if (LG_CollisionWorldEventTrigger.IsInside(context.Collider, ((Agent)current).Position)) { list.Add(current); } } catch { Bounds bounds = context.Collider.bounds; if (((Bounds)(ref bounds)).Contains(((Agent)current).Position)) { list.Add(current); } } } return list; } if (context.HasRadius) { float num = context.Radius * context.Radius; List list2 = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current2 = enumerator.Current; if (!((Object)(object)current2 == (Object)null) && ((Agent)current2).Alive) { Vector3 val = ((Agent)current2).Position - context.Position; if (((Vector3)(ref val)).sqrMagnitude <= num) { list2.Add(current2); } } } return list2; } if ((Object)(object)context.TriggeringPlayer != (Object)null) { return new List { context.TriggeringPlayer }; } return new List(); } private static bool HasUsefulGenericZone(WardenObjectiveEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 if ((int)eventData.LocalIndex == 0 && eventData.Count == 0 && (int)eventData.Layer == 0) { return (int)eventData.DimensionIndex > 0; } return true; } private static List GetAllPlayers() { List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current != (Object)null && ((Agent)current).Alive) { list.Add(current); } } return list; } private static List GetPlayersInZoneArea(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex zone, bool hasArea, int areaIndex) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) List list = new List(); Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; if ((Object)(object)current == (Object)null || !((Agent)current).Alive || ((Agent)current).CourseNode == null) { continue; } try { AIG_CourseNode courseNode = ((Agent)current).CourseNode; if (courseNode.LayerType != layer) { continue; } LG_Zone zone2 = courseNode.m_zone; if (!((Object)(object)zone2 == (Object)null) && zone2.DimensionIndex == dim && zone2.LocalIndex == zone) { if (!hasArea) { goto IL_0095; } LG_Area area = courseNode.m_area; if (!((Object)(object)area == (Object)null) && GetAreaIndex(zone2, area) == areaIndex) { goto IL_0095; } } goto end_IL_0037; IL_0095: list.Add(current); end_IL_0037:; } catch { } } return list; } private static int GetAreaIndex(LG_Zone zone, LG_Area area) { try { int num = 0; Enumerator enumerator = zone.m_areas.GetEnumerator(); while (enumerator.MoveNext()) { LG_Area current = enumerator.Current; if ((Object)(object)current != (Object)null && ((Il2CppObjectBase)current).Pointer == ((Il2CppObjectBase)area).Pointer) { return num; } num++; } } catch { } return -1; } private static bool IsCarrierWithTag(PlayerAgent player, string tag) { if (string.IsNullOrWhiteSpace(tag)) { return false; } if (string.Equals(player.PlayerName, tag, StringComparison.OrdinalIgnoreCase)) { return true; } try { if ((Object)(object)player.Owner != (Object)null && string.Equals(player.Owner.GetName(), tag, StringComparison.OrdinalIgnoreCase)) { return true; } } catch { } return false; } } internal static class AWOPocketItemsBridge { private readonly struct CachedPocketItemTag { internal readonly int Frame; internal readonly string Tag; internal readonly bool Found; internal CachedPocketItemTag(int frame, string tag, bool found) { Frame = frame; Tag = tag; Found = found; } } private static bool _resolved; private static FieldInfo? _mapField; private static PropertyInfo? _tagProperty; private static readonly Dictionary FrameTagCache = new Dictionary(4); internal static bool TryGetPocketItemTag(int index, out string tag) { tag = string.Empty; int frameCount = Time.frameCount; if (FrameTagCache.TryGetValue(index, out var value) && value.Frame == frameCount) { tag = value.Tag; return value.Found; } bool flag = TryReadPocketItemTagUncached(index, out tag); FrameTagCache[index] = new CachedPocketItemTag(frameCount, tag, flag); return flag; } private static bool TryReadPocketItemTagUncached(int index, out string tag) { //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown tag = string.Empty; Resolve(); if (_mapField == null) { return false; } try { if (!(_mapField.GetValue(null) is IDictionary dictionary) || !dictionary.Contains(index)) { return false; } object obj = dictionary[index]; if (obj == null) { return false; } tag = ((_tagProperty = _tagProperty ?? obj.GetType().GetProperty("Tag", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))?.GetValue(obj))?.ToString() ?? string.Empty; return !string.IsNullOrWhiteSpace(tag); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(58, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 could not read AWO PocketItemsMap Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(index); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogDebug(val); } return false; } } private static void Resolve() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if (_resolved) { return; } _resolved = true; try { _mapField = FindAwoSetPocketItemEventType()?.GetField("PocketItemsMap", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(73, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA Type 2003 could not resolve AWO SetPocketItemEvent.PocketItemsMap: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogDebug(val); } } } private static Type? FindAwoSetPocketItemEventType() { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (IsAwoAssemblyName(assembly.GetName().Name ?? string.Empty)) { Type type = assembly.GetType("AWO.Modules.WEE.Events.SetPocketItemEvent", throwOnError: false, ignoreCase: false); if (type != null) { return type; } } } return null; } private static bool IsAwoAssemblyName(string assemblyName) { if (!string.Equals(assemblyName, "AdvancedWardenObjective", StringComparison.OrdinalIgnoreCase) && !string.Equals(assemblyName, "AWO", StringComparison.OrdinalIgnoreCase)) { return assemblyName.IndexOf("AdvancedWardenObjective", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } } [HarmonyPatch(typeof(LG_CollisionWorldEventTrigger), "Trigger")] internal static class TOAType2003_CollisionWorldEventTriggerPatch { private static void Prefix(LG_CollisionWorldEventTrigger __instance, SNet_Player source, out TOAType2003TriggerScope? __state) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) __state = TOAType2003TriggerScope.PushCollider("LG_CollisionWorldEventTrigger", TOAType2003PlayerResolver.GetPlayerAgent(source), __instance.m_collider, ((Component)__instance).transform.position); } private static void Finalizer(TOAType2003TriggerScope? __state) { __state?.Dispose(); } } [HarmonyPatch(typeof(LG_LookatWorldEventTrigger), "Trigger")] internal static class TOAType2003_LookatWorldEventTriggerPatch { private static void Prefix(SNet_Player source, out TOAType2003TriggerScope? __state) { __state = TOAType2003TriggerScope.PushPlayer("LG_LookatWorldEventTrigger", TOAType2003PlayerResolver.GetPlayerAgent(source)); } private static void Finalizer(TOAType2003TriggerScope? __state) { __state?.Dispose(); } } [HarmonyPatch(typeof(LG_InteractWorldEventTrigger), "Trigger")] internal static class TOAType2003_InteractWorldEventTriggerPatch { private static void Prefix(SNet_Player source, out TOAType2003TriggerScope? __state) { __state = TOAType2003TriggerScope.PushPlayer("LG_InteractWorldEventTrigger", TOAType2003PlayerResolver.GetPlayerAgent(source)); } private static void Finalizer(TOAType2003TriggerScope? __state) { __state?.Dispose(); } } internal static class TOAType2003PlayerResolver { internal static PlayerAgent? GetPlayerAgent(SNet_Player? source) { if ((Object)(object)source == (Object)null || !source.HasPlayerAgent) { return null; } try { SNet_IPlayerAgent playerAgent = source.PlayerAgent; return (playerAgent != null) ? ((Il2CppObjectBase)playerAgent).TryCast() : null; } catch { return null; } } } internal static class TOAForceFailEvents { internal static void ToggleCheck(WardenObjectiveEventData eventData) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_ToggleFFCheck, eventData)) { return; } TOAForceFailManager.Current.ToggleCheck(eventData.Enabled); ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA FF check enabled="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventData.Enabled); } log.LogMessage(val); } } internal static void AddPlayersInRangeToCheck(WardenObjectiveEventData eventData) { //IL_0016: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Expected O, but got Unknown if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_AddPlayersInRangeToCheck, eventData)) { return; } float fogTransitionDuration = eventData.FogTransitionDuration; Vector3 position = eventData.Position; int count = eventData.Count; Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); bool flag = default(bool); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; Vector3 val = ((Agent)current).Position - position; float magnitude = ((Vector3)(ref val)).magnitude; ManualLogSource log; if (magnitude < fogTransitionDuration) { TOAForceFailManager.Current.AddPlayerToGroup(current.PlayerSlotIndex, count); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(52, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA FF group "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": added player slot "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(current.PlayerSlotIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; distance="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(magnitude, "F2"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", range="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(fogTransitionDuration, "F2"); } log.LogMessage(val2); } continue; } log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(56, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA FF group "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(count); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": player slot "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(current.PlayerSlotIndex); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" not added; distance="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(magnitude, "F2"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", range="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(fogTransitionDuration, "F2"); } log.LogWarning(val3); } } } internal static void AddPlayersOutOfRangeToCheck(WardenObjectiveEventData eventData) { //IL_0016: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Expected O, but got Unknown if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_AddPlayersOutOfRangeToCheck, eventData)) { return; } float fogTransitionDuration = eventData.FogTransitionDuration; Vector3 position = eventData.Position; int count = eventData.Count; Enumerator enumerator = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); bool flag = default(bool); while (enumerator.MoveNext()) { PlayerAgent current = enumerator.Current; Vector3 val = ((Component)current).transform.position - position; float magnitude = ((Vector3)(ref val)).magnitude; if (!(magnitude > fogTransitionDuration)) { continue; } TOAForceFailManager.Current.AddPlayerToGroup(current.PlayerSlotIndex, count); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(52, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA FF group "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": added player slot "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(current.PlayerSlotIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; distance="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(magnitude, "F2"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", range="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(fogTransitionDuration, "F2"); } log.LogMessage(val2); } } } internal static void ToggleCheckOnGroup(WardenObjectiveEventData eventData) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_ToggleCheckOnGroup, eventData)) { return; } int count = eventData.Count; bool flag = default(bool); ManualLogSource log; if (TOAForceFailManager.Current.ToggleCheckOnGroup(count, eventData.Enabled)) { log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(22, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA FF group "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" enabled="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventData.Enabled); } log.LogMessage(val); } return; } log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(29, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA FF group "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is not defined."); } log.LogError(val2); } } internal static void Reset(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_Reset, eventData)) { TOAForceFailManager.Current.ResetSynced(); ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogMessage((object)"TOA FF reset."); } } } internal static void ResetGroup(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_ResetGroup, eventData)) { TOAForceFailManager.Current.ResetGroupSynced(eventData.Count); } } internal static void SetExpeditionFailedText(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_SetExpeditionFailedText, eventData)) { TOAForceFailManager.Current.SetExpeditionFailedText(GetLocalizedText(eventData)); } } internal static void ResetExpeditionFailedText(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.FF_ResetExpeditionFailedText, eventData)) { TOAForceFailManager.Current.ResetExpeditionFailedText(); } } private static string GetLocalizedText(WardenObjectiveEventData eventData) { try { if (eventData.CustomSubObjective.Id != 0) { return Text.Get(eventData.CustomSubObjective.Id); } string untranslatedText = eventData.CustomSubObjective.UntranslatedText; if (!string.IsNullOrWhiteSpace(untranslatedText)) { return untranslatedText; } } catch { } return string.Empty; } } internal sealed class TOAForceFailManager { internal const int MaxGroups = 4; private readonly List _playerGroups = new List(); private bool _initialized; private bool _delayedSetupLogged; internal static TOAForceFailManager Current { get; } = new TOAForceFailManager(); internal void Init() { if (!_initialized) { _initialized = true; EventAPI.OnManagersSetup += SetupGroups; LevelAPI.OnBuildStart += ResetUnsynced; LevelAPI.OnLevelCleanup += ResetUnsynced; LevelAPI.OnBuildStart += ResetExpeditionFailedText; LevelAPI.OnBuildDone += ResetExpeditionFailedText; LevelAPI.OnBuildDone += SetupGroups; } } internal void AddPlayerToGroup(int playerSlotIndex, int groupIndex) { if (TryGetGroup(groupIndex, out TOAForceFailPlayerGroup group)) { group.SetPlayerInGroup(playerSlotIndex, inGroup: true); } } internal void ResetSynced() { foreach (TOAForceFailPlayerGroup playerGroup in _playerGroups) { playerGroup.ResetSynced(); } } internal void ResetUnsynced() { foreach (TOAForceFailPlayerGroup playerGroup in _playerGroups) { playerGroup.ResetUnsynced(); } } internal void ResetGroupSynced(int groupIndex) { if (TryGetGroup(groupIndex, out TOAForceFailPlayerGroup group)) { group.ResetSynced(); } } internal void ToggleCheck(bool enabled) { foreach (TOAForceFailPlayerGroup playerGroup in _playerGroups) { playerGroup.Toggle(enabled); } } internal bool ToggleCheckOnGroup(int groupIndex, bool enabled) { if (!TryGetGroup(groupIndex, out TOAForceFailPlayerGroup group)) { return false; } group.Toggle(enabled); return true; } internal bool IsCheckEnabled() { EnsureGroups(); foreach (TOAForceFailPlayerGroup playerGroup in _playerGroups) { if (playerGroup.Enabled && playerGroup.NumPlayersInGroup() > 0) { return true; } } return false; } internal bool CheckLevelForceFailed() { EnsureGroups(); foreach (TOAForceFailPlayerGroup playerGroup in _playerGroups) { if (!playerGroup.Enabled) { continue; } bool flag = false; int num = 0; Enumerator enumerator2 = PlayerManager.PlayerAgentsInLevel.GetEnumerator(); while (enumerator2.MoveNext()) { PlayerAgent current2 = enumerator2.Current; if (playerGroup.PlayerInGroup(current2.PlayerSlotIndex)) { flag = ((Agent)current2).Alive || flag; num++; } } if (flag) { if (num != playerGroup.NumPlayersInGroup()) { return true; } continue; } return true; } return false; } internal void SetExpeditionFailedText(string text) { try { ((TMP_Text)MainMenuGuiLayer.Current.PageExpeditionFail.m_missionFailed_text).SetText(text, true); } catch (Exception ex) { TOARuntime.LogThrottled("TOA FF failed text could not be set: " + ex.Message); } } internal void ResetExpeditionFailedText() { try { ((TMP_Text)MainMenuGuiLayer.Current.PageExpeditionFail.m_missionFailed_text).SetText(Text.Get(962u), true); } catch { } } private void SetupGroups() { EnsureGroups(); } private bool EnsureGroups() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Expected O, but got Unknown if (_playerGroups.Count >= 4) { return true; } bool flag = default(bool); if (!TOAStateReplicatorCompat.CanCreateReplicator("TOA ForceFail", logIfNotReady: false)) { if (!_delayedSetupLogged) { _delayedSetupLogged = true; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(88, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA FF player groups setup delayed until network state is ready. Current group count: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_playerGroups.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); } } return false; } _delayedSetupLogged = false; while (_playerGroups.Count < 4) { TOAForceFailPlayerGroup tOAForceFailPlayerGroup = TOAForceFailPlayerGroup.Instantiate(); if (tOAForceFailPlayerGroup == null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(98, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA FF player group setup incomplete; instantiated "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_playerGroups.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(". It will retry when the group is next needed."); } log.LogWarning(val2); } return false; } _playerGroups.Add(tOAForceFailPlayerGroup); } return true; } private bool TryGetGroup(int groupIndex, out TOAForceFailPlayerGroup? group) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Expected O, but got Unknown EnsureGroups(); bool flag = default(bool); if (groupIndex < 0 || groupIndex >= 4) { group = null; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(48, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA FF group index must be between 0 and "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(3); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; got "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(groupIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } return false; } if (groupIndex >= _playerGroups.Count) { group = null; ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(87, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA FF group "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(groupIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" is not ready yet. Instantiated "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_playerGroups.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("; network state may still be unavailable."); } log.LogWarning(val2); } return false; } group = _playerGroups[groupIndex]; return true; } private TOAForceFailManager() { } } public struct TOAFFReplicationState { public bool enabled; public bool checkP1; public bool checkP2; public bool checkP3; public bool checkP4; } internal sealed class TOAForceFailPlayerGroup { internal const int MaxPlayers = 4; private readonly bool[] _players = new bool[4]; private StateReplicator? _stateReplicator; internal bool Enabled { get; private set; } internal bool PlayerInGroup(int playerSlotIndex) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!IsValidPlayerSlot(playerSlotIndex)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(50, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA FF invalid player slot index "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(playerSlotIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; expected [0, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } log.LogError(val); } return false; } return _players[playerSlotIndex]; } internal int NumPlayersInGroup() { int num = 0; for (int i = 0; i < _players.Length; i++) { if (_players[i]) { num++; } } return num; } internal void Toggle(bool enabled) { Enabled = enabled; Sync(); } internal void SetPlayerInGroup(int playerSlotIndex, bool inGroup) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown if (!IsValidPlayerSlot(playerSlotIndex)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(50, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA FF invalid player slot index "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(playerSlotIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; expected [0, "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } log.LogError(val); } } else { int num = NumPlayersInGroup(); _players[playerSlotIndex] = inGroup; int num2 = NumPlayersInGroup(); if (num == 0 && num2 > 0) { Enabled = true; } else if (num > 0 && num2 == 0) { Enabled = false; } Sync(); } } internal void ResetSynced() { Reset(); Sync(); } internal void ResetUnsynced() { Reset(); _stateReplicator?.SetStateUnsynced(GetSyncState()); } private void Reset() { Enabled = false; for (int i = 0; i < _players.Length; i++) { _players[i] = false; } } private void Sync() { if (!SNet.IsMaster) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TOA FF state sync blocked on client; state changes must be executed by host."); } } else { _stateReplicator?.SetState(GetSyncState()); } } private void OnStateChanged(TOAFFReplicationState oldState, TOAFFReplicationState newState, bool isRecall) { if (isRecall) { Enabled = newState.enabled; _players[0] = newState.checkP1; _players[1] = newState.checkP2; _players[2] = newState.checkP3; _players[3] = newState.checkP4; } } private TOAFFReplicationState GetSyncState() { return new TOAFFReplicationState { enabled = Enabled, checkP1 = _players[0], checkP2 = _players[1], checkP3 = _players[2], checkP4 = _players[3] }; } internal static TOAForceFailPlayerGroup? Instantiate() { if (!TOAStateReplicatorCompat.CanCreateReplicator("TOA ForceFail", logIfNotReady: false)) { return null; } uint num = EOSNetworking.AllotForeverReplicatorID(); if (num == 0) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogError((object)"TOA FF could not allocate a network replicator id."); } return null; } TOAForceFailPlayerGroup tOAForceFailPlayerGroup = new TOAForceFailPlayerGroup(); tOAForceFailPlayerGroup._stateReplicator = TOAStateReplicatorCompat.Create(num, default(TOAFFReplicationState), (LifeTimeType)0, "TOA ForceFail"); if (tOAForceFailPlayerGroup._stateReplicator == null) { return null; } tOAForceFailPlayerGroup._stateReplicator.OnStateChanged += tOAForceFailPlayerGroup.OnStateChanged; tOAForceFailPlayerGroup.ResetUnsynced(); return tOAForceFailPlayerGroup; } private static bool IsValidPlayerSlot(int playerSlotIndex) { if (playerSlotIndex >= 0) { return playerSlotIndex < 4; } return false; } private TOAForceFailPlayerGroup() { } } internal struct TOALaserRoomSyncState { public byte Enabled; } internal enum LaserMovementAnchor { Start, End } internal sealed class TOALaserRoomComponent : MonoBehaviour { private const string ShaderName = "Unlit/Color"; private GameObject? _visual; private CapsuleCollider? _trigger; private Light? _light; private readonly List _lines = new List(); private readonly List _materials = new List(); private Vector3 _basePosition; private readonly List _movingPositions = new List(); private bool _isMovable; private int _moveSegmentIndex; private float _moveSegmentLerp; private float _movementSpeed; private bool _enabled; private Vector3 _centerOffsetFromStart; private LaserMovementAnchor _movementAnchor; private StateReplicator? _stateReplicator; internal TOALaserRoomDefinition? Definition; internal TOALaserRoomSensorDefinition? Sensor; internal void Setup() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: 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_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_02d5: Unknown result type (might be due to invalid IL or missing references) //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) TOALaserRoomDefinition definition = Definition; if (definition == null) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogError((object)"LaserRoom Setup failed: definition is null."); } return; } TOALaserRoomSensorDefinition sensor = Sensor; Vector3 startPosition = GetStartPosition(definition, sensor); Vector3 endPosition = GetEndPosition(definition, sensor); Vector3 val = endPosition - startPosition; float magnitude = ((Vector3)(ref val)).magnitude; float num = Mathf.Max(0.01f, definition.Radius); bool flag = default(bool); ManualLogSource log2; if (magnitude < 0.1f) { log2 = TOARuntime.Log; if (log2 != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(63, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LaserRoom Count="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(definition.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" endpoint distance is too short. Laser skipped."); } log2.LogWarning(val2); } return; } Vector3 val3 = (startPosition + endPosition) * 0.5f; Quaternion rotation = Quaternion.LookRotation(((Vector3)(ref val)).normalized, Vector3.up); _centerOffsetFromStart = val3 - startPosition; ((Component)this).transform.position = val3; ((Component)this).transform.rotation = rotation; _basePosition = val3; SetupMovement(); _visual = new GameObject("Visual"); _visual.transform.SetParent(((Component)this).transform, false); Color color = ToColor(definition.Color); BuildLaserVisual(magnitude, num, color, definition.VisualLayers, definition.CoreWidthScale, definition.GlowWidthScale); _trigger = ((Component)this).gameObject.AddComponent(); ((Collider)_trigger).isTrigger = true; _trigger.direction = 2; _trigger.radius = num; _trigger.height = magnitude; _trigger.center = Vector3.zero; Rigidbody obj = ((Component)this).gameObject.AddComponent(); obj.isKinematic = true; obj.useGravity = false; if (definition.LightIntensity > 0f && definition.LightRange > 0f) { _light = _visual.AddComponent(); _light.type = (LightType)2; _light.color = color; _light.intensity = definition.LightIntensity; _light.range = definition.LightRange; } SetupNetworkState(definition.StartEnabled); ApplyEnabled(definition.StartEnabled); Vector3 value = ((Component)this).transform.TransformPoint(new Vector3(0f, 0f, (0f - magnitude) * 0.5f)); Vector3 value2 = ((Component)this).transform.TransformPoint(new Vector3(0f, 0f, magnitude * 0.5f)); log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val4 = new BepInExMessageLogInterpolatedStringHandler(59, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("LaserRoom built Count="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(definition.Count); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" Center="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(FormatVector(val3)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" Start="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(FormatVector(value)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" End="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(FormatVector(value2)); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" Length="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(magnitude, "0.###"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" Radius="); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(num, "0.###"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("."); } log2.LogMessage(val4); } } internal void SetEnabled(bool enabled) { ApplyEnabled(enabled); TOALaserRoomDefinition definition = Definition; if (_stateReplicator != null && definition != null && TOANetworkStateAudit.Current.CanMasterWrite($"LaserRoom:{definition.Count}", $"SetEnabled:{enabled}")) { _stateReplicator.SetState(new TOALaserRoomSyncState { Enabled = (enabled ? ((byte)1) : ((byte)0)) }); } } private void ApplyEnabled(bool enabled) { _enabled = enabled; if ((Object)(object)_visual != (Object)null) { _visual.SetActive(enabled); } if ((Object)(object)_trigger != (Object)null) { ((Collider)_trigger).enabled = enabled; } } private void SetupNetworkState(bool startEnabled) { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown TOALaserRoomDefinition definition = Definition; if (definition == null) { return; } uint num = EOSNetworking.AllotReplicatorID(); bool flag = default(bool); if (num == 0) { TOANetworkStateAudit.Current.ReplicatorFailed($"LaserRoom:{definition.Count}", "Replicator ID depleted"); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(62, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom Count="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(definition.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": Replicator ID depleted, state sync disabled."); } log.LogError(val); } return; } _stateReplicator = TOAStateReplicatorCompat.Create(num, new TOALaserRoomSyncState { Enabled = (startEnabled ? ((byte)1) : ((byte)0)) }, (LifeTimeType)1, $"LaserRoom:{definition.Count}"); if (_stateReplicator == null) { TOANetworkStateAudit.Current.ReplicatorFailed($"LaserRoom:{definition.Count}", "StateReplicator creation failed"); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(71, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom Count="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(definition.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": StateReplicator creation failed, state sync disabled."); } log.LogError(val); } } else { _stateReplicator.OnStateChanged += OnStateChanged; TOANetworkStateAudit.Current.ReplicatorCreated($"LaserRoom:{definition.Count}", num, "Level"); } } private void OnStateChanged(TOALaserRoomSyncState oldState, TOALaserRoomSyncState newState, bool isRecall) { TOALaserRoomDefinition definition = Definition; bool enabled = newState.Enabled != 0; ApplyEnabled(enabled); if (definition != null && isRecall) { TOANetworkStateAudit.Current.StateRecall($"LaserRoom:{definition.Count}", (oldState.Enabled != 0).ToString(), enabled.ToString()); } } private void OnTriggerStay(Collider other) { TOALaserRoomDefinition definition = Definition; if (_enabled && definition != null && definition.DamagePlayers) { PlayerAgent val = ResolvePlayer(other); if ((Object)(object)val != (Object)null && val.Owner.IsLocal && definition.DamagePerSecond > 0f) { ApplySmoothDamage(val, definition.DamagePerSecond * Time.deltaTime); } } } private void Update() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!_enabled || !_isMovable || _movingPositions.Count < 2) { return; } Vector3 val = _movingPositions[_moveSegmentIndex]; Vector3 val2 = _movingPositions[_moveSegmentIndex + 1]; float num = Mathf.Max(0.001f, Vector3.Distance(val, val2)); _moveSegmentLerp += Time.deltaTime * _movementSpeed / num; while (_moveSegmentLerp >= 1f) { _moveSegmentLerp -= 1f; _moveSegmentIndex++; if (_moveSegmentIndex >= _movingPositions.Count - 1) { _moveSegmentIndex = 0; } val = _movingPositions[_moveSegmentIndex]; val2 = _movingPositions[_moveSegmentIndex + 1]; num = Mathf.Max(0.001f, Vector3.Distance(val, val2)); } float num2 = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(_moveSegmentLerp)); ((Component)this).transform.position = Vector3.Lerp(val, val2, num2); } private void BuildLaserVisual(float length, float radius, Color color, int visualLayers, float coreWidthScale, float glowWidthScale) { //IL_0047: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(visualLayers, 1, 2); float num2 = radius * 2f; Color color2 = default(Color); for (int i = 0; i < num; i++) { GameObject val = new GameObject((i == 0) ? "Core" : $"Glow_{i}"); val.transform.SetParent(_visual.transform, false); LineRenderer val2 = val.AddComponent(); val2.useWorldSpace = false; val2.positionCount = 2; val2.SetPosition(0, new Vector3(0f, 0f, (0f - length) * 0.5f)); val2.SetPosition(1, new Vector3(0f, 0f, length * 0.5f)); val2.numCapVertices = 4; val2.numCornerVertices = 0; val2.alignment = (LineAlignment)0; ((Renderer)val2).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)val2).receiveShadows = false; float num3 = ((num == 1) ? 0f : ((float)i / (float)(num - 1))); float num4 = ((i == 0) ? coreWidthScale : Mathf.Lerp(1f, glowWidthScale, num3)); float num5 = ((i == 0) ? 1f : Mathf.Lerp(0.45f, 0.12f, num3)); ((Color)(ref color2))..ctor(color.r, color.g, color.b, color.a * num5); val2.startWidth = Mathf.Max(0.005f, num2 * num4); val2.endWidth = val2.startWidth; ((Renderer)val2).material = CreateMaterial(color2); _lines.Add(val2); } } private static PlayerAgent? ResolvePlayer(Collider collider) { try { PlayerAgent component = ((Component)collider).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } return ((Component)collider).GetComponentInParent(); } catch { return null; } } private void SetupMovement() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) TOALaserRoomDefinition definition = Definition; _movingPositions.Clear(); _moveSegmentIndex = 0; _moveSegmentLerp = 0f; if (definition == null) { _isMovable = false; return; } _movementSpeed = ((definition.MovingSpeedMulti > 0f) ? definition.MovingSpeedMulti : 1f); _isMovable = string.Equals(definition.SensorType, "MOVABLE", StringComparison.OrdinalIgnoreCase); List movingPosition = GetMovingPosition(definition, Sensor); if (!_isMovable || movingPosition.Count < 1) { return; } Vector3 startPosition = GetStartPosition(definition, Sensor); Vector3 endPosition = GetEndPosition(definition, Sensor); Vector3 val = movingPosition[0].ToVector3(); _movementAnchor = GetMovementAnchor(val, startPosition, endPosition); if (!Approximately((_movementAnchor == LaserMovementAnchor.End) ? endPosition : startPosition, val)) { _movingPositions.Add(_basePosition); } for (int i = 0; i < movingPosition.Count; i++) { Vector3 anchorPoint = movingPosition[i].ToVector3(); Vector3 val2 = AnchorPointToCenter(anchorPoint); if (_movingPositions.Count == 0 || !Approximately(_movingPositions[_movingPositions.Count - 1], val2)) { _movingPositions.Add(val2); } } if (_movingPositions.Count > 0 && !Approximately(_basePosition, _movingPositions[_movingPositions.Count - 1])) { _movingPositions.Add(_basePosition); } _isMovable = _movingPositions.Count >= 2; } private static bool Approximately(Vector3 a, Vector3 b) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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) Vector3 val = a - b; return ((Vector3)(ref val)).sqrMagnitude < 0.0001f; } private Vector3 AnchorPointToCenter(Vector3 anchorPoint) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: 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) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (_movementAnchor != LaserMovementAnchor.End) { return anchorPoint + _centerOffsetFromStart; } return anchorPoint - _centerOffsetFromStart; } private static LaserMovementAnchor GetMovementAnchor(Vector3 firstPoint, Vector3 start, Vector3 end) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //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_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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) Vector3 val = firstPoint - start; float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude; val = firstPoint - end; if (!(((Vector3)(ref val)).sqrMagnitude < sqrMagnitude)) { return LaserMovementAnchor.Start; } return LaserMovementAnchor.End; } private static Vector3 GetStartPosition(TOALaserRoomDefinition definition, TOALaserRoomSensorDefinition? sensor) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) return (sensor?.StartPosition ?? definition.StartPosition).ToVector3(); } private static Vector3 GetEndPosition(TOALaserRoomDefinition definition, TOALaserRoomSensorDefinition? sensor) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) return (sensor?.EndPosition ?? definition.EndPosition).ToVector3(); } private static List GetMovingPosition(TOALaserRoomDefinition definition, TOALaserRoomSensorDefinition? sensor) { if (sensor?.MovingPosition != null && sensor.MovingPosition.Count > 0) { return sensor.MovingPosition; } return definition.MovingPosition ?? new List(); } private static void ApplySmoothDamage(PlayerAgent player, float damage) { if (damage <= 0f || (Object)(object)player.Damage == (Object)null) { return; } try { ((Dam_SyncedDamageBase)player.Damage).NoAirDamage(damage); if (((Dam_SyncedDamageBase)player.Damage).Health <= 1.01f) { player.Damage.OnIncomingDamage(damage, 0f, (Agent)null); } } catch (Exception ex) { TOARuntime.LogThrottled("LaserRoom player damage failed: " + ex.GetType().Name + ": " + ex.Message); } } private Material CreateMaterial(Color color) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_002d: Unknown result type (might be due to invalid IL or missing references) Shader val = Shader.Find("Unlit/Color"); Material val2 = (((Object)(object)val != (Object)null) ? new Material(val) : new Material(Shader.Find("Sprites/Default"))); val2.color = color; _materials.Add(val2); return val2; } private static Color ToColor(TOAVec4 color) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Color(color.r, color.g, color.b, color.a); } private static string FormatVector(Vector3 value) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) return $"({value.x:0.###}, {value.y:0.###}, {value.z:0.###})"; } private void OnDestroy() { for (int i = 0; i < _materials.Count; i++) { Material val = _materials[i]; if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } _materials.Clear(); _lines.Clear(); _stateReplicator = null; } static TOALaserRoomComponent() { ClassInjector.RegisterTypeInIl2Cpp(); } } public sealed class TOALaserRoomDefinition { public int Count { get; set; } public bool Enabled { get; set; } = true; public bool StartEnabled { get; set; } = true; public List LaserGroup { get; set; } = new List(); public List SensorGroup { get; set; } = new List(); public TOAVec3 StartPosition { get; set; } = new TOAVec3 { x = 0f, y = 1.5f, z = 0f }; public TOAVec3 EndPosition { get; set; } = new TOAVec3 { x = 10f, y = 1.5f, z = 0f }; public float Radius { get; set; } = 0.06f; public float DamagePerSecond { get; set; } = 8f; public bool DamagePlayers { get; set; } = true; public int VisualLayers { get; set; } = 1; public float CoreWidthScale { get; set; } = 1f; public float GlowWidthScale { get; set; } = 1f; public float LightIntensity { get; set; } public float LightRange { get; set; } = 3f; public TOAVec4 Color { get; set; } = new TOAVec4 { r = 1f, g = 0f, b = 0f, a = 1f }; public string SensorType { get; set; } = "BASIC"; public float MovingSpeedMulti { get; set; } = 1f; public List MovingPosition { get; set; } = new List { new TOAVec3() }; } public sealed class TOALaserRoomSensorDefinition { public TOAVec3 StartPosition { get; set; } = new TOAVec3 { x = 0f, y = 1.5f, z = 0f }; public TOAVec3 EndPosition { get; set; } = new TOAVec3 { x = 10f, y = 1.5f, z = 0f }; public List MovingPosition { get; set; } = new List { new TOAVec3() }; } public sealed class TOAVec4 { public float r { get; set; } public float g { get; set; } public float b { get; set; } public float a { get; set; } = 1f; } internal static class TOALaserRoomEvents { internal static void ToggleLaserRoom(WardenObjectiveEventData eventData) { TOALaserRoomManager.Current.SetLaserEnabledFromEvent(eventData); } } internal sealed class TOALaserRoomManager { internal sealed class LaserRoomBuildItem { internal readonly TOALaserRoomDefinition Definition; internal readonly TOALaserRoomSensorDefinition Sensor; internal readonly int SensorIndex; internal LaserRoomBuildItem(TOALaserRoomDefinition definition, TOALaserRoomSensorDefinition sensor, int sensorIndex) { Definition = definition; Sensor = sensor; SensorIndex = sensorIndex; } } private sealed class CachedLaserRoomDefinitionFile { internal readonly long LastWriteUtcTicks; internal readonly long Length; internal readonly uint MainLevelLayout; internal readonly GenericExpeditionDefinition Definition; internal CachedLaserRoomDefinitionFile(long lastWriteUtcTicks, long length, uint mainLevelLayout, GenericExpeditionDefinition definition) { LastWriteUtcTicks = lastWriteUtcTicks; Length = length; MainLevelLayout = mainLevelLayout; Definition = definition; } } private const string DefinitionFolderName = "LaserRoom"; private const int ImmediateBuildLimit = 8; private const int DeferredBuildPerFrame = 4; private readonly string _definitionPath = TOAConfigPaths.GetFeaturePath("LaserRoom"); private readonly Dictionary> _definitions = new Dictionary>(); private readonly Dictionary> _lasers = new Dictionary>(); private readonly Dictionary _definitionCache = new Dictionary(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _desiredEnabledStates = new Dictionary(); private LiveEditListener? _liveEditListener; private TOALaserRoomBuildDriver? _buildDriver; private int _buildGeneration; public static TOALaserRoomManager Current { get; } = new TOALaserRoomManager(); private TOALaserRoomManager() { LevelAPI.OnBuildDone += Build; LevelAPI.OnLevelCleanup += Clear; } internal void Init() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Expected O, but got Unknown bool flag = default(bool); try { EnsureDefinitionPath(); ReloadDefinitionsFromDisk(); if (_liveEditListener == null) { _liveEditListener = LiveEdit.CreateListener(_definitionPath, "*.json", true); _liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(31, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom definitions path: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_definitionPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(25, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LaserRoom Init failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogError(val2); } } } private void EnsureDefinitionPath() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown Directory.CreateDirectory(_definitionPath); string text = Path.Combine(_definitionPath, "Template.json"); if (File.Exists(text)) { return; } File.WriteAllText(text, CreateTemplateJson()); ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(33, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom template generated: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } private string CreateTemplateJson() { return "{\n \"MainLevelLayout\": \"Layout-T-L1\",\n \"Definitions\": [\n {\n \"Count\": 0,\n \"Enabled\": true,\n \"StartEnabled\": true,\n \"Radius\": 0.06,\n \"DamagePerSecond\": 8.0,\n \"DamagePlayers\": true,\n \"VisualLayers\": 1,\n \"CoreWidthScale\": 1.0,\n \"GlowWidthScale\": 1.0,\n \"LightIntensity\": 0.0,\n \"LightRange\": 3.0,\n \"Color\": { \"r\": 1.0, \"g\": 0.0, \"b\": 0.0, \"a\": 1.0 },\n \"SensorType\": \"BASIC\",\n \"MovingSpeedMulti\": 1.0,\n \"LaserGroup\": [\n {\n \"StartPosition\": { \"x\": 100.0, \"y\": 1.5, \"z\": -50.0 },\n \"EndPosition\": { \"x\": 112.0, \"y\": 1.5, \"z\": -50.0 },\n \"MovingPosition\": [\n { \"x\": 100.0, \"y\": 1.5, \"z\": -50.0 }\n ]\n }\n ]\n }\n ]\n}\n"; } private void FileChanged(LiveEditEventArgs e) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(36, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom LiveEdit file changed: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(e.FullPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { if (TryLoadDefinitionContent(content, e.FullPath, out uint mainLevelLayout, out GenericExpeditionDefinition conf) && conf != null) { TryRefreshDefinitionCache(e.FullPath, mainLevelLayout, conf); AddDefinitions(mainLevelLayout, conf, e.FullPath); } }); } private void ReloadDefinitionsFromDisk() { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Expected O, but got Unknown //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Expected O, but got Unknown Dictionary> dictionary = new Dictionary>(); int num = 0; int num2 = 0; HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); bool flag = default(bool); ManualLogSource log; foreach (string item in Directory.EnumerateFiles(_definitionPath, "*.json", SearchOption.TopDirectoryOnly)) { try { hashSet.Add(item); if (!TryLoadDefinitionFile(item, out uint mainLevelLayout, out GenericExpeditionDefinition conf) || conf == null) { num2++; continue; } AddDefinitions(dictionary, mainLevelLayout, conf, item); num++; } catch (Exception ex) { num2++; _definitionCache.Remove(item); log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom config load failed for '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } } } PruneDefinitionCache(hashSet); _definitions.Clear(); foreach (KeyValuePair> item2 in dictionary) { _definitions[item2.Key] = item2.Value; } string text = ((dictionary.Count == 0) ? "" : string.Join(",", dictionary.Keys.OrderBy((uint id) => id))); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(80, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LaserRoom config reload complete. FilesLoaded="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", FilesFailed="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", MainLevelLayouts="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } private bool TryLoadDefinitionFile(string file, out uint mainLevelLayout, out GenericExpeditionDefinition? conf) { mainLevelLayout = 0u; conf = null; FileInfo fileInfo = new FileInfo(file); if (_definitionCache.TryGetValue(file, out CachedLaserRoomDefinitionFile value) && value.LastWriteUtcTicks == fileInfo.LastWriteTimeUtc.Ticks && value.Length == fileInfo.Length) { mainLevelLayout = value.MainLevelLayout; conf = value.Definition; return conf != null; } string content = File.ReadAllText(file); if (!TryLoadDefinitionContent(content, file, out mainLevelLayout, out conf) || conf == null) { _definitionCache.Remove(file); return false; } _definitionCache[file] = new CachedLaserRoomDefinitionFile(fileInfo.LastWriteTimeUtc.Ticks, fileInfo.Length, mainLevelLayout, conf); return true; } private bool TryLoadDefinitionContent(string content, string file, out uint mainLevelLayout, out GenericExpeditionDefinition? conf) { //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Expected O, but got Unknown //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown mainLevelLayout = 0u; conf = null; bool flag2 = default(bool); try { using JsonDocument jsonDocument = JsonDocument.Parse(content, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }); ManualLogSource log; if (!TryGetPropertyCaseInsensitive(jsonDocument.RootElement, "MainLevelLayout", out var value)) { log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(47, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is missing MainLevelLayout."); } log.LogError(val); } return false; } if (!TOATimedTerminalSequenceManager.TryResolveMainLevelLayoutForExternalConfig(value, out mainLevelLayout, out string resolvedBy)) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(60, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' MainLevelLayout could not be resolved: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } return false; } string text = RewriteMainLevelLayout(jsonDocument.RootElement, mainLevelLayout); conf = EOSJson.Deserialize>(text); if (conf == null) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(41, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' deserialized to null."); } log.LogError(val); } return false; } conf.MainLevelLayout = mainLevelLayout; log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(52, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LaserRoom config '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' MainLevelLayout resolved as "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(mainLevelLayout); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(resolvedBy); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } log.LogMessage(val2); } return true; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(36, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' parse failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } return false; } } private static bool TryGetPropertyCaseInsensitive(JsonElement element, string name, out JsonElement value) { foreach (JsonProperty item in element.EnumerateObject()) { if (string.Equals(item.Name, name, StringComparison.OrdinalIgnoreCase)) { value = item.Value; return true; } } value = default(JsonElement); return false; } private static string RewriteMainLevelLayout(JsonElement root, uint mainLevelLayout) { using MemoryStream memoryStream = new MemoryStream(); using (Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter((Stream)memoryStream, new JsonWriterOptions { Indented = false })) { utf8JsonWriter.WriteStartObject(); foreach (JsonProperty item in root.EnumerateObject()) { if (string.Equals(item.Name, "MainLevelLayout", StringComparison.OrdinalIgnoreCase)) { utf8JsonWriter.WriteNumber("MainLevelLayout", mainLevelLayout); } else { item.WriteTo(utf8JsonWriter); } } utf8JsonWriter.WriteEndObject(); } return Encoding.UTF8.GetString(memoryStream.ToArray()); } private void AddDefinitions(uint mainLevelLayout, GenericExpeditionDefinition conf, string file) { AddDefinitions(_definitions, mainLevelLayout, conf, file); } private static void AddDefinitions(Dictionary> target, uint mainLevelLayout, GenericExpeditionDefinition conf, string file) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown conf.MainLevelLayout = mainLevelLayout; if (target.ContainsKey(mainLevelLayout)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(63, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom config reload replaced MainLevelLayout "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(mainLevelLayout); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" from file '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } target[mainLevelLayout] = conf; } private void Build() { //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Expected O, but got Unknown //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Expected O, but got Unknown bool flag = default(bool); try { ReloadDefinitionsFromDisk(); if (RundownManager.ActiveExpedition == null) { ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"LaserRoom Build skipped: ActiveExpedition is null."); } return; } uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; ManualLogSource log2; if (!_definitions.TryGetValue(levelLayoutData, out GenericExpeditionDefinition value)) { log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(63, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom Build: no LaserRoom definitions for LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(levelLayoutData); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log2.LogMessage(val); } return; } Clear(); List list = new List(); foreach (TOALaserRoomDefinition definition in value.Definitions) { if (definition.Enabled) { _desiredEnabledStates[definition.Count] = definition.StartEnabled; List sensors = GetSensors(definition); for (int i = 0; i < sensors.Count; i++) { list.Add(new LaserRoomBuildItem(definition, sensors[i], i)); } } } if (list.Count > 8) { StartDeferredBuild(list, levelLayoutData, value.Definitions.Count); return; } int num = 0; for (int j = 0; j < list.Count; j++) { if (BuildLaserSensor(list[j].Definition, list[j].Sensor, list[j].SensorIndex)) { num++; } } log2 = TOARuntime.Log; if (log2 != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(57, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom Build: LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(levelLayoutData); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(value.Definitions.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Lasers="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log2.LogMessage(val); } } catch (Exception ex) { ManualLogSource log2 = TOARuntime.Log; if (log2 != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(26, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LaserRoom Build failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log2.LogError(val2); } } } private int BuildLaser(TOALaserRoomDefinition def) { if (!def.Enabled) { return 0; } List sensors = GetSensors(def); int num = 0; for (int i = 0; i < sensors.Count; i++) { if (BuildLaserSensor(def, sensors[i], i)) { num++; } } return num; } private bool BuildLaserSensor(TOALaserRoomDefinition def, TOALaserRoomSensorDefinition sensor, int sensorIndex) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown GameObject val = new GameObject($"TOA_LaserRoom_{def.Count}_{sensorIndex}"); TOALevelObjectTracker.Current.Track(val, "LaserRoom"); TOALaserRoomComponent tOALaserRoomComponent = val.AddComponent(); tOALaserRoomComponent.Definition = def; tOALaserRoomComponent.Sensor = sensor; tOALaserRoomComponent.Setup(); if (_desiredEnabledStates.TryGetValue(def.Count, out var value) && value != def.StartEnabled) { tOALaserRoomComponent.SetEnabled(value); } if (!_lasers.TryGetValue(def.Count, out List value2)) { value2 = new List(); _lasers[def.Count] = value2; } value2.Add(tOALaserRoomComponent); return true; } private static List GetSensors(TOALaserRoomDefinition def) { if (def.LaserGroup != null && def.LaserGroup.Count > 0) { return def.LaserGroup; } if (def.SensorGroup != null && def.SensorGroup.Count > 0) { return def.SensorGroup; } return new List { new TOALaserRoomSensorDefinition { StartPosition = def.StartPosition, EndPosition = def.EndPosition, MovingPosition = (def.MovingPosition ?? new List()) } }; } internal void SetLaserEnabledFromEvent(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.ToggleLaserRoom, eventData)) { SetLaserEnabled(eventData.Count, eventData.Enabled); } } internal void SetLaserEnabled(int count, bool enabled) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown _desiredEnabledStates[count] = enabled; bool flag = default(bool); ManualLogSource log; if (!_lasers.TryGetValue(count, out List value) || value.Count == 0) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(41, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(enabled ? "enable" : "disable"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" skipped: Count="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" was not found."); } log.LogWarning(val); } return; } int num = 0; foreach (TOALaserRoomComponent item in value) { if (!((Object)(object)item == (Object)null)) { item.SetEnabled(enabled); num++; } } log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(28, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LaserRoom "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(enabled ? "enabled" : "disabled"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" Count="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Changed="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } private void Clear() { _buildGeneration++; if ((Object)(object)_buildDriver != (Object)null) { _buildDriver.Cancel(); } foreach (List value in _lasers.Values) { foreach (TOALaserRoomComponent item in value) { if ((Object)(object)item != (Object)null) { Object.Destroy((Object)(object)((Component)item).gameObject); } } } _lasers.Clear(); _desiredEnabledStates.Clear(); } private void StartDeferredBuild(List buildItems, uint layoutId, int definitionCount) { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown EnsureBuildDriver(); bool flag = default(bool); ManualLogSource log; if ((Object)(object)_buildDriver == (Object)null) { int num = 0; for (int i = 0; i < buildItems.Count; i++) { if (BuildLaserSensor(buildItems[i].Definition, buildItems[i].Sensor, buildItems[i].SensorIndex)) { num++; } } log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(106, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom deferred build driver unavailable; built synchronously. LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(layoutId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(definitionCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Lasers="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogWarning(val); } return; } int buildGeneration = _buildGeneration; _buildDriver.Begin(this, buildGeneration, layoutId, definitionCount, buildItems, 4); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(84, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("LaserRoom Build deferred: LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(layoutId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(definitionCount); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", PendingLasers="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(buildItems.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", PerFrame="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(4); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } private void EnsureBuildDriver() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown if (!((Object)(object)_buildDriver != (Object)null)) { GameObject val = new GameObject("TOA_LaserRoom_BuildDriver"); Object.DontDestroyOnLoad((Object)(object)val); _buildDriver = val.AddComponent(); } } internal bool BuildDeferredItem(int generation, LaserRoomBuildItem item) { if (generation == _buildGeneration) { return BuildLaserSensor(item.Definition, item.Sensor, item.SensorIndex); } return false; } internal bool IsBuildGenerationActive(int generation) { return generation == _buildGeneration; } private void TryRefreshDefinitionCache(string file, uint mainLevelLayout, GenericExpeditionDefinition conf) { try { FileInfo fileInfo = new FileInfo(file); _definitionCache[file] = new CachedLaserRoomDefinitionFile(fileInfo.LastWriteTimeUtc.Ticks, fileInfo.Length, mainLevelLayout, conf); } catch { _definitionCache.Remove(file); } } private void PruneDefinitionCache(HashSet seenFiles) { List list = _definitionCache.Keys.Where((string file) => !seenFiles.Contains(file)).ToList(); for (int num = 0; num < list.Count; num++) { _definitionCache.Remove(list[num]); } } } internal sealed class TOALaserRoomBuildDriver : MonoBehaviour { private TOALaserRoomManager? _manager; private List? _items; private int _generation; private int _index; private int _built; private int _perFrame = 4; private uint _layoutId; private int _definitionCount; internal void Begin(TOALaserRoomManager manager, int generation, uint layoutId, int definitionCount, List items, int perFrame) { _manager = manager; _generation = generation; _layoutId = layoutId; _definitionCount = definitionCount; _items = items; _index = 0; _built = 0; _perFrame = Mathf.Max(1, perFrame); ((Behaviour)this).enabled = true; } internal void Cancel() { _items = null; _manager = null; ((Behaviour)this).enabled = false; } private void Update() { //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown if (_manager == null || _items == null) { ((Behaviour)this).enabled = false; return; } if (!_manager.IsBuildGenerationActive(_generation)) { Cancel(); return; } int perFrame = _perFrame; while (perFrame-- > 0 && _items != null && _index < _items.Count) { if (_manager.BuildDeferredItem(_generation, _items[_index])) { _built++; } _index++; } if (_items == null || _index < _items.Count) { return; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(75, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LaserRoom deferred build complete: LevelLayoutData="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_layoutId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Definitions="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_definitionCount); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Lasers="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_built); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } Cancel(); } static TOALaserRoomBuildDriver() { ClassInjector.RegisterTypeInIl2Cpp(); } } internal sealed class TOALevelObjectTracker { private readonly Dictionary _trackedObjects = new Dictionary(); public static TOALevelObjectTracker Current { get; } = new TOALevelObjectTracker(); internal void Track(GameObject go, string owner) { if (!((Object)(object)go == (Object)null)) { int instanceID = ((Object)go).GetInstanceID(); if (!_trackedObjects.ContainsKey(instanceID)) { _trackedObjects[instanceID] = new TOATrackedObject(go, owner); } } } internal void Forget(GameObject go) { if (!((Object)(object)go == (Object)null)) { _trackedObjects.Remove(((Object)go).GetInstanceID()); } } internal void Clear() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Expected O, but got Unknown int num = 0; int num2 = 0; bool flag = default(bool); foreach (TOATrackedObject value in _trackedObjects.Values) { GameObject gameObject = value.GameObject; if ((Object)(object)gameObject == (Object)null) { num2++; continue; } num++; try { Object.Destroy((Object)(object)gameObject); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(30, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA cleanup failed for '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(value.Owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("/"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((Object)gameObject).name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } if (num > 0 || num2 > 0) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(61, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA level object cleanup: Destroyed="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", AlreadyGone="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", Tracked="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_trackedObjects.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } _trackedObjects.Clear(); } private TOALevelObjectTracker() { } } internal readonly struct TOATrackedObject { internal readonly GameObject GameObject; internal readonly string Owner; internal TOATrackedObject(GameObject gameObject, string owner) { GameObject = gameObject; Owner = owner; } } internal sealed class TOANetworkStateAudit { public static TOANetworkStateAudit Current { get; } = new TOANetworkStateAudit(); internal bool CanMasterWrite(string owner, string operation) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown if (SNet.IsMaster) { return true; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(86, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network audit blocked client state write: Owner="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Operation="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(operation); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", IsMaster="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsMaster); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", InLobby="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsInLobby); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogWarning(val); } return false; } internal void ReplicatorCreated(string owner, uint id, string lifetime) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(82, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network audit replicator created: Owner="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ID="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(id); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Lifetime="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(lifetime); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", IsMaster="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsMaster); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", InLobby="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsInLobby); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } } internal void ReplicatorFailed(string owner, string reason) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(74, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network audit replicator failed: Owner="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Reason="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(reason); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", IsMaster="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsMaster); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", InLobby="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsInLobby); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } } internal void StateRecall(string owner, string fromState, string toState) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(56, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network audit state recall: Owner="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(fromState); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" => "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(toState); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", IsMaster="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsMaster); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } } internal void OnLevelBoundary(string stage) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Expected O, but got Unknown ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(56, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA network audit level boundary: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(stage); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", IsMaster="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsMaster); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", InLobby="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsInLobby); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } } private TOANetworkStateAudit() { } } internal static class TOAOptimizationManager { private static bool _initialized; internal static void Init() { if (!_initialized) { _initialized = true; LevelAPI.OnBuildStart += OnBuildStart; LevelAPI.OnLevelCleanup += OnLevelCleanup; ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogMessage((object)"TOA optimization manager initialized."); } } } private static void OnBuildStart() { SafeInvoke("BuildStart", TOALevelObjectTracker.Current.Clear); SafeInvoke("BuildStart", TOAVisualObjectPool.Current.Clear); TOANetworkStateAudit.Current.OnLevelBoundary("BuildStart"); } private static void OnLevelCleanup() { SafeInvoke("LevelCleanup", TOALevelObjectTracker.Current.Clear); SafeInvoke("LevelCleanup", TOAVisualObjectPool.Current.Clear); TOANetworkStateAudit.Current.OnLevelBoundary("LevelCleanup"); } private static void SafeInvoke(string stage, Action action) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown try { action(); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA optimization "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(stage); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } } } } internal sealed class TOAVisualObjectPool { private readonly Dictionary> _pool = new Dictionary>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary _borrowedKeys = new Dictionary(); public static TOAVisualObjectPool Current { get; } = new TOAVisualObjectPool(); internal GameObject Rent(string key, GameObject template, string owner) { GameObject val = null; if (_pool.TryGetValue(key, out Stack value)) { while (value.Count > 0 && (Object)(object)val == (Object)null) { val = value.Pop(); } } if ((Object)(object)val == (Object)null) { val = Object.Instantiate(template); ((Object)val).name = key; } val.SetActive(true); _borrowedKeys[((Object)val).GetInstanceID()] = key; TOALevelObjectTracker.Current.Track(val, owner); return val; } internal void Return(GameObject go) { if ((Object)(object)go == (Object)null) { return; } int instanceID = ((Object)go).GetInstanceID(); if (!_borrowedKeys.TryGetValue(instanceID, out string value)) { Object.Destroy((Object)(object)go); return; } _borrowedKeys.Remove(instanceID); TOALevelObjectTracker.Current.Forget(go); go.SetActive(false); go.transform.SetParent((Transform)null, false); if (!_pool.TryGetValue(value, out Stack value2)) { value2 = new Stack(); _pool[value] = value2; } value2.Push(go); } internal void Clear() { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown int num = 0; foreach (Stack value in _pool.Values) { while (value.Count > 0) { GameObject val = value.Pop(); if ((Object)(object)val != (Object)null) { num++; Object.Destroy((Object)(object)val); } } } _pool.Clear(); _borrowedKeys.Clear(); if (num <= 0) { return; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA visual pool cleanup: DestroyedPooled="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } private TOAVisualObjectPool() { } } [HarmonyPatch(typeof(CM_PlayerLobbyBar), "HideLoadoutUI")] internal static class CM_PlayerLobbyBar_HideLoadoutUI_Patch { private static void Prefix(ref bool hide) { if (TOARuntime.ShouldAllowNativeEscLoadout()) { hide = false; } } } [HarmonyPatch(typeof(CM_InventorySlotItem), "LoadData")] internal static class CM_InventorySlotItem_LoadData_Patch { private static void Prefix(CM_InventorySlotItem __instance, ref bool clickable) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) if (clickable) { return; } try { if (TOARuntime.CanEditLobbyBar(((CM_LobbyScrollItem)__instance).m_parentBar)) { clickable = true; } } catch (Exception ex) { TOARuntime.LogThrottled("CM_InventorySlotItem.LoadData patch failed: " + ex.Message); } } } [HarmonyPatch] internal static class PrioritizeEnemyTargeting { private static bool s_patch = true; [HarmonyPostfix] [HarmonyPatch(typeof(EnemyCourseNavigation), "UpdateTracking")] private static void UpdateTracking(EnemyCourseNavigation __instance) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 if (!s_patch) { return; } int count = PlayerManager.PlayerAgentsInLevel.Count; if (!SNet.IsMaster || count <= 1) { return; } EnemyAgent owner = __instance.m_owner; if ((int)((StateMachine)(object)owner.Locomotion).m_currentState.m_stateEnum == 14 || ((Il2CppObjectBase)__instance.m_targetRef.m_agent.CourseNode).Pointer == ((Il2CppObjectBase)((Agent)owner).CourseNode).Pointer) { return; } PlayerAgent val = null; int num = Random.RandomRangeInt(0, count); for (int i = 0; i < count; i++) { PlayerAgent val2 = PlayerManager.PlayerAgentsInLevel[num]; if (((Agent)val2).Alive && ((Il2CppObjectBase)((Agent)val2).CourseNode).Pointer == ((Il2CppObjectBase)((Agent)owner).CourseNode).Pointer) { val = val2; break; } num = (num + 1) % count; } if (!((Object)(object)val != (Object)null)) { return; } try { s_patch = false; ((AgentAI)owner.AI).SetTarget((Agent)(object)val); } finally { s_patch = true; } } } [HarmonyPatch(typeof(EOSTerminalUtils), "GetUniqueCommandEvents")] internal static class TOAEOSCommandEventsPatch { private static bool Prefix(LG_ComputerTerminal terminal, string command, ref List __result) { try { if (TryGetToaTimedTerminalCommandEvents(terminal, command, out List events)) { __result = events; return false; } } catch (Exception ex) { TOARuntime.LogThrottled("TOA EOS command event compatibility patch failed for '" + command + "': " + ex.Message); } return true; } private static bool TryGetToaTimedTerminalCommandEvents(LG_ComputerTerminal terminal, string command, out List events) { //IL_0047: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_00a8: Invalid comparison between Unknown and I4 events = new List(); if ((Object)(object)terminal == (Object)null || string.IsNullOrWhiteSpace(command)) { return false; } string text = command.Trim().ToLowerInvariant(); if (!terminal.m_command.m_commandsPerString.ContainsKey(text)) { return false; } TERM_Command val = terminal.m_command.m_commandsPerString[text]; if (!terminal.m_command.m_commandEventMap.ContainsKey(val)) { return false; } List val2 = terminal.m_command.m_commandEventMap[val]; if (val2 == null || val2.Count <= 0) { return false; } bool flag = false; for (int i = 0; i < val2.Count; i++) { WardenObjectiveEventData val3 = val2[i]; events.Add(val3); if ((int)val3.Type == 2009) { flag = true; } } if (flag) { return true; } events.Clear(); return false; } } [HarmonyPatch(typeof(WardenObjectiveManager), "CheckExpeditionFailed")] internal static class WardenObjectiveManager_CheckExpeditionFailed_TOAForceFailPatch { private static bool Prefix(ref bool __result) { try { if (!TOAForceFailManager.Current.IsCheckEnabled()) { return true; } if (TOAForceFailManager.Current.CheckLevelForceFailed()) { __result = true; ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogMessage((object)"TOA FF condition satisfied; expedition forced failed."); } return false; } } catch (Exception ex) { TOARuntime.LogThrottled("TOA FF CheckExpeditionFailed patch failed: " + ex.Message); } return true; } } internal static class PluginInfo { public const string GUID = "toa.heavyindustries"; public const string NAME = "TOA_Heavy_Industries"; public const string VERSION = "2.2.0"; } [BepInPlugin("toa.heavyindustries", "TOA_Heavy_Industries", "2.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BasePlugin { private Harmony? _harmony; private TOAButtonYeeter? _buttonYeeter; public override void Load() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown TOARuntime.Log = ((BasePlugin)this).Log; _harmony = new Harmony("toa.heavyindustries"); SafePatchAll(_harmony, ((BasePlugin)this).Log); _buttonYeeter = ((BasePlugin)this).AddComponent(); _buttonYeeter.Log = ((BasePlugin)this).Log; AssetAPI.OnStartupAssetsLoaded += _buttonYeeter.Initialize; TOAType2003SidecarStore.ScanDiskForDefinitions(); TOAType2004SidecarStore.ScanDiskForDefinitions(); TOAType2005SidecarStore.ScanDiskForDefinitions(); TOAJsonConfig.LoadOrCreate(((BasePlugin)this).Log, force: true); TOAJsonConfig.ApplyInstantReloadMode(((BasePlugin)this).Log); TOANetworkEventProxy.Init(); TOACustomEventRegistry.RegisterDefaults(); TOAOptimizationManager.Init(); TOAForceFailManager.Current.Init(); TOADeathEventGroupManager.Current.Init(); TOAAllDownEventGroupManager.Current.Init(); TOATimedTerminalSequenceManager.Current.Init(); TOAEventScanManager.Current.Init(); TOALaserRoomManager.Current.Init(); BigPickupFogBeaconSettingManager.Current.Init(); BigPickupCustomizationManager.Current.Init(); LevelSpawnedFogBeaconSettingManager.Current.Init(); EventAPI.OnExpeditionStarted += TOARuntime.OnExpeditionStarted; } private static void SafePatchAll(Harmony harmony, ManualLogSource log) { //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown Type[] types = Assembly.GetExecutingAssembly().GetTypes(); bool flag = default(bool); foreach (Type type in types) { if (!type.GetCustomAttributes(typeof(HarmonyPatch), inherit: true).Any()) { continue; } try { harmony.CreateClassProcessor(type).Patch(); } catch (Exception ex) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(36, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Optional Harmony patch skipped: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(type.FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } } internal static class TOAAssets { private const string EventScanBundleName = "eventscan-compressed"; private const string EventScanInternalPath = "Assets/EventObjects/EventScan.prefab"; private static readonly string[] EventScanInternalPathCandidates = new string[4] { "Assets/EventObjects/EventScan.prefab", "assets/eventobjects/eventscan.prefab", "Assets/eventobjects/eventscan.prefab", "assets/EventObjects/EventScan.prefab" }; private static bool _initialized; private static AssetBundle? _eventScanBundle; internal static GameObject? EventScan { get; private set; } internal static void Init() { //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown if (_initialized && (Object)(object)EventScan != (Object)null) { return; } _initialized = true; EventScan = LoadEventScanFromAssetAPI(); if ((Object)(object)EventScan == (Object)null) { EventScan = LoadEventScanBundleFromDisk(); } if ((Object)(object)EventScan == (Object)null) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(124, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA EventScan asset was not found in specified bundle '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted("eventscan-compressed"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'. EventScan definitions cannot spawn until this prefab is available."); } log.LogWarning(val); } } else { ManualLogSource? log2 = TOARuntime.Log; if (log2 != null) { log2.LogMessage((object)"TOA EventScan asset loaded."); } } } internal static bool EnsureEventScanLoaded() { Init(); return (Object)(object)EventScan != (Object)null; } private static GameObject? LoadEventScanFromAssetAPI() { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown string[] eventScanInternalPathCandidates = EventScanInternalPathCandidates; bool flag = default(bool); foreach (string text in eventScanInternalPathCandidates) { try { GameObject loadedAsset = AssetAPI.GetLoadedAsset(text); if (!((Object)(object)loadedAsset != (Object)null)) { continue; } ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(86, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TOA EventScan asset found through GTFO-API AssetAPI path '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' (Legacy-compatible path). "); } log.LogMessage(val); } return loadedAsset; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(52, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA EventScan AssetAPI lookup failed for path '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } } return null; } private static GameObject? LoadEventScanBundleFromDisk() { //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Expected O, but got Unknown //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Expected O, but got Unknown if ((Object)(object)_eventScanBundle != (Object)null) { GameObject val = TryLoadEventScanFromBundle(_eventScanBundle, "cached disk bundle"); if ((Object)(object)val != (Object)null) { return val; } } List list = new List(); bool flag = default(bool); ManualLogSource log; foreach (string eventScanBundlePath in GetEventScanBundlePaths()) { try { list.Add(eventScanBundlePath); if (!File.Exists(eventScanBundlePath)) { continue; } AssetBundle val2 = AssetBundle.LoadFromFile(eventScanBundlePath); if ((Object)(object)val2 == (Object)null) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(49, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA EventScan AssetBundle load returned null: '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(eventScanBundlePath); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("'."); } log.LogWarning(val3); } } else { GameObject val4 = TryLoadEventScanFromBundle(val2, "disk bundle '" + eventScanBundlePath + "'"); if ((Object)(object)val4 != (Object)null) { _eventScanBundle = val2; return val4; } val2.Unload(false); } } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(58, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA EventScan specified AssetBundle load failed for '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(eventScanBundlePath); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(ex.Message); } log.LogWarning(val3); } } } log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(134, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TOA EventScan AssetBundle was not found or did not contain any known EventScan prefab path. Primary='"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted("Assets/EventObjects/EventScan.prefab"); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("', Candidates=["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(string.Join(", ", EventScanInternalPathCandidates)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("], CheckedPaths=["); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(string.Join("; ", list)); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("]"); } log.LogWarning(val3); } return null; } private static IEnumerable GetEventScanBundlePaths() { HashSet paths = new HashSet(StringComparer.OrdinalIgnoreCase); Add(Path.Combine(Paths.PluginPath, "TOA Heavy Industries", "Assets", "AssetBundles", "eventscan-compressed")); Add(Path.Combine(Paths.PluginPath, "TOA_Heavy_Industries", "Assets", "AssetBundles", "eventscan-compressed")); try { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (!string.IsNullOrWhiteSpace(directoryName)) { Add(Path.Combine(directoryName, "Assets", "AssetBundles", "eventscan-compressed")); Add(Path.Combine(directoryName, "..", "Assets", "AssetBundles", "eventscan-compressed")); } } catch { } foreach (string item in paths) { yield return item; } void Add(string path) { if (!string.IsNullOrWhiteSpace(path)) { paths.Add(Path.GetFullPath(path)); } } } private static GameObject? TryLoadEventScanFromBundle(AssetBundle bundle, string source) { //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown bool flag = default(bool); try { string[] eventScanInternalPathCandidates = EventScanInternalPathCandidates; foreach (string text in eventScanInternalPathCandidates) { Object obj = bundle.LoadAsset(text); GameObject val = ((obj != null) ? ((Il2CppObjectBase)obj).TryCast() : null); if (!((Object)(object)val != (Object)null)) { continue; } ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(83, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA EventScan asset found in specified "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(source); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" path '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' (Legacy-compatible EventScan path)."); } log.LogMessage(val2); } return val; } try { string[] array = Il2CppArrayBase.op_Implicit((Il2CppArrayBase)(object)bundle.GetAllAssetNames()); string text2 = array.FirstOrDefault((string name) => string.Equals(name, "Assets/EventObjects/EventScan.prefab", StringComparison.OrdinalIgnoreCase)) ?? array.FirstOrDefault((string name) => name.EndsWith("eventscan.prefab", StringComparison.OrdinalIgnoreCase)); ManualLogSource log; if (!string.IsNullOrWhiteSpace(text2)) { Object obj2 = bundle.LoadAsset(text2); GameObject val3 = ((obj2 != null) ? ((Il2CppObjectBase)obj2).TryCast() : null); if ((Object)(object)val3 != (Object)null) { log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(63, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TOA EventScan asset found by AssetBundle name scan in "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(source); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" path '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } log.LogMessage(val2); } return val3; } } log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(76, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("TOA EventScan AssetBundle "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(source); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" did not expose an EventScan prefab. AssetNames=["); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(string.Join(", ", array.Take(32))); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted((array.Length > 32) ? ", ..." : string.Empty); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("]"); } log.LogWarning(val4); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(50, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("TOA EventScan AssetBundle name scan failed in "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(source); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex.Message); } log.LogWarning(val4); } } } catch (Exception ex2) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val4 = new BepInExWarningLogInterpolatedStringHandler(60, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("TOA EventScan AssetBundle prefab load failed in "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(source); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(" path '"); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted("Assets/EventObjects/EventScan.prefab"); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex2.GetType().Name); ((BepInExLogInterpolatedStringHandler)val4).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val4).AppendFormatted(ex2.Message); } log.LogWarning(val4); } } return null; } } internal sealed class TOAButtonYeeter : MonoBehaviour { internal ManualLogSource? Log; public void Initialize() { ManualLogSource? log = Log; if (log != null) { log.LogInfo((object)"TOA ButtonYeeter is loaded"); } CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(Yeeter()), (Action)null); } private IEnumerator Yeeter() { ManualLogSource? log = Log; if (log != null) { log.LogInfo((object)"TOA ButtonYeeter coroutine running"); } while ((Object)Object.FindObjectOfType() == (Object)null) { yield return (object)new WaitForSeconds(0.5f); } CM_PageRundown_New menu = Object.FindObjectOfType(); while (true) { if ((int)FocusStateManager.CurrentState == 2) { menu.GifSprite(false); menu.m_isGifEnabled = false; ((Component)menu.m_gifButton).transform.position = new Vector3(9000f, 9000f, 0f); ((Component)menu.m_tutorialButton).transform.position = new Vector3(9000f, 9000f, 0f); ((Component)menu.m_creditsButton).transform.position = new Vector3(9000f, 9000f, 0f); ((Component)menu.m_matchmakeAllButton).transform.position = new Vector3(9000f, 9000f, 0f); ((Component)menu.m_discordButton).transform.position = new Vector3(9000f, 9000f, 0f); ((Component)menu.m_tutorialButton).transform.position = new Vector3(9000f, 9000f, 0f); ((Component)menu.m_aboutTheRundownButton).transform.position = new Vector3(9000f, 9000f, 0f); } yield return (object)new WaitForSeconds(1f); } } } internal static class TOARuntime { internal static ManualLogSource? Log; private static float _lastBlockedLogTime; private static readonly object _policySync = new object(); private static bool _policyCached; private static bool _cachedAllowed; private static TOAConfigDocument? _cachedConfig; private static TOALevelRule? _cachedRule; private static uint _cachedLayoutId; private static string _cachedLayoutName = string.Empty; private static string _cachedMatchedBy = string.Empty; internal static void OnExpeditionStarted() { TOAJsonConfig.LoadOrCreate(Log, force: true); CacheCurrentLevelPolicy(EvaluateCurrentLevelPolicy(out TOAConfigDocument matchedConfig, out uint layoutId, out string layoutName, out string matchedBy, out TOALevelRule matchedRule), matchedConfig, layoutId, layoutName, matchedBy, matchedRule); } private static void CacheCurrentLevelPolicy(bool allowed, TOAConfigDocument? config, uint levelLayoutId, string levelLayoutName, string matchedBy, TOALevelRule? rule) { lock (_policySync) { _policyCached = true; _cachedAllowed = allowed; _cachedConfig = config; _cachedRule = rule; _cachedLayoutId = levelLayoutId; _cachedLayoutName = levelLayoutName; _cachedMatchedBy = matchedBy; } } private static Type? FindLoadedType(string fullName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { Type type = assemblies[i].GetType(fullName, throwOnError: false, ignoreCase: false); if (type != null) { return type; } } return null; } internal static bool ShouldAllowNativeEscLoadout() { TOAConfigDocument matchedConfig; uint layoutId; string layoutName; string matchedBy; TOALevelRule matchedRule; return TryGetCurrentLevelPolicy(out matchedConfig, out layoutId, out layoutName, out matchedBy, out matchedRule); } internal static bool CanEditLobbyBar(CM_PlayerLobbyBar? bar) { if (!TryGetCurrentLevelPolicy(out TOAConfigDocument _, out uint _, out string _, out string _, out TOALevelRule _)) { return false; } try { SNet_Player val = ((bar != null) ? bar.m_player : null); return (Object)(object)val != (Object)null && val.IsLocal; } catch (Exception ex) { LogThrottled("Could not evaluate native ESC loadout permission: " + ex.Message); return false; } } internal static bool TryGetCurrentLevelPolicy(out TOAConfigDocument? matchedConfig, out uint layoutId, out string layoutName, out string matchedBy, out TOALevelRule? matchedRule) { lock (_policySync) { if (_policyCached) { matchedConfig = _cachedConfig; matchedRule = _cachedRule; layoutId = _cachedLayoutId; layoutName = _cachedLayoutName; matchedBy = _cachedMatchedBy; return _cachedAllowed; } } matchedConfig = null; matchedRule = null; layoutId = GetCurrentLevelLayoutId(); layoutName = ((layoutId == 0) ? string.Empty : TryGetLevelLayoutName(layoutId)); matchedBy = string.Empty; return false; } private static bool EvaluateCurrentLevelPolicy(out TOAConfigDocument? matchedConfig, out uint layoutId, out string layoutName, out string matchedBy, out TOALevelRule? matchedRule) { matchedConfig = null; matchedRule = null; layoutId = GetCurrentLevelLayoutId(); layoutName = TryGetLevelLayoutName(layoutId); matchedBy = string.Empty; foreach (TOAConfigDocument config in TOAJsonConfig.Configs) { if (!config.Enabled) { continue; } foreach (TOALevelRule level in config.Levels) { if (layoutId != 0 && level.OfflineIDs.Contains(layoutId)) { matchedConfig = config; matchedRule = level; matchedBy = $"MainLevelLayoutIDs:{layoutId}"; return true; } foreach (string levelLayoutIDString in level.LevelLayoutIDStrings) { if (MatchesCurrentLevelLayoutString(levelLayoutIDString, layoutId, out string reason)) { matchedConfig = config; matchedRule = level; matchedBy = reason; return true; } } } } return false; } internal static uint GetCurrentLevelLayoutId() { try { return RundownManager.ActiveExpedition.LevelLayoutData; } catch { return 0u; } } private static bool MatchesCurrentLevelLayoutString(string token, uint currentLayoutId, out string reason) { reason = string.Empty; if (string.IsNullOrWhiteSpace(token) || currentLayoutId == 0) { return false; } string text = token.Trim(); if (uint.TryParse(text, out var result)) { if (result == currentLayoutId) { reason = $"MainLevelLayoutIDs:{result}"; return true; } return false; } if (TryResolvePartialDataPersistentId(text, out var id) && id == currentLayoutId) { reason = $"MainLevelLayoutIDs persistentID:{text}->{id}"; return true; } if (TryResolveLevelLayoutStringToId(text, out var id2) && id2 == currentLayoutId) { reason = $"MainLevelLayoutIDs blockID:{text}->{id2}"; return true; } return false; } private static bool TryResolvePartialDataPersistentId(string persistentId, out uint id) { id = 0u; if (string.IsNullOrWhiteSpace(persistentId)) { return false; } string text = persistentId.Trim(); if (uint.TryParse(text, out var result)) { id = result; return result != 0; } if (MTFOPartialDataIdResolver.TryResolve(text, out id)) { return id != 0; } if (TryResolvePartialDataPersistentIdViaManager(text, out id)) { return id != 0; } return false; } private static bool TryResolvePartialDataPersistentIdViaManager(string persistentId, out uint id) { id = 0u; try { string[] array = new string[3] { "MTFO.Ext.PartialData.PersistentIDManager", "MTFO.Extension.PartialBlocks.PersistentIDManager", "MTFO.Ext.PartialBlocks.PersistentIDManager" }; for (int i = 0; i < array.Length; i++) { Type type = FindLoadedType(array[i]); if (!(type == null) && (TryInvokePersistentIdMethod(type, "TryGetId", persistentId, out id) || TryInvokePersistentIdMethod(type, "TryGetID", persistentId, out id) || TryInvokePersistentIdMethod(type, "TryGetPersistentID", persistentId, out id) || TryInvokePersistentIdMethod(type, "TryGetPersistentId", persistentId, out id) || TryInvokePersistentIdMethod(type, "GetId", persistentId, out id) || TryInvokePersistentIdMethod(type, "GetID", persistentId, out id))) { return id != 0; } } } catch (Exception ex) { LogThrottled("Could not resolve MTFO PartialData persistentID '" + persistentId + "': " + ex.Message); } return false; } private static bool TryInvokePersistentIdMethod(Type managerType, string methodName, string persistentId, out uint id) { id = 0u; try { MethodInfo method = managerType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[2] { typeof(string), typeof(uint).MakeByRefType() }, null); if (method != null) { object[] array = new object[2] { persistentId, 0u }; object obj = method.Invoke(null, array); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0 && TryConvertToUInt(array[1], out id)) { return id != 0; } } MethodInfo method2 = managerType.GetMethod(methodName, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); if (method2 != null && TryConvertToUInt(method2.Invoke(null, new object[1] { persistentId }), out id)) { return id != 0; } } catch { } return false; } private static bool TryConvertToUInt(object? value, out uint id) { id = 0u; if (!(value is uint num)) { if (!(value is int num2)) { if (!(value is long num3)) { if (!(value is ulong num4)) { if (value is string s && uint.TryParse(s, out var result)) { id = result; return true; } } else { ulong num5 = num4; if (num5 <= uint.MaxValue) { id = (uint)num5; return true; } } } else { long num6 = num3; if (num6 >= 0 && num6 <= uint.MaxValue) { id = (uint)num6; return true; } } } else { int num7 = num2; if (num7 >= 0) { id = (uint)num7; return true; } } return false; } uint num8 = num; id = num8; return true; } private static bool TryResolveLevelLayoutStringToId(string levelLayoutString, out uint id) { id = 0u; try { if (uint.TryParse(levelLayoutString, out var result)) { id = result; return result != 0; } if (GameDataBlockBase.HasBlock(levelLayoutString)) { id = GameDataBlockBase.GetBlockID(levelLayoutString); return id != 0; } } catch (Exception ex) { LogThrottled("Could not resolve LevelLayout string '" + levelLayoutString + "' via LevelLayoutDataBlock: " + ex.Message); } return false; } private static string TryGetLevelLayoutName(uint layoutId) { if (layoutId == 0) { return string.Empty; } try { string blockName = GameDataBlockBase.GetBlockName(layoutId); if (!string.IsNullOrWhiteSpace(blockName)) { return blockName; } } catch { } try { LevelLayoutDataBlock block = GameDataBlockBase.GetBlock(layoutId); if (block != null && !string.IsNullOrWhiteSpace(((GameDataBlockBase)(object)block).name)) { return ((GameDataBlockBase)(object)block).name; } } catch { } return string.Empty; } internal static void LogThrottled(string message) { if (!(Time.realtimeSinceStartup - _lastBlockedLogTime < 1f)) { _lastBlockedLogTime = Time.realtimeSinceStartup; ManualLogSource? log = Log; if (log != null) { log.LogWarning((object)message); } } } } internal static class TOAStateReplicatorCompat { internal static StateReplicator? Create(uint id, T initialState, LifeTimeType lifeTimeType, string owner) where T : struct { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Expected O, but got Unknown //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Expected O, but got Unknown //IL_000e: 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_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0255: Expected O, but got Unknown if (!CanCreateReplicator(owner)) { return null; } LifeTimeType lifeTimeType2 = (LifeTimeType)(((int)lifeTimeType == 0) ? 1 : ((int)lifeTimeType)); Type typeFromHandle; bool flag = default(bool); ManualLogSource log; try { typeFromHandle = typeof(StateReplicator); } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(75, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": StateReplicator generic type could not be constructed for state type "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(typeof(T).FullName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } return null; } foreach (MethodInfo item in from m in typeFromHandle.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) where m.Name == "Create" select m) { if (!TryBuildArguments(item, id, initialState, lifeTimeType2, out object[] args)) { continue; } try { if (item.Invoke(null, args) is StateReplicator result) { return result; } } catch (TargetInvocationException ex2) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(51, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": StateReplicator.Create reflection call failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.InnerException?.GetType().Name ?? ex2.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex2.InnerException?.Message ?? ex2.Message); } log.LogWarning(val2); } } catch (Exception ex3) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(51, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": StateReplicator.Create reflection call failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex3.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex3.Message); } log.LogWarning(val2); } } } log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(123, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": could not create a network-backed StateReplicator. Local unsynced fallback is disabled to prevent divergent client state."); } log.LogError(val); } return null; } internal static bool CanCreateReplicator(string owner, bool logIfNotReady = true) { //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) bool flag = default(bool); try { if (SNet.IsInLobby) { return true; } if (logIfNotReady) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(117, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": StateReplicator creation delayed/skipped because network level state is not ready. IsMaster="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsMaster); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", InLobby="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(SNet.IsInLobby); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", GameState="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(GameStateManager.CurrentStateName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogWarning(val); } } return false; } catch (Exception ex) { if (logIfNotReady) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(95, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": StateReplicator creation delayed/skipped because network level state could not be queried: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } return false; } } private static bool TryBuildArguments(MethodInfo method, uint id, T initialState, LifeTimeType lifeTimeType, out object?[] args) where T : struct { //IL_00ff: Unknown result type (might be due to invalid IL or missing references) ParameterInfo[] parameters = method.GetParameters(); args = new object[parameters.Length]; bool result = false; for (int i = 0; i < parameters.Length; i++) { ParameterInfo parameterInfo = parameters[i]; Type parameterType = parameterInfo.ParameterType; if (parameterType == typeof(uint) || parameterType == typeof(uint)) { args[i] = id; continue; } if ((parameterType == typeof(int) || parameterType == typeof(int)) && (parameterInfo.Name ?? string.Empty).IndexOf("id", StringComparison.OrdinalIgnoreCase) >= 0) { args[i] = (int)id; continue; } if (parameterType == typeof(T) || parameterType.IsAssignableFrom(typeof(T))) { args[i] = initialState; result = true; continue; } if (parameterType == typeof(LifeTimeType)) { args[i] = lifeTimeType; continue; } if (parameterType == typeof(bool)) { args[i] = false; continue; } if (parameterType.IsEnum) { Array values = Enum.GetValues(parameterType); args[i] = ((values.Length > 0) ? values.GetValue(0) : Activator.CreateInstance(parameterType)); continue; } if (parameterInfo.HasDefaultValue) { args[i] = parameterInfo.DefaultValue; continue; } if (!parameterType.IsValueType) { args[i] = null; continue; } return false; } return result; } private static StateReplicator? TryCreateLocalReplicator(T initialState, string owner) where T : struct { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown ConstructorInfo[] constructors = typeof(StateReplicator).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); bool flag = default(bool); foreach (ConstructorInfo constructorInfo in constructors) { ParameterInfo[] parameters = constructorInfo.GetParameters(); if (parameters.Length != 1) { continue; } Type parameterType = parameters[0].ParameterType; if (parameterType != typeof(T) && !parameterType.IsAssignableFrom(typeof(T))) { continue; } try { return constructorInfo.Invoke(new object[1] { initialState }) as StateReplicator; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(55, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(owner); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": local StateReplicator constructor fallback failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } return null; } } public sealed class TOAVec3 { public float x { get; set; } public float y { get; set; } public float z { get; set; } public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } } public enum TOATimedTerminalPickMode { Random, Sequential, RoundIndex } public enum TOATimedTerminalVerificationType { TerminalCommand, CustomEvent, CustomEventNotConfirm, CustomEventNotVerify } public class TOATimedTerminalReference { public eDimensionIndex DimensionIndex { get; set; } public LG_LayerType LayerType { get; set; } public eLocalZoneIndex LocalIndex { get; set; } public int InstanceIndex { get; set; } } public sealed class TOATimedTerminalReceiverTerminal : TOATimedTerminalReference { public List EventsOnSelected { get; set; } = new List(); } public sealed class TOATimedTerminalReceiverPool { public int Index { get; set; } public TOATimedTerminalPickMode PickMode { get; set; } public List Terminals { get; set; } = new List(); } public sealed class TOATimedTerminalHudText { public string RoundStarted { get; set; } = "在{ReceiverTerminal}上输入[{VerifyCommand}]进行[定时验证]"; public string ConfirmationRequired { get; set; } = "返回{SourceTerminal}并输入[{ConfirmCommand}]完成[定时验证]"; public string TimeRemaining { get; set; } = "剩余时间:[TIMER]"; public string SequenceFailed { get; set; } = "Sequence failed - restart initialization sequence on source terminal."; public string SequenceComplete { get; set; } = "All timed terminal sequences completed."; } public sealed class TOATimedTerminalCommandDesc { public string Start { get; set; } = "Start timed terminal sequence."; public string Confirm { get; set; } = "Confirm the current timed connection."; public string Verify { get; set; } = "Verify timed connection round {Round}."; } public sealed class TOATimedTerminalRoundOverride { public int RoundIndex { get; set; } = -1; public string VerificationType { get; set; } = "TerminalCommand"; public int ReceiverTerminalPoolIndex { get; set; } public uint ChainedPuzzleToEndRound { get; set; } public float TimePerRound { get; set; } = -1f; public float TimeForConfirmation { get; set; } = -1f; public List EventsOnSequenceStart { get; set; } = new List(); public List EventsOnSequenceDone { get; set; } = new List(); public List EventsOnSequenceFail { get; set; } = new List(); } public sealed class TOATimedTerminalSequenceDefinition : TOATimedTerminalReference { public bool Enabled { get; set; } = true; [JsonIgnore] public int RuntimeIndex { get; set; } = -1; public int NumberOfRounds { get; set; } = 4; public int NumberOfTerminals { get; set; } = 5; public float TimePerRound { get; set; } = 100f; public float TimeForConfirmation { get; set; } = 15f; public bool AllowRepeatReceiverTerminal { get; set; } public uint ChainedPuzzleToStart { get; set; } public string StartCommand { get; set; } = "INIT_TIMED_SEQUENCE"; public string ConfirmCommand { get; set; } = "CONFIRM_TIMED_CONNECTION"; public string VerifyCommand { get; set; } = "VERIFY_TIMED_CONNECTION"; public TOATimedTerminalCommandDesc CommandDesc { get; set; } = new TOATimedTerminalCommandDesc(); public List ReceiverTerminalPools { get; set; } = new List { new TOATimedTerminalReceiverPool() }; public List RoundOverrides { get; set; } = new List(); public List EventsOnSequenceStart { get; set; } = new List(); public List EventsOnSequenceDone { get; set; } = new List(); public List EventsOnSequenceFail { get; set; } = new List(); public TOATimedTerminalHudText HudText { get; set; } = new TOATimedTerminalHudText(); } internal sealed class TOATimedTerminalSequenceManager { private sealed class TOATimedTerminalReceiverSelection { public LG_ComputerTerminal Terminal { get; set; } public List EventsOnSelected { get; set; } = new List(); } private sealed class TOATimedTerminalSequenceRuntime { private readonly TOATimedTerminalSequenceDefinition _def; private readonly LG_ComputerTerminal _sourceTerminal; private readonly List _receivers; private readonly List> _receiverSelectedEvents; private readonly HashSet _receivedConfirmKeys = new HashSet(StringComparer.Ordinal); private int _phaseId; private int _hudPhaseId = -1; private readonly TOATimedTerminalSequenceManager _manager; private StateReplicator? _replicator; private ChainedPuzzleInstance? _startChainedPuzzle; private readonly Dictionary _endRoundChainedPuzzles = new Dictionary(); private TERM_Command _startCommandSlot; private bool _hasStartCommand; private TERM_Command _confirmCommandSlot; private bool _hasConfirmCommand; private readonly List<(LG_ComputerTerminal Terminal, TERM_Command Slot)> _verifyCommandSlots = new List<(LG_ComputerTerminal, TERM_Command)>(); private int _pendingVisibilityRefreshFrames; private TOATimedTerminalSequenceStatus _pendingVisibilityStatus; private int _pendingVisibilityRound; private bool _hasEventDisableResumeSnapshot; private TOATimedTerminalSequenceStatus _eventDisableResumeStatus; private int _eventDisableResumeRound; private float _eventDisableResumeRemainingTime; private bool _hudRegistered; private bool _hudVisible; private string _hudHeader = string.Empty; private string _hudBody = string.Empty; private string _hudMessage = string.Empty; private string _hudMainTemplate = string.Empty; private int _hudRound; private float _nextHudUpdateTime; private float _hudHideAtTime; private const float HudTextRefreshInterval = 0.25f; private const float CompletedHudVisibleSeconds = 10f; private const float FailedHudVisibleSeconds = 5f; private const int HudPriority = 900; private float _clientClockOffset; private float SyncTime => Clock.Time + (SNet.IsMaster ? 0f : _clientClockOffset); internal void ApplyHostClock(float hostClockTime, float hostDeadline) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (SNet.IsMaster) { return; } _clientClockOffset = hostClockTime - Clock.Time; ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(67, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence client clock aligned. Offset="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_clientClockOffset, "0.000"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", HostDeadline="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(hostDeadline, "0.000"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } } internal TOATimedTerminalSequenceRuntime(TOATimedTerminalSequenceDefinition def, LG_ComputerTerminal sourceTerminal, List receiverSelections, TOATimedTerminalSequenceManager manager) { _def = def; _sourceTerminal = sourceTerminal; _receivers = receiverSelections.ConvertAll((TOATimedTerminalReceiverSelection selection) => selection.Terminal); _receiverSelectedEvents = receiverSelections.ConvertAll((TOATimedTerminalReceiverSelection selection) => selection.EventsOnSelected ?? new List()); _manager = manager; } private void NormalizeCommands() { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown TOATimedTerminalSequenceDefinition def = _def; if (def.CommandDesc == null) { TOATimedTerminalCommandDesc tOATimedTerminalCommandDesc = (def.CommandDesc = new TOATimedTerminalCommandDesc()); } bool flag = default(bool); if (string.IsNullOrWhiteSpace(_def.VerifyCommand) || string.Equals(_def.VerifyCommand.Trim(), "CONFIRM_TIMED_CONNECTION", StringComparison.OrdinalIgnoreCase)) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(121, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": VerifyCommand was empty or used the confirm command; normalized to VERIFY_TIMED_CONNECTION."); } log.LogWarning(val); } _def.VerifyCommand = "VERIFY_TIMED_CONNECTION"; } if (!string.IsNullOrWhiteSpace(_def.ConfirmCommand) && !string.Equals(_def.ConfirmCommand.Trim(), "VERIFY_TIMED_CONNECTION", StringComparison.OrdinalIgnoreCase)) { return; } if (string.Equals(_def.ConfirmCommand?.Trim(), "VERIFY_TIMED_CONNECTION", StringComparison.OrdinalIgnoreCase)) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(171, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ConfirmCommand used old default VERIFY_TIMED_CONNECTION; upgraded to CONFIRM_TIMED_CONNECTION. Update the config file to remove this warning."); } log.LogWarning(val); } } _def.ConfirmCommand = "CONFIRM_TIMED_CONNECTION"; } internal bool Setup() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Expected O, but got Unknown NormalizeCommands(); BuildChainedPuzzles(); AddSourceCommands(); AddReceiverCommands(); uint num = EOSNetworking.AllotReplicatorID(); bool flag = default(bool); if (num == 0) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(93, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" could not allocate StateReplicator id after commands were added."); } log.LogError(val); } return false; } _replicator = TOAStateReplicatorCompat.Create(num, new TOATimedTerminalSequenceSyncState { Status = TOATimedTerminalSequenceStatus.Waiting, CurrentRound = 0, ReceiverTerminalIndex = 0, Deadline = 0f }, (LifeTimeType)1, $"TimedTerminalSequence Index={_def.RuntimeIndex}"); if (_replicator == null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(182, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" could not create StateReplicator after commands were added. Commands will remain registered but the sequence cannot run until network state is available."); } log.LogError(val); } return false; } _replicator.OnStateChanged += OnStateChanged; RefreshCommandVisibility(TOATimedTerminalSequenceStatus.Waiting, 0); ScheduleCommandVisibilityRefresh(TOATimedTerminalSequenceStatus.Waiting, 0); return true; } private unsafe void BuildChainedPuzzles() { _startChainedPuzzle = CreateChainedPuzzle(_def.ChainedPuzzleToStart, _sourceTerminal, "start uplink"); if ((Object)(object)_startChainedPuzzle != (Object)null) { ChainedPuzzleInstance? startChainedPuzzle = _startChainedPuzzle; startChainedPuzzle.OnPuzzleSolved += Action.op_Implicit((Action)OnStartChainedPuzzleSolved); ChainedPuzzleInstance? startChainedPuzzle2 = _startChainedPuzzle; startChainedPuzzle2.OnPuzzleSolved += Action.op_Implicit(new Action(_startChainedPuzzle, (nint)(delegate*)(&EOSUtils.ResetProgress))); } _endRoundChainedPuzzles.Clear(); for (int i = 0; i < _def.NumberOfRounds; i++) { TOATimedTerminalRoundOverride roundOverride = GetRoundOverride(_def, i); if (roundOverride == null || roundOverride.ChainedPuzzleToEndRound == 0) { continue; } ChainedPuzzleInstance val = CreateChainedPuzzle(roundOverride.ChainedPuzzleToEndRound, _sourceTerminal, $"round {i} end"); if (!((Object)(object)val == (Object)null)) { int capturedRound = i; val.OnPuzzleSolved += Action.op_Implicit((Action)delegate { OnEndRoundChainedPuzzleSolved(capturedRound); }); _endRoundChainedPuzzles[capturedRound] = val; } } } private ChainedPuzzleInstance? CreateChainedPuzzle(uint puzzleBlockId, LG_ComputerTerminal terminal, string context) { //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Expected O, but got Unknown //IL_012b: Unknown result type (might be due to invalid IL or missing references) if (puzzleBlockId == 0) { return null; } ChainedPuzzleDataBlock block = GameDataBlockBase.GetBlock(puzzleBlockId); bool flag = default(bool); if (block == null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(65, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(context); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": ChainedPuzzleDataBlock "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(puzzleBlockId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found."); } log.LogError(val); } return null; } if ((Object)(object)terminal == (Object)null || terminal.SpawnNode == null || (Object)(object)terminal.m_wardenObjectiveSecurityScanAlign == (Object)null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(65, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(context); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": terminal anchor not available on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(((terminal != null) ? terminal.PublicName : null) ?? ""); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } return null; } try { return ChainedPuzzleManager.CreatePuzzleInstance(block, terminal.SpawnNode.m_area, terminal.m_wardenObjectiveSecurityScanAlign.position, terminal.m_wardenObjectiveSecurityScanAlign); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(70, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(context); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": chained puzzle creation failed for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(puzzleBlockId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } return null; } } private void OnStartChainedPuzzleSolved() { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown if (_replicator == null || !SNet.IsMaster) { return; } TOATimedTerminalSequenceSyncState state = _replicator.State; if (state.Status != TOATimedTerminalSequenceStatus.Waiting && state.Status != TOATimedTerminalSequenceStatus.Failed) { return; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(119, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": start chained puzzle solved for round "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(state.CurrentRound); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; starting sequence and resetting puzzle for reuse."); } log.LogDebug(val); } Start(state.CurrentRound); } private void OnEndRoundChainedPuzzleSolved(int round) { if (_replicator == null || !SNet.IsMaster) { return; } TOATimedTerminalSequenceSyncState state = _replicator.State; if (state.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation && state.CurrentRound == round) { ClearEventDisableResumeSnapshot(); ExecuteRoundEvents(GetDoneEvents(round)); TOANetworkEventProxy.BroadcastTimedTerminalSequenceConfirm(_def.RuntimeIndex, round, 2, (_replicator != null) ? _replicator.State.Deadline : 0f); if (round >= _def.NumberOfRounds - 1) { SetState(TOATimedTerminalSequenceStatus.Finished, round, 0f); ShowStatusHud(round, _def.HudText.SequenceComplete, 10f); } else { int round2 = round + 1; SetState(TOATimedTerminalSequenceStatus.Waiting, round2, 0f); SetHudVisible(visible: false); } } } private void OnStateChanged(TOATimedTerminalSequenceSyncState oldState, TOATimedTerminalSequenceSyncState newState, bool isRecall) { RefreshCommandVisibility(newState.Status, newState.CurrentRound); ApplyStatePresentation(newState); } private void ReplayClientDisplayEvents(TOATimedTerminalSequenceSyncState oldState, TOATimedTerminalSequenceSyncState newState, bool isRecall) { if (SNet.IsMaster || isRecall || (oldState.Status == newState.Status && oldState.CurrentRound == newState.CurrentRound)) { return; } try { if (newState.Status == TOATimedTerminalSequenceStatus.InProgress) { ExecuteDisplayOnlyRoundEvents(GetStartEvents(newState.CurrentRound)); ExecuteDisplayOnlyRoundEvents(GetSelectedReceiverEvents(newState.CurrentRound)); } else if ((newState.Status == TOATimedTerminalSequenceStatus.Waiting || newState.Status == TOATimedTerminalSequenceStatus.Finished) && oldState.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation) { ExecuteDisplayOnlyRoundEvents(GetDoneEvents(oldState.CurrentRound)); } else if (newState.Status == TOATimedTerminalSequenceStatus.Failed) { ExecuteDisplayOnlyRoundEvents(GetFailEvents(newState.CurrentRound)); } } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence client display event replay failed: " + ex.GetType().Name + ": " + ex.Message); } } private void ApplyStatePresentation(TOATimedTerminalSequenceSyncState state) { switch (state.Status) { case TOATimedTerminalSequenceStatus.InProgress: ShowRoundHud(state.CurrentRound, _def.HudText.RoundStarted); break; case TOATimedTerminalSequenceStatus.AwaitingConfirmation: ShowRoundHud(state.CurrentRound, _def.HudText.ConfirmationRequired); break; case TOATimedTerminalSequenceStatus.Disabled: case TOATimedTerminalSequenceStatus.Waiting: SetHudVisible(visible: false); break; case TOATimedTerminalSequenceStatus.Failed: ShowStatusHud(state.CurrentRound, _def.HudText.SequenceFailed, 5f); break; case TOATimedTerminalSequenceStatus.Finished: ShowStatusHud(state.CurrentRound, _def.HudText.SequenceComplete, 10f); break; } } internal void SetEnabled(bool enabled) { if (_replicator != null && SNet.IsMaster) { if (!enabled) { TOATimedTerminalSequenceSyncState state = _replicator.State; CaptureEventDisableResumeSnapshot(state); SetState(TOATimedTerminalSequenceStatus.Disabled, state.CurrentRound, 0f); SetHudVisible(visible: false); } else if (!TryRestoreEventDisableResumeSnapshot()) { Reset(); } } } internal void Start(int round) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (_replicator != null && SNet.IsMaster) { ClearEventDisableResumeSnapshot(); int round2 = Mathf.Clamp(round, 0, Math.Max(0, _def.NumberOfRounds - 1)); SetCommandVisible(_sourceTerminal, _startCommandSlot, visible: false); SetState(TOATimedTerminalSequenceStatus.InProgress, round2, SyncTime + GetTimePerRound(round2)); ExecuteRoundEvents(GetStartEvents(round2)); ExecuteRoundEvents(GetSelectedReceiverEvents(round2)); TOANetworkEventProxy.BroadcastTimedTerminalSequenceConfirm(_def.RuntimeIndex, round2, 1, (_replicator != null) ? _replicator.State.Deadline : 0f); ShowRoundHud(round2, _def.HudText.RoundStarted); } } internal void ReceiveClientConfirm(int round, byte actionKind, int messageId) { if (SNet.IsMaster) { return; } string item = messageId + ":" + round + ":" + actionKind; if (_receivedConfirmKeys.Add(item)) { switch (actionKind) { case 1: ExecuteDisplayOnlyRoundEvents(GetStartEvents(round)); ExecuteDisplayOnlyRoundEvents(GetSelectedReceiverEvents(round)); break; case 2: ExecuteDisplayOnlyRoundEvents(GetDoneEvents(round)); break; case 3: ExecuteDisplayOnlyRoundEvents(GetFailEvents(round)); break; } } } internal void StartFromCommand() { if (_replicator == null || !SNet.IsMaster) { return; } TOATimedTerminalSequenceSyncState state = _replicator.State; if (state.Status == TOATimedTerminalSequenceStatus.Waiting || state.Status == TOATimedTerminalSequenceStatus.Failed) { if ((Object)(object)_startChainedPuzzle != (Object)null) { _startChainedPuzzle.AttemptInteract((eChainedPuzzleInteraction)0); } else { Start(state.CurrentRound); } } } internal void VerifyRound(int round, bool fromCustomEvent = false) { if (_replicator == null || !SNet.IsMaster) { return; } TOATimedTerminalSequenceSyncState state = _replicator.State; if (state.Status == TOATimedTerminalSequenceStatus.InProgress && state.CurrentRound == round) { TOATimedTerminalVerificationType verificationType = GetVerificationType(round); if (fromCustomEvent == RequiresCustomVerify(verificationType)) { HideVerifyCommand(round); SetState(TOATimedTerminalSequenceStatus.AwaitingConfirmation, round, SyncTime + GetTimeForConfirmation(round)); TOANetworkEventProxy.BroadcastTimedTerminalSequenceConfirm(_def.RuntimeIndex, round, 4, (_replicator != null) ? _replicator.State.Deadline : 0f); ShowRoundHud(round, _def.HudText.ConfirmationRequired); } } } internal void ConfirmCurrentRound(bool fromCustomEvent = false) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (_replicator == null || !SNet.IsMaster) { return; } TOATimedTerminalSequenceSyncState state = _replicator.State; if (state.Status != TOATimedTerminalSequenceStatus.AwaitingConfirmation) { return; } int currentRound = state.CurrentRound; TOATimedTerminalVerificationType verificationType = GetVerificationType(currentRound); if (fromCustomEvent != RequiresCustomConfirm(verificationType)) { return; } ClearEventDisableResumeSnapshot(); SetCommandVisible(_sourceTerminal, _confirmCommandSlot, visible: false); if (_endRoundChainedPuzzles.TryGetValue(currentRound, out ChainedPuzzleInstance value) && (Object)(object)value != (Object)null) { value.AttemptInteract((eChainedPuzzleInteraction)0); return; } ExecuteRoundEvents(GetDoneEvents(currentRound)); TOANetworkEventProxy.BroadcastTimedTerminalSequenceConfirm(_def.RuntimeIndex, currentRound, 2, (_replicator != null) ? _replicator.State.Deadline : 0f); if (currentRound >= _def.NumberOfRounds - 1) { SetState(TOATimedTerminalSequenceStatus.Finished, currentRound, 0f); ShowStatusHud(currentRound, _def.HudText.SequenceComplete, 10f); } else { int round = currentRound + 1; SetState(TOATimedTerminalSequenceStatus.Waiting, round, 0f); SetHudVisible(visible: false); } } internal bool TryExecuteCustomValidation() { if (_replicator == null || !SNet.IsMaster) { return false; } TOATimedTerminalSequenceSyncState state = _replicator.State; TOATimedTerminalVerificationType verificationType = GetVerificationType(state.CurrentRound); if (state.Status == TOATimedTerminalSequenceStatus.InProgress && RequiresCustomVerify(verificationType)) { VerifyRound(state.CurrentRound, fromCustomEvent: true); return true; } if (state.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation && RequiresCustomConfirm(verificationType)) { ConfirmCurrentRound(fromCustomEvent: true); return true; } return false; } internal bool TryAdjustActiveTimer(float deltaSeconds) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown if (_replicator == null || !SNet.IsMaster) { return false; } TOATimedTerminalSequenceSyncState state = _replicator.State; if (state.Status != TOATimedTerminalSequenceStatus.InProgress && state.Status != TOATimedTerminalSequenceStatus.AwaitingConfirmation) { return false; } float num = Mathf.Max(0.01f, state.Deadline - SyncTime); float num2 = Mathf.Max(0.01f, num + deltaSeconds); float deadline = SyncTime + num2; SetState(state.Status, state.CurrentRound, deadline); ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(62, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" timer adjusted by "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(deltaSeconds, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s. Remaining="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num2, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("s."); } log.LogMessage(val); } return true; } internal void FailCurrentRound() { if (_replicator != null && SNet.IsMaster) { int round = Mathf.Clamp(_replicator.State.CurrentRound, 0, Math.Max(0, _def.NumberOfRounds - 1)); ClearEventDisableResumeSnapshot(); ExecuteRoundEvents(GetFailEvents(round)); TOANetworkEventProxy.BroadcastTimedTerminalSequenceConfirm(_def.RuntimeIndex, round, 3, (_replicator != null) ? _replicator.State.Deadline : 0f); SetState(TOATimedTerminalSequenceStatus.Failed, round, 0f); ShowStatusHud(round, _def.HudText.SequenceFailed, 5f); } } internal void Reset() { if (_replicator != null && SNet.IsMaster) { ClearEventDisableResumeSnapshot(); SetState(TOATimedTerminalSequenceStatus.Waiting, 0, 0f); SetHudVisible(visible: false); } } internal void ResetCurrentRound() { if (_replicator != null && SNet.IsMaster) { int round = Mathf.Clamp(_replicator.State.CurrentRound, 0, Math.Max(0, _def.NumberOfRounds - 1)); ClearEventDisableResumeSnapshot(); SetState(TOATimedTerminalSequenceStatus.InProgress, round, SyncTime + GetTimePerRound(round)); ShowRoundHud(round, _def.HudText.RoundStarted); } } internal void CompleteSequence() { if (_replicator != null && SNet.IsMaster) { int round = Mathf.Clamp(_replicator.State.CurrentRound, 0, Math.Max(0, _def.NumberOfRounds - 1)); ClearEventDisableResumeSnapshot(); ExecuteRoundEvents(GetDoneEvents(round)); TOANetworkEventProxy.BroadcastTimedTerminalSequenceConfirm(_def.RuntimeIndex, round, 2, (_replicator != null) ? _replicator.State.Deadline : 0f); SetState(TOATimedTerminalSequenceStatus.Finished, round, 0f); ShowStatusHud(round, _def.HudText.SequenceComplete, 10f); } } private void CaptureEventDisableResumeSnapshot(TOATimedTerminalSequenceSyncState state) { if (state.Status != TOATimedTerminalSequenceStatus.Disabled) { if (state.Status != TOATimedTerminalSequenceStatus.InProgress && state.Status != TOATimedTerminalSequenceStatus.AwaitingConfirmation) { ClearEventDisableResumeSnapshot(); return; } _hasEventDisableResumeSnapshot = true; _eventDisableResumeStatus = state.Status; _eventDisableResumeRound = Mathf.Clamp(state.CurrentRound, 0, Math.Max(0, _def.NumberOfRounds - 1)); _eventDisableResumeRemainingTime = ((state.Deadline > 0f) ? Mathf.Max(0.01f, state.Deadline - SyncTime) : 0f); } } private bool TryRestoreEventDisableResumeSnapshot() { if (!_hasEventDisableResumeSnapshot) { return false; } TOATimedTerminalSequenceStatus eventDisableResumeStatus = _eventDisableResumeStatus; int round = Mathf.Clamp(_eventDisableResumeRound, 0, Math.Max(0, _def.NumberOfRounds - 1)); float deadline = ((_eventDisableResumeRemainingTime > 0f) ? (SyncTime + _eventDisableResumeRemainingTime) : 0f); ClearEventDisableResumeSnapshot(); SetState(eventDisableResumeStatus, round, deadline); return true; } private void ClearEventDisableResumeSnapshot() { _hasEventDisableResumeSnapshot = false; _eventDisableResumeStatus = TOATimedTerminalSequenceStatus.Disabled; _eventDisableResumeRound = 0; _eventDisableResumeRemainingTime = 0f; } internal void Tick() { if (_replicator != null) { TOANetworkEventProxy.TickRegistration(); if (SNet.IsMaster) { TickVisibilityRefresh(); } TickHudRefresh(); TOATimedTerminalSequenceSyncState state = _replicator.State; if (SNet.IsMaster && (state.Status == TOATimedTerminalSequenceStatus.InProgress || state.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation) && state.Deadline > 0f && SyncTime >= state.Deadline) { FailCurrentRound(); } } } internal void Cleanup() { _replicator = null; _startChainedPuzzle = null; _endRoundChainedPuzzles.Clear(); _receivedConfirmKeys.Clear(); } private void AddSourceCommands() { _hasStartCommand = AddCommand(_sourceTerminal, _def.StartCommand, FormatCommandDesc(_def.CommandDesc.Start, 0), MakeCommandEvent("START", 0), out _startCommandSlot); _hasConfirmCommand = AddCommand(_sourceTerminal, _def.ConfirmCommand, FormatCommandDesc(_def.CommandDesc.Confirm, 0), MakeCommandEvent("CONFIRM", 0), out _confirmCommandSlot); } private void AddReceiverCommands() { //IL_0065: Unknown result type (might be due to invalid IL or missing references) _verifyCommandSlots.Clear(); for (int i = 0; i < _def.NumberOfRounds && i < _receivers.Count; i++) { if (AddCommand(_receivers[i], _def.VerifyCommand, FormatCommandDesc(_def.CommandDesc.Verify, i), MakeCommandEvent("VERIFY", i), out var slot)) { _verifyCommandSlots.Add((_receivers[i], slot)); } } } private WardenObjectiveEventData MakeCommandEvent(string action, int round) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Expected O, but got Unknown return new WardenObjectiveEventData { Type = (eWardenObjectiveEventType)2009, Count = _def.RuntimeIndex, Enabled = true, WorldEventObjectFilter = MakeActionKey(_def.RuntimeIndex, action, round) }; } private bool AddCommand(LG_ComputerTerminal terminal, string command, string description, WardenObjectiveEventData commandEvent, out TERM_Command slot) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected I4, but got Unknown //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Expected O, but got Unknown //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: Expected O, but got Unknown //IL_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_02c6: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Expected O, but got Unknown slot = (TERM_Command)0; if ((Object)(object)terminal == (Object)null || string.IsNullOrWhiteSpace(command)) { return false; } string text = command.Trim().ToUpperInvariant(); string text2 = text.ToLowerInvariant(); bool flag2 = default(bool); ManualLogSource log; if (terminal.m_command.m_commandsPerString.ContainsKey(text2)) { try { slot = (TERM_Command)(int)terminal.m_command.m_commandsPerString[text2]; if (AttachCommandEvent(terminal, slot, commandEvent)) { log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(61, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": reused existing command '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(terminal.PublicName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); } return true; } } catch (Exception ex) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(74, 5, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": failed to attach existing command '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' on "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(terminal.PublicName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } } log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(63, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": terminal "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(terminal.PublicName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" already has command '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'."); } log.LogWarning(val2); } return false; } if (!terminal.m_command.TryGetUniqueCommandSlot(ref slot)) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val3 = new BepInExErrorLogInterpolatedStringHandler(72, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": terminal "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(terminal.PublicName); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" has no free unique command slot."); } log.LogError(val3); } return false; } terminal.m_command.AddCommand(slot, text, new LocalizedText { UntranslatedText = (description ?? text) }, (TERM_CommandRule)0, ListExtensions.ToIl2Cpp(new List { commandEvent }), ListExtensions.ToIl2Cpp(new List())); log = TOARuntime.Log; if (log != null) { BepInExDebugLogInterpolatedStringHandler val = new BepInExDebugLogInterpolatedStringHandler(63, 4, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": added command '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' on "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(terminal.PublicName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" using slot "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(slot); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogDebug(val); } return true; } private static bool AttachCommandEvent(LG_ComputerTerminal terminal, TERM_Command slot, WardenObjectiveEventData commandEvent) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) try { if (terminal.m_command.m_commandEventMap.ContainsKey(slot)) { List val = terminal.m_command.m_commandEventMap[slot]; if (val == null) { terminal.m_command.m_commandEventMap[slot] = ListExtensions.ToIl2Cpp(new List { commandEvent }); return true; } AddCommandEventIfMissing(val, commandEvent); return true; } terminal.m_command.m_commandEventMap.Add(slot, ListExtensions.ToIl2Cpp(new List { commandEvent })); return true; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(78, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence could not attach event to terminal command slot "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(slot); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" on "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(terminal.PublicName); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogWarning(val2); } return false; } } private static void AddCommandEventIfMissing(List events, WardenObjectiveEventData commandEvent) { //IL_000d: 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) for (int i = 0; i < events.Count; i++) { WardenObjectiveEventData val = events[i]; if (val.Type == commandEvent.Type && val.Count == commandEvent.Count && string.Equals(val.WorldEventObjectFilter, commandEvent.WorldEventObjectFilter, StringComparison.Ordinal)) { return; } } events.Add(commandEvent); } private void RefreshCommandVisibility(TOATimedTerminalSequenceStatus status, int round) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) bool flag = status == TOATimedTerminalSequenceStatus.Waiting || status == TOATimedTerminalSequenceStatus.Failed; TOATimedTerminalVerificationType verificationType = GetVerificationType(round); bool flag2 = status == TOATimedTerminalSequenceStatus.AwaitingConfirmation && AllowsTerminalConfirm(verificationType); SetCommandVisible(_sourceTerminal, _startCommandSlot, _hasStartCommand && flag); SetCommandVisible(_sourceTerminal, _confirmCommandSlot, _hasConfirmCommand && flag2); List<(LG_ComputerTerminal, TERM_Command, bool)> list = new List<(LG_ComputerTerminal, TERM_Command, bool)>(); int num = Mathf.Clamp(round, 0, Math.Max(0, _verifyCommandSlots.Count - 1)); for (int i = 0; i < _verifyCommandSlots.Count; i++) { (LG_ComputerTerminal Terminal, TERM_Command Slot) entry = _verifyCommandSlots[i]; bool flag3 = status == TOATimedTerminalSequenceStatus.InProgress && i == num && AllowsTerminalVerify(verificationType); int num2 = list.FindIndex(((LG_ComputerTerminal Terminal, TERM_Command Slot, bool Visible) v) => v.Slot == entry.Slot && ((Il2CppObjectBase)v.Terminal).Pointer == ((Il2CppObjectBase)entry.Terminal).Pointer); if (num2 >= 0) { (LG_ComputerTerminal, TERM_Command, bool) tuple = list[num2]; list[num2] = (tuple.Item1, tuple.Item2, tuple.Item3 || flag3); } else { list.Add((entry.Terminal, entry.Slot, flag3)); } } foreach (var item in list) { SetCommandVisible(item.Item1, item.Item2, item.Item3); } } private TOATimedTerminalVerificationType GetVerificationType(int round) { string text = GetRoundOverride(_def, round)?.VerificationType ?? "TerminalCommand"; switch ((text ?? string.Empty).Trim().Replace("-", string.Empty, StringComparison.Ordinal).Replace("_", string.Empty, StringComparison.Ordinal) .Replace(" ", string.Empty, StringComparison.Ordinal) .ToLowerInvariant()) { case "terminalcommand": return TOATimedTerminalVerificationType.TerminalCommand; case "customevent": return TOATimedTerminalVerificationType.CustomEvent; case "customeventnotconfirm": return TOATimedTerminalVerificationType.CustomEventNotConfirm; case "customeventnotverify": return TOATimedTerminalVerificationType.CustomEventNotVerify; default: if (!string.IsNullOrWhiteSpace(text) && !string.Equals(text, "TerminalCommand", StringComparison.OrdinalIgnoreCase)) { TOARuntime.LogThrottled($"TimedTerminalSequence Index={_def.RuntimeIndex} round={round}: invalid VerificationType '{text}', using TerminalCommand."); } return TOATimedTerminalVerificationType.TerminalCommand; } } private static bool RequiresCustomVerify(TOATimedTerminalVerificationType type) { if (type != TOATimedTerminalVerificationType.CustomEvent) { return type == TOATimedTerminalVerificationType.CustomEventNotConfirm; } return true; } private static bool RequiresCustomConfirm(TOATimedTerminalVerificationType type) { if (type != TOATimedTerminalVerificationType.CustomEvent) { return type == TOATimedTerminalVerificationType.CustomEventNotVerify; } return true; } private static bool AllowsTerminalVerify(TOATimedTerminalVerificationType type) { return !RequiresCustomVerify(type); } private static bool AllowsTerminalConfirm(TOATimedTerminalVerificationType type) { return !RequiresCustomConfirm(type); } private void HideVerifyCommand(int round) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(round, 0, Math.Max(0, _verifyCommandSlots.Count - 1)); if (num >= 0 && num < _verifyCommandSlots.Count) { SetCommandVisible(_verifyCommandSlots[num].Terminal, _verifyCommandSlots[num].Slot, visible: false); } } private static void SetCommandVisible(LG_ComputerTerminal terminal, TERM_Command slot, bool visible) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)terminal == (Object)null) { return; } try { pComputerTerminalState state = terminal.m_stateReplicator.State; if (visible) { state.TryShowCommand(slot); } else { state.TryHideCommand(slot); } terminal.m_stateReplicator.SetStateUnsynced(state); } catch { } if (visible) { terminal.TrySyncSetCommandShow(slot); } else { terminal.TrySyncSetCommandHidden(slot); } } catch (Exception ex) { TOARuntime.LogThrottled($"TimedTerminalSequence command visibility update failed for {((terminal != null) ? terminal.PublicName : null)} / {slot}: {ex.Message}"); } } private void SetState(TOATimedTerminalSequenceStatus status, int round, float deadline) { if (_replicator != null && SNet.IsMaster) { TOATimedTerminalSequenceSyncState state = _replicator.State; if (state.Status != status || state.CurrentRound != round || (deadline > 0f && Mathf.Abs(state.Deadline - deadline) > 0.05f)) { _phaseId++; } _replicator.SetState(new TOATimedTerminalSequenceSyncState { Status = status, CurrentRound = round, ReceiverTerminalIndex = Mathf.Clamp(round, 0, Math.Max(0, _receivers.Count - 1)), Deadline = deadline, PhaseId = _phaseId }); RefreshCommandVisibility(status, round); ScheduleCommandVisibilityRefresh(status, round); } } private void ScheduleCommandVisibilityRefresh(TOATimedTerminalSequenceStatus status, int round) { _pendingVisibilityStatus = status; _pendingVisibilityRound = round; _pendingVisibilityRefreshFrames = 30; } private void TickVisibilityRefresh() { if (_pendingVisibilityRefreshFrames > 0) { _pendingVisibilityRefreshFrames--; RefreshCommandVisibility(_pendingVisibilityStatus, _pendingVisibilityRound); } } private float GetTimePerRound(int round) { TOATimedTerminalRoundOverride roundOverride = GetRoundOverride(_def, round); if (roundOverride == null || !(roundOverride.TimePerRound >= 0f)) { return _def.TimePerRound; } return roundOverride.TimePerRound; } private float GetTimeForConfirmation(int round) { TOATimedTerminalRoundOverride roundOverride = GetRoundOverride(_def, round); if (roundOverride == null || !(roundOverride.TimeForConfirmation >= 0f)) { return _def.TimeForConfirmation; } return roundOverride.TimeForConfirmation; } private List GetStartEvents(int round) { TOATimedTerminalRoundOverride roundOverride = GetRoundOverride(_def, round); List eventsOnSequenceStart; if (roundOverride == null || roundOverride.EventsOnSequenceStart.Count <= 0) { eventsOnSequenceStart = _def.EventsOnSequenceStart; if (eventsOnSequenceStart == null) { return new List(); } } else { eventsOnSequenceStart = roundOverride.EventsOnSequenceStart; } return eventsOnSequenceStart; } private List GetDoneEvents(int round) { TOATimedTerminalRoundOverride roundOverride = GetRoundOverride(_def, round); List eventsOnSequenceDone; if (roundOverride == null || roundOverride.EventsOnSequenceDone.Count <= 0) { eventsOnSequenceDone = _def.EventsOnSequenceDone; if (eventsOnSequenceDone == null) { return new List(); } } else { eventsOnSequenceDone = roundOverride.EventsOnSequenceDone; } return eventsOnSequenceDone; } private List GetFailEvents(int round) { TOATimedTerminalRoundOverride roundOverride = GetRoundOverride(_def, round); List eventsOnSequenceFail; if (roundOverride == null || roundOverride.EventsOnSequenceFail.Count <= 0) { eventsOnSequenceFail = _def.EventsOnSequenceFail; if (eventsOnSequenceFail == null) { return new List(); } } else { eventsOnSequenceFail = roundOverride.EventsOnSequenceFail; } return eventsOnSequenceFail; } private List GetSelectedReceiverEvents(int round) { if (round < 0 || round >= _receiverSelectedEvents.Count) { return new List(); } return _receiverSelectedEvents[round] ?? new List(); } private static void ExecuteRoundEvents(List events) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown bool flag = default(bool); foreach (WardenObjectiveEventData @event in events) { try { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(@event, (eWardenObjectiveEventTrigger)0, true, 0f); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(45, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence nested event failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } } private void ExecuteDisplayOnlyRoundEvents(List events) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected I4, but got Unknown bool flag = default(bool); foreach (WardenObjectiveEventData @event in events) { if (!IsDisplayOnlyEvent(@event)) { continue; } try { ExecuteClientVisibleEvent(@event); RestoreTimedHudAfterClientEvent((int)@event.Type); } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(60, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence client display event failed: Type="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(@event.Type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } } } } private static void ExecuteClientVisibleEvent(WardenObjectiveEventData eventData) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected I4, but got Unknown //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Expected O, but got Unknown //IL_01e4: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Expected O, but got Unknown //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Expected I4, but got Unknown //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Expected O, but got Unknown int num = (int)eventData.Type; bool flag = default(bool); ManualLogSource log; if (num >= 20000 && IsAwoLoaded()) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(59, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence client routed AWO common event Type="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } return; } if (num == 20015) { ManualLogSource? log2 = TOARuntime.Log; if (log2 != null) { log2.LogMessage((object)"TimedTerminalSequence client skipped MultiProgression event Type=20015."); } return; } string text = TOATextResolver.ResolveObject(ReadObjectMember(eventData, "WardenIntel")); if (!string.IsNullOrWhiteSpace(text)) { GuiManager.PlayerLayer.ShowWardenIntel(text, 0f, 5f); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(61, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence client displayed WardenIntel Type="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } return; } if (num == 20017) { object? instance = ReadObjectMember(eventData, "CustomHudText") ?? ReadObjectMember(eventData, "CustomHud"); string text2 = TOATextResolver.ResolveObject(ReadObjectMember(instance, "Title")); string text3 = TOATextResolver.ResolveObject(ReadObjectMember(instance, "Body")); string text4 = (string.IsNullOrWhiteSpace(text3) ? text2 : (string.IsNullOrWhiteSpace(text2) ? text3 : (text2 + "\n" + text3))); if (!string.IsNullOrWhiteSpace(text4)) { GuiManager.PlayerLayer.ShowWardenIntel(text4, 0f, 5f); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(57, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence client displayed CustomHudText: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text4); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } return; } } WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(eventData, (eWardenObjectiveEventTrigger)0, true, 0f); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(56, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence client executed local event Type="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted((int)eventData.Type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } } private void RestoreTimedHudAfterClientEvent(int eventType) { if (eventType == 20018) { return; } try { TOATimedTerminalSequenceSyncState tOATimedTerminalSequenceSyncState = ((_replicator != null) ? _replicator.State : default(TOATimedTerminalSequenceSyncState)); if ((tOATimedTerminalSequenceSyncState.Status == TOATimedTerminalSequenceStatus.InProgress || tOATimedTerminalSequenceSyncState.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation) && tOATimedTerminalSequenceSyncState.Deadline > 0f && _hudVisible) { EnsureTOAHudRegistered(blink: false); UpdateTOAProgressionHudTimerOnly(); } } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence HUDTime restore failed: " + ex.Message); } } private static bool IsAwoLoaded() { try { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { string text = assembly.GetName().Name ?? string.Empty; if (text.IndexOf("AdvancedWardenObjective", StringComparison.OrdinalIgnoreCase) >= 0 || text.Equals("AWO", StringComparison.OrdinalIgnoreCase) || assembly.GetType("AWO.Modules.WEE.WardenEventExt", throwOnError: false, ignoreCase: false) != null) { return true; } } } catch { } return false; } private static object? ReadObjectMember(object? instance, string name) { if (instance == null) { return null; } try { object obj = instance.GetType().GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance); if (obj != null) { return obj; } return instance.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(instance); } catch { return null; } } private static string ReadStringMember(object? instance, string name) { return ReadObjectMember(instance, name)?.ToString() ?? string.Empty; } private static bool IsDisplayOnlyEvent(WardenObjectiveEventData e) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected I4, but got Unknown //IL_0008: 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) int num = (int)e.Type; string text = (((object)e.Type/*cast due to .constrained prefix*/).ToString() ?? string.Empty).Trim().Replace("_", string.Empty).Replace("-", string.Empty) .Replace(" ", string.Empty) .ToLowerInvariant(); if (num == 10010 || num == 20007 || num == 20008 || num == 20010 || num == 20011 || num == 20013 || num == 20014 || num == 20015 || num == 20016 || num == 20017 || num == 20018 || num == 20019 || num == 20020 || num == 20026) { return true; } if (!string.IsNullOrWhiteSpace(ReadStringMember(e, "WardenIntel")) || ReadObjectMember(e, "CustomHudText") != null || ReadObjectMember(e, "CustomHud") != null) { return true; } if (num != 2 && num != 20015 && !text.Contains("wardenintel") && !text.Contains("intel") && !text.Contains("message") && !text.Contains("dialog") && !text.Contains("subtitle") && !text.Contains("text") && !text.Contains("objective") && !text.Contains("progression") && !text.Contains("hud") && !text.Contains("countdown") && !text.Contains("countup") && !text.Contains("dialogue") && !text.Contains("terminalog") && !text.Contains("navmarker")) { return text.Contains("shakescreen"); } return true; } private void ShowObjectiveMessage(string text, int round) { ShowStatusHud(round, text); } private void ShowRoundHud(int round, string mainTemplate) { _hudMainTemplate = mainTemplate ?? string.Empty; _hudRound = Mathf.Clamp(round, 0, Math.Max(0, _def.NumberOfRounds - 1)); _hudVisible = true; _hudHideAtTime = 0f; _nextHudUpdateTime = 0f; RefreshTOAProgressionHud(force: true); } private void ShowStatusHud(int round, string statusTemplate, float hideAfterSeconds = 0f) { _hudMainTemplate = statusTemplate ?? string.Empty; _hudRound = Mathf.Clamp(round, 0, Math.Max(0, _def.NumberOfRounds - 1)); _hudVisible = !string.IsNullOrWhiteSpace(_hudMainTemplate); _hudHideAtTime = ((_hudVisible && hideAfterSeconds > 0f) ? (SyncTime + hideAfterSeconds) : 0f); _nextHudUpdateTime = 0f; RefreshTOAProgressionHud(force: true, includeTimer: false); } private void TickHudRefresh() { if (!_hudVisible) { return; } if (_hudHideAtTime > 0f && SyncTime >= _hudHideAtTime) { _hudHideAtTime = 0f; SetHudVisible(visible: false); return; } TOATimedTerminalSequenceSyncState tOATimedTerminalSequenceSyncState = ((_replicator != null) ? _replicator.State : default(TOATimedTerminalSequenceSyncState)); if ((tOATimedTerminalSequenceSyncState.Status == TOATimedTerminalSequenceStatus.InProgress || tOATimedTerminalSequenceSyncState.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation) && tOATimedTerminalSequenceSyncState.Deadline > 0f) { UpdateTOAProgressionHudTimerOnly(); if (!(SyncTime < _nextHudUpdateTime)) { RefreshTOAProgressionHud(force: false); _nextHudUpdateTime = SyncTime + 0.25f; } } else if (!(SyncTime < _nextHudUpdateTime)) { RefreshTOAProgressionHud(force: false); _nextHudUpdateTime = SyncTime + 0.25f; } } private void RefreshTOAProgressionHud(bool force, bool includeTimer = true) { try { if (!_hudVisible) { RemoveTOAProgressionHud(); return; } string text = Format(_hudMainTemplate, _hudRound); string text2 = string.Empty; TOATimedTerminalSequenceSyncState tOATimedTerminalSequenceSyncState = ((_replicator != null) ? _replicator.State : default(TOATimedTerminalSequenceSyncState)); if (_hudPhaseId != tOATimedTerminalSequenceSyncState.PhaseId) { _hudPhaseId = tOATimedTerminalSequenceSyncState.PhaseId; _hudRegistered = false; _hudMessage = string.Empty; } int num; if (includeTimer && (tOATimedTerminalSequenceSyncState.Status == TOATimedTerminalSequenceStatus.InProgress || tOATimedTerminalSequenceSyncState.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation)) { num = ((tOATimedTerminalSequenceSyncState.Deadline > 0f) ? 1 : 0); if (num != 0 && !string.IsNullOrWhiteSpace(_def.HudText.TimeRemaining)) { text2 = Format(_def.HudText.TimeRemaining, _hudRound); } } else { num = 0; } if (num != 0 || force || !_hudRegistered || !string.Equals(_hudHeader, text, StringComparison.Ordinal) || !string.Equals(_hudBody, text2, StringComparison.Ordinal)) { bool flag = !string.Equals(_hudHeader, text, StringComparison.Ordinal); _hudHeader = text; _hudBody = text2; EnsureTOAHudRegistered(flag || force); } } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence AWO-style HUD update failed: " + ex.Message); } } private static InteractionGuiLayer? TryGetAWOSpecialHudLayer() { try { return GuiManager.InteractionLayer; } catch { return null; } } private string BuildAWOSpecialHudMessage() { string text = _hudHeader ?? string.Empty; string text2 = _hudBody ?? string.Empty; if (string.IsNullOrWhiteSpace(text)) { return text2; } if (string.IsNullOrWhiteSpace(text2)) { return text; } return text + "\n" + text2; } private float GetCurrentHudDuration(TOATimedTerminalSequenceSyncState state) { int round = Mathf.Clamp(state.CurrentRound, 0, Math.Max(0, _def.NumberOfRounds - 1)); return state.Status switch { TOATimedTerminalSequenceStatus.InProgress => Mathf.Max(0.01f, GetTimePerRound(round)), TOATimedTerminalSequenceStatus.AwaitingConfirmation => Mathf.Max(0.01f, GetTimeForConfirmation(round)), _ => 0f, }; } private void UpdateTOAProgressionHudTimerOnly() { try { if (!_hudVisible || !_hudRegistered) { return; } InteractionGuiLayer val = TryGetAWOSpecialHudLayer(); if (val != null) { TOATimedTerminalSequenceSyncState state = ((_replicator != null) ? _replicator.State : default(TOATimedTerminalSequenceSyncState)); float currentHudDuration = GetCurrentHudDuration(state); if ((state.Status == TOATimedTerminalSequenceStatus.InProgress || state.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation) && state.Deadline > 0f && currentHudDuration > 0f) { float num = Mathf.Max(0f, state.Deadline - SyncTime); float num2 = Mathf.Clamp(currentHudDuration - num, 0f, currentHudDuration); val.MessageVisible = true; val.MessageTimerVisible = true; val.SetMessageTimer(Mathf.Clamp01(num2 / currentHudDuration)); } } } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence HUD timer-only update failed: " + ex.Message); } } private void EnsureTOAHudRegistered(bool blink) { InteractionGuiLayer val = TryGetAWOSpecialHudLayer(); if (val == null) { return; } try { string text = BuildAWOSpecialHudMessage(); if (string.IsNullOrWhiteSpace(text)) { RemoveTOAProgressionHud(); return; } TOATimedTerminalSequenceSyncState state = ((_replicator != null) ? _replicator.State : default(TOATimedTerminalSequenceSyncState)); float currentHudDuration = GetCurrentHudDuration(state); float num = ((state.Deadline > 0f) ? Mathf.Max(0f, state.Deadline - SyncTime) : 0f); bool flag = _hudVisible && (state.Status == TOATimedTerminalSequenceStatus.InProgress || state.Status == TOATimedTerminalSequenceStatus.AwaitingConfirmation) && state.Deadline > 0f && currentHudDuration > 0f; val.MessageVisible = true; val.MessageTimerVisible = flag; if (flag) { float messageTimer = Mathf.Clamp01(Mathf.Clamp(currentHudDuration - num, 0f, currentHudDuration) / currentHudDuration); val.SetMessageTimer(messageTimer); } if (blink || !_hudRegistered || !string.Equals(_hudMessage, text, StringComparison.Ordinal)) { val.SetMessage(text, (ePUIMessageStyle)0, 900); DisableInteractionLayerAutoWrap(val); _hudMessage = text; } _hudRegistered = true; } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence AWO SpecialHudTimer HUD update failed: " + ex.Message); } } private static void DisableInteractionLayerAutoWrap(InteractionGuiLayer hud) { try { FieldInfo[] fields = ((object)hud).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { object value = null; try { value = fieldInfo.GetValue(hud); } catch { } ApplyNoWrapFromObject(value); } PropertyInfo[] properties = ((object)hud).GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { if (propertyInfo.GetIndexParameters().Length == 0) { object value2 = null; try { value2 = propertyInfo.GetValue(hud); } catch { } ApplyNoWrapFromObject(value2); } } } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence HUD word-wrap suppression failed: " + ex.Message); } } private static void ApplyNoWrapFromObject(object? value) { ApplyNoWrap((TMP_Text?)((value is TMP_Text) ? value : null)); Component val = (Component)((value is Component) ? value : null); if (val != null) { ApplyNoWrap(val.GetComponentsInChildren(true)); return; } GameObject val2 = (GameObject)((value is GameObject) ? value : null); if (val2 != null) { ApplyNoWrap(val2.GetComponentsInChildren(true)); } } private static void ApplyNoWrap(Il2CppArrayBase? texts) { if (texts == null) { return; } foreach (TMP_Text text in texts) { ApplyNoWrap(text); } } private static void ApplyNoWrap(TMP_Text? text) { if (!((Object)(object)text == (Object)null)) { text.enableWordWrapping = false; text.overflowMode = (TextOverflowModes)0; } } private void RemoveTOAProgressionHud() { if (!_hudRegistered) { return; } try { InteractionGuiLayer val = TryGetAWOSpecialHudLayer(); if (val != null) { val.MessageVisible = false; val.MessageTimerVisible = false; } } catch { } _hudRegistered = false; _hudHeader = string.Empty; _hudBody = string.Empty; _hudMessage = string.Empty; } private void SetHudVisible(bool visible) { _hudVisible = visible; if (!visible) { _hudHideAtTime = 0f; RemoveTOAProgressionHud(); } try { if (_sourceTerminal.UplinkPuzzle != null) { _sourceTerminal.UplinkPuzzle.CurrentRound.ShowGui = false; _sourceTerminal.UplinkPuzzle.Connected = false; _sourceTerminal.UplinkPuzzle.Solved = false; } if (_sourceTerminal.TimedSequencePuzzle != null && _sourceTerminal.TimedSequencePuzzle.CurrentRound != null) { _sourceTerminal.TimedSequencePuzzle.CurrentRound.ShowGui = false; _sourceTerminal.TimedSequencePuzzle.Connected = false; } } catch { } } private void ApplyOfficialHudText(int round, string mainText) { } private void SetupTimedSequenceHud(int round) { } private void StartOfficialTimedVerification(int round) { } private void StartOfficialTimedConfirmation(int round) { } private void SafeUpdateTimedSequenceGui(bool forceUpdate) { } private void UpdateUplinkHudFallback(int round, string mainText, bool visible) { } private void ResetOfficialTimedRound(bool failed) { } private void MarkOfficialTimedSolved() { } private void SetupUplinkHud() { } private static string NormalizeTerminalName(string name) { if (string.IsNullOrWhiteSpace(name)) { return string.Empty; } string text = name.Trim(); if (!text.StartsWith("[")) { return "[" + text + "]"; } return text; } private string Format(string text, int round) { if (string.IsNullOrWhiteSpace(text)) { return string.Empty; } return ApplyFormatTokens(TOATextResolver.Resolve(text), round); } private string FormatCommandDesc(string text, int round) { if (string.IsNullOrWhiteSpace(text)) { return string.Empty; } return ApplyFormatTokens(ResolveCommandDescText(text), round); } private static string ResolveCommandDescText(string text) { string text2 = text.Trim(); if (uint.TryParse(text2, out var result)) { if (result != 0) { return text; } return string.Empty; } try { if (MTFOPartialDataIdResolver.TryResolve(text2, out var id) && id != 0) { return Text.Get(id); } } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence CommandDesc text resolver failed for '" + text2 + "': " + ex.Message); } return text; } private string ApplyFormatTokens(string text, int round) { string newValue = ((round >= 0 && round < _receivers.Count) ? NormalizeTerminalName(_receivers[round].PublicName) : string.Empty); LG_ComputerTerminal sourceTerminal = _sourceTerminal; string newValue2 = NormalizeTerminalName(((sourceTerminal != null) ? sourceTerminal.PublicName : null) ?? string.Empty); float num = 0f; if (_replicator != null && _replicator.State.Deadline > 0f) { num = Mathf.Max(0f, _replicator.State.Deadline - SyncTime); } string newValue3 = FormatRemainingTime(num); return text.Replace("{Round}", (round + 1).ToString()).Replace("{RoundIndex}", round.ToString()).Replace("{TotalRounds}", Math.Max(1, _def.NumberOfRounds).ToString()) .Replace("{ReceiverTerminal}", newValue) .Replace("{SourceTerminal}", newValue2) .Replace("{StartCommand}", _def.StartCommand) .Replace("{ConfirmCommand}", _def.ConfirmCommand) .Replace("{VerifyCommand}", _def.VerifyCommand) .Replace("{RemainingTime}", newValue3) .Replace("{RemainingSeconds}", Mathf.CeilToInt(num).ToString()) .Replace("[TIMER]", newValue3, StringComparison.Ordinal); } private static string FormatRemainingTime(float seconds) { TimeSpan timeSpan = TimeSpan.FromSeconds(Mathf.CeilToInt(Mathf.Max(0f, seconds))); return $"{(int)timeSpan.TotalMinutes:D2}:{timeSpan.Seconds:D2}"; } } private const string DefinitionFolderName = "TimedTerminalSequence"; private const string ActionStart = "START"; private const string ActionConfirm = "CONFIRM"; private const string ActionVerify = "VERIFY"; private const string ActionComplete = "COMPLETE"; private const byte ConfirmStart = 1; private const byte ConfirmDone = 2; private const byte ConfirmFail = 3; private const byte ConfirmValidation = 4; private const string HashPrefix = "TTS"; private readonly string _definitionPath = TOAConfigPaths.GetFeaturePath("TimedTerminalSequence"); private readonly Dictionary> _definitions = new Dictionary>(); private readonly Dictionary _runtimes = new Dictionary(); private readonly Dictionary _filterByHash = new Dictionary(); private LiveEditListener? _liveEditListener; private TOATimedTerminalSequenceDriver? _driver; public static TOATimedTerminalSequenceManager Current { get; } = new TOATimedTerminalSequenceManager(); private TOATimedTerminalSequenceManager() { LevelAPI.OnBuildDone += Build; LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } internal void Init() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Expected O, but got Unknown bool flag = default(bool); try { EnsureDefinitionPath(); ReloadDefinitionsFromDisk(); if (_liveEditListener == null) { _liveEditListener = LiveEdit.CreateListener(_definitionPath, "*.json", true); _liveEditListener.FileChanged += new LiveEditEventHandler(FileChanged); } _driver = TOATimedTerminalSequenceDriver.Ensure(); ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(43, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence definitions path: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(_definitionPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(37, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence Init failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(ex.Message); } log.LogError(val2); } } } internal bool TryGetWorldEventObjectFilterByHash(int hash, out string filter) { return _filterByHash.TryGetValue(hash, out filter); } internal void ReceiveClientConfirm(int runtimeIndex, int round, byte actionKind, int messageId, float hostClockTime, float hostDeadline) { if (_runtimes.TryGetValue(runtimeIndex, out TOATimedTerminalSequenceRuntime value)) { value.ApplyHostClock(hostClockTime, hostDeadline); value.ReceiveClientConfirm(round, actionKind, messageId); } } internal void ToggleFromEvent(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.TOA_ToggleTimedTerminalSequence, eventData)) { int index2; string action; int round; int index = (TryParseActionKey(eventData.WorldEventObjectFilter, out index2, out action, out round) ? index2 : eventData.Count); if (TryGetRuntime(index, out TOATimedTerminalSequenceRuntime runtime)) { runtime.SetEnabled(eventData.Enabled); } } } internal void ResetRoundFromEvent(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.TOA_ResetTimedTerminalSequenceRound, eventData)) { int index2; string action; int round; int index = (TryParseActionKey(eventData.WorldEventObjectFilter, out index2, out action, out round) ? index2 : eventData.Count); if (TryGetRuntime(index, out TOATimedTerminalSequenceRuntime runtime)) { runtime.ResetCurrentRound(); } } } internal void CompleteFromEvent(WardenObjectiveEventData eventData) { if (TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.TOA_CompleteTimedTerminalSequence, eventData)) { int index2; string action; int round; int index = (TryParseActionKey(eventData.WorldEventObjectFilter, out index2, out action, out round) ? index2 : eventData.Count); if (TryGetRuntime(index, out TOATimedTerminalSequenceRuntime runtime)) { runtime.CompleteSequence(); } } } internal void AdjustActiveTimerFromEvent(WardenObjectiveEventData eventData) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown if (!SNet.IsMaster) { return; } int num = TOANetworkEventProxy.NextMessageId(); ManualLogSource log = TOARuntime.Log; bool flag = default(bool); if (log != null) { BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(77, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Type 2011 host trigger accepted. MessageId="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", Duration="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventData.Duration, "0.###"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogMessage(val); } foreach (TOATimedTerminalSequenceRuntime value in _runtimes.Values) { if (value.TryAdjustActiveTimer(eventData.Duration)) { return; } } log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(95, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence timer adjustment ignored because no sequence is currently active. Delta="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(eventData.Duration, "0.###"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogWarning(val2); } } internal void ExecuteCustomValidationEvent(WardenObjectiveEventData eventData) { if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.TOA_TimedTerminalSequenceCustomValidation, eventData)) { return; } foreach (TOATimedTerminalSequenceRuntime value in _runtimes.Values) { if (value.TryExecuteCustomValidation()) { return; } } ManualLogSource? log = TOARuntime.Log; if (log != null) { log.LogWarning((object)"TimedTerminalSequence custom validation ignored because no sequence is currently in progress."); } } internal void ExecuteCommandEvent(WardenObjectiveEventData eventData) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown if (!TOANetworkEventProxy.EnsureHostExecution(TOACustomEventType.TOA_TimedTerminalSequenceCommand, eventData)) { return; } TOATimedTerminalSequenceRuntime runtime; if (!TryParseActionKey(eventData.WorldEventObjectFilter, out int index, out string action, out int round)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(72, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence command ignored because action key is invalid: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(eventData.WorldEventObjectFilter); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogWarning(val); } } else if (TryGetRuntime(index, out runtime)) { switch (action) { case "START": runtime.StartFromCommand(); break; case "CONFIRM": runtime.ConfirmCurrentRound(); break; case "VERIFY": runtime.VerifyRound(round); break; case "COMPLETE": runtime.CompleteSequence(); break; } } } internal void Tick() { foreach (TOATimedTerminalSequenceRuntime value in _runtimes.Values) { value.Tick(); } } private void EnsureDefinitionPath() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown Directory.CreateDirectory(_definitionPath); string text = Path.Combine(_definitionPath, "Template.json"); if (File.Exists(text)) { return; } File.WriteAllText(text, CreateTemplateJson()); ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(45, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence template generated: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } private void FileChanged(LiveEditEventArgs e) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(48, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence LiveEdit file changed: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(e.FullPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } LiveEdit.TryReadFileContent(e.FullPath, (Action)delegate(string content) { if (TryDeserializeDefinition(content, e.FullPath, out uint mainLevelLayout, out GenericExpeditionDefinition conf) && conf != null) { AddDefinitions(mainLevelLayout, conf, e.FullPath); } }); } private void ReloadDefinitionsFromDisk() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Expected O, but got Unknown Dictionary> dictionary = new Dictionary>(); int num = 0; int num2 = 0; bool flag = default(bool); ManualLogSource log; foreach (string item in Directory.EnumerateFiles(_definitionPath, "*.json", SearchOption.TopDirectoryOnly)) { try { if (!TryDeserializeDefinition(File.ReadAllText(item), item, out uint mainLevelLayout, out GenericExpeditionDefinition conf)) { num2++; } else if (conf != null) { AddDefinitions(dictionary, mainLevelLayout, conf, item); num++; } } catch (Exception ex) { num2++; log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(51, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence config load failed for '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(item); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } } } _definitions.Clear(); foreach (KeyValuePair> item2 in dictionary) { _definitions[item2.Key] = item2.Value; } string text = ((dictionary.Count == 0) ? "" : string.Join(",", dictionary.Keys.OrderBy((uint id) => id))); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(92, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence config reload complete. FilesLoaded="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", FilesFailed="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", MainLevelLayouts="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } private void AddDefinitions(uint mainLevelLayout, GenericExpeditionDefinition conf, string file) { AddDefinitions(_definitions, mainLevelLayout, conf, file); } private static void AddDefinitions(Dictionary> target, uint mainLevelLayout, GenericExpeditionDefinition conf, string file) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown conf.MainLevelLayout = mainLevelLayout; if (target.ContainsKey(mainLevelLayout)) { ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(75, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence config reload replaced MainLevelLayout "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(mainLevelLayout); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" from file '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } target[mainLevelLayout] = conf; } private static bool TryDeserializeDefinition(string content, string file, out uint mainLevelLayout, out GenericExpeditionDefinition? conf) { //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Expected O, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Expected O, but got Unknown //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Expected O, but got Unknown mainLevelLayout = 0u; conf = null; bool flag2 = default(bool); try { using JsonDocument jsonDocument = JsonDocument.Parse(content, new JsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }); ManualLogSource log; if (jsonDocument.RootElement.ValueKind != JsonValueKind.Object) { log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(55, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' root must be an object."); } log.LogError(val); } return false; } if (!TryGetPropertyCaseInsensitive(jsonDocument.RootElement, "MainLevelLayout", out var value)) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(59, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' is missing MainLevelLayout."); } log.LogError(val); } return false; } if (!TryResolveMainLevelLayout(value, out mainLevelLayout, out string resolvedBy)) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(72, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' MainLevelLayout could not be resolved: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); } log.LogError(val); } return false; } string text = RewriteConfigForDeserialize(jsonDocument.RootElement, mainLevelLayout); conf = EOSJson.Deserialize>(text); if (conf == null) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(53, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' deserialized to null."); } log.LogError(val); } return false; } log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(64, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence config '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' MainLevelLayout resolved as "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(mainLevelLayout); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(resolvedBy); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } log.LogMessage(val2); } return true; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(48, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' parse failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } return false; } } private static bool TryResolveMainLevelLayout(JsonElement element, out uint id, out string resolvedBy) { id = 0u; resolvedBy = string.Empty; if (element.ValueKind == JsonValueKind.Number && element.TryGetUInt32(out id)) { resolvedBy = "numeric"; return true; } string text = ((element.ValueKind == JsonValueKind.String) ? (element.GetString() ?? string.Empty) : element.ToString()); text = text.Trim(); if (string.IsNullOrWhiteSpace(text)) { return false; } if (uint.TryParse(text, out id)) { resolvedBy = "numeric-string"; return true; } if (MTFOPartialDataIdResolver.TryResolve(text, out id) && id != 0) { resolvedBy = "mtfo-partialdata:" + text; return true; } try { if (GameDataBlockBase.HasBlock(text)) { id = GameDataBlockBase.GetBlockID(text); resolvedBy = "level-layout-datablock:" + text; return id != 0; } } catch (Exception ex) { TOARuntime.LogThrottled("TimedTerminalSequence could not resolve MainLevelLayout '" + text + "' via LevelLayoutDataBlock: " + ex.Message); } return false; } internal static bool TryResolveMainLevelLayoutForExternalConfig(JsonElement element, out uint id, out string resolvedBy) { return TryResolveMainLevelLayout(element, out id, out resolvedBy); } private static bool TryGetPropertyCaseInsensitive(JsonElement element, string propertyName, out JsonElement value) { foreach (JsonProperty item in element.EnumerateObject()) { if (string.Equals(item.Name, propertyName, StringComparison.OrdinalIgnoreCase)) { value = item.Value; return true; } } value = default(JsonElement); return false; } private static string RewriteConfigForDeserialize(JsonElement root, uint mainLevelLayout) { using MemoryStream memoryStream = new MemoryStream(); using (Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter((Stream)memoryStream, new JsonWriterOptions { Indented = false })) { utf8JsonWriter.WriteStartObject(); foreach (JsonProperty item in root.EnumerateObject()) { if (string.Equals(item.Name, "MainLevelLayout", StringComparison.OrdinalIgnoreCase)) { utf8JsonWriter.WriteNumber("MainLevelLayout", mainLevelLayout); } else { WriteConfigProperty(utf8JsonWriter, item); } } utf8JsonWriter.WriteEndObject(); } return Encoding.UTF8.GetString(memoryStream.ToArray()); } private static void WriteConfigProperty(Utf8JsonWriter writer, JsonProperty property) { if (property.NameEquals("Definitions") && property.Value.ValueKind == JsonValueKind.Array) { writer.WritePropertyName(property.Name); writer.WriteStartArray(); foreach (JsonElement item in property.Value.EnumerateArray()) { if (item.ValueKind == JsonValueKind.Object) { WriteDefinitionObject(writer, item); } else { item.WriteTo(writer); } } writer.WriteEndArray(); } else { property.WriteTo(writer); } } private static void WriteDefinitionObject(Utf8JsonWriter writer, JsonElement definition) { writer.WriteStartObject(); foreach (JsonProperty item in definition.EnumerateObject()) { uint id; if (item.NameEquals("CommandDesc") && item.Value.ValueKind == JsonValueKind.Object) { writer.WritePropertyName(item.Name); writer.WriteStartObject(); foreach (JsonProperty item2 in item.Value.EnumerateObject()) { WriteCommandDescValue(writer, item2); } writer.WriteEndObject(); } else if (item.NameEquals("RoundOverrides") && item.Value.ValueKind == JsonValueKind.Array) { writer.WritePropertyName(item.Name); writer.WriteStartArray(); foreach (JsonElement item3 in item.Value.EnumerateArray()) { if (item3.ValueKind == JsonValueKind.Object) { WriteRoundOverrideObject(writer, item3); } else { item3.WriteTo(writer); } } writer.WriteEndArray(); } else if (item.NameEquals("ChainedPuzzleToStart") && TryResolveUIntValue(item.Value, out id)) { writer.WriteNumber(item.Name, id); } else { item.WriteTo(writer); } } writer.WriteEndObject(); } private static void WriteRoundOverrideObject(Utf8JsonWriter writer, JsonElement roundOverride) { writer.WriteStartObject(); foreach (JsonProperty item in roundOverride.EnumerateObject()) { if (item.NameEquals("ChainedPuzzleToEndRound") && TryResolveUIntValue(item.Value, out var id)) { writer.WriteNumber(item.Name, id); } else { item.WriteTo(writer); } } writer.WriteEndObject(); } private static bool TryResolveUIntValue(JsonElement element, out uint id) { id = 0u; if (element.ValueKind == JsonValueKind.Number && element.TryGetUInt32(out id)) { return true; } string text = ((element.ValueKind == JsonValueKind.String) ? (element.GetString() ?? string.Empty) : element.ToString()); text = text.Trim(); if (string.IsNullOrWhiteSpace(text)) { return false; } if (uint.TryParse(text, out id)) { return true; } if (MTFOPartialDataIdResolver.TryResolve(text, out id)) { return id != 0; } return false; } private static void WriteCommandDescValue(Utf8JsonWriter writer, JsonProperty property) { writer.WritePropertyName(property.Name); double value; if (property.Value.ValueKind == JsonValueKind.Null) { writer.WriteStringValue(string.Empty); } else if (property.Value.ValueKind == JsonValueKind.Number && property.Value.TryGetDouble(out value) && Math.Abs(value) < double.Epsilon) { writer.WriteStringValue(string.Empty); } else { property.Value.WriteTo(writer); } } private static string CreateTemplateJson() { return "{\n \"MainLevelLayout\": \"Layout-T-L1\",\n \"Definitions\": [\n {\n \"Enabled\": true,\n \"DimensionIndex\": \"Reality\",\n \"LayerType\": \"MainLayer\",\n \"LocalIndex\": \"Zone_0\",\n \"InstanceIndex\": 0,\n \"NumberOfRounds\": 4,\n \"NumberOfTerminals\": 5,\n \"TimePerRound\": 100.0,\n \"TimeForConfirmation\": 15.0,\n \"AllowRepeatReceiverTerminal\": false,\n \"ChainedPuzzleToStart\": 0,\n \"StartCommand\": \"INIT_TIMED_SEQUENCE\",\n \"ConfirmCommand\": \"CONFIRM_TIMED_CONNECTION\",\n \"VerifyCommand\": \"VERIFY_TIMED_CONNECTION\",\n \"CommandDesc\": {\n \"Start\": \"Start timed terminal sequence.\",\n \"Confirm\": \"Confirm the current timed connection.\",\n \"Verify\": \"Verify timed connection round {Round}.\"\n },\n \"ReceiverTerminalPools\": [\n {\n \"Index\": 0,\n \"PickMode\": \"Random\",\n \"Terminals\": [\n {\n \"DimensionIndex\": \"Reality\",\n \"LayerType\": \"MainLayer\",\n \"LocalIndex\": \"Zone_0\",\n \"InstanceIndex\": 0,\n \"EventsOnSelected\": []\n }\n ]\n }\n ],\n \"RoundOverrides\": [\n {\n \"RoundIndex\": 0,\n \"VerificationType\": \"TerminalCommand\",\n \"ReceiverTerminalPoolIndex\": 0,\n \"ChainedPuzzleToEndRound\": 0,\n \"TimePerRound\": -1.0,\n \"TimeForConfirmation\": -1.0,\n \"EventsOnSequenceStart\": [],\n \"EventsOnSequenceDone\": [],\n \"EventsOnSequenceFail\": []\n }\n ],\n \"EventsOnSequenceStart\": [],\n \"EventsOnSequenceDone\": [],\n \"EventsOnSequenceFail\": [],\n \"HudText\": {\n \"RoundStarted\": \"Input [{VerifyCommand}] on {ReceiverTerminal} to perform [timed verification].\",\n \"ConfirmationRequired\": \"Return to {SourceTerminal} and input [{ConfirmCommand}] to complete [timed verification].\",\n \"TimeRemaining\": \"Time remaining: [TIMER]\",\n \"SequenceFailed\": \"Sequence failed - restart initialization sequence on source terminal.\",\n \"SequenceComplete\": \"All timed terminal sequences completed.\"\n }\n }\n ]\n}\n"; } private void Build() { Clear(); uint currentLevelLayoutId = TOARuntime.GetCurrentLevelLayoutId(); if (!_definitions.TryGetValue(currentLevelLayoutId, out GenericExpeditionDefinition value)) { return; } for (int i = 0; i < value.Definitions.Count; i++) { TOATimedTerminalSequenceDefinition tOATimedTerminalSequenceDefinition = value.Definitions[i]; tOATimedTerminalSequenceDefinition.RuntimeIndex = i; if (tOATimedTerminalSequenceDefinition.Enabled) { Build(tOATimedTerminalSequenceDefinition); } } } private void Build(TOATimedTerminalSequenceDefinition def) { //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02f4: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Expected O, but got Unknown bool flag = default(bool); try { ManualLogSource log; if (_runtimes.ContainsKey(def.RuntimeIndex)) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(71, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" duplicated. Skipping duplicate definition."); } log.LogError(val); } return; } LG_ComputerTerminal val2 = ResolveTerminal(def, $"source Index={def.RuntimeIndex}"); if ((Object)(object)val2 == (Object)null) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(67, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" source terminal not found at ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.DimensionIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.LayerType); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.LocalIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.InstanceIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")."); } log.LogError(val); } return; } List list = SelectReceivers(def); if (list.Count <= 0) { log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(55, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" has no receiver terminals."); } log.LogError(val); } return; } TOATimedTerminalSequenceRuntime tOATimedTerminalSequenceRuntime = new TOATimedTerminalSequenceRuntime(def, val2, list, this); if (!tOATimedTerminalSequenceRuntime.Setup()) { return; } _runtimes[def.RuntimeIndex] = tOATimedTerminalSequenceRuntime; RegisterFilter(MakeActionKey(def.RuntimeIndex, "START", 0)); RegisterFilter(MakeActionKey(def.RuntimeIndex, "CONFIRM", 0)); RegisterFilter(MakeActionKey(def.RuntimeIndex, "COMPLETE", 0)); for (int i = 0; i < def.NumberOfRounds; i++) { RegisterFilter(MakeActionKey(def.RuntimeIndex, "VERIFY", i)); } log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val3 = new BepInExMessageLogInterpolatedStringHandler(65, 4, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("TimedTerminalSequence build Index="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(": Source="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(val2.PublicName); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", Rounds="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(def.NumberOfRounds); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(", Receivers="); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted(list.Count); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("."); } log.LogMessage(val3); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(45, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence build failed Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogError(val); } } } private void RegisterFilter(string filter) { int num = TOANetworkEventProxy.StableHash(filter); if (num != 0 && !_filterByHash.ContainsKey(num)) { _filterByHash[num] = filter; } } private bool TryGetRuntime(int index, out TOATimedTerminalSequenceRuntime runtime) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown if (_runtimes.TryGetValue(index, out runtime)) { return true; } ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(39, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(index); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" not found."); } log.LogError(val); } return false; } private List SelectReceivers(TOATimedTerminalSequenceDefinition def) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0173: Unknown result type (might be due to invalid IL or missing references) List list = new List(); HashSet hashSet = new HashSet(); bool flag = default(bool); for (int i = 0; i < Math.Max(1, def.NumberOfRounds); i++) { int poolIndex = GetRoundOverride(def, i)?.ReceiverTerminalPoolIndex ?? 0; TOATimedTerminalReceiverPool tOATimedTerminalReceiverPool = def.ReceiverTerminalPools.FirstOrDefault((TOATimedTerminalReceiverPool p) => p.Index == poolIndex) ?? def.ReceiverTerminalPools.FirstOrDefault(); if (tOATimedTerminalReceiverPool == null) { continue; } List list2 = new List(); foreach (TOATimedTerminalReceiverTerminal terminal in tOATimedTerminalReceiverPool.Terminals) { LG_ComputerTerminal val = ResolveTerminal(terminal, $"receiver Index={def.RuntimeIndex} pool={poolIndex} round={i}"); if ((Object)(object)val == (Object)null) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(69, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("TimedTerminalSequence Index="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(def.RuntimeIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" receiver terminal not found at ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(terminal.DimensionIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(terminal.LayerType); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(terminal.LocalIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted(terminal.InstanceIndex); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(")."); } log.LogWarning(val2); } } else if (def.AllowRepeatReceiverTerminal || !hashSet.Contains(((Il2CppObjectBase)val).Pointer)) { list2.Add(new TOATimedTerminalReceiverSelection { Terminal = val, EventsOnSelected = ((terminal.EventsOnSelected == null) ? new List() : new List(terminal.EventsOnSelected)) }); } } if (list2.Count <= 0) { list2 = ((list.Count > 0) ? new List { list[list.Count - 1] } : new List()); } if (list2.Count > 0) { TOATimedTerminalReceiverSelection tOATimedTerminalReceiverSelection = list2[tOATimedTerminalReceiverPool.PickMode switch { TOATimedTerminalPickMode.Sequential => i % list2.Count, TOATimedTerminalPickMode.RoundIndex => Math.Min(i, list2.Count - 1), _ => Builder.SessionSeedRandom.Range(0, list2.Count, "TOA_TIMED_TERMINAL_SEQUENCE"), }]; list.Add(tOATimedTerminalReceiverSelection); hashSet.Add(((Il2CppObjectBase)tOATimedTerminalReceiverSelection.Terminal).Pointer); } } return list; } private static LG_ComputerTerminal? ResolveTerminal(TOATimedTerminalReference terminalRef, string context) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Expected O, but got Unknown bool flag = default(bool); try { if (TryGetTerminalInZone(terminalRef.DimensionIndex, terminalRef.LayerType, terminalRef.LocalIndex, terminalRef.InstanceIndex, out LG_ComputerTerminal terminal)) { return terminal; } ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(151, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(context); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": terminal not found at exact configured address "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DescribeTerminalRef(terminalRef)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(". No cross-layer fallback will be used. Available terminals in configured zone: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DescribeConfiguredZoneTerminalCandidates(terminalRef)); } log.LogWarning(val); } return null; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(53, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("TimedTerminalSequence terminal lookup failed for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(DescribeTerminalRef(terminalRef)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted(ex.Message); } log.LogWarning(val); } return null; } } private static bool TryGetTerminalInZone(eDimensionIndex dimension, LG_LayerType layer, eLocalZoneIndex localIndex, int instanceIndex, out LG_ComputerTerminal? terminal) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) terminal = null; try { LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimension, layer, localIndex, ref val) || (Object)(object)val == (Object)null) { return false; } if (instanceIndex < 0 || instanceIndex >= val.TerminalsSpawnedInZone.Count) { return false; } terminal = val.TerminalsSpawnedInZone[instanceIndex]; return (Object)(object)terminal != (Object)null; } catch { terminal = null; return false; } } private static string DescribeTerminalRef(TOATimedTerminalReference terminalRef) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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) return $"({terminalRef.DimensionIndex}, {terminalRef.LayerType}, {terminalRef.LocalIndex}, {terminalRef.InstanceIndex})"; } private static string DescribeConfiguredZoneTerminalCandidates(TOATimedTerminalReference terminalRef) { //IL_000c: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) List list = new List(); try { LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(terminalRef.DimensionIndex, terminalRef.LayerType, terminalRef.LocalIndex, ref val) || (Object)(object)val == (Object)null) { return ""; } int count = val.TerminalsSpawnedInZone.Count; if (count <= 0) { return $"({terminalRef.DimensionIndex}, {terminalRef.LayerType}, {terminalRef.LocalIndex}) terminals=0"; } for (int i = 0; i < count; i++) { LG_ComputerTerminal val2 = val.TerminalsSpawnedInZone[i]; string value = (((Object)(object)val2 == (Object)null) ? "" : val2.PublicName); list.Add($"({terminalRef.DimensionIndex}, {terminalRef.LayerType}, {terminalRef.LocalIndex}, {i})={value}"); } } catch (Exception ex) { return ""; } if (list.Count != 0) { return string.Join("; ", list); } return ""; } private static TOATimedTerminalRoundOverride? GetRoundOverride(TOATimedTerminalSequenceDefinition def, int round) { return def.RoundOverrides.FirstOrDefault((TOATimedTerminalRoundOverride r) => r.RoundIndex == round); } internal static string MakeActionKey(int index, string action, int round) { return $"{"TTS"}:{index}:{action}:{round}"; } internal static bool TryParseActionKey(string key, out int index, out string action, out int round) { index = 0; action = string.Empty; round = 0; if (string.IsNullOrWhiteSpace(key)) { return false; } string[] array = key.Split(':'); if (array.Length != 4 || !string.Equals(array[0], "TTS", StringComparison.OrdinalIgnoreCase)) { return false; } if (!int.TryParse(array[1], out index) || !int.TryParse(array[3], out round)) { return false; } action = array[2].ToUpperInvariant(); return true; } private void Clear() { foreach (TOATimedTerminalSequenceRuntime value in _runtimes.Values) { value.Cleanup(); } _runtimes.Clear(); _filterByHash.Clear(); } } [HarmonyPatch] internal static class TOATimedTerminalSequenceGuiPatch { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminal), "Update")] private static void Post_LG_ComputerTerminal_Update(LG_ComputerTerminal __instance) { } } internal sealed class TOATimedTerminalSequenceDriver : MonoBehaviour { private static TOATimedTerminalSequenceDriver? _instance; internal static TOATimedTerminalSequenceDriver Ensure() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if ((Object)(object)_instance != (Object)null) { return _instance; } GameObject val = new GameObject("TOA_TimedTerminalSequenceDriver") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); return _instance; } private void Update() { TOATimedTerminalSequenceManager.Current.Tick(); } static TOATimedTerminalSequenceDriver() { ClassInjector.RegisterTypeInIl2Cpp(); } } public enum TOATimedTerminalSequenceStatus { Disabled, Waiting, InProgress, AwaitingConfirmation, Failed, Finished } public struct TOATimedTerminalSequenceSyncState { public TOATimedTerminalSequenceStatus Status; public int CurrentRound; public int ReceiverTerminalIndex; public float Deadline; public int PhaseId; } }