334 Commits

Author SHA1 Message Date
IChooseYou
d22661446b feat: turn sentinel dock tab into "+" new tab button
Instead of hiding the sentinel tab (which leaked space on macOS),
repurpose it as a visible "+" button that creates a new struct tab
on click. Compact 32px icon-only tab with pixel-perfect cross drawn
via fillRect. Skips context menu and middle-click. Always positioned
as the last tab in the group.
2026-03-16 07:39:18 -06:00
IChooseYou
ecb954f9e2 fix: dock tab sizing and scanner dock area restrictions
- Add 24px width padding to dock tab size calculation to account for
  DockTabButtons close icon (prevents text clipping into button area)
- Enable scroll buttons on dock tab bars so tabs scroll instead of
  compressing when they overflow
- Allow scanner dock to be docked on all sides (was missing TopDockWidgetArea)
2026-03-15 18:50:40 -06:00
IChooseYou
747cbd93d8 Merge pull request #13 from NohamR/mac 2026-03-15 16:07:23 -06:00
IChooseYou
44fbc2e6d6 fix: dock tab labels hard-clip instead of eliding
The previous middle-elide logic had a 2x threshold that caused text
between 1x and 2x overflow to draw un-elided into a clipped rect,
producing ugly truncation like "Projec" instead of "Proje…".

Replace with Qt's built-in elidedText (right-elide) which always
produces clean "…" truncation when text overflows the tab width.
2026-03-15 15:22:02 -06:00
IChooseYou
bc94a595c7 fix: sidebar dock tabs get functional close buttons when tabified
When Project and Modules docks are tabified together, Qt creates a
tab bar with close buttons via setupDockTabBars(). The dock lookup
only searched m_docDocks, so sidebar dock close buttons were installed
but never connected — clicking × did nothing.

Now the lookup also checks m_workspaceDock, m_scannerDock, and
m_symbolsDock. Middle-click close and right-click context menu also
work for sidebar tabs. Sidebar tabs get a minimal context menu
(Close + Float/Dock) while doc tabs keep the full menu.
2026-03-15 15:19:08 -06:00
√(noham)²
b4727df3e9 Add macOS support for ProcessMemory plugin
Implement macOS-specific support for the ProcessMemory plugin and update plugin discovery/build.

- Add macOS build/install support: include plugins/ProcessMemory in top-level CMake and copy the built plugin into Reclass.app/Contents/PlugIns on macOS.
- Implement Apple-specific ProcessMemoryProvider: task_for_pid usage, mach_vm_read_overwrite/mach_vm_write, proc_pidpath/proc_regionfilename based module caching, region enumeration, symbol formatting, module enumeration, and proper cleanup (mach_port_deallocate).
- Extend plugin header to track m_task and adjust readability checks for macOS.
- Add macOS handling in getInitialBaseAddress and process enumeration to find base addresses and processes using proc APIs.
- Improve PluginManager to probe multiple plugin locations (including Contents/PlugIns inside macOS bundles), aggregate/log candidate counts, and continue scanning multiple dirs.
- Add macOS screenshot to README (docs/README_PIC6.png) and reference it in README.

These changes enable the ProcessMemory plugin to operate on macOS and make plugin discovery more robust on macOS app bundles.
2026-03-15 14:47:48 +01:00
IChooseYou
b2a81ea687 fix: dock tab labels elide too aggressively on short names
"Project" showed as "Pr…ct" and "Modules" as "Mod…les" when two
dock widgets shared a narrow side panel. The middle-elide logic
kicked in as soon as text exceeded the available width. Now it
only elides when the text is more than 2x the available width,
so short names render in full and only genuinely long names
(like struct type names in doc tabs) get truncated.
2026-03-15 07:38:03 -06:00
IChooseYou
dc6963e0d5 feat: extract typeIndex from PDB symbols and add symbols.importType MCP tool
extractPdbSymbols() was reading S_GDATA32/S_GTHREAD32 records which
contain a typeIndex field linking the symbol to its type definition in
the TPI stream, but this field was discarded — only name + RVA were
kept. This meant loading symbols gave you address resolution but no
way to automatically import the type associated with a global variable.

Changes:
- PdbSymbol now carries typeIndex (0 = no type info / public symbol)
- extractPdbSymbols() captures typeIndex from all global data symbols
- PdbSymbolSet stores nameToTypeIndex mapping alongside nameToRva
- New importTypeForSymbol() follows LF_POINTER/LF_MODIFIER chains to
  find the underlying UDT/enum and imports it with full recursive children
- New symbols.importType MCP tool: given "ntdll!g_pShimEngineModule",
  resolves its typeIndex, imports the type definition from the PDB, and
  merges it into the active project
- loadPdbIntoStore() helper consolidates the extract+store pattern with
  type index support
2026-03-14 18:11:57 -06:00
IChooseYou
cb10bc8a82 docs: remove dedicated kernel driver section from README snapshot-15-03-2026 2026-03-14 17:47:07 -06:00
IChooseYou
b5521bd638 docs: add kernel driver plugin to README
Document the KernelMemory plugin — capabilities, driver build
instructions, and architecture diagram.
2026-03-14 17:45:21 -06:00
IChooseYou
89d6e1944b fix: guard computeOffset against negative results before address arithmetic
computeOffset() returns int64_t but most callers added the result directly
to baseAddress (uint64_t) without checking for negative values. A malformed
tree with negative cumulative offsets would produce wrapped addresses,
potentially reading/writing arbitrary memory in the bitfield toggle and
edit paths. Added sign checks at all 9 unguarded call sites.
2026-03-14 17:31:13 -06:00
IChooseYou
7528d1bbbb Merge pull request #12 from 70RMUND/fix/linux-menubar-toolbuttons
fix: Linux menu bar horizontal layout via QToolButton fallback
2026-03-14 16:07:39 -06:00
Your Name
4f2288048e fix: Linux menu bar renders as horizontal tool buttons instead of collapsed extension popup
On Linux, QMenuBar inside a custom title bar widget (setMenuWidget) collapses
all items into the extension overflow popup. Replace with QToolButton widgets
on Linux that share the same QMenu objects. Includes hover-to-switch behavior
via event filter on open menus.

Windows and macOS paths are unchanged — guarded by #ifdef __linux__ and
runtime m_useToolButtons flag.
2026-03-14 15:51:31 -04:00
IChooseYou
97b6f55e1f fix: Linux menu popups and SVG icon rendering
- Guard FramelessWindowHint + WA_TranslucentBackground on QMenu to
  Windows only — breaks popup submenus on Linux/Wayland compositors
- Render SVG icons via QSvgRenderer to QPixmap explicitly, avoiding
  dependency on the qsvgicon image format plugin which may not be
  deployed on Linux
2026-03-14 12:41:11 -06:00
IChooseYou
6a30e0a402 fix: replace remaining QList::append({}) in plugins and tests
Missed plugin and test directories in the previous Qt 6.8 compat fix.
2026-03-14 12:11:08 -06:00
IChooseYou
1501a1542c feat: symbol double-click navigation, tree icons, and module.dll address parsing
- Double-click symbol in Symbols tab navigates to moduleBase + RVA
- Add symbol-method.svg icon for function symbols, symbol-structure.svg for modules
- Force-populate all modules on search so filter works without expanding first
- Parse module.dll/exe/sys as identifiers in address bar (e.g. client.dll + 0xFF)
2026-03-14 11:57:32 -06:00
IChooseYou
4f82b39785 fix: uint64_t to QVariant ambiguity on Qt 6.8 Linux 2026-03-14 11:52:45 -06:00
IChooseYou
009ddc951c fix: commit remaining uncommitted source changes for CI
Add extractPdbSymbols declaration to import_pdb.h,
enumerateModules to provider.h, and other pending changes
that were only local.
2026-03-14 09:36:49 -06:00
IChooseYou
5921af2b4f fix: replace QList::append({}) with push_back/emplaceBack for Qt 6.8
Qt 6.8's stricter QList rejects brace-enclosed initializer lists in
append(). Fixed 43 call sites across 13 files.
2026-03-14 09:21:14 -06:00
IChooseYou
5ded192990 fix: sync tab title on keyword convert, add new screenshots
- Update dock tab title when converting enum/class via workspace menu
- Add tooltip and source picker screenshots to README
2026-03-14 09:14:28 -06:00
IChooseYou
54bee5022b fix: add missing symbols dock declarations to mainwindow.h 2026-03-14 09:03:41 -06:00
IChooseYou
5d2d324946 fix: add missing symbol store and PDB debug info sources
These files were referenced in CMakeLists.txt and main.cpp but
never committed, breaking the CI build.
2026-03-14 08:13:58 -06:00
IChooseYou
5b2cf1ae1f feat: arrow tooltip improvements and base address cheat sheet
- Scale tooltip font to 90% of editor font
- Replace inline edit hint for base address with hover tooltip
- Two-column cheat sheet: syntax examples + explanations
- Dismiss all popups on alt-tab (ActivationChange)
2026-03-14 08:03:23 -06:00
IChooseYou
f1a36f2ad3 feat: custom arrow tooltip with transparent background
Rewrite RcxTooltip to use WA_TranslucentBackground with a single
contiguous QPainterPath (rounded rect + arrow notch). Pre-set the
DarkTitleBar property to prevent DarkApp from calling
DwmSetWindowAttribute which breaks layered window compositing.

Dismiss all popups (including arrow tooltip) on alt-tab via
MainWindow::changeEvent(ActivationChange).
2026-03-14 06:45:45 -06:00
IChooseYou
665138e688 fix: force all nodes collapsed on file load
Prevents 512-element arrays from expanding on load and triggering
thousands of memory reads. Root nodes still show children via
isRootHeader override.
2026-03-14 06:05:53 -06:00
IChooseYou
7688bb5b92 ci: add SDK include paths for WDK NuGet driver build
NuGet splits WDK and SDK into separate packages. specstrings.h
lives in the SDK shared headers. Add SDK_INC_ROOT for shared/ucrt.
snapshot-14-03-2026
2026-03-14 05:40:24 -06:00
IChooseYou
701e088be8 ci: install WDK via NuGet for driver build in CI
Runner doesn't have WDK headers installed. Use NuGet to install
Microsoft.Windows.WDK.x64 and pass paths via env vars.
build_driver.bat now accepts WDK_INC_ROOT/WDK_LIB_ROOT overrides.
2026-03-14 05:20:23 -06:00
IChooseYou
3c0c248d54 fix: use delayed expansion in build_driver.bat for CI
Parentheses in "Program Files (x86)" broke cmd parser inside
for loop bodies. Switch to !var! delayed expansion.
2026-03-14 04:56:46 -06:00
IChooseYou
7af969f6bd ci: build kernel driver and include rcxdrv.sys in release
Add build_driver.bat step to Windows CI using runner's MSVC + WDK.
Copy rcxdrv.sys into Plugins/ in the release zip.
2026-03-13 15:27:51 -06:00
IChooseYou
8ba1fd2492 fix: auto-detect MSVC and WDK paths in build_driver.bat
Remove hardcoded MSVC 14.39.33519 and WDK 10.0.22621.0 paths.
Now scans for the newest installed version automatically.
2026-03-13 15:05:59 -06:00
IChooseYou
b08736245b feat: kernel memory plugin + unified source menu + driver improvements
- KernelMemory plugin: kernel-mode process/physical memory R/W via IOCTL driver
- rcxdrv.sys: MmCopyMemory for reads, MDL mapping with correct cache types
  (MmCached for RAM, MmNonCached for MMIO only — fixes cache corruption BSOD)
- Driver reconnect: ensureDriverLoaded tries device handle first, no auto
  stop+delete cycle. Manual unload closes handle only, service stays running.
- Unified source menu: ProviderRegistry::populateSourceMenu() shared by both
  main window Data Source menu and RcxEditor inline picker (icons + dll names)
- IProviderPlugin::populatePluginMenu() for conditional plugin actions
  (e.g. "Unload Kernel Driver" only when loaded)
- Physical memory mode removed from selectTarget (access via context menu only)
- requestOpenProviderTab sets base address from provider after template load
- Address parser: vtop(), cr3(), physRead() callbacks for kernel paging expressions
2026-03-13 14:46:22 -06:00
IChooseYou
7f7bbdcc45 fix: remove isRelative references from generator.cpp
Node::isRelative is not yet in the pushed core.h, breaking CI builds.
snapshot-13-03-2026
2026-03-12 18:07:34 -06:00
IChooseYou
79b5125229 fix: remove unreleased isRelative/ToggleRelative references from controller
These were local-only changes that referenced cmd::ToggleRelative and
Node::isRelative which don't exist in the pushed core.h, breaking CI.
2026-03-12 16:30:59 -06:00
IChooseYou
3aeb1a80d5 feat: inline hex byte and ASCII preview editors for hex nodes
Right-click context menu adds "Edit Hex Bytes" and "Edit ASCII" for
hex nodes (Hex8/16/32/64). Both are fixed-length overwrite-mode editors
with space-skipping, input validation, and IND_HEX_DIM indicator
preservation.
2026-03-11 16:01:37 -06:00
IChooseYou
3b7ed682ac Merge commit 'refs/pull/11/head' of github.com:IChooseYou/Reclass
# Conflicts:
#	src/mcp/mcp_bridge.cpp
2026-03-10 16:02:12 -06:00
IChooseYou
0582cb286b fix: commit missing selectPage() for OptionsDialog 2026-03-10 15:43:27 -06:00
IChooseYou
ea85b7a621 feat: add C# and Python ctypes code generators
- C# backend: [StructLayout(LayoutKind.Explicit)] with [FieldOffset], IntPtr pointers, fixed arrays, enums
- Python backend: ctypes.Structure with _fields_, POINTER() for typed pointers, c_void_p, padding
- Both support enums, vectors, bitfields, arrays, unions, static fields
- Export menu: C# Structs... and Python ctypes... entries
- Format combo auto-populates new options
- 14 new tests for both backends (all passing)
2026-03-10 15:20:56 -06:00
IChooseYou
6c8b7d3d97 feat: Rust/#define generators, code tab format/scope combos, enum #define support
- Add Rust #[repr(C)] and #define offset code generators with dispatch
- Add format combo + scope combo + gear button as corner widget on Code tab
- Corner controls hidden on Reclass tab, shown only on Code tab
- Chevron-down SVG arrows on combo dropdowns for consistent styling
- Fix enum #define output: emit named members instead of empty 0x0 struct
2026-03-10 15:05:23 -06:00
IChooseYou
d1321b5165 fix: per-group sentinel docks, editor inline-edit comment alignment
Sentinel dock refactored to per-tab-group model — each split group gets
its own hidden sentinel so tab bars stay visible without the Hide event
filter hack.  Editor inline-edit comment column now anchors correctly
for base-address edits and shows expression hint instead of generic text.
2026-03-09 11:44:55 -06:00
IChooseYou
483f87cfbd feat: type hints green [bracketed] notation, workspace cleanup, unique naming
- Type inference hints now show value-first with bracketed type in comment
  green: "0x7ff718570000 [ptr64]", "6, 16 [int32_t×2]"
- Raise hint threshold to strong-only (score >= 75%)
- Remove Bool inference, widen Int16 range to ±16384
- Workspace: remove dead WorkspaceProxy, fix null deref, debounce search,
  cache icons, add pinning support
- Unique naming: UnnamedClass0/UnnamedEnum1 with global counter
- Footer buttons: +10h +100h +1000h replacing +1024
- MCP: project lifecycle API, snapshot provider fix
snapshot-09-03-2026
2026-03-09 10:39:22 -06:00
noita-player
4d0782db68 MCP bridge: support multiple concurrent clients
Replace single-client model (m_client/m_readBuffer/m_initialized)
with a ClientState vector. Each client gets its own read buffer and
initialized flag. Responses route to m_currentSender (set during
request processing); notifications broadcast to all initialized
clients.

Re-entrancy guard in onReadyRead: re-resolve ClientState after each
processLine() call since sendJson flush can re-enter the event loop
and trigger onDisconnected, removing the client mid-iteration.

Tests: 378-line test_mcp exercising connect, initialize, tools/list,
disconnect one client, notification broadcast, and serial requests
against a MockMcpServer with the same multi-client architecture.
2026-03-08 22:44:47 -07:00
noita-player
51de48a6ed Add MCP scanner tools, source.modules, reconnect, and constraint regions
Scanner engine:
- Add constrainRegions to ScanRequest — callers pass address ranges
  that are intersected with provider regions before scanning
- Merge overlapping/adjacent constraints to prevent duplicate results
- Fix final-chunk overlap: skip overlap advance on last chunk to avoid
  re-scanning the tail of a region

MCP tools:
- scanner.scan: value scans (int/float types) with optional region
  constraints, returns first 15 addresses
- scanner.scan_pattern: pattern/signature scans with wildcards
- source.modules: list loaded modules with base address and size
- mcp.reconnect: graceful client disconnect for IDE reconnection
- parseInteger() helper for hex string args (avoids JSON double
  precision loss on 64-bit addresses)
- Fix baseRelative semantics in hex.read/hex.write (was inverted)
- Auto-set tree.baseAddress from provider after process attach

Scanner panel:
- runValueScanAndWait() and runPatternScanAndWait() for blocking
  scan execution from MCP/automation code

Tests: 41 new test cases for constrainRegions covering gaps, partial
overlap, adjacent regions, writable filter, degenerate ranges,
overlapping constraints, boundary patterns, alignment, and value
types at region start/end positions.
2026-03-08 22:44:46 -07:00
noita-player
7b9b140823 Fix MCP use-after-free, scanner chunk overlap, build scripts
- MCP bridge: guard against use-after-free when client disconnects
  during sendJson flush by re-checking m_client after write
- Scanner engine: fix chunk overlap advancing past region end on
  final chunk; fix fallback region flags for providers without
  enumerateRegions
- Build scripts: prefer GCC MinGW over LLVM-MinGW in PATH detection
2026-03-08 22:44:36 -07:00
IChooseYou
a21e5a07a8 feat: replace +1024 footer button with +10h +100h +1000h granular grow
- Three hex-sized grow buttons: +10h (16B), +100h (256B), +1000h (4096B)
- Single-space gaps between buttons for tighter layout
- All click, hover, cursor, and pill styling updated
- Enum +10 button unchanged and correctly disambiguated

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 16:38:03 -06:00
IChooseYou
25afbe373b feat: status bar format, tab titles with source, taller tabs, pill hover, source switch base fix
- Status bar: show StructName.field +0xOFFSET with dimmed offset suffix
- Status bar: sync font to global editor font (JetBrains Mono 10pt)
- Dock tab title: include active source name (StructName — source.exe)
- Dock tabs +10% height (28→31), pane tabs (24→26), workspace title (26→29)
- Footer pills (+1024, Trim, +10): add visual hover highlight via IND_HOVER_SPAN
- Fix source switch keeping old base address for plugin providers
2026-03-08 16:29:12 -06:00
IChooseYou
6a4cb47ed4 fix: kill Fusion outline on QScintilla, type inference hints, workspace styling
- Suppress PE_Frame on QsciScintilla in MenuBarStyle to eliminate the
  1px dark (#171717) Fusion outline around the editor area
- Add --screenshot flag for automated pixel regression testing
- Add type inference engine (typeinfer.h) with hex pattern analysis
- Show inferred type hints on hex nodes in compose output
- Style workspace tree corner/header widgets to match theme
- Fix integer overflow in compose.cpp array element addressing
- Fix integer overflow in core.h structSpan calculation
- Add bounds check on activePaneIdx in controller
- Use QPointer for deferred dock lambda safety
- Workspace delegate uses icon Normal/Disabled for viewed state
2026-03-08 10:26:12 -06:00
IChooseYou
431e2b90c9 perf: TypeSelector — zero-alloc fuzzy scorer, warm popup 75% faster
Stack arrays + pre-lowered QChars in fuzzyScore eliminate all heap
allocations in the hot path. applyFilter uses indices instead of
deep-copying TypeEntry. popup() width estimated from cached max name
length. QListView: uniform sizes, batched layout, cached sizeHint.

Benchmark (5000 structs): warm popup 27ms→7ms, filter 5ms→1.7ms.
2026-03-08 08:33:21 -06:00
IChooseYou
43365c1aff fix: close project actually destroys dock, editor perf single-pass line attributes
- Set WA_DeleteOnClose on doc docks so all close paths trigger cleanup
- Create fresh empty class when last project closes
- Add splitDockWidget/resizeDocks to project_new() so workspace doesn't eat editor space
- Merge applyMarginText, applyMarkers, applyFoldLevels into single-pass applyLineAttributes
- Cache line texts for heatmap/symbol coloring passes (avoid redundant Scintilla IPC)
- Zero-alloc scroll width scan replaces QString::split
2026-03-08 08:13:36 -06:00
IChooseYou
596f410b96 perf: compose 30% faster — move semantics, BFS offsets, zero-alloc hex formatting
- compose.cpp: emitLine takes LineMeta&& (move, not copy) at all 22 call sites
- compose.cpp: reserve meta/text buffers, BFS offset computation O(N) vs O(N*D)
- compose.cpp: pre-compute typeNameLens[], merge global width loops
- format.cpp: bytesToHex uses stack buffer + lookup table (zero heap allocs)
- format.cpp: hexVal single QString::asprintf instead of 2-string concat
- editor.cpp: guard hover updates during applyDocument (stale index safety)
- core.h: assertion on makeArrayElemSelId negative index
- format.cpp: assertion on extractBits overflow
- main.cpp: tree lines enabled by default
- bench_large_class: add 2000-field benchComposeLarge test

Benchmark: 500 fields 0.70→0.51ms (27%), 2000 fields 2.28→1.57ms (31%)
snapshot-08-03-2026
2026-03-08 07:28:26 -06:00
IChooseYou
f0fc85f60f fix: CI test failures from collapsed=true default
- compose.cpp: show static fields for root structs even when collapsed
- test_compose: set collapsed=false on nodes needing expanded rendering
- test_disasm: set collapsed=false on vtable pointer nodes
- test_static_fields: rewrite collapsed test to use non-root child struct
2026-03-07 11:58:08 -07:00