2022-12-25 01:14:41 +13:00
|
|
|
import os
|
2023-01-07 08:55:41 +13:00
|
|
|
from argparse import Namespace
|
2022-12-25 01:14:41 +13:00
|
|
|
from logging import getLogger
|
|
|
|
|
2023-02-16 06:49:04 +13:00
|
|
|
from PyQt5.QtCore import pyqtSignal, QObject
|
2022-12-25 01:14:41 +13:00
|
|
|
|
|
|
|
from rare.lgndr.cli import LegendaryCLI
|
2023-01-07 08:55:41 +13:00
|
|
|
from rare.lgndr.core import LegendaryCore
|
2022-12-25 01:14:41 +13:00
|
|
|
from rare.lgndr.glue.arguments import LgndrVerifyGameArgs
|
|
|
|
from rare.lgndr.glue.monkeys import LgndrIndirectStatus
|
2023-01-07 08:55:41 +13:00
|
|
|
from rare.models.game import RareGame
|
2023-02-03 21:55:56 +13:00
|
|
|
from .worker import QueueWorker, QueueWorkerInfo
|
2022-12-25 01:14:41 +13:00
|
|
|
|
2023-01-25 02:35:12 +13:00
|
|
|
logger = getLogger("VerifyWorker")
|
2022-12-25 01:14:41 +13:00
|
|
|
|
|
|
|
|
2023-02-01 02:43:26 +13:00
|
|
|
class VerifyWorker(QueueWorker):
|
2022-12-25 01:14:41 +13:00
|
|
|
class Signals(QObject):
|
2023-01-25 02:35:12 +13:00
|
|
|
progress = pyqtSignal(RareGame, int, int, float, float)
|
2023-01-07 08:55:41 +13:00
|
|
|
result = pyqtSignal(RareGame, bool, int, int)
|
|
|
|
error = pyqtSignal(RareGame, str)
|
2022-12-25 01:14:41 +13:00
|
|
|
|
2023-02-03 21:55:56 +13:00
|
|
|
# num: int = 0
|
|
|
|
# total: int = 1 # set default to 1 to avoid DivisionByZero before it is initialized
|
2022-12-25 01:14:41 +13:00
|
|
|
|
2023-01-21 13:15:06 +13:00
|
|
|
def __init__(self, core: LegendaryCore, args: Namespace, rgame: RareGame):
|
2022-12-25 01:14:41 +13:00
|
|
|
super(VerifyWorker, self).__init__()
|
|
|
|
self.signals = VerifyWorker.Signals()
|
2023-01-07 08:55:41 +13:00
|
|
|
self.core = core
|
|
|
|
self.args = args
|
|
|
|
self.rgame = rgame
|
2022-12-25 01:14:41 +13:00
|
|
|
|
|
|
|
def status_callback(self, num: int, total: int, percentage: float, speed: float):
|
2023-01-07 08:55:41 +13:00
|
|
|
self.rgame.signals.progress.update.emit(num * 100 // total)
|
2023-01-25 02:35:12 +13:00
|
|
|
self.signals.progress.emit(self.rgame, num, total, percentage, speed)
|
2022-12-25 01:14:41 +13:00
|
|
|
|
2023-02-03 21:55:56 +13:00
|
|
|
def worker_info(self) -> QueueWorkerInfo:
|
|
|
|
return QueueWorkerInfo(
|
|
|
|
app_name=self.rgame.app_name, app_title=self.rgame.app_title, worker_type="Verify", state=self.state
|
|
|
|
)
|
2023-02-01 02:43:26 +13:00
|
|
|
|
2023-02-01 00:59:22 +13:00
|
|
|
def run_real(self):
|
2023-01-07 08:55:41 +13:00
|
|
|
self.rgame.signals.progress.start.emit()
|
2023-02-16 21:50:53 +13:00
|
|
|
|
2022-12-25 01:14:41 +13:00
|
|
|
cli = LegendaryCLI(self.core)
|
|
|
|
status = LgndrIndirectStatus()
|
|
|
|
args = LgndrVerifyGameArgs(
|
2023-01-07 08:55:41 +13:00
|
|
|
app_name=self.rgame.app_name, indirect_status=status, verify_stdout=self.status_callback
|
2022-12-25 01:14:41 +13:00
|
|
|
)
|
|
|
|
|
|
|
|
# lk: first pass, verify with the current manifest
|
|
|
|
repair_mode = False
|
|
|
|
result = cli.verify_game(
|
|
|
|
args, print_command=False, repair_mode=repair_mode, repair_online=not self.args.offline
|
|
|
|
)
|
|
|
|
if result is None:
|
|
|
|
# lk: second pass with downloading the latest manifest
|
|
|
|
# lk: this happens if the manifest was not found and repair_mode was not requested
|
|
|
|
# lk: we already have checked if the directory exists before starting the worker
|
|
|
|
try:
|
|
|
|
# lk: this try-except block handles the exception caused by a missing manifest
|
|
|
|
# lk: and is raised only in the case we are offline
|
|
|
|
repair_mode = True
|
|
|
|
result = cli.verify_game(
|
|
|
|
args, print_command=False, repair_mode=repair_mode, repair_online=not self.args.offline
|
|
|
|
)
|
|
|
|
if result is None:
|
|
|
|
raise ValueError
|
|
|
|
except ValueError:
|
2023-01-07 08:55:41 +13:00
|
|
|
self.rgame.signals.progress.finish.emit(True)
|
|
|
|
self.signals.error.emit(self.rgame, status.message)
|
2022-12-25 01:14:41 +13:00
|
|
|
return
|
|
|
|
|
|
|
|
success = result is not None and not any(result)
|
|
|
|
if success:
|
|
|
|
# lk: if verification was successful we delete the repair file and run the clean procedure
|
|
|
|
# lk: this could probably be cut down to what is relevant for this use-case and skip the `cli` call
|
2023-01-07 08:55:41 +13:00
|
|
|
repair_file = os.path.join(self.core.lgd.get_tmp_path(), f"{self.rgame.app_name}.repair")
|
2023-01-25 02:35:12 +13:00
|
|
|
cli.install_game_cleanup(
|
|
|
|
game=self.rgame.game, igame=self.rgame.igame, repair_mode=True, repair_file=repair_file
|
|
|
|
)
|
2023-03-16 08:20:52 +13:00
|
|
|
self.rgame.needs_verification = False
|
2023-01-07 08:55:41 +13:00
|
|
|
self.rgame.update_rgame()
|
|
|
|
|
|
|
|
self.rgame.signals.progress.finish.emit(False)
|
|
|
|
self.signals.result.emit(self.rgame, success, *result)
|