28 Commits

Author SHA1 Message Date
2edbcf72c7 fixes for client cli publish script 2025-11-09 14:18:50 +01:00
19b9a64721 fix missing version 2025-11-09 14:17:31 +01:00
ec6830e636 also add the new file !!!! 2025-11-09 14:16:06 +01:00
9a5c70581b build also cli 2025-11-09 14:15:53 +01:00
a6175b3874 ui(client) also publish win-arm64, osx-x64, osx-arm64 2025-11-09 14:04:24 +01:00
27ce41e0d1 ui(client): disable flatpak build 2025-11-09 13:59:30 +01:00
574a8d5ec2 final fix 2025-11-09 13:58:43 +01:00
d570d29c92 update nuget packages 2025-11-09 13:43:20 +01:00
562ce27341 ui(client): optimize installation key caching & show invalid key hint 2025-11-09 08:40:18 +01:00
463c2bbf2b ui(client): use Margin instead of RowSpacing and ColumnSpacing
-> fixes visible spacing of invisible rows
2025-11-09 08:11:27 +01:00
145a5771a1 ignore .idea 2025-11-08 22:51:12 +01:00
3adfcda472 update 2025-11-08 22:50:45 +01:00
078d5c0661 version improvement 2025-11-08 22:49:46 +01:00
06db3289c0 fix home share permission 2025-11-08 18:40:51 +01:00
a573f4fb89 fix release build 2025-11-08 18:36:45 +01:00
091d820332 fix build 2025-11-08 18:29:04 +01:00
1d44f93a92 enable network & home directory access for flatpak 2025-11-08 18:17:13 +01:00
3de764b833 fixes 2025-11-08 17:31:17 +01:00
3e6b70bc4c fixes 2025-11-08 16:36:40 +01:00
065d915d46 improvements & deployment 2025-11-08 15:46:56 +01:00
11b76ee73b add license 2025-11-08 11:33:29 +00:00
1c070891f1 ui(client): formatting & code improvements 2025-11-07 15:22:28 +01:00
4baf571713 Merge branch 'feat/migrate-client-to-avalonia' into 'master'
Feat/migrate client to avalonia

See merge request litw-refined/minecraft-modpack-updater!2
2025-11-07 13:58:36 +00:00
Pascal
b899d2ee7d ui(client): improvements 2025-11-07 10:45:55 +01:00
Pascal
05b94a3189 migrate to Pilz.Features 2025-11-06 12:20:03 +01:00
Pascal
6a6fd7efe6 ui(client): translation 2025-11-06 11:42:08 +01:00
Pascal
a89145071d ui(client): migrate to AvaloniaUI 2025-11-06 07:42:44 +01:00
554304c801 version bump, again 2025-08-23 09:28:24 +02:00
52 changed files with 1344 additions and 2952 deletions

2
.gitignore vendored
View File

@@ -349,3 +349,5 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder # Ionide (cross platform F# VS Code tools) working folder
.ionide/ .ionide/
*.json *.json
.idea/

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>

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Pilzinsel64
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -7,7 +7,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<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" />
</ItemGroup> </ItemGroup>

View File

@@ -0,0 +1,10 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ModpackUpdater.Apps.Client.Gui.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Styles>
<FluentTheme />
</Application.Styles>
</Application>

View File

@@ -0,0 +1,20 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
namespace ModpackUpdater.Apps.Client.Gui;
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
desktop.MainWindow = new MainForm();
base.OnFrameworkInitializationCompleted();
}
}

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="TelerikWinFormsThemeName" value="Windows11CompactDark" />
</appSettings>
</configuration>

View File

