v0.0.31 - Clean public release

- Updated to v0.0.31 with GUI startup warning fix
- Updated jackify-engine for improved compatibility
- Removed development-only files from public repo
- Added LICENSE and CONTRIBUTING.md for professional release
- Professional public repository ready for alpha release
This commit is contained in:
Omni
2025-09-07 21:43:22 +01:00
parent cd591c14e3
commit af7685dd21
65 changed files with 1250 additions and 647 deletions

View File

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

View File

@@ -592,6 +592,7 @@ class ModlistInstallCLI:
"""
Run the configuration phase: execute the Linux-native Jackify Install Engine.
"""
import os
import subprocess
import time
import sys

View File

@@ -235,7 +235,7 @@ class ModlistHandler:
# 2. Get shortcuts pointing to the executable from shortcuts.vdf
matching_vdf_shortcuts = self.shortcut_handler.find_shortcuts_by_exe(executable_name)
if not matching_vdf_shortcuts:
self.logger.warning(f"No shortcuts found pointing to '{executable_name}' in shortcuts.vdf.")
self.logger.debug(f"No shortcuts found pointing to '{executable_name}' in shortcuts.vdf.")
return []
self.logger.debug(f"Shortcuts matching executable '{executable_name}' in VDF: {matching_vdf_shortcuts}")

View File

@@ -291,10 +291,50 @@ class PathHandler:
logger.error("Could not determine location for dxvk.conf")
return False
# Create simple dxvk.conf content - just one line
dxvk_conf_content = "dxvk.enableGraphicsPipelineLibrary = False\n"
# The required line that Jackify needs
required_line = "dxvk.enableGraphicsPipelineLibrary = False"
# Check if dxvk.conf already exists
if os.path.exists(dxvk_conf_path):
logger.info(f"Found existing dxvk.conf at {dxvk_conf_path}")
# Read existing content
try:
with open(dxvk_conf_path, 'r') as f:
existing_content = f.read().strip()
# Check if our required line is already present
existing_lines = existing_content.split('\n') if existing_content else []
has_required_line = any(line.strip() == required_line for line in existing_lines)
if has_required_line:
logger.info("Required DXVK setting already present in existing file")
return True
else:
# Append our required line to existing content
if existing_content:
# File has content, append our line
updated_content = existing_content + '\n' + required_line + '\n'
logger.info("Appending required DXVK setting to existing file")
else:
# File is empty, just add our line
updated_content = required_line + '\n'
logger.info("Adding required DXVK setting to empty file")
with open(dxvk_conf_path, 'w') as f:
f.write(updated_content)
logger.info(f"dxvk.conf updated successfully at {dxvk_conf_path}")
return True
except Exception as e:
logger.error(f"Error reading/updating existing dxvk.conf: {e}")
# Fall back to creating new file
logger.info("Falling back to creating new dxvk.conf file")
# Create new dxvk.conf file (original behavior)
dxvk_conf_content = required_line + '\n'
# Write dxvk.conf to the appropriate location
with open(dxvk_conf_path, 'w') as f:
f.write(dxvk_conf_content)

View File

@@ -1203,8 +1203,8 @@ class ShortcutHandler:
return []
if not matching_shortcuts:
# Changed log level to warning as this is an expected outcome sometimes
self.logger.warning(f"No shortcuts found pointing to '{executable_name}' in {vdf_path}.")
# Changed log level to debug as this is an expected outcome sometimes
self.logger.debug(f"No shortcuts found pointing to '{executable_name}' in {vdf_path}.")
return matching_shortcuts

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

Binary file not shown.

View File

@@ -8,7 +8,7 @@ import time
from jackify.shared.colors import (
COLOR_SELECTION, COLOR_RESET, COLOR_ACTION, COLOR_PROMPT, COLOR_INFO, COLOR_DISABLED
)
from jackify.shared.ui_utils import print_jackify_banner, print_section_header
from jackify.shared.ui_utils import print_jackify_banner, print_section_header, clear_screen
class AdditionalMenuHandler:
"""
@@ -20,9 +20,8 @@ class AdditionalMenuHandler:
self.logger = None # Will be set by CLI when needed
def _clear_screen(self):
"""Clear the terminal screen"""
import os
os.system('cls' if os.name == 'nt' else 'clear')
"""Clear the terminal screen with AppImage compatibility"""
clear_screen()
def show_additional_tasks_menu(self, cli_instance):
"""Show the MO2, NXM Handling & Recovery submenu"""

View File

@@ -9,7 +9,7 @@ from typing import Optional
from jackify.shared.colors import (
COLOR_SELECTION, COLOR_RESET, COLOR_ACTION, COLOR_PROMPT, COLOR_ERROR
)
from jackify.shared.ui_utils import print_jackify_banner
from jackify.shared.ui_utils import print_jackify_banner, clear_screen
class MainMenuHandler:
"""
@@ -22,9 +22,8 @@ class MainMenuHandler:
self.dev_mode = dev_mode
def _clear_screen(self):
"""Clear the terminal screen"""
import os
os.system('cls' if os.name == 'nt' else 'clear')
"""Clear the terminal screen with AppImage compatibility"""
clear_screen()
def show_main_menu(self, cli_instance) -> str:
"""
@@ -43,8 +42,8 @@ class MainMenuHandler:
print(f"{COLOR_SELECTION}{'-'*22}{COLOR_RESET}") # Standard separator
print(f"{COLOR_SELECTION}1.{COLOR_RESET} Modlist Tasks")
print(f" {COLOR_ACTION}→ Install & Configure Modlists{COLOR_RESET}")
print(f"{COLOR_SELECTION}2.{COLOR_RESET} Tuxborn Automatic Installer")
print(f" {COLOR_ACTION}Simple, fully automated Tuxborn installation{COLOR_RESET}")
print(f"{COLOR_SELECTION}2.{COLOR_RESET} Coming Soon...")
print(f" {COLOR_ACTION}More features coming in future releases{COLOR_RESET}")
if self.dev_mode:
print(f"{COLOR_SELECTION}3.{COLOR_RESET} Hoolamike Tasks")
print(f" {COLOR_ACTION}→ Wabbajack alternative: Install Modlists, TTW, etc{COLOR_RESET}")
@@ -61,7 +60,13 @@ class MainMenuHandler:
if choice == "1":
return "wabbajack"
elif choice == "2":
return "tuxborn" # Will be handled by TuxbornMenuHandler
# Additional features are coming in future releases
print(f"\n{COLOR_PROMPT}Coming Soon!{COLOR_RESET}")
print(f"More features will be added in future releases.")
print(f"Please use 'Modlist Tasks' for all current functionality.")
print(f"Press Enter to continue...")
input()
continue # Return to main menu
if self.dev_mode:
if choice == "3":
return "hoolamike"

View File

@@ -9,7 +9,7 @@ from pathlib import Path
from jackify.shared.colors import (
COLOR_SELECTION, COLOR_RESET, COLOR_PROMPT, COLOR_INFO, COLOR_ERROR
)
from jackify.shared.ui_utils import print_jackify_banner, print_section_header
from jackify.shared.ui_utils import print_jackify_banner, print_section_header, clear_screen
class RecoveryMenuHandler:
"""
@@ -21,9 +21,8 @@ class RecoveryMenuHandler:
self.logger = logging.getLogger(__name__)
def _clear_screen(self):
"""Clear the terminal screen"""
import os
os.system('cls' if os.name == 'nt' else 'clear')
"""Clear the terminal screen with AppImage compatibility"""
clear_screen()
def show_recovery_menu(self, cli_instance):
"""Show the recovery tools menu."""

View File

@@ -8,7 +8,7 @@ import time
from jackify.shared.colors import (
COLOR_SELECTION, COLOR_RESET, COLOR_ACTION, COLOR_PROMPT, COLOR_INFO
)
from jackify.shared.ui_utils import print_jackify_banner, print_section_header
from jackify.shared.ui_utils import print_jackify_banner, print_section_header, clear_screen
class WabbajackMenuHandler:
"""
@@ -20,9 +20,8 @@ class WabbajackMenuHandler:
self.logger = None # Will be set by CLI when needed
def _clear_screen(self):
"""Clear the terminal screen"""
import os
os.system('cls' if os.name == 'nt' else 'clear')
"""Clear the terminal screen with AppImage compatibility"""
clear_screen()
def show_wabbajack_tasks_menu(self, cli_instance):
"""Show the Modlist and Wabbajack Tasks menu"""

View File

@@ -603,41 +603,75 @@ class ConfigureNewModlistScreen(QWidget):
self._safe_append_text("")
self._safe_append_text("=== Steam Integration Phase ===")
self._safe_append_text("Starting automated Steam setup workflow...")
self._safe_append_text("This will automatically configure Steam integration without manual steps.")
# Start automated prefix workflow
self._start_automated_prefix_workflow(modlist_name, install_dir, mo2_exe_path, resolution)
def _start_automated_prefix_workflow(self, modlist_name, install_dir, mo2_exe_path, resolution):
"""Start the automated prefix workflow using AutomatedPrefixService"""
"""Start the automated prefix workflow using AutomatedPrefixService in a background thread"""
self._safe_append_text(f"Initializing automated Steam setup for '{modlist_name}'...")
self._safe_append_text("Starting automated Steam shortcut creation and configuration...")
# Disable the start button to prevent multiple workflows
self.start_btn.setEnabled(False)
# Create and start the automated prefix thread
class AutomatedPrefixThread(QThread):
progress_update = Signal(str)
workflow_complete = Signal(object) # Will emit the result tuple
error_occurred = Signal(str)
def __init__(self, modlist_name, install_dir, mo2_exe_path, steamdeck):
super().__init__()
self.modlist_name = modlist_name
self.install_dir = install_dir
self.mo2_exe_path = mo2_exe_path
self.steamdeck = steamdeck
def run(self):
try:
from jackify.backend.services.automated_prefix_service import AutomatedPrefixService
# Initialize the automated prefix service
prefix_service = AutomatedPrefixService()
# Define progress callback for GUI updates
def progress_callback(message):
self.progress_update.emit(message)
# Run the automated workflow (this contains the blocking operations)
result = prefix_service.run_working_workflow(
self.modlist_name, self.install_dir, self.mo2_exe_path,
progress_callback, steamdeck=self.steamdeck
)
# Emit the result
self.workflow_complete.emit(result)
except Exception as e:
self.error_occurred.emit(str(e))
# Detect Steam Deck once
try:
import os
_is_steamdeck = False
if os.path.exists('/etc/os-release'):
with open('/etc/os-release') as f:
if 'steamdeck' in f.read().lower():
_is_steamdeck = True
except Exception:
_is_steamdeck = False
# Create and start the thread
self.automated_prefix_thread = AutomatedPrefixThread(modlist_name, install_dir, mo2_exe_path, _is_steamdeck)
self.automated_prefix_thread.progress_update.connect(self._safe_append_text)
self.automated_prefix_thread.workflow_complete.connect(self._on_automated_prefix_complete)
self.automated_prefix_thread.error_occurred.connect(self._on_automated_prefix_error)
self.automated_prefix_thread.start()
def _on_automated_prefix_complete(self, result):
"""Handle completion of the automated prefix workflow"""
try:
from jackify.backend.services.automated_prefix_service import AutomatedPrefixService
self._safe_append_text(f"Initializing automated Steam setup for '{modlist_name}'...")
# Initialize the automated prefix service
prefix_service = AutomatedPrefixService()
# Define progress callback for GUI updates
def progress_callback(message):
self._safe_append_text(message)
# Run the automated workflow
self._safe_append_text("Starting automated Steam shortcut creation and configuration...")
# Detect Steam Deck once and pass through
try:
import os
_is_steamdeck = False
if os.path.exists('/etc/os-release'):
with open('/etc/os-release') as f:
if 'steamdeck' in f.read().lower():
_is_steamdeck = True
except Exception:
_is_steamdeck = False
result = prefix_service.run_working_workflow(
modlist_name, install_dir, mo2_exe_path, progress_callback, steamdeck=_is_steamdeck
)
# Handle the result - check for conflicts
if isinstance(result, tuple) and len(result) == 4:
if result[0] == "CONFLICT":
@@ -653,7 +687,9 @@ class ConfigureNewModlistScreen(QWidget):
self._safe_append_text(f"New AppID assigned: {new_appid}")
# Continue with post-Steam configuration, passing the last timestamp
self.continue_configuration_after_automated_prefix(new_appid, modlist_name, install_dir, last_timestamp)
self.continue_configuration_after_automated_prefix(new_appid, self.modlist_name_edit.text().strip(),
os.path.dirname(self.install_dir_edit.text().strip()) if self.install_dir_edit.text().strip().endswith('ModOrganizer.exe') else self.install_dir_edit.text().strip(),
last_timestamp)
else:
self._safe_append_text(f"Automated Steam setup failed")
self._safe_append_text("Please check the logs for details.")
@@ -666,7 +702,8 @@ class ConfigureNewModlistScreen(QWidget):
self._safe_append_text(f"New AppID assigned: {new_appid}")
# Continue with post-Steam configuration
self.continue_configuration_after_automated_prefix(new_appid, modlist_name, install_dir)
self.continue_configuration_after_automated_prefix(new_appid, self.modlist_name_edit.text().strip(),
os.path.dirname(self.install_dir_edit.text().strip()) if self.install_dir_edit.text().strip().endswith('ModOrganizer.exe') else self.install_dir_edit.text().strip())
else:
self._safe_append_text(f"Automated Steam setup failed")
self._safe_append_text("Please check the logs for details.")
@@ -678,9 +715,14 @@ class ConfigureNewModlistScreen(QWidget):
self.start_btn.setEnabled(True)
except Exception as e:
self._safe_append_text(f"Error during automated Steam setup: {str(e)}")
self._safe_append_text("Please check the logs for details.")
self._safe_append_text(f"Error handling automated prefix result: {str(e)}")
self.start_btn.setEnabled(True)
def _on_automated_prefix_error(self, error_message):
"""Handle error from the automated prefix workflow"""
self._safe_append_text(f"Error during automated Steam setup: {error_message}")
self._safe_append_text("Please check the logs for details.")
self.start_btn.setEnabled(True)
def show_shortcut_conflict_dialog(self, conflicts):
"""Show dialog to resolve shortcut name conflicts"""
@@ -1120,6 +1162,9 @@ class ConfigureNewModlistScreen(QWidget):
def on_configuration_complete(self, success, message, modlist_name):
"""Handle configuration completion (same as Tuxborn)"""
# Always re-enable the start button when workflow completes
self.start_btn.setEnabled(True)
if success:
# Calculate time taken
time_taken = self._calculate_time_taken()
@@ -1140,6 +1185,9 @@ class ConfigureNewModlistScreen(QWidget):
def on_configuration_error(self, error_message):
"""Handle configuration error"""
# Re-enable the start button on error
self.start_btn.setEnabled(True)
self._safe_append_text(f"Configuration error: {error_message}")
MessageService.critical(self, "Configuration Error", f"Configuration failed: {error_message}", safety_level="medium")
@@ -1208,7 +1256,19 @@ class ConfigureNewModlistScreen(QWidget):
def cleanup(self):
"""Clean up any running threads when the screen is closed"""
debug_print("DEBUG: cleanup called - cleaning up ConfigThread")
debug_print("DEBUG: cleanup called - cleaning up threads")
# Clean up automated prefix thread if running
if hasattr(self, 'automated_prefix_thread') and self.automated_prefix_thread and self.automated_prefix_thread.isRunning():
debug_print("DEBUG: Terminating AutomatedPrefixThread")
try:
self.automated_prefix_thread.progress_update.disconnect()
self.automated_prefix_thread.workflow_complete.disconnect()
self.automated_prefix_thread.error_occurred.disconnect()
except:
pass
self.automated_prefix_thread.terminate()
self.automated_prefix_thread.wait(2000) # Wait up to 2 seconds
# Clean up config thread if running
if hasattr(self, 'config_thread') and self.config_thread and self.config_thread.isRunning():

View File

@@ -1098,7 +1098,6 @@ class TuxbornInstallerScreen(QWidget):
# Use automated prefix service instead of manual steps
self._safe_append_text("Starting automated Steam setup workflow...")
self._safe_append_text("This will automatically configure Steam integration without manual steps.")
# Start automated prefix workflow
modlist_name = self.modlist_name_edit.text().strip()
@@ -1110,24 +1109,56 @@ class TuxbornInstallerScreen(QWidget):
MessageService.critical(self, "Steam Restart Failed", "Failed to restart Steam automatically. Please restart Steam manually, then try again.", safety_level="medium")
def _start_automated_prefix_workflow(self, modlist_name, install_dir, mo2_exe_path):
"""Start the automated prefix workflow using AutomatedPrefixService"""
"""Start the automated prefix workflow using AutomatedPrefixService in a background thread"""
self._safe_append_text(f"Initializing automated Steam setup for '{modlist_name}'...")
self._safe_append_text("Starting automated Steam shortcut creation and configuration...")
# Create and start the automated prefix thread
class AutomatedPrefixThread(QThread):
progress_update = Signal(str)
workflow_complete = Signal(object) # Will emit the result tuple
error_occurred = Signal(str)
def __init__(self, modlist_name, install_dir, mo2_exe_path):
super().__init__()
self.modlist_name = modlist_name
self.install_dir = install_dir
self.mo2_exe_path = mo2_exe_path
def run(self):
try:
from jackify.backend.services.automated_prefix_service import AutomatedPrefixService
# Initialize the automated prefix service
prefix_service = AutomatedPrefixService()
# Define progress callback for GUI updates
def progress_callback(message):
self.progress_update.emit(message)
# Run the automated workflow (this contains the blocking operations)
result = prefix_service.run_working_workflow(
self.modlist_name, self.install_dir, self.mo2_exe_path, progress_callback
)
# Emit the result
self.workflow_complete.emit(result)
except Exception as e:
self.error_occurred.emit(str(e))
# Create and start the thread
self.automated_prefix_thread = AutomatedPrefixThread(modlist_name, install_dir, mo2_exe_path)
self.automated_prefix_thread.progress_update.connect(self._safe_append_text)
self.automated_prefix_thread.workflow_complete.connect(self._on_automated_prefix_complete)
self.automated_prefix_thread.error_occurred.connect(self._on_automated_prefix_error)
self.automated_prefix_thread.start()
def _on_automated_prefix_complete(self, result):
"""Handle completion of the automated prefix workflow"""
try:
from jackify.backend.services.automated_prefix_service import AutomatedPrefixService
self._safe_append_text(f"Initializing automated Steam setup for '{modlist_name}'...")
# Initialize the automated prefix service
prefix_service = AutomatedPrefixService()
# Define progress callback for GUI updates
def progress_callback(message):
self._safe_append_text(f"{message}")
# Run the automated workflow
self._safe_append_text("Starting automated Steam shortcut creation and configuration...")
result = prefix_service.run_working_workflow(
modlist_name, install_dir, mo2_exe_path, progress_callback
)
modlist_name = self.modlist_name_edit.text().strip()
install_dir = self.install_dir_edit.text().strip()
# Handle the result - check for conflicts
if isinstance(result, tuple) and len(result) == 4:
@@ -1175,11 +1206,18 @@ class TuxbornInstallerScreen(QWidget):
self.cancel_install_btn.setVisible(False)
except Exception as e:
self._safe_append_text(f"Error during automated Steam setup: {str(e)}")
self._safe_append_text("Please check the logs for details.")
self._safe_append_text(f"Error handling automated prefix result: {str(e)}")
self.start_btn.setEnabled(True)
self.cancel_btn.setVisible(True)
self.cancel_install_btn.setVisible(False)
def _on_automated_prefix_error(self, error_message):
"""Handle error from the automated prefix workflow"""
self._safe_append_text(f"Error during automated Steam setup: {error_message}")
self._safe_append_text("Please check the logs for details.")
self.start_btn.setEnabled(True)
self.cancel_btn.setVisible(True)
self.cancel_install_btn.setVisible(False)
def show_shortcut_conflict_dialog(self, conflicts):
"""Show dialog to resolve shortcut name conflicts"""
@@ -1649,6 +1687,11 @@ class TuxbornInstallerScreen(QWidget):
def on_configuration_complete(self, success, message, modlist_name):
"""Handle configuration completion on main thread"""
# Always re-enable the start button when workflow completes
self.start_btn.setEnabled(True)
self.cancel_btn.setVisible(True)
self.cancel_install_btn.setVisible(False)
if success:
# Calculate time taken
time_taken = self._calculate_time_taken()
@@ -1689,6 +1732,11 @@ class TuxbornInstallerScreen(QWidget):
def on_configuration_error(self, error_message):
"""Handle configuration error on main thread"""
# Re-enable the start button on error
self.start_btn.setEnabled(True)
self.cancel_btn.setVisible(True)
self.cancel_install_btn.setVisible(False)
self._safe_append_text(f"Configuration failed with error: {error_message}")
MessageService.critical(self, "Configuration Error", f"Configuration failed: {error_message}", safety_level="medium")
@@ -1755,7 +1803,19 @@ class TuxbornInstallerScreen(QWidget):
def cleanup_processes(self):
"""Clean up any running processes when the window closes or is cancelled"""
debug_print("DEBUG: cleanup_processes called - cleaning up InstallationThread and other processes")
debug_print("DEBUG: cleanup_processes called - cleaning up all threads")
# Clean up automated prefix thread if running
if hasattr(self, 'automated_prefix_thread') and self.automated_prefix_thread and self.automated_prefix_thread.isRunning():
debug_print("DEBUG: Terminating AutomatedPrefixThread")
try:
self.automated_prefix_thread.progress_update.disconnect()
self.automated_prefix_thread.workflow_complete.disconnect()
self.automated_prefix_thread.error_occurred.disconnect()
except:
pass
self.automated_prefix_thread.terminate()
self.automated_prefix_thread.wait(2000) # Wait up to 2 seconds
# Clean up InstallationThread if running
if hasattr(self, 'install_thread') and self.install_thread.isRunning():

View File

@@ -3,6 +3,52 @@ UI Utilities for Jackify
Shared UI components and utilities used across frontend interfaces
"""
import os
import sys
def clear_screen():
"""
Clear the terminal screen with AppImage compatibility.
This function provides robust screen clearing that works in various environments
including AppImage containers where standard terminal utilities might not work properly.
"""
try:
# Method 1: Try standard os.system approach first
if os.name == 'nt':
# Windows
result = os.system('cls')
else:
# Unix/Linux - try clear command
result = os.system('clear')
# If os.system failed (non-zero return), try fallback methods
if result != 0:
_clear_screen_fallback()
except Exception:
# If os.system completely fails, use fallback
_clear_screen_fallback()
def _clear_screen_fallback():
"""
Fallback screen clearing methods for environments where os.system doesn't work.
This is particularly useful in AppImage environments.
"""
try:
# Method 2: ANSI escape sequences (works in most terminals)
# \033[H moves cursor to home position (0,0)
# \033[2J clears entire screen
# \033[3J clears scroll buffer (optional, not all terminals support)
print('\033[H\033[2J\033[3J', end='', flush=True)
except Exception:
try:
# Method 3: Alternative ANSI sequence
print('\033c', end='', flush=True) # Full terminal reset
except Exception:
# Method 4: Last resort - print enough newlines to "clear" screen
print('\n' * 50)
def print_jackify_banner():
"""Print the Jackify application banner"""
print("""