Decompiled source of DSPMultiDistributorFork v0.0.5

BepInEx/plugins/DSPMultiDistributor.dll

Decompiled 2 months ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("DSPMultiDistributor")]
[assembly: AssemblyDescription("A distributor can now transport with multiple distributors.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Appun")]
[assembly: AssemblyProduct("DSPMultiDistributor")]
[assembly: AssemblyCopyright("Copyright © Appun")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("81df3045-8007-4f6a-aaf6-903139d85b6c")]
[assembly: AssemblyFileVersion("0.0.5.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.5.0")]
[module: UnverifiableCode]
namespace DSPMultiDistributor;

[BepInPlugin("Appun.DSP.plugin.MultiDistributor", "DSPMultiDistributor", "0.0.5")]
[HarmonyPatch]
public class Main : BaseUnityPlugin
{
	public class LogManager
	{
		public static ManualLogSource Logger;

		public static bool DebugEnabled;

		public static void LogDebug(string message)
		{
			if (DebugEnabled && Logger != null)
			{
				Logger.LogInfo((object)("[DSPMultiDistributor] " + message));
			}
		}

		public static void LogWarning(string message)
		{
			if (Logger != null)
			{
				Logger.LogWarning((object)("[DSPMultiDistributor] " + message));
			}
		}

		public static void LogError(string message)
		{
			if (Logger != null)
			{
				Logger.LogError((object)("[DSPMultiDistributor] " + message));
			}
		}
	}

