Sync from development - prepare for v0.5.0.4

This commit is contained in:
Omni
2026-03-29 15:46:37 +01:00
parent 8e4dd06f11
commit c3551cd269
55 changed files with 334 additions and 333 deletions

View File

@@ -1,5 +1,16 @@
# Jackify Changelog # Jackify Changelog
## v0.5.0.4 - Hotfix
**Release Date:** 29/03/26
- Fixed self-update failing silently due to the downloaded archive overwriting the extraction target before the update helper could apply it.
- Engine updated to 0.5.3. NAME_MAX pre-flight check removed — was incorrectly blocking installs on standard filesystems. eCryptFS/fscrypt users still receive an error at the point of failure.
- Fixed Google Drive downloads failing. The Wabbajack CDN proxy was returning a cached broken response for some files; the engine now detects the hash mismatch, retries direct, and constructs a `drive.usercontent.google.com` URL with `confirm=t` to bypass the virus-scan warning page.
- Fixed focus stealing from other windows during the Wine component install phase.
- Fixed a crash on window close from a leaked focus-reclaim timer.
- Baloo file indexer suspended during install and config phases on KDE. No-op elsewhere.
- Fixed Flatpak protontricks install failing on fresh Steam Decks due to Flathub not being registered at user scope.
## v0.5.0.3 - Hotfix ## v0.5.0.3 - Hotfix
**Release Date:** 23/03/26 **Release Date:** 23/03/26

View File

@@ -5,4 +5,4 @@ This package provides both CLI and GUI interfaces for managing
Wabbajack modlists natively on Linux systems. Wabbajack modlists natively on Linux systems.
""" """
__version__ = "0.5.0.3" __version__ = "0.5.0.4"

View File

@@ -8,6 +8,31 @@ import shutil
import logging import logging
import threading import threading
logger = logging.getLogger(__name__)
def suspend_baloo() -> bool:
"""Suspend KDE Baloo file indexer. Safe to call on non-KDE or headless systems."""
if not shutil.which("balooctl"):
return False
try:
subprocess.run(["balooctl", "suspend"], capture_output=True, timeout=5)
logger.debug("Baloo file indexer suspended")
return True
except Exception:
return False
def resume_baloo() -> None:
"""Resume KDE Baloo file indexer. No-op if balooctl is not present."""
if not shutil.which("balooctl"):
return
try:
subprocess.run(["balooctl", "resume"], capture_output=True, timeout=5)
logger.debug("Baloo file indexer resumed")
except Exception:
pass
def get_safe_python_executable(): def get_safe_python_executable():
""" """
Get a safe Python executable for subprocess calls. Get a safe Python executable for subprocess calls.

View File

@@ -257,6 +257,8 @@ class ModlistService(ModlistServiceInstallationMixin):
original_gui_mode = os.environ.get('JACKIFY_GUI_MODE') original_gui_mode = os.environ.get('JACKIFY_GUI_MODE')
original_stdout = None original_stdout = None
from ..handlers.subprocess_utils import suspend_baloo, resume_baloo
suspend_baloo()
try: try:
# Force GUI mode to prevent input prompts # Force GUI mode to prevent input prompts
os.environ['JACKIFY_GUI_MODE'] = '1' os.environ['JACKIFY_GUI_MODE'] = '1'
@@ -344,6 +346,7 @@ class ModlistService(ModlistServiceInstallationMixin):
return success return success
finally: finally:
resume_baloo()
# Always restore stdout and environment # Always restore stdout and environment
if original_stdout: if original_stdout:
sys.stdout = original_stdout sys.stdout = original_stdout

View File

@@ -59,11 +59,16 @@ class ModlistServiceInstallationMixin:
logger.error("Discovery phase failed or was cancelled") logger.error("Discovery phase failed or was cancelled")
return False return False
success = self._run_installation_only( from ..handlers.subprocess_utils import suspend_baloo, resume_baloo
confirmed_context, suspend_baloo()
progress_callback=progress_callback, try:
output_callback=output_callback success = self._run_installation_only(
) confirmed_context,
progress_callback=progress_callback,
output_callback=output_callback
)
finally:
resume_baloo()
if success: if success:
logger.info("Modlist installation completed successfully (configuration done separately)") logger.info("Modlist installation completed successfully (configuration done separately)")

View File

@@ -132,13 +132,24 @@ class ProtontricksDetectionService:
logger.error(error_msg) logger.error(error_msg)
return False, error_msg return False, error_msg
# Use clean environment
env = handler._get_clean_subprocess_env()
# Register flathub at user level if not already present.
# Fresh Steam Decks only have flathub at system scope; --user install can't see it.
try:
subprocess.run(
["flatpak", "remote-add", "--if-not-exists", "--user",
"flathub", "https://dl.flathub.org/repo/flathub.flatpakrepo"],
check=True, text=True, env=env, capture_output=True, timeout=30,
)
except subprocess.CalledProcessError as e:
logger.warning(f"Could not register flathub remote: {e.stderr.strip()}")
# Install command - use --user flag for user-level installation (works on Steam Deck) # Install command - use --user flag for user-level installation (works on Steam Deck)
# Avoids system-wide installation permissions # Avoids system-wide installation permissions
install_cmd = ["flatpak", "install", "--user", "-y", "--noninteractive", "flathub", "com.github.Matoking.protontricks"] install_cmd = ["flatpak", "install", "--user", "-y", "--noninteractive", "flathub", "com.github.Matoking.protontricks"]
# Use clean environment
env = handler._get_clean_subprocess_env()
# Log the command for debugging # Log the command for debugging
logger.debug(f"Running flatpak install command: {' '.join(install_cmd)}") logger.debug(f"Running flatpak install command: {' '.join(install_cmd)}")

View File

@@ -5,14 +5,11 @@ This service handles checking for updates via GitHub releases API
and coordinating the update process. and coordinating the update process.
""" """
import json
import logging import logging
import os import os
import subprocess import subprocess
import tempfile
import threading import threading
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from typing import Optional, Callable from typing import Optional, Callable
import requests import requests
@@ -358,26 +355,31 @@ class UpdateService:
update_dir = get_jackify_data_dir() / "updates" update_dir = get_jackify_data_dir() / "updates"
update_dir.mkdir(parents=True, exist_ok=True) update_dir.mkdir(parents=True, exist_ok=True)
# Nexus delivers a .7z archive; GitHub delivers the AppImage directly.
# Detect which we have after download, then handle accordingly.
# Saving as .7z avoids any path collision with the final .AppImage name.
archive_file = update_dir / f"Jackify-{update_info.version}.7z"
temp_file = update_dir / f"Jackify-{update_info.version}.AppImage" temp_file = update_dir / f"Jackify-{update_info.version}.AppImage"
with open(temp_file, 'wb') as f: with open(archive_file, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192): for chunk in response.iter_content(chunk_size=8192):
if chunk: if chunk:
f.write(chunk) f.write(chunk)
downloaded_size += len(chunk) downloaded_size += len(chunk)
if progress_callback: if progress_callback:
progress_callback(downloaded_size, total_size) progress_callback(downloaded_size, total_size)
# Nexus delivers a 7z archive — extract the AppImage before handing off if self._is_7z_archive(archive_file):
if self._is_7z_archive(temp_file):
logger.info("Downloaded file is a 7z archive, extracting AppImage") logger.info("Downloaded file is a 7z archive, extracting AppImage")
extracted = self._extract_appimage_from_7z(temp_file, update_dir, update_info.version) extracted = self._extract_appimage_from_7z(archive_file, update_dir, update_info.version)
temp_file.unlink(missing_ok=True) archive_file.unlink(missing_ok=True)
if not extracted: if not extracted:
logger.error("Failed to extract AppImage from 7z archive") logger.error("Failed to extract AppImage from 7z archive")
return None return None
temp_file = extracted temp_file = extracted
else:
archive_file.rename(temp_file)
# Make executable # Make executable
temp_file.chmod(0o755) temp_file.chmod(0o755)
@@ -437,80 +439,56 @@ class UpdateService:
def apply_update(self, new_appimage_path: Path) -> bool: def apply_update(self, new_appimage_path: Path) -> bool:
""" """
Apply update by replacing current AppImage. Apply update by replacing current AppImage.
This creates a helper script that waits for Jackify to exit, Creates a helper script that waits for Jackify to exit,
then replaces the AppImage and restarts it. then replaces the AppImage and restarts it.
Args:
new_appimage_path: Path to downloaded update
Returns:
bool: True if update application was initiated successfully
""" """
current_appimage = get_appimage_path() current_appimage = get_appimage_path()
if not current_appimage: if not current_appimage:
logger.error("Cannot determine current AppImage path") logger.error("Cannot determine current AppImage path")
return False return False
try: try:
# Create update helper script
helper_script = self._create_update_helper(current_appimage, new_appimage_path) helper_script = self._create_update_helper(current_appimage, new_appimage_path)
if helper_script: if helper_script:
logger.info("Applying update: replacing %s with %s", current_appimage, new_appimage_path) logger.info("Applying update: replacing %s with %s", current_appimage, new_appimage_path)
subprocess.Popen(['nohup', 'bash', str(helper_script)], subprocess.Popen(['nohup', 'bash', str(helper_script)],
stdout=subprocess.DEVNULL, stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL) stderr=subprocess.DEVNULL)
return True return True
return False return False
except Exception as e: except Exception as e:
logger.error(f"Failed to apply update: {e}") logger.error(f"Failed to apply update: {e}")
return False return False
def _create_update_helper(self, current_appimage: Path, new_appimage: Path) -> Optional[Path]: def _create_update_helper(self, current_appimage: Path, new_appimage: Path) -> Optional[Path]:
""" """Create helper script that replaces the AppImage after Jackify exits."""
Create helper script for update replacement.
Args:
current_appimage: Path to current AppImage
new_appimage: Path to new AppImage
Returns:
Path to helper script, or None if creation failed
"""
try: try:
# Create update directory in user's data directory
from jackify.shared.paths import get_jackify_data_dir from jackify.shared.paths import get_jackify_data_dir
update_dir = get_jackify_data_dir() / "updates" update_dir = get_jackify_data_dir() / "updates"
update_dir.mkdir(parents=True, exist_ok=True) update_dir.mkdir(parents=True, exist_ok=True)
helper_script = update_dir / "update_helper.sh" helper_script = update_dir / "update_helper.sh"
script_content = f'''#!/bin/bash script_content = f'''#!/bin/bash
# Jackify Update Helper Script # Jackify Update Helper Script
# Safely replaces current AppImage with new version
CURRENT_APPIMAGE="{current_appimage}" CURRENT_APPIMAGE="{current_appimage}"
NEW_APPIMAGE="{new_appimage}" NEW_APPIMAGE="{new_appimage}"
TEMP_NAME="$CURRENT_APPIMAGE.updating" TEMP_NAME="$CURRENT_APPIMAGE.updating"
echo "Jackify Update Helper" echo "Jackify Update Helper"
echo "Waiting for Jackify to exit..." echo "Waiting for Jackify to exit..."
# Wait longer for Jackify to fully exit and unmount
sleep 5 sleep 5
echo "Validating new AppImage..." echo "Validating new AppImage..."
# Validate new AppImage exists and is executable
if [ ! -f "$NEW_APPIMAGE" ]; then if [ ! -f "$NEW_APPIMAGE" ]; then
echo "ERROR: New AppImage not found: $NEW_APPIMAGE" echo "ERROR: New AppImage not found: $NEW_APPIMAGE"
exit 1 exit 1
fi fi
# Test that new AppImage can execute --version
if ! timeout 10 "$NEW_APPIMAGE" --version >/dev/null 2>&1; then if ! timeout 10 "$NEW_APPIMAGE" --version >/dev/null 2>&1; then
echo "ERROR: New AppImage failed validation test" echo "ERROR: New AppImage failed validation test"
exit 1 exit 1
@@ -519,34 +497,24 @@ fi
echo "New AppImage validated successfully" echo "New AppImage validated successfully"
echo "Performing safe replacement..." echo "Performing safe replacement..."
# Backup current version
if [ -f "$CURRENT_APPIMAGE" ]; then if [ -f "$CURRENT_APPIMAGE" ]; then
cp "$CURRENT_APPIMAGE" "$CURRENT_APPIMAGE.backup" cp "$CURRENT_APPIMAGE" "$CURRENT_APPIMAGE.backup"
fi fi
# Safe replacement: copy to temp name first, then atomic move
if cp "$NEW_APPIMAGE" "$TEMP_NAME"; then if cp "$NEW_APPIMAGE" "$TEMP_NAME"; then
chmod +x "$TEMP_NAME" chmod +x "$TEMP_NAME"
# Atomic move to replace
if mv "$TEMP_NAME" "$CURRENT_APPIMAGE"; then if mv "$TEMP_NAME" "$CURRENT_APPIMAGE"; then
echo "Update completed successfully!" echo "Update completed successfully!"
# Clean up
rm -f "$NEW_APPIMAGE" rm -f "$NEW_APPIMAGE"
rm -f "$CURRENT_APPIMAGE.backup" rm -f "$CURRENT_APPIMAGE.backup"
# Restart Jackify
echo "Restarting Jackify..." echo "Restarting Jackify..."
sleep 1 sleep 1
exec "$CURRENT_APPIMAGE" exec "$CURRENT_APPIMAGE"
else else
echo "ERROR: Failed to move updated AppImage" echo "ERROR: Failed to move updated AppImage"
rm -f "$TEMP_NAME" rm -f "$TEMP_NAME"
# Restore backup
if [ -f "$CURRENT_APPIMAGE.backup" ]; then if [ -f "$CURRENT_APPIMAGE.backup" ]; then
mv "$CURRENT_APPIMAGE.backup" "$CURRENT_APPIMAGE" mv "$CURRENT_APPIMAGE.backup" "$CURRENT_APPIMAGE"
echo "Restored original AppImage"
fi fi
exit 1 exit 1
fi fi
@@ -555,19 +523,16 @@ else
exit 1 exit 1
fi fi
# Clean up this script
rm -f "{helper_script}" rm -f "{helper_script}"
''' '''
with open(helper_script, 'w') as f: with open(helper_script, 'w') as f:
f.write(script_content) f.write(script_content)
# Make executable
helper_script.chmod(0o755) helper_script.chmod(0o755)
logger.debug(f"Created update helper script: {helper_script}") logger.debug(f"Created update helper script: {helper_script}")
return helper_script return helper_script
except Exception as e: except Exception as e:
logger.error(f"Failed to create update helper script: {e}") logger.error(f"Failed to create update helper script: {e}")
return None return None

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -7,7 +7,7 @@
"targets": { "targets": {
".NETCoreApp,Version=v8.0": {}, ".NETCoreApp,Version=v8.0": {},
".NETCoreApp,Version=v8.0/linux-x64": { ".NETCoreApp,Version=v8.0/linux-x64": {
"jackify-engine/0.5.2": { "jackify-engine/0.5.3": {
"dependencies": { "dependencies": {
"Markdig": "0.40.0", "Markdig": "0.40.0",
"Microsoft.Extensions.Configuration.Json": "9.0.1", "Microsoft.Extensions.Configuration.Json": "9.0.1",
@@ -22,16 +22,16 @@
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"System.CommandLine": "2.0.0-beta4.22272.1", "System.CommandLine": "2.0.0-beta4.22272.1",
"System.CommandLine.NamingConventionBinder": "2.0.0-beta4.22272.1", "System.CommandLine.NamingConventionBinder": "2.0.0-beta4.22272.1",
"Wabbajack.CLI.Builder": "0.5.2", "Wabbajack.CLI.Builder": "0.5.3",
"Wabbajack.Downloaders.Bethesda": "0.5.2", "Wabbajack.Downloaders.Bethesda": "0.5.3",
"Wabbajack.Downloaders.Dispatcher": "0.5.2", "Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.2", "Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Networking.Discord": "0.5.2", "Wabbajack.Networking.Discord": "0.5.3",
"Wabbajack.Networking.GitHub": "0.5.2", "Wabbajack.Networking.GitHub": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2", "Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.Server.Lib": "0.5.2", "Wabbajack.Server.Lib": "0.5.3",
"Wabbajack.Services.OSIntegrated": "0.5.2", "Wabbajack.Services.OSIntegrated": "0.5.3",
"Wabbajack.VFS": "0.5.2", "Wabbajack.VFS": "0.5.3",
"MegaApiClient": "1.0.0.0", "MegaApiClient": "1.0.0.0",
"runtimepack.Microsoft.NETCore.App.Runtime.linux-x64": "8.0.24" "runtimepack.Microsoft.NETCore.App.Runtime.linux-x64": "8.0.24"
}, },
@@ -1781,7 +1781,7 @@
} }
} }
}, },
"Wabbajack.CLI.Builder/0.5.2": { "Wabbajack.CLI.Builder/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.Configuration.Json": "9.0.1", "Microsoft.Extensions.Configuration.Json": "9.0.1",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
@@ -1791,109 +1791,109 @@
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"System.CommandLine": "2.0.0-beta4.22272.1", "System.CommandLine": "2.0.0-beta4.22272.1",
"System.CommandLine.NamingConventionBinder": "2.0.0-beta4.22272.1", "System.CommandLine.NamingConventionBinder": "2.0.0-beta4.22272.1",
"Wabbajack.Paths": "0.5.2" "Wabbajack.Paths": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.CLI.Builder.dll": {} "Wabbajack.CLI.Builder.dll": {}
} }
}, },
"Wabbajack.Common/0.5.2": { "Wabbajack.Common/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"System.Reactive": "6.0.1", "System.Reactive": "6.0.1",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2" "Wabbajack.Paths.IO": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Common.dll": {} "Wabbajack.Common.dll": {}
} }
}, },
"Wabbajack.Compiler/0.5.2": { "Wabbajack.Compiler/0.5.3": {
"dependencies": { "dependencies": {
"F23.StringSimilarity": "6.0.0", "F23.StringSimilarity": "6.0.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3", "Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Downloaders.Dispatcher": "0.5.2", "Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Installer": "0.5.2", "Wabbajack.Installer": "0.5.3",
"Wabbajack.VFS": "0.5.2", "Wabbajack.VFS": "0.5.3",
"ini-parser-netstandard": "2.5.2" "ini-parser-netstandard": "2.5.2"
}, },
"runtime": { "runtime": {
"Wabbajack.Compiler.dll": {} "Wabbajack.Compiler.dll": {}
} }
}, },
"Wabbajack.Compression.BSA/0.5.2": { "Wabbajack.Compression.BSA/0.5.3": {
"dependencies": { "dependencies": {
"K4os.Compression.LZ4.Streams": "1.3.8", "K4os.Compression.LZ4.Streams": "1.3.8",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"SharpZipLib": "1.4.2", "SharpZipLib": "1.4.2",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.2" "Wabbajack.DTOs": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Compression.BSA.dll": {} "Wabbajack.Compression.BSA.dll": {}
} }
}, },
"Wabbajack.Compression.Zip/0.5.2": { "Wabbajack.Compression.Zip/0.5.3": {
"dependencies": { "dependencies": {
"Wabbajack.IO.Async": "0.5.2" "Wabbajack.IO.Async": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Compression.Zip.dll": {} "Wabbajack.Compression.Zip.dll": {}
} }
}, },
"Wabbajack.Configuration/0.5.2": { "Wabbajack.Configuration/0.5.3": {
"runtime": { "runtime": {
"Wabbajack.Configuration.dll": {} "Wabbajack.Configuration.dll": {}
} }
}, },
"Wabbajack.Downloaders.Bethesda/0.5.2": { "Wabbajack.Downloaders.Bethesda/0.5.3": {
"dependencies": { "dependencies": {
"LibAES-CTR": "1.1.0", "LibAES-CTR": "1.1.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"SharpZipLib": "1.4.2", "SharpZipLib": "1.4.2",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.BethesdaNet": "0.5.2" "Wabbajack.Networking.BethesdaNet": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Bethesda.dll": {} "Wabbajack.Downloaders.Bethesda.dll": {}
} }
}, },
"Wabbajack.Downloaders.Dispatcher/0.5.2": { "Wabbajack.Downloaders.Dispatcher/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3", "Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Downloaders.Bethesda": "0.5.2", "Wabbajack.Downloaders.Bethesda": "0.5.3",
"Wabbajack.Downloaders.GameFile": "0.5.2", "Wabbajack.Downloaders.GameFile": "0.5.3",
"Wabbajack.Downloaders.GoogleDrive": "0.5.2", "Wabbajack.Downloaders.GoogleDrive": "0.5.3",
"Wabbajack.Downloaders.Http": "0.5.2", "Wabbajack.Downloaders.Http": "0.5.3",
"Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.5.2", "Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Downloaders.Manual": "0.5.2", "Wabbajack.Downloaders.Manual": "0.5.3",
"Wabbajack.Downloaders.MediaFire": "0.5.2", "Wabbajack.Downloaders.MediaFire": "0.5.3",
"Wabbajack.Downloaders.Mega": "0.5.2", "Wabbajack.Downloaders.Mega": "0.5.3",
"Wabbajack.Downloaders.ModDB": "0.5.2", "Wabbajack.Downloaders.ModDB": "0.5.3",
"Wabbajack.Downloaders.Nexus": "0.5.2", "Wabbajack.Downloaders.Nexus": "0.5.3",
"Wabbajack.Downloaders.VerificationCache": "0.5.2", "Wabbajack.Downloaders.VerificationCache": "0.5.3",
"Wabbajack.Downloaders.WabbajackCDN": "0.5.2", "Wabbajack.Downloaders.WabbajackCDN": "0.5.3",
"Wabbajack.Networking.WabbajackClientApi": "0.5.2" "Wabbajack.Networking.WabbajackClientApi": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Dispatcher.dll": {} "Wabbajack.Downloaders.Dispatcher.dll": {}
} }
}, },
"Wabbajack.Downloaders.GameFile/0.5.2": { "Wabbajack.Downloaders.GameFile/0.5.3": {
"dependencies": { "dependencies": {
"GameFinder.StoreHandlers.EADesktop": "4.5.0", "GameFinder.StoreHandlers.EADesktop": "4.5.0",
"GameFinder.StoreHandlers.EGS": "4.5.0", "GameFinder.StoreHandlers.EGS": "4.5.0",
@@ -1903,361 +1903,361 @@
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.VFS": "0.5.2" "Wabbajack.VFS": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.GameFile.dll": {} "Wabbajack.Downloaders.GameFile.dll": {}
} }
}, },
"Wabbajack.Downloaders.GoogleDrive/0.5.2": { "Wabbajack.Downloaders.GoogleDrive/0.5.3": {
"dependencies": { "dependencies": {
"HtmlAgilityPack": "1.11.72", "HtmlAgilityPack": "1.11.72",
"Microsoft.AspNetCore.Http.Extensions": "2.3.0", "Microsoft.AspNetCore.Http.Extensions": "2.3.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2" "Wabbajack.Networking.Http.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.GoogleDrive.dll": {} "Wabbajack.Downloaders.GoogleDrive.dll": {}
} }
}, },
"Wabbajack.Downloaders.Http/0.5.2": { "Wabbajack.Downloaders.Http/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.BethesdaNet": "0.5.2", "Wabbajack.Networking.BethesdaNet": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2", "Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2" "Wabbajack.Paths.IO": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Http.dll": {} "Wabbajack.Downloaders.Http.dll": {}
} }
}, },
"Wabbajack.Downloaders.Interfaces/0.5.2": { "Wabbajack.Downloaders.Interfaces/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.Compression.Zip": "0.5.2", "Wabbajack.Compression.Zip": "0.5.3",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2" "Wabbajack.Paths.IO": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Interfaces.dll": {} "Wabbajack.Downloaders.Interfaces.dll": {}
} }
}, },
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.2": { "Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.3": {
"dependencies": { "dependencies": {
"F23.StringSimilarity": "6.0.0", "F23.StringSimilarity": "6.0.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2" "Wabbajack.Networking.Http.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.IPS4OAuth2Downloader.dll": {} "Wabbajack.Downloaders.IPS4OAuth2Downloader.dll": {}
} }
}, },
"Wabbajack.Downloaders.Manual/0.5.2": { "Wabbajack.Downloaders.Manual/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2" "Wabbajack.Downloaders.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Manual.dll": {} "Wabbajack.Downloaders.Manual.dll": {}
} }
}, },
"Wabbajack.Downloaders.MediaFire/0.5.2": { "Wabbajack.Downloaders.MediaFire/0.5.3": {
"dependencies": { "dependencies": {
"HtmlAgilityPack": "1.11.72", "HtmlAgilityPack": "1.11.72",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2" "Wabbajack.Networking.Http.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.MediaFire.dll": {} "Wabbajack.Downloaders.MediaFire.dll": {}
} }
}, },
"Wabbajack.Downloaders.Mega/0.5.2": { "Wabbajack.Downloaders.Mega/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3", "Newtonsoft.Json": "13.0.3",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2" "Wabbajack.Paths.IO": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Mega.dll": {} "Wabbajack.Downloaders.Mega.dll": {}
} }
}, },
"Wabbajack.Downloaders.ModDB/0.5.2": { "Wabbajack.Downloaders.ModDB/0.5.3": {
"dependencies": { "dependencies": {
"HtmlAgilityPack": "1.11.72", "HtmlAgilityPack": "1.11.72",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3", "Newtonsoft.Json": "13.0.3",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2" "Wabbajack.Networking.Http.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.ModDB.dll": {} "Wabbajack.Downloaders.ModDB.dll": {}
} }
}, },
"Wabbajack.Downloaders.Nexus/0.5.2": { "Wabbajack.Downloaders.Nexus/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.2", "Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2", "Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Networking.NexusApi": "0.5.2", "Wabbajack.Networking.NexusApi": "0.5.3",
"Wabbajack.Paths": "0.5.2" "Wabbajack.Paths": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Nexus.dll": {} "Wabbajack.Downloaders.Nexus.dll": {}
} }
}, },
"Wabbajack.Downloaders.VerificationCache/0.5.2": { "Wabbajack.Downloaders.VerificationCache/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Stub.System.Data.SQLite.Core.NetStandard": "1.0.119", "Stub.System.Data.SQLite.Core.NetStandard": "1.0.119",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2" "Wabbajack.Paths.IO": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.VerificationCache.dll": {} "Wabbajack.Downloaders.VerificationCache.dll": {}
} }
}, },
"Wabbajack.Downloaders.WabbajackCDN/0.5.2": { "Wabbajack.Downloaders.WabbajackCDN/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Microsoft.Toolkit.HighPerformance": "7.1.2", "Microsoft.Toolkit.HighPerformance": "7.1.2",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.RateLimiter": "0.5.2" "Wabbajack.RateLimiter": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.WabbajackCDN.dll": {} "Wabbajack.Downloaders.WabbajackCDN.dll": {}
} }
}, },
"Wabbajack.DTOs/0.5.2": { "Wabbajack.DTOs/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.Hashing.xxHash64": "0.5.2", "Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Paths": "0.5.2" "Wabbajack.Paths": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.DTOs.dll": {} "Wabbajack.DTOs.dll": {}
} }
}, },
"Wabbajack.FileExtractor/0.5.2": { "Wabbajack.FileExtractor/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"OMODFramework": "3.0.1", "OMODFramework": "3.0.1",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Compression.BSA": "0.5.2", "Wabbajack.Compression.BSA": "0.5.3",
"Wabbajack.Hashing.PHash": "0.5.2", "Wabbajack.Hashing.PHash": "0.5.3",
"Wabbajack.Paths": "0.5.2" "Wabbajack.Paths": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.FileExtractor.dll": {} "Wabbajack.FileExtractor.dll": {}
} }
}, },
"Wabbajack.Hashing.PHash/0.5.2": { "Wabbajack.Hashing.PHash/0.5.3": {
"dependencies": { "dependencies": {
"BCnEncoder.Net.ImageSharp": "1.1.1", "BCnEncoder.Net.ImageSharp": "1.1.1",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Shipwreck.Phash": "0.5.0", "Shipwreck.Phash": "0.5.0",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths": "0.5.2", "Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2" "Wabbajack.Paths.IO": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Hashing.PHash.dll": {} "Wabbajack.Hashing.PHash.dll": {}
} }
}, },
"Wabbajack.Hashing.xxHash64/0.5.2": { "Wabbajack.Hashing.xxHash64/0.5.3": {
"dependencies": { "dependencies": {
"Wabbajack.Paths": "0.5.2", "Wabbajack.Paths": "0.5.3",
"Wabbajack.RateLimiter": "0.5.2" "Wabbajack.RateLimiter": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Hashing.xxHash64.dll": {} "Wabbajack.Hashing.xxHash64.dll": {}
} }
}, },
"Wabbajack.Installer/0.5.2": { "Wabbajack.Installer/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3", "Newtonsoft.Json": "13.0.3",
"Octopus.Octodiff": "2.0.548", "Octopus.Octodiff": "2.0.548",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Dispatcher": "0.5.2", "Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Downloaders.GameFile": "0.5.2", "Wabbajack.Downloaders.GameFile": "0.5.3",
"Wabbajack.FileExtractor": "0.5.2", "Wabbajack.FileExtractor": "0.5.3",
"Wabbajack.Networking.NexusApi": "0.5.2", "Wabbajack.Networking.NexusApi": "0.5.3",
"Wabbajack.Networking.WabbajackClientApi": "0.5.2", "Wabbajack.Networking.WabbajackClientApi": "0.5.3",
"Wabbajack.Paths": "0.5.2", "Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2", "Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.VFS": "0.5.2", "Wabbajack.VFS": "0.5.3",
"ini-parser-netstandard": "2.5.2" "ini-parser-netstandard": "2.5.2"
}, },
"runtime": { "runtime": {
"Wabbajack.Installer.dll": {} "Wabbajack.Installer.dll": {}
} }
}, },
"Wabbajack.IO.Async/0.5.2": { "Wabbajack.IO.Async/0.5.3": {
"runtime": { "runtime": {
"Wabbajack.IO.Async.dll": {} "Wabbajack.IO.Async.dll": {}
} }
}, },
"Wabbajack.Networking.BethesdaNet/0.5.2": { "Wabbajack.Networking.BethesdaNet/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2" "Wabbajack.Networking.Http.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.BethesdaNet.dll": {} "Wabbajack.Networking.BethesdaNet.dll": {}
} }
}, },
"Wabbajack.Networking.Discord/0.5.2": { "Wabbajack.Networking.Discord/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Networking.Http.Interfaces": "0.5.2" "Wabbajack.Networking.Http.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.Discord.dll": {} "Wabbajack.Networking.Discord.dll": {}
} }
}, },
"Wabbajack.Networking.GitHub/0.5.2": { "Wabbajack.Networking.GitHub/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Octokit": "14.0.0", "Octokit": "14.0.0",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2" "Wabbajack.Networking.Http.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.GitHub.dll": {} "Wabbajack.Networking.GitHub.dll": {}
} }
}, },
"Wabbajack.Networking.Http/0.5.2": { "Wabbajack.Networking.Http/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Http": "9.0.1", "Microsoft.Extensions.Http": "9.0.1",
"Microsoft.Extensions.Logging": "9.0.1", "Microsoft.Extensions.Logging": "9.0.1",
"Wabbajack.Configuration": "0.5.2", "Wabbajack.Configuration": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.2", "Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.2", "Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2", "Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Paths": "0.5.2", "Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2" "Wabbajack.Paths.IO": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.Http.dll": {} "Wabbajack.Networking.Http.dll": {}
} }
}, },
"Wabbajack.Networking.Http.Interfaces/0.5.2": { "Wabbajack.Networking.Http.Interfaces/0.5.3": {
"dependencies": { "dependencies": {
"Wabbajack.Hashing.xxHash64": "0.5.2" "Wabbajack.Hashing.xxHash64": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.Http.Interfaces.dll": {} "Wabbajack.Networking.Http.Interfaces.dll": {}
} }
}, },
"Wabbajack.Networking.NexusApi/0.5.2": { "Wabbajack.Networking.NexusApi/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http": "0.5.2", "Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2", "Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Networking.WabbajackClientApi": "0.5.2" "Wabbajack.Networking.WabbajackClientApi": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.NexusApi.dll": {} "Wabbajack.Networking.NexusApi.dll": {}
} }
}, },
"Wabbajack.Networking.WabbajackClientApi/0.5.2": { "Wabbajack.Networking.WabbajackClientApi/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Octokit": "14.0.0", "Octokit": "14.0.0",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2", "Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.VFS.Interfaces": "0.5.2", "Wabbajack.VFS.Interfaces": "0.5.3",
"YamlDotNet": "16.3.0" "YamlDotNet": "16.3.0"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.WabbajackClientApi.dll": {} "Wabbajack.Networking.WabbajackClientApi.dll": {}
} }
}, },
"Wabbajack.Paths/0.5.2": { "Wabbajack.Paths/0.5.3": {
"runtime": { "runtime": {
"Wabbajack.Paths.dll": {} "Wabbajack.Paths.dll": {}
} }
}, },
"Wabbajack.Paths.IO/0.5.2": { "Wabbajack.Paths.IO/0.5.3": {
"dependencies": { "dependencies": {
"Wabbajack.Paths": "0.5.2", "Wabbajack.Paths": "0.5.3",
"shortid": "4.0.0" "shortid": "4.0.0"
}, },
"runtime": { "runtime": {
"Wabbajack.Paths.IO.dll": {} "Wabbajack.Paths.IO.dll": {}
} }
}, },
"Wabbajack.RateLimiter/0.5.2": { "Wabbajack.RateLimiter/0.5.3": {
"runtime": { "runtime": {
"Wabbajack.RateLimiter.dll": {} "Wabbajack.RateLimiter.dll": {}
} }
}, },
"Wabbajack.Server.Lib/0.5.2": { "Wabbajack.Server.Lib/0.5.3": {
"dependencies": { "dependencies": {
"FluentFTP": "52.0.0", "FluentFTP": "52.0.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
@@ -2265,58 +2265,58 @@
"Nettle": "3.0.0", "Nettle": "3.0.0",
"Newtonsoft.Json": "13.0.3", "Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.2", "Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Services.OSIntegrated": "0.5.2" "Wabbajack.Services.OSIntegrated": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Server.Lib.dll": {} "Wabbajack.Server.Lib.dll": {}
} }
}, },
"Wabbajack.Services.OSIntegrated/0.5.2": { "Wabbajack.Services.OSIntegrated/0.5.3": {
"dependencies": { "dependencies": {
"DeviceId": "6.8.0", "DeviceId": "6.8.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3", "Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Compiler": "0.5.2", "Wabbajack.Compiler": "0.5.3",
"Wabbajack.Downloaders.Dispatcher": "0.5.2", "Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Installer": "0.5.2", "Wabbajack.Installer": "0.5.3",
"Wabbajack.Networking.BethesdaNet": "0.5.2", "Wabbajack.Networking.BethesdaNet": "0.5.3",
"Wabbajack.Networking.Discord": "0.5.2", "Wabbajack.Networking.Discord": "0.5.3",
"Wabbajack.VFS": "0.5.2" "Wabbajack.VFS": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.Services.OSIntegrated.dll": {} "Wabbajack.Services.OSIntegrated.dll": {}
} }
}, },
"Wabbajack.VFS/0.5.2": { "Wabbajack.VFS/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1", "Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"SixLabors.ImageSharp": "3.1.6", "SixLabors.ImageSharp": "3.1.6",
"System.Data.SQLite.Core": "1.0.119", "System.Data.SQLite.Core": "1.0.119",
"Wabbajack.Common": "0.5.2", "Wabbajack.Common": "0.5.3",
"Wabbajack.FileExtractor": "0.5.2", "Wabbajack.FileExtractor": "0.5.3",
"Wabbajack.Hashing.PHash": "0.5.2", "Wabbajack.Hashing.PHash": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.2", "Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Paths": "0.5.2", "Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.2", "Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.VFS.Interfaces": "0.5.2" "Wabbajack.VFS.Interfaces": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.VFS.dll": {} "Wabbajack.VFS.dll": {}
} }
}, },
"Wabbajack.VFS.Interfaces/0.5.2": { "Wabbajack.VFS.Interfaces/0.5.3": {
"dependencies": { "dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1", "Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2", "Wabbajack.DTOs": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.2", "Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Paths": "0.5.2" "Wabbajack.Paths": "0.5.3"
}, },
"runtime": { "runtime": {
"Wabbajack.VFS.Interfaces.dll": {} "Wabbajack.VFS.Interfaces.dll": {}
@@ -2333,7 +2333,7 @@
} }
}, },
"libraries": { "libraries": {
"jackify-engine/0.5.2": { "jackify-engine/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
@@ -3022,202 +3022,202 @@
"path": "yamldotnet/16.3.0", "path": "yamldotnet/16.3.0",
"hashPath": "yamldotnet.16.3.0.nupkg.sha512" "hashPath": "yamldotnet.16.3.0.nupkg.sha512"
}, },
"Wabbajack.CLI.Builder/0.5.2": { "Wabbajack.CLI.Builder/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Common/0.5.2": { "Wabbajack.Common/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Compiler/0.5.2": { "Wabbajack.Compiler/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Compression.BSA/0.5.2": { "Wabbajack.Compression.BSA/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Compression.Zip/0.5.2": { "Wabbajack.Compression.Zip/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Configuration/0.5.2": { "Wabbajack.Configuration/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Bethesda/0.5.2": { "Wabbajack.Downloaders.Bethesda/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Dispatcher/0.5.2": { "Wabbajack.Downloaders.Dispatcher/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.GameFile/0.5.2": { "Wabbajack.Downloaders.GameFile/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.GoogleDrive/0.5.2": { "Wabbajack.Downloaders.GoogleDrive/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Http/0.5.2": { "Wabbajack.Downloaders.Http/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Interfaces/0.5.2": { "Wabbajack.Downloaders.Interfaces/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.2": { "Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Manual/0.5.2": { "Wabbajack.Downloaders.Manual/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.MediaFire/0.5.2": { "Wabbajack.Downloaders.MediaFire/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Mega/0.5.2": { "Wabbajack.Downloaders.Mega/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.ModDB/0.5.2": { "Wabbajack.Downloaders.ModDB/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Nexus/0.5.2": { "Wabbajack.Downloaders.Nexus/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.VerificationCache/0.5.2": { "Wabbajack.Downloaders.VerificationCache/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.WabbajackCDN/0.5.2": { "Wabbajack.Downloaders.WabbajackCDN/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.DTOs/0.5.2": { "Wabbajack.DTOs/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.FileExtractor/0.5.2": { "Wabbajack.FileExtractor/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Hashing.PHash/0.5.2": { "Wabbajack.Hashing.PHash/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Hashing.xxHash64/0.5.2": { "Wabbajack.Hashing.xxHash64/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Installer/0.5.2": { "Wabbajack.Installer/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.IO.Async/0.5.2": { "Wabbajack.IO.Async/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.BethesdaNet/0.5.2": { "Wabbajack.Networking.BethesdaNet/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.Discord/0.5.2": { "Wabbajack.Networking.Discord/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.GitHub/0.5.2": { "Wabbajack.Networking.GitHub/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.Http/0.5.2": { "Wabbajack.Networking.Http/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.Http.Interfaces/0.5.2": { "Wabbajack.Networking.Http.Interfaces/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.NexusApi/0.5.2": { "Wabbajack.Networking.NexusApi/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.WabbajackClientApi/0.5.2": { "Wabbajack.Networking.WabbajackClientApi/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Paths/0.5.2": { "Wabbajack.Paths/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Paths.IO/0.5.2": { "Wabbajack.Paths.IO/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.RateLimiter/0.5.2": { "Wabbajack.RateLimiter/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Server.Lib/0.5.2": { "Wabbajack.Server.Lib/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Services.OSIntegrated/0.5.2": { "Wabbajack.Services.OSIntegrated/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.VFS/0.5.2": { "Wabbajack.VFS/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.VFS.Interfaces/0.5.2": { "Wabbajack.VFS.Interfaces/0.5.3": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""

Binary file not shown.

View File

@@ -86,6 +86,7 @@ class ConfigureNewModlistDialogsMixin:
def cleanup_processes(self): def cleanup_processes(self):
"""Clean up any running processes when the window closes or is cancelled""" """Clean up any running processes when the window closes or is cancelled"""
self._stop_focus_reclaim()
if hasattr(self, 'file_progress_list'): if hasattr(self, 'file_progress_list'):
self.file_progress_list.stop_cpu_tracking() self.file_progress_list.stop_cpu_tracking()

View File

@@ -501,6 +501,7 @@ class InstallMO2Screen(ScreenBackMixin, FocusReclaimMixin, QWidget):
def cleanup_processes(self): def cleanup_processes(self):
"""Stop active MO2 worker and CPU tracking before screen/app shutdown.""" """Stop active MO2 worker and CPU tracking before screen/app shutdown."""
self._stop_focus_reclaim()
try: try:
self.file_progress_list.stop_cpu_tracking() self.file_progress_list.stop_cpu_tracking()
except Exception: except Exception:

View File

@@ -419,6 +419,9 @@ class InstallModlistScreen(ScreenBackMixin, InstallModlistUISetupMixin, ConsoleO
self._vnv_controller.cleanup() self._vnv_controller.cleanup()
self._vnv_controller = None self._vnv_controller = None
self._stop_focus_reclaim()
def _stop_thread(attr_name: str, cancel_method: Optional[str] = None, cooperative_ms: int = 5000, force_ms: int = 10000): def _stop_thread(attr_name: str, cancel_method: Optional[str] = None, cooperative_ms: int = 5000, force_ms: int = 10000):
thread = getattr(self, attr_name, None) thread = getattr(self, attr_name, None)
if thread is None: if thread is None:

View File

@@ -44,9 +44,7 @@ class ConfigurationPhaseMixin(FocusReclaimMixin, InstallModlistShortcutDialogMix
pass pass
finally: finally:
self.steam_restart_progress = None self.steam_restart_progress = None
# Controls are managed by the proper control management system. pass
# Reclaim focus with bounded retries because Steam restart timing varies.
self._start_focus_reclaim_retries()
def _detect_game_type_from_mo2_ini(self, install_dir: str) -> str: def _detect_game_type_from_mo2_ini(self, install_dir: str) -> str:
"""Detect game type by checking ModOrganizer.ini for loader executables.""" """Detect game type by checking ModOrganizer.ini for loader executables."""

View File

@@ -15,44 +15,19 @@ class FocusReclaimMixin:
progress messages for STEAM_RESTART_SENTINEL. progress messages for STEAM_RESTART_SENTINEL.
""" """
def _start_focus_reclaim_retries(self): def _stop_focus_reclaim(self):
try: pass # No timer to stop — single-shot, no state
if hasattr(self, "_focus_reclaim_timer") and self._focus_reclaim_timer:
self._focus_reclaim_timer.stop()
self._focus_reclaim_timer.deleteLater()
except Exception:
pass
self._focus_reclaim_attempt = 0 def _start_focus_reclaim_retries(self):
self._focus_reclaim_max_attempts = 12 # ~24 seconds total QTimer.singleShot(500, self._focus_reclaim_tick)
self._focus_reclaim_timer = QTimer(self)
self._focus_reclaim_timer.setInterval(2000)
self._focus_reclaim_timer.timeout.connect(self._focus_reclaim_tick)
self._focus_reclaim_timer.start()
self._focus_reclaim_tick()
def _focus_reclaim_tick(self): def _focus_reclaim_tick(self):
try: try:
win = self.window() win = self.window()
if win is None: if win is None:
return return
self._focus_reclaim_attempt += 1
win.raise_() win.raise_()
win.activateWindow() win.activateWindow()
win.setWindowState(win.windowState() & ~Qt.WindowMinimized | Qt.WindowActive) win.setWindowState(win.windowState() & ~Qt.WindowMinimized | Qt.WindowActive)
if win.isActiveWindow():
logger.info("Foreground focus reclaimed after Steam restart")
self._focus_reclaim_timer.stop()
return
if self._focus_reclaim_attempt >= self._focus_reclaim_max_attempts:
logger.warning("Foreground focus reclaim timed out after Steam restart")
self._focus_reclaim_timer.stop()
except Exception as e: except Exception as e:
logger.debug(f"Focus reclaim tick failed: {e}") logger.debug(f"Focus reclaim attempt failed: {e}")
try:
self._focus_reclaim_timer.stop()
except Exception:
pass

View File

@@ -624,6 +624,9 @@ class WabbajackInstallerScreen(ScreenBackMixin, FocusReclaimMixin, QWidget):
self.collapse_show_details_before_leave() self.collapse_show_details_before_leave()
self.go_back() self.go_back()
def cleanup_processes(self):
self._stop_focus_reclaim()
def showEvent(self, event): def showEvent(self, event):
"""Called when widget becomes visible""" """Called when widget becomes visible"""
super().showEvent(event) super().showEvent(event)