Decompiled source of HuraHappyTimes v1.0.2

HuraHappyTimes.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Hura.Project;
using Hura.Project.Cheats;
using Hura.Project.Utility;
using HuraHappyTimes.Project;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("HuraHappyTimes")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("HP")]
[assembly: AssemblyProduct("HuraHappyTimes")]
[assembly: AssemblyCopyright("Copyright © HP 2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("36b637e7-d1d5-43d1-94b8-14d41177383c")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace HuraHappyTimes.Project
{
	[HarmonyPatch(typeof(ShipTeleporter))]
	public class TeleporterCheat
	{
		[HarmonyPatch("PressTeleportButtonClientRpc")]
		[HarmonyPrefix]
		public static void OnTeleportPressedPatch(ref ShipTeleporter __instance)
		{
			__instance.cooldownAmount = 10f;
		}
	}
}
namespace Hura
{
	[BepInPlugin("Hura.HappyTimes", "Hura Happy Times", "1.0.2")]
	public class HuraHappyTimes : BaseUnityPlugin
	{
		private const string MOD_GUID = "Hura.HappyTimes";

		private const string MOD_NAME = "Hura Happy Times";

		private const string MOD_VERSION = "1.0.2";

		private readonly Harmony harmony = new Harmony("Hura.HappyTimes");

		public static HuraHappyTimes Instance { get; private set; }

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			Log.Init(Logger.CreateLogSource("Hura.HappyTimes"));
			harmony.PatchAll(typeof(HuraHappyTimes));
			harmony.PatchAll(typeof(TerminalHelper));
			harmony.PatchAll(typeof(TerminalCheats));
			harmony.PatchAll(typeof(TeleporterCheat));
			Log.Message("Hura's Happy Times has been loaded!");
		}
	}
	public static class Log
	{
		private static ManualLogSource logger;

		public static void Init(ManualLogSource instance)
		{
			logger = instance;
		}

		public static void Message(string message)
		{
			logger.LogMessage((object)message);
		}

		public static void Error(string error)
		{
			logger.LogError((object)error);
		}

		public static void Warning(string warning)
		{
			logger.LogWarning((object)warning);
		}

		public static void NullReference(object obj, string name)
		{
			logger.LogMessage((object)("Is " + name + " null? " + ((obj == null) ? "Yes" : "No")));
		}
	}
}
namespace Hura.Project
{
	internal static class ItemsHelper
	{
		public const string WALKIE_TALKIE_NAME = "Walkie-talkie";

		public const string FLASHLIGHT_NAME = "Flashlight";

		public const string SHOVEL_NAME = "Shovel";

		public const string LOCKPICKER_NAME = "Lockpicker";

		public const string PRO_FLASHLIGHT_NAME = "Pro-flashlight";

		public const string STUN_GRENADE_NAME = "Stun grenade";

		public const string BOOMBOX_NAME = "Boombox";

		public const string TZP_INHALANT_NAME = "TZP-Inhalant";

		public const string ZAP_GUN_NAME = "Zap gun";

		public const string JETPACK_NAME = "Jetpack";

		public const string EXTENSION_LADDER_NAME = "Extension ladder";

		public const string RADAR_BOOSTER_NAME = "Radar-booster";

		public const string SPRAY_PAINT_NAME = "Spray paint";

		public static Item[] GetItems()
		{
			return TerminalHelper.Terminal.buyableItemsList;
		}

		public static Item GetItem(string itemName)
		{
			Item[] items = GetItems();
			foreach (Item val in items)
			{
				if (val.itemName == itemName)
				{
					return val;
				}
			}
			Log.Error("Couldn't find item with name: " + itemName + ".");
			return null;
		}
	}
	internal static class MoonsHelper
	{
		public struct MoonData
		{
			public int Cost { get; set; }

			public TerminalNode Node { get; set; }

			public TerminalNode ConfirmNode { get; set; }

			public string Name => ((Object)Node).name;
		}

		public enum RerouteID
		{
			Company = -1,
			Moons = -2
		}

		private static List<MoonData> moons;

		public static IReadOnlyList<MoonData> Moons => moons;

		public static bool IsMoonsConfirmationNode(TerminalNode node)
		{
			if (node.buyRerouteToMoon != -1)
			{
				return node.buyRerouteToMoon != -2;
			}
			return false;
		}

		public static void PopulateMoonsData()
		{
			Terminal terminal = TerminalHelper.Terminal;
			if ((Object)(object)terminal == (Object)null)
			{
				Log.Error("Error while populating moons data. Couldn't find the Terminal.");
				return;
			}
			moons = new List<MoonData>();
			TerminalKeyword[] allKeywords = terminal.terminalNodes.allKeywords;
			foreach (TerminalKeyword val in allKeywords)
			{
				if ((Object)(object)val == (Object)null || val.word == null || !(val.word == "route"))
				{
					continue;
				}
				CompatibleNoun[] compatibleNouns = val.compatibleNouns;
				for (int j = 0; j < compatibleNouns.Length; j++)
				{
					TerminalNode result = compatibleNouns[j].result;
					if ((Object)(object)result == (Object)null || result.buyRerouteToMoon != -2)
					{
						continue;
					}
					MoonData item = default(MoonData);
					item.Node = result;
					item.Cost = result.itemCost;
					CompatibleNoun[] terminalOptions = result.terminalOptions;
					foreach (CompatibleNoun val2 in terminalOptions)
					{
						if (val2.result.itemCost > 0)
						{
							item.ConfirmNode = val2.result;
						}
					}
					moons.Add(item);
					Log.Message($"Added Moon. Node: {item.Node}. Cost: {item.Cost}.");
				}
			}
		}
	}
	public enum SpecialTerminalNode
	{
		Login,
		Home,
		CannotAffordItems,
		UnableToRouteNeedOrbit,
		DevileryVehicleIsFull,
		Error,
		MissingCreatureData,
		UnableToBuyDecorationNeedOrbit,
		AlreadyInOrbit,
		DataCorrupted,
		NoActionWasGivenWithWord,
		ParsingError,
		ActionWasIncompatibleWithObject,
		Help,
		AlreadyUnlock,
		ShipIsStuck,
		ItemNotInStock,
		ItemReturnedFromStorage,
		LockedFromDemo,
		BroadcastCodeEntered,
		RadarSwitchToPlayer,
		RadarPinged,
		TransmissionSent,
		FlashedRadar
	}
	[HarmonyPatch(typeof(Terminal))]
	public static class TerminalHelper
	{
		private static StringBuilder stringBuilder = new StringBuilder();

		public static Terminal Terminal { get; private set; }

		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void RegisterTerminalInstance(ref Terminal __instance)
		{
			Terminal = __instance;
		}

		public static TerminalNode CreateNode(string text, bool clear = true)
		{
			TerminalNode obj = ScriptableObject.CreateInstance<TerminalNode>();
			obj.displayText = text;
			obj.clearPreviousText = clear;
			return obj;
		}

		public static TerminalKeyword CreateKeyword(string word, bool isVerb, TerminalNode destinationNode)
		{
			TerminalKeyword obj = ScriptableObject.CreateInstance<TerminalKeyword>();
			obj.word = word;
			obj.isVerb = isVerb;
			obj.specialKeywordResult = destinationNode;
			return obj;
		}

		public static void AddKeyworkToTerminal(TerminalKeyword keyword)
		{
			ArrayUtility.Add(ref Terminal.terminalNodes.allKeywords, keyword);
		}

		public static string CreateNodeText(params string[] args)
		{
			stringBuilder.Clear();
			for (int i = 0; i < args.Length; i++)
			{
				stringBuilder.Append(args[i]).Append("\n");
			}
			return stringBuilder.ToString();
		}

		public static CompatibleNoun CreateCompatibleNoun(TerminalKeyword noun, TerminalNode destinationNode)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			return new CompatibleNoun
			{
				noun = noun,
				result = destinationNode
			};
		}

		public static void AddCompatibleNounToVerb(TerminalKeyword verb, TerminalKeyword noun, TerminalNode destinationNode)
		{
			if (!verb.isVerb)
			{
				Log.Error("Error while adding compatible noun to verb. Given verb is not a verb: " + verb.word);
				return;
			}
			if (noun.isVerb)
			{
				Log.Error("Error while adding compatible noun to verb. Given noun is a verb: " + noun.word);
				return;
			}
			CompatibleNoun element = CreateCompatibleNoun(noun, destinationNode);
			ArrayUtility.Add(ref verb.compatibleNouns, element);
		}

		public static TerminalNode GetSpecialNode(SpecialTerminalNode specialNode)
		{
			List<TerminalNode> specialNodes = Terminal.terminalNodes.specialNodes;
			if (!specialNodes.IsValidIndex((int)specialNode))
			{
				Log.Error($"Error while trying to get special node at index [{(int)specialNode}]. Returning the first special node...");
				return specialNodes[0];
			}
			return Terminal.terminalNodes.specialNodes[(int)specialNode];
		}
	}
	internal class UpdateHelper
	{
		public static void LogAllSpecialNodes()
		{
			for (int i = 0; i < TerminalHelper.Terminal.terminalNodes.specialNodes.Count; i++)
			{
				TerminalNode val = TerminalHelper.Terminal.terminalNodes.specialNodes[i];
				Log.Message($"Node [{i}]: {val.displayText}]");
			}
		}

		public static void LogAllItemsInfos()
		{
			Item[] buyableItemsList = TerminalHelper.Terminal.buyableItemsList;
			foreach (Item val in buyableItemsList)
			{
				Log.Message($"Item name: {val.itemName}. Item ID: {val.itemId}.");
			}
		}

		public static void LogAllMoonsInfos()
		{
			SelectableLevel[] moonsCatalogueList = TerminalHelper.Terminal.moonsCatalogueList;
			foreach (SelectableLevel val in moonsCatalogueList)
			{
				Log.Message($"Moon. Name: {val.PlanetName}. ID: {val.levelID}. Scene Name: {val.sceneName}");
			}
			Log.Message($"Moon Nodes. {TerminalHelper.Terminal.terminalNodes.terminalNodes.Count}");
			foreach (TerminalNode terminalNode in TerminalHelper.Terminal.terminalNodes.terminalNodes)
			{
				Log.Message($"Moon Node. Name: {((Object)terminalNode).name}. Price: {terminalNode.itemCost}.");
			}
			TerminalKeyword[] allKeywords = TerminalHelper.Terminal.terminalNodes.allKeywords;
			foreach (TerminalKeyword val2 in allKeywords)
			{
				if (val2.word == "route")
				{
					CompatibleNoun[] compatibleNouns = val2.compatibleNouns;
					foreach (CompatibleNoun val3 in compatibleNouns)
					{
						Log.Message($"Moon Node. Node Name: {((Object)val3.result).name}. MoonID: {val3.result.buyRerouteToMoon}. Price: {val3.result.itemCost}.");
					}
				}
			}
		}
	}
}
namespace Hura.Project.Cheats
{
	internal abstract class Cheat : ICheat
	{
		protected TerminalNode node;

		public virtual string ID => GetType().ToString();

		public abstract string Description { get; }

		public abstract bool NeedsOption { get; }

		public TerminalNode Node => node;

		public abstract void AddToTerminal(Terminal terminal, TerminalKeyword cheatVerb);

		public abstract void Execute(string option);
	}
	internal class CustomItemsPriceCheat : ToggleCheat
	{
		private const int SKIP_OVERRIDE_VALUE = -1;

		public static bool currentSettings = false;

		private static Dictionary<string, int> overridePrices = new Dictionary<string, int>
		{
			{ "Walkie-talkie", -1 },
			{ "Flashlight", -1 },
			{ "Shovel", -1 },
			{ "Lockpicker", -1 },
			{ "Pro-flashlight", -1 },
			{ "Stun grenade", -1 },
			{ "Boombox", 25 },
			{ "TZP-Inhalant", 20 },
			{ "Zap gun", -1 },
			{ "Jetpack", 75 },
			{ "Extension ladder", 30 },
			{ "Radar-booster", -1 },
			{ "Spray paint", 10 }
		};

		public override string Description => "Set custom item prices.\n\"cheat customitemsprice on\" to enable.\n\"cheat customitemsprice off\" to disable.";

		public override void AddToTerminal(Terminal terminal, TerminalKeyword cheatVerb)
		{
			node = TerminalHelper.CreateNode(TerminalHelper.CreateNodeText("You have set custom items price!"));
			node.terminalEvent = ID;
			TerminalKeyword val = TerminalHelper.CreateKeyword("customitemsprice", isVerb: false, null);
			TerminalHelper.AddCompatibleNounToVerb(cheatVerb, val, node);
			TerminalHelper.AddKeyworkToTerminal(val);
		}

		protected override void OnEnable()
		{
			OverridePrices();
		}

		protected override void OnDisable()
		{
			ResetPriceToDefault();
		}

		private void OverridePrices()
		{
			Item[] items = ItemsHelper.GetItems();
			foreach (Item val in items)
			{
				if (overridePrices.TryGetValue(val.itemName, out var value) && value != -1)
				{
					val.creditsWorth = value;
					Log.Message($"Priced overriden on item: {val.itemId}. Item name: {val.itemName}");
				}
			}
		}

		private void ResetPriceToDefault()
		{
			Item[] items = ItemsHelper.GetItems();
			foreach (Item val in items)
			{
				if (TerminalCheats.DefaultItemsPrice.TryGetValue(((Object)val).name, out var value))
				{
					val.creditsWorth = value;
				}
			}
		}
	}
	internal class CustomMoonsPrices : ToggleCheat
	{
		public override string Description => "Set custom moons prices.\n\"cheat custommoonsprice on\" to enable.\n\"cheat custommoonsprice off\" to disable.";

		public override void AddToTerminal(Terminal terminal, TerminalKeyword cheatVerb)
		{
			node = TerminalHelper.CreateNode(TerminalHelper.CreateNodeText("You have set custom moons price!"));
			node.terminalEvent = ID;
			TerminalKeyword val = TerminalHelper.CreateKeyword("custommoonsprice", isVerb: false, null);
			TerminalHelper.AddCompatibleNounToVerb(cheatVerb, val, node);
			TerminalHelper.AddKeyworkToTerminal(val);
			UpdateHelper.LogAllMoonsInfos();
		}

		protected override void OnEnable()
		{
			OverridePrices();
		}

		protected override void OnDisable()
		{
			ResetPriceToDefault();
		}

		private void OverridePrices()
		{
			foreach (MoonsHelper.MoonData moon in MoonsHelper.Moons)
			{
				if (moon.Cost > 0)
				{
					moon.Node.itemCost = 100;
					moon.ConfirmNode.itemCost = 100;
				}
			}
		}

		private void ResetPriceToDefault()
		{
			foreach (MoonsHelper.MoonData moon in MoonsHelper.Moons)
			{
				if (moon.Cost > 0)
				{
					moon.Node.itemCost = moon.Cost;
					moon.ConfirmNode.itemCost = moon.Cost;
				}
			}
		}
	}
	internal interface ICheat
	{
		string ID { get; }

		bool NeedsOption { get; }

		TerminalNode Node { get; }

		void AddToTerminal(Terminal terminal, TerminalKeyword cheatVerb);

		void Execute(string option);
	}
	internal class MoneyCheat : Cheat
	{
		private Terminal terminal;

		public override bool NeedsOption => true;

		public override string Description => "Add credits to the group.\n\"cheat addmoney X\" where X is the amount you want to add.";

		public override void AddToTerminal(Terminal terminal, TerminalKeyword cheatVerb)
		{
			this.terminal = terminal;
			node = TerminalHelper.CreateNode(TerminalHelper.CreateNodeText("You have added money!"));
			node.terminalEvent = ID;
			TerminalKeyword val = TerminalHelper.CreateKeyword("addmoney", isVerb: false, null);
			TerminalHelper.AddCompatibleNounToVerb(cheatVerb, val, node);
			TerminalHelper.AddKeyworkToTerminal(val);
		}

		public override void Execute(string option)
		{
			if (int.TryParse(option, out var result))
			{
				AddMoney(result);
			}
		}

		private void AddMoney(int money)
		{
			Terminal obj = terminal;
			obj.groupCredits += money;
			terminal.SyncGroupCreditsServerRpc(terminal.groupCredits, terminal.numberOfItemsInDropship);
		}
	}
	[HarmonyPatch(typeof(Terminal))]
	internal static class TerminalCheats
	{
		public const string CHEAT_KEYWORD_NAME = "cheat";

