summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxXJSONDeruloXx <danielhimebauch@gmail.com>2025-09-26 20:21:36 -0400
committerxXJSONDeruloXx <danielhimebauch@gmail.com>2025-09-26 20:21:36 -0400
commit1b4a70c67013b87ff413506d5a25f66e4eb5bb87 (patch)
tree8dedfacec2c6d9977b1b95447c96b970e396f76b
parent1cc6a781fe7d6c053b2eb59aa79766a859c66209 (diff)
downloadDecky-Framegen-1b4a70c67013b87ff413506d5a25f66e4eb5bb87.tar.gz
Decky-Framegen-1b4a70c67013b87ff413506d5a25f66e4eb5bb87.zip
fix patching, logging additions
-rw-r--r--main.py303
1 files changed, 171 insertions, 132 deletions
diff --git a/main.py b/main.py
index 881298a..5b6b8e8 100644
--- a/main.py
+++ b/main.py
@@ -420,155 +420,194 @@ class Plugin:
for file_name in required_files:
if not path.joinpath(file_name).exists():
return {"exists": False}
-
+
# Check plugins directory and OptiPatcher ASI
plugins_dir = path / "plugins"
if not plugins_dir.exists() or not (plugins_dir / "OptiPatcher.asi").exists():
return {"exists": False}
-
+
return {"exists": True}
else:
return {"exists": False}
- def _resolve_target_directory(self, directory: str) -> Path:
- target = Path(directory).expanduser()
- if not target.exists():
- raise FileNotFoundError(f"Target directory does not exist: {directory}")
- if not target.is_dir():
- raise NotADirectoryError(f"Target path is not a directory: {directory}")
- if not os.access(target, os.W_OK | os.X_OK):
- raise PermissionError(f"Insufficient permissions for {directory}")
- return target
-
- def _manual_patch_directory_impl(self, directory: Path) -> dict:
- fgmod_path = Path(decky.HOME) / "fgmod"
- if not fgmod_path.exists():
- return {
- "status": "error",
- "message": "OptiScaler bundle not installed. Run Install first.",
- }
-
- optiscaler_dll = fgmod_path / "OptiScaler.dll"
- if not optiscaler_dll.exists():
- return {
- "status": "error",
- "message": "OptiScaler.dll not found in ~/fgmod. Reinstall OptiScaler.",
- }
+ def _resolve_target_directory(self, directory: str) -> Path:
+ decky.logger.info(f"Resolving target directory: {directory}")
+ target = Path(directory).expanduser()
+ if not target.exists():
+ raise FileNotFoundError(f"Target directory does not exist: {directory}")
+ if not target.is_dir():
+ raise NotADirectoryError(f"Target path is not a directory: {directory}")
+ if not os.access(target, os.W_OK | os.X_OK):
+ raise PermissionError(f"Insufficient permissions for {directory}")
+ decky.logger.info(f"Resolved directory {directory} to absolute path {target}")
+ return target
+
+ def _manual_patch_directory_impl(self, directory: Path) -> dict:
+ fgmod_path = Path(decky.HOME) / "fgmod"
+ if not fgmod_path.exists():
+ return {
+ "status": "error",
+ "message": "OptiScaler bundle not installed. Run Install first.",
+ }
- dll_name = "dxgi.dll"
- preserve_ini = True
+ optiscaler_dll = fgmod_path / "OptiScaler.dll"
+ if not optiscaler_dll.exists():
+ return {
+ "status": "error",
+ "message": "OptiScaler.dll not found in ~/fgmod. Reinstall OptiScaler.",
+ }
- try:
- decky.logger.info(f"Manual patch started for {directory}")
+ dll_name = "dxgi.dll"
+ preserve_ini = True
- for filename in INJECTOR_FILENAMES:
- path = directory / filename
- if path.exists():
- path.unlink()
+ try:
+ decky.logger.info(f"Manual patch started for {directory}")
+
+ removed_injectors = []
+ for filename in INJECTOR_FILENAMES:
+ path = directory / filename
+ if path.exists():
+ path.unlink()
+ removed_injectors.append(filename)
+ decky.logger.info(f"Removed injector DLLs: {removed_injectors}" if removed_injectors else "No injector DLLs found to remove")
+
+ backed_up_originals = []
+ for dll in ORIGINAL_DLL_BACKUPS:
+ source = directory / dll
+ backup = directory / f"{dll}.b"
+ if source.exists() and not backup.exists():
+ shutil.move(source, backup)
+ backed_up_originals.append(dll)
+ decky.logger.info(f"Backed up original DLLs: {backed_up_originals}" if backed_up_originals else "No original DLLs required backup")
+
+ removed_legacy = []
+ for legacy in ["nvapi64.dll", "nvapi64.dll.b"]:
+ legacy_path = directory / legacy
+ if legacy_path.exists():
+ legacy_path.unlink()
+ removed_legacy.append(legacy)
+ decky.logger.info(f"Removed legacy files: {removed_legacy}" if removed_legacy else "No legacy files to remove")
+
+ renamed = fgmod_path / "renames" / dll_name
+ destination_dll = directory / dll_name
+ source_for_copy = renamed if renamed.exists() else optiscaler_dll
+ shutil.copy2(source_for_copy, destination_dll)
+ decky.logger.info(f"Copied injector DLL from {source_for_copy} to {destination_dll}")
+
+ target_ini = directory / "OptiScaler.ini"
+ source_ini = fgmod_path / "OptiScaler.ini"
+ if preserve_ini and target_ini.exists():
+ decky.logger.info(f"Preserving existing OptiScaler.ini at {target_ini}")
+ elif source_ini.exists():
+ shutil.copy2(source_ini, target_ini)
+ decky.logger.info(f"Copied OptiScaler.ini from {source_ini} to {target_ini}")
+ else:
+ decky.logger.warning("No OptiScaler.ini found to copy")
- for dll in ORIGINAL_DLL_BACKUPS:
- source = directory / dll
- backup = directory / f"{dll}.b"
- if source.exists() and not backup.exists():
- shutil.move(source, backup)
-
- for legacy in ["nvapi64.dll", "nvapi64.dll.b"]:
- legacy_path = directory / legacy
- if legacy_path.exists():
- legacy_path.unlink()
-
- renamed = fgmod_path / "renames" / dll_name
- destination_dll = directory / dll_name
- source_for_copy = renamed if renamed.exists() else optiscaler_dll
- shutil.copy2(source_for_copy, destination_dll)
-
- target_ini = directory / "OptiScaler.ini"
- source_ini = fgmod_path / "OptiScaler.ini"
- if preserve_ini and target_ini.exists():
- decky.logger.info(f"Preserving existing OptiScaler.ini at {target_ini}")
- elif source_ini.exists():
- shutil.copy2(source_ini, target_ini)
-
- plugins_src = fgmod_path / "plugins"
- plugins_dest = directory / "plugins"
- if plugins_src.exists():
- shutil.copytree(plugins_src, plugins_dest, dirs_exist_ok=True)
-
- for filename in SUPPORT_FILES:
- source = fgmod_path / filename
- if source.exists():
- shutil.copy2(source, directory / filename)
-
- decky.logger.info(f"Manual patch complete for {directory}")
- return {
- "status": "success",
- "message": f"OptiScaler files copied to {directory}",
- }
+ plugins_src = fgmod_path / "plugins"
+ plugins_dest = directory / "plugins"
+ if plugins_src.exists():
+ shutil.copytree(plugins_src, plugins_dest, dirs_exist_ok=True)
+ decky.logger.info(f"Synced plugins directory from {plugins_src} to {plugins_dest}")
+ else:
+ decky.logger.warning("Plugins directory missing in fgmod bundle")
+
+ copied_support = []
+ missing_support = []
+ for filename in SUPPORT_FILES:
+ source = fgmod_path / filename
+ dest = directory / filename
+ if source.exists():
+ shutil.copy2(source, dest)
+ copied_support.append(filename)
+ else:
+ missing_support.append(filename)
+ if copied_support:
+ decky.logger.info(f"Copied support files: {copied_support}")
+ if missing_support:
+ decky.logger.warning(f"Support files missing from fgmod bundle: {missing_support}")
- except PermissionError as exc:
- decky.logger.error(f"Manual patch permission error: {exc}")
- return {
- "status": "error",
- "message": f"Permission error while patching: {exc}",
- }
- except Exception as exc:
- decky.logger.error(f"Manual patch failed: {exc}")
- return {
- "status": "error",
- "message": f"Manual patch failed: {exc}",
- }
+ decky.logger.info(f"Manual patch complete for {directory}")
+ return {
+ "status": "success",
+ "message": f"OptiScaler files copied to {directory}",
+ }
- def _manual_unpatch_directory_impl(self, directory: Path) -> dict:
- try:
- decky.logger.info(f"Manual unpatch started for {directory}")
+ except PermissionError as exc:
+ decky.logger.error(f"Manual patch permission error: {exc}")
+ return {
+ "status": "error",
+ "message": f"Permission error while patching: {exc}",
+ }
+ except Exception as exc:
+ decky.logger.error(f"Manual patch failed: {exc}")
+ return {
+ "status": "error",
+ "message": f"Manual patch failed: {exc}",
+ }
- for filename in set(INJECTOR_FILENAMES + SUPPORT_FILES):
- path = directory / filename
- if path.exists():
+ def _manual_unpatch_directory_impl(self, directory: Path) -> dict:
+ try:
+ decky.logger.info(f"Manual unpatch started for {directory}")
+
+ removed_files = []
+ for filename in set(INJECTOR_FILENAMES + SUPPORT_FILES):
+ path = directory / filename
+ if path.exists():
+ path.unlink()
+ removed_files.append(filename)
+ decky.logger.info(f"Removed injector/support files: {removed_files}" if removed_files else "No injector/support files found to remove")
+
+ legacy_removed = []
+ for legacy in LEGACY_FILES:
+ path = directory / legacy
+ if path.exists():
+ try:
path.unlink()
+ except IsADirectoryError:
+ shutil.rmtree(path, ignore_errors=True)
+ legacy_removed.append(legacy)
+ decky.logger.info(f"Removed legacy artifacts: {legacy_removed}" if legacy_removed else "No legacy artifacts present")
+
+ plugins_dir = directory / "plugins"
+ if plugins_dir.exists():
+ shutil.rmtree(plugins_dir, ignore_errors=True)
+ decky.logger.info(f"Removed plugins directory at {plugins_dir}")
+
+ restored_backups = []
+ for dll in ORIGINAL_DLL_BACKUPS:
+ backup = directory / f"{dll}.b"
+ original = directory / dll
+ if backup.exists():
+ if original.exists():
+ original.unlink()
+ shutil.move(backup, original)
+ restored_backups.append(dll)
+ decky.logger.info(f"Restored backups: {restored_backups}" if restored_backups else "No backups found to restore")
+
+ uninstaller = directory / "fgmod-uninstaller.sh"
+ if uninstaller.exists():
+ uninstaller.unlink()
+ decky.logger.info(f"Removed fgmod uninstaller at {uninstaller}")
+
+ decky.logger.info(f"Manual unpatch complete for {directory}")
+ return {
+ "status": "success",
+ "message": f"OptiScaler files removed from {directory}",
+ }
- for legacy in LEGACY_FILES:
- path = directory / legacy
- if path.exists():
- try:
- path.unlink()
- except IsADirectoryError:
- shutil.rmtree(path, ignore_errors=True)
-
- plugins_dir = directory / "plugins"
- if plugins_dir.exists():
- shutil.rmtree(plugins_dir, ignore_errors=True)
-
- for dll in ORIGINAL_DLL_BACKUPS:
- backup = directory / f"{dll}.b"
- original = directory / dll
- if backup.exists():
- if original.exists():
- original.unlink()
- shutil.move(backup, original)
-
- uninstaller = directory / "fgmod-uninstaller.sh"
- if uninstaller.exists():
- uninstaller.unlink()
-
- decky.logger.info(f"Manual unpatch complete for {directory}")
- return {
- "status": "success",
- "message": f"OptiScaler files removed from {directory}",
- }
-
- except PermissionError as exc:
- decky.logger.error(f"Manual unpatch permission error: {exc}")
- return {
- "status": "error",
- "message": f"Permission error while unpatching: {exc}",
- }
- except Exception as exc:
- decky.logger.error(f"Manual unpatch failed: {exc}")
- return {
- "status": "error",
- "message": f"Manual unpatch failed: {exc}",
- }
+ except PermissionError as exc:
+ decky.logger.error(f"Manual unpatch permission error: {exc}")
+ return {
+ "status": "error",
+ "message": f"Permission error while unpatching: {exc}",
+ }
+ except Exception as exc:
+ decky.logger.error(f"Manual unpatch failed: {exc}")
+ return {
+ "status": "error",
+ "message": f"Manual unpatch failed: {exc}",
+ }
async def list_installed_games(self) -> dict:
try: