Decompiled source of ShipComputerAssistant v1.0.0

ShipComputerAssistant.dll

Decompiled 2 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("ShipComputerAssistant")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ShipComputerAssistant")]
[assembly: AssemblyTitle("ShipComputerAssistant")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 ShipComputerAssistant
{
	[HarmonyPatch(typeof(Terminal), "ParsePlayerSentence")]
	internal static class CrewStatusTerminalPatch
	{
		[HarmonyPrefix]
		private static bool BeforeParsePlayerSentence(Terminal __instance, ref TerminalNode __result)
		{
			if ((Object)(object)__instance == (Object)null)
			{
				return true;
			}
			string currentCommand = GetCurrentCommand(__instance);
			if (currentCommand.Equals("crew upgrade", StringComparison.OrdinalIgnoreCase) || currentCommand.Equals("crew monitoring", StringComparison.OrdinalIgnoreCase) || currentCommand.Equals("buy crew monitor", StringComparison.OrdinalIgnoreCase))
			{
				__result = CreateCrewUpgradePurchaseNode(__instance);
				return false;
			}
			if (currentCommand.Equals("confirm", StringComparison.OrdinalIgnoreCase) && CrewUpgradeManager.PurchasePending)
			{
				__result = CompleteCrewUpgradePurchase(__instance);
				return false;
			}
			if (currentCommand.Equals("deny", StringComparison.OrdinalIgnoreCase) && CrewUpgradeManager.PurchasePending)
			{
				CrewUpgradeManager.PurchasePending = false;
				__result = CreateSimpleNode("\nPurchase cancelled.\n\n");
				return false;
			}
			if (!currentCommand.Equals("crew", StringComparison.OrdinalIgnoreCase) && !currentCommand.Equals("status", StringComparison.OrdinalIgnoreCase))
			{
				return true;
			}
			if (!CrewUpgradeManager.IsPurchased)
			{
				__result = CreateLockedCrewNode();
				return false;
			}
			__result = CreateCrewStatusNode();
			return false;
		}

		private static string GetCurrentCommand(Terminal terminal)
		{
			if ((Object)(object)terminal == (Object)null || (Object)(object)terminal.screenText == (Object)null)
			{
				return string.Empty;
			}
			string text = terminal.screenText.text ?? string.Empty;
			if (string.IsNullOrWhiteSpace(text))
			{
				return string.Empty;
			}
			string[] array = text.Replace("\r", "").Split(new char[1] { '\n' });
			for (int num = array.Length - 1; num >= 0; num--)
			{
				string text2 = array[num].Trim();
				if (!string.IsNullOrWhiteSpace(text2))
				{
					if (text2.StartsWith(">"))
					{
						return text2.Substring(1).Trim().ToLowerInvariant();
					}
					return text2.ToLowerInvariant();
				}
			}
			return string.Empty;
		}

		private static TerminalNode CreateSimpleNode(string text)
		{
			TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>();
			obj.clearPreviousText = true;
			obj.displayText = text;
			return obj;
		}

		private static TerminalNode CreateLockedCrewNode()
		{
			return CreateSimpleNode("\n================================\n   CREW MONITORING SOFTWARE\n================================\n\nACCESS DENIED\n\nCrew Monitoring Software is not installed.\n\nPrice: $" + 300 + "\n\nType \"crew upgrade\" to purchase.\n\n");
		}

		private static TerminalNode CreateCrewUpgradePurchaseNode(Terminal terminal)
		{
			if (CrewUpgradeManager.IsPurchased)
			{
				CrewUpgradeManager.PurchasePending = false;
				return CreateSimpleNode("\nCrew Monitoring Software is already installed.\n\nType \"crew\" to access employee information.\n\n");
			}
			if ((Object)(object)terminal == (Object)null)
			{
				CrewUpgradeManager.PurchasePending = false;
				return CreateSimpleNode("\nPurchase unavailable: terminal not found.\n\n");
			}
			CrewUpgradeManager.PurchasePending = true;
			return CreateSimpleNode("\n================================\n   CREW MONITORING SOFTWARE\n================================\n\nProvides remote access to employee:\n\n - Health\n - General location\n - Carried weight\n - Currently held equipment\n\nPrice: $" + 300 + "\nCurrent credits: $" + terminal.groupCredits + "\n\nPlease CONFIRM or DENY.\n\n");
		}

		private static TerminalNode CompleteCrewUpgradePurchase(Terminal terminal)
		{
			CrewUpgradeManager.PurchasePending = false;
			if (CrewUpgradeManager.IsPurchased)
			{
				return CreateSimpleNode("\nCrew Monitoring Software is already installed.\n\n");
			}
			if ((Object)(object)terminal == (Object)null)
			{
				return CreateSimpleNode("\nPurchase failed: terminal unavailable.\n\n");
			}
			int num = 300;
			if (terminal.groupCredits < num)
			{
				return CreateSimpleNode("\nPURCHASE DECLINED\n\nInsufficient credits.\n\nRequired: $" + num + "\nAvailable: $" + terminal.groupCredits + "\n\n");
			}
			terminal.groupCredits -= num;
			terminal.SyncGroupCreditsServerRpc(terminal.groupCredits, terminal.numberOfItemsInDropship);
			CrewUpgradeManager.IsPurchased = true;
			return CreateSimpleNode("\n================================\n       PURCHASE COMPLETE\n================================\n\nCrew Monitoring Software installed.\n\nRemaining credits: $" + terminal.groupCredits + "\n\nType \"crew\" to access employee information.\n\n");
		}

		private static TerminalNode CreateCrewStatusNode()
		{
			TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>();
			obj.clearPreviousText = true;
			obj.displayText = BuildCrewStatusText();
			return obj;
		}

		private static string BuildCrewStatusText()
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine();
			stringBuilder.AppendLine("> CREW STATUS");
			stringBuilder.AppendLine();
			if ((Object)(object)StartOfRound.Instance == (Object)null || StartOfRound.Instance.allPlayerScripts == null)
			{
				stringBuilder.AppendLine("Crew information is currently unavailable.");
				stringBuilder.AppendLine();
				return stringBuilder.ToString();
			}
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			int num = 0;
			int num2 = 0;
			PlayerControllerB[] array = allPlayerScripts;
			foreach (PlayerControllerB val in array)
			{
				if (!((Object)(object)val == (Object)null) && val.isPlayerControlled)
				{
					num++;
					string text = (string.IsNullOrWhiteSpace(val.playerUsername) ? "Unknown employee" : val.playerUsername);
					if (val.isPlayerDead)
					{
						stringBuilder.AppendLine(text + " : DECEASED");
						continue;
					}
					num2++;
					stringBuilder.AppendLine(text + " : ALIVE");
					stringBuilder.AppendLine("  Health: " + val.health);
					stringBuilder.AppendLine("  Weight: " + GetDisplayedWeight(val) + " lb");
					stringBuilder.AppendLine("  Location: " + GetPlayerLocation(val));
					stringBuilder.AppendLine("  Held item: " + GetHeldItemName(val));
					stringBuilder.AppendLine();
				}
			}
			if (num == 0)
			{
				stringBuilder.AppendLine("No active employees detected.");
			}
			else
			{
				stringBuilder.AppendLine("Employees alive: " + num2 + "/" + num);
			}
			stringBuilder.AppendLine();
			return stringBuilder.ToString();
		}

		private static int GetDisplayedWeight(PlayerControllerB player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 0;
			}
			return Mathf.RoundToInt(Mathf.Max(0f, player.carryWeight - 1f) * 105f);
		}

		private static string GetPlayerLocation(PlayerControllerB player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return "Unknown";
			}
			if (player.isInHangarShipRoom)
			{
				return "Ship";
			}
			if (player.isInsideFactory)
			{
				return "Facility";
			}
			return "Outside";
		}

		private static string GetHeldItemName(PlayerControllerB player)
		{
			if ((Object)(object)player == (Object)null || (Object)(object)player.currentlyHeldObjectServer == (Object)null || (Object)(object)player.currentlyHeldObjectServer.itemProperties == (Object)null)
			{
				return "None";
			}
			string itemName = player.currentlyHeldObjectServer.itemProperties.itemName;
			if (!string.IsNullOrWhiteSpace(itemName))
			{
				return itemName;
			}
			return "Unknown item";
		}
	}
	[HarmonyPatch(typeof(Terminal), "LoadNewNode")]
	internal static class CrewHelpPagePatch
	{
		[HarmonyPatch(typeof(Terminal), "LoadNewNode")]
		internal static class CrewUpgradeComingSoonPatch
		{
			private static string CrewUpgradeEntry => "\n>CREW UPGRADE // $" + 300 + "\nDisplays employee health, location, weight, and held equipment.\nType \"crew upgrade\" for purchase information.\n";

			[HarmonyPrefix]
			private static void BeforeLoadNewNode(TerminalNode node)
			{
				if (!((Object)(object)node == (Object)null) && !string.IsNullOrEmpty(node.displayText) && IsShipUpgradesPage(node.displayText) && node.displayText.IndexOf(">CREW MONITORING SOFTWARE", StringComparison.OrdinalIgnoreCase) < 0)
				{
					node.displayText += CrewUpgradeEntry;
				}
			}

			private static bool IsShipUpgradesPage(string text)
			{
				return text.IndexOf("SHIP UPGRADES", StringComparison.OrdinalIgnoreCase) >= 0;
			}
		}

		private const string CrewHelpEntry = "\n>CREW\nDisplays employee status after Crew Monitoring Software is installed.\n\n>CREW UPGRADE\nViews or purchases Crew Monitoring Software.\n";

		[HarmonyPrefix]
		private static void BeforeLoadNewNode(TerminalNode node)
		{
			if (!((Object)(object)node == (Object)null) && !string.IsNullOrEmpty(node.displayText) && IsHelpNode(node) && node.displayText.IndexOf(">CREW", StringComparison.OrdinalIgnoreCase) < 0)
			{
				node.displayText += "\n>CREW\nDisplays employee status after Crew Monitoring Software is installed.\n\n>CREW UPGRADE\nViews or purchases Crew Monitoring Software.\n";
			}
		}

		private static bool IsHelpNode(TerminalNode node)
		{
			string displayText = node.displayText;
			if (displayText.IndexOf(">MOONS", StringComparison.OrdinalIgnoreCase) >= 0 && displayText.IndexOf(">STORE", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return displayText.IndexOf(">BESTIARY", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}
	}
	internal static class CrewUpgradeManager
	{
		internal const int Price = 300;

		internal static bool IsPurchased;

		internal static bool PurchasePending;

		internal static void Reset()
		{
			IsPurchased = false;
			PurchasePending = false;
		}
	}
	[BepInPlugin("gavin.shipcomputerassistant", "Ship Computer Assistant", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "gavin.shipcomputerassistant";

		public const string NAME = "Ship Computer Assistant";

		public const string VERSION = "1.0.0";

		private Harmony harmony;

		private void Awake()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Applying Harmony patches...");
			harmony = new Harmony("gavin.shipcomputerassistant");
			harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Harmony patches applied.");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
}