Refactor part 3
This commit is contained in:
parent
87ea315787
commit
2bfc3d59fb
1 changed files with 156 additions and 150 deletions
|
@ -49,6 +49,14 @@ namespace Ryujinx.Modules
|
||||||
|
|
||||||
private static readonly string[] _windowsDependencyDirs = Array.Empty<string>();
|
private static readonly string[] _windowsDependencyDirs = Array.Empty<string>();
|
||||||
|
|
||||||
|
private static readonly HttpClient httpClient = new HttpClient
|
||||||
|
{
|
||||||
|
DefaultRequestHeaders =
|
||||||
|
{
|
||||||
|
{ "User-Agent", "Ryujinx-Updater/1.0.0" }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public static async Task BeginParse(Window mainWindow, bool showVersionUpToDate)
|
public static async Task BeginParse(Window mainWindow, bool showVersionUpToDate)
|
||||||
{
|
{
|
||||||
if (_running)
|
if (_running)
|
||||||
|
@ -58,7 +66,35 @@ namespace Ryujinx.Modules
|
||||||
|
|
||||||
_running = true;
|
_running = true;
|
||||||
|
|
||||||
// Detect current platform
|
DetectPlatform();
|
||||||
|
|
||||||
|
Version currentVersion = GetCurrentVersion();
|
||||||
|
if (currentVersion == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string buildInfoUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
|
||||||
|
if (!await TryUpdateVersionInfo(buildInfoUrl, showVersionUpToDate))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!await HandleVersionComparison(currentVersion, showVersionUpToDate))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await FetchBuildSizeInfo();
|
||||||
|
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(async () =>
|
||||||
|
{
|
||||||
|
await ShowUpdateDialogAndExecute(mainWindow);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DetectPlatform()
|
||||||
|
{
|
||||||
if (OperatingSystem.IsMacOS())
|
if (OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
_platformExt = "macos_universal.app.tar.gz";
|
_platformExt = "macos_universal.app.tar.gz";
|
||||||
|
@ -72,144 +108,114 @@ namespace Ryujinx.Modules
|
||||||
var arch = RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64";
|
var arch = RuntimeInformation.OSArchitecture == Architecture.Arm64 ? "arm64" : "x64";
|
||||||
_platformExt = $"linux_{arch}.tar.gz";
|
_platformExt = $"linux_{arch}.tar.gz";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Version newVersion;
|
private static Version GetCurrentVersion()
|
||||||
Version currentVersion;
|
{
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
currentVersion = Version.Parse(Program.Version);
|
return Version.Parse(Program.Version);
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
|
Logger.Error?.Print(LogClass.Application, "Failed to convert the current Ryujinx version!");
|
||||||
|
|
||||||
await ContentDialogHelper.CreateWarningDialog(
|
ContentDialogHelper.CreateWarningDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedMessage],
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedMessage],
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
|
return null;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get latest version number from GitHub API
|
private static async Task<bool> TryUpdateVersionInfo(string buildInfoUrl, bool showVersionUpToDate)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
HttpResponseMessage response = await SendAsyncWithHeaders(buildInfoUrl);
|
||||||
string buildInfoUrl = $"{GitHubApiUrl}/repos/{ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelRepo}/releases/latest";
|
string fetchedJson = await response.Content.ReadAsStringAsync();
|
||||||
string fetchedJson = await httpClient.GetStringAsync(buildInfoUrl);
|
|
||||||
var fetched = JsonHelper.Deserialize(fetchedJson, _serializerContext.GithubReleasesJsonResponse);
|
var fetched = JsonHelper.Deserialize(fetchedJson, _serializerContext.GithubReleasesJsonResponse);
|
||||||
_buildVer = fetched.Name;
|
_buildVer = fetched.Name;
|
||||||
|
|
||||||
foreach (var asset in fetched.Assets)
|
foreach (var asset in fetched.Assets)
|
||||||
{
|
{
|
||||||
if (asset.Name.StartsWith("ryujinx") && asset.Name.EndsWith(_platformExt))
|
if (asset.Name.StartsWith("ryujinx") && asset.Name.EndsWith(_platformExt) && asset.State == "uploaded")
|
||||||
{
|
{
|
||||||
_buildUrl = asset.BrowserDownloadUrl;
|
_buildUrl = asset.BrowserDownloadUrl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (asset.State != "uploaded")
|
if (_buildUrl == null && showVersionUpToDate)
|
||||||
{
|
|
||||||
if (showVersionUpToDate)
|
|
||||||
{
|
{
|
||||||
await ContentDialogHelper.CreateUpdaterInfoDialog(
|
await ContentDialogHelper.CreateUpdaterInfoDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage], "");
|
||||||
"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
|
return false;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If build not done, assume no new update are available.
|
|
||||||
if (_buildUrl is null)
|
|
||||||
{
|
|
||||||
if (showVersionUpToDate)
|
|
||||||
{
|
|
||||||
await ContentDialogHelper.CreateUpdaterInfoDialog(
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
|
|
||||||
"");
|
|
||||||
}
|
|
||||||
|
|
||||||
_running = false;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception exception)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
Logger.Error?.Print(LogClass.Application, exception.Message);
|
Logger.Error?.Print(LogClass.Application, exception.Message);
|
||||||
|
|
||||||
await ContentDialogHelper.CreateErrorDialog(
|
await ContentDialogHelper.CreateErrorDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterFailedToGetVersionMessage]);
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterFailedToGetVersionMessage]);
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
|
return false;
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task<bool> HandleVersionComparison(Version currentVersion, bool showVersionUpToDate)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
newVersion = Version.Parse(_buildVer);
|
Version newVersion = Version.Parse(_buildVer);
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
|
|
||||||
|
|
||||||
await ContentDialogHelper.CreateWarningDialog(
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage],
|
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
|
|
||||||
|
|
||||||
_running = false;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newVersion <= currentVersion)
|
if (newVersion <= currentVersion)
|
||||||
{
|
{
|
||||||
if (showVersionUpToDate)
|
if (showVersionUpToDate)
|
||||||
{
|
{
|
||||||
await ContentDialogHelper.CreateUpdaterInfoDialog(
|
await ContentDialogHelper.CreateUpdaterInfoDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage],
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterAlreadyOnLatestVersionMessage], "");
|
||||||
"");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_running = false;
|
_running = false;
|
||||||
|
return false;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fetch build size information to learn chunk sizes.
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Logger.Error?.Print(LogClass.Application, "Failed to convert the received Ryujinx version from Github!");
|
||||||
|
await ContentDialogHelper.CreateWarningDialog(
|
||||||
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterConvertFailedGithubMessage],
|
||||||
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterCancelUpdateMessage]);
|
||||||
|
_running = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task FetchBuildSizeInfo()
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
httpClient.DefaultRequestHeaders.Range = new RangeHeaderValue(0, 0);
|
HttpResponseMessage message = await SendAsyncWithHeaders(_buildUrl, new RangeHeaderValue(0, 0));
|
||||||
|
|
||||||
HttpResponseMessage message = await httpClient.GetAsync(new Uri(_buildUrl), HttpCompletionOption.ResponseHeadersRead);
|
|
||||||
|
|
||||||
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
_buildSize = message.Content.Headers.ContentRange.Length.Value;
|
||||||
|
|
||||||
httpClient.DefaultRequestHeaders.Remove("Range");
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logger.Warning?.Print(LogClass.Application, ex.Message);
|
Logger.Warning?.Print(LogClass.Application, ex.Message);
|
||||||
Logger.Warning?.Print(LogClass.Application, "Couldn't determine build size for update, using single-threaded updater");
|
Logger.Warning?.Print(LogClass.Application, "Couldn't determine build size for update, using single-threaded updater");
|
||||||
|
|
||||||
_buildSize = -1;
|
_buildSize = -1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
await Dispatcher.UIThread.InvokeAsync(async () =>
|
private static async Task ShowUpdateDialogAndExecute(Window mainWindow)
|
||||||
{
|
{
|
||||||
// Show a message asking the user if they want to update
|
|
||||||
var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(
|
var shouldUpdate = await ContentDialogHelper.CreateChoiceDialog(
|
||||||
LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
||||||
LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
|
LocaleManager.Instance[LocaleKeys.RyujinxUpdaterMessage],
|
||||||
$"{Program.Version} -> {newVersion}");
|
$"{Program.Version} -> {_buildVer}");
|
||||||
|
|
||||||
if (shouldUpdate)
|
if (shouldUpdate)
|
||||||
{
|
{
|
||||||
|
@ -219,17 +225,17 @@ namespace Ryujinx.Modules
|
||||||
{
|
{
|
||||||
_running = false;
|
_running = false;
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly HttpClient httpClient = new HttpClient
|
private static async Task<HttpResponseMessage> SendAsyncWithHeaders(string url, RangeHeaderValue range = null)
|
||||||
{
|
{
|
||||||
// Required by GitHub to interact with APIs.
|
using var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||||
DefaultRequestHeaders =
|
if (range != null)
|
||||||
{
|
{
|
||||||
{ "User-Agent", "Ryujinx-Updater/1.0.0" }
|
request.Headers.Range = range;
|
||||||
|
}
|
||||||
|
return await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
private static async Task UpdateRyujinx(Window parent, string downloadUrl)
|
private static async Task UpdateRyujinx(Window parent, string downloadUrl)
|
||||||
{
|
{
|
||||||
|
@ -274,17 +280,24 @@ namespace Ryujinx.Modules
|
||||||
|
|
||||||
if (!OperatingSystem.IsMacOS())
|
if (!OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
shouldRestart = await ContentDialogHelper.CreateChoiceDialog(LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
shouldRestart = await ContentDialogHelper.CreateChoiceDialog(
|
||||||
|
LocaleManager.Instance[LocaleKeys.RyujinxUpdater],
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterCompleteMessage],
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterCompleteMessage],
|
||||||
LocaleManager.Instance[LocaleKeys.DialogUpdaterRestartMessage]);
|
LocaleManager.Instance[LocaleKeys.DialogUpdaterRestartMessage]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldRestart)
|
if (shouldRestart)
|
||||||
|
{
|
||||||
|
RestartApplication(parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RestartApplication(Window parent)
|
||||||
{
|
{
|
||||||
List<string> arguments = CommandLineState.Arguments.ToList();
|
List<string> arguments = CommandLineState.Arguments.ToList();
|
||||||
string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
string executableDirectory = AppDomain.CurrentDomain.BaseDirectory;
|
||||||
|
|
||||||
// On macOS we perform the update at relaunch.
|
|
||||||
if (OperatingSystem.IsMacOS())
|
if (OperatingSystem.IsMacOS())
|
||||||
{
|
{
|
||||||
string baseBundlePath = Path.GetFullPath(Path.Combine(executableDirectory, "..", ".."));
|
string baseBundlePath = Path.GetFullPath(Path.Combine(executableDirectory, "..", ".."));
|
||||||
|
@ -297,17 +310,12 @@ namespace Ryujinx.Modules
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Find the process name.
|
string ryuName = Path.GetFileName(Environment.ProcessPath) ?? (OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx");
|
||||||
string ryuName = Path.GetFileName(Environment.ProcessPath) ?? string.Empty;
|
|
||||||
|
|
||||||
// Migration: Start the updated binary.
|
|
||||||
// TODO: Remove this in a future update.
|
|
||||||
if (ryuName.StartsWith("Ryujinx.Ava"))
|
if (ryuName.StartsWith("Ryujinx.Ava"))
|
||||||
{
|
{
|
||||||
ryuName = ryuName.Replace(".Ava", "");
|
ryuName = ryuName.Replace(".Ava", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some operating systems can see the renamed executable, so strip off the .ryuold if found.
|
|
||||||
if (ryuName.EndsWith(".ryuold"))
|
if (ryuName.EndsWith(".ryuold"))
|
||||||
{
|
{
|
||||||
ryuName = ryuName[..^7];
|
ryuName = ryuName[..^7];
|
||||||
|
@ -319,13 +327,13 @@ namespace Ryujinx.Modules
|
||||||
ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
ryuName = OperatingSystem.IsWindows() ? "Ryujinx.exe" : "Ryujinx";
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessStartInfo processStart = new(ryuName)
|
ProcessStartInfo processStart = new ProcessStartInfo(ryuName)
|
||||||
{
|
{
|
||||||
UseShellExecute = true,
|
UseShellExecute = true,
|
||||||
WorkingDirectory = executableDirectory,
|
WorkingDirectory = executableDirectory,
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (string argument in CommandLineState.Arguments)
|
foreach (string argument in arguments)
|
||||||
{
|
{
|
||||||
processStart.ArgumentList.Add(argument);
|
processStart.ArgumentList.Add(argument);
|
||||||
}
|
}
|
||||||
|
@ -335,8 +343,6 @@ namespace Ryujinx.Modules
|
||||||
|
|
||||||
Environment.Exit(0);
|
Environment.Exit(0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static async Task DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
private static async Task DoUpdateWithMultipleThreads(TaskDialog taskDialog, string downloadUrl, string updateFile)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue