diff --git a/MainForm.cs b/MainForm.cs index 045d91c..4fbb364 100755 --- a/MainForm.cs +++ b/MainForm.cs @@ -4654,6 +4654,7 @@ CTRL + F4 - Instantly relaunch Rookie Sideloader"); if (webView21.CoreWebView2 != null) return; // Check if WebView2 runtime DLLs are present + // (downloadFiles() should have already downloaded them, but check anyway) string runtimesPath = Path.Combine(Environment.CurrentDirectory, "runtimes"); string webView2LoaderArm64 = Path.Combine(runtimesPath, "win-arm64", "native", "WebView2Loader.dll"); string webView2LoaderX86 = Path.Combine(runtimesPath, "win-x86", "native", "WebView2Loader.dll"); @@ -4663,32 +4664,11 @@ CTRL + F4 - Instantly relaunch Rookie Sideloader"); if (!runtimeExists) { - try - { - changeTitle("Downloading Runtime..."); - string archivePath = Path.Combine(Environment.CurrentDirectory, "runtimes.7z"); - - using (var client = new WebClient()) - { - ServicePointManager.Expect100Continue = true; - ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; - await Task.Run(() => client.DownloadFile("https://vrpirates.wiki/downloads/runtimes.7z", archivePath)); - } - - changeTitle("Extracting Runtime..."); - await Task.Run(() => Utilities.Zip.ExtractFile(archivePath, Environment.CurrentDirectory)); - File.Delete(archivePath); - } - catch (Exception ex) - { - Logger.Log($"Failed to download WebView2 runtime: {ex.Message}", LogLevel.ERROR); - _ = FlexibleMessageBox.Show(Program.form, - $"Unable to download WebView2 runtime: {ex.Message}\n\nTrailer playback will be disabled.", - "WebView2 Download Failed"); - enviromentCreated = true; - webView21.Hide(); - return; - } + // Runtime wasn't downloaded during startup - disable trailers + Logger.Log("WebView2 runtime not found, disabling trailer playback", LogLevel.WARNING); + enviromentCreated = true; + webView21.Hide(); + return; } try @@ -4713,14 +4693,6 @@ CTRL + F4 - Instantly relaunch Rookie Sideloader"); } catch (Exception /* ex */) { - /* - Logger.Log($"Failed to initialize WebView2: {ex.Message}", LogLevel.ERROR); - _ = FlexibleMessageBox.Show(Program.form, - $"WebView2 Runtime is not installed on this system.\n\n" + - "Please download from: https://go.microsoft.com/fwlink/p/?LinkId=2124703\n\n" + - "Trailer playback will be disabled.", - "WebView2 Runtime Required"); - */ enviromentCreated = true; webView21.Hide(); } diff --git a/Program.cs b/Program.cs index 0dc1188..e20a759 100644 --- a/Program.cs +++ b/Program.cs @@ -8,7 +8,7 @@ namespace AndroidSideloader { internal static class Program { - private static readonly SettingsManager settings = SettingsManager.Instance; + private static SettingsManager settings; /// /// The main entry point for the application. /// @@ -16,7 +16,54 @@ namespace AndroidSideloader [SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)] private static void Main() { + // Handle corrupted user.config files + bool configFixed = false; + Exception configException = null; + try + { + // Force settings initialization to trigger any config errors early + var test = AndroidSideloader.Properties.Settings.Default.FontStyle; + } + catch (Exception ex) + { + configException = ex; + // Delete the corrupted config file and retry + try + { + string configPath = GetUserConfigPath(); + if (!string.IsNullOrEmpty(configPath) && File.Exists(configPath)) + { + File.Delete(configPath); + configFixed = true; + } + } + catch + { + // If we can't delete it, try to continue anyway + } + } + + if (configFixed) + { + // Restart the application after fixing config + Application.Restart(); + return; + } + + if (configException != null) + { + MessageBox.Show( + "Settings file is corrupted and could not be repaired automatically.\n\n" + + "Please delete this folder and restart the application:\n" + + Path.GetDirectoryName(GetUserConfigPath()), + "Configuration Error", + MessageBoxButtons.OK, + MessageBoxIcon.Error); + return; + } + + settings = SettingsManager.Instance; AppDomain currentDomain = AppDomain.CurrentDomain; currentDomain.UnhandledException += new UnhandledExceptionEventHandler(CrashHandler); Application.EnableVisualStyles(); @@ -25,6 +72,23 @@ namespace AndroidSideloader Application.Run(form); //form.Show(); } + + private static string GetUserConfigPath() + { + try + { + string appData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData); + string companyName = "Rookie.AndroidSideloader"; + string exeName = "AndroidSideloader.exe_Url_dkp0unsd4fjaabhwwafgfxvvbrerf10b"; + string version = "2.0.0.0"; + return Path.Combine(appData, companyName, exeName, version, "user.config"); + } + catch + { + return null; + } + } + public static MainForm form; private static void CrashHandler(object sender, UnhandledExceptionEventArgs args) @@ -37,10 +101,10 @@ namespace AndroidSideloader string date_time = DateTime.Now.ToString("dddd, MMMM dd @ hh:mmtt (UTC)"); File.WriteAllText(Sideloader.CrashLogPath, $"Date/Time of crash: {date_time}\nMessage: {e.Message}\nInner Message: {innerExceptionMessage}\nData: {e.Data}\nSource: {e.Source}\nTargetSite: {e.TargetSite}\nStack Trace: \n{e.StackTrace}\n\n\nDebuglog: \n\n\n"); // If a debuglog exists we append it to the crashlog. - if (File.Exists(settings.CurrentLogPath)) + if (settings != null && File.Exists(settings.CurrentLogPath)) { File.AppendAllText(Sideloader.CrashLogPath, File.ReadAllText($"{settings.CurrentLogPath}")); } } } -} +} \ No newline at end of file diff --git a/Sideloader/GetDependencies.cs b/Sideloader/GetDependencies.cs index c5e0c9e..46994a1 100644 --- a/Sideloader/GetDependencies.cs +++ b/Sideloader/GetDependencies.cs @@ -61,7 +61,7 @@ namespace AndroidSideloader } } - // Download required dependencies. + // Download required dependencies public static void downloadFiles() { // Initialize DNS helper early to detect and configure fallback if needed @@ -151,30 +151,75 @@ namespace AndroidSideloader _ = FlexibleMessageBox.Show(Program.form, "Rclone was unable to be downloaded\nRookie will now close, please use Offline Mode for manual sideloading if needed"); Application.Exit(); } + + // Download WebView2 runtime if needed + downloadWebView2Runtime(); } - // Downloads a file with DNS fallback support - private static void DownloadFileWithDnsFallback(WebClient client, string url, string localPath) + // Downloads a file using the DNS fallback proxy if active + public static void DownloadFileWithDnsFallback(WebClient client, string url, string localPath) { try { + // Use DNS fallback proxy if active + if (DnsHelper.UseFallbackDns && !string.IsNullOrEmpty(DnsHelper.ProxyUrl)) + { + client.Proxy = new WebProxy(DnsHelper.ProxyUrl); + } + client.DownloadFile(url, localPath); } - catch when (DnsHelper.UseFallbackDns) + catch (Exception ex) { - // Try with fallback DNS - var uri = new Uri(url); - var ip = DnsHelper.ResolveHostname(uri.Host); - if (ip != null) + _ = Logger.Log($"Download failed for {url}: {ex.Message}", LogLevel.ERROR); + throw; + } + finally + { + // Reset proxy to avoid affecting other operations + client.Proxy = null; + } + } + + // Overload that creates its own WebClient for convenience + public static void DownloadFileWithDnsFallback(string url, string localPath) + { + using (var client = new WebClient()) + { + ServicePointManager.Expect100Continue = true; + ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + DownloadFileWithDnsFallback(client, url, localPath); + } + } + + // Downloads WebView2 runtime if not present + private static void downloadWebView2Runtime() + { + string runtimesPath = Path.Combine(Environment.CurrentDirectory, "runtimes"); + string webView2LoaderArm64 = Path.Combine(runtimesPath, "win-arm64", "native", "WebView2Loader.dll"); + string webView2LoaderX86 = Path.Combine(runtimesPath, "win-x86", "native", "WebView2Loader.dll"); + string webView2LoaderX64 = Path.Combine(runtimesPath, "win-x64", "native", "WebView2Loader.dll"); + + bool runtimeExists = File.Exists(webView2LoaderX86) || File.Exists(webView2LoaderX64) || File.Exists(webView2LoaderArm64); + + if (!runtimeExists) + { + try { - var builder = new UriBuilder(uri) { Host = ip.ToString() }; - client.Headers["Host"] = uri.Host; - client.DownloadFile(builder.Uri, localPath); - client.Headers.Remove("Host"); + _ = Logger.Log("Missing WebView2 runtime. Attempting to download..."); + string archivePath = Path.Combine(Environment.CurrentDirectory, "runtimes.7z"); + + DownloadFileWithDnsFallback("https://vrpirates.wiki/downloads/runtimes.7z", archivePath); + + _ = Logger.Log("Extracting WebView2 runtime..."); + Utilities.Zip.ExtractFile(archivePath, Environment.CurrentDirectory); + File.Delete(archivePath); + _ = Logger.Log("WebView2 runtime download successful"); } - else + catch (Exception ex) { - throw; + _ = Logger.Log($"Failed to download WebView2 runtime: {ex.Message}", LogLevel.ERROR); + // Don't show message box here - let CreateEnvironment handle the UI feedback } } } diff --git a/Utilities/Zip.cs b/Utilities/Zip.cs index 338eef5..762c357 100644 --- a/Utilities/Zip.cs +++ b/Utilities/Zip.cs @@ -38,12 +38,12 @@ namespace AndroidSideloader.Utilities if (!File.Exists(Path.Combine(Environment.CurrentDirectory, "7z.exe")) || !File.Exists(Path.Combine(Environment.CurrentDirectory, "7z.dll"))) { _ = Logger.Log("Begin download 7-zip"); - WebClient client = new WebClient(); string architecture = Environment.Is64BitOperatingSystem ? "64" : ""; try { - client.DownloadFile($"https://github.com/VRPirates/rookie/raw/master/7z{architecture}.exe", $"7z.exe"); - client.DownloadFile($"https://github.com/VRPirates/rookie/raw/master/7z{architecture}.dll", $"7z.dll"); + // Use DNS fallback download method from GetDependencies + GetDependencies.DownloadFileWithDnsFallback($"https://github.com/VRPirates/rookie/raw/master/7z{architecture}.exe", "7z.exe"); + GetDependencies.DownloadFileWithDnsFallback($"https://github.com/VRPirates/rookie/raw/master/7z{architecture}.dll", "7z.dll"); } catch (Exception ex) { @@ -127,7 +127,6 @@ namespace AndroidSideloader.Utilities extractionError = null; // Reset the error message throw new ExtractionException(errorMessage); } - } } }