Skip to content

feat/dual menu backend - #24

Merged
47PADO47 merged 54 commits into
refactor/ue-splitfrom
feat/dual-menu-backend
Sep 14, 2026
Merged

47PADO47 merged 54 commits into
refactor/ue-splitfrom
feat/dual-menu-backend

Conversation

@47PADO47

Copy link
Copy Markdown
Member

Stack created with GitHub Stacks CLIGive Feedback 💬

47PADO47 and others added 30 commits September 6, 2026 08:02
…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 <noreply@anthropic.com>
… 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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
The read counterpart to CopyToClipboard, so the DLL can paste without its own Win32 helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
IsMouseClicked/IsKeyPressed/IsAnyMouseDown/Handle + per-element state, for the UE-canvas menu (replaces the standalone UCanvasInput/ZeroInput).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Mutable FLinearColor members defaulting to Render::Palette; Accent is retinted per-frame for the RGB feature.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
Pure interface (no ImGui/UCanvasGUI) mirroring the Renderer strategy: lifecycle, window/tab chrome, core + rich widgets, clipboard.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Native ImGui widgets/chrome, demo & style windows, gamepad toggle, software cursor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
One backend-agnostic driver + shared Tabs[] list; each backend picks its own hook via phase().

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Menu::ToggleSetting lives in the UI facade now; sections call UI:: directly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the imguiMenu identity check; MouseDrawCursor defaults off (the ImGui backend re-enables it itself).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add canvas/Colors.h, UCanvasGUI.h, components/*, and backend/*; remove the ZeroInput/ZeroGUI entries.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 <noreply@anthropic.com>
The loaded-script list now draws via UI::BeginChild + UI:: widgets on both backends.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Profiles + share-code panels use UI::InputText/InputTextMultiline/clipboard instead of raw ImGui.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Redirect editor + mitmproxy config + request flow use UI:: widgets (ToggleButton->UI::Toggle, clipper->UI::ClippedList).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Object/class/name-pool/instance explorers use UI::BeginChild + UI::ClippedList + UI::Selectable.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
47PADO47 and others added 23 commits September 6, 2026 18:13
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Persisted font name for the UE-canvas renderer; empty = the engine default (Roboto).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
Writes the whole cached FName pool (NameCache) to Dumps/FNames.txt, beside the existing GObjects dump.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@47PADO47
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 <noreply@anthropic.com>
@47PADO47
47PADO47 merged commit 0b18d2f into master Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant