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 MatrixTermExtensions v1.1.2
MatrixTermExtensions.dll
Decompiled 2 years agousing System; using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalAPI.LibTerminal; using LethalAPI.LibTerminal.Attributes; using LethalAPI.LibTerminal.Models; using Matrix.TerminalExtensions.Commands; using Matrix.TerminalExtensions.Configs; using Matrix.TerminalExtensions.Extensions; 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.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MatrixTermExtensions")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("A customized variant of Terminal Extensions for use in sessions with my friends.")] [assembly: AssemblyFileVersion("1.1.2.0")] [assembly: AssemblyInformationalVersion("1.1.2+291ddd33c0b90956ef8deba1c0236128b964ab05")] [assembly: AssemblyProduct("MatrixTermExtensions")] [assembly: AssemblyTitle("MatrixTermExtensions")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/D0t-Matrix/LC-TermExtensions")] [assembly: AssemblyVersion("1.1.2.0")] [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.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 System.Runtime.Versioning { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiresPreviewFeaturesAttribute : Attribute { public string? Message { get; } public string? Url { get; set; } public RequiresPreviewFeaturesAttribute() { } public RequiresPreviewFeaturesAttribute(string? message) { Message = message; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CallerArgumentExpressionAttribute : Attribute { public string ParameterName { get; } public CallerArgumentExpressionAttribute(string parameterName) { ParameterName = parameterName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CollectionBuilderAttribute : Attribute { public Type BuilderType { get; } public string MethodName { get; } public CollectionBuilderAttribute(Type builderType, string methodName) { BuilderType = builderType; MethodName = methodName; } } [AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class CompilerFeatureRequiredAttribute : Attribute { public const string RefStructs = "RefStructs"; public const string RequiredMembers = "RequiredMembers"; public string FeatureName { get; } public bool IsOptional { get; set; } public CompilerFeatureRequiredAttribute(string featureName) { FeatureName = featureName; } } [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute { public string[] Arguments { get; } public InterpolatedStringHandlerArgumentAttribute(string argument) { Arguments = new string[1] { argument }; } public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) { Arguments = arguments; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class InterpolatedStringHandlerAttribute : Attribute { } [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal static class IsExternalInit { } [AttributeUsage(AttributeTargets.Method, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ModuleInitializerAttribute : Attribute { } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class RequiredMemberAttribute : Attribute { } [AttributeUsage(AttributeTargets.Parameter, Inherited = false)] [EditorBrowsable(EditorBrowsableState.Never)] [ExcludeFromCodeCoverage] internal sealed class RequiresLocationAttribute : Attribute { } [AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SkipLocalsInitAttribute : Attribute { } } namespace System.Diagnostics.CodeAnalysis { [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class ExperimentalAttribute : Attribute { public string DiagnosticId { get; } public string? UrlFormat { get; set; } public ExperimentalAttribute(string diagnosticId) { DiagnosticId = diagnosticId; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullAttribute : Attribute { public string[] Members { get; } public MemberNotNullAttribute(string member) { Members = new string[1] { member }; } public MemberNotNullAttribute(params string[] members) { Members = members; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)] [ExcludeFromCodeCoverage] internal sealed class MemberNotNullWhenAttribute : Attribute { public bool ReturnValue { get; } public string[] Members { get; } public MemberNotNullWhenAttribute(bool returnValue, string member) { ReturnValue = returnValue; Members = new string[1] { member }; } public MemberNotNullWhenAttribute(bool returnValue, params string[] members) { ReturnValue = returnValue; Members = members; } } [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class SetsRequiredMembersAttribute : Attribute { } [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class StringSyntaxAttribute : Attribute { public const string CompositeFormat = "CompositeFormat"; public const string DateOnlyFormat = "DateOnlyFormat"; public const string DateTimeFormat = "DateTimeFormat"; public const string EnumFormat = "EnumFormat"; public const string GuidFormat = "GuidFormat"; public const string Json = "Json"; public const string NumericFormat = "NumericFormat"; public const string Regex = "Regex"; public const string TimeOnlyFormat = "TimeOnlyFormat"; public const string TimeSpanFormat = "TimeSpanFormat"; public const string Uri = "Uri"; public const string Xml = "Xml"; public string Syntax { get; } public object?[] Arguments { get; } public StringSyntaxAttribute(string syntax) { Syntax = syntax; Arguments = new object[0]; } public StringSyntaxAttribute(string syntax, params object?[] arguments) { Syntax = syntax; Arguments = arguments; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] [ExcludeFromCodeCoverage] internal sealed class UnscopedRefAttribute : Attribute { } } namespace Matrix.TerminalExtensions { [BepInPlugin("matrix.lethalcompany.termextensions", "MatrixTermExtensions", "1.1.2")] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; internal static Config Config; private readonly Harmony _harmony = new Harmony("matrix.lethalcompany.termextensions"); private readonly TerminalModRegistry _commands = TerminalRegistry.CreateTerminalRegistry(); public void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Config = new Config(((BaseUnityPlugin)this).Config); try { _harmony.PatchAll(typeof(Plugin).Assembly); Logger.LogInfo((object)"<!!!> MatrixTermExtensions Plugin has loaded. <!!!>"); _commands.RegisterFrom<DoorCommands>(); _commands.RegisterFrom<TeleporterCommands>(); _commands.RegisterFrom<LightsCommands>(); _commands.RegisterFrom<LaunchCommands>(); if (Config.EnableCheatCommands) { Logger.LogInfo((object)"Enabling Cheat Commands."); _commands.RegisterFrom<CheatCommands>(); } Logger.LogInfo((object)"<!!!> MatrixTermExtensions Custom Terminal Commands loaded. <!!!>"); } catch (Exception ex) { Logger.LogError((object)ex); } } } internal static class Utils { internal static T GetInstancedStructField<T>(object instance, string fieldName) where T : struct { object value = instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic).GetValue(instance); if (value is T) { return (T)value; } return default(T); } internal static void SetInstancedStructField<T>(object instance, string fieldName, T value) where T : struct { instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic).SetValue(instance, value); } internal static T? GetInstancedClassField<T>(object instance, string fieldName) where T : class { if (!(instance.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic).GetValue(instance) is T result)) { return null; } return result; } internal static T GetInstanceMethod<T>(Type type, object instance, string methodName) { MethodInfo method = type.GetMethod(methodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); return (T)(object)Delegate.CreateDelegate(typeof(T), instance, method); } } [CompilerGenerated] internal static class GeneratedPluginInfo { public const string Identifier = "matrix.lethalcompany.termextensions"; public const string Name = "MatrixTermExtensions"; public const string Version = "1.1.2"; } } namespace Matrix.TerminalExtensions.Patches { [HarmonyPatch(typeof(RoundManager))] internal sealed class LevelPatches { [HarmonyPostfix] [HarmonyPatch("LoadNewLevel")] private static void LoadNewLevel() { Plugin.Logger.LogInfo((object)"Resetting the Inverse Teleporter Cooldown"); TeleporterCommands.TryResetInverseTeleporter(); } } } namespace Matrix.TerminalExtensions.Extensions { internal static class StringExtensions { internal static bool IsNullOrEmpty([NotNullWhen(false)] this string? str) { return string.IsNullOrEmpty(str); } internal static bool IsNullOrWhitespace([NotNullWhen(false)] this string? str) { return string.IsNullOrWhiteSpace(str); } } } namespace Matrix.TerminalExtensions.Configs { [DataContract] public class Config : SyncedInstance<Config> { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } [DataMember] public bool EnablePlugin { get; private set; } [DataMember] public bool EnableCheatCommands { get; private set; } public Config(ConfigFile cfg) { InitInstance(this); EnablePlugin = cfg.Bind<bool>("MatrixTermExtensions", "enabled", true, "Enable or disable the plugin globally.").Value; EnableCheatCommands = cfg.Bind<bool>("MatrixTermExtensions", "cheat commands enabled", false, "Enable or disable the cheat commands.").Value; } public static void RequestSync() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<Config>.IsClient) { return; } FastBufferWriter stream = default(FastBufferWriter); ((FastBufferWriter)(ref stream))..ctor(SyncedInstance<Config>.IntSize, (Allocator)2, -1); try { SyncedInstance<Config>.SendMessage("MatrixTermExtensions_OnRequestConfigSync", 0uL, stream); } finally { ((IDisposable)(FastBufferWriter)(ref stream)).Dispose(); } } public static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_005a: 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) if (!SyncedInstance<Config>.IsHost) { return; } Plugin.Logger.LogInfo((object)$"Config sync request received from client: {clientId}"); byte[] array = SyncedInstance<Config>.SerializeToBytes(SyncedInstance<Config>.Instance); if (array == null) { Plugin.Logger.LogWarning((object)"Config instance is null, unable to sync data!"); return; } int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + SyncedInstance<Config>.IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); } catch (Exception arg) { Plugin.Logger.LogInfo((object)$"Error occurred when syncing config with client: {clientId}\n{arg}"); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<Config>.IntSize)) { Plugin.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)) { Plugin.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<Config>.SyncInstance(data); Plugin.Logger.LogInfo((object)"Successfully synced config with host."); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "JoinLobby")] public static void InitializeLocalPlayer() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown if (SyncedInstance<Config>.IsHost) { CustomMessagingManager messageManager = SyncedInstance<Config>.MessageManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } messageManager.RegisterNamedMessageHandler("MatrixTermExtensions_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); SyncedInstance<Config>.IsSynced = true; return; } SyncedInstance<Config>.IsSynced = false; CustomMessagingManager messageManager2 = SyncedInstance<Config>.MessageManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } messageManager2.RegisterNamedMessageHandler("MatrixTermExtensions_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); RequestSync(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")] public static void PlayerLeave() { SyncedInstance<Config>.RevertSync(); } } [Serializable] public class SyncedInstance<T> { [NonSerialized] protected static int IntSize = 4; [NonSerialized] private static readonly DataContractSerializer serializer = new DataContractSerializer(typeof(T)); internal static bool IsSynced; public static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager; public static bool IsClient => NetworkManager.Singleton.IsClient; public static bool IsHost => NetworkManager.Singleton.IsHost; internal static T? Default { get; private set; } internal static T? Instance { get; private set; } protected void InitInstance(T instance) { Default = instance; Instance = instance; IntSize = 4; } internal static void SyncInstance(byte[] data) { Instance = DeserializeFromBytes(data); IsSynced = true; } internal static void RevertSync() { Instance = Default; IsSynced = false; } public static byte[]? SerializeToBytes(T? val) { if (val == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); try { serializer.WriteObject(memoryStream, val); return memoryStream.ToArray(); } catch (Exception arg) { Plugin.Logger.LogError((object)$"Error serializing instance: {arg}"); return null; } } public static T? DeserializeFromBytes(byte[] data) { using MemoryStream stream = new MemoryStream(data); try { return (T)serializer.ReadObject(stream); } catch (Exception arg) { Plugin.Logger.LogDebug((object)$"Error deserializing instance: {arg}"); return default(T); } } internal static void SendMessage(string label, ulong clientId, FastBufferWriter stream) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) bool num = ((FastBufferWriter)(ref stream)).Capacity >= ((FastBufferWriter)(ref stream)).MaxCapacity; NetworkDelivery val = (NetworkDelivery)(num ? 4 : 2); if (num) { Plugin.Logger.LogDebug((object)($"Size of stream ({((FastBufferWriter)(ref stream)).Capacity}) was past the max buffer size.\n" + "Config instance will be sent in fragments to avoid overflowing the buffer.")); } MessageManager.SendNamedMessage(label, clientId, stream, val); } } } namespace Matrix.TerminalExtensions.Commands { public class CheatCommands { private const string AmountAdded = "{0} has been added, ye dirty cheater!"; private const string ItemSpawned = "Item Spawned"; private const string ItemsSpawned = "Items Spawned"; private const string ResetCooldown = "Cooldown Reset"; private const string FailedReset = "Failed to reset cooldown"; [TerminalCommand("GiveMoney", true)] public string GiveMoneyCommand(Terminal terminal, int amount) { terminal.groupCredits += amount; return $"{amount} has been added, ye dirty cheater!"; } [TerminalCommand("SpawnLoot", true)] public string SpawnLootCommand(int amount, int value) { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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) int index = RoundManager.Instance.LevelRandom.Next(RoundManager.Instance.currentLevel.spawnableScrap.Count); GameObject spawnPrefab = RoundManager.Instance.currentLevel.spawnableScrap[index].spawnableItem.spawnPrefab; Vector3 position = ((Component)GameNetworkManager.Instance.localPlayerController).transform.position; for (int i = 0; i < amount; i++) { GrabbableObject component = Object.Instantiate<GameObject>(spawnPrefab, position, Quaternion.identity).GetComponent<GrabbableObject>(); component.startFallingPosition = position; component.targetFloorPosition = component.GetItemFloorPosition(position); component.SetScrapValue(value); ((NetworkBehaviour)component).NetworkObject.Spawn(false); } if (amount != 1) { return "Items Spawned"; } return "Item Spawned"; } [TerminalCommand("ResetInverse", false)] public string ResetInverseTeleporterCooldownCommand() { if (TeleporterCommands.TryResetInverseTeleporter()) { return "Cooldown Reset"; } return "Failed to reset cooldown"; } } public class DoorCommands { private const string StartButton = "StartButton"; private const string StopButton = "StopButton"; private const string OpenParameter = "open"; private const string CloseParameter = "close"; private const string ToggleParameter = "toggle"; private const string InvalidParameter = "Invalid Parameter!"; private const string DoorsOpened = "Doors Opened."; private const string DoorsClosed = "Doors Closed."; private const string DoorsAlreadyOpen = "Doors already open!"; private const string DoorsAlreadyClosed = "Doors already closed!"; private const string InSpaceError = "Can't open doors in space!"; [TerminalCommand("Doors", false)] public string DoorCommand([RemainingText] string? subcommand) { return subcommand?.ToLowerInvariant() switch { "open" => OpenCommand(), "close" => CloseCommand(), "toggle" => ToggleDoors(), _ => "Invalid Parameter!", }; } [TerminalCommand("Door", false)] [CommandInfo("Opens or closes the door", "[open/close]")] public string DoorsCommand([RemainingText] string? subcommand) { string text = subcommand?.ToLowerInvariant(); if (!(text == "open")) { if (text == "close") { return CloseCommand(); } return "Invalid Parameter!"; } return OpenCommand(); } [TerminalCommand("Open", false)] [CommandInfo("Opens doors, if not already open.", "")] public string OpenCommand() { if (!StartOfRound.Instance.shipDoorsEnabled) { return "Can't open doors in space!"; } if (TryOpenDoors()) { return "Doors Opened."; } return "Doors already open!"; } [TerminalCommand("Close", false)] [CommandInfo("Closes doors, if not already closed.", "")] public string CloseCommand() { if (!StartOfRound.Instance.shipDoorsEnabled) { return "Can't open doors in space!"; } if (TryCloseDoors()) { return "Doors Closed."; } return "Doors already closed!"; } private static bool TryOpenDoors() { if (StartOfRound.Instance.hangarDoorsClosed) { ((UnityEvent<PlayerControllerB>)(object)GameObject.Find("StartButton").GetComponentInChildren<InteractTrigger>().onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return true; } return false; } private static bool TryCloseDoors() { if (!StartOfRound.Instance.hangarDoorsClosed) { ((UnityEvent<PlayerControllerB>)(object)GameObject.Find("StopButton").GetComponentInChildren<InteractTrigger>().onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return true; } return false; } private string ToggleDoors() { if (StartOfRound.Instance.hangarDoorsClosed) { return OpenCommand(); } return CloseCommand(); } } public class LaunchCommands { private const string StartGameLever = "StartGameLever"; private const string alreadyInTransitMsg = "Unable to comply. Ship is alredy in tranist."; private const string CantFindStartComponent = "<!!!> Can't find StartMatchLever Component <!!!>"; private const string InitiatingLaunch = "Initiating launch sequence."; private const string InitiatingLanding = "Initiating landing sequence."; private const string AlreadyInSpace = "Already in space!"; private const string AlreadyLanded = "Already landed on moon!"; [TerminalCommand("Launch", false)] public string LaunchCommand() { if (!TryGetShipLever(out StartMatchLever startMatchLever)) { return "<!!!> Can't find StartMatchLever Component <!!!>"; } if (StartOfRound.Instance.shipDoorsEnabled && !StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.shipIsLeaving) { return "Unable to comply. Ship is alredy in tranist."; } if (!StartOfRound.Instance.shipDoorsEnabled && StartOfRound.Instance.travellingToNewLevel) { return "Unable to comply. Ship is alredy in tranist."; } return PullLever(startMatchLever); } [TerminalCommand("Go", false)] [CommandInfo("Pull the lever, Kronk!", "")] public string GoCommand() { return LaunchCommand(); } [TerminalCommand("TakeOff", false)] [CommandInfo("Takes off from moon.", "")] public string TakeOffCommand() { if (!TryGetShipLever(out StartMatchLever startMatchLever)) { return "<!!!> Can't find StartMatchLever Component <!!!>"; } if (!StartOfRound.Instance.shipDoorsEnabled) { return "Already in space!"; } if (StartOfRound.Instance.shipDoorsEnabled && !StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.shipIsLeaving) { return "Unable to comply. Ship is alredy in tranist."; } return PullLever(startMatchLever); } [TerminalCommand("Land", false)] [CommandInfo("Lands ship on routed moon.", "")] public string LandCommand() { if (!TryGetShipLever(out StartMatchLever startMatchLever)) { return "<!!!> Can't find StartMatchLever Component <!!!>"; } if (StartOfRound.Instance.shipDoorsEnabled) { return "Already landed on moon!"; } if (!StartOfRound.Instance.shipDoorsEnabled && StartOfRound.Instance.travellingToNewLevel) { return "Unable to comply. Ship is alredy in tranist."; } return PullLever(startMatchLever); } private static bool TryGetShipLever([NotNullWhen(true)] out StartMatchLever? startMatchLever) { startMatchLever = null; GameObject val = GameObject.Find("StartGameLever"); if (val == null) { return false; } startMatchLever = val.GetComponent<StartMatchLever>(); return startMatchLever != null; } private static string PullLever(StartMatchLever lever) { bool num = !lever.leverHasBeenPulled; lever.PullLever(); lever.LeverAnimation(); if (num) { lever.StartGame(); } else { lever.EndGame(); } if (!lever.leverHasBeenPulled) { return "Initiating launch sequence."; } return "Initiating landing sequence."; } } public class LightsCommands { private enum LightState { On, Off, Toggle } private const string LightsTurnedOn = "Turning lights on."; private const string LightsTurnedOff = "Turning lights off."; private const string LightsDisabled = "Unable to switch lights, as they are disabled."; private const string LightsAlreadyOn = "Lights are already on!"; private const string LightsAlreadyOff = "Lights are already off!"; private const string ParameterError = "Invalid Parameter."; [TerminalCommand("Lights", false)] [CommandInfo("Toggles the lights on or off", "")] public string SwitchLightsCommand() { return TrySwitchLights(LightState.Toggle); } [TerminalCommand("Lightup", false)] public string LightsOnCommand() { return TrySwitchLights(LightState.On); } [TerminalCommand("lightout", false)] [CommandInfo("Turns the lights off, if not already off", "")] public string LightsOffCommand() { return TrySwitchLights(LightState.Off); } [TerminalCommand("nox", false)] public string NoxCommand() { return LightsOffCommand(); } [TerminalCommand("lumos", false)] [CommandInfo("Turns the lights off, if not already off", "")] public string LumosCommand() { return LightsOnCommand(); } private static string TrySwitchLights(LightState switchState) { if (!((Behaviour)StartOfRound.Instance.shipRoomLights).enabled) { return "Unable to switch lights, as they are disabled."; } InteractTrigger component = GameObject.Find("LightSwitch").GetComponent<InteractTrigger>(); switch (switchState) { case LightState.Off: if (StartOfRound.Instance.shipRoomLights.areLightsOn) { ((UnityEvent<PlayerControllerB>)(object)component.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return "Turning lights off."; } return "Lights are already off!"; case LightState.On: if (!StartOfRound.Instance.shipRoomLights.areLightsOn) { ((UnityEvent<PlayerControllerB>)(object)component.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return "Turning lights on."; } return "Lights are already on!"; case LightState.Toggle: ((UnityEvent<PlayerControllerB>)(object)component.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); if (!StartOfRound.Instance.shipRoomLights.areLightsOn) { return "Turning lights off."; } return "Turning lights on."; default: return "Invalid Parameter."; } } } public class TeleporterCommands { private const string TeleporterObjectName = "Teleporter(Clone)"; private const string InverseTeleporterObjectName = "InverseTeleporter(Clone)"; private const string TeleporterCooldown = "Teleporter is on cooldown, {0:D} seconds left!"; private const string InverseTeleporterCooldown = "Inverse Teleporter is on cooldown, {0:D} seconds left!"; private const string TeleportingPlayer = "Teleporting Player.."; private const string InverseTeleporting = "Tally ho, lads!"; private const string NoTeleporterInShip = "No Teleporter in ship!"; private const string ShipTeleporterComponentNotFound = "<!!!> Cannot locate ShipTeleporter Component! <!!!>"; private const string UnableToResetInverted = "Unable to reset inverse teleporter."; private const string InSpaceError = "Can't use the Inverse Teleporter in space!"; [TerminalCommand("Teleport", false)] public string TeleportCommand() { if (!TryGetTeleporter(out ShipTeleporter teleporter, out string errorMessage)) { return errorMessage; } if (!teleporter.buttonTrigger.interactable) { int num = (int)Utils.GetInstancedStructField<float>(teleporter, "cooldownTime"); return $"Teleporter is on cooldown, {num:D} seconds left!"; } ((UnityEvent<PlayerControllerB>)(object)teleporter.buttonTrigger.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return "Teleporting Player.."; } [TerminalCommand("iTeleport", false)] public string InverseTeleportCommand() { if (!StartOfRound.Instance.shipDoorsEnabled) { return "Can't use the Inverse Teleporter in space!"; } if (!TryGetTeleporter(out ShipTeleporter teleporter, out string errorMessage, isInverted: true)) { return errorMessage; } if (!teleporter.buttonTrigger.interactable) { int num = (int)Utils.GetInstancedStructField<float>(teleporter, "cooldownTime"); return $"Inverse Teleporter is on cooldown, {num:D} seconds left!"; } ((UnityEvent<PlayerControllerB>)(object)teleporter.buttonTrigger.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return "Tally ho, lads!"; } [TerminalCommand("tp", false)] [CommandInfo("Activates teleporter.", "")] public string TpCommand() { return TeleportCommand(); } [TerminalCommand("itp", false)] [CommandInfo("Activates the Inverse Teleporter.", "")] public string ItpCommand() { return InverseTeleportCommand(); } internal static bool TryGetTeleporter([NotNullWhen(true)] out ShipTeleporter? teleporter, out string errorMessage, bool isInverted = false) { errorMessage = string.Empty; GameObject val = GameObject.Find(isInverted ? "InverseTeleporter(Clone)" : "Teleporter(Clone)"); if (val == null) { teleporter = null; errorMessage = "No Teleporter in ship!"; return false; } teleporter = val.GetComponent<ShipTeleporter>(); if (teleporter == null) { teleporter = null; errorMessage = "<!!!> Cannot locate ShipTeleporter Component! <!!!>"; return false; } return errorMessage.IsNullOrWhitespace(); } internal static bool TryResetInverseTeleporter() { if (!TryGetTeleporter(out ShipTeleporter teleporter, out string errorMessage, isInverted: true)) { Plugin.Logger.LogDebug((object)"Unable to reset inverse teleporter."); Plugin.Logger.LogDebug((object)errorMessage); return false; } Plugin.Logger.LogInfo((object)"Inverse Teleporter loaded. Resetting cooldown"); Utils.SetInstancedStructField(teleporter, "cooldownTime", 0f); ((Behaviour)teleporter).enabled = true; teleporter.buttonTrigger.cooldownTime = 0f; teleporter.buttonTrigger.interactable = true; int num = (int)Utils.GetInstancedStructField<float>(teleporter, "cooldownTime"); Plugin.Logger.LogInfo((object)$"Inverse Teleporter is on cooldown, {num:D} seconds left!"); return true; } } }