- Added new config mode for use with http mirror
- Removed previous http mirror workarounds
- Added Offline Mode launcher to package fetch.
- Add splash screen on startup
This commit is contained in:
SytheZN
2022-10-01 12:59:12 +02:00
parent c966066c67
commit 40b88a2d4c
23 changed files with 729 additions and 169 deletions

View File

@@ -1,7 +0,0 @@
{
"ExpandedNodes": [
""
],
"SelectedNode": "\\Sideloader.cs",
"PreviewInSolutionExplorer": false
}

Binary file not shown.

View File

@@ -169,6 +169,13 @@
<DependentUpon>DonorsListView.cs</DependentUpon>
</Compile>
<Compile Include="FlexibleMessageBox.cs" />
<Compile Include="Splash.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Splash.Designer.cs">
<DependentUpon>Splash.cs</DependentUpon>
</Compile>
<Compile Include="Models\PublicConfig.cs" />
<Compile Include="NewApps.cs">
<SubType>Form</SubType>
</Compile>
@@ -235,6 +242,9 @@
<EmbeddedResource Include="DonorsListView.resx">
<DependentUpon>DonorsListView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Splash.resx">
<DependentUpon>Splash.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="NewApps.resx">
<DependentUpon>NewApps.cs</DependentUpon>
</EmbeddedResource>
@@ -285,6 +295,9 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<None Include="Rookie Offline.cmd">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="version" />
</ItemGroup>
<ItemGroup>
@@ -294,6 +307,7 @@
<Content Include="changelog.txt" />
<Content Include="icon.ico" />
<Content Include="ChangelogHistory.txt" />
<Content Include="Resources\splash.jpg" />
<None Include="Resources\UpdatesKey.png" />
<None Include="Resources\battery11.png" />
<None Include="Resources\battery.png" />

View File

@@ -1,14 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectView>ShowAllFiles</ProjectView>
<PublishUrlHistory>publish\</PublishUrlHistory>
<InstallUrlHistory />
<SupportUrlHistory />
<UpdateUrlHistory />
<BootstrapperUrlHistory />
<ErrorReportUrlHistory />
<FallbackCulture>en-US</FallbackCulture>
<VerifyUploadedFiles>false</VerifyUploadedFiles>
</PropertyGroup>
</Project>

View File

@@ -1,4 +1,13 @@
RSL 2.12
RSL 2.13
- Added new config mode for use with http mirror
- Removed previous http mirror workarounds
- Added Offline Mode launcher to package fetch.
- Add splash screen on startup
~SytheZN
RSL 2.12
- updated auto-update source
- update status text

26
MainForm.Designer.cs generated
View File

@@ -93,7 +93,7 @@ namespace AndroidSideloader
this.label5 = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.label8 = new System.Windows.Forms.Label();
this.lblMirror = new System.Windows.Forms.Label();
this.EnterInstallBox = new System.Windows.Forms.CheckBox();
this.ADBcommandbox = new System.Windows.Forms.TextBox();
this.label11 = new System.Windows.Forms.Label();
@@ -1231,17 +1231,17 @@ namespace AndroidSideloader
this.label7.Text = "= Up to date";
this.label7.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// label8
// lblMirror
//
this.label8.AutoSize = true;
this.label8.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
this.label8.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.label8.Location = new System.Drawing.Point(459, 42);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(65, 17);
this.label8.TabIndex = 90;
this.label8.Text = "Mirror #";
this.label8.TextAlign = System.Drawing.ContentAlignment.TopCenter;
this.lblMirror.AutoSize = true;
this.lblMirror.Font = new System.Drawing.Font("Microsoft Sans Serif", 10F, System.Drawing.FontStyle.Bold);
this.lblMirror.ForeColor = System.Drawing.SystemColors.ControlLightLight;
this.lblMirror.Location = new System.Drawing.Point(459, 42);
this.lblMirror.Name = "lblMirror";
this.lblMirror.Size = new System.Drawing.Size(65, 17);
this.lblMirror.TabIndex = 90;
this.lblMirror.Text = "Mirror #";
this.lblMirror.TextAlign = System.Drawing.ContentAlignment.TopCenter;
//
// EnterInstallBox
//
@@ -1419,7 +1419,7 @@ namespace AndroidSideloader
this.Controls.Add(this.label10);
this.Controls.Add(this.label7);
this.Controls.Add(this.label6);
this.Controls.Add(this.label8);
this.Controls.Add(this.lblMirror);
this.Controls.Add(this.label5);
this.Controls.Add(this.label11);
this.Controls.Add(this.ADBcommandbox);
@@ -1531,7 +1531,7 @@ namespace AndroidSideloader
private System.Windows.Forms.PictureBox pictureBox4;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label label7;
private System.Windows.Forms.Label label8;
private System.Windows.Forms.Label lblMirror;
private System.Windows.Forms.CheckBox EnterInstallBox;
private System.Windows.Forms.TextBox ADBcommandbox;
private System.Windows.Forms.Label label11;

