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 Overworked v1.1.2
Overworked.dll
Decompiled 10 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Overworked.Core; using Overworked.Core.AlwaysGrab; using Overworked.Core.CustomTerminal; using Overworked.Core.Levels; using Overworked.Core.Placement; using Overworked.Core.Scanner; using Overworked.Core.Selling; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Overworked")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Overworked")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+ab047318a31c4cc88a99e75a832c7cc07bffdeaf")] [assembly: AssemblyProduct("Overworked")] [assembly: AssemblyTitle("Overworked")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [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 Overworked { [BepInPlugin("dev.timmywastor.overworked", "Overworked", "1.1.0")] public class Plugin : BaseUnityPlugin { public const string ModGUID = "dev.timmywastor.overworked"; public const string ModName = "Overworked"; public const string ModVersion = "1.1.0"; public static Harmony Harmony = new Harmony("dev.timmywastor.overworked"); public static ManualLogSource OverworkedLogger; public static string PluginFolder; private void Awake() { string location = ((BaseUnityPlugin)this).Info.Location; PluginFolder = Path.GetDirectoryName(location); OverworkedLogger = ((BaseUnityPlugin)this).Logger; OverworkedCore.Initialize(); } } public static class PluginInfo { public const string PLUGIN_GUID = "Overworked"; public const string PLUGIN_NAME = "Overworked"; public const string PLUGIN_VERSION = "1.1.0"; } } namespace Overworked.Core { internal class OverworkedCore { public static void Initialize() { Patch(); } private static void Patch() { Plugin.Harmony.PatchAll(typeof(SellingModule)); Plugin.Harmony.PatchAll(typeof(ItemPlacement)); Plugin.Harmony.PatchAll(typeof(ObjectGrab)); Plugin.Harmony.PatchAll(typeof(LevelLoading)); Plugin.Harmony.PatchAll(typeof(OverworkedTerminal)); } } } namespace Overworked.Core.Selling { internal class SellingModule { private const string _moneyFieldName = "Ow_money"; private static Terminal _currentTerminal; private static int _money = 0; private static readonly string helpHost = ">MOONS\r\nTo see the list of moons the autopilot can route to.\r\n\r\n>STORE\r\nTo see the company store's selection of useful items.\r\n\r\n>BESTIARY\r\nTo see the list of wildlife on record.\r\n\r\n>STORAGE\r\nTo access objects placed into storage.\r\n\r\n>STOCK\r\nStore and manipulate your scrap.\r\n\r\n>OTHER\r\nTo see the list of other commands\r\n\r\n[numberOfItemsOnRoute]\r\n"; private static readonly string helpClient = ">MOONS\r\nTo see the list of moons the autopilot can route to.\r\n\r\n>STORE\r\nTo see the company store's selection of useful items.\r\n\r\n>BESTIARY\r\nTo see the list of wildlife on record.\r\n\r\n>STORAGE\r\nTo access objects placed into storage.\r\n\r\n>OTHER\r\nTo see the list of other commands\r\n\r\n[numberOfItemsOnRoute]\r\n"; private static readonly string commands = ">STOCK [scrap]\nStocks all the available ship scrap.\n\n>STOCK [view] [-S](OPTIONAL,shares it to the chat)\nCheck how much scrap value is stored.\n\n>STOCK SELL [amount]\nAllows you to sell your stored scrap value at the company building.\n\n"; private static readonly string stockMessage = "Welcome to STOCK™.\nuse the following commands to manipulate your stock.\n----------------------------\n\n" + commands; private static readonly string stockScrapMessage = "You have requested to stock all the available ship scrap.\n\nPlease CONFIRM or DENY"; private static readonly string[] _blacklistedItems = new string[3] { "Shotgun", "Ammo", "Kitchen knife" }; private static MethodInfo AddTextMessageServerRpc = AccessTools.Method(typeof(HUDManager), "AddTextMessageServerRpc", (Type[])null, (Type[])null); private static MethodInfo SellAndDisplayItemProfits = AccessTools.Method(typeof(DepositItemsDesk), "SellAndDisplayItemProfits", (Type[])null, (Type[])null); private static IEnumerator ShowTipDelayed() { yield return (object)new WaitForSeconds(2f); HUDManager.Instance.DisplayTip("Overworked", "Scrap stocking module initialized, type 'stock' on the terminal for the list of commands.", false, false, ""); } public static void Initialize(Terminal t) { if (((NetworkBehaviour)StartOfRound.Instance).IsHost) { ((MonoBehaviour)t).StartCoroutine(ShowTipDelayed()); t.terminalNodes.allKeywords[5].specialKeywordResult.displayText = helpHost; _currentTerminal = t; _money = 0; InjectCommands(); Load(); } else { t.terminalNodes.allKeywords[5].specialKeywordResult.displayText = helpClient; } } public static void ResetMoney() { _money = 0; } private static void Load() { string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName; if (ES3.KeyExists("Ow_money", currentSaveFileName)) { _money = ES3.Load<int>("Ow_money", currentSaveFileName); } } public static void Save() { string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName; ES3.Save<int>("Ow_money", _money, currentSaveFileName); } private static void GetMoneyAndUpdate() { int num = _money; GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if (val.itemProperties.isScrap && !_blacklistedItems.Contains(val.itemProperties.itemName) && ((NetworkBehaviour)val).IsSpawned && val.isInShipRoom && !val.isHeld) { num += val.scrapValue; ((NetworkBehaviour)val).NetworkObject.Despawn(true); } } _money = num; } public static void SendMessage(string text) { AddTextMessageServerRpc.Invoke(HUDManager.Instance, new object[1] { text }); } private static bool StockSell(int sellAmountParsed) { DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>(); int num = (int)((float)sellAmountParsed * StartOfRound.Instance.companyBuyingRate); if (sellAmountParsed <= 0 || sellAmountParsed > _money) { return false; } Terminal currentTerminal = _currentTerminal; currentTerminal.groupCredits += num; val.SellItemsClientRpc(num, _currentTerminal.groupCredits, 0, StartOfRound.Instance.companyBuyingRate); SellAndDisplayItemProfits.Invoke(val, new object[2] { num, _currentTerminal.groupCredits }); _money -= sellAmountParsed; return true; } private static void InjectCommands() { TerminalCommand stockCommand = new TerminalCommand("stock"); int currentSellAmount = 0; string currentSellMessage = ""; stockCommand.AddState("default", delegate(string[] args) { if (args.Length > 1) { switch (args[1]) { case "scrap": stockCommand.MoveTo("scrap"); return stockScrapMessage; case "view": if (args.Length > 2 && OverworkedTerminal.Match(args[2], "-share")) { SendMessage($"<size=10><mark=#000000><color=#00FF00>Terminal/Stock™: ${_money}</mark></color></size>"); } stockCommand.Finish(); return $"You have obtained ${_money} worth of scrap."; case "sell": { if (args.Length > 2 && int.TryParse(args[2], out var result) && result > 0) { DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>(); if ((Object)(object)val == (Object)null) { stockCommand.Finish(); return "You must route and land to the company building to sell your stocked scrap."; } currentSellAmount = result; currentSellMessage = $"You have requested to sell ${currentSellAmount} of stocked scrap value.\n\nPlease CONFIRM or DENY"; stockCommand.MoveTo("sell"); return currentSellMessage; } stockCommand.Finish(); return "Invalid amount of scrap value to sell detected, protocol aborted."; } } } stockCommand.Finish(); return stockMessage; }); stockCommand.AddState("sell", delegate(string[] args) { DepositItemsDesk val = Object.FindObjectOfType<DepositItemsDesk>(); if ((Object)(object)val != (Object)null) { if (OverworkedTerminal.Match(args[0], "confirm")) { stockCommand.Finish(); if (StockSell(currentSellAmount)) { _currentTerminal.PlayTerminalAudioServerRpc(0); SendMessage($"{GameNetworkManager.Instance.localPlayerController.playerUsername} sold <color=#3AFF61>${currentSellAmount}</color>."); return $"Successfully sold ${currentSellAmount}! Your work keeps the company happy."; } return $"You do not have enough stock value to sell ${currentSellAmount}"; } if (OverworkedTerminal.Match(args[0], "deny")) { stockCommand.Finish(); return "You have cancelled the selling protocol."; } return currentSellMessage; } stockCommand.Finish(); return "You must route and land to the company building to sell your stocked scrap."; }); stockCommand.AddState("scrap", delegate(string[] args) { if (StartOfRound.Instance.inShipPhase) { if (OverworkedTerminal.Match(args[0], "confirm")) { stockCommand.Finish(); GetMoneyAndUpdate(); _currentTerminal.PlayTerminalAudioServerRpc(2); SendMessage(GameNetworkManager.Instance.localPlayerController.playerUsername + " stocked the ship scrap."); return $"Successfully stocked the ship scrap, your new balance is ${_money}."; } if (OverworkedTerminal.Match(args[0], "deny")) { stockCommand.Finish(); return "You have cancelled the ship stocking protocol."; } return stockScrapMessage; } stockCommand.Finish(); return "Cannot stock scrap while the ship isn't in orbit."; }); OverworkedTerminal.AddCommand(stockCommand); } [HarmonyPatch(typeof(StartOfRound), "EndOfGame")] [HarmonyPrefix] private static void EndOfGame_Prefix(StartOfRound __instance) { if (((NetworkBehaviour)StartOfRound.Instance).IsHost && __instance.allPlayersDead) { ResetMoney(); } } [HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")] [HarmonyPrefix] private static void SaveGame_Prefix(GameNetworkManager __instance) { if (((NetworkBehaviour)StartOfRound.Instance).IsHost && StartOfRound.Instance.inShipPhase) { Save(); } } } } namespace Overworked.Core.Scanner { internal struct ScanData { public int ShipValue; public int OutdoorValue; public int IndoorValue; public int ShipScrapAmount; public int OutdoorScrapAmount; public int IndoorScrapAmount; public bool FoundEggs; public bool FoundHives; public ScanData() { ShipValue = 0; OutdoorValue = 0; IndoorValue = 0; ShipScrapAmount = 0; OutdoorScrapAmount = 0; IndoorScrapAmount = 0; FoundEggs = false; FoundHives = false; } } internal class Scan { private static ScanData RunScan() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); ScanData result = new ScanData(); GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if (val.itemProperties.itemName == "Body") { continue; } if (val.itemProperties.itemName == "Egg" && !val.isInShipRoom) { result.FoundEggs = true; } if (val.itemProperties.itemName == "Hive" && !val.isInShipRoom) { result.FoundHives = true; } if (val.itemProperties.isScrap && !val.isInShipRoom) { if (((Component)val).transform.position.y < -80f) { result.IndoorValue += val.scrapValue; result.IndoorScrapAmount++; } else { result.OutdoorValue += val.scrapValue; result.OutdoorScrapAmount++; } } else if (val.itemProperties.isScrap) { result.ShipValue += val.scrapValue; result.ShipScrapAmount++; } } return result; } public static void Initialize(Terminal t) { if (!((NetworkBehaviour)StartOfRound.Instance).IsHost) { return; } TerminalCommand scanCommand = new TerminalCommand("scan"); scanCommand.AddState("default", delegate(string[] args) { ScanData scanData = RunScan(); if (args.Length > 1 && OverworkedTerminal.Match(args[1], "-share")) { SellingModule.SendMessage($"<size=10><mark=#000000><color=#00FF00>Terminal/Scan: {scanData.IndoorScrapAmount} {scanData.OutdoorScrapAmount}</mark></color></size>"); } scanCommand.Finish(); return "The ship scanners have detected the following:\n\n" + $"* Ship value: ${scanData.ShipValue} ({scanData.ShipScrapAmount} items)\n" + $"* Outdoor value: ${scanData.OutdoorValue} ({scanData.OutdoorScrapAmount} items)\n" + $"* Indoor value: ${scanData.IndoorValue} ({scanData.IndoorScrapAmount} items)" + (scanData.FoundEggs ? "\n\nA giant bird like creature seems to have nested on the exomoon." : "") + (scanData.FoundHives ? "\n\nDangerous insect life seems to live in harmony with the ecosystem." : "") + $"\n\nFor a total of {scanData.IndoorScrapAmount + scanData.OutdoorScrapAmount} items outside."; }); OverworkedTerminal.AddCommand(scanCommand); } } } namespace Overworked.Core.Placement { [HarmonyPatch(typeof(StartOfRound))] internal class ItemPlacement { private static readonly Dictionary<string, Vector3> placements = new Dictionary<string, Vector3> { { "Pro-flashlight", new Vector3(7.7134f, 1f, -14.1152f) }, { "Flashlight", new Vector3(7.7134f, 0.3565f, -14.1152f) }, { "Shovel", new Vector3(5.7842f, 0.3817f, -14.9624f) }, { "Lockpicker", new Vector3(6.6094f, 0.3796f, -14.103f) }, { "Weed killer", new Vector3(5.3645f, 0.7417f, -14.1853f) }, { "Spray paint", new Vector3(4.6839f, 0.3617f, -13.9803f) }, { "Walkie-talkie", new Vector3(4.1293f, 0.3417f, -14.1254f) }, { "Stun grenade", new Vector3(3.4229f, 0.3009f, -13.9947f) }, { "Extension ladder", new Vector3(7.8912f, 0.396f, -13.0898f) }, { "Belt bag", new Vector3(6.547f, 0.6398f, -12.9742f) }, { "Jetpack", new Vector3(5.6698f, 0.4417f, -13.0838f) }, { "Key", new Vector3(4.0051f, 0.3117f, -13.084f) }, { "Shotgun", new Vector3(4.7607f, 0.323f, -15.0969f) }, { "Ammo", new Vector3(4.1876f, 0.4307f, -15.0332f) }, { "Kitchen knife", new Vector3(5.0984f, 0.3517f, -13.1254f) } }; public static void ReplaceItems() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>(); GrabbableObject[] array2 = array; foreach (GrabbableObject val in array2) { if (placements.TryGetValue(val.itemProperties.itemName, out var value)) { ((Component)val).gameObject.transform.position = value; } } } [HarmonyPatch("LoadShipGrabbableItems")] [HarmonyPostfix] private static void LoadShipGrabbableItems_Postfix(StartOfRound __instance) { ReplaceItems(); } } } namespace Overworked.Core.Levels { [HarmonyPatch(typeof(RoundManager))] internal class LevelLoading { public static void ApplyLevelData(SelectableLevel newLevel) { string planetName = newLevel.PlanetName; string text = planetName; string text2 = text; if (!(text2 == "20 Adamance")) { if (text2 == "68 Artifice") { newLevel.maxScrap = 37; newLevel.minScrap = 31; } } else { newLevel.maxScrap = 18; newLevel.minScrap = 16; } foreach (SpawnableEnemyWithRarity enemy in newLevel.Enemies) { string enemyName = enemy.enemyType.enemyName; if (enemyName == "Cadaver Growths" && planetName == "20 Adamance") { enemy.rarity = 0; } } } [HarmonyPatch("LoadNewLevel")] [HarmonyPrefix] private static void LoadNewLevel_Prefix(ref SelectableLevel newLevel) { ApplyLevelData(newLevel); } } } namespace Overworked.Core.CustomTerminal { internal class TerminalCommand { public bool ShouldUnfocus = false; public string Keyword { get; } public string CommandState { get; private set; } = "default"; public Dictionary<string, Func<string[], string>> RegisteredStates { get; } = new Dictionary<string, Func<string[], string>>(); public TerminalCommand(string keyword) { Keyword = keyword.ToLower(); } public void AddState(string stateName, Func<string[], string> newState) { RegisteredStates[stateName] = newState; } public void MoveTo(string state) { if (RegisteredStates.ContainsKey(state)) { CommandState = state; } } public void Finish() { ShouldUnfocus = true; CommandState = "default"; } } [HarmonyPatch(typeof(Terminal))] internal class OverworkedTerminal { private static List<TerminalCommand> _commands = new List<TerminalCommand>(); private static TerminalNode _resultNode = new TerminalNode(); private static TerminalCommand _focusedCommand; public static void AddCommand(TerminalCommand newCommand) { _commands.Add(newCommand); } public static bool Match(string input, string compare) { if (input.Length > compare.Length) { return false; } return compare.StartsWith(input, StringComparison.OrdinalIgnoreCase); } [HarmonyPatch("ParsePlayerSentence")] [HarmonyPrefix] private static bool ParsePlayerSentence(Terminal __instance, ref TerminalNode __result) { string text = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded); string[] array = text.Split(" ", StringSplitOptions.RemoveEmptyEntries); if (array.Length == 0) { return true; } string firstArgument = array[0].ToLower(); if (_focusedCommand == null) { _focusedCommand = _commands.FirstOrDefault((TerminalCommand c) => c.Keyword == firstArgument); } if (_focusedCommand == null) { return true; } Func<string[], string> func = _focusedCommand.RegisteredStates[_focusedCommand.CommandState]; string text2 = func(array); if (_focusedCommand.ShouldUnfocus) { _focusedCommand.ShouldUnfocus = false; _focusedCommand = null; } _resultNode.displayText = text2 ?? "OverworkedTerminal: No data was returned from your command."; TerminalNode resultNode = _resultNode; resultNode.displayText += "\n\n"; _resultNode.clearPreviousText = true; __result = _resultNode; return false; } [HarmonyPatch("Start")] [HarmonyPostfix] private static void Start_Prefix(Terminal __instance) { _commands.Clear(); SellingModule.Initialize(__instance); Scan.Initialize(__instance); } } } namespace Overworked.Core.AlwaysGrab { [HarmonyPatch(typeof(GrabbableObject))] internal class ObjectGrab { [HarmonyPatch("Start")] [HarmonyPostfix] private static void Start_Postfix(GrabbableObject __instance) { __instance.itemProperties.canBeGrabbedBeforeGameStart = true; } } }