def patch(self): patches = self.conf.get("patches", {}) for op, files in patches.items(): if op == "bspatch": for file, patch_file in files.items(): target_file = eval_path(Path(file), self.env) self.perform_bspatch( target_file, Path(PATCHES_BASE_PATH) / self.title / patch_file) elif op == "copy_file": for dst_dir, patch_files in files.items(): dst_dir = eval_path(dst_dir, self.env) for p_file in patch_files: p_file = Path(PATCHES_BASE_PATH) / self.title / p_file copy_ex(p_file, dst_dir) elif op == "find_replace_text": for file, replaces in files.items(): target_file = eval_path(Path(file), self.env) for repl in replaces: if "eval" in repl: find = f"{{{repl['eval']}}}" replace = get_var_val_by_name(repl['eval']) else: find = repl["find"] replace = repl["replace"] find_replace_text(target_file, find, replace) elif op == "regedit": Wine(self.title).upd_reg(files) else: raise Exception(f"unknown patch type: {op}")
def handle_saves(self): portable_saves_path = Path(SAVES_BASE_PATH) / self.title portable_saves_path.mkdir(parents=True, exist_ok=True) copy_saves = self.conf["copy_saves"] if copy_saves: # stupid game stores saves in its working dir, so we have to copy them back and forth copy_saves = eval_path(copy_saves, self.env) portable_saves = portable_saves_path / copy_saves.name copy_ex(portable_saves, self.game_path) return portable_saves_path actual_saves_path = self.conf.get("saves_path", None) if actual_saves_path: actual_saves_path = eval_path(actual_saves_path, self.env) if actual_saves_path.exists(): if actual_saves_path.is_symlink(): return portable_saves_path # some games depends on existing files in saves folder even on a first run (faust) if os.listdir(str(actual_saves_path)) and not os.listdir( str(portable_saves_path)): copy_ex(actual_saves_path / "*", portable_saves_path) rm_dir(actual_saves_path) actual_saves_path.parent.mkdir(parents=True, exist_ok=True) print( f"creating a symlink: {actual_saves_path}->{portable_saves_path}" ) actual_saves_path.symlink_to(portable_saves_path) return portable_saves_path
def copy(self): images = self.conf.get("images", {}) for img_name, dst_src in images.items(): for dst, src_files in dst_src.items(): dst = eval_path(dst, self.env) if isinstance(src_files, list): Path(dst).mkdir(parents=True, exist_ok=True) for s in src_files: src = self.mounts[img_name] / s copy_ex(Path(src), Path(dst)) else: src = self.mounts[img_name] / src_files copy_ex(src, Path(dst)) # perform inside a loop to avoid permission issues on copying same files from diff images cmd_exec(f"chmod -R 755 {self.game_path}")
def __init__(self, title): self.title = title self.conf = GAMES_CONF[title]["run"] self.game_path = Path(GAMES_BASE_PATH) / title assert(self.game_path.exists()) self.saves_path = Path(SAVES_BASE_PATH) / title assert(self.saves_path.exists()) self.env = { "GAME_PATH": str(self.game_path), "SAVES_PATH": str(self.saves_path) } self.conf["copy_saves"] = GAMES_CONF[title].get("copy_saves", None) self.cdrom_folder = self.conf.get("cdrom_folder", None) if self.cdrom_folder: self.cdrom_folder = eval_path(self.cdrom_folder, self.env)
def run(self): self.mount() screen_resolution = self.conf.get("screen_resolution", None) if self.conf.get("emul_virtual_desktop", False): assert screen_resolution is not None self.emul_virtual_desktop(screen_resolution) else: self.emul_virtual_desktop() if screen_resolution: set_screen_resolution(screen_resolution) pre_cmd = self.conf.get("pre_cmd", None) if pre_cmd: _, stderr = cmd_exec(pre_cmd) if stderr: print(f"pre_cmd errors: {stderr}") cwd = eval_path(Path(self.conf.get("cwd", self.game_path)), self.env) self.run_wine_cmd(cmd=f'"{self.conf["exec_file"]}"', cwd=str(cwd))
def __del__(self): if self.conf["copy_saves"]: # stupid game stores saves in its working dir, so we have to copy them back and forth portable_saves_path = Path(SAVES_BASE_PATH) / self.title actual_saves = eval_path(self.conf["copy_saves"], self.env) copy_ex(actual_saves, portable_saves_path)