		private static readonly ICheat[] cheats = new ICheat[3]
		{
			new MoneyCheat(),
			new CustomItemsPriceCheat(),
			new CustomMoonsPrices()
		};

		private static Dictionary<string, int> defaultItemsPrice = new Dictionary<string, int>();

		private static string lastInputOption;

		public static IReadOnlyDictionary<string, int> DefaultItemsPrice => defaultItemsPrice;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void Initialize()
		{
			SaveItemsPrice();
			MoonsHelper.PopulateMoonsData();
			AddCheatCommandsToTerminal();
			ICheat[] array = cheats;
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i] is ToggleCheat toggleCheat)
				{
					toggleCheat.Execute("on");
				}
			}
		}

		private static void SaveItemsPrice()
		{
			Item[] buyableItemsList = TerminalHelper.Terminal.buyableItemsList;
			foreach (Item val in buyableItemsList)
			{
				defaultItemsPrice.Add(val.itemName, val.creditsWorth);
			}
		}

		private static void AddCheatCommandsToTerminal()
		{
			TerminalNode destinationNode = TerminalHelper.CreateNode(TerminalHelper.CreateNodeText("Welcome to Hura's cheat codes!"));
			TerminalKeyword val = TerminalHelper.CreateKeyword("cheat", isVerb: true, destinationNode);
			TerminalHelper.AddKeyworkToTerminal(val);
			ICheat[] array = cheats;
			for (int i = 0; i < array.Length; i++)
			{
				array[i].AddToTerminal(TerminalHelper.Terminal, val);
			}
		}

		[HarmonyPatch("RunTerminalEvents")]
		[HarmonyPostfix]
		public static void RunQuizTerminalEvents(TerminalNode node)
		{
			string terminalEvent = node.terminalEvent;
			if (string.IsNullOrEmpty(terminalEvent))
			{
				return;
			}
			ICheat[] array = cheats;
			foreach (ICheat cheat in array)
			{
				if (cheat.ID == terminalEvent)
				{
					cheat.Execute(lastInputOption);
				}
			}
		}

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPrefix]
		private static void ParsePlayerSentencePrefix(ref Terminal __instance, ref TerminalNode __result)
		{
			string[] array = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Split(new char[1] { ' ' });
			if (array.Length == 3)
			{
				lastInputOption = array[2];
			}
		}

		[HarmonyPatch("ParsePlayerSentence")]
		[HarmonyPostfix]
		private static void ParsePlayerSentencePostfix(ref Terminal __instance, ref TerminalNode __result)
		{
			string[] array = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded).Split(new char[1] { ' ' });
			if (!(array[0] == "cheat"))
			{
				return;
			}
			ICheat[] array2 = cheats;
			for (int i = 0; i < array2.Length; i++)
			{
				if (array2[i].NeedsOption && array.Length != 3)
				{
					__result = TerminalHelper.GetSpecialNode(SpecialTerminalNode.ParsingError);
				}
			}
		}
	}
	internal abstract class ToggleCheat : Cheat
	{
		public override bool NeedsOption => true;

		public override void Execute(string option)
		{
			string text = option.ToLower();
			if (!(text == "on"))
			{
				if (text == "off")
				{
					OnDisable();
				}
				else
				{
					Log.Warning("No third argument was given when trying to set a toggle cheat.");
				}
			}
			else
			{
				OnEnable();
			}
		}

		protected abstract void OnEnable();

		protected abstract void OnDisable();
	}
}
namespace Hura.Project.Utility
{
	internal static class ArrayUtility
	{
		public static void Add<T>(ref T[] array, T element)
		{
			if (array == null)
			{
				array = new T[0];
			}
			Array.Resize(ref array, array.Length + 1);
			array[array.Length - 1] = element;
		}

		public static bool IsValidIndex<T>(this ICollection<T> list, int index)
		{
			if (index < 0)
			{
				return false;
			}
			if (index >= list.Count)
			{
				return false;
			}
			return true;
		}
	}
}