From 6cbfdbe52c254bd94237c2b25412223873568929 Mon Sep 17 00:00:00 2001 From: jp64k <122999544+jp64k@users.noreply.github.com> Date: Mon, 15 Dec 2025 00:07:54 +0100 Subject: [PATCH] Refactored file download logic to use DNS fallback for 7-zip and WebView2 downloads, fixed crash craused by corrupted user.config preventing startup Refactored all file download logic to use DNS fallback and applied it to 7-zip and WebView2 runtime downloads. Moved WebView2 runtime download logic to GetDependencies and ensures it is downloaded at startup if missing. Added robust handling for corrupted user.config files in Program.cs, including auto-repair and fallback guidance. --- MainForm.cs | 40 +++---------------- Program.cs | 70 +++++++++++++++++++++++++++++++-- Sideloader/GetDependencies.cs | 73 ++++++++++++++++++++++++++++------- Utilities/Zip.cs | 7 ++-- 4 files changed, 135 insertions(+), 55 deletions(-) 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); } - } } }