2022-12-24 09:49:27 +13:00
|
|
|
import os
|
2023-02-02 09:40:46 +13:00
|
|
|
import platform
|
2023-02-02 01:17:51 +13:00
|
|
|
import time
|
|
|
|
from configparser import ConfigParser
|
2023-01-26 00:04:21 +13:00
|
|
|
from logging import getLogger
|
2023-03-13 05:59:58 +13:00
|
|
|
from typing import Union, Iterable
|
2022-12-24 09:49:27 +13:00
|
|
|
|
2023-03-12 12:09:51 +13:00
|
|
|
from PyQt5.QtCore import pyqtSignal, QObject, QRunnable
|
2022-12-24 09:49:27 +13:00
|
|
|
|
2023-03-10 23:27:13 +13:00
|
|
|
import rare.utils.wine as wine
|
2022-12-27 04:26:33 +13:00
|
|
|
from rare.lgndr.core import LegendaryCore
|
2023-02-02 01:17:51 +13:00
|
|
|
from rare.models.game import RareGame
|
2022-12-24 09:49:27 +13:00
|
|
|
from rare.models.pathspec import PathSpec
|
2023-03-10 23:27:13 +13:00
|
|
|
from rare.utils.misc import path_size, format_size
|
2023-02-01 00:59:22 +13:00
|
|
|
from .worker import Worker
|
2022-12-24 09:49:27 +13:00
|
|
|
|
2023-02-02 09:40:46 +13:00
|
|
|
if platform.system() == "Windows":
|
|
|
|
# noinspection PyUnresolvedReferences
|
|
|
|
import winreg # pylint: disable=E0401
|
|
|
|
from legendary.lfs import windows_helpers
|
|
|
|
|
2023-01-26 00:04:21 +13:00
|
|
|
logger = getLogger("WineResolver")
|
|
|
|
|
2022-12-24 09:49:27 +13:00
|
|
|
|
2023-02-01 00:59:22 +13:00
|
|
|
class WineResolver(Worker):
|
2022-12-24 09:49:27 +13:00
|
|
|
class Signals(QObject):
|
|
|
|
result_ready = pyqtSignal(str)
|
|
|
|
|
2022-12-27 04:26:33 +13:00
|
|
|
def __init__(self, core: LegendaryCore, path: str, app_name: str):
|
2022-12-24 09:49:27 +13:00
|
|
|
super(WineResolver, self).__init__()
|
|
|
|
self.signals = WineResolver.Signals()
|
2023-03-10 23:27:13 +13:00
|
|
|
self.wine_env = wine.environ(core, app_name)
|
|
|
|
self.wine_exec = wine.wine(core, app_name)
|
2022-12-24 09:49:27 +13:00
|
|
|
self.path = PathSpec(core, app_name).cook(path)
|
|
|
|
|
2023-02-01 00:59:22 +13:00
|
|
|
def run_real(self):
|
2022-12-24 09:49:27 +13:00
|
|
|
if "WINEPREFIX" not in self.wine_env or not os.path.exists(self.wine_env["WINEPREFIX"]):
|
|
|
|
# pylint: disable=E1136
|
|
|
|
self.signals.result_ready[str].emit("")
|
|
|
|
return
|
2023-03-10 23:27:13 +13:00
|
|
|
if not os.path.exists(self.wine_exec) or not os.path.exists(wine.winepath(self.wine_exec)):
|
2022-12-24 09:49:27 +13:00
|
|
|
# pylint: disable=E1136
|
|
|
|
self.signals.result_ready[str].emit("")
|
|
|
|
return
|
2023-03-10 23:27:13 +13:00
|
|
|
path = wine.resolve_path(self.wine_exec, self.wine_env, self.path)
|
2022-12-24 09:49:27 +13:00
|
|
|
# Clean wine output
|
2023-03-10 23:27:13 +13:00
|
|
|
real_path = wine.convert_to_unix_path(self.wine_exec, self.wine_env, path)
|
2022-12-24 09:49:27 +13:00
|
|
|
# pylint: disable=E1136
|
|
|
|
self.signals.result_ready[str].emit(real_path)
|
|
|
|
return
|
2023-02-02 01:17:51 +13:00
|
|
|
|
|
|
|
|
2023-03-12 12:09:51 +13:00
|
|
|
class OriginWineWorker(QRunnable):
|
2023-03-13 05:59:58 +13:00
|
|
|
def __init__(self, core: LegendaryCore, games: Union[Iterable[RareGame], RareGame]):
|
2023-03-12 12:09:51 +13:00
|
|
|
super(OriginWineWorker, self).__init__()
|
2023-02-02 01:17:51 +13:00
|
|
|
self.__cache: dict[str, ConfigParser] = {}
|
2023-03-12 12:09:51 +13:00
|
|
|
self.core = core
|
2023-02-02 01:17:51 +13:00
|
|
|
if isinstance(games, RareGame):
|
|
|
|
games = [games]
|
|
|
|
self.games = games
|
|
|
|
|
2023-03-12 12:09:51 +13:00
|
|
|
def run(self) -> None:
|
2023-02-02 01:17:51 +13:00
|
|
|
t = time.time()
|
2023-03-11 08:28:37 +13:00
|
|
|
|
2023-02-02 01:17:51 +13:00
|
|
|
for rgame in self.games:
|
|
|
|
|
|
|
|
reg_path: str = rgame.game.metadata \
|
|
|
|
.get("customAttributes", {}) \
|
|
|
|
.get("RegistryPath", {}).get("value", None)
|
|
|
|
if not reg_path:
|
|
|
|
continue
|
|
|
|
|
2023-03-10 23:27:13 +13:00
|
|
|
reg_key: str = rgame.game.metadata \
|
|
|
|
.get("customAttributes", {}) \
|
|
|
|
.get("RegistryKey", {}).get("value", None)
|
2023-03-12 12:09:51 +13:00
|
|
|
if not reg_key:
|
|
|
|
continue
|
2023-03-10 23:27:13 +13:00
|
|
|
|
2023-02-02 09:40:46 +13:00
|
|
|
if platform.system() == "Windows":
|
2023-03-10 23:27:13 +13:00
|
|
|
install_dir = windows_helpers.query_registry_value(winreg.HKEY_LOCAL_MACHINE, reg_path, reg_key)
|
2023-02-02 09:40:46 +13:00
|
|
|
else:
|
2023-03-10 23:27:13 +13:00
|
|
|
wine_env = wine.environ(self.core, rgame.app_name)
|
|
|
|
wine_exec = wine.wine(self.core, rgame.app_name)
|
|
|
|
|
|
|
|
# lk: this is the original way of gettijng the path by parsing "system.reg"
|
|
|
|
wine_prefix = wine.prefix(self.core, rgame.app_name)
|
|
|
|
reg = self.__cache.get(wine_prefix, None) or wine.read_registry("system.reg", wine_prefix)
|
2023-02-02 09:40:46 +13:00
|
|
|
self.__cache[wine_prefix] = reg
|
2023-02-02 01:17:51 +13:00
|
|
|
|
2023-03-08 09:53:18 +13:00
|
|
|
reg_path = reg_path.replace("SOFTWARE", "Software").replace("WOW6432Node", "Wow6432Node")
|
|
|
|
# lk: split and rejoin the registry path to avoid slash expansion
|
|
|
|
reg_path = "\\\\".join([x for x in reg_path.split("\\") if bool(x)])
|
2023-02-02 01:17:51 +13:00
|
|
|
|
2023-03-10 23:27:13 +13:00
|
|
|
install_dir = reg.get(reg_path, f'"{reg_key}"', fallback=None)
|
|
|
|
|
|
|
|
# lk: this is the alternative way of getting the path by using wine itself
|
|
|
|
# install_dir = wine.query_reg_key(wine_exec, wine_env, f"HKLM\\{reg_path}", reg_key)
|
|
|
|
|
2023-03-08 09:53:18 +13:00
|
|
|
if install_dir:
|
2023-03-10 23:27:13 +13:00
|
|
|
install_dir = wine.convert_to_unix_path(wine_exec, wine_env, install_dir)
|
|
|
|
|
2023-02-02 01:17:51 +13:00
|
|
|
if install_dir:
|
2023-03-10 23:27:13 +13:00
|
|
|
if os.path.isdir(install_dir):
|
2023-03-11 08:28:37 +13:00
|
|
|
install_size = path_size(install_dir)
|
2023-03-12 12:09:51 +13:00
|
|
|
rgame.set_origin_attributes(install_dir, install_size)
|
2023-03-11 08:28:37 +13:00
|
|
|
logger.debug(f"Found Origin game {rgame.title} ({install_dir}, {format_size(install_size)})")
|
2023-02-02 11:02:46 +13:00
|
|
|
else:
|
|
|
|
logger.warning(f"Found Origin game {rgame.title} ({install_dir} does not exist)")
|
2023-02-02 01:17:51 +13:00
|
|
|
logger.info(f"Origin registry worker finished in {time.time() - t}s")
|