Decompiled source of BetterLogisticsStations v1.0.0

BetterLogisticsStation.dll

Decompiled 2 months ago
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using xiaoye97;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("BetterLogisticsStation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BetterLogisticsStation")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("71194e8d-0a80-4719-a0b8-0a6a8390888f")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace sebdalf;

[BepInDependency(/*Could not decode attribute arguments.*/)]
[BepInPlugin("sebdalf.dsp.betterlogisticsstation", "DSP Better Logistics Station", "1.0.0")]
[BepInProcess("DSPGAME.exe")]
public class BetterLogisticsStation : BaseUnityPlugin
{
	private Harmony _harmony;

	internal static ManualLogSource logger;

	private static ConfigEntry<int> PlanetaryLogisticsStationMaxItemKinds;

	private static ConfigEntry<int> PlanetaryLogisticsStationMaxItemCount;

	private static ConfigEntry<int> InterstellarLogisticsStationMaxItemKinds;

	private static ConfigEntry<int> InterstellarLogisticsStationMaxItemCount;

	private void Awake()
	{
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown
		_harmony = new Harmony("sebdalf.dsp.betterlogisticsstation");
		try
		{
			_harmony.PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BetterLogisticsStation: Harmony.PatchAll() done");
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("BetterLogisticsStation: Harmony.PatchAll() FAILED: " + ex));
		}
	}

	private void Start()
	{
		logger = ((BaseUnityPlugin)this).Logger;
		PlanetaryLogisticsStationMaxItemKinds = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PlanetaryLogisticsStationMaxItemKinds", 6, "Number of different items planetary logistics stations can hold, shouldn't be larger than 6");
		PlanetaryLogisticsStationMaxItemCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "PlanetaryLogisticsStationMaxItemCount", 5000, "Capacity the planetary logistics station can hold of one item");
		InterstellarLogisticsStationMaxItemKinds = ((BaseUnityPlugin)this).Config.Bind<int>("General", "InterstellarLogisticsStationMaxItemKinds", 6, "Number of different items interstellar logistics stations can hold, shouldn't be larger than 6");
		InterstellarLogisticsStationMaxItemCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "InterstellarLogisticsStationMaxItemCount", 10000, "Capacity the interstellar logistics station can hold of one item");
		LDBTool.EditDataAction = (Action<Proto>)Delegate.Combine(LDBTool.EditDataAction, new Action<Proto>(Edit));
		logger.LogInfo((object)"BetterLogisticStations loaded!");
	}

	private void Edit(Proto proto)
	{
		if (!(proto is ItemProto))
		{
			return;
		}
		ItemProto val = (ItemProto)(object)((proto is ItemProto) ? proto : null);
		if (val.prefabDesc.isStation)
		{
			if (val.prefabDesc.isStellarStation)
			{
				val.prefabDesc.stationMaxItemKinds = InterstellarLogisticsStationMaxItemKinds.Value;
				val.prefabDesc.stationMaxItemCount = InterstellarLogisticsStationMaxItemCount.Value;
			}
			else
			{
				val.prefabDesc.stationMaxItemKinds = PlanetaryLogisticsStationMaxItemKinds.Value;
				val.prefabDesc.stationMaxItemCount = PlanetaryLogisticsStationMaxItemCount.Value;
			}
		}
	}
}
[HarmonyPatch(typeof(CargoPath))]
[HarmonyPatch("TryPickItemAtRear")]
public static class CargoPath_TryPickItemAtRear_Patch
{
	public static readonly FieldRef<CargoPath, int> bufferLengthRef = AccessTools.FieldRefAccess<CargoPath, int>("bufferLength");

	public static readonly FieldRef<CargoPath, int> updateLenRef = AccessTools.FieldRefAccess<CargoPath, int>("updateLen");

	public static bool Prefix(CargoPath __instance, int[] needs, ref int needIdx, ref byte stack, ref byte inc, ref int __result)
	{
		__result = Custom_TryPickItemAtRear(__instance, needs, out needIdx, out stack, out inc);
		return false;
	}

	private static int Custom_TryPickItemAtRear(CargoPath __instance, int[] needs, out int needIdx, out byte stack, out byte inc)
	{
		lock (__instance.buffer)
		{
			stack = 1;
			inc = 0;
			needIdx = -1;
			if (__instance.buffer[bufferLengthRef.Invoke(__instance) - 5 - 1] == 250)
			{
				int num = bufferLengthRef.Invoke(__instance) - 5 - 1;
				int num2 = __instance.buffer[num + 1] - 1 + (__instance.buffer[num + 2] - 1) * 100 + (__instance.buffer[num + 3] - 1) * 10000 + (__instance.buffer[num + 4] - 1) * 1000000;
				int item = __instance.cargoContainer.cargoPool[num2].item;
				stack = __instance.cargoContainer.cargoPool[num2].stack;
				inc = __instance.cargoContainer.cargoPool[num2].inc;
				for (int i = 0; i < needs.Length; i++)
				{
					if (item == needs[i])
					{
						Array.Clear(__instance.buffer, num - 4, 10);
						int num3 = num + 5 + 1;
						if (updateLenRef.Invoke(__instance) < num3)
						{
							updateLenRef.Invoke(__instance) = num3;
						}
						__instance.cargoContainer.RemoveCargo(num2);
						needIdx = i;
						return item;
					}
				}
			}
		}
		return 0;
	}
}
[HarmonyPatch]
public static class CargoPath_TryPickItem_Patch
{
	public static readonly FieldRef<CargoPath, int> bufferLengthRef = AccessTools.FieldRefAccess<CargoPath, int>("bufferLength");

	public static readonly FieldRef<CargoPath, int> updateLenRef = AccessTools.FieldRefAccess<CargoPath, int>("updateLen");

	private static MethodBase TargetMethod()
	{
		return AccessTools.Method(typeof(CargoPath), "TryPickItem", new Type[6]
		{
			typeof(int),
			typeof(int),
			typeof(int),
			typeof(int[]),
			typeof(byte).MakeByRefType(),
			typeof(byte).MakeByRefType()
		}, (Type[])null);
	}

	public static bool Prefix(CargoPath __instance, int index, int length, int filter, int[] needs, ref byte stack, ref byte inc, ref int __result)
	{
		__result = Custom_TryPickItem(__instance, index, length, filter, needs, out stack, out inc);
		return false;
	}

	private static int Custom_TryPickItem(CargoPath __instance, int index, int length, int filter, int[] needs, out byte stack, out byte inc)
	{
		lock (__instance.buffer)
		{
			stack = 1;
			inc = 0;
			if (index < 0)
			{
				index = 0;
			}
			else if (index >= bufferLengthRef.Invoke(__instance))
			{
				index = bufferLengthRef.Invoke(__instance) - 1;
			}
			int num = index + length;
			if (num > bufferLengthRef.Invoke(__instance))
			{
				num = bufferLengthRef.Invoke(__instance);
			}
			for (int i = index; i < num; i++)
			{
				if (__instance.buffer[i] < 246)
				{
					continue;
				}
				i += 250 - __instance.buffer[i];
				int num2 = __instance.buffer[i + 1] - 1 + (__instance.buffer[i + 2] - 1) * 100 + (__instance.buffer[i + 3] - 1) * 10000 + (__instance.buffer[i + 4] - 1) * 1000000;
				int item = __instance.cargoContainer.cargoPool[num2].item;
				stack = __instance.cargoContainer.cargoPool[num2].stack;
				inc = __instance.cargoContainer.cargoPool[num2].inc;
				if ((filter == 0 || item == filter) && Utils.IsItemInNeeds(item, needs, valueOnNull: false))
				{
					Array.Clear(__instance.buffer, i - 4, 10);
					int num3 = i + 5 + 1;
					if (updateLenRef.Invoke(__instance) < num3)
					{
						updateLenRef.Invoke(__instance) = num3;
					}
					__instance.cargoContainer.RemoveCargo(num2);
					return item;
				}
				return 0;
			}
		}
		return 0;
	}
}
[HarmonyPatch(typeof(CargoPath))]
[HarmonyPatch("CanPickItemFromRear")]
public static class CargoPath_CanPickItemFromRear_Patch
{
	public static readonly FieldRef<CargoPath, int> bufferLengthRef = AccessTools.FieldRefAccess<CargoPath, int>("bufferLength");

	public static bool Prefix(CargoPath __instance, int[] needs, ref bool __result)
	{
		__result = Custom_CanPickItemFromRear(__instance, needs);
		return false;
	}

