Decompiled source of PlanetwideAmmoSupply v1.0.0

plugins\PlanetwideAmmoSupply.dll

Decompiled a day 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("PlanetwideAmmoSupply")]
[assembly: AssemblyDescription("Dyson Sphere Program BepInEx mod.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("PlanetwideAmmoSupply")]
[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 PlanetwideAmmoSupply;

internal static class AmmoSourcing
{
	private struct StationDist
	{
		public int index;

		public float distSqr;
	}

	private static readonly List<StationDist> _scratch = new List<StationDist>(64);

	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_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01da: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e0: 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)
		{
			_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;
	}

	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;
		}
	}

	internal static int FindAvailableAmmo(PlanetFactory factory, EAmmoType ammoType, Vector3 pos, float radius)
	{
		//IL_0000: Unknown result type (might be due to invalid IL or missing references)
		//IL_0002: Expected I4, but got Unknown
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0044: Unknown result type (might be due to invalid IL or missing references)
		int num = (int)ammoType;
		if (num <= 0 || ItemProto.turretNeeds == null || num >= ItemProto.turretNeeds.Length)
		{
			return 0;
		}
		int[] array = ItemProto.turretNeeds[num];
		if (array == null)
		{
			return 0;
		}
		if (Plugin.PreferHighestAmmoTier.Value)
		{
			for (int num2 = array.Length - 1; num2 >= 0; num2--)
			{
				int num3 = array[num2];
				if (num3 > 0 && HasStock(factory, num3, pos, radius))
				{
					return num3;
				}
			}
		}
		else
		{
			foreach (int num4 in array)
			{
				if (num4 > 0 && HasStock(factory, num4, pos, radius))
				{
					return num4;
				}
			}
		}
		return 0;
	}

	internal static float NearestAmmoStationDistance(PlanetFactory factory, int itemId, EAmmoType ammoType, Vector3 pos)
	{
		//IL_003e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected I4, but got Unknown
		//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)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_0119: 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)
		{
			int num = (int)ammoType;
			if (num > 0 && ItemProto.turretNeeds != null && num < ItemProto.turretNeeds.Length)
			{
				array = ItemProto.turretNeeds[num];
			}
		}
		float num2 = -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 num3 = 0f;
			if (entityPool != null)
			{
				int entityId = val2.entityId;
				if (entityId > 0 && entityId < entityPool.Length)
				{
					Vector3 val3 = entityPool[entityId].pos - pos;
					num3 = ((Vector3)(ref val3)).sqrMagnitude;
				}
			}
			if (num2 < 0f || num3 < num2)
			{
				num2 = num3;
			}
		}
		if (!(num2 < 0f))
		{
			return Mathf.Sqrt(num2);
		}
		return -1f;
	}

	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 PlanetwideAmmoSupplyLog
{
	private const string Tag = "[PlanetwideAmmoSupply] ";

	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)("[PlanetwideAmmoSupply] " + msg));
		}
	}

	public static void Warn(string msg)
	{
		if (logger != null)
		{
			logger.LogWarning((object)("[PlanetwideAmmoSupply] " + msg));
		}
	}

	public static void Error(string msg)
	{
		if (logger != null)
		{
			logger.LogError((object)("[PlanetwideAmmoSupply] " + msg));
		}
	}
}
[HarmonyPatch(typeof(DefenseSystem), "GameTick", new Type[]
{
	typeof(long),
	typeof(bool)
})]
internal static class DefenseSystemSupplyPatch
{
	private struct TurretScan
	{
		public int total;

		public int belowCap;

		public int refilled;

		public int movedItems;

		public int noStock;

		public float nearestSupply;
	}

	private struct BattleScan
	{
		public int bases;

		public int slotsRefilled;

		public int movedItems;
	}

	private const int TurretAmmoTarget = 5;

	private const long LogThrottleTicks = 300L;

	private static long _lastLogTick = long.MinValue;

