Decompiled source of TOA Heavy Industries v1.1.83
BeplnEx/plugins/TOA Heavy Industries/Custom/Net.6/TOA_Heavy_Industries_2.2.4.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
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 AK; 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 BoosterImplants; 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 TOA_Heavy_Industries.TOAPort; using TOA_Heavy_Industries.TOAPort.Compatibility; using TOA_Heavy_Industries.TOAPort.TOAOverride.DummyVisual; using TOA_Heavy_Industries.TOAPort.TOAOverride.DummyVisual.VisualGOAnimation; using TOA_Heavy_Industries.TOAPort.TOAOverride.DummyVisual.VisualGOAnimation.AnimationConfig; using TOA_Heavy_Industries.TOAPort.TOAOverride.DummyVisual.VisualSequenceType; using TOA_Heavy_Industries.TOAPort.TOAOverride.ExpeditionIntelNotification; using TOA_Heavy_Industries.TOAPort.TOAOverride.ExpeditionSuccessPage; using TOA_Heavy_Industries.TOAPort.TOAOverride.ResourceStations; using TOA_Heavy_Industries.TOAPort.Utils; 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.4.0")] [assembly: AssemblyInformationalVersion("2.2.4")] [assembly: AssemblyProduct("TOA_Heavy_Industries")] [assembly: AssemblyTitle("TOA_Heavy_Industries")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.2.4.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<T> where T : new() { protected readonly Dictionary<uint, GenericDefinition<T>> definitions = new Dictionary<uint, GenericDefinition<T>>(); 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<GenericDefinition<T>>(new GenericDefinition<T>())); } } private void LoadDefinitions() { foreach (string item in Directory.EnumerateFiles(DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { try { AddDefinitions(EOSJson.Deserialize<GenericDefinition<T>>(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<string>)delegate(string content) { AddDefinitions(EOSJson.Deserialize<GenericDefinition<T>>(content)); }); } private void AddDefinitions(GenericDefinition<T> definition) { if (definition != null) { definitions[definition.ID] = definition; } } public GenericDefinition<T> GetDefinition(uint id) { if (!definitions.TryGetValue(id, out GenericDefinition<T> value)) { return null; } return value; } public virtual void Init() { } } public abstract class TOAExpeditionDefinitionManager<T> where T : new() { protected readonly Dictionary<uint, GenericExpeditionDefinition<T>> definitions = new Dictionary<uint, GenericExpeditionDefinition<T>>(); 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<GenericExpeditionDefinition<T>>(new GenericExpeditionDefinition<T>())); } } private void LoadDefinitions() { foreach (string item in Directory.EnumerateFiles(DEFINITION_PATH, "*.json", SearchOption.AllDirectories)) { try { AddDefinitions(EOSJson.Deserialize<GenericExpeditionDefinition<T>>(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<string>)delegate(string content) { AddDefinitions(EOSJson.Deserialize<GenericExpeditionDefinition<T>>(content)); }); } private void AddDefinitions(GenericExpeditionDefinition<T> definition) { if (definition != null) { definitions[definition.MainLevelLayout] = definition; } } public GenericExpeditionDefinition<T> GetDefinition(uint levelLayout) { if (!definitions.TryGetValue(levelLayout, out GenericExpeditionDefinition<T> 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<CarryItemPickup_Core> { 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<LG_PickupItem>(); } } public abstract class PickupItemManager<T> where T : ItemInLevel { protected Dictionary<uint, List<T>> RegisteredItems { get; private set; } = new Dictionary<uint, List<T>>(); public virtual void Register(LG_PickupItem item) { T componentInChildren = ((Component)item.m_root).GetComponentInChildren<T>(); Register(componentInChildren); } public virtual void Register(T item) { ItemDataBlock itemDataBlock = ((Item)(object)item).ItemDataBlock; if (!RegisteredItems.TryGetValue(((GameDataBlockBase<ItemDataBlock>)(object)itemDataBlock).persistentID, out List<T> value)) { value = new List<T>(); RegisteredItems[((GameDataBlockBase<ItemDataBlock>)(object)itemDataBlock).persistentID] = value; } value.Add(item); } public virtual Dictionary<(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localIndex), List<T>> GetItemsOf(uint itemId) { if (!RegisteredItems.TryGetValue(itemId, out List<T> 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<ePickupItemStatus, List<WardenObjectiveEventData>> eventsOnState = new Dictionary<ePickupItemStatus, List<WardenObjectiveEventData>>(); public ItemInLevel Item { get; private set; } private void Setup(ItemInLevel item) { Item = item; item.GetSyncComponent().OnSyncStateChange += Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>.op_Implicit((Action<ePickupItemStatus, pPickupPlacement, PlayerAgent, bool>)OnSyncStateChange); } public bool TryGetEvents(ePickupItemStatus state, out List<WardenObjectiveEventData> 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<WardenObjectiveEventData> events)) { EOSLogger.Log($"item {((Item)Item).PublicName} on state {state}, executing {events.Count} events"); WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(events), (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)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<BigPickupCustomHelper>(); if ((Object)(object)bigPickupCustomHelper == (Object)null) { bigPickupCustomHelper = ((Component)item).gameObject.AddComponent<BigPickupCustomHelper>(); bigPickupCustomHelper.Setup(item); } foreach (BigPickupStateEvent item2 in states.OnState) { if (!bigPickupCustomHelper.eventsOnState.TryGetValue(item2.State, out List<WardenObjectiveEventData> value)) { value = new List<WardenObjectiveEventData>(); bigPickupCustomHelper.eventsOnState[item2.State] = value; } value.AddRange(item2.EventsOnState); } } static BigPickupCustomHelper() { ClassInjector.RegisterTypeInIl2Cpp<BigPickupCustomHelper>(); } } public class BigPickupCustomizationManager : EOSExt.TacticalBigPickup.FogBeacon.Generic.TOAExpeditionDefinitionManager<BigPickups> { public static BigPickupCustomizationManager Current { get; } = new BigPickupCustomizationManager(); protected override string DEFINITION_NAME => "BigPickupCustomization"; private void Build(BigPickups def) { Dictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex), List<CarryItemPickup_Core>> 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<BigPickups> 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<BigPickupFunction> Functions { get; set; } = new List<BigPickupFunction> { new BigPickupFunction() }; public List<BigPickupStateEvent> OnState { get; set; } = new List<BigPickupStateEvent> { new BigPickupStateEvent() }; } public class BigPickups { public uint ItemId { get; set; } public List<BigPickupCustomization> BigPickupItems { get; set; } = new List<BigPickupCustomization> { new BigPickupCustomization() }; } public class BigPickupStateEvent { public ePickupItemStatus State { get; set; } public List<WardenObjectiveEventData> EventsOnState { get; set; } = new List<WardenObjectiveEventData>(); } } 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<LevelSpawnedFogBeaconSettings> SpawnedBeaconsInZone { get; set; } = new List<LevelSpawnedFogBeaconSettings> { new LevelSpawnedFogBeaconSettings() }; } public class LevelSpawnedFogBeaconSettingManager : EOSExt.TacticalBigPickup.FogBeacon.Generic.TOAExpeditionDefinitionManager<LevelSpawnedFogBeaconDefinition> { public enum LSFBEvent { ToggleLevelSpawnedFogBeaconState = 922 } private Dictionary<IntPtr, LevelSpawnedFogBeaconSettings> LSFBGlobalStatesSet = new Dictionary<IntPtr, LevelSpawnedFogBeaconSettings>(); public static LevelSpawnedFogBeaconSettingManager Current { get; } protected override string DEFINITION_NAME => "LevelSpawnedFogBeacon_EOS"; private Dictionary<string, LevelSpawnedFogBeacon> LevelSpawnedFogBeacons { get; } = new Dictionary<string, LevelSpawnedFogBeacon>(); 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<WardenObjectiveEventData>)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<BigPickupFogBeaconSetting> { 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<string, CustomBigPickupFunctionImplementor> s_implementors; protected abstract string FunctionName { get; } public static void SetupCustomBigPickupFunctions(LG_PickupItem item, List<BigPickupFunction> 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<string, CustomBigPickupFunctionImplementor>(); 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<Dictionary<byte, iCarryItemWithGlobalState>>)(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<CarryItemPickup_Core>(); LG_PickupItem_Sync val2 = ((Il2CppObjectBase)componentInChildren.m_sync).Cast<LG_PickupItem_Sync>(); 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<Interact_Pickup_PickupItem>()).gameObject.SetActive(false); iTerminalItem componentInChildren2 = ((Component)LG_PickupItem).GetComponentInChildren<iTerminalItem>(); 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<HeavyFogRepellerGlobalState>(); FogRepeller_Sphere repellerSphere = GlobalState.m_repellerSphere; repellerSphere.GrowDuration = def.GrowDuration; repellerSphere.ShrinkDuration = def.ShrinkDuration; repellerSphere.Range = def.Range; HeavyFogRepellerGlobalState globalState = GlobalState; globalState.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)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<ItemDataBlock>)(object)GameDataBlockBase<ItemDataBlock>.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<BigPickupFogBeaconSetting> 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<FogRepeller_Sphere>(); val.InfiniteDuration = false; val.LifeDuration = 99999f; val.GrowDuration = 99999f; val.ShrinkDuration = 99999f; val.Range = 1f; FogRepeller_Sphere fogRepHold = new GameObject("FogInstance_Beacon_SmallLayer").AddComponent<FogRepeller_Sphere>(); 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<FogRepeller_Sphere>(); 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<CarryItemPickup_Core>(); HeavyFogRepellerPickup val2 = ((Il2CppObjectBase)componentInChildren).Cast<HeavyFogRepellerPickup>(); 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<HeavyFogRepellerGlobalState>(); ((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_Pickup_PickupItem>(); ((Interact_Timed)interact).InteractDuration = setting.TimeToPickup; val5.CallbackOnStateChange += Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>.op_Implicit((Action<pCarryItemWithGlobalState_State, pCarryItemWithGlobalState_State, bool>)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 sealed class TOABigPickupCarryOnBackConfig { public JsonElement MainLevelLayout { get; set; } public List<TOABigPickupCarryOnBackDefinition> Definitions { get; set; } = new List<TOABigPickupCarryOnBackDefinition>(); } internal sealed class TOABigPickupCarryOnBackDefinition { public bool Enabled { get; set; } = true; public uint ItemId { get; set; } public float InteractDuration { get; set; } = -1f; public float MoveSpeedMultiplier { get; set; } = 0.7f; public string SwitchBackKey { get; set; } = "Alpha8"; public string AlternateSwitchBackKey { get; set; } = "Keypad8"; internal KeyCode ParsedSwitchBackKey { get; set; } = (KeyCode)56; internal KeyCode ParsedAlternateSwitchBackKey { get; set; } = (KeyCode)264; } [HarmonyPatch(typeof(FirstPersonItemHolder), "ItemCanMoveQuick")] internal static class TOABigPickupCarryOnBackQuickMovePatch { [HarmonyPrefix] private static bool Pre_ItemCanMoveQuick(ref bool __result) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 if (TOABigPickupCarryOnBackManager.Current.IsTargetCarried() && (int)PlayerManager.GetLocalPlayerAgent().Inventory.WieldedSlot != 8) { __result = false; return false; } return true; } } [HarmonyPatch(typeof(PlayerBackpackManager), "HasItem_Local")] internal static class TOABigPickupCarryOnBackCarryStatePatch { [HarmonyPrefix] private static bool Pre_HasItem_Local(InventorySlot slot, ref bool __result) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 if ((int)slot != 8 || !TOABigPickupCarryOnBackManager.Current.IsTargetCarried()) { return true; } __result = false; return false; } } [HarmonyPatch(typeof(PlayerInventoryLocal))] internal static class TOABigPickupCarryOnBackInventoryPatches { private static void ForceWieldSlot(PlayerInventoryLocal inventory, InventorySlot slot) { //IL_000b: 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_0022: 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_0026: 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_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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) ((PlayerInventoryBase)inventory).Owner.Sync.WantsToWieldSlot(slot, false); pInventoryStatus syncedInventoryStatus = ((PlayerInventoryBase)inventory).Owner.Sync.m_syncedInventoryStatus; syncedInventoryStatus.wieldedSlot = slot; ((PlayerInventoryBase)inventory).Owner.Sync.m_syncedInventoryStatus = syncedInventoryStatus; ((PlayerInventoryBase)inventory).Owner.Sync.LastWantedSlot = syncedInventoryStatus.wieldedSlot; ((PlayerInventoryBase)inventory).Owner.Sync.m_inventoryStatusPacket.Send(syncedInventoryStatus, (SNet_ChannelType)4); ((PlayerInventoryBase)inventory).Owner.Sync.DoInventoryWield(syncedInventoryStatus); } [HarmonyPostfix] [HarmonyPatch("Awake")] private static void Post_Awake(PlayerInventoryLocal __instance) { if (TOABigPickupCarryOnBackManager.Current.HasActiveDefinitions() && !__instance.m_allowedScrollSlots.Contains((InventorySlot)8)) { __instance.m_allowedScrollSlots.Add((InventorySlot)8); } } [HarmonyPrefix] [HarmonyPatch("CheckInput")] private static bool Pre_CheckInput(PlayerInventoryLocal __instance) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Invalid comparison between Unknown and I4 //IL_00ee: 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_0102: 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_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) if ((int)((PlayerInventoryBase)__instance).WieldedSlot != 8 || !TOABigPickupCarryOnBackManager.Current.IsTargetCarried()) { return true; } if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)32, (eFocusState)0)) { ((PlayerInventoryBase)__instance).Owner.Sync.WantsToSetFlashlightEnabled(!((PlayerInventoryBase)__instance).WantsFlashlightEnabled, false); } if (((PlayerInventoryBase)__instance).Owner.FPItemHolder.ItemHiddenTrigger) { return false; } InventorySlot? val = null; if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)23, (eFocusState)0)) { val = (InventorySlot)1; } else if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)24, (eFocusState)0)) { val = (InventorySlot)2; } else if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)25, (eFocusState)0)) { val = (InventorySlot)3; } else if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)27, (eFocusState)0)) { val = (InventorySlot)4; } else if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)28, (eFocusState)0)) { val = (InventorySlot)5; } else if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)26, (eFocusState)0)) { val = (InventorySlot)10; } else if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)29, (eFocusState)0)) { val = (InventorySlot)11; } if (val.HasValue && val.Value != ((PlayerInventoryBase)__instance).WieldedSlot) { BackpackItem val2 = default(BackpackItem); if (!PlayerBackpackManager.TryGetItem(SNet.LocalPlayer, val.Value, ref val2) || val2 == null) { return false; } ItemEquippable val3 = ((Il2CppObjectBase)val2.Instance).TryCast<ItemEquippable>(); if ((Object)(object)val3 != (Object)null && val3.CanWield) { ForceWieldSlot(__instance, val.Value); __instance.m_itemScrollTimer = Clock.Time + 0.1f; } } if ((int)FocusStateManager.CurrentState != 6 && !__instance.CheckWieldingKeys() && (Object)(object)((PlayerInventoryBase)__instance).m_wieldedItem != (Object)null) { float axisKeyMouse = InputMapper.GetAxisKeyMouse((InputAction)30, (eFocusState)0); bool buttonDownKeyMouseGamepad = InputMapper.GetButtonDownKeyMouseGamepad((InputAction)31, (eFocusState)0); if ((((PlayerInventoryBase)__instance).AllowScrollInput && ((PlayerInventoryBase)__instance).m_wieldedItem.WeaponSwitchAllowed && Mathf.Abs(axisKeyMouse) > 0f && Clock.Time > __instance.m_itemScrollTimer) || buttonDownKeyMouseGamepad) { int num = ((axisKeyMouse > 0f) ? __instance.GetNextSlot(((PlayerInventoryBase)__instance).WieldedSlot, -1) : __instance.GetNextSlot(((PlayerInventoryBase)__instance).WieldedSlot, 1)); if (num > -1) { ForceWieldSlot(__instance, (InventorySlot)(byte)num); __instance.m_itemScrollTimer = Clock.Time + 0.1f; } } } if (__instance.m_FPItemHolder.ItemIsBusy) { return false; } if (InputMapper.GetButtonDownKeyMouseGamepad((InputAction)11, (eFocusState)0) && ((PlayerInventoryBase)__instance).CanReloadCurrent()) { ((PlayerInventoryBase)__instance).TriggerReload(); } return false; } [HarmonyPostfix] [HarmonyPatch("CheckInput")] private static void Post_CheckInput(PlayerInventoryLocal __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 if (!((PlayerInventoryBase)__instance).Owner.FPItemHolder.ItemHiddenTrigger && (int)FocusStateManager.CurrentState != 6 && (int)((PlayerInventoryBase)__instance).WieldedSlot != 8 && TOABigPickupCarryOnBackManager.Current.IsTargetCarried(out BackpackItem _, out TOABigPickupCarryOnBackDefinition settings) && TOABigPickupCarryOnBackManager.Current.IsSwitchBackKeyPressed(settings) && !(Clock.Time <= __instance.m_itemScrollTimer)) { ForceWieldSlot(__instance, (InventorySlot)8); __instance.m_itemScrollTimer = Clock.Time + 0.1f; } } } internal sealed class TOABigPickupCarryOnBackManager { private const string DefinitionFolderName = "BigPickupCarryOnBack"; private const string TemplateFileName = "Template.json"; private static readonly JsonSerializerOptions SerializerOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, AllowTrailingCommas = true, ReadCommentHandling = JsonCommentHandling.Skip, WriteIndented = true }; private readonly string _definitionPath = TOAConfigPaths.GetFeaturePath("BigPickupCarryOnBack"); private Dictionary<uint, Dictionary<uint, TOABigPickupCarryOnBackDefinition>> _definitions = new Dictionary<uint, Dictionary<uint, TOABigPickupCarryOnBackDefinition>>(); private LiveEditListener? _liveEditListener; internal static TOABigPickupCarryOnBackManager Current { get; } = new TOABigPickupCarryOnBackManager(); private TOABigPickupCarryOnBackManager() { } 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(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack definitions path: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(_definitionPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(36, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("BigPickupCarryOnBack Init failed: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogError(val2); } } } internal bool HasActiveDefinitions() { if (TryGetActiveDefinitions(out Dictionary<uint, TOABigPickupCarryOnBackDefinition> definitions)) { return definitions.Count > 0; } return false; } internal bool TryGetSettings(uint itemId, out TOABigPickupCarryOnBackDefinition settings) { settings = null; if (!TryGetActiveDefinitions(out Dictionary<uint, TOABigPickupCarryOnBackDefinition> definitions) || !definitions.TryGetValue(itemId, out var value) || !value.Enabled) { return false; } settings = value; return true; } internal bool IsTargetCarried() { BackpackItem carryItem; TOABigPickupCarryOnBackDefinition settings; return IsTargetCarried(out carryItem, out settings); } internal bool IsTargetCarried(out BackpackItem carryItem, out TOABigPickupCarryOnBackDefinition settings) { carryItem = null; settings = null; try { return PlayerBackpackManager.TryGetItem(SNet.LocalPlayer, (InventorySlot)8, ref carryItem) && carryItem != null && TryGetSettings(carryItem.ItemID, out settings); } catch { carryItem = null; settings = null; return false; } } internal bool IsSwitchBackKeyPressed(TOABigPickupCarryOnBackDefinition settings) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (!Input.GetKeyDown(settings.ParsedSwitchBackKey)) { return Input.GetKeyDown(settings.ParsedAlternateSwitchBackKey); } return true; } private bool TryGetActiveDefinitions(out Dictionary<uint, TOABigPickupCarryOnBackDefinition> definitions) { definitions = null; try { uint levelLayoutData = RundownManager.ActiveExpedition.LevelLayoutData; if (!_definitions.TryGetValue(levelLayoutData, out Dictionary<uint, TOABigPickupCarryOnBackDefinition> value)) { return false; } definitions = value; return true; } catch { return false; } } private void EnsureDefinitionPath() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown Directory.CreateDirectory(_definitionPath); string text = Path.Combine(_definitionPath, "Template.json"); if (File.Exists(text)) { return; } string contents = "{\n \"MainLevelLayout\": 0,\n \"Definitions\": [\n {\n \"Enabled\": false,\n \"ItemId\": 0,\n \"InteractDuration\": 1.5,\n \"MoveSpeedMultiplier\": 0.7,\n \"SwitchBackKey\": \"Alpha8\",\n \"AlternateSwitchBackKey\": \"Keypad8\"\n }\n ]\n}\n"; File.WriteAllText(text, contents); ManualLogSource log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExMessageLogInterpolatedStringHandler val = new BepInExMessageLogInterpolatedStringHandler(44, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack template generated: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } } private void FileChanged(LiveEditEventArgs e) { //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(47, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack LiveEdit file changed: '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.FullPath); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("'."); } log.LogMessage(val); } ReloadDefinitionsFromDisk(); } private void ReloadDefinitionsFromDisk() { //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown Dictionary<uint, Dictionary<uint, TOABigPickupCarryOnBackDefinition>> dictionary = new Dictionary<uint, Dictionary<uint, TOABigPickupCarryOnBackDefinition>>(); int num = 0; int num2 = 0; bool flag = default(bool); ManualLogSource log; foreach (string item in Directory.EnumerateFiles(_definitionPath, "*.json", SearchOption.AllDirectories).OrderBy<string, string>((string path) => path, StringComparer.OrdinalIgnoreCase)) { if (TryLoadFile(item, out uint layoutId, out List<TOABigPickupCarryOnBackDefinition> definitions)) { if (!dictionary.TryGetValue(layoutId, out var value)) { value = (dictionary[layoutId] = new Dictionary<uint, TOABigPickupCarryOnBackDefinition>()); } foreach (TOABigPickupCarryOnBackDefinition item2 in definitions) { if (!item2.Enabled || item2.ItemId == 0) { continue; } if (value.ContainsKey(item2.ItemId)) { log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(89, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack duplicate MainLevelLayout="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(layoutId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", ItemId="); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<uint>(item2.ItemId); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("; later file '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(item); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' takes precedence."); } log.LogWarning(val); } } value[item2.ItemId] = item2; } num++; } else { num2++; } } _definitions = dictionary; string text = ((dictionary.Count == 0) ? "<none>" : string.Join(",", dictionary.Keys.OrderBy((uint id) => id))); log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(91, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("BigPickupCarryOnBack config reload complete. FilesLoaded="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", FilesFailed="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(num2); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", MainLevelLayouts="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } } private bool TryLoadFile(string file, out uint layoutId, out List<TOABigPickupCarryOnBackDefinition> definitions) { //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown layoutId = 0u; definitions = new List<TOABigPickupCarryOnBackDefinition>(); bool flag2 = default(bool); try { TOABigPickupCarryOnBackConfig tOABigPickupCarryOnBackConfig = JsonSerializer.Deserialize<TOABigPickupCarryOnBackConfig>(File.ReadAllText(file), SerializerOptions); ManualLogSource log; if (tOABigPickupCarryOnBackConfig == null || !TOATimedTerminalSequenceManager.TryResolveMainLevelLayoutForExternalConfig(tOABigPickupCarryOnBackConfig.MainLevelLayout, out layoutId, out string resolvedBy)) { log = TOARuntime.Log; if (log != null) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(62, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has an invalid MainLevelLayout."); } log.LogError(val); } return false; } definitions = tOABigPickupCarryOnBackConfig.Definitions ?? new List<TOABigPickupCarryOnBackDefinition>(); foreach (TOABigPickupCarryOnBackDefinition definition in definitions) { PrepareDefinition(definition, file); } log = TOARuntime.Log; if (log != null) { BepInExMessageLogInterpolatedStringHandler val2 = new BepInExMessageLogInterpolatedStringHandler(77, 4, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("BigPickupCarryOnBack config '"); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(file); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("' MainLevelLayout resolved as "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<uint>(layoutId); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ("); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(resolvedBy); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("), Definitions="); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(definitions.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("."); } log.LogMessage(val2); } return true; } catch (Exception ex) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(52, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack config reload failed for '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("': "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } log.LogError(val); } return false; } } private static void PrepareDefinition(TOABigPickupCarryOnBackDefinition definition, string file) { //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown //IL_00e4: 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_00a0: Expected O, but got Unknown definition.MoveSpeedMultiplier = Mathf.Max(0f, definition.MoveSpeedMultiplier); bool flag = default(bool); if (!Enum.TryParse<KeyCode>(definition.SwitchBackKey, ignoreCase: true, out KeyCode result)) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(74, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has invalid SwitchBackKey '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(definition.SwitchBackKey); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', using Alpha8."); } log.LogWarning(val); } result = (KeyCode)56; } if (!Enum.TryParse<KeyCode>(definition.AlternateSwitchBackKey, ignoreCase: true, out KeyCode result2)) { ManualLogSource log = TOARuntime.Log; if (log != null) { BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(84, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("BigPickupCarryOnBack config '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(file); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("' has invalid AlternateSwitchBackKey '"); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(definition.AlternateSwitchBackKey); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("', using Keypad8."); } log.LogWarning(val); } result2 = (KeyCode)264; } definition.ParsedSwitchBackKey = result; definition.ParsedAlternateSwitchBackKey = result2; } } [HarmonyPatch(typeof(PLOC_Base), "GetHorizontalVelocityFromInput")] internal static class TOABigPickupCarryOnBackMovementPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Post_GetHorizontalVelocityFromInput(PLOC_Base __instance, ref Vector3 __result) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Invalid comparison between Unknown and I4 //IL_0038: 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) if (__instance.m_owner.Owner.IsLocal && TOABigPickupCarryOnBackManager.Current.IsTargetCarried(out BackpackItem _, out TOABigPickupCarryOnBackDefinition settings) && (int)__instance.m_owner.Inventory.WieldedSlot != 8) { __result *= settings.MoveSpeedMultiplier; } } } [HarmonyPatch(typeof(LG_PickupItem), "SetupBigPickupItemWithItemId")] internal static class TOABigPickupCarryOnBackSetupPatch { [HarmonyPostfix] private static void Post_SetupBigPickupItemWithItemId(LG_PickupItem __instance, uint itemId) { if (TOABigPickupCarryOnBackManager.Current.TryGetSettings(itemId, out TOABigPickupCarryOnBackDefinition settings) && !(settings.InteractDuration < 0f)) { CarryItemPickup_Core componentInChildren = ((Component)__instance.m_root).GetComponentInChildren<CarryItemPickup_Core>(); Interact_Pickup_PickupItem val = ((componentInChildren != null) ? ((Il2CppObjectBase)componentInChildren.m_interact).Cast<Interact_Pickup_PickupItem>() : null); if ((Object)(object)val != (Object)null) { ((Interact_Timed)val).InteractDuration = settings.InteractDuration; } } } } 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<string, uint>? _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<string, uint> 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<BasePlugin>)(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<string, uint> ReadPersistentIdFile(string idFilePath) { Dictionary<string, uint> dictionary = new Dictionary<string, uint>(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*\\\"(?<guid>(?:\\\\.|[^\\\"])*)\\\"[^{}]*\\\"ID\\\"\\s*:\\s*(?<id>\\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<uint> OfflineIDs = new HashSet<uint>(); internal readonly HashSet<string> LevelLayoutIDStrings = new HashSet<string>(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<TOALevelRule> Levels = new List<TOALevelRule>(); } 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<TOAConfigDocument> _configs = new List<TOAConfigDocument>(); private static readonly List<string> _configPaths = new List<string>(); private static readonly List<FileSystemWatcher> _watchers = new List<FileSystemWatcher>(); 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) ? "<none>" : string.Join(" | ", _configPaths); } } } internal static IReadOnlyList<TOAConfigDocument> 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<string> list = DiscoverExistingConfigPaths().ToList(); if (list.Count == 0) { list = CreateDefaultConfigsInCandidateRundownFolders(log).ToList(); } string text = BuildConfigStamp(list); if (!force && text == _lastConfigStamp) { return; } List<TOAConfigDocument> list2 = new List<TOAConfigDocument>(); 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<string>(item); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<Exception>(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<Exception>(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<TOALevelRule> ReadLevelRules(string json) { List<string> list = new List<string>(); 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<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string configPath in _configPaths) { string directoryName = Path.GetDirectoryName(configPath); if (!string.IsNullOrWhiteSpace(directoryName) && Directory.Exists(directoryName)) { hashSet.Add(directoryName); } } using HashSet<string>.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<string>(ex.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(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<string> DiscoverExistingConfigPaths() { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (string item in EnumerateFilesSafe(TOAConfigPaths.GetFeaturePath("GearSwap"), "*.json", SearchOption.TopDirectoryOnly)) { hashSet.Add(Path.GetFullPath(item)); } return hashSet.OrderBy<string, string>((string p) => p, StringComparer.OrdinalIgnoreCase); } private static IEnumerable<string> CreateDefaultConfigsInCandidateRundownFolders(ManualLogSource? log) { HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); hashSet.Add(TOAConfigPaths.GetFeaturePath("GearSwap")); foreach (string item in hashSet.OrderBy<string, string>((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<string> DiscoverRundownCustomRoots() { HashSet<string> hashSet = new HashSet<string>(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, string>((string p) => p, StringComparer.OrdinalIgnoreCase); } private static IEnumerable<string> EnumerateDirectoriesSafe(string root, string searchPattern, SearchOption option) { if (!Directory.Exists(root)) { return Array.Empty<string>(); } try { return Directory.EnumerateDirectories(root, searchPattern, option).ToArray(); } catch { return Array.Empty<string>(); } } private static IEnumerable<string> EnumerateFilesSafe(string root, string searchPattern, SearchOption option) { if (!Directory.Exists(root)) { return Array.Empty<string>(); } try { return (from path in Directory.EnumerateFiles(root, searchPattern, option) where !ShouldIgnoreConfigFile(path) select path).ToArray(); } catch { return Array.Empty<string>(); } } 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<string> configPaths) { StringBuilder stringBuilder = new StringBuilder(); foreach (string item in configPaths.OrderBy<string, string>((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*\\\"(?<value>(?:\\\\.|[^\\\"])*)\\\"", 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<uint> numericTarget, HashSet<string> 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<uint> numericTarget, HashSet<string> 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<string> 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<string> ReadArrayStringItems(string arrayContent) { foreach (string item in ReadTopLevelArrayScalarItems(arrayContent)) { if (!uint.TryParse(item.Trim(), out var _)) { yield return item; } } } private static IEnumerable<string> 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<string> 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<Renderer> _visualRenderers = new List<Renderer>(); 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<TOAEventScanStatus> 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 '");