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 PlanetaryLogisticsStationMaxItemKinds; public static ConfigEntry PlanetaryLogisticsStationMaxItemCount; public static ConfigEntry InterstellarLogisticsStationMaxItemKinds; public static ConfigEntry 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("PlanetaryStation", "MaxItemKinds", 6, "Number of slots for PLS (Max 6)"); PlanetaryLogisticsStationMaxItemCount = ((BaseUnityPlugin)this).Config.Bind("PlanetaryStation", "MaxItemCount", 5000, "Capacity per slot for PLS"); InterstellarLogisticsStationMaxItemKinds = ((BaseUnityPlugin)this).Config.Bind("InterstellarStation", "MaxItemKinds", 6, "Number of slots for ILS (Max 6)"); InterstellarLogisticsStationMaxItemCount = ((BaseUnityPlugin)this).Config.Bind("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)Delegate.Combine(LDBTool.EditDataAction, new Action(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 bufferLengthRef = AccessTools.FieldRefAccess("bufferLength"); public static readonly FieldRef updateLenRef = AccessTools.FieldRefAccess("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 bufferLengthRef = AccessTools.FieldRefAccess("bufferLength"); public static readonly FieldRef updateLenRef = AccessTools.FieldRefAccess("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 bufferLengthRef = AccessTools.FieldRefAccess("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)(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(); 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; } }