using 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;
}
}
}