Compare commits

..

No commits in common. "197dc767a81c04acc3888e9f3df926e20270b3d5" and "32d6ca18914ab21a590e5bba3af3ad6cf673e372" have entirely different histories.

9 changed files with 16 additions and 144 deletions

View File

@ -38,14 +38,14 @@ class HSR:
def __patch_jadeite(self): def __patch_jadeite(self):
try: try:
print("Installing patch...", end=" ") print("Installing patch...", end=" ")
jadeite_dir = self._patcher.patch_game(game=self._game) jadelte_dir = self._patcher.patch_game(game=self._game)
except PatcherError as e: except PatcherError as e:
print("FAILED") print("FAILED")
print(f"Patching failed with following error: {e}") print(f"Patching failed with following error: {e}")
return return
print("OK") print("OK")
exe_path = jadeite_dir.joinpath("jadeite.exe") exe_path = jadelte_dir.joinpath("jadeite.exe")
print("jadeite executable is located at:", exe_path) print("Jadelte executable is located at:", exe_path)
print( print(
"Installation succeeded, but note that you need to run the game using " "Installation succeeded, but note that you need to run the game using "
+ "Jadeite to use the patch." + "Jadeite to use the patch."

View File

@ -6,8 +6,8 @@ def ask(question: str):
print(question + " [Y/n] Y") print(question + " [Y/n] Y")
return True return True
while True: while True:
answer = input(question + " [Y/n] ") answer = input(question + " [y/n] ")
if answer.lower().strip() in ["y", "yes", ""]: if answer.lower() in ["y", "yes"]:
return True return True
# Pacman way, treat all other answers as no # Pacman way, treat all other answers as no
else: else:

View File

@ -1,4 +1,5 @@
TELEMETRY_HOSTS = [ # Common
telemetry_hosts = [
# Global # Global
"log-upload-os.hoyoverse.com", "log-upload-os.hoyoverse.com",
"sg-public-data-api.hoyoverse.com", "sg-public-data-api.hoyoverse.com",
@ -7,4 +8,3 @@ TELEMETRY_HOSTS = [
"log-upload.mihoyo.com", "log-upload.mihoyo.com",
"public-data-api.mihoyo.com", "public-data-api.mihoyo.com",
] ]
HDIFFPATCH_GIT_URL = "https://github.com/sisong/HDiffPatch"

View File

@ -1,5 +1,5 @@
LATEST_VERSION = (1, 1, 0) latest_version = (1, 1, 0)
MD5SUMS = { md5sums = {
"1.0.5": { "1.0.5": {
"cn": { "cn": {
"StarRailBase.dll": "66c42871ce82456967d004ccb2d7cf77", "StarRailBase.dll": "66c42871ce82456967d004ccb2d7cf77",
@ -12,5 +12,5 @@ MD5SUMS = {
} }
} }
# Patches # Patches
ASTRA_REPO = "https://notabug.org/mkrsym1/astra" astra_repo = "https://notabug.org/mkrsym1/astra"
JADEITE_REPO = "https://codeberg.org/mkrsym1/jadeite/" jadeite_repo = "https://codeberg.org/mkrsym1/jadeite/"

View File

@ -11,7 +11,7 @@ from vollerei.exceptions.patcher import (
from vollerei.hsr.launcher.game import Game, GameChannel from vollerei.hsr.launcher.game import Game, GameChannel
from vollerei.utils import download_and_extract, Git, Xdelta3 from vollerei.utils import download_and_extract, Git, Xdelta3
from vollerei.paths import tools_data_path from vollerei.paths import tools_data_path
from vollerei.hsr.constants import ASTRA_REPO, JADEITE_REPO from vollerei.hsr.constants import astra_repo, jadeite_repo
class PatchType(Enum): class PatchType(Enum):
@ -49,10 +49,10 @@ class Patcher(PatcherABC):
self._patch_type = value self._patch_type = value
def _update_astra(self): def _update_astra(self):
self._git.pull_or_clone(ASTRA_REPO, self._astra) self._git.pull_or_clone(astra_repo, self._astra)
def _update_jadeite(self): def _update_jadeite(self):
release_info = self._git.get_latest_release(JADEITE_REPO) release_info = self._git.get_latest_release(jadeite_repo)
file = self._git.get_latest_release_dl(release_info)[0] file = self._git.get_latest_release_dl(release_info)[0]
file_version = release_info["tag_name"][1:] # Remove "v" prefix file_version = release_info["tag_name"][1:] # Remove "v" prefix
current_version = None current_version = None

View File

View File

@ -1,104 +0,0 @@
import platform
import subprocess
from zipfile import ZipFile
import requests
from io import BytesIO
from shutil import which
from vollerei.constants import HDIFFPATCH_GIT_URL
from vollerei.paths import tools_data_path
class HDiffPatch:
def __init__(self):
self._data = tools_data_path.joinpath("hdiffpatch")
self._data.mkdir(parents=True, exist_ok=True)
@staticmethod
def _get_platform_arch():
match platform.system():
case "Windows":
match platform.architecture()[0]:
case "32bit":
return "windows32"
case "64bit":
return "windows64"
case "Linux":
match platform.architecture()[0]:
case "32bit":
return "linux32"
case "64bit":
return "linux64"
case "Darwin":
return "macos"
# Rip BSD they need to use Linux compatibility layer to run this
# (or use Wine if they prefer that)
raise RuntimeError("Only Windows, Linux and macOS are supported by HDiffPatch")
def _get_hdiffpatch_exec(self, exec_name) -> str | None:
if which(exec_name):
return exec_name
if not self.data_path.exists():
return None
if not any(self.data_path.iterdir()):
return None
platform_arch_path = self.data_path.joinpath(self._get_platform_arch())
file = platform_arch_path.joinpath(exec_name)
if file.exists():
file.chmod(0o755)
return str(file)
def _hpatchz(self):
hpatchz_name = "hpatchz" + (".exe" if platform.system() == "Windows" else "")
return self._get_hdiffpatch_exec(hpatchz_name)
def patch_file(self, in_file, out_file, patch_file):
hpatchz = self.get_hpatchz_executable()
if not hpatchz:
raise RuntimeError("hpatchz executable not found")
subprocess.check_call([hpatchz, "-f", in_file, patch_file, out_file])
async def _get_latest_release_info(self) -> dict:
split = HDIFFPATCH_GIT_URL.split("/")
repo = split[-1]
owner = split[-2]
rsp = requests.get(
"https://api.github.com/repos/{}/{}/releases/latest".format(owner, repo),
params={"Headers": "Accept: application/vnd.github.v3+json"},
)
rsp.raise_for_status()
for asset in (await rsp.json())["assets"]:
if not asset["name"].endswith(".zip"):
continue
if "linux" in asset["name"]:
continue
if "windows" in asset["name"]:
continue
if "macos" in asset["name"]:
continue
if "android" in asset["name"]:
continue
return asset
async def get_latest_release_url(self):
asset = await self._get_latest_release_info()
return asset["browser_download_url"]
async def get_latest_release_name(self):
asset = await self._get_latest_release_info()
return asset["name"]
async def download(self):
"""
Download the latest release of HDiffPatch.
"""
url = await self.get_latest_release_url()
if not url:
raise RuntimeError("Unable to find latest release")
file = BytesIO()
with requests.get(url, stream=True) as r:
with open(file, "wb") as f:
for chunk in r.iter_content(chunk_size=32768):
f.write(chunk)
with ZipFile(file) as z:
z.extractall(self._data)

View File

@ -1,22 +0,0 @@
class HDiffPatchError(Exception):
"""Base class for HDiffPatch errors"""
pass
class HPatchZError(HDiffPatchError):
"""Raised when hpatchz fails"""
pass
class NotInstalledError(HPatchZError):
"""Raised when HDiffPatch is not installed"""
pass
class HPatchZPatchError(HPatchZError):
"""Raised when hpatchz patch fails"""
pass

View File

@ -2,7 +2,6 @@ import platform
import subprocess import subprocess
import requests import requests
from os import PathLike from os import PathLike
from io import BytesIO
from zipfile import ZipFile from zipfile import ZipFile
from shutil import which from shutil import which
from vollerei.paths import tools_cache_path from vollerei.paths import tools_cache_path
@ -61,12 +60,11 @@ class Xdelta3:
url = "https://github.com/jmacd/xdelta-gpl/releases/download/v3.1.0/xdelta3-3.1.0-i686.exe.zip" url = "https://github.com/jmacd/xdelta-gpl/releases/download/v3.1.0/xdelta3-3.1.0-i686.exe.zip"
case "i686": case "i686":
url = "https://github.com/jmacd/xdelta-gpl/releases/download/v3.1.0/xdelta3-3.1.0-i686.exe.zip" url = "https://github.com/jmacd/xdelta-gpl/releases/download/v3.1.0/xdelta3-3.1.0-i686.exe.zip"
file = BytesIO()
with requests.get(url, stream=True) as r: with requests.get(url, stream=True) as r:
with open(file, "wb") as f: with open(self._xdelta3_path.joinpath("xdelta3.zip"), "wb") as f:
for chunk in r.iter_content(chunk_size=32768): for chunk in r.iter_content(chunk_size=32768):
f.write(chunk) f.write(chunk)
with ZipFile(file) as z: with ZipFile(self._xdelta3_path.joinpath("xdelta3.zip")) as z:
z.extractall(self._xdelta3_path) z.extractall(self._xdelta3_path)
def patch_file(self, patch: PathLike, target: PathLike, output: PathLike): def patch_file(self, patch: PathLike, target: PathLike, output: PathLike):