Decompiled source of ExtraObjectiveSetup v1.6.4
plugins/Inas07.ExtraObjectiveSetup.dll
Decompiled a week 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.Concurrent; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; using AIGraph; using AK; using Agents; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Utils.Collections; using ChainedPuzzles; using Enemies; using ExtraObjectiveSetup.BaseClasses; using ExtraObjectiveSetup.BaseClasses.CustomTerminalDefinition; using ExtraObjectiveSetup.Expedition; using ExtraObjectiveSetup.Expedition.Gears; using ExtraObjectiveSetup.Expedition.IndividualGeneratorGroup; using ExtraObjectiveSetup.ExtendedWardenEvents; using ExtraObjectiveSetup.Instances; using ExtraObjectiveSetup.Instances.ChainedPuzzle; using ExtraObjectiveSetup.JSON; using ExtraObjectiveSetup.Objectives.ActivateSmallHSU; using ExtraObjectiveSetup.Objectives.GeneratorCluster; using ExtraObjectiveSetup.Objectives.IndividualGenerator; using ExtraObjectiveSetup.Objectives.ObjectiveCounter; using ExtraObjectiveSetup.Objectives.TerminalUplink; using ExtraObjectiveSetup.Tweaks.BossEvents; using ExtraObjectiveSetup.Tweaks.Scout; using ExtraObjectiveSetup.Tweaks.TerminalPosition; using ExtraObjectiveSetup.Tweaks.TerminalTweak; using ExtraObjectiveSetup.Utils; using FloLib.Networks.Replications; using GTFO.API; using GTFO.API.Extensions; using GTFO.API.JSON.Converters; using GTFO.API.Utilities; using GameData; using Gear; using HarmonyLib; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Localization; using MTFO.API; using Microsoft.CodeAnalysis; using Player; using SNetwork; using StateMachines; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("Inas07.ExtraObjectiveSetup")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+0ed85c89f89e18967872da5c48fee511edd6ad21")] [assembly: AssemblyProduct("Inas07.ExtraObjectiveSetup")] [assembly: AssemblyTitle("Inas07.ExtraObjectiveSetup")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ExtraObjectiveSetup { public static class EOSNetworking { public const uint INVALID_ID = 0u; public const uint FOREVER_REPLICATOR_ID_START = 1000u; public const uint REPLICATOR_ID_START = 10000u; private static uint currentForeverID; private static uint currentID; private static HashSet<uint> foreverUsedIDs; private static HashSet<uint> usedIDs; public static uint AllotReplicatorID() { while (currentID >= 10000 && usedIDs.Contains(currentID)) { currentID++; } if (currentID < 10000) { EOSLogger.Error("Replicator ID depleted. How?"); return 0u; } uint num = currentID; usedIDs.Add(num); currentID++; return num; } public static bool TryAllotID(uint id) { return usedIDs.Add(id); } public static uint AllotForeverReplicatorID() { while (currentForeverID < 10000 && foreverUsedIDs.Contains(currentForeverID)) { currentForeverID++; } if (currentForeverID >= 10000) { EOSLogger.Error("Forever Replicator ID depleted."); return 0u; } uint num = currentForeverID; foreverUsedIDs.Add(num); currentForeverID++; return num; } private static void Clear() { usedIDs.Clear(); currentID = 10000u; } public static void ClearForever() { foreverUsedIDs.Clear(); currentForeverID = 1000u; } static EOSNetworking() { currentForeverID = 1000u; currentID = 10000u; foreverUsedIDs = new HashSet<uint>(); usedIDs = new HashSet<uint>(); LevelAPI.OnBuildStart += Clear; LevelAPI.OnLevelCleanup += Clear; } } public sealed class BatchBuildManager { private Dictionary<BatchName, Action> OnBatchDone = new Dictionary<BatchName, Action>(); public static BatchBuildManager Current { get; private set; } public void Init() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (OnBatchDone.Count > 0) { return; } foreach (object value in Enum.GetValues(typeof(BatchName))) { OnBatchDone[(BatchName)value] = null; } } public void Add_OnBatchDone(BatchName batchName, Action action) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Dictionary<BatchName, Action> onBatchDone = OnBatchDone; onBatchDone[batchName] = (Action)Delegate.Combine(onBatchDone[batchName], action); } public void Remove_OnBatchDone(BatchName batchName, Action action) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) Dictionary<BatchName, Action> onBatchDone = OnBatchDone; onBatchDone[batchName] = (Action)Delegate.Remove(onBatchDone[batchName], action); } public Action Get_OnBatchDone(BatchName batchName) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) return OnBatchDone[batchName]; } private BatchBuildManager() { } static BatchBuildManager() { Current = new BatchBuildManager(); } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("Inas.ExtraObjectiveSetup", "ExtraObjectiveSetup", "1.6.4")] public class EntryPoint : BasePlugin { public const string AUTHOR = "Inas"; public const string PLUGIN_NAME = "ExtraObjectiveSetup"; public const string VERSION = "1.6.4"; private Harmony m_Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown m_Harmony = new Harmony("ExtraObjectiveSetup"); m_Harmony.PatchAll(); SetupManagers(); } private void SetupManagers() { BatchBuildManager.Current.Init(); IndividualGeneratorObjectiveManager.Current.Init(); GeneratorClusterObjectiveManager.Current.Init(); HSUActivatorObjectiveManager.Current.Init(); UplinkObjectiveManager.Current.Init(); TerminalPositionOverrideManager.Current.Init(); ScoutScreamEventManager.Current.Init(); BossDeathEventManager.Current.Init(); ExpeditionDefinitionManager.Current.Init(); ExpeditionGearManager.Current.Init(); ExpeditionIGGroupManager.Current.Init(); GeneratorClusterInstanceManager.Current.Init(); HSUActivatorInstanceManager.Current.Init(); PowerGeneratorInstanceManager.Current.Init(); TerminalInstanceManager.Current.Init(); ObjectiveCounterManager.Current.Init(); } } } namespace ExtraObjectiveSetup.Utils { public static class EOSTerminalUtils { public static List<LG_ComputerTerminal> FindTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, Predicate<LG_ComputerTerminal> predicate) { //IL_0005: 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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) LG_Zone val = default(LG_Zone); if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"SelectTerminal: Could NOT find zone {(dimensionIndex, layerType, localIndex)}"); return null; } if (val.TerminalsSpawnedInZone.Count <= 0) { EOSLogger.Error($"SelectTerminal: Could not find any terminals in zone {(dimensionIndex, layerType, localIndex)}"); return null; } List<LG_ComputerTerminal> list = new List<LG_ComputerTerminal>(); Enumerator<LG_ComputerTerminal> enumerator = val.TerminalsSpawnedInZone.GetEnumerator(); while (enumerator.MoveNext()) { LG_ComputerTerminal current = enumerator.Current; if (predicate != null) { if (predicate(current)) { list.Add(current); } } else { list.Add(current); } } return list; } public static TerminalLogFileData GetLocalLog(this LG_ComputerTerminal terminal, string logName) { Dictionary<string, TerminalLogFileData> localLogs = terminal.GetLocalLogs(); logName = logName.ToUpperInvariant(); if (!localLogs.ContainsKey(logName)) { return null; } return localLogs[logName]; } public static void ResetInitialOutput(this LG_ComputerTerminal terminal) { terminal.m_command.ClearOutputQueueAndScreenBuffer(); terminal.m_command.AddInitialTerminalOutput(); if (terminal.IsPasswordProtected) { terminal.m_command.AddPasswordProtectedOutput((Il2CppStringArray)null); } } public static List<WardenObjectiveEventData> GetUniqueCommandEvents(this LG_ComputerTerminal terminal, string command) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected I4, but got Unknown //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) List<WardenObjectiveEventData> result = new List<WardenObjectiveEventData>(); if ((Object)(object)terminal.ConnectedReactor != (Object)null) { return result; } uint num = 0u; if (terminal.SpawnNode.m_dimension.IsMainDimension) { LG_LayerType layerType = terminal.SpawnNode.LayerType; switch ((int)layerType) { case 0: num = RundownManager.ActiveExpedition.LevelLayoutData; break; case 1: num = RundownManager.ActiveExpedition.SecondaryLayout; break; case 2: num = RundownManager.ActiveExpedition.ThirdLayout; break; default: EOSLogger.Error($"GetCommandEvents: Unimplemented layer type {terminal.SpawnNode.LayerType}"); return result; } } else { num = terminal.SpawnNode.m_dimension.DimensionData.LevelLayoutData; } LevelLayoutDataBlock block = GameDataBlockBase<LevelLayoutDataBlock>.GetBlock(num); if (block == null) { EOSLogger.Error($"GetCommandEvents: {terminal.ItemKey} is in {terminal.SpawnNode.LayerType}, {terminal.SpawnNode.m_dimension.DimensionIndex} but its LevelLayoutData is not found!"); return result; } int num2 = terminal.SpawnNode.m_zone.TerminalsSpawnedInZone.IndexOf(terminal); ExpeditionZoneData val = null; Enumerator<ExpeditionZoneData> enumerator = block.Zones.GetEnumerator(); while (enumerator.MoveNext()) { ExpeditionZoneData current = enumerator.Current; if (current.LocalIndex == terminal.SpawnNode.m_zone.LocalIndex) { val = current; break; } } if (val == null) { EOSLogger.Error("GetCommandEvents: Cannot find target zone data."); return result; } if (num2 >= val.TerminalPlacements.Count) { EOSLogger.Debug("GetCommandEvents: TerminalDataIndex >= TargetZoneData.TerminalPlacements.Count: found a custom terminal, skipped"); return result; } Enumerator<CustomTerminalCommand> enumerator2 = val.TerminalPlacements[num2].UniqueCommands.GetEnumerator(); while (enumerator2.MoveNext()) { CustomTerminalCommand current2 = enumerator2.Current; if (current2.Command.ToLower().Equals(command.ToLower())) { return current2.CommandEvents.ToManaged<WardenObjectiveEventData>(); } } EOSLogger.Error("GetCommandEvents: command '" + command + "' not found on " + terminal.ItemKey); return result; } public static LG_ComputerTerminal SelectPasswordTerminal(eDimensionIndex dimensionIndex, LG_LayerType layerType, eLocalZoneIndex localIndex, eSeedType seedType, int staticSeed = 1) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) //IL_0073: 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) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Expected I4, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) if ((int)seedType == 0) { EOSLogger.Error($"SelectTerminal: unsupported seed type {seedType}"); return null; } List<LG_ComputerTerminal> list = FindTerminal(dimensionIndex, layerType, localIndex, (LG_ComputerTerminal x) => !x.HasPasswordPart); if (list == null) { EOSLogger.Error($"SelectTerminal: Could not find zone {(dimensionIndex, layerType, localIndex)}!"); return null; } if (list.Count <= 0) { EOSLogger.Error($"SelectTerminal: Could not find any terminals without a password part in zone {(dimensionIndex, layerType, localIndex)}, putting the password on random (session) already used terminal."); LG_Zone val = default(LG_Zone); Builder.CurrentFloor.TryGetZoneByLocalIndex(dimensionIndex, layerType, localIndex, ref val); return val.TerminalsSpawnedInZone[Builder.SessionSeedRandom.Range(0, val.TerminalsSpawnedInZone.Count, "NO_TAG")]; } switch (seedType - 1) { case 0: return list[Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG")]; case 1: return list[Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG")]; case 2: Random.InitState(staticSeed); return list[Random.Range(0, list.Count)]; default: EOSLogger.Error("SelectTerminal: did not have a valid SeedType!!"); return null; } } public static void BuildPassword(LG_ComputerTerminal terminal, TerminalPasswordData data) { //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: 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_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_049e: Unknown result type (might be due to invalid IL or missing references) //IL_04c0: Unknown result type (might be due to invalid IL or missing references) //IL_04cc: Expected O, but got Unknown //IL_04ce: Expected O, but got Unknown if (!data.PasswordProtected) { return; } if (terminal.IsPasswordProtected) { EOSLogger.Error("EOSTerminalUtils.BuildPassword: " + terminal.PublicName + " is already password-protected!"); return; } if (!data.GeneratePassword) { terminal.LockWithPassword(data.Password, new string[1] { data.PasswordHintText }); return; } if (data.TerminalZoneSelectionDatas.Count <= 0) { EOSLogger.Error($"Tried to generate a password for terminal {terminal.PublicName} with no {typeof(TerminalZoneSelectionData).Name}!! This is not allowed."); return; } string codeWord = SerialGenerator.GetCodeWord(); string passwordHintText = data.PasswordHintText; string text = "<b>[Forgot your password?]</b> Backup security key(s) located in logs on "; int num = data.PasswordPartCount; if (codeWord.Length % num != 0) { EOSLogger.Error($"Build() password.Length ({codeWord.Length}) not divisible by passwordParts ({num}). Defaulting to 1."); num = 1; } string[] array = ((num > 1) ? Il2CppArrayBase<string>.op_Implicit((Il2CppArrayBase<string>)(object)StringUtils.SplitIntoChunksArray(codeWord, codeWord.Length / num)) : new string[1] { codeWord }); string text2 = ""; if (data.ShowPasswordPartPositions) { for (int i = 0; i < array[0].Length; i++) { text2 += "-"; } } HashSet<LG_ComputerTerminal> hashSet = new HashSet<LG_ComputerTerminal>(); LG_Zone val = default(LG_Zone); for (int j = 0; j < num; j++) { int index = j % data.TerminalZoneSelectionDatas.Count; List<CustomTerminalZoneSelectionData> list = data.TerminalZoneSelectionDatas[index]; int index2 = Builder.SessionSeedRandom.Range(0, list.Count, "NO_TAG"); CustomTerminalZoneSelectionData customTerminalZoneSelectionData = list[index2]; LG_ComputerTerminal val2; if ((int)customTerminalZoneSelectionData.SeedType == 0) { if (!Builder.CurrentFloor.TryGetZoneByLocalIndex(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, ref val) || (Object)(object)val == (Object)null) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}"); } if (val.TerminalsSpawnedInZone.Count <= 0) { EOSLogger.Error($"BuildPassword: seedType {0} specified but cannot find terminal zone {customTerminalZoneSelectionData.GlobalZoneIndexTuple()}"); } val2 = val.TerminalsSpawnedInZone[customTerminalZoneSelectionData.TerminalIndex]; } else { val2 = SelectPasswordTerminal(customTerminalZoneSelectionData.DimensionIndex, customTerminalZoneSelectionData.LayerType, customTerminalZoneSelectionData.LocalIndex, customTerminalZoneSelectionData.SeedType); } if ((Object)(object)val2 == (Object)null) { EOSLogger.Error($"BuildPassword: CRITICAL ERROR, could not get a LG_ComputerTerminal for password part ({j + 1}/{num}) for {terminal.PublicName} backup log."); continue; } string text3 = ""; string text4; if (data.ShowPasswordPartPositions) { for (int k = 0; k < j; k++) { text3 += text2; } text4 = text3 + array[j]; for (int l = j; l < num - 1; l++) { text4 += text2; } } else { text4 = array[j]; } string value = (data.ShowPasswordPartPositions ? $"0{j + 1}" : $"0{Builder.SessionSeedRandom.Range(0, 9, "NO_TAG")}"); TerminalLogFileData val3 = new TerminalLogFileData { FileName = $"key{value}_{LG_TerminalPasswordLinkerJob.GetTerminalNumber(terminal)}{(val2.HasPasswordPart ? "_1" : "")}.LOG", FileContent = new LocalizedText { UntranslatedText = string.Format(Text.Get((num > 1) ? 1431221909u : 2260297836u), text4), Id = 0u } }; val2.AddLocalLog(val3, true); if (!hashSet.Contains(val2)) { if (j > 0) { text += ", "; } text = text + val2.PublicName + " in " + val2.SpawnNode.m_zone.AliasName; } hashSet.Add(val2); val2.HasPasswordPart = true; } string text5 = text + "."; if (data.ShowPasswordLength) { terminal.LockWithPassword(codeWord, new string[3] { passwordHintText, text5, "Char[" + codeWord.Length + "]" }); } else { terminal.LockWithPassword(codeWord, new string[2] { passwordHintText, text5 }); } } public static void AddUniqueCommand(LG_ComputerTerminal terminal, CustomCommand cmd) { //IL_0053: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) if (terminal.m_command.m_commandsPerString.ContainsKey(cmd.Command)) { EOSLogger.Error("Duplicate command name: '" + cmd.Command + "', cannot add command"); return; } TERM_Command val = default(TERM_Command); if (!terminal.m_command.TryGetUniqueCommandSlot(ref val)) { EOSLogger.Error("Cannot get more unique command slot, max: 5"); return; } terminal.m_command.AddCommand(val, cmd.Command, cmd.CommandDesc, cmd.SpecialCommandRule, ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents), ListExtensions.ToIl2Cpp<TerminalOutput>(cmd.PostCommandOutputs)); for (int i = 0; i < cmd.CommandEvents.Count; i++) { WardenObjectiveEventData val2 = cmd.CommandEvents[i]; if (val2.ChainPuzzle == 0) { continue; } ChainedPuzzleDataBlock block = GameDataBlockBase<ChainedPuzzleDataBlock>.GetBlock(val2.ChainPuzzle); if (block == null) { continue; } LG_Area val3; Transform val4; if (terminal.SpawnNode != null) { val3 = terminal.SpawnNode.m_area; val4 = terminal.m_wardenObjectiveSecurityScanAlign; } else { LG_WardenObjective_Reactor connectedReactor = terminal.ConnectedReactor; object obj; if (connectedReactor == null) { obj = null; } else { AIG_CourseNode spawnNode = connectedReactor.SpawnNode; obj = ((spawnNode != null) ? spawnNode.m_area : null); } if (obj == null) { obj = null; } val3 = (LG_Area)obj; LG_WardenObjective_Reactor connectedReactor2 = terminal.ConnectedReactor; val4 = ((connectedReactor2 != null) ? connectedReactor2.m_chainedPuzzleAlign : null) ?? null; } if ((Object)(object)val3 == (Object)null) { EOSLogger.Error("Terminal Source Area is not found! Cannot create chained puzzle for command " + cmd.Command + "!"); continue; } ChainedPuzzleInstance val5 = ChainedPuzzleManager.CreatePuzzleInstance(block, val3, val4.position, val4, val2.UseStaticBioscanPoints); List<WardenObjectiveEventData> events = ListExtensions.ToIl2Cpp<WardenObjectiveEventData>(cmd.CommandEvents.GetRange(i, cmd.CommandEvents.Count - i)); val5.OnPuzzleSolved += Action.op_Implicit((Action)delegate { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(events, (eWardenObjectiveEventTrigger)0, true, 0f, (Il2CppStructArray<eWardenObjectiveEventType>)null); }); terminal.SetChainPuzzleForCommand(val, i, val5); } } } public static class EOSUtils { public static List<T> ToManaged<T>(this List<T> il2cppList) { List<T> list = new List<T>(); Enumerator<T> enumerator = il2cppList.GetEnumerator(); while (enumerator.MoveNext()) { T current = enumerator.Current; list.Add(current); } return list; } public static void ResetProgress(this ChainedPuzzleInstance chainedPuzzle) { //IL_0014: 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_0023: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: 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) if (chainedPuzzle.Data.DisableSurvivalWaveOnComplete) { chainedPuzzle.m_sound = new CellSoundPlayer(chainedPuzzle.m_parent.position); } foreach (iChainedPuzzleCore item in (Il2CppArrayBase<iChainedPuzzleCore>)(object)chainedPuzzle.m_chainedPuzzleCores) { ResetChild(item); } if (SNet.IsMaster) { pChainedPuzzleState state = chainedPuzzle.m_stateReplicator.State; pChainedPuzzleState val = default(pChainedPuzzleState); val.status = (eChainedPuzzleStatus)0; val.currentSurvivalWave_EventID = state.currentSurvivalWave_EventID; val.isSolved = false; val.isActive = false; pChainedPuzzleState val2 = val; chainedPuzzle.m_stateReplicator.InteractWithState(val2, new pChainedPuzzleInteraction { type = (eChainedPuzzleInteraction)2 }); } static void ResetChild(iChainedPuzzleCore ICore) { CP_Bioscan_Core val3 = ((Il2CppObjectBase)ICore).TryCast<CP_Bioscan_Core>(); if ((Object)(object)val3 != (Object)null) { ((Il2CppObjectBase)val3.m_spline).Cast<CP_Holopath_Spline>(); ((Il2CppObjectBase)val3.PlayerScanner).Cast<CP_PlayerScanner>().ResetScanProgression(0f); val3.Deactivate(); } else { CP_Cluster_Core val4 = ((Il2CppObjectBase)ICore).TryCast<CP_Cluster_Core>(); if ((Object)(object)val4 == (Object)null) { EOSLogger.Error("ResetChild: found iChainedPuzzleCore that is neither CP_Bioscan_Core nor CP_Cluster_Core..."); } else { ((Il2CppObjectBase)val4.m_spline).Cast<CP_Holopath_Spline>(); foreach (iChainedPuzzleCore item2 in (Il2CppArrayBase<iChainedPuzzleCore>)(object)val4.m_childCores) { ResetChild(item2); } val4.Deactivate(); } } } } } public class EOSColor { public float r { get; set; } public float g { get; set; } public float b { get; set; } public float a { get; set; } = 1f; public Color ToUnityColor() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Color(r, g, b, a); } } public static class VanillaTMPPros { public const string VANILLA_CP_PREFAB_PATH = "Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab"; public static GameObject Instantiate(GameObject parent = null) { GameObject loadedAsset = AssetAPI.GetLoadedAsset<GameObject>("Assets/AssetPrefabs/Complex/Generic/ChainedPuzzles/CP_Bioscan_sustained_RequireAll.prefab"); if ((Object)(object)loadedAsset == (Object)null) { EOSLogger.Error("VanillaTMPPros.Instantiate: Cannot find TMPPro from vanilla CP!"); return null; } GameObject gameObject = ((Component)loadedAsset.transform.GetChild(0).GetChild(1).GetChild(0)).gameObject; if (!((Object)(object)parent != (Object)null)) { return Object.Instantiate<GameObject>(gameObject.gameObject); } return Object.Instantiate<GameObject>(gameObject.gameObject, parent.transform); } } public class Vec4 : Vec3 { [JsonPropertyOrder(-9)] public float w { get; set; } public Vector4 ToVector4() { //IL_0018: Unknown result type (might be due to invalid IL or missing references) return new Vector4(base.x, base.y, base.z, w); } } public class Vec3 { [JsonPropertyOrder(-10)] public float x { get; set; } [JsonPropertyOrder(-10)] public float y { get; set; } [JsonPropertyOrder(-10)] public float z { get; set; } public Vector3 ToVector3() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return new Vector3(x, y, z); } public Quaternion ToQuaternion() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) return Quaternion.Euler(x, y, z); } } public static class EOSLogger { private static ManualLogSource logger = Logger.CreateLogSource("ExtraObjectiveSetup"); public static void Log(string format, params object[] args) { Log(string.Format(format, args)); } public static void Log(string str) { if (logger != null) { logger.Log((LogLevel)8, (object)str); } } public static void Warning(string format, params object[] args) { Warning(string.Format(format, args)); } public static void Warning(string str) { if (logger != null) { logger.Log((LogLevel)4, (object)str); } } public static void Error(string format, params object[] args) { Error(string.Format(format, args)); } public static void Error(string str) { if (logger != null) { logger.Log((LogLevel)2, (object)str); } } public static void Debug(string format, params object[] args) { Debug(string.Format(format, args)); } public static void Debug(string str) { if (logger != null) { logger.Log((LogLevel)32, (object)str); } } } } namespace ExtraObjectiveSetup.Tweaks.TerminalTweak { public struct TerminalState { public bool Enabled; public TerminalState() { Enabled = true; } public TerminalState(bool Enabled) { this.Enabled = true; this.Enabled = Enabled; } public TerminalState(TerminalState o) { Enabled = true; Enabled = o.Enabled; } } public class TerminalWrapper { public LG_ComputerTerminal lgTerminal { get; private set; } public StateReplicator<TerminalState> stateReplicator { get; private set; } private void ChangeStateUnsynced(bool enabled) { EOSLogger.Debug($"{lgTerminal.ItemKey} state, enabled: {enabled}"); lgTerminal.OnProximityExit(); Interact_ComputerTerminal componentInChildren = ((Component)lgTerminal).GetComponentInChildren<Interact_ComputerTerminal>(true); bool flag = enabled; if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = flag; ((Interact_Base)componentInChildren).SetActive(flag); } lgTerminal.m_interfaceScreen.SetActive(flag); lgTerminal.m_loginScreen.SetActive(flag); if ((Object)(object)lgTerminal.m_text != (Object)null) { ((Behaviour)lgTerminal.m_text).enabled = flag; } if (!flag) { PlayerAgent localInteractionSource = lgTerminal.m_localInteractionSource; if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger) { lgTerminal.ExitFPSView(); } } } public void ChangeState(bool enabled) { ChangeStateUnsynced(enabled); if (SNet.IsMaster) { stateReplicator.SetState(new TerminalState { Enabled = enabled }); } } private void OnStateChanged(TerminalState oldState, TerminalState newState, bool isRecall) { if (isRecall) { ChangeStateUnsynced(newState.Enabled); } } public static TerminalWrapper Instantiate(LG_ComputerTerminal lgTerminal, uint replicatorID) { if ((Object)(object)lgTerminal == (Object)null || replicatorID == 0) { return null; } TerminalWrapper terminalWrapper = new TerminalWrapper(); terminalWrapper.lgTerminal = lgTerminal; terminalWrapper.stateReplicator = StateReplicator<TerminalState>.Create(replicatorID, new TerminalState { Enabled = true }, (LifeTimeType)1, (IStateReplicatorHolder<TerminalState>)null); terminalWrapper.stateReplicator.OnStateChanged += terminalWrapper.OnStateChanged; return terminalWrapper; } private TerminalWrapper() { } } } namespace ExtraObjectiveSetup.Tweaks.TerminalPosition { public class TerminalPosition : BaseInstanceDefinition { public Vec3 Position { get; set; } = new Vec3(); public Vec3 Rotation { get; set; } = new Vec3(); } internal class TerminalPositionOverrideManager : InstanceDefinitionManager<TerminalPosition> { public static TerminalPositionOverrideManager Current; protected override string DEFINITION_NAME => "TerminalPosition"; private TerminalPositionOverrideManager() { } static TerminalPositionOverrideManager() { Current = new TerminalPositionOverrideManager(); } } } namespace ExtraObjectiveSetup.Tweaks.Scout { public class EventsOnZoneScoutScream : GlobalZoneIndex { public bool SuppressVanillaScoutWave { get; set; } public List<WardenObjectiveEventData> EventsOnScoutScream { get; set; } = new List<WardenObjectiveEventData>(); } internal class ScoutScreamEventManager : ZoneDefinitionManager<EventsOnZoneScoutScream> { public static ScoutScreamEventManager Current; protected override string DEFINITION_NAME => "EventsOnScoutScream"; private ScoutScreamEventManager() { } static ScoutScreamEventManager() { Current = new ScoutScreamEventManager(); } } } namespace ExtraObjectiveSetup.Tweaks.BossEvents { public struct FiniteBDEState { public int ApplyToHibernateCount; public int ApplyToWaveCount; public FiniteBDEState() { ApplyToHibernateCount = int.MaxValue; ApplyToWaveCount = int.MaxValue; } public FiniteBDEState(FiniteBDEState other) { ApplyToHibernateCount = int.MaxValue; ApplyToWaveCount = int.MaxValue; ApplyToHibernateCount = other.ApplyToHibernateCount; ApplyToHibernateCount = other.ApplyToWaveCount; } public FiniteBDEState(int ApplyToHibernateCount, int ApplyToWaveCount) { this.ApplyToHibernateCount = int.MaxValue; this.ApplyToWaveCount = int.MaxValue; this.ApplyToHibernateCount = ApplyToHibernateCount; this.ApplyToWaveCount = ApplyToWaveCount; } } public class EventsOnZoneBossDeath : GlobalZoneIndex { public bool ApplyToHibernate { get; set; } = true; public int ApplyToHibernateCount { get; set; } = int.MaxValue; public bool ApplyToWave { get; set; } public int ApplyToWaveCount { get; set; } = int.MaxValue; public List<uint> BossIDs { get; set; } = new List<uint> { 29u, 36u, 37u }; public List<WardenObjectiveEventData> EventsOnBossDeath { get; set; } = new List<WardenObjectiveEventData>(); [JsonIgnore] public StateReplicator<FiniteBDEState> FiniteBDEStateReplicator { get; private set; } [JsonIgnore] public int RemainingWaveBDE { get { if (FiniteBDEStateReplicator == null) { return ApplyToWaveCount; } return FiniteBDEStateReplicator.State.ApplyToWaveCount; } } [JsonIgnore] public int RemainingHibernateBDE { get { if (FiniteBDEStateReplicator == null) { return ApplyToHibernateCount; } return FiniteBDEStateReplicator.State.ApplyToHibernateCount; } } public void SetupReplicator(uint replicatorID) { if (ApplyToHibernateCount != int.MaxValue || ApplyToWaveCount != int.MaxValue) { FiniteBDEStateReplicator = StateReplicator<FiniteBDEState>.Create(replicatorID, new FiniteBDEState { ApplyToHibernateCount = ApplyToHibernateCount, ApplyToWaveCount = ApplyToWaveCount }, (LifeTimeType)1, (IStateReplicatorHolder<FiniteBDEState>)null); FiniteBDEStateReplicator.OnStateChanged += OnStateChanged; } } private void OnStateChanged(FiniteBDEState oldState, FiniteBDEState newState, bool isRecall) { } internal void Destroy() { FiniteBDEStateReplicator = null; } } internal class BossDeathEventManager : ZoneDefinitionManager<EventsOnZoneBossDeath> { public enum Mode { HIBERNATE, WAVE } public static BossDeathEventManager Current; public const int UNLIMITED_COUNT = int.MaxValue; private ConcurrentDictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex), EventsOnZoneBossDeath> LevelBDEs { get; } = new ConcurrentDictionary<(eDimensionIndex, LG_LayerType, eLocalZoneIndex), EventsOnZoneBossDeath>(); protected override string DEFINITION_NAME => "EventsOnBossDeath"; public bool TryConsumeBDEventsExecutionTimes(EventsOnZoneBossDeath def, Mode mode) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) return TryConsumeBDEventsExecutionTimes(def.DimensionIndex, def.LayerType, def.LocalIndex, mode); } public bool TryConsumeBDEventsExecutionTimes(eDimensionIndex dimensionIndex, LG_LayerType layer, eLocalZoneIndex localIndex, Mode mode) { //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_0008: 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) //IL_0051: 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_002d: 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) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!LevelBDEs.ContainsKey((dimensionIndex, layer, localIndex))) { EOSLogger.Error($"BossDeathEventManager: got an unregistered entry: {(dimensionIndex, layer, localIndex, mode)}"); return false; } EventsOnZoneBossDeath eventsOnZoneBossDeath = LevelBDEs[(dimensionIndex, layer, localIndex)]; int num = ((mode == Mode.HIBERNATE) ? eventsOnZoneBossDeath.RemainingHibernateBDE : eventsOnZoneBossDeath.RemainingWaveBDE); if (num == int.MaxValue) { return true; } if (num > 0) { FiniteBDEState state = eventsOnZoneBossDeath.FiniteBDEStateReplicator.State; if (SNet.IsMaster) { eventsOnZoneBossDeath.FiniteBDEStateReplicator.SetState(new FiniteBDEState { ApplyToHibernateCount = ((mode == Mode.HIBERNATE) ? (num - 1) : state.ApplyToHibernateCount), ApplyToWaveCount = ((mode == Mode.WAVE) ? (num - 1) : state.ApplyToWaveCount) }); } return true; } return false; } private void Clear() { foreach (EventsOnZoneBossDeath value in LevelBDEs.Values) { value.Destroy(); } LevelBDEs.Clear(); } private void SetupForCurrentExpedition() { if (!definitions.ContainsKey(RundownManager.ActiveExpedition.LevelLayoutData)) { return; } foreach (EventsOnZoneBossDeath definition in definitions[RundownManager.ActiveExpedition.LevelLayoutData].Definitions) { if (LevelBDEs.ContainsKey(definition.GlobalZoneIndexTuple())) { EOSLogger.Error($"BossDeathEvent: found duplicate setup for zone {definition.GlobalZoneIndexTuple()}, will overwrite!"); } if (definition.ApplyToHibernateCount != int.MaxValue || definition.ApplyToWaveCount != int.MaxValue) { uint num = EOSNetworking.AllotReplicatorID(); if (num != 0) { definition.SetupReplicator(num); } else { EOSLogger.Error("BossDeathEvent: replicator ID depleted, cannot setup replicator!"); } } LevelBDEs[definition.GlobalZoneIndexTuple()] = definition; } } private BossDeathEventManager() { LevelAPI.OnBuildStart += delegate { Clear(); SetupForCurrentExpedition(); }; LevelAPI.OnLevelCleanup += Clear; } static BossDeathEventManager() { Current = new BossDeathEventManager(); } } } namespace ExtraObjectiveSetup.Patches { [HarmonyPatch] internal class Patch_CheckAndExecuteEventsOnTrigger { [HarmonyPrefix] [HarmonyPatch(typeof(WardenObjectiveManager), "CheckAndExecuteEventsOnTrigger", new Type[] { typeof(WardenObjectiveEventData), typeof(eWardenObjectiveEventTrigger), typeof(bool), typeof(float) })] private static bool Pre_CheckAndExecuteEventsOnTrigger(WardenObjectiveEventData eventToTrigger, eWardenObjectiveEventTrigger trigger, bool ignoreTrigger, float currentDuration) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected I4, but got Unknown if (eventToTrigger == null || (!ignoreTrigger && eventToTrigger.Trigger != trigger) || ((double)currentDuration != 0.0 && eventToTrigger.Delay <= currentDuration)) { return true; } uint num = (uint)(int)eventToTrigger.Type; if (!EOSWardenEventManager.Current.HasEventDefinition(num)) { return true; } string value = (EOSWardenEventManager.Current.IsVanillaEventID(num) ? "overriding vanilla event implementation..." : "executing..."); EOSLogger.Debug($"WardenEvent: found definition for event ID {num}, {value}"); EOSWardenEventManager.Current.ExecuteEvent(eventToTrigger, currentDuration); return false; } } [HarmonyPatch] internal class Patch_EventsOnBossDeath { private static HashSet<ushort> ExecutedForInstances; [HarmonyPostfix] [HarmonyPatch(typeof(EnemySync), "OnSpawn")] private static void Post_SpawnEnemy(EnemySync __instance, pEnemySpawnData spawnData) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Invalid comparison between Unknown and I4 //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Invalid comparison between Unknown and I4 //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Invalid comparison between Unknown and I4 //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Invalid comparison between Unknown and I4 //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode val = default(AIG_CourseNode); if (!((pCourseNode)(ref spawnData.courseNode)).TryGet(ref val) || val == null) { EOSLogger.Error("Failed to get spawnnode for a boss! Skipped EventsOnBossDeath for it"); return; } LG_Zone zone = val.m_zone; EventsOnZoneBossDeath def = BossDeathEventManager.Current.GetDefinition(zone.DimensionIndex, zone.Layer.m_type, zone.LocalIndex); if (def == null) { return; } EnemyAgent enemy = __instance.m_agent; if (!def.BossIDs.Contains(((GameDataBlockBase<EnemyDataBlock>)(object)enemy.EnemyData).persistentID) || ((((int)spawnData.mode != 4 && (int)spawnData.mode != 3) || !def.ApplyToHibernate) && ((int)spawnData.mode != 1 || !def.ApplyToWave))) { return; } BossDeathEventManager.Mode mode = (((int)spawnData.mode != 4) ? BossDeathEventManager.Mode.WAVE : BossDeathEventManager.Mode.HIBERNATE); enemy.OnDeadCallback += Action.op_Implicit((Action)delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)GameStateManager.CurrentStateName == 10) { if (!BossDeathEventManager.Current.TryConsumeBDEventsExecutionTimes(def, mode)) { EOSLogger.Debug($"EventsOnBossDeath: execution times depleted for {def.GlobalZoneIndexTuple()}, {mode}"); } else { ushort globalID = ((Agent)enemy).GlobalID; if (ExecutedForInstances.Contains(globalID)) { ExecutedForInstances.Remove(globalID); } else { def.EventsOnBossDeath.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); ExecutedForInstances.Add(globalID); } } } }); EOSLogger.Debug($"EventsOnBossDeath: added for enemy with id {((GameDataBlockBase<EnemyDataBlock>)(object)enemy.EnemyData).persistentID}, mode: {spawnData.mode}"); } static Patch_EventsOnBossDeath() { ExecutedForInstances = new HashSet<ushort>(); LevelAPI.OnLevelCleanup += ExecutedForInstances.Clear; } } [HarmonyPatch] internal class Patch_EventsOnZoneScoutScream { [HarmonyPrefix] [HarmonyPatch(typeof(ES_ScoutScream), "CommonUpdate")] private static bool Pre_ES_ScoutScream_CommonUpdate(ES_ScoutScream __instance) { //IL_0017: 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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) AIG_CourseNode courseNode = ((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode; EventsOnZoneScoutScream definition = ScoutScreamEventManager.Current.GetDefinition(courseNode.m_dimension.DimensionIndex, courseNode.LayerType, courseNode.m_zone.LocalIndex); if (definition == null) { return true; } if ((int)__instance.m_state != 3 || __instance.m_stateDoneTimer >= Clock.Time) { return true; } if (definition.EventsOnScoutScream != null && definition.EventsOnScoutScream.Count > 0) { EOSLogger.Debug($"EventsOnZoneScoutScream: found config for {definition.GlobalZoneIndexTuple()}, executing events."); definition.EventsOnScoutScream.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } if (!definition.SuppressVanillaScoutWave) { if (SNet.IsMaster && ((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode != null) { if (RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings != 0 && RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation != 0) { ushort num = default(ushort); Mastermind.Current.TriggerSurvivalWave(((Agent)((ES_Base)__instance).m_enemyAgent).CourseNode, RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings, RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation, ref num, (SurvivalWaveSpawnType)0, 0f, 2f, true, false, default(Vector3), ""); } else { Debug.LogError(Object.op_Implicit("ES_ScoutScream, a scout is screaming but we can't spawn a wave because the the scout settings are not set for this expedition! ScoutWaveSettings: " + RundownManager.ActiveExpedition.Expedition.ScoutWaveSettings + " ScoutWavePopulation: " + RundownManager.ActiveExpedition.Expedition.ScoutWavePopulation)); } } } else { EOSLogger.Debug("Vanilla scout wave suppressed."); } if (SNet.IsMaster) { ((ES_Base)__instance).m_enemyAgent.AI.m_behaviour.ChangeState((EB_States)5); } ((MachineState<ES_Base>)(object)__instance).m_machine.ChangeState(2); __instance.m_state = (ScoutScreamState)4; return false; } } } namespace ExtraObjectiveSetup.Patches.Uplink { [HarmonyPatch] internal static class CorruptedUplinkConfirm { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConfirm")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConfirm(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { LG_ComputerTerminal receiver = __instance.m_terminal; LG_ComputerTerminal sender = __instance.m_terminal.CorruptedUplinkReceiver; if ((Object)(object)sender == (Object)null) { EOSLogger.Error("TerminalCorruptedUplinkConfirm() critical failure because terminal does not have a CorruptedUplinkReceiver (sender)."); __result = false; return false; } if (sender.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(sender); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(sender); UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); receiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(2816126705u), sender.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0); if ((Object)(object)sender.ChainedPuzzleForWardenObjective != (Object)null) { ChainedPuzzleInstance chainedPuzzleForWardenObjective = sender.ChainedPuzzleForWardenObjective; chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate { receiver.m_command.StartTerminalUplinkSequence(string.Empty, true); UplinkObjectiveManager.Current.ChangeState(sender, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = 0 }); }); sender.m_command.AddOutput("", true); sender.m_command.AddOutput(Text.Get(3268596368u), true); sender.m_command.AddOutput(Text.Get(2277987284u), true); receiver.m_command.AddOutput("", true); receiver.m_command.AddOutput(Text.Get(3268596368u), true); receiver.m_command.AddOutput(Text.Get(2277987284u), true); if (SNet.IsMaster) { sender.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0); } } else { receiver.m_command.StartTerminalUplinkSequence(string.Empty, true); UplinkObjectiveManager.Current.ChangeState(sender, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = 0 }); } __result = true; return false; } } [HarmonyPatch] internal static class CorruptedUplinkConnect { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalCorruptedUplinkConnect")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalCorruptedUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Expected O, but got Unknown LG_ComputerTerminal terminal = __instance.m_terminal; if (terminal.m_isWardenObjective) { return true; } __result = false; LG_ComputerTerminal corruptedUplinkReceiver = terminal.CorruptedUplinkReceiver; if ((Object)(object)corruptedUplinkReceiver == (Object)null) { EOSLogger.Error("TerminalCorruptedUplinkConnect() critical failure because terminal does not have a CorruptedUplinkReceiver."); return false; } if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID) { __instance.AddOngoingUplinkOutput(); __result = false; return false; } LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = terminal.SyncID; (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition.UseUplinkAddress) { param1 = param1.ToUpper(); EOSLogger.Debug("TerminalCorruptedUplinkConnect, param1: " + param1 + ", TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString()); } else { param1 = terminal.UplinkPuzzle.TerminalUplinkIP.ToUpper(); EOSLogger.Debug("TerminalCorruptedUplinkConnect, not using uplink address, TerminalUplink: " + ((Object)terminal.UplinkPuzzle).ToString()); } if (!definition.UseUplinkAddress || param1 == terminal.UplinkPuzzle.TerminalUplinkIP) { if (corruptedUplinkReceiver.m_command.HasRegisteredCommand((TERM_Command)27)) { terminal.m_command.AddUplinkCorruptedOutput(); } else { terminal.m_command.AddUplinkCorruptedOutput(); terminal.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(3492863045u), corruptedUplinkReceiver.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(2761366063u), 0.6f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)0, Text.Get(3435969025u), 0.8f, (TerminalSoundType)0, (TerminalSoundType)0); corruptedUplinkReceiver.m_command.AddCommand((TERM_Command)27, "UPLINK_CONFIRM", new LocalizedText { UntranslatedText = Text.Get(112719254u), Id = 0u }, (TERM_CommandRule)2); corruptedUplinkReceiver.m_command.AddOutput((TerminalLineType)0, string.Format(Text.Get(1173595354u), terminal.PublicName), 0f, (TerminalSoundType)0, (TerminalSoundType)0); } } else { terminal.m_command.AddUplinkWrongAddressError(param1); } return false; } } [HarmonyPatch] internal static class StartTerminalUplinkSequence { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "StartTerminalUplinkSequence")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_StartTerminalUplinkSequence(LG_ComputerTerminalCommandInterpreter __instance, string uplinkIp, bool corrupted) { if (!corrupted) { LG_ComputerTerminal uplinkTerminal = __instance.m_terminal; if (uplinkTerminal.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(uplinkTerminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(uplinkTerminal); UplinkDefinition uplinkConfig = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); uplinkTerminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2583360288u), uplinkIp), 3f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.TerminalUplinkSequenceOutputs(uplinkTerminal, false); uplinkTerminal.m_command.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Debug("UPLINK CONNECTION DONE!"); uplinkTerminal.UplinkPuzzle.Connected = true; uplinkTerminal.UplinkPuzzle.CurrentRound.ShowGui = true; uplinkTerminal.UplinkPuzzle.OnStartSequence(); uplinkConfig.EventsOnCommence.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); int num2 = uplinkConfig.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0); ((num2 != -1) ? uplinkConfig.RoundOverrides[num2] : null)?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); }); } else { LG_ComputerTerminal terminal = __instance.m_terminal; LG_ComputerTerminal sender = __instance.m_terminal.CorruptedUplinkReceiver; if (sender.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex2 = TerminalInstanceManager.Current.GetGlobalZoneIndex(sender); uint zoneInstanceIndex2 = TerminalInstanceManager.Current.GetZoneInstanceIndex(sender); UplinkDefinition uplinkConfig2 = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex2, zoneInstanceIndex2); sender.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), sender.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); sender.m_command.AddOutput("", true); terminal.m_command.AddOutput((TerminalLineType)4, string.Format(Text.Get(2056072887u), sender.PublicName), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); terminal.m_command.TerminalUplinkSequenceOutputs(sender, false); terminal.m_command.TerminalUplinkSequenceOutputs(terminal, true); terminal.m_command.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Debug("UPLINK CONNECTION DONE!"); sender.UplinkPuzzle.Connected = true; sender.UplinkPuzzle.CurrentRound.ShowGui = true; sender.UplinkPuzzle.OnStartSequence(); uplinkConfig2.EventsOnCommence.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); int num = uplinkConfig2.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == 0); ((num != -1) ? uplinkConfig2.RoundOverrides[num] : null)?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); }); } return false; } } [HarmonyPatch] internal static class TerminalUplinkConnect { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkConnect")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkConnect(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { LG_ComputerTerminal terminal = __instance.m_terminal; if (terminal.m_isWardenObjective) { return true; } if (LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != 0 && LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId != terminal.SyncID) { __instance.AddOngoingUplinkOutput(); return false; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance.m_terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (!definition.UseUplinkAddress) { param1 = __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP; } if (!definition.UseUplinkAddress || param1 == __instance.m_terminal.UplinkPuzzle.TerminalUplinkIP) { __instance.m_terminal.TrySyncSetCommandRule((TERM_Command)25, (TERM_CommandRule)1); if ((Object)(object)__instance.m_terminal.ChainedPuzzleForWardenObjective != (Object)null) { ChainedPuzzleInstance chainedPuzzleForWardenObjective = __instance.m_terminal.ChainedPuzzleForWardenObjective; chainedPuzzleForWardenObjective.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.StartTerminalUplinkSequence(param1, false); }); __instance.AddOutput("", true); __instance.AddOutput(Text.Get(3268596368u), true); __instance.AddOutput(Text.Get(3041541194u), true); if (SNet.IsMaster) { __instance.m_terminal.ChainedPuzzleForWardenObjective.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.StartTerminalUplinkSequence(param1, false); } __result = true; } else { __instance.AddUplinkWrongAddressError(param1); __result = false; } return false; } } [HarmonyPatch] internal static class TerminalUplinkSequenceOutput { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkSequenceOutputs")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkSequenceOutputs(LG_ComputerTerminal terminal, bool corrupted) { if (terminal.m_isWardenObjective) { return true; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null) { if (!((Object)(object)terminal.CorruptedUplinkReceiver != (Object)null)) { return true; } LG_ComputerTerminal corruptedUplinkReceiver = terminal.CorruptedUplinkReceiver; globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(corruptedUplinkReceiver); zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(corruptedUplinkReceiver); definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition == null || definition.DisplayUplinkWarning) { return true; } } terminal.m_command.AddOutput((TerminalLineType)3, Text.Get(3418104670u), 3f, (TerminalSoundType)0, (TerminalSoundType)0); terminal.m_command.AddOutput("", true); if (!corrupted) { terminal.m_command.AddOutput(string.Format(Text.Get(947485599u), terminal.UplinkPuzzle.CurrentRound.CorrectPrefix), true); } return false; } } [HarmonyPatch] internal static class TerminalUplinkVerify { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "TerminalUplinkVerify")] private static bool Pre_LG_ComputerTerminalCommandInterpreter_TerminalUplinkVerify(LG_ComputerTerminalCommandInterpreter __instance, string param1, string param2, ref bool __result) { if (__instance.m_terminal.m_isWardenObjective) { return true; } TerminalUplinkPuzzle uplinkPuzzle = __instance.m_terminal.UplinkPuzzle; (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance.m_terminal); uint zoneInstanceIndex = TerminalInstanceManager.Current.GetZoneInstanceIndex(__instance.m_terminal); UplinkDefinition definition = UplinkObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); int CurrentRoundIndex = uplinkPuzzle.m_roundIndex; int num = definition.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == CurrentRoundIndex); UplinkRound roundOverride = ((num != -1) ? definition.RoundOverrides[num] : null); TimeSettings timeSettings = ((num != -1) ? roundOverride.OverrideTimeSettings : definition.DefaultTimeSettings); float num2 = ((timeSettings.TimeToStartVerify >= 0f) ? timeSettings.TimeToStartVerify : definition.DefaultTimeSettings.TimeToStartVerify); float timeToCompleteVerify = ((timeSettings.TimeToCompleteVerify >= 0f) ? timeSettings.TimeToCompleteVerify : definition.DefaultTimeSettings.TimeToCompleteVerify); float num3 = ((timeSettings.TimeToRestoreFromFail >= 0f) ? timeSettings.TimeToRestoreFromFail : definition.DefaultTimeSettings.TimeToRestoreFromFail); if (uplinkPuzzle.Connected) { __instance.AddOutput((TerminalLineType)3, Text.Get(2734004688u), num2, (TerminalSoundType)0, (TerminalSoundType)0); if (!uplinkPuzzle.Solved && uplinkPuzzle.CurrentRound.CorrectCode.ToUpper() == param1.ToUpper()) { __instance.AddOutput(string.Format(Text.Get(1221800228u), uplinkPuzzle.CurrentProgress), true); if (uplinkPuzzle.TryGoToNextRound()) { int newRoundIndex = uplinkPuzzle.m_roundIndex; int num4 = definition.RoundOverrides.FindIndex((UplinkRound o) => o.RoundIndex == newRoundIndex); UplinkRound newRoundOverride = ((num4 != -1) ? definition.RoundOverrides[num4] : null); roundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)2, false, 0f); }); if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null) { TextDataBlock block = GameDataBlockBase<TextDataBlock>.GetBlock("InGame.UplinkTerminal.ScanRequiredToProgress"); if (block != null) { __instance.AddOutput((TerminalLineType)4, Text.Get(((GameDataBlockBase<TextDataBlock>)(object)block).persistentID), 0f, (TerminalSoundType)0, (TerminalSoundType)0); } ChainedPuzzleInstance chainedPuzzleToEndRoundInstance = roundOverride.ChainedPuzzleToEndRoundInstance; chainedPuzzleToEndRoundInstance.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Log("UPLINK VERIFICATION GO TO NEXT ROUND!"); uplinkPuzzle.CurrentRound.ShowGui = true; newRoundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); }); }); if (SNet.IsMaster) { roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.AddOutput((TerminalLineType)4, Text.Get(27959760u), timeToCompleteVerify, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.AddOutput(string.Format(Text.Get(4269617288u), uplinkPuzzle.CurrentProgress, uplinkPuzzle.CurrentRound.CorrectPrefix), true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Log("UPLINK VERIFICATION GO TO NEXT ROUND!"); uplinkPuzzle.CurrentRound.ShowGui = true; newRoundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)1, false, 0f); }); UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.InProgress, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); }); } } else { __instance.AddOutput((TerminalLineType)3, Text.Get(1780488547u), 3f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { roundOverride?.EventsOnRound.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)2, false, 0f); }); uplinkPuzzle.CurrentRound.ShowGui = false; if (roundOverride != null && (Object)(object)roundOverride.ChainedPuzzleToEndRoundInstance != (Object)null) { ChainedPuzzleInstance chainedPuzzleToEndRoundInstance2 = roundOverride.ChainedPuzzleToEndRoundInstance; chainedPuzzleToEndRoundInstance2.OnPuzzleSolved += Action.op_Implicit((Action)delegate { __instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); __instance.OnEndOfQueue = Action.op_Implicit((Action)delegate { EOSLogger.Error("UPLINK VERIFICATION SEQUENCE DONE!"); LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = 0u; uplinkPuzzle.Solved = true; Action onPuzzleSolved2 = uplinkPuzzle.OnPuzzleSolved; if (onPuzzleSolved2 != null) { onPuzzleSolved2.Invoke(); } UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.Finished, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); }); }); if (SNet.IsMaster) { roundOverride.ChainedPuzzleToEndRoundInstance.AttemptInteract((eChainedPuzzleInteraction)0); } } else { __instance.AddOutput((TerminalLineType)0, string.Format(Text.Get(3928683780u), uplinkPuzzle.TerminalUplinkIP), 2f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput("", true); EOSLogger.Error("UPLINK VERIFICATION SEQUENCE DONE!"); LG_ComputerTerminalManager.OngoingUplinkConnectionTerminalId = 0u; uplinkPuzzle.Solved = true; Action onPuzzleSolved = uplinkPuzzle.OnPuzzleSolved; if (onPuzzleSolved != null) { onPuzzleSolved.Invoke(); } UplinkObjectiveManager.Current.ChangeState(__instance.m_terminal, new UplinkState { Status = UplinkStatus.Finished, CurrentRoundIndex = uplinkPuzzle.m_roundIndex }); } }); } } else if (uplinkPuzzle.Solved) { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)1, Text.Get(4080876165u), 0f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), 6f, (TerminalSoundType)0, (TerminalSoundType)0); } else { __instance.AddOutput("", true); __instance.AddOutput((TerminalLineType)1, string.Format(Text.Get(507647514u), uplinkPuzzle.CurrentRound.CorrectPrefix), 0f, (TerminalSoundType)0, (TerminalSoundType)0); __instance.AddOutput((TerminalLineType)0, Text.Get(4104839742u), num3, (TerminalSoundType)0, (TerminalSoundType)0); } } else { __instance.AddOutput("", true); __instance.AddOutput(Text.Get(403360908u), true); } __result = false; return false; } } [HarmonyPatch] internal static class UplinkGUI_Update { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminal), "Update")] private static void Post_LG_ComputerTerminal_Update(LG_ComputerTerminal __instance) { if (!__instance.m_isWardenObjective && __instance.UplinkPuzzle != null) { __instance.UplinkPuzzle.UpdateGUI(false); } } } } namespace ExtraObjectiveSetup.Patches.PowerGenerator { [HarmonyPatch] internal static class Patch_LG_PowerGeneratorCluster { [HarmonyPostfix] [HarmonyPatch(typeof(LG_PowerGeneratorCluster), "Setup")] private static void Post_PowerGeneratorCluster_Setup(LG_PowerGeneratorCluster __instance) { uint instanceIndex = GeneratorClusterInstanceManager.Current.Register(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = GeneratorClusterInstanceManager.Current.GetGlobalZoneIndex(__instance); GeneratorClusterDefinition definition = GeneratorClusterObjectiveManager.Current.GetDefinition(globalZoneIndex, instanceIndex); if (definition == null) { return; } EOSLogger.Debug("Found LG_PowerGeneratorCluster and its definition! Building this Generator cluster..."); __instance.m_serialNumber = SerialGenerator.GetUniqueSerialNo(); __instance.m_itemKey = "GENERATOR_CLUSTER_" + __instance.m_serialNumber; __instance.m_terminalItem = GOUtil.GetInterfaceFromComp<iTerminalItem>(__instance.m_terminalItemComp); __instance.m_terminalItem.Setup(__instance.m_itemKey, (AIG_CourseNode)null); __instance.m_terminalItem.FloorItemStatus = (eFloorInventoryObjectStatus)4; if (__instance.SpawnNode != null) { __instance.m_terminalItem.FloorItemLocation = __instance.SpawnNode.m_zone.NavInfo.GetFormattedText((LG_NavInfoFormat)7); } List<Transform> list = new List<Transform>((IEnumerable<Transform>)__instance.m_generatorAligns); uint numberOfGenerators = definition.NumberOfGenerators; __instance.m_generators = Il2CppReferenceArray<LG_PowerGenerator_Core>.op_Implicit((LG_PowerGenerator_Core[])(object)new LG_PowerGenerator_Core[numberOfGenerators]); if (list.Count >= numberOfGenerators) { for (int i = 0; i < numberOfGenerators; i++) { int index = Builder.BuildSeedRandom.Range(0, list.Count, "NO_TAG"); LG_PowerGenerator_Core val = GOUtil.SpawnChildAndGetComp<LG_PowerGenerator_Core>(__instance.m_generatorPrefab, list[index]); ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)__instance.m_generators)[i] = val; val.SpawnNode = __instance.SpawnNode; PowerGeneratorInstanceManager.Current.MarkAsGCGenerator(__instance, val); val.Setup(); val.SetCanTakePowerCell(true); Debug.Log(Object.op_Implicit("Spawning generator at alignIndex: " + index)); list.RemoveAt(index); } } else { Debug.LogError(Object.op_Implicit("LG_PowerGeneratorCluster does NOT have enough generator aligns to support the warden objective! Has " + list.Count + " needs " + numberOfGenerators)); } __instance.ObjectiveItemSolved = true; if (definition.EndSequenceChainedPuzzle != 0) { GeneratorClusterObjectiveManager.Current.RegisterForChainedPuzzleBuild(__instance, definition); } } } [HarmonyPatch] internal static class Patch_LG_PowerGenerator_Core_SyncStatusChanged { [HarmonyPostfix] [HarmonyPatch(typeof(LG_PowerGenerator_Core), "SyncStatusChanged")] private static void Post_SyncStatusChanged(LG_PowerGenerator_Core __instance, pPowerGeneratorState state, bool isDropinState) { //IL_0058: 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) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) uint zoneInstanceIndex = PowerGeneratorInstanceManager.Current.GetZoneInstanceIndex(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = PowerGeneratorInstanceManager.Current.GetGlobalZoneIndex(__instance); LG_PowerGeneratorCluster parentGeneratorCluster = PowerGeneratorInstanceManager.Current.GetParentGeneratorCluster(__instance); GeneratorClusterDefinition generatorClusterDefinition = null; if ((Object)(object)parentGeneratorCluster != (Object)null) { uint zoneInstanceIndex2 = GeneratorClusterInstanceManager.Current.GetZoneInstanceIndex(parentGeneratorCluster); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex2 = GeneratorClusterInstanceManager.Current.GetGlobalZoneIndex(parentGeneratorCluster); generatorClusterDefinition = GeneratorClusterObjectiveManager.Current.GetDefinition(globalZoneIndex2, zoneInstanceIndex2); } ePowerGeneratorStatus status = state.status; if (generatorClusterDefinition != null) { EOSLogger.Log($"LG_PowerGeneratorCluster.powerGenerator.OnSyncStatusChanged! status: {status}, isDropinState: {isDropinState}"); if ((int)status == 0) { uint num = 0u; for (int i = 0; i < ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)parentGeneratorCluster.m_generators).Length; i++) { if ((int)((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)parentGeneratorCluster.m_generators)[i].m_stateReplicator.State.status == 0) { num++; } } EOSLogger.Log($"Generator Cluster PowerCell inserted ({num} / {((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)parentGeneratorCluster.m_generators).Count})"); List<List<WardenObjectiveEventData>> eventsOnInsertCell = generatorClusterDefinition.EventsOnInsertCell; int num2 = (int)(num - 1); if (!isDropinState) { if (num2 >= 0 && num2 < eventsOnInsertCell.Count) { EOSLogger.Log($"Executing events ({num} / {((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)parentGeneratorCluster.m_generators).Count}). Event count: {eventsOnInsertCell[num2].Count}"); eventsOnInsertCell[num2].ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } if (num == ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)parentGeneratorCluster.m_generators).Count && !parentGeneratorCluster.m_endSequenceTriggered) { EOSLogger.Log("All generators powered, executing end sequence"); ((MonoBehaviour)__instance).StartCoroutine(parentGeneratorCluster.ObjectiveEndSequence()); parentGeneratorCluster.m_endSequenceTriggered = true; } } else if (num != ((Il2CppArrayBase<LG_PowerGenerator_Core>)(object)parentGeneratorCluster.m_generators).Count) { parentGeneratorCluster.m_endSequenceTriggered = false; } } } IndividualGeneratorDefinition definition = IndividualGeneratorObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (definition != null && definition.EventsOnInsertCell != null && (int)status == 0 && !isDropinState) { definition.EventsOnInsertCell.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } ExpeditionIGGroup expeditionIGGroup = ExpeditionIGGroupManager.Current.FindGroupDefOf(__instance); if (expeditionIGGroup == null) { return; } int num3 = 0; foreach (LG_PowerGenerator_Core generatorInstance in expeditionIGGroup.GeneratorInstances) { if ((int)generatorInstance.m_stateReplicator.State.status == 0) { num3++; } } if (isDropinState) { return; } if (num3 == expeditionIGGroup.GeneratorInstances.Count && expeditionIGGroup.PlayEndSequenceOnGroupComplete) { Coroutine val = CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ExpeditionIGGroupManager.PlayGroupEndSequence(expeditionIGGroup)), (Action)null); WorldEventManager.m_worldEventEventCoroutines.Add(val); return; } int num4 = num3 - 1; if (num4 >= 0 && num4 < expeditionIGGroup.EventsOnInsertCell.Count) { expeditionIGGroup.EventsOnInsertCell[num4].ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } } } [HarmonyPatch] internal static class Patch_LG_PowerGenerator_Core_Setup { [HarmonyPostfix] [HarmonyPatch(typeof(LG_PowerGenerator_Core), "Setup")] private static void Post_PowerGenerator_Setup(LG_PowerGenerator_Core __instance) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) iCarryItemInteractionTarget powerCellInteraction = __instance.m_powerCellInteraction; powerCellInteraction.AttemptCarryItemInsert += Action<SNet_Player, Item>.op_Implicit((Action<SNet_Player, Item>)delegate(SNet_Player p, Item item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Item val2 = default(Item); if (PlayerBackpackManager.TryGetItemInLevelFromItemData(item.Get_pItemData(), ref val2)) { ((Il2CppObjectBase)val2).Cast<ItemInLevel>().CanWarp = false; } else { EOSLogger.Error($"Inserting sth other than PowerCell ({item.PublicName}) into {__instance.m_itemKey}, how?"); } }); if (PowerGeneratorInstanceManager.Current.IsGCGenerator(__instance)) { return; } uint num = PowerGeneratorInstanceManager.Current.Register(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = PowerGeneratorInstanceManager.Current.GetGlobalZoneIndex(__instance); IndividualGeneratorDefinition definition = IndividualGeneratorObjectiveManager.Current.GetDefinition(globalZoneIndex, num); if (definition != null) { Vector3 val = definition.Position.ToVector3(); Quaternion rotation = definition.Rotation.ToQuaternion(); if (val != Vector3.zero) { ((Component)__instance).transform.position = val; ((Component)__instance).transform.rotation = rotation; __instance.m_sound.UpdatePosition(val); EOSLogger.Debug("LG_PowerGenerator_Core: modified position / rotation"); } if (definition.ForceAllowPowerCellInsertion) { __instance.SetCanTakePowerCell(true); } EOSLogger.Debug($"LG_PowerGenerator_Core: overriden, instance {num} in {globalZoneIndex}"); } } [HarmonyPostfix] [HarmonyPatch(typeof(LG_PowerGenerator_Core), "SyncStatusChanged")] private static void Post_SyncStatusChanged(LG_PowerGenerator_Core __instance, pPowerGeneratorState state, bool isDropinState) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Invalid comparison between Unknown and I4 uint zoneInstanceIndex = PowerGeneratorInstanceManager.Current.GetZoneInstanceIndex(__instance); (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = PowerGeneratorInstanceManager.Current.GetGlobalZoneIndex(__instance); IndividualGeneratorDefinition definition = IndividualGeneratorObjectiveManager.Current.GetDefinition(globalZoneIndex, zoneInstanceIndex); if (!(definition == null || definition.EventsOnInsertCell == null || (int)state.status > 0 || isDropinState) && definition.EventsOnInsertCell.Count > 0) { definition.EventsOnInsertCell.ForEach(delegate(WardenObjectiveEventData e) { WardenObjectiveManager.CheckAndExecuteEventsOnTrigger(e, (eWardenObjectiveEventTrigger)0, true, 0f); }); } } } } namespace ExtraObjectiveSetup.Patches.Terminal { [HarmonyPatch] internal static class Patch_FixHiddenCommandExecution { [HarmonyPrefix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "ReceiveCommand")] private static void Pre_TerminalInterpreter_ReceiveCommand(LG_ComputerTerminalCommandInterpreter __instance, ref TERM_Command cmd) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Expected I4, but got Unknown TERM_Command val = cmd; switch (val - 1) { case 0: case 1: case 2: case 3: case 11: case 13: case 14: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 31: case 32: case 33: case 42: if (__instance.m_terminal.CommandIsHidden(cmd)) { cmd = (TERM_Command)10; } break; case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 12: case 15: case 16: case 29: case 30: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: break; } } } [HarmonyPatch] internal static class Patch_FixRepeatablePuzzleBugs { [HarmonyPrefix] [HarmonyPatch(typeof(CP_Cluster_Core), "OnSyncStateChange")] private static bool Pre_CheckEventsOnPuzzleSolved(CP_Cluster_Core __instance, eClusterStatus newStatus, bool isDropinState) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_004b: 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_0052: Invalid comparison between Unknown and I4 //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 pClusterState currentState = __instance.m_sync.GetCurrentState(); if (isDropinState && (int)newStatus == 3) { __instance.m_spline.SetVisible(false); for (int i = 0; i < ((Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores).Length; i++) { ((Il2CppArrayBase<iChainedPuzzleCore>)(object)__instance.m_childCores)[i].Deactivate(); } return false; } if (!isDropinState && (int)currentState.status == 3 && (int)newStatus == 1) { __instance.m_spline.Reveal(0f); return false; } return true; } } [HarmonyPatch] internal static class Patch_LG_ComputerTerminal_Setup { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminal), "Setup")] private static void Post_LG_ComputerTerminal_Setup(LG_ComputerTerminal __instance) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) uint instanceIndex = TerminalInstanceManager.Current.Register(__instance); TerminalInstanceManager.Current.SetupTerminalWrapper(__instance); if (__instance.SpawnNode == null) { return; } (eDimensionIndex, LG_LayerType, eLocalZoneIndex) globalZoneIndex = TerminalInstanceManager.Current.GetGlobalZoneIndex(__instance); TerminalPosition definition = TerminalPositionOverrideManager.Current.GetDefinition(globalZoneIndex, instanceIndex); if (definition != null) { if (definition.Position.ToVector3() != Vector3.zeroVector) { ((Component)__instance).transform.position = definition.Position.ToVector3(); ((Component)__instance).transform.rotation = definition.Rotation.ToQuaternion(); } EOSLogger.Debug($"TerminalPositionOverride: {definition.LocalIndex}, {definition.LayerType}, {definition.DimensionIndex}, TerminalIndex {definition.InstanceIndex}"); } } } [HarmonyPatch] internal static class Patch_RepeatableCommandEventFix { [HarmonyPostfix] [HarmonyPatch(typeof(LG_ComputerTerminalCommandInterpreter), "SetupCommandEvents")] private static void Post_ResetRepeatableUniqueCommandChainedPuzzle(LG_ComputerTerminalCommandInterpreter __instance) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) LG_ComputerTerminal terminal = __instance.m_terminal; ChainedPuzzleInstance val = default(ChainedPuzzleInstance); foreach (TERM_Command uNIQUE_CMD in TerminalInstanceManager.UNIQUE_CMDS) { if (!__instance.m_commandsPerEnum.ContainsKey(uNIQUE_CMD)) { continue; } string text = __instance.m_commandsPerEnum[uNIQUE_CMD]; if ((int)__instance.m_terminal.GetCommandRule(uNIQUE_CMD) != 0) { continue; } List<WardenObjectiveEventData> uniqueCommandEvents = __instance.m_terminal.GetUniqueCommandEvents(text); for (int i = 0; i < uniqueCommandEvents.Count; i++) { if (uniqueCommandEvents[i].ChainPuzzle != 0) { if (__instance.m_terminal.TryGetChainPuzzleForCommand(uNIQUE_CMD, i, ref val) && (Object)(object)val != (Object)null) { ChainedPuzzleInstance obj = val; obj.OnPuzzleSolved += Action.op_Implicit((Action)val.ResetProgress); } EOSLogger.Debug($"TerminalTweak: {terminal.ItemKey}, command {text} set to be repeatable!"); } } } } } } namespace ExtraObjectiveSetup.Patches.LGFactory { [HarmonyPatch] internal class Patch_LG_Factory_NextBatch { [HarmonyPostfix] [HarmonyPatch(typeof(LG_Factory), "NextBatch")] private static void Post_LG_Factory_NextBatch(LG_Factory __instance) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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) int num = __instance.m_batchStep - 1; if (num >= 0) { BatchName batchName = ((Il2CppArrayBase<LG_FactoryBatch>)(object)__instance.m_batches)[num].m_batchName; Action action = BatchBuildManager.Current.Get_OnBatchDone(batchName); if (action != null) { EOSLogger.Warning($"On Batch '{batchName}' Done: {action.GetInvocationList().Length} injected jobs"); action(); } } } } } namespace ExtraObjectiveSetup.Patches.HSUActivator { [HarmonyPatch] internal class SetupFromCustomGeomorph { [HarmonyPostfix] [HarmonyPatch(typeof(LG_HSUActivator_Core), "SetupFromCustomGeomorph")] private static void Post_LG_HSUActivator_Core_SetupFromCustomGeomorph(LG_HSUActivator_Core __instance) { //IL_0033: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0239: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) uint instanceIndex = HSUActivatorInstanceManager.Current.Register(__instance); HSUActivatorDefinition definition = HSUActivatorObjectiveManager.Current.GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, instanceIndex); if (definition == null) { return; } if (__instance.m_isWardenObjective) { EOSLogger.Error("BuildCustomHSUActivator: the HSUActivator has been set up by vanilla! Aborting custom setup..."); EOSLogger.Error($"HSUActivator in {__instance.SpawnNode.m_zone.LocalIndex}, {__instance.SpawnNode.LayerType}, {__instance.SpawnNode.m_dimension.DimensionIndex}"); return; } __instance.m_linkedItemGoingIn = __instance.SpawnPickupItemOnAlign(definition.ItemFromStart, __instance.m_itemGoingInAlign, false, -1); __instance.m_linkedItemComingOut = __instance.SpawnPickupItemOnAlign(definition.ItemAfterActivation, __instance.m_itemComingOutAlign, false, -1); LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemGoingIn).GetComponentInChildren<iTerminalItem>()); LG_LevelInteractionManager.DeregisterTerminalItem(((Component)__instance.m_linkedItemComingOut).GetComponentInChildren<iTerminalItem>()); __instance.m_linkedItemGoingIn.SetPickupInteractionEnabled(false); __instance.m_linkedItemComingOut.SetPickupInteractionEnabled(false); __instance.m_insertHSUInteraction.OnInteractionSelected = Action<PlayerAgent>.op_Implicit((Action<PlayerAgent>)delegate { }); __instance.m_sequencerInsertItem.OnSequenceDone = Action.op_Implicit((Action)delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) pHSUActivatorState state2 = __instance.m_stateReplicator.State; if (!state2.isSequenceIncomplete) { EOSLogger.Log(">>>>>> HSUInsertSequenceDone! Sequence was already complete"); } state2.isSequenceIncomplete = false; __instance.m_stateReplicator.SetStateUnsynced(state2); EOSLogger.Log(">>>>>> HSUInsertSequenceDone!"); if (__instance.m_triggerExtractSequenceRoutine != null) { ((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine); } }); __instance.m_sequencerExtractItem.OnSequenceDone = Action.op_Implicit((Action)delegate { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) SNet_StateReplicator<pHSUActivatorState, pHSUActivatorInteraction> stateReplicator = __instance.m_stateReplicator; pHSUActivatorState state = __instance.m_stateReplicator.State; state.isSequenceIncomplete = true; stateReplicator.SetStateUnsynced(state); if (SNet.IsMaster) { __instance.AttemptInteract(new pHSUActivatorInteraction { type = (eHSUActivatorInteractionType)2 }); } }); EOSLogger.Debug($"HSUActivator: {(definition.DimensionIndex, definition.LayerType, definition.LocalIndex, definition.InstanceIndex)}, custom setup complete"); } } [HarmonyPatch] internal class SyncStatusChanged { [HarmonyPrefix] [HarmonyPatch(typeof(LG_HSUActivator_Core), "SyncStatusChanged")] private static bool Pre_LG_HSUActivator_Core_SyncStatusChanged(LG_HSUActivator_Core __instance, pHSUActivatorState newState, bool isRecall) { //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected I4, but got Unknown //IL_030b: Unknown result type (might be due to invalid IL or missing references) if (__instance.m_isWardenObjective) { return true; } uint zoneInstanceIndex = HSUActivatorInstanceManager.Current.GetZoneInstanceIndex(__instance); if (zoneInstanceIndex == uint.MaxValue) { EOSLogger.Error($"Found unregistered HSUActivator!! {HSUActivatorInstanceManager.Current.GetGlobalZoneIndex(__instance)}"); return true; } HSUActivatorDefinition definition = HSUActivatorObjectiveManager.Current.GetDefinition(__instance.SpawnNode.m_dimension.DimensionIndex, __instance.SpawnNode.LayerType, __instance.SpawnNode.m_zone.LocalIndex, zoneInstanceIndex); if (definition == null) { return true; } if (__instance.m_triggerExtractSequenceRoutine != null) { ((MonoBehaviour)__instance).StopCoroutine(__instance.m_triggerExtractSequenceRoutine); } bool goingInVisibleForPostCulling = __instance.m_goingInVisibleForPostCulling; bool comingOutVisibleForPostCulling = __instance.m_comingOutVisibleForPostCulling; EOSLogger.Debug("LG_HSUActivator_Core.OnSyncStatusChanged " + ((object)(eHSUActivatorStatus)(ref newState.status)).ToString()); eHSUActivatorStatus status = newState.status; switch ((int)status) { case 0: __instance.m_insertHSUInteraction.SetActive(true); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, false, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingForItem.StartSequence(); __instance.m_sequencerInsertItem.StopSequence(); __instance.m_sequencerExtractItem.StopSequence(); __instance.m_sequencerExtractionDone.StopSequence(); break; case 1: __instance.m_insertHSUInteraction.SetActive(false); __instance.ResetItem(__instance.m_itemGoingInAlign, __instance.m_linkedItemGoingIn, true, false, true, ref goingInVisibleForPostCulling); __instance.ResetItem(__instance.m_itemComingOutAlign, __instance.m_linkedItemComingOut, false, false, true, ref comingOutVisibleForPostCulling); __instance.m_sequencerWaitingFor
plugins/FloLib.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using AIGraph; using AK; using Agents; using AssetShards; using BepInEx; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using BepInEx.Unity.IL2CPP.Hook; using BepInEx.Unity.IL2CPP.Utils; using BepInEx.Unity.IL2CPP.Utils.Collections; using FloLib.Attributes; using FloLib.Events; using FloLib.Infos; using FloLib.Infos.Comps; using FloLib.Infos.Inject; using FloLib.Networks; using FloLib.Networks.Inject; using FloLib.Networks.PayloadStructs; using FloLib.Utils; using FloLib.Utils.Comps; using FloLib.Utils.Extensions; using GTFO.API; using GameData; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppInterop.Runtime.InteropTypes.Fields; using Il2CppInterop.Runtime.Runtime; using Il2CppSystem; using Il2CppSystem.Collections.Generic; using LevelGeneration; using Microsoft.CodeAnalysis; using Player; using SNetwork; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("FloLib")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+gitd7090d7-dirty-master")] [assembly: AssemblyProduct("FloLib")] [assembly: AssemblyTitle("FloLib")] [assembly: TargetPlatform("Windows7.0")] [assembly: SupportedOSPlatform("Windows7.0")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NativeIntegerAttribute : Attribute { public readonly bool[] TransformFlags; public NativeIntegerAttribute() { TransformFlags = new bool[1] { true }; } public NativeIntegerAttribute(bool[] P_0) { TransformFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace FloLib { public static class Automation { private const BindingFlags ALL = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenStartGame; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenStartupAssetLoaded; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenEnemyAssetLoaded; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenSharedAssetLoaded; private static readonly Queue<(MethodInfo method, object[] args)> _InvokeWhenAllAssetsLoaded; static Automation() { _InvokeWhenStartGame = new Queue<(MethodInfo, object[])>(); _InvokeWhenStartupAssetLoaded = new Queue<(MethodInfo, object[])>(); _InvokeWhenEnemyAssetLoaded = new Queue<(MethodInfo, object[])>(); _InvokeWhenSharedAssetLoaded = new Queue<(MethodInfo, object[])>(); _InvokeWhenAllAssetsLoaded = new Queue<(MethodInfo, object[])>(); StartGameEvent.OnGameLoaded += delegate { (MethodInfo, object[]) result5; while (_InvokeWhenStartGame.TryDequeue(out result5)) { RunMethod(result5.Item1, result5.Item2); } }; AssetEvent.OnStartupAssetLoaded += delegate { (MethodInfo, object[]) result4; while (_InvokeWhenStartupAssetLoaded.TryDequeue(out result4)) { RunMethod(result4.Item1, result4.Item2); } }; AssetEvent.OnEnemyAssetLoaded += delegate { (MethodInfo, object[]) result3; while (_InvokeWhenEnemyAssetLoaded.TryDequeue(out result3)) { RunMethod(result3.Item1, result3.Item2); } }; AssetEvent.OnSharedAssetLoaded += delegate { (MethodInfo, object[]) result2; while (_InvokeWhenSharedAssetLoaded.TryDequeue(out result2)) { RunMethod(result2.Item1, result2.Item2); } }; AssetEvent.OnAllAssetsLoaded += delegate { (MethodInfo, object[]) result; while (_InvokeWhenAllAssetsLoaded.TryDequeue(out result)) { RunMethod(result.Item1, result.Item2); } }; } public static void RegisterTypes() { Assembly obj = new StackFrame(1).GetMethod()?.GetType()?.Assembly ?? null; if (obj == null) { throw new NullReferenceException("Caller Assembly was null"); } RegisterTypes(obj); } public static void RegisterTypes(Type target) { if (target == null) { throw new ArgumentNullException("target"); } RegisterTypes(target.Assembly); } public static void RegisterTypes(Assembly target) { if (target == null) { throw new ArgumentNullException("target"); } InjectAll(target); AddAutoInvokes(target); } private static void InjectAll(Assembly assem) { //IL_0069: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown foreach (Type item in assem.GetTypes()?.Where((Type x) => Attribute.IsDefined(x, typeof(AutoInjectAttribute))) ?? Enumerable.Empty<Type>()) { AutoInjectAttribute autoInjectAttribute = (AutoInjectAttribute)Attribute.GetCustomAttribute(item, typeof(AutoInjectAttribute)); if (autoInjectAttribute.Interfaces.Length != 0) { RegisterTypeOptions val = new RegisterTypeOptions(); val.set_Interfaces(Il2CppInterfaceCollection.op_Implicit(autoInjectAttribute.Interfaces)); val.set_LogSuccess(RegisterTypeOptions.Default.LogSuccess); ClassInjector.RegisterTypeInIl2Cpp(item, val); } else { ClassInjector.RegisterTypeInIl2Cpp(item); } } } private static void AddAutoInvokes(Assembly assem) { foreach (MethodInfo item in assem.GetTypes()?.SelectMany((Type x) => x.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))?.Where((MethodInfo x) => x.IsStatic && Attribute.IsDefined(x, typeof(AutoInvokeAttribute))) ?? Enumerable.Empty<MethodInfo>()) { AutoInvokeAttribute obj = (AutoInvokeAttribute)Attribute.GetCustomAttribute(item, typeof(AutoInvokeAttribute)); object[] arguments = obj.Arguments; switch (obj.When) { case InvokeWhen.PluginLoaded: RunMethod(item, arguments); break; case InvokeWhen.StartGame: _InvokeWhenStartGame.Enqueue((item, arguments)); break; case InvokeWhen.StartupAssetLoaded: _InvokeWhenStartupAssetLoaded.Enqueue((item, arguments)); break; case InvokeWhen.EnemyAssetLoaded: _InvokeWhenEnemyAssetLoaded.Enqueue((item, arguments)); break; case InvokeWhen.SharedAssetLoaded: _InvokeWhenSharedAssetLoaded.Enqueue((item, arguments)); break; case InvokeWhen.AllAssetsLoaded: _InvokeWhenAllAssetsLoaded.Enqueue((item, arguments)); break; } } } private static void RunMethod(MethodInfo method, params object[] args) { if (method.IsConstructor) { RuntimeHelpers.RunClassConstructor(method.DeclaringType.TypeHandle); } else { method.Invoke(null, args); } } } [BepInPlugin("GTFO.FloLib", "FloLib", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal class EntryPoint : BasePlugin { private Harmony _Harmony; public override void Load() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown _Harmony = new Harmony("FloLib.Harmony"); _Harmony.PatchAll(); Automation.RegisterTypes(((object)this).GetType()); } public override bool Unload() { _Harmony.UnpatchSelf(); return ((BasePlugin)this).Unload(); } } internal static class Logger { internal static bool LogExceptionInDetail; private static readonly ManualLogSource _Logger; static Logger() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown _Logger = new ManualLogSource("FloLib"); Logger.Sources.Add((ILogSource)(object)_Logger); } private static string Format(object msg) { return msg.ToString(); } public static void Info(BepInExInfoLogInterpolatedStringHandler handler) { _Logger.LogInfo(handler); } public static void Info(string str) { _Logger.LogMessage((object)str); } public static void Info(object data) { _Logger.LogMessage((object)Format(data)); } public static void Debug(BepInExDebugLogInterpolatedStringHandler handler) { _Logger.LogDebug(handler); } public static void Debug(string str) { _Logger.LogDebug((object)str); } public static void Debug(object data) { _Logger.LogDebug((object)Format(data)); } public static void Error(BepInExErrorLogInterpolatedStringHandler handler) { _Logger.LogError(handler); } public static void Error(string str) { _Logger.LogError((object)str); } public static void Error(object data) { _Logger.LogError((object)Format(data)); } public static void Fatal(BepInExFatalLogInterpolatedStringHandler handler) { _Logger.LogFatal(handler); } public static void Fatal(string str) { _Logger.LogFatal((object)str); } public static void Fatal(object data) { _Logger.LogFatal((object)Format(data)); } public static void Warn(BepInExWarningLogInterpolatedStringHandler handler) { _Logger.LogWarning(handler); } public static void Warn(string str) { _Logger.LogWarning((object)str); } public static void Warn(object data) { _Logger.LogWarning((object)Format(data)); } [Conditional("DEBUG")] public static void DebugOnly(object data) { } public static void Exception(Exception e) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown if (LogExceptionInDetail) { _Logger.LogError((object)e.ToString()); return; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(2, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.GetType().Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(e.Message); } _Logger.LogError(val); } } internal static class TaskQueue { public const float INTERVAL = 0.15f; private static readonly ConcurrentQueue<(Action action, string? name)> q; public static Coroutine mainCoroutine { get; private set; } private static IEnumerator MainLoop() { while (true) { if (q.TryDequeue(out (Action, string) result)) { CoroutineManager.StartCoroutine(CollectionExtensions.WrapToIl2Cpp(ExecuteTask(result.Item1, (result.Item2 == null) ? "unnamed" : result.Item2)), (Action)null); } yield return (object)new WaitForSeconds(0.15f); } } private static IEnumerator ExecuteTask(Action task, string name) { try { task?.Invoke(); } catch (Exception ex) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(46, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Exception occurred during execution of task "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } Logger.Error(val); } yield break; } public static void AddTask(Action task, string name = null) { q.Enqueue((task, name)); } static TaskQueue() { q = new ConcurrentQueue<(Action, string)>(); Logger.Debug("TaskQueue: Coroutine started"); mainCoroutine = CoroutineManager.StartPersistantCoroutine(CollectionExtensions.WrapToIl2Cpp(MainLoop())); } } [GeneratedCode("VersionInfoGenerator", "2.1.3+git35c0c2a-master")] [CompilerGenerated] internal static class VersionInfo { public const string RootNamespace = "FloLib"; public const string Version = "1.0.0"; public const string VersionPrerelease = null; public const string VersionMetadata = "gitd7090d7-dirty-master"; public const string SemVer = "1.0.0+gitd7090d7-dirty-master"; public const string GitRevShort = "d7090d7-dirty"; public const string GitRevLong = "d7090d7625ec9ea5a37260ec10ba96729e107216-dirty"; public const string GitBranch = "master"; public const string GitTag = null; public const int GitCommitsSinceTag = 0; public const bool GitIsDirty = true; } } namespace FloLib.Utils { public enum CoroutineLifeTime { Forever, Lobby, Level, BetweenRecall } public static class Coroutines { private static MonoBehaviour _Runner; private static readonly Queue<Coroutine> _Coroutines_Lobby = new Queue<Coroutine>(); private static readonly Queue<Coroutine> _Coroutines_Level = new Queue<Coroutine>(); private static readonly Queue<Coroutine> _Coroutines_CPLoad = new Queue<Coroutine>(); [AutoInvoke(InvokeWhen.StartGame)] internal static void Init() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject(); Object.DontDestroyOnLoad((Object)val); _Runner = (MonoBehaviour)(object)val.AddComponent<EmptyMB>(); LevelAPI.OnLevelCleanup += LevelAPI_OnLevelCleanup; Inject_SNet_Capture.OnBufferRecalled += Inject_SNet_Capture_OnBufferRecalled; } private static void Inject_SNet_Capture_OnBufferRecalled(eBufferType obj) { StopAll(CoroutineLifeTime.BetweenRecall); } private static void LevelAPI_OnLevelCleanup() { StopAll(); StopAll(CoroutineLifeTime.BetweenRecall); } public static void StopAll(CoroutineLifeTime lifeTime = CoroutineLifeTime.Level) { Queue<Coroutine> queue = lifeTime switch { CoroutineLifeTime.Lobby => _Coroutines_Lobby, CoroutineLifeTime.Level => _Coroutines_Level, CoroutineLifeTime.BetweenRecall => _Coroutines_CPLoad, _ => throw new NotSupportedException($"{"CoroutineLifeTime"}: {lifeTime} is not supported!"), }; Coroutine result; while (queue.TryDequeue(out result)) { _Runner.StopCoroutine(result); } } public static void Stop(Coroutine coroutine) { _Runner.StopCoroutine(coroutine); } public static Coroutine Start(IEnumerator coroutine, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { switch (lifeTime) { case CoroutineLifeTime.Forever: return MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); case CoroutineLifeTime.Lobby: { Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); _Coroutines_Lobby.Enqueue(val); return val; } case CoroutineLifeTime.Level: { Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); _Coroutines_Level.Enqueue(val); return val; } case CoroutineLifeTime.BetweenRecall: { Coroutine val = MonoBehaviourExtensions.StartCoroutine(_Runner, coroutine); _Coroutines_CPLoad.Enqueue(val); return val; } default: throw new NotSupportedException($"{"CoroutineLifeTime"}: {lifeTime} is not supported!!"); } } public static Coroutine DoWait(float delay, Action onDone, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(Wait(delay, onDone), lifeTime); } public static Coroutine DoWaitRealtime(float delay, Action onDone, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(WaitRealtime(delay, onDone), lifeTime); } public static Coroutine DoBlink(BlinkInfo blinkInfo, Action<bool> onBlinkChanged, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(Blink(blinkInfo, onBlinkChanged), lifeTime); } public static Coroutine DoLerp(LerpInfo lerpInfo, Action<float> onValueChanged, CoroutineLifeTime lifeTime = CoroutineLifeTime.Forever) { return Start(Lerp(lerpInfo, onValueChanged), lifeTime); } public static IEnumerator Wait(float delay, Action onDone) { yield return (object)new WaitForSeconds(delay); onDone?.Invoke(); } public static IEnumerator WaitRealtime(float delay, Action onDone) { yield return (object)new WaitForSecondsRealtime(delay); onDone?.Invoke(); } public static IEnumerator Blink(BlinkInfo info, Action<bool> onBlinkChanged) { float time = 0f; bool lastCond = false; onBlinkChanged?.Invoke(obj: false); while (time < info.Duration) { bool flag = BlinkByProgress(Mathf.Repeat(time * info.Speed, 1f)); if (flag != lastCond) { onBlinkChanged?.Invoke(flag); lastCond = flag; } time += Time.deltaTime; yield return null; } onBlinkChanged?.Invoke(info.EndBlinkState); } public static IEnumerator Lerp(LerpInfo info, Action<float> onValueChanged) { float time = 0f; onValueChanged?.Invoke(info.From); while (time < info.Duration) { float num = info.Easing.Evaluate(time / info.Duration); float obj = Mathf.Lerp(info.From, info.To, num); onValueChanged?.Invoke(obj); time += Time.deltaTime; yield return null; } onValueChanged?.Invoke(info.To); } private static bool BlinkByProgress(float progress) { return progress % 0.25f < 0.125f; } } public struct BlinkInfo { public bool EndBlinkState; public float Speed; public float Duration; public static readonly BlinkInfo InDefault = new BlinkInfo { Duration = 0.33f, Speed = 3f, EndBlinkState = true }; public static readonly BlinkInfo OutDefault = new BlinkInfo { Duration = 0.33f, Speed = 3f, EndBlinkState = false }; } public struct LerpInfo { public float From; public float To; public float Duration; public EaseFunc.Type Easing; public LerpInfo(float from, float to, float duration, EaseFunc.Type ease = EaseFunc.Type.Linear) { From = from; To = to; Duration = duration; Easing = ease; } } public static class EaseFunc { public enum Type : byte { Linear, Zero, One, InQuad, OutQuad, InOutQuad, InCubic, OutCubic, InOutCubic, InQuart, OutQuart, InOutQuart, InQuint, OutQuint, InOutQuint, InSine, OutSine, InOutSine, InExpo, OutExpo, InOutExpo, InCirc, OutCirc, InOutCirc, InElastic, OutElastic, InOutElastic, InBack, OutBack, InOutBack, InBounce, OutBounce, InOutBounce } public static float Evaluate(this Type type, float t) { t = Mathf.Clamp01(t); return type switch { Type.Linear => t, Type.Zero => 0f, Type.One => 1f, Type.InQuad => InQuad(t), Type.OutQuad => OutQuad(t), Type.InOutQuad => InOutQuad(t), Type.InCubic => InCubic(t), Type.OutCubic => OutCubic(t), Type.InOutCubic => InOutCubic(t), Type.InQuart => InQuart(t), Type.OutQuart => OutQuart(t), Type.InOutQuart => InOutQuart(t), Type.InQuint => InQuint(t), Type.OutQuint => OutQuint(t), Type.InOutQuint => InOutQuint(t), Type.InSine => InSine(t), Type.OutSine => OutSine(t), Type.InOutSine => InOutSine(t), Type.InExpo => InExpo(t), Type.OutExpo => OutExpo(t), Type.InOutExpo => InOutExpo(t), Type.InCirc => InCirc(t), Type.OutCirc => OutCirc(t), Type.InOutCirc => InOutCirc(t), Type.InElastic => InElastic(t), Type.OutElastic => OutElastic(t), Type.InOutElastic => InOutElastic(t), Type.InBack => InBack(t), Type.OutBack => OutBack(t), Type.InOutBack => InOutBack(t), Type.InBounce => InBounce(t), Type.OutBounce => OutBounce(t), Type.InOutBounce => InOutBounce(t), _ => throw new ArgumentOutOfRangeException("type", "Given type was invalid!"), }; } public static float InQuad(float t) { return t * t; } public static float OutQuad(float t) { return 1f - InQuad(1f - t); } public static float InOutQuad(float t) { if ((double)t < 0.5) { return InQuad(t * 2f) / 2f; } return 1f - InQuad((1f - t) * 2f) / 2f; } public static float InCubic(float t) { return t * t * t; } public static float OutCubic(float t) { return 1f - InCubic(1f - t); } public static float InOutCubic(float t) { if ((double)t < 0.5) { return InCubic(t * 2f) / 2f; } return 1f - InCubic((1f - t) * 2f) / 2f; } public static float InQuart(float t) { return t * t * t * t; } public static float OutQuart(float t) { return 1f - InQuart(1f - t); } public static float InOutQuart(float t) { if ((double)t < 0.5) { return InQuart(t * 2f) / 2f; } return 1f - InQuart((1f - t) * 2f) / 2f; } public static float InQuint(float t) { return t * t * t * t * t; } public static float OutQuint(float t) { return 1f - InQuint(1f - t); } public static float InOutQuint(float t) { if ((double)t < 0.5) { return InQuint(t * 2f) / 2f; } return 1f - InQuint((1f - t) * 2f) / 2f; } public static float InSine(float t) { return (float)(0.0 - Math.Cos((double)t * Math.PI / 2.0)); } public static float OutSine(float t) { return (float)Math.Sin((double)t * Math.PI / 2.0); } public static float InOutSine(float t) { return (float)(Math.Cos((double)t * Math.PI) - 1.0) / -2f; } public static float InExpo(float t) { return (float)Math.Pow(2.0, 10f * (t - 1f)); } public static float OutExpo(float t) { return 1f - InExpo(1f - t); } public static float InOutExpo(float t) { if ((double)t < 0.5) { return InExpo(t * 2f) / 2f; } return 1f - InExpo((1f - t) * 2f) / 2f; } public static float InCirc(float t) { return 0f - ((float)Math.Sqrt(1f - t * t) - 1f); } public static float OutCirc(float t) { return 1f - InCirc(1f - t); } public static float InOutCirc(float t) { if ((double)t < 0.5) { return InCirc(t * 2f) / 2f; } return 1f - InCirc((1f - t) * 2f) / 2f; } public static float InElastic(float t) { return 1f - OutElastic(1f - t); } public static float OutElastic(float t) { float num = 0.3f; return (float)Math.Pow(2.0, -10f * t) * (float)Math.Sin((double)(t - num / 4f) * (Math.PI * 2.0) / (double)num) + 1f; } public static float InOutElastic(float t) { if ((double)t < 0.5) { return InElastic(t * 2f) / 2f; } return 1f - InElastic((1f - t) * 2f) / 2f; } public static float InBack(float t) { float num = 1.70158f; return t * t * ((num + 1f) * t - num); } public static float OutBack(float t) { return 1f - InBack(1f - t); } public static float InOutBack(float t) { if ((double)t < 0.5) { return InBack(t * 2f) / 2f; } return 1f - InBack((1f - t) * 2f) / 2f; } public static float InBounce(float t) { return 1f - OutBounce(1f - t); } public static float OutBounce(float t) { float num = 2.75f; float num2 = 7.5625f; if (t < 1f / num) { return num2 * t * t; } if (t < 2f / num) { t -= 1.5f / num; return num2 * t * t + 0.75f; } if ((double)t < 2.5 / (double)num) { t -= 2.25f / num; return num2 * t * t + 0.9375f; } t -= 2.625f / num; return num2 * t * t + 63f / 64f; } public static float InOutBounce(float t) { if ((double)t < 0.5) { return InBounce(t * 2f) / 2f; } return 1f - InBounce((1f - t) * 2f) / 2f; } } public static class EasyDetour { public unsafe delegate void StaticVoidDelegate(Il2CppMethodInfo* methodInfo); public unsafe delegate void InstanceVoidDelegate(IntPtr instancePtr, Il2CppMethodInfo* methodInfo); public static bool TryCreate<T>(DetourDescriptor descriptor, T to, out T originalCall, out INativeDetour detourInstance) where T : Delegate { try { nint methodPointer = descriptor.GetMethodPointer(); detourInstance = INativeDetour.CreateAndApply<T>((IntPtr)methodPointer, to, ref originalCall); return detourInstance != null; } catch (Exception ex) { Logger.Error("Exception Thrown while creating Detour:"); Logger.Error(ex.ToString()); } originalCall = null; detourInstance = null; return false; } } public struct DetourDescriptor { public Type Type; public Type ReturnType; public Type[] ArgTypes; public string MethodName; public bool IsGeneric; public unsafe nint GetMethodPointer() { if (Type == null) { throw new MissingFieldException("Field Type is not set!"); } if (ReturnType == null) { throw new MissingFieldException("Field ReturnType is not set! If you mean 'void' do typeof(void)"); } if (string.IsNullOrEmpty(MethodName)) { throw new MissingFieldException("Field MethodName is not set or valid!"); } Il2CppType.From(Type, true); IntPtr nativeClassPointer = Il2CppClassPointerStore.GetNativeClassPointer(Type); string fullName = GetFullName(ReturnType); string[] array; if (ArgTypes == null || ArgTypes.Length == 0) { array = Array.Empty<string>(); } else { int num = ArgTypes.Length; array = new string[num]; for (int i = 0; i < num; i++) { Type type = ArgTypes[i]; array[i] = GetFullName(type); } } void** ptr = (void**)IL2CPP.GetIl2CppMethod(nativeClassPointer, IsGeneric, MethodName, fullName, array).ToPointer(); if (ptr == null) { return (nint)ptr; } return (nint)(*ptr); } private static string GetFullName(Type type) { bool isPointer = type.IsPointer; if (isPointer) { type = type.GetElementType(); } if (type.IsPrimitive || type == typeof(string)) { if (isPointer) { return type.MakePointerType().FullName; } return type.FullName; } Type val = Il2CppType.From(type, true); if (isPointer) { return val.MakePointerType().FullName; } return val.FullName; } } public struct HalfColor { public Half R; public Half G; public Half B; public Half A; public HalfColor() { R = (Half)0f; G = (Half)0f; B = (Half)0f; A = (Half)0f; } public HalfColor(float r, float g, float b, float a) { R = (Half)r; G = (Half)g; B = (Half)b; A = (Half)a; } public static implicit operator Color(HalfColor halfCol) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new Color((float)halfCol.R, (float)halfCol.G, (float)halfCol.B, (float)halfCol.A); } public static implicit operator HalfColor(Color col) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) HalfColor result = new HalfColor(); result.R = (Half)col.r; result.G = (Half)col.g; result.B = (Half)col.b; result.A = (Half)col.a; return result; } } public struct HalfRGBColor { public Half R; public Half G; public Half B; public static implicit operator Color(HalfRGBColor halfCol) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) return new Color((float)halfCol.R, (float)halfCol.G, (float)halfCol.B); } public static implicit operator HalfRGBColor(Color col) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) HalfRGBColor result = default(HalfRGBColor); result.R = (Half)col.r; result.G = (Half)col.g; result.B = (Half)col.b; return result; } } public class RNG { private const int Float01Precision = 2000000000; private const float Float01Inv = 5E-10f; private static uint _UniqueIDForRandomSeed = 0u; private Random _Rand; private int _Seed; public static GlobalRNG Global { get; private set; } = new GlobalRNG(); public float Float01 => (float)_Rand.Next(0, 2000000001) * 5E-10f; public float FloatMinusOneToPlusOne => (float)_Rand.Next(-2000000000, 2000000001) * 5E-10f; public int Int0ToPositive => _Rand.Next(0, int.MaxValue); public int Int0ToNegative => _Rand.Next(int.MinValue, 1); public int Int => _Rand.Next(int.MinValue, int.MaxValue); public RNG() { if (_UniqueIDForRandomSeed == uint.MaxValue) { _UniqueIDForRandomSeed = 0u; } else { _UniqueIDForRandomSeed++; } _Seed = $"{_UniqueIDForRandomSeed} {Environment.TickCount64}".GetHashCode(); _Rand = new Random(_Seed); } public RNG(int seed) { _Seed = seed; _Rand = new Random(seed); } public virtual void Reset(int? newSeed = null) { if (newSeed.HasValue) { _Seed = newSeed.Value; } _Rand = new Random(_Seed); } public bool Probability(float probability) { if (probability <= 0f) { return false; } if (probability >= 1f) { return true; } return Float01 < probability; } public bool OneIn(int cases) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown if (cases <= 0) { bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(46, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RNG"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("."); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("OneIn"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" received "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(cases); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (0 or negative); fallback to false"); } Logger.Warn(val); return false; } if (cases == 1) { return true; } return _Rand.Next(0, cases) == 0; } public T Choice<T>(params T[] items) { return Choice((IEnumerable<T>)items); } public T Choice<T>(IEnumerable<T> items) { if (IsChoiceHaveSimpleScenarioValue(items, out var value)) { return value; } int maxValue = items.Count(); int index = _Rand.Next(0, maxValue); return items.ElementAt(index); } public T[] Choice<T>(IEnumerable<T> items, int count) { if (IsChoiceHaveSimpleScenarioValue(items, out var value)) { return new T[1] { value }; } return items.OrderBy((T x) => _Rand.NextDouble()).Take(count).ToArray(); } public T WeightedChoice<T>(IEnumerable<(T item, float weight)> itemTuples) { if (IsChoiceHaveSimpleScenarioValue<(T, float)>(itemTuples, out var value)) { return value.Item1; } T[] array = itemTuples.Select(((T item, float weight) x) => x.item).ToArray(); float[] array2 = itemTuples.Select(((T item, float weight) x) => x.weight).ToArray(); float num = 0f; for (int i = 0; i < array2.Length; i++) { float num2 = array2[i]; if (num2 <= 0f) { array2[i] = -1f; } else { num = (array2[i] = num + num2); } } if (num <= 0f) { return Choice(array); } float num3 = Float01 * num; for (int j = 0; j < array2.Length; j++) { if (j == array2.Length - 1 || num3 <= array2[j]) { return array[j]; } } throw new InvalidOperationException("What? this should never happen"); } private static bool IsChoiceHaveSimpleScenarioValue<T>(IEnumerable<T> items, out T value) { int num = items.Count(); if (num <= 0) { throw new ArgumentException("Argument Item Count is 0!", "items"); } if (num == 1) { value = items.First(); return true; } value = default(T); return false; } } public sealed class GlobalRNG : RNG { public sealed override void Reset(int? newSeed = null) { Logger.Warn("Resetting Seed Value is not allowed on RNG.Global"); } } } namespace FloLib.Utils.Extensions { public static class ColorExtension { public static string ToHex(this Color input) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGB(input); } public static string ToHexRGBA(this Color input) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return "#" + ColorUtility.ToHtmlStringRGBA(input); } public static void GetColorInfo(this Color input, out Color baseColor, out float colorMultiplier) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) //IL_0077: Unknown result type (might be due to invalid IL or missing references) float num = 0f; float num2 = 0f; float r = input.r; float g = input.g; float b = input.b; float num3 = Mathf.Abs(r); float num4 = Mathf.Abs(g); float num5 = Mathf.Abs(b); if (num3 > num2) { num2 = num3; num = r; } if (num4 > num2) { num2 = num4; num = g; } if (num5 > num2) { num2 = num5; num = b; } if (num2 > 0f) { baseColor = new Color(r / num, g / num, b / num, 1f); colorMultiplier = num; } else { baseColor = Color.black; colorMultiplier = 1f; } } } public static class ComponentExtension { public static bool TryGetComp<T>(this Component comp, out T component) { component = comp.GetComponent<T>(); return component != null; } public static bool TryGetVirtualScene(this Component comp, out GUIX_VirtualScene scene) { GUIX_VirtualSceneLink component = comp.GetComponent<GUIX_VirtualSceneLink>(); if ((Object)(object)component == (Object)null) { scene = null; return false; } scene = component.m_virtualScene; return (Object)(object)scene != (Object)null; } public static string GetGameObjectPath(this Component comp) { return comp.gameObject.GetPath(); } } public static class GameObjectExtension { public static bool TryGetComp<T>(this GameObject obj, out T component) { component = obj.GetComponent<T>(); return component != null; } public static T GetCompInParentOrChild<T>(this GameObject obj) { T val = obj.GetComponentInParent<T>(); if (val == null) { val = obj.GetComponentInChildren<T>(); if (val == null) { obj.GetComponent<T>(); } } return val; } public static string GetPath(this GameObject obj) { string text = "/" + ((Object)obj).name; while ((Object)(object)obj.transform.parent != (Object)null) { obj = ((Component)obj.transform.parent).gameObject; text = "/" + ((Object)obj).name + text; } return text; } } public static class Il2CppBoxingExtension { public static Object BoxToIl2CppObject(this bool value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Boolean val = default(Boolean); val.m_value = value; return ((Boolean)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this byte value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Byte val = default(Byte); val.m_value = value; return ((Byte)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this sbyte value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) SByte val = default(SByte); val.m_value = value; return ((SByte)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this char value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Char val = default(Char); val.m_value = value; return ((Char)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this short value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Int16 val = default(Int16); val.m_value = value; return ((Int16)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this ushort value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UInt16 val = default(UInt16); val.m_value = value; return ((UInt16)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this int value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Int32 val = default(Int32); val.m_value = value; return ((Int32)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this uint value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UInt32 val = default(UInt32); val.m_value = value; return ((UInt32)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this long value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Int64 val = default(Int64); val.m_value = value; return ((Int64)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this ulong value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) UInt64 val = default(UInt64); val.m_value = value; return ((UInt64)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this float value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Single val = default(Single); val.m_value = value; return ((Single)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this double value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) Double val = default(Double); val.m_value = value; return ((Double)(ref val)).BoxIl2CppObject(); } public static Object BoxToIl2CppObject(this nint value) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) IntPtr val = default(IntPtr); val.m_value = value; return ((IntPtr)(ref val)).BoxIl2CppObject(); } } public static class Il2CppObjectExtension { public static bool CanCastToType<T>(this Il2CppObjectBase obj) where T : Il2CppObjectBase { return obj.TryCast<T>() != null; } public static bool TryCastToType<T>(this Il2CppObjectBase obj, out T result) where T : Il2CppObjectBase { result = obj.TryCast<T>(); return result != null; } } public static class LGLightExtension { public static void SetColor(this IEnumerable<LG_Light> lights, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) foreach (LG_Light light in lights) { light.ChangeColor(color); } } public static void SetEnabled(this IEnumerable<LG_Light> lights, bool enabled) { foreach (LG_Light light in lights) { light.SetEnabled(enabled); } } public static bool Is(this LG_Light light, LightCategory lightCategory) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 return (int)light.m_category == (int)lightCategory; } public static bool IsAny(this LG_Light light, params LightCategory[] categories) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 for (int i = 0; i < categories.Length; i++) { if ((int)light.m_category == (int)categories[i]) { return true; } } return false; } } public enum LightCategory { General = 0, Special = 1, Independent = 3, Sign = 5, Door = 4, DoorImportant = 6, Emergency = 2 } public static class TerminalExtension { public static void SetPowered(this LG_ComputerTerminal terminal, bool isPowered) { terminal.OnProximityExit(); Interact_ComputerTerminal componentInChildren = ((Component)terminal).GetComponentInChildren<Interact_ComputerTerminal>(true); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = isPowered; ((Interact_Base)componentInChildren).SetActive(isPowered); } GUIX_VirtualSceneLink component = ((Component)terminal).GetComponent<GUIX_VirtualSceneLink>(); if ((Object)(object)component != (Object)null && (Object)(object)component.m_virtualScene != (Object)null) { GUIX_VirtualCamera virtualCamera = component.m_virtualScene.virtualCamera; float num = (isPowered ? 0.3f : 0f); float num2 = (isPowered ? 1000f : 0f); virtualCamera.SetFovAndClip(virtualCamera.paramCamera.fieldOfView, num, num2); } if ((Object)(object)terminal.m_text != (Object)null) { ((Behaviour)terminal.m_text).enabled = isPowered; } if (!isPowered) { PlayerAgent localInteractionSource = terminal.m_localInteractionSource; if ((Object)(object)localInteractionSource != (Object)null && localInteractionSource.FPItemHolder.InTerminalTrigger) { terminal.ExitFPSView(); } } } } public static class VectorExtension { public static string ToFormattedString(this Vector2 vector) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) return $"x: {vector.x:0.0000}, y: {vector.y:0.0000}"; } public static string ToFormattedString(this Vector3 vector) { //IL_0018: 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_0054: Unknown result type (might be due to invalid IL or missing references) return $"x: {vector.x:0.0000}, y: {vector.y:0.0000} z: {vector.z:0.0000}"; } public static string ToFormattedString(this Vector4 vector) { //IL_0018: 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_0054: 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) return $"x: {vector.x:0.0000}, y: {vector.y:0.0000} z: {vector.z:0.0000} w: {vector.w:0.0000}"; } } } namespace FloLib.Utils.Comps { [AutoInject] internal sealed class EmptyMB : MonoBehaviour { } } namespace FloLib.Networks { public static class GlobalNetAction<P> where P : struct { private static string _EventName; private static bool _IsSetup; public static SNet_ChannelType SendChannel { get; set; } public static SNet_Player LastSender { get; private set; } public static ulong LastSenderID { get; private set; } public static event Action<ulong, P> OnReceive; public static event Action<ulong, P> OnReceiveLocally; static GlobalNetAction() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendChannel = (SNet_ChannelType)2; _IsSetup = false; Setup(); } public static void Setup() { if (!_IsSetup) { _EventName = UName.Get(typeof(P), "NA"); NetworkAPI.RegisterEvent<P>(_EventName, (Action<ulong, P>)Received); _IsSetup = true; } } public static void Send(P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SendToLocal(payload); TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetAction.Send"); } public static void SendTo(P payload, SNet_Player target) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } if (target.IsLocal) { SendToLocal(payload); return; } TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetAction.SendTo"); } public static void SendTo(P payload, SNet_SendGroup group) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } Enumerator<SNet_Player> enumerator = SNet_PlayerSendGroupManager.GetGroup(group).GetEnumerator(); while (enumerator.MoveNext()) { SNet_Player current = enumerator.Current; SendTo(payload, current); } } private static void SendToLocal(P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SNet_Player val = (LastSender = SNet.LocalPlayer); if ((Object)(object)val != (Object)null) { LastSenderID = val.Lookup; } GlobalNetAction<P>.OnReceive?.Invoke(LastSenderID, payload); GlobalNetAction<P>.OnReceiveLocally?.Invoke(LastSenderID, payload); } private static void Received(ulong sender, P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SNet_Player lastSender = default(SNet_Player); if (!SNet.Core.TryGetPlayer(sender, ref lastSender, false)) { LastSender = null; LastSenderID = 0uL; Logger.Error("NetAction sender was invalid!"); } LastSender = lastSender; LastSenderID = sender; GlobalNetAction<P>.OnReceive?.Invoke(sender, payload); } } public static class GlobalNetMasterAction<P> where P : struct { public static Func<ulong, P, bool> IsActionValid; private static string _AskEventName; private static string _EventName; private static bool _IsSetup; public static SNet_ChannelType SendChannel { get; set; } public static SNet_Player LastSender { get; private set; } public static ulong LastSenderID { get; private set; } public static event Action<ulong, P> OnReceive; public static event Action<ulong, P> OnMasterReceive; static GlobalNetMasterAction() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) SendChannel = (SNet_ChannelType)2; IsActionValid = (ulong sender, P p) => true; _IsSetup = false; Setup(); } public static void Setup() { if (!_IsSetup) { _AskEventName = UName.Get(typeof(P), "NMA0"); _EventName = UName.Get(typeof(P), "NMA1"); NetworkAPI.RegisterEvent<P>(_AskEventName, (Action<ulong, P>)ReceivedAsk); NetworkAPI.RegisterEvent<P>(_EventName, (Action<ulong, P>)Received); _IsSetup = true; } } public static void Ask(P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); } else { if (!SNet.HasMaster) { return; } if (SNet.IsMaster) { Func<ulong, P, bool> isActionValid = IsActionValid; if (isActionValid == null || isActionValid(SNet.LocalPlayer.Lookup, payload)) { TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetMasterAction.Master"); GlobalNetMasterAction<P>.OnReceive?.Invoke(SNet.LocalPlayer.Lookup, payload); GlobalNetMasterAction<P>.OnMasterReceive?.Invoke(SNet.LocalPlayer.Lookup, payload); } } else { TaskQueue.AddTask(delegate { //IL_0010: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_AskEventName, payload, SNet.Master, SendChannel); }, "GlobalNetMasterAction.Ask.Client"); } } } private static void ReceivedAsk(ulong sender, P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } if (!SNet.IsMaster) { Logger.Error("Non Master Received Ask Action!"); return; } Func<ulong, P, bool> isActionValid = IsActionValid; if (isActionValid == null || isActionValid(sender, payload)) { TaskQueue.AddTask(delegate { //IL_000b: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(_EventName, payload, SendChannel); }, "GlobalNetMasterAction.ReceivedAsk.Master"); GlobalNetMasterAction<P>.OnReceive?.Invoke(SNet.LocalPlayer.Lookup, payload); GlobalNetMasterAction<P>.OnMasterReceive?.Invoke(sender, payload); } } private static void Received(ulong sender, P payload) { if (!_IsSetup) { Logger.Error("Action Wasn't Setup!"); return; } SNet_Player lastSender = default(SNet_Player); if (!SNet.Core.TryGetPlayer(sender, ref lastSender, false)) { LastSender = null; LastSenderID = 0uL; Logger.Error("NetMasterAction sender was invalid!"); return; } LastSender = lastSender; LastSenderID = sender; if (!LastSender.IsMaster) { Logger.Error("Sender was not a master"); } else { GlobalNetMasterAction<P>.OnReceive?.Invoke(sender, payload); } } } internal static class UName { private static readonly SHA1 SHA = SHA1.Create(); public static string Get(Type type, string prefix) { return prefix + GetHash(type.FullName); } public static string GetHash(string text) { return Convert.ToBase64String(SHA.ComputeHash(Encoding.Unicode.GetBytes(text + "this is salt text, Awesome!"))); } } } namespace FloLib.Networks.Replications { public interface IStateReplicatorHolder<S> where S : struct { StateReplicator<S> Replicator { get; } void OnStateChange(S oldState, S state, bool isRecall); } public sealed class ReplicatorHandshake { public delegate void ClientRequestedSyncDel(SNet_Player requestedPlayer); public struct Packet { public uint replicatorID; public PacketAction action; } public enum PacketAction : byte { Created, Destroyed, SyncRequest } public sealed class Data { public bool SetupOnHost; public bool SetupOnClient; } private readonly Dictionary<uint, Data> _Lookup = new Dictionary<uint, Data>(); public string EventName { get; private set; } public bool IsReadyToSync { get; private set; } public event ClientRequestedSyncDel OnClientSyncRequested; public static ReplicatorHandshake Create(string guid) { if (string.IsNullOrWhiteSpace(guid)) { return null; } string text = "RHs" + guid; if (!NetworkAPI.IsEventRegistered(text)) { return new ReplicatorHandshake(text); } return null; } private ReplicatorHandshake(string eventName) { EventName = eventName; NetworkAPI.RegisterEvent<Packet>(eventName, (Action<ulong, Packet>)OnSyncAction); Inject_OnRecallDone.OnRecallDone += delegate { Logger.Warn("ReplicatorHandshake: client sending sync request"); ClientSyncRequest(); }; } private void ClientSyncRequest() { if (SNet.IsMaster) { return; } foreach (uint replicatorID in _Lookup.Keys) { TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = replicatorID, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); }, $"SyncReplicatorID_{replicatorID}"); } } public void Reset() { _Lookup.Clear(); } private void OnSyncAction(ulong sender, Packet packet) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown if (!SNet.IsMaster && sender == SNet.Master.Lookup) { if (packet.action == PacketAction.Created) { SetHostState(packet.replicatorID, isSetup: true); } else if (packet.action == PacketAction.Destroyed) { SetHostState(packet.replicatorID, isSetup: false); } } else { if (!SNet.IsMaster) { return; } if (packet.action == PacketAction.Created) { SetClientState(packet.replicatorID, isSetup: true); } else if (packet.action == PacketAction.Destroyed) { SetClientState(packet.replicatorID, isSetup: false); } else { if (packet.action != PacketAction.SyncRequest) { return; } SNet_Player requestedPlayer = default(SNet_Player); if (!SNet.TryGetPlayer(sender, ref requestedPlayer)) { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Cannot find player from sender: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<ulong>(sender); } Logger.Error(val); } else { this.OnClientSyncRequested?.Invoke(requestedPlayer); } } } } public void UpdateCreated(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, (SNet_ChannelType)2); }, "UpdateCreated.Master"); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Created }, SNet.Master, (SNet_ChannelType)2); }, "UpdateCreated.Client"); } else { Logger.Error("Handshake::MASTER is NULL in lobby; This should NOT happen!!!!!!!!!!!!"); } } else { Logger.Error("Handshake::Session Type StateReplicator cannot be created without lobby!"); } } public void UpdateDestroyed(uint id) { if (SNet.IsInLobby) { if (SNet.IsMaster) { SetHostState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, (SNet_ChannelType)2); }, "UpdateDestroyed.Master"); } else if (SNet.HasMaster) { SetClientState(id, isSetup: true); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.Destroyed }, SNet.Master, (SNet_ChannelType)2); }, "UpdateDestroyed.Client"); } else { Logger.Error("Handshake::MASTER is NULL in lobby; This should NOT happen!!!!!!!!!!!!"); } } else { Logger.Error("Handshake::Session Type StateReplicator cannot be created without lobby!"); } } private void SetHostState(uint id, bool isSetup) { if (_Lookup.TryGetValue(id, out var value)) { value.SetupOnHost = isSetup; } else { _Lookup[id] = new Data { SetupOnHost = isSetup }; } UpdateSyncState(id); } private void SetClientState(uint id, bool isSetup) { if (_Lookup.TryGetValue(id, out var value)) { value.SetupOnClient = isSetup; } else { _Lookup[id] = new Data { SetupOnClient = isSetup }; } UpdateSyncState(id); } private void UpdateSyncState(uint id) { bool isReadyToSync = IsReadyToSync; if (_Lookup.TryGetValue(id, out var value)) { IsReadyToSync = value.SetupOnHost && value.SetupOnClient; } else { IsReadyToSync = false; } if (IsReadyToSync && isReadyToSync != IsReadyToSync && SNet.HasMaster && !SNet.IsMaster) { TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<Packet>(EventName, new Packet { replicatorID = id, action = PacketAction.SyncRequest }, SNet.Master, (SNet_ChannelType)2); }, "Client.UpdateSyncState.SyncRequest"); } } } public delegate void OnReceiveDel<S>(ulong sender, uint replicatorID, S newState) where S : struct; public static class StatePayloads { public enum Size { State4Byte = 4, State8Byte = 8, State16Byte = 16, State32Byte = 32, State48Byte = 48, State64Byte = 64, State80Byte = 80, State96Byte = 96, State128Byte = 128, State196Byte = 196, State256Byte = 256 } public static Size GetSizeType(int size) { Size size2 = Size.State8Byte; foreach (object value in Enum.GetValues(typeof(Size))) { if (size <= (int)value && (int)size2 < (int)value) { size2 = (Size)value; break; } } return size2; } public static IReplicatorEvent<S> CreateEvent<S>(Size size, string eventName, OnReceiveDel<S> onReceiveCallback) where S : struct { return size switch { Size.State4Byte => ReplicatorPayloadWrapper<S, StatePayload4Byte>.Create(eventName, onReceiveCallback), Size.State8Byte => ReplicatorPayloadWrapper<S, StatePayload8Byte>.Create(eventName, onReceiveCallback), Size.State16Byte => ReplicatorPayloadWrapper<S, StatePayload16Byte>.Create(eventName, onReceiveCallback), Size.State32Byte => ReplicatorPayloadWrapper<S, StatePayload32Byte>.Create(eventName, onReceiveCallback), Size.State48Byte => ReplicatorPayloadWrapper<S, StatePayload48Byte>.Create(eventName, onReceiveCallback), Size.State64Byte => ReplicatorPayloadWrapper<S, StatePayload64Byte>.Create(eventName, onReceiveCallback), Size.State80Byte => ReplicatorPayloadWrapper<S, StatePayload80Byte>.Create(eventName, onReceiveCallback), Size.State96Byte => ReplicatorPayloadWrapper<S, StatePayload96Byte>.Create(eventName, onReceiveCallback), Size.State128Byte => ReplicatorPayloadWrapper<S, StatePayload128Byte>.Create(eventName, onReceiveCallback), Size.State196Byte => ReplicatorPayloadWrapper<S, StatePayload196Byte>.Create(eventName, onReceiveCallback), Size.State256Byte => ReplicatorPayloadWrapper<S, StatePayload256Byte>.Create(eventName, onReceiveCallback), _ => null, }; } public static S Get<S>(byte[] bytes, int bytesLength) where S : struct { int num = Marshal.SizeOf(typeof(S)); if (num > bytesLength) { throw new ArgumentException($"StateData Exceed size of {bytesLength} : Unable to Deserialize", "S"); } IntPtr intPtr = Marshal.AllocHGlobal(num); Marshal.Copy(bytes, 0, intPtr, num); S result = (S)Marshal.PtrToStructure(intPtr, typeof(S)); Marshal.FreeHGlobal(intPtr); return result; } public static void Set<S>(S stateData, int size, ref byte[] payloadBytes) where S : struct { if (Marshal.SizeOf(stateData) > size) { throw new ArgumentException($"StateData Exceed size of {size} : Unable to Serialize", "S"); } byte[] array = new byte[size]; IntPtr intPtr = Marshal.AllocHGlobal(size); Marshal.StructureToPtr(stateData, intPtr, fDeleteOld: false); Marshal.Copy(intPtr, array, 0, size); Marshal.FreeHGlobal(intPtr); payloadBytes = array; } } public interface IReplicatorEvent<S> where S : struct { string Name { get; } bool IsRegistered { get; } void Invoke(uint replicatorID, S data); void Invoke(uint replicatorID, S data, SNet_ChannelType channelType); void Invoke(uint replicatorID, S data, SNet_Player target); void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType); } public class ReplicatorPayloadWrapper<S, P> : IReplicatorEvent<S> where S : struct where P : struct, IStatePayload { public string Name { get; private set; } public bool IsRegistered { get; private set; } public static IReplicatorEvent<S> Create(string eventName, OnReceiveDel<S> onReceiveCallback) { ReplicatorPayloadWrapper<S, P> replicatorPayloadWrapper = new ReplicatorPayloadWrapper<S, P>(); replicatorPayloadWrapper.Register(eventName, onReceiveCallback); if (!replicatorPayloadWrapper.IsRegistered) { return null; } return replicatorPayloadWrapper; } public void Register(string eventName, OnReceiveDel<S> onReceiveCallback) { if (!IsRegistered && !NetworkAPI.IsEventRegistered(eventName)) { NetworkAPI.RegisterEvent<P>(eventName, (Action<ulong, P>)delegate(ulong sender, P payload) { onReceiveCallback?.Invoke(sender, payload.ID, payload.Get<S>()); }); IsRegistered = true; Name = eventName; } } public void Invoke(uint replicatorID, S data) { P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<P>(Name, payload, (SNet_ChannelType)2); }, "ReplicatorPayloadWrapper.Invoke(uint, S)"); } public void Invoke(uint replicatorID, S data, SNet_ChannelType channelType) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { //IL_0012: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(Name, payload, channelType); }, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_ChannelType)"); } public void Invoke(uint replicatorID, S data, SNet_Player target) { P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { NetworkAPI.InvokeEvent<P>(Name, payload, target, (SNet_ChannelType)2); }, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_Player)"); } public void Invoke(uint replicatorID, S data, SNet_Player target, SNet_ChannelType channelType) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) P payload = new P { ID = replicatorID }; payload.Set(data); TaskQueue.AddTask(delegate { //IL_0018: Unknown result type (might be due to invalid IL or missing references) NetworkAPI.InvokeEvent<P>(Name, payload, target, channelType); }, "ReplicatorPayloadWrapper.Invoke(uint, S, SNet_Player, SNet_ChannelType)"); } } public interface IStatePayload { uint ID { get; set; } S Get<S>() where S : struct; void Set<S>(S stateData) where S : struct; } public struct StatePayload4Byte : IStatePayload { public const int Size = 4; private uint id; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] public byte[] PayloadBytes; public uint ID { get { return id; } set { id = value; } } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 4); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 4, ref PayloadBytes); } } public struct StatePayload8Byte : IStatePayload { public const int Size = 8; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 8); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 8, ref PayloadBytes); } } public struct StatePayload16Byte : IStatePayload { public const int Size = 16; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 16); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 16, ref PayloadBytes); } } public struct StatePayload32Byte : IStatePayload { public const int Size = 32; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 32); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 32, ref PayloadBytes); } } public struct StatePayload48Byte : IStatePayload { public const int Size = 48; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 48); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 48, ref PayloadBytes); } } public struct StatePayload64Byte : IStatePayload { public const int Size = 64; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 64); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 64, ref PayloadBytes); } } public struct StatePayload80Byte : IStatePayload { public const int Size = 80; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 80); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 80, ref PayloadBytes); } } public struct StatePayload96Byte : IStatePayload { public const int Size = 96; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 96)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 96); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 96, ref PayloadBytes); } } public struct StatePayload128Byte : IStatePayload { public const int Size = 128; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 128)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 128); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 128, ref PayloadBytes); } } public struct StatePayload196Byte : IStatePayload { public const int Size = 196; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 196)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 196); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 196, ref PayloadBytes); } } public struct StatePayload256Byte : IStatePayload { public const int Size = 256; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 256)] public byte[] PayloadBytes; [field: MarshalAs(UnmanagedType.U4)] public uint ID { get; set; } public S Get<S>() where S : struct { return StatePayloads.Get<S>(PayloadBytes, 256); } public void Set<S>(S stateData) where S : struct { StatePayloads.Set(stateData, 256, ref PayloadBytes); } } public enum LifeTimeType { Forever, Level } public sealed class StateReplicator<S> where S : struct { private readonly Dictionary<eBufferType, S> _RecallStateSnapshots = new Dictionary<eBufferType, S>(); public static readonly string Name; public static readonly string HashName; public static readonly string ClientRequestEventName; public static readonly string HostSetStateEventName; public static readonly string HostSetRecallStateEventName; public static readonly int StateSize; public static readonly StatePayloads.Size StateSizeType; private static readonly IReplicatorEvent<S> _C_RequestEvent; private static readonly IReplicatorEvent<S> _H_SetStateEvent; private static readonly IReplicatorEvent<S> _H_SetRecallStateEvent; private static readonly ReplicatorHandshake _Handshake; private static readonly Dictionary<uint, StateReplicator<S>> _Replicators; public bool IsValid => ID != 0; public bool IsInvalid => ID == 0; public uint ID { get; private set; } public LifeTimeType LifeTime { get; private set; } public IStateReplicatorHolder<S> Holder { get; private set; } public S State { get; private set; } public bool ClientSendStateAllowed { get; set; } = true; public bool CanSendToClient { get { if (SNet.IsInLobby) { return SNet.IsMaster; } return false; } } public bool CanSendToHost { get { if (SNet.IsInLobby && !SNet.IsMaster && SNet.HasMaster) { return ClientSendStateAllowed; } return false; } } public bool IsHandshakeSetup { get; private set; } public event Action<S, S, bool> OnStateChanged; public void SetupHandshake() { if (!IsInvalid && !IsHandshakeSetup) { _Handshake.UpdateCreated(ID); IsHandshakeSetup = true; } } public void SetState(S state) { if (!IsInvalid) { DoSync(state); } } public void SetStateUnsynced(S state) { if (!IsInvalid) { State = state; } } public void Unload() { if (IsValid) { _Replicators.Remove(ID); _RecallStateSnapshots.Clear(); _Handshake.UpdateDestroyed(ID); IsHandshakeSetup = false; ID = 0u; } } private void DoSync(S newState) { if (!IsInvalid) { if (CanSendToClient) { _H_SetStateEvent.Invoke(ID, newState); Internal_ChangeState(newState, isRecall: false); } else if (CanSendToHost) { _C_RequestEvent.Invoke(ID, newState, SNet.Master); } } } private void Internal_ChangeState(S state, bool isRecall) { if (!IsInvalid) { S state2 = State; State = state; this.OnStateChanged?.Invoke(state2, state, isRecall); Holder?.OnStateChange(state2, state, isRecall); } } private void SendDropInState(SNet_Player target) { if (!IsInvalid) { if ((Object)(object)target == (Object)null) { Logger.Error("SendDropInState::Target was null??"); } else { _H_SetRecallStateEvent.Invoke(ID, State, target); } } } public void ClearAllRecallSnapshot() { if (!IsInvalid) { _RecallStateSnapshots.Clear(); } } private void SaveSnapshot(eBufferType type) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) if (!IsInvalid) { _RecallStateSnapshots[type] = State; } } private void RestoreSnapshot(eBufferType type) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (IsInvalid || !CanSendToClient) { return; } if (_RecallStateSnapshots.TryGetValue(type, out var value)) { _H_SetRecallStateEvent.Invoke(ID, value); Internal_ChangeState(value, isRecall: true); return; } bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("RestoreSnapshot"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("::There was no snapshot for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<eBufferType>(type); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("?"); } Logger.Error(val); } static StateReplicator() { _Replicators = new Dictionary<uint, StateReplicator<S>>(); Name = typeof(S).Name; StateSize = Marshal.SizeOf(typeof(S)); StateSizeType = StatePayloads.GetSizeType(StateSize); using (MD5.Create()) { HashName = UName.GetHash(typeof(S).FullName); ClientRequestEventName = "SRs" + Name + "-" + HashName; HostSetStateEventName = "SRr" + Name + "-" + HashName; HostSetRecallStateEventName = "SRre" + Name + "-" + HashName; _C_RequestEvent = StatePayloads.CreateEvent<S>(StateSizeType, ClientRequestEventName, ClientRequestEventCallback); _H_SetStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetStateEventName, HostSetStateEventCallback); _H_SetRecallStateEvent = StatePayloads.CreateEvent<S>(StateSizeType, HostSetRecallStateEventName, HostSetRecallStateEventCallback); _Handshake = ReplicatorHandshake.Create(Name + "-" + HashName); _Handshake.OnClientSyncRequested += ClientSyncRequested; Inject_SNet_Capture.OnBufferCapture += BufferStored; Inject_SNet_Capture.OnBufferRecalled += BufferRecalled; Inject_Builder.BeforeBuildStart += LevelCleanedUp; LevelAPI.OnLevelCleanup += LevelCleanedUp; } } public static void Setup() { } private static void ClientSyncRequested(SNet_Player requestedPlayer) { foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.SendDropInState(requestedPlayer); } } } private static void BufferStored(eBufferType type) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.SaveSnapshot(type); } } } private static void BufferRecalled(eBufferType type) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) foreach (StateReplicator<S> value in _Replicators.Values) { if (value.IsValid) { value.RestoreSnapshot(type); } } } private static void LevelCleanedUp() { UnloadSessionReplicator(); } private StateReplicator() { } public static StateReplicator<S> Create(uint replicatorID, S startState, LifeTimeType lifeTime, IStateReplicatorHolder<S> owner = null) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Expected O, but got Unknown if (replicatorID == 0) { Logger.Error("Replicator ID 0 is reserved for empty!"); return null; } if (_Replicators.ContainsKey(replicatorID)) { Logger.Error("Replicator ID has already assigned!"); return null; } StateReplicator<S> stateReplicator = new StateReplicator<S> { ID = replicatorID, LifeTime = lifeTime, Holder = owner, State = startState }; switch (lifeTime) { case LifeTimeType.Forever: stateReplicator.IsHandshakeSetup = true; break; case LifeTimeType.Level: stateReplicator.SetupHandshake(); break; default: { bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("LifeTime is invalid!: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<LifeTimeType>(lifeTime); } Logger.Error(val); return null; } } _Replicators[replicatorID] = stateReplicator; return stateReplicator; } public static void UnloadSessionReplicator() { List<uint> list = new List<uint>(); foreach (StateReplicator<S> value in _Replicators.Values) { if (value.LifeTime == LifeTimeType.Level) { list.Add(value.ID); value.Unload(); } } foreach (uint item in list) { _Replicators.Remove(item); } _Handshake.Reset(); } private static void ClientRequestEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.IsMaster && _Replicators.TryGetValue(replicatorID, out var value)) { value.SetState(newState); } } private static void HostSetStateEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out var value)) { value.Internal_ChangeState(newState, isRecall: false); } } private static void HostSetRecallStateEventCallback(ulong sender, uint replicatorID, S newState) { if (SNet.HasMaster && SNet.Master.Lookup == sender && _Replicators.TryGetValue(replicatorID, out var value)) { value.Internal_ChangeState(newState, isRecall: true); } } } } namespace FloLib.Networks.PayloadStructs { public struct PL_Agent { public ushort AgentID; public PL_Agent() { AgentID = 0; } public PL_Agent(Agent agent) { AgentID = agent.GlobalID; } public void Set(Agent agent) { AgentID = agent.GlobalID; } public bool TryGet(out Agent agent) { IReplicator val = default(IReplicator); if (!SNet_Replication.TryGetReplicator(AgentID, ref val)) { agent = null; return false; } if (val == null) { agent = null; return false; } if (val.ReplicatorSupplier == null) { agent = null; return false; } MonoBehaviour val2 = ((Il2CppObjectBase)val.ReplicatorSupplier).TryCast<MonoBehaviour>(); if ((Object)(object)val2 == (Object)null) { agent = null; return false; } agent = ((Component)val2).GetComponent<Agent>(); return (Object)(object)agent != (Object)null; } } } namespace FloLib.Networks.Inject { [HarmonyPatch] internal class Inject_OnRecallDone { public static event Action OnRecallDone; [HarmonyPostfix] [HarmonyPatch(typeof(SNet_SyncManager), "OnRecallDone")] private static void Post_OnRecallDone(SNet_SyncManager __instance) { Inject_OnRecallDone.OnRecallDone?.Invoke(); } } [HarmonyPatch(typeof(SNet_Capture))] internal static class Inject_SNet_Capture { public static event Action<eBufferType> OnBufferCapture; public static event Action<eBufferType> OnBufferRecalled; [HarmonyPatch("TriggerCapture")] [HarmonyPrefix] private static void Pre_TriggerCapture(SNet_Capture __instance) { //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_0011: Unknown result type (might be due to invalid IL or missing references) eBufferType primedBufferType = __instance.PrimedBufferType; Inject_SNet_Capture.OnBufferCapture?.Invoke(primedBufferType); } [HarmonyPatch("RecallBuffer")] [HarmonyPostfix] [HarmonyWrapSafe] private static void Post_RecallBuffer(SNet_Capture __instance, eBufferType bufferType) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!__instance.IsRecalling) { Inject_SNet_Capture.OnBufferRecalled?.Invoke(bufferType); } } } } namespace FloLib.Infos { public sealed class ComponentList<T> : IEnumerable<T>, IEnumerable where T : Component { private readonly List<T> _InternalList = new List<T>(); private T[] _ArrayCache = Array.Empty<T>(); public T[] Items => _ArrayCache; internal void Add(T itemToAdd) { int id = ((Object)(object)itemToAdd).GetInstanceID(); if (!_InternalList.Any((T t) => ((Object)(object)t).GetInstanceID() == id)) { _InternalList.Add(itemToAdd); _ArrayCache = _InternalList.ToArray(); } } internal void AddRange(IEnumerable<T> itemsToAdd) { foreach (T item in itemsToAdd) { Add(item); } } internal void Remove(T itemToRemove) { int id = ((Object)(object)itemToRemove).GetInstanceID(); int num = _InternalList.FindIndex((T i) => ((Object)(object)i).GetInstanceID() == id); if (num > -1) { _InternalList.RemoveAt(num); _ArrayCache = _InternalList.ToArray(); } } internal void Clear() { _InternalList.Clear(); _ArrayCache = Array.Empty<T>(); } public IEnumerator<T> GetEnumerator() { return _InternalList.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return _InternalList.GetEnumerator(); } } public static class LG_LightInfo { public struct Data { public float PrefabIntensity; public LightMode SpawnedMode; public float SpawnedIntensity; public Color SpawnedColor; } public static bool TryGetLightData(LG_Light light, out Data data) { if ((Object)(object)light == (Object)null) { data = default(Data); return false; } if (!((Component)(object)light).TryGetComp<LightData>(out var component)) { data = default(Data); return false; } data = component.CreateData(); return true; } public static void RevertToSpawnedState(LG_Light light) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)light == (Object)null) && ((Component)(object)light).TryGetComp<LightData>(out var component)) { light.ChangeColor(component.SpawnedColor); light.ChangeIntensity(component.SpawnedIntensity); } } } public enum LightMode { Off, On, Broken_Flickering } public static class LG_Objects { public static ComponentList<LG_SecurityDoor> SecurityDoors { get; private set; } = new ComponentList<LG_SecurityDoor>(); public static ComponentList<LG_WeakDoor> WeakDoors { get; private set; } = new ComponentList<LG_WeakDoor>(); public static ComponentList<LG_Light> Lights { get; private set; } = new ComponentList<LG_Light>(); public static ComponentList<LG_ComputerTerminal> Terminals { get; private set; } = new ComponentList<LG_ComputerTerminal>(); public static ComponentList<LG_LabDisplay> LabDisplays { get; private set; } = new ComponentList<LG_LabDisplay>(); public static ComponentList<LG_DoorButton> DoorButtons { get; private set; } = new ComponentList<LG_DoorButton>(); public static ComponentList<LG_WeakLock> WeakLocks { get; private set; } = new ComponentList<LG_WeakLock>(); public static ComponentList<LG_HSUActivator_Core> HSUActivators { get; private set; } = new ComponentList<LG_HSUActivator_Core>(); public static ComponentList<CarryItemPickup_Core> CarryItems { get; private set; } = new ComponentList<CarryItemPickup_Core>(); public static ComponentList<GenericSmallPickupItem_Core> PickupItems { get; private set; } = new ComponentList<GenericSmallPickupItem_Core>(); public static ComponentList<LG_Ladder> Ladders { get; private set; } = new ComponentList<LG_Ladder>(); public static ComponentList<LG_WardenObjective_Reactor> Reactors { get; private set; } = new ComponentList<LG_WardenObjective_Reactor>(); public static ComponentList<LG_PowerGeneratorCluster> GeneratorClusters { get; private set; } = new ComponentList<LG_PowerGeneratorCluster>(); public static ComponentList<LG_PowerGenerator_Core> Generators { get; private set; } = new ComponentList<LG_PowerGenerator_Core>(); [AutoInvoke(InvokeWhen.PluginLoaded)] internal static void Init() { LevelAPI.OnLevelCleanup += OnLevelCleanup; } private static void OnLevelCleanup() { SecurityDoors.Clear(); WeakDoors.Clear(); Lights.Clear(); Terminals.Clear(); LabDisplays.Clear(); DoorButtons.Clear(); WeakLocks.Clear(); HSUActivators.Clear(); CarryItems.Clear(); PickupItems.Clear(); Ladders.Clear(); Reactors.Clear(); GeneratorClusters.Clear(); Generators.Clear(); } public static O FindObjectInLevel<O>(bool includeInactive = false) where O : Object { return ((Component)Builder.CurrentFloor).GetComponentInChildren<O>(includeInactive); } public static IEnumerable<O> FindObjectsInLevel<O>(bool includeInactive = false) where O : Object { return (IEnumerable<O>)((Component)Builder.CurrentFloor).GetComponentsInChildren<O>(includeInactive); } public static LG_SecurityDoor FindSecurityDoor(LG_LayerType layer, eLocalZoneIndex localindex) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) return FindSecurityDoor((eDimensionIndex)0, layer, localindex); } public static LG_SecurityDoor FindSecurityDoor(eDimensionIndex dim, LG_LayerType layer, eLocalZoneIndex localindex) { //IL_0005: 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) LG_Zone val = default(LG_Zone); Builder.CurrentFloor.TryGetZoneByLocalIndex(dim, layer, localindex, ref val); if ((Object)(object)val == (Object)null) { return null; } if ((Object)(object)val.m_sourceGate == (Object)null) { return null; } if (val.m_sourceGate.SpawnedDoor == null) { return null; } return ((Il2CppObjectBase)val.m_sourceGate.SpawnedDoor).TryCast<LG_SecurityDoor>(); } } public static class LocalPlayer { private static int? _InstanceID; public static bool HasAgent { get; private set; } public static PlayerAgent Agent { get; private set; } public static LocalPlayerAgent LocalAgent { get; private set; } public static bool TryGetAgent(out PlayerAgent agent) { agent = Agent; return HasAgent; } public static bool TryGetLocalAgent(out LocalPlayerAgent agent) { agent = LocalAgent; return HasAgent; } public static Vector3 GetPosition() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).Position; } return Vector3.zero; } public static Vector3 GetPosition(Vector3 fallback) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).Position; } return fallback; } public static Vector3 GetEyePosition() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).EyePosition; } return Vector3.zero; } public static Vector3 GetEyePosition(Vector3 fallback) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (HasAgent) { return ((Agent)Agent).EyePosition; } return fallback; } [AutoInvoke(InvokeWhen.StartupAssetLoaded)] internal static void Init() { Coroutines.Start(UpdatePlayerInfo()); } private static IEnumerator UpdatePlayerInfo() { while (true) { if (PlayerManager.HasLocalPlayerAgent()) { PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent(); int instanceID = ((Object)localPlayerAgent).GetInstanceID(); if (!_InstanceID.HasValue || _InstanceID.Value != instanceID) { Agent = localPlayerAgent; LocalAgent = ((Il2CppObjectBase)localPlayerAgent).Cast<LocalPlayerAgent>(); _InstanceID = ((Object)localPlayerAgent).GetInstanceID(); HasAgent = true; } } else { Agent = null; LocalAgent = null; _InstanceID = null; HasAgent = false; } yield return null; } } } } namespace FloLib.Infos.Inject { [HarmonyPatch] internal static class Inject_Builder { internal static event Action BeforeBuildStart; [HarmonyPostfix] [HarmonyPatch(typeof(Builder), "BuildDone")] [HarmonyPriority(800)] private static void Post_BuildDone() { LG_Objects.Terminals.AddRange(Find<LG_ComputerTerminal>()); LG_Objects.LabDisplays.AddRange(Find<LG_LabDisplay>()); LG_Objects.DoorButtons.AddRange(Find<LG_DoorButton>()); LG_Objects.WeakLocks.AddRange(Find<LG_WeakLock>()); LG_Objects.HSUActivators.AddRange(Find<LG_HSUActivator_Core>()); LG_Objects.CarryItems.AddRange(Find<CarryItemPickup_Core>()); LG_Objects.PickupItems.AddRange(Find<GenericSmallPickupItem_Core>()); LG_Objects.Ladders.AddRange(Find<LG_Ladder>()); LG_Objects.Reactors.AddRange(Find<LG_WardenObjective_Reactor>()); LG_Objects.GeneratorClusters.AddRange(Find<LG_PowerGeneratorCluster>()); LG_Objects.Generators.AddRange(Find<LG_PowerGenerator_Core>()); } [HarmonyPrefix] [HarmonyPatch(typeof(Builder), "Build")] private static void Pre_Build() { Inject_Builder.BeforeBuildStart?.Invoke(); } private static IEnumerable<T> Find<T>() where T : Object { return LG_Objects.FindObjectsInLevel<T>(); } } [HarmonyPatch(typeof(LG_BuildZoneLightsJob), "Build")] internal static class Inject_LG_LightBuild { [HarmonyPriority(0)] private static void Prefix(LG_BuildZoneLightsJob __instance, out List<LG_Light> __state) { __state = new List<LG_Light>(); Enumerator<AIG_CourseNode> enumerator = __instance.m_zone.m_courseNodes.GetEnumerator(); while (enumerator.MoveNext()) { foreach (LG_Light componentsInChild in ((Component)enumerator.Current.m_area).GetComponentsInChildren<LG_Light>()) { LightData lightData = ((Component)componentsInChild).gameObject.AddComponent<LightData>(); LG_PointLight result2; if (((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_SpotLight>(out LG_SpotLight result)) { lightData.PrefabIntensity.Set(result.m_spotLight.intensity); } else if (((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_PointLight>(out result2)) { lightData.PrefabIntensity.Set(result2.m_pointLight.intensity); } else { if (!((Il2CppObjectBase)(object)componentsInChild).TryCastToType<LG_SpotLightAmbient>(out LG_SpotLightAmbient result3)) { continue; } lightData.PrefabIntensity.Set(result3.m_spotLight.intensity); } __state.Add(componentsInChild); } } LG_Objects.Lights.AddRange(__state); } [HarmonyPriority(0)] private static void Postfix(List<LG_Light> __state) { //IL_0076: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Expected O, but got Unknown bool flag = default(bool); foreach (LG_Light item in __state) { LightData component = ((Component)item).GetComponent<LightData>(); if ((Object)(object)component == (Object)null) { BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(32, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Found Light without "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("LightData"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" Component! "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(((Component)(object)item).GetGameObjectPath()); } Logger.Error(val); } else { component.SpawnedIntensity = item.m_intensity; component.SpawnedColor = item.m_color; component.SpawnedMode = GetLightMode(item); } } __state.Clear(); } private static LightMode GetLightMode(LG_Light light) { if (light.GetC_Light().LightUpdator != null) { return LightMode.Broken_Flickering; } if (((Component)light).gameObject.active) { return LightMode.On; } return LightMode.Off; } } [HarmonyPatch(typeof(LG_SecurityDoor), "Setup")] internal static class Inject_LG_SecDoor { private static void Postfix(LG_SecurityDoor __instance) { LG_Objects.SecurityDoors.Add(__instance); } } [HarmonyPatch(typeof(LG_WeakDoor), "Setup")] internal static class Inject_LG_WeakDoor { private static void Postfix(LG_WeakDoor __instance) { LG_Objects.WeakDoors.Add(__instance); } } } namespace FloLib.Infos.Comps { [AutoInject] internal sealed class LightData : MonoBehaviour { public Il2CppValueField<float> PrefabIntensity; public LightMode SpawnedMode; public float SpawnedIntensity; public Color SpawnedColor; public LG_LightInfo.Data CreateData() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) LG_LightInfo.Data result = default(LG_LightInfo.Data); result.PrefabIntensity = Il2CppValueField<float>.op_Implicit(PrefabIntensity); result.SpawnedMode = SpawnedMode; result.SpawnedIntensity = SpawnedIntensity; result.SpawnedColor = SpawnedColor; return result; } } } namespace FloLib.Game.ScreenShakes { public sealed class ScreenShake { [AutoInvoke(InvokeWhen.StartupAssetLoaded)] internal static void Init() { GlobalNetAction<ScreenShakeDescriptor>.OnReceive += OnReceive; } public static void Trigger(ScreenShakeDescriptor data) { GlobalNetAction<ScreenShakeDescriptor>.Send(data); } private static void OnReceive(ulong sender, ScreenShakeDescriptor data) { if (LocalPlayer.TryGetAgent(out var agent)) { FPSCamera fPSCamera = agent.FPSCamera; MonoBehaviourExtensions.StartCoroutine((MonoBehaviour)(object)fPSCamera, DoShake(fPSCamera, data)); } } private static IEnumerator DoShake(FPSCamera camera, ScreenShakeDescriptor data) { float time = 0f; while (time < data.Duration) { float num = 1f; if (data.Mode == ScreenShakeMode.PositionFalloff) { float num2 = Vector3.Distance(data.Position, camera.Position); num = Mathf.InverseLerp(data.FalloffEnd, data.FalloffStart, num2); } float t = data.Modifier switch { ScreenShakeModifier.PingPong => Mathf.PingPong(Mathf.InverseLerp(data.Duration, 0f, time) * 2f, 1f), ScreenShakeModifier.Increase => Mathf.InverseLerp(0f, data.Duration, time), ScreenShakeModifier.Decrease => Mathf.InverseLerp(data.Duration, 0f, time), _ => 1f, }; t = data.IntensityEasing.Evaluate(t); float constantCameraShakeAmount = num * t * data.Intensity; camera.SetConstantCameraShakeAmount(constantCameraShakeAmount); time += Time.deltaTime; yield return null; } camera.SetConstantCameraShakeAmount(0f); } } public struct ScreenShakeDescriptor { public ScreenShakeMode Mode; public ScreenShakeModifier Modifier; public Vector3 Position; public float Intensity; public float Duration; public float FalloffStart; public float FalloffEnd; public EaseFunc.Type IntensityEasing; } public enum ScreenShakeMode : byte { Global, PositionFalloff } public enum ScreenShakeModifier : byte { PingPong, Increase, Decrease, Constant } } namespace FloLib.Game.Projectiles { public class Projectile : MonoBehaviour { } } namespace FloLib.Game.Explosions { public sealed class Explosion { public static readonly Color DefaultFlashColor = new Color(1f, 0.2f, 0f, 1f); [AutoInvoke(InvokeWhen.StartupAssetLoaded)] internal static void Init() { ExplosionEffectPooling.Initialize(); GlobalNetAction<ExplosionDescriptor>.OnReceive += OnReceive; } private static void OnReceive(ulong sender, ExplosionDescriptor data) { Internal_TriggerExplosion(data); } public static void Trigger(ExplosionDescriptor data) { GlobalNetAction<ExplosionDescriptor>.Send(data); } internal static void Internal_TriggerExplosion(ExplosionDescriptor data) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0023: 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) CellSound.Post(EVENTS.STICKYMINEEXPLODE, data.Position); LightFlash(data.Position, data.MaxDamageRange, data.LightColor); if (!SNet.IsMaster) { return; } Il2CppReferenceArray<Collider> val = Physics.OverlapSphere(data.Position, data.MaxDamageRange, LayerManager.MASK_EXPLOSION_TARGETS); if (((Il2CppArrayBase<Collider>)(object)val).Count < 1) { return; } DamageUtil.IncrementSearchID(); uint searchID = DamageUtil.SearchID; foreach (Collider item in (Il2CppArrayBase<Collider>)(object)val) { ProcessExplosion(data, item, searchID); } } private static void ProcessExplosion(ExplosionDescriptor data, Collider target, uint searchID) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004d: 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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || (Object)(object)((Component)target).gameObject == (Object)null || !((Component)target).gameObject.TryGetComp<IDamageable>(out var component)) { return; } component = component.GetBaseDamagable(); if (component == null || component.TempSearchID == searchID) { return; } Vector3 damagablePosition = GetDamagablePosition(component); component.TempSearchID = searchID; float distance = Vector3.Distance(data.Position, damagablePosition); if (!IsExplosionBlocked(data.Position, damagablePosition, target)) { float num = CalcBaseRangeDamage(data.MaxDamage, distance, data.MaxDamageRange, data.MinDamageRange); if ((Object)(object)((Il2CppObjectBase)component).TryCast<Dam_EnemyDamageBase>() != (Object)null) { num *= (float)data.DamageMultiplierToEnemy; } else if ((Object)(object)((Il2CppObjectBase)component).TryCast<Dam_PlayerDamageBase>() != (Object)null) { num *= (float)data.DamageMultiplierToPlayer; } Agent baseAgent = component.GetBaseAgent(); if ((Object)(object)baseAgent != (Object)null && baseAgent.GlobalID == data.Inflictor.AgentID) { num *= (float)data.DamageMultiplierToInflictor; } if (Mathf.Abs(num) > float.Epsilon) { component.ExplosionDamage(num, data.Position, Vector3.up * 1000f, 0u); } } } private static Vector3 GetDamagablePosition(IDamageable damagable) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) Agent baseAgent = damagable.GetBaseAgent(); if ((Object)(object)baseAgent != (Object)null) { return baseAgent.EyePosition; } return damagable.DamageTargetPos; } private static bool IsExplosionBlocked(Vector3 pos1, Vector3 pos2, Collider targetCollider) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) RaycastHit val = default(RaycastHit); if (Physics.Linecast(pos1, pos2, ref val, LayerManager.MASK_EXPLOSION_BLOCKERS)) { if