Decompiled source of PlanetwideGeneratorSupply v1.0.0

plugins\PlanetwideGeneratorSupply.dll

Decompiled 6 hours 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.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<StationDist> _scratch;

	private static readonly Comparison<StationDist> _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<StationDist>(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<int> 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<int>();
		}
		string[] array = csv.Split(',');
		List<int> list = new List<int>(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<ItemProto>)(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<bool> debugGate;

	public static void Init(ManualLogSource src, ConfigEntry<bool> 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<int>();

	private static HashSet<int> _proliferatorIds = new HashSet<int>();

	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<int>(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<int> 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<bool> Enabled;

	internal static ConfigEntry<bool> SupplyThermal;

	internal static ConfigEntry<bool> SupplyFusion;

	internal static ConfigEntry<bool> SupplyArtificialStar;

	internal static ConfigEntry<bool> PreferHighestFuelTier;

	internal static ConfigEntry<float> SupplyRadius;

	internal static ConfigEntry<bool> NearestStationFirst;

	internal static ConfigEntry<int> RefillIntervalTicks;

	internal static ConfigEntry<bool> RequireStationSupplyFlag;

	internal static ConfigEntry<bool> VerboseScan;

	internal static ConfigEntry<string> ThermalFuelPriority;

	internal static ConfigEntry<bool> ExcludeProliferatorFuel;

	internal static ConfigEntry<bool> SkipInserterFedGenerators;

	internal static ConfigEntry<bool> 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<bool>("Diagnostics", "DebugLog", false, "Enable verbose diagnostic logging to the BepInEx console.");
		Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Master switch. If false the mod is fully inert.");
		SupplyThermal = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SupplyThermal", true, "Auto-refill thermal power plants (chemical fuels).");
		SupplyFusion = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SupplyFusion", true, "Auto-refill mini fusion power plants (deuterium fuel rods).");
		SupplyArtificialStar = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SupplyArtificialStar", true, "Auto-refill artificial stars (antimatter fuel rods).");
		PreferHighestFuelTier = ((BaseUnityPlugin)this).Config.Bind<bool>("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<float>("General", "SupplyRadius", 0f, "Max straight-line distance from a generator to an eligible station. 0 = planetwide.");
		NearestStationFirst = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "NearestStationFirst", true, "Pull from the closest eligible station first (true) instead of station build order (false).");
		RefillIntervalTicks = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RefillIntervalTicks", 60, "Game ticks between refill scans. ~60 = 1s.");
		RequireStationSupplyFlag = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "RequireStationSupplyFlag", false, "If true, only pull from station slots set to Supply.");
		VerboseScan = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "VerboseScan", false, "Debug aid (needs DebugLog on): periodic scan heartbeat even when nothing moved.");
		ThermalFuelPriority = ((BaseUnityPlugin)this).Config.Bind<string>("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<bool>("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<bool>("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);
			}
		}
	}
}