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 BetterTerminal v1.1.1
BetterTerminal.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; 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 LethalAPI.LibTerminal; using LethalAPI.LibTerminal.Attributes; using LethalAPI.LibTerminal.Models; 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: AssemblyTitle("BetterTerminal")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("BetterTerminal")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e8857ce3-5d85-4646-b810-d07713a6c929")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] public class TerminalNetworkHandler : NetworkBehaviour { public static TerminalNetworkHandler Instance; private void Awake() { Instance = this; } public void SyncOrderedItems(List<int> orderedItems) { if (((NetworkBehaviour)this).IsServer) { SyncOrderedItemsClientRpc(orderedItems); } else { SyncOrderedItemsServerRpc(orderedItems); } } [ClientRpc] private void SyncOrderedItemsClientRpc(List<int> orderedItems) { Terminal val = Object.FindObjectOfType<Terminal>(); if ((Object)(object)val != (Object)null) { val.orderedItemsFromTerminal = orderedItems; } } [ServerRpc(RequireOwnership = false)] private void SyncOrderedItemsServerRpc(List<int> orderedItems) { SyncOrderedItemsClientRpc(orderedItems); } } namespace BetterTerminal; internal class Alias { private MainBetterTerminal instance = new MainBetterTerminal(); [TerminalCommand("scan", true)] public string ScanAlias(string scanspot) { if (scanspot == "inside") { return instance.ScanInsideCommand(); } if (scanspot == "ship") { return instance.ItemsCommand(); } return "[There was no scan type supplied with that word.]"; } [TerminalCommand("light", true)] public string LightAlias() { return instance.LightsCommand(); } [TerminalCommand("teleport", true)] public string TpAlias() { return instance.TpCommand(); } [TerminalCommand("doors", true)] public string DoorAlias() { return instance.ToggleDoorCommand(); } [TerminalCommand("Land", true)] public string LaunchAlias() { return instance.LaunchCommand(); } [TerminalCommand("Go", true)] public string LaunchAlias2() { return instance.LaunchCommand(); } [TerminalCommand("InverseTp", true)] public string InverseAlias() { return instance.InverseCommand(); } } [Serializable] public class BetterTerminalConfig : SyncedInstance<BetterTerminalConfig> { public ConfigEntry<bool> restartCommandDisable; public ConfigEntry<bool> cancelDeliveryDisable; public ConfigEntry<bool> itpDisable; public ConfigEntry<bool> itpHost; public ConfigEntry<bool> launchDisable; public ConfigEntry<bool> launchHost; public ConfigEntry<bool> doorDisable; public ConfigEntry<bool> doorHost; public ConfigEntry<bool> teleportDisable; public ConfigEntry<bool> teleportHost; public ConfigEntry<bool> lightsDisable; public ConfigEntry<bool> lightsHost; public ConfigEntry<bool> itemsDisable; public ConfigEntry<bool> itemsHost; public ConfigEntry<bool> scanInsideDisable; public ConfigEntry<bool> scanInsideHost; public BetterTerminalConfig(ConfigFile cfg) { InitInstance(this); restartCommandDisable = cfg.Bind<bool>("Commands.Restart", "Disable", false, "Disables the restart command"); itpDisable = cfg.Bind<bool>("Commands.itp", "Disable", false, "Disables the ITP (Inverse Teleporter) command"); itpHost = cfg.Bind<bool>("Commands.itp", "Host Only", false, "Makes the ITP (Inverse Teleporter) command for hosts only"); launchDisable = cfg.Bind<bool>("Commands.Launch", "Disable", false, "Disables the Launch command"); launchHost = cfg.Bind<bool>("Commands.Launch", "Host Only", false, "Makes the Launch command for hosts only"); doorDisable = cfg.Bind<bool>("Commands.Door", "Disable", false, "Disables the Door command"); doorHost = cfg.Bind<bool>("Commands.Door", "Host Only", false, "Makes the Door command for hosts only"); teleportDisable = cfg.Bind<bool>("Commands.Teleport", "Disable", false, "Disables the Door command"); teleportHost = cfg.Bind<bool>("Commands.Teleport", "Host Only", false, "Makes the Door command for hosts only"); lightsDisable = cfg.Bind<bool>("Commands.Lights", "Disable", false, "Disables the Lights command"); lightsHost = cfg.Bind<bool>("Commands.Lights", "Host Only", false, "Makes the Lights command for hosts only"); cancelDeliveryDisable = cfg.Bind<bool>("Commands.CancelDelivery", "Disable", false, "Disables the Cancel Delivery command"); itemsDisable = cfg.Bind<bool>("Commands.Items", "Disable", false, "Disables the Items command"); itemsHost = cfg.Bind<bool>("Commands.Items", "Host Only", false, "Makes the Items command for hosts only"); scanInsideDisable = cfg.Bind<bool>("Commands.ScanInside", "Disable", false, "Disables the Scan Inside command"); scanInsideHost = cfg.Bind<bool>("Commands.ScanInside", "Host Only", false, "Makes the Scan Inside command for hosts only"); } } [BepInPlugin("zg.BetterTerminal", "BetterTerminal", "1.1.1")] [HarmonyPatch(typeof(Terminal))] public class MainBetterTerminal : BaseUnityPlugin { private const string modVersion = "1.1.1"; private const string modGUID = "zg.BetterTerminal"; private const string modName = "BetterTerminal"; private readonly Harmony harmony = new Harmony("zg.BetterTerminal"); private TerminalModRegistry Commands; internal ManualLogSource pnt; public static BetterTerminalConfig Config { get; internal set; } public static MainBetterTerminal instance { get; internal set; } public ManualLogSource getLogger() { return ((BaseUnityPlugin)this).Logger; } private void Awake() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown if ((Object)(object)instance == (Object)null) { instance = this; } Config = new BetterTerminalConfig(((BaseUnityPlugin)this).Config); Commands = TerminalRegistry.CreateTerminalRegistry(); Commands.RegisterFrom<MainBetterTerminal>(this); Commands.RegisterFrom<Alias>(); GameObject val = new GameObject("TerminalNetworkHandler"); TerminalNetworkHandler terminalNetworkHandler = val.AddComponent<TerminalNetworkHandler>(); TerminalNetworkHandler.Instance = terminalNetworkHandler; pnt = Logger.CreateLogSource("zg.BetterTerminal"); pnt.LogInfo((object)"BetterTerminal Enabled"); pnt.LogInfo((object)"Make sure to review BetterTerminal"); harmony.PatchAll(typeof(MainBetterTerminal)); harmony.PatchAll(typeof(TerminalNetworkHandler)); } [TerminalCommand("ScanInside", true)] [CommandInfo("See how many items are INSIDE the facility", "")] public string ScanInsideCommand() { if (Config.scanInsideDisable.Value) { return "This command is Disabled"; } if (Config.scanInsideHost.Value && !isHost()) { return "This command is Host Only"; } Debug.Log((object)"Got to debug 1"); Random random = new Random(StartOfRound.Instance.randomMapSeed + 91); int num = 0; int num2 = 0; int num3 = 0; GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); for (int i = 0; i < array.Length; i++) { Debug.Log((object)"Got to debug 2"); if (array[i].itemProperties.isScrap && array[i].isInFactory) { Debug.Log((object)"Got to debug 3"); num3 += array[i].itemProperties.maxValue - array[i].itemProperties.minValue; num2 += Mathf.Clamp(random.Next(array[i].itemProperties.minValue, array[i].itemProperties.maxValue), array[i].scrapValue - 6 * i, array[i].scrapValue + 9 * i); num++; } Debug.Log((object)"Got to debug 4"); } Debug.Log((object)"Got to debug 5"); return "There are currently " + num + " items inside the facility"; } [TerminalCommand("Items", true)] [CommandInfo("See the value of items inside of the ship", "")] public string ItemsCommand() { if (Config.itemsDisable.Value) { return "This command is Disabled"; } if (Config.itemsHost.Value && !isHost()) { return "This command is Host Only"; } GameObject val = GameObject.Find("/Environment/HangarShip"); if ((Object)(object)val == (Object)null) { return "0"; } List<GrabbableObject> source = (from obj in val.GetComponentsInChildren<GrabbableObject>() where ((Object)obj).name != "ClipboardManual" && ((Object)obj).name != "StickyNoteItem" && ((Object)obj).name != "KeyItem" select obj).ToList(); float num = source.Sum((GrabbableObject scrap) => scrap.scrapValue); Debug.Log((object)$"There is currently ${num} value of scrap inside the ship"); return $"There is currently ${num} value of scrap inside of the ship"; } [TerminalCommand("CancelDelivery", true)] [AllowedCaller(/*Could not decode attribute arguments.*/)] [CommandInfo("Cancel purchased items for a refund before delivery", "")] public string CancelDeliveryCommand() { if (Config.cancelDeliveryDisable.Value) { return "This command is Disabled"; } Terminal val = Object.FindObjectOfType<Terminal>(); if (val.numberOfItemsInDropship > 0) { TerminalNetworkHandler.Instance.SyncOrderedItems(val.orderedItemsFromTerminal); int num = 0; foreach (int item in val.orderedItemsFromTerminal) { if (item >= 0 && item < val.buyableItemsList.Count()) { num += val.buyableItemsList[item].creditsWorth; } else { Debug.LogError((object)"Why is this happening?!?"); } } int num2 = (val.groupCredits += num); Debug.Log((object)num); num = 0; val.orderedItemsFromTerminal.Clear(); val.numberOfItemsInDropship = 0; val.SyncGroupCreditsClientRpc(num2, val.numberOfItemsInDropship); val.SyncGroupCreditsServerRpc(num2, val.numberOfItemsInDropship); return "Purchase cancelled and items refunded"; } return "No items in delivery to cancel."; } [TerminalCommand("bettermods", true)] [CommandInfo("Info about BetterMods", "")] public string BetterModsCommand() { return "BetterSpec and BetterTerminal were made by Higgins, You can get them both on Thunderstore"; } [TerminalCommand("lights", true)] [CommandInfo("Use this to toggle ship lights remotely", "")] public string LightsCommand() { if (Config.lightsDisable.Value) { return "This command is Disabled"; } if (Config.lightsHost.Value && !isHost()) { return "This command is Host Only"; } StartOfRound.Instance.shipRoomLights.ToggleShipLights(); return "You've toggled the lights inside of the ship"; } [TerminalCommand("tp", true)] [CommandInfo("Teleport the player currently on the monitor", "")] public string TpCommand() { if (Config.teleportDisable.Value) { return "This command is Disabled"; } if (Config.teleportHost.Value && !isHost()) { return "This command is Host Only"; } ShipTeleporter component = GameObject.Find("Teleporter(Clone)").GetComponent<ShipTeleporter>(); FieldInfo field = ((object)component).GetType().GetField("cooldownTime", BindingFlags.Instance | BindingFlags.NonPublic); float num = (float)field.GetValue(component); if (num > 0f) { return "The teleporter is currently on cooldown"; } if ((Object)(object)component == (Object)null) { return "You must purchase a Teleporter to teleport"; } ((UnityEvent<PlayerControllerB>)(object)component.buttonTrigger.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return "Teleporting"; } [TerminalCommand("door", true)] [CommandInfo("Safely toggle the Ship Door", "")] public string ToggleDoorCommand() { if (Config.doorDisable.Value) { return "This command is Disabled"; } if (Config.doorHost.Value && !isHost()) { return "This command is Host Only"; } InteractTrigger componentInChildren = GameObject.Find(StartOfRound.Instance.hangarDoorsClosed ? "StartButton" : "StopButton").GetComponentInChildren<InteractTrigger>(); ((UnityEvent<PlayerControllerB>)(object)componentInChildren.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); if (StartOfRound.Instance.hangarDoorsClosed) { return "Opened the doors"; } return "Closed the doors, stay safe"; } [TerminalCommand("Launch", true)] [CommandInfo("Use this to land or launch the ship", "")] public string LaunchCommand() { if (Config.launchDisable.Value) { return "This command is Disabled"; } if (Config.launchHost.Value && !isHost()) { return "This command is Host Only"; } if ((Object)(object)GameObject.Find("StartGameLever") == (Object)null) { return "Error finding the Lever"; } StartMatchLever component = GameObject.Find("StartGameLever").GetComponent<StartMatchLever>(); if (StartOfRound.Instance.shipDoorsEnabled && !StartOfRound.Instance.shipHasLanded && !StartOfRound.Instance.shipIsLeaving) { return "Contact the Pilot someone's already done this!"; } if (!StartOfRound.Instance.shipDoorsEnabled && StartOfRound.Instance.travellingToNewLevel) { return "Contact the Pilot someone's already done this!"; } component.PullLever(); component.LeverAnimation(); if (component.leverHasBeenPulled) { component.StartGame(); return "Copy that Pilot ship is heading there now"; } if (!component.leverHasBeenPulled) { component.EndGame(); return "Copy that Pilot, Leaving the moon now"; } return "If you see this run the command again"; } [TerminalCommand("itp", true)] [CommandInfo("Uses the inverse teleporter", "")] public string InverseCommand() { if (Config.itpDisable.Value) { return "This command is Disabled"; } if (Config.itpHost.Value && !isHost()) { return "This command is Host Only"; } if (!StartOfRound.Instance.shipHasLanded) { return "You can't teleport in space you'll die!"; } if ((Object)(object)GameObject.Find("InverseTeleporter(Clone)") == (Object)null) { return "You need to purchase a inverse teleporter"; } ShipTeleporter component = GameObject.Find("InverseTeleporter(Clone)").GetComponent<ShipTeleporter>(); FieldInfo field = ((object)component).GetType().GetField("cooldownTime", BindingFlags.Instance | BindingFlags.NonPublic); float num = (float)field.GetValue(component); if (num > 0f) { return "The inverse teleporter is currently on cooldown"; } if ((Object)(object)component == (Object)null) { return "You need to purchase a inverse teleporter"; } ((UnityEvent<PlayerControllerB>)(object)component.buttonTrigger.onInteract).Invoke(GameNetworkManager.Instance.localPlayerController); return "You sent him to die, Goodluck!"; } [TerminalCommand("Restart", true)] [AllowedCaller(/*Could not decode attribute arguments.*/)] [CommandInfo("Resets all the ships furniture", "")] public string RestartCommand() { if (Config.restartCommandDisable.Value) { return "This command is Disabled"; } if (!StartOfRound.Instance.shipDoorsEnabled) { StartOfRound.Instance.ResetShip(); return "The company has shunned you, Go back to square 1"; } return "You must be in space to restart, the company wants you working on the moon"; } private bool isHost() { return ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost; } } [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) { MainBetterTerminal.instance.getLogger().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) { MainBetterTerminal.instance.getLogger().LogError((object)$"Error deserializing instance: {arg}"); return default(T); } } public static void RequestSync() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!IsClient) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(IntSize, (Allocator)2, -1); try { MessageManager.SendNamedMessage("BetterTerminal_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_0059: 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_007d: Unknown result type (might be due to invalid IL or missing references) if (!IsHost) { return; } MainBetterTerminal.instance.getLogger().LogInfo((object)$"Config sync request received from client: {clientId}"); byte[] array = SerializeToBytes(Instance); int num = array.Length; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num + IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); MessageManager.SendNamedMessage("BetterTerminal_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3); } catch (Exception arg) { MainBetterTerminal.instance.getLogger().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_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(IntSize)) { MainBetterTerminal.instance.getLogger().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)) { MainBetterTerminal.instance.getLogger().LogError((object)"Config sync error: Host could not sync."); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); SyncInstance(data); MainBetterTerminal.instance.getLogger().LogInfo((object)"Successfully synced config with host."); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] public static void InitializeLocalPlayer() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown if (IsHost) { MessageManager.RegisterNamedMessageHandler("BetterTerminal_OnRequestConfigSync", new HandleNamedMessageDelegate(OnRequestSync)); Synced = true; } else { Synced = false; MessageManager.RegisterNamedMessageHandler("BetterTerminal_OnReceiveConfigSync", new HandleNamedMessageDelegate(OnReceiveSync)); RequestSync(); } } } public static class MyPluginInfo { public const string PLUGIN_GUID = "BetterTerminal"; public const string PLUGIN_NAME = ""; public const string PLUGIN_VERSION = "1.0.0.0"; }