Skip to content

Commit deeb989

Browse files
Added auto updating (#14)
1 parent c09b0b1 commit deeb989

File tree

14 files changed

+252
-6
lines changed

14 files changed

+252
-6
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -493,4 +493,4 @@ fabric.properties
493493
# *.ipr
494494

495495
### Custom ###
496-
ShinRyuModManager-CE/Properties/launchSettings.json
496+
launchSettings.json

RyuUpdater/Program.cs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System.Diagnostics;
2+
using System.IO.Compression;
3+
4+
namespace RyuUpdater;
5+
6+
public static class Program {
7+
private static async Task Main(string[] args) {
8+
if (args.Length == 0) {
9+
Console.WriteLine("This is a helper application for SRMM. Please don't run manually!\nPress any key to exit...");
10+
Console.ReadKey();
11+
12+
return;
13+
}
14+
15+
var pid = int.Parse(args[0]);
16+
var updateFile = args[1];
17+
var targetDir = args[2];
18+
var srmmFileName = args[3];
19+
20+
var tempDir = new FileInfo(updateFile).Directory!.FullName;
21+
22+
try {
23+
if (pid != -1) {
24+
await Process.GetProcessById(pid).WaitForExitAsync();
25+
}
26+
} catch {
27+
// ignore
28+
}
29+
30+
await Task.Delay(500);
31+
32+
ZipFile.ExtractToDirectory(updateFile, targetDir, overwriteFiles: true);
33+
Directory.Delete(tempDir, recursive: true);
34+
35+
var srmmPath = Path.Combine(targetDir, srmmFileName);
36+
37+
Process.Start(new ProcessStartInfo {
38+
FileName = srmmPath,
39+
UseShellExecute = true
40+
});
41+
}
42+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"$schema": "http://json.schemastore.org/launchsettings.json",
3+
"profiles": {
4+
"RyuUpdater": {
5+
"commandName": "Project",
6+
"commandLineArgs": "<SRMM PID> <ZipFilePath> <TempDir> <SRMMFileName>",
7+
"workingDirectory": "" // Path to folder containing exe
8+
}
9+
}
10+
}

RyuUpdater/RyuUpdater.csproj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFrameworks>net8.0;net8.0-windows</TargetFrameworks>
6+
<LangVersion>12</LangVersion>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>disable</Nullable>
9+
<Configurations>Debug;Release</Configurations>
10+
<Platforms>x64</Platforms>
11+
<IsPackable>false</IsPackable>
12+
<ApplicationIcon>..\ShinRyuModManager-CE\UserInterface\Assets\Icons\SRMM_icon.ico</ApplicationIcon>
13+
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
14+
<TrimmerSingleWarn>false</TrimmerSingleWarn>
15+
<AssemblyVersion>1.0.0</AssemblyVersion>
16+
<VersionPrefix>$(AssemblyVersion)</VersionPrefix>
17+
<Version>$(AssemblyVersion)</Version>
18+
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
19+
</PropertyGroup>
20+
21+
</Project>

ShinRyuModManager-CE.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ParLibrary.Tests", "ParLibr
88
EndProject
99
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Utils", "Utils\Utils.csproj", "{7F2462E1-FB0A-4BFA-BBF9-91CD9DB1FC56}"
1010
EndProject
11+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RyuUpdater", "RyuUpdater\RyuUpdater.csproj", "{FDE3D69A-37FA-4187-9CAE-07EA4382D8A6}"
12+
EndProject
1113
Global
1214
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1315
Debug|x64 = Debug|x64
@@ -30,5 +32,9 @@ Global
3032
{7F2462E1-FB0A-4BFA-BBF9-91CD9DB1FC56}.Debug|x64.Build.0 = Debug|x64
3133
{7F2462E1-FB0A-4BFA-BBF9-91CD9DB1FC56}.Release|x64.ActiveCfg = Release|x64
3234
{7F2462E1-FB0A-4BFA-BBF9-91CD9DB1FC56}.Release|x64.Build.0 = Release|x64
35+
{FDE3D69A-37FA-4187-9CAE-07EA4382D8A6}.Debug|x64.ActiveCfg = Debug|Any CPU
36+
{FDE3D69A-37FA-4187-9CAE-07EA4382D8A6}.Debug|x64.Build.0 = Debug|Any CPU
37+
{FDE3D69A-37FA-4187-9CAE-07EA4382D8A6}.Release|x64.ActiveCfg = Release|Any CPU
38+
{FDE3D69A-37FA-4187-9CAE-07EA4382D8A6}.Release|x64.Build.0 = Release|Any CPU
3339
EndGlobalSection
3440
EndGlobal

ShinRyuModManager-CE/ShinRyuModManager-CE.csproj

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<EnableTrimAnalyzer>true</EnableTrimAnalyzer>
1616

1717
<!-- Versioning -->
18-
<AssemblyVersion>1.1.12</AssemblyVersion>
18+
<AssemblyVersion>1.2.0</AssemblyVersion>
1919
<VersionPrefix>$(AssemblyVersion)</VersionPrefix>
2020
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
2121
</PropertyGroup>
@@ -45,6 +45,7 @@
4545
<PackageReference Include="ini-parser" Version="2.5.2" />
4646
<PackageReference Include="Markdown.Avalonia" Version="11.0.2" />
4747
<PackageReference Include="Microsoft.IO.RecyclableMemoryStream" Version="3.0.1" />
48+
<PackageReference Include="NetSparkleUpdater.UI.Avalonia" Version="3.0.4" />
4849
<PackageReference Include="Serilog" Version="4.3.0" />
4950
<PackageReference Include="Serilog.Exceptions" Version="8.4.0" />
5051
<PackageReference Include="Serilog.Expressions" Version="5.0.0" />

ShinRyuModManager-CE/UserInterface/Assets/changelog.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
> ### **%{color:orange} Version 1.2.0 %** ###
2+
* Added auto updater
3+
4+
---
5+
16
> ### **%{color:orange} Version 1.1.12 %** ###
27
* Minor Cleanup
38
* Updated libraries
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
using System.IO.Compression;
2+
using Avalonia.Media;
3+
using Avalonia.Media.Immutable;
4+
using NetSparkleUpdater;
5+
using NetSparkleUpdater.Enums;
6+
using NetSparkleUpdater.SignatureVerifiers;
7+
using NetSparkleUpdater.UI.Avalonia;
8+
using Serilog;
9+
using Utils;
10+
11+
namespace ShinRyuModManager.UserInterface.Updater;
12+
13+
public static class AutoUpdating {
14+
private const string GH_PAGES_ROOT = "https://thetruecolonel.github.io/SRMM-AppCast";
15+
16+
private static string _tempDir;
17+
private static SparkleUpdater _updater;
18+
19+
public static void Init() {
20+
_tempDir = Path.Combine(Environment.CurrentDirectory, "srmm_temp");
21+
22+
try {
23+
HandleRyuUpdater();
24+
} catch (Exception ex) {
25+
Log.Error(ex, "Problem trying to download RyuUpdater! Aborting auto updating...");
26+
27+
return;
28+
}
29+
30+
var suffix = AssemblyVersion.GetBuildSuffix();
31+
32+
if (string.Equals(suffix, "debug", StringComparison.OrdinalIgnoreCase)) {
33+
return; // Don't need to be annoyed with "Update Now" when debugging
34+
}
35+
36+
var appcastUrl = $"{GH_PAGES_ROOT}/releases/appcast_{suffix}.xml";
37+
38+
// Update check for SRMM
39+
_updater = new PortableUpdater(appcastUrl, new Ed25519Checker(SecurityMode.Unsafe)) {
40+
UIFactory = new UIFactory {
41+
HideReleaseNotes = true,
42+
UseStaticUpdateWindowBackgroundColor = true,
43+
UpdateWindowGridBackgroundBrush = new ImmutableSolidColorBrush(Color.Parse("#373535"))
44+
},
45+
TmpDownloadFilePath = _tempDir,
46+
TmpDownloadFileNameWithExtension = $"{Guid.NewGuid()}.zip",
47+
RelaunchAfterUpdate = false,
48+
LogWriter = new SerilogWriter()
49+
};
50+
51+
_ = _updater.StartLoop(true, TimeSpan.FromMinutes(5));
52+
}
53+
54+
private static void HandleRyuUpdater() {
55+
string ryuUpdaterPath;
56+
string updaterAppcastUrl;
57+
string updaterLatestUrl;
58+
59+
if (OperatingSystem.IsWindows()) {
60+
ryuUpdaterPath = Path.Combine(Environment.CurrentDirectory, "RyuUpdater.exe");
61+
updaterAppcastUrl = $"{GH_PAGES_ROOT}/releases/appcast_ryuupdater-windows.xml";
62+
updaterLatestUrl = $"{GH_PAGES_ROOT}/updater/RyuUpdater-Windows-Latest.zip";
63+
} else {
64+
ryuUpdaterPath = Path.Combine(Environment.CurrentDirectory, "RyuUpdater");
65+
updaterAppcastUrl = $"{GH_PAGES_ROOT}/releases/appcast_ryuupdater-linux.xml";
66+
updaterLatestUrl = $"{GH_PAGES_ROOT}/updater/RyuUpdater-Linux-Latest.zip";
67+
}
68+
69+
// Pull grab latest version of updater if missing
70+
if (!File.Exists(ryuUpdaterPath)) {
71+
using var downloadStream = Utils.Client.GetStreamAsync(updaterLatestUrl).GetAwaiter().GetResult();
72+
73+
ZipFile.ExtractToDirectory(downloadStream, Environment.CurrentDirectory, overwriteFiles: true);
74+
}
75+
76+
// TODO: Linux doesn't store the required information for this to work on compiled binaries. To come back to.
77+
/*// Update RyuUpdater quietly
78+
var ryuUpdater = new RyuUpdaterUpdater(updaterAppcastUrl, new Ed25519Checker(SecurityMode.Unsafe), ryuUpdaterPath) {
79+
UserInteractionMode = UserInteractionMode.DownloadAndInstall,
80+
UIFactory = null,
81+
TmpDownloadFilePath = _tempDir,
82+
TmpDownloadFileNameWithExtension = $"{Guid.NewGuid()}.zip"
83+
};
84+
_ = ryuUpdater.StartLoop(true);*/
85+
}
86+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
using System.Diagnostics;
2+
using NetSparkleUpdater;
3+
using NetSparkleUpdater.Interfaces;
4+
5+
namespace ShinRyuModManager.UserInterface.Updater;
6+
7+
public sealed class PortableUpdater : SparkleUpdater {
8+
public PortableUpdater(string appcastUrl, ISignatureVerifier signatureVerifier) : base(appcastUrl, signatureVerifier) { }
9+
10+
protected override Task RunDownloadedInstaller(string downloadFilePath) {
11+
var ryuPath = Path.Combine(Environment.CurrentDirectory, "RyuUpdater");
12+
13+
using var currentProcess = Process.GetCurrentProcess();
14+
15+
var pid = Environment.ProcessId;
16+
var name = currentProcess.ProcessName;
17+
18+
Process.Start(new ProcessStartInfo {
19+
FileName = ryuPath,
20+
ArgumentList = {
21+
pid.ToString(),
22+
downloadFilePath,
23+
Environment.CurrentDirectory,
24+
name
25+
},
26+
UseShellExecute = false,
27+
});
28+
29+
Environment.Exit(0x55504454); //UPDT
30+
31+
return Task.CompletedTask;
32+
}
33+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.IO.Compression;
2+
using NetSparkleUpdater;
3+
using NetSparkleUpdater.Interfaces;
4+
5+
namespace ShinRyuModManager.UserInterface.Updater;
6+
7+
public class RyuUpdaterUpdater : SparkleUpdater {
8+
public RyuUpdaterUpdater(string appcastUrl, ISignatureVerifier signatureVerifier) : base(appcastUrl, signatureVerifier) { }
9+
public RyuUpdaterUpdater(string appcastUrl, ISignatureVerifier signatureVerifier, string referenceAssembly) : base(appcastUrl, signatureVerifier, referenceAssembly, null) { }
10+
public RyuUpdaterUpdater(string appcastUrl, ISignatureVerifier signatureVerifier, string referenceAssembly, IUIFactory factory) : base(appcastUrl, signatureVerifier, referenceAssembly, factory) { }
11+
12+
protected override Task RunDownloadedInstaller(string downloadFilePath) {
13+
ZipFile.ExtractToDirectory(downloadFilePath, Environment.CurrentDirectory, overwriteFiles: true);
14+
15+
return Task.CompletedTask;
16+
}
17+
}

0 commit comments

Comments
 (0)