mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-06 10:03:49 -06:00
fix: judge content-found cores by any dump
A core with found_by: content reads no file by the destination's name. Any dump its profile accepts for the system settles the slot: Batocera, KNULLI and ROCKNIX ship scph1001.bin v2.0, which DuckStation and rustation accept under scph1001_v20.bin.
This commit is contained in:
1 parent
19898cb6ea
commit
b550b9780c
2 files changed
+50
-1
No files matched your search
+31
-1
@@ -43,7 +43,12 @@ from common import (
|
||||
variant_base_name,
|
||||
)
|
||||
from packresolve import preferred_entries
|
||||
from validation import outside_gap_scope, read_from_save_dir, with_archive_members
|
||||
from validation import (
|
||||
opens_by_name,
|
||||
outside_gap_scope,
|
||||
read_from_save_dir,
|
||||
with_archive_members,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from packextras import ExtraPlacement
|
||||
@@ -85,6 +90,9 @@ class Claim:
|
||||
entry: dict = field(default_factory=dict)
|
||||
local_path: str | None = None
|
||||
status: str = ""
|
||||
# A core that identifies its firmware by content reads no file by this
|
||||
# name: any dump it accepts for the system answers for it.
|
||||
accepts: tuple[dict, ...] = ()
|
||||
|
||||
@property
|
||||
def is_proven(self) -> bool:
|
||||
@@ -210,6 +218,12 @@ def profile_claims(
|
||||
zip_contents, data_dir_registry,
|
||||
)
|
||||
)
|
||||
labels = [
|
||||
f for f in profile.get("files") or []
|
||||
if isinstance(f, dict)
|
||||
and not opens_by_name(f, profile, is_standalone)
|
||||
and _lists_hashes(f)
|
||||
]
|
||||
for entry in profile.get("files") or []:
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
@@ -260,6 +274,13 @@ def profile_claims(
|
||||
)
|
||||
if status == "name_exact" and _size_the_code_reads(entry, local):
|
||||
status = SIZE_EXACT
|
||||
accepts: tuple[dict, ...] = ()
|
||||
if not opens_by_name(entry, profile, is_standalone):
|
||||
systems = set(entry_system_ids(entry, profile))
|
||||
accepts = tuple(
|
||||
f for f in labels
|
||||
if not systems or systems & set(entry_system_ids(f, profile))
|
||||
)
|
||||
claims.append(
|
||||
Claim(
|
||||
origin="profile",
|
||||
@@ -269,6 +290,7 @@ def profile_claims(
|
||||
entry=entry,
|
||||
local_path=local,
|
||||
status=status,
|
||||
accepts=accepts,
|
||||
)
|
||||
)
|
||||
return claims
|
||||
@@ -746,6 +768,10 @@ def _satisfies(profile: Claim, platform: Claim, db: dict) -> bool:
|
||||
They agree when they resolve to the same bytes, when the platform's own
|
||||
hash list accepts the profile's file, or when the profile's accepts the
|
||||
platform's. A contradiction needs both lists to reject the other side.
|
||||
A core found by content (found_by: content) reads no file by the
|
||||
destination's name, so any dump it accepts for the system settles the
|
||||
slot: DuckStation takes Batocera's scph1001.bin v2.0, which its profile
|
||||
labels scph1001_v20.bin.
|
||||
"""
|
||||
if profile.local_path == platform.local_path:
|
||||
return True
|
||||
@@ -764,6 +790,10 @@ def _satisfies(profile: Claim, platform: Claim, db: dict) -> bool:
|
||||
and _accepted_by_all(profile.local_path, [platform.entry], db)
|
||||
):
|
||||
return True
|
||||
if platform.local_path and any(
|
||||
_accepted_by_all(platform.local_path, [label], db) for label in profile.accepts
|
||||
):
|
||||
return True
|
||||
return bool(
|
||||
platform.local_path
|
||||
and _lists_hashes(profile.entry)
|
||||
|
||||
@@ -111,6 +111,25 @@ class TestConflicts(unittest.TestCase):
|
||||
conflicts = slots.find_conflicts(config, self._profile("GC/JAP/IPL.bin"), REGIONS_DB)
|
||||
self.assertEqual([c.destination for c in conflicts], ["bios/GC/JAP/IPL.bin"])
|
||||
|
||||
def test_a_core_found_by_content_takes_any_dump_it_accepts(self):
|
||||
"""DuckStation identifies its BIOS by content, so the name of its
|
||||
scph1001.bin entry is a label. Batocera ships the v2.0 dump there,
|
||||
which the profile accepts under scph1001_v20.bin: no conflict."""
|
||||
files = [
|
||||
{"name": "IPL.bin", "path": "GC/JAP/IPL.bin", "md5": "n" * 32},
|
||||
{"name": "IPL_usa.bin", "md5": "m" * 32},
|
||||
]
|
||||
by_name = slots.find_conflicts(
|
||||
self._config("m" * 32), {"dolphin": {"files": files}}, REGIONS_DB
|
||||
)
|
||||
self.assertEqual(len(by_name), 1)
|
||||
by_content = slots.find_conflicts(
|
||||
self._config("m" * 32),
|
||||
{"dolphin": {"found_by": "content", "files": files}},
|
||||
REGIONS_DB,
|
||||
)
|
||||
self.assertEqual(by_content, [])
|
||||
|
||||
def test_wrong_region_under_a_region_slot_is_reported(self):
|
||||
conflicts = slots.find_conflicts(
|
||||
self._config("m" * 32), self._profile("GC/JAP/IPL.bin"), REGIONS_DB
|
||||
|
||||
Reference in new issue
Block a user