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.
333 lines
16 KiB
C#
333 lines
16 KiB
C#
using AndroidSideloader.Utilities;
|
|
using JR.Utils.GUI.Forms;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
|
|
namespace AndroidSideloader
|
|
{
|
|
internal class GetDependencies
|
|
{
|
|
public static void updatePublicConfig()
|
|
{
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls
|
|
| SecurityProtocolType.Tls11
|
|
| SecurityProtocolType.Tls12
|
|
| SecurityProtocolType.Ssl3;
|
|
|
|
_ = Logger.Log("Attempting to update public config from main.");
|
|
|
|
string configUrl = "https://raw.githubusercontent.com/vrpyou/quest/main/vrp-public.json";
|
|
string fallbackUrl = "https://vrpirates.wiki/downloads/vrp-public.json";
|
|
|
|
try
|
|
{
|
|
string resultString;
|
|
|
|
// Try fetching raw JSON data from the provided link
|
|
HttpWebRequest getUrl = DnsHelper.CreateWebRequest(configUrl);
|
|
using (StreamReader responseReader = new StreamReader(getUrl.GetResponse().GetResponseStream()))
|
|
{
|
|
resultString = responseReader.ReadToEnd();
|
|
_ = Logger.Log($"Retrieved updated config from main: {configUrl}.");
|
|
File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "vrp-public.json"), resultString);
|
|
_ = Logger.Log("Public config updated successfully from main.");
|
|
}
|
|
}
|
|
catch (Exception mainException)
|
|
{
|
|
_ = Logger.Log($"Failed to update public config from main: {mainException.Message}, trying fallback.", LogLevel.ERROR);
|
|
try
|
|
{
|
|
HttpWebRequest getUrl = DnsHelper.CreateWebRequest(fallbackUrl);
|
|
using (StreamReader responseReader = new StreamReader(getUrl.GetResponse().GetResponseStream()))
|
|
{
|
|
string resultString = responseReader.ReadToEnd();
|
|
_ = Logger.Log($"Retrieved updated config from fallback: {fallbackUrl}.");
|
|
File.WriteAllText(Path.Combine(Environment.CurrentDirectory, "vrp-public.json"), resultString);
|
|
_ = Logger.Log("Public config updated successfully from fallback.");
|
|
}
|
|
}
|
|
catch (Exception fallbackException)
|
|
{
|
|
_ = Logger.Log($"Failed to update public config from fallback: {fallbackException.Message}.", LogLevel.ERROR);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Download required dependencies
|
|
public static void downloadFiles()
|
|
{
|
|
// Initialize DNS helper early to detect and configure fallback if needed
|
|
DnsHelper.Initialize();
|
|
|
|
WebClient client = new WebClient();
|
|
ServicePointManager.Expect100Continue = true;
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
|
var currentAccessedWebsite = "";
|
|
try
|
|
{
|
|
if (!File.Exists("Sideloader Launcher.exe"))
|
|
{
|
|
currentAccessedWebsite = "github";
|
|
_ = Logger.Log($"Missing 'Sideloader Launcher.exe'. Attempting to download from {currentAccessedWebsite}");
|
|
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/Sideloader%20Launcher.exe", "Sideloader Launcher.exe");
|
|
_ = Logger.Log($"'Sideloader Launcher.exe' download successful");
|
|
}
|
|
|
|
if (!File.Exists("Rookie Offline.cmd"))
|
|
{
|
|
currentAccessedWebsite = "github";
|
|
_ = Logger.Log($"Missing 'Rookie Offline.cmd'. Attempting to download from {currentAccessedWebsite}");
|
|
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/Rookie%20Offline.cmd", "Rookie Offline.cmd");
|
|
_ = Logger.Log($"'Rookie Offline.cmd' download successful");
|
|
}
|
|
|
|
if (!File.Exists("CleanupInstall.cmd"))
|
|
{
|
|
currentAccessedWebsite = "github";
|
|
_ = Logger.Log($"Missing 'CleanupInstall.cmd'. Attempting to download from {currentAccessedWebsite}");
|
|
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/CleanupInstall.cmd", "CleanupInstall.cmd");
|
|
_ = Logger.Log($"'CleanupInstall.cmd' download successful");
|
|
}
|
|
|
|
if (!File.Exists("AddDefenderExceptions.ps1"))
|
|
{
|
|
currentAccessedWebsite = "github";
|
|
_ = Logger.Log($"Missing 'AddDefenderExceptions.ps1'. Attempting to download from {currentAccessedWebsite}");
|
|
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/AddDefenderExceptions.ps1", "AddDefenderExceptions.ps1");
|
|
_ = Logger.Log($"'AddDefenderExceptions.ps1' download successful");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_ = FlexibleMessageBox.Show(Program.form, $"You are unable to access raw.githubusercontent.com with the Exception:\n{ex.Message}\n\nSome files may be missing (Offline/Cleanup Script, Launcher)");
|
|
}
|
|
|
|
string adbPath = Path.Combine(Environment.CurrentDirectory, "platform-tools", "adb.exe");
|
|
string platformToolsDir = Path.Combine(Environment.CurrentDirectory, "platform-tools");
|
|
|
|
try
|
|
{
|
|
if (!File.Exists(adbPath)) //if adb is not updated, download and auto extract
|
|
{
|
|
if (!Directory.Exists(platformToolsDir))
|
|
{
|
|
_ = Directory.CreateDirectory(platformToolsDir);
|
|
}
|
|
|
|
currentAccessedWebsite = "github";
|
|
_ = Logger.Log($"Missing adb within {platformToolsDir}. Attempting to download from {currentAccessedWebsite}");
|
|
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/dependencies.7z", "dependencies.7z");
|
|
Utilities.Zip.ExtractFile(Path.Combine(Environment.CurrentDirectory, "dependencies.7z"), platformToolsDir);
|
|
File.Delete("dependencies.7z");
|
|
_ = Logger.Log($"adb download successful");
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_ = FlexibleMessageBox.Show(Program.form, $"You are unable to access raw.githubusercontent.com page with the Exception:\n{ex.Message}\n\nSome files may be missing (ADB)");
|
|
_ = FlexibleMessageBox.Show(Program.form, "ADB was unable to be downloaded\nRookie will now close.");
|
|
Application.Exit();
|
|
}
|
|
|
|
string wantedRcloneVersion = "1.68.2";
|
|
bool rcloneSuccess = false;
|
|
|
|
rcloneSuccess = downloadRclone(wantedRcloneVersion, false);
|
|
if (!rcloneSuccess)
|
|
{
|
|
rcloneSuccess = downloadRclone(wantedRcloneVersion, true);
|
|
}
|
|
if (!rcloneSuccess)
|
|
{
|
|
_ = Logger.Log($"Unable to download rclone", LogLevel.ERROR);
|
|
_ = 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 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 (Exception ex)
|
|
{
|
|
_ = 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
|
|
{
|
|
_ = 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");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_ = Logger.Log($"Failed to download WebView2 runtime: {ex.Message}", LogLevel.ERROR);
|
|
// Don't show message box here - let CreateEnvironment handle the UI feedback
|
|
}
|
|
}
|
|
}
|
|
|
|
public static bool downloadRclone(string wantedRcloneVersion, bool useFallback = false)
|
|
{
|
|
try
|
|
{
|
|
bool updateRclone = false;
|
|
string currentRcloneVersion = "0.0.0";
|
|
|
|
WebClient client = new WebClient();
|
|
ServicePointManager.Expect100Continue = true;
|
|
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
|
|
|
|
_ = Logger.Log($"Checking for Local rclone...");
|
|
string dirRclone = Path.Combine(Environment.CurrentDirectory, "rclone");
|
|
string pathToRclone = Path.Combine(dirRclone, "rclone.exe");
|
|
if (File.Exists(pathToRclone))
|
|
{
|
|
var versionInfo = FileVersionInfo.GetVersionInfo(pathToRclone);
|
|
currentRcloneVersion = versionInfo.ProductVersion;
|
|
Logger.Log($"Current RCLONE Version {currentRcloneVersion}");
|
|
if (!MainForm.noRcloneUpdating)
|
|
{
|
|
if (currentRcloneVersion != wantedRcloneVersion)
|
|
{
|
|
updateRclone = true;
|
|
_ = Logger.Log($"RCLONE Version does not match ({currentRcloneVersion})! Downloading required version ({wantedRcloneVersion})");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
updateRclone = true;
|
|
_ = Logger.Log($"RCLONE exe does not exist, attempting to download");
|
|
}
|
|
|
|
if (!Directory.Exists(dirRclone))
|
|
{
|
|
updateRclone = true;
|
|
_ = Logger.Log($"Missing RCLONE Folder, attempting to download");
|
|
|
|
Directory.CreateDirectory(dirRclone);
|
|
}
|
|
|
|
if (updateRclone == true)
|
|
{
|
|
// Preserve vrp.download.config if it exists
|
|
string configPath = Path.Combine(dirRclone, "vrp.download.config");
|
|
string tempConfigPath = Path.Combine(Environment.CurrentDirectory, "vrp.download.config.bak");
|
|
bool hasConfig = false;
|
|
|
|
if (File.Exists(configPath))
|
|
{
|
|
_ = Logger.Log("Preserving vrp.download.config before update");
|
|
File.Copy(configPath, tempConfigPath, true);
|
|
hasConfig = true;
|
|
}
|
|
|
|
string architecture = Environment.Is64BitOperatingSystem ? "amd64" : "386";
|
|
string url = $"https://downloads.rclone.org/v{wantedRcloneVersion}/rclone-v{wantedRcloneVersion}-windows-{architecture}.zip";
|
|
if (useFallback == true)
|
|
{
|
|
_ = Logger.Log($"Using git fallback for rclone download");
|
|
url = $"https://raw.githubusercontent.com/VRPirates/rookie/master/dep/rclone-v{wantedRcloneVersion}-windows-{architecture}.zip";
|
|
}
|
|
_ = Logger.Log($"Downloading rclone from {url}");
|
|
|
|
_ = Logger.Log("Begin download rclone");
|
|
DownloadFileWithDnsFallback(client, url, "rclone.zip");
|
|
_ = Logger.Log("Complete download rclone");
|
|
|
|
_ = Logger.Log($"Extract {Environment.CurrentDirectory}\\rclone.zip");
|
|
Utilities.Zip.ExtractFile(Path.Combine(Environment.CurrentDirectory, "rclone.zip"), Environment.CurrentDirectory);
|
|
string dirExtractedRclone = Path.Combine(Environment.CurrentDirectory, $"rclone-v{wantedRcloneVersion}-windows-{architecture}");
|
|
File.Delete("rclone.zip");
|
|
_ = Logger.Log("rclone extracted. Moving files");
|
|
|
|
foreach (string file in Directory.GetFiles(dirExtractedRclone))
|
|
{
|
|
string fileName = Path.GetFileName(file);
|
|
string destFile = Path.Combine(dirRclone, fileName);
|
|
if (File.Exists(destFile))
|
|
{
|
|
File.Delete(destFile);
|
|
}
|
|
File.Move(file, destFile);
|
|
}
|
|
Directory.Delete(dirExtractedRclone, true);
|
|
|
|
// Restore vrp.download.config if it was backed up
|
|
if (hasConfig && File.Exists(tempConfigPath))
|
|
{
|
|
_ = Logger.Log("Restoring vrp.download.config after update");
|
|
File.Move(tempConfigPath, configPath);
|
|
}
|
|
|
|
_ = Logger.Log($"rclone download successful");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_ = Logger.Log($"Unable to download rclone: {ex}", LogLevel.ERROR);
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
} |