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 HuraHappyTimes v1.0.2
HuraHappyTimes.dll
Decompiled 2 years agousing 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; } } }