1
0
Fork 0
mirror of synced 2024-06-29 19:51:02 +12:00

Fix startup_check and verification

This commit is contained in:
Dummerle 2022-01-15 16:40:31 +01:00
parent 761204aa80
commit 45163eafb5
No known key found for this signature in database
GPG key ID: AB68CC59CA39F2F1
3 changed files with 48 additions and 75 deletions

View file

@ -19,6 +19,7 @@ from rare import cache_dir, resources_path
from rare.components.dialogs.launch_dialog import LaunchDialog from rare.components.dialogs.launch_dialog import LaunchDialog
from rare.components.main_window import MainWindow from rare.components.main_window import MainWindow
from rare.components.tray_icon import TrayIcon from rare.components.tray_icon import TrayIcon
from rare.utils import legendary_utils
from rare.utils.utils import set_color_pallete, set_style_sheet from rare.utils.utils import set_color_pallete, set_style_sheet
start_time = time.strftime("%y-%m-%d--%H-%M") # year-month-day-hour-minute start_time = time.strftime("%y-%m-%d--%H-%M") # year-month-day-hour-minute
@ -158,11 +159,15 @@ class App(QApplication):
self.mainwindow.show_window_centralized() self.mainwindow.show_window_centralized()
def start_app(self): def start_app(self):
for igame in self.core.get_installed_list(): for igame in self.core.get_installed_list():
if not os.path.exists(igame.executable): if not os.path.exists(igame.install_path):
legendary_utils.uninstall(igame.app_name, self.core)
logger.info(f"Uninstalled {igame.title}, because no game files exist")
continue
if not os.path.exists(os.path.join(igame.install_path, igame.executable)):
igame.needs_verification = True igame.needs_verification = True
self.core.lgd.set_installed_game(igame.app_name, igame) self.core.lgd.set_installed_game(igame.app_name, igame)
logger.info(f"{igame.title} needs verification")
self.mainwindow = MainWindow() self.mainwindow = MainWindow()
self.launch_dialog.close() self.launch_dialog.close()

View file

