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