Skip to content

Commit

Permalink
fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
steven11sjf committed Oct 16, 2024
1 parent 16920b3 commit ec1d0df
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 50 deletions.
8 changes: 2 additions & 6 deletions src/mercury_engine_data_structures/file_tree_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def _update_headers(self):
self.headers = {}
self._ensured_asset_ids = {}
self._files_for_asset_id = {}
self.version = version_validation.identify_version(self)
self.version = version_validation.identify_version(self.romfs)
self._name_for_asset_id = copy.copy(self.version.all_asset_id_for_version())

self._toc = Toc.parse(self.romfs.get_file(Toc.system_files_name()), target_game=self.target_game)
Expand Down Expand Up @@ -128,11 +128,7 @@ def all_asset_names_in_folder(self, folder: str) -> Iterator[str]:
"""
returns an iterator of all known asset names in a folder
"""
return (
self._name_for_asset_id[asset_name]
for asset_name in self.all_asset_names()
if asset_name.startswith(folder)
)
return (asset_name for asset_name in self.all_asset_names() if asset_name.startswith(folder))

def find_pkgs(self, asset_id: NameOrAssetId) -> Iterator[str]:
for pkg_name in self._files_for_asset_id[resolve_asset_id(asset_id, self.target_game)]:
Expand Down
28 changes: 2 additions & 26 deletions src/mercury_engine_data_structures/version_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,18 @@
from mercury_engine_data_structures.game_check import GameVersion

if TYPE_CHECKING:
from mercury_engine_data_structures.file_tree_editor import FileTreeEditor
from mercury_engine_data_structures.romfs import RomFs

Check warning on line 10 in src/mercury_engine_data_structures/version_validation.py

View check run for this annotation

Codecov / codecov/patch

src/mercury_engine_data_structures/version_validation.py#L10

Added line #L10 was not covered by tests


def _get_md5(data: bytes) -> bytes:
return md5(data, usedforsecurity=False).digest()


def identify_version(editor: FileTreeEditor) -> GameVersion:
romfs = editor.romfs
def identify_version(romfs: RomFs) -> GameVersion:
toc = romfs.get_file(Toc.system_files_name())
toc_hash = _get_md5(toc)
for ver in GameVersion:
if ver.toc_hash == toc_hash:
return ver

raise ValueError("Not a valid version!")

Check warning on line 24 in src/mercury_engine_data_structures/version_validation.py

View check run for this annotation

Codecov / codecov/patch

src/mercury_engine_data_structures/version_validation.py#L24

Added line #L24 was not covered by tests


def verify_file_structure(editor: FileTreeEditor) -> GameVersion:
ver = identify_version(editor)
for assetid in editor.version.all_asset_id_for_version():
if not editor.does_asset_exists(assetid):
raise ValueError(f"Missing asset {assetid}")

return ver


def verify_file_integrity(editor: FileTreeEditor) -> GameVersion:
ver = identify_version(editor)
all_hashes = b""
for assetid in editor.version.all_asset_id_for_version():
if not editor.does_asset_exists(assetid):
raise ValueError(f"Missing asset {assetid}")
all_hashes += _get_md5(editor.get_raw_asset(assetid))

if _get_md5(all_hashes) == ver.all_files_hash:
return ver
else:
raise ValueError(f"Invalid hash {_get_md5(all_hashes).hex()}!")
17 changes: 17 additions & 0 deletions tests/test_file_tree_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,20 @@ def test_add_new_file_exists_romfs(dread_tree_100):
def test_add_new_file_exists_pkg(dread_tree_100):
with pytest.raises(ValueError, match=re.escape("Asset already exists in:\npacks/maps/s010_cave/s010_cave.pkg")):
dread_tree_100.add_new_asset("maps/levels/c10_samus/s010_cave/s010_cave.brfld", b"boo", [])


def test_all_asset_ids_in_folder(dread_tree_100):
doorshieldmissile_assets = dread_tree_100.all_asset_names_in_folder("actors/props/doorshieldmissile")
expected_doorshieldmissile_assets = [
"actors/props/doorshieldmissile/charclasses/doorshieldmissile.bmsad",
"actors/props/doorshieldmissile/charclasses/doorshieldmissile.bmsas",
"actors/props/doorshieldmissile/charclasses/timeline.bmsas",
"actors/props/doorshieldmissile/collisions/doorshieldmissile.bmscd",
"actors/props/doorshieldmissile/fx/explosion_shieldparticle.bcptl",
"actors/props/doorshieldmissile/fx/imats/shieldmissile_shieldfx.bsmat",
"actors/props/doorshieldmissile/fx/shieldmissilefx.bcmdl",
"actors/props/doorshieldmissile/models/doorshieldmissile.bcmdl",
"actors/props/doorshieldmissile/models/imats/doorshieldmissile_mp_opaque_01.bsmat",
]

assert set(doorshieldmissile_assets) == set(expected_doorshieldmissile_assets)
22 changes: 4 additions & 18 deletions tests/test_version_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

import pytest

from mercury_engine_data_structures.file_tree_editor import FileTreeEditor, GameVersion
from mercury_engine_data_structures.game_check import GameVersion
from mercury_engine_data_structures.romfs import ExtractedRomFs
from mercury_engine_data_structures.version_validation import verify_file_integrity, verify_file_structure
from mercury_engine_data_structures.version_validation import identify_version

# ignores unsupported dread versions
GAME_VERSIONS_TESTS = [
Expand All @@ -20,19 +20,5 @@
def test_identify_version(path_fixture_name: str, version: GameVersion, request: pytest.FixtureRequest):
# finds correct version after creating an editor
path = request.getfixturevalue(path_fixture_name)
editor = FileTreeEditor(ExtractedRomFs(path), version.game)
assert editor.version == version


@pytest.mark.parametrize(("path_fixture_name", "version"), GAME_VERSIONS_TESTS)
def test_verify_structure(path_fixture_name: str, version: GameVersion, request: pytest.FixtureRequest):
path = request.getfixturevalue(path_fixture_name)
editor = FileTreeEditor(ExtractedRomFs(path), version.game)
assert verify_file_structure(editor) == version


@pytest.mark.parametrize(("path_fixture_name", "version"), GAME_VERSIONS_TESTS)
def test_verify_data(path_fixture_name: str, version: GameVersion, request: pytest.FixtureRequest):
path = request.getfixturevalue(path_fixture_name)
editor = FileTreeEditor(ExtractedRomFs(path), version.game)
assert verify_file_integrity(editor) == version
romfs = ExtractedRomFs(path)
assert identify_version(romfs) == version

0 comments on commit ec1d0df

Please sign in to comment.