feat/dual menu backend - #24
Merged
Merged
Conversation
…context Features call Render::Measure from PostRender (game thread) while the external overlay switches/destroys ImGui's global current-context on the Present thread; measuring through ImGui::GetFont() raced that global and crashed (access violation in GetFont). Cache the game context's default font once after init and measure through it - ImFont::CalcTextSizeA is a const, context-free call - so text measurement never touches GImGui and the cross-thread race is gone at the source. Supersedes the earlier null-context guard. Co-Authored-By: Claude Opus 4.8 <[email protected]>
… window Log (first frames + periodically) the focus state, back-buffer size, the frame's total vertex count, and the Present HRESULT, so the next run tells us why the overlay shows nothing: vtx==0 = recorded commands aren't reaching this draw list; vtx>0 but blank = DirectComposition isn't compositing; present!=0 = Present failed. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Selects which GUI engine draws the menu, independent of RendererMode (the ESP overlay renderer). Mirrors the RendererMode enum + NLOHMANN_JSON_SERIALIZE_ENUM and persists via the MenuSettings macro (missing key -> ImGui default). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Recovers the project's original UE-canvas immediate-mode GUI (ZeroGUI/ZeroInput) into menu/canvas/, adapted to the neutral Render API: all drawing routes through Render::canvas (no direct K2_Draw*, no per-scanline fill loops), s2wc dropped, colors normalized to 0-1, everything inline, and an array-form Combobox for the facade. ZeroInput samples all mouse buttons + keys each frame. Menu::UI (menu/ui/UI.h) is the backend-neutral widget vocabulary the sections call, dispatching on Settings.MENU.Backend: ImGui forwards to native ImGui / Custom.h widgets, Canvas forwards to ZeroGUI via Render::canvas. IsImGui()/ IsCanvas() gate the ImGui-only idioms; Vis() strips ##id suffixes for canvas text. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…hooks Menu::Tick draws the ZeroGUI menu through Render::canvas from PostRender (Engine:: Canvas is now published before the in-game gate, so the canvas menu works at the main menu / loading too) with a left tab column + content column and its own software cursor. The Ins toggle is factored into Menu::HandleToggle, shared by Draw (ImGui) and Tick (Canvas). Present gates Menu::Draw on the ImGui backend and only paints ImGui's cursor there; game-input capture stays keyed on ShowMenu. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…s on Canvas All 10 tab sections now call Menu::UI::* instead of ImGui:: directly, so the same section tree renders under either backend. The Visuals tab hosts the new Menu- backend combo. ImGui-only idioms (searchable map/class/skin combos in Misc, the SDK explorer, the Network redirect editor, Config profiles/share-codes, the Scripts/Debug child lists) stay behind if (UI::IsImGui()) guards and show a 'use the ImGui menu backend' note in Canvas mode. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Retint the ImGui style to the renamed token; Success (green) and Muted (gray) back the canvas checkbox mark and slider knob. Co-Authored-By: Claude Opus 4.8 <[email protected]>
The read counterpart to CopyToClipboard, so the DLL can paste without its own Win32 helper. Co-Authored-By: Claude Opus 4.8 <[email protected]>
IsMouseClicked/IsKeyPressed/IsAnyMouseDown/Handle + per-element state, for the UE-canvas menu (replaces the standalone UCanvasInput/ZeroInput). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Mutable FLinearColor members defaulting to Render::Palette; Accent is retinted per-frame for the RGB feature. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…dget components The monolithic ZeroGUI.h becomes an umbrella (UCanvasGUI.h) over components/: Core (shared state, draw primitives, layout, PostRenderer queue) plus one file per widget (Window, Text, Tab, Button, Checkbox, Slider, Combobox, Hotkey, ColorPicker, TextField, Selectable, CollapsingHeader, Combo, Child). Widgets draw through the active Render backend and the project Input namespace; dead helpers removed; naming brought to the project conventions. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Pure interface (no ImGui/UCanvasGUI) mirroring the Renderer strategy: lifecycle, window/tab chrome, core + rich widgets, clipboard. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Native ImGui widgets/chrome, demo & style windows, gamepad toggle, software cursor. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Window/tab chrome + every widget over UCanvasGUI, per-frame accent retint, input sampling, own cursor; clipboard via Shared::Utilities. Co-Authored-By: Claude Opus 4.8 <[email protected]>
backends[] ordered by MenuBackend; Menu::active + Menu::Select mirror Render.h. A third backend is a new file + enum value + one entry. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Every UI:: call is a one-line forward to Menu::active->*; drop IsImGui/IsCanvas/Vis and the per-backend branches. UI::Count replaces ImGui's IM_ARRAYSIZE. Co-Authored-By: Claude Opus 4.8 <[email protected]>
One backend-agnostic driver + shared Tabs[] list; each backend picks its own hook via phase(). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Menu::ToggleSetting lives in the UI facade now; sections call UI:: directly. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Drop the imguiMenu identity check; MouseDrawCursor defaults off (the ImGui backend re-enables it itself). Co-Authored-By: Claude Opus 4.8 <[email protected]>
…r first Replace the Menu::Tick gate with Menu::Frame(Phase::PostRender); run Render::Select unconditionally before it so the canvas menu draws through the selected backend even at the main menu. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add canvas/Colors.h, UCanvasGUI.h, components/*, and backend/*; remove the ZeroInput/ZeroGUI entries. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Drop the IsImGui-gated BeginDisabled; use UI::BeginDisabled/EndDisabled (a no-op where a backend has no disabled scope). Co-Authored-By: Claude Opus 4.8 <[email protected]>
The loaded-script list now draws via UI::BeginChild + UI:: widgets on both backends. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Profiles + share-code panels use UI::InputText/InputTextMultiline/clipboard instead of raw ImGui. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Console input, feature tree and log child go through UI::; the log's auto-scroll (no facade equivalent) is dropped. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Redirect editor + mitmproxy config + request flow use UI:: widgets (ToggleButton->UI::Toggle, clipper->UI::ClippedList). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Object/class/name-pool/instance explorers use UI::BeginChild + UI::ClippedList + UI::Selectable. Co-Authored-By: Claude Opus 4.8 <[email protected]>
FOV/speed, and the searchable load-into-map / spawn / cosmetics dropdowns, use UI:: rich widgets on both backends. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Build wchar->char narrowing explicitly (static_cast per char) instead of the std::string(begin,end) range ctor, which tripped C4244 in <xutility>. Hosts are ASCII, so the narrowing is safe; the cast just makes it intentional. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…e flip PostRender compares IsInGame against the previous frame and dispatches the transition, so features can react to entering a match / returning to the lobby instead of polling every frame. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…vent/payload to Run()
Feature::Event becomes Feature::Triggers (a vector, default {Render}); Execute runs a feature if Render is among its triggers, and Init subscribes each non-Render trigger to the bus. RunFeature forwards the triggering event + payload to Run(), which gains an overload chain (Run() / Run(event) / Run(event, payload)) so existing nullary overrides are untouched.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Subscribe to the two transition events instead of running every frame; drop the 5s throttle and refresh presence only when the in-game/in-lobby state changes (Run(event) logs which). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
Set Feature::ThrottleMs to cap how often Run() fires; the runner gates on ThrottleReady() (0 = every tick/event, so existing features are unchanged). Replaces the hand-rolled chrono throttle pattern. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Add PlayerKilled to the triggers so K/D updates on kills, not just the in-game/in-lobby transition; UpdateGameState's change-guard means it only pushes to Discord on the local player's own kills/deaths. Co-Authored-By: Claude Opus 4.8 <[email protected]>
A plain field read (no ProcessEvent) giving each actor a lifetime-stable key for per-actor state / a future spawn-despawn diff. Available but not yet wired to a consumer. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Code-patch-free hook (PAGE_GUARD + a vectored exception handler that redirects RIP to the detour and single-steps to re-arm), an alternative to the MinHook trampoline for a code-integrity-sensitive, low-frequency target. Opt-in primitive; not wired to a live hook yet. Documents its one-exception-per-call cost and the re-arm race. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
…in the dump) A dump search (FunctionsInfo.json) found reflected Server* hit/fire RPCs (ALineTraceGun::ServerNotifyHit, AShotgun::ServerProcessHits, AProjectileGun::ServerSpawnProjectile, ...); on the client these dispatch through ProcessEvent, so the existing funnel can rewrite the hit params without a native AOB hook. Correct the BLOCKED note and record the remaining work. Co-Authored-By: Claude Opus 4.8 <[email protected]>
InternalIndex is a reused slot index, so it aliases after free exactly like a pointer — it doesn't give the reuse-safe identity the doc claimed, and its intended consumer (the spawn/despawn-diff cache) was skipped. Reuse-safe identity would need a pointer+SerialNumber handle instead. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Persisted font name for the UE-canvas renderer; empty = the engine default (Roboto). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Lazily-built name+pointer list of UFont objects (mirrors ClassCache), with Find(name) to resolve one; Rebuild() rescans for newly-loaded fonts. Co-Authored-By: Claude Opus 4.8 <[email protected]>
CanvasRenderer resolves Settings.VISUALS.CanvasFont via FontCache (re-resolving only when the setting changes) and passes it to K2_DrawText/K2_TextSize/K2_StrLen instead of the null (Roboto) font. Co-Authored-By: Claude Opus 4.8 <[email protected]>
When the renderer is UE Canvas, a font combo (Default/Roboto + every UFont from FontCache) and a Refresh button; ImGui mode uses its own atlas so the picker is hidden there. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
…patch New cases: Execute runs a feature when Render is among several triggers; ThrottleMs gates a repeated run and reopens after the interval (back-dating lastRun, no sleep); RunFeature forwards the event to Run(event) and the event+payload to Run(event, payload). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Convert the batched 'changed |= UI::Toggle' toggles to UI::ToggleSetting (per-control dispatch tagged with the label), matching the Exploits tab; combos/sliders keep the tab's batched dispatch. Finishes the SettingsChanged-payload rollout for Aim, Visuals, and Network. Co-Authored-By: Claude Opus 4.8 <[email protected]>
SelfTest guard-hooks a scratch VirtualAlloc'd page (a lone ret) and confirms the detour ran instead — an in-process proof that touches no game code. A 'Test GuardHook' button in Debug runs it and logs the result. Also routes the Debug tab's toggles through UI::ToggleSetting (the same SettingsChanged-payload rollout). Co-Authored-By: Claude Opus 4.8 <[email protected]>
Writes the whole cached FName pool (NameCache) to Dumps/FNames.txt, beside the existing GObjects dump. Co-Authored-By: Claude Opus 4.8 <[email protected]>
47PADO47
added this pull request to stack #25
September 14, 2026 17:54
Drop the push/pull_request triggers so the build only runs on manual workflow_dispatch. Update actions/checkout to v7, actions/setup-python to v7, microsoft/setup-msbuild to v3, and actions/upload-artifact to v7. Co-Authored-By: Claude Opus 4.8 <[email protected]>
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.
Stack created with GitHub Stacks CLI • Give Feedback 💬