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.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("PlanetwideGeneratorSupply")] [assembly: AssemblyDescription("Dyson Sphere Program BepInEx mod.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PlanetwideGeneratorSupply")] [assembly: AssemblyCopyright("Copyright (c) 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("00000000-0000-0000-0000-000000000000")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = "")] [assembly: AssemblyVersion("1.0.0.0")] namespace PlanetwideGeneratorSupply; internal static class GeneratorSourcing { private struct StationDist { public int index; public float distSqr; } [ThreadStatic] private static List _scratch; private static readonly Comparison _byDist = (StationDist a, StationDist b) => a.distSqr.CompareTo(b.distSqr); internal static int TryPullFromPlanet(PlanetFactory factory, int itemId, int want, Vector3 pos, float radius, out int incMoved) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) incMoved = 0; if (factory == null || itemId <= 0 || want <= 0) { return 0; } PlanetTransport transport = factory.transport; if (transport == null || transport.stationPool == null) { return 0; } bool value = Plugin.RequireStationSupplyFlag.Value; bool value2 = Plugin.NearestStationFirst.Value; float num = ((radius > 0f) ? (radius * radius) : 0f); EntityData[] entityPool = factory.entityPool; int stationCursor = transport.stationCursor; int moved = 0; Vector3 val2; if (value2) { if (_scratch == null) { _scratch = new List(64); } _scratch.Clear(); for (int i = 1; i < stationCursor; i++) { StationComponent val = transport.stationPool[i]; if (val == null || val.id != i || val.storage == null) { continue; } float num2 = 0f; if (entityPool != null) { int entityId = val.entityId; if (entityId > 0 && entityId < entityPool.Length) { val2 = entityPool[entityId].pos - pos; num2 = ((Vector3)(ref val2)).sqrMagnitude; if (num > 0f && num2 > num) { continue; } } } if (StationHasItem(val, itemId, value)) { _scratch.Add(new StationDist { index = i, distSqr = num2 }); } } _scratch.Sort(_byDist); for (int j = 0; j < _scratch.Count; j++) { if (moved >= want) { break; } DrainStation(transport.stationPool[_scratch[j].index], itemId, want, value, ref moved, ref incMoved); } } else { for (int k = 1; k < stationCursor && moved < want; k++) { StationComponent val3 = transport.stationPool[k]; if (val3 == null || val3.id != k || val3.storage == null) { continue; } if (num > 0f && entityPool != null) { int entityId2 = val3.entityId; if (entityId2 > 0 && entityId2 < entityPool.Length) { val2 = entityPool[entityId2].pos - pos; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } } } DrainStation(val3, itemId, want, value, ref moved, ref incMoved); } } return moved; } internal static int FindAvailableFuel(PlanetFactory factory, short fuelMask, Vector3 pos, float radius, HashSet exclude = null) { //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) if (fuelMask <= 0 || ItemProto.fuelNeeds == null || fuelMask >= ItemProto.fuelNeeds.Length) { return 0; } int[] array = ItemProto.fuelNeeds[fuelMask]; if (array == null) { return 0; } if (Plugin.PreferHighestFuelTier.Value) { for (int num = array.Length - 1; num >= 0; num--) { int num2 = array[num]; if (num2 > 0 && (exclude == null || !exclude.Contains(num2)) && HasStock(factory, num2, pos, radius)) { return num2; } } } else { foreach (int num3 in array) { if (num3 > 0 && (exclude == null || !exclude.Contains(num3)) && HasStock(factory, num3, pos, radius)) { return num3; } } } return 0; } internal static int FindPriorityFuel(PlanetFactory factory, int[] priorityItemIds, Vector3 pos, float radius) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (priorityItemIds == null) { return 0; } foreach (int num in priorityItemIds) { if (num > 0 && HasStock(factory, num, pos, radius)) { return num; } } return 0; } internal static int[] ResolveItemNamesByCsv(string csv) { if (string.IsNullOrWhiteSpace(csv)) { return Array.Empty(); } string[] array = csv.Split(','); List list = new List(array.Length); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (text.Length != 0) { int num = FindItemIdByName(text); if (num > 0) { list.Add(num); } else { PlanetwideGeneratorSupplyLog.Warn("[fuel] no item found matching name: " + text); } } } return list.ToArray(); } private static int FindItemIdByName(string name) { ItemProto[] dataArray = ((ProtoSet)(object)LDB.items).dataArray; if (dataArray == null) { return 0; } foreach (ItemProto val in dataArray) { if (val != null && string.Equals(((Proto)val).name, name, StringComparison.OrdinalIgnoreCase)) { return ((Proto)val).ID; } } return 0; } internal static float NearestFuelStationDistance(PlanetFactory factory, short fuelMask, int itemId, Vector3 pos) { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) PlanetTransport val = factory?.transport; if (val == null || val.stationPool == null) { return -1f; } bool value = Plugin.RequireStationSupplyFlag.Value; EntityData[] entityPool = factory.entityPool; int stationCursor = val.stationCursor; int[] array = null; if (itemId <= 0 && fuelMask > 0 && ItemProto.fuelNeeds != null && fuelMask < ItemProto.fuelNeeds.Length) { array = ItemProto.fuelNeeds[fuelMask]; } float num = -1f; for (int i = 1; i < stationCursor; i++) { StationComponent val2 = val.stationPool[i]; if (val2 == null || val2.id != i || val2.storage == null) { continue; } bool flag = false; if (itemId > 0) { flag = StationHasItem(val2, itemId, value); } else if (array != null) { for (int j = 0; j < array.Length; j++) { if (flag) { break; } if (array[j] > 0) { flag = StationHasItem(val2, array[j], value); } } } if (!flag) { continue; } float num2 = 0f; if (entityPool != null) { int entityId = val2.entityId; if (entityId > 0 && entityId < entityPool.Length) { Vector3 val3 = entityPool[entityId].pos - pos; num2 = ((Vector3)(ref val3)).sqrMagnitude; } } if (num < 0f || num2 < num) { num = num2; } } if (!(num < 0f)) { return Mathf.Sqrt(num); } return -1f; } private static bool StationHasItem(StationComponent station, int itemId, bool requireSupply) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Invalid comparison between Unknown and I4 //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 StationStore[] storage = station.storage; for (int i = 0; i < storage.Length; i++) { if (storage[i].itemId == itemId && storage[i].count > 0 && (!requireSupply || (int)storage[i].localLogic == 1 || (int)storage[i].remoteLogic == 1)) { return true; } } return false; } private static void DrainStation(StationComponent station, int itemId, int want, bool requireSupply, ref int moved, ref int incMoved) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 StationStore[] storage = station.storage; for (int i = 0; i < storage.Length; i++) { if (moved >= want) { break; } if (storage[i].itemId != itemId || storage[i].count <= 0 || (requireSupply && (int)storage[i].localLogic != 1 && (int)storage[i].remoteLogic != 1)) { continue; } int num = want - moved; if (num > storage[i].count) { num = storage[i].count; } int num2 = 0; if (storage[i].inc > 0) { num2 = (int)((float)storage[i].inc * (float)num / (float)storage[i].count + 0.5f); if (num2 > storage[i].inc) { num2 = storage[i].inc; } } storage[i].count -= num; storage[i].inc -= num2; moved += num; incMoved += num2; } } private static bool HasStock(PlanetFactory factory, int itemId, Vector3 pos, float radius) { //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) PlanetTransport transport = factory.transport; if (transport == null || transport.stationPool == null) { return false; } bool value = Plugin.RequireStationSupplyFlag.Value; float num = ((radius > 0f) ? (radius * radius) : 0f); EntityData[] entityPool = factory.entityPool; int stationCursor = transport.stationCursor; for (int i = 1; i < stationCursor; i++) { StationComponent val = transport.stationPool[i]; if (val == null || val.id != i || val.storage == null) { continue; } if (num > 0f && entityPool != null) { int entityId = val.entityId; if (entityId > 0 && entityId < entityPool.Length) { Vector3 val2 = entityPool[entityId].pos - pos; if (((Vector3)(ref val2)).sqrMagnitude > num) { continue; } } } if (StationHasItem(val, itemId, value)) { return true; } } return false; } } internal static class PlanetwideGeneratorSupplyLog { private const string Tag = "[PlanetwideGeneratorSupply] "; private static ManualLogSource logger; private static ConfigEntry debugGate; public static void Init(ManualLogSource src, ConfigEntry debug) { logger = src; debugGate = debug; } public static bool IsDebugEnabled() { if (debugGate != null) { return debugGate.Value; } return false; } public static void Info(string msg) { if (logger != null && IsDebugEnabled()) { logger.LogInfo((object)("[PlanetwideGeneratorSupply] " + msg)); } } public static void Warn(string msg) { if (logger != null) { logger.LogWarning((object)("[PlanetwideGeneratorSupply] " + msg)); } } public static void Error(string msg) { if (logger != null) { logger.LogError((object)("[PlanetwideGeneratorSupply] " + msg)); } } } [HarmonyPatch(typeof(PowerSystem), "GameTick", new Type[] { typeof(long), typeof(bool), typeof(bool), typeof(int) })] internal static class PowerSystemSupplyPatch { private struct GenScan { public int total; public int belowCap; public int refilled; public int movedItems; public int noStock; public int skippedInserter; public float nearestSupply; } private const int FuelTarget = 10; private const long LogThrottleTicks = 300L; private static long _lastLogTick = long.MinValue; private static bool _fuelNamesResolved; private static int[] _thermalPriorityIds = Array.Empty(); private static HashSet _proliferatorIds = new HashSet(); private const string ProliferatorItemNames = "Proliferator Mk.I,Proliferator Mk.II,Proliferator Mk.III"; [ThreadStatic] private static bool[] _servicedByInserter; private static void Postfix(PowerSystem __instance, long time, bool isActive, bool multithreaded, int threadOrdinal) { try { if (!Plugin.Enabled.Value || __instance == null) { return; } if (!_fuelNamesResolved) { ResolveConfiguredFuel(); } int num = Plugin.RefillIntervalTicks.Value; if (num < 1) { num = 1; } if (time % num != 0L) { return; } PlanetFactory factory = __instance.factory; if (factory == null) { return; } GenScan genScan = RefillGenerators(__instance, factory, Plugin.SupplyRadius.Value); if (!isActive || !PlanetwideGeneratorSupplyLog.IsDebugEnabled()) { return; } bool value = Plugin.VerboseScan.Value; bool flag = genScan.movedItems > 0 || genScan.noStock > 0 || genScan.skippedInserter > 0; if (!(value || flag) || time - _lastLogTick < 300) { return; } _lastLogTick = time; string text = "[supply] planet=" + factory.planetId + " gens{" + (value ? ("total=" + genScan.total + " belowCap=" + genScan.belowCap + " ") : "") + "refilled=" + genScan.refilled + " items=" + genScan.movedItems + ((genScan.noStock > 0) ? (" noStock=" + genScan.noStock) : "") + ((genScan.skippedInserter > 0) ? (" skippedInserter=" + genScan.skippedInserter) : "") + "}"; if (value) { float value2 = Plugin.SupplyRadius.Value; text = text + " radius=" + ((value2 <= 0f) ? "planetwide" : value2.ToString("0")); if (genScan.belowCap > 0) { text = text + " nearestStation=" + ((genScan.nearestSupply < 0f) ? "none-on-planet" : genScan.nearestSupply.ToString("0")); } } PlanetwideGeneratorSupplyLog.Info(text); } catch (Exception ex) { PlanetwideGeneratorSupplyLog.Error("[patch] PowerSystem.GameTick postfix threw: " + ex); } } private static void ResolveConfiguredFuel() { _thermalPriorityIds = GeneratorSourcing.ResolveItemNamesByCsv(Plugin.ThermalFuelPriority.Value); _proliferatorIds = new HashSet(GeneratorSourcing.ResolveItemNamesByCsv("Proliferator Mk.I,Proliferator Mk.II,Proliferator Mk.III")); _fuelNamesResolved = true; if (_thermalPriorityIds.Length != 0) { string text = ""; for (int i = 0; i < _thermalPriorityIds.Length; i++) { text = text + ((i > 0) ? ", " : "") + _thermalPriorityIds[i]; } PlanetwideGeneratorSupplyLog.Info("[fuel] resolved ThermalFuelPriority -> " + text); } } private static GenScan RefillGenerators(PowerSystem power, PlanetFactory factory, float radius) { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) GenScan result = default(GenScan); PowerGeneratorComponent[] genPool = power.genPool; if (genPool == null) { return result; } bool value = Plugin.SkipInserterFedGenerators.Value; if (value) { BuildInserterIndex(factory); } int genCursor = power.genCursor; EntityData[] entityPool = factory.entityPool; bool flag = Plugin.VerboseScan.Value && PlanetwideGeneratorSupplyLog.IsDebugEnabled(); bool flag2 = false; result.nearestSupply = -1f; for (int i = 1; i < genCursor; i++) { if (genPool[i].id != i || !IsFuelBurner(genPool[i]) || !IsEnabledForMask(genPool[i].fuelMask)) { continue; } result.total++; if (genPool[i].fuelCount >= 10) { continue; } int entityId = genPool[i].entityId; if (value && _servicedByInserter != null && entityId > 0 && entityId < _servicedByInserter.Length && _servicedByInserter[entityId]) { result.skippedInserter++; continue; } result.belowCap++; Vector3 pos = Vector3.zero; if (entityPool != null && entityId > 0 && entityId < entityPool.Length) { pos = entityPool[entityId].pos; } if (flag && !flag2) { result.nearestSupply = GeneratorSourcing.NearestFuelStationDistance(factory, genPool[i].fuelMask, genPool[i].fuelId, pos); flag2 = true; } int num = genPool[i].fuelId; if (num == 0) { if (genPool[i].fuelMask == 1 && _thermalPriorityIds.Length != 0) { num = GeneratorSourcing.FindPriorityFuel(factory, _thermalPriorityIds, pos, radius); } if (num == 0) { HashSet exclude = ((genPool[i].fuelMask == 1 && Plugin.ExcludeProliferatorFuel.Value) ? _proliferatorIds : null); num = GeneratorSourcing.FindAvailableFuel(factory, genPool[i].fuelMask, pos, radius, exclude); } if (num == 0) { result.noStock++; continue; } } int want = 10 - genPool[i].fuelCount; int incMoved; int num2 = GeneratorSourcing.TryPullFromPlanet(factory, num, want, pos, radius, out incMoved); if (num2 <= 0) { result.noStock++; continue; } if (genPool[i].fuelId == 0) { ((PowerGeneratorComponent)(ref genPool[i])).SetNewFuel(num, (short)num2, (short)incMoved); } else { genPool[i].fuelCount += (short)num2; genPool[i].fuelInc += (short)incMoved; } result.refilled++; result.movedItems += num2; } return result; } private static void BuildInserterIndex(PlanetFactory factory) { int num = ((factory.entityPool != null) ? factory.entityPool.Length : 0); if (_servicedByInserter == null || _servicedByInserter.Length < num) { _servicedByInserter = new bool[num]; } else { Array.Clear(_servicedByInserter, 0, _servicedByInserter.Length); } FactorySystem factorySystem = factory.factorySystem; if (factorySystem == null || factorySystem.inserterPool == null) { return; } InserterComponent[] inserterPool = factorySystem.inserterPool; int inserterCursor = factorySystem.inserterCursor; for (int i = 1; i < inserterCursor; i++) { if (inserterPool[i].id == i) { int insertTarget = inserterPool[i].insertTarget; if (insertTarget > 0 && insertTarget < _servicedByInserter.Length) { _servicedByInserter[insertTarget] = true; } } } } private static bool IsFuelBurner(PowerGeneratorComponent gen) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (gen.fuelMask > 0 && !gen.photovoltaic && !gen.wind && !gen.gamma) { return !gen.geothermal; } return false; } private static bool IsEnabledForMask(short fuelMask) { return fuelMask switch { 1 => Plugin.SupplyThermal.Value, 2 => Plugin.SupplyFusion.Value, 4 => Plugin.SupplyArtificialStar.Value, _ => false, }; } } [BepInPlugin("com.zicarius.PlanetwideGeneratorSupply", "PlanetwideGeneratorSupply", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.zicarius.PlanetwideGeneratorSupply"; public const string PluginName = "PlanetwideGeneratorSupply"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry Enabled; internal static ConfigEntry SupplyThermal; internal static ConfigEntry SupplyFusion; internal static ConfigEntry SupplyArtificialStar; internal static ConfigEntry PreferHighestFuelTier; internal static ConfigEntry SupplyRadius; internal static ConfigEntry NearestStationFirst; internal static ConfigEntry RefillIntervalTicks; internal static ConfigEntry RequireStationSupplyFlag; internal static ConfigEntry VerboseScan; internal static ConfigEntry ThermalFuelPriority; internal static ConfigEntry ExcludeProliferatorFuel; internal static ConfigEntry SkipInserterFedGenerators; internal static ConfigEntry DebugLog; private Harmony harmony; private void Awake() { //IL_0372: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Expected O, but got Unknown DebugLog = ((BaseUnityPlugin)this).Config.Bind("Diagnostics", "DebugLog", false, "Enable verbose diagnostic logging to the BepInEx console."); Enabled = ((BaseUnityPlugin)this).Config.Bind("General", "Enabled", true, "Master switch. If false the mod is fully inert."); SupplyThermal = ((BaseUnityPlugin)this).Config.Bind("General", "SupplyThermal", true, "Auto-refill thermal power plants (chemical fuels)."); SupplyFusion = ((BaseUnityPlugin)this).Config.Bind("General", "SupplyFusion", true, "Auto-refill mini fusion power plants (deuterium fuel rods)."); SupplyArtificialStar = ((BaseUnityPlugin)this).Config.Bind("General", "SupplyArtificialStar", true, "Auto-refill artificial stars (antimatter fuel rods)."); PreferHighestFuelTier = ((BaseUnityPlugin)this).Config.Bind("General", "PreferHighestFuelTier", true, "When a generator's fuel chamber is empty, pick the highest available fuel tier (true) or the lowest/cheapest (false). A generator that already holds fuel keeps that item."); SupplyRadius = ((BaseUnityPlugin)this).Config.Bind("General", "SupplyRadius", 0f, "Max straight-line distance from a generator to an eligible station. 0 = planetwide."); NearestStationFirst = ((BaseUnityPlugin)this).Config.Bind("General", "NearestStationFirst", true, "Pull from the closest eligible station first (true) instead of station build order (false)."); RefillIntervalTicks = ((BaseUnityPlugin)this).Config.Bind("General", "RefillIntervalTicks", 60, "Game ticks between refill scans. ~60 = 1s."); RequireStationSupplyFlag = ((BaseUnityPlugin)this).Config.Bind("Advanced", "RequireStationSupplyFlag", false, "If true, only pull from station slots set to Supply."); VerboseScan = ((BaseUnityPlugin)this).Config.Bind("Advanced", "VerboseScan", false, "Debug aid (needs DebugLog on): periodic scan heartbeat even when nothing moved."); ThermalFuelPriority = ((BaseUnityPlugin)this).Config.Bind("Advanced", "ThermalFuelPriority", "", "Comma-separated item names exactly as shown in-game (e.g. \"Graphite, Coal, Wood\" - your game's current language), tried in order for Thermal Power Plants only. Falls back to the highest available tier when empty or when none of these have stock."); ExcludeProliferatorFuel = ((BaseUnityPlugin)this).Config.Bind("Advanced", "ExcludeProliferatorFuel", true, "If true, never burn Proliferator Mk.I/II/III as Thermal Power Plant fuel, whether via ThermalFuelPriority or the fallback search."); SkipInserterFedGenerators = ((BaseUnityPlugin)this).Config.Bind("Advanced", "SkipInserterFedGenerators", true, "If true, never auto-refill a generator that already has a sorter/inserter delivering fuel to it - only top up generators with no inserter connection at all."); PlanetwideGeneratorSupplyLog.Init(((BaseUnityPlugin)this).Logger, DebugLog); PlanetwideGeneratorSupplyLog.Info("[config] Enabled=" + Enabled.Value + " SupplyThermal=" + SupplyThermal.Value + " SupplyFusion=" + SupplyFusion.Value + " SupplyArtificialStar=" + SupplyArtificialStar.Value + " SupplyRadius=" + SupplyRadius.Value + " RefillIntervalTicks=" + RefillIntervalTicks.Value + " PreferHighestFuelTier=" + PreferHighestFuelTier.Value + " NearestStationFirst=" + NearestStationFirst.Value + " RequireStationSupplyFlag=" + RequireStationSupplyFlag.Value + " VerboseScan=" + VerboseScan.Value + " ThermalFuelPriority=" + ThermalFuelPriority.Value + " ExcludeProliferatorFuel=" + ExcludeProliferatorFuel.Value + " SkipInserterFedGenerators=" + SkipInserterFedGenerators.Value); harmony = new Harmony("com.zicarius.PlanetwideGeneratorSupply"); try { harmony.PatchAll(); PlanetwideGeneratorSupplyLog.Info("[patch] PatchAll complete."); } catch (Exception ex) { PlanetwideGeneratorSupplyLog.Error("[patch] PatchAll failed: " + ex); } if (DebugLog.Value) { DumpTargetMethodSignatures(); } PlanetwideGeneratorSupplyLog.Info("PlanetwideGeneratorSupply 1.0.0 loaded."); } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); harmony = null; } PlanetwideGeneratorSupplyLog.Info("PlanetwideGeneratorSupply unloaded."); } private static void DumpTargetMethodSignatures() { string[][] array = new string[1][] { new string[2] { "PowerSystem", "GameTick" } }; foreach (string[] array2 in array) { try { Type type = AccessTools.TypeByName(array2[0]); if (type == null) { PlanetwideGeneratorSupplyLog.Warn("[diag] Type not found: " + array2[0]); continue; } MethodInfo methodInfo = AccessTools.Method(type, array2[1], new Type[4] { typeof(long), typeof(bool), typeof(bool), typeof(int) }, (Type[])null); if (methodInfo == null) { PlanetwideGeneratorSupplyLog.Warn("[diag] Method not found: " + array2[0] + "." + array2[1]); continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.Append("[diag] ").Append(array2[0]).Append('.') .Append(array2[1]) .Append('('); for (int j = 0; j < parameters.Length; j++) { if (j > 0) { stringBuilder.Append(", "); } stringBuilder.Append(parameters[j].ParameterType.Name).Append(' ').Append(parameters[j].Name); } stringBuilder.Append(')'); PlanetwideGeneratorSupplyLog.Info(stringBuilder.ToString()); } catch (Exception ex) { PlanetwideGeneratorSupplyLog.Error("[diag] Failed to inspect " + array2[0] + "." + array2[1] + ": " + ex.Message); } } array = new string[5][] { new string[2] { "PowerSystem", "genPool" }, new string[2] { "PowerSystem", "genCursor" }, new string[2] { "PowerSystem", "factory" }, new string[2] { "PlanetFactory", "transport" }, new string[2] { "PlanetTransport", "stationPool" } }; foreach (string[] array3 in array) { try { Type type2 = AccessTools.TypeByName(array3[0]); if (type2 == null) { PlanetwideGeneratorSupplyLog.Warn("[diag] Type not found: " + array3[0]); continue; } FieldInfo fieldInfo = AccessTools.Field(type2, array3[1]); if (fieldInfo == null) { PlanetwideGeneratorSupplyLog.Warn("[diag] Field not found: " + array3[0] + "." + array3[1]); continue; } PlanetwideGeneratorSupplyLog.Info("[diag] field " + array3[0] + "." + array3[1] + " : " + fieldInfo.FieldType.Name); } catch (Exception ex2) { PlanetwideGeneratorSupplyLog.Error("[diag] Failed to inspect field " + array3[0] + "." + array3[1] + ": " + ex2.Message); } } } }