improvements & deployment

This commit is contained in:
2025-11-08 15:46:56 +01:00
parent 11b76ee73b
commit 065d915d46
10 changed files with 173 additions and 112 deletions

16
Directory.Build.props Normal file
View File

@@ -0,0 +1,16 @@
<Project>
<PropertyGroup>
<PackageProjectUrl>https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<GenerateSerializationAssemblies>False</GenerateSerializationAssemblies>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<NoWarn>1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
</PropertyGroup>
</Project>

View File

@@ -1,83 +0,0 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Pilz.Extensions;
using System.Reflection;
namespace ModpackUpdater.Apps.Client.Gui;
public class AppUpdater(string updateUrl)
{
private class UpdateInfo
{
[JsonConverter(typeof(VersionConverter))]
public Version? Version { get; set; }
public string? DownloadUrl { get; set; }
}
private readonly HttpClient httpClient = new();
private UpdateInfo? info;
public async Task<bool> Check()
{
var hasUpdate = false;
try
{
var appVersion = Assembly.GetExecutingAssembly().GetAppVersion().Version;
var result = await httpClient.GetStringAsync(updateUrl);
info = JsonConvert.DeserializeObject<UpdateInfo>(result);
if (info is not null && info.Version > appVersion)
hasUpdate = true;
}
catch
{
}
return hasUpdate;
}
public async Task Install()
{
var client = new HttpClient();
var tempFileName = Path.GetTempFileName();
var appFileName = Environment.ProcessPath;
var oldFileName = appFileName + ".old";
// Delete old file
try
{
File.Delete(oldFileName);
}
catch
{
}
// Download the new file
await using (var tempFileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite))
{
Stream? downloadStream = null;
try
{
var url = info?.DownloadUrl;
downloadStream = await client.GetStreamAsync(url);
await downloadStream.CopyToAsync(tempFileStream);
}
catch
{
}
finally
{
if (downloadStream != null)
await downloadStream.DisposeAsync();
}
}
// Replace current application file with new file
if (!string.IsNullOrWhiteSpace(appFileName))
{
File.Move(appFileName, oldFileName, true);
File.Move(tempFileName, appFileName);
}
}
}

View File

@@ -6,7 +6,9 @@
xmlns:pilz="https://git.pilzinsel64.de/pilz-framework/pilz" xmlns:pilz="https://git.pilzinsel64.de/pilz-framework/pilz"
mc:Ignorable="d" mc:Ignorable="d"
x:Class="ModpackUpdater.Apps.Client.Gui.MainForm" x:Class="ModpackUpdater.Apps.Client.Gui.MainForm"
SizeToContent="WidthAndHeight" Width="520"
SizeToContent="Height"
WindowStartupLocation="CenterScreen"
Title="Minecraft Modpack Updater" Title="Minecraft Modpack Updater"
Icon="/Assets/app.ico" Icon="/Assets/app.ico"
> >
@@ -21,9 +23,9 @@
> >
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" MinWidth="300"/> <ColumnDefinition Width="*" MinWidth="250"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- Labels --> <!-- Labels -->
@@ -31,10 +33,10 @@
<Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.ModpackConfigUrl}" /> <Label Grid.Row="1" Grid.Column="0" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.ModpackConfigUrl}" />
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" IsVisible="false" x:Name="LabelInstallKey" Content="{x:Static lang:GeneralLangRes.InstallationKey}" /> <Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" IsVisible="false" x:Name="LabelInstallKey" Content="{x:Static lang:GeneralLangRes.InstallationKey}" />
<Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.Status}" /> <Label Grid.Row="3" Grid.Column="0" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.Status}" />
<Label Grid.Row="3" Grid.Column="1" VerticalAlignment="Center"> <Label Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal" Spacing="6">
<Image Width="16" Height="16" x:Name="ImageStatus" /> <Image Width="16" Height="16" x:Name="ImageStatus" />
<TextBlock Margin="3, 0, 0, 0" x:Name="TextStatus" /> <TextBlock x:Name="TextStatus" />
</StackPanel> </StackPanel>
</Label> </Label>
@@ -45,7 +47,7 @@
Grid.Column="1" Grid.Column="1"
VerticalAlignment="Center" VerticalAlignment="Center"
Watermark="C:\..." Watermark="C:\..."
TextInput="TextBoxMinecraftProfileFolder_TextInserted" TextChanged="TextBoxMinecraftProfileFolder_TextChanged"
/> />
<!-- TextBoxes: ModpackConfig --> <!-- TextBoxes: ModpackConfig -->
@@ -56,7 +58,7 @@
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
VerticalAlignment="Center" VerticalAlignment="Center"
Watermark="https://..." Watermark="https://..."
TextInput="TextBoxModpackConfig_TextInserted" TextChanged="TextBoxModpackConfig_TextChanged"
/> />
<!-- TextBoxes: InstallKey --> <!-- TextBoxes: InstallKey -->
@@ -67,7 +69,7 @@
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
VerticalAlignment="Center" VerticalAlignment="Center"
Watermark="XXXXX-YYYYY-ZZZZZ-AAAAA-BBBBB" Watermark="XXXXX-YYYYY-ZZZZZ-AAAAA-BBBBB"
TextInput="TextBoxInstallKey_TextInserted" TextChanged="TextBoxInstallKey_TextChanged"
IsVisible="false" IsVisible="false"
/> />