	private static bool Custom_CanPickItemFromRear(CargoPath __instance, int[] needs)
	{
		int num = bufferLengthRef.Invoke(__instance) - 5 - 1;
		if (__instance.buffer[num] == 250)
		{
			int num2 = __instance.buffer[num + 1] - 1 + (__instance.buffer[num + 2] - 1) * 100 + (__instance.buffer[num + 3] - 1) * 10000 + (__instance.buffer[num + 4] - 1) * 1000000;
			int item = __instance.cargoContainer.cargoPool[num2].item;
			if (item == 0)
			{
				return false;
			}
			if (Utils.IsItemInNeeds(item, needs, valueOnNull: false))
			{
				return true;
			}
		}
		return false;
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("Init")]
public static class StationComponent_Init_Patch
{
	public static void Postfix(StationComponent __instance)
	{
		__instance.needs = new int[__instance.storage.Length + 1];
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("Import")]
[HarmonyPatch(new Type[] { typeof(BinaryReader) })]
public static class StationComponent_Import_Patch
{
	public static void Postfix(StationComponent __instance)
	{
		__instance.needs = new int[__instance.storage.Length + 1];
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("UpdateNeeds")]
public static class StationComponent_UpdateNeeds_Patch
{
	public static bool Prefix(StationComponent __instance)
	{
		lock (__instance.storage)
		{
			int num = __instance.needs.Length;
			for (int i = 0; i < num - 1; i++)
			{
				__instance.needs[i] = ((__instance.storage[i].count < __instance.storage[i].max) ? __instance.storage[i].itemId : 0);
			}
			__instance.needs[num - 1] = ((__instance.isStellar && __instance.warperCount < __instance.warperMaxCount) ? 1210 : 0);
		}
		return false;
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("AddItem")]
public static class StationComponent_AddItem_Patch
{
	[HarmonyPrefix]
	public static bool Prefix(StationComponent __instance, int itemId, int count, int inc, ref int __result)
	{
		__result = Custom_AddItem(__instance, itemId, count, inc);
		return false;
	}

	private static int Custom_AddItem(StationComponent __instance, int itemId, int count, int inc)
	{
		if (itemId <= 0)
		{
			return 0;
		}
		lock (__instance.storage)
		{
			int num = __instance.storage.Length;
			for (int i = 0; i < num; i++)
			{
				if (__instance.storage[i].itemId == itemId)
				{
					__instance.storage[i].count = count;
					__instance.storage[i].inc = inc;
					return count;
				}
			}
		}
		return 0;
	}
}
[HarmonyPatch]
public static class StationComponent_TakeItem_Patch
{
	private static MethodBase TargetMethod()
	{
		return AccessTools.Method(typeof(StationComponent), "TakeItem", new Type[4]
		{
			typeof(int).MakeByRefType(),
			typeof(int).MakeByRefType(),
			typeof(int[]),
			typeof(int).MakeByRefType()
		}, (Type[])null);
	}

	[HarmonyPrefix]
	public static bool Prefix(StationComponent __instance, ref int _itemId, ref int _count, int[] _needs, ref int _inc)
	{
		Custom_TakeItem(__instance, ref _itemId, ref _count, _needs, out _inc);
		return false;
	}

	private static void Custom_TakeItem(StationComponent __instance, ref int _itemId, ref int _count, int[] _needs, out int _inc)
	{
		_inc = 0;
		if (_itemId > 0 && _count > 0 && Utils.IsItemInNeeds(_itemId, _needs))
		{
			lock (__instance.storage)
			{
				int num = __instance.storage.Length;
				for (int i = 0; i < num; i++)
				{
					if (__instance.storage[i].itemId == _itemId && __instance.storage[i].count > 0)
					{
						_count = ((_count < __instance.storage[i].count) ? _count : __instance.storage[i].count);
						_itemId = __instance.storage[i].itemId;
						_inc = split_inc(ref __instance.storage[i].count, ref __instance.storage[i].inc, _count);
						return;
					}
				}
			}
		}
		_itemId = 0;
		_count = 0;
		_inc = 0;
	}

	private static int split_inc(ref int n, ref int m, int p)
	{
		if (n == 0)
		{
			return 0;
		}
		int num = m / n;
		int num2 = m - num * n;
		n -= p;
		num2 -= n;
		num = ((num2 > 0) ? (num * p + num2) : (num * p));
		m -= num;
		return num;
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("HasLocalSupply")]
public static class StationComponent_HasLocalSupply_Patch
{
	public static bool Prefix(StationComponent __instance, int itemId, int countAtLeast, ref int __result)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Invalid comparison between Unknown and I4
		int num = __instance.storage.Length;
		for (int i = 0; i < num; i++)
		{
			if (__instance.storage[i].itemId == itemId && (int)__instance.storage[i].localLogic == 1 && __instance.storage[i].count >= countAtLeast)
			{
				__result = i;
				return false;
			}
		}
		return true;
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("HasLocalDemand")]
public static class StationComponent_HasLocalDemand_Patch
{
	public static bool Prefix(StationComponent __instance, int itemId, int countAtLeast, ref int __result)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Invalid comparison between Unknown and I4
		int num = __instance.storage.Length;
		for (int i = 0; i < num; i++)
		{
			if (__instance.storage[i].itemId == itemId && (int)__instance.storage[i].localLogic == 2 && __instance.storage[i].max - __instance.storage[i].count >= countAtLeast)
			{
				__result = i;
				return false;
			}
		}
		return true;
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("HasRemoteSupply")]
public static class StationComponent_HasRemoteSupply_Patch
{
	public static bool Prefix(StationComponent __instance, int itemId, int countAtLeast, ref int __result)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Invalid comparison between Unknown and I4
		int num = __instance.storage.Length;
		for (int i = 0; i < num; i++)
		{
			if (__instance.storage[i].itemId == itemId && (int)__instance.storage[i].remoteLogic == 1 && __instance.storage[i].count >= countAtLeast)
			{
				__result = i;
				return false;
			}
		}
		return true;
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("HasRemoteDemand")]
public static class StationComponent_HasRemoteDemand_Patch
{
	public static bool Prefix(StationComponent __instance, int itemId, int countAtLeast, ref int __result)
	{
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Invalid comparison between Unknown and I4
		int num = __instance.storage.Length;
		for (int i = 0; i < num; i++)
		{
			if (__instance.storage[i].itemId == itemId && (int)__instance.storage[i].remoteLogic == 2 && __instance.storage[i].max - __instance.storage[i].count >= countAtLeast)
			{
				__result = i;
				return false;
			}
		}
		return true;
	}
}
[HarmonyPatch(typeof(StationComponent))]
[HarmonyPatch("UpdateInputSlots")]
public static class StationComponent_UpdateInputSlots_Patch
{
	public static bool Prefix(StationComponent __instance, CargoTraffic traffic, SignData[] signPool, bool active)
	{
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: Invalid comparison between Unknown and I4
		//IL_012e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0134: Invalid comparison between Unknown and I4
		lock (__instance.storage)
		{
			int num = __instance.slots.Length;
			BeltComponent[] beltPool = traffic.beltPool;
			int num2 = __instance.needs.Sum();
			byte b = default(byte);
			byte b2 = default(byte);
			for (int i = 0; i < num; i++)
			{
				ref SlotData reference = ref __instance.slots[i];
				if ((int)reference.dir == 2)
				{
					if (reference.counter > 0)
					{
						reference.counter--;
					}
					else
					{
						if (num2 == 0 || reference.beltId == 0)
						{
							continue;
						}
						ref BeltComponent reference2 = ref beltPool[reference.beltId];
						CargoPath cargoPath = traffic.GetCargoPath(reference2.segPathId);
						if (cargoPath == null)
						{
							continue;
						}
						int num3 = -1;
						int num4 = cargoPath.TryPickItemAtRear(__instance.needs, ref num3, ref b, ref b2);
						if (num3 >= 0)
						{
							__instance.InputItem(num4, num3, (int)b, (int)b2);
							reference.storageIdx = num3 + 1;
							reference.counter = 1;
						}
						if (active)
						{
							if (__instance.isVeinCollector)
							{
								ref SignData reference3 = ref signPool[reference2.entityId];
								reference3.iconType = 0u;
								reference3.iconId0 = 0u;
							}
							else if (num4 > 0)
							{
								ref SignData reference4 = ref signPool[reference2.entityId];
								reference4.iconType = 1u;
								reference4.iconId0 = (uint)num4;
							}
						}
					}
				}
				else if ((int)reference.dir != 1)
				{
					reference.beltId = 0;
					reference.counter = 0;
				}
			}
		}
		return false;
	}
}
public static class Utils
{
	public static bool IsItemInNeeds(int itemId, int[] needs, bool valueOnNull = true)
	{
		if (needs == null)
		{
			return valueOnNull;
		}
		for (int i = 0; i < needs.Length; i++)
		{
			if (needs[i] == itemId)
			{
				return true;
			}
		}
		return false;
	}
}