aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Hansen <emmausssss@gmail.com>2022-10-03 14:25:25 +0000
committerGitHub <noreply@github.com>2022-10-03 11:25:25 -0300
commit7539e26144c71f3d73684bf721c9fee115a1a75b (patch)
tree88c5f48de4766f6742f08546cc59a1ca10b97422
parent1c3697b6a4127bb0ef953604af766c57ef15518a (diff)
Avalonia - Fixes updater (#3670)1.1.290
* update avalonia * fix updater * fix spacing * addressed review * convert permission value to octal * Add missing comma * revert package updates
-rw-r--r--Ryujinx.Ava/Assets/Locales/en_US.json5
-rw-r--r--Ryujinx.Ava/Modules/Updater/Updater.cs146
-rw-r--r--Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml66
-rw-r--r--Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs73
4 files changed, 103 insertions, 187 deletions
diff --git a/Ryujinx.Ava/Assets/Locales/en_US.json b/Ryujinx.Ava/Assets/Locales/en_US.json
index 95f663aa..3a841157 100644
--- a/Ryujinx.Ava/Assets/Locales/en_US.json
+++ b/Ryujinx.Ava/Assets/Locales/en_US.json
@@ -574,12 +574,12 @@
"Discard": "Discard",
"UserProfilesSetProfileImage": "Set Profile Image",
"UserProfileEmptyNameError": "Name is required",
- "UserProfileNoImageError": "Profile image must be set",
+ "UserProfileNoImageError": "Profile image must be set",
"GameUpdateWindowHeading": "Updates Available for {0} [{1}]",
"SettingsTabHotkeysResScaleUpHotkey": "Increase resolution:",
"SettingsTabHotkeysResScaleDownHotkey": "Decrease resolution:",
"UserProfilesName": "Name:",
- "UserProfilesUserId" : "User Id:",
+ "UserProfilesUserId": "User Id:",
"SettingsTabGraphicsBackend": "Graphics Backend",
"SettingsTabGraphicsBackendTooltip": "Graphics Backend to use",
"SettingsEnableTextureRecompression": "Enable Texture Recompression",
@@ -589,6 +589,7 @@
"SettingsAppRequiredRestartMessage": "Ryujinx Restart Required",
"SettingsGpuBackendRestartMessage": "Graphics Backend or Gpu settings have been modified. This will require a restart to be applied",
"SettingsGpuBackendRestartSubMessage": "Do you want to restart now?",
+ "RyujinxUpdaterMessage": "Do you want to update Ryujinx to the latest version?",
"SettingsTabHotkeysVolumeUpHotkey": "Increase Volume:",
"SettingsTabHotkeysVolumeDownHotkey": "Decrease Volume:",
"VolumeShort": "Vol"
diff --git a/Ryujinx.Ava/Modules/Updater/Updater.cs b/Ryujinx.Ava/Modules/Updater/Updater.cs
index bbcf6679..d3c655b0 100644
--- a/Ryujinx.Ava/Modules/Updater/Updater.cs
+++ b/Ryujinx.Ava/Modules/Updater/Updater.cs
@@ -1,4 +1,6 @@
+using Avalonia.Controls;
using Avalonia.Threading;
+using FluentAvalonia.UI.Controls;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Tar;
using ICSharpCode.SharpZipLib.Zip;
@@ -11,11 +13,13 @@ using Ryujinx.Common;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.NetworkInformation;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
@@ -40,6 +44,8 @@ namespace Ryujinx.Modules
private static readonly string[] WindowsDependencyDirs = Array.Empty<string>();
+ public static bool UpdateSuccessful { get; private set; }
+
public static async Task BeginParse(MainWindow mainWindow, bool showVersionUpToDate)
{
if (Running)
@@ -198,11 +204,18 @@ namespace Ryujinx.Modules
_buildSize = -1;
}
}
+
Dispatcher.UIThread.Post(async () =>
{
// Show a message asking the user if they want to update
- UpdaterWindow updateDialog = new(mainWindow, newVersion, _buildUrl);
- await updateDialog.ShowDialog(mainWindow);
+ var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance["RyujinxUpdater"],
+ LocaleManager.Instance["RyujinxUpdaterMessage"],
+ $"{Program.Version} -> {newVersion}");
+
+ if (shouldUpdate)
+ {
+ UpdateRyujinx(mainWindow, _buildUrl);
+ }
});
}
@@ -216,8 +229,10 @@ namespace Ryujinx.Modules
return result;
}
- public static void UpdateRyujinx(UpdaterWindow updateDialog, string downloadUrl)
+ public static async void UpdateRyujinx(Window parent, string downloadUrl)
{
+ UpdateSuccessful = false;
+
// Empty update dir, although it shouldn't ever have anything inside it
if (Directory.Exists(UpdateDir))
{
@@ -228,25 +243,56 @@ namespace Ryujinx.Modules
string updateFile = Path.Combine(UpdateDir, "update.bin");
- // Download the update .zip
- updateDialog.MainText.Text = LocaleManager.Instance["UpdaterDownloading"];
- updateDialog.ProgressBar.Value = 0;
- updateDialog.ProgressBar.Maximum = 100;
+ var taskDialog = new TaskDialog()
+ {
+ Header = LocaleManager.Instance["RyujinxUpdater"],
+ SubHeader = LocaleManager.Instance["UpdaterDownloading"],
+ IconSource = new SymbolIconSource { Symbol = Symbol.Download },
+ Buttons = { },
+ ShowProgressBar = true
+ };
+
+ taskDialog.XamlRoot = parent;
- Task.Run(() =>
+ taskDialog.Opened += (s, e) =>
{
if (_buildSize >= 0)
{
- DoUpdateWithMultipleThreads(updateDialog, downloadUrl, updateFile);
+ DoUpdateWithMultipleThreads(taskDialog, downloadUrl, updateFile);
}
else
{
- DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
+ DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
}
- });
+ };
+
+ await taskDialog.ShowAsync(true);
+
+ if (UpdateSuccessful)
+ {
+ var shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance["RyujinxUpdater"],
+ LocaleManager.Instance["DialogUpdaterCompleteMessage"],
+ LocaleManager.Instance["DialogUpdaterRestartMessage"]);
+
+ if (shouldRestart)
+ {
+ string ryuName = Path.GetFileName(Environment.ProcessPath);
+ string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
+ string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).ToArray());
+
+ if (!OperatingSystem.IsWindows())
+ {
+ chmod(ryuExe, Convert.ToUInt32("0777", 8));
+ }
+
+ Process.Start(ryuExe, ryuArg);
+
+ Environment.Exit(0);
+ }
+ }
}
- private static void DoUpdateWithMultipleThreads(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
// Multi-Threaded Updater
long chunkSize = _buildSize / ConnectionCount;
@@ -290,7 +336,7 @@ namespace Ryujinx.Modules
Interlocked.Exchange(ref progressPercentage[index], args.ProgressPercentage);
Interlocked.Add(ref totalProgressPercentage, args.ProgressPercentage);
- updateDialog.ProgressBar.Value = totalProgressPercentage / ConnectionCount;
+ taskDialog.SetProgressBarState(totalProgressPercentage / ConnectionCount, TaskDialogProgressState.Normal);
};
client.DownloadDataCompleted += (_, args) =>
@@ -301,6 +347,8 @@ namespace Ryujinx.Modules
{
webClients[index].Dispose();
+ taskDialog.Hide();
+
return;
}
@@ -320,14 +368,14 @@ namespace Ryujinx.Modules
try
{
- InstallUpdate(updateDialog, updateFile);
+ InstallUpdate(taskDialog, updateFile);
}
catch (Exception e)
{
Logger.Warning?.Print(LogClass.Application, e.Message);
Logger.Warning?.Print(LogClass.Application, "Multi-Threaded update failed, falling back to single-threaded updater.");
- DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
+ DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
return;
}
@@ -348,7 +396,7 @@ namespace Ryujinx.Modules
webClients[j].CancelAsync();
}
- DoUpdateWithSingleThread(updateDialog, downloadUrl, updateFile);
+ DoUpdateWithSingleThread(taskDialog, downloadUrl, updateFile);
return;
}
@@ -356,7 +404,7 @@ namespace Ryujinx.Modules
}
}
- private static void DoUpdateWithSingleThreadWorker(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
+ private static void DoUpdateWithSingleThreadWorker(TaskDialog taskDialog, string downloadUrl, string updateFile)
{
using (HttpClient client = new HttpClient())
{
@@ -384,19 +432,26 @@ namespace Ryujinx.Modules
byteWritten += readSize;
- updateDialog.ProgressBar.Value = ((double)byteWritten / totalBytes) * 100;
+ taskDialog.SetProgressBarState(GetPercentage(byteWritten, totalBytes), TaskDialogProgressState.Normal);
+
updateFileStream.Write(buffer, 0, readSize);
}
}
}
- InstallUpdate(updateDialog, updateFile);
+ InstallUpdate(taskDialog, updateFile);
}
}
- private static void DoUpdateWithSingleThread(UpdaterWindow updateDialog, string downloadUrl, string updateFile)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private static double GetPercentage(double value, double max)
{
- Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(updateDialog, downloadUrl, updateFile));
+ return max == 0 ? 0 : value / max * 100;
+ }
+
+ private static void DoUpdateWithSingleThread(TaskDialog taskDialog, string downloadUrl, string updateFile)
+ {
+ Thread worker = new Thread(() => DoUpdateWithSingleThreadWorker(taskDialog, downloadUrl, updateFile));
worker.Name = "Updater.SingleThreadWorker";
worker.Start();
}
@@ -414,11 +469,11 @@ namespace Ryujinx.Modules
}
}
- private static async void InstallUpdate(UpdaterWindow updateDialog, string updateFile)
+ private static async void InstallUpdate(TaskDialog taskDialog, string updateFile)
{
// Extract Update
- updateDialog.MainText.Text = LocaleManager.Instance["UpdaterExtracting"];
- updateDialog.ProgressBar.Value = 0;
+ taskDialog.SubHeader = LocaleManager.Instance["UpdaterExtracting"];
+ taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
if (OperatingSystem.IsLinux())
{
@@ -426,8 +481,6 @@ namespace Ryujinx.Modules
using (Stream gzipStream = new GZipInputStream(inStream))
using (TarInputStream tarStream = new TarInputStream(gzipStream, Encoding.ASCII))
{
- updateDialog.ProgressBar.Maximum = inStream.Length;
-
await Task.Run(() =>
{
TarEntry tarEntry;
@@ -450,12 +503,12 @@ namespace Ryujinx.Modules
Dispatcher.UIThread.Post(() =>
{
- updateDialog.ProgressBar.Value += entry.Size;
+ taskDialog.SetProgressBarState(GetPercentage(entry.Size, inStream.Length), TaskDialogProgressState.Normal);
});
}
});
- updateDialog.ProgressBar.Value = inStream.Length;
+ taskDialog.SetProgressBarState(100, TaskDialogProgressState.Normal);
}
}
else
@@ -463,12 +516,12 @@ namespace Ryujinx.Modules
using (Stream inStream = File.OpenRead(updateFile))
using (ZipFile zipFile = new ZipFile(inStream))
{
- updateDialog.ProgressBar.Maximum = zipFile.Count;
-
await Task.Run(() =>
{
+ double count = 0;
foreach (ZipEntry zipEntry in zipFile)
{
+ count++;
if (zipEntry.IsDirectory) continue;
string outPath = Path.Combine(UpdateDir, zipEntry.Name);
@@ -485,7 +538,7 @@ namespace Ryujinx.Modules
Dispatcher.UIThread.Post(() =>
{
- updateDialog.ProgressBar.Value++;
+ taskDialog.SetProgressBarState(GetPercentage(count, zipFile.Count), TaskDialogProgressState.Normal);
});
}
});
@@ -497,22 +550,23 @@ namespace Ryujinx.Modules
List<string> allFiles = EnumerateFilesToDelete().ToList();
- updateDialog.MainText.Text = LocaleManager.Instance["UpdaterRenaming"];
- updateDialog.ProgressBar.Value = 0;
- updateDialog.ProgressBar.Maximum = allFiles.Count;
+ taskDialog.SubHeader = LocaleManager.Instance["UpdaterRenaming"];
+ taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
// Replace old files
await Task.Run(() =>
{
+ double count = 0;
foreach (string file in allFiles)
{
+ count++;
try
{
File.Move(file, file + ".ryuold");
Dispatcher.UIThread.Post(() =>
{
- updateDialog.ProgressBar.Value++;
+ taskDialog.SetProgressBarState(GetPercentage(count, allFiles.Count), TaskDialogProgressState.Normal);
});
}
catch
@@ -523,23 +577,20 @@ namespace Ryujinx.Modules
Dispatcher.UIThread.Post(() =>
{
- updateDialog.MainText.Text = LocaleManager.Instance["UpdaterAddingFiles"];
- updateDialog.ProgressBar.Value = 0;
- updateDialog.ProgressBar.Maximum = Directory.GetFiles(UpdatePublishDir, "*", SearchOption.AllDirectories).Length;
+ taskDialog.SubHeader = LocaleManager.Instance["UpdaterAddingFiles"];
+ taskDialog.SetProgressBarState(0, TaskDialogProgressState.Normal);
});
- MoveAllFilesOver(UpdatePublishDir, HomeDir, updateDialog);
+ MoveAllFilesOver(UpdatePublishDir, HomeDir, taskDialog);
});
Directory.Delete(UpdateDir, true);
SetUnixPermissions();
- updateDialog.MainText.Text = LocaleManager.Instance["DialogUpdaterCompleteMessage"];
- updateDialog.SecondaryText.Text = LocaleManager.Instance["DialogUpdaterRestartMessage"];
+ UpdateSuccessful = true;
- updateDialog.ProgressBar.IsVisible = false;
- updateDialog.ButtonBox.IsVisible = true;
+ taskDialog.Hide();
}
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
@@ -618,8 +669,9 @@ namespace Ryujinx.Modules
return files;
}
- private static void MoveAllFilesOver(string root, string dest, UpdaterWindow dialog)
+ private static void MoveAllFilesOver(string root, string dest, TaskDialog taskDialog)
{
+ var total = Directory.GetFiles(root, "*", SearchOption.AllDirectories).Length;
foreach (string directory in Directory.GetDirectories(root))
{
string dirName = Path.GetFileName(directory);
@@ -629,16 +681,18 @@ namespace Ryujinx.Modules
Directory.CreateDirectory(Path.Combine(dest, dirName));
}
- MoveAllFilesOver(directory, Path.Combine(dest, dirName), dialog);
+ MoveAllFilesOver(directory, Path.Combine(dest, dirName), taskDialog);
}
+ double count = 0;
foreach (string file in Directory.GetFiles(root))
{
+ count++;
File.Move(file, Path.Combine(dest, Path.GetFileName(file)), true);
Dispatcher.UIThread.InvokeAsync(() =>
{
- dialog.ProgressBar.Value++;
+ taskDialog.SetProgressBarState(GetPercentage(count, total), TaskDialogProgressState.Normal);
});
}
}
diff --git a/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml b/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml
deleted file mode 100644
index 180ba52d..00000000
--- a/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml
+++ /dev/null
@@ -1,66 +0,0 @@
-<window:StyleableWindow
- x:Class="Ryujinx.Ava.Ui.Windows.UpdaterWindow"
- xmlns="https://github.com/avaloniaui"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:locale="clr-namespace:Ryujinx.Ava.Common.Locale"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:window="clr-namespace:Ryujinx.Ava.Ui.Windows"
- Title="Ryujinx Updater"
- Width="500"
- Height="500"
- MinWidth="500"
- MinHeight="500"
- d:DesignHeight="350"
- d:DesignWidth="400"
- CanResize="False"
- SizeToContent="Height"
- WindowStartupLocation="CenterOwner"
- mc:Ignorable="d">
- <Grid
- Margin="20"
- HorizontalAlignment="Stretch"
- VerticalAlignment="Stretch">
- <Grid.RowDefinitions>
- <RowDefinition />
- <RowDefinition />
- <RowDefinition />
- <RowDefinition />
- <RowDefinition />
- </Grid.RowDefinitions>
- <TextBlock
- Name="MainText"
- Grid.Row="1"
- Height="20"
- HorizontalAlignment="Stretch"
- TextAlignment="Center" />
- <TextBlock
- Name="SecondaryText"
- Grid.Row="2"
- Height="20"
- HorizontalAlignment="Stretch"
- TextAlignment="Center" />
- <ProgressBar
- Name="ProgressBar"
- Grid.Row="3"
- Margin="20"
- HorizontalAlignment="Stretch"
- IsVisible="False"
- Maximum="100"
- Minimum="0" />
- <StackPanel
- Name="ButtonBox"
- Grid.Row="4"
- HorizontalAlignment="Right"
- IsVisible="False"
- Orientation="Horizontal"
- Spacing="20">
- <Button MinWidth="50" Command="{Binding YesPressed}">
- <TextBlock Text="{locale:Locale InputDialogYes}" TextAlignment="Center" />
- </Button>
- <Button MinWidth="50" Command="{Binding NoPressed}">
- <TextBlock Text="{locale:Locale InputDialogNo}" TextAlignment="Center" />
- </Button>
- </StackPanel>
- </Grid>
-</window:StyleableWindow> \ No newline at end of file
diff --git a/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs b/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs
deleted file mode 100644
index 526ca0bb..00000000
--- a/Ryujinx.Ava/Ui/Windows/UpdaterWindow.axaml.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using Ryujinx.Ava.Common.Locale;
-using Ryujinx.Modules;
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Runtime.InteropServices;
-
-namespace Ryujinx.Ava.Ui.Windows
-{
- public partial class UpdaterWindow : StyleableWindow
- {
- private readonly string _buildUrl;
- private readonly MainWindow _mainWindow;
- private readonly Version _newVersion;
- private bool _restartQuery;
-
- public UpdaterWindow()
- {
- DataContext = this;
-
- InitializeComponent();
-
- Title = LocaleManager.Instance["RyujinxUpdater"];
- }
-
- public UpdaterWindow(MainWindow mainWindow, Version newVersion, string buildUrl) : this()
- {
- _mainWindow = mainWindow;
- _newVersion = newVersion;
- _buildUrl = buildUrl;
- }
-
- [DllImport("libc", SetLastError = true)]
- private static extern int chmod(string path, uint mode);
-
- public void YesPressed()
- {
- if (_restartQuery)
- {
- string ryuName = OperatingSystem.IsWindows() ? "Ryujinx.Ava.exe" : "Ryujinx.Ava";
- string ryuExe = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ryuName);
- string ryuArg = string.Join(" ", Environment.GetCommandLineArgs().AsEnumerable().Skip(1).ToArray());
-
- if (!OperatingSystem.IsWindows())
- {
- chmod(ryuExe, 0777);
- }
-
- Process.Start(ryuExe, ryuArg);
-
- Environment.Exit(0);
- }
- else
- {
- ButtonBox.IsVisible = false;
- ProgressBar.IsVisible = true;
-
- SecondaryText.Text = "";
- _restartQuery = true;
-
- Updater.UpdateRyujinx(this, _buildUrl);
- }
- }
-
- public void NoPressed()
- {
- _mainWindow.UpdateMenuItem.IsEnabled = true;
-
- Close();
- }
- }
-} \ No newline at end of file