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
## 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
**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.
"""
__version__ = "0.5.0.3"
__version__ = "0.5.0.4"

View File

@@ -8,6 +8,31 @@ import shutil
import logging
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():
"""
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_stdout = None
from ..handlers.subprocess_utils import suspend_baloo, resume_baloo
suspend_baloo()
try:
# Force GUI mode to prevent input prompts
os.environ['JACKIFY_GUI_MODE'] = '1'
@@ -344,6 +346,7 @@ class ModlistService(ModlistServiceInstallationMixin):
return success
finally:
resume_baloo()
# Always restore stdout and environment
if original_stdout:
sys.stdout = original_stdout

View File

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

View File

@@ -132,13 +132,24 @@ class ProtontricksDetectionService:
logger.error(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)
# Avoids system-wide installation permissions
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
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.
"""
import json
import logging
import os
import subprocess
import tempfile
import threading
from dataclasses import dataclass
from datetime import datetime, timedelta
from pathlib import Path
from typing import Optional, Callable
import requests
@@ -358,26 +355,31 @@ class UpdateService:
update_dir = get_jackify_data_dir() / "updates"
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"
with open(temp_file, 'wb') as f:
with open(archive_file, 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
if chunk:
f.write(chunk)
downloaded_size += len(chunk)
if progress_callback:
progress_callback(downloaded_size, total_size)
# Nexus delivers a 7z archive — extract the AppImage before handing off
if self._is_7z_archive(temp_file):
if self._is_7z_archive(archive_file):
logger.info("Downloaded file is a 7z archive, extracting AppImage")
extracted = self._extract_appimage_from_7z(temp_file, update_dir, update_info.version)
temp_file.unlink(missing_ok=True)
extracted = self._extract_appimage_from_7z(archive_file, update_dir, update_info.version)
archive_file.unlink(missing_ok=True)
if not extracted:
logger.error("Failed to extract AppImage from 7z archive")
return None
temp_file = extracted
else:
archive_file.rename(temp_file)
# Make executable
temp_file.chmod(0o755)
@@ -437,80 +439,56 @@ class UpdateService:
def apply_update(self, new_appimage_path: Path) -> bool:
"""
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.
Args:
new_appimage_path: Path to downloaded update
Returns:
bool: True if update application was initiated successfully
"""
current_appimage = get_appimage_path()
if not current_appimage:
logger.error("Cannot determine current AppImage path")
return False
try:
# Create update helper script
helper_script = self._create_update_helper(current_appimage, new_appimage_path)
if helper_script:
logger.info("Applying update: replacing %s with %s", current_appimage, new_appimage_path)
subprocess.Popen(['nohup', 'bash', str(helper_script)],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
subprocess.Popen(['nohup', 'bash', str(helper_script)],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
return True
return False
except Exception as e:
logger.error(f"Failed to apply update: {e}")
return False
def _create_update_helper(self, current_appimage: Path, new_appimage: Path) -> Optional[Path]:
"""
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
"""
"""Create helper script that replaces the AppImage after Jackify exits."""
try:
# Create update directory in user's data directory
from jackify.shared.paths import get_jackify_data_dir
update_dir = get_jackify_data_dir() / "updates"
update_dir.mkdir(parents=True, exist_ok=True)
helper_script = update_dir / "update_helper.sh"
script_content = f'''#!/bin/bash
# Jackify Update Helper Script
# Safely replaces current AppImage with new version
CURRENT_APPIMAGE="{current_appimage}"
NEW_APPIMAGE="{new_appimage}"
TEMP_NAME="$CURRENT_APPIMAGE.updating"
echo "Jackify Update Helper"
echo "Waiting for Jackify to exit..."
# Wait longer for Jackify to fully exit and unmount
sleep 5
echo "Validating new AppImage..."
# Validate new AppImage exists and is executable
if [ ! -f "$NEW_APPIMAGE" ]; then
echo "ERROR: New AppImage not found: $NEW_APPIMAGE"
exit 1
fi
# Test that new AppImage can execute --version
if ! timeout 10 "$NEW_APPIMAGE" --version >/dev/null 2>&1; then
echo "ERROR: New AppImage failed validation test"
exit 1
@@ -519,34 +497,24 @@ fi
echo "New AppImage validated successfully"
echo "Performing safe replacement..."
# Backup current version
if [ -f "$CURRENT_APPIMAGE" ]; then
cp "$CURRENT_APPIMAGE" "$CURRENT_APPIMAGE.backup"
fi
# Safe replacement: copy to temp name first, then atomic move
if cp "$NEW_APPIMAGE" "$TEMP_NAME"; then
chmod +x "$TEMP_NAME"
# Atomic move to replace
if mv "$TEMP_NAME" "$CURRENT_APPIMAGE"; then
echo "Update completed successfully!"
# Clean up
rm -f "$NEW_APPIMAGE"
rm -f "$CURRENT_APPIMAGE.backup"
# Restart Jackify
echo "Restarting Jackify..."
sleep 1
exec "$CURRENT_APPIMAGE"
else
echo "ERROR: Failed to move updated AppImage"
rm -f "$TEMP_NAME"
# Restore backup
if [ -f "$CURRENT_APPIMAGE.backup" ]; then
mv "$CURRENT_APPIMAGE.backup" "$CURRENT_APPIMAGE"
echo "Restored original AppImage"
fi
exit 1
fi
@@ -555,19 +523,16 @@ else
exit 1
fi
# Clean up this script
rm -f "{helper_script}"
'''
with open(helper_script, 'w') as f:
f.write(script_content)
# Make executable
helper_script.chmod(0o755)
logger.debug(f"Created update helper script: {helper_script}")
return helper_script
except Exception as e:
logger.error(f"Failed to create update helper script: {e}")
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": {
".NETCoreApp,Version=v8.0": {},
".NETCoreApp,Version=v8.0/linux-x64": {
"jackify-engine/0.5.2": {
"jackify-engine/0.5.3": {
"dependencies": {
"Markdig": "0.40.0",
"Microsoft.Extensions.Configuration.Json": "9.0.1",
@@ -22,16 +22,16 @@
"SixLabors.ImageSharp": "3.1.6",
"System.CommandLine": "2.0.0-beta4.22272.1",
"System.CommandLine.NamingConventionBinder": "2.0.0-beta4.22272.1",
"Wabbajack.CLI.Builder": "0.5.2",
"Wabbajack.Downloaders.Bethesda": "0.5.2",
"Wabbajack.Downloaders.Dispatcher": "0.5.2",
"Wabbajack.Hashing.xxHash64": "0.5.2",
"Wabbajack.Networking.Discord": "0.5.2",
"Wabbajack.Networking.GitHub": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2",
"Wabbajack.Server.Lib": "0.5.2",
"Wabbajack.Services.OSIntegrated": "0.5.2",
"Wabbajack.VFS": "0.5.2",
"Wabbajack.CLI.Builder": "0.5.3",
"Wabbajack.Downloaders.Bethesda": "0.5.3",
"Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Networking.Discord": "0.5.3",
"Wabbajack.Networking.GitHub": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.Server.Lib": "0.5.3",
"Wabbajack.Services.OSIntegrated": "0.5.3",
"Wabbajack.VFS": "0.5.3",
"MegaApiClient": "1.0.0.0",
"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": {
"Microsoft.Extensions.Configuration.Json": "9.0.1",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
@@ -1791,109 +1791,109 @@
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"System.CommandLine": "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": {
"Wabbajack.CLI.Builder.dll": {}
}
},
"Wabbajack.Common/0.5.2": {
"Wabbajack.Common/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"System.Reactive": "6.0.1",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2"
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3"
},
"runtime": {
"Wabbajack.Common.dll": {}
}
},
"Wabbajack.Compiler/0.5.2": {
"Wabbajack.Compiler/0.5.3": {
"dependencies": {
"F23.StringSimilarity": "6.0.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Downloaders.Dispatcher": "0.5.2",
"Wabbajack.Installer": "0.5.2",
"Wabbajack.VFS": "0.5.2",
"Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Installer": "0.5.3",
"Wabbajack.VFS": "0.5.3",
"ini-parser-netstandard": "2.5.2"
},
"runtime": {
"Wabbajack.Compiler.dll": {}
}
},
"Wabbajack.Compression.BSA/0.5.2": {
"Wabbajack.Compression.BSA/0.5.3": {
"dependencies": {
"K4os.Compression.LZ4.Streams": "1.3.8",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"SharpZipLib": "1.4.2",
"Wabbajack.Common": "0.5.2",
"Wabbajack.DTOs": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.3"
},
"runtime": {
"Wabbajack.Compression.BSA.dll": {}
}
},
"Wabbajack.Compression.Zip/0.5.2": {
"Wabbajack.Compression.Zip/0.5.3": {
"dependencies": {
"Wabbajack.IO.Async": "0.5.2"
"Wabbajack.IO.Async": "0.5.3"
},
"runtime": {
"Wabbajack.Compression.Zip.dll": {}
}
},
"Wabbajack.Configuration/0.5.2": {
"Wabbajack.Configuration/0.5.3": {
"runtime": {
"Wabbajack.Configuration.dll": {}
}
},
"Wabbajack.Downloaders.Bethesda/0.5.2": {
"Wabbajack.Downloaders.Bethesda/0.5.3": {
"dependencies": {
"LibAES-CTR": "1.1.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"SharpZipLib": "1.4.2",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Networking.BethesdaNet": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.BethesdaNet": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.Bethesda.dll": {}
}
},
"Wabbajack.Downloaders.Dispatcher/0.5.2": {
"Wabbajack.Downloaders.Dispatcher/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Downloaders.Bethesda": "0.5.2",
"Wabbajack.Downloaders.GameFile": "0.5.2",
"Wabbajack.Downloaders.GoogleDrive": "0.5.2",
"Wabbajack.Downloaders.Http": "0.5.2",
"Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Downloaders.Manual": "0.5.2",
"Wabbajack.Downloaders.MediaFire": "0.5.2",
"Wabbajack.Downloaders.Mega": "0.5.2",
"Wabbajack.Downloaders.ModDB": "0.5.2",
"Wabbajack.Downloaders.Nexus": "0.5.2",
"Wabbajack.Downloaders.VerificationCache": "0.5.2",
"Wabbajack.Downloaders.WabbajackCDN": "0.5.2",
"Wabbajack.Networking.WabbajackClientApi": "0.5.2"
"Wabbajack.Downloaders.Bethesda": "0.5.3",
"Wabbajack.Downloaders.GameFile": "0.5.3",
"Wabbajack.Downloaders.GoogleDrive": "0.5.3",
"Wabbajack.Downloaders.Http": "0.5.3",
"Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Downloaders.Manual": "0.5.3",
"Wabbajack.Downloaders.MediaFire": "0.5.3",
"Wabbajack.Downloaders.Mega": "0.5.3",
"Wabbajack.Downloaders.ModDB": "0.5.3",
"Wabbajack.Downloaders.Nexus": "0.5.3",
"Wabbajack.Downloaders.VerificationCache": "0.5.3",
"Wabbajack.Downloaders.WabbajackCDN": "0.5.3",
"Wabbajack.Networking.WabbajackClientApi": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.Dispatcher.dll": {}
}
},
"Wabbajack.Downloaders.GameFile/0.5.2": {
"Wabbajack.Downloaders.GameFile/0.5.3": {
"dependencies": {
"GameFinder.StoreHandlers.EADesktop": "4.5.0",
"GameFinder.StoreHandlers.EGS": "4.5.0",
@@ -1903,361 +1903,361 @@
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.VFS": "0.5.2"
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.VFS": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.GameFile.dll": {}
}
},
"Wabbajack.Downloaders.GoogleDrive/0.5.2": {
"Wabbajack.Downloaders.GoogleDrive/0.5.3": {
"dependencies": {
"HtmlAgilityPack": "1.11.72",
"Microsoft.AspNetCore.Http.Extensions": "2.3.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.GoogleDrive.dll": {}
}
},
"Wabbajack.Downloaders.Http/0.5.2": {
"Wabbajack.Downloaders.Http/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Networking.BethesdaNet": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.BethesdaNet": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.Http.dll": {}
}
},
"Wabbajack.Downloaders.Interfaces/0.5.2": {
"Wabbajack.Downloaders.Interfaces/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.Compression.Zip": "0.5.2",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2"
"Wabbajack.Compression.Zip": "0.5.3",
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.Interfaces.dll": {}
}
},
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.2": {
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.3": {
"dependencies": {
"F23.StringSimilarity": "6.0.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.IPS4OAuth2Downloader.dll": {}
}
},
"Wabbajack.Downloaders.Manual/0.5.2": {
"Wabbajack.Downloaders.Manual/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.Manual.dll": {}
}
},
"Wabbajack.Downloaders.MediaFire/0.5.2": {
"Wabbajack.Downloaders.MediaFire/0.5.3": {
"dependencies": {
"HtmlAgilityPack": "1.11.72",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.MediaFire.dll": {}
}
},
"Wabbajack.Downloaders.Mega/0.5.2": {
"Wabbajack.Downloaders.Mega/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.Mega.dll": {}
}
},
"Wabbajack.Downloaders.ModDB/0.5.2": {
"Wabbajack.Downloaders.ModDB/0.5.3": {
"dependencies": {
"HtmlAgilityPack": "1.11.72",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.ModDB.dll": {}
}
},
"Wabbajack.Downloaders.Nexus/0.5.2": {
"Wabbajack.Downloaders.Nexus/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Hashing.xxHash64": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2",
"Wabbajack.Networking.NexusApi": "0.5.2",
"Wabbajack.Paths": "0.5.2"
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Networking.NexusApi": "0.5.3",
"Wabbajack.Paths": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.Nexus.dll": {}
}
},
"Wabbajack.Downloaders.VerificationCache/0.5.2": {
"Wabbajack.Downloaders.VerificationCache/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Stub.System.Data.SQLite.Core.NetStandard": "1.0.119",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2"
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.VerificationCache.dll": {}
}
},
"Wabbajack.Downloaders.WabbajackCDN/0.5.2": {
"Wabbajack.Downloaders.WabbajackCDN/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Microsoft.Toolkit.HighPerformance": "7.1.2",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.RateLimiter": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.RateLimiter": "0.5.3"
},
"runtime": {
"Wabbajack.Downloaders.WabbajackCDN.dll": {}
}
},
"Wabbajack.DTOs/0.5.2": {
"Wabbajack.DTOs/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.Hashing.xxHash64": "0.5.2",
"Wabbajack.Paths": "0.5.2"
"Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Paths": "0.5.3"
},
"runtime": {
"Wabbajack.DTOs.dll": {}
}
},
"Wabbajack.FileExtractor/0.5.2": {
"Wabbajack.FileExtractor/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"OMODFramework": "3.0.1",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Compression.BSA": "0.5.2",
"Wabbajack.Hashing.PHash": "0.5.2",
"Wabbajack.Paths": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Compression.BSA": "0.5.3",
"Wabbajack.Hashing.PHash": "0.5.3",
"Wabbajack.Paths": "0.5.3"
},
"runtime": {
"Wabbajack.FileExtractor.dll": {}
}
},
"Wabbajack.Hashing.PHash/0.5.2": {
"Wabbajack.Hashing.PHash/0.5.3": {
"dependencies": {
"BCnEncoder.Net.ImageSharp": "1.1.1",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Shipwreck.Phash": "0.5.0",
"SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Common": "0.5.2",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Paths": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3"
},
"runtime": {
"Wabbajack.Hashing.PHash.dll": {}
}
},
"Wabbajack.Hashing.xxHash64/0.5.2": {
"Wabbajack.Hashing.xxHash64/0.5.3": {
"dependencies": {
"Wabbajack.Paths": "0.5.2",
"Wabbajack.RateLimiter": "0.5.2"
"Wabbajack.Paths": "0.5.3",
"Wabbajack.RateLimiter": "0.5.3"
},
"runtime": {
"Wabbajack.Hashing.xxHash64.dll": {}
}
},
"Wabbajack.Installer/0.5.2": {
"Wabbajack.Installer/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3",
"Octopus.Octodiff": "2.0.548",
"SixLabors.ImageSharp": "3.1.6",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Downloaders.Dispatcher": "0.5.2",
"Wabbajack.Downloaders.GameFile": "0.5.2",
"Wabbajack.FileExtractor": "0.5.2",
"Wabbajack.Networking.NexusApi": "0.5.2",
"Wabbajack.Networking.WabbajackClientApi": "0.5.2",
"Wabbajack.Paths": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2",
"Wabbajack.VFS": "0.5.2",
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Downloaders.GameFile": "0.5.3",
"Wabbajack.FileExtractor": "0.5.3",
"Wabbajack.Networking.NexusApi": "0.5.3",
"Wabbajack.Networking.WabbajackClientApi": "0.5.3",
"Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.VFS": "0.5.3",
"ini-parser-netstandard": "2.5.2"
},
"runtime": {
"Wabbajack.Installer.dll": {}
}
},
"Wabbajack.IO.Async/0.5.2": {
"Wabbajack.IO.Async/0.5.3": {
"runtime": {
"Wabbajack.IO.Async.dll": {}
}
},
"Wabbajack.Networking.BethesdaNet/0.5.2": {
"Wabbajack.Networking.BethesdaNet/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2"
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.Networking.BethesdaNet.dll": {}
}
},
"Wabbajack.Networking.Discord/0.5.2": {
"Wabbajack.Networking.Discord/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection.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": {
"Wabbajack.Networking.Discord.dll": {}
}
},
"Wabbajack.Networking.GitHub/0.5.2": {
"Wabbajack.Networking.GitHub/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Octokit": "14.0.0",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2"
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.Networking.GitHub.dll": {}
}
},
"Wabbajack.Networking.Http/0.5.2": {
"Wabbajack.Networking.Http/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Http": "9.0.1",
"Microsoft.Extensions.Logging": "9.0.1",
"Wabbajack.Configuration": "0.5.2",
"Wabbajack.Downloaders.Interfaces": "0.5.2",
"Wabbajack.Hashing.xxHash64": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2",
"Wabbajack.Paths": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2"
"Wabbajack.Configuration": "0.5.3",
"Wabbajack.Downloaders.Interfaces": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3"
},
"runtime": {
"Wabbajack.Networking.Http.dll": {}
}
},
"Wabbajack.Networking.Http.Interfaces/0.5.2": {
"Wabbajack.Networking.Http.Interfaces/0.5.3": {
"dependencies": {
"Wabbajack.Hashing.xxHash64": "0.5.2"
"Wabbajack.Hashing.xxHash64": "0.5.3"
},
"runtime": {
"Wabbajack.Networking.Http.Interfaces.dll": {}
}
},
"Wabbajack.Networking.NexusApi/0.5.2": {
"Wabbajack.Networking.NexusApi/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Networking.Http": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2",
"Wabbajack.Networking.WabbajackClientApi": "0.5.2"
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Networking.Http": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Networking.WabbajackClientApi": "0.5.3"
},
"runtime": {
"Wabbajack.Networking.NexusApi.dll": {}
}
},
"Wabbajack.Networking.WabbajackClientApi/0.5.2": {
"Wabbajack.Networking.WabbajackClientApi/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"Octokit": "14.0.0",
"Wabbajack.Common": "0.5.2",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2",
"Wabbajack.VFS.Interfaces": "0.5.2",
"Wabbajack.Common": "0.5.3",
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.VFS.Interfaces": "0.5.3",
"YamlDotNet": "16.3.0"
},
"runtime": {
"Wabbajack.Networking.WabbajackClientApi.dll": {}
}
},
"Wabbajack.Paths/0.5.2": {
"Wabbajack.Paths/0.5.3": {
"runtime": {
"Wabbajack.Paths.dll": {}
}
},
"Wabbajack.Paths.IO/0.5.2": {
"Wabbajack.Paths.IO/0.5.3": {
"dependencies": {
"Wabbajack.Paths": "0.5.2",
"Wabbajack.Paths": "0.5.3",
"shortid": "4.0.0"
},
"runtime": {
"Wabbajack.Paths.IO.dll": {}
}
},
"Wabbajack.RateLimiter/0.5.2": {
"Wabbajack.RateLimiter/0.5.3": {
"runtime": {
"Wabbajack.RateLimiter.dll": {}
}
},
"Wabbajack.Server.Lib/0.5.2": {
"Wabbajack.Server.Lib/0.5.3": {
"dependencies": {
"FluentFTP": "52.0.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
@@ -2265,58 +2265,58 @@
"Nettle": "3.0.0",
"Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Common": "0.5.2",
"Wabbajack.Networking.Http.Interfaces": "0.5.2",
"Wabbajack.Services.OSIntegrated": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.Networking.Http.Interfaces": "0.5.3",
"Wabbajack.Services.OSIntegrated": "0.5.3"
},
"runtime": {
"Wabbajack.Server.Lib.dll": {}
}
},
"Wabbajack.Services.OSIntegrated/0.5.2": {
"Wabbajack.Services.OSIntegrated/0.5.3": {
"dependencies": {
"DeviceId": "6.8.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Newtonsoft.Json": "13.0.3",
"SixLabors.ImageSharp": "3.1.6",
"Wabbajack.Compiler": "0.5.2",
"Wabbajack.Downloaders.Dispatcher": "0.5.2",
"Wabbajack.Installer": "0.5.2",
"Wabbajack.Networking.BethesdaNet": "0.5.2",
"Wabbajack.Networking.Discord": "0.5.2",
"Wabbajack.VFS": "0.5.2"
"Wabbajack.Compiler": "0.5.3",
"Wabbajack.Downloaders.Dispatcher": "0.5.3",
"Wabbajack.Installer": "0.5.3",
"Wabbajack.Networking.BethesdaNet": "0.5.3",
"Wabbajack.Networking.Discord": "0.5.3",
"Wabbajack.VFS": "0.5.3"
},
"runtime": {
"Wabbajack.Services.OSIntegrated.dll": {}
}
},
"Wabbajack.VFS/0.5.2": {
"Wabbajack.VFS/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Microsoft.Extensions.Logging.Abstractions": "9.0.1",
"SixLabors.ImageSharp": "3.1.6",
"System.Data.SQLite.Core": "1.0.119",
"Wabbajack.Common": "0.5.2",
"Wabbajack.FileExtractor": "0.5.2",
"Wabbajack.Hashing.PHash": "0.5.2",
"Wabbajack.Hashing.xxHash64": "0.5.2",
"Wabbajack.Paths": "0.5.2",
"Wabbajack.Paths.IO": "0.5.2",
"Wabbajack.VFS.Interfaces": "0.5.2"
"Wabbajack.Common": "0.5.3",
"Wabbajack.FileExtractor": "0.5.3",
"Wabbajack.Hashing.PHash": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Paths": "0.5.3",
"Wabbajack.Paths.IO": "0.5.3",
"Wabbajack.VFS.Interfaces": "0.5.3"
},
"runtime": {
"Wabbajack.VFS.dll": {}
}
},
"Wabbajack.VFS.Interfaces/0.5.2": {
"Wabbajack.VFS.Interfaces/0.5.3": {
"dependencies": {
"Microsoft.Extensions.DependencyInjection": "9.0.1",
"Microsoft.Extensions.DependencyInjection.Abstractions": "9.0.1",
"Wabbajack.DTOs": "0.5.2",
"Wabbajack.Hashing.xxHash64": "0.5.2",
"Wabbajack.Paths": "0.5.2"
"Wabbajack.DTOs": "0.5.3",
"Wabbajack.Hashing.xxHash64": "0.5.3",
"Wabbajack.Paths": "0.5.3"
},
"runtime": {
"Wabbajack.VFS.Interfaces.dll": {}
@@ -2333,7 +2333,7 @@
}
},
"libraries": {
"jackify-engine/0.5.2": {
"jackify-engine/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
@@ -3022,202 +3022,202 @@
"path": "yamldotnet/16.3.0",
"hashPath": "yamldotnet.16.3.0.nupkg.sha512"
},
"Wabbajack.CLI.Builder/0.5.2": {
"Wabbajack.CLI.Builder/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Common/0.5.2": {
"Wabbajack.Common/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Compiler/0.5.2": {
"Wabbajack.Compiler/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Compression.BSA/0.5.2": {
"Wabbajack.Compression.BSA/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Compression.Zip/0.5.2": {
"Wabbajack.Compression.Zip/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Configuration/0.5.2": {
"Wabbajack.Configuration/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.Bethesda/0.5.2": {
"Wabbajack.Downloaders.Bethesda/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.Dispatcher/0.5.2": {
"Wabbajack.Downloaders.Dispatcher/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.GameFile/0.5.2": {
"Wabbajack.Downloaders.GameFile/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.GoogleDrive/0.5.2": {
"Wabbajack.Downloaders.GoogleDrive/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.Http/0.5.2": {
"Wabbajack.Downloaders.Http/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.Interfaces/0.5.2": {
"Wabbajack.Downloaders.Interfaces/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.2": {
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.Manual/0.5.2": {
"Wabbajack.Downloaders.Manual/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.MediaFire/0.5.2": {
"Wabbajack.Downloaders.MediaFire/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.Mega/0.5.2": {
"Wabbajack.Downloaders.Mega/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.ModDB/0.5.2": {
"Wabbajack.Downloaders.ModDB/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.Nexus/0.5.2": {
"Wabbajack.Downloaders.Nexus/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.VerificationCache/0.5.2": {
"Wabbajack.Downloaders.VerificationCache/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Downloaders.WabbajackCDN/0.5.2": {
"Wabbajack.Downloaders.WabbajackCDN/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.DTOs/0.5.2": {
"Wabbajack.DTOs/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.FileExtractor/0.5.2": {
"Wabbajack.FileExtractor/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Hashing.PHash/0.5.2": {
"Wabbajack.Hashing.PHash/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Hashing.xxHash64/0.5.2": {
"Wabbajack.Hashing.xxHash64/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Installer/0.5.2": {
"Wabbajack.Installer/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.IO.Async/0.5.2": {
"Wabbajack.IO.Async/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Networking.BethesdaNet/0.5.2": {
"Wabbajack.Networking.BethesdaNet/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Networking.Discord/0.5.2": {
"Wabbajack.Networking.Discord/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Networking.GitHub/0.5.2": {
"Wabbajack.Networking.GitHub/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Networking.Http/0.5.2": {
"Wabbajack.Networking.Http/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Networking.Http.Interfaces/0.5.2": {
"Wabbajack.Networking.Http.Interfaces/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Networking.NexusApi/0.5.2": {
"Wabbajack.Networking.NexusApi/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Networking.WabbajackClientApi/0.5.2": {
"Wabbajack.Networking.WabbajackClientApi/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Paths/0.5.2": {
"Wabbajack.Paths/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Paths.IO/0.5.2": {
"Wabbajack.Paths.IO/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.RateLimiter/0.5.2": {
"Wabbajack.RateLimiter/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Server.Lib/0.5.2": {
"Wabbajack.Server.Lib/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.Services.OSIntegrated/0.5.2": {
"Wabbajack.Services.OSIntegrated/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.VFS/0.5.2": {
"Wabbajack.VFS/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""
},
"Wabbajack.VFS.Interfaces/0.5.2": {
"Wabbajack.VFS.Interfaces/0.5.3": {
"type": "project",
"serviceable": false,
"sha512": ""

Binary file not shown.

View File

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

View File

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

View File

@@ -419,6 +419,9 @@ class InstallModlistScreen(ScreenBackMixin, InstallModlistUISetupMixin, ConsoleO
self._vnv_controller.cleanup()
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):
thread = getattr(self, attr_name, None)
if thread is None:

View File

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

View File

@@ -15,44 +15,19 @@ class FocusReclaimMixin:
progress messages for STEAM_RESTART_SENTINEL.
"""
def _start_focus_reclaim_retries(self):
try:
if hasattr(self, "_focus_reclaim_timer") and self._focus_reclaim_timer:
self._focus_reclaim_timer.stop()
self._focus_reclaim_timer.deleteLater()
except Exception:
pass
def _stop_focus_reclaim(self):
pass # No timer to stop — single-shot, no state
self._focus_reclaim_attempt = 0
self._focus_reclaim_max_attempts = 12 # ~24 seconds total
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 _start_focus_reclaim_retries(self):
QTimer.singleShot(500, self._focus_reclaim_tick)
def _focus_reclaim_tick(self):
try:
win = self.window()
if win is None:
return
self._focus_reclaim_attempt += 1
win.raise_()
win.activateWindow()
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:
logger.debug(f"Focus reclaim tick failed: {e}")
try:
self._focus_reclaim_timer.stop()
except Exception:
pass
logger.debug(f"Focus reclaim attempt failed: {e}")

View File

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