Add Sort by Available Cargo - #190
dawidmachon wants to merge 2 commits into
Conversation
|
Check compatibility with the recently approved https://github.com/OwendB1/se-unified-storage plugin. |
There was a problem hiding this comment.
Reviewed at pinned commit 2597e4fd8066f93c4d8e449dabce67fbb01b3077 (= tag v1.0.0).
Summary: manifest, security audit and from-source build all pass. One real interop defect against Unified Storage needs fixing before merge; the rest are minor polish.
Manifest ✅
python3 test.py Plugins → All files validated. SourceDirectories correctly narrows the compile to ClientPlugin, excluding the solution, docs and deploy scripts. The GUID <Id> + <RepoId> pairing is consistent with the 16 existing manifests that already use it.
No <NuGetReferences> is needed: the only package the source actually uses is Harmony, and Pulsar injects Lib.Harmony 2.4.2 itself, which matches the csproj. (The Mono.Cecil PackageReference in ClientPlugin.csproj is unused — worth dropping.)
Pin check: repo HEAD is one commit ahead of the pin, but that commit only edits the repo's own manifest copy (<Commit>scaffold</Commit> → the hash). Zero code delta, so the pinned tree is the reviewed tree. Per registry convention that in-repo copy is a backup and its <Commit> should read TODO rather than carry a hash.
Security ✅
Clean. 1834 LOC, of which ~1270 is the stock client-plugin-template settings framework.
- No network of any kind — no
HttpClient/WebClient/WebRequest/sockets anywhere. - No
Assembly.Load*, no runtime Roslyn, noEmit/DynamicMethod, no crypto- or base64-to-execute, no string obfuscation. - No
Process.Startor shell invocation. - No committed binaries — only
docs/screenshot.png. - The two
Activator.CreateInstancehits are unmodified template code over compile-time-fixed generic types, not data-driven. - Only file I/O is
SortAvailableCargo.cfgunder the game's ownMyFileSystem.UserDataPath/Storage. - No privacy or multiplayer-abuse surface: it reads
MaxVolume/CurrentVolumeon inventories the terminal already displays and reorders GUI controls. Purely cosmetic, client-side.
From-source build ✅
Since the registry ignores the csproj, I replicated Pulsar's actual compile path (RoslynCompiler: C# 14, nullable context off, no DEV_BUILD, Bin64 + Harmony 2.4.2): 0 errors, build succeeded. Plain dotnet build is also clean.
Every reflected game member checks out against the decompiled source, and the accessibility story is right: MyTerminalInventoryController is internal, which is exactly why it is reached through AccessTools.TypeByName instead of a publicizer; MyGuiScreenTerminal, MyGuiControlInventoryOwner and .InventoryOwner are public, so no IgnoresAccessChecksTo is required. Signatures, control names (BlockSearchRight, CheckboxHideEmptyRight, LabelHideEmptyRight), the vanilla num = 0.004f coordinate offsets and FilterCharacter == 0 are all correct. Nicely researched work.
Unified Storage compatibility — needs a fix
Checked against OwendB1/se-unified-storage @ da09598.
Good news on layout: no collision. Unified Storage anchors its toggle to RightFilterSystemButton on the filter row (y = -0.338) and shifts the five filter buttons left; the Sort checkbox sits on the search row (y = -0.255). Disjoint. There is also no overlap in Harmony targets — Unified Storage patches Init/Close/Refresh/UpdateBeforeDraw/HandleInput/SetSearch/GetDefaultFocus, none of which this plugin touches.
The problem is functional. When Unified mode owns the right column, Unified Storage's Refresh prefix returns false, so vanilla Refresh never runs, CreateInventoryControlsInList is never reached, and CompareGuiControlInventoryOwners never fires. Two consequences:
-
The Sort checkbox is still drawn but does nothing. It is added from
MyGuiScreenTerminal.CreateInventoryPageRightSection, which Unified Storage does not patch, so the control appears regardless of who owns the panel. -
Toggling it corrupts the unified view.
RefreshInventoryList()reflectively invokes the privateCreateInventoryControlsInListand thenBlockSearchRight_TextChanged. Unified Storage's prefixes sit onRefreshandSetSearch, not on those two, so both calls bypass its suppression and repopulate the sharedm_rightOwnersControlwith vanilla per-container controls while Unified Storage still believes it owns the panel.
Suggested fix, which also simplifies the code: in RefreshInventoryList(), call the controller's public Refresh() instead of reaching past it into CreateInventoryControlsInList + BlockSearchRight_TextChanged. Refresh() is the game's own entry point, reaches CreateInventoryControlsInList through RightTypeGroup_SelectedChanged, needs no private reflection, and — because it is what Unified Storage prefixes — composes correctly instead of bypassing it. Tradeoff: it rebuilds both columns and resets the radio selection to the persisted indices, so please check scroll/focus still behave.
It would also be worth hiding the Sort checkbox when another plugin owns the right column, so it does not present a dead control.
Minor, non-blocking
- 42 × CS8632 warnings in Pulsar's compile log. The
Type?/MyEntity?annotations rely on the csproj's<Nullable>annotations</Nullable>andNoWarn, neither of which applies to the registry build. A single#nullable enable annotationsat the top ofPlugin.cssilences all of them. - Localization overlap. The Sort label and checkbox use absolute X (0.285 / 0.325) while vanilla's Hide Empty label is right-aligned at 0.419. A longer localized label pushes its left edge below 0.325 and overlaps. The search-box shrink is guarded by
if (searchBox.Size.X > 0.20f); these positions are not. - Wrong - Viktors_sortCheckbox/s_sortLabelare never cleared, andDispose()neither unpatches Harmony nor resets statics, so GUI controls outlive the terminal screen.GetTotalAvailableSpaceusesbreakwherecontinueis meant — an owner with a null inventory slot mid-range under-counts its free space.- Non-transitive comparator.
Math.Abs(spaceX - spaceY) > 0.0001fis not transitive, andSortNoAlloc→List.Sortcan throw on an inconsistent comparer. It needs a contrived chain of containers within 0.1 L of each other, so the risk is low. (TheKeepActiveContainerFirstdouble-1asymmetry mirrors vanilla exactly and is off by default, so it is not a new defect.) LICENSEreadsCopyright (c) 2026with no name.
Everything except the Unified Storage item is author-side polish and does not block.
|
Hello, I will adress these. Many thanks for review. Ofc I will add compability with unified - that georgous plugin. |
|
If you need any additional guidance let us know. |
|
Fixed at Unified Storage compatibility — implemented your suggested fix: Dead checkbox when another plugin owns the column — the Sort checkbox (and label) now hide whenever a plugin other than ours has a Harmony prefix on Minor items, all done:
Also fixed while verifying: the csproj's unconditional version defaults were silently overriding Thanks for the thorough review — the |
Adds Sort by Available Cargo.
Client-side Pulsar plugin that adds a Sort checkbox to the terminal inventory UI (right panel, next to Hide Empty). When enabled, inventory containers are ordered by remaining free cargo space (most empty first). MIT licensed.