@ -88,17 +88,17 @@ class GameInfo(QWidget, Ui_GameInfo):
) )
return return
self.verify_widget.setCurrentIndex(1) self.verify_widget.setCurrentIndex(1)
verify_worker = VerifyWorker(self.core, self.game.app_name) verify_worker = VerifyWorker(self.game.app_name)
verify_worker.signals.status.connect(self.verify_staistics) verify_worker.signals.status.connect(self.verify_staistics)
verify_worker.signals.summary.connect(self.finish_verify) verify_worker.signals.summary.connect(self.finish_verify)
self.verify_progress.setValue(0) self.verify_progress.setValue(0)
self.verify_threads[self.game.app_name] = verify_worker self.verify_threads[self.game.app_name] = verify_worker
self.verify_pool.start(verify_worker) self.verify_pool.start(verify_worker)
def verify_staistics(self, progress): def verify_staistics(self, num, total, app_name):
# checked, max, app_name # checked, max, app_name
if progress[2] == self.game.app_name: if app_name == self.game.app_name:
self.verify_progress.setValue(progress[0] * 100 // progress[1]) self.verify_progress.setValue(num * 100 // total)
def finish_verify(self, failed, missing, app_name): def finish_verify(self, failed, missing, app_name):
if failed == missing == 0: if failed == missing == 0:

View file

@ -4,11 +4,11 @@ import shutil
from logging import getLogger from logging import getLogger
from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QRunnable from PyQt5.QtCore import pyqtSignal, QCoreApplication, QObject, QRunnable
from PyQt5.QtWidgets import QMessageBox
from legendary.core import LegendaryCore from legendary.core import LegendaryCore
from legendary.models.game import VerifyResult from legendary.models.game import VerifyResult
from legendary.utils.lfs import validate_files from legendary.utils.lfs import validate_files
from rare import shared
logger = getLogger("Legendary Utils") logger = getLogger("Legendary Utils")
@ -92,7 +92,7 @@ def update_manifest(app_name: str, core: LegendaryCore):
class VerifySignals(QObject): class VerifySignals(QObject):
status = pyqtSignal(tuple) status = pyqtSignal(int, int, str)
summary = pyqtSignal(int, int, str) summary = pyqtSignal(int, int, str)
@ -100,97 +100,65 @@ class VerifyWorker(QRunnable):
num: int = 0 num: int = 0
total: int = 1 # set default to 1 to avoid DivisionByZero before it is initialized total: int = 1 # set default to 1 to avoid DivisionByZero before it is initialized
def __init__(self, core, app_name): def __init__(self, app_name):
super(VerifyWorker, self).__init__() super(VerifyWorker, self).__init__()
self.core, self.app_name = core, app_name self.app_name = app_name
self.signals = VerifySignals() self.signals = VerifySignals()
self.setAutoDelete(True) self.setAutoDelete(True)
def run(self): def run(self):
if not self.core.is_installed(self.app_name): if not shared.core.is_installed(self.app_name):
logger.error(f'Game "{self.app_name}" is not installed') logger.error(f'Game "{self.app_name}" is not installed')
return return
igame = self.core.get_installed_game(self.app_name)
logger.info(f'Loading installed manifest for "{igame.title}"') logger.info(f'Loading installed manifest for "{self.app_name}"')
manifest_data, _ = self.core.get_installed_manifest(self.app_name) igame = shared.core.get_installed_game(self.app_name)
if not manifest_data: manifest_data, _ = shared.core.get_installed_manifest(self.app_name)
update_manifest(self.app_name, self.core) manifest = shared.core.load_manifest(manifest_data)
manifest_data, _ = self.core.get_installed_manifest(self.app_name)
if not manifest_data:
self.signals.summary.emit(-1, -1, self.app_name)
return
manifest = self.core.load_manifest(manifest_data) files = sorted(manifest.file_manifest_list.elements,
key=lambda a: a.filename.lower())
files = sorted(
manifest.file_manifest_list.elements, key=lambda a: a.filename.lower()
)
# build list of hashes # build list of hashes
file_list = [(f.filename, f.sha_hash.hex()) for f in files] file_list = [(f.filename, f.sha_hash.hex()) for f in files]
self.total = len(file_list) total = len(file_list)
self.num = 0 num = 0
failed = [] failed = []
missing = [] missing = []
_translate = QCoreApplication.translate logger.info(f'Verifying "{igame.title}" version "{manifest.meta.build_version}"')
logger.info(
f'Verifying "{igame.title}" version "{manifest.meta.build_version}"'
)
repair_file = [] repair_file = []
try: for result, path, result_hash, _ in validate_files(igame.install_path, file_list):
for result, path, result_hash in validate_files( num += 1
igame.install_path, file_list self.signals.status.emit(num, total, self.app_name)
):
self.signals.status.emit((self.num, self.total, self.app_name))
self.num += 1
if result == VerifyResult.HASH_MATCH: if result == VerifyResult.HASH_MATCH:
repair_file.append(f"{result_hash}:{path}") repair_file.append(f"{result_hash}:{path}")
continue continue
elif result == VerifyResult.HASH_MISMATCH: elif result == VerifyResult.HASH_MISMATCH:
logger.error(f'File does not match hash: "{path}"') logger.error(f'File does not match hash: "{path}"')
repair_file.append(f"{result_hash}:{path}") repair_file.append(f"{result_hash}:{path}")
failed.append(path) failed.append(path)
elif result == VerifyResult.FILE_MISSING: elif result == VerifyResult.FILE_MISSING:
logger.error(f'File is missing: "{path}"') logger.error(f'File is missing: "{path}"')
missing.append(path) missing.append(path)
else: else:
logger.error( logger.error(f'Other failure (see log), treating file as missing: "{path}"')
f'Other failure (see log), treating file as missing: "{path}"' missing.append(path)
)
missing.append(path)
except OSError as e:
QMessageBox.warning(
None, "Error", _translate("VerifyWorker", "Path does not exist")
)
logger.error(str(e))
except ValueError as e:
QMessageBox.warning(
None, "Error", _translate("VerifyWorker", "No files to validate")
)
logger.error(str(e))
# always write repair file, even if all match # always write repair file, even if all match
if repair_file: if repair_file:
repair_filename = os.path.join( repair_filename = os.path.join(shared.core.lgd.get_tmp_path(), f'{self.app_name}.repair')
self.core.lgd.get_tmp_path(), f"{self.app_name}.repair" with open(repair_filename, 'w') as f:
) f.write('\n'.join(repair_file))
with open(repair_filename, "w") as f:
f.write("\n".join(repair_file))
logger.debug(f'Written repair file to "{repair_filename}"') logger.debug(f'Written repair file to "{repair_filename}"')
if not missing and not failed: if not missing and not failed:
logger.info("Verification finished successfully.") logger.info('Verification finished successfully.')
self.signals.summary.emit(0, 0, self.app_name)
else: else:
logger.error( logger.warning(
f"Verification finished, {len(failed)} file(s) corrupted, {len(missing)} file(s) are missing." f'Verification failed, {len(failed)} file(s) corrupted, {len(missing)} file(s) are missing.')
) self.signals.summary.emit(len(failed), len(missing), self.app_name)
self.signals.summary.emit(len(failed), len(missing), self.app_name)
def import_game(core: LegendaryCore, app_name: str, path: str) -> str: def import_game(core: LegendaryCore, app_name: str, path: str) -> str: