@@ -5,8 +5,8 @@ use indicatif::{ProgressBar, ProgressStyle}; |
| 5 | 5 | use std::path::PathBuf; |
| 6 | 6 | use wanda_core::{ |
| 7 | 7 | config::WandaConfig, |
| 8 | | - prefix::PrefixManager, |
| 9 | | - steam::{ProtonManager, SteamInstallation}, |
| 8 | + prefix::{PrefixBuilder, PrefixManager}, |
| 9 | + steam::{ProtonCompatibility, ProtonManager, SteamInstallation}, |
| 10 | 10 | wemod::{WemodDownloader, WemodInstaller}, |
| 11 | 11 | Result, WandaError, |
| 12 | 12 | }; |
@@ -25,6 +25,10 @@ pub struct InitArgs { |
| 25 | 25 | #[arg(long)] |
| 26 | 26 | skip_wemod: bool, |
| 27 | 27 | |
| 28 | + /// Skip .NET Framework installation (WeMod needs it for trainers) |
| 29 | + #[arg(long)] |
| 30 | + skip_dotnet: bool, |
| 31 | + |
| 28 | 32 | /// Force reinitialization even if already set up |
| 29 | 33 | #[arg(long, short)] |
| 30 | 34 | force: bool, |
@@ -66,19 +70,44 @@ pub async fn run(args: InitArgs, config_path: Option<PathBuf>) -> Result<()> { |
| 66 | 70 | } |
| 67 | 71 | |
| 68 | 72 | // Select Proton version |
| 73 | + // Priority: 1) --proton arg, 2) config preferred_version, 3) get_recommended() |
| 74 | + // Experimental/Unsupported versions from config are auto-overridden unless --proton is explicit |
| 69 | 75 | let proton = if let Some(ref name) = args.proton { |
| 70 | | - proton_manager.find_by_name(name).ok_or_else(|| { |
| 76 | + let v = proton_manager.find_by_name(name).ok_or_else(|| { |
| 71 | 77 | eprintln!("Available Proton versions:"); |
| 72 | 78 | for v in &proton_manager.versions { |
| 73 | | - eprintln!(" - {}", v.name); |
| 79 | + eprintln!(" - {} ({})", v.name, v.compatibility); |
| 74 | 80 | } |
| 75 | 81 | WandaError::ProtonNotFound |
| 76 | | - })? |
| 82 | + })?; |
| 83 | + if matches!(v.compatibility, ProtonCompatibility::Experimental | ProtonCompatibility::Unsupported) { |
| 84 | + eprintln!( |
| 85 | + " Warning: '{}' is {} — this may cause WeMod to fail", |
| 86 | + v.name, v.compatibility |
| 87 | + ); |
| 88 | + } |
| 89 | + v |
| 90 | + } else if let Some(ref preferred) = config.proton.preferred_version { |
| 91 | + match proton_manager.find_by_name(preferred) { |
| 92 | + Some(v) if matches!(v.compatibility, ProtonCompatibility::Experimental | ProtonCompatibility::Unsupported) => { |
| 93 | + let recommended = proton_manager.get_recommended().ok_or(WandaError::ProtonNotFound)?; |
| 94 | + eprintln!( |
| 95 | + " Configured Proton '{}' is {} — auto-switching to '{}' ({})", |
| 96 | + v.name, v.compatibility, recommended.name, recommended.compatibility |
| 97 | + ); |
| 98 | + recommended |
| 99 | + } |
| 100 | + Some(v) => v, |
| 101 | + None => { |
| 102 | + eprintln!(" Configured Proton '{}' not found, using recommended", preferred); |
| 103 | + proton_manager.get_recommended().ok_or(WandaError::ProtonNotFound)? |
| 104 | + } |
| 105 | + } |
| 77 | 106 | } else { |
| 78 | 107 | proton_manager.get_recommended().ok_or(WandaError::ProtonNotFound)? |
| 79 | 108 | }; |
| 80 | 109 | |
| 81 | | - println!(" Using: {} ({:?})", proton.name, proton.compatibility); |
| 110 | + println!(" Using: {} ({})", proton.name, proton.compatibility); |
| 82 | 111 | |
| 83 | 112 | // Set up prefix |
| 84 | 113 | println!("\nSetting up Wine prefix..."); |
@@ -109,6 +138,36 @@ pub async fn run(args: InitArgs, config_path: Option<PathBuf>) -> Result<()> { |
| 109 | 138 | pb.finish_with_message("Prefix created successfully"); |
| 110 | 139 | } |
| 111 | 140 | |
| 141 | + // Install .NET Framework 4.8 (required by WeMod's trainer engine) |
| 142 | + if !args.skip_dotnet { |
| 143 | + println!("\nInstalling .NET Framework 4.8..."); |
| 144 | + println!(" This may take 10-15 minutes. Use --skip-dotnet to skip."); |
| 145 | + |
| 146 | + let prefix_path = prefix_manager.base_path.join("default"); |
| 147 | + let dotnet_builder = PrefixBuilder::new(&prefix_path, proton); |
| 148 | + |
| 149 | + let pb = ProgressBar::new_spinner(); |
| 150 | + pb.set_style( |
| 151 | + ProgressStyle::default_spinner() |
| 152 | + .template("{spinner:.green} {msg}") |
| 153 | + .unwrap(), |
| 154 | + ); |
| 155 | + pb.set_message("Installing .NET Framework 4.8 via winetricks..."); |
| 156 | + pb.enable_steady_tick(std::time::Duration::from_millis(100)); |
| 157 | + |
| 158 | + match dotnet_builder.install_dotnet().await { |
| 159 | + Ok(_) => { |
| 160 | + pb.finish_with_message(".NET Framework installed successfully"); |
| 161 | + } |
| 162 | + Err(e) => { |
| 163 | + pb.finish_with_message(".NET Framework installation failed"); |
| 164 | + eprintln!(" Warning: .NET install failed: {}", e); |
| 165 | + eprintln!(" WeMod may show a '.NET framework' error on startup."); |
| 166 | + eprintln!(" You can retry manually: winetricks -q dotnet48"); |
| 167 | + } |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 112 | 171 | // Reload prefix after creation |
| 113 | 172 | prefix_manager.load()?; |
| 114 | 173 | let prefix = prefix_manager.get("default").unwrap(); |