	private static void Postfix(DefenseSystem __instance, long tick, bool isActive)
	{
		try
		{
			if (!Plugin.Enabled.Value || __instance == null)
			{
				return;
			}
			int num = Plugin.RefillIntervalTicks.Value;
			if (num < 1)
			{
				num = 1;
			}
			if (tick % num != 0L)
			{
				return;
			}
			PlanetFactory factory = __instance.factory;
			if (factory == null)
			{
				return;
			}
			float value = Plugin.SupplyRadius.Value;
			TurretScan turretScan = default(TurretScan);
			BattleScan battleScan = default(BattleScan);
			if (Plugin.SupplyTurrets.Value)
			{
				turretScan = RefillTurrets(__instance, factory, value);
			}
			if (Plugin.SupplyBattleBases.Value)
			{
				battleScan = RefillBattleBases(__instance, factory, value);
			}
			if (!isActive || !PlanetwideAmmoSupplyLog.IsDebugEnabled())
			{
				return;
			}
			bool value2 = Plugin.VerboseScan.Value;
			bool flag = turretScan.movedItems > 0 || battleScan.movedItems > 0 || turretScan.noStock > 0;
			if (!(value2 || flag) || tick - _lastLogTick < 300)
			{
				return;
			}
			_lastLogTick = tick;
			string text = "[supply] planet=" + factory.planetId + " turrets{" + (value2 ? ("total=" + turretScan.total + " belowCap=" + turretScan.belowCap + " ") : "") + "refilled=" + turretScan.refilled + " items=" + turretScan.movedItems + ((turretScan.noStock > 0) ? (" noStock=" + turretScan.noStock) : "") + "}";
			if (value2)
			{
				text = text + " radius=" + ((value <= 0f) ? "planetwide" : value.ToString("0"));
				if (turretScan.belowCap > 0)
				{
					text = text + " nearestStation=" + ((turretScan.nearestSupply < 0f) ? "none-on-planet" : turretScan.nearestSupply.ToString("0"));
				}
			}
			if (value2 || battleScan.movedItems > 0)
			{
				text = text + " battlebase{" + (value2 ? ("bases=" + battleScan.bases + " ") : "") + "items=" + battleScan.movedItems + "}";
			}
			PlanetwideAmmoSupplyLog.Info(text);
		}
		catch (Exception ex)
		{
			PlanetwideAmmoSupplyLog.Error("[patch] DefenseSystem.GameTick postfix threw: " + ex);
		}
	}

	private static TurretScan RefillTurrets(DefenseSystem def, PlanetFactory factory, float radius)
	{
		//IL_009e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
		TurretScan result = default(TurretScan);
		DataPool<TurretComponent> turrets = def.turrets;
		if (turrets == null || turrets.buffer == null)
		{
			return result;
		}
		TurretComponent[] buffer = turrets.buffer;
		int cursor = turrets.cursor;
		EntityData[] entityPool = factory.entityPool;
		bool flag = Plugin.VerboseScan.Value && PlanetwideAmmoSupplyLog.IsDebugEnabled();
		bool flag2 = false;
		result.nearestSupply = -1f;
		for (int i = 1; i < cursor; i++)
		{
			if (buffer[i].id != i)
			{
				continue;
			}
			result.total++;
			if (buffer[i].itemCount >= 5)
			{
				continue;
			}
			result.belowCap++;
			Vector3 pos = Vector3.zero;
			int entityId = buffer[i].entityId;
			if (entityPool != null && entityId > 0 && entityId < entityPool.Length)
			{
				pos = entityPool[entityId].pos;
			}
			if (flag && !flag2)
			{
				result.nearestSupply = AmmoSourcing.NearestAmmoStationDistance(factory, buffer[i].itemId, buffer[i].ammoType, pos);
				flag2 = true;
			}
			int num = buffer[i].itemId;
			if (num == 0)
			{
				num = AmmoSourcing.FindAvailableAmmo(factory, buffer[i].ammoType, pos, radius);
				if (num == 0)
				{
					result.noStock++;
					continue;
				}
			}
			int want = 5 - buffer[i].itemCount;
			int incMoved;
			int num2 = AmmoSourcing.TryPullFromPlanet(factory, num, want, pos, radius, out incMoved);
			if (num2 <= 0)
			{
				result.noStock++;
				continue;
			}
			if (buffer[i].itemId == 0)
			{
				((TurretComponent)(ref buffer[i])).SetNewItem(num, (short)num2, (short)incMoved);
			}
			else
			{
				buffer[i].itemCount += (short)num2;
				buffer[i].itemInc += (short)incMoved;
			}
			result.refilled++;
			result.movedItems += num2;
		}
		return result;
	}

	private static BattleScan RefillBattleBases(DefenseSystem def, PlanetFactory factory, float radius)
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		BattleScan result = default(BattleScan);
		ObjectPool<BattleBaseComponent> battleBases = def.battleBases;
		if (battleBases == null || battleBases.buffer == null)
		{
			return result;
		}
		BattleBaseComponent[] buffer = battleBases.buffer;
		int cursor = battleBases.cursor;
		EntityData[] entityPool = factory.entityPool;
		string value = Plugin.FighterItemFilter.Value;
		bool flag = !string.IsNullOrEmpty(value);
		int num3 = default(int);
		for (int i = 1; i < cursor; i++)
		{
			BattleBaseComponent val = buffer[i];
			if (val == null || val.id != i)
			{
				continue;
			}
			StorageComponent storage = val.storage;
			if (storage == null || storage.grids == null)
			{
				continue;
			}
			result.bases++;
			Vector3 pos = Vector3.zero;
			int entityId = val.entityId;
			if (entityPool != null && entityId > 0 && entityId < entityPool.Length)
			{
				pos = entityPool[entityId].pos;
			}
			GRID[] grids = storage.grids;
			for (int j = 0; j < grids.Length; j++)
			{
				int itemId = grids[j].itemId;
				if (itemId <= 0)
				{
					continue;
				}
				int stackSize = grids[j].stackSize;
				if (stackSize > 0 && grids[j].count < stackSize && (!flag || value.IndexOf(itemId.ToString(), StringComparison.Ordinal) >= 0))
				{
					int want = stackSize - grids[j].count;
					int incMoved;
					int num = AmmoSourcing.TryPullFromPlanet(factory, itemId, want, pos, radius, out incMoved);
					if (num > 0)
					{
						int num2 = storage.AddItem(itemId, num, incMoved, ref num3, false);
						result.slotsRefilled++;
						result.movedItems += num2;
					}
				}
			}
		}
		return result;
	}
}
[BepInPlugin("com.zicarius.PlanetwideAmmoSupply", "PlanetwideAmmoSupply", "1.0.0")]
public sealed class Plugin : BaseUnityPlugin
{
	public const string PluginGuid = "com.zicarius.PlanetwideAmmoSupply";

	public const string PluginName = "PlanetwideAmmoSupply";

	public const string PluginVersion = "1.0.0";

	internal static ConfigEntry<bool> Enabled;

	internal static ConfigEntry<bool> SupplyTurrets;

	internal static ConfigEntry<bool> SupplyBattleBases;

	internal static ConfigEntry<bool> PreferHighestAmmoTier;

	internal static ConfigEntry<float> SupplyRadius;

	internal static ConfigEntry<bool> NearestStationFirst;

	internal static ConfigEntry<int> RefillIntervalTicks;

	internal static ConfigEntry<bool> RequireStationSupplyFlag;

	internal static ConfigEntry<string> FighterItemFilter;

	internal static ConfigEntry<bool> VerboseScan;

	internal static ConfigEntry<bool> DebugLog;

	private Harmony harmony;

