manager: migrate base project structure & deps

This commit is contained in:
2025-11-10 18:28:20 +01:00
parent da25510543
commit 6cf27b4867
28 changed files with 304 additions and 155 deletions

View File

@@ -1,5 +1,12 @@
<Project> <Project>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageProjectUrl>https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater</PackageProjectUrl> <PackageProjectUrl>https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>

View File

@@ -1,15 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.IO" Version="2.1.0" />
</ItemGroup>
</Project>

View File

@@ -12,8 +12,6 @@ using MsBox.Avalonia.Enums;
using Pilz; using Pilz;
using Pilz.Extensions; using Pilz.Extensions;
using Pilz.Runtime; using Pilz.Runtime;
using Pilz.SymbolPacks.Sets;
using Pilz.UI.AvaloniaUI.Symbols;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.Updating.Client; using Pilz.Updating.Client;
@@ -39,10 +37,10 @@ public partial class MainForm : Window
Closing += MainForm_Closing; Closing += MainForm_Closing;
Loaded += MainForm_Loaded; Loaded += MainForm_Loaded;
ButtonSearchProfileFolder.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.opened_folder); ButtonSearchProfileFolder.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.opened_folder);
ButtonCheckForUpdates.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.update); ButtonCheckForUpdates.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done);
ButtonInstall.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer); ButtonInstall.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer);
MenuItemRepair.Icon = Symbols.Fluent.GetImage(SymbolsFluent.wrench, SymbolSize.Small); MenuItemRepair.Icon = AppGlobals.Symbols.GetImage(AppSymbols.wrench, SymbolSize.Small);
ClearStatus(); ClearStatus();
LoadProfileToUi(); LoadProfileToUi();
@@ -66,7 +64,7 @@ public partial class MainForm : Window
{ {
loadingData = true; loadingData = true;
TextBoxMinecraftProfileFolder.Text = modpackInfo.LocaLPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text; TextBoxMinecraftProfileFolder.Text = modpackInfo.LocalPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text;
TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text; TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text;
TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text; TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text;
@@ -110,36 +108,33 @@ public partial class MainForm : Window
// Ignore // Ignore
} }
if (modpackInfo != null) features = new(updateConfig);
modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim();
if (!features.IsInvalid() && !string.IsNullOrWhiteSpace(TextBoxInstallKey.Text) && !AllowExtras())
{ {
features = new(updateConfig); SetStatus(GeneralLangRes.InstallationKeyNotValid, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign));
modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim(); return false;
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); LabelInstallKey.IsVisible = TextBoxInstallKey.IsVisible = !string.IsNullOrWhiteSpace(updateConfig.UnleashApiUrl);
if (modpackInfo == null || string.IsNullOrWhiteSpace(TextBoxMinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/) if (string.IsNullOrWhiteSpace(TextBoxMinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
{ {
SetStatus(GeneralLangRes.MinecraftProfileFolderSeemsInvalid, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield)); SetStatus(GeneralLangRes.MinecraftProfileFolderSeemsInvalid, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign));
ButtonCheckForUpdates.IsEnabled = false; ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false; ButtonInstall.IsEnabled = false;
return false; return false;
} }
else if (string.IsNullOrWhiteSpace(TextBoxModpackConfig.Text)) else if (string.IsNullOrWhiteSpace(TextBoxModpackConfig.Text))
{ {
SetStatus(GeneralLangRes.ConfigIncompleteOrNotLoaded, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield)); SetStatus(GeneralLangRes.ConfigIncompleteOrNotLoaded, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign));
ButtonCheckForUpdates.IsEnabled = false; ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false; ButtonInstall.IsEnabled = false;
return false; return false;
} }
else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance) else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance)
{ {
SetStatus(GeneralLangRes.UpdateServerInMaintenance, Symbols.Fluent.GetImageSource(SymbolsFluent.services)); SetStatus(GeneralLangRes.UpdateServerInMaintenance, AppGlobals.Symbols.GetImageSource(AppSymbols.services));
ButtonCheckForUpdates.IsEnabled = false; ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false; ButtonInstall.IsEnabled = false;
return false; return false;
@@ -161,28 +156,28 @@ public partial class MainForm : Window
void error() void error()
{ {
SetStatus(GeneralLangRes.ErrorOnUpdateCheckOrUpdating, Symbols.Fluent.GetImageSource(SymbolsFluent.close)); SetStatus(GeneralLangRes.ErrorOnUpdateCheckOrUpdating, AppGlobals.Symbols.GetImageSource(AppSymbols.close));
currentUpdating = false; currentUpdating = false;
} }
void installing() void installing()
{ {
SetStatus(GeneralLangRes.Installing, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); SetStatus(GeneralLangRes.Installing, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
currentUpdating = true; currentUpdating = true;
} }
void updatesAvailable() void updatesAvailable()
{ {
SetStatus(GeneralLangRes.AnUpdateIsAvailable, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); SetStatus(GeneralLangRes.AnUpdateIsAvailable, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
} }
void everythingOk() void everythingOk()
{ {
SetStatus(GeneralLangRes.EverythingIsRightAndUpToDate, Symbols.Fluent.GetImageSource(SymbolsFluent.done)); SetStatus(GeneralLangRes.EverythingIsRightAndUpToDate, AppGlobals.Symbols.GetImageSource(AppSymbols.done));
currentUpdating = false; currentUpdating = false;
} }
// Check only if not pressed "install", not really needed otherwise. // Check only if not pressed "install", not really needed otherwise.
if (lastUpdateCheckResult is null || !doInstall || repair) if (lastUpdateCheckResult is null || !doInstall || repair)
{ {
SetStatus(GeneralLangRes.CheckingForUpdates, Symbols.Fluent.GetImageSource(SymbolsFluent.update)); SetStatus(GeneralLangRes.CheckingForUpdates, AppGlobals.Symbols.GetImageSource(AppSymbols.update_done));
// Check for extras once again // Check for extras once again
updateOptions.IncludeExtras = AllowExtras(); updateOptions.IncludeExtras = AllowExtras();
@@ -259,13 +254,13 @@ public partial class MainForm : Window
private void Updated_CheckingProgresssUpdated(int toCheck, int processed) private void Updated_CheckingProgresssUpdated(int toCheck, int processed)
{ {
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.update)); SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppGlobals.Symbols.GetImageSource(AppSymbols.update_done));
} }
private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs) private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs)
{ {
var actionCount = result.Actions.Count; var actionCount = result.Actions.Count;
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
} }
#endregion #endregion
@@ -291,7 +286,7 @@ public partial class MainForm : Window
if (await updater.CheckForUpdate() is {} packageToInstall 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) && 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)); SetStatus(GeneralLangRes.DownloadProgramUpdate, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
IsEnabled = false; IsEnabled = false;
if (await updater.DownloadPackageAsync(packageToInstall) if (await updater.DownloadPackageAsync(packageToInstall)
&& await updater.InstallPackageAsync(packageToInstall, myAppPath)) && await updater.InstallPackageAsync(packageToInstall, myAppPath))
@@ -314,7 +309,7 @@ public partial class MainForm : Window
} }
catch (Exception ex) catch (Exception ex)
{ {
await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowAsync(); await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowAsync();
IsEnabled = true; IsEnabled = true;
} }
#endif #endif