View File

@@ -1,17 +1,21 @@
using Avalonia.Controls; using System.Diagnostics;
using System.Reflection;
using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Threading;
using ModpackUpdater.Apps.Client.Gui.LangRes; using ModpackUpdater.Apps.Client.Gui.LangRes;
using ModpackUpdater.Manager; using ModpackUpdater.Manager;
using MsBox.Avalonia; using MsBox.Avalonia;
using MsBox.Avalonia.Enums; using MsBox.Avalonia.Enums;
using Pilz;
using Pilz.Extensions; using Pilz.Extensions;
using Pilz.Runtime;
using Pilz.SymbolPacks.Sets; using Pilz.SymbolPacks.Sets;
using Pilz.UI.AvaloniaUI.Symbols; using Pilz.UI.AvaloniaUI.Symbols;
using System.Diagnostics;
using System.Reflection;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.Updating.Client;
namespace ModpackUpdater.Apps.Client.Gui; namespace ModpackUpdater.Apps.Client.Gui;
@@ -66,7 +70,7 @@ public partial class MainForm : Window
TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text; TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text;
TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text; TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text;
loadingData = false; Dispatcher.UIThread.Post(() => loadingData = false, DispatcherPriority.Background);
} }
private void LoadOptionsToUi() private void LoadOptionsToUi()
@@ -91,6 +95,7 @@ public partial class MainForm : Window
} }
catch catch
{ {
// Ignore
} }
if (loadProfileToUi) if (loadProfileToUi)
@@ -100,8 +105,9 @@ public partial class MainForm : Window
{ {
updateConfig = ModpackConfig.LoadFromUrl(TextBoxModpackConfig.Text); updateConfig = ModpackConfig.LoadFromUrl(TextBoxModpackConfig.Text);
} }
catch (Exception) catch
{ {
// Ignore
} }
if (modpackInfo != null) if (modpackInfo != null)
@@ -260,31 +266,45 @@ public partial class MainForm : Window
private async void MainForm_Loaded(object? sender, RoutedEventArgs e) private async void MainForm_Loaded(object? sender, RoutedEventArgs e)
{ {
var updater = new AppUpdater(Program.UpdateUrl); #if !DISABLE_UPDATE
if (await updater.Check() && await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, MsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo).ShowWindowDialogAsync(this) == ButtonResult.Ok) var myAppPath = EnvironmentEx.ProcessPath;
var updater = new UpdateClient(Program.UpdateUrl, Assembly.GetEntryAssembly()!.GetAppVersion(), AppChannel.Stable)
{
Distro = RuntimeInformationsEx.GetRuntimeIdentifier(),
};
if (await updater.CheckForUpdate() is {} packageToInstall
&& await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, MsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo).ShowWindowDialogAsync(this) == ButtonResult.Ok)
{ {
SetStatus(GeneralLangRes.DownloadProgramUpdate, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); SetStatus(GeneralLangRes.DownloadProgramUpdate, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer));
IsEnabled = false; IsEnabled = false;
await updater.Install(); if (await updater.DownloadPackageAsync(packageToInstall)
//Application.Restart(); // FIXME && await updater.InstallPackageAsync(packageToInstall, myAppPath))
return; {
Process.Start(myAppPath);
Environment.Exit(0);
return;
}
IsEnabled = true;
} }
#endif
CheckStatusAndUpdate(true); CheckStatusAndUpdate(true);
} }
private void TextBoxMinecraftProfileFolder_TextInserted(object? o, Avalonia.Input.TextInputEventArgs args) private void TextBoxMinecraftProfileFolder_TextChanged(object? o, TextChangedEventArgs args)
{ {
if (!loadingData) if (!loadingData)
CheckStatusAndUpdate(true); CheckStatusAndUpdate(true);
} }
private void TextBoxModpackConfig_TextInserted(object? o, Avalonia.Input.TextInputEventArgs args) private void TextBoxModpackConfig_TextChanged(object? o, RoutedEventArgs args)
{ {
if (!loadingData) if (!loadingData)
CheckStatusAndUpdate(false); CheckStatusAndUpdate(false);
} }
private void TextBoxInstallKey_TextInserted(object? o, Avalonia.Input.TextInputEventArgs args) private void TextBoxInstallKey_TextChanged(object? o, RoutedEventArgs args)
{ {
if (!loadingData) if (!loadingData)
CheckStatusAndUpdate(false); CheckStatusAndUpdate(false);
@@ -300,7 +320,7 @@ public partial class MainForm : Window
}); });
if (filePaths.Count >= 1) if (filePaths.Count >= 1)
TextBoxMinecraftProfileFolder.Text = filePaths[0].Path.ToString(); TextBoxMinecraftProfileFolder.Text = filePaths[0].Path.AbsolutePath;
} }
private async void ButtonCheckForUpdates_Click(object? sender, RoutedEventArgs e) private async void ButtonCheckForUpdates_Click(object? sender, RoutedEventArgs e)

View File

@@ -1,10 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ApplicationIcon>Assets/app.ico</ApplicationIcon> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<AssemblyName>Minecraft Modpack Updater</AssemblyName> <AssemblyName>MinecraftModpackUpdater</AssemblyName>
<ImplicitUsings>true</ImplicitUsings> <ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
@@ -13,6 +13,11 @@
<LangVersion>latest</LangVersion> <LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<TrimmerRootAssembly Include="Newtonsoft.Json" />
<TrimmerRootAssembly Include="Pilz.SymbolPacks.Fluent" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Version.cs" /> <Compile Include="..\Version.cs" />
</ItemGroup> </ItemGroup>
@@ -58,6 +63,7 @@
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" /> <PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
<PackageReference Include="Mono.Options" Version="6.12.0.148" /> <PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Pilz" Version="2.6.0" />
<PackageReference Include="Pilz.Configuration" Version="3.2.7" /> <PackageReference Include="Pilz.Configuration" Version="3.2.7" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" /> <PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.IO" Version="2.1.0" /> <PackageReference Include="Pilz.IO" Version="2.1.0" />
@@ -74,6 +80,8 @@
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets> <IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets> <PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Pilz.Updating" Version="4.3.4" />
<PackageReference Include="Pilz.Updating.Client" Version="4.4.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -7,7 +7,7 @@ namespace ModpackUpdater.Apps.Client.Gui;
public static class Program public static class Program
{ {
public const string UpdateUrl = "https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater/-/snippets/3/raw/main/updates.json"; public const string UpdateUrl = "https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater/-/snippets/3/raw/main/updates-new.json";
private static readonly SettingsManager settingsManager; private static readonly SettingsManager settingsManager;

View File

@@ -0,0 +1,89 @@
# PUPNET DEPLOY: 1.9.1
# Use: 'pupnet --help conf' for information.
# APP PREAMBLE
AppBaseName = MinecraftModpackUpdater
AppFriendlyName = Minecraft Modpack Updater
AppId = de.pilzinsel64.minecraft-modpack-updater
AppVersionRelease = 1.10.0[1]
AppShortSummary = Install and Update Minecraft Modpacks easliy.
AppDescription = """
Minecraft Modpack Updater is a simple tool to install and update a modpack to a selected minecraft profile by a selected modpack configuration file. It downloads a config file via https and checks the version there and what files has been changed and download the updateded files via a given link from the config.
"""
AppLicenseId = MIT
AppLicenseFile = ../LICENSE
AppChangeFile =
# PUBLISHER
PublisherName = Pilzinsel64
PublisherId = de.pilzinsel64
PublisherCopyright = Copyright (C) Pilzinsel64 2025
PublisherLinkName = Pilzinsel64 Homepage
PublisherLinkUrl = https://pilzinsel64.de
PublisherEmail =
# DESKTOP INTEGRATION
DesktopNoDisplay = false
DesktopTerminal = false
DesktopFile =
StartCommand =
PrimeCategory =
MetaFile =
IconFiles = """
Assets/app.ico
Assets/app.svg
"""
# DOTNET PUBLISH
DotnetProjectPath = ModpackUpdater.Apps.Client.Gui.csproj
DotnetPublishArgs = -p:Version=${APP_VERSION} --self-contained true -p:DebugType=None -p:DebugSymbols=false -p:PublishSingleFile=true -p:PublishTrimmed=false
DotnetPostPublish =
DotnetPostPublishOnWindows =
# PACKAGE OUTPUT
PackageName = minecraft-modpack-updater
OutputDirectory = ../publish/client-ui
# APPIMAGE OPTIONS
AppImageArgs =
AppImageRuntimePath =
AppImageVersionOutput = false
# FLATPAK OPTIONS
FlatpakPlatformRuntime = org.freedesktop.Platform
FlatpakPlatformSdk = org.freedesktop.Sdk
FlatpakPlatformVersion = 25.08
FlatpakFinishArgs = """
--socket=x11
"""
FlatpakBuilderArgs =
# RPM OPTIONS
RpmAutoReq = false
RpmAutoProv = true
RpmRequires = """
krb5-libs
libicu
openssl-libs
"""
# DEBIAN OPTIONS
DebianRecommends = """
libc6
libgcc1
libgssapi-krb5-2
libicu70
libssl3
libstdc++6
zlib1g
"""
# WINDOWS SETUP OPTIONS
SetupGroupName =
SetupAdminInstall = false
SetupCommandPrompt =
SetupMinWindowsVersion = 10
SetupSignTool =
SetupSuffixOutput =
SetupVersionOutput = false
SetupUninstallScript =

View File

@@ -1,3 +1,3 @@
using Pilz; using Pilz;
[assembly: AssemblyAppVersion("1.9.5.0")] [assembly: AssemblyAppVersion("1.10.0")]

9
publish.sh Executable file
View File

@@ -0,0 +1,9 @@
pupnet -y -r linux-x64 -k appimage
pupnet -y -r linux-x64 -k flatpak -p DefineConstants=DISABLE_UPDATE
#pupnet -y -r linux-x64 -k deb -p DefineConstants=DISABLE_UPDATE
#pupnet -y -r linux-x64 -k rpm -p DefineConstants=DISABLE_UPDATE
pupnet -y -r linux-arm64 -k appimage
pupnet -y -r linux-arm64 -k flatpak -p DefineConstants=DISABLE_UPDATE
#pupnet -y -r linux-arm64 -k deb -p DefineConstants=DISABLE_UPDATE
#pupnet -y -r linux-arm64 -k rpm -p DefineConstants=DISABLE_UPDATE
pupnet -y -r win-x64 -k zip