Xdelta3 workaround (because xdelta3-python doesn't work)

This commit is contained in:
tretrauit 2022-02-18 21:04:44 +07:00
parent a481e529b6
commit bd515c73cd
No known key found for this signature in database
GPG Key ID: 862760FF1903319E
2 changed files with 39 additions and 6 deletions

View File

@ -1,5 +1,5 @@
aiohttp==3.8.1 aiohttp==3.8.1
appdirs~=1.4.4 appdirs~=1.4.4
aiopath~=0.6.10 aiopath~=0.6.10
setuptools~=59.3.0 setuptools==60.9.3
xdelta3~=0.0.5 xdelta3~=0.0.5

View File

@ -93,6 +93,32 @@ class Patcher:
""" """
await self._download_repo() await self._download_repo()
async def _patch_unityplayer_fallback(self):
# xdelta3-python doesn't work becuase it's outdated.
if self._overseas:
patch = "unityplayer_patch_os.vcdiff"
else:
patch = "unityplayer_patch_cn.vcdiff"
gamever = "".join(self._installer.get_game_version().split("."))
unity_path = self._gamedir.joinpath("UnityPlayer.dll")
unity_path.rename(self._gamedir.joinpath("UnityPlayer.dll.bak"))
await asyncio.create_subprocess_exec("xdelta3", "-d", "-s", str(self._gamedir.joinpath("UnityPlayer.dll.bak")),
str(self._patch_path.joinpath("{}/patch_files/{}".format(gamever, patch))),
str(self._gamedir.joinpath("UnityPlayer.dll")), cwd=self._gamedir)
async def _patch_xlua_fallback(self):
# xdelta3-python doesn't work becuase it's outdated.
patch = "xlua_patch.vcdiff"
gamever = "".join(self._installer.get_game_version().split("."))
data_name = self._installer.get_game_data_name()
xlua_path = self._gamedir.joinpath("{}/Plugins/xlua.dll".format(data_name))
xlua_path.rename(self._gamedir.joinpath("{}/Plugins/xlua.dll.bak").format(data_name))
await asyncio.create_subprocess_exec("xdelta3", "-d", "-s",
str(self._gamedir.joinpath("{}/Plugins/xlua.dll.bak".format(data_name))),
str(self._patch_path.joinpath("{}/patch_files/{}".format(gamever, patch))),
str(self._gamedir.joinpath("{}/Plugins/xlua.dll".format(data_name))),
cwd=self._gamedir)
def _patch_unityplayer(self): def _patch_unityplayer(self):
if self._overseas: if self._overseas:
patch = "unityplayer_patch_os.vcdiff" patch = "unityplayer_patch_os.vcdiff"
@ -113,23 +139,30 @@ class Patcher:
xlua_path = self._gamedir.joinpath("{}/Plugins/xlua.dll".format(data_name)) xlua_path = self._gamedir.joinpath("{}/Plugins/xlua.dll".format(data_name))
patch_bytes = self._patch_path.joinpath("{}/patch_files/{}".format(gamever, patch)).read_bytes() patch_bytes = self._patch_path.joinpath("{}/patch_files/{}".format(gamever, patch)).read_bytes()
patched_xlua_bytes = xdelta3.decode(xlua_path.read_bytes(), patch_bytes) patched_xlua_bytes = xdelta3.decode(xlua_path.read_bytes(), patch_bytes)
xlua_path.rename(self._gamedir.joinpath("xlua.dll.bak")) xlua_path.rename(self._gamedir.joinpath("{}/Plugins/xlua.dll.bak".format(data_name)))
with Path(self._gamedir.joinpath("{}/Plugins/xlua.dll".format(data_name))).open("wb") as f: with Path(self._gamedir.joinpath("{}/Plugins/xlua.dll".format(data_name))).open("wb") as f:
f.write(patched_xlua_bytes) f.write(patched_xlua_bytes)
def apply_xlua_patch(self): def apply_xlua_patch(self, fallback=True):
if fallback:
asyncio.run(self._patch_xlua_fallback())
return
self._patch_xlua() self._patch_xlua()
def apply_patch(self, crash_fix=False) -> None: def apply_patch(self, crash_fix=False, fallback=True) -> None:
""" """
Patch the game (and optionally patch xLua if specified) Patch the game (and optionally patch xLua if specified)
:param fallback:
:param crash_fix: Whether to patch xLua or not :param crash_fix: Whether to patch xLua or not
:return: None :return: None
""" """
if fallback:
asyncio.run(self._patch_unityplayer_fallback())
else:
self._patch_unityplayer() self._patch_unityplayer()
if crash_fix: if crash_fix:
self._patch_xlua() self.apply_xlua_patch(fallback=fallback)
def _revert_file(self, original_file: str, base_file: Path, ignore_error=False): def _revert_file(self, original_file: str, base_file: Path, ignore_error=False):
original_path = self._gamedir.joinpath(original_file + ".bak").resolve() original_path = self._gamedir.joinpath(original_file + ".bak").resolve()