View File

@@ -2,22 +2,13 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ApplicationIcon>Assets\app.ico</ApplicationIcon> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<AssemblyName>MinecraftModpackUpdater</AssemblyName> <AssemblyName>MinecraftModpackUpdater</AssemblyName>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <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>
@@ -64,10 +55,6 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="Classic.Avalonia.Theme" Version="11.3.0.1" />
<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="MessageBox.Avalonia" Version="3.3.0" />
<PackageReference Include="Mono.Options" Version="6.12.0.148" /> <PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
@@ -75,9 +62,8 @@
<PackageReference Include="Pilz.Configuration" Version="3.2.7" /> <PackageReference Include="Pilz.Configuration" Version="3.2.7" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" /> <PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.IO" Version="2.1.0" /> <PackageReference Include="Pilz.IO" Version="2.1.0" />
<PackageReference Include="Pilz.SymbolPacks.Fluent" Version="1.0.12" /> <PackageReference Include="Pilz.UI" Version="3.1.1" />
<PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.1.3" /> <PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.0" />
<PackageReference Include="Pilz.UI.AvaloniaUI.Symbols" Version="1.0.0" />
<PackageReference Include="Avalonia" Version="11.3.8" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.8" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<PackageReference Include="Avalonia.Svg" Version="11.3.0" /> <PackageReference Include="Avalonia.Svg" Version="11.3.0" />
@@ -93,7 +79,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<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

@@ -25,6 +25,7 @@ public static class Program
[STAThread] [STAThread]
internal static void Main(string[] args) internal static void Main(string[] args)
{ {
AppGlobals.Initialize();
BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
} }

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="480" height="480" viewBox="0 0 480 480" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip_path_1">
<rect width="480" height="480" />
</clipPath>
</defs>
<g clip-path="url(#clip_path_1)">
<path d="M360 40L180 40L140 0C140 0 40 0 40 0C17.91 0 0 17.91 0 40C0 40 0 120 0 120L400 120C400 120 400 80 400 80C400 57.91 382.09 40 360 40C360 40 360 40 360 40Z" fill="#FFA000" transform="translate(20 100)" />
<g transform="translate(53 -7)">
<path d="M160.042 63.3334L0 7.91667L13.9167 213.75L160.042 300.833L278.333 205.833L292.25 0L160.042 63.3334Z" fill="#5D4037" fill-rule="evenodd" transform="translate(20.875 63.333)" />
<path d="M0 0L13.9167 205.834L160.042 292.917L160.042 55.4167L0 0Z" fill="#8D6E63" fill-rule="evenodd" transform="translate(20.875 71.25)" />
<path d="M13.9167 112.084L13.9167 79.1667L27.8333 72.2554L27.8333 95L41.75 87.0833L41.75 118.75L62.625 109.028L62.625 55.4167L76.5417 48.6954L76.5417 87.0833L90.4583 80.5679L90.4583 63.3333L104.375 55.4167L104.375 35.3637L118.292 28.6979L118.292 47.5L129.425 41.1667L132.208 0L0 63.3333L0 118.75L13.9167 112.084Z" fill="#43A047" fill-rule="evenodd" transform="translate(180.917 63.333)" />
<path d="M0 47.5L139.167 0L292.25 39.5833L160.042 102.917L0 47.5Z" fill="#B2FF59" fill-rule="evenodd" transform="translate(20.875 23.75)" />
<path d="M0 0L2.78333 40.6442L13.9167 44.3888L13.9167 34.9363L27.8333 39.5833L27.8333 65.0513L48.7083 72.2792L48.7083 34.6196L62.625 39.5833L62.625 77.1004L76.5417 81.9217L76.5417 58.9713L90.4583 63.7925L90.4583 86.743L104.375 91.5563L104.375 82.1671L118.292 87.0834L118.292 74.6067L132.208 79.1667L132.208 101.199L160.042 110.833L160.042 55.4167L0 0Z" fill="#66BB6A" fill-rule="evenodd" transform="translate(20.875 71.25)" />
</g>
<path d="M360 0C360 0 40 0 40 0C17.91 0 0 15.1595 0 33.8571C0 33.8571 0 203.143 0 203.143C0 221.84 17.91 237 40 237C40 237 360 237 360 237C382.09 237 400 221.84 400 203.143C400 203.143 400 33.8571 400 33.8571C400 15.1595 382.09 0 360 0C360 0 360 0 360 0Z" fill="#FFCA28" transform="translate(20 183)" />
<path d="M70 80L0 0L140 0L70 80Z" fill="#1565C0" transform="translate(150 380)" />
<path d="M0 0L60 0L60 111.25L0 111.25L0 0Z" fill="#1565C0" transform="translate(190 280)" />
<path d="M30 15C30 23.28 23.29 30 15 30C6.71002 30 0 23.28 0 15C0 6.72 6.71002 0 15 0C23.29 0 30 6.72 30 15C30 15 30 15 30 15Z" fill="#4A148C" transform="translate(430 60)" />
<path d="M125 100C72.62 100 30 57.38 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.84 74.93 55.08 127.16 120 129.75C120 129.75 120 130 120 130L130 130L130 100L125 100C125 100 125 100 125 100Z" fill="#9C27B0" transform="translate(330 60)" />
<path d="M75 50C50.19 50 30 29.81 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.73004 47.36 32.63 77.27 70 79.75C70 79.75 70 80 70 80L80 80L80 50L75 50C75 50 75 50 75 50Z" fill="#7B1FA2" transform="translate(380 60)" />
<path d="M175 150C95.05 150 30 84.95 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.88998 102.5 77.51 177.11 170 179.75C170 179.75 170 180 170 180L180 180L180 150L175 150C175 150 175 150 175 150Z" fill="#BA68C8" transform="translate(280 60)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -2,9 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>MinecraftModpackUpdaterCli</AssemblyName> <AssemblyName>MinecraftModpackUpdaterCli</AssemblyName>
</PropertyGroup> </PropertyGroup>
@@ -12,6 +10,10 @@
<Compile Include="..\Version.cs" /> <Compile Include="..\Version.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<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.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
@@ -21,7 +23,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Apps.AppUpdates\ModpackUpdater.Apps.AppUpdates.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,14 +1,12 @@
namespace ModpackUpdater.Apps.Manager.Api.Model; using Avalonia.Controls;
namespace ModpackUpdater.Apps.Manager.Api.Model;
public interface IMainApi public interface IMainApi
{ {
IWorkspace? CurWorkspace { get; } IWorkspace? CurWorkspace { get; }
IActionSetInfos? CurActionSet { get; } IActionSetInfos? CurActionSet { get; }
Window MainWindow { get; }
Form MainWindow { get; }
void UpdateItem(InstallAction action); void UpdateItem(InstallAction action);
void UpdateItem(IActionSetInfos actionSetInfos); void UpdateItem(IActionSetInfos actionSetInfos);
} }

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="480" height="480" viewBox="0 0 480 480" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip_path_1">
<rect width="480" height="480" />
</clipPath>
</defs>
<g clip-path="url(#clip_path_1)">
<path d="M360 40L180 40L140 0C140 0 40 0 40 0C17.91 0 0 17.91 0 40C0 40 0 120 0 120L400 120C400 120 400 80 400 80C400 57.91 382.09 40 360 40C360 40 360 40 360 40Z" fill="#FFA000" transform="translate(20 100)" />
<g transform="translate(53 -7)">
<path d="M160.042 63.3334L0 7.91667L13.9167 213.75L160.042 300.833L278.333 205.833L292.25 0L160.042 63.3334Z" fill="#5D4037" fill-rule="evenodd" transform="translate(20.875 63.333)" />
<path d="M0 0L13.9167 205.834L160.042 292.917L160.042 55.4167L0 0Z" fill="#8D6E63" fill-rule="evenodd" transform="translate(20.875 71.25)" />
<path d="M13.9167 112.084L13.9167 79.1667L27.8333 72.2554L27.8333 95L41.75 87.0833L41.75 118.75L62.625 109.028L62.625 55.4167L76.5417 48.6954L76.5417 87.0833L90.4583 80.5679L90.4583 63.3333L104.375 55.4167L104.375 35.3637L118.292 28.6979L118.292 47.5L129.425 41.1667L132.208 0L0 63.3333L0 118.75L13.9167 112.084Z" fill="#43A047" fill-rule="evenodd" transform="translate(180.917 63.333)" />
<path d="M0 47.5L139.167 0L292.25 39.5833L160.042 102.917L0 47.5Z" fill="#B2FF59" fill-rule="evenodd" transform="translate(20.875 23.75)" />
<path d="M0 0L2.78333 40.6442L13.9167 44.3888L13.9167 34.9363L27.8333 39.5833L27.8333 65.0513L48.7083 72.2792L48.7083 34.6196L62.625 39.5833L62.625 77.1004L76.5417 81.9217L76.5417 58.9713L90.4583 63.7925L90.4583 86.743L104.375 91.5563L104.375 82.1671L118.292 87.0834L118.292 74.6067L132.208 79.1667L132.208 101.199L160.042 110.833L160.042 55.4167L0 0Z" fill="#66BB6A" fill-rule="evenodd" transform="translate(20.875 71.25)" />
</g>
<path d="M360 0C360 0 40 0 40 0C17.91 0 0 15.1595 0 33.8571C0 33.8571 0 203.143 0 203.143C0 221.84 17.91 237 40 237C40 237 360 237 360 237C382.09 237 400 221.84 400 203.143C400 203.143 400 33.8571 400 33.8571C400 15.1595 382.09 0 360 0C360 0 360 0 360 0Z" fill="#FFCA28" transform="translate(20 183)" />
<path d="M70 80L0 0L140 0L70 80Z" fill="#1565C0" transform="translate(150 380)" />
<path d="M0 0L60 0L60 111.25L0 111.25L0 0Z" fill="#1565C0" transform="translate(190 280)" />
<path d="M30 15C30 23.28 23.29 30 15 30C6.71002 30 0 23.28 0 15C0 6.72 6.71002 0 15 0C23.29 0 30 6.72 30 15C30 15 30 15 30 15Z" fill="#4A148C" transform="translate(430 60)" />
<path d="M125 100C72.62 100 30 57.38 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.84 74.93 55.08 127.16 120 129.75C120 129.75 120 130 120 130L130 130L130 100L125 100C125 100 125 100 125 100Z" fill="#9C27B0" transform="translate(330 60)" />
<path d="M75 50C50.19 50 30 29.81 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.73004 47.36 32.63 77.27 70 79.75C70 79.75 70 80 70 80L80 80L80 50L75 50C75 50 75 50 75 50Z" fill="#7B1FA2" transform="translate(380 60)" />
<path d="M175 150C95.05 150 30 84.95 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.88998 102.5 77.51 177.11 170 179.75C170 179.75 170 180 170 180L180 180L180 150L175 150C175 150 175 150 175 150Z" fill="#BA68C8" transform="translate(280 60)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -2,26 +2,46 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<Nullable>enable</Nullable> <AssemblyName>MinecraftModpackUpdateManager</AssemblyName>
<UseWindowsForms>true</UseWindowsForms> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<ImplicitUsings>enable</ImplicitUsings> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationIcon>icons8_Windows_Update.ico</ApplicationIcon> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<AssemblyName>Minecraft Modpack Update Manager</AssemblyName>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Version.cs" />
<Compile Update="App.axaml.cs">
<DependentUpon>App.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
<PackageReference Include="EPPlus" Version="8.2.1" /> <PackageReference Include="EPPlus" Version="8.2.1" />
<PackageReference Include="NGitLab" Version="11.0.0" /> <PackageReference Include="NGitLab" Version="11.0.1" />
<PackageReference Include="Pilz" Version="2.6.1" />
<PackageReference Include="Pilz.Configuration" Version="3.2.7" /> <PackageReference Include="Pilz.Configuration" Version="3.2.7" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.Features" Version="2.12.0" />
<PackageReference Include="Pilz.UI" Version="3.1.1" /> <PackageReference Include="Pilz.UI" Version="3.1.1" />
<PackageReference Include="Pilz.UI.WinForms" Version="2.7.0" /> <PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.0" />
<PackageReference Include="Pilz.UI.WinForms.Telerik" Version="2.14.3" /> <PackageReference Include="Pilz.UI.AvaloniaUI.Features" Version="1.0.0" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Features" Version="1.9.0" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.3.812" /> <PackageReference Include="Avalonia.Svg" Version="11.3.0" />
<PackageReference Include="UI.for.WinForms.GridView" Version="2025.3.812" /> <PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.8" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.3.812" /> <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>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -81,4 +101,10 @@
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Reference Include="Pilz">
<HintPath>..\..\..\.nuget\packages\pilz\2.6.1\lib\net8.0\Pilz.dll</HintPath>
</Reference>
</ItemGroup>
</Project> </Project>

View File

@@ -1,3 +1,4 @@
using Avalonia;
using OfficeOpenXml; using OfficeOpenXml;
using Pilz.Configuration; using Pilz.Configuration;
using Pilz.Features; using Pilz.Features;
@@ -20,24 +21,31 @@ public static class Program
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
internal static void Main() internal static void Main(string[] args)
{ {
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize();
AppGlobals.Initialize(); AppGlobals.Initialize();
PluginFeatureController.Instance.RegisterAllOwn(); PluginFeatureController.Instance.RegisterAllOwn();
Application.Run(new Ui.MainForm()); BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
}
public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
} }
private static string GetSettingsPath() private static string GetSettingsPath()
{ {
const string AppDataDirectoryName = "MinecraftModpackUpdateManager"; const string AppDataDirectoryName = "MinecraftModpackUpdateManager";
var SettingsFileName = $"Settings.json"; const string settingsFileName = "Settings.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,9 @@
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ModpackUpdater.Apps.Manager.Ui.MainWindow"
Title="MainWindow">
Welcome to Avalonia!
</Window>

View File

@@ -0,0 +1,13 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}

View File

@@ -1,6 +1,5 @@
using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Manager; using ModpackUpdater.Manager;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Ui; namespace ModpackUpdater.Apps.Manager.Ui;
@@ -18,9 +17,7 @@ public partial class UpdatesCollectorUi : RadForm
private readonly InstallAction[] actions; private readonly InstallAction[] actions;
public ModUpdates? CurrentUpdates { get; private set; } public ModUpdates? CurrentUpdates { get; private set; }
public ModUpdateInfo? SelectedUpdate => radListView_Updates.SelectedItem?.Value as ModUpdateInfo; public ModUpdateInfo? SelectedUpdate => radListView_Updates.SelectedItem?.Value as ModUpdateInfo;
public int SelectedVersion => radListView_VersionTags.SelectedIndex; public int SelectedVersion => radListView_VersionTags.SelectedIndex;
public UpdatesCollectorUi(IWorkspace workspace, params InstallAction[] actions) public UpdatesCollectorUi(IWorkspace workspace, params InstallAction[] actions)

View File

@@ -0,0 +1,10 @@
<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"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
Width="800" Height="500"
x:Class="ModpackUpdater.Apps.Manager.Ui.UpdatesCollectorWindow"
Title="UpdatesCollectorWindow">
</Window>

View File

@@ -0,0 +1,33 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Manager;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class UpdatesCollectorWindow : Window
{
public record ModUpdateInfo(KeyValuePair<string, string>[] AvailableVersions, InstallAction Origin)
{
public int NewVersion { get; set; } = 0;
}
public record ModUpdates(List<ModUpdateInfo> List);
private readonly IWorkspace workspace;
private readonly ModpackFactory factory = new();
private readonly InstallAction[] actions;
public ModUpdates? CurrentUpdates { get; private set; }
public ModUpdateInfo? SelectedUpdate => radListView_Updates.SelectedItem?.Value as ModUpdateInfo;
public int SelectedVersion => radListView_VersionTags.SelectedIndex;
public UpdatesCollectorWindow(IWorkspace workspace, params InstallAction[] actions)
{
this.workspace = workspace;
this.actions = actions;
InitializeComponent();
}
}

View File

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

View File

@@ -1,24 +1,20 @@
using ModpackUpdater.Apps.Manager; using Pilz.UI.AvaloniaUI.Symbols;
using Pilz.UI.WinForms.Telerik.Dialogs;
using Pilz.UI.WinForms.Telerik.Symbols;
using Pilz.UI.WinForms.Telerik.Theming;
using Telerik.WinControls.Themes;
namespace ModpackUpdater.Apps; namespace ModpackUpdater.Apps;
public static class AppGlobals public static class AppGlobals
{ {
public static IRadSymbolFactory<AppSymbols> Symbols { get; } = new AppSymbolFactory(); public static ISymbolFactory<AppSymbols> Symbols { get; } = new AppSymbolFactory();
public static void Initialize() public static void Initialize()
{ {
ThemeHelper.ApplyApplicationTheme(new ThemeDefinition(ApplicationTheme.Auto, HighContrastMode.Auto), n => n.Theme switch // ThemeHelper.ApplyApplicationTheme(new ThemeDefinition(ApplicationTheme.Auto, HighContrastMode.Auto), n => n.Theme switch
{ // {
ApplicationTheme.Light => new Windows11CompactTheme(), // ApplicationTheme.Light => new Windows11CompactTheme(),
ApplicationTheme.Gray or ApplicationTheme.Dark => new Windows11CompactDarkTheme(), // ApplicationTheme.Gray or ApplicationTheme.Dark => new Windows11CompactDarkTheme(),
_ => throw new NotImplementedException(), // _ => throw new NotImplementedException(),
}); // });
RadFlyoutBase.ConfirmSvg = Symbols.GetSvgImage(AppSymbols.checkmark, Pilz.UI.Symbols.SymbolSize.Small); // RadFlyoutBase.ConfirmSvg = Symbols.GetSvgImage(AppSymbols.checkmark, Pilz.UI.Symbols.SymbolSize.Small);
RadFlyoutBase.CancelSvg = Symbols.GetSvgImage(AppSymbols.cancel, Pilz.UI.Symbols.SymbolSize.Small); // RadFlyoutBase.CancelSvg = Symbols.GetSvgImage(AppSymbols.cancel, Pilz.UI.Symbols.SymbolSize.Small);
} }
} }

View File

@@ -1,9 +1,9 @@
using Pilz.UI.WinForms.Telerik.Symbols; using System.Reflection;
using System.Reflection; using Pilz.UI.AvaloniaUI.Symbols;
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps;
internal class AppSymbolFactory : RadSymbolFactory<AppSymbols> internal class AppSymbolFactory : SymbolFactory<AppSymbols>
{ {
public override Assembly GetImageResourceAssembly() public override Assembly GetImageResourceAssembly()
{ {

View File

@@ -1,20 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<Nullable>enable</Nullable> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ImplicitUsings>enable</ImplicitUsings> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Symbols\*.svg" /> <EmbeddedResource Include="Symbols\*.svg" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Pilz" Version="2.6.1" />
<PackageReference Include="Pilz.UI" Version="3.1.1" /> <PackageReference Include="Pilz.UI" Version="3.1.1" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" /> <PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.0" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.3.812" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.3.812" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<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>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -58,7 +58,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
return result; return result;
} }
if (modpackInfo == null || !Directory.Exists(modpackInfo.LocaLPath)) if (modpackInfo == null || !Directory.Exists(modpackInfo.LocalPath))
{ {
result.HasError = true; result.HasError = true;
return result; return result;
@@ -168,7 +168,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
foreach (InstallAction iaction in checkResult.Actions) foreach (InstallAction iaction in checkResult.Actions)
{ {
var destFilePath = iaction.GetDestPath(modpackInfo.LocaLPath); var destFilePath = iaction.GetDestPath(modpackInfo.LocalPath);
var sourceUrl = updateConfig.PreferDirectLinks && !string.IsNullOrWhiteSpace(iaction.SourceUrl) var sourceUrl = updateConfig.PreferDirectLinks && !string.IsNullOrWhiteSpace(iaction.SourceUrl)
? iaction.GetSourceUrl(checkResult.LatestVersion, overwriteVersion: OverwriteVersion) ? iaction.GetSourceUrl(checkResult.LatestVersion, overwriteVersion: OverwriteVersion)
: await factory.ResolveSourceUrl(iaction, targetVersion: checkResult.LatestVersion, overwriteVersion: OverwriteVersion); : await factory.ResolveSourceUrl(iaction, targetVersion: checkResult.LatestVersion, overwriteVersion: OverwriteVersion);
@@ -194,7 +194,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
break; break;
case UpdateActionType.Copy: case UpdateActionType.Copy:
{ {
var srcFilePath = Path.Combine(modpackInfo.LocaLPath, uaction.SrcPath); var srcFilePath = Path.Combine(modpackInfo.LocalPath, uaction.SrcPath);
if (uaction.IsDirectory) if (uaction.IsDirectory)
{ {
if (Directory.Exists(srcFilePath)) if (Directory.Exists(srcFilePath))
@@ -209,7 +209,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
break; break;
case UpdateActionType.Move: case UpdateActionType.Move:
{ {
var srcFilePath = Path.Combine(modpackInfo.LocaLPath, uaction.SrcPath); var srcFilePath = Path.Combine(modpackInfo.LocalPath, uaction.SrcPath);
if (uaction.IsDirectory) if (uaction.IsDirectory)
{ {
if (Directory.Exists(srcFilePath)) if (Directory.Exists(srcFilePath))

View File

@@ -19,8 +19,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps", "Modp
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps.Client", "ModpackUpdater.Apps.Client\ModpackUpdater.Apps.Client.csproj", "{415A7854-C358-4DCD-8C9E-D8413097A06D}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps.Client", "ModpackUpdater.Apps.Client\ModpackUpdater.Apps.Client.csproj", "{415A7854-C358-4DCD-8C9E-D8413097A06D}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps.AppUpdates", "ModpackUpdater.Apps.AppUpdates\ModpackUpdater.Apps.AppUpdates.csproj", "{7D8F9265-7BAC-4541-A6A8-168F45D0EA56}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@@ -51,10 +49,6 @@ Global
{415A7854-C358-4DCD-8C9E-D8413097A06D}.Debug|Any CPU.Build.0 = Debug|Any CPU {415A7854-C358-4DCD-8C9E-D8413097A06D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{415A7854-C358-4DCD-8C9E-D8413097A06D}.Release|Any CPU.ActiveCfg = Release|Any CPU {415A7854-C358-4DCD-8C9E-D8413097A06D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{415A7854-C358-4DCD-8C9E-D8413097A06D}.Release|Any CPU.Build.0 = Release|Any CPU {415A7854-C358-4DCD-8C9E-D8413097A06D}.Release|Any CPU.Build.0 = Release|Any CPU
{7D8F9265-7BAC-4541-A6A8-168F45D0EA56}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7D8F9265-7BAC-4541-A6A8-168F45D0EA56}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7D8F9265-7BAC-4541-A6A8-168F45D0EA56}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7D8F9265-7BAC-4541-A6A8-168F45D0EA56}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -66,7 +60,6 @@ Global
{227A37AA-73F0-431D-B976-B9B3A8ADD8C2} = {743892CF-E482-4FBD-9BAB-02920C140F2B} {227A37AA-73F0-431D-B976-B9B3A8ADD8C2} = {743892CF-E482-4FBD-9BAB-02920C140F2B}
{EF2EAFAF-01CD-46BD-BE45-0125B51316A4} = {743892CF-E482-4FBD-9BAB-02920C140F2B} {EF2EAFAF-01CD-46BD-BE45-0125B51316A4} = {743892CF-E482-4FBD-9BAB-02920C140F2B}
{415A7854-C358-4DCD-8C9E-D8413097A06D} = {743892CF-E482-4FBD-9BAB-02920C140F2B} {415A7854-C358-4DCD-8C9E-D8413097A06D} = {743892CF-E482-4FBD-9BAB-02920C140F2B}
{7D8F9265-7BAC-4541-A6A8-168F45D0EA56} = {743892CF-E482-4FBD-9BAB-02920C140F2B}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {322E6A6B-9F3E-4E88-8945-C98A9EF613BF} SolutionGuid = {322E6A6B-9F3E-4E88-8945-C98A9EF613BF}

View File

@@ -6,25 +6,25 @@ namespace ModpackUpdater;
public class ModpackConfig public class ModpackConfig
{ {
public bool Maintenance { get; set; } public bool Maintenance { get; set; }
public string Name { get; set; } public string? Name { get; set; }
public string UpdateUrl { get; set; } public string? UpdateUrl { get; set; }
public string InstallUrl { get; set; } public string? InstallUrl { get; set; }
public string UnleashApiUrl { get; set; } public string? UnleashApiUrl { get; set; }
public string UnleashInstanceId { get; set; } public string? UnleashInstanceId { get; set; }
public bool PreferDirectLinks { get; set; } public bool PreferDirectLinks { get; set; }
public string MinecraftVersion { get; set; } public string? MinecraftVersion { get; set; }
public string RefTag { get; set; } public string? RefTag { get; set; }
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public ModLoader ModLoader { get; set; } public ModLoader ModLoader { get; set; }
[JsonIgnore] [JsonIgnore]
public string ConfigUrl { get; private set; } public string? ConfigUrl { get; private set; }
public static ModpackConfig LoadFromUrl(string url) public static ModpackConfig LoadFromUrl(string? url)
{ {
var result = new HttpClient().GetStringAsync(url).Result; var result = new HttpClient().GetStringAsync(url).Result;
var config = JsonConvert.DeserializeObject<ModpackConfig>(result); var config = JsonConvert.DeserializeObject<ModpackConfig>(result) ?? new();
config.ConfigUrl = url; config.ConfigUrl = url;
return config; return config;
} }

View File

@@ -9,41 +9,42 @@ public class ModpackInfo
private const string FILENAME_MODPACKINFO = "modpack-info.json"; private const string FILENAME_MODPACKINFO = "modpack-info.json";
[JsonConverter(typeof(VersionConverter))] [JsonConverter(typeof(VersionConverter))]
public Version Version { get; set; } public Version? Version { get; set; }
public string ConfigUrl { get; set; } public string? ConfigUrl { get; set; }
public string ExtrasKey { get; set; } public string? ExtrasKey { get; set; }
public InstallOptionValueDictionary Options { get; } = []; public InstallOptionValueDictionary Options { get; } = [];
[JsonIgnore] [JsonIgnore]
public string LocaLPath { get; private set; } public string? LocalPath { get; private set; }
[JsonIgnore] [JsonIgnore]
public bool Exists => File.Exists(GetFilePath(LocaLPath)); public bool Exists => LocalPath != null && File.Exists(GetFilePath(LocalPath));
public void Save() public void Save()
{ {
File.WriteAllText(GetFilePath(LocaLPath), JsonConvert.SerializeObject(this)); if (LocalPath != null)
File.WriteAllText(GetFilePath(LocalPath), JsonConvert.SerializeObject(this));
} }
public void Save(string mcRoot) public void Save(string mcRoot)
{ {
LocaLPath = mcRoot; LocalPath = mcRoot;
Save(); Save();
} }
public static ModpackInfo TryLoad(string mcRoot) public static ModpackInfo TryLoad(string? mcRoot)
{ {
if (HasModpackInfo(mcRoot)) if (mcRoot != null && HasModpackInfo(mcRoot))
return Load(mcRoot); return Load(mcRoot);
return new() return new()
{ {
LocaLPath = mcRoot LocalPath = mcRoot
}; };
} }
public static ModpackInfo Load(string mcRoot) public static ModpackInfo Load(string mcRoot)
{ {
var info = JsonConvert.DeserializeObject<ModpackInfo>(File.ReadAllText(GetFilePath(mcRoot))); var info = JsonConvert.DeserializeObject<ModpackInfo>(File.ReadAllText(GetFilePath(mcRoot))) ?? new();
info.LocaLPath = mcRoot; info.LocalPath = mcRoot;
return info; return info;
} }