Beispiel #1
0
    def __init__(self, core: LegendaryCore):
        super(GameListUninstalled, self).__init__()
        self.core = core
        self.widget = QWidget()
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        self.layout = QVBoxLayout()

        self.filter = QLineEdit()
        self.filter.textChanged.connect(self.filter_games)
        self.filter.setPlaceholderText(self.tr("Filter Games"))
        self.import_button = QPushButton(
            self.tr("Import installed Game from Epic Games Store"))
        self.import_button.clicked.connect(self.import_game)
        self.layout.addWidget(self.filter)
        self.layout.addWidget(self.import_button)
        self.widgets_uninstalled = []
        games = []
        installed = [i.app_name for i in core.get_installed_list()]
        for game in core.get_game_list():
            if not game.app_name in installed:
                games.append(game)
        games = sorted(games, key=lambda x: x.app_title)
        for game in games:
            game_widget = UninstalledGameWidget(game)
            game_widget.finished.connect(lambda: self.reload.emit())
            self.layout.addWidget(game_widget)
            self.widgets_uninstalled.append(game_widget)

        self.layout.addStretch(1)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
Beispiel #2
0
    def __init__(self, parent, core: LegendaryCore):
        super(GameListUninstalled, self).__init__(parent=parent)
        self.widget = QWidget()
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded)

        self.layout = QVBoxLayout()

        self.filter = QLineEdit()
        self.filter.textChanged.connect(self.filter_games)
        self.filter.setPlaceholderText("Filter Games")
        self.layout.addWidget(self.filter)

        self.widgets_uninstalled = []
        games = []
        installed = [i.app_name for i in core.get_installed_list()]
        for game in core.get_game_list():
            if not game.app_name in installed:
                games.append(game)
        games = sorted(games, key=lambda x: x.app_title)
        for game in games:
            game_widget = UninstalledGameWidget(game)
            self.layout.addWidget(game_widget)
            self.widgets_uninstalled.append(game_widget)

        self.layout.addStretch(1)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
Beispiel #3
0
def launch_game(app_name: str,
                lgd_core: LegendaryCore,
                offline: bool = False,
                skip_version_check: bool = False,
                username_override=None,
                wine_bin: str = None,
                wine_prfix: str = None,
                language: str = None,
                wrapper=None,
                no_wine: bool = os.name == "nt",
                extra: [] = None):
    game = lgd_core.get_installed_game(app_name)
    if not game:
        print("Game not found")
        return None
    if game.is_dlc:
        print("Game is dlc")
        return None
    if not os.path.exists(game.install_path):
        print("Game doesn't exist")
        return None

    if not offline:
        print("logging in")
        if not lgd_core.login():
            return None
        if not skip_version_check and not core.is_noupdate_game(app_name):
            # check updates
            try:
                latest = lgd_core.get_asset(app_name, update=True)
            except ValueError:
                print("Metadata doesn't exist")
                return None
            if latest.build_version != game.version:
                print("Please update game")
                return None
    params, cwd, env = lgd_core.get_launch_parameters(app_name=app_name,
                                                      offline=offline,
                                                      extra_args=extra,
                                                      user=username_override,
                                                      wine_bin=wine_bin,
                                                      wine_pfx=wine_prfix,
                                                      language=language,
                                                      wrapper=wrapper,
                                                      disable_wine=no_wine)
    process = QProcess()
    process.setWorkingDirectory(cwd)
    environment = QProcessEnvironment()
    for e in env:
        environment.insert(e, env[e])
    process.setProcessEnvironment(environment)
    process.start(params[0], params[1:])
    return process
Beispiel #4
0
    def __init__(self, parent, core: LegendaryCore):
        super(GameListInstalled, self).__init__(parent=parent)
        self.widget = QWidget()
        self.core = core
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        self.layout = QVBoxLayout()
        self.widgets = {}
        for i in sorted(core.get_installed_list(), key=lambda game: game.title):
            widget = GameWidget(i, core)
            widget.signal.connect(self.remove_game)
            self.widgets[i.app_name] = widget
            self.layout.addWidget(widget)
        self.widget.setLayout(self.layout)
        self.setWidget(self.widget)
Beispiel #5
0
    def __init__(self, core: LegendaryCore):
        super(LaunchDialog, self).__init__()

        self.title = QLabel("<h3>" + self.tr("Launching Rare") + "</h3>")
        self.thread = LaunchThread(core, self)
        self.thread.download_progess.connect(self.update_pb)
        self.thread.action.connect(self.info)
        self.info_pb = QProgressBar()
        self.info_pb.setMaximum(len(core.get_game_list()))
        self.info_text = QLabel(self.tr("Logging in"))
        self.layout = QVBoxLayout()

        self.layout.addWidget(self.title)
        self.layout.addWidget(self.info_pb)
        self.layout.addWidget(self.info_text)

        self.setLayout(self.layout)
        self.thread.start()
Beispiel #6
0
 def __init__(self):
     self.core = LegendaryCore()
     self.logger = logging.getLogger('cli')
     self.logging_queue = None
Beispiel #7
0
class LegendaryCLI:
    def __init__(self):
        self.core = LegendaryCore()
        self.logger = logging.getLogger('cli')
        self.logging_queue = None

    def setup_threaded_logging(self):
        self.logging_queue = MPQueue(-1)
        shandler = logging.StreamHandler()
        sformatter = logging.Formatter(
            '[%(asctime)s] [%(name)s] %(levelname)s: %(message)s')
        shandler.setFormatter(sformatter)
        ql = QueueListener(self.logging_queue, shandler)
        ql.start()
        return ql

    def auth(self, args):
        try:
            logger.info('Testing existing login data if present...')
            if self.core.login():
                logger.info(
                    'Stored credentials are still valid, if you wish to switch to a different'
                    'account, delete ~/.config/legendary/user.json and try again.'
                )
                exit(0)
        except ValueError:
            pass
        except InvalidCredentialsError:
            logger.error(
                'Stored credentials were found but were no longer valid. Continuing with login...'
            )
            self.core.lgd.invalidate_userdata()

        if os.name == 'nt' and args.import_egs_auth:
            logger.info('Importing login session from the Epic Launcher...')
            try:
                if self.core.auth_import():
                    logger.info(
                        'Successfully imported login session from EGS!')
                    logger.info(
                        f'Now logged in as user "{self.core.lgd.userdata["displayName"]}"'
                    )
                    exit(0)
                else:
                    logger.warning(
                        'Login session from EGS seems to no longer be valid.')
                    exit(1)
            except ValueError:
                logger.error(
                    'No EGS login session found, please login normally.')
                exit(1)

        # unfortunately the captcha stuff makes a complete CLI login flow kinda impossible right now...
        print('Please login via the epic web login!')
        webbrowser.open(
            'https://www.epicgames.com/id/login?redirectUrl=https%3A%2F%2Fwww.epicgames.com%2Fid%2Fapi%2Fexchange'
        )
        print('If web page did not open automatically, please navigate '
              'to https://www.epicgames.com/id/login in your web browser')
        print(
            '- In case you opened the link manually; please open https://www.epicgames.com/id/api/exchange '
            'in your web browser after you have finished logging in.')
        exchange_code = input('Please enter code from JSON response: ')
        exchange_token = exchange_code.strip().strip('"')

        if self.core.auth_code(exchange_token):
            logger.info(
                f'Successfully logged in as "{self.core.lgd.userdata["displayName"]}"'
            )
        else:
            logger.error('Login attempt failed, please see log for details.')

    def list_games(self, args):
        logger.info('Logging in...')
        if not self.core.login():
            logger.error('Login failed, cannot continue!')
            exit(1)
        logger.info('Getting game list... (this may take a while)')
        games, dlc_list = self.core.get_game_and_dlc_list(
            platform_override=args.platform_override,
            skip_ue=not args.include_ue)

        print('\nAvailable games:')
        for game in sorted(games, key=lambda x: x.app_title):
            print(
                f'  * {game.app_title} (App name: {game.app_name}, version: {game.app_version})'
            )
            for dlc in sorted(dlc_list[game.asset_info.catalog_item_id],
                              key=lambda d: d.app_title):
                print(
                    f'    + {dlc.app_title} (App name: {dlc.app_name}, version: {dlc.app_version})'
                )

        print(f'\nTotal: {len(games)}')

    def list_installed(self, args):
        games = self.core.get_installed_list()

        if args.check_updates:
            logger.info('Logging in to check for updates...')
            if not self.core.login():
                logger.error('Login failed! Not checking for updates.')
            else:
                self.core.get_assets(True)

        print('\nInstalled games:')
        for game in sorted(games, key=lambda x: x.title):
            print(
                f'  * {game.title} (App name: {game.app_name}, version: {game.version})'
            )
            game_asset = self.core.get_asset(game.app_name)
            if game_asset.build_version != game.version:
                print(
                    f'    -> Update available! Installed: {game.version}, Latest: {game_asset.build_version}'
                )

        print(f'\nTotal: {len(games)}')

    def launch_game(self, args, extra):
        app_name = args.app_name
        if not self.core.is_installed(app_name):
            logger.error(f'Game {app_name} is not currently installed!')
            exit(1)

        if self.core.is_dlc(app_name):
            logger.error(
                f'{app_name} is DLC; please launch the base game instead!')
            exit(1)

        # override with config value
        args.offline = self.core.is_offline_game(app_name)
        if not args.offline:
            logger.info('Logging in...')
            if not self.core.login():
                logger.error('Login failed, cannot continue!')
                exit(1)

            if not args.skip_version_check and not self.core.is_noupdate_game(
                    app_name):
                logger.info('Checking for updates...')
                installed = self.core.lgd.get_installed_game(app_name)
                latest = self.core.get_asset(app_name, update=True)
                if latest.build_version != installed.version:
                    logger.error(
                        'Game is out of date, please update or launch with update check skipping!'
                    )
                    exit(1)

        params, cwd, env = self.core.get_launch_parameters(
            app_name=app_name,
            offline=args.offline,
            extra_args=extra,
            user=args.user_name_override)

        logger.info(f'Launching {app_name}...')
        if args.dry_run:
            logger.info(f'Launch parameters: {shlex.join(params)}')
            logger.info(f'Working directory: {cwd}')
            if env:
                logger.info('Environment overrides:', env)
        else:
            logger.debug(f'Launch parameters: {shlex.join(params)}')
            logger.debug(f'Working directory: {cwd}')
            if env:
                logger.debug('Environment overrides:', env)

            subprocess.Popen(params, cwd=cwd, env=env)

    def install_game(self, args):
        if not self.core.login():
            logger.error(
                'Login failed! Cannot continue with download process.')
            exit(1)

        if args.update_only:
            if not self.core.is_installed(args.app_name):
                logger.error(
                    f'Update requested for "{args.app_name}", but app not installed!'
                )
                exit(1)

        if args.platform_override:
            args.no_install = True

        game = self.core.get_game(args.app_name, update_meta=True)

        if not game:
            logger.error(
                f'Could not find "{args.app_name}" in list of available games,'
                f'did you type the name correctly?')
            exit(1)

        if game.is_dlc:
            logger.info('Install candidate is DLC')
            app_name = game.metadata['mainGameItem']['releaseInfo'][0]['appId']
            base_game = self.core.get_game(app_name)
            # check if base_game is actually installed
            if not self.core.is_installed(app_name):
                # download mode doesn't care about whether or not something's installed
                if not args.no_install:
                    logger.fatal(f'Base game "{app_name}" is not installed!')
                    exit(1)
        else:
            base_game = None

        # todo use status queue to print progress from CLI
        dlm, analysis, igame = self.core.prepare_download(
            game=game,
            base_game=base_game,
            base_path=args.base_path,
            force=args.force,
            max_shm=args.shared_memory,
            max_workers=args.max_workers,
            game_folder=args.game_folder,
            disable_patching=args.disable_patching,
            override_manifest=args.override_manifest,
            override_old_manifest=args.override_old_manifest,
            override_base_url=args.override_base_url,
            platform_override=args.platform_override)

        # game is either up to date or hasn't changed, so we have nothing to do
        if not analysis.dl_size:
            logger.info(
                'Download size is 0, the game is either already up to date or has not changed. Exiting...'
            )
            exit(0)

        logger.info(
            f'Install size: {analysis.install_size / 1024 / 1024:.02f} MiB')
        compression = (
            1 - (analysis.dl_size / analysis.uncompressed_dl_size)) * 100
        logger.info(
            f'Download size: {analysis.dl_size / 1024 / 1024:.02f} MiB '
            f'(Compression savings: {compression:.01f}%)')
        logger.info(
            f'Reusable size: {analysis.reuse_size / 1024 / 1024:.02f} MiB (chunks) / '
            f'{analysis.unchanged / 1024 / 1024:.02f} MiB (unchanged)')

        res = self.core.check_installation_conditions(analysis=analysis,
                                                      install=igame)

        if res.failures:
            logger.fatal(
                'Download cannot proceed, the following errors occured:')
            for msg in sorted(res.failures):
                logger.fatal(msg)
            exit(1)

        if res.warnings:
            logger.warning(
                'Installation requirements check returned the following warnings:'
            )
            for warn in sorted(res.warnings):
                logger.warning(warn)

        if not args.yes:
            choice = input(f'Do you wish to install "{igame.title}"? [Y/n]: ')
            if choice and choice.lower()[0] != 'y':
                print('Aborting...')
                exit(0)

        start_t = time.time()

        try:
            # set up logging stuff (should be moved somewhere else later)
            dlm.logging_queue = self.logging_queue
            dlm.proc_debug = args.dlm_debug

            dlm.start()
            dlm.join()
        except Exception as e:
            end_t = time.time()
            logger.info(
                f'Installation failed after {end_t - start_t:.02f} seconds.')
            logger.warning(
                f'The following exception occured while waiting for the donlowader to finish: {e!r}. '
                f'Try restarting the process, the resume file will be used to start where it failed. '
                f'If it continues to fail please open an issue on GitHub.')
        else:
            end_t = time.time()
            if not args.no_install:
                dlcs = self.core.get_dlc_for_game(game.app_name)
                if dlcs:
                    print('The following DLCs are available for this game:')
                    for dlc in dlcs:
                        print(
                            f' - {dlc.app_title} (App name: {dlc.app_name}, version: {dlc.app_version})'
                        )
                    # todo recursively call install with modified args to install DLC automatically (after confirm)
                    print(
                        'Installing DLCs works the same as the main game, just use the DLC app name instead.'
                    )
                    print(
                        '(Automatic installation of DLC is currently not supported.)'
                    )

                postinstall = self.core.install_game(igame)
                if postinstall:
                    self._handle_postinstall(postinstall, igame, yes=args.yes)

            logger.info(
                f'Finished installation process in {end_t - start_t:.02f} seconds.'
            )

    def _handle_postinstall(self, postinstall, igame, yes=False):
        print('This game lists the following prequisites to be installed:')
        print(
            f'- {postinstall["name"]}: {" ".join((postinstall["path"], postinstall["args"]))}'
        )
        if os.name == 'nt':
            if yes:
                c = 'n'  # we don't want to launch anything, just silent install.
            else:
                choice = input(
                    'Do you wish to install the prerequisites? ([y]es, [n]o, [i]gnore): '
                )
                c = choice.lower()[0]

            if c == 'i':  # just set it to installed
                print('Marking prerequisites as installed...')
                self.core.prereq_installed(igame.app_name)
            elif c == 'y':  # set to installed and launch installation
                print('Launching prerequisite executable..')
                self.core.prereq_installed(igame.app_name)
                req_path, req_exec = os.path.split(postinstall['path'])
                work_dir = os.path.join(igame.install_path, req_path)
                fullpath = os.path.join(work_dir, req_exec)
                subprocess.Popen([fullpath, postinstall['args']], cwd=work_dir)
        else:
            logger.info('Automatic installation not available on Linux.')

    def uninstall_game(self, args):
        igame = self.core.get_installed_game(args.app_name)
        if not igame:
            logger.error(
                f'Game {args.app_name} not installed, cannot uninstall!')
            exit(0)
        if igame.is_dlc:
            logger.error('Uninstalling DLC is not supported.')
            exit(1)

        if not args.yes:
            choice = input(
                f'Do you wish to uninstall "{igame.title}"? [y/N]: ')
            if not choice or choice.lower()[0] != 'y':
                print('Aborting...')
                exit(0)

        try:
            logger.info(
                f'Removing "{igame.title}" from "{igame.install_path}"...')
            self.core.uninstall_game(igame)

            # DLCs are already removed once we delete the main game, so this just removes them from the list
            dlcs = self.core.get_dlc_for_game(igame.app_name)
            for dlc in dlcs:
                idlc = self.core.get_installed_game(dlc.app_name)
                if self.core.is_installed(dlc.app_name):
                    logger.info(f'Uninstalling DLC "{dlc.app_name}"...')
                    self.core.uninstall_game(idlc, delete_files=False)

            logger.info('Game has been uninstalled.')
        except Exception as e:
            logger.warning(
                f'Removing game failed: {e!r}, please remove {igame.install_path} manually.'
            )
