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 StoreTweaks v0.0.5
StoreTweaks.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; 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.Configuration; using BepInEx.Logging; using HarmonyLib; using LethalNetworkAPI; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: AssemblyCompany("StoreTweaks")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.0.5.0")] [assembly: AssemblyInformationalVersion("0.0.5+4ea9226b9ab3f347cab41a51c8a46aa8ffd7628b")] [assembly: AssemblyProduct("StoreTweaks")] [assembly: AssemblyTitle("StoreTweaks")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.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 StoreTweaks { public static class StorePricesHandler { private static readonly Dictionary<int, TerminalStoreItem> Items = new Dictionary<int, TerminalStoreItem>(); private static Dictionary<int, TerminalStoreItem> _backup; public static void AddItem(int index, Item item, TerminalNode node) { if (Items.TryGetValue(index, out TerminalStoreItem value)) { value.Nodes.Add(node); return; } Items.Add(index, new TerminalStoreItem(item, new List<TerminalNode>(1) { node }, item.creditsWorth)); } public static void Backup() { _backup = Items.ToDictionary<KeyValuePair<int, TerminalStoreItem>, int, TerminalStoreItem>((KeyValuePair<int, TerminalStoreItem> kvp) => kvp.Key, (KeyValuePair<int, TerminalStoreItem> kvp) => kvp.Value); } public static Item[] Restore() { foreach (var (_, terminalStoreItem2) in _backup) { terminalStoreItem2.Item.creditsWorth = terminalStoreItem2.OriginalPrice; foreach (TerminalNode node in terminalStoreItem2.Nodes) { node.itemCost = terminalStoreItem2.OriginalPrice; } } return RenderInternal(_backup); } public static void UpdatePrice(int index, int price) { Items[index].Item.creditsWorth = price; foreach (TerminalNode node in Items[index].Nodes) { node.itemCost = price; } } public static void Remove(int index) { foreach (TerminalNode node in Items[index].Nodes) { node.buyItemIndex = -1; node.itemCost = -1; } Items.Remove(index); } public static Item[] Render() { return RenderInternal(Items); } private static Item[] RenderInternal(Dictionary<int, TerminalStoreItem> items) { TerminalStoreItem[] array = items.Values.ToArray(); List<Item> list = new List<Item>(); for (int i = 0; i < array.Length; i++) { TerminalStoreItem terminalStoreItem = array[i]; foreach (TerminalNode node in terminalStoreItem.Nodes) { node.buyItemIndex = i; } list.Add(terminalStoreItem.Item); } return list.ToArray(); } } public class TerminalStoreItem { public Item Item { get; } public int OriginalPrice { get; } public List<TerminalNode> Nodes { get; } public TerminalStoreItem(Item item, List<TerminalNode> nodes, int price) { Item = item; OriginalPrice = price; Nodes = nodes; base..ctor(); } } [BepInPlugin("StoreTweaks", "StoreTweaks", "0.0.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class StoreTweaks : BaseUnityPlugin { public static StoreTweaks Instance { get; private set; } internal static ManualLogSource Logger { get; private set; } internal static Harmony? Harmony { get; set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Instance = this; Patch(); Logger.LogInfo((object)"StoreTweaks v0.0.5 has loaded!"); } internal static void Patch() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Expected O, but got Unknown if (Harmony == null) { Harmony = new Harmony("StoreTweaks"); } Logger.LogDebug((object)"Patching..."); Harmony.PatchAll(); Logger.LogDebug((object)"Finished patching!"); } internal static void Unpatch() { Logger.LogDebug((object)"Unpatching..."); Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } Logger.LogDebug((object)"Finished unpatching!"); } } public class TerminalConfig { public readonly Dictionary<string, ItemConfig> Items = new Dictionary<string, ItemConfig>(); public TerminalConfig(ConfigFile cfg, List<Item> itemList) { cfg.SaveOnConfigSet = false; foreach (Item item in itemList) { ConfigEntry<bool> val = cfg.Bind<bool>("Item: " + item.itemName, "Enabled", true, "Enables/Disable the item from the store"); ConfigEntry<int> val2 = cfg.Bind<int>("Item: " + item.itemName, "Price", item.creditsWorth, "Price of the item in credits"); Items.Add(item.itemName, new ItemConfig(val.Value, val2.Value)); } ClearOrphanedEntries(cfg); cfg.Save(); cfg.SaveOnConfigSet = true; } private static void ClearOrphanedEntries(ConfigFile cfg) { PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries"); Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg); dictionary.Clear(); } } public class ItemConfig { public readonly bool Enabled; public readonly int Price; public ItemConfig(bool enabled, int price) { Enabled = enabled; Price = price; base..ctor(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "StoreTweaks"; public const string PLUGIN_NAME = "StoreTweaks"; public const string PLUGIN_VERSION = "0.0.5"; } } namespace StoreTweaks.Patches { [HarmonyPatch(typeof(QuickMenuManager))] public class QuickMenuManagerPatch { [HarmonyPatch("LeaveGameConfirm")] [HarmonyPrefix] private static void LeaveGameConfirmPatch() { StoreTweaks.Logger.LogDebug((object)"Leaving game, reverting patch."); Terminal val = Object.FindObjectOfType<Terminal>(); val.buyableItemsList = StorePricesHandler.Restore(); TerminalPatch.Unlock(); } } [HarmonyPatch(typeof(Terminal))] public class TerminalPatch { private static readonly LethalNetworkVariable<Dictionary<string, ItemConfig>> SharedItemsConfig = new LethalNetworkVariable<Dictionary<string, ItemConfig>>("items"); private static Dictionary<string, ItemConfig> _itemsConfig = new Dictionary<string, ItemConfig>(); private static bool _tweaked; public static void Unlock() { _tweaked = false; } [HarmonyPatch("Awake")] [HarmonyPostfix] private static void Setup(Terminal __instance) { if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { StoreTweaks.Logger.LogInfo((object)"I'm hosting, initializing configs."); TerminalConfig terminalConfig = new TerminalConfig(((BaseUnityPlugin)StoreTweaks.Instance).Config, __instance.buyableItemsList.ToList()); _itemsConfig = terminalConfig.Items; } List<TerminalNode> nodes = FindStoreNodes(); BuildStoreHandler(nodes, __instance.buyableItemsList); } [HarmonyPatch("RotateShipDecorSelection")] [HarmonyPrefix] private static void TweakPrices(Terminal __instance) { if (!_tweaked) { StoreTweaks.Logger.LogInfo((object)"Tweaking the terminal."); if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { SharedItemsConfig.Value = _itemsConfig; } ApplyConfig(__instance.buyableItemsList); __instance.buyableItemsList = StorePricesHandler.Render(); _tweaked = true; } } [HarmonyPatch("LoadNewNode")] [HarmonyPrefix] private static void CheckNodeAvailability(Terminal __instance, ref TerminalNode node) { if (node.itemCost == -1) { StoreTweaks.Logger.LogDebug((object)(((Object)node).name + " is disabled in configs, returning a parse error to the terminal.")); node = __instance.terminalNodes.specialNodes[10]; } } private static List<TerminalNode> FindStoreNodes() { List<TerminalNode> list = Resources.FindObjectsOfTypeAll<TerminalNode>().ToList(); return list.FindAll((TerminalNode n) => n.buyItemIndex >= 0); } private static void BuildStoreHandler(List<TerminalNode> nodes, Item[] buyableItems) { foreach (TerminalNode node in nodes) { if (node.buyItemIndex >= buyableItems.Length) { StoreTweaks.Logger.LogWarning((object)$"Item {((Object)node).name} has a buyItemIndex ({node.buyItemIndex}) which is out of range ({buyableItems.Length}), skipping."); } else { StorePricesHandler.AddItem(node.buyItemIndex, buyableItems[node.buyItemIndex], node); } } StorePricesHandler.Backup(); } private static void ApplyConfig(Item[] buyableItems) { Dictionary<string, ItemConfig> value = SharedItemsConfig.Value; for (int i = 0; i < buyableItems.Length; i++) { Item val = buyableItems[i]; if (!value.TryGetValue(val.itemName, out var value2) || !value2.Enabled) { StoreTweaks.Logger.LogDebug((object)("Removing item " + ((Object)val).name + " from store.")); StorePricesHandler.Remove(i); } else { StoreTweaks.Logger.LogDebug((object)$"Setting item {((Object)val).name} price to {value2.Price}"); StorePricesHandler.UpdatePrice(i, value2.Price); } } } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }