Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ repos:
args: [--fix=lf]
- id: check-case-conflict
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.15.20 # must match pyproject.toml
rev: v0.16.10 # must match pyproject.toml
hooks:
- id: ruff
args: [--extend-select, I, --fix]
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ from ..basic_game import BasicGame


class Witcher3Game(BasicGame):

Name = "Witcher 3 Support Plugin"
Author = "Holt59"
Version = "1.0.0a"
Expand Down Expand Up @@ -129,7 +128,6 @@ import mobase


class Witcher3Game(BasicGame):

Name = "Witcher 3 Support Plugin"
Author = "Holt59"

Expand Down
8 changes: 4 additions & 4 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

def createPlugins():
# List of game class from python:
game_plugins: typing.List[IPlugin] = []
game_plugins: list[IPlugin] = []

# We are going to list all game plugins:
curpath = os.path.abspath(os.path.dirname(__file__))
Expand All @@ -43,9 +43,9 @@ def createPlugins():
try:
module = importlib.import_module(".games." + module_p[:-3], __package__)
except ImportError as e:
print("Failed to import module {}: {}".format(module_p, e), file=sys.stderr)
print(f"Failed to import module {module_p}: {e}", file=sys.stderr)
except Exception as e:
print("Failed to import module {}: {}".format(module_p, e), file=sys.stderr)
print(f"Failed to import module {module_p}: {e}", file=sys.stderr)

# Lookup game plugins:
for name in dir(module):
Expand All @@ -60,7 +60,7 @@ def createPlugins():
game_plugins.append(obj())
except Exception as e:
print(
"Failed to instantiate {}: {}".format(name, e),
f"Failed to instantiate {name}: {e}",
file=sys.stderr,
)
for path in pathlib.Path(escaped_games_path).rglob("plugins/__init__.py"):
Expand Down
4 changes: 2 additions & 2 deletions basic_features/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
from .basic_save_game_info import BasicGameSaveGameInfo

__all__ = [
"BasicModDataChecker",
"BasicGameSaveGameInfo",
"GlobPatterns",
"BasicLocalSavegames",
"BasicModDataChecker",
"GlobPatterns",
]
7 changes: 4 additions & 3 deletions basic_features/basic_mod_data_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import fnmatch
import re
from collections.abc import Iterable
from dataclasses import dataclass, field
from typing import Iterable, Literal
from typing import Literal

import mobase

Expand All @@ -28,7 +29,7 @@ def regex_from_glob_list(glob_list: Iterable[str]) -> re.Pattern[str]:
give the `glob_list` index.
"""
return re.compile(
"|".join(f"({fnmatch.translate(f)})" for f in glob_list), re.I
"|".join(f"({fnmatch.translate(f)})" for f in glob_list), re.IGNORECASE
)

def match(self, value: str) -> bool:
Expand All @@ -48,7 +49,7 @@ def __init__(self, globs: GlobPatterns) -> None:
self.valid = OptionalRegexPattern(globs.valid)

self.move = {
key: re.compile(fnmatch.translate(key), re.I) for key in globs.move
key: re.compile(fnmatch.translate(key), re.IGNORECASE) for key in globs.move
}
self.ignore = OptionalRegexPattern(globs.ignore)

Expand Down
6 changes: 2 additions & 4 deletions basic_features/basic_save_game_info.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
# -*- encoding: utf-8 -*-

import sys
from collections.abc import Mapping
from collections.abc import Callable, Mapping, Sequence
from datetime import datetime
from pathlib import Path
from typing import Any, Callable, Self, Sequence
from typing import Any, Self

from PyQt6.QtCore import QDateTime, QLocale, Qt
from PyQt6.QtGui import QImage, QPixmap
Expand Down
11 changes: 6 additions & 5 deletions basic_game.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import shutil
import sys
from collections.abc import Callable
from pathlib import Path
from typing import Callable, Generic, TypeVar
from typing import Generic, TypeVar

from PyQt6.QtCore import QDir, QFileInfo, QStandardPaths
from PyQt6.QtGui import QIcon
Expand Down Expand Up @@ -49,7 +50,7 @@ def replace_variables(value: str, game: BasicGame) -> str:

class BasicGameMapping(Generic[_T]):
# The game:
_game: "BasicGame"
_game: BasicGame

# Name of the attribute for exposure:
_exposed_name: str
Expand All @@ -61,7 +62,7 @@ class BasicGameMapping(Generic[_T]):
_required: bool

# Callable returning a default value (if not required):
_default: Callable[["BasicGame"], _T]
_default: Callable[[BasicGame], _T]

# Function to apply to the value:
_apply_fn: Callable[[_T | str], _T] | None
Expand Down Expand Up @@ -256,7 +257,7 @@ def __init__(self, game: BasicGame):
game,
"Description",
"description",
lambda g: "Adds basic support for game {}.".format(g.gameName()),
lambda g: f"Adds basic support for game {g.gameName()}.",
)
self.gameName = BasicGameMapping(game, "GameName", "gameName")
self.gameShortName = BasicGameMapping(game, "GameShortName", "gameShortName")
Expand Down Expand Up @@ -416,7 +417,7 @@ def setup():
_gamePath: str

def __init__(self):
super(BasicGame, self).__init__()
super().__init__()

if not hasattr(self, "_fromName"):
self._fromName = self.__class__.__name__
Expand Down
2 changes: 0 additions & 2 deletions basic_game_ini.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-

import configparser
import os

Expand Down
9 changes: 3 additions & 6 deletions eadesktop_utils.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
# -*- encoding: utf-8 -*-

import configparser
import os
import sys
import xml.etree.ElementTree as et
from configparser import NoOptionError
from pathlib import Path
from typing import Dict


def find_games(errors: list[tuple[str, Exception]] | None = None) -> Dict[str, Path]:
def find_games(errors: list[tuple[str, Exception]] | None = None) -> dict[str, Path]:
"""
Find the list of EA Desktop games installed.

Returns:
A mapping from EA Desktop content IDs to install locations for available
EA Desktop games.
"""
games: Dict[str, Path] = {}
games: dict[str, Path] = {}

local_app_data_path = os.path.expandvars("%LocalAppData%")
ea_desktop_settings_path = Path(local_app_data_path).joinpath(
Expand Down Expand Up @@ -82,4 +79,4 @@ def find_games(errors: list[tuple[str, Exception]] | None = None) -> Dict[str, P
if __name__ == "__main__":
games = find_games()
for k, v in games.items():
print("Found game with id {} at {}.".format(k, v))
print(f"Found game with id {k} at {v}.")
3 changes: 1 addition & 2 deletions epic_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# -*- encoding: utf-8 -*-
from __future__ import annotations

import itertools
Expand Down Expand Up @@ -98,4 +97,4 @@ def find_games(errors: ErrorList | None = None) -> dict[str, Path]:
if __name__ == "__main__":
games = find_games()
for k, v in games.items():
print("Found game with id {} at {}.".format(k, v))
print(f"Found game with id {k} at {v}.")
4 changes: 2 additions & 2 deletions games/baldursgate3/bg3_file_mapper.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import functools
import os
from collections.abc import Callable
from pathlib import Path
from typing import Callable, Optional

from PyQt6.QtCore import QDir, QLoggingCategory, qDebug, qInfo, qWarning
from PyQt6.QtWidgets import QApplication
Expand Down Expand Up @@ -75,7 +75,7 @@ def mappings(self) -> list[mobase.Mapping]:
def map_files(
self,
path: Path,
dest: Optional[Path] = None,
dest: Path | None = None,
pattern: str = "*",
rel: bool = True,
only_convert: bool = False,
Expand Down
3 changes: 1 addition & 2 deletions games/baldursgate3/bg3_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import functools
import shutil
import typing
from pathlib import Path
from time import sleep

Expand Down Expand Up @@ -193,7 +192,7 @@ def on_settings_changed(
def construct_modsettings_xml(
self,
exec_path: str = "",
working_dir: typing.Optional[QDir] = None,
working_dir: QDir | None = None,
args: str = "",
force_reparse_metadata: bool = False,
) -> bool:
Expand Down
4 changes: 2 additions & 2 deletions games/baldursgate3/lslib_retriever.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ def __init__(self, utils: bg3_utils.BG3Utils):
def _needed_lslib_files(self):
return {
self._utils.tools_dir / x
for x in {
for x in (
"CommandLineArgumentsParser.dll",
"Divine.dll",
"Divine.dll.config",
"Divine.exe",
"Divine.runtimeconfig.json",
}
)
}

def download_lslib_if_missing(self, force: bool = False) -> bool:
Expand Down
5 changes: 2 additions & 3 deletions games/baldursgate3/pak_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
import shutil
import subprocess
import traceback
from collections.abc import Callable
from functools import cached_property
from pathlib import Path
from typing import Callable
from xml.etree import ElementTree
from xml.etree.ElementTree import Element

Expand Down Expand Up @@ -172,8 +172,7 @@ def _get_metadata_for_file(
except OSError as e:
qDebug(f"Error accessing file {file_path}: {e}")
break
else:
build_pak = False
build_pak = False
except OSError as e:
qDebug(f"Error accessing file {pak_path}: {e}")
build_pak = False
Expand Down
3 changes: 1 addition & 2 deletions games/game_arkhamcity.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,7 @@ def savesDirectory(self) -> QDir:
steamSaves = child.joinpath("200260", "remote")
if steamSaves.is_dir():
return QDir(str(steamSaves))
else:
return docSaves
return docSaves
else:
return docSaves

Expand Down
2 changes: 1 addition & 1 deletion games/game_baldursgate3.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ def _on_finished_run(self, exec_path: str, exit_code: int):
moved: dict[str, str] = {}
for path in self.utils.overwrite_path.rglob("*.log"):
try:
moved[str(path)] = str((self.utils.log_dir / path.name))
moved[str(path)] = str(self.utils.log_dir / path.name)
path.replace(self.utils.log_dir / path.name)
except PermissionError as e:
qDebug(str(e))
Expand Down
2 changes: 0 additions & 2 deletions games/game_blackandwhite2.py
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,6 @@ def detectGame(self):
if installation_path.exists():
self.setGamePath(installation_path.parent)

return

def executables(self) -> list[mobase.ExecutableInfo]:
execs = super().executables()

Expand Down
4 changes: 2 additions & 2 deletions games/game_borderlands1.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
from ..basic_features import BasicModDataChecker
from ..basic_game import BasicGame

_extention_pattern = re.compile("\\.(upk|umap|u|int|dll|exe)$", re.I)
_mapslot_pattern = re.compile("^Mapslot\\d\\d?\\.umap$", re.I)
_extention_pattern = re.compile("\\.(upk|umap|u|int|dll|exe)$", re.IGNORECASE)
_mapslot_pattern = re.compile("^Mapslot\\d\\d?\\.umap$", re.IGNORECASE)

_mod_dirs = {
"Binaries".casefold(): "/",
Expand Down
6 changes: 3 additions & 3 deletions games/game_cyberpunk2077.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def __init__(self):
)


def time_from_seconds(s: int | float) -> str:
def time_from_seconds(s: float) -> str:
m, s = divmod(int(s), 60)
h, m = divmod(int(m), 60)
return f"{h:02}:{m:02}:{s:02}"
Expand Down Expand Up @@ -496,7 +496,7 @@ def _onAboutToRun(self, app_path_str: str, wd: QDir, args: str) -> bool:
return True
app_path = Path(app_path_str)
if app_path == self._get_redmod_binary():
if m := re.search(r"%modlist%", args, re.I):
if m := re.search(r"%modlist%", args, re.IGNORECASE):
# Manual deployment: replace %modlist% variable
(
modlist_path,
Expand Down Expand Up @@ -592,7 +592,7 @@ def _deploy_redmod(self) -> tuple[bool, int]:
):
# Only load order changed: recreate redmod deploys
# Fix for redmod not detecting change of load order.
# Faster than -force https://github.com/E1337Kat/cyberpunk2077_ext_redux/issues/297 # noqa: E501
# Faster than -force https://github.com/E1337Kat/cyberpunk2077_ext_redux/issues/297
qInfo("Redmod order changed, recreate deployed files")
self._clean_deployed_redmod(modlist_path)
qInfo(f"Deploying redmod with modlist: {modlist_path}")
Expand Down
2 changes: 0 additions & 2 deletions games/game_divinityoriginalsinee.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
# -*- encoding: utf-8 -*-

import os
from pathlib import Path

Expand Down
4 changes: 2 additions & 2 deletions games/game_finalfantasy7rebirth.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import math
import random
from collections.abc import Iterable
from pathlib import Path
from typing import Iterable, List

import mobase

Expand Down Expand Up @@ -139,7 +139,7 @@ def executableForcedLoads(self) -> list[mobase.ExecutableForcedLoadSetting]:
def _get_settings(self, key: str) -> mobase.MoVariant:
return self._organizer.pluginSetting(self.name(), key)

def mappings(self) -> List[mobase.Mapping]:
def mappings(self) -> list[mobase.Mapping]:
mod_path = Path(self.gameDirectory().absolutePath()) / "End/Content/Paks/~Mods"
file_path = Path(self.gameDirectory().absolutePath()) / "End/Binaries/Win64"
load_enabled = self._get_settings("enforce_mod_load_order")
Expand Down
6 changes: 3 additions & 3 deletions games/game_finalfantasy7remake.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import math
from collections.abc import Iterable
from pathlib import Path
from typing import Iterable, List

import mobase

Expand Down Expand Up @@ -46,7 +46,7 @@ def _active_mod_paths(self) -> Iterable[Path]:
if self._organizer.modList().state(mod) & mobase.ModState.ACTIVE:
yield mods_parent_path / mod

def _active_mod_mappings(self, mod_paths: List[Path]) -> Iterable[mobase.Mapping]:
def _active_mod_mappings(self, mod_paths: list[Path]) -> Iterable[mobase.Mapping]:
if not mod_paths:
return
pak_priority_digits = math.floor(math.log10(len(mod_paths))) + 1
Expand All @@ -65,7 +65,7 @@ def _active_mod_mappings(self, mod_paths: List[Path]) -> Iterable[mobase.Mapping
child.is_dir(),
)

def mappings(self) -> List[mobase.Mapping]:
def mappings(self) -> list[mobase.Mapping]:
return [
# Not applying load order modifications to overwrites is OK
# since the UX is better this way and it will generally work out anyways
Expand Down
Loading
Loading