@@ -7,10 +7,10 @@ public class AppConfig : ISettingsNode, ISettingsIdentifier
{ {
public static string Identifier => "pilz.appconfig"; public static string Identifier => "pilz.appconfig";
public string LastMinecraftProfilePath { get; set; } public string? LastMinecraftProfilePath { get; set; }
[JsonIgnore, Obsolete] [JsonIgnore, Obsolete]
public string ConfigFilePath { get; private set; } public string? ConfigFilePath { get; private set; }
[JsonProperty("ConfigFilePath"), Obsolete] [JsonProperty("ConfigFilePath"), Obsolete]
private string ConfigFilePathLegacy private string ConfigFilePathLegacy
{ {

View File

@@ -1,82 +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
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
{
downloadStream?.Dispose();
}
}
// Replace current application file with new file
if (!string.IsNullOrWhiteSpace(appFileName))
{
File.Move(appFileName, oldFileName, true);
File.Move(tempFileName, appFileName);
}
}
}

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -8,7 +8,7 @@
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
namespace ModpackUpdater.My.Resources { namespace ModpackUpdater.Apps.Client.Gui {
using System; using System;

View File

@@ -1,162 +0,0 @@
//------------------------------------------------------------------------------
// <auto-generated>
// Dieser Code wurde von einem Tool generiert.
// Laufzeitversion:4.0.30319.42000
//
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
// der Code erneut generiert wird.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.My.Resources {
using System;
/// <summary>
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
/// </summary>
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class LangRes {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal LangRes() {
}
/// <summary>
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Client.Gui.LangRes", typeof(LangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die A new version of this program is available. If you confirm, the update will be installed automatically. It takes just a few seconds. Continue? ähnelt.
/// </summary>
internal static string MsgBox_UpdateAvailable {
get {
return ResourceManager.GetString("MsgBox_UpdateAvailable", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die New program version available ähnelt.
/// </summary>
internal static string MsgBox_UpdateAvailable_Title {
get {
return ResourceManager.GetString("MsgBox_UpdateAvailable_Title", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Everything is right and up-to-date. ähnelt.
/// </summary>
internal static string StatusTest_EverythingOk {
get {
return ResourceManager.GetString("StatusTest_EverythingOk", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Checking for Updates... ähnelt.
/// </summary>
internal static string StatusText_CheckingForUpdates {
get {
return ResourceManager.GetString("StatusText_CheckingForUpdates", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Config incomplete or not loaded! ähnelt.
/// </summary>
internal static string StatusText_ConfigIncompleteOrNotLoaded {
get {
return ResourceManager.GetString("StatusText_ConfigIncompleteOrNotLoaded", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Error on update check or while updating! ähnelt.
/// </summary>
internal static string StatusText_ErrorWhileUpdateCheckOrUpdate {
get {
return ResourceManager.GetString("StatusText_ErrorWhileUpdateCheckOrUpdate", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Installing... ähnelt.
/// </summary>
internal static string StatusText_Installing {
get {
return ResourceManager.GetString("StatusText_Installing", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Downloading program update... ähnelt.
/// </summary>
internal static string StatusText_InstallingAppUpdate {
get {
return ResourceManager.GetString("StatusText_InstallingAppUpdate", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The update servers are in maintenance. ähnelt.
/// </summary>
internal static string StatusText_Maintenance {
get {
return ResourceManager.GetString("StatusText_Maintenance", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Minecraft profile folder seems to be not valid. ähnelt.
/// </summary>
internal static string StatusText_MinecraftProfileWarning {
get {
return ResourceManager.GetString("StatusText_MinecraftProfileWarning", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die An update is available! ähnelt.
/// </summary>
internal static string StatusText_UpdateAvailable {
get {
return ResourceManager.GetString("StatusText_UpdateAvailable", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,162 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Client.Gui.LangRes {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class GeneralLangRes {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal GeneralLangRes() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Client.Gui.LangRes.GeneralLangRes", typeof(GeneralLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
public static string AnUpdateIsAvailable {
get {
return ResourceManager.GetString("AnUpdateIsAvailable", resourceCulture);
}
}
public static string CheckForUpdates {
get {
return ResourceManager.GetString("CheckForUpdates", resourceCulture);
}
}
public static string CheckingForUpdates {
get {
return ResourceManager.GetString("CheckingForUpdates", resourceCulture);
}
}
public static string ConfigIncompleteOrNotLoaded {
get {
return ResourceManager.GetString("ConfigIncompleteOrNotLoaded", resourceCulture);
}
}
public static string DownloadProgramUpdate {
get {
return ResourceManager.GetString("DownloadProgramUpdate", resourceCulture);
}
}
public static string ErrorOnUpdateCheckOrUpdating {
get {
return ResourceManager.GetString("ErrorOnUpdateCheckOrUpdating", resourceCulture);
}
}
public static string EverythingIsRightAndUpToDate {
get {
return ResourceManager.GetString("EverythingIsRightAndUpToDate", resourceCulture);
}
}
public static string Install {
get {
return ResourceManager.GetString("Install", resourceCulture);
}
}
public static string InstallationKey {
get {
return ResourceManager.GetString("InstallationKey", resourceCulture);
}
}
public static string Installing {
get {
return ResourceManager.GetString("Installing", resourceCulture);
}
}
public static string MinecraftProfile {
get {
return ResourceManager.GetString("MinecraftProfile", resourceCulture);
}
}
public static string MinecraftProfileFolderSeemsInvalid {
get {
return ResourceManager.GetString("MinecraftProfileFolderSeemsInvalid", resourceCulture);
}
}
public static string ModpackConfigUrl {
get {
return ResourceManager.GetString("ModpackConfigUrl", resourceCulture);
}
}
public static string Repair {
get {
return ResourceManager.GetString("Repair", resourceCulture);
}
}
public static string Select {
get {
return ResourceManager.GetString("Select", resourceCulture);
}
}
public static string SelectMinecraftProfileFolder {
get {
return ResourceManager.GetString("SelectMinecraftProfileFolder", resourceCulture);
}
}
public static string Status {
get {
return ResourceManager.GetString("Status", resourceCulture);
}
}
public static string UpdateServerInMaintenance {
get {
return ResourceManager.GetString("UpdateServerInMaintenance", resourceCulture);
}
}
public static string InstallationKeyNotValid {
get {
return ResourceManager.GetString("InstallationKeyNotValid", resourceCulture);
}
}
}
}

View File

@@ -117,37 +117,61 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="MsgBox_UpdateAvailable" xml:space="preserve"> <data name="AnUpdateIsAvailable" xml:space="preserve">
<value>A new version of this program is available. If you confirm, the update will be installed automatically. It takes just a few seconds. Continue?</value>
</data>
<data name="MsgBox_UpdateAvailable_Title" xml:space="preserve">
<value>New program version available</value>
</data>
<data name="StatusTest_EverythingOk" xml:space="preserve">
<value>Everything is right and up-to-date.</value>
</data>
<data name="StatusText_CheckingForUpdates" xml:space="preserve">
<value>Checking for Updates...</value>
</data>
<data name="StatusText_ConfigIncompleteOrNotLoaded" xml:space="preserve">
<value>Config incomplete or not loaded!</value>
</data>
<data name="StatusText_ErrorWhileUpdateCheckOrUpdate" xml:space="preserve">
<value>Error on update check or while updating!</value>
</data>
<data name="StatusText_Installing" xml:space="preserve">
<value>Installing...</value>
</data>
<data name="StatusText_InstallingAppUpdate" xml:space="preserve">
<value>Downloading program update...</value>
</data>
<data name="StatusText_Maintenance" xml:space="preserve">
<value>The update servers are in maintenance.</value>
</data>
<data name="StatusText_MinecraftProfileWarning" xml:space="preserve">
<value>Minecraft profile folder seems to be not valid.</value>
</data>
<data name="StatusText_UpdateAvailable" xml:space="preserve">
<value>An update is available!</value> <value>An update is available!</value>
</data> </data>
<data name="CheckForUpdates" xml:space="preserve">
<value>Check for updates</value>
</data>
<data name="CheckingForUpdates" xml:space="preserve">
<value>Checking for Updates...</value>
</data>
<data name="ConfigIncompleteOrNotLoaded" xml:space="preserve">
<value>Config incomplete or not loaded!</value>
</data>
<data name="DownloadProgramUpdate" xml:space="preserve">
<value>Downloading program update...</value>
</data>
<data name="ErrorOnUpdateCheckOrUpdating" xml:space="preserve">
<value>Error on update check or while updating!</value>
</data>
<data name="EverythingIsRightAndUpToDate" xml:space="preserve">
<value>Everything is right and up-to-date.</value>
</data>
<data name="Install" xml:space="preserve">
<value>Install</value>
</data>
<data name="InstallationKey" xml:space="preserve">
<value>Installation key</value>
</data>
<data name="Installing" xml:space="preserve">
<value>Installing...</value>
</data>
<data name="MinecraftProfile" xml:space="preserve">
<value>Minecraft profile</value>
</data>
<data name="MinecraftProfileFolderSeemsInvalid" xml:space="preserve">
<value>Minecraft profile folder seems to be not valid.</value>
</data>
<data name="ModpackConfigUrl" xml:space="preserve">
<value>Modpack config url</value>
</data>
<data name="Repair" xml:space="preserve">
<value>Repair</value>
</data>
<data name="Select" xml:space="preserve">
<value>Select</value>
</data>
<data name="SelectMinecraftProfileFolder" xml:space="preserve">
<value>Select the minecraft profile folder (usually named .minecraft)</value>
</data>
<data name="Status" xml:space="preserve">
<value>Status</value>
</data>
<data name="UpdateServerInMaintenance" xml:space="preserve">
<value>The update servers are in maintenance.</value>
</data>
<data name="InstallationKeyNotValid" xml:space="preserve">
<value>Installation key seems to be invalid</value>
</data>
</root> </root>

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Client.Gui.LangRes {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
public class MsgBoxLangRes {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal MsgBoxLangRes() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Client.Gui.LangRes.MsgBoxLangRes", typeof(MsgBoxLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
public static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
public static string UpdateAvailable {
get {
return ResourceManager.GetString("UpdateAvailable", resourceCulture);
}
}
public static string UpdateAvailable_Title {
get {
return ResourceManager.GetString("UpdateAvailable_Title", resourceCulture);
}
}
public static string ErrorWhileUpdate_Title {
get {
return ResourceManager.GetString("ErrorWhileUpdate_Title", resourceCulture);
}
}
public static string ErrorWhileUpdate {
get {
return ResourceManager.GetString("ErrorWhileUpdate", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,133 @@
<?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>
<data name="UpdateAvailable" xml:space="preserve">
<value>A new version of this program is available! Install now?
If you confirm, the update will be installed automatically within a few seconds.</value>
</data>
<data name="UpdateAvailable_Title" xml:space="preserve">
<value>New program version available</value>
</data>
<data name="ErrorWhileUpdate_Title" xml:space="preserve">
<value>Error while updating</value>
</data>
<data name="ErrorWhileUpdate" xml:space="preserve">
<value>An error happened while updating the program. Error message:\n{0}</value>
</data>
</root>

View File

@@ -1,288 +0,0 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace ModpackUpdater.Apps.Client.Gui
{
[Microsoft.VisualBasic.CompilerServices.DesignerGenerated()]
public partial class MainForm : Telerik.WinControls.UI.RadForm
{
// Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
[DebuggerNonUserCode()]
protected override void Dispose(bool disposing)
{
try
{
if (disposing && components is not null)
components.Dispose();
}
finally
{
base.Dispose(disposing);
}
}
// Wird vom Windows Form-Designer benötigt.
private System.ComponentModel.IContainer components = new System.ComponentModel.Container();
// Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
// Das Bearbeiten ist mit dem Windows Form-Designer möglich.
// Das Bearbeiten mit dem Code-Editor ist nicht möglich.
[DebuggerStepThrough()]
private void InitializeComponent()
{
var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
RadLabel_MinecraftProfile = new Telerik.WinControls.UI.RadLabel();
RadLabel_ModpackUrl = new Telerik.WinControls.UI.RadLabel();
RadTextBox_MinecraftProfileFolder = new Telerik.WinControls.UI.RadTextBoxControl();
RadTextBox_ModpackConfig = new Telerik.WinControls.UI.RadTextBoxControl();
RadButton_Install = new Telerik.WinControls.UI.RadSplitButton();
radMenuItem_Install = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_Repair = new Telerik.WinControls.UI.RadMenuItem();
RadButton_CheckForUpdates = new Telerik.WinControls.UI.RadButton();
RadButton_SearchMinecraftProfileFolder = new Telerik.WinControls.UI.RadButton();
tableLayoutPanel1 = new TableLayoutPanel();
RadLabel_Status = new Telerik.WinControls.UI.RadLabel();
RadLabel_StatusDesc = new Telerik.WinControls.UI.RadLabel();
radLabel_InstallationKey = new Telerik.WinControls.UI.RadLabel();
radTextBox_InstallKey = new Telerik.WinControls.UI.RadTextBoxControl();
((System.ComponentModel.ISupportInitialize)RadLabel_MinecraftProfile).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel_ModpackUrl).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_MinecraftProfileFolder).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_ModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).BeginInit();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel_StatusDesc).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel_InstallationKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout();
//
// RadLabel_MinecraftProfile
//
RadLabel_MinecraftProfile.Anchor = AnchorStyles.Left;
RadLabel_MinecraftProfile.Location = new Point(3, 6);
RadLabel_MinecraftProfile.Name = "RadLabel_MinecraftProfile";
RadLabel_MinecraftProfile.Size = new Size(89, 18);
RadLabel_MinecraftProfile.TabIndex = 0;
RadLabel_MinecraftProfile.Text = "Minecraft profile";
//
// RadLabel_ModpackUrl
//
RadLabel_ModpackUrl.Anchor = AnchorStyles.Left;
RadLabel_ModpackUrl.Location = new Point(3, 36);
RadLabel_ModpackUrl.Name = "RadLabel_ModpackUrl";
RadLabel_ModpackUrl.Size = new Size(76, 18);
RadLabel_ModpackUrl.TabIndex = 1;
RadLabel_ModpackUrl.Text = "Modpack URL";
//
// RadTextBox_MinecraftProfileFolder
//
RadTextBox_MinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBox_MinecraftProfileFolder, 3);
RadTextBox_MinecraftProfileFolder.Location = new Point(98, 3);
RadTextBox_MinecraftProfileFolder.Name = "RadTextBox_MinecraftProfileFolder";
RadTextBox_MinecraftProfileFolder.NullText = "C:\\Users\\...\\AppData\\...";
RadTextBox_MinecraftProfileFolder.Size = new Size(221, 24);
RadTextBox_MinecraftProfileFolder.TabIndex = 1;
RadTextBox_MinecraftProfileFolder.TextChanged += RadTextBox_MinecraftFolder_TextInserted;
//
// RadTextBox_ModpackConfig
//
RadTextBox_ModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBox_ModpackConfig, 5);
RadTextBox_ModpackConfig.Location = new Point(98, 33);
RadTextBox_ModpackConfig.Name = "RadTextBox_ModpackConfig";
RadTextBox_ModpackConfig.NullText = "https://...";
RadTextBox_ModpackConfig.Size = new Size(321, 24);
RadTextBox_ModpackConfig.TabIndex = 3;
RadTextBox_ModpackConfig.TextChanged += RadTextBox_ModpackUrl_TextInserted;
//
// RadButton_Install
//
RadButton_Install.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_Install, 2);
RadButton_Install.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_Install.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_Install, radMenuItem_Repair });
RadButton_Install.Location = new Point(325, 121);
RadButton_Install.Name = "RadButton_Install";
RadButton_Install.Size = new Size(94, 24);
RadButton_Install.TabIndex = 0;
RadButton_Install.Text = "Install";
RadButton_Install.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_Install.TextImageRelation = TextImageRelation.ImageBeforeText;
//
// radMenuItem_Install
//
radMenuItem_Install.Name = "radMenuItem_Install";
radMenuItem_Install.Text = "Install";
radMenuItem_Install.Click += RadMenuItem_Install_Click;
//
// radMenuItem_Repair
//
radMenuItem_Repair.Name = "radMenuItem_Repair";
radMenuItem_Repair.Text = "Repair";
radMenuItem_Repair.Click += RadMenuItem_Repair_Click;
//
// RadButton_CheckForUpdates
//
RadButton_CheckForUpdates.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_CheckForUpdates, 3);
RadButton_CheckForUpdates.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_CheckForUpdates.Location = new Point(98, 121);
RadButton_CheckForUpdates.Name = "RadButton_CheckForUpdates";
RadButton_CheckForUpdates.Size = new Size(221, 24);
RadButton_CheckForUpdates.TabIndex = 100;
RadButton_CheckForUpdates.Text = "Check for Updates";
RadButton_CheckForUpdates.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_CheckForUpdates.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_CheckForUpdates.Click += ButtonX_CheckForUpdates_Click;
//
// RadButton_SearchMinecraftProfileFolder
//
RadButton_SearchMinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_SearchMinecraftProfileFolder, 2);
RadButton_SearchMinecraftProfileFolder.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_SearchMinecraftProfileFolder.Location = new Point(325, 3);
RadButton_SearchMinecraftProfileFolder.Name = "RadButton_SearchMinecraftProfileFolder";
RadButton_SearchMinecraftProfileFolder.Size = new Size(94, 24);
RadButton_SearchMinecraftProfileFolder.TabIndex = 2;
RadButton_SearchMinecraftProfileFolder.Text = "Search";
RadButton_SearchMinecraftProfileFolder.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_SearchMinecraftProfileFolder.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_SearchMinecraftProfileFolder.Click += ButtonX_SearchMinecraftProfile_Click;
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel1.ColumnCount = 6;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.Controls.Add(RadLabel_MinecraftProfile, 0, 0);
tableLayoutPanel1.Controls.Add(RadLabel_ModpackUrl, 0, 1);
tableLayoutPanel1.Controls.Add(RadTextBox_MinecraftProfileFolder, 1, 0);
tableLayoutPanel1.Controls.Add(RadTextBox_ModpackConfig, 1, 1);
tableLayoutPanel1.Controls.Add(RadLabel_Status, 1, 3);
tableLayoutPanel1.Controls.Add(RadLabel_StatusDesc, 0, 3);
tableLayoutPanel1.Controls.Add(RadButton_Install, 4, 4);
tableLayoutPanel1.Controls.Add(radLabel_InstallationKey, 0, 2);
tableLayoutPanel1.Controls.Add(radTextBox_InstallKey, 1, 2);
tableLayoutPanel1.Controls.Add(RadButton_CheckForUpdates, 1, 4);
tableLayoutPanel1.Controls.Add(RadButton_SearchMinecraftProfileFolder, 4, 0);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 0);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 5;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(422, 151);
tableLayoutPanel1.TabIndex = 7;
//
// RadLabel_Status
//
RadLabel_Status.Anchor = AnchorStyles.Left;
tableLayoutPanel1.SetColumnSpan(RadLabel_Status, 5);
RadLabel_Status.Location = new Point(98, 95);
RadLabel_Status.Name = "RadLabel_Status";
RadLabel_Status.Size = new Size(11, 18);
RadLabel_Status.TabIndex = 3;
RadLabel_Status.Text = "-";
RadLabel_Status.TextImageRelation = TextImageRelation.ImageBeforeText;
//
// RadLabel_StatusDesc
//
RadLabel_StatusDesc.Anchor = AnchorStyles.Left;
RadLabel_StatusDesc.Location = new Point(3, 93);
RadLabel_StatusDesc.Name = "RadLabel_StatusDesc";
RadLabel_StatusDesc.Size = new Size(46, 22);
RadLabel_StatusDesc.TabIndex = 2;
RadLabel_StatusDesc.Text = "Status";
//
// radLabel_InstallationKey
//
radLabel_InstallationKey.Anchor = AnchorStyles.Left;
radLabel_InstallationKey.Location = new Point(3, 66);
radLabel_InstallationKey.Name = "radLabel_InstallationKey";
radLabel_InstallationKey.Size = new Size(81, 18);
radLabel_InstallationKey.TabIndex = 12;
radLabel_InstallationKey.Text = "Installation key";
radLabel_InstallationKey.Visible = false;
//
// radTextBox_InstallKey
//
radTextBox_InstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radTextBox_InstallKey, 5);
radTextBox_InstallKey.Location = new Point(98, 63);
radTextBox_InstallKey.Name = "radTextBox_InstallKey";
radTextBox_InstallKey.NullText = "AAAAA-BBBBB-CCCCC-DDDDD-EEEEE";
radTextBox_InstallKey.Size = new Size(321, 24);
radTextBox_InstallKey.TabIndex = 4;
radTextBox_InstallKey.Visible = false;
radTextBox_InstallKey.TextChanged += RadTextBox_InstallationKey_TextInserted;
//
// MainForm
//
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
ClientSize = new Size(422, 151);
Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
MinimumSize = new Size(430, 0);
Name = "MainForm";
StartPosition = FormStartPosition.CenterScreen;
Text = "Minecraft Modpack Updater";
FormClosing += Form1_FormClosing;
Load += Form1_Load;
Shown += Form1_Shown;
((System.ComponentModel.ISupportInitialize)RadLabel_MinecraftProfile).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel_ModpackUrl).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_MinecraftProfileFolder).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_ModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).EndInit();
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel_StatusDesc).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel_InstallationKey).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
PerformLayout();
}
internal Telerik.WinControls.UI.RadLabel RadLabel_MinecraftProfile;
internal Telerik.WinControls.UI.RadLabel RadLabel_ModpackUrl;
internal Telerik.WinControls.UI.RadTextBoxControl RadTextBox_MinecraftProfileFolder;
internal Telerik.WinControls.UI.RadTextBoxControl RadTextBox_ModpackConfig;
internal Telerik.WinControls.UI.RadSplitButton RadButton_Install;
internal Telerik.WinControls.UI.RadButton RadButton_CheckForUpdates;
internal Telerik.WinControls.UI.RadButton RadButton_SearchMinecraftProfileFolder;
private TableLayoutPanel tableLayoutPanel1;
internal Telerik.WinControls.UI.RadLabel radLabel_InstallationKey;
internal Telerik.WinControls.UI.RadTextBoxControl radTextBox_InstallKey;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Repair;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Install;
internal Telerik.WinControls.UI.RadLabel RadLabel_Status;
internal Telerik.WinControls.UI.RadLabel RadLabel_StatusDesc;
}
}

View File

@@ -0,0 +1,121 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:lang="clr-namespace:ModpackUpdater.Apps.Client.Gui.LangRes"
xmlns:pilz="https://git.pilzinsel64.de/pilz-framework/pilz"
mc:Ignorable="d"
x:Class="ModpackUpdater.Apps.Client.Gui.MainForm"
Width="520"
SizeToContent="Height"
WindowStartupLocation="CenterScreen"
CanMaximize="false"
Title="Minecraft Modpack Updater"
Icon="/Assets/app.ico"
>
<Grid
RowDefinitions="Auto,Auto,Auto,Auto,Auto"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
x:Name="MainGrid"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" MinWidth="250"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Labels -->
<Label Grid.Row="0" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.MinecraftProfile}" />
<Label Grid.Row="1" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.ModpackConfigUrl}" />
<Label Grid.Row="2" Grid.Column="0" Margin="3" VerticalAlignment="Center" IsVisible="false" x:Name="LabelInstallKey" Content="{x:Static lang:GeneralLangRes.InstallationKey}" />
<Label Grid.Row="3" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.Status}" />
<Label Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="3" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal" Spacing="6">
<Image Width="16" Height="16" x:Name="ImageStatus" />
<TextBlock x:Name="TextStatus" />
</StackPanel>
</Label>
<!-- TextBoxes: Profile -->
<TextBox
x:Name="TextBoxMinecraftProfileFolder"
Grid.Row="0"
Grid.Column="1"
Margin="3"
VerticalAlignment="Center"
Watermark="C:\..."
TextChanged="TextBoxMinecraftProfileFolder_TextChanged"
/>
<!-- TextBoxes: ModpackConfig -->
<TextBox
x:Name="TextBoxModpackConfig"
Grid.Row="1"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="3"
VerticalAlignment="Center"
Watermark="https://..."
TextChanged="TextBoxModpackConfig_TextChanged"
/>
<!-- TextBoxes: InstallKey -->
<TextBox
x:Name="TextBoxInstallKey"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
Margin="3"
VerticalAlignment="Center"
Watermark="XXXXX-YYYYY-ZZZZZ-AAAAA-BBBBB"
TextChanged="TextBoxInstallKey_TextChanged"
IsVisible="false"
/>
<!-- Button: SearchProfileFolder -->
<pilz:ImageButton
x:Name="ButtonSearchProfileFolder"
Grid.Row="0"
Grid.Column="2"
Margin="3"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Text="{x:Static lang:GeneralLangRes.Select}"
Click="ButtonSearchProfileFolder_Click"
/>
<!-- Button: CheckForUpdates -->
<pilz:ImageButton
x:Name="ButtonCheckForUpdates"
Grid.Row="4"
Grid.Column="1"
Margin="3"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Text="{x:Static lang:GeneralLangRes.CheckForUpdates}"
Click="ButtonCheckForUpdates_Click"
/>
<!-- Button: Install -->
<pilz:ImageSplitButton
x:Name="ButtonInstall"
Grid.Row="4"
Grid.Column="2"
Margin="3"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Text="{x:Static lang:GeneralLangRes.Install}"
Click="ButtonInstall_Click"
>
<SplitButton.Flyout>
<MenuFlyout>
<MenuItem x:Name="MenuItemRepair" Header="{x:Static lang:GeneralLangRes.Repair}" Click="MenuItemRepair_Click" />
</MenuFlyout>
</SplitButton.Flyout>
</pilz:ImageSplitButton>
</Grid>
</Window>

View File

@@ -0,0 +1,381 @@
using System.Diagnostics;
using System.Reflection;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Media;
using Avalonia.Platform.Storage;
using Avalonia.Threading;
using ModpackUpdater.Apps.Client.Gui.LangRes;
using ModpackUpdater.Manager;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz;
using Pilz.Extensions;
using Pilz.Runtime;
using Pilz.SymbolPacks.Sets;
using Pilz.UI.AvaloniaUI.Symbols;
using Pilz.UI.Symbols;
using Pilz.Updating.Client;
namespace ModpackUpdater.Apps.Client.Gui;
public partial class MainForm : Window
{
private readonly UpdateCheckOptions updateOptions = new();
private ModpackInfo modpackInfo = new();
private ModpackConfig updateConfig = new();
private ModpackFeatures? features;
private UpdateCheckResult? lastUpdateCheckResult;
private bool currentUpdating;
private bool loadingData;
private int curOptionsRow = 3;
public MainForm()
{
InitializeComponent();
Title = $"{Title} (v{Assembly.GetExecutingAssembly().GetAppVersion().ToShortString()})";
Closing += MainForm_Closing;
Loaded += MainForm_Loaded;
ButtonSearchProfileFolder.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.opened_folder);
ButtonCheckForUpdates.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.update);
ButtonInstall.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer);
MenuItemRepair.Icon = Symbols.Fluent.GetImage(SymbolsFluent.wrench, SymbolSize.Small);
ClearStatus();
LoadProfileToUi();
}
#region Features
private void SetStatus(string statusText, IImage? image)
{
TextStatus.Text = statusText;
ImageStatus.Source = image;
}
private void ClearStatus()
{
TextStatus.Text = "-";
ImageStatus.Source = null;
}
private void LoadProfileToUi()
{
loadingData = true;
TextBoxMinecraftProfileFolder.Text = modpackInfo.LocaLPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text;
TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text;
TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text;
Dispatcher.UIThread.Post(() => loadingData = false, DispatcherPriority.Background);
}
private void LoadOptionsToUi()
{
//foreach (var set in )
//{
// // ...
//}
}
private async void CheckStatusAndUpdate(bool loadProfileToUi)
{
if (CheckStatus(loadProfileToUi))
await ExecuteUpdate(false, false);
}
private bool CheckStatus(bool loadProfileToUi)
{
try
{
modpackInfo = ModpackInfo.TryLoad(TextBoxMinecraftProfileFolder.Text?.Trim());
}
catch
{
// Ignore
}
if (loadProfileToUi)
LoadProfileToUi();
try
{
updateConfig = ModpackConfig.LoadFromUrl(TextBoxModpackConfig.Text);
}
catch
{
// Ignore
}
if (modpackInfo != null)
{
features = new(updateConfig);
modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim();
if (!features.IsInvalid() && !string.IsNullOrWhiteSpace(TextBoxInstallKey.Text) && !AllowExtras())
{
SetStatus(GeneralLangRes.InstallationKeyNotValid, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield));
return false;
}
}
LabelInstallKey.IsVisible = TextBoxInstallKey.IsVisible = !string.IsNullOrWhiteSpace(updateConfig.UnleashApiUrl);
if (modpackInfo == null || string.IsNullOrWhiteSpace(TextBoxMinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
{
SetStatus(GeneralLangRes.MinecraftProfileFolderSeemsInvalid, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield));
ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false;
return false;
}
else if (string.IsNullOrWhiteSpace(TextBoxModpackConfig.Text))
{
SetStatus(GeneralLangRes.ConfigIncompleteOrNotLoaded, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield));
ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false;
return false;
}
else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance)
{
SetStatus(GeneralLangRes.UpdateServerInMaintenance, Symbols.Fluent.GetImageSource(SymbolsFluent.services));
ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false;
return false;
}
LoadOptionsToUi();
ButtonCheckForUpdates.IsEnabled = true;
ButtonInstall.IsEnabled = true;
return true;
}
private async Task ExecuteUpdate(bool doInstall, bool repair)
{
// Ensure set extras key
modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim();
var updater = new ModpackInstaller(updateConfig, modpackInfo);
updater.InstallProgessUpdated += Update_InstallProgessUpdated;
updater.CheckingProgressUpdated += Updated_CheckingProgresssUpdated;
void error()
{
SetStatus(GeneralLangRes.ErrorOnUpdateCheckOrUpdating, Symbols.Fluent.GetImageSource(SymbolsFluent.close));
currentUpdating = false;
}
void installing()
{
SetStatus(GeneralLangRes.Installing, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer));
currentUpdating = true;
}
void updatesAvailable()
{
SetStatus(GeneralLangRes.AnUpdateIsAvailable, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer));
}
void everythingOk()
{
SetStatus(GeneralLangRes.EverythingIsRightAndUpToDate, Symbols.Fluent.GetImageSource(SymbolsFluent.done));
currentUpdating = false;
}
// Check only if not pressed "install", not really needed otherwise.
if (lastUpdateCheckResult is null || !doInstall || repair)
{
SetStatus(GeneralLangRes.CheckingForUpdates, Symbols.Fluent.GetImageSource(SymbolsFluent.update));
// Check for extras once again
updateOptions.IncludeExtras = AllowExtras();
// Force re-install on repair
updateOptions.IgnoreInstalledVersion = repair;
try
{
lastUpdateCheckResult = await updater.Check(updateOptions);
}
catch (Exception)
{
error();
if (Debugger.IsAttached)
throw;
}
}
// Error while update check
if (lastUpdateCheckResult is null || lastUpdateCheckResult.HasError)
{
error();
return;
}
// Load options
// lastUpdateCheckResult.OptionsAvailable...
// lastUpdateCheckResult.OptionsEnabled...
// No updates available
if (!lastUpdateCheckResult.HasUpdates)
{
everythingOk();
return;
}
// Updates available (but don't install)
if (!doInstall)
{
updatesAvailable();
return;
}
// Install updates
installing();
currentUpdating = true;
try
{
// Install
if (await updater.Install(lastUpdateCheckResult) == false)
{
error();
return;
}
// Success
lastUpdateCheckResult = null; // Reset last update check, a new one would be needed now.
everythingOk();
}
catch (Exception)
{
// Error
error();
if (Debugger.IsAttached)
throw;
}
}
private bool AllowExtras()
{
return features != null && features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(modpackInfo));
}
private void Updated_CheckingProgresssUpdated(int toCheck, int processed)
{
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.update));
}
private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs)
{
var actionCount = result.Actions.Count;
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer));
}
#endregion
#region Gui
private void MainForm_Closing(object? sender, WindowClosingEventArgs e)
{
AppConfig.Instance.LastMinecraftProfilePath = TextBoxMinecraftProfileFolder.Text?.Trim();
}
private async Task UpdateApp()
{
if (Debugger.IsAttached)
return;
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, MsBox.Avalonia.Enums.Icon.Info).ShowWindowDialogAsync(this) == ButtonResult.Yes)
{
SetStatus(GeneralLangRes.DownloadProgramUpdate, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer));
IsEnabled = false;
if (await updater.DownloadPackageAsync(packageToInstall)
&& await updater.InstallPackageAsync(packageToInstall, myAppPath))
{
IsVisible = false;
await Process.Start(myAppPath).WaitForExitAsync();
Environment.Exit(0);
return;
}
IsEnabled = true;
}
}
private async void MainForm_Loaded(object? sender, RoutedEventArgs e)
{
#if !DISABLE_UPDATE
try
{
await UpdateApp();
}
catch (Exception ex)
{
await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowAsync();
IsEnabled = true;
}
#endif
CheckStatusAndUpdate(true);
}
private void TextBoxMinecraftProfileFolder_TextChanged(object? o, TextChangedEventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(true);
}
private void TextBoxModpackConfig_TextChanged(object? o, RoutedEventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(false);
}
private void TextBoxInstallKey_TextChanged(object? o, RoutedEventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(false);
}
private async void ButtonSearchProfileFolder_Click(object? sender, RoutedEventArgs e)
{
var filePaths = await StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = GeneralLangRes.SelectMinecraftProfileFolder,
SuggestedStartLocation = await StorageProvider.TryGetFolderFromPathAsync(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)),
AllowMultiple = false,
});
if (filePaths.Count >= 1)
TextBoxMinecraftProfileFolder.Text = filePaths[0].Path.AbsolutePath;
}
private async void ButtonCheckForUpdates_Click(object? sender, RoutedEventArgs e)
{
ClearStatus();
await ExecuteUpdate(false, false);
}
private async void ButtonInstall_Click(object? sender, RoutedEventArgs e)
{
if (currentUpdating)
return;
ClearStatus();
await ExecuteUpdate(true, false);
}
private async void MenuItemRepair_Click(object? sender, RoutedEventArgs e)
{
if (currentUpdating)
return;
ClearStatus();
await ExecuteUpdate(true, true);
}
#endregion
}

View File

@@ -1,328 +0,0 @@
using ModpackUpdater.Manager;
using ModpackUpdater.My.Resources;
using Pilz.Extensions;
using Pilz.UI.Symbols;
using Pilz.UI.WinForms.Extensions;
using System.Diagnostics;
using System.Reflection;
using Telerik.WinControls;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Client.Gui;
public partial class MainForm
{
private readonly UpdateCheckOptions updateOptions = new();
private ModpackInfo modpackInfo = new();
private ModpackConfig updateConfig = new();
private ModpackFeatures features;
private UpdateCheckResult lastUpdateCheckResult;
private bool currentUpdating;
private bool loadingData;
private int curOptionsRow = 3;
public MainForm()
{
InitializeComponent();
Text = $"{Text} (v{Assembly.GetExecutingAssembly().GetAppVersion()})";
RadButton_Install.DefaultItem = radMenuItem_Install;
RadButton_CheckForUpdates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small);
RadButton_SearchMinecraftProfileFolder.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.opened_folder, SymbolSize.Small);
RadButton_Install.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small);
radMenuItem_Install.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small);
radMenuItem_Repair.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.wrench, SymbolSize.Small);
LoadProfileToUi();
}
#region Features
private void SetStatus(string statusText, RadSvgImage image)
{
RadLabel_Status.Text = statusText;
RadLabel_Status.SvgImage = image;
}
private void ClearStatus()
{
RadLabel_Status.Text = "-";
RadLabel_Status.SvgImage = null;
}
private void LoadProfileToUi()
{
loadingData = true;
tableLayoutPanel1.SuspendLayout();
RadTextBox_MinecraftProfileFolder.Text = modpackInfo?.LocaLPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? RadTextBox_MinecraftProfileFolder.Text;
RadTextBox_ModpackConfig.Text = modpackInfo?.ConfigUrl ?? RadTextBox_ModpackConfig.Text;
radTextBox_InstallKey.Text = modpackInfo?.ExtrasKey ?? radTextBox_InstallKey.Text;
tableLayoutPanel1.ResumeLayout();
loadingData = false;
}
private void LoadOptionsToUi()
{
//foreach (var set in )
//{
// // ...
//}
}
private async void CheckStatusAndUpdate(bool loadProfileToUi)
{
if (CheckStatus(loadProfileToUi))
await ExecuteUpdate(false, false);
}
private bool CheckStatus(bool loadProfileToUi)
{
try
{
modpackInfo = ModpackInfo.TryLoad(RadTextBox_MinecraftProfileFolder.Text.Trim());
}
catch
{
}
if (loadProfileToUi)
LoadProfileToUi();
try
{
updateConfig = ModpackConfig.LoadFromUrl(RadTextBox_ModpackConfig.Text);
}
catch (Exception)
{
}
if (modpackInfo != null)
features = new(updateConfig);
radTextBox_InstallKey.Visible = radLabel_InstallationKey.Visible = !string.IsNullOrWhiteSpace(updateConfig.UnleashApiUrl);
if (modpackInfo == null || string.IsNullOrWhiteSpace(RadTextBox_MinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
{
SetStatus(LangRes.StatusText_MinecraftProfileWarning, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small));
RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false;
return false;
}
else if (updateConfig == null || string.IsNullOrWhiteSpace(RadTextBox_ModpackConfig.Text))
{
SetStatus(LangRes.StatusText_ConfigIncompleteOrNotLoaded, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small));
RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false;
return false;
}
else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance)
{
SetStatus(LangRes.StatusText_Maintenance, AppGlobals.Symbols.GetSvgImage(AppSymbols.services, SymbolSize.Small));
RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false;
return false;
}
LoadOptionsToUi();
RadButton_CheckForUpdates.Enabled = true;
RadButton_Install.Enabled = true;
return true;
}
private async Task ExecuteUpdate(bool doInstall, bool repair)
{
// Ensure set extras key
modpackInfo.ExtrasKey = radTextBox_InstallKey.Text.Trim();
var updater = new ModpackInstaller(updateConfig, modpackInfo);
updater.InstallProgessUpdated += Update_InstallProgessUpdated;
updater.CheckingProgressUpdated += Updated_CheckingProgresssUpdated;
void error()
{
SetStatus(LangRes.StatusText_ErrorWhileUpdateCheckOrUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.close, SymbolSize.Small));
currentUpdating = false;
}
void installing()
{
SetStatus(LangRes.StatusText_Installing, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
currentUpdating = true;
}
void updatesAvailable()
{
SetStatus(LangRes.StatusText_UpdateAvailable, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
}
void everythingOk()
{
SetStatus(LangRes.StatusTest_EverythingOk, AppGlobals.Symbols.GetSvgImage(AppSymbols.done, SymbolSize.Small));
currentUpdating = false;
}
// Check only if not pressed "install", not really needed otherwise.
if (lastUpdateCheckResult is null || !doInstall || repair)
{
SetStatus(LangRes.StatusText_CheckingForUpdates, AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small));
// Check for extras once again
updateOptions.IncludeExtras = features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(modpackInfo));
// Force re-install on repair
updateOptions.IgnoreInstalledVersion = repair;
try
{
lastUpdateCheckResult = await updater.Check(updateOptions);
}
catch (Exception)
{
error();
if (Debugger.IsAttached)
throw;
}
finally
{
}
}
// Error while update check
if (lastUpdateCheckResult is null || lastUpdateCheckResult.HasError)
{
error();
return;
}
// Load options
// lastUpdateCheckResult.OptionsAvailable...
// lastUpdateCheckResult.OptionsEnabled...
// No updates available
if (!lastUpdateCheckResult.HasUpdates)
{
everythingOk();
return;
}
// Updates available (but don't install)
if (!doInstall)
{
updatesAvailable();
return;
}
// Install updates
installing();
currentUpdating = true;
try
{
// Install
if (await updater.Install(lastUpdateCheckResult) == false)
{
error();
return;
}
// Success
lastUpdateCheckResult = null; // Reset last update check, a new one would be needed now.
everythingOk();
}
catch (Exception)
{
// Error
error();
if (Debugger.IsAttached)
throw;
}
}
private void Updated_CheckingProgresssUpdated(int toCheck, int processed)
{
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small));
}
private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs)
{
int actionCount = result.Actions.Count;
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
}
#endregion
#region Gui
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
AppConfig.Instance.LastMinecraftProfilePath = RadTextBox_MinecraftProfileFolder.Text.Trim();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private async void Form1_Shown(object sender, EventArgs e)
{
var updater = new AppUpdater(Program.UPDATE_URL);
if (await updater.Check() && RadMessageBox.Show(LangRes.MsgBox_UpdateAvailable, LangRes.MsgBox_UpdateAvailable_Title, MessageBoxButtons.YesNo, RadMessageIcon.Info).IsYes())
{
SetStatus(LangRes.StatusText_InstallingAppUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
Enabled = false;
await updater.Install();
Application.Restart();
return;
}
CheckStatusAndUpdate(true);
}
private void RadTextBox_MinecraftFolder_TextInserted(object o, EventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(true);
}
private void RadTextBox_ModpackUrl_TextInserted(object o, EventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(false);
}
private void RadTextBox_InstallationKey_TextInserted(object o, EventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(false);
}
private void ButtonX_SearchMinecraftProfile_Click(object sender, EventArgs e)
{
var ofd = new RadOpenFolderDialog();
if (ofd.ShowDialog(this) == DialogResult.OK)
RadTextBox_MinecraftProfileFolder.Text = ofd.FileName;
}
private async void ButtonX_CheckForUpdates_Click(object sender, EventArgs e)
{
ClearStatus();
await ExecuteUpdate(false, false);
}
private async void RadMenuItem_Install_Click(object sender, EventArgs e)
{
if (!currentUpdating)
{
ClearStatus();
await ExecuteUpdate(true, false);
}
}
private async void RadMenuItem_Repair_Click(object sender, EventArgs e)
{
if (!currentUpdating)
{
ClearStatus();
await ExecuteUpdate(true, true);
}
}
#endregion
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,61 +2,97 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ApplicationIcon>minecraft modpack updater.ico</ApplicationIcon> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<AssemblyName>Minecraft Modpack Updater</AssemblyName> <AssemblyName>MinecraftModpackUpdater</AssemblyName>
<ImplicitUsings>true</ImplicitUsings> <ImplicitUsings>true</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms> <Nullable>enable</Nullable>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<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>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="FiledialogFilters.Designer.cs"> <Compile Update="FiledialogFilters.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>FiledialogFilters.resx</DependentUpon> <DependentUpon>FiledialogFilters.resx</DependentUpon>
</Compile> </Compile>
<Compile Update="LangRes.Designer.cs"> <Compile Update="LangRes\GeneralLangRes.Designer.cs">
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DependentUpon>LangRes.resx</DependentUpon> <DependentUpon>GeneralLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\MsgBoxLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>MsgBoxLangRes.resx</DependentUpon>
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Update="FiledialogFilters.resx"> <EmbeddedResource Update="FiledialogFilters.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>FiledialogFilters.Designer.cs</LastGenOutput> <LastGenOutput>FiledialogFilters.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes.resx"> <EmbeddedResource Update="LangRes\GeneralLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace> <LastGenOutput>GeneralLangRes.Designer.cs</LastGenOutput>
<LastGenOutput>LangRes.Designer.cs</LastGenOutput> </EmbeddedResource>
<EmbeddedResource Update="LangRes\MsgBoxLangRes.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Avalonia.BuildServices" Version="11.3.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="HarfBuzzSharp" Version="8.3.1.2" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="8.3.1.2" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="8.3.1.2" />
<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.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Pilz.Configuration" Version="3.2.6" /> <PackageReference Include="Pilz" Version="2.6.1" />
<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" />
<PackageReference Include="Pilz.UI" Version="3.0.0" /> <PackageReference Include="Pilz.SymbolPacks.Fluent" Version="1.0.12" />
<PackageReference Include="Pilz.UI.WinForms" Version="2.6.2" /> <PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.1.3" />
<PackageReference Include="Pilz.UI.WinForms.Telerik" Version="2.13.3" /> <PackageReference Include="Pilz.UI.AvaloniaUI.Symbols" Version="1.0.0" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.2.612-preview" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.2.612-preview" /> <PackageReference Include="Avalonia.Svg" Version="11.3.0" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.8" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.8" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.8">
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="Pilz.Updating" Version="4.3.5" />
<PackageReference Include="Pilz.Updating.Client" Version="4.4.6" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Apps.AppUpdates\ModpackUpdater.Apps.AppUpdates.csproj" /> <ProjectReference Include="..\ModpackUpdater.Apps.AppUpdates\ModpackUpdater.Apps.AppUpdates.csproj" />
<ProjectReference Include="..\ModpackUpdater.Apps\ModpackUpdater.Apps.csproj" />
<ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" /> <ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" />
<ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" /> <ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -1,18 +1,20 @@
using Castle.Core.Logging; using Avalonia;
using Castle.Core.Logging;
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz;
using Pilz.Configuration; using Pilz.Configuration;
namespace ModpackUpdater.Apps.Client.Gui; namespace ModpackUpdater.Apps.Client.Gui;
public static class Program public static class Program
{ {
public const string UPDATE_URL = "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;
private static readonly ILogger log = new ConsoleLogger();
public static string ProcessPath = EnvironmentEx.ProcessPath!;
public static ISettings Settings => settingsManager.Instance; public static ISettings Settings => settingsManager.Instance;
public static ILogger Log => log; public static ILogger Log { get; } = new ConsoleLogger();
static Program() static Program()
{ {
@@ -23,20 +25,26 @@ public static class Program
[STAThread] [STAThread]
internal static void Main(string[] args) internal static void Main(string[] args)
{ {
ApplicationConfiguration.Initialize(); BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
AppGlobals.Initialize(); }
Application.Run(new MainForm());
public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
} }
private static string GetSettingsPath(int? settingsVersion = 3) private static string GetSettingsPath(int? settingsVersion = 3)
{ {
const string AppDataDirectoryName = "MinecraftModpackUpdater"; const string appDataDirectoryName = "MinecraftModpackUpdater";
var fileNamePostfix = settingsVersion == null ? string.Empty : $"V{settingsVersion}"; var fileNamePostfix = settingsVersion == null ? string.Empty : $"V{settingsVersion}";
var SettingsFileName = $"Settings{fileNamePostfix}.json"; var settingsFileName = $"Settings{fileNamePostfix}.json";
var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName); var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), appDataDirectoryName);
Directory.CreateDirectory(settingsPath); Directory.CreateDirectory(settingsPath);
settingsPath = Path.Combine(settingsPath, SettingsFileName); settingsPath = Path.Combine(settingsPath, settingsFileName);
return settingsPath; return settingsPath;
} }

View File

@@ -0,0 +1,92 @@
# 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.0.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=wayland
--socket=fallback-x11
--filesystem=home
--share=network
"""
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

@@ -0,0 +1,12 @@
pupnet -y -v "$1[1]" -r linux-x64 -k appimage
#pupnet -y -v "$1[1]" -r linux-x64 -k flatpak -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-x64 -k deb -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-x64 -k rpm -p DefineConstants=DISABLE_UPDATE
pupnet -y -v "$1[1]" -r linux-arm64 -k appimage
#pupnet -y -v "$1[1]" -r linux-arm64 -k flatpak -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-arm64 -k deb -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-arm64 -k rpm -p DefineConstants=DISABLE_UPDATE
pupnet -y -v "$1[1]" -r win-x64 -k zip
pupnet -y -v "$1[1]" -r win-arm64 -k zip
pupnet -y -v "$1[1]" -r osx-x64 -k zip
pupnet -y -v "$1[1]" -r osx-arm64 -k zip

View File

@@ -5,7 +5,7 @@
<TargetFramework>net8.0</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AssemblyName>mmu-cli</AssemblyName> <AssemblyName>MinecraftModpackUpdaterCli</AssemblyName>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
@@ -14,7 +14,8 @@
<ItemGroup> <ItemGroup>
<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.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Pilz" Version="2.6.1" />
<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" />
</ItemGroup> </ItemGroup>

View File

@@ -0,0 +1,90 @@
# PUPNET DEPLOY: 1.9.1
# Use: 'pupnet --help conf' for information.
# APP PREAMBLE
AppBaseName = MinecraftModpackUpdaterCli
AppFriendlyName = Minecraft Modpack Updater CLI
AppId = de.pilzinsel64.minecraft-modpack-updater-cli
AppVersionRelease = 1.0.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 = """
"""
# DOTNET PUBLISH
DotnetProjectPath = ModpackUpdater.Apps.Client.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-cli
OutputDirectory = ../publish/client-cli
# APPIMAGE OPTIONS
AppImageArgs =
AppImageRuntimePath =
AppImageVersionOutput = false
# FLATPAK OPTIONS
FlatpakPlatformRuntime = org.freedesktop.Platform
FlatpakPlatformSdk = org.freedesktop.Sdk
FlatpakPlatformVersion = 25.08
FlatpakFinishArgs = """
--socket=wayland
--socket=fallback-x11
--filesystem=home
--share=network
"""
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

@@ -0,0 +1,12 @@
pupnet -y -v "$1[1]" -r linux-x64 -k appimage
#pupnet -y -v "$1[1]" -r linux-x64 -k flatpak
#pupnet -y -v "$1[1]"-r linux-x64 -k deb
#pupnet -y -v "$1[1]"-r linux-x64 -k rpm
pupnet -y -v "$1[1]" -r linux-arm64 -k appimage
#pupnet -y -v "$1[1]" -r linux-arm64 -k flatpak
#pupnet -y -v "$1[1]"-r linux-arm64 -k deb
#pupnet -y -v "$1[1]"-r linux-arm64 -k rpm
pupnet -y -v "$1[1]" -r win-x64 -k zip
pupnet -y -v "$1[1]" -r win-arm64 -k zip
pupnet -y -v "$1[1]" -r osx-x64 -k zip
pupnet -y -v "$1[1]" -r osx-arm64 -k zip

View File

@@ -1,5 +1,5 @@
using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Apps.Manager.Api.Model;
using Pilz.Plugins.Advanced; using Pilz.Features;
namespace ModpackUpdater.Apps.Manager.Api.Plugins.Features; namespace ModpackUpdater.Apps.Manager.Api.Plugins.Features;

View File

@@ -1,5 +1,5 @@
using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Apps.Manager.Api.Model;
using Pilz.Plugins.Advanced; using Pilz.Features;
namespace ModpackUpdater.Apps.Manager.Api.Plugins.Params; namespace ModpackUpdater.Apps.Manager.Api.Plugins.Params;

View File

@@ -1,7 +1,7 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;

View File

@@ -1,7 +1,7 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;

View File

@@ -1,7 +1,7 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;

View File

@@ -1,7 +1,7 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;

View File

@@ -1,7 +1,7 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;

View File

@@ -1,6 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Features;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;

View File

@@ -1,6 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Telerik.WinControls; using Telerik.WinControls;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;

View File

@@ -1,6 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Telerik.WinControls; using Telerik.WinControls;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;

View File

@@ -1,6 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Telerik.WinControls; using Telerik.WinControls;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;

View File

@@ -1,6 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Features;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;

View File

@@ -1,6 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;

View File

@@ -1,7 +1,7 @@
using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features; using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.UI.WinForms.Extensions; using Pilz.UI.WinForms.Extensions;
using Pilz.UI.WinForms.Telerik.Dialogs; using Pilz.UI.WinForms.Telerik.Dialogs;

View File

@@ -11,19 +11,17 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="EPPlus" Version="8.0.8" /> <PackageReference Include="EPPlus" Version="8.2.1" />
<PackageReference Include="NGitLab" Version="9.2.0" /> <PackageReference Include="NGitLab" Version="11.0.0" />
<PackageReference Include="Pilz.Configuration" Version="3.2.6" /> <PackageReference Include="Pilz.Configuration" Version="3.2.7" />
<PackageReference Include="Pilz.Plugins.Advanced" Version="2.10.7" /> <PackageReference Include="Pilz.UI" Version="3.1.1" />
<PackageReference Include="Pilz.Plugins.Advanced.UI.WinForms" Version="1.9.1" /> <PackageReference Include="Pilz.UI.WinForms" Version="2.7.0" />
<PackageReference Include="Pilz.Plugins.Advanced.UI.WinForms.Telerik" Version="1.8.3" /> <PackageReference Include="Pilz.UI.WinForms.Telerik" Version="2.14.3" />
<PackageReference Include="Pilz.UI" Version="3.0.0" /> <PackageReference Include="Pilz.UI.WinForms.Telerik.Features" Version="1.9.0" />
<PackageReference Include="Pilz.UI.WinForms" Version="2.6.2" />
<PackageReference Include="Pilz.UI.WinForms.Telerik" Version="2.13.3" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" /> <PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.2.612-preview" /> <PackageReference Include="UI.for.WinForms.Common" Version="2025.3.812" />
<PackageReference Include="UI.for.WinForms.GridView" Version="2025.2.612-preview" /> <PackageReference Include="UI.for.WinForms.GridView" Version="2025.3.812" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.2.612-preview" /> <PackageReference Include="UI.for.WinForms.Themes" Version="2025.3.812" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,7 +1,6 @@
using OfficeOpenXml; using OfficeOpenXml;
using Pilz;
using Pilz.Configuration; using Pilz.Configuration;
using Pilz.Plugins.Advanced; using Pilz.Features;
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager;

View File

@@ -3,10 +3,10 @@ using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Settings; using ModpackUpdater.Apps.Manager.Settings;
using Pilz.Plugins.Advanced; using Pilz.Features;
using Pilz.Plugins.Advanced.UI.WinForms.Telerik;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.UI.WinForms.Extensions; using Pilz.UI.WinForms.Extensions;
using Pilz.UI.WinForms.Telerik.Features;
using Telerik.WinControls; using Telerik.WinControls;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;

View File

@@ -11,10 +11,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Pilz.UI" Version="3.0.0" /> <PackageReference Include="Pilz.UI" Version="3.1.1" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" /> <PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.2.612-preview" /> <PackageReference Include="UI.for.WinForms.Common" Version="2025.3.812" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.2.612-preview" /> <PackageReference Include="UI.for.WinForms.Themes" Version="2025.3.812" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,11 +1,12 @@
using Unleash; using System.Diagnostics.CodeAnalysis;
using Unleash;
using Unleash.ClientFactory; using Unleash.ClientFactory;
namespace ModpackUpdater.Manager; namespace ModpackUpdater.Manager;
public class ModpackFeatures(ModpackConfig modpackConfig) public class ModpackFeatures(ModpackConfig modpackConfig)
{ {
private IUnleash api; private IUnleash? api;
private UnleashContext context; private UnleashContext context;
private UnleashSettings settings; private UnleashSettings settings;
@@ -26,20 +27,28 @@ public class ModpackFeatures(ModpackConfig modpackConfig)
return CheckFeature(feature, context); return CheckFeature(feature, context);
} }
public bool IsInvalid()
{
return string.IsNullOrWhiteSpace(modpackConfig.UnleashApiUrl) || string.IsNullOrWhiteSpace(modpackConfig.UnleashInstanceId);
}
[MemberNotNullWhen(true, nameof(api))]
private bool InitializeApi() private bool InitializeApi()
{ {
if (api == null && !string.IsNullOrWhiteSpace(modpackConfig.UnleashApiUrl) && !string.IsNullOrWhiteSpace(modpackConfig.UnleashInstanceId)) if (api != null
{ || string.IsNullOrWhiteSpace(modpackConfig.UnleashApiUrl)
settings = new UnleashSettings || string.IsNullOrWhiteSpace(modpackConfig.UnleashInstanceId))
{ return api != null;
AppName = "Modpack Updater",
UnleashApi = new Uri(modpackConfig.UnleashApiUrl),
FetchTogglesInterval = TimeSpan.FromSeconds(60 * 5),
InstanceTag = modpackConfig.UnleashInstanceId,
};
api = new UnleashClientFactory().CreateClient(settings, synchronousInitialization: true); settings = new UnleashSettings
} {
AppName = "Modpack Updater",
UnleashApi = new Uri(modpackConfig.UnleashApiUrl),
FetchTogglesInterval = TimeSpan.FromSeconds(0),
InstanceTag = modpackConfig.UnleashInstanceId,
};
api = new UnleashClientFactory().CreateClient(settings, synchronousInitialization: true);
return api != null; return api != null;
} }

View File

@@ -9,10 +9,11 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Castle.Core" Version="5.2.1" /> <PackageReference Include="Castle.Core" Version="5.2.1" />
<PackageReference Include="CurseForge.APIClient" Version="4.2.0" /> <PackageReference Include="CurseForge.APIClient" Version="4.2.0" />
<PackageReference Include="Modrinth.Net" Version="3.5.1" /> <PackageReference Include="LaunchDarkly.EventSource" Version="5.2.1" />
<PackageReference Include="Modrinth.Net" Version="3.6.0" />
<PackageReference Include="Octokit" Version="14.0.0" /> <PackageReference Include="Octokit" Version="14.0.0" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" /> <PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
<PackageReference Include="Unleash.Client" Version="5.3.0" /> <PackageReference Include="Unleash.Client" Version="5.5.3" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,3 +1,3 @@
using Pilz; using Pilz;
[assembly: AssemblyAppVersion("1.9.4.0")] [assembly: AssemblyAppVersion(AssemblyAppVersionAttribute.EntryAssemblyVersionKey)]

6
publish-client.sh Executable file
View File

@@ -0,0 +1,6 @@
#!/bin/bash
set -e
for dir in ModpackUpdater.Apps.Client ModpackUpdater.Apps.Client.Gui; do
( cd "$dir" && ./publish.sh "$1" )
done