diff --git a/worthless/installer.py b/worthless/installer.py index a417f7e..105bd18 100644 --- a/worthless/installer.py +++ b/worthless/installer.py @@ -46,6 +46,17 @@ async def _download_file(file_url: str, file_name: str, file_path: Path | str, f await f.write(chunk) +def calculate_md5(file_to_calculate): + file_to_calculate = Path(file_to_calculate) + if not file_to_calculate.exists(): + return "" + with file_to_calculate.open("rb") as f: + file_hash = hashlib.md5() + while chunk := f.read(8192): + file_hash.update(chunk) + return file_hash.hexdigest() + + class HDiffPatch: def __init__(self, git_url=None, data_dir=None): if not git_url: @@ -397,6 +408,8 @@ class Installer: game = await self._get_game(pre_download) archive_name = game.latest.path.split("/")[-1] await self._download_file(game.latest.path, archive_name, game.latest.size) + if calculate_md5(self.temp_path.joinpath(archive_name)) != game.latest.md5: + raise RuntimeError("mismatch md5 for downloaded game archive") async def download_full_voiceover(self, language: str, pre_download=False): game = await self._get_game(pre_download) @@ -413,16 +426,16 @@ class Installer: archive = Path(archive).resolve() if not archive.exists(): raise FileNotFoundError(f"'{archive}' not found") - game_dir_str = str(self._gamedir) - if not game_dir_str.endswith("/"): - game_dir_str += "/" - print(f'-o"{game_dir_str}"') - proc = await asyncio.create_subprocess_shell(f'7z x {str(archive)} -o"{game_dir_str}"') - await proc.wait() - if proc.returncode != 0: - raise RuntimeError("Extracting failed") - # with zipfile.ZipFile(archive, 'r') as f: - # await asyncio.to_thread(f.extractall, path=self._gamedir) + # game_dir_str = str(self._gamedir) + # if not game_dir_str.endswith("/"): + # game_dir_str += "/" + # print(f'-o"{game_dir_str}"') + # proc = await asyncio.create_subprocess_shell(f'7z x {str(archive)} -o"{game_dir_str}"') + # await proc.wait() + # if proc.returncode != 0: + # raise RuntimeError("Extracting failed") + with zipfile.ZipFile(archive, 'r') as f: + await asyncio.to_thread(f.extractall, path=self._gamedir) async def apply_voiceover(self, voiceover_archive: str | Path): # Since Voiceover packages are unclear about diff package or full package @@ -517,18 +530,8 @@ class Installer: async def verify_from_pkg_version(self, pkg_version: AsyncPath, ignore_mismatch=False): contents = await pkg_version.read_text() - async def calculate_md5(file_to_calculate): - file_to_calculate = AsyncPath(file_to_calculate) - if not await file_to_calculate.exists(): - return "" - async with file_to_calculate.open("rb") as f: - file_hash = hashlib.md5() - while chunk := await f.read(self._download_chunk): - file_hash.update(chunk) - return file_hash.hexdigest() - async def verify_file(file_to_verify, md5): - file_md5 = await calculate_md5(file_to_verify) + file_md5 = asyncio.to_thread(calculate_md5, file_to_verify) if file_md5 == md5: return None if ignore_mismatch: