Sync from development - prepare for v0.1.0.1

This commit is contained in:
Omni
2025-09-14 20:18:33 +01:00
parent c2803e854e
commit 2e4cdc2854
51 changed files with 378 additions and 314 deletions

View File

@@ -1,5 +1,30 @@
# Jackify Changelog # Jackify Changelog
## v0.1.0.1 - Engine Update and Stability Improvements
**Release Date:** September 14, 2025
### Engine Updates
- **jackify-engine v0.3.13**: Major stability and resource management improvements
- **Wine Prefix Cleanup**: Automatic cleanup of ~281MB Wine prefix directories after each modlist installation
- **Manual Download Handling**: Fixed installation crashes when manual downloads are required
- **Enhanced Error Messaging**: Detailed mod information for failed downloads (Nexus ModID/FileID, Google Drive, HTTP sources)
- **Resource Settings Compliance**: Fixed resource settings not being respected during VFS and Installer operations
- **VFS Crash Prevention**: Fixed KeyNotFoundException crashes during "Priming VFS" phase with missing archives
- **Creation Club File Handling**: Fixed incorrect re-download attempts for Creation Club files
- **BSA Extraction Fix**: Fixed DirectoryNotFoundException during BSA building operations
### Improvements
- **Disk Space Management**: No more accumulation of Wine prefix directories consuming hundreds of MB per installation
- **Clean Error Handling**: Manual download requirements now show clear summary instead of stack traces
- **Better Resource Control**: Users can now properly control CPU usage during installation via resource_settings.json
### Bug Fixes
- **Download System**: Fixed GoogleDrive and MEGA download regressions
- **Configuration Integration**: MEGA tokens properly stored in Jackify's config directory structure
- **Installation Reliability**: Enhanced error handling prevents crashes with missing or corrupted archives
---
## v0.1.0 - First Public Release ## v0.1.0 - First Public Release
**Release Date:** September 11, 2025 **Release Date:** September 11, 2025

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.1.0" __version__ = "0.1.0.1"

View File

@@ -1400,8 +1400,9 @@ class ModlistInstallCLI:
# Remove status indicators to get clean line # Remove status indicators to get clean line
clean_line = line.replace('[DOWN]', '').replace('[NSFW]', '').strip() clean_line = line.replace('[DOWN]', '').replace('[NSFW]', '').strip()
# Split on ' - ' to get: [Modlist Name, Game, Sizes, MachineURL] # Split from right to handle modlist names with dashes
parts = clean_line.split(' - ') # Format: "NAME - GAME - SIZES - MACHINE_URL"
parts = clean_line.rsplit(' - ', 3) # Split from right, max 3 splits = 4 parts
if len(parts) != 4: if len(parts) != 4:
continue # Skip malformed lines continue # Skip malformed lines

View File

@@ -213,11 +213,14 @@ class ConfigHandler:
def get_api_key(self): def get_api_key(self):
""" """
Retrieve and decode the saved Nexus API key Retrieve and decode the saved Nexus API key
Always reads fresh from disk to pick up changes from other instances
Returns: Returns:
str: Decoded API key or None if not saved str: Decoded API key or None if not saved
""" """
try: try:
# Reload config from disk to pick up changes from Settings dialog
self._load_config()
encoded_key = self.settings.get("nexus_api_key") encoded_key = self.settings.get("nexus_api_key")
if encoded_key: if encoded_key:
# Decode the base64 encoded key # Decode the base64 encoded key
@@ -231,10 +234,13 @@ class ConfigHandler:
def has_saved_api_key(self): def has_saved_api_key(self):
""" """
Check if an API key is saved in configuration Check if an API key is saved in configuration
Always reads fresh from disk to pick up changes from other instances
Returns: Returns:
bool: True if API key exists, False otherwise bool: True if API key exists, False otherwise
""" """
# Reload config from disk to pick up changes from Settings dialog
self._load_config()
return self.settings.get("nexus_api_key") is not None return self.settings.get("nexus_api_key") is not None
def clear_api_key(self): def clear_api_key(self):

View File

@@ -1117,6 +1117,7 @@ class ModlistHandler:
("grid-hero.png", f"{appid}_hero.png"), ("grid-hero.png", f"{appid}_hero.png"),
("grid-logo.png", f"{appid}_logo.png"), ("grid-logo.png", f"{appid}_logo.png"),
("grid-tall.png", f"{appid}.png"), ("grid-tall.png", f"{appid}.png"),
("grid-tall.png", f"{appid}p.png"),
] ]
for src_name, dest_name in images: for src_name, dest_name in images:

View File

@@ -1020,8 +1020,9 @@ class ModlistInstallCLI:
# Remove status indicators to get clean line # Remove status indicators to get clean line
clean_line = line.replace('[DOWN]', '').replace('[NSFW]', '').strip() clean_line = line.replace('[DOWN]', '').replace('[NSFW]', '').strip()
# Split on ' - ' to get: [Modlist Name, Game, Sizes, MachineURL] # Split from right to handle modlist names with dashes
parts = clean_line.split(' - ') # Format: "NAME - GAME - SIZES - MACHINE_URL"
parts = clean_line.rsplit(' - ', 3) # Split from right, max 3 splits = 4 parts
if len(parts) != 4: if len(parts) != 4:
continue # Skip malformed lines continue # Skip malformed lines

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.3.12": { "jackify-engine/0.3.13": {
"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.3.12", "Wabbajack.CLI.Builder": "0.3.13",
"Wabbajack.Downloaders.Bethesda": "0.3.12", "Wabbajack.Downloaders.Bethesda": "0.3.13",
"Wabbajack.Downloaders.Dispatcher": "0.3.12", "Wabbajack.Downloaders.Dispatcher": "0.3.13",
"Wabbajack.Hashing.xxHash64": "0.3.12", "Wabbajack.Hashing.xxHash64": "0.3.13",
"Wabbajack.Networking.Discord": "0.3.12", "Wabbajack.Networking.Discord": "0.3.13",
"Wabbajack.Networking.GitHub": "0.3.12", "Wabbajack.Networking.GitHub": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12", "Wabbajack.Paths.IO": "0.3.13",
"Wabbajack.Server.Lib": "0.3.12", "Wabbajack.Server.Lib": "0.3.13",
"Wabbajack.Services.OSIntegrated": "0.3.12", "Wabbajack.Services.OSIntegrated": "0.3.13",
"Wabbajack.VFS": "0.3.12", "Wabbajack.VFS": "0.3.13",
"MegaApiClient": "1.0.0.0", "MegaApiClient": "1.0.0.0",
"runtimepack.Microsoft.NETCore.App.Runtime.linux-x64": "8.0.19" "runtimepack.Microsoft.NETCore.App.Runtime.linux-x64": "8.0.19"
}, },
@@ -1781,7 +1781,7 @@
} }
} }
}, },
"Wabbajack.CLI.Builder/0.3.12": { "Wabbajack.CLI.Builder/0.3.13": {
"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.3.12" "Wabbajack.Paths": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.CLI.Builder.dll": {} "Wabbajack.CLI.Builder.dll": {}
} }
}, },
"Wabbajack.Common/0.3.12": { "Wabbajack.Common/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12" "Wabbajack.Paths.IO": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Common.dll": {} "Wabbajack.Common.dll": {}
} }
}, },
"Wabbajack.Compiler/0.3.12": { "Wabbajack.Compiler/0.3.13": {
"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.3.12", "Wabbajack.Downloaders.Dispatcher": "0.3.13",
"Wabbajack.Installer": "0.3.12", "Wabbajack.Installer": "0.3.13",
"Wabbajack.VFS": "0.3.12", "Wabbajack.VFS": "0.3.13",
"ini-parser-netstandard": "2.5.2" "ini-parser-netstandard": "2.5.2"
}, },
"runtime": { "runtime": {
"Wabbajack.Compiler.dll": {} "Wabbajack.Compiler.dll": {}
} }
}, },
"Wabbajack.Compression.BSA/0.3.12": { "Wabbajack.Compression.BSA/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.DTOs": "0.3.12" "Wabbajack.DTOs": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Compression.BSA.dll": {} "Wabbajack.Compression.BSA.dll": {}
} }
}, },
"Wabbajack.Compression.Zip/0.3.12": { "Wabbajack.Compression.Zip/0.3.13": {
"dependencies": { "dependencies": {
"Wabbajack.IO.Async": "0.3.12" "Wabbajack.IO.Async": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Compression.Zip.dll": {} "Wabbajack.Compression.Zip.dll": {}
} }
}, },
"Wabbajack.Configuration/0.3.12": { "Wabbajack.Configuration/0.3.13": {
"runtime": { "runtime": {
"Wabbajack.Configuration.dll": {} "Wabbajack.Configuration.dll": {}
} }
}, },
"Wabbajack.Downloaders.Bethesda/0.3.12": { "Wabbajack.Downloaders.Bethesda/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Networking.BethesdaNet": "0.3.12" "Wabbajack.Networking.BethesdaNet": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Bethesda.dll": {} "Wabbajack.Downloaders.Bethesda.dll": {}
} }
}, },
"Wabbajack.Downloaders.Dispatcher/0.3.12": { "Wabbajack.Downloaders.Dispatcher/0.3.13": {
"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.3.12", "Wabbajack.Downloaders.Bethesda": "0.3.13",
"Wabbajack.Downloaders.GameFile": "0.3.12", "Wabbajack.Downloaders.GameFile": "0.3.13",
"Wabbajack.Downloaders.GoogleDrive": "0.3.12", "Wabbajack.Downloaders.GoogleDrive": "0.3.13",
"Wabbajack.Downloaders.Http": "0.3.12", "Wabbajack.Downloaders.Http": "0.3.13",
"Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.3.12", "Wabbajack.Downloaders.IPS4OAuth2Downloader": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Downloaders.Manual": "0.3.12", "Wabbajack.Downloaders.Manual": "0.3.13",
"Wabbajack.Downloaders.MediaFire": "0.3.12", "Wabbajack.Downloaders.MediaFire": "0.3.13",
"Wabbajack.Downloaders.Mega": "0.3.12", "Wabbajack.Downloaders.Mega": "0.3.13",
"Wabbajack.Downloaders.ModDB": "0.3.12", "Wabbajack.Downloaders.ModDB": "0.3.13",
"Wabbajack.Downloaders.Nexus": "0.3.12", "Wabbajack.Downloaders.Nexus": "0.3.13",
"Wabbajack.Downloaders.VerificationCache": "0.3.12", "Wabbajack.Downloaders.VerificationCache": "0.3.13",
"Wabbajack.Downloaders.WabbajackCDN": "0.3.12", "Wabbajack.Downloaders.WabbajackCDN": "0.3.13",
"Wabbajack.Networking.WabbajackClientApi": "0.3.12" "Wabbajack.Networking.WabbajackClientApi": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Dispatcher.dll": {} "Wabbajack.Downloaders.Dispatcher.dll": {}
} }
}, },
"Wabbajack.Downloaders.GameFile/0.3.12": { "Wabbajack.Downloaders.GameFile/0.3.13": {
"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,360 +1903,360 @@
"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.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.VFS": "0.3.12" "Wabbajack.VFS": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.GameFile.dll": {} "Wabbajack.Downloaders.GameFile.dll": {}
} }
}, },
"Wabbajack.Downloaders.GoogleDrive/0.3.12": { "Wabbajack.Downloaders.GoogleDrive/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.DTOs": "0.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12" "Wabbajack.Networking.Http.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.GoogleDrive.dll": {} "Wabbajack.Downloaders.GoogleDrive.dll": {}
} }
}, },
"Wabbajack.Downloaders.Http/0.3.12": { "Wabbajack.Downloaders.Http/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.DTOs": "0.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Networking.BethesdaNet": "0.3.12", "Wabbajack.Networking.BethesdaNet": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12", "Wabbajack.Networking.Http.Interfaces": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12" "Wabbajack.Paths.IO": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Http.dll": {} "Wabbajack.Downloaders.Http.dll": {}
} }
}, },
"Wabbajack.Downloaders.Interfaces/0.3.12": { "Wabbajack.Downloaders.Interfaces/0.3.13": {
"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.3.12", "Wabbajack.Compression.Zip": "0.3.13",
"Wabbajack.DTOs": "0.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12" "Wabbajack.Paths.IO": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Interfaces.dll": {} "Wabbajack.Downloaders.Interfaces.dll": {}
} }
}, },
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.3.12": { "Wabbajack.Downloaders.IPS4OAuth2Downloader/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12" "Wabbajack.Networking.Http.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.IPS4OAuth2Downloader.dll": {} "Wabbajack.Downloaders.IPS4OAuth2Downloader.dll": {}
} }
}, },
"Wabbajack.Downloaders.Manual/0.3.12": { "Wabbajack.Downloaders.Manual/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12" "Wabbajack.Downloaders.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Manual.dll": {} "Wabbajack.Downloaders.Manual.dll": {}
} }
}, },
"Wabbajack.Downloaders.MediaFire/0.3.12": { "Wabbajack.Downloaders.MediaFire/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12" "Wabbajack.Networking.Http.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.MediaFire.dll": {} "Wabbajack.Downloaders.MediaFire.dll": {}
} }
}, },
"Wabbajack.Downloaders.Mega/0.3.12": { "Wabbajack.Downloaders.Mega/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12" "Wabbajack.Paths.IO": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Mega.dll": {} "Wabbajack.Downloaders.Mega.dll": {}
} }
}, },
"Wabbajack.Downloaders.ModDB/0.3.12": { "Wabbajack.Downloaders.ModDB/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12" "Wabbajack.Networking.Http.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.ModDB.dll": {} "Wabbajack.Downloaders.ModDB.dll": {}
} }
}, },
"Wabbajack.Downloaders.Nexus/0.3.12": { "Wabbajack.Downloaders.Nexus/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Hashing.xxHash64": "0.3.12", "Wabbajack.Hashing.xxHash64": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12", "Wabbajack.Networking.Http.Interfaces": "0.3.13",
"Wabbajack.Networking.NexusApi": "0.3.12", "Wabbajack.Networking.NexusApi": "0.3.13",
"Wabbajack.Paths": "0.3.12" "Wabbajack.Paths": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.Nexus.dll": {} "Wabbajack.Downloaders.Nexus.dll": {}
} }
}, },
"Wabbajack.Downloaders.VerificationCache/0.3.12": { "Wabbajack.Downloaders.VerificationCache/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12" "Wabbajack.Paths.IO": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.VerificationCache.dll": {} "Wabbajack.Downloaders.VerificationCache.dll": {}
} }
}, },
"Wabbajack.Downloaders.WabbajackCDN/0.3.12": { "Wabbajack.Downloaders.WabbajackCDN/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.RateLimiter": "0.3.12" "Wabbajack.RateLimiter": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Downloaders.WabbajackCDN.dll": {} "Wabbajack.Downloaders.WabbajackCDN.dll": {}
} }
}, },
"Wabbajack.DTOs/0.3.12": { "Wabbajack.DTOs/0.3.13": {
"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.3.12", "Wabbajack.Hashing.xxHash64": "0.3.13",
"Wabbajack.Paths": "0.3.12" "Wabbajack.Paths": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.DTOs.dll": {} "Wabbajack.DTOs.dll": {}
} }
}, },
"Wabbajack.FileExtractor/0.3.12": { "Wabbajack.FileExtractor/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Compression.BSA": "0.3.12", "Wabbajack.Compression.BSA": "0.3.13",
"Wabbajack.Hashing.PHash": "0.3.12", "Wabbajack.Hashing.PHash": "0.3.13",
"Wabbajack.Paths": "0.3.12" "Wabbajack.Paths": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.FileExtractor.dll": {} "Wabbajack.FileExtractor.dll": {}
} }
}, },
"Wabbajack.Hashing.PHash/0.3.12": { "Wabbajack.Hashing.PHash/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.DTOs": "0.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Paths": "0.3.12", "Wabbajack.Paths": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12" "Wabbajack.Paths.IO": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Hashing.PHash.dll": {} "Wabbajack.Hashing.PHash.dll": {}
} }
}, },
"Wabbajack.Hashing.xxHash64/0.3.12": { "Wabbajack.Hashing.xxHash64/0.3.13": {
"dependencies": { "dependencies": {
"Wabbajack.Paths": "0.3.12", "Wabbajack.Paths": "0.3.13",
"Wabbajack.RateLimiter": "0.3.12" "Wabbajack.RateLimiter": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Hashing.xxHash64.dll": {} "Wabbajack.Hashing.xxHash64.dll": {}
} }
}, },
"Wabbajack.Installer/0.3.12": { "Wabbajack.Installer/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Downloaders.Dispatcher": "0.3.12", "Wabbajack.Downloaders.Dispatcher": "0.3.13",
"Wabbajack.Downloaders.GameFile": "0.3.12", "Wabbajack.Downloaders.GameFile": "0.3.13",
"Wabbajack.FileExtractor": "0.3.12", "Wabbajack.FileExtractor": "0.3.13",
"Wabbajack.Networking.WabbajackClientApi": "0.3.12", "Wabbajack.Networking.WabbajackClientApi": "0.3.13",
"Wabbajack.Paths": "0.3.12", "Wabbajack.Paths": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12", "Wabbajack.Paths.IO": "0.3.13",
"Wabbajack.VFS": "0.3.12", "Wabbajack.VFS": "0.3.13",
"ini-parser-netstandard": "2.5.2" "ini-parser-netstandard": "2.5.2"
}, },
"runtime": { "runtime": {
"Wabbajack.Installer.dll": {} "Wabbajack.Installer.dll": {}
} }
}, },
"Wabbajack.IO.Async/0.3.12": { "Wabbajack.IO.Async/0.3.13": {
"runtime": { "runtime": {
"Wabbajack.IO.Async.dll": {} "Wabbajack.IO.Async.dll": {}
} }
}, },
"Wabbajack.Networking.BethesdaNet/0.3.12": { "Wabbajack.Networking.BethesdaNet/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12" "Wabbajack.Networking.Http.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.BethesdaNet.dll": {} "Wabbajack.Networking.BethesdaNet.dll": {}
} }
}, },
"Wabbajack.Networking.Discord/0.3.12": { "Wabbajack.Networking.Discord/0.3.13": {
"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.3.12" "Wabbajack.Networking.Http.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.Discord.dll": {} "Wabbajack.Networking.Discord.dll": {}
} }
}, },
"Wabbajack.Networking.GitHub/0.3.12": { "Wabbajack.Networking.GitHub/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12" "Wabbajack.Networking.Http.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.GitHub.dll": {} "Wabbajack.Networking.GitHub.dll": {}
} }
}, },
"Wabbajack.Networking.Http/0.3.12": { "Wabbajack.Networking.Http/0.3.13": {
"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.3.12", "Wabbajack.Configuration": "0.3.13",
"Wabbajack.Downloaders.Interfaces": "0.3.12", "Wabbajack.Downloaders.Interfaces": "0.3.13",
"Wabbajack.Hashing.xxHash64": "0.3.12", "Wabbajack.Hashing.xxHash64": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12", "Wabbajack.Networking.Http.Interfaces": "0.3.13",
"Wabbajack.Paths": "0.3.12", "Wabbajack.Paths": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12" "Wabbajack.Paths.IO": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.Http.dll": {} "Wabbajack.Networking.Http.dll": {}
} }
}, },
"Wabbajack.Networking.Http.Interfaces/0.3.12": { "Wabbajack.Networking.Http.Interfaces/0.3.13": {
"dependencies": { "dependencies": {
"Wabbajack.Hashing.xxHash64": "0.3.12" "Wabbajack.Hashing.xxHash64": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.Http.Interfaces.dll": {} "Wabbajack.Networking.Http.Interfaces.dll": {}
} }
}, },
"Wabbajack.Networking.NexusApi/0.3.12": { "Wabbajack.Networking.NexusApi/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Networking.Http": "0.3.12", "Wabbajack.Networking.Http": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12", "Wabbajack.Networking.Http.Interfaces": "0.3.13",
"Wabbajack.Networking.WabbajackClientApi": "0.3.12" "Wabbajack.Networking.WabbajackClientApi": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.NexusApi.dll": {} "Wabbajack.Networking.NexusApi.dll": {}
} }
}, },
"Wabbajack.Networking.WabbajackClientApi/0.3.12": { "Wabbajack.Networking.WabbajackClientApi/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.DTOs": "0.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12", "Wabbajack.Paths.IO": "0.3.13",
"Wabbajack.VFS.Interfaces": "0.3.12", "Wabbajack.VFS.Interfaces": "0.3.13",
"YamlDotNet": "16.3.0" "YamlDotNet": "16.3.0"
}, },
"runtime": { "runtime": {
"Wabbajack.Networking.WabbajackClientApi.dll": {} "Wabbajack.Networking.WabbajackClientApi.dll": {}
} }
}, },
"Wabbajack.Paths/0.3.12": { "Wabbajack.Paths/0.3.13": {
"runtime": { "runtime": {
"Wabbajack.Paths.dll": {} "Wabbajack.Paths.dll": {}
} }
}, },
"Wabbajack.Paths.IO/0.3.12": { "Wabbajack.Paths.IO/0.3.13": {
"dependencies": { "dependencies": {
"Wabbajack.Paths": "0.3.12", "Wabbajack.Paths": "0.3.13",
"shortid": "4.0.0" "shortid": "4.0.0"
}, },
"runtime": { "runtime": {
"Wabbajack.Paths.IO.dll": {} "Wabbajack.Paths.IO.dll": {}
} }
}, },
"Wabbajack.RateLimiter/0.3.12": { "Wabbajack.RateLimiter/0.3.13": {
"runtime": { "runtime": {
"Wabbajack.RateLimiter.dll": {} "Wabbajack.RateLimiter.dll": {}
} }
}, },
"Wabbajack.Server.Lib/0.3.12": { "Wabbajack.Server.Lib/0.3.13": {
"dependencies": { "dependencies": {
"FluentFTP": "52.0.0", "FluentFTP": "52.0.0",
"Microsoft.Extensions.DependencyInjection": "9.0.1", "Microsoft.Extensions.DependencyInjection": "9.0.1",
@@ -2264,58 +2264,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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.Networking.Http.Interfaces": "0.3.12", "Wabbajack.Networking.Http.Interfaces": "0.3.13",
"Wabbajack.Services.OSIntegrated": "0.3.12" "Wabbajack.Services.OSIntegrated": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Server.Lib.dll": {} "Wabbajack.Server.Lib.dll": {}
} }
}, },
"Wabbajack.Services.OSIntegrated/0.3.12": { "Wabbajack.Services.OSIntegrated/0.3.13": {
"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.3.12", "Wabbajack.Compiler": "0.3.13",
"Wabbajack.Downloaders.Dispatcher": "0.3.12", "Wabbajack.Downloaders.Dispatcher": "0.3.13",
"Wabbajack.Installer": "0.3.12", "Wabbajack.Installer": "0.3.13",
"Wabbajack.Networking.BethesdaNet": "0.3.12", "Wabbajack.Networking.BethesdaNet": "0.3.13",
"Wabbajack.Networking.Discord": "0.3.12", "Wabbajack.Networking.Discord": "0.3.13",
"Wabbajack.VFS": "0.3.12" "Wabbajack.VFS": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.Services.OSIntegrated.dll": {} "Wabbajack.Services.OSIntegrated.dll": {}
} }
}, },
"Wabbajack.VFS/0.3.12": { "Wabbajack.VFS/0.3.13": {
"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.3.12", "Wabbajack.Common": "0.3.13",
"Wabbajack.FileExtractor": "0.3.12", "Wabbajack.FileExtractor": "0.3.13",
"Wabbajack.Hashing.PHash": "0.3.12", "Wabbajack.Hashing.PHash": "0.3.13",
"Wabbajack.Hashing.xxHash64": "0.3.12", "Wabbajack.Hashing.xxHash64": "0.3.13",
"Wabbajack.Paths": "0.3.12", "Wabbajack.Paths": "0.3.13",
"Wabbajack.Paths.IO": "0.3.12", "Wabbajack.Paths.IO": "0.3.13",
"Wabbajack.VFS.Interfaces": "0.3.12" "Wabbajack.VFS.Interfaces": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.VFS.dll": {} "Wabbajack.VFS.dll": {}
} }
}, },
"Wabbajack.VFS.Interfaces/0.3.12": { "Wabbajack.VFS.Interfaces/0.3.13": {
"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.3.12", "Wabbajack.DTOs": "0.3.13",
"Wabbajack.Hashing.xxHash64": "0.3.12", "Wabbajack.Hashing.xxHash64": "0.3.13",
"Wabbajack.Paths": "0.3.12" "Wabbajack.Paths": "0.3.13"
}, },
"runtime": { "runtime": {
"Wabbajack.VFS.Interfaces.dll": {} "Wabbajack.VFS.Interfaces.dll": {}
@@ -2332,7 +2332,7 @@
} }
}, },
"libraries": { "libraries": {
"jackify-engine/0.3.12": { "jackify-engine/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
@@ -3021,202 +3021,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.3.12": { "Wabbajack.CLI.Builder/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Common/0.3.12": { "Wabbajack.Common/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Compiler/0.3.12": { "Wabbajack.Compiler/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Compression.BSA/0.3.12": { "Wabbajack.Compression.BSA/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Compression.Zip/0.3.12": { "Wabbajack.Compression.Zip/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Configuration/0.3.12": { "Wabbajack.Configuration/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Bethesda/0.3.12": { "Wabbajack.Downloaders.Bethesda/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Dispatcher/0.3.12": { "Wabbajack.Downloaders.Dispatcher/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.GameFile/0.3.12": { "Wabbajack.Downloaders.GameFile/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.GoogleDrive/0.3.12": { "Wabbajack.Downloaders.GoogleDrive/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Http/0.3.12": { "Wabbajack.Downloaders.Http/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Interfaces/0.3.12": { "Wabbajack.Downloaders.Interfaces/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.IPS4OAuth2Downloader/0.3.12": { "Wabbajack.Downloaders.IPS4OAuth2Downloader/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Manual/0.3.12": { "Wabbajack.Downloaders.Manual/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.MediaFire/0.3.12": { "Wabbajack.Downloaders.MediaFire/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Mega/0.3.12": { "Wabbajack.Downloaders.Mega/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.ModDB/0.3.12": { "Wabbajack.Downloaders.ModDB/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.Nexus/0.3.12": { "Wabbajack.Downloaders.Nexus/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.VerificationCache/0.3.12": { "Wabbajack.Downloaders.VerificationCache/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Downloaders.WabbajackCDN/0.3.12": { "Wabbajack.Downloaders.WabbajackCDN/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.DTOs/0.3.12": { "Wabbajack.DTOs/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.FileExtractor/0.3.12": { "Wabbajack.FileExtractor/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Hashing.PHash/0.3.12": { "Wabbajack.Hashing.PHash/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Hashing.xxHash64/0.3.12": { "Wabbajack.Hashing.xxHash64/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Installer/0.3.12": { "Wabbajack.Installer/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.IO.Async/0.3.12": { "Wabbajack.IO.Async/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.BethesdaNet/0.3.12": { "Wabbajack.Networking.BethesdaNet/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.Discord/0.3.12": { "Wabbajack.Networking.Discord/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.GitHub/0.3.12": { "Wabbajack.Networking.GitHub/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.Http/0.3.12": { "Wabbajack.Networking.Http/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.Http.Interfaces/0.3.12": { "Wabbajack.Networking.Http.Interfaces/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.NexusApi/0.3.12": { "Wabbajack.Networking.NexusApi/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Networking.WabbajackClientApi/0.3.12": { "Wabbajack.Networking.WabbajackClientApi/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Paths/0.3.12": { "Wabbajack.Paths/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Paths.IO/0.3.12": { "Wabbajack.Paths.IO/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.RateLimiter/0.3.12": { "Wabbajack.RateLimiter/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Server.Lib/0.3.12": { "Wabbajack.Server.Lib/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.Services.OSIntegrated/0.3.12": { "Wabbajack.Services.OSIntegrated/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.VFS/0.3.12": { "Wabbajack.VFS/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
}, },
"Wabbajack.VFS.Interfaces/0.3.12": { "Wabbajack.VFS.Interfaces/0.3.13": {
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""

Binary file not shown.

View File

@@ -181,59 +181,76 @@ class SettingsDialog(QDialog):
self.resource_edits = {} self.resource_edits = {}
resource_row_index = 0 resource_row_index = 0
for resource_row_index, (k, v) in enumerate(self.resource_settings.items(), start=1): for resource_row_index, (k, v) in enumerate(self.resource_settings.items(), start=1):
# Create resource label with optional inline checkbox for File Extractor try:
if k == "File Extractor": # Create resource label with optional inline checkbox for File Extractor
# Create horizontal layout for File Extractor with inline checkbox if k == "File Extractor":
resource_row = QHBoxLayout() # Create horizontal layout for File Extractor with inline checkbox
resource_label = QLabel(f"{k}:", parent=self) resource_row = QHBoxLayout()
resource_row.addWidget(resource_label) resource_label = QLabel(f"{k}:", parent=self)
resource_row.addSpacing(10) # Add some spacing resource_row.addWidget(resource_label)
resource_row.addSpacing(10) # Add some spacing
multithreading_checkbox = QCheckBox("Multithreading (Experimental)")
multithreading_checkbox.setChecked(v.get('_7zzMultiThread', 'off') == 'on')
multithreading_checkbox.setToolTip("Enables multithreaded file extraction using 7-Zip. May improve extraction speed on multi-core systems but could be less stable.")
multithreading_checkbox.setStyleSheet("color: #fff;")
resource_row.addWidget(multithreading_checkbox)
resource_row.addStretch() # Push checkbox to the left
# Add the horizontal layout to the grid
resource_layout.addLayout(resource_row, resource_row_index, 0)
else:
resource_layout.addWidget(QLabel(f"{k}:", parent=self), resource_row_index, 0, 1, 1, Qt.AlignLeft)
multithreading_checkbox = QCheckBox("Multithreading (Experimental)") max_tasks_spin = QSpinBox()
multithreading_checkbox.setChecked(v.get('_7zzMultiThread', 'off') == 'on') max_tasks_spin.setMinimum(1)
multithreading_checkbox.setToolTip("Enables multithreaded file extraction using 7-Zip. May improve extraction speed on multi-core systems but could be less stable.") max_tasks_spin.setMaximum(128)
multithreading_checkbox.setStyleSheet("color: #fff;") max_tasks_spin.setValue(v.get('MaxTasks', 16))
resource_row.addWidget(multithreading_checkbox) max_tasks_spin.setToolTip("Maximum number of concurrent tasks for this resource.")
resource_row.addStretch() # Push checkbox to the left max_tasks_spin.setFixedWidth(160)
resource_layout.addWidget(max_tasks_spin, resource_row_index, 1)
# Add the horizontal layout to the grid # Store the widgets (checkbox for File Extractor, None for others)
resource_layout.addLayout(resource_row, resource_row_index, 0) if k == "File Extractor":
else: self.resource_edits[k] = (multithreading_checkbox, max_tasks_spin)
resource_layout.addWidget(QLabel(f"{k}:", parent=self), resource_row_index, 0, 1, 1, Qt.AlignLeft) else:
self.resource_edits[k] = (None, max_tasks_spin)
max_tasks_spin = QSpinBox() except Exception as e:
max_tasks_spin.setMinimum(1) print(f"[ERROR] Failed to create widgets for resource '{k}': {e}")
max_tasks_spin.setMaximum(128) continue
max_tasks_spin.setValue(v.get('MaxTasks', 16))
max_tasks_spin.setToolTip("Maximum number of concurrent tasks for this resource.")
max_tasks_spin.setFixedWidth(160)
resource_layout.addWidget(max_tasks_spin, resource_row_index, 1)
# Store the widgets (checkbox for File Extractor, None for others)
if k == "File Extractor":
self.resource_edits[k] = (multithreading_checkbox, max_tasks_spin)
else:
self.resource_edits[k] = (None, max_tasks_spin)
# Bandwidth limiter row
self.app_settings_path = os.path.expanduser("~/.config/jackify/app_settings.json")
self.app_settings = self._load_json(self.app_settings_path)
self.bandwidth_spin = QSpinBox()
self.bandwidth_spin.setMinimum(0)
self.bandwidth_spin.setMaximum(1000000)
self.bandwidth_spin.setValue(self.app_settings.get("MaxDownloadSpeedKBps", 0))
self.bandwidth_spin.setSuffix(" KB/s")
self.bandwidth_spin.setFixedWidth(160)
self.bandwidth_spin.setToolTip("Set the maximum download speed for modlist downloads. 0 = unlimited.")
bandwidth_note = QLabel("(0 = unlimited)")
bandwidth_note.setStyleSheet("color: #aaa; font-size: 10pt;")
# Create horizontal layout for bandwidth row
bandwidth_row = QHBoxLayout()
bandwidth_row.addWidget(self.bandwidth_spin)
bandwidth_row.addWidget(bandwidth_note)
bandwidth_row.addStretch() # Push to the left
resource_layout.addWidget(QLabel("Bandwidth Limit:", parent=self), resource_row_index+1, 0, 1, 1, Qt.AlignLeft) # If no resources exist, show helpful message
resource_layout.addLayout(bandwidth_row, resource_row_index+1, 1) if not self.resource_edits:
info_label = QLabel("Resource Limit settings will be generated once a modlist install action is performed")
info_label.setStyleSheet("color: #aaa; font-style: italic; padding: 20px; font-size: 11pt;")
info_label.setWordWrap(True)
info_label.setAlignment(Qt.AlignCenter)
info_label.setMinimumHeight(60) # Ensure enough height to prevent cutoff
resource_layout.addWidget(info_label, 1, 0, 3, 2) # Span more rows for better space
# Bandwidth limiter row (only show if Downloads resource exists)
if "Downloads" in self.resource_settings:
downloads_throughput = self.resource_settings["Downloads"].get("MaxThroughput", 0)
self.bandwidth_spin = QSpinBox()
self.bandwidth_spin.setMinimum(0)
self.bandwidth_spin.setMaximum(1000000)
self.bandwidth_spin.setValue(downloads_throughput)
self.bandwidth_spin.setSuffix(" KB/s")
self.bandwidth_spin.setFixedWidth(160)
self.bandwidth_spin.setToolTip("Set the maximum download speed for modlist downloads. 0 = unlimited.")
bandwidth_note = QLabel("(0 = unlimited)")
bandwidth_note.setStyleSheet("color: #aaa; font-size: 10pt;")
# Create horizontal layout for bandwidth row
bandwidth_row = QHBoxLayout()
bandwidth_row.addWidget(self.bandwidth_spin)
bandwidth_row.addWidget(bandwidth_note)
bandwidth_row.addStretch() # Push to the left
resource_layout.addWidget(QLabel("Bandwidth Limit:", parent=self), resource_row_index+1, 0, 1, 1, Qt.AlignLeft)
resource_layout.addLayout(bandwidth_row, resource_row_index+1, 1)
else:
self.bandwidth_spin = None # No bandwidth UI if Downloads resource doesn't exist
main_layout.addWidget(resource_group) main_layout.addWidget(resource_group)
main_layout.addSpacing(12) main_layout.addSpacing(12)
@@ -328,12 +345,13 @@ class SettingsDialog(QDialog):
main_layout.addLayout(btn_layout) main_layout.addLayout(btn_layout)
# Set tab order for accessibility # Set tab order for accessibility
# Get the first resource's widgets # Get the first resource's widgets if any exist
first_resource_key = list(self.resource_edits.keys())[0] if self.resource_edits:
first_multithreading, first_max_tasks = self.resource_edits[first_resource_key] first_resource_key = list(self.resource_edits.keys())[0]
first_multithreading, first_max_tasks = self.resource_edits[first_resource_key]
# Set tab order starting with the first max tasks spinner # Set tab order starting with the first max tasks spinner
self.setTabOrder(first_max_tasks, self.bandwidth_spin) self.setTabOrder(first_max_tasks, self.bandwidth_spin)
# Continue with bandwidth spinner regardless of resources
self.setTabOrder(self.bandwidth_spin, self.debug_checkbox) self.setTabOrder(self.bandwidth_spin, self.debug_checkbox)
self.setTabOrder(self.debug_checkbox, self.api_key_edit) self.setTabOrder(self.debug_checkbox, self.api_key_edit)
self.setTabOrder(self.api_key_edit, self.api_show_btn) self.setTabOrder(self.api_key_edit, self.api_show_btn)
@@ -412,7 +430,7 @@ class SettingsDialog(QDialog):
if max_tasks_spin.value() > 128: if max_tasks_spin.value() > 128:
self.error_label.setText(f"Invalid value for {k}: Max Tasks must be <= 128.") self.error_label.setText(f"Invalid value for {k}: Max Tasks must be <= 128.")
return return
if self.bandwidth_spin.value() > 1000000: if self.bandwidth_spin and self.bandwidth_spin.value() > 1000000:
self.error_label.setText("Bandwidth limit must be <= 1,000,000 KB/s.") self.error_label.setText("Bandwidth limit must be <= 1,000,000 KB/s.")
return return
self.error_label.setText("") self.error_label.setText("")
@@ -428,12 +446,18 @@ class SettingsDialog(QDialog):
# Remove the setting if unchecked (don't add 'off') # Remove the setting if unchecked (don't add 'off')
resource_data.pop('_7zzMultiThread', None) resource_data.pop('_7zzMultiThread', None)
self.resource_settings[k] = resource_data self.resource_settings[k] = resource_data
# Save bandwidth limit to Downloads resource MaxThroughput (only if bandwidth UI exists)
if self.bandwidth_spin:
if "Downloads" not in self.resource_settings:
self.resource_settings["Downloads"] = {"MaxTasks": 16} # Provide default MaxTasks
self.resource_settings["Downloads"]["MaxThroughput"] = self.bandwidth_spin.value()
# Save all resource settings (including bandwidth) in one operation
self._save_json(self.resource_settings_path, self.resource_settings) self._save_json(self.resource_settings_path, self.resource_settings)
# Save debug mode to config # Save debug mode to config
self.config_handler.set('debug_mode', self.debug_checkbox.isChecked()) self.config_handler.set('debug_mode', self.debug_checkbox.isChecked())
# Save bandwidth limit
self.app_settings["MaxDownloadSpeedKBps"] = self.bandwidth_spin.value()
self._save_json(self.app_settings_path, self.app_settings)
# Save API key # Save API key
api_key = self.api_key_edit.text().strip() api_key = self.api_key_edit.text().strip()
self.config_handler.save_api_key(api_key) self.config_handler.save_api_key(api_key)

View File

@@ -745,19 +745,22 @@ class InstallModlistScreen(QWidget):
self.console.setMinimumHeight(50) # Keep minimum height for usability self.console.setMinimumHeight(50) # Keep minimum height for usability
def showEvent(self, event): def showEvent(self, event):
"""Called when the widget becomes visible - reload saved API key only""" """Called when the widget becomes visible - always reload saved API key"""
super().showEvent(event) super().showEvent(event)
# Reload saved API key if available and field is empty # Always reload saved API key to pick up changes from Settings dialog
if not self.api_key_edit.text().strip() or (self.api_key_is_obfuscated and not self.api_key_original_text.strip()): saved_key = self.api_key_service.get_saved_api_key()
saved_key = self.api_key_service.get_saved_api_key() if saved_key:
if saved_key: self.api_key_original_text = saved_key
self.api_key_original_text = saved_key self.api_key_edit.setText(saved_key)
self.api_key_edit.setText(saved_key) self.api_key_is_obfuscated = False # Start unobfuscated
self.api_key_is_obfuscated = False # Start unobfuscated # Set checkbox state
# Set checkbox state self.save_api_key_checkbox.setChecked(True)
self.save_api_key_checkbox.setChecked(True) # Immediately obfuscate saved keys (don't wait 3 seconds)
# Start obfuscation timer self._obfuscate_api_key()
self.api_key_obfuscation_timer.start(3000) elif not self.api_key_edit.text().strip():
# Only clear if no saved key and field is empty
self.api_key_original_text = ""
self.save_api_key_checkbox.setChecked(False)
# Do NOT load saved parent directories # Do NOT load saved parent directories
def _load_saved_parent_directories(self): def _load_saved_parent_directories(self):

View File

@@ -461,19 +461,22 @@ class TuxbornInstallerScreen(QWidget):
self.console.setMinimumHeight(50) # Keep minimum height for usability self.console.setMinimumHeight(50) # Keep minimum height for usability
def showEvent(self, event): def showEvent(self, event):
"""Called when the widget becomes visible - reload saved API key and parent directories""" """Called when the widget becomes visible - always reload saved API key and parent directories"""
super().showEvent(event) super().showEvent(event)
# Reload saved API key if available and field is empty # Always reload saved API key to pick up changes from Settings dialog
if not self.api_key_edit.text().strip() or (self.api_key_is_obfuscated and not self.api_key_original_text.strip()): saved_key = self.api_key_service.get_saved_api_key()
saved_key = self.api_key_service.get_saved_api_key() if saved_key:
if saved_key: self.api_key_original_text = saved_key
self.api_key_original_text = saved_key self.api_key_edit.setText(saved_key)
self.api_key_edit.setText(saved_key) self.api_key_is_obfuscated = False # Start unobfuscated
self.api_key_is_obfuscated = False # Start unobfuscated # Set checkbox state
# Set checkbox state self.save_api_key_checkbox.setChecked(True)
self.save_api_key_checkbox.setChecked(True) # Immediately obfuscate saved keys (don't wait 3 seconds)
# Start obfuscation timer self._obfuscate_api_key()
self.api_key_obfuscation_timer.start(3000) elif not self.api_key_edit.text().strip():
# Only clear if no saved key and field is empty
self.api_key_original_text = ""
self.save_api_key_checkbox.setChecked(False)
# Load saved parent directories and pre-populate fields # Load saved parent directories and pre-populate fields
self._load_saved_parent_directories() self._load_saved_parent_directories()