Initial commit with nexus updates and streamlined UI
This commit is contained in:
commit
f780daecad
41 files changed
+4668
No files matched your search
@@ -0,0 +1,70 @@
|
||||
import hashlib
|
||||
import os
|
||||
import struct
|
||||
import tempfile
|
||||
import unittest
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
from mhwmm.core.paks import path_hash, pak_name
|
||||
from mhwmm.core.paths import Paths
|
||||
|
||||
|
||||
def snapshot(root: Path) -> dict:
|
||||
"""Byte-level picture of a tree: files by hash, symlinks by target, and directories."""
|
||||
snap = {}
|
||||
for dirpath, dirnames, filenames in os.walk(root):
|
||||
for n in dirnames + filenames:
|
||||
p = Path(dirpath) / n
|
||||
rel = str(p.relative_to(root))
|
||||
if p.is_symlink():
|
||||
snap[rel] = ("l", os.readlink(p))
|
||||
elif p.is_dir():
|
||||
snap[rel] = ("d",)
|
||||
else:
|
||||
snap[rel] = ("f", hashlib.sha256(p.read_bytes()).hexdigest())
|
||||
return snap
|
||||
|
||||
|
||||
def make_game(root: Path, ceiling: int = 15) -> Path:
|
||||
game = root / "game"
|
||||
game.mkdir()
|
||||
for chain in ("main", "sub"):
|
||||
for n in range(1, ceiling + 1):
|
||||
(game / pak_name(chain, n)).write_bytes(f"vanilla-{chain}-{n}".encode())
|
||||
(game / "re_chunk_000.pak").write_bytes(b"base")
|
||||
(game / "MonsterHunterWilds.exe").write_bytes(b"exe")
|
||||
return game
|
||||
|
||||
|
||||
def write_tree(root: Path, files: dict[str, bytes | str]) -> Path:
|
||||
for rel, data in files.items():
|
||||
p = root / rel
|
||||
p.parent.mkdir(parents=True, exist_ok=True)
|
||||
p.write_bytes(data if isinstance(data, bytes) else data.encode())
|
||||
return root
|
||||
|
||||
|
||||
def make_kpka(paths: list[str]) -> bytes:
|
||||
"""Minimal KPKA with entries keyed by the path hashes of `paths`."""
|
||||
out = b"KPKA" + struct.pack("<BBHII", 4, 0, 0, len(paths), 0)
|
||||
for p in paths:
|
||||
lo, up = path_hash(p)
|
||||
out += struct.pack("<IIQQQQQ", lo, up, 0, 0, 0, 0, 0)
|
||||
return out
|
||||
|
||||
|
||||
def make_zip(path: Path, files: dict[str, bytes | str]) -> Path:
|
||||
with zipfile.ZipFile(path, "w") as zf:
|
||||
for name, data in files.items():
|
||||
zf.writestr(name, data)
|
||||
return path
|
||||
|
||||
|
||||
class TmpCase(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._td = tempfile.TemporaryDirectory()
|
||||
self.addCleanup(self._td.cleanup)
|
||||
self.tmp = Path(self._td.name)
|
||||
self.paths = Paths(self.tmp / "data", self.tmp / "config")
|
||||
self.paths.ensure()
|
||||
Reference in new issue
Block a user