Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
7e2d7f56df
|
|||
|
c7b2fff7e7
|
|||
|
a6a3d9d5a9
|
|||
|
5a90cc7e82
|
|||
|
1e3d2701fc
|
|||
|
f5e84b6da7
|
|||
|
c864d9125a
|
|||
|
|
e7aa79db64 | ||
|
|
c0f013a6c5 | ||
|
|
f21e31ebcc | ||
|
|
0ae2a780b0 | ||
|
|
474f76df4a | ||
|
|
6454d97173 | ||
|
|
e57d2316de | ||
|
2cbe25e0f8
|
|||
|
86f93cf3d7
|
|||
|
bbec2cbe07
|
|||
|
07bb19771a
|
|||
|
49845e841d
|
|||
|
d44ccbaaab
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "publish-scripts"]
|
||||
path = publish-scripts
|
||||
url = https://git.pilzinsel64.de/pilz-framework/publish-scripts.git
|
||||
@@ -5,6 +5,7 @@
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>true</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<JsonSerializerIsReflectionEnabledByDefault>true</JsonSerializerIsReflectionEnabledByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
@@ -15,9 +16,22 @@
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DefineConstants>$(DefineConstants);DISABLE_UPDATE</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<DebugSymbols>False</DebugSymbols>
|
||||
<DebugType>None</DebugType>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="Newtonsoft.Json"/>
|
||||
<TrimmerRootAssembly Include="Pilz"/>
|
||||
<TrimmerRootAssembly Include="Yggdrasil.Engine"/>
|
||||
<TrimmerRootAssembly Include="Octokit"/>
|
||||
<TrimmerRootAssembly Include="Modrinth.Net"/>
|
||||
<TrimmerRootAssembly Include="CurseForge.APIClient"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -7,19 +7,22 @@ public class AppConfig : ISettingsNode, ISettingsIdentifier
|
||||
{
|
||||
public static string Identifier => "pilz.appconfig";
|
||||
|
||||
public string? LastMinecraftProfilePath { get; set; }
|
||||
public List<string> RecentMinecraftProfilePaths { get; } = [];
|
||||
|
||||
[JsonIgnore, Obsolete]
|
||||
public string? ConfigFilePath { get; private set; }
|
||||
[JsonProperty("ConfigFilePath"), Obsolete]
|
||||
private string ConfigFilePathLegacy
|
||||
[JsonProperty, Obsolete]
|
||||
private string? LastMinecraftProfilePath
|
||||
{
|
||||
set => ConfigFilePath = value;
|
||||
get => RecentMinecraftProfilePaths.FirstOrDefault();
|
||||
set
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(value))
|
||||
RecentMinecraftProfilePaths.Insert(0, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
LastMinecraftProfilePath = null;
|
||||
RecentMinecraftProfilePaths.Clear();
|
||||
}
|
||||
|
||||
public static AppConfig Instance => Program.Settings.Get<AppConfig>();
|
||||
|
||||
@@ -11,32 +11,46 @@ 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()]
|
||||
/// <summary>
|
||||
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||
/// </summary>
|
||||
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||
// class via a tool like ResGen or Visual Studio.
|
||||
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||
// with the /str option, or rebuild your VS project.
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class GeneralLangRes {
|
||||
|
||||
private static System.Resources.ResourceManager resourceMan;
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static System.Globalization.CultureInfo resourceCulture;
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal GeneralLangRes() {
|
||||
}
|
||||
|
||||
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static System.Resources.ResourceManager ResourceManager {
|
||||
/// <summary>
|
||||
/// Returns the cached ResourceManager instance used by this class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::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);
|
||||
if (object.ReferenceEquals(resourceMan, null)) {
|
||||
global::System.Resources.ResourceManager temp = new global::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 {
|
||||
/// <summary>
|
||||
/// Overrides the current thread's CurrentUICulture property for all
|
||||
/// resource lookups using this strongly typed resource class.
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
public static global::System.Globalization.CultureInfo Culture {
|
||||
get {
|
||||
return resourceCulture;
|
||||
}
|
||||
@@ -45,118 +59,184 @@ namespace ModpackUpdater.Apps.Client.Gui.LangRes {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to An update is available!.
|
||||
/// </summary>
|
||||
public static string AnUpdateIsAvailable {
|
||||
get {
|
||||
return ResourceManager.GetString("AnUpdateIsAvailable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Check for updates.
|
||||
/// </summary>
|
||||
public static string CheckForUpdates {
|
||||
get {
|
||||
return ResourceManager.GetString("CheckForUpdates", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Checking for Updates....
|
||||
/// </summary>
|
||||
public static string CheckingForUpdates {
|
||||
get {
|
||||
return ResourceManager.GetString("CheckingForUpdates", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Config incomplete or not loaded!.
|
||||
/// </summary>
|
||||
public static string ConfigIncompleteOrNotLoaded {
|
||||
get {
|
||||
return ResourceManager.GetString("ConfigIncompleteOrNotLoaded", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Downloading program update....
|
||||
/// </summary>
|
||||
public static string DownloadProgramUpdate {
|
||||
get {
|
||||
return ResourceManager.GetString("DownloadProgramUpdate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Error on update check or while updating!.
|
||||
/// </summary>
|
||||
public static string ErrorOnUpdateCheckOrUpdating {
|
||||
get {
|
||||
return ResourceManager.GetString("ErrorOnUpdateCheckOrUpdating", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Everything is right and up-to-date..
|
||||
/// </summary>
|
||||
public static string EverythingIsRightAndUpToDate {
|
||||
get {
|
||||
return ResourceManager.GetString("EverythingIsRightAndUpToDate", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Install.
|
||||
/// </summary>
|
||||
public static string Install {
|
||||
get {
|
||||
return ResourceManager.GetString("Install", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Installation key.
|
||||
/// </summary>
|
||||
public static string InstallationKey {
|
||||
get {
|
||||
return ResourceManager.GetString("InstallationKey", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Installation key seems to be invalid.
|
||||
/// </summary>
|
||||
public static string InstallationKeyNotValid {
|
||||
get {
|
||||
return ResourceManager.GetString("InstallationKeyNotValid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Installing....
|
||||
/// </summary>
|
||||
public static string Installing {
|
||||
get {
|
||||
return ResourceManager.GetString("Installing", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Minecraft profile.
|
||||
/// </summary>
|
||||
public static string MinecraftProfile {
|
||||
get {
|
||||
return ResourceManager.GetString("MinecraftProfile", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Minecraft profile folder seems to be not valid..
|
||||
/// </summary>
|
||||
public static string MinecraftProfileFolderSeemsInvalid {
|
||||
get {
|
||||
return ResourceManager.GetString("MinecraftProfileFolderSeemsInvalid", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Modpack config url.
|
||||
/// </summary>
|
||||
public static string ModpackConfigUrl {
|
||||
get {
|
||||
return ResourceManager.GetString("ModpackConfigUrl", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to No recent profiles available..
|
||||
/// </summary>
|
||||
public static string NoRecentProfilesAvailable {
|
||||
get {
|
||||
return ResourceManager.GetString("NoRecentProfilesAvailable", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Repair.
|
||||
/// </summary>
|
||||
public static string Repair {
|
||||
get {
|
||||
return ResourceManager.GetString("Repair", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Select.
|
||||
/// </summary>
|
||||
public static string Select {
|
||||
get {
|
||||
return ResourceManager.GetString("Select", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Select the minecraft profile folder (usually named .minecraft).
|
||||
/// </summary>
|
||||
public static string SelectMinecraftProfileFolder {
|
||||
get {
|
||||
return ResourceManager.GetString("SelectMinecraftProfileFolder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Status.
|
||||
/// </summary>
|
||||
public static string Status {
|
||||
get {
|
||||
return ResourceManager.GetString("Status", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to The update servers are in maintenance..
|
||||
/// </summary>
|
||||
public static string UpdateServerInMaintenance {
|
||||
get {
|
||||
return ResourceManager.GetString("UpdateServerInMaintenance", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string InstallationKeyNotValid {
|
||||
get {
|
||||
return ResourceManager.GetString("InstallationKeyNotValid", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,4 +174,7 @@
|
||||
<data name="InstallationKeyNotValid" xml:space="preserve">
|
||||
<value>Installation key seems to be invalid</value>
|
||||
</data>
|
||||
<data name="NoRecentProfilesAvailable" xml:space="preserve">
|
||||
<value>No recent profiles available.</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -12,7 +12,8 @@
|
||||
WindowStartupLocation="CenterScreen"
|
||||
CanMaximize="false"
|
||||
Title="Minecraft Modpack Updater"
|
||||
Icon="/Assets/app.ico">
|
||||
Icon="/Assets/app.ico"
|
||||
Loaded="MainForm_Loaded">
|
||||
|
||||
<Grid
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto"
|
||||
@@ -71,7 +72,7 @@
|
||||
IsVisible="false"/>
|
||||
|
||||
<!-- Button: SearchProfileFolder -->
|
||||
<pilz:ImageButton
|
||||
<pilz:ImageSplitButton
|
||||
x:Name="ButtonSearchProfileFolder"
|
||||
Grid.Row="0"
|
||||
Grid.Column="2"
|
||||
|
||||
@@ -7,18 +7,15 @@ 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.Extensions.Collections;
|
||||
using Pilz.UI.Symbols;
|
||||
using Pilz.Updating.Client;
|
||||
|
||||
namespace ModpackUpdater.Apps.Client.Gui;
|
||||
|
||||
public partial class MainForm : Window
|
||||
{
|
||||
private readonly MenuFlyout menuFlyoutSearchProfileFolder = new();
|
||||
private readonly UpdateCheckOptions updateOptions = new();
|
||||
private ModpackInfo modpackInfo = new();
|
||||
private ModpackConfig updateConfig = new();
|
||||
@@ -26,16 +23,13 @@ public partial class MainForm : Window
|
||||
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.Flyout = menuFlyoutSearchProfileFolder;
|
||||
|
||||
ButtonSearchProfileFolder.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.opened_folder);
|
||||
ButtonCheckForUpdates.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done);
|
||||
@@ -59,12 +53,50 @@ public partial class MainForm : Window
|
||||
TextStatus.Text = "-";
|
||||
ImageStatus.Source = null;
|
||||
}
|
||||
private void LoadRecentFilesToUi()
|
||||
{
|
||||
menuFlyoutSearchProfileFolder.Items.Clear();
|
||||
|
||||
if (AppConfig.Instance.RecentMinecraftProfilePaths.Count == 0)
|
||||
{
|
||||
menuFlyoutSearchProfileFolder.Items.Add(new TextBlock
|
||||
{
|
||||
Text = GeneralLangRes.NoRecentProfilesAvailable,
|
||||
FontStyle = FontStyle.Italic,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
AppConfig.Instance.RecentMinecraftProfilePaths.ForEach(path =>
|
||||
{
|
||||
if (File.Exists(path))
|
||||
return;
|
||||
|
||||
var item = new MenuItem
|
||||
{
|
||||
Header = path.Length > 50 ? $"...{path[^50..]}" : path,
|
||||
DataContext = path,
|
||||
};
|
||||
item.Click += MenuItemRecentMinecraftProfilePathItem_Click;
|
||||
menuFlyoutSearchProfileFolder.Items.Add(item);
|
||||
});
|
||||
}
|
||||
|
||||
private void StoreRecentMinecraftProfilePath(string? path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
return;
|
||||
|
||||
AppConfig.Instance.RecentMinecraftProfilePaths.Remove(path);
|
||||
AppConfig.Instance.RecentMinecraftProfilePaths.Insert(0, path);
|
||||
AppConfig.Instance.RecentMinecraftProfilePaths.Skip(10).ForEach(n => AppConfig.Instance.RecentMinecraftProfilePaths.Remove(n));
|
||||
}
|
||||
|
||||
private void LoadProfileToUi()
|
||||
{
|
||||
loadingData = true;
|
||||
|
||||
TextBoxMinecraftProfileFolder.Text = modpackInfo.LocalPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text;
|
||||
TextBoxMinecraftProfileFolder.Text = modpackInfo.LocalPath ?? AppConfig.Instance.RecentMinecraftProfilePaths.FirstOrDefault() ?? TextBoxMinecraftProfileFolder.Text;
|
||||
TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text;
|
||||
TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text;
|
||||
|
||||
@@ -81,8 +113,13 @@ public partial class MainForm : Window
|
||||
|
||||
private async void CheckStatusAndUpdate(bool loadProfileToUi)
|
||||
{
|
||||
if (CheckStatus(loadProfileToUi))
|
||||
await ExecuteUpdate(false, false);
|
||||
if (!CheckStatus(loadProfileToUi))
|
||||
return;
|
||||
|
||||
await ExecuteUpdate(false, false);
|
||||
|
||||
StoreRecentMinecraftProfilePath(modpackInfo.LocalPath);
|
||||
LoadRecentFilesToUi();
|
||||
}
|
||||
|
||||
private bool CheckStatus(bool loadProfileToUi)
|
||||
@@ -189,7 +226,7 @@ public partial class MainForm : Window
|
||||
{
|
||||
lastUpdateCheckResult = await updater.Check(updateOptions);
|
||||
}
|
||||
catch (Exception)
|
||||
catch
|
||||
{
|
||||
error();
|
||||
if (Debugger.IsAttached)
|
||||
@@ -267,18 +304,13 @@ public partial class MainForm : Window
|
||||
|
||||
#region Gui
|
||||
|
||||
private void MainForm_Closing(object? sender, WindowClosingEventArgs e)
|
||||
{
|
||||
AppConfig.Instance.LastMinecraftProfilePath = TextBoxMinecraftProfileFolder.Text?.Trim();
|
||||
}
|
||||
|
||||
private async void MainForm_Loaded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var updates = new AppUpdates(Program.UpdateUrl, this);
|
||||
updates.OnDownloadProgramUpdate += (o, args) => SetStatus(GeneralLangRes.DownloadProgramUpdate, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
|
||||
var updates = new AppUpdates("client", this);
|
||||
updates.OnDownloadProgramUpdate += (_, _) => SetStatus(GeneralLangRes.DownloadProgramUpdate, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
|
||||
await updates.UpdateApp();
|
||||
ClearStatus();
|
||||
|
||||
LoadRecentFilesToUi();
|
||||
CheckStatusAndUpdate(true);
|
||||
}
|
||||
|
||||
@@ -337,5 +369,11 @@ public partial class MainForm : Window
|
||||
await ExecuteUpdate(true, true);
|
||||
}
|
||||
|
||||
private void MenuItemRecentMinecraftProfilePathItem_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is MenuItem item && item.DataContext is string path)
|
||||
TextBoxMinecraftProfileFolder.Text = path;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -8,6 +8,17 @@
|
||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="MinecraftModpackUpdater"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater.Manager"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater.Apps"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater"/>
|
||||
<TrimmerRootAssembly Include="Pilz.Updating"/>
|
||||
<TrimmerRootAssembly Include="Pilz.Updating.Client"/>
|
||||
<TrimmerRootAssembly Include="Pilz.Configuration"/>
|
||||
<TrimmerRootAssembly Include="ExCSS"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Version.cs" />
|
||||
@@ -49,7 +60,7 @@
|
||||
<LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.BuildServices" Version="11.3.2">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
|
||||
@@ -8,8 +8,6 @@ namespace ModpackUpdater.Apps.Client.Gui;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
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;
|
||||
|
||||
public static ISettings Settings => settingsManager.Instance;
|
||||
@@ -18,7 +16,6 @@ public static class Program
|
||||
static Program()
|
||||
{
|
||||
settingsManager = new(GetSettingsPath(2), true);
|
||||
MigrateLegacySettings(GetSettingsPath(null));
|
||||
}
|
||||
|
||||
[STAThread]
|
||||
@@ -47,25 +44,4 @@ public static class Program
|
||||
|
||||
return settingsPath;
|
||||
}
|
||||
|
||||
private static void MigrateLegacySettings(string settingsPath)
|
||||
{
|
||||
// Try load legacy config file
|
||||
if (!File.Exists(settingsPath) || JsonConvert.DeserializeObject<AppConfig>(File.ReadAllText(settingsPath)) is not AppConfig legacyConfig)
|
||||
return;
|
||||
|
||||
// Migrate
|
||||
var newConfig = Settings.Get<AppConfig>();
|
||||
newConfig.LastMinecraftProfilePath = legacyConfig.LastMinecraftProfilePath;
|
||||
|
||||
if (ModpackInfo.TryLoad(legacyConfig.LastMinecraftProfilePath) is ModpackInfo info)
|
||||
#pragma warning disable CS0612 // Typ oder Element ist veraltet
|
||||
info.ConfigUrl = legacyConfig.ConfigFilePath;
|
||||
|
||||
// Ensure save settings
|
||||
settingsManager.Save();
|
||||
|
||||
// Delete legacy config file
|
||||
File.Delete(settingsPath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ IconFiles = """
|
||||
|
||||
# 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
|
||||
DotnetPublishArgs = -p:Version=${APP_VERSION} --self-contained true -p:DebugType=None -p:DebugSymbols=false -p:PublishSingleFile=true -p:PublishTrimmed=true
|
||||
DotnetPostPublish =
|
||||
DotnetPostPublishOnWindows =
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
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
|
||||
@@ -6,6 +6,12 @@
|
||||
<AssemblyName>MinecraftModpackUpdaterCli</AssemblyName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="MinecraftModpackUpdaterCli"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater.Manager"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Version.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
@@ -34,7 +34,7 @@ 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
|
||||
DotnetPublishArgs = -p:Version=${APP_VERSION} --self-contained true -p:DebugType=None -p:DebugSymbols=false -p:PublishSingleFile=true -p:PublishTrimmed=true
|
||||
DotnetPostPublish =
|
||||
DotnetPostPublishOnWindows =
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
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
|
||||
@@ -6,7 +6,6 @@ using ModpackUpdater.Apps.Manager.Ui;
|
||||
using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
|
||||
using ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
|
||||
using ModpackUpdater.Manager;
|
||||
using MsBox.Avalonia;
|
||||
using OfficeOpenXml;
|
||||
using OfficeOpenXml.Table;
|
||||
using Pilz.UI.AvaloniaUI.Dialogs;
|
||||
@@ -39,7 +38,7 @@ internal static class SharedFunctions
|
||||
var result = await factory.ResolveSourceUrl(row.Action);
|
||||
failed = string.IsNullOrWhiteSpace(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
catch
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
@@ -65,13 +64,13 @@ internal static class SharedFunctions
|
||||
return false;
|
||||
|
||||
// Collect versions with changes
|
||||
var updates = resultUpdates.List.Where(update => update.Origin.SourceTag != update.AvailableVersions[update.NewVersion].Key).ToList();
|
||||
var updates = resultUpdates.List.Where(update => update.Origin.SourceTag != update.AvailableVersions[update.NewVersion].Tag).ToList();
|
||||
|
||||
// Path install actions
|
||||
foreach (var update in updates)
|
||||
{
|
||||
var sourceTag = update.AvailableVersions[update.NewVersion].Key;
|
||||
if (api.Model.CurrentGridRows?.FirstOrDefault(n => n.Action == update.Origin) is { } row)
|
||||
var sourceTag = update.AvailableVersions[update.NewVersion].Tag;
|
||||
if (api.Model.CurrentGridRows.List.Items.FirstOrDefault(n => n.Action == update.Origin) is { } row)
|
||||
row.SourceTag = sourceTag;
|
||||
else
|
||||
update.Origin.SourceTag = sourceTag;
|
||||
|
||||
@@ -17,10 +17,10 @@ internal class CheckAllActionsHealthyFeature : PluginFunction, IPluginFeaturePro
|
||||
|
||||
protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
|
||||
{
|
||||
if (@params is not MainApiParameters p || p.Api.Model.CurrentGridRows is null)
|
||||
if (@params is not MainApiParameters p)
|
||||
return null;
|
||||
|
||||
await SharedFunctions.CheckActionHealthy(p.Api, [.. p.Api.Model.CurrentGridRows]);
|
||||
await SharedFunctions.CheckActionHealthy(p.Api, [.. p.Api.Model.CurrentGridRows.View]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@ internal class ClearDirectLinksFeature : PluginFunction, IPluginFeatureProvider<
|
||||
|
||||
protected override Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
|
||||
{
|
||||
if (@params is MainApiParameters p && p.Api.Model.CurrentGridRows is not null)
|
||||
SharedFunctions.ClearDirectLinks(p.Api, [.. p.Api.Model.CurrentGridRows]);
|
||||
if (@params is MainApiParameters p)
|
||||
SharedFunctions.ClearDirectLinks(p.Api, [.. p.Api.Model.CurrentGridRows.View]);
|
||||
return Task.FromResult<object?>(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ internal class UpdateDirectLinksFeature : PluginFunction, IPluginFeatureProvider
|
||||
|
||||
protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
|
||||
{
|
||||
if (@params is not MainApiParameters p || p.Api.Model.CurrentGridRows is null)
|
||||
if (@params is not MainApiParameters p)
|
||||
return null;
|
||||
|
||||
await SharedFunctions.FindNewDirectLinks(p.Api, [.. p.Api.Model.CurrentGridRows]);
|
||||
await SharedFunctions.FindNewDirectLinks(p.Api, [.. p.Api.Model.CurrentGridRows.View]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -273,6 +273,12 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
|
||||
}
|
||||
}
|
||||
|
||||
public static string SourceTag {
|
||||
get {
|
||||
return ResourceManager.GetString("SourceTag", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string SourceRegex {
|
||||
get {
|
||||
return ResourceManager.GetString("SourceRegex", resourceCulture);
|
||||
@@ -314,5 +320,11 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
|
||||
return ResourceManager.GetString("SelectRootFolder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string Search {
|
||||
get {
|
||||
return ResourceManager.GetString("Search", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,6 +231,9 @@
|
||||
<data name="SourceName" xml:space="preserve">
|
||||
<value>Source name</value>
|
||||
</data>
|
||||
<data name="SourceTag" xml:space="preserve">
|
||||
<value>Source tag</value>
|
||||
</data>
|
||||
<data name="SourceRegex" xml:space="preserve">
|
||||
<value>Source RegEx</value>
|
||||
</data>
|
||||
@@ -252,4 +255,7 @@
|
||||
<data name="SelectRootFolder" xml:space="preserve">
|
||||
<value>Select root folder</value>
|
||||
</data>
|
||||
<data name="Search" xml:space="preserve">
|
||||
<value>Search</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -9,6 +9,18 @@
|
||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<TrimmerRootAssembly Include="MinecraftModpackUpdateManager"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater.Manager"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater.Apps"/>
|
||||
<TrimmerRootAssembly Include="ModpackUpdater"/>
|
||||
<TrimmerRootAssembly Include="NGitLab"/>
|
||||
<TrimmerRootAssembly Include="Pilz.Updating"/>
|
||||
<TrimmerRootAssembly Include="Pilz.Updating.Client"/>
|
||||
<TrimmerRootAssembly Include="Pilz.Configuration"/>
|
||||
<TrimmerRootAssembly Include="ExCSS"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Version.cs" />
|
||||
<Compile Update="LangRes\UpdateActionTypeLangRes.Designer.cs">
|
||||
@@ -38,6 +50,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.8" />
|
||||
<PackageReference Include="DynamicData" Version="9.4.1" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
|
||||
<PackageReference Include="EPPlus" Version="8.2.1" />
|
||||
<PackageReference Include="NGitLab" Version="11.0.1" />
|
||||
|
||||
@@ -7,8 +7,6 @@ namespace ModpackUpdater.Apps.Manager;
|
||||
|
||||
public static class Program
|
||||
{
|
||||
public const string UpdateUrl = "https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater/-/snippets/3/raw/main/updates-manager.json";
|
||||
|
||||
internal static readonly SettingsManager settingsManager;
|
||||
|
||||
public static ISettings Settings => settingsManager.Instance;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
xmlns:symbols="clr-namespace:Pilz.UI.Symbols;assembly=Pilz.UI"
|
||||
xmlns:mainWindow="clr-namespace:ModpackUpdater.Apps.Manager.Ui.Models.MainWindow"
|
||||
xmlns:langRes="clr-namespace:ModpackUpdater.Apps.Manager.LangRes"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
mc:Ignorable="d" d:DesignWidth="1000" d:DesignHeight="450"
|
||||
x:Class="ModpackUpdater.Apps.Manager.Ui.MainWindow"
|
||||
Title="Minecraft Modpack Manager"
|
||||
WindowState="Maximized"
|
||||
@@ -109,42 +109,53 @@
|
||||
Orientation="Horizontal"
|
||||
VerticalAlignment="Center">
|
||||
|
||||
<!-- Panel: Menu list -->
|
||||
<StackPanel
|
||||
Orientation="Horizontal">
|
||||
|
||||
<!-- Button: Add action -->
|
||||
<pilz:ImageButton
|
||||
x:Name="ButtonAddAction"
|
||||
Text="{x:Static langRes:GeneralLangRes.Add}"
|
||||
ImageSource="{x:Static local:MainWindow.ButtonImageAddAction}"
|
||||
Background="Transparent"
|
||||
Click="ButtonAddAction_OnClick"/>
|
||||
|
||||
<!-- Button: Remove action -->
|
||||
<pilz:ImageButton
|
||||
x:Name="ButtonRemoveAction"
|
||||
Text="{x:Static langRes:GeneralLangRes.Remove}"
|
||||
ImageSource="{x:Static local:MainWindow.ButtonImageRemoveAction}"
|
||||
Background="Transparent"
|
||||
Click="ButtonRemoveAction_OnClick"/>
|
||||
</StackPanel>
|
||||
|
||||
<!-- TextBox: Search -->
|
||||
<TextBox
|
||||
Width="200"
|
||||
Watermark="{x:Static langRes:GeneralLangRes.Search}"
|
||||
Text="{Binding CurrentGridRows.SearchText}"/>
|
||||
|
||||
<!-- Panel: Menu -->
|
||||
<ContentControl
|
||||
Content="{Binding SelectedTreeNode}">
|
||||
Content="{Binding SelectedTreeNode}"
|
||||
>
|
||||
|
||||
<ContentControl.DataTemplates>
|
||||
<DataTemplate
|
||||
DataType="mainWindow:ActionSetTreeNode">
|
||||
|
||||
<StackPanel
|
||||
Orientation="Horizontal">
|
||||
|
||||
<!-- Button: Add action -->
|
||||
<pilz:ImageButton
|
||||
x:Name="ButtonAddAction"
|
||||
Text="{x:Static langRes:GeneralLangRes.Add}"
|
||||
ImageSource="{x:Static local:MainWindow.ButtonImageAddAction}"
|
||||
Background="Transparent"
|
||||
Click="ButtonAddAction_OnClick"/>
|
||||
|
||||
<!-- Button: Remove action -->
|
||||
<pilz:ImageButton
|
||||
x:Name="ButtonRemoveAction"
|
||||
Text="{x:Static langRes:GeneralLangRes.Remove}"
|
||||
ImageSource="{x:Static local:MainWindow.ButtonImageRemoveAction}"
|
||||
Background="Transparent"
|
||||
Click="ButtonRemoveAction_OnClick"/>
|
||||
Orientation="Horizontal"
|
||||
Spacing="6">
|
||||
|
||||
<!-- TextBox: Version -->
|
||||
<TextBox
|
||||
Margin="3, 0, 3, 0"
|
||||
Width="100"
|
||||
Text="{Binding Version}"/>
|
||||
|
||||
<!-- CheckBox: Is public -->
|
||||
<CheckBox
|
||||
Margin="3, 0, 3, 0"
|
||||
Content="{x:Static langRes:GeneralLangRes.Public}"
|
||||
IsChecked="{Binding IsPublic}"/>
|
||||
</StackPanel>
|
||||
@@ -172,7 +183,7 @@
|
||||
Grid.Row="1"
|
||||
x:Name="DataGridActions"
|
||||
VerticalAlignment="Stretch"
|
||||
ItemsSource="{Binding CurrentGridRows}"
|
||||
ItemsSource="{Binding CurrentGridRows.View}"
|
||||
SelectedItem="{Binding SelectedGridRow}">
|
||||
|
||||
<DataGrid.ContextMenu>
|
||||
@@ -182,24 +193,31 @@
|
||||
<DataGrid.Columns>
|
||||
<DataGridTextColumn
|
||||
Header="{x:Static langRes:GeneralLangRes.Id}"
|
||||
Binding="{Binding InheritedId}"/>
|
||||
Binding="{Binding InheritedId}"
|
||||
Width="*"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Header="{x:Static langRes:GeneralLangRes.Side}"
|
||||
Binding="{Binding InheritedSide}"/>
|
||||
Header="{x:Static langRes:GeneralLangRes.Name}"
|
||||
Binding="{Binding InheritedName}"
|
||||
Width="*"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Header="{x:Static langRes:GeneralLangRes.UpdateType}"
|
||||
Binding="{Binding InheritedUpdateType}"
|
||||
IsVisible="{Binding IsUpdate}"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Header="{x:Static langRes:GeneralLangRes.Side}"
|
||||
Binding="{Binding InheritedSide}"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Header="{x:Static langRes:GeneralLangRes.SourceType}"
|
||||
Binding="{Binding InheritedSourceType}"/>
|
||||
|
||||
<DataGridTextColumn
|
||||
Header="{x:Static langRes:GeneralLangRes.DestinationPath}"
|
||||
Binding="{Binding InheritedDestPath}"/>
|
||||
Binding="{Binding InheritedDestPath}"
|
||||
Width="*"/>
|
||||
|
||||
<DataGridTemplateColumn
|
||||
Header="{x:Static langRes:GeneralLangRes.State}">
|
||||
@@ -356,7 +374,7 @@
|
||||
<!-- Source -->
|
||||
<Grid
|
||||
ColumnDefinitions="150,*"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"
|
||||
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"
|
||||
RowSpacing="6"
|
||||
ColumnSpacing="6">
|
||||
|
||||
@@ -402,25 +420,32 @@
|
||||
x:Name="TextBoxInstallActionSourceName"
|
||||
Text="{Binding SourceName}"/>
|
||||
|
||||
<!-- Source RegEx -->
|
||||
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceRegex}" Target="TextBoxInstallActionSourceRegEx"/>
|
||||
<!-- Source tag -->
|
||||
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceTag}" Target="TextBoxInstallActionSourceTag"/>
|
||||
<TextBox
|
||||
Grid.Row="5" Grid.Column="1"
|
||||
x:Name="TextBoxInstallActionSourceTag"
|
||||
Text="{Binding SourceTag}"/>
|
||||
|
||||
<!-- Source RegEx -->
|
||||
<Label Grid.Row="6" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceRegex}" Target="TextBoxInstallActionSourceRegEx"/>
|
||||
<TextBox
|
||||
Grid.Row="6" Grid.Column="1"
|
||||
x:Name="TextBoxInstallActionSourceRegEx"
|
||||
Text="{Binding SourceRegex}"/>
|
||||
|
||||
<!-- Source url -->
|
||||
<Label Grid.Row="6" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceUrl}" Target="TextBoxInstallActionSourceUrl"/>
|
||||
<Label Grid.Row="7" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceUrl}" Target="TextBoxInstallActionSourceUrl"/>
|
||||
<TextBox
|
||||
Grid.Row="6" Grid.Column="1"
|
||||
Grid.Row="7" Grid.Column="1"
|
||||
x:Name="TextBoxInstallActionSourceUrl" Text="{Binding SourceUrl}"/>
|
||||
|
||||
<!-- Zip archive path -->
|
||||
<Label Grid.Row="7" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.ZipArchivePath}" Target="TextBoxInstallActionZipArchivePath"/>
|
||||
<Label Grid.Row="8" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.ZipArchivePath}" Target="TextBoxInstallActionZipArchivePath"/>
|
||||
<TextBox
|
||||
Grid.Row="7" Grid.Column="1"
|
||||
Grid.Row="8" Grid.Column="1"
|
||||
x:Name="TextBoxInstallActionZipArchivePath"
|
||||
Text="{Binding SourceUrl}"/>
|
||||
Text="{Binding ZipPath}"/>
|
||||
</Grid>
|
||||
|
||||
<!-- Metadata -->
|
||||
|
||||
@@ -3,6 +3,7 @@ using Avalonia.Controls;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
using DynamicData;
|
||||
using ModpackUpdater.Apps.Manager.Api;
|
||||
using ModpackUpdater.Apps.Manager.Api.Model;
|
||||
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
|
||||
@@ -10,6 +11,7 @@ using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
|
||||
using ModpackUpdater.Apps.Manager.Settings;
|
||||
using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
|
||||
using Pilz.Extensions;
|
||||
using Pilz.Extensions.Collections;
|
||||
using Pilz.Features;
|
||||
using Pilz.UI.AvaloniaUI.Features;
|
||||
using Pilz.UI.Symbols;
|
||||
@@ -118,18 +120,18 @@ public partial class MainWindow : Window, IMainApi
|
||||
private static void AddToRecentFiles(IWorkspace workspace)
|
||||
{
|
||||
var settings = Program.Settings.Get<WorkspaceSettings>();
|
||||
|
||||
settings.Workspaces.Remove(workspace.Config);
|
||||
settings.Workspaces.Insert(0, workspace.Config);
|
||||
|
||||
while (settings.Workspaces.Count > 20)
|
||||
settings.Workspaces.RemoveAt(20);
|
||||
settings.Workspaces.Skip(20).ForEach(n => settings.Workspaces.Remove(n));
|
||||
}
|
||||
|
||||
private async void Window_OnLoaded(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var updater = new AppUpdates(Program.UpdateUrl, this);
|
||||
updater.OnDownloadProgramUpdate += (o, args) => Model.Progress.Start();
|
||||
var updater = new AppUpdates("manager", this)
|
||||
{
|
||||
UsePopups = true,
|
||||
};
|
||||
updater.OnDownloadProgramUpdate += (_, _) => Model.Progress.Start();
|
||||
await updater.UpdateApp();
|
||||
Model.Progress.Stop();
|
||||
|
||||
@@ -239,7 +241,7 @@ public partial class MainWindow : Window, IMainApi
|
||||
return;
|
||||
}
|
||||
|
||||
rows.Add(new MainWindowGridRow(action, rootInfos));
|
||||
rows.List.Add(new MainWindowGridRow(action, rootInfos));
|
||||
}
|
||||
|
||||
private void ButtonRemoveAction_OnClick(object? sender, RoutedEventArgs e)
|
||||
@@ -262,6 +264,6 @@ public partial class MainWindow : Window, IMainApi
|
||||
return;
|
||||
}
|
||||
|
||||
rows.Remove(row);
|
||||
rows.List.Remove(row);
|
||||
}
|
||||
}
|
||||
34
ModpackUpdater.Apps.Manager/Ui/Models/DynamicDataView.cs
Normal file
34
ModpackUpdater.Apps.Manager/Ui/Models/DynamicDataView.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using DynamicData;
|
||||
|
||||
namespace ModpackUpdater.Apps.Manager.Ui.Models;
|
||||
|
||||
public class DynamicDataView<T> : INotifyPropertyChanged where T : notnull
|
||||
{
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private string? searchText;
|
||||
private readonly Subject<string?> searchTextSubject = new();
|
||||
|
||||
public SourceList<T> List { get; } = new();
|
||||
public ReadOnlyObservableCollection<T> View { get; }
|
||||
|
||||
public DynamicDataView(Func<string?, Func<T, bool>> predicate)
|
||||
{
|
||||
List.Connect()
|
||||
.Filter(searchTextSubject/*.Throttle(TimeSpan.FromMilliseconds(250))*/.Select(predicate))
|
||||
.Bind(out var view)
|
||||
.Subscribe();
|
||||
searchTextSubject?.OnNext(searchText);
|
||||
View = view;
|
||||
}
|
||||
|
||||
public string? SearchText
|
||||
{
|
||||
get => searchText;
|
||||
set => searchTextSubject.OnNext(searchText = value);
|
||||
}
|
||||
}
|
||||
@@ -23,14 +23,21 @@ public class MainWindowGridRow(InstallAction action, IActionSet baseActions) : I
|
||||
|
||||
[DependsOn(nameof(Id), nameof(InheritFrom))]
|
||||
public string? InheritedId => action is UpdateAction ua && !string.IsNullOrWhiteSpace(ua.InheritFrom) ? ua.InheritFrom : action.Id;
|
||||
|
||||
[DependsOn(nameof(Side), nameof(InheritedId), nameof(Id))]
|
||||
public string InheritedSide => Sides[Inherited.Side];
|
||||
|
||||
[DependsOn(nameof(UpdateType), nameof(InheritedId), nameof(Id))]
|
||||
public string InheritedUpdateType => action is UpdateAction ua ? UpdateActionTypes[ua.Type] : string.Empty;
|
||||
|
||||
[DependsOn(nameof(SourceType), nameof(InheritedId), nameof(Id))]
|
||||
public string InheritedSourceType => SourceTypes[Inherited.SourceType];
|
||||
|
||||
[DependsOn(nameof(DestPath), nameof(InheritedId), nameof(Id))]
|
||||
public string? InheritedDestPath => Inherited.DestPath;
|
||||
|
||||
[DependsOn(nameof(Name), nameof(InheritedId), nameof(Id))]
|
||||
public string? InheritedName => Inherited.Name;
|
||||
|
||||
public string? Id
|
||||
{
|
||||
|
||||
@@ -11,13 +11,13 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
private ObservableCollection<MainWindowTreeNode>? currentTreeNodes;
|
||||
private ObservableCollection<MainWindowGridRow>? currentGridRows;
|
||||
private MainWindowTreeNode? selectedTreeNode;
|
||||
private IWorkspace? currentWorkspace;
|
||||
|
||||
public bool IsUpdate => selectedTreeNode is ActionSetTreeNode node && node.Infos is UpdateInfo;
|
||||
public ProgressInfos Progress { get; } = new();
|
||||
public MainWindowGridRow? SelectedGridRow { get; set; }
|
||||
public DynamicDataView<MainWindowGridRow> CurrentGridRows { get; } = new(FilterGridRows);
|
||||
|
||||
[AlsoNotifyFor(nameof(CurrentTreeNodes))]
|
||||
public IWorkspace? CurrentWorkspace
|
||||
@@ -48,24 +48,38 @@ public class MainWindowViewModel : INotifyPropertyChanged
|
||||
}
|
||||
}
|
||||
|
||||
[AlsoNotifyFor(nameof(CurrentGridRows))]
|
||||
public MainWindowTreeNode? SelectedTreeNode
|
||||
{
|
||||
get => selectedTreeNode;
|
||||
set
|
||||
{
|
||||
currentGridRows = null;
|
||||
selectedTreeNode = value;
|
||||
CurrentGridRows.List.Edit(list =>
|
||||
{
|
||||
list.Clear();
|
||||
if (CurrentWorkspace?.InstallInfos != null && selectedTreeNode is ActionSetTreeNode node)
|
||||
list.AddRange(node.Infos.Actions.Select(n => new MainWindowGridRow(n, CurrentWorkspace.InstallInfos)));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<MainWindowGridRow>? CurrentGridRows
|
||||
private static Func<MainWindowGridRow, bool> FilterGridRows(string? searchText)
|
||||
{
|
||||
get
|
||||
{
|
||||
if (currentGridRows == null && CurrentWorkspace?.InstallInfos != null && selectedTreeNode is ActionSetTreeNode node)
|
||||
currentGridRows = [.. node.Infos.Actions.Select(n => new MainWindowGridRow(n, CurrentWorkspace.InstallInfos))];
|
||||
return currentGridRows;
|
||||
}
|
||||
return n => string.IsNullOrWhiteSpace(searchText)
|
||||
|| (!string.IsNullOrWhiteSpace(n.Name) && n.Name.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.InheritFrom) && n.InheritFrom.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.InheritedDestPath) && n.InheritedDestPath.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.InheritedId) && n.InheritedId.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.InheritedSide) && n.InheritedSide.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.InheritedSourceType) && n.InheritedSourceType.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.InheritedUpdateType) && n.InheritedUpdateType.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.SourceName) && n.SourceName.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.SourceOwner) && n.SourceOwner.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.SourceRegex) && n.SourceRegex.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.SourceTag) && n.SourceTag.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.SourceUrl) && n.SourceUrl.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.SrcPath) && n.SrcPath.Contains(searchText))
|
||||
|| (!string.IsNullOrWhiteSpace(n.Website) && n.Website.Contains(searchText))
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,30 @@
|
||||
using System.ComponentModel;
|
||||
using ModpackUpdater.Manager;
|
||||
|
||||
namespace ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
|
||||
|
||||
public record ModUpdateInfo(KeyValuePair<string, string>[] AvailableVersions, InstallAction Origin) : INotifyPropertyChanged
|
||||
public record ModUpdateInfo(ModVersionInfo[] AvailableVersions, InstallAction Origin) : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public int NewVersion { get; set; }
|
||||
public bool Visible { get; set; } = true;
|
||||
|
||||
public string? OldVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (AvailableVersions.FirstOrDefault(n => n.Tag.Equals(Origin.SourceTag)) is { } old
|
||||
&& !old.Name.Equals(old.Tag, StringComparison.InvariantCulture))
|
||||
return $"{old.Name} ({old.Tag})";
|
||||
return Origin.SourceTag;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> DisplayVersions { get; } = AvailableVersions.Select(n =>
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(n.Value) || n.Value.Equals(n.Key, StringComparison.InvariantCulture))
|
||||
return n.Key;
|
||||
return $"{n.Value} ({n.Value})";
|
||||
if (string.IsNullOrWhiteSpace(n.Tag) || n.Tag.Equals(n.Name, StringComparison.InvariantCulture))
|
||||
return n.Name;
|
||||
return $"{n.Name} ({n.Tag})";
|
||||
});
|
||||
}
|
||||
@@ -1,5 +1,9 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using DynamicData;
|
||||
using PropertyChanged;
|
||||
|
||||
namespace ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
|
||||
@@ -9,6 +13,10 @@ public class UpdatesCollectorViewModel : INotifyPropertyChanged
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
public ProgressInfos Progress { get; } = new();
|
||||
public string? SearchText { get; set; }
|
||||
public ObservableCollection<ModUpdateInfo> Updates { get; } = [];
|
||||
public DynamicDataView<ModUpdateInfo> Updates { get; } = new(FilterUpdates);
|
||||
|
||||
private static Func<ModUpdateInfo, bool> FilterUpdates(string? searchText)
|
||||
{
|
||||
return n => string.IsNullOrWhiteSpace(searchText) || (n.Origin.Name != null && n.Origin.Name.Contains(searchText, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
}
|
||||
@@ -25,16 +25,15 @@
|
||||
<!-- TextBox: Search -->
|
||||
<TextBox
|
||||
Grid.Row="0"
|
||||
Watermark="Search"
|
||||
Text="{Binding SearchText}"
|
||||
TextChanged="TextBoxSearch_OnTextChanged"/>
|
||||
Watermark="{x:Static langRes:GeneralLangRes.Search}"
|
||||
Text="{Binding Updates.SearchText}"/>
|
||||
|
||||
<!-- ScrollViewer: Updates -->
|
||||
<ScrollViewer
|
||||
Grid.Row="1">
|
||||
|
||||
<ItemsControl
|
||||
ItemsSource="{Binding Updates}">
|
||||
ItemsSource="{Binding Updates.View}">
|
||||
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
@@ -43,8 +42,7 @@
|
||||
ColumnDefinitions="20*,20*,20*,Auto"
|
||||
ColumnSpacing="6"
|
||||
RowSpacing="6"
|
||||
Margin="3"
|
||||
IsVisible="{Binding Visible}">
|
||||
Margin="3">
|
||||
|
||||
<!-- Label: Name -->
|
||||
<TextBlock
|
||||
@@ -56,7 +54,7 @@
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Origin.SourceTag}"/>
|
||||
Text="{Binding OldVersion}"/>
|
||||
|
||||
<!-- ComboBox: Version (new) -->
|
||||
<ComboBox
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using DynamicData;
|
||||
using ModpackUpdater.Apps.Manager.Api.Model;
|
||||
using ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
|
||||
using ModpackUpdater.Manager;
|
||||
@@ -33,10 +34,10 @@ public partial class UpdatesCollectorView : AvaloniaFlyoutBase
|
||||
|
||||
Model.Progress.Increment();
|
||||
|
||||
if (updates == null || updates.Length == 0 || updates[0].Value == action.SourceTag)
|
||||
if (updates == null || updates.Length == 0 || updates[0].Tag == action.SourceTag)
|
||||
continue;
|
||||
|
||||
Model.Updates.Add(new(updates, action));
|
||||
Model.Updates.List.Add(new(updates, action));
|
||||
|
||||
if (IsClosed)
|
||||
break;
|
||||
@@ -47,7 +48,7 @@ public partial class UpdatesCollectorView : AvaloniaFlyoutBase
|
||||
|
||||
protected override object GetResult()
|
||||
{
|
||||
return new ModUpdates(Model.Updates);
|
||||
return new ModUpdates([.. Model.Updates.List.Items]);
|
||||
}
|
||||
|
||||
private async void Me_OnLoaded(object? sender, RoutedEventArgs e)
|
||||
@@ -55,18 +56,9 @@ public partial class UpdatesCollectorView : AvaloniaFlyoutBase
|
||||
await FindUpdates();
|
||||
}
|
||||
|
||||
private void TextBoxSearch_OnTextChanged(object? sender, TextChangedEventArgs e)
|
||||
{
|
||||
var searchString = Model.SearchText?.Trim().ToLowerInvariant();
|
||||
var hasNoSearch = string.IsNullOrWhiteSpace(searchString);
|
||||
|
||||
foreach (var item in Model.Updates)
|
||||
item.Visible = hasNoSearch || (item.Origin.Name != null && item.Origin.Name.Contains(searchString!, StringComparison.InvariantCultureIgnoreCase));
|
||||
}
|
||||
|
||||
private void ButtonRemoveUpdate_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Button button && button.DataContext is ModUpdateInfo update)
|
||||
Model.Updates.Remove(update);
|
||||
Model.Updates.List.Remove(update);
|
||||
}
|
||||
}
|
||||
@@ -36,7 +36,7 @@ IconFiles = """
|
||||
|
||||
# DOTNET PUBLISH
|
||||
DotnetProjectPath = ModpackUpdater.Apps.Manager.csproj
|
||||
DotnetPublishArgs = -p:Version=${APP_VERSION} --self-contained true -p:DebugType=None -p:DebugSymbols=false -p:PublishSingleFile=true -p:PublishTrimmed=false
|
||||
DotnetPublishArgs = -p:Version=${APP_VERSION} --self-contained true -p:DebugType=None -p:DebugSymbols=false -p:PublishSingleFile=true -p:PublishTrimmed=true
|
||||
DotnetPostPublish =
|
||||
DotnetPostPublishOnWindows =
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
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
|
||||
@@ -10,13 +10,19 @@ using Pilz.Updating.Client;
|
||||
|
||||
namespace ModpackUpdater.Apps;
|
||||
|
||||
public class AppUpdates(string updateUrl, Window mainWindow)
|
||||
public class AppUpdates(string appShortName, Window mainWindow)
|
||||
{
|
||||
public const string UpdateUrl = "https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater/-/snippets/3/raw/main/updates-new.json";
|
||||
|
||||
public event EventHandler? OnDownloadProgramUpdate;
|
||||
|
||||
public bool UsePopups { get; set; }
|
||||
|
||||
public async Task UpdateApp()
|
||||
{
|
||||
#if !DISABLE_UPDATE
|
||||
#if DISABLE_UPDATE
|
||||
await Task.CompletedTask;
|
||||
#else
|
||||
try
|
||||
{
|
||||
await UpdateAppCore();
|
||||
@@ -35,25 +41,33 @@ public class AppUpdates(string updateUrl, Window mainWindow)
|
||||
return;
|
||||
|
||||
var myAppPath = EnvironmentEx.ProcessPath!;
|
||||
var updater = new UpdateClient(updateUrl, Assembly.GetEntryAssembly()!.GetAppVersion(), AppChannel.Stable)
|
||||
var updater = new UpdateClient(UpdateUrl, Assembly.GetEntryAssembly()!.GetAppVersion(), AppChannel.Stable)
|
||||
{
|
||||
Distro = RuntimeInformationsEx.GetRuntimeIdentifier(),
|
||||
Distro = $"{appShortName}-{RuntimeInformationsEx.GetRuntimeIdentifier()}",
|
||||
};
|
||||
|
||||
if (await updater.CheckForUpdate() is not { } packageToInstall || await AskForUpdate() != ButtonResult.Yes)
|
||||
return;
|
||||
|
||||
if (await updater.CheckForUpdate() is {} packageToInstall
|
||||
&& await MessageBoxManager.GetMessageBoxStandard(GeneralMsgBoxLangRes.UpdateAvailable_Title, GeneralMsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowDialogAsync(mainWindow) == ButtonResult.Yes)
|
||||
OnDownloadProgramUpdate?.Invoke(this, EventArgs.Empty);
|
||||
mainWindow.IsEnabled = false;
|
||||
|
||||
if (await updater.DownloadPackageAsync(packageToInstall) && await updater.InstallPackageAsync(packageToInstall, myAppPath))
|
||||
{
|
||||
OnDownloadProgramUpdate?.Invoke(this, EventArgs.Empty);
|
||||
mainWindow.IsEnabled = false;
|
||||
if (await updater.DownloadPackageAsync(packageToInstall)
|
||||
&& await updater.InstallPackageAsync(packageToInstall, myAppPath))
|
||||
{
|
||||
mainWindow.IsVisible = false;
|
||||
await Process.Start(myAppPath).WaitForExitAsync();
|
||||
Environment.Exit(0);
|
||||
return;
|
||||
}
|
||||
mainWindow.IsEnabled = true;
|
||||
mainWindow.IsVisible = false;
|
||||
await Process.Start(myAppPath).WaitForExitAsync();
|
||||
Environment.Exit(0);
|
||||
return;
|
||||
}
|
||||
|
||||
mainWindow.IsEnabled = true;
|
||||
}
|
||||
|
||||
private Task<ButtonResult> AskForUpdate()
|
||||
{
|
||||
var msgBox = MessageBoxManager.GetMessageBoxStandard(GeneralMsgBoxLangRes.UpdateAvailable_Title, GeneralMsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo, Icon.Info);
|
||||
if (UsePopups)
|
||||
return msgBox.ShowAsPopupAsync(mainWindow);
|
||||
return msgBox.ShowWindowDialogAsync(mainWindow);
|
||||
}
|
||||
}
|
||||
3
ModpackUpdater.Manager/ModVersionInfo.cs
Normal file
3
ModpackUpdater.Manager/ModVersionInfo.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace ModpackUpdater.Manager;
|
||||
|
||||
public record ModVersionInfo(string Name, string Tag);
|
||||
@@ -1,7 +1,8 @@
|
||||
using CurseForge.APIClient.Models.Mods;
|
||||
using System.Text.RegularExpressions;
|
||||
using CurseForge.APIClient.Models.Mods;
|
||||
using Modrinth;
|
||||
using Octokit;
|
||||
using System.Text.RegularExpressions;
|
||||
using ApiClient = CurseForge.APIClient.ApiClient;
|
||||
|
||||
namespace ModpackUpdater.Manager;
|
||||
|
||||
@@ -11,7 +12,10 @@ public class ModpackFactory
|
||||
{
|
||||
Credentials = new Credentials("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"),
|
||||
};
|
||||
private readonly CurseForge.APIClient.ApiClient curseForge = new("$2a$10$pE4dD09gmr7IcOe8hjWhleWWjXopJcDNpq1P9FlrDMCBw05pCyAXa", "pilzinsel64@gmx.de");
|
||||
private readonly ApiClient curseForge = new("$2a$10$pE4dD09gmr7IcOe8hjWhleWWjXopJcDNpq1P9FlrDMCBw05pCyAXa", "pilzinsel64@gmx.de")
|
||||
{
|
||||
RequestTimeout = new TimeSpan(0, 0, 30),
|
||||
};
|
||||
private readonly ModrinthClient modrinth = new(new ModrinthClientConfig
|
||||
{
|
||||
ModrinthToken = "mrp_zUlDSET5actMUdTU3FK242TXgvlWgaErSSEFuegNG7thLgkC50IiK2NCGOzW",
|
||||
@@ -26,37 +30,41 @@ public class ModpackFactory
|
||||
|
||||
public async Task<string> ResolveSourceUrl(InstallAction action, Version? targetVersion = null, string? overwriteVersion = null)
|
||||
{
|
||||
if (action.SourceType == SourceType.GitHub)
|
||||
switch (action.SourceType)
|
||||
{
|
||||
var repo = await github.Repository.Get(action.SourceOwner, action.SourceName);
|
||||
var release = await github.Repository.Release.Get(repo.Id, action.SourceTag);
|
||||
var assets = await github.Repository.Release.GetAllAssets(repo.Id, release.Id);
|
||||
case SourceType.GitHub:
|
||||
{
|
||||
var repo = await github.Repository.Get(action.SourceOwner, action.SourceName);
|
||||
var release = await github.Repository.Release.Get(repo.Id, action.SourceTag);
|
||||
var assets = await github.Repository.Release.GetAllAssets(repo.Id, release.Id);
|
||||
|
||||
if (assets.LastOrDefault(asset => Regex.IsMatch(asset.Name, action.SourceRegex)) is ReleaseAsset asset)
|
||||
return asset.BrowserDownloadUrl;
|
||||
}
|
||||
else if (action.SourceType == SourceType.GitLab)
|
||||
{
|
||||
throw new NotImplementedException("To be implemented soon.");
|
||||
}
|
||||
else if (action.SourceType == SourceType.CurseForge)
|
||||
{
|
||||
var res = await curseForge.GetModFileDownloadUrlAsync(Convert.ToInt32(action.SourceName), Convert.ToInt32(action.SourceTag));
|
||||
if (!string.IsNullOrWhiteSpace(res.Data))
|
||||
return res.Data;
|
||||
}
|
||||
else if (action.SourceType == SourceType.Modrinth)
|
||||
{
|
||||
var res = await modrinth.VersionFile.GetVersionByHashAsync(action.SourceTag);
|
||||
var file = res.Files.Length == 1 ? res.Files[0] : res.Files.FirstOrDefault(n => Regex.IsMatch(n.FileName, action.SourceRegex));
|
||||
if (file != null)
|
||||
return file.Url;
|
||||
if (assets.LastOrDefault(a => Regex.IsMatch(a.Name, action.SourceRegex)) is ReleaseAsset asset)
|
||||
return asset.BrowserDownloadUrl;
|
||||
break;
|
||||
}
|
||||
case SourceType.GitLab:
|
||||
throw new NotSupportedException("To be implemented soon.");
|
||||
case SourceType.CurseForge:
|
||||
{
|
||||
var res = await curseForge.GetModFileDownloadUrlAsync(Convert.ToInt32(action.SourceName), Convert.ToInt32(action.SourceTag));
|
||||
if (!string.IsNullOrWhiteSpace(res.Data))
|
||||
return res.Data;
|
||||
break;
|
||||
}
|
||||
case SourceType.Modrinth:
|
||||
{
|
||||
var res = await modrinth.VersionFile.GetVersionByHashAsync(action.SourceTag);
|
||||
var file = res.Files.Length == 1 ? res.Files[0] : res.Files.FirstOrDefault(n => Regex.IsMatch(n.FileName, action.SourceRegex));
|
||||
if (file != null)
|
||||
return file.Url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return action.GetSourceUrl(targetVersion, overwriteVersion: overwriteVersion);
|
||||
}
|
||||
|
||||
public async Task<KeyValuePair<string, string>[]?> FindUpdates(InstallAction action, string? gameVersion, ModLoader modLoader)
|
||||
public async Task<ModVersionInfo[]?> FindUpdates(InstallAction action, string? gameVersion, ModLoader modLoader)
|
||||
{
|
||||
switch (action.SourceType)
|
||||
{
|
||||
@@ -65,7 +73,7 @@ public class ModpackFactory
|
||||
{
|
||||
var repo = await github.Repository.Get(action.SourceOwner, action.SourceName);
|
||||
var releases = await github.Repository.Release.GetAll(repo.Id);
|
||||
return releases.Select(r => new KeyValuePair<string, string>(r.TagName, r.Name ?? r.TagName)).ToArray();
|
||||
return releases.Select(r => new ModVersionInfo(r.Name ?? r.TagName, r.TagName)).ToArray();
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -73,18 +81,18 @@ public class ModpackFactory
|
||||
}
|
||||
break;
|
||||
case SourceType.GitLab:
|
||||
throw new NotImplementedException("To be implemented soon.");
|
||||
throw new NotSupportedException("To be implemented soon.");
|
||||
case SourceType.CurseForge:
|
||||
{
|
||||
var res = await curseForge.GetModFilesAsync(Convert.ToInt32(action.SourceName), gameVersion: gameVersion, modLoaderType: GetModLoaderForCurseForge(modLoader));
|
||||
if (res.Data != null)
|
||||
return res.Data.Select(n => new KeyValuePair<string, string>(n.DisplayName, n.Id.ToString())).ToArray();
|
||||
return res.Data.Select(n => new ModVersionInfo(n.DisplayName, n.Id.ToString())).ToArray();
|
||||
break;
|
||||
}
|
||||
case SourceType.Modrinth:
|
||||
{
|
||||
var res = await modrinth.Version.GetProjectVersionListAsync(action.SourceName, gameVersions: GetGameVersionForModrinth(gameVersion), loaders: GetModLoaderForModrinth(modLoader));
|
||||
return res.Select(v => new KeyValuePair<string, string>($"{v.VersionNumber} {v.ProjectVersionType} {v.Name}", v.Id)).ToArray();
|
||||
return res.Select(v => new ModVersionInfo(v.VersionNumber, v.Id)).ToArray();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -116,7 +124,7 @@ public class ModpackFactory
|
||||
ModLoader.LiteLoader => ["liteloader"],
|
||||
ModLoader.Cauldron => ["cauldron"],
|
||||
ModLoader.Quilt => ["quilt"],
|
||||
_ => null,
|
||||
_ => [],
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
1
publish-scripts
Submodule
1
publish-scripts
Submodule
Submodule publish-scripts added at fd658bd9d1
@@ -1,6 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
for dir in ModpackUpdater.Apps.Client ModpackUpdater.Apps.Client.Gui ModpackUpdater.Apps.Manager; do
|
||||
( cd "$dir" && ./publish.sh "$1" )
|
||||
done
|
||||
Reference in New Issue
Block a user