Add macOS readMtgaCardDatabase + readMtgaInventory#4
Closed
dan-blanchard wants to merge 2 commits intomtgatool:mainfrom
Closed
Add macOS readMtgaCardDatabase + readMtgaInventory#4dan-blanchard wants to merge 2 commits intomtgatool:mainfrom
dan-blanchard wants to merge 2 commits intomtgatool:mainfrom
Conversation
Adds a macOS-only readMtgaCards napi export that bypasses the fragile PAPA/WrapperController walker by signature-scanning Arena's heap for the card-collection Dictionary<int,int>. The signature scan identifies the dictionary by its data invariant: - hash == key (Dictionary<int,V> with default EqualityComparer<int>) - Keys in Arena card-ID range [1, 200000] - Values in ownership range [1, 4] - Count in [500, 50000] - First 30 sampled entries must satisfy all constraints This uniquely identifies the live collection dictionary across 200K+ candidate heap positions. Supports optional MTGA_KNOWN_CARD_IDS and MTGA_VERIFY_QTYS env vars for ground-truth cross-validation. Also adds investigation notes in NOTES.md documenting the IL2CPP memory layout, CardPrintingRecord field table (50 fields with offsets), and the approaches tried during reverse engineering. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extends the heap-signature-scan approach to two more data sources:
readMtgaCardDatabase: scans for a Dictionary<int, CardPrintingData*>
with ~23K entries. Discovers that the runtime class is CardPrintingData
(not CardPrintingRecord as expected), with an embedded Record struct
at offset 0xC0. Handles the IL2CPP class variant duplication (metadata
vs runtime class pointers) by resolving class names instead of
comparing pointers. Adjusts for the embedded-struct header omission
(field offsets shift by -0x10 when a class is inlined as a value type).
Returns { grpId, set, collectorNumber, titleId } for all ~23,694 cards.
readMtgaInventory: scans for ClientPlayerInventory using a class-pointer
set pre-filter (via find_all_classes_by_name) plus value plausibility
checks and activity-score ranking. Discovers that vaultProgress is an
8-byte double (not int32), storing the UI percentage directly (e.g.
58.9). Ground-truth verified against Arena's UI.
Both functions support MTGA_DEBUG_CARD_DB and MTGA_DEBUG_INVENTORY
env vars for verbose diagnostic output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
4 tasks
Author
|
Superseded — the card database portion is now handled by the SQLite reader in #1. Reopening as inventory-only PR. |
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.
Extends the heap-signature-scan approach from #3 to two more data sources: the card-printing database and the player inventory.
Depends on #3 for the scanner infrastructure.
readMtgaCardDatabase
Scans for a `Dictionary<int, CardPrintingData*>` with ~23K entries at stride 24. Returns `{ grpId, set, collectorNumber, titleId }` for every card printing in Arena's memory.
Key discoveries during implementation:
readMtgaInventory
Scans for `ClientPlayerInventory` using a class-pointer-set pre-filter plus value plausibility and activity-score ranking. Returns wildcards, gold, gems, and vault progress.
Key discovery: `vaultProgress` is an 8-byte `double` (not `int32`), storing the UI percentage directly (e.g., 58.9). Field spacing confirms this: `vaultProgress @ 0x30`, `boosters @ 0x38` = 8-byte field.
Both functions support `MTGA_DEBUG_CARD_DB` and `MTGA_DEBUG_INVENTORY` env vars for verbose diagnostic output.
Testing
Verified against live Arena on macOS arm64 (Unity 2022.3.62f2):
🤖 Generated with Claude Code