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.
This commit is contained in:
40
MainForm.cs
40
MainForm.cs
@@ -4654,6 +4654,7 @@ CTRL + F4 - Instantly relaunch Rookie Sideloader");
|
|||||||
if (webView21.CoreWebView2 != null) return;
|
if (webView21.CoreWebView2 != null) return;
|
||||||
|
|
||||||
// Check if WebView2 runtime DLLs are present
|
// Check if WebView2 runtime DLLs are present
|
||||||
|
// (downloadFiles() should have already downloaded them, but check anyway)
|
||||||
string runtimesPath = Path.Combine(Environment.CurrentDirectory, "runtimes");
|
string runtimesPath = Path.Combine(Environment.CurrentDirectory, "runtimes");
|
||||||
string webView2LoaderArm64 = Path.Combine(runtimesPath, "win-arm64", "native", "WebView2Loader.dll");
|
string webView2LoaderArm64 = Path.Combine(runtimesPath, "win-arm64", "native", "WebView2Loader.dll");
|
||||||
string webView2LoaderX86 = Path.Combine(runtimesPath, "win-x86", "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)
|
if (!runtimeExists)
|
||||||
{
|
{
|
||||||
try
|
// Runtime wasn't downloaded during startup - disable trailers
|
||||||
{
|
Logger.Log("WebView2 runtime not found, disabling trailer playback", LogLevel.WARNING);
|
||||||
changeTitle("Downloading Runtime...");
|
enviromentCreated = true;
|
||||||
string archivePath = Path.Combine(Environment.CurrentDirectory, "runtimes.7z");
|
webView21.Hide();
|
||||||
|
return;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -4713,14 +4693,6 @@ CTRL + F4 - Instantly relaunch Rookie Sideloader");
|
|||||||
}
|
}
|
||||||
catch (Exception /* ex */)
|
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;
|
enviromentCreated = true;
|
||||||
webView21.Hide();
|
webView21.Hide();
|
||||||
}
|
}
|
||||||
|
|||||||
70
Program.cs
70
Program.cs
@@ -8,7 +8,7 @@ namespace AndroidSideloader
|
|||||||
{
|
{
|
||||||
internal static class Program
|
internal static class Program
|
||||||
{
|
{
|
||||||
private static readonly SettingsManager settings = SettingsManager.Instance;
|
private static SettingsManager settings;
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The main entry point for the application.
|
/// The main entry point for the application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -16,7 +16,54 @@ namespace AndroidSideloader
|
|||||||
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
|
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.ControlAppDomain)]
|
||||||
private static void Main()
|
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;
|
AppDomain currentDomain = AppDomain.CurrentDomain;
|
||||||
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(CrashHandler);
|
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(CrashHandler);
|
||||||
Application.EnableVisualStyles();
|
Application.EnableVisualStyles();
|
||||||
@@ -25,6 +72,23 @@ namespace AndroidSideloader
|
|||||||
Application.Run(form);
|
Application.Run(form);
|
||||||
//form.Show();
|
//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;
|
public static MainForm form;
|
||||||
|
|
||||||
private static void CrashHandler(object sender, UnhandledExceptionEventArgs args)
|
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)");
|
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");
|
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 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}"));
|
File.AppendAllText(Sideloader.CrashLogPath, File.ReadAllText($"{settings.CurrentLogPath}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,7 @@ namespace AndroidSideloader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Download required dependencies.
|
// Download required dependencies
|
||||||
public static void downloadFiles()
|
public static void downloadFiles()
|
||||||
{
|
{
|
||||||
// Initialize DNS helper early to detect and configure fallback if needed
|
// 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");
|
_ = 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();
|
Application.Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Download WebView2 runtime if needed
|
||||||
|
downloadWebView2Runtime();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Downloads a file with DNS fallback support
|
// Downloads a file using the DNS fallback proxy if active
|
||||||
private static void DownloadFileWithDnsFallback(WebClient client, string url, string localPath)
|
public static void DownloadFileWithDnsFallback(WebClient client, string url, string localPath)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Use DNS fallback proxy if active
|
||||||
|
if (DnsHelper.UseFallbackDns && !string.IsNullOrEmpty(DnsHelper.ProxyUrl))
|
||||||
|
{
|
||||||
|
client.Proxy = new WebProxy(DnsHelper.ProxyUrl);
|
||||||
|
}
|
||||||
|
|
||||||
client.DownloadFile(url, localPath);
|
client.DownloadFile(url, localPath);
|
||||||
}
|
}
|
||||||
catch when (DnsHelper.UseFallbackDns)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Try with fallback DNS
|
_ = Logger.Log($"Download failed for {url}: {ex.Message}", LogLevel.ERROR);
|
||||||
var uri = new Uri(url);
|
throw;
|
||||||
var ip = DnsHelper.ResolveHostname(uri.Host);
|
}
|
||||||
if (ip != null)
|
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() };
|
_ = Logger.Log("Missing WebView2 runtime. Attempting to download...");
|
||||||
client.Headers["Host"] = uri.Host;
|
string archivePath = Path.Combine(Environment.CurrentDirectory, "runtimes.7z");
|
||||||
client.DownloadFile(builder.Uri, localPath);
|
|
||||||
client.Headers.Remove("Host");
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,12 +38,12 @@ namespace AndroidSideloader.Utilities
|
|||||||
if (!File.Exists(Path.Combine(Environment.CurrentDirectory, "7z.exe")) || !File.Exists(Path.Combine(Environment.CurrentDirectory, "7z.dll")))
|
if (!File.Exists(Path.Combine(Environment.CurrentDirectory, "7z.exe")) || !File.Exists(Path.Combine(Environment.CurrentDirectory, "7z.dll")))
|
||||||
{
|
{
|
||||||
_ = Logger.Log("Begin download 7-zip");
|
_ = Logger.Log("Begin download 7-zip");
|
||||||
WebClient client = new WebClient();
|
|
||||||
string architecture = Environment.Is64BitOperatingSystem ? "64" : "";
|
string architecture = Environment.Is64BitOperatingSystem ? "64" : "";
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
client.DownloadFile($"https://github.com/VRPirates/rookie/raw/master/7z{architecture}.exe", $"7z.exe");
|
// Use DNS fallback download method from GetDependencies
|
||||||
client.DownloadFile($"https://github.com/VRPirates/rookie/raw/master/7z{architecture}.dll", $"7z.dll");
|
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)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -127,7 +127,6 @@ namespace AndroidSideloader.Utilities
|
|||||||
extractionError = null; // Reset the error message
|
extractionError = null; // Reset the error message
|
||||||
throw new ExtractionException(errorMessage);
|
throw new ExtractionException(errorMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user