Decompiled source of ExtraObjectiveSetup v1.6.4

plugins/Inas07.ExtraObjectiveSetup.dll

Decompiled a week ago
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
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