	private void Awake()
	{
		//IL_029e: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a8: 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 (vanilla belt supply unchanged).");
		SupplyTurrets = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SupplyTurrets", true, "Auto-refill turret ammo from the planet's logistics stations.");
		SupplyBattleBases = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "SupplyBattleBases", true, "Auto-refill battle-base ammo and fighters from the planet's logistics stations.");
		PreferHighestAmmoTier = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "PreferHighestAmmoTier", true, "When auto-filling an EMPTY turret, pick the highest available ammo tier (true) or the lowest/cheapest (false). A turret that already holds an ammo item keeps that item's tier - this only chooses the first fill.");
		SupplyRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "SupplyRadius", 0f, "Max straight-line distance (metres) from a structure to an eligible station. 0 = planetwide (recommended - matches how PLS/ILS serve a whole planet). Scale: a standard planet is ~200m radius, so distances reach ~400m (opposite side). Rough guide: ~50 = tight cluster, ~150 = large base, ~300 = most of the planet, ~400 = whole standard planet. Small values like 10 are basically 'touching' and will match nothing.");
		NearestStationFirst = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "NearestStationFirst", true, "Pull from the closest eligible station first (true) instead of station build order (false). Pairs naturally with SupplyRadius.");
		RefillIntervalTicks = ((BaseUnityPlugin)this).Config.Bind<int>("General", "RefillIntervalTicks", 60, "Game ticks between refill scans (throttle). ~60 = 1s. Higher = cheaper, lower = more responsive.");
		RequireStationSupplyFlag = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "RequireStationSupplyFlag", false, "If true, only pull from station slots set to 'Supply' (never 'Demand'/'Storage'). False = pull from any slot holding the ammo.");
		FighterItemFilter = ((BaseUnityPlugin)this).Config.Bind<string>("Advanced", "FighterItemFilter", "", "Optional: restrict which fighter/ammo items battle bases pull (empty = everything the base already accepts).");
		VerboseScan = ((BaseUnityPlugin)this).Config.Bind<bool>("Advanced", "VerboseScan", false, "Debug aid (needs DebugLog on): log a periodic scan heartbeat on the active planet (~1 per 5s) showing total/belowCap/refilled/noStock even when nothing moved - so you can see it working and why. Off = only log when ammo actually moves.");
		PlanetwideAmmoSupplyLog.Init(((BaseUnityPlugin)this).Logger, DebugLog);
		PlanetwideAmmoSupplyLog.Info("[config] Enabled=" + Enabled.Value + " SupplyTurrets=" + SupplyTurrets.Value + " SupplyBattleBases=" + SupplyBattleBases.Value + " SupplyRadius=" + SupplyRadius.Value + " RefillIntervalTicks=" + RefillIntervalTicks.Value + " RequireStationSupplyFlag=" + RequireStationSupplyFlag.Value + " PreferHighestAmmoTier=" + PreferHighestAmmoTier.Value + " NearestStationFirst=" + NearestStationFirst.Value + " VerboseScan=" + VerboseScan.Value);
		harmony = new Harmony("com.zicarius.PlanetwideAmmoSupply");
		try
		{
			harmony.PatchAll();
			PlanetwideAmmoSupplyLog.Info("[patch] PatchAll complete.");
		}
		catch (Exception ex)
		{
			PlanetwideAmmoSupplyLog.Error("[patch] PatchAll failed: " + ex);
		}
		if (DebugLog.Value)
		{
			DumpTargetMethodSignatures();
		}
		PlanetwideAmmoSupplyLog.Info("PlanetwideAmmoSupply 1.0.0 loaded.");
	}

	private void Start()
	{
	}

	private void OnDestroy()
	{
		if (harmony != null)
		{
			harmony.UnpatchSelf();
			harmony = null;
		}
		PlanetwideAmmoSupplyLog.Info("PlanetwideAmmoSupply unloaded.");
	}

	private static void DumpTargetMethodSignatures()
	{
		string[][] array = new string[2][]
		{
			new string[2] { "DefenseSystem", "GameTick" },
			new string[2] { "StorageComponent", "AddItem" }
		};
		foreach (string[] array2 in array)
		{
			try
			{
				Type type = AccessTools.TypeByName(array2[0]);
				if (type == null)
				{
					PlanetwideAmmoSupplyLog.Warn("[diag] Type not found: " + array2[0]);
					continue;
				}
				MethodInfo methodInfo = ((array2[0] == "StorageComponent" && array2[1] == "AddItem") ? AccessTools.Method(type, array2[1], new Type[5]
				{
					typeof(int),
					typeof(int),
					typeof(int),
					typeof(int).MakeByRefType(),
					typeof(bool)
				}, (Type[])null) : AccessTools.Method(type, array2[1], (Type[])null, (Type[])null));
				if (methodInfo == null)
				{
					PlanetwideAmmoSupplyLog.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(')');
				PlanetwideAmmoSupplyLog.Info(stringBuilder.ToString());
			}
			catch (Exception ex)
			{
				PlanetwideAmmoSupplyLog.Error("[diag] Failed to inspect " + array2[0] + "." + array2[1] + ": " + ex.Message);
			}
		}
		array = new string[6][]
		{
			new string[2] { "DefenseSystem", "turrets" },
			new string[2] { "DefenseSystem", "battleBases" },
			new string[2] { "BattleBaseComponent", "storage" },
			new string[2] { "PlanetFactory", "transport" },
			new string[2] { "PlanetTransport", "stationPool" },
			new string[2] { "StationComponent", "storage" }
		};
		foreach (string[] array3 in array)
		{
			try
			{
				Type type2 = AccessTools.TypeByName(array3[0]);
				if (type2 == null)
				{
					PlanetwideAmmoSupplyLog.Warn("[diag] Type not found: " + array3[0]);
					continue;
				}
				FieldInfo fieldInfo = AccessTools.Field(type2, array3[1]);
				if (fieldInfo == null)
				{
					PlanetwideAmmoSupplyLog.Warn("[diag] Field not found: " + array3[0] + "." + array3[1]);
					continue;
				}
				PlanetwideAmmoSupplyLog.Info("[diag] field " + array3[0] + "." + array3[1] + " : " + fieldInfo.FieldType.Name);
			}
			catch (Exception ex2)
			{
				PlanetwideAmmoSupplyLog.Error("[diag] Failed to inspect field " + array3[0] + "." + array3[1] + ": " + ex2.Message);
			}
		}
	}
}