From f69a90d45275677b8d03a1b3d45b7cd4d128b6c3 Mon Sep 17 00:00:00 2001 From: Soar Qin Date: Mon, 16 Mar 2026 19:51:16 +0800 Subject: [PATCH] Fix potential bugs in UXAssist and CheatEnabler UXAssist: - PlanetFunctions: fix infinite loop in constructStats cleanup (i++ -> i--) - PlanetFunctions: skip entityPool slot 0 (sentinel) in DismantleAll foreach - PlanetFunctions: fix belt buffer walk infinite loop when buffer[j]==250, add cargoPool bounds check - FactoryPatch: fix UnfixProto guard condition (< 3 -> < PowerPoleIds.Length) - FactoryPatch: fix Array.Resize(index*2) -> (index+1)*2 to handle index==0 - LogisticsPatch: fix UpdateStorageMax early-exit to check both local and remote - LogisticsPatch: fix storage max scan to use Math.Max instead of last-write - LogisticsPatch: add divide-by-zero guard in station storage ratio calculation - LogisticsPatch: fix station entry right-click delegates using per-instance dictionary instead of shared static array to prevent unsubscribe mismatch - LogisticsPatch: add null checks for GameObject.Find results in InitGUI - GamePatch: log exception in previously empty catch block - GameLogic: invoke event handlers individually with try/catch so one failing subscriber does not abort subsequent ones - DysonSpherePatch/LogisticsPatch/PersistPatch/PlayerPatch: replace matcher.Labels = null with matcher.Labels = [] (5 sites) - UIConfigWindow: remove duplicate I18N.Add for 'Outgoing integration count' - UIConfigWindow: remove two orphaned y += 36f spacing increments CheatEnabler: - GamePatch: add null check for GameMain.gameScenario in AbnormalDisabler.OnEnable - FactoryPatch: add null check for GameMain.mainPlayer in TakeTailItemsPatch and GetItemCountPatch - FactoryPatch: add null check for GameMain.mainPlayer in ConstructionSystem_GameTick_Prefix - FactoryPatch: fix _portalFrom.Remove(beltId) -> Remove(v) (wrong key) - FactoryPatch: add null guard for GameMain.data before iterating factories in WindTurbinesPowerGlobalCoverage - DysonSphereFunctions: fix shell pool rebuild loop writing all shells to slot 1 (id=1); now uses j+1 per iteration - DysonSphereFunctions: replace GameMain.gameScenario.NotifyOnPlanDysonShell() with null-conditional call (?.) at 4 sites - DysonSpherePatch: fix SkipAbsorbPatch/QuickAbsorbPatch sharing _instantAbsorb: OnDisable now recalculates the flag instead of unconditionally clearing it - PlayerFunctions: add null check for GameMain.galaxy in TeleportToOuterSpace - UIConfigWindow: add null guard in UpdateButtons before accessing button fields - PlanetFunctions: add colliderId bounds check in BuryAllVeins --- .../Functions/DysonSphereFunctions.cs | 13 ++-- CheatEnabler/Functions/PlanetFunctions.cs | 8 +- CheatEnabler/Functions/PlayerFunctions.cs | 1 + CheatEnabler/Patches/DysonSpherePatch.cs | 8 +- CheatEnabler/Patches/FactoryPatch.cs | 8 +- CheatEnabler/Patches/GamePatch.cs | 3 +- CheatEnabler/UIConfigWindow.cs | 1 + UXAssist/Common/GameLogic.cs | 23 +++++- UXAssist/Functions/PlanetFunctions.cs | 6 +- UXAssist/Patches/DysonSpherePatch.cs | 2 +- UXAssist/Patches/FactoryPatch.cs | 11 ++- UXAssist/Patches/GamePatch.cs | 3 +- UXAssist/Patches/LogisticsPatch.cs | 78 ++++++++++++------- UXAssist/Patches/PersistPatch.cs | 2 +- UXAssist/Patches/PlayerPatch.cs | 4 +- UXAssist/UIConfigWindow.cs | 7 +- 16 files changed, 116 insertions(+), 62 deletions(-) diff --git a/CheatEnabler/Functions/DysonSphereFunctions.cs b/CheatEnabler/Functions/DysonSphereFunctions.cs index 22f08b8..b560be3 100644 --- a/CheatEnabler/Functions/DysonSphereFunctions.cs +++ b/CheatEnabler/Functions/DysonSphereFunctions.cs @@ -1101,7 +1101,7 @@ public static class DysonSphereFunctions dysonSphere.PickAutoNode(); } dysonSphere.modelRenderer.RebuildModels(); - GameMain.gameScenario.NotifyOnPlanDysonShell(); + GameMain.gameScenario?.NotifyOnPlanDysonShell(); dysonSphere.inEditorRenderMaskS = 0; dysonSphere.inEditorRenderMaskL = 0; dysonSphere.inGameRenderMaskS = 0; @@ -1163,8 +1163,9 @@ public static class DysonSphereFunctions { var shell = shells[j]; retainNodes.UnionWith(shell.nodes.Select(node => node.id)); - layer.shellPool[1] = shell; - shell.id = 1; + int shellId = j + 1; + layer.shellPool[shellId] = shell; + shell.id = shellId; for (var k = 0; k < shell.nodes.Count; k++) { var idA = shell.nodes[k].id; @@ -1328,7 +1329,7 @@ public static class DysonSphereFunctions dysonSphere.CheckAutoNodes(); if (dysonSphere.autoNodeCount <= 0) dysonSphere.PickAutoNode(); dysonSphere.modelRenderer.RebuildModels(); - GameMain.gameScenario.NotifyOnPlanDysonShell(); + GameMain.gameScenario?.NotifyOnPlanDysonShell(); return; } } @@ -1460,7 +1461,7 @@ public static class DysonSphereFunctions dysonSphere.CheckAutoNodes(); if (dysonSphere.autoNodeCount <= 0) dysonSphere.PickAutoNode(); dysonSphere.modelRenderer.RebuildModels(); - if (shellsChanged) GameMain.gameScenario.NotifyOnPlanDysonShell(); + if (shellsChanged) GameMain.gameScenario?.NotifyOnPlanDysonShell(); dysonSphere.inEditorRenderMaskS = 0; dysonSphere.inEditorRenderMaskL = 0; dysonSphere.inGameRenderMaskS = 0; @@ -1623,7 +1624,7 @@ public static class DysonSphereFunctions dysonSphere.CheckAutoNodes(); if (dysonSphere.autoNodeCount <= 0) dysonSphere.PickAutoNode(); dysonSphere.modelRenderer.RebuildModels(); - if (shellsChanged) GameMain.gameScenario.NotifyOnPlanDysonShell(); + if (shellsChanged) GameMain.gameScenario?.NotifyOnPlanDysonShell(); dysonSphere.inEditorRenderMaskS = 0; dysonSphere.inEditorRenderMaskL = 0; dysonSphere.inGameRenderMaskS = 0; diff --git a/CheatEnabler/Functions/PlanetFunctions.cs b/CheatEnabler/Functions/PlanetFunctions.cs index 05b1481..54471c9 100644 --- a/CheatEnabler/Functions/PlanetFunctions.cs +++ b/CheatEnabler/Functions/PlanetFunctions.cs @@ -17,9 +17,15 @@ public static class PlanetFunctions { var pos = array[m].pos; var colliderId = array[m].colliderId; + if (colliderId <= 0) continue; + var chunkIdx = colliderId >> 20; + var poolIdx = colliderId & 0xFFFFF; + if (chunkIdx >= physics.colChunks.Length) continue; + var chunk = physics.colChunks[chunkIdx]; + if (chunk == null || poolIdx >= chunk.colliderPool.Length) continue; var colliderData = physics.GetColliderData(colliderId); var vector = colliderData.pos.normalized * (height + 0.4f); - physics.colChunks[colliderId >> 20].colliderPool[colliderId & 0xFFFFF].pos = vector; + chunk.colliderPool[poolIdx].pos = vector; array[m].pos = pos.normalized * height; var quaternion = Maths.SphericalRotation(array[m].pos, Random.value * 360f); physics.SetPlanetPhysicsColliderDirty(); diff --git a/CheatEnabler/Functions/PlayerFunctions.cs b/CheatEnabler/Functions/PlayerFunctions.cs index a22d5a4..2bb2c97 100644 --- a/CheatEnabler/Functions/PlayerFunctions.cs +++ b/CheatEnabler/Functions/PlayerFunctions.cs @@ -35,6 +35,7 @@ public static class PlayerFunctions { var maxSqrDistance = 0.0; var starPosition = VectorLF3.zero; + if (GameMain.galaxy == null) return; foreach (var star in GameMain.galaxy.stars) { var sqrDistance = star.position.sqrMagnitude; diff --git a/CheatEnabler/Patches/DysonSpherePatch.cs b/CheatEnabler/Patches/DysonSpherePatch.cs index c35e7c2..ab4a86a 100644 --- a/CheatEnabler/Patches/DysonSpherePatch.cs +++ b/CheatEnabler/Patches/DysonSpherePatch.cs @@ -365,12 +365,12 @@ public class DysonSpherePatch : PatchImpl { protected override void OnEnable() { - _instantAbsorb = QuickAbsorbEnabled.Value; + _instantAbsorb = QuickAbsorbEnabled.Value && QuickAbsorbPatch.GetHarmony() != null; } protected override void OnDisable() { - _instantAbsorb = false; + _instantAbsorb = QuickAbsorbEnabled.Value && QuickAbsorbPatch.GetHarmony() != null; } [HarmonyTranspiler] @@ -407,12 +407,12 @@ public class DysonSpherePatch : PatchImpl { protected override void OnEnable() { - _instantAbsorb = SkipAbsorbEnabled.Value; + _instantAbsorb = SkipAbsorbEnabled.Value && SkipAbsorbPatch.GetHarmony() != null; } protected override void OnDisable() { - _instantAbsorb = false; + _instantAbsorb = SkipAbsorbEnabled.Value && SkipAbsorbPatch.GetHarmony() != null; } [HarmonyTranspiler] diff --git a/CheatEnabler/Patches/FactoryPatch.cs b/CheatEnabler/Patches/FactoryPatch.cs index 7f5ce28..9982805 100644 --- a/CheatEnabler/Patches/FactoryPatch.cs +++ b/CheatEnabler/Patches/FactoryPatch.cs @@ -448,6 +448,7 @@ public class FactoryPatch : PatchImpl var factory = __instance.factory; if (factory.prebuildCount <= 0) return; var player = GameMain.mainPlayer; + if (player == null) return; var total = factory.prebuildCursor - 1; var stepCount = total switch { @@ -588,7 +589,7 @@ public class FactoryPatch : PatchImpl [ArgumentType.Ref, ArgumentType.Ref, ArgumentType.Normal, ArgumentType.Out, ArgumentType.Normal])] public static bool TakeTailItemsPatch(StorageComponent __instance, int itemId) { - if (__instance == null || __instance.id != GameMain.mainPlayer.package.id) return true; + if (__instance == null || GameMain.mainPlayer == null || __instance.id != GameMain.mainPlayer.package.id) return true; if (itemId <= 0) return true; if (_canBuildItems == null) { @@ -603,7 +604,7 @@ public class FactoryPatch : PatchImpl public static void GetItemCountPatch(StorageComponent __instance, int itemId, ref int __result) { if (__result > 99) return; - if (__instance == null || __instance.id != GameMain.mainPlayer.package.id) return; + if (__instance == null || GameMain.mainPlayer == null || __instance.id != GameMain.mainPlayer.package.id) return; if (itemId <= 0) return; if (_canBuildItems == null) { @@ -1020,7 +1021,7 @@ public class FactoryPatch : PatchImpl { var v = ((long)factory << 32) | (uint)beltId; if (!_portalFrom.TryGetValue(v, out var number)) return; - _portalFrom.Remove(beltId); + _portalFrom.Remove(v); if (!_portalTo.TryGetValue(number, out var set)) return; set.Remove(v); } @@ -1649,6 +1650,7 @@ public class FactoryPatch : PatchImpl } // Iterate all factories and update wind turbines power nodes + if (GameMain.data == null) return; foreach (var factory in GameMain.data.factories) { var powerSystem = factory?.powerSystem; diff --git a/CheatEnabler/Patches/GamePatch.cs b/CheatEnabler/Patches/GamePatch.cs index a3f2953..9dae83e 100644 --- a/CheatEnabler/Patches/GamePatch.cs +++ b/CheatEnabler/Patches/GamePatch.cs @@ -42,7 +42,8 @@ public static class GamePatch protected override void OnEnable() { if (_savedDeterminators == null) return; - var abnormalLogic = GameMain.gameScenario.abnormalityLogic; + var abnormalLogic = GameMain.gameScenario?.abnormalityLogic; + if (abnormalLogic == null) return; foreach (var p in _savedDeterminators) { p.Value.OnUnregEvent(); diff --git a/CheatEnabler/UIConfigWindow.cs b/CheatEnabler/UIConfigWindow.cs index 934180e..240b416 100644 --- a/CheatEnabler/UIConfigWindow.cs +++ b/CheatEnabler/UIConfigWindow.cs @@ -385,6 +385,7 @@ public static class UIConfigWindow private static void UpdateButtons() { + if (_resignGameBtn == null || _clearBanBtn == null) return; var data = GameMain.data; if (data == null) return; var resignEnabled = data.account != AccountData.me; diff --git a/UXAssist/Common/GameLogic.cs b/UXAssist/Common/GameLogic.cs index 3762995..2c551bc 100644 --- a/UXAssist/Common/GameLogic.cs +++ b/UXAssist/Common/GameLogic.cs @@ -1,5 +1,6 @@ using System; using HarmonyLib; +using UnityEngine; namespace UXAssist.Common; @@ -9,24 +10,40 @@ public class GameLogic : PatchImpl public static Action OnGameBegin; public static Action OnGameEnd; + private static void InvokeSafe(Action action) + { + if (action == null) return; + foreach (var handler in action.GetInvocationList()) + { + try + { + ((Action)handler)(); + } + catch (Exception ex) + { + Debug.LogException(ex); + } + } + } + [HarmonyPostfix] [HarmonyPatch(typeof(VFPreload), nameof(VFPreload.InvokeOnLoadWorkEnded))] public static void VFPreload_InvokeOnLoadWorkEnded_Postfix() { - OnDataLoaded?.Invoke(); + InvokeSafe(OnDataLoaded); } [HarmonyPostfix, HarmonyPriority(Priority.First)] [HarmonyPatch(typeof(GameMain), nameof(GameMain.Begin))] public static void GameMain_Begin_Postfix() { - OnGameBegin?.Invoke(); + InvokeSafe(OnGameBegin); } [HarmonyPostfix, HarmonyPriority(Priority.Last)] [HarmonyPatch(typeof(GameMain), nameof(GameMain.End))] public static void GameMain_End_Postfix() { - OnGameEnd?.Invoke(); + InvokeSafe(OnGameEnd); } } diff --git a/UXAssist/Functions/PlanetFunctions.cs b/UXAssist/Functions/PlanetFunctions.cs index 63ab24d..d6cba7a 100644 --- a/UXAssist/Functions/PlanetFunctions.cs +++ b/UXAssist/Functions/PlanetFunctions.cs @@ -24,6 +24,7 @@ public static class PlanetFunctions if (factory == null) return; foreach (var etd in factory.entityPool) { + if (etd.id == 0) continue; var stationId = etd.stationId; if (stationId > 0) { @@ -106,7 +107,7 @@ public static class PlanetFunctions } if (constructionSystem.constructStats?.buffer != null) { - for (var i = constructionSystem.constructStats.cursor - 1; i > 0; i++) + for (var i = constructionSystem.constructStats.cursor - 1; i > 0; i--) { ref var constructStat = ref constructionSystem.constructStats.buffer[i]; if (constructStat.id <= 0) continue; @@ -405,7 +406,8 @@ public static class PlanetFunctions { if (buffer[j] >= 246) { - j += 250 - buffer[j]; + var delta = 250 - buffer[j]; + if (delta > 0) j += delta; var bufferIndex = buffer[j + 1] - 1 + (buffer[j + 2] - 1) * 100 + (buffer[j + 3] - 1) * 10000 + (buffer[j + 4] - 1) * 1000000; ref var cargo = ref cargoPath.cargoContainer.cargoPool[bufferIndex]; var stack = cargo.stack; diff --git a/UXAssist/Patches/DysonSpherePatch.cs b/UXAssist/Patches/DysonSpherePatch.cs index 4db947f..9ccbb36 100644 --- a/UXAssist/Patches/DysonSpherePatch.cs +++ b/UXAssist/Patches/DysonSpherePatch.cs @@ -414,7 +414,7 @@ public class DysonSpherePatch : PatchImpl ); if (jmpTarget == null) return matcher.InstructionEnumeration(); var labels = matcher.Labels; - matcher.Labels = null; + matcher.Labels = []; matcher.Insert( new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels), new CodeInstruction(OpCodes.Ldfld, AccessTools.Field(typeof(EjectorComponent), nameof(EjectorComponent.runtimeOrbitId))), diff --git a/UXAssist/Patches/FactoryPatch.cs b/UXAssist/Patches/FactoryPatch.cs index 101df2e..f5b04ba 100644 --- a/UXAssist/Patches/FactoryPatch.cs +++ b/UXAssist/Patches/FactoryPatch.cs @@ -1542,7 +1542,7 @@ public class FactoryPatch : PatchImpl private static void UnfixProto() { - if (GetHarmony() == null || OldDragBuild.Count < 3 || DSPGame.IsMenuDemo) return; + if (GetHarmony() == null || OldDragBuild.Count < PowerPoleIds.Length || DSPGame.IsMenuDemo) return; var i = 0; foreach (var id in PowerPoleIds) { @@ -1860,7 +1860,7 @@ public class FactoryPatch : PatchImpl if (index < 0) return null; if (index >= _signalBelts.Length) { - Array.Resize(ref _signalBelts, index * 2); + Array.Resize(ref _signalBelts, (index + 1) * 2); } else { @@ -2540,14 +2540,13 @@ public class FactoryPatch : PatchImpl { if (buffer[i] >= 246) { - i += 250 - buffer[i]; + var delta = 250 - buffer[i]; + if (delta > 0) i += delta; var index = buffer[i + 1] - 1 + (buffer[i + 2] - 1) * 100 + (buffer[i + 3] - 1) * 10000 + (buffer[i + 4] - 1) * 1000000; ref var cargo = ref cargoPath.cargoContainer.cargoPool[index]; var item = cargo.item; - var stack = cargo.stack; - var inc = cargo.inc; takeOutItems[item] = (takeOutItems.TryGetValue(item, out var value) ? value : 0) - + ((long)stack | ((long)inc << 32)); + + ((long)cargo.stack | ((long)cargo.inc << 32)); Array.Clear(buffer, i - 4, 10); i += 6; if (cargoPath.updateLen < i) cargoPath.updateLen = i; diff --git a/UXAssist/Patches/GamePatch.cs b/UXAssist/Patches/GamePatch.cs index a1a5971..d82d5d5 100644 --- a/UXAssist/Patches/GamePatch.cs +++ b/UXAssist/Patches/GamePatch.cs @@ -521,8 +521,9 @@ public class GamePatch : PatchImpl __instance.ImportXML(optionPath); return false; } - catch + catch (Exception ex) { + Debug.LogException(ex); } } var gameXMLOptionPath = GameConfig.gameXMLOptionPath; diff --git a/UXAssist/Patches/LogisticsPatch.cs b/UXAssist/Patches/LogisticsPatch.cs index f5bea7f..ac29518 100644 --- a/UXAssist/Patches/LogisticsPatch.cs +++ b/UXAssist/Patches/LogisticsPatch.cs @@ -481,6 +481,7 @@ public static class LogisticsPatch var modelIndex = factory.entityPool[stationPool[i].entityId].modelIndex; var maxCount = LDB.models.Select(modelIndex).prefabDesc.stationMaxItemCount; var oldMaxCount = maxCount + history.localStationExtraStorage - _valuelf; + if (oldMaxCount < 1.0) continue; var intOldMaxCount = (int)Math.Round(oldMaxCount); var intNewMaxCount = maxCount + history.localStationExtraStorage; var ratio = intNewMaxCount / oldMaxCount; @@ -506,6 +507,7 @@ public static class LogisticsPatch var modelIndex = factory.entityPool[stationPool[i].entityId].modelIndex; var maxCount = LDB.models.Select(modelIndex).prefabDesc.stationMaxItemCount; var oldMaxCount = maxCount + history.remoteStationExtraStorage - _valuelf; + if (oldMaxCount < 1.0) continue; var intOldMaxCount = (int)Math.Round(oldMaxCount); var intNewMaxCount = maxCount + history.remoteStationExtraStorage; var ratio = intNewMaxCount / oldMaxCount; @@ -681,7 +683,7 @@ public static class LogisticsPatch } var labels = matcher.Labels; - matcher.Labels = null; + matcher.Labels = []; matcher.Insert( new CodeInstruction(OpCodes.Ldarg_0).WithLabels(labels), Transpilers.EmitDelegate((UIGame uiGame) => @@ -710,37 +712,37 @@ public static class LogisticsPatch controlPanelWindow.DetermineFilterResults(); } - private static readonly Action[] OnStationEntryItemIconRightClickActions = new Action[5]; + private static readonly Dictionary[]> OnStationEntryItemIconRightClickActionsMap = new(); [HarmonyPostfix] [HarmonyPatch(typeof(UIControlPanelStationEntry), nameof(UIControlPanelStationEntry._OnRegEvent))] private static void UIControlPanelStationEntry__OnRegEvent_Postfix(UIControlPanelStationEntry __instance) { - OnStationEntryItemIconRightClickActions[0] = _ => OnStationEntryItemIconRightClick(__instance, 0); - OnStationEntryItemIconRightClickActions[1] = _ => OnStationEntryItemIconRightClick(__instance, 1); - OnStationEntryItemIconRightClickActions[2] = _ => OnStationEntryItemIconRightClick(__instance, 2); - OnStationEntryItemIconRightClickActions[3] = _ => OnStationEntryItemIconRightClick(__instance, 3); - OnStationEntryItemIconRightClickActions[4] = _ => OnStationEntryItemIconRightClick(__instance, 4); - __instance.storageItem0.itemButton.onRightClick += OnStationEntryItemIconRightClickActions[0]; - __instance.storageItem1.itemButton.onRightClick += OnStationEntryItemIconRightClickActions[1]; - __instance.storageItem2.itemButton.onRightClick += OnStationEntryItemIconRightClickActions[2]; - __instance.storageItem3.itemButton.onRightClick += OnStationEntryItemIconRightClickActions[3]; - __instance.storageItem4.itemButton.onRightClick += OnStationEntryItemIconRightClickActions[4]; + var actions = new Action[5]; + actions[0] = _ => OnStationEntryItemIconRightClick(__instance, 0); + actions[1] = _ => OnStationEntryItemIconRightClick(__instance, 1); + actions[2] = _ => OnStationEntryItemIconRightClick(__instance, 2); + actions[3] = _ => OnStationEntryItemIconRightClick(__instance, 3); + actions[4] = _ => OnStationEntryItemIconRightClick(__instance, 4); + OnStationEntryItemIconRightClickActionsMap[__instance] = actions; + __instance.storageItem0.itemButton.onRightClick += actions[0]; + __instance.storageItem1.itemButton.onRightClick += actions[1]; + __instance.storageItem2.itemButton.onRightClick += actions[2]; + __instance.storageItem3.itemButton.onRightClick += actions[3]; + __instance.storageItem4.itemButton.onRightClick += actions[4]; } [HarmonyPostfix] [HarmonyPatch(typeof(UIControlPanelStationEntry), nameof(UIControlPanelStationEntry._OnUnregEvent))] private static void UIControlPanelStationEntry__OnUnregEvent_Postfix(UIControlPanelStationEntry __instance) { - __instance.storageItem0.itemButton.onRightClick -= OnStationEntryItemIconRightClickActions[0]; - __instance.storageItem1.itemButton.onRightClick -= OnStationEntryItemIconRightClickActions[1]; - __instance.storageItem2.itemButton.onRightClick -= OnStationEntryItemIconRightClickActions[2]; - __instance.storageItem3.itemButton.onRightClick -= OnStationEntryItemIconRightClickActions[3]; - __instance.storageItem4.itemButton.onRightClick -= OnStationEntryItemIconRightClickActions[4]; - for (var i = 0; i < 5; i++) - { - OnStationEntryItemIconRightClickActions[i] = null; - } + if (!OnStationEntryItemIconRightClickActionsMap.TryGetValue(__instance, out var actions)) return; + __instance.storageItem0.itemButton.onRightClick -= actions[0]; + __instance.storageItem1.itemButton.onRightClick -= actions[1]; + __instance.storageItem2.itemButton.onRightClick -= actions[2]; + __instance.storageItem3.itemButton.onRightClick -= actions[3]; + __instance.storageItem4.itemButton.onRightClick -= actions[4]; + OnStationEntryItemIconRightClickActionsMap.Remove(__instance); } } @@ -777,7 +779,7 @@ public static class LogisticsPatch { var history = GameMain.history; if (history == null) return false; - if (_remoteStorageExtra == history.remoteStationExtraStorage) return false; + if (_remoteStorageExtra == history.remoteStationExtraStorage && _localStorageExtra == history.localStationExtraStorage) return false; _localStorageExtra = history.localStationExtraStorage; _remoteStorageExtra = history.remoteStationExtraStorage; _localStorageMaxTotal = _localStorageMax + _localStorageExtra; @@ -846,14 +848,14 @@ public static class LogisticsPatch { if (!prefabDesc.isCollectStation) { - _remoteStorageMax = prefabDesc.stationMaxItemCount; + _remoteStorageMax = Math.Max(_remoteStorageMax, prefabDesc.stationMaxItemCount); } } else { if (!prefabDesc.isVeinCollector) { - _localStorageMax = prefabDesc.stationMaxItemCount; + _localStorageMax = Math.Max(_localStorageMax, prefabDesc.stationMaxItemCount); } } } @@ -880,12 +882,36 @@ public static class LogisticsPatch rtrans.anchoredPosition3D = new Vector3(0, 0, 0f); var sliderBgPrefab = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Station Window/storage-box-0/slider-bg"); + if (sliderBgPrefab == null) + { + UXAssist.Logger.LogWarning("RealtimeLogisticsInfoPanel.InitGUI: slider-bg prefab not found, aborting GUI init"); + Object.Destroy(_stationTipsRoot); + _stationTipsRoot = null; + return; + } - _tipPrefab = Object.Instantiate(GameObject.Find("UI Root/Overlay Canvas/In Game/Scene UIs/Vein Marks/vein-tips/vein-tip-prefab"), _stationTipsRoot.transform); + var veinTipPrefabGo = GameObject.Find("UI Root/Overlay Canvas/In Game/Scene UIs/Vein Marks/vein-tips/vein-tip-prefab"); + if (veinTipPrefabGo == null) + { + UXAssist.Logger.LogWarning("RealtimeLogisticsInfoPanel.InitGUI: vein-tip-prefab not found, aborting GUI init"); + Object.Destroy(_stationTipsRoot); + _stationTipsRoot = null; + return; + } + var keyTipPrefabGo = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Key Tips/tip-prefab"); + if (keyTipPrefabGo == null) + { + UXAssist.Logger.LogWarning("RealtimeLogisticsInfoPanel.InitGUI: key tip-prefab not found, aborting GUI init"); + Object.Destroy(_stationTipsRoot); + _stationTipsRoot = null; + return; + } + + _tipPrefab = Object.Instantiate(veinTipPrefabGo, _stationTipsRoot.transform); _tipPrefab.name = "tipPrefab"; Object.Destroy(_tipPrefab.GetComponent()); var image = _tipPrefab.GetComponent(); - image.sprite = GameObject.Find("UI Root/Overlay Canvas/In Game/Windows/Key Tips/tip-prefab").GetComponent().sprite; + image.sprite = keyTipPrefabGo.GetComponent().sprite; image.color = new Color(0, 0, 0, 0.8f); image.enabled = true; var rectTrans = (RectTransform)_tipPrefab.transform; diff --git a/UXAssist/Patches/PersistPatch.cs b/UXAssist/Patches/PersistPatch.cs index f3a8702..4629d52 100644 --- a/UXAssist/Patches/PersistPatch.cs +++ b/UXAssist/Patches/PersistPatch.cs @@ -53,7 +53,7 @@ public class PersistPatch : PatchImpl ); var ldLocOpr = matcher.Operand; var labels = matcher.Labels; - matcher.Labels = null; + matcher.Labels = []; matcher.Insert( new CodeInstruction(OpCodes.Ldloc_S, ldLocOpr).WithLabels(labels), new CodeInstruction(OpCodes.Callvirt, AccessTools.PropertyGetter(typeof(Component), nameof(Component.transform))), diff --git a/UXAssist/Patches/PlayerPatch.cs b/UXAssist/Patches/PlayerPatch.cs index 879c8a8..f6b3f1c 100644 --- a/UXAssist/Patches/PlayerPatch.cs +++ b/UXAssist/Patches/PlayerPatch.cs @@ -266,7 +266,7 @@ public class PlayerPatch : PatchImpl ); matcher.CreateLabelAt(matcher.Pos + 8, out var jumpPos); var labels = matcher.Labels; - matcher.Labels = null; + matcher.Labels = []; matcher.InsertAndAdvance( new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))).WithLabels(labels), new CodeInstruction(OpCodes.Ldc_I4_1), @@ -316,7 +316,7 @@ public class PlayerPatch : PatchImpl ); matcher.CreateLabelAt(matcher.Pos + 10, out var jumpPos); var labels = matcher.Labels; - matcher.Labels = null; + matcher.Labels = []; matcher.InsertAndAdvance( new CodeInstruction(OpCodes.Ldsfld, AccessTools.Field(typeof(ShortcutKeysForStarsName), nameof(_showAllStarsNameStatus))).WithLabels(labels), new CodeInstruction(OpCodes.Ldc_I4_1), diff --git a/UXAssist/UIConfigWindow.cs b/UXAssist/UIConfigWindow.cs index 6c20415..6914948 100644 --- a/UXAssist/UIConfigWindow.cs +++ b/UXAssist/UIConfigWindow.cs @@ -93,7 +93,6 @@ public static class UIConfigWindow I18N.Add("Vessel transport range", "Vessel transport range", "运输船最远路程"); I18N.Add("Warp distance", "Warp distance", "曲速启用路程"); I18N.Add("Min. Load of Vessels", "Min. Load of Vessels", "运输船起送量"); - I18N.Add("Outgoing integration count", "Outgoing integration count", "输出货物集装数量"); I18N.Add("Include Orbital Collector", "Include Orbital Collector", "包含轨道采集器"); I18N.Add("Warpers required", "Warpers required", "翘曲器必备"); I18N.Add("Count of Vessels filled", "Count of Vessels filled", "填充的运输船数量"); @@ -767,8 +766,7 @@ public static class UIConfigWindow x = 10; y = 10; wnd.AddCheckBox(x, y, tab6, UIPatch.PlanetVeinUtilizationEnabled, "Planet vein utilization"); - y += 36f; - y += 36f; + y += 72f; wnd.AddCheckBox(x, y, tab6, TechPatch.BatchBuyoutTechEnabled, "Buy out techs with their prerequisites"); y += 36f; wnd.AddCheckBox(x, y, tab6, TechPatch.SorterCargoStackingEnabled, "Restore upgrades of \"Sorter Cargo Stacking\" on panel"); @@ -778,8 +776,7 @@ public static class UIConfigWindow wnd.AddButton(x, y, 300f, tab6, "Set \"Sorter Cargo Stacking\" to unresearched state", 16, "button-remove-cargo-stacking", TechFunctions.RemoveCargoStackingTechs); y += 36f; wnd.AddButton(x, y, 300f, tab6, "Unlock all techs with metadata", 16, "button-unlock-all-techs-with-metadata", TechFunctions.UnlockAllProtoWithMetadataAndPrompt); - y += 36f; - y += 36f; + y += 72f; wnd.AddButton(x, y, 300f, tab6, "Open Dark Fog Communicator", 16, "button-open-df-communicator", () => { if (!(GameMain.data?.gameDesc.isCombatMode ?? false)) return;