Skip to content
Closed
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
3 changes: 2 additions & 1 deletion src/mo2-lint/command/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from util.nexus.install_handler import install as install_handler
from step.workarounds import apply_workarounds
from step.load_game_info import get_launcher, get_library
from step.external_resources import download
from step.external_resources import download, download_winetricks
from step.configure_prefix import prompt as configure_prefix
from step.launch_opt import add_launch_opt

Expand Down Expand Up @@ -66,6 +66,7 @@ def install(
)
raise SystemExit(1)

download_winetricks()
configure_prefix()
download()
install_handler()
Expand Down
10 changes: 5 additions & 5 deletions src/mo2-lint/step/external_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@
from urllib.request import urlopen, Request
from util import lang, variables as var, state_file as state
from util.checksum import compare_checksum
from util.download import download as dl, download_nexus as nexus_dl
from util.download import download as dl, download_nexus as nexus_dl, download_dir
from util.state_file import symlink_instance
from util.wine.winetricks import winetricks_path
import json
import ssl
import certifi

ssl_context = ssl.create_default_context(cafile=certifi.where())

cache_dir: Path = Path("~/.cache/mo2-lint").expanduser()
download_dir = cache_dir / "downloads"
extract_dir = download_dir / "extracted"


Expand Down Expand Up @@ -62,6 +61,9 @@ def download_winetricks():
"""
Runs the download process for Winetricks.
"""
if str(winetricks_path) != str(download_dir / "winetricks"):
logger.info("Using provided Winetricks. Skipping download")
return
logger.info("Starting download process for Winetricks")
url = var.resource_info.winetricks.download_url
checksum = var.resource_info.winetricks.checksum
Expand Down Expand Up @@ -385,7 +387,6 @@ def download():
"""
Runs the download process for all required external resources.
"""
cache_dir.mkdir(parents=True, exist_ok=True)
params = var.input_params
game_info = var.game_info
script_extenders = game_info.script_extenders if game_info is not None else None
Expand All @@ -395,7 +396,6 @@ def download():
if params.plugins:
for plugin in params.plugins:
download_plugin(plugin)
download_winetricks()
if params.script_extender:
for entry in script_extenders or []:
match = False
Expand Down
2 changes: 2 additions & 0 deletions src/mo2-lint/util/download.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import certifi

ssl_context = ssl.create_default_context(cafile=certifi.where())
cache_dir: Path = Path("~/.cache/mo2-lint").expanduser()
download_dir = cache_dir / "downloads"


def download(
Expand Down
10 changes: 9 additions & 1 deletion src/mo2-lint/util/wine/protontricks.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,21 @@
from loguru import logger
from pathlib import Path
from protontricks.cli.main import main as pt
from typing import List
from shared.logger import remove_loggers, add_loggers
from typing import List
from util.wine.winetricks import winetricks_path, cached_winetricks
import os
import re
import sys
import threading

winetricks_str = str(winetricks_path)
if winetricks_str == str(cached_winetricks):
logger.debug("setting WINETRICKS")
os.environ["WINETRICKS"] = winetricks_str
else:
logger.debug("not setting WINETRICKS")


def run(command: List[str]) -> List[str]:
"""
Expand Down
76 changes: 42 additions & 34 deletions src/mo2-lint/util/wine/winetricks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,30 @@

from loguru import logger
from pathlib import Path
from typing import List, Optional
from typing import List
from shared.logger import remove_loggers, add_loggers
from util.download import download_dir
import os
import re
import shutil
import subprocess

found_exec = shutil.which("winetricks") or "~/.cache/mo2-lint/downloads/winetricks"
cached_winetricks = download_dir / "winetricks"
found_exec = shutil.which("winetricks")
# Try to use $WINETRICKS, only if it provides a file
winetricks_path = os.environ.get("WINETRICKS")
if winetricks_path:
winetricks_path = Path(winetricks_path).expanduser()
elif found_exec:
winetricks_path = Path(found_exec)
else:
winetricks_path = cached_winetricks


def run(
exec: Optional[Path | str] = found_exec,
prefix: Path = None,
command: List[str] = None,
exe: Path | str = winetricks_path,
prefix: Path | str = None,
command: List[str] = [],
) -> List[str]:
"""
Runs a winetricks command and captures its output.
Expand All @@ -33,34 +43,33 @@ def run(
The output lines from the winetricks command.
"""

if not isinstance(exe, (str, Path)):
raise TypeError("exe parameter must be a Path or string")
if not isinstance(prefix, (str, Path)):
raise TypeError("prefix parameter must be a Path or string")
if not isinstance(command, list):
raise TypeError("command parameter must be a list")
if isinstance(exe, str):
exe = Path(exe)
exe = exe.expanduser().resolve()
if isinstance(prefix, str):
prefix = Path(prefix)
prefix = prefix.expanduser().resolve()
exec = (
exec.expanduser().resolve()
if isinstance(exec, Path)
else str(exec.expanduser().resolve())
)

# Convert executable to string, with absolute path
if str(exec).startswith("/usr/bin"):
if isinstance(exec, str):
exec = str(Path(exec).name)
elif isinstance(exec, Path):
exec = str(exec.name)
elif isinstance(exec, str):
if not Path(exec).exists():
logger.error(f"Winetricks executable not found at specified path: {exec}")
return []
exec = exec
elif isinstance(exec, Path):
if not exec.exists():
logger.error(f"Winetricks executable not found at specified path: {exec}")

if exe.is_relative_to("/usr/bin"):
# If referring to winetricks by bare name when possible is correct behavior, then it should
# probably be done whenever bool(found_exec), not just when it was found in /usr/bin?
exe = str(exe.name)
else:
if not exe.exists():
logger.error(f"Winetricks executable not found at specified path: {exe}")
return []
exec = str(exec)
logger.info(f"Using winetricks executable: {exec}")
exe = str(exe)
logger.info(f"Using winetricks executable: {exe}")

command = ["-q", "-f"] + command # -q for unattended, -f to force
cmd = [exec] + command
cmd = ["-q", "-f"] + command # -q for unattended, -f to force
logger.debug(f"Constructed winetricks command: {' '.join(cmd)}")
cmd.insert(exe)
env = os.environ.copy()
env.setdefault("WINEPREFIX", str(prefix))
logger.trace(f"Using Wine prefix: {prefix}")
Expand All @@ -69,7 +78,7 @@ def run(
add_loggers(script="mo2-lint", process="winetricks")
output_lines = []

if not cmd == [exec, "-q", "-f"]:
if not cmd == [exe, "-q", "-f"]:
proc = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
Expand Down Expand Up @@ -100,9 +109,8 @@ def run(


def apply(
exec: Optional[Path | str] = found_exec,
prefix: Path = None,
tricks: List[str] = None,
prefix: Path,
tricks: List[str],
):
"""
Applies tricks to the specified prefix.
Expand All @@ -119,7 +127,7 @@ def apply(
logger.warning("No tricks provided to apply, skipping winetricks execution.")
return
logger.info(f"Applying tricks to prefix with winetricks: {tricks}")
run(exec, prefix, tricks)
run(prefix=prefix, tricks=tricks)


def log_translation(input: str = None):
Expand Down
Loading