Beispiel #8
0
class LegendaryCLI:
    def __init__(self):
        self.core = LegendaryCore()
        self.logger = logging.getLogger('cli')
        self.logging_queue = None

    def setup_threaded_logging(self):
        self.logging_queue = MPQueue(-1)
        shandler = logging.StreamHandler()
        sformatter = logging.Formatter('[%(name)s] %(levelname)s: %(message)s')
        shandler.setFormatter(sformatter)
        ql = QueueListener(self.logging_queue, shandler)
        ql.start()
        return ql

    def install_game(self, manifest: str, game_folder: str,
                     override_base_url: str):
        game = self.core.get_game('Fortnite', update_meta=True)
        base_game = None

        logger.info('Preparing download...')
        # todo use status queue to print progress from CLI
        # This has become a little ridiculous hasn't it?
        dlm, analysis, igame = self.core.prepare_download(
            game=game,
            base_game=base_game,
            base_path=None,
            force=None,
            max_shm=None,
            max_workers=None,
            game_folder=game_folder,
            disable_patching=None,
            override_manifest=manifest,
            override_old_manifest=None,
            override_base_url=override_base_url,
            platform_override=None,
            file_prefix_filter=None,
            file_exclude_filter=None,
            file_install_tag=None,
            dl_optimizations=None,
            dl_timeout=None,
            repair=None,
            repair_use_latest=None,
            disable_delta=None,
            override_delta_manifest=None)

        # game is either up to date or hasn't changed, so we have nothing to doc
        if not analysis.dl_size:
            logger.info(
                'Download size is 0, the game is either already up to date or has not changed. Exiting...'
            )
            if args.repair_mode and os.path.exists(repair_file):
                igame = self.core.get_installed_game(game.app_name)
                if igame.needs_verification:
                    igame.needs_verification = False
                    self.core.install_game(igame)

                logger.debug('Removing repair file.')
                os.remove(repair_file)
            exit(0)

        logger.info(
            f'Install size: {analysis.install_size / 1024 / 1024:.02f} MiB')
        compression = (
            1 - (analysis.dl_size / analysis.uncompressed_dl_size)) * 100
        logger.info(
            f'Download size: {analysis.dl_size / 1024 / 1024:.02f} MiB '
            f'(Compression savings: {compression:.01f}%)')
        logger.info(
            f'Reusable size: {analysis.reuse_size / 1024 / 1024:.02f} MiB (chunks) / '
            f'{analysis.unchanged / 1024 / 1024:.02f} MiB (unchanged / skipped)'
        )

        res = self.core.check_installation_conditions(analysis=analysis,
                                                      install=igame,
                                                      game=game,
                                                      updating=False,
                                                      ignore_space_req=None)

        if res.warnings or res.failures:
            logger.info(
                'Installation requirements check returned the following results:'
            )

        if res.warnings:
            for warn in sorted(res.warnings):
                logger.warning(warn)

        if res.failures:
            for msg in sorted(res.failures):
                logger.fatal(msg)
            logger.error('Installation cannot proceed, exiting.')
            if not input('Do you want to continue anyway (y/N): ').lower(
            ).startswith('y'):
                exit(1)

        logger.info(
            'Downloads are resumable, you can interrupt the download with '
            'CTRL-C and resume it using the same command later on.')

        start_t = time.time()

        try:
            # set up logging stuff (should be moved somewhere else later)
            dlm.logging_queue = self.logging_queue
            dlm.proc_debug = None

            dlm.start()
            dlm.join()
        except Exception as e:
            end_t = time.time()
            logger.info(
                f'Installation failed after {end_t - start_t:.02f} seconds.')
            logger.warning(
                f'The following exception occured while waiting for the donlowader to finish: {e!r}. '
                f'Try restarting the process, the resume file will be used to start where it failed. '
                f'If it continues to fail please open an issue on GitHub.')
        else:
            end_t = time.time()
            logger.info(
                f'Finished installation process in {end_t - start_t:.02f} seconds.'
            )
Beispiel #9
0
def download_images(signal: pyqtSignal, core: LegendaryCore):
    if not os.path.isdir(IMAGE_DIR):
        os.makedirs(IMAGE_DIR)
        logger.info("Create Image dir")

    # Download Images
    for i, game in enumerate(
            sorted(core.get_game_list(), key=lambda x: x.app_title)):

        if not os.path.isdir(f"{IMAGE_DIR}/" + game.app_name):
            os.mkdir(f"{IMAGE_DIR}/" + game.app_name)

        if not os.path.isfile(f"{IMAGE_DIR}/{game.app_name}/image.json"):
            json_data = {"DieselGameBoxTall": None, "DieselGameBoxLogo": None}
        else:
            json_data = json.load(
                open(f"{IMAGE_DIR}/{game.app_name}/image.json", "r"))

        for image in game.metadata["keyImages"]:
            if image["type"] == "DieselGameBoxTall" or image[
                    "type"] == "DieselGameBoxLogo":

                if json_data[
                        image["type"]] != image["md5"] or not os.path.isfile(
                            f"{IMAGE_DIR}/{game.app_name}/{image['type']}.png"
                        ):
                    # Download
                    json_data[image["type"]] = image["md5"]
                    # os.remove(f"{IMAGE_DIR}/{game.app_name}/{image['type']}.png")
                    json.dump(
                        json_data,
                        open(f"{IMAGE_DIR}/{game.app_name}/image.json", "w"))
                    logger.info(f"Download Image for Game: {game.app_title}")
                    url = image["url"]
                    with open(
                            f"{IMAGE_DIR}/{game.app_name}/{image['type']}.png",
                            "wb") as f:
                        f.write(requests.get(url).content)
                        f.close()

        if not os.path.isfile(f'{IMAGE_DIR}/' + game.app_name +
                              '/UninstalledArt.png'):

            if os.path.isfile(f'{IMAGE_DIR}/' + game.app_name +
                              '/DieselGameBoxTall.png'):
                # finalArt = Image.open(f'{IMAGE_DIR}/' + game.app_name + '/DieselGameBoxTall.png')
                # finalArt.save(f'{IMAGE_DIR}/{game.app_name}/FinalArt.png')
                # And same with the grayscale one

                bg = Image.open(
                    f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png")
                uninstalledArt = bg.convert('L')
                uninstalledArt.save(
                    f'{IMAGE_DIR}/{game.app_name}/UninstalledArt.png')
            elif os.path.isfile(
                    f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png"):
                bg: Image.Image = Image.open(
                    f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png")
                bg = bg.resize((int(bg.size[1] * 3 / 4), bg.size[1]))
                logo = Image.open(
                    f'{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png'
                ).convert('RGBA')
                wpercent = ((bg.size[0] * (3 / 4)) / float(logo.size[0]))
                hsize = int((float(logo.size[1]) * float(wpercent)))
                logo = logo.resize((int(bg.size[0] * (3 / 4)), hsize),
                                   Image.ANTIALIAS)
                # Calculate where the image has to be placed
                pasteX = int((bg.size[0] - logo.size[0]) / 2)
                pasteY = int((bg.size[1] - logo.size[1]) / 2)
                # And finally copy the background and paste in the image
                # finalArt = bg.copy()
                # finalArt.paste(logo, (pasteX, pasteY), logo)
                # Write out the file
                # finalArt.save(f'{IMAGE_DIR}/' + game.app_name + '/FinalArt.png')
                logoCopy = logo.copy()
                logoCopy.putalpha(int(256 * 3 / 4))
                logo.paste(logoCopy, logo)
                uninstalledArt = bg.copy()
                uninstalledArt.paste(logo, (pasteX, pasteY), logo)
                uninstalledArt = uninstalledArt.convert('L')
                uninstalledArt.save(f'{IMAGE_DIR}/' + game.app_name +
                                    '/UninstalledArt.png')
            else:
                logger.warning(
                    f"File {IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png dowsn't exist"
                )
        signal.emit(i)
Beispiel #10
0
import logging
import os
import subprocess

from PyQt5.QtCore import QProcess, QProcessEnvironment, QThread
from legendary.core import LegendaryCore

logger = logging.getLogger("LGD")
core = LegendaryCore()


def get_installed():
    return sorted(core.get_installed_list(), key=lambda name: name.title)


def get_installed_names():
    return [i.app_name for i in core.get_installed_list()]


def get_not_installed():
    games = []
    installed = get_installed_names()
    for game in get_games():
        if not game.app_name in installed:
            games.append(game)
    return games


# return (games, dlcs)
def get_games_and_dlcs():
    if not core.login():
Beispiel #11
0
 def update_list(self):
     self.core = LegendaryCore()
     del self.widget
     self.setWidget(QWidget())
     self.init_ui()
     self.update()
Beispiel #12
0
    def __init__(self, game: InstalledGame, core: LegendaryCore):
        super(GameWidget, self).__init__()
        self.core = core
        self.game = game
        self.dev = core.get_game(self.game.app_name).metadata["developer"]
        self.title = game.title
        self.app_name = game.app_name
        self.version = game.version
        self.size = game.install_size
        self.launch_params = game.launch_parameters
        # self.dev =
        self.game_running = False
        self.layout = QHBoxLayout()
        if os.path.exists(f"{IMAGE_DIR}/{game.app_name}/FinalArt.png"):
            pixmap = QPixmap(f"{IMAGE_DIR}/{game.app_name}/FinalArt.png")
        elif os.path.exists(
                f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png"):
            pixmap = QPixmap(
                f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxTall.png")
        elif os.path.exists(
                f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png"):
            pixmap = QPixmap(
                f"{IMAGE_DIR}/{game.app_name}/DieselGameBoxLogo.png")
        else:
            logger.warning(f"No Image found: {self.game.title}")
            pixmap = None
        if pixmap:

            pixmap = pixmap.scaled(180, 240)
            self.image = QLabel()
            self.image.setPixmap(pixmap)
            self.layout.addWidget(self.image)

        ##Layout on the right
        self.childLayout = QVBoxLayout()

        play_icon = self.style().standardIcon(getattr(QStyle, 'SP_MediaPlay'))
        settings_icon = self.style().standardIcon(getattr(
            QStyle, 'SP_DirIcon'))
        self.title_widget = QLabel(f"<h1>{self.title}</h1>")
        self.launch_button = QPushButton(play_icon, "Launch")
        self.launch_button.clicked.connect(self.launch)
        self.wine_rating = QLabel("Wine Rating: " + self.get_rating())
        self.developer_label = QLabel("Dev: " + self.dev)
        self.version_label = QLabel("Version: " + str(self.version))
        self.size_label = QLabel(
            f"Installed size: {round(self.size / (1024 ** 3), 2)} GB")
        self.settings_button = QPushButton(settings_icon,
                                           " Settings (Icon TODO)")
        self.settings_button.clicked.connect(self.settings)

        self.childLayout.addWidget(self.title_widget)
        self.childLayout.addWidget(self.launch_button)
        self.childLayout.addWidget(self.developer_label)
        self.childLayout.addWidget(self.wine_rating)
        self.childLayout.addWidget(self.version_label)
        self.childLayout.addWidget(self.size_label)
        self.childLayout.addWidget(self.settings_button)

        self.childLayout.addStretch(1)
        self.layout.addLayout(self.childLayout)
        self.layout.addStretch(1)
        self.setLayout(self.layout)