feat(KitsunePackRelayLauncher): v0.1 scaffold + verified hook (#227) - #97
Merged
Merged
Conversation
…_MainMenu.OnOpen (#227)
New sibling mod to KitsuneJoinDiag -- the in-game half of the
"make every Connect button actually one-click into the server"
loop tracked as Kitsunebi #227.
## What this lands (v0.1, scaffold)
- `src/KitsunePackRelayLauncher/KitsunePackRelayLauncher.csproj`
-- mirrors KitsuneJoinDiag's csproj shape; targets net48,
references the shared refs/ dir DLLs.
- `src/KitsunePackRelayLauncher/ModInfo.xml`.
- `src/KitsunePackRelayLauncher/ModEntry.cs` -- standard
Harmony.PatchAll bootstrap.
- `src/KitsunePackRelayLauncher/Patches/MainMenuOpenedPatch.cs`
-- the hook + sentinel-file reader + freshness gate.
## Reflection findings
Spelunked `Assembly-CSharp.dll` via Mono.Cecil from PowerShell
during the 2026-05-28 session. The two key types confirmed:
- `XUiC_MainMenu.OnOpen()` -- fires when the main menu becomes
visible after the splash dismisses. The hook this mod uses.
- `XUiC_ServerBrowserDirectConnect` -- the Direct Connect dialog.
Fields: `txtIp` (XUiC_TextInput), `txtPort` (XUiC_TextInput),
`btnDirectConnectConnect` (XUiC_SimpleButton), `btnCancel`,
`ipPortMatcher` (Regex). This is what v0.2 will drive.
Full notes: `D:\Claude\Claude\runbooks\packrelay-quickjoin-mod-plan.md`.
## Hook + sentinel-file convention
Postfix on `XUiC_MainMenu.OnOpen()` checks for
`<userdatafolder>/packrelay-quickjoin.json`:
```
{
"host": "play.kitsuneden.net",
"port": 26900,
"writtenAt": "2026-05-28T19:30:00Z"
}
```
with a 60s freshness gate so an interrupted launch followed by
the user manually opening the game later doesn't surprise-join,
and a sentinel from yesterday doesn't fire today. On fire, the
mod deletes the sentinel so a re-open of the main menu (player
quitting back from a server, say) doesn't re-fire.
The patch is also guarded by a session-static `_firedThisSession`
flag for the same reason: only the FIRST OnOpen of the process
checks the sentinel.
## Why this is v0.1 stub-only
v0.1 logs what it WOULD do and deletes the sentinel; it doesn't
actually fire the Direct Connect. v0.2 will fill in the UI
driving:
1. Locate `XUiC_ServerBrowserDirectConnect` window in the live
XUi tree.
2. Set `txtIp` / `txtPort` field text to the sentinel values.
3. Invoke `btnDirectConnectConnect.OnPressed` -- same delegate
the actual button click fires.
Splitting v0.1 / v0.2 lets us verify the hook attaches + the
sentinel-reading round-trip works end-to-end before adding the
UI manipulation that's harder to debug.
## Launcher side (NOT in this PR)
The PackRelay launcher's `launch_game` Tauri command (in
`packrelay-launcher` repo) will need to start writing
`packrelay-quickjoin.json` into the active profile's userdatafolder
before spawning 7DTD. That's a small Rust change deferred to the
v0.2 push so this PR stays mod-only.
## Safety
- Postfix is wrapped in try/catch -- a parse / read / delete
failure logs a warning but never breaks 7DTD's main menu open
path. The player can always use the UI normally.
- Stale sentinel detection + deletion means a launcher that
crashed before launching 7DTD doesn't leave a time bomb for
the next manual launch.
- Harmless on dedicated servers (XUiC code path doesn't fire
server-side), so safe to ship in a both-sides pack.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #227 — the in-game half of "make every Connect button across the launcher actually one-click into the server."
Sibling mod to KitsuneJoinDiag. KitsuneJoinDiag surfaces the actual DisconnectReason when joins FAIL; this mod is the SUCCESS-path counterpart that skips the splash → main menu → Direct Connect → paste → CONNECT dance when the launcher hands off a known target.
v0.1 scope (this PR — scaffold + verified hook)
Lands a working mod that:
dotnet build -c Releasesucceeds; the type references (XUiC_MainMenu,nameof(XUiC_MainMenu.OnOpen)) resolve against the real game assemblies.<userdatafolder>/packrelay-quickjoin.jsononXUiC_MainMenu.OnOpen()(postfix), with a 60s freshness gate.Output on a sentinel hit looks like:
Reflection findings (the spelunk)
Used Mono.Cecil from PowerShell to enumerate
Assembly-CSharp.dll. Key candidates surfaced:XUiC_MainMenu.OnOpen()— the hook this mod uses. Fires when the main menu becomes visible after splash dismissal.XUiC_ServerBrowserDirectConnect— the Direct Connect dialog. Fields visible:txtIp(XUiC_TextInput),txtPort(XUiC_TextInput),btnDirectConnectConnect(XUiC_SimpleButton),btnCancel,cancelTarget,ipPortMatcher(Regex). This is what v0.2 will drive.Full notes in vault:
D:\Claude\Claude\runbooks\packrelay-quickjoin-mod-plan.md.What's NOT in this PR
txtIp/txtPortfield text + firebtnDirectConnectConnect.OnPressed. The strategy is documented in the patch's doc comment; implementing it needs careful XUi-tree-walking that's easier to debug as a focused follow-up.launch_gameTauri command will need to writepackrelay-quickjoin.jsoninto the active profile's userdatafolder before spawning 7DTD. Small Rust change inpackrelay-launcherrepo, deferred.Safety
Test plan
dotnet build -c Releasefromsrc/KitsunePackRelayLauncher/succeeds (it does — verified in this commit).KitsunePackRelayLauncher.dll+ModInfo.xmlinto a 7DTD client's Mods folder.[KitsunePackRelayLauncher] WOULD auto-connectblock (because no sentinel).<userdatafolder>/packrelay-quickjoin.jsonwith validhost/port/writtenAt: <now>. Launch 7DTD. After main menu appears, theWOULD auto-connectblock appears inPlayer.logwith the correct host/port. The sentinel file is gone after.writtenAt: 2026-05-27T00:00:00Z(yesterday). Launch 7DTD. The stale-sentinel log line appears; sentinel deleted; noWOULD auto-connect.🤖 Generated with Claude Code