	public void Awake()
	{
		LogManager.Logger = ((BaseUnityPlugin)this).Logger;
		LogManager.DebugEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "EnableDebugLogging", false, "Enable verbose debug logging to the BepInEx log. Off by default.").Value;
		LogManager.LogDebug("DSPMultiDistributor loaded, applying Harmony patches...");
		try
		{
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			LogManager.LogDebug("Harmony patches applied successfully.");
		}
		catch (Exception ex)
		{
			LogManager.LogError("Failed to apply Harmony patches: " + ex);
			throw;
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(UIDispenserWindow), "_OnClose")]
	public static void UIDispenserWindow_OnClose_Prefix2(UIDispenserWindow __instance)
	{
		LogManager.LogDebug("UIDispenserWindow closed -> calling RefreshDispenserTraffic()");
		GameMain.data.localLoadedPlanetFactory.transport.RefreshDispenserTraffic(0);
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(PlanetTransport), "RefreshDispenserTraffic")]
	public static void PlanetTransport_RefreshDispenserTraffic_Postfix(PlanetTransport __instance, int keyId)
	{
		//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cf: Invalid comparison between Unknown and I4
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02af: Invalid comparison between Unknown and I4
		//IL_0195: Unknown result type (might be due to invalid IL or missing references)
		//IL_019b: Invalid comparison between Unknown and I4
		//IL_0331: Unknown result type (might be due to invalid IL or missing references)
		//IL_0337: Invalid comparison between Unknown and I4
		LogManager.LogDebug("=== RefreshDispenserTraffic postfix: dispenserCursor=" + __instance.dispenserCursor + " keyId=" + keyId);
		for (int i = 1; i < __instance.dispenserCursor; i++)
		{
			try
			{
				DispenserComponent val = __instance.dispenserPool[i];
				if (val == null || val.storage == null || val.id != i || val.filter != 0)
				{
					continue;
				}
				LogManager.LogDebug("  filterless dispenser " + i + " mode=" + ((object)Unsafe.As<EStorageDeliveryMode, EStorageDeliveryMode>(ref val.storageMode)/*cast due to .constrained prefix*/).ToString() + " storageSize=" + val.storage.size);
				if ((int)val.storageMode == 1)
				{
					for (int j = 0; j < val.storage.size; j++)
					{
						int itemId = val.storage.grids[j].itemId;
						if (itemId <= 0)
						{
							continue;
						}
						LogManager.LogDebug("    [SUPPLY] slot " + j + " contains item " + itemId + " (gridFilter=" + val.storage.grids[j].filter + ")");
						for (int k = 1; k < __instance.dispenserCursor; k++)
						{
							DispenserComponent val2 = __instance.dispenserPool[k];
							if (val2 != null && val2.id == k && (int)val2.storageMode == 2)
							{
								bool flag = val2.filter == itemId || DispenserRequestsItem(val2, itemId);
								LogManager.LogDebug("      check demand " + k + " filter=" + val2.filter + " wants " + itemId + " -> " + flag);
								if (flag)
								{
									val.AddPair(i, 0, k, 0);
									val2.AddPair(i, 0, k, 0);
									LogManager.LogDebug("      [SUPPLY] PAIRED supply " + i + " -> demand " + k);
								}
							}
						}
					}
				}
				else if ((int)val.storageMode == 2)
				{
					for (int l = 0; l < val.storage.size; l++)
					{
						int filter = val.storage.grids[l].filter;
						if (filter <= 0)
						{
							continue;
						}
						LogManager.LogDebug("    [DEMAND] slot " + l + " requests item " + filter);
						for (int m = 1; m < __instance.dispenserCursor; m++)
						{
							DispenserComponent val3 = __instance.dispenserPool[m];
							if (val3 != null && val3.id == m && (int)val3.storageMode == 1 && val3.filter == filter)
							{
								val.AddPair(m, 0, i, 0);
								val3.AddPair(m, 0, i, 0);
								LogManager.LogDebug("      [DEMAND] PAIRED supply " + m + " -> demand " + i);
							}
						}
					}
				}
				int logisticCourierCarries = GameMain.history.logisticCourierCarries;
				LogManager.LogDebug("  dispenser " + i + " calling OnRematchPairs");
				val.OnRematchPairs(__instance.factory, __instance.dispenserPool, keyId, logisticCourierCarries);
			}
			catch (Exception ex)
			{
				LogManager.LogError("Exception in RefreshDispenserTraffic postfix at dispenser " + i + ": " + ex);
			}
		}
	}

	[HarmonyPrefix]
	[HarmonyPatch(typeof(DispenserComponent), "InternalTick")]
	public static void DispenserComponent_InternalTick_Prefix(DispenserComponent __instance, ref int __state, long time)
	{
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Invalid comparison between Unknown and I4
		//IL_013c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0142: Invalid comparison between Unknown and I4
		__state = 0;
		if (__instance.filter != 0 || __instance.storage == null)
		{
			return;
		}
		if ((int)__instance.storageMode == 1)
		{
			int num = 0;
			for (int i = 0; i < __instance.storage.size; i++)
			{
				if (__instance.storage.grids[i].itemId > 0)
				{
					num++;
				}
			}
			if (num <= 0)
			{
				return;
			}
			int num2 = (int)(time % num);
			int num3 = 0;
			int num4 = -1;
			for (int j = 0; j < __instance.storage.size; j++)
			{
				int itemId = __instance.storage.grids[j].itemId;
				if (itemId > 0)
				{
					if (num3 == num2)
					{
						num4 = itemId;
						break;
					}
					num3++;
				}
			}
			if (num4 > 0)
			{
				__state = num4;
				__instance.filter = num4;
				LogManager.LogDebug("  [DISPATCH] temp filter set on filterless supply dispenser " + __instance.id + " -> item " + num4);
			}
		}
		else
		{
			if ((int)__instance.storageMode != 2)
			{
				return;
			}
			int num5 = 0;
			for (int k = 0; k < __instance.storage.size; k++)
			{
				if (__instance.storage.grids[k].filter > 0)
				{
					num5++;
				}
			}
			if (num5 <= 0)
			{
				return;
			}
			int num6 = (int)(time % num5);
			int num7 = 0;
			int num8 = -1;
			for (int l = 0; l < __instance.storage.size; l++)
			{
				int filter = __instance.storage.grids[l].filter;
				if (filter > 0)
				{
					if (num7 == num6)
					{
						num8 = filter;
						break;
					}
					num7++;
				}
			}
			if (num8 > 0)
			{
				__state = num8;
				__instance.filter = num8;
				LogManager.LogDebug("  [DISPATCH] temp filter set on filterless demand dispenser " + __instance.id + " -> fetch item " + num8);
			}
		}
	}

	[HarmonyPostfix]
	[HarmonyPatch(typeof(DispenserComponent), "InternalTick")]
	public static void DispenserComponent_InternalTick_Postfix(DispenserComponent __instance, int __state)
	{
		if (__state > 0)
		{
			__instance.filter = 0;
		}
	}

	private static bool DispenserRequestsItem(DispenserComponent dispenser, int itemId)
	{
		if (dispenser.storage == null)
		{
			return false;
		}
		for (int i = 0; i < dispenser.storage.size; i++)
		{
			if (dispenser.storage.grids[i].filter == itemId)
			{
				return true;
			}
		}
		return false;
	}
}