Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Lockout v1.3.1
Lockout.dll
Decompiled 2 years agousing System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Lockout; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Lockout")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Lockout")] [assembly: AssemblyTitle("Lockout")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/AntoninJuquel/lethal-company-lockout")] [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; } } } [Serializable] public class SyncedInstance<T> { [NonSerialized] protected static int IntSize = 4; internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager; internal static bool IsClient => NetworkManager.Singleton.IsClient; internal static bool IsHost => NetworkManager.Singleton.IsHost; public static T Default { get; private set; } public static T Instance { get; private set; } public static bool Synced { get; internal set; } protected void InitInstance(T instance) { Default = instance; Instance = instance; IntSize = 4; } internal static void SyncInstance(byte[] data) { Instance = DeserializeFromBytes(data); Synced = true; } internal static void RevertSync() { Instance = Default; Synced = false; } public static byte[] SerializeToBytes(T val) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream memoryStream = new MemoryStream(); try { binaryFormatter.Serialize(memoryStream, val); return memoryStream.ToArray(); } catch (Exception arg) { LockoutBase.Logger.LogError((object)$"Error serializing instance: {arg}"); return null; } } public static T DeserializeFromBytes(byte[] data) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream serializationStream = new MemoryStream(data); try { return (T)binaryFormatter.Deserialize(serializationStream); } catch (Exception arg) { LockoutBase.Logger.LogError((object)$"Error deserializing instance: {arg}"); return default(T); } } } namespace Lockout { [BepInPlugin("com.github.somindras.lethal-company-lockout", "Lockout", "1.3.1")] public class LockoutBase : BaseUnityPlugin { public enum KeyUsage { No, Inventory, Hand } [HarmonyPatch(typeof(TimeOfDay))] internal class TimeOfDayPatch : HarmonyPatch { [HarmonyPatch("TimeOfDayEvents")] [HarmonyPostfix] public static void TimeOfDayEventsPostfix(float ___currentDayTime, float ___totalTime) { timeRatio = ___currentDayTime / ___totalTime; if (timeRatio < TimeBeforeLockout || (CanPowerOffLockout && !powerOn)) { if (isLocked) { Logger.LogInfo((object)"TimeOfDayEventsPostfix: Unlock Alert"); HUDManager.Instance.ReadDialogue(unlockDialog); isLocked = false; } } else if (timeRatio < TimeBeforeUnlock) { if (!isLocked) { Logger.LogInfo((object)"TimeOfDayEventsPostfix: Lockout Alert"); HUDManager.Instance.ReadDialogue(lockoutDialog); isLocked = true; } } else if (isLocked) { Logger.LogInfo((object)"TimeOfDayEventsPostfix: Unlock Alert"); HUDManager.Instance.ReadDialogue(unlockDialog); isLocked = false; } } } [HarmonyPatch(typeof(EntranceTeleport))] internal class EntranceTeleportPatch : HarmonyPatch { private static bool UseKey() { PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; switch (CanUseKey) { case KeyUsage.No: Logger.LogInfo((object)$"UseKey: config DISABLED key usage: {CanUseKey}"); return false; default: { int num = Array.FindIndex(localPlayerController.ItemSlots, (GrabbableObject item) => Object.op_Implicit((Object)(object)item) && item is KeyItem); bool flag2 = num != -1; if (flag2) { localPlayerController.isHoldingObject = true; localPlayerController.DestroyItemInSlotAndSync(num); } Logger.LogInfo((object)string.Format("UseKey: was ({0}) to use key in inventory got slot {1}", flag2 ? "ABLE" : "UNABLE", num)); return flag2; } case KeyUsage.Hand: { bool flag = Object.op_Implicit((Object)(object)localPlayerController.currentlyHeldObjectServer) && localPlayerController.currentlyHeldObjectServer is KeyItem; if (flag) { localPlayerController.DespawnHeldObject(); } Logger.LogInfo((object)("UseKey: was (" + (flag ? "ABLE" : "UNABLE") + ") to use currently held key")); return flag; } } } private static bool CanEnter(bool isMainEntrance) { if (isLocked) { if (isMainEntrance) { return CanEnterMainEntranceDuringLockout; } return CanEnterFireExitDuringLockout; } if (isMainEntrance) { return CanEnterMainEntranceDuringUnlock; } return CanEnterFireExitDuringUnlock; } private static bool CanExit(bool isMainEntrance) { if (isLocked) { if (isMainEntrance) { return CanExitMainEntranceDuringLockout; } return CanExitFireExitDuringLockout; } if (isMainEntrance) { return CanExitMainEntranceDuringUnlock; } return CanExitFireExitDuringUnlock; } [HarmonyPatch("TeleportPlayer")] [HarmonyPrefix] public static bool TeleportPlayerPrefix(bool ___isEntranceToBuilding, int ___entranceId) { bool flag = ___entranceId == 0; bool flag2 = ___isEntranceToBuilding; bool flag3 = (flag2 ? CanEnter(flag) : CanExit(flag)) || UseKey(); Logger.LogInfo((object)("Player is " + (flag3 ? "ALLOWED" : "UNALLOWED") + " to " + (flag2 ? "ENTER" : "EXIT") + " through the " + (flag ? "MAIN ENTRANCE" : "FIRE EXIT"))); if (!flag3) { HUDManager.Instance.DisplayTip("???", (flag2 ? "ENTERING" : "EXITING") + " through the " + (flag ? "MAIN ENTRANCE" : "FIRE EXIT") + " seems blocked", false, false, "LC_Tip1"); } return flag3; } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerControllerBPatch : HarmonyPatch { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } [HarmonyPatch("ConnectClientToPlayerObject")] [HarmonyPostfix] public static void ConnectClientToPlayerObjectPostfix() { //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown if (SyncedInstance<LockoutConfig>.IsHost) { Logger.LogInfo((object)"ConnectClientToPlayerObjectPostfix: Host is syncing config"); CustomMessagingManager messageManager = SyncedInstance<LockoutConfig>.MessageManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = LockoutConfig.OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } messageManager.RegisterNamedMessageHandler("Lockout_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); SyncedInstance<LockoutConfig>.Synced = true; return; } Logger.LogInfo((object)"ConnectClientToPlayerObjectPostfix: Client is requesting config sync"); SyncedInstance<LockoutConfig>.Synced = false; CustomMessagingManager messageManager2 = SyncedInstance<LockoutConfig>.MessageManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = LockoutConfig.OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } messageManager2.RegisterNamedMessageHandler("Lockout_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); LockoutConfig.RequestSync(); } } [HarmonyPatch(typeof(GameNetworkManager))] internal class GameNetworkManagerPatch : HarmonyPatch { [HarmonyPatch("StartDisconnect")] [HarmonyPostfix] public static void StartDisconnectPostfix() { Logger.LogInfo((object)"StartDisconnectPostfix: Disconnecting"); SyncedInstance<LockoutConfig>.RevertSync(); } } [HarmonyPatch(typeof(RoundManager))] internal class RoundManagerPatch : HarmonyPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix() { Logger.LogInfo((object)"Start: Registering event handlers"); ((UnityEvent<bool>)(object)RoundManager.Instance.onPowerSwitch).AddListener((UnityAction<bool>)OnPowerSwitch); } [HarmonyPatch("OnDestroy")] [HarmonyPostfix] private static void OnDestroy() { Logger.LogInfo((object)"OnDestroy: Unregistering event handlers"); ((UnityEvent<bool>)(object)RoundManager.Instance.onPowerSwitch).RemoveListener((UnityAction<bool>)OnPowerSwitch); } [HarmonyPatch("SetLevelObjectVariables")] [HarmonyPrefix] private static void SetLevelObjectVariablesPrefix() { OnPowerSwitch(on: true); isLocked = false; } private static void OnPowerSwitch(bool on) { Logger.LogInfo((object)$"OnPowerSwitch: {on}"); powerOn = on; } } private readonly Harmony harmony = new Harmony("com.github.somindras.lethal-company-lockout"); private static LockoutBase Instance; private static float timeRatio = 0f; private static bool isLocked = false; private static bool powerOn = true; private static readonly DialogueSegment[] lockoutDialog = (DialogueSegment[])(object)new DialogueSegment[1] { new DialogueSegment { speakerText = "Facility AI", bodyText = "The building is now locked down.", waitTime = 3f } }; private static readonly DialogueSegment[] unlockDialog = (DialogueSegment[])(object)new DialogueSegment[1] { new DialogueSegment { speakerText = "Facility AI", bodyText = "The building is now unlocked.", waitTime = 3f } }; internal static ManualLogSource Logger { get; private set; } public static LockoutConfig Config { get; internal set; } private static float TimeBeforeLockout => SyncedInstance<LockoutConfig>.Instance.timeBeforeLockout; private static float TimeBeforeUnlock => SyncedInstance<LockoutConfig>.Instance.timeBeforeUnlock; private static bool CanEnterFireExitDuringLockout => SyncedInstance<LockoutConfig>.Instance.canEnterFireExitDuringLockout; private static bool CanEnterFireExitDuringUnlock => SyncedInstance<LockoutConfig>.Instance.canEnterFireExitDuringUnlock; private static bool CanExitFireExitDuringLockout => SyncedInstance<LockoutConfig>.Instance.canExitFireExitDuringLockout; private static bool CanExitFireExitDuringUnlock => SyncedInstance<LockoutConfig>.Instance.canExitFireExitDuringUnlock; private static bool CanEnterMainEntranceDuringLockout => SyncedInstance<LockoutConfig>.Instance.canEnterMainEntranceDuringLockout; private static bool CanEnterMainEntranceDuringUnlock => SyncedInstance<LockoutConfig>.Instance.canEnterMainEntranceDuringUnlock; private static bool CanExitMainEntranceDuringLockout => SyncedInstance<LockoutConfig>.Instance.canExitMainEntranceDuringLockout; private static bool CanExitMainEntranceDuringUnlock => SyncedInstance<LockoutConfig>.Instance.canExitMainEntranceDuringUnlock; private static bool CanPowerOffLockout => SyncedInstance<LockoutConfig>.Instance.canPowerOffLockout; private static KeyUsage CanUseKey => SyncedInstance<LockoutConfig>.Instance.canUseKey; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } Logger = Logger.CreateLogSource("com.github.somindras.lethal-company-lockout"); Logger.LogInfo((object)"Plugin Lockout is loaded!"); Config = new LockoutConfig(((BaseUnityPlugin)this).Config); harmony.PatchAll(typeof(TimeOfDayPatch)); harmony.PatchAll(typeof(EntranceTeleportPatch)); harmony.PatchAll(typeof(LockoutConfig)); harmony.PatchAll(typeof(PlayerControllerBPatch)); harmony.PatchAll(typeof(GameNetworkManagerPatch)); harmony.PatchAll(typeof(RoundManagerPatch)); } } [Serializable] public class LockoutConfig : SyncedInstance<LockoutConfig> { public float timeBeforeLockout = 0.2f; public float timeBeforeUnlock = 0.9f; public bool canEnterFireExitDuringLockout = false; public bool canEnterFireExitDuringUnlock = false; public bool canExitFireExitDuringLockout = true; public bool canExitFireExitDuringUnlock = true; public bool canEnterMainEntranceDuringLockout = false; public bool canEnterMainEntranceDuringUnlock = true; public bool canExitMainEntranceDuringLockout = false; public bool canExitMainEntranceDuringUnlock = true; public bool canPowerOffLockout = true; public LockoutBase.KeyUsage canUseKey = LockoutBase.KeyUsage.Inventory; public LockoutConfig(ConfigFile cfg) { InitInstance(this); timeBeforeLockout = cfg.Bind<float>("Time", "Time Before Lockout", 0.2f, "The time of day when the building lockout (0-1)").Value; timeBeforeUnlock = cfg.Bind<float>("Time", "Time Before Unlock", 0.9f, "The time of day when the building unlocks (0-1)").Value; canEnterFireExitDuringLockout = cfg.Bind<bool>("Fire Exit", "Can Enter Fire Exit During Lockout", false, "Can enter the fire exit during lockout").Value; canEnterFireExitDuringUnlock = cfg.Bind<bool>("Fire Exit", "Can Enter Fire Exit During Unlock", false, "Can enter the fire exit during unlock").Value; canExitFireExitDuringLockout = cfg.Bind<bool>("Fire Exit", "Can Exit Fire Exit During Lockout", true, "Can exit the fire exit during lockout").Value; canExitFireExitDuringUnlock = cfg.Bind<bool>("Fire Exit", "Can Exit Fire Exit During Unlock", true, "Can exit the fire exit during unlock").Value; canEnterMainEntranceDuringLockout = cfg.Bind<bool>("Main Entrance", "Can Enter Main Entrance During Lockout", false, "Can enter the main entrance during lockout").Value; canEnterMainEntranceDuringUnlock = cfg.Bind<bool>("Main Entrance", "Can Enter Main Entrance During Unlock", true, "Can enter the main entrance during unlock").Value; canExitMainEntranceDuringLockout = cfg.Bind<bool>("Main Entrance", "Can Exit Main Entrance During Lockout", false, "Can exit the main entrance during lockout").Value; canExitMainEntranceDuringUnlock = cfg.Bind<bool>("Main Entrance", "Can Exit Main Entrance During Unlock", true, "Can exit the main entrance during unlock").Value; canPowerOffLockout = cfg.Bind<bool>("Power", "Can Power Off Lockout", true, "Can power off the lockout").Value; canUseKey = (LockoutBase.KeyUsage)cfg.Bind<int>("Key", "Can use key", 1, "Can use the key to enter/exit during lockout |0: No|1: Key in inventory slot|2: Key must be held|").Value; if (timeBeforeLockout < 0f || timeBeforeLockout > 1f) { LockoutBase.Logger.LogWarning((object)$"Time Before Lockout was set to {timeBeforeLockout}. Setting to default."); timeBeforeLockout = 0.2f; } if (timeBeforeUnlock < 0f || timeBeforeUnlock > 1f) { LockoutBase.Logger.LogWarning((object)$"Time Before Unlock was set to {timeBeforeUnlock}. Setting to default."); timeBeforeUnlock = 0.9f; } if (timeBeforeLockout > timeBeforeUnlock) { LockoutBase.Logger.LogWarning((object)$"Time Before Lockout was set to {timeBeforeLockout} and is Greater than Time Before Unlock was set to {timeBeforeUnlock}. Setting to default."); timeBeforeLockout = 0.2f; timeBeforeUnlock = 0.9f; } if (!Enum.IsDefined(typeof(LockoutBase.KeyUsage), canUseKey)) { LockoutBase.Logger.LogWarning((object)$"Can Use Key was set to {canUseKey}. Setting to default."); canUseKey = LockoutBase.KeyUsage.Inventory; } LockoutBase.Logger.LogInfo((object)"Config loaded."); LockoutBase.Logger.LogInfo((object)$"Time Before Lockout: {timeBeforeLockout}"); LockoutBase.Logger.LogInfo((object)$"Time Before Unlock: {timeBeforeUnlock}"); LockoutBase.Logger.LogInfo((object)$"Can Enter Fire Exit During Lockout: {canEnterFireExitDuringLockout}"); LockoutBase.Logger.LogInfo((object)$"Can Enter Fire Exit During Unlock: {canEnterFireExitDuringUnlock}"); LockoutBase.Logger.LogInfo((object)$"Can Exit Fire Exit During Lockout: {canExitFireExitDuringLockout}"); LockoutBase.Logger.LogInfo((object)$"Can Exit Fire Exit During Unlock: {canExitFireExitDuringUnlock}"); LockoutBase.Logger.LogInfo((object)$"Can Enter Main Entrance During Lockout: {canEnterMainEntranceDuringLockout}"); LockoutBase.Logger.LogInfo((object)$"Can Enter Main Entrance During Unlock: {canEnterMainEntranceDuringUnlock}"); LockoutBase.Logger.LogInfo((object)$"Can Exit Main Entrance During Lockout: {canExitMainEntranceDuringLockout}"); LockoutBase.Logger.LogInfo((object)$"Can Exit Main Entrance During Unlock: {canExitMainEntranceDuringUnlock}"); LockoutBase.Logger.LogInfo((object)$"Can Power Off Lockout: {canPowerOffLockout}"); LockoutBase.Logger.LogInfo((object)$"Can Use Key: {canUseKey}"); } public static void RequestSync() { //IL_0029: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<LockoutConfig>.IsClient) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(SyncedInstance<LockoutConfig>.IntSize, (Allocator)2, -1); try { SyncedInstance<LockoutConfig>.MessageManager.SendNamedMessage("Lockout_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_0053: 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_0077: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<LockoutConfig>.IsHost) { return; } LockoutBase.Logger.LogInfo((object)$"Config sync request received from client: {clientId}"); byte[] array = SyncedInstance<LockoutConfig>.SerializeToBytes(SyncedInstance<LockoutConfig>.Instance); int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<LockoutConfig>.IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); SyncedInstance<LockoutConfig>.MessageManager.SendNamedMessage("Lockout_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3); } catch (Exception arg) { LockoutBase.Logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}"); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<LockoutConfig>.IntSize)) { LockoutBase.Logger.LogError((object)"Config sync error: Could not begin reading buffer."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (!((FastBufferReader)(ref reader)).TryBeginRead(num)) { LockoutBase.Logger.LogError((object)"Config sync error: Host could not sync."); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); SyncedInstance<LockoutConfig>.SyncInstance(data); LockoutBase.Logger.LogInfo((object)"Successfully synced config with host."); } } public static class LockoutInfo { public const string GUID = "com.github.somindras.lethal-company-lockout"; public const string NAME = "Lockout"; public const string VERSION = "1.3.1"; } public static class PluginInfo { public const string PLUGIN_GUID = "Lockout"; public const string PLUGIN_NAME = "Lockout"; public const string PLUGIN_VERSION = "1.0.0"; } }