Skip to content

fix(metadata): identify archives by their largest member again - #4059

Closed
gantoine wants to merge 1 commit into
masterfrom
fix/archive-member-hash-lookup
Closed

fix(metadata): identify archives by their largest member again#4059
gantoine wants to merge 1 commit into
masterfrom
fix/archive-member-hash-lookup

Conversation

@gantoine

@gantoine gantoine commented Aug 1, 2026

Copy link
Copy Markdown
Member

Description
Explain the changes or enhancements you are proposing with this pull request.

Completes phase 2 of #3411, which #3412 deferred.

Since 4.9.0 an archive's RomFile carries a composite hash computed across every entry inside it. The Hasheous and Playmatch lookups read their digests straight off that file record, so they silently switched from "hash of the largest file inside the archive" (what 4.8.x sent) to the composite. Both services index a multi-file archive by its largest internal file, so the composite matches nothing and those ROMs stopped resolving by hash — most visibly on arcade sets, where multi-file zips are the norm.

RomFile.lookup_hashes now owns the question of which digests a ROM database should be queried with:

file hashes sent
CHD the disc-data SHA1 from its header (unchanged, just moved here)
multi-file archive the largest member's crc / md5 / sha1, read from archive_members
anything else the file's own crc / md5 / sha1

Both hasheous_handler.lookup_rom and playmatch_handler.lookup_rom use it, as does the Playmatch suggestion payload — contributing a composite hash back to their index would have been worse than not contributing at all.

Notes:

  • Nothing is re-hashed. archive_members has been populated since 4.9.0, so existing libraries are fixed by a rescan without touching the files.
  • The composite stays the stored ROM-level identity, which is what [Feature] Compute composite hash & individual file hashes for multi-file archives) #3411 set out to add.
  • Single-file archives are unaffected: a composite over one entry equals that entry's hash.
  • ScreenScraper is deliberately left alone. It reads the same file-record digests, but its lookup falls back to romnom (the filename), which for arcade zips is the set name, so it still resolves. Changing it would shift match results for a lot of libraries and belongs in its own change.

Checklist
Please check all that apply.

  • I've tested the changes locally
  • I've updated relevant comments
  • I've assigned reviewers for this PR
  • I've added unit tests that cover the changes

Tests added: RomFile.lookup_hashes (own digests / CHD / largest member) in tests/models/test_rom.py, plus a payload assertion for each of the two handlers.

Screenshots (if applicable)

n/a — backend only.

Fixes #3742


🤖 AI assistance disclosure: this change was written with Claude Code (Claude Opus 5), working from the analysis in the issue. Reviewed by me before opening.

🤖 Generated with Claude Code

Since 4.9.0 an archive's RomFile carries a composite hash computed across
every entry inside it, and the Hasheous and Playmatch lookups picked that up
by reading the file record's digests. Both services index a multi-file archive
by the largest file inside it, so the composite matched nothing and arcade
sets (where multi-file zips are the norm) silently stopped resolving.

`RomFile.lookup_hashes` now centralises which digests a ROM database should be
queried with: the disc-data SHA1 for a CHD, the largest member's digests for an
archive, the file's own otherwise. Single-file archives are unaffected, since a
composite over one entry equals that entry's hash. Nothing is re-hashed, the
composite stays the stored ROM-level identity, and the same digests are what we
now contribute back through Playmatch's suggestion endpoint.

Fixes #3742

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gantoine
gantoine requested a review from Spinnich August 1, 2026 23:08
@Spinnich

Spinnich commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Maybe I'm misunderstanding, but for multi-file folder .chd games submitted to Playmatch, PlayMatch doesn't get the largest top-level file's CHD SHA-1 hash, it just uses first file with a size > 0? This would cause .m3u files to get submitted I'd think...

@gantoine gantoine closed this Aug 2, 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.

[Bug] Hasheous and Playmatch hash matching broken for multi-file archives since 4.9.0 (composite hash sent, but they index by largest file)

2 participants