View File

@@ -10,10 +10,13 @@ using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using AndroidSideloader.Models;
namespace AndroidSideloader
@@ -50,6 +53,9 @@ namespace AndroidSideloader
private bool isLoading = true;
public static bool isOffline = false;
public static bool hasPublicConfig = false;
public static PublicConfig PublicConfigFile;
public MainForm()
{
@@ -66,6 +72,24 @@ namespace AndroidSideloader
{
FlexibleMessageBox.Show("Offline mode activated. You can't download games in this mode, only do local stuff.");
}
else
{
if (File.Exists($"{Environment.CurrentDirectory}\\vrp-public.json"))
{
try
{
var configFileData =
File.ReadAllText($"{Environment.CurrentDirectory}\\vrp-public.json");
var config = JsonConvert.DeserializeObject<PublicConfig>(configFileData);
PublicConfigFile = config;
hasPublicConfig = true;
}
catch
{
hasPublicConfig = false;
}
}
}
InitializeComponent();
//Time between asking for new apps if user clicks No. 96,0,0 DEFAULT
@@ -75,8 +99,8 @@ namespace AndroidSideloader
TimeSpan comparison;
TimeSpan comparison2;
//These two variables set to show difference.
DateTime A = Properties.Settings.Default.LastLaunch;
//These two variables set to show difference.
DateTime A = Properties.Settings.Default.LastLaunch;
DateTime B = DateTime.Now;
DateTime C = Properties.Settings.Default.LastLaunch2;
comparison = B - A;
@@ -151,6 +175,9 @@ namespace AndroidSideloader
private async void Form1_Load(object sender, EventArgs e)
{
var splash = new Splash();
splash.Show();
if (File.Exists("C:\\RSL\\platform-tools\\adb.exe"))
{
ADB.RunAdbCommandToString("kill-server");
@@ -233,6 +260,19 @@ namespace AndroidSideloader
File.Delete($"{Environment.CurrentDirectory}\\crashlog.txt");
}
}
if (hasPublicConfig)
{
lblMirror.Text = " Public Mirror";
remotesList.Size = Size.Empty;
}
if (isOffline)
{
lblMirror.Text = " Offline Mode";
remotesList.Size = Size.Empty;
}
splash.Close();
}
@@ -261,15 +301,17 @@ namespace AndroidSideloader
{
ChangeTitle("Initializing Servers...");
initMirrors(true);
if (Properties.Settings.Default.autoUpdateConfig) {
if (Properties.Settings.Default.autoUpdateConfig)
{
ChangeTitle("Checking for a new Configuration File...");
SideloaderRCLONE.updateConfig(currentRemote);
}
ChangeTitle("Grabbing the Games List...");
SideloaderRCLONE.initGames(currentRemote);
//ChangeTitle("Syncing Game Photos");
//ChangeTitle("Updating list of needed clean apps...");
//ChangeTitle("Checking for Updates on server...");
if (!hasPublicConfig)
{
ChangeTitle("Grabbing the Games List...");
SideloaderRCLONE.initGames(currentRemote);
}
}
else
{
@@ -279,10 +321,12 @@ namespace AndroidSideloader
});
t1.SetApartmentState(ApartmentState.STA);
t1.IsBackground = true;
if (HasInternet)
t1.Start();
while (t1.IsAlive)
await Task.Delay(100);
Thread t5 = new Thread(() =>
{
if (!String.IsNullOrEmpty(Properties.Settings.Default.IPAddress))
@@ -331,51 +375,80 @@ namespace AndroidSideloader
t5.Start();
while (t5.IsAlive)
await Task.Delay(100);
Thread t2 = new Thread(() =>
{
ChangeTitle("Updating Game Notes...");
SideloaderRCLONE.UpdateGameNotes(currentRemote);
});
Thread t3 = new Thread(() =>
if (hasPublicConfig)
{
ChangeTitle("Updating Game Thumbnails (This may take a minute or two)...");
SideloaderRCLONE.UpdateGamePhotos(currentRemote);
});
Thread t4 = new Thread(() =>
{
SideloaderRCLONE.UpdateNouns(currentRemote);
if (!Directory.Exists(SideloaderRCLONE.ThumbnailsFolder) || !Directory.Exists(SideloaderRCLONE.NotesFolder))
var t2 = new Thread((() =>
{
FlexibleMessageBox.Show("It seems you are missing the thumbnails and/or notes database, the first start of the sideloader takes a bit more time, so dont worry if it looks stuck!");
ChangeTitle("Updating Metadata...");
SideloaderRCLONE.UpdateMetadataFromPublic();
ChangeTitle("Processing Metadata...");
SideloaderRCLONE.ProcessMetadataFromPublic();
}));
t2.IsBackground = true;
if (HasInternet)
{
t2.Start();
}
});
t2.IsBackground = true;
t3.IsBackground = true;
t4.IsBackground = true;
if (HasInternet)
{
t2.Start();
while (t2.IsAlive)
await Task.Delay(50);
}
while (t2.IsAlive)
await Task.Delay(50);
if (HasInternet)
else
{
t3.Start();
}
while (t3.IsAlive)
await Task.Delay(50);
if (HasInternet)
{
t4.Start();
}
while (t4.IsAlive)
await Task.Delay(50);
Thread t2 = new Thread(() =>
{
ChangeTitle("Updating Game Notes...");
SideloaderRCLONE.UpdateGameNotes(currentRemote);
});
Thread t3 = new Thread(() =>
{
ChangeTitle("Updating Game Thumbnails (This may take a minute or two)...");
SideloaderRCLONE.UpdateGamePhotos(currentRemote);
});
Thread t4 = new Thread(() =>
{
SideloaderRCLONE.UpdateNouns(currentRemote);
if (!Directory.Exists(SideloaderRCLONE.ThumbnailsFolder) ||
!Directory.Exists(SideloaderRCLONE.NotesFolder))
{
FlexibleMessageBox.Show(
"It seems you are missing the thumbnails and/or notes database, the first start of the sideloader takes a bit more time, so dont worry if it looks stuck!");
}
});
t2.IsBackground = true;
t3.IsBackground = true;
t4.IsBackground = true;
if (HasInternet)
{
t2.Start();
}
while (t2.IsAlive)
await Task.Delay(50);
if (HasInternet)
{
t3.Start();
}
while (t3.IsAlive)
await Task.Delay(50);
if (HasInternet)
{
t4.Start();
}
while (t4.IsAlive)
await Task.Delay(50);
}
progressBar.Style = ProgressBarStyle.Marquee;
@@ -386,7 +459,7 @@ namespace AndroidSideloader
{
nodeviceonstart = true;
}
listappsbtn();
listappsbtn();
showAvailableSpace();
downloadInstallGameButton.Enabled = true;
isLoading = false;
@@ -579,7 +652,8 @@ namespace AndroidSideloader
public static void notify(string message)
{
if (Properties.Settings.Default.enableMessageBoxes == true)
FlexibleMessageBox.Show(new Form {
FlexibleMessageBox.Show(new Form
{
TopMost = true,
StartPosition = FormStartPosition.CenterScreen
}, message);
@@ -906,7 +980,7 @@ namespace AndroidSideloader
ChangeTitle("Uploading to shared drive, you can continue to use Rookie while it uploads in the background.");
RCLONE.runRcloneCommand($"copy \"{Properties.Settings.Default.MainDir}\\{GameName} v{VersionInt} {packageName}.zip\" RSL-gameuploads:");
File.Delete($"{Properties.Settings.Default.MainDir}\\{GameName} v{VersionInt} {packageName}.zip");
FlexibleMessageBox.Show($"Upload of {currentlyuploading} is complete! Thank you for your contribution!");
this.Invoke(() => FlexibleMessageBox.Show($"Upload of {currentlyuploading} is complete! Thank you for your contribution!"));
Directory.Delete($"{Properties.Settings.Default.MainDir}\\{packageName}", true);
});
t3.IsBackground = true;
@@ -1442,7 +1516,7 @@ namespace AndroidSideloader
while (t1.IsAlive)
await Task.Delay(100);
}
else if(!isOffline)
else if (!isOffline)
{
SwitchMirrors();
initListView();
@@ -1659,7 +1733,7 @@ namespace AndroidSideloader
public static async void newpackageupload()
{
if (!String.IsNullOrEmpty(Properties.Settings.Default.NonAppPackages) && !Properties.Settings.Default.ListUpped)
if (!String.IsNullOrEmpty(Properties.Settings.Default.NonAppPackages) && !Properties.Settings.Default.ListUpped)
{
Random r = new Random();
int x = r.Next(9999);
@@ -1759,7 +1833,7 @@ namespace AndroidSideloader
remotesList.Invoke(() =>
{
remotesList.SelectedIndex = 0; //set mirror to first
currentRemote = "VRP-mirror" + remotesList.SelectedItem.ToString();
currentRemote = "VRP-mirror" + remotesList.SelectedItem.ToString();
});
@@ -1905,13 +1979,14 @@ without him none of this would be possible
ShowError_QuotaExceeded();
DialogResult om = MessageBox.Show("Relaunch Rookie in Offline Mode?", "Offline Mode?", MessageBoxButtons.YesNo);
if (om == DialogResult.Yes) {
if (om == DialogResult.Yes)
{
Process pr = new Process();
pr.StartInfo.WorkingDirectory = Application.StartupPath;
pr.StartInfo.FileName = System.AppDomain.CurrentDomain.FriendlyName;
pr.StartInfo.Arguments = "--offline";
pr.Start();
Process.GetCurrentProcess().Kill();
pr.StartInfo.WorkingDirectory = Application.StartupPath;
pr.StartInfo.FileName = System.AppDomain.CurrentDomain.FriendlyName;
pr.StartInfo.Arguments = "--offline";
pr.Start();
Process.GetCurrentProcess().Kill();
}
if (System.Windows.Forms.Application.MessageLoop)
@@ -1972,7 +2047,8 @@ Things you can try:
initListView();
}
progressBar.Style = ProgressBarStyle.Marquee;
if (gamesListView.SelectedItems.Count == 0) {
if (gamesListView.SelectedItems.Count == 0)
{
progressBar.Style = ProgressBarStyle.Continuous;
ChangeTitle("You must select a game from the Game List!");
return;
@@ -2032,16 +2108,71 @@ Things you can try:
string dir = Path.GetDirectoryName(gameName);
string gameDirectory = Environment.CurrentDirectory + "\\" + gameName;
string path = gameDirectory;
Directory.CreateDirectory(gameDirectory);
var gameNameHash = string.Empty;
using (var md5 = MD5.Create())
{
var bytes = Encoding.UTF8.GetBytes(gameName + "\n");
var hash = md5.ComputeHash(bytes);
var sb = new StringBuilder();
foreach (var b in hash)
{
sb.Append(b.ToString("x2"));
}
gameNameHash = sb.ToString();
}
ProcessOutput gameDownloadOutput = new ProcessOutput("", "");
Logger.Log($"Starting Game Download");
Logger.Log($"rclone copy \"{currentRemote}:{SideloaderRCLONE.RcloneGamesFolder}/{gameName}\"");
Thread t1 = new Thread(() =>
Thread t1;
if (hasPublicConfig)
{
gameDownloadOutput = RCLONE.runRcloneCommand($"copy \"{currentRemote}:{SideloaderRCLONE.RcloneGamesFolder}/{gameName}\" \"{Environment.CurrentDirectory}\\{gameName}\" --progress --rc --transfers 1 --multi-thread-streams 1 --checkers 1", Properties.Settings.Default.BandwithLimit);
});
bool doDownload = true;
if (Directory.Exists(gameDirectory))
{
var res = FlexibleMessageBox.Show(
$"{gameName} exists in destination directory.\r\nWould you like to overwrite it?",
"Download again?", MessageBoxButtons.YesNo);
doDownload = res == DialogResult.Yes;
if (doDownload)
{
// only delete after extraction; allows for resume if the fetch fails midway.
if (Directory.Exists($"{Environment.CurrentDirectory}\\{gameName}"))
Directory.Delete($"{Environment.CurrentDirectory}\\{gameName}", true);
}
}
if (doDownload)
{
Logger.Log($"rclone copy \"Public:{SideloaderRCLONE.RcloneGamesFolder}/{gameName}\"");
t1 = new Thread(() =>
{
var rclonecommand =
$"copy --progress --rc --http-url {PublicConfigFile.BaseUri} \":http:/{gameNameHash}/\" \"{Environment.CurrentDirectory}\\{gameNameHash}\"";
gameDownloadOutput = RCLONE.runRcloneCommand(rclonecommand,
Properties.Settings.Default.BandwithLimit, true);
});
}
else
{
t1 = new Thread(() => { gameDownloadOutput = new ProcessOutput("Download skipped."); });
}
}
else
{
Directory.CreateDirectory(gameDirectory);
Logger.Log($"rclone copy \"{currentRemote}:{SideloaderRCLONE.RcloneGamesFolder}/{gameName}\"");
t1 = new Thread(() =>
{
gameDownloadOutput = RCLONE.runRcloneCommand($"copy \"{currentRemote}:{SideloaderRCLONE.RcloneGamesFolder}/{gameName}\" \"{Environment.CurrentDirectory}\\{gameName}\" --progress --rc", Properties.Settings.Default.BandwithLimit);
});
}
t1.IsBackground = true;
t1.Start();
@@ -2104,14 +2235,26 @@ Things you can try:
}
if (removedownloading)
{
ChangeTitle("Deleting game files", false);
try
{
Directory.Delete(Environment.CurrentDirectory + "\\" + gameName, true);
if (hasPublicConfig)
{
if (Directory.Exists($"{Environment.CurrentDirectory}\\{gameNameHash}"))
Directory.Delete($"{Environment.CurrentDirectory}\\{gameNameHash}", true);
if (Directory.Exists($"{Environment.CurrentDirectory}\\{gameName}"))
Directory.Delete($"{Environment.CurrentDirectory}\\{gameName}", true);
}
else
{
Directory.Delete(Environment.CurrentDirectory + "\\" + gameName, true);
}
}
catch (Exception ex) {
catch (Exception ex)
{
FlexibleMessageBox.Show($"Error deleting game files: {ex.Message}");
}
ChangeTitle("");
@@ -2121,6 +2264,7 @@ Things you can try:
//Quota Errors
bool isinstalltxt = false;
bool quotaError = false;
bool otherError = false;
if (gameDownloadOutput.Error.Length > 0 && !isOffline)
{
string err = gameDownloadOutput.Error.ToLower();
@@ -2135,9 +2279,39 @@ Things you can try:
gamesQueListBox.DataSource = null;
gamesQueListBox.DataSource = gamesQueueList;
}
else if (!gameDownloadOutput.Error.Contains("localhost")) FlexibleMessageBox.Show($"Rclone error: {gameDownloadOutput.Error}");
else if (!gameDownloadOutput.Error.Contains("localhost"))
{
otherError = true;
//Remove current game
gamesQueueList.RemoveAt(0);
gamesQueListBox.DataSource = null;
gamesQueListBox.DataSource = gamesQueueList;
FlexibleMessageBox.Show($"Rclone error: {gameDownloadOutput.Error}");
output += new ProcessOutput("", "Download Failed");
}
}
if (quotaError == false)
if (hasPublicConfig && otherError == false && gameDownloadOutput.Output != "Download skipped.")
{
try
{
ChangeTitle("Extracting " + gameName, false);
Zip.ExtractFile($"{Environment.CurrentDirectory}\\{gameNameHash}\\{gameNameHash}.7z.001", $"{Environment.CurrentDirectory}", PublicConfigFile.Password);
if (Directory.Exists($"{Environment.CurrentDirectory}\\{gameNameHash}"))
Directory.Delete($"{Environment.CurrentDirectory}\\{gameNameHash}", true);
}
catch (Exception ex)
{
otherError = true;
FlexibleMessageBox.Show($"7zip error: {ex.Message}");
output += new ProcessOutput("", "Extract Failed");
}
}
if (quotaError == false && otherError == false)
{
ADB.WakeDevice();
ADB.DeviceID = GetDeviceID();
@@ -2238,17 +2412,17 @@ Things you can try:
isinstalling = false;
return;
}
ChangeTitle("Refreshing games list, please wait... \n");
showAvailableSpace();
listappsbtn();
initListView();
ShowPrcOutput(output);
progressBar.Style = ProgressBarStyle.Continuous;
etaLabel.Text = "ETA: Finished Queue";
speedLabel.Text = "DLS: Finished Queue";
ProgressText.Text = "";
gamesAreDownloading = false;
isinstalling = false;
ChangeTitle("Refreshing games list, please wait... \n");
showAvailableSpace();
listappsbtn();
initListView();
ShowPrcOutput(output);
progressBar.Style = ProgressBarStyle.Continuous;
etaLabel.Text = "ETA: Finished Queue";
speedLabel.Text = "DLS: Finished Queue";
ProgressText.Text = "";
gamesAreDownloading = false;
isinstalling = false;
ChangeTitle(" \n\n");
}

View File

@@ -117,4 +117,76 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="startsideloadbutton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="devicesbutton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>752, 113</value>
</metadata>
<metadata name="obbcopybutton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>498, 113</value>
</metadata>
<metadata name="backupbutton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>256, 113</value>
</metadata>
<metadata name="restorebutton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 113</value>
</metadata>
<metadata name="getApkButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>2205, 65</value>
</metadata>
<metadata name="uninstallAppButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1921, 65</value>
</metadata>
<metadata name="pullAppToDesktopBtn_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1614, 65</value>
</metadata>
<metadata name="copyBulkObbButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1322, 65</value>
</metadata>
<metadata name="downloadInstallGameButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>963, 65</value>
</metadata>
<metadata name="aboutBtn_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>761, 65</value>
</metadata>
<metadata name="settingsButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>515, 65</value>
</metadata>
<metadata name="InstallQUset_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>290, 65</value>
</metadata>
<metadata name="removeQUSetting_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 65</value>
</metadata>
<metadata name="ThemeChangerButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>2122, 17</value>
</metadata>
<metadata name="QuestOptionsButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1827, 17</value>
</metadata>
<metadata name="ADBWirelessDisable_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1537, 17</value>
</metadata>
<metadata name="ADBWirelessEnable_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1252, 17</value>
</metadata>
<metadata name="UpdateGamesButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>955, 17</value>
</metadata>
<metadata name="listApkButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>718, 17</value>
</metadata>
<metadata name="speedLabel_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>499, 17</value>
</metadata>
<metadata name="etaLabel_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>304, 17</value>
</metadata>
<metadata name="MountButton_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>994, 113</value>
</metadata>
<metadata name="EnterInstallBox_Tooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>1231, 113</value>
</metadata>
</root>

25
Models/PublicConfig.cs Normal file
View File

@@ -0,0 +1,25 @@
using Newtonsoft.Json;
using System;
using System.Text;
namespace AndroidSideloader.Models
{
[JsonObject(MemberSerialization.OptIn)]
public class PublicConfig
{
[JsonProperty("baseUri")]
public string BaseUri { get; set; }
private string password;
[JsonProperty("password")]
public string Password
{
get => password;
set
{
password = Encoding.UTF8.GetString(Convert.FromBase64String(value));
}
}
}
}

View File

@@ -19,7 +19,7 @@ namespace AndroidSideloader.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class Resources {
@@ -160,6 +160,16 @@ namespace AndroidSideloader.Properties {
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
public static System.Drawing.Bitmap splash {
get {
object obj = ResourceManager.GetObject("splash", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>

View File

@@ -151,4 +151,7 @@
<data name="UpdatesKey" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\UpdatesKey.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="splash" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\splash.jpg;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>

View File

@@ -27,14 +27,15 @@ namespace AndroidSideloader
}
//Change if you want to use a config
public static string configPath = ""; // ".\\a"
public static string configPath = "vrp.download.config";
public static string rclonepw = "";
private static Process rclone = new Process();
//Run rclone command
public static ProcessOutput runRcloneCommand(string command, string bandwithLimit = "")
// noconfig suppresses the config directive for using with a command specified mirror
public static ProcessOutput runRcloneCommand(string command, string bandwithLimit = "", bool noConfig = false)
{
if (!MainForm.HasInternet || MainForm.isOffline)
{
@@ -53,7 +54,7 @@ namespace AndroidSideloader
}
//set configpath if there is any
if (configPath.Length > 0)
if (configPath.Length > 0 && !noConfig)
{
command += $" --config {configPath}";
}
@@ -91,6 +92,9 @@ namespace AndroidSideloader
//if there is one of these errors, we switch the mirrors
if (error.Contains("400 Bad Request") || error.Contains("cannot fetch token") || error.Contains("authError") || error.Contains("quota") || error.Contains("exceeded") || error.Contains("directory not found") || error.Contains("Failed to"))
{
if (MainForm.hasPublicConfig)
return new ProcessOutput("Failed to fetch from public mirror.", "Failed to fetch from public mirror.");
string oldRemote = MainForm.currentRemote;
try
{

BIN
Resources/splash.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

10
Rookie Offline.cmd Normal file
View File

@@ -0,0 +1,10 @@
@echo off
for /f "tokens=* usebackq" %%f in (`dir /b AndroidSideloader*.exe`) do (set "sideloader=%%f" & goto :next)
:next
echo %sideloader%
start "" "%sideloader%" "--offline"

View File

@@ -247,6 +247,10 @@ And all of them added to PATH, without ANY of them, the spoofer won't work!";
{
if (!File.Exists("Sideloader Launcher.exe"))
client.DownloadFile("https://github.com/nerdunit/androidsideloader/raw/master/Sideloader%20Launcher.exe", "Sideloader Launcher.exe");
if (!File.Exists("Rookie Offline.cmd"))
client.DownloadFile("https://github.com/nerdunit/androidsideloader/raw/master/Rookie%20Offline.cmd", "Rookie Offline.cmd");
if (!File.Exists("C:\\RSL\\platform-tools\\aug2021.txt") || !File.Exists("C:\\RSL\\platform-tools\\adb.exe")) //if adb is not updated, download and auto extract
{
if (Directory.Exists($"C:\\RSL\\2.8.2"))

View File

@@ -4,6 +4,7 @@ using System.Net;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using AndroidSideloader.Utilities;
namespace AndroidSideloader
{
@@ -48,19 +49,68 @@ namespace AndroidSideloader
public static void UpdateNouns(string remote)
{
Logger.Log($"Updating Nouns");
RCLONE.runRcloneCommand($"sync \"{remote}:{RcloneGamesFolder}/.meta/nouns\" \"{Nouns}\" --http-no-head --transfers 2 --multi-thread-streams 1");
RCLONE.runRcloneCommand($"sync \"{remote}:{RcloneGamesFolder}/.meta/nouns\" \"{Nouns}\"");
}
public static void UpdateGamePhotos(string remote)
{
Logger.Log($"Updating Thumbnails");
RCLONE.runRcloneCommand($"sync \"{remote}:{RcloneGamesFolder}/.meta/thumbnails\" \"{ThumbnailsFolder}\" --http-no-head --transfers 2 --multi-thread-streams 1");
RCLONE.runRcloneCommand($"sync \"{remote}:{RcloneGamesFolder}/.meta/thumbnails\" \"{ThumbnailsFolder}\"");
}
public static void UpdateGameNotes(string remote)
{
Logger.Log($"Updating Game Notes");
RCLONE.runRcloneCommand($"sync \"{remote}:{RcloneGamesFolder}/.meta/notes\" \"{NotesFolder}\" --http-no-head --transfers 2 --multi-thread-streams 1");
RCLONE.runRcloneCommand($"sync \"{remote}:{RcloneGamesFolder}/.meta/notes\" \"{NotesFolder}\"");
}
public static void UpdateMetadataFromPublic()
{
Logger.Log($"Downloading Metadata");
var rclonecommand =
$"sync --http-url {MainForm.PublicConfigFile.BaseUri} \":http:/meta.7z\" \"{Environment.CurrentDirectory}\"";
RCLONE.runRcloneCommand(rclonecommand);
}
public static void ProcessMetadataFromPublic()
{
try
{
Logger.Log($"Extracting Metadata");
Zip.ExtractFile($"{Environment.CurrentDirectory}\\meta.7z", $"{Environment.CurrentDirectory}\\meta",
MainForm.PublicConfigFile.Password);
Logger.Log($"Updating Metadata");
if (Directory.Exists(Nouns)) Directory.Delete(Nouns, true);
if (Directory.Exists(ThumbnailsFolder)) Directory.Delete(ThumbnailsFolder, true);
if (Directory.Exists(NotesFolder)) Directory.Delete(NotesFolder, true);
Directory.Move($"{Environment.CurrentDirectory}\\meta\\.meta\\nouns", Nouns);
Directory.Move($"{Environment.CurrentDirectory}\\meta\\.meta\\thumbnails", ThumbnailsFolder);
Directory.Move($"{Environment.CurrentDirectory}\\meta\\.meta\\notes", NotesFolder);
Logger.Log($"Initializing Games List");
var gameList = File.ReadAllText($"{Environment.CurrentDirectory}\\meta\\VRP-GameList.txt");
string[] splitList = gameList.Split('\n');
splitList = splitList.Skip(1).ToArray();
foreach (string game in splitList)
{
if (game.Length > 1)
{
string[] splitGame = game.Split(';');
games.Add(splitGame);
}
}
Directory.Delete($"{Environment.CurrentDirectory}\\meta", true);
}
catch (Exception e)
{
Logger.Log(e.Message);
Logger.Log(e.StackTrace);
}
}
public static void RefreshRemotes()

55
Splash.Designer.cs generated Normal file
View File

@@ -0,0 +1,55 @@
namespace AndroidSideloader
{
partial class Splash
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// Splash
//
this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImage = global::AndroidSideloader.Properties.Resources.splash;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
this.CausesValidation = false;
this.ClientSize = new System.Drawing.Size(640, 384);
this.ControlBox = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "Splash";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "Splash";
this.ResumeLayout(false);
}
#endregion
}
}

20
Splash.cs Normal file
View File

@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AndroidSideloader
{
public partial class Splash : Form
{
public Splash()
{
InitializeComponent();
}
}
}

120
Splash.resx Normal file
View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -17,7 +17,7 @@ namespace AndroidSideloader
private static string RawGitHubUrl;
private static string GitHubUrl;
static readonly public string LocalVersion = "2.12";
static readonly public string LocalVersion = "2.13";
public static string currentVersion = string.Empty;
public static string changelog = string.Empty;

View File

@@ -104,6 +104,18 @@ namespace AndroidSideloader.Utilities
class Zip
{
public static void ExtractFile(string sourceArchive, string destination)
{
var args = $"x \"{sourceArchive}\" -y -o\"{destination}\"";
DoExtract(args);
}
public static void ExtractFile(string sourceArchive, string destination, string password)
{
var args = $"x \"{sourceArchive}\" -y -o\"{destination}\" -p\"{password}\"";
DoExtract(args);
}
private static void DoExtract(string args)
{
if (!File.Exists(Environment.CurrentDirectory + "\\7z.exe") || !File.Exists(Environment.CurrentDirectory + "\\7z.dll"))
{
@@ -114,9 +126,11 @@ namespace AndroidSideloader.Utilities
ProcessStartInfo pro = new ProcessStartInfo();
pro.WindowStyle = ProcessWindowStyle.Hidden;
pro.FileName = "7z.exe";
pro.Arguments = string.Format("x \"{0}\" -y -o\"{1}\"", sourceArchive, destination);
pro.Arguments = args;
Process x = Process.Start(pro);
x.WaitForExit();
if (x.ExitCode != 0)
throw new ApplicationException($"Extracting failed, status code {x.ExitCode}");
}
}

View File

@@ -1,11 +1,8 @@
RSL 2.12
RSL 2.13
- fixed issue with configuration always updating
- fixed github version vs app version comparison
- fixed github download url
- restored "auto update config" checkbox
- fixed tooltips; added additional tooltips to all menu items
- gui fixes and updates to game donation menu
- additional logging and on-screen notifications
- Added new config mode for use with http mirror
- Removed previous http mirror workarounds
- Added Offline Mode launcher to package fetch.
- Add splash screen on startup
~fenopy
~SytheZN

View File

@@ -1 +1 @@
2.12
2.13