Compare commits
8 Commits
v3.0-beta
...
v3.0-beta2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c48043a178 | ||
|
|
15f0c1ee72 | ||
|
|
44df1666f4 | ||
|
|
6cbfdbe52c | ||
|
|
75d22ab504 | ||
|
|
0c20841db3 | ||
|
|
b33251d98b | ||
|
|
3ef0652a85 |
@@ -239,6 +239,7 @@
|
||||
<Compile Include="Sideloader\ProcessOutput.cs" />
|
||||
<Compile Include="Sideloader\RCLONE.cs" />
|
||||
<Compile Include="Sideloader\Utilities.cs" />
|
||||
<Compile Include="Utilities\DnsHelper.cs" />
|
||||
<Compile Include="Utilities\Logger.cs" />
|
||||
<Compile Include="QuestForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
||||
2
MainForm.Designer.cs
generated
2
MainForm.Designer.cs
generated
@@ -1266,6 +1266,7 @@ namespace AndroidSideloader
|
||||
this.rookieStatusLabel.Size = new System.Drawing.Size(225, 17);
|
||||
this.rookieStatusLabel.TabIndex = 0;
|
||||
this.rookieStatusLabel.Text = "Status";
|
||||
this.rookieStatusLabel.UseMnemonic = false;
|
||||
//
|
||||
// sidebarMediaPanel
|
||||
//
|
||||
@@ -1320,6 +1321,7 @@ namespace AndroidSideloader
|
||||
this.selectedGameLabel.Size = new System.Drawing.Size(217, 20);
|
||||
this.selectedGameLabel.TabIndex = 99;
|
||||
this.selectedGameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.selectedGameLabel.UseMnemonic = false;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
|
||||
81
MainForm.cs
81
MainForm.cs
@@ -2989,19 +2989,6 @@ Additional Thanks & Resources
|
||||
quotaTries++;
|
||||
remotesList.Invoke((MethodInvoker)delegate
|
||||
{
|
||||
if (quotaTries > remotesList.Items.Count)
|
||||
{
|
||||
ShowError_QuotaExceeded();
|
||||
|
||||
if (System.Windows.Forms.Application.MessageLoop)
|
||||
{
|
||||
// Process.GetCurrentProcess().Kill();
|
||||
isOffline = true;
|
||||
success = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (remotesList.SelectedIndex + 1 == remotesList.Items.Count)
|
||||
{
|
||||
reset = true;
|
||||
@@ -3026,20 +3013,35 @@ Additional Thanks & Resources
|
||||
success = false;
|
||||
}
|
||||
|
||||
// If we've tried all remotes and failed, show quota exceeded error
|
||||
if (quotaTries > remotesList.Items.Count)
|
||||
{
|
||||
ShowError_QuotaExceeded();
|
||||
|
||||
if (Application.MessageLoop)
|
||||
{
|
||||
isOffline = true;
|
||||
success = false;
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private static void ShowError_QuotaExceeded()
|
||||
{
|
||||
string errorMessage =
|
||||
$@"Unable to connect to Remote Server. Rookie is unable to connect to our Servers.
|
||||
$@"Rookie cannot reach our servers.
|
||||
|
||||
First time launching Rookie? Please relaunch and try again.
|
||||
If this is your first time launching Rookie, please relaunch and try again.
|
||||
|
||||
Please visit our Telegram (https://t.me/VRPirates) or Discord (https://discord.gg/tBKMZy7QDA) for Troubleshooting steps!
|
||||
";
|
||||
If the problem persists, visit our Telegram (https://t.me/VRPirates) or Discord (https://discord.gg/tBKMZy7QDA) for troubleshooting steps.";
|
||||
|
||||
_ = FlexibleMessageBox.Show(Program.form, errorMessage, "Unable to connect to Remote Server");
|
||||
FlexibleMessageBox.Show(Program.form, errorMessage, "Unable to connect to remote server");
|
||||
|
||||
// Close application after showing the message
|
||||
Application.Exit();
|
||||
}
|
||||
|
||||
public async void cleanupActiveDownloadStatus()
|
||||
@@ -3865,6 +3867,9 @@ Please visit our Telegram (https://t.me/VRPirates) or Discord (https://discord.g
|
||||
|
||||
private async void Form1_FormClosing(object sender, FormClosingEventArgs e)
|
||||
{
|
||||
// Cleanup DNS helper (stops proxy)
|
||||
DnsHelper.Cleanup();
|
||||
|
||||
if (isinstalling)
|
||||
{
|
||||
DialogResult res1 = FlexibleMessageBox.Show(Program.form, "There are downloads and/or installations in progress,\nif you exit now you'll have to start the entire process over again.\nAre you sure you want to exit?", "Still downloading/installing.",
|
||||
@@ -4649,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");
|
||||
@@ -4658,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
|
||||
@@ -4708,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();
|
||||
}
|
||||
|
||||
70
Program.cs
70
Program.cs
@@ -8,7 +8,7 @@ namespace AndroidSideloader
|
||||
{
|
||||
internal static class Program
|
||||
{
|
||||
private static readonly SettingsManager settings = SettingsManager.Instance;
|
||||
private static SettingsManager settings;
|
||||
/// <summary>
|
||||
/// The main entry point for the application.
|
||||
/// </summary>
|
||||
@@ -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}"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
RCLONE.cs
38
RCLONE.cs
@@ -357,27 +357,35 @@ namespace AndroidSideloader
|
||||
|
||||
private static void setRcloneProxy()
|
||||
{
|
||||
// Use the user's proxy settings if set, otherwise fallback to DNS fallback proxy if active
|
||||
string proxyUrl = DnsHelper.ProxyUrl;
|
||||
|
||||
if (settings.useProxy)
|
||||
{
|
||||
if (!rclone.StartInfo.EnvironmentVariables.ContainsKey("HTTP_PROXY")) {
|
||||
rclone.StartInfo.EnvironmentVariables.Add("HTTP_PROXY", $"http://{settings.ProxyAddress}:{settings.ProxyPort}");
|
||||
}
|
||||
if (!rclone.StartInfo.EnvironmentVariables.ContainsKey("HTTPS_PROXY"))
|
||||
{
|
||||
rclone.StartInfo.EnvironmentVariables.Add("HTTPS_PROXY", $"http://{settings.ProxyAddress}:{settings.ProxyPort}");
|
||||
}
|
||||
// Use user's configured proxy
|
||||
var url = $"http://{settings.ProxyAddress}:{settings.ProxyPort}";
|
||||
rclone.StartInfo.EnvironmentVariables["HTTP_PROXY"] = url;
|
||||
rclone.StartInfo.EnvironmentVariables["HTTPS_PROXY"] = url;
|
||||
rclone.StartInfo.EnvironmentVariables["http_proxy"] = url;
|
||||
rclone.StartInfo.EnvironmentVariables["https_proxy"] = url;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(proxyUrl))
|
||||
{
|
||||
// Use our DNS-resolving proxy
|
||||
rclone.StartInfo.EnvironmentVariables["HTTP_PROXY"] = proxyUrl;
|
||||
rclone.StartInfo.EnvironmentVariables["HTTPS_PROXY"] = proxyUrl;
|
||||
rclone.StartInfo.EnvironmentVariables["http_proxy"] = proxyUrl;
|
||||
rclone.StartInfo.EnvironmentVariables["https_proxy"] = proxyUrl;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rclone.StartInfo.EnvironmentVariables.ContainsKey("HTTP_PROXY"))
|
||||
{
|
||||
rclone.StartInfo.EnvironmentVariables.Remove("HTTP_PROXY");
|
||||
}
|
||||
if (rclone.StartInfo.EnvironmentVariables.ContainsKey("HTTPS_PROXY"))
|
||||
{
|
||||
rclone.StartInfo.EnvironmentVariables.Remove("HTTPS_PROXY");
|
||||
}
|
||||
// No proxy
|
||||
rclone.StartInfo.EnvironmentVariables.Remove("HTTP_PROXY");
|
||||
rclone.StartInfo.EnvironmentVariables.Remove("HTTPS_PROXY");
|
||||
rclone.StartInfo.EnvironmentVariables.Remove("http_proxy");
|
||||
rclone.StartInfo.EnvironmentVariables.Remove("https_proxy");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ namespace AndroidSideloader
|
||||
|
||||
private void applyButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
//parsing bandwidth value
|
||||
// Parse bandwidth value
|
||||
var bandwidthInput = bandwidthLimitTextBox.Text;
|
||||
Regex regex = new Regex(@"^\d+(\.\d+)?$");
|
||||
|
||||
@@ -153,38 +153,42 @@ namespace AndroidSideloader
|
||||
return;
|
||||
}
|
||||
|
||||
//parsing proxy address
|
||||
var proxyAddressInput = proxyAddressTextBox.Text;
|
||||
// Parse proxy values if proxy is enabled
|
||||
if (toggleProxy.Checked)
|
||||
{
|
||||
// Parse proxy address
|
||||
var proxyAddressInput = proxyAddressTextBox.Text;
|
||||
|
||||
if (proxyAddressInput.StartsWith("http://"))
|
||||
{
|
||||
proxyAddressInput = proxyAddressInput.Substring("http://".Length);
|
||||
}
|
||||
else if (proxyAddressInput.StartsWith("https://"))
|
||||
{
|
||||
proxyAddressInput = proxyAddressInput.Substring("https://".Length);
|
||||
}
|
||||
if (proxyAddressInput.StartsWith("http://"))
|
||||
{
|
||||
proxyAddressInput = proxyAddressInput.Substring("http://".Length);
|
||||
}
|
||||
else if (proxyAddressInput.StartsWith("https://"))
|
||||
{
|
||||
proxyAddressInput = proxyAddressInput.Substring("https://".Length);
|
||||
}
|
||||
|
||||
if (proxyAddressInput.Equals("localhost", StringComparison.OrdinalIgnoreCase) ||
|
||||
IPAddress.TryParse(proxyAddressInput, out _))
|
||||
{
|
||||
_settings.ProxyAddress = proxyAddressInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Please enter a valid address for the proxy.");
|
||||
}
|
||||
if (proxyAddressInput.Equals("localhost", StringComparison.OrdinalIgnoreCase) ||
|
||||
IPAddress.TryParse(proxyAddressInput, out _))
|
||||
{
|
||||
_settings.ProxyAddress = proxyAddressInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Please enter a valid address for the proxy.");
|
||||
}
|
||||
|
||||
//parsing proxy port
|
||||
var proxyPortInput = proxyPortTextBox.Text;
|
||||
// Parse proxy port
|
||||
var proxyPortInput = proxyPortTextBox.Text;
|
||||
|
||||
if (ushort.TryParse(proxyPortInput, out _))
|
||||
{
|
||||
_settings.ProxyPort = proxyPortInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Please enter a valid port for the proxy.");
|
||||
if (ushort.TryParse(proxyPortInput, out _))
|
||||
{
|
||||
_settings.ProxyPort = proxyPortInput;
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("Please enter a valid port for the proxy.");
|
||||
}
|
||||
}
|
||||
|
||||
SaveAllSettings();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using JR.Utils.GUI.Forms;
|
||||
using AndroidSideloader.Utilities;
|
||||
using JR.Utils.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@@ -30,7 +31,7 @@ namespace AndroidSideloader
|
||||
string resultString;
|
||||
|
||||
// Try fetching raw JSON data from the provided link
|
||||
HttpWebRequest getUrl = (HttpWebRequest)WebRequest.Create(configUrl);
|
||||
HttpWebRequest getUrl = DnsHelper.CreateWebRequest(configUrl);
|
||||
using (StreamReader responseReader = new StreamReader(getUrl.GetResponse().GetResponseStream()))
|
||||
{
|
||||
resultString = responseReader.ReadToEnd();
|
||||
@@ -44,7 +45,7 @@ namespace AndroidSideloader
|
||||
_ = Logger.Log($"Failed to update public config from main: {mainException.Message}, trying fallback.", LogLevel.ERROR);
|
||||
try
|
||||
{
|
||||
HttpWebRequest getUrl = (HttpWebRequest)WebRequest.Create(fallbackUrl);
|
||||
HttpWebRequest getUrl = DnsHelper.CreateWebRequest(fallbackUrl);
|
||||
using (StreamReader responseReader = new StreamReader(getUrl.GetResponse().GetResponseStream()))
|
||||
{
|
||||
string resultString = responseReader.ReadToEnd();
|
||||
@@ -60,9 +61,12 @@ namespace AndroidSideloader
|
||||
}
|
||||
}
|
||||
|
||||
// Download required dependencies.
|
||||
// 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;
|
||||
@@ -73,7 +77,7 @@ namespace AndroidSideloader
|
||||
{
|
||||
currentAccessedWebsite = "github";
|
||||
_ = Logger.Log($"Missing 'Sideloader Launcher.exe'. Attempting to download from {currentAccessedWebsite}");
|
||||
client.DownloadFile("https://github.com/VRPirates/rookie/raw/master/Sideloader%20Launcher.exe", "Sideloader Launcher.exe");
|
||||
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/Sideloader%20Launcher.exe", "Sideloader Launcher.exe");
|
||||
_ = Logger.Log($"'Sideloader Launcher.exe' download successful");
|
||||
}
|
||||
|
||||
@@ -81,7 +85,7 @@ namespace AndroidSideloader
|
||||
{
|
||||
currentAccessedWebsite = "github";
|
||||
_ = Logger.Log($"Missing 'Rookie Offline.cmd'. Attempting to download from {currentAccessedWebsite}");
|
||||
client.DownloadFile("https://github.com/VRPirates/rookie/raw/master/Rookie%20Offline.cmd", "Rookie Offline.cmd");
|
||||
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/Rookie%20Offline.cmd", "Rookie Offline.cmd");
|
||||
_ = Logger.Log($"'Rookie Offline.cmd' download successful");
|
||||
}
|
||||
|
||||
@@ -89,7 +93,7 @@ namespace AndroidSideloader
|
||||
{
|
||||
currentAccessedWebsite = "github";
|
||||
_ = Logger.Log($"Missing 'CleanupInstall.cmd'. Attempting to download from {currentAccessedWebsite}");
|
||||
client.DownloadFile("https://github.com/VRPirates/rookie/raw/master/CleanupInstall.cmd", "CleanupInstall.cmd");
|
||||
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/CleanupInstall.cmd", "CleanupInstall.cmd");
|
||||
_ = Logger.Log($"'CleanupInstall.cmd' download successful");
|
||||
}
|
||||
|
||||
@@ -97,13 +101,13 @@ namespace AndroidSideloader
|
||||
{
|
||||
currentAccessedWebsite = "github";
|
||||
_ = Logger.Log($"Missing 'AddDefenderExceptions.ps1'. Attempting to download from {currentAccessedWebsite}");
|
||||
client.DownloadFile("https://github.com/VRPirates/rookie/raw/master/AddDefenderExceptions.ps1", "AddDefenderExceptions.ps1");
|
||||
DownloadFileWithDnsFallback(client, "https://github.com/VRPirates/rookie/raw/master/AddDefenderExceptions.ps1", "AddDefenderExceptions.ps1");
|
||||
_ = Logger.Log($"'AddDefenderExceptions.ps1' download successful");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_ = FlexibleMessageBox.Show($"You are unable to access raw.githubusercontent.com with the Exception:\n{ex.Message}\n\nSome files may be missing (Offline/Cleanup Script, Launcher)");
|
||||
_ = 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");
|
||||
@@ -120,7 +124,7 @@ namespace AndroidSideloader
|
||||
|
||||
currentAccessedWebsite = "github";
|
||||
_ = Logger.Log($"Missing adb within {platformToolsDir}. Attempting to download from {currentAccessedWebsite}");
|
||||
client.DownloadFile("https://github.com/VRPirates/rookie/raw/master/dependencies.7z", "dependencies.7z");
|
||||
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");
|
||||
@@ -128,8 +132,8 @@ namespace AndroidSideloader
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_ = FlexibleMessageBox.Show($"You are unable to access raw.githubusercontent.com page with the Exception:\n{ex.Message}\n\nSome files may be missing (ADB)");
|
||||
_ = FlexibleMessageBox.Show("ADB was unable to be downloaded\nRookie will now close.");
|
||||
_ = 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();
|
||||
}
|
||||
|
||||
@@ -137,16 +141,88 @@ namespace AndroidSideloader
|
||||
bool rcloneSuccess = false;
|
||||
|
||||
rcloneSuccess = downloadRclone(wantedRcloneVersion, false);
|
||||
if (!rcloneSuccess) {
|
||||
if (!rcloneSuccess)
|
||||
{
|
||||
rcloneSuccess = downloadRclone(wantedRcloneVersion, true);
|
||||
}
|
||||
if (!rcloneSuccess) {
|
||||
if (!rcloneSuccess)
|
||||
{
|
||||
_ = Logger.Log($"Unable to download rclone", LogLevel.ERROR);
|
||||
_ = FlexibleMessageBox.Show("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();
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
@@ -175,12 +251,15 @@ namespace AndroidSideloader
|
||||
_ = Logger.Log($"RCLONE Version does not match ({currentRcloneVersion})! Downloading required version ({wantedRcloneVersion})");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
updateRclone = true;
|
||||
_ = Logger.Log($"RCLONE exe does not exist, attempting to download");
|
||||
}
|
||||
|
||||
if (!Directory.Exists(dirRclone)) {
|
||||
if (!Directory.Exists(dirRclone))
|
||||
{
|
||||
updateRclone = true;
|
||||
_ = Logger.Log($"Missing RCLONE Folder, attempting to download");
|
||||
|
||||
@@ -203,14 +282,15 @@ namespace AndroidSideloader
|
||||
|
||||
string architecture = Environment.Is64BitOperatingSystem ? "amd64" : "386";
|
||||
string url = $"https://downloads.rclone.org/v{wantedRcloneVersion}/rclone-v{wantedRcloneVersion}-windows-{architecture}.zip";
|
||||
if (useFallback == true) {
|
||||
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");
|
||||
client.DownloadFile(url, "rclone.zip");
|
||||
DownloadFileWithDnsFallback(client, url, "rclone.zip");
|
||||
_ = Logger.Log("Complete download rclone");
|
||||
|
||||
_ = Logger.Log($"Extract {Environment.CurrentDirectory}\\rclone.zip");
|
||||
@@ -250,4 +330,4 @@ namespace AndroidSideloader
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +215,8 @@ namespace AndroidSideloader
|
||||
{
|
||||
string configUrl = "https://vrpirates.wiki/downloads/vrp.upload.config";
|
||||
|
||||
var getUrl = (HttpWebRequest)WebRequest.Create(configUrl);
|
||||
// Use DnsHelper for fallback DNS support
|
||||
var getUrl = DnsHelper.CreateWebRequest(configUrl);
|
||||
using (var response = getUrl.GetResponse())
|
||||
using (var stream = response.GetResponseStream())
|
||||
using (var responseReader = new StreamReader(stream))
|
||||
|
||||
491
Utilities/DnsHelper.cs
Normal file
491
Utilities/DnsHelper.cs
Normal file
@@ -0,0 +1,491 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace AndroidSideloader.Utilities
|
||||
{
|
||||
// Provides DNS fallback functionality using Cloudflare DNS (1.1.1.1, 1.0.0.1) if system DNS fails to resolve critical hostnames
|
||||
// Also provides a proxy for rclone that handles DNS resolution
|
||||
public static class DnsHelper
|
||||
{
|
||||
private static readonly string[] FallbackDnsServers = { "1.1.1.1", "1.0.0.1" };
|
||||
private static readonly string[] CriticalHostnames =
|
||||
{
|
||||
"raw.githubusercontent.com",
|
||||
"downloads.rclone.org",
|
||||
"vrpirates.wiki",
|
||||
"go.vrpyourself.online",
|
||||
"github.com"
|
||||
};
|
||||
|
||||
private static readonly ConcurrentDictionary<string, IPAddress> _dnsCache =
|
||||
new ConcurrentDictionary<string, IPAddress>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static bool _initialized;
|
||||
private static bool _useFallbackDns;
|
||||
private static readonly object _lock = new object();
|
||||
|
||||
// Local proxy for rclone
|
||||
private static TcpListener _proxyListener;
|
||||
private static CancellationTokenSource _proxyCts;
|
||||
private static int _proxyPort;
|
||||
private static bool _proxyRunning;
|
||||
|
||||
public static bool UseFallbackDns
|
||||
{
|
||||
get { if (!_initialized) Initialize(); return _useFallbackDns; }
|
||||
}
|
||||
|
||||
// Gets the proxy URL for rclone to use, or empty string if not needed
|
||||
public static string ProxyUrl => _proxyRunning ? $"http://127.0.0.1:{_proxyPort}" : string.Empty;
|
||||
|
||||
public static void Initialize()
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
if (_initialized) return;
|
||||
Logger.Log("Testing DNS resolution for critical hostnames...");
|
||||
|
||||
if (!TestSystemDns())
|
||||
{
|
||||
Logger.Log("System DNS failed. Testing Cloudflare DNS fallback...", LogLevel.WARNING);
|
||||
if (TestFallbackDns())
|
||||
{
|
||||
_useFallbackDns = true;
|
||||
Logger.Log("Using Cloudflare DNS fallback.", LogLevel.INFO);
|
||||
PreResolveHostnames();
|
||||
ServicePointManager.DnsRefreshTimeout = 0;
|
||||
|
||||
// Start local proxy for rclone
|
||||
StartProxy();
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log("Both system and fallback DNS failed.", LogLevel.ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger.Log("System DNS is working correctly.");
|
||||
}
|
||||
_initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Cleans up resources. Called on application exit
|
||||
public static void Cleanup()
|
||||
{
|
||||
StopProxy();
|
||||
}
|
||||
|
||||
private static void PreResolveHostnames()
|
||||
{
|
||||
foreach (string hostname in CriticalHostnames)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ip = ResolveWithFallbackDns(hostname);
|
||||
if (ip != null)
|
||||
{
|
||||
_dnsCache[hostname] = ip;
|
||||
Logger.Log($"Pre-resolved {hostname} -> {ip}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log($"Failed to pre-resolve {hostname}: {ex.Message}", LogLevel.WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TestSystemDns()
|
||||
{
|
||||
foreach (string hostname in CriticalHostnames)
|
||||
{
|
||||
try
|
||||
{
|
||||
var addresses = Dns.GetHostAddresses(hostname);
|
||||
if (addresses == null || addresses.Length == 0) return false;
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool TestFallbackDns()
|
||||
{
|
||||
foreach (string dnsServer in FallbackDnsServers)
|
||||
{
|
||||
try
|
||||
{
|
||||
var addresses = ResolveWithDns(CriticalHostnames[0], dnsServer);
|
||||
if (addresses != null && addresses.Count > 0) return true;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static IPAddress ResolveWithFallbackDns(string hostname)
|
||||
{
|
||||
foreach (string dnsServer in FallbackDnsServers)
|
||||
{
|
||||
try
|
||||
{
|
||||
var addresses = ResolveWithDns(hostname, dnsServer);
|
||||
if (addresses != null && addresses.Count > 0)
|
||||
return addresses[0];
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<IPAddress> ResolveWithDns(string hostname, string dnsServer, int timeoutMs = 5000)
|
||||
{
|
||||
byte[] query = BuildDnsQuery(hostname);
|
||||
using (var udp = new UdpClient())
|
||||
{
|
||||
udp.Client.ReceiveTimeout = timeoutMs;
|
||||
udp.Client.SendTimeout = timeoutMs;
|
||||
udp.Send(query, query.Length, new IPEndPoint(IPAddress.Parse(dnsServer), 53));
|
||||
IPEndPoint remoteEp = null;
|
||||
byte[] response = udp.Receive(ref remoteEp);
|
||||
return ParseDnsResponse(response);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] BuildDnsQuery(string hostname)
|
||||
{
|
||||
var ms = new MemoryStream();
|
||||
var writer = new BinaryWriter(ms);
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)new Random().Next(0, ushort.MaxValue)));
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)0x0100));
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)1));
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)0));
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)0));
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)0));
|
||||
foreach (string label in hostname.Split('.'))
|
||||
{
|
||||
writer.Write((byte)label.Length);
|
||||
writer.Write(Encoding.ASCII.GetBytes(label));
|
||||
}
|
||||
writer.Write((byte)0);
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)1));
|
||||
writer.Write(IPAddress.HostToNetworkOrder((short)1));
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private static List<IPAddress> ParseDnsResponse(byte[] response)
|
||||
{
|
||||
var addresses = new List<IPAddress>();
|
||||
if (response.Length < 12) return addresses;
|
||||
int pos = 12;
|
||||
while (pos < response.Length && response[pos] != 0) pos += response[pos] + 1;
|
||||
pos += 5;
|
||||
int answerCount = (response[6] << 8) | response[7];
|
||||
for (int i = 0; i < answerCount && pos + 12 <= response.Length; i++)
|
||||
{
|
||||
if ((response[pos] & 0xC0) == 0xC0) pos += 2;
|
||||
else { while (pos < response.Length && response[pos] != 0) pos += response[pos] + 1; pos++; }
|
||||
if (pos + 10 > response.Length) break;
|
||||
ushort type = (ushort)((response[pos] << 8) | response[pos + 1]);
|
||||
pos += 8;
|
||||
ushort rdLength = (ushort)((response[pos] << 8) | response[pos + 1]);
|
||||
pos += 2;
|
||||
if (pos + rdLength > response.Length) break;
|
||||
if (type == 1 && rdLength == 4)
|
||||
addresses.Add(new IPAddress(new[] { response[pos], response[pos + 1], response[pos + 2], response[pos + 3] }));
|
||||
pos += rdLength;
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
|
||||
#region Local HTTP CONNECT Proxy for rclone
|
||||
|
||||
private static void StartProxy()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Find an available port
|
||||
_proxyListener = new TcpListener(IPAddress.Loopback, 0);
|
||||
_proxyListener.Start();
|
||||
_proxyPort = ((IPEndPoint)_proxyListener.LocalEndpoint).Port;
|
||||
_proxyCts = new CancellationTokenSource();
|
||||
_proxyRunning = true;
|
||||
|
||||
Logger.Log($"Started DNS proxy on port {_proxyPort}");
|
||||
|
||||
// Accept connections in background
|
||||
Task.Run(() => ProxyAcceptLoop(_proxyCts.Token));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log($"Failed to start DNS proxy: {ex.Message}", LogLevel.WARNING);
|
||||
_proxyRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
private static void StopProxy()
|
||||
{
|
||||
_proxyRunning = false;
|
||||
_proxyCts?.Cancel();
|
||||
try { _proxyListener?.Stop(); } catch { }
|
||||
}
|
||||
|
||||
private static async Task ProxyAcceptLoop(CancellationToken ct)
|
||||
{
|
||||
while (!ct.IsCancellationRequested && _proxyRunning)
|
||||
{
|
||||
try
|
||||
{
|
||||
var client = await _proxyListener.AcceptTcpClientAsync();
|
||||
_ = Task.Run(() => HandleProxyClient(client, ct));
|
||||
}
|
||||
catch (ObjectDisposedException) { break; }
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!ct.IsCancellationRequested)
|
||||
Logger.Log($"Proxy accept error: {ex.Message}", LogLevel.WARNING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleProxyClient(TcpClient client, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (client)
|
||||
using (var stream = client.GetStream())
|
||||
{
|
||||
client.ReceiveTimeout = 30000;
|
||||
client.SendTimeout = 30000;
|
||||
|
||||
// Read the HTTP request
|
||||
var buffer = new byte[8192];
|
||||
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, ct);
|
||||
if (bytesRead == 0) return;
|
||||
|
||||
string request = Encoding.ASCII.GetString(buffer, 0, bytesRead);
|
||||
string[] lines = request.Split(new[] { "\r\n" }, StringSplitOptions.None);
|
||||
if (lines.Length == 0) return;
|
||||
|
||||
string[] requestLine = lines[0].Split(' ');
|
||||
if (requestLine.Length < 2) return;
|
||||
|
||||
string method = requestLine[0];
|
||||
string target = requestLine[1];
|
||||
|
||||
if (method == "CONNECT")
|
||||
{
|
||||
// HTTPS proxy - tunnel mode
|
||||
await HandleConnectRequest(stream, target, ct);
|
||||
}
|
||||
else
|
||||
{
|
||||
// HTTP proxy - forward mode
|
||||
await HandleHttpRequest(stream, request, target, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
if (!ct.IsCancellationRequested)
|
||||
Logger.Log($"Proxy client error: {ex.Message}", LogLevel.WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleConnectRequest(NetworkStream clientStream, string target, CancellationToken ct)
|
||||
{
|
||||
// Parse host:port
|
||||
string[] parts = target.Split(':');
|
||||
string host = parts[0];
|
||||
int port = parts.Length > 1 ? int.Parse(parts[1]) : 443;
|
||||
|
||||
// Resolve hostname using our DNS
|
||||
IPAddress ip = ResolveAnyHostname(host);
|
||||
if (ip == null)
|
||||
{
|
||||
byte[] errorResponse = Encoding.ASCII.GetBytes("HTTP/1.1 502 Bad Gateway\r\n\r\n");
|
||||
await clientStream.WriteAsync(errorResponse, 0, errorResponse.Length, ct);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Connect to target
|
||||
using (var targetClient = new TcpClient())
|
||||
{
|
||||
await targetClient.ConnectAsync(ip, port);
|
||||
using (var targetStream = targetClient.GetStream())
|
||||
{
|
||||
// Send 200 OK to client
|
||||
byte[] okResponse = Encoding.ASCII.GetBytes("HTTP/1.1 200 Connection Established\r\n\r\n");
|
||||
await clientStream.WriteAsync(okResponse, 0, okResponse.Length, ct);
|
||||
|
||||
// Tunnel data bidirectionally
|
||||
var clientToTarget = RelayData(clientStream, targetStream, ct);
|
||||
var targetToClient = RelayData(targetStream, clientStream, ct);
|
||||
await Task.WhenAny(clientToTarget, targetToClient);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log($"CONNECT tunnel error to {host}: {ex.Message}", LogLevel.WARNING);
|
||||
byte[] errorResponse = Encoding.ASCII.GetBytes("HTTP/1.1 502 Bad Gateway\r\n\r\n");
|
||||
try { await clientStream.WriteAsync(errorResponse, 0, errorResponse.Length, ct); } catch { }
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task HandleHttpRequest(NetworkStream clientStream, string request, string url, CancellationToken ct)
|
||||
{
|
||||
try
|
||||
{
|
||||
var uri = new Uri(url);
|
||||
IPAddress ip = ResolveAnyHostname(uri.Host);
|
||||
if (ip == null)
|
||||
{
|
||||
byte[] errorResponse = Encoding.ASCII.GetBytes("HTTP/1.1 502 Bad Gateway\r\n\r\n");
|
||||
await clientStream.WriteAsync(errorResponse, 0, errorResponse.Length, ct);
|
||||
return;
|
||||
}
|
||||
|
||||
int port = uri.Port > 0 ? uri.Port : 80;
|
||||
|
||||
using (var targetClient = new TcpClient())
|
||||
{
|
||||
await targetClient.ConnectAsync(ip, port);
|
||||
using (var targetStream = targetClient.GetStream())
|
||||
{
|
||||
// Modify request to use relative path
|
||||
string modifiedRequest = request.Replace(url, uri.PathAndQuery);
|
||||
byte[] requestBytes = Encoding.ASCII.GetBytes(modifiedRequest);
|
||||
await targetStream.WriteAsync(requestBytes, 0, requestBytes.Length, ct);
|
||||
|
||||
// Relay response
|
||||
await RelayData(targetStream, clientStream, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Log($"HTTP proxy error: {ex.Message}", LogLevel.WARNING);
|
||||
}
|
||||
}
|
||||
|
||||
private static async Task RelayData(NetworkStream from, NetworkStream to, CancellationToken ct)
|
||||
{
|
||||
byte[] buffer = new byte[8192];
|
||||
try
|
||||
{
|
||||
int bytesRead;
|
||||
while ((bytesRead = await from.ReadAsync(buffer, 0, buffer.Length, ct)) > 0)
|
||||
{
|
||||
await to.WriteAsync(buffer, 0, bytesRead, ct);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static IPAddress ResolveHostname(string hostname)
|
||||
{
|
||||
if (_dnsCache.TryGetValue(hostname, out IPAddress cached))
|
||||
return cached;
|
||||
|
||||
try
|
||||
{
|
||||
var addresses = Dns.GetHostAddresses(hostname);
|
||||
if (addresses != null && addresses.Length > 0)
|
||||
{
|
||||
_dnsCache[hostname] = addresses[0];
|
||||
return addresses[0];
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (_useFallbackDns || !_initialized)
|
||||
{
|
||||
var ip = ResolveWithFallbackDns(hostname);
|
||||
if (ip != null)
|
||||
{
|
||||
_dnsCache[hostname] = ip;
|
||||
return ip;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static IPAddress ResolveAnyHostname(string hostname)
|
||||
{
|
||||
if (_dnsCache.TryGetValue(hostname, out IPAddress cached))
|
||||
return cached;
|
||||
|
||||
try
|
||||
{
|
||||
var addresses = Dns.GetHostAddresses(hostname);
|
||||
if (addresses != null && addresses.Length > 0)
|
||||
{
|
||||
_dnsCache[hostname] = addresses[0];
|
||||
return addresses[0];
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
var ip = ResolveWithFallbackDns(hostname);
|
||||
if (ip != null)
|
||||
{
|
||||
_dnsCache[hostname] = ip;
|
||||
return ip;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static HttpWebRequest CreateWebRequest(string url)
|
||||
{
|
||||
var uri = new Uri(url);
|
||||
|
||||
if (!_useFallbackDns)
|
||||
{
|
||||
try
|
||||
{
|
||||
Dns.GetHostAddresses(uri.Host);
|
||||
return (HttpWebRequest)WebRequest.Create(url);
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (!_initialized) Initialize();
|
||||
}
|
||||
}
|
||||
|
||||
if (_useFallbackDns)
|
||||
{
|
||||
var ip = ResolveHostname(uri.Host);
|
||||
if (ip == null)
|
||||
{
|
||||
ip = ResolveAnyHostname(uri.Host);
|
||||
}
|
||||
|
||||
if (ip != null)
|
||||
{
|
||||
var builder = new UriBuilder(uri) { Host = ip.ToString() };
|
||||
var request = (HttpWebRequest)WebRequest.Create(builder.Uri);
|
||||
request.Host = uri.Host;
|
||||
return request;
|
||||
}
|
||||
}
|
||||
|
||||
return (HttpWebRequest)WebRequest.Create(url);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,17 +38,17 @@ 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)
|
||||
{
|
||||
_ = FlexibleMessageBox.Show($"You are unable to access the GitHub page with the Exception: {ex.Message}\nSome files may be missing (7z)");
|
||||
_ = FlexibleMessageBox.Show("7z was unable to be downloaded\nRookie will now close");
|
||||
_ = FlexibleMessageBox.Show(Program.form, $"You are unable to access the GitHub page with the Exception: {ex.Message}\nSome files may be missing (7z)");
|
||||
_ = FlexibleMessageBox.Show(Program.form, "7z was unable to be downloaded\nRookie will now close");
|
||||
Application.Exit();
|
||||
}
|
||||
_ = Logger.Log("Complete download 7-zip");
|
||||
@@ -127,7 +127,6 @@ namespace AndroidSideloader.Utilities
|
||||
extractionError = null; // Reset the error message
|
||||
throw new ExtractionException(errorMessage);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user