mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-28 14:47:21 -05:00
fix: a refused regional file wins no slot
emulator_region_drops counted as held any file that resolved. A regional dump whose md5 the core's own check refuses won its region, the fallback was withdrawn, and the emulator pack then refused the winner: no BIOS for the system, and verify --emulator, reading the same drops, did not see it. Held now means what the builder ships, as _ships decides on the platform side.
This commit is contained in:
1 parent
38af19091d
commit
1c2360926b
2 files changed
+85
-4
No files matched your search
+27
-4
@@ -1296,11 +1296,12 @@ def emulator_region_drops(
|
||||
"""
|
||||
import region as region_mod
|
||||
from packpaths import _resolve_destination
|
||||
from validation import filter_files_by_mode
|
||||
from validation import _build_validation_index, filter_files_by_mode
|
||||
|
||||
region_index = region_mod.build_region_index(dict(selected))
|
||||
region_groups: dict[str, list[tuple[str, str]]] = {}
|
||||
held: set[str] | None = set() if db is not None else None
|
||||
validation_index = _build_validation_index(dict(selected)) if db is not None else {}
|
||||
for emu_name, profile in sorted(selected):
|
||||
# Decided over what the pack keeps, as on the platform side: an
|
||||
# optional winner removed afterwards left its slot empty.
|
||||
@@ -1312,13 +1313,35 @@ def emulator_region_drops(
|
||||
region_groups.setdefault(group_id, []).append(
|
||||
(dest, fe.get("name", ""))
|
||||
)
|
||||
if held is not None and resolve_local_file(
|
||||
dict(fe, source_profile=emu_name), db, dest_hint=dest
|
||||
)[0]:
|
||||
if held is not None and _emulator_ships(
|
||||
fe, emu_name, profile, db, dest, validation_index
|
||||
):
|
||||
held.add(dest)
|
||||
return region_mod.resolve_region_drops(region_groups, region_index, regions, held)
|
||||
|
||||
|
||||
def _emulator_ships(
|
||||
file_entry: dict, emu_name: str, profile: dict, db: dict, dest: str,
|
||||
validation_index: dict,
|
||||
) -> bool:
|
||||
"""Whether the emulator pack ships this entry: held, and not refused by
|
||||
the core's own check, the test _ships applies on the platform side.
|
||||
"""
|
||||
from validation import validated_choice, with_archive_members
|
||||
|
||||
local, _status = resolve_local_file(
|
||||
{**with_archive_members(file_entry, profile.get("files", [])),
|
||||
"source_profile": emu_name},
|
||||
db, dest_hint=dest,
|
||||
)
|
||||
if not local:
|
||||
return False
|
||||
_chosen, disagreement = validated_choice(
|
||||
file_entry, local, db, validation_index, "bios", None, emulators={emu_name},
|
||||
)
|
||||
return disagreement is None
|
||||
|
||||
|
||||
def _emulator_region_group(
|
||||
emu_name: str, profile: dict, file_entry: dict, dest: str
|
||||
) -> str:
|
||||
|
||||
@@ -1113,5 +1113,63 @@ class NoMarketStopsAtAustralia(unittest.TestCase):
|
||||
self.assertEqual(tagged, [])
|
||||
|
||||
|
||||
class ARefusedRegionalFileHoldsNoSlot(unittest.TestCase):
|
||||
"""rg_us.bin is held but its md5 contradicts the one the core checks, so
|
||||
the emulator pack refuses it. Counted held, it won the region and the
|
||||
Japanese BIOS was withdrawn: --emulator --region us shipped no BIOS for
|
||||
the system, and verify, reading the same drops, did not see it."""
|
||||
|
||||
def test_the_fallback_stays_in_pack_and_report(self):
|
||||
import hashlib
|
||||
import shutil
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
import yaml
|
||||
|
||||
from generate_pack import generate_emulator_pack
|
||||
from verify import verify_emulator
|
||||
|
||||
common._emulator_profiles_cache.clear()
|
||||
repo = Path(__file__).resolve().parents[1]
|
||||
(repo / "tmp").mkdir(exist_ok=True)
|
||||
root = Path(tempfile.mkdtemp(dir=repo / "tmp"))
|
||||
self.addCleanup(shutil.rmtree, root, True)
|
||||
previous = os.getcwd()
|
||||
os.chdir(root)
|
||||
self.addCleanup(os.chdir, previous)
|
||||
files, by_name = {}, {}
|
||||
for name, data in (("rg_us.bin", b"NOT THE US DUMP"), ("rg_jp.bin", b"JP DUMP")):
|
||||
path = Path("bios") / name
|
||||
path.parent.mkdir(exist_ok=True)
|
||||
path.write_bytes(data)
|
||||
sha1 = hashlib.sha1(data).hexdigest()
|
||||
files[sha1] = {"path": str(path), "name": name, "size": len(data),
|
||||
"md5": hashlib.md5(data).hexdigest()}
|
||||
by_name[name] = [sha1]
|
||||
db = {"files": files, "indexes": {"by_name": by_name, "by_md5": {},
|
||||
"by_crc32": {}, "by_path_suffix": {}}}
|
||||
Path("emulators").mkdir()
|
||||
Path("emulators/rgemu.yml").write_text(yaml.safe_dump({
|
||||
"emulator": "RgEmu", "type": "libretro", "systems": ["sys"],
|
||||
"files": [
|
||||
{"name": "rg_us.bin", "region": ["north-america"], "required": True,
|
||||
"md5": hashlib.md5(b"THE US DUMP").hexdigest(), "validation": ["md5"]},
|
||||
{"name": "rg_jp.bin", "region": ["japan"], "required": True},
|
||||
],
|
||||
}))
|
||||
with contextlib.redirect_stdout(io.StringIO()):
|
||||
zip_path = generate_emulator_pack(
|
||||
["rgemu"], "emulators", db, "bios", "out", regions=["north-america"],
|
||||
offline=True, platforms_dir="platforms",
|
||||
)
|
||||
with zipfile.ZipFile(zip_path) as zf:
|
||||
self.assertIn("rg_jp.bin", zf.namelist())
|
||||
report = verify_emulator(
|
||||
["rgemu"], "emulators", db, regions=["north-america"], platforms_dir="platforms",
|
||||
)
|
||||
self.assertIn("rg_jp.bin", report["pack_destinations"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user