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 UnityEngine;
using xiaoye97;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[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 SharpChedda;
[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;
public static ConfigEntry<int> PlanetaryLogisticsStationMaxItemKinds;
public static ConfigEntry<int> PlanetaryLogisticsStationMaxItemCount;
public static ConfigEntry<int> InterstellarLogisticsStationMaxItemKinds;
public static ConfigEntry<int> InterstellarLogisticsStationMaxItemCount;
private void Awake()
{
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00a4: Expected O, but got Unknown
logger = ((BaseUnityPlugin)this).Logger;
PlanetaryLogisticsStationMaxItemKinds = ((BaseUnityPlugin)this).Config.Bind<int>("PlanetaryStation", "MaxItemKinds", 6, "Number of slots for PLS (Max 6)");
PlanetaryLogisticsStationMaxItemCount = ((BaseUnityPlugin)this).Config.Bind<int>("PlanetaryStation", "MaxItemCount", 5000, "Capacity per slot for PLS");
InterstellarLogisticsStationMaxItemKinds = ((BaseUnityPlugin)this).Config.Bind<int>("InterstellarStation", "MaxItemKinds", 6, "Number of slots for ILS (Max 6)");
InterstellarLogisticsStationMaxItemCount = ((BaseUnityPlugin)this).Config.Bind<int>("InterstellarStation", "MaxItemCount", 10000, "Capacity per slot for ILS");
_harmony = new Harmony("sebdalf.dsp.betterlogisticsstation");
try
{
_harmony.PatchAll();
logger.LogInfo((object)"BetterLogisticsStation: Patches Applied Successfully");
}
catch (Exception ex)
{
logger.LogError((object)("BetterLogisticsStation: Patching FAILED: " + ex));
}
LDBTool.EditDataAction = (Action<Proto>)Delegate.Combine(LDBTool.EditDataAction, new Action<Proto>(Edit));
}
private void Edit(Proto proto)
{
ItemProto val = (ItemProto)(object)((proto is ItemProto) ? proto : null);
if (val != null && val.prefabDesc != null && val.prefabDesc.isStation)
{
if (val.prefabDesc.isStellarStation)
{
val.prefabDesc.stationMaxItemKinds = Math.Min(InterstellarLogisticsStationMaxItemKinds.Value, 6);
val.prefabDesc.stationMaxItemCount = InterstellarLogisticsStationMaxItemCount.Value;
}
else
{
val.prefabDesc.stationMaxItemKinds = Math.Min(PlanetaryLogisticsStationMaxItemKinds.Value, 6);
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)
{
int num = __instance.storage.Length;
__instance.needs = new int[num + 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("UpdateInputSlots")]
public static class StationComponent_UpdateInputSlots_Patch
{
public static bool Prefix(StationComponent __instance, CargoTraffic traffic, SignData[] signPool, bool active)
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Invalid comparison between Unknown and I4
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0188: 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;
}
}
[HarmonyPatch(typeof(UIStationWindow), "_OnOpen")]
public static class UIStationWindow_Simple_Patch
{
[HarmonyPostfix]
public static void OnOpenPostfix(UIStationWindow __instance)
{
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
FieldInfo field = typeof(UIStationWindow).GetField("groupCount", BindingFlags.Instance | BindingFlags.NonPublic);
FieldInfo field2 = typeof(UIStationWindow).GetField("_stationId", BindingFlags.Instance | BindingFlags.NonPublic);
if (field2 == null)
{
return;
}
int num = (int)field2.GetValue(__instance);
if (num <= 0)
{
return;
}
PlanetFactory factory = GameMain.mainPlayer.factory;
StationComponent stationComponent = factory.transport.GetStationComponent(num);
if (stationComponent != null)
{
int protoId = factory.entityPool[stationComponent.entityId].protoId;
ItemProto val = ((ProtoSet<ItemProto>)(object)LDB.items).Select(protoId);
int stationMaxItemKinds = val.prefabDesc.stationMaxItemKinds;
if (field != null)
{
field.SetValue(__instance, stationMaxItemKinds);
}
Transform val2 = ((Component)__instance).transform.Find("storage-group");
if ((Object)(object)val2 != (Object)null)
{
RectTransform component = ((Component)val2).GetComponent<RectTransform>();
component.sizeDelta = new Vector2(component.sizeDelta.x, (float)stationMaxItemKinds * 76f);
}
}
}
}
public static class Utils
{
public static bool IsItemInNeeds(int itemId, int[] needs, bool valueOnNull = true)
{
if (needs == null)
{
return valueOnNull;
}
foreach (int num in needs)
{
if (num == itemId)
{
return true;
}
}
return false;
}
}