refactor: move the input hook and the proxy into core - #28
Merged
Merged
Conversation
Neither depends on the game version. The WH_GETMESSAGE hook, the game-window WndProc subclass and the injected-input tagging move to core/input; the SOCKS5 connect hook moves to core/proxy. The backend now hands core a table of callbacks instead of core reaching into the backend, so the dependency runs one way. The input callbacks are plain function pointers, matching the GameCallbacks entries they are fed from. Remove() clears the table from a different thread than the one dispatching, and under std::function that destroyed a callable while it was executing; each dispatch site also loads its pointer once, so a clear between the guard and the call cannot turn it into a null call. Unhooking has to happen on the window thread, the only one that runs the hook procedure and the subclass. GameThread::Execute cannot carry it there - by teardown the frontend has shut its engine down and the per-frame drain no longer runs - so Remove sends a private message and falls back to the caller thread if the window does not answer. Contract. InstallHooks returns bool and the frontend aborts init rather than running on half-installed hooks. game::console::BackendPanel lets a backend contribute console tabs as an interface instead of a list of function pointers; the 1.14d backend contributes none. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ResurrectedTrader
force-pushed
the
split/core-moves
branch
from
September 16, 2026 22:32
00f123e to
d5cad54
Compare
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.
Targets
maindirectly; #27 has landed. Last of the five PRs that replaced the original combined branch.Neither the input hook nor the SOCKS5 proxy depends on the game version, so neither belongs in a backend.
The moves
core/input/— theWH_GETMESSAGEhook, the game-window WndProc subclass, and the injected-input tagging. The backend now hands core a table of callbacks rather than core reaching into the backend, so the dependency runs one way.core/proxy/— the SOCKS5 connect hook, previouslylod114d/hooks/Socks5Proxy.cpp. A near-verbatim move; git shows it as a rename.Two things in here that are not just moves
The input callbacks are plain function pointers, not
std::function.Remove()clears the table from a different thread than the one dispatching, and tearing down astd::functionunder a caller destroys the callable while it is executing. They're fed fromGameCallbacksentries, which were already raw pointers, so nothing had to adapt. Each dispatch site also loads its pointer once into a local — otherwise a clear landing between the null check and the call turns the guard into a null call.Unhooking has to run on the window thread, the only one that runs the hook procedure and the subclass, so neither can be mid-call while it happens.
GameThread::Executecan't carry it there: by teardown the frontend has shut its engine down and the per-frame drain no longer runs, so the post would never land.Removetherefore sends a privateWM_REMOVE_INPUT_HOOKSand falls back to retiring from the caller's thread if the window doesn't answer within two seconds.That fallback has a cost worth knowing about: teardown runs under the loader lock, so if the game thread is itself blocked there, unload stalls for the full two seconds before falling through.
Contract changes
InstallHooksreturnsbool, and the frontend aborts init rather than running on half-installed hooks. The 1.14d backend always returnstruetoday, so this is a contract change with no behaviour change yet.game::console::BackendPanellets a backend contribute console tabs as an interface instead of a list of function pointers. The 1.14d backend contributes none.Both exist so a second backend has somewhere to plug in; neither does anything visible in this tree.
Docs
docs/window_message_handling.mdis updated for the move, the function-pointer change, and the teardown handshake — the last of which the doc never described.Verification
clang-format clean; clang-tidy clean (118 files, full no-cache run). Not exercised at runtime by me; the teardown path in particular deserves a live check, since it's the one with new cross-thread behaviour.
🤖 Generated with Claude Code