55 Commits

Author SHA1 Message Date
785c4ce41d version bump 2025-08-23 08:41:02 +02:00
bd7ce5bbe7 use full version string for {version} 2025-08-23 08:40:09 +02:00
8ef522bc6c 1.9.3 2025-08-20 08:32:27 +02:00
582752c987 seperated cli & some work for options 2025-08-20 08:17:33 +02:00
b434ddf480 preparation for dynamic options 2025-07-31 14:51:30 +02:00
8300f571a3 update nuget packages 2025-07-31 14:43:27 +02:00
e86fe2ee17 another fix 2025-07-04 22:27:37 +02:00
531c2a60bf fix option shit 2025-07-04 22:13:47 +02:00
b1ac3cd73c uff, enough for now 2025-06-30 18:55:30 +02:00
6674872848 more release shit 2025-06-30 17:31:42 +02:00
03f27214d6 update client app symbol 2025-06-30 14:44:07 +02:00
d8c798fe09 remove linux update url 2025-06-30 11:49:24 +02:00
70786fc169 version bump 2025-06-30 11:45:38 +02:00
aed70d4f3f update publish profile 2025-06-30 05:53:38 +02:00
45ef76e647 ui: hide installation key if no extras key can be used 2025-06-30 05:50:41 +02:00
433613e43d ui: migrate client back to WinForms
-> let's use wine for comatibility again
-> easier to maintain
-> easier to build dynamic options with
2025-06-29 20:03:02 +02:00
6e8b4f0a9d manager: tree view & action set infos editor panel 2025-06-29 14:19:58 +02:00
87cb9b8b37 update nuget packages 2025-06-29 13:40:36 +02:00
Pascal
77a93b585a manager: add proper support for options 2025-06-27 11:24:53 +02:00
Pascal
d0e3d2fa61 finalize model for option sets 2025-06-27 09:29:57 +02:00
Pascal
f5596ab0ba manager: allow parent path annotations
- Allows unlimited amount of `..\` or `../` at the start of DestPath string.
- Each of then will go back one folder.
- Similar to how Linux works or Visual Studio project styles.
- This allows us to install/update lwjgl3ify in PrismLauncher.
2025-06-27 09:10:18 +02:00
Pascal
09c1ac8b08 ui: simplify workspaces menu 2025-06-27 08:34:03 +02:00
Pascal
4e69acaf04 ui: row context menu fine tuning 2025-06-27 08:24:20 +02:00
Pascal
55db801c4c update nuget packages 2025-06-27 08:22:08 +02:00
Pascal
cbbb546f30 ui: fixed adding new row beeing empty 2025-06-27 08:09:26 +02:00
04848d4622 repair manager project 2025-06-26 18:53:00 +02:00
d85a41c158 update url 2025-06-19 12:54:11 +02:00
798961ea22 update publish profiles 2025-06-19 12:25:33 +02:00
bf0037cf79 hide console on windows only 2025-06-19 12:15:31 +02:00
c52c4059a0 version bump 2025-06-19 11:41:52 +02:00
03fefa33fe update AppUpdate to support linux updates 2025-06-19 11:41:04 +02:00
30b1832cd0 ui: migrate client to gtk 2025-06-17 09:40:10 +02:00
0aa6ed98c6 add install options (WIP) 2025-06-16 15:34:15 +02:00
c1616fecf0 fix modlist plugin not loading 2025-06-16 15:33:37 +02:00
a5eb9fad43 fix some null reference exceptions 2025-04-23 15:40:01 +02:00
df21d8180d version bump 2025-04-23 14:46:04 +02:00
f19974599f add repair mode 2025-04-23 14:45:22 +02:00
e14dedc924 support first placeholder & overwriting version 2025-04-23 13:38:51 +02:00
0285892f20 fixes 2025-04-21 20:55:55 +02:00
01fc5606cb add reftag commandline argument 2025-04-21 20:50:16 +02:00
70805083ba version bump 2025-04-21 20:48:19 +02:00
96cd9bcaac add support for {ref} placeholder 2025-04-21 20:43:09 +02:00
986257c0a4 v1.6.5 2025-04-21 18:40:19 +02:00
b11ad06287 add support for version placeholder in download links 2025-04-21 18:39:47 +02:00
d68dd09ad2 add option to generate markdown table 2025-04-03 06:19:47 +02:00
1b3070493c order by name 2025-01-28 20:46:47 +01:00
1c9c50778a add the missing files from the last commit (wtf?) 2025-01-28 20:43:27 +01:00
33a209a01a add generate modlist feature 2025-01-28 20:38:27 +01:00
2ce73ad032 list only relevant modrinth versions 2025-01-26 09:19:07 +01:00
ecb7ae0d1a fail silently if url can not be resolved 2024-12-22 18:48:30 +01:00
40380d088f version bump 2024-12-07 18:11:48 +01:00
50cbf081e1 fix endless update 2024-12-07 18:11:04 +01:00
3b79335e85 more logging 2024-12-05 07:22:01 +01:00
3e1ab72162 update deps & enable console logging 2024-12-05 07:06:06 +01:00
a83d109f24 fix first install includes ALL updates 2024-12-05 06:56:45 +01:00
73 changed files with 2348 additions and 1841 deletions

View File

@@ -0,0 +1,15 @@
<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.3" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.IO" Version="2.1.0" />
</ItemGroup>
</Project>

View File

@@ -1,9 +1,9 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using Pilz.Configuration; using Pilz.Configuration;
namespace ModpackUpdater.Apps.Client; namespace ModpackUpdater.Apps.Client.Gui;
public class AppConfig : IChildSettings, ISettingsIdentifier public class AppConfig : ISettingsNode, ISettingsIdentifier
{ {
public static string Identifier => "pilz.appconfig"; public static string Identifier => "pilz.appconfig";

View File

@@ -3,9 +3,9 @@ using Newtonsoft.Json.Converters;
using Pilz.Extensions; using Pilz.Extensions;
using System.Reflection; using System.Reflection;
namespace ModpackUpdater.Apps.Client; namespace ModpackUpdater.Apps.Client.Gui;
public class AppUpdater public class AppUpdater(string updateUrl)
{ {
private class UpdateInfo private class UpdateInfo
{ {
@@ -14,7 +14,6 @@ public class AppUpdater
public string DownloadUrl { get; set; } public string DownloadUrl { get; set; }
} }
private const string UPDATE_URL = "https://git.pilzinsel64.de/gaming/minecraft/minecraft-modpack-updater/-/snippets/3/raw/main/updates.json";
private readonly HttpClient httpClient = new(); private readonly HttpClient httpClient = new();
private UpdateInfo info; private UpdateInfo info;
@@ -25,7 +24,7 @@ public class AppUpdater
try try
{ {
var appVersion = Assembly.GetExecutingAssembly().GetAppVersion().Version; var appVersion = Assembly.GetExecutingAssembly().GetAppVersion().Version;
var result = await httpClient.GetStringAsync(UPDATE_URL); var result = await httpClient.GetStringAsync(updateUrl);
info = JsonConvert.DeserializeObject<UpdateInfo>(result); info = JsonConvert.DeserializeObject<UpdateInfo>(result);
if (info is not null && info.Version > appVersion) if (info is not null && info.Version > appVersion)
@@ -42,7 +41,7 @@ public class AppUpdater
{ {
var client = new HttpClient(); var client = new HttpClient();
var tempFileName = Path.GetTempFileName(); var tempFileName = Path.GetTempFileName();
var appFileName = Pilz.Win32.NativeTools.GetExecutablePath(); var appFileName = Environment.ProcessPath;
var oldFileName = appFileName + ".old"; var oldFileName = appFileName + ".old";
// Delete old file // Delete old file
@@ -57,10 +56,11 @@ public class AppUpdater
// Download the new file // Download the new file
using (var tempFileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite)) using (var tempFileStream = new FileStream(tempFileName, FileMode.Create, FileAccess.ReadWrite))
{ {
Stream downloadStream = null; Stream? downloadStream = null;
try try
{ {
downloadStream = await client.GetStreamAsync(info.DownloadUrl); var url = info?.DownloadUrl;
downloadStream = await client.GetStreamAsync(url);
await downloadStream.CopyToAsync(tempFileStream); await downloadStream.CopyToAsync(tempFileStream);
} }
catch catch
@@ -73,7 +73,10 @@ public class AppUpdater
} }
// Replace current application file with new file // Replace current application file with new file
if (!string.IsNullOrWhiteSpace(appFileName))
{
File.Move(appFileName, oldFileName, true); File.Move(appFileName, oldFileName, true);
File.Move(tempFileName, appFileName); File.Move(tempFileName, appFileName);
} }
}
} }

View File

@@ -39,7 +39,7 @@ namespace ModpackUpdater.My.Resources {
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Client.FiledialogFilters", typeof(FiledialogFilters).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Client.Gui.FiledialogFilters", typeof(FiledialogFilters).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;

View File

@@ -39,7 +39,7 @@ namespace ModpackUpdater.My.Resources {
internal static global::System.Resources.ResourceManager ResourceManager { internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Client.LangRes", typeof(LangRes).Assembly); global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Client.Gui.LangRes", typeof(LangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;

View File

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

View File

@@ -2,64 +2,42 @@
using ModpackUpdater.My.Resources; using ModpackUpdater.My.Resources;
using Pilz.Extensions; using Pilz.Extensions;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.UI.WinForms.Extensions;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection; using System.Reflection;
using Telerik.WinControls; using Telerik.WinControls;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Client; namespace ModpackUpdater.Apps.Client.Gui;
public partial class Form1 public partial class MainForm
{ {
private readonly UpdateCheckOptions updateOptions = new();
private ModpackInfo modpackInfo = new(); private ModpackInfo modpackInfo = new();
private ModpackConfig updateConfig = new(); private ModpackConfig updateConfig = new();
private ModpackFeatures features; private ModpackFeatures features;
private bool currentUpdating = false; private UpdateCheckResult lastUpdateCheckResult;
private UpdateCheckResult lastUpdateCheckResult = null; private bool currentUpdating;
private readonly UpdateCheckOptionsAdv updateOptions; private bool loadingData;
private int curOptionsRow = 3;
public Form1(UpdateCheckOptionsAdv updateOptions) : this() public MainForm()
{
this.updateOptions = updateOptions;
if (!string.IsNullOrWhiteSpace(updateOptions.ProfileFolder))
LoadMinecraftProfile(updateOptions.ProfileFolder);
else if (!string.IsNullOrWhiteSpace(AppConfig.Instance.LastMinecraftProfilePath))
LoadMinecraftProfile(AppConfig.Instance.LastMinecraftProfilePath);
}
public Form1()
{ {
InitializeComponent(); InitializeComponent();
Text = $"{Text} (v{Assembly.GetExecutingAssembly().GetAppVersion()})"; Text = $"{Text} (v{Assembly.GetExecutingAssembly().GetAppVersion()})";
RadButton_Install.DefaultItem = radMenuItem_Install;
RadButton_Install.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small);
RadButton_CheckForUpdates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small); RadButton_CheckForUpdates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small);
radButton_RefreshConfig.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.refresh, SymbolSize.Small);
RadButton_SearchMinecraftProfileFolder.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.opened_folder, SymbolSize.Small); RadButton_SearchMinecraftProfileFolder.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.opened_folder, SymbolSize.Small);
radButton_PasteInstallKey.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.paste, SymbolSize.Small); RadButton_Install.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small);
RadButton_PasteModpackConfig.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.paste, SymbolSize.Small); radMenuItem_Install.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small);
radMenuItem_Repair.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.wrench, SymbolSize.Small);
LoadProfileToUi();
} }
private void LoadMinecraftProfile(string folderPath) #region Features
{
RadTextBox_MinecraftProfileFolder.Text = folderPath;
AppConfig.Instance.LastMinecraftProfilePath = folderPath;
CheckStatusAndUpdate(loadedProfile: true);
}
private void LoadUpdateConfigFile(string filePath)
{
RadTextBox_ModpackConfig.Text = filePath;
CheckStatusAndUpdate();
}
private void LoadInstallKey(string installKey)
{
radTextBox_InstallKey.Text = installKey;
CheckStatusAndUpdate();
}
private void SetStatus(string statusText, RadSvgImage image) private void SetStatus(string statusText, RadSvgImage image)
{ {
@@ -73,29 +51,46 @@ public partial class Form1
RadLabel_Status.SvgImage = null; RadLabel_Status.SvgImage = null;
} }
private void CheckStatusAndUpdate(bool loadedProfile = false) private void LoadProfileToUi()
{ {
if (CheckStatus(loadedProfile)) loadingData = true;
RadButton_CheckForUpdates.PerformClick(); tableLayoutPanel1.SuspendLayout();
RadTextBox_MinecraftProfileFolder.Text = modpackInfo?.LocaLPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? RadTextBox_MinecraftProfileFolder.Text;
RadTextBox_ModpackConfig.Text = modpackInfo?.ConfigUrl ?? RadTextBox_ModpackConfig.Text;
radTextBox_InstallKey.Text = modpackInfo?.ExtrasKey ?? radTextBox_InstallKey.Text;
tableLayoutPanel1.ResumeLayout();
loadingData = false;
} }
private bool CheckStatus(bool loadedProfile) private void LoadOptionsToUi()
{
//foreach (var set in )
//{
// // ...
//}
}
private async void CheckStatusAndUpdate(bool loadProfileToUi)
{
if (CheckStatus(loadProfileToUi))
await ExecuteUpdate(false, false);
}
private bool CheckStatus(bool loadProfileToUi)
{ {
try try
{ {
modpackInfo = ModpackInfo.TryLoad(RadTextBox_MinecraftProfileFolder.Text.Trim()); modpackInfo = ModpackInfo.TryLoad(RadTextBox_MinecraftProfileFolder.Text.Trim());
if (loadedProfile)
{
RadTextBox_ModpackConfig.Text = modpackInfo.ConfigUrl;
radTextBox_InstallKey.Text = modpackInfo.ExtrasKey;
}
else
modpackInfo.ExtrasKey = radTextBox_InstallKey.Text;
} }
catch catch
{ {
} }
if (loadProfileToUi)
LoadProfileToUi();
try try
{ {
updateConfig = ModpackConfig.LoadFromUrl(RadTextBox_ModpackConfig.Text); updateConfig = ModpackConfig.LoadFromUrl(RadTextBox_ModpackConfig.Text);
@@ -107,11 +102,11 @@ public partial class Form1
if (modpackInfo != null) if (modpackInfo != null)
features = new(updateConfig); features = new(updateConfig);
radTextBox_InstallKey.Visible = radLabel_InstallationKey.Visible = !string.IsNullOrWhiteSpace(updateConfig.UnleashApiUrl);
if (modpackInfo == null || string.IsNullOrWhiteSpace(RadTextBox_MinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/) if (modpackInfo == null || string.IsNullOrWhiteSpace(RadTextBox_MinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
{ {
SetStatus(LangRes.StatusText_MinecraftProfileWarning, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small)); SetStatus(LangRes.StatusText_MinecraftProfileWarning, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small));
RadButton_PasteModpackConfig.Enabled = false;
radButton_PasteInstallKey.Enabled = false;
RadButton_CheckForUpdates.Enabled = false; RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false; RadButton_Install.Enabled = false;
return false; return false;
@@ -119,8 +114,6 @@ public partial class Form1
else if (updateConfig == null || string.IsNullOrWhiteSpace(RadTextBox_ModpackConfig.Text)) else if (updateConfig == null || string.IsNullOrWhiteSpace(RadTextBox_ModpackConfig.Text))
{ {
SetStatus(LangRes.StatusText_ConfigIncompleteOrNotLoaded, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small)); SetStatus(LangRes.StatusText_ConfigIncompleteOrNotLoaded, AppGlobals.Symbols.GetSvgImage(AppSymbols.general_warning_sign, SymbolSize.Small));
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = false;
RadButton_CheckForUpdates.Enabled = false; RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false; RadButton_Install.Enabled = false;
return false; return false;
@@ -128,22 +121,21 @@ public partial class Form1
else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance) else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance)
{ {
SetStatus(LangRes.StatusText_Maintenance, AppGlobals.Symbols.GetSvgImage(AppSymbols.services, SymbolSize.Small)); SetStatus(LangRes.StatusText_Maintenance, AppGlobals.Symbols.GetSvgImage(AppSymbols.services, SymbolSize.Small));
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = true;
RadButton_CheckForUpdates.Enabled = false; RadButton_CheckForUpdates.Enabled = false;
RadButton_Install.Enabled = false; RadButton_Install.Enabled = false;
return false; return false;
} }
LoadOptionsToUi();
RadButton_PasteModpackConfig.Enabled = true;
radButton_PasteInstallKey.Enabled = true;
RadButton_CheckForUpdates.Enabled = true; RadButton_CheckForUpdates.Enabled = true;
RadButton_Install.Enabled = true; RadButton_Install.Enabled = true;
return true; return true;
} }
private async Task ExecuteUpdate(bool doInstall) private async Task ExecuteUpdate(bool doInstall, bool repair)
{ {
// Ensure set extras key
modpackInfo.ExtrasKey = radTextBox_InstallKey.Text.Trim();
var updater = new ModpackInstaller(updateConfig, modpackInfo); var updater = new ModpackInstaller(updateConfig, modpackInfo);
updater.InstallProgessUpdated += Update_InstallProgessUpdated; updater.InstallProgessUpdated += Update_InstallProgessUpdated;
updater.CheckingProgressUpdated += Updated_CheckingProgresssUpdated; updater.CheckingProgressUpdated += Updated_CheckingProgresssUpdated;
@@ -169,18 +161,21 @@ public partial class Form1
} }
// 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) if (lastUpdateCheckResult is null || !doInstall || repair)
{ {
SetStatus(LangRes.StatusText_CheckingForUpdates, AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small)); SetStatus(LangRes.StatusText_CheckingForUpdates, AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small));
// Check for extras once again // Check for extras once again
updateOptions.IncludeExtras = features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(modpackInfo)); updateOptions.IncludeExtras = features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(modpackInfo));
// Force re-install on repair
updateOptions.IgnoreInstalledVersion = repair;
try try
{ {
lastUpdateCheckResult = await updater.Check(updateOptions); lastUpdateCheckResult = await updater.Check(updateOptions);
} }
catch(Exception) catch (Exception)
{ {
error(); error();
if (Debugger.IsAttached) if (Debugger.IsAttached)
@@ -198,6 +193,10 @@ public partial class Form1
return; return;
} }
// Load options
// lastUpdateCheckResult.OptionsAvailable...
// lastUpdateCheckResult.OptionsEnabled...
// No updates available // No updates available
if (!lastUpdateCheckResult.HasUpdates) if (!lastUpdateCheckResult.HasUpdates)
{ {
@@ -237,74 +236,93 @@ public partial class Form1
} }
} }
private void Updated_CheckingProgresssUpdated(int toCheck, int processed)
{
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small));
}
private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs) private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs)
{ {
int actionCount = result.Actions.Count; int actionCount = result.Actions.Count;
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small)); SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
} }
private void Updated_CheckingProgresssUpdated(int toCheck, int processed) #endregion
#region Gui
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{ {
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small)); AppConfig.Instance.LastMinecraftProfilePath = RadTextBox_MinecraftProfileFolder.Text.Trim();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private async void Form1_Shown(object sender, EventArgs e)
{
var updater = new AppUpdater(Program.UPDATE_URL);
if (await updater.Check() && RadMessageBox.Show(LangRes.MsgBox_UpdateAvailable, LangRes.MsgBox_UpdateAvailable_Title, MessageBoxButtons.YesNo, RadMessageIcon.Info).IsYes())
{
SetStatus(LangRes.StatusText_InstallingAppUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
Enabled = false;
await updater.Install();
Application.Restart();
return;
}
CheckStatusAndUpdate(true);
}
private void RadTextBox_MinecraftFolder_TextInserted(object o, EventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(true);
}
private void RadTextBox_ModpackUrl_TextInserted(object o, EventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(false);
}
private void RadTextBox_InstallationKey_TextInserted(object o, EventArgs args)
{
if (!loadingData)
CheckStatusAndUpdate(false);
} }
private void ButtonX_SearchMinecraftProfile_Click(object sender, EventArgs e) private void ButtonX_SearchMinecraftProfile_Click(object sender, EventArgs e)
{ {
var ofd = new RadOpenFolderDialog(); var ofd = new RadOpenFolderDialog();
if (ofd.ShowDialog(this) == DialogResult.OK) if (ofd.ShowDialog(this) == DialogResult.OK)
LoadMinecraftProfile(ofd.FileName); RadTextBox_MinecraftProfileFolder.Text = ofd.FileName;
}
private void RadButton_PasteModpackConfig_Click(object sender, EventArgs e)
{
LoadUpdateConfigFile(Clipboard.GetText());
}
private void RadButton_PasteInstallKey_Click(object sender, EventArgs e)
{
LoadInstallKey(Clipboard.GetText());
}
private void RadButton_RefreshConfig_Click(object sender, EventArgs e)
{
LoadUpdateConfigFile(RadTextBox_ModpackConfig.Text);
} }
private async void ButtonX_CheckForUpdates_Click(object sender, EventArgs e) private async void ButtonX_CheckForUpdates_Click(object sender, EventArgs e)
{ {
ClearStatus(); ClearStatus();
await ExecuteUpdate(false); await ExecuteUpdate(false, false);
} }
private async void ButtonX_StartUpdate_Click(object sender, EventArgs e) private async void RadMenuItem_Install_Click(object sender, EventArgs e)
{ {
if (!currentUpdating) if (!currentUpdating)
{ {
ClearStatus(); ClearStatus();
await ExecuteUpdate(true); await ExecuteUpdate(true, false);
} }
} }
private void Form1_FormClosing(object sender, FormClosingEventArgs e) private async void RadMenuItem_Repair_Click(object sender, EventArgs e)
{ {
AppConfig.Instance.LastMinecraftProfilePath = RadTextBox_MinecraftProfileFolder.Text; if (!currentUpdating)
{
ClearStatus();
await ExecuteUpdate(true, true);
}
} }
private void Form1_Load(object sender, EventArgs e) #endregion
{
if (Directory.Exists(AppConfig.Instance.LastMinecraftProfilePath))
LoadMinecraftProfile(AppConfig.Instance.LastMinecraftProfilePath);
}
private async void Form1_Shown(object sender, EventArgs e)
{
var updater = new AppUpdater();
if (!updateOptions.NoUpdate && await updater.Check() && RadMessageBox.Show(LangRes.MsgBox_UpdateAvailable, LangRes.MsgBox_UpdateAvailable_Title, MessageBoxButtons.YesNo, RadMessageIcon.Info) == DialogResult.Yes)
{
SetStatus(LangRes.StatusText_InstallingAppUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.software_installer, SymbolSize.Small));
Enabled = false;
await updater.Install();
Application.Restart();
}
}
} }

View File

@@ -0,0 +1,64 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework>
<ApplicationIcon>minecraft modpack updater.ico</ApplicationIcon>
<AssemblyName>Minecraft Modpack Updater</AssemblyName>
<ImplicitUsings>true</ImplicitUsings>
<UseWindowsForms>true</UseWindowsForms>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\Version.cs" />
</ItemGroup>
<ItemGroup>
<Compile Update="FiledialogFilters.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>FiledialogFilters.resx</DependentUpon>
</Compile>
<Compile Update="LangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>LangRes.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="FiledialogFilters.resx">
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>FiledialogFilters.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>LangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Pilz.Configuration" Version="3.2.6" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.IO" Version="2.1.0" />
<PackageReference Include="Pilz.UI" Version="3.0.0" />
<PackageReference Include="Pilz.UI.WinForms" Version="2.6.2" />
<PackageReference Include="Pilz.UI.WinForms.Telerik" Version="2.13.3" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.2.612-preview" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.2.612-preview" />
</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\ModpackUpdater.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,64 @@
using Castle.Core.Logging;
using Newtonsoft.Json;
using Pilz.Configuration;
namespace ModpackUpdater.Apps.Client.Gui;
public static class Program
{
public const string UPDATE_URL = "https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater/-/snippets/3/raw/main/updates.json";
private static readonly SettingsManager settingsManager;
private static readonly ILogger log = new ConsoleLogger();
public static ISettings Settings => settingsManager.Instance;
public static ILogger Log => log;
static Program()
{
settingsManager = new(GetSettingsPath(2), true);
MigrateLegacySettings(GetSettingsPath(null));
}
[STAThread]
internal static void Main(string[] args)
{
ApplicationConfiguration.Initialize();
AppGlobals.Initialize();
Application.Run(new MainForm());
}
private static string GetSettingsPath(int? settingsVersion = 3)
{
const string AppDataDirectoryName = "MinecraftModpackUpdater";
var fileNamePostfix = settingsVersion == null ? string.Empty : $"V{settingsVersion}";
var SettingsFileName = $"Settings{fileNamePostfix}.json";
var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName);
Directory.CreateDirectory(settingsPath);
settingsPath = Path.Combine(settingsPath, SettingsFileName);
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);
}
}

View File

@@ -6,12 +6,12 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
<PropertyGroup> <PropertyGroup>
<Configuration>Release</Configuration> <Configuration>Release</Configuration>
<Platform>Any CPU</Platform> <Platform>Any CPU</Platform>
<PublishDir>bin\publish\general\</PublishDir> <PublishDir>..\publish\ui\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol> <PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId> <_TargetId>Folder</_TargetId>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<RuntimeIdentifier>win-x86</RuntimeIdentifier> <RuntimeIdentifier>win-x86</RuntimeIdentifier>
<SelfContained>false</SelfContained> <SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile> <PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun> <PublishReadyToRun>false</PublishReadyToRun>
</PropertyGroup> </PropertyGroup>

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

@@ -1,334 +0,0 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
namespace ModpackUpdater.Apps.Client
{
[Microsoft.VisualBasic.CompilerServices.DesignerGenerated()]
public partial class Form1 : Telerik.WinControls.UI.RadForm
{
// Das Formular überschreibt den Löschvorgang, um die Komponentenliste zu bereinigen.
[DebuggerNonUserCode()]
protected override void Dispose(bool disposing)
{
try
{
if (disposing && components is not null)
components.Dispose();
}
finally
{
base.Dispose(disposing);
}
}
// Wird vom Windows Form-Designer benötigt.
private System.ComponentModel.IContainer components = new System.ComponentModel.Container();
// Hinweis: Die folgende Prozedur ist für den Windows Form-Designer erforderlich.
// Das Bearbeiten ist mit dem Windows Form-Designer möglich.
// Das Bearbeiten mit dem Code-Editor ist nicht möglich.
[DebuggerStepThrough()]
private void InitializeComponent()
{
var resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
RadLabel1 = new Telerik.WinControls.UI.RadLabel();
RadLabel2 = new Telerik.WinControls.UI.RadLabel();
RadLabel3 = new Telerik.WinControls.UI.RadLabel();
RadLabel_Status = new Telerik.WinControls.UI.RadLabel();
RadTextBox_MinecraftProfileFolder = new Telerik.WinControls.UI.RadTextBox();
RadTextBox_ModpackConfig = new Telerik.WinControls.UI.RadTextBox();
RadButton_Install = new Telerik.WinControls.UI.RadButton();
RadButton_CheckForUpdates = new Telerik.WinControls.UI.RadButton();
RadButton_PasteModpackConfig = new Telerik.WinControls.UI.RadButton();
RadButton_SearchMinecraftProfileFolder = new Telerik.WinControls.UI.RadButton();
tableLayoutPanel1 = new TableLayoutPanel();
radLabel4 = new Telerik.WinControls.UI.RadLabel();
radTextBox_InstallKey = new Telerik.WinControls.UI.RadTextBox();
radButton_PasteInstallKey = new Telerik.WinControls.UI.RadButton();
radButton_RefreshConfig = new Telerik.WinControls.UI.RadButton();
((System.ComponentModel.ISupportInitialize)RadLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel2).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel3).BeginInit();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_MinecraftProfileFolder).BeginInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_ModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_PasteModpackConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).BeginInit();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel4).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radButton_PasteInstallKey).BeginInit();
((System.ComponentModel.ISupportInitialize)radButton_RefreshConfig).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout();
//
// RadLabel1
//
RadLabel1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
RadLabel1.AutoSize = false;
RadLabel1.Location = new Point(3, 3);
RadLabel1.Name = "RadLabel1";
RadLabel1.Size = new Size(144, 24);
RadLabel1.TabIndex = 0;
RadLabel1.Text = "Minecraft profile folder:";
//
// RadLabel2
//
RadLabel2.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
RadLabel2.AutoSize = false;
RadLabel2.Location = new Point(3, 63);
RadLabel2.Name = "RadLabel2";
RadLabel2.Size = new Size(144, 24);
RadLabel2.TabIndex = 1;
RadLabel2.Text = "Modpack config:";
//
// RadLabel3
//
RadLabel3.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
RadLabel3.AutoSize = false;
RadLabel3.Location = new Point(3, 183);
RadLabel3.Name = "RadLabel3";
RadLabel3.Size = new Size(144, 24);
RadLabel3.TabIndex = 2;
RadLabel3.Text = "Status:";
//
// RadLabel_Status
//
RadLabel_Status.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
RadLabel_Status.AutoSize = false;
tableLayoutPanel1.SetColumnSpan(RadLabel_Status, 6);
RadLabel_Status.Location = new Point(153, 183);
RadLabel_Status.Name = "RadLabel_Status";
RadLabel_Status.Size = new Size(266, 24);
RadLabel_Status.TabIndex = 3;
RadLabel_Status.Text = "-";
RadLabel_Status.TextImageRelation = TextImageRelation.ImageBeforeText;
//
// RadTextBox_MinecraftProfileFolder
//
RadTextBox_MinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBox_MinecraftProfileFolder, 6);
RadTextBox_MinecraftProfileFolder.Location = new Point(153, 3);
RadTextBox_MinecraftProfileFolder.Name = "RadTextBox_MinecraftProfileFolder";
RadTextBox_MinecraftProfileFolder.NullText = "No file loaded!";
RadTextBox_MinecraftProfileFolder.ReadOnly = true;
RadTextBox_MinecraftProfileFolder.Size = new Size(266, 24);
RadTextBox_MinecraftProfileFolder.TabIndex = 4;
//
// RadTextBox_ModpackConfig
//
RadTextBox_ModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadTextBox_ModpackConfig, 6);
RadTextBox_ModpackConfig.Location = new Point(153, 63);
RadTextBox_ModpackConfig.Name = "RadTextBox_ModpackConfig";
RadTextBox_ModpackConfig.NullText = "No config url provided.";
RadTextBox_ModpackConfig.ReadOnly = true;
RadTextBox_ModpackConfig.Size = new Size(266, 24);
RadTextBox_ModpackConfig.TabIndex = 5;
//
// RadButton_Install
//
RadButton_Install.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_Install, 2);
RadButton_Install.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_Install.Location = new Point(325, 213);
RadButton_Install.Name = "RadButton_Install";
RadButton_Install.Size = new Size(94, 24);
RadButton_Install.TabIndex = 10;
RadButton_Install.Text = "Install";
RadButton_Install.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_Install.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_Install.Click += ButtonX_StartUpdate_Click;
//
// RadButton_CheckForUpdates
//
RadButton_CheckForUpdates.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_CheckForUpdates, 3);
RadButton_CheckForUpdates.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_CheckForUpdates.Location = new Point(175, 213);
RadButton_CheckForUpdates.Name = "RadButton_CheckForUpdates";
RadButton_CheckForUpdates.Size = new Size(144, 24);
RadButton_CheckForUpdates.TabIndex = 0;
RadButton_CheckForUpdates.Text = "Check for Updates";
RadButton_CheckForUpdates.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_CheckForUpdates.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_CheckForUpdates.Click += ButtonX_CheckForUpdates_Click;
//
// RadButton_PasteModpackConfig
//
RadButton_PasteModpackConfig.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_PasteModpackConfig, 2);
RadButton_PasteModpackConfig.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_PasteModpackConfig.Location = new Point(325, 93);
RadButton_PasteModpackConfig.Name = "RadButton_PasteModpackConfig";
RadButton_PasteModpackConfig.Size = new Size(94, 24);
RadButton_PasteModpackConfig.TabIndex = 7;
RadButton_PasteModpackConfig.Text = "Paste";
RadButton_PasteModpackConfig.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_PasteModpackConfig.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_PasteModpackConfig.Click += RadButton_PasteModpackConfig_Click;
//
// RadButton_SearchMinecraftProfileFolder
//
RadButton_SearchMinecraftProfileFolder.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(RadButton_SearchMinecraftProfileFolder, 2);
RadButton_SearchMinecraftProfileFolder.ImageAlignment = ContentAlignment.MiddleRight;
RadButton_SearchMinecraftProfileFolder.Location = new Point(325, 33);
RadButton_SearchMinecraftProfileFolder.Name = "RadButton_SearchMinecraftProfileFolder";
RadButton_SearchMinecraftProfileFolder.Size = new Size(94, 24);
RadButton_SearchMinecraftProfileFolder.TabIndex = 6;
RadButton_SearchMinecraftProfileFolder.Text = "Search";
RadButton_SearchMinecraftProfileFolder.TextAlignment = ContentAlignment.MiddleLeft;
RadButton_SearchMinecraftProfileFolder.TextImageRelation = TextImageRelation.ImageBeforeText;
RadButton_SearchMinecraftProfileFolder.Click += ButtonX_SearchMinecraftProfile_Click;
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel1.ColumnCount = 7;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 150F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 50F));
tableLayoutPanel1.Controls.Add(RadButton_CheckForUpdates, 2, 7);
tableLayoutPanel1.Controls.Add(RadLabel1, 0, 0);
tableLayoutPanel1.Controls.Add(RadLabel2, 0, 2);
tableLayoutPanel1.Controls.Add(RadTextBox_MinecraftProfileFolder, 1, 0);
tableLayoutPanel1.Controls.Add(RadTextBox_ModpackConfig, 1, 2);
tableLayoutPanel1.Controls.Add(RadLabel_Status, 1, 6);
tableLayoutPanel1.Controls.Add(RadLabel3, 0, 6);
tableLayoutPanel1.Controls.Add(RadButton_SearchMinecraftProfileFolder, 5, 1);
tableLayoutPanel1.Controls.Add(RadButton_Install, 5, 7);
tableLayoutPanel1.Controls.Add(radLabel4, 0, 4);
tableLayoutPanel1.Controls.Add(radTextBox_InstallKey, 1, 4);
tableLayoutPanel1.Controls.Add(radButton_PasteInstallKey, 5, 5);
tableLayoutPanel1.Controls.Add(RadButton_PasteModpackConfig, 5, 3);
tableLayoutPanel1.Controls.Add(radButton_RefreshConfig, 4, 3);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 0);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 8;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(422, 249);
tableLayoutPanel1.TabIndex = 7;
//
// radLabel4
//
radLabel4.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radLabel4.AutoSize = false;
radLabel4.Location = new Point(3, 123);
radLabel4.Name = "radLabel4";
radLabel4.Size = new Size(144, 24);
radLabel4.TabIndex = 12;
radLabel4.Text = "Installation key:";
//
// radTextBox_InstallKey
//
radTextBox_InstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radTextBox_InstallKey, 6);
radTextBox_InstallKey.Location = new Point(153, 123);
radTextBox_InstallKey.Name = "radTextBox_InstallKey";
radTextBox_InstallKey.NullText = "No key provided. Only for private servers.";
radTextBox_InstallKey.ReadOnly = true;
radTextBox_InstallKey.Size = new Size(266, 24);
radTextBox_InstallKey.TabIndex = 13;
//
// radButton_PasteInstallKey
//
radButton_PasteInstallKey.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel1.SetColumnSpan(radButton_PasteInstallKey, 2);
radButton_PasteInstallKey.ImageAlignment = ContentAlignment.MiddleRight;
radButton_PasteInstallKey.Location = new Point(325, 153);
radButton_PasteInstallKey.Name = "radButton_PasteInstallKey";
radButton_PasteInstallKey.Size = new Size(94, 24);
radButton_PasteInstallKey.TabIndex = 14;
radButton_PasteInstallKey.Text = "Paste";
radButton_PasteInstallKey.TextAlignment = ContentAlignment.MiddleLeft;
radButton_PasteInstallKey.TextImageRelation = TextImageRelation.ImageBeforeText;
radButton_PasteInstallKey.Click += RadButton_PasteInstallKey_Click;
//
// radButton_RefreshConfig
//
radButton_RefreshConfig.Anchor = AnchorStyles.Top | AnchorStyles.Right;
radButton_RefreshConfig.DisplayStyle = Telerik.WinControls.DisplayStyle.Image;
radButton_RefreshConfig.ImageAlignment = ContentAlignment.MiddleCenter;
radButton_RefreshConfig.Location = new Point(295, 93);
radButton_RefreshConfig.Name = "radButton_RefreshConfig";
radButton_RefreshConfig.Size = new Size(24, 24);
radButton_RefreshConfig.TabIndex = 11;
radButton_RefreshConfig.Text = "Reload";
radButton_RefreshConfig.Click += RadButton_RefreshConfig_Click;
//
// Form1
//
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
ClientSize = new Size(422, 249);
Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon");
MaximizeBox = false;
MinimumSize = new Size(430, 0);
Name = "Form1";
StartPosition = FormStartPosition.CenterScreen;
Text = "Minecraft Modpack Updater";
FormClosing += Form1_FormClosing;
Load += Form1_Load;
Shown += Form1_Shown;
((System.ComponentModel.ISupportInitialize)RadLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel2).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel3).EndInit();
((System.ComponentModel.ISupportInitialize)RadLabel_Status).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_MinecraftProfileFolder).EndInit();
((System.ComponentModel.ISupportInitialize)RadTextBox_ModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_Install).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_CheckForUpdates).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_PasteModpackConfig).EndInit();
((System.ComponentModel.ISupportInitialize)RadButton_SearchMinecraftProfileFolder).EndInit();
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)radLabel4).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)radButton_PasteInstallKey).EndInit();
((System.ComponentModel.ISupportInitialize)radButton_RefreshConfig).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
PerformLayout();
}
internal Telerik.WinControls.UI.RadLabel RadLabel1;
internal Telerik.WinControls.UI.RadLabel RadLabel2;
internal Telerik.WinControls.UI.RadLabel RadLabel3;
internal Telerik.WinControls.UI.RadLabel RadLabel_Status;
internal Telerik.WinControls.UI.RadTextBox RadTextBox_MinecraftProfileFolder;
internal Telerik.WinControls.UI.RadTextBox RadTextBox_ModpackConfig;
internal Telerik.WinControls.UI.RadButton RadButton_Install;
internal Telerik.WinControls.UI.RadButton RadButton_CheckForUpdates;
internal Telerik.WinControls.UI.RadButton RadButton_SearchMinecraftProfileFolder;
internal Telerik.WinControls.UI.RadButton RadButton_PasteModpackConfig;
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadButton radButton_RefreshConfig;
internal Telerik.WinControls.UI.RadLabel radLabel4;
internal Telerik.WinControls.UI.RadTextBox radTextBox_InstallKey;
internal Telerik.WinControls.UI.RadButton radButton_PasteInstallKey;
}
}

View File

@@ -2,54 +2,25 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms> <ImplicitUsings>enable</ImplicitUsings>
<ApplicationIcon>icons8_download_from_ftp.ico</ApplicationIcon> <Nullable>enable</Nullable>
<AssemblyName>Minecraft Modpack Updater</AssemblyName> <AssemblyName>mmu-cli</AssemblyName>
<ImplicitUsings>true</ImplicitUsings>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Update="FiledialogFilters.Designer.cs"> <Compile Include="..\Version.cs" />
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>FiledialogFilters.resx</DependentUpon>
</Compile>
<Compile Update="LangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>LangRes.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="FiledialogFilters.resx">
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>FiledialogFilters.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<CustomToolNamespace>ModpackUpdater.My.Resources</CustomToolNamespace>
<LastGenOutput>LangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup> </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.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Pilz.Configuration" Version="3.1.3" /> <PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.1" />
<PackageReference Include="Pilz.IO" Version="2.1.0" /> <PackageReference Include="Pilz.IO" Version="2.1.0" />
<PackageReference Include="Pilz.UI" Version="2.3.10" />
<PackageReference Include="Pilz.UI.Telerik" Version="2.7.4" />
<PackageReference Include="Pilz.Win32" Version="2.1.0" />
<PackageReference Include="UI.for.WinForms.Common" Version="2024.3.806" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Apps\ModpackUpdater.Apps.csproj" /> <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

@@ -10,7 +10,8 @@ internal class Options
public IReadOnlyList<string> Additionals => additionals; public IReadOnlyList<string> Additionals => additionals;
public bool Help { get; private set; } public bool Help { get; private set; }
public bool Silent { get; private set; } public bool Silent { get; private set; }
public bool NoUi { get; private set; } public string? RefTag { get; private set; }
public string? Version { get; private set; }
public UpdateCheckOptionsAdv UpdateOptions { get; } = new(); public UpdateCheckOptionsAdv UpdateOptions { get; } = new();
public Options(string[] args) public Options(string[] args)
@@ -19,15 +20,15 @@ internal class Options
{ {
{ "silent", "Do not output anything.", s => Silent = true }, { "silent", "Do not output anything.", s => Silent = true },
{ "h|help", "Writes the help text as output.", h => Help = true }, { "h|help", "Writes the help text as output.", h => Help = true },
{ "n|noui", "Install without user interface.", n => NoUi = true },
{ "p|profile=", "Sets the minecraft profile folder.", p => UpdateOptions.ProfileFolder = p }, { "p|profile=", "Sets the minecraft profile folder.", p => UpdateOptions.ProfileFolder = p },
{ "c|config=", "Sets the modpack update info url.", c => UpdateOptions.ModpackConfig = c }, { "c|config=", "Sets the modpack update info url.", c => UpdateOptions.ModpackConfig = c },
{ "s|side=", "Sets the installation side.\nDefault side is Client.\nAvailable: Client, Server", s => UpdateOptions.Side = Enum.Parse<Side>(s)}, { "s|side=", "Sets the installation side.\nDefault side is Client.\nAvailable: Client, Server", s => UpdateOptions.Side = Enum.Parse<Side>(s)},
{ "u|uai", "Disallow an update directly after install. This only has effect if there is no existing installation.", uai => UpdateOptions.AllowUpdaterAfterInstall = false}, { "u|uai", "Disallow an update directly after install. This only has effect if there is no existing installation.", uai => UpdateOptions.AllowUpdaterAfterInstall = false},
{ "noupdate", "Skip the update check.", noupdate => UpdateOptions.NoUpdate = true},
{ "m|maintenance", "Ignores the maintenance mode.", m => UpdateOptions.IgnoreMaintenance = true}, { "m|maintenance", "Ignores the maintenance mode.", m => UpdateOptions.IgnoreMaintenance = true},
{ "i|nonpublic", "Include non public (currently hidden) updates.", i => UpdateOptions.IncludeNonPublic = true}, { "i|nonpublic", "Include non public (currently hidden) updates.", i => UpdateOptions.IncludeNonPublic = true},
{ "k|key=", "An key for retriving extra files on updates.", k => UpdateOptions.ExtrasKey = k}, { "k|key=", "An key for retriving extra files on updates.", k => UpdateOptions.ExtrasKey = k},
{ "r|reftag=", "Force uses a specific reference tag, if supported.", r => RefTag = r},
{ "v|version=", "Force uses a specific version, if supported.", v => Version = v},
}; };
additionals.AddRange(options.Parse(args)); additionals.AddRange(options.Parse(args));

View File

@@ -1,93 +1,29 @@
using ModpackUpdater.Manager; using Castle.Core.Logging;
using Newtonsoft.Json; using ModpackUpdater.Manager;
using Pilz;
using Pilz.Configuration;
using System.Runtime.InteropServices;
[assembly: AssemblyAppVersion("1.6.2.0")]
namespace ModpackUpdater.Apps.Client; namespace ModpackUpdater.Apps.Client;
public static class Program public static class Program
{ {
private static readonly SettingsManager settingsManager; private static readonly ILogger log = new ConsoleLogger();
public static ISettings Settings => settingsManager.Instance; public static ILogger Log => log;
internal static Options Options { get; private set; } = null!;
[DllImport("kernel32.dll")]
static extern nint GetConsoleWindow();
[DllImport("user32.dll")]
static extern bool ShowWindow(nint hWnd, int nCmdShow);
static Program()
{
settingsManager = new(GetSettingsPath(2), true);
MigrateLegacySettings(GetSettingsPath(null));
}
[STAThread] [STAThread]
internal static void Main(string[] args) internal static void Main(string[] args)
{ {
var options = new Options(args); Options = new Options(args);
if (options.Help) if (Options.Help)
options.DrawHelp(); Options.DrawHelp();
else if (options.NoUi)
InstallWithoutGui(options.UpdateOptions, options.Silent);
else else
{ InstallWithoutGui(Options.UpdateOptions, Options.Silent);
ShowWindow(GetConsoleWindow(), 0);
RunApp(options.UpdateOptions);
}
}
private static void RunApp(UpdateCheckOptionsAdv updateOptions)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);
AppGlobals.Initialize();
Application.Run(new Form1(updateOptions));
}
private static string GetSettingsPath(int? settingsVersion = 3)
{
const string AppDataDirectoryName = "MinecraftModpackUpdater";
var fileNamePostfix = settingsVersion == null ? string.Empty : $"V{settingsVersion}";
var SettingsFileName = $"Settings{fileNamePostfix}.json";
var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName);
Directory.CreateDirectory(settingsPath);
settingsPath = Path.Combine(settingsPath, SettingsFileName);
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);
} }
private static void InstallWithoutGui(UpdateCheckOptionsAdv updateOptions, bool silent) private static void InstallWithoutGui(UpdateCheckOptionsAdv updateOptions, bool silent)
{ {
var info = ModpackInfo.TryLoad(updateOptions.ProfileFolder); var info = ModpackInfo.TryLoad(updateOptions.ProfileFolder);
var config = ModpackConfig.LoadFromUrl(CheckModpackConfigUrl(updateOptions.ModpackConfig, info)); var config = ModpackConfig.LoadFromUrl(CheckModpackConfigUrl(updateOptions.ModpackConfig!, info));
var features = new ModpackFeatures(config); var features = new ModpackFeatures(config);
// Check features // Check features
@@ -97,20 +33,22 @@ public static class Program
updateOptions.IncludeExtras = features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(info)); updateOptions.IncludeExtras = features.IsEnabled(ModpackFeatures.FeatureAllowExtas, new AllowExtrasFeatureContext(info));
// Check for update // Check for update
var installer = new ModpackInstaller(config, info); var installer = new ModpackInstaller(config, info)
{
OverwriteRefTag = Options.RefTag,
OverwriteVersion = Options.Version,
Log = Log,
};
var result = installer.Check(updateOptions).Result; var result = installer.Check(updateOptions).Result;
if (!silent && !updateOptions.NoUpdate && new AppUpdater().Check().Result)
Console.WriteLine("A new version is available!");
if (result.HasUpdates) if (result.HasUpdates)
{ {
var success = installer.Install(result).Result; var success = installer.Install(result).Result;
if (!silent) if (!silent)
Console.WriteLine($"Installation {(success ?? false ? "completed successfully" : "failed")}!"); Log.Info($"Installation {(success ?? false ? "completed successfully" : "failed")}!");
} }
else if (!silent) else if (!silent)
Console.WriteLine("No updates available"); Log.Info("No updates available");
} }
private static string CheckModpackConfigUrl(string configUrl, ModpackInfo info) private static string CheckModpackConfigUrl(string configUrl, ModpackInfo info)

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>..\publish\cli\linux-arm64</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifier>linux-arm64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>..\publish\cli\linux-x64</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifier>linux-x64</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>..\publish\cli\windows\</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0</TargetFramework>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
<PublishReadyToRun>false</PublishReadyToRun>
<PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>
</Project>

View File

@@ -4,8 +4,7 @@ namespace ModpackUpdater.Apps.Client;
public class UpdateCheckOptionsAdv : UpdateCheckOptions public class UpdateCheckOptionsAdv : UpdateCheckOptions
{ {
public string ProfileFolder { get; set; } public string? ProfileFolder { get; set; }
public string ModpackConfig { get; set; } public string? ModpackConfig { get; set; }
public bool NoUpdate { get; set; } public string? ExtrasKey { get; set; }
public string ExtrasKey { get; set; }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -1,8 +1,9 @@
using Microsoft.Extensions.Primitives; using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using ModpackUpdater.Manager; using ModpackUpdater.Manager;
using Pilz.UI.Extensions; using OfficeOpenXml;
using Pilz.UI.WinForms.Extensions;
using System.Text; using System.Text;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
@@ -122,11 +123,18 @@ internal static class SharedFunctions
foreach (var action in actions) foreach (var action in actions)
{ {
if (action.SourceType != SourceType.DirectLink) if (action.SourceType != SourceType.DirectLink)
{
try
{ {
Task.Run(async () => Task.Run(async () =>
{ {
action.SourceUrl = await factory.ResolveSourceUrl(action); action.SourceUrl = await factory.ResolveSourceUrl(action);
}).Wait(); }).Wait();
}
catch (Exception)
{
// Fail silently
}
api.UpdateItem(action); api.UpdateItem(action);
} }
} }
@@ -202,4 +210,100 @@ internal static class SharedFunctions
return log.ToString().TrimEnd(); return log.ToString().TrimEnd();
} }
public static string GenerateModlistAsMarkdown(InstallInfos installInfos)
{
var sb = new StringBuilder();
sb.Append("|" + ActionsListLangRes.Col_Name);
sb.Append("|" + ActionsListLangRes.Col_SrcTag);
sb.Append("|" + ActionsListLangRes.Col_Side);
sb.Append("|" + ActionsListLangRes.Col_SrcType);
sb.Append("|" + ActionsListLangRes.Col_SrcOwner);
sb.Append("|" + ActionsListLangRes.Col_SrcName);
sb.AppendLine("|");
sb.AppendLine("|---|---|---|---|---|---|");
// Rows
foreach (var action in installInfos.Actions.OrderBy(n => n.Name))
{
if (action.IsExtra || action.IsZip || string.IsNullOrWhiteSpace(action.Id) || !action.Id.StartsWith("mod:"))
continue;
if (string.IsNullOrWhiteSpace(action.Website))
sb.Append($"|{action.Name}");
else
sb.Append($"|[{action.Name}]({action.Website})");
if (string.IsNullOrWhiteSpace(action.SourceUrl))
sb.Append($"|{action.SourceTag}");
else
sb.Append($"|[{action.SourceTag}]({action.GetSourceUrl(installInfos.Version)})");
sb.Append($"|{action.Side.ToString()}");
sb.Append($"|{action.SourceType}");
sb.Append($"|{action.SourceOwner}");
sb.Append($"|{action.SourceName}");
sb.AppendLine("|");
}
return sb.ToString().TrimEnd();
}
public static ExcelPackage? GenerateModlistAsExcel(InstallInfos installInfos)
{
var pkg = new ExcelPackage();
var ws = pkg.Workbook.Worksheets.Add(string.Format(GeneralLangRes.Text_ModlistForVersion, installInfos.Version));
var cr = 1;
var cc = 1;
// Header
ws.Cells[cr, cc++].Value = ActionsListLangRes.Col_Name;
ws.Cells[cr, cc++].Value = ActionsListLangRes.Col_SrcTag;
ws.Cells[cr, cc++].Value = ActionsListLangRes.Col_Side;
ws.Cells[cr, cc++].Value = ActionsListLangRes.Col_SrcType;
ws.Cells[cr, cc++].Value = ActionsListLangRes.Col_SrcOwner;
ws.Cells[cr, cc++].Value = ActionsListLangRes.Col_SrcName;
cr += 1;
cc = 1;
// Rows
foreach (var action in installInfos.Actions.OrderBy(n => n.Name))
{
if (action.IsExtra || action.IsZip || string.IsNullOrWhiteSpace(action.Id) || !action.Id.StartsWith("mod:"))
continue;
var cellName = ws.Cells[cr, cc++];
cellName.Value = action.Name;
if (!string.IsNullOrWhiteSpace(action.Website))
cellName.SetHyperlink(new Uri(action.Website));
var cellTag = ws.Cells[cr, cc++];
cellTag.Value = string.IsNullOrWhiteSpace(action.SourceTag) ? "direct link" : action.SourceTag;
if (!string.IsNullOrWhiteSpace(action.SourceUrl))
cellTag.SetHyperlink(new Uri(action.GetSourceUrl(installInfos.Version)));
ws.Cells[cr, cc++].Value = action.Side.ToString();
ws.Cells[cr, cc++].Value = action.SourceType;
ws.Cells[cr, cc++].Value = action.SourceOwner;
ws.Cells[cr, cc++].Value = action.SourceName;
cr += 1;
cc = 1;
}
// Styling
cc = 1;
ws.Column(cc++).Width = 30;
ws.Column(cc++).Width = 20;
ws.Column(cc++).Width = 10;
ws.Column(cc++).Width = 20;
ws.Column(cc++).Width = 20;
ws.Column(cc++).Width = 30;
var tableDef = ws.Tables.Add(ws.Cells[1, 1, cr - 1, cc - 1], "Table");
tableDef.TableStyle = OfficeOpenXml.Table.TableStyles.Medium16;
tableDef.ShowHeader = true;
return pkg;
}
} }

View File

@@ -0,0 +1,39 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced;
using Telerik.WinControls;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class GenerateModlistAsExcelFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsExcelFeature>
{
public static GenerateModlistAsExcelFeature Instance { get; } = new();
public GenerateModlistAsExcelFeature() : base(FeatureTypes.Tools, "origin.genmodlist.xlsx", FeatureNamesLangRes.GenerateModlistAsExcelFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.list_view, Pilz.UI.Symbols.SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurWorkspace?.InstallInfos is null)
return null;
using var pkg = SharedFunctions.GenerateModlistAsExcel(p.Api.CurWorkspace.InstallInfos);
if (pkg is null)
return null;
using var sfd = new RadSaveFileDialog
{
Filter = "*.xlsx|*.xlsx|*|*"
};
if (sfd.ShowDialog(p.Api.MainWindow) == DialogResult.OK)
{
pkg.SaveAs(sfd.FileName);
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ModlistGenerated, MsgBoxLangRes.ModlistGenerated_Title, MessageBoxButtons.OK, RadMessageIcon.Info);
}
return null;
}
}

View File

@@ -0,0 +1,27 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced;
using Telerik.WinControls;
namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class GenerateModlistAsMarkdownFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsMarkdownFeature>
{
public static GenerateModlistAsMarkdownFeature Instance { get; } = new();
public GenerateModlistAsMarkdownFeature() : base(FeatureTypes.Tools, "origin.genmodlist.md", FeatureNamesLangRes.GenerateModlistAsMarkdownFeature)
{
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.list_view, Pilz.UI.Symbols.SymbolSize.Small);
}
protected override object? ExecuteFunction(PluginFunctionParameter? @params)
{
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurWorkspace?.InstallInfos is null)
return null;
Clipboard.SetText(SharedFunctions.GenerateModlistAsMarkdown(p.Api.CurWorkspace.InstallInfos));
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ModlistCopiedToClipboard, MsgBoxLangRes.ModlistCopiedToClipboard_Title, MessageBoxButtons.OK, RadMessageIcon.Info);
return null;
}
}

View File

@@ -1,7 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Apps.Manager.Api.Model;
using NGitLab; using NGitLab;
using NGitLab.Models; using NGitLab.Models;
using System.Text.Encodings.Web;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo; namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;

View File

@@ -1,5 +1,5 @@
using Pilz.UI; using Pilz.UI;
using Pilz.UI.Telerik.Dialogs; using Pilz.UI.WinForms.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo; namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;

View File

@@ -2,9 +2,9 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Features; using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Plugins.Advanced; using Pilz.Plugins.Advanced;
using Pilz.UI.Extensions;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.UI.Telerik.Dialogs; using Pilz.UI.WinForms.Extensions;
using Pilz.UI.WinForms.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo; namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;

View File

@@ -105,6 +105,24 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Generate modlist excel file ähnelt.
/// </summary>
internal static string GenerateModlistAsExcelFeature {
get {
return ResourceManager.GetString("GenerateModlistAsExcelFeature", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Generate modlist markdown table ähnelt.
/// </summary>
internal static string GenerateModlistAsMarkdownFeature {
get {
return ResourceManager.GetString("GenerateModlistAsMarkdownFeature", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die GitLab workspace ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die GitLab workspace ähnelt.
/// </summary> /// </summary>

View File

@@ -132,6 +132,12 @@
<data name="GenerateChangelogFeature" xml:space="preserve"> <data name="GenerateChangelogFeature" xml:space="preserve">
<value>Generate changelog</value> <value>Generate changelog</value>
</data> </data>
<data name="GenerateModlistAsExcelFeature" xml:space="preserve">
<value>Generate modlist excel file</value>
</data>
<data name="GenerateModlistAsMarkdownFeature" xml:space="preserve">
<value>Generate modlist markdown table</value>
</data>
<data name="GitLabWorkspace" xml:space="preserve"> <data name="GitLabWorkspace" xml:space="preserve">
<value>GitLab workspace</value> <value>GitLab workspace</value>
</data> </data>

View File

@@ -77,5 +77,14 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
return ResourceManager.GetString("Node_Update", resourceCulture); return ResourceManager.GetString("Node_Update", resourceCulture);
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Modlist for v{0} ähnelt.
/// </summary>
internal static string Text_ModlistForVersion {
get {
return ResourceManager.GetString("Text_ModlistForVersion", resourceCulture);
}
}
} }
} }

View File

@@ -123,4 +123,7 @@
<data name="Node_Update" xml:space="preserve"> <data name="Node_Update" xml:space="preserve">
<value>Update: {0}</value> <value>Update: {0}</value>
</data> </data>
<data name="Text_ModlistForVersion" xml:space="preserve">
<value>Modlist for v{0}</value>
</data>
</root> </root>

View File

@@ -78,6 +78,42 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The modlist has been generated and copied to the clipboard. ähnelt.
/// </summary>
internal static string ModlistCopiedToClipboard {
get {
return ResourceManager.GetString("ModlistCopiedToClipboard", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Modlist generated successfully ähnelt.
/// </summary>
internal static string ModlistCopiedToClipboard_Title {
get {
return ResourceManager.GetString("ModlistCopiedToClipboard_Title", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die The modlist has been generated successfully and saved to the selected location. ähnelt.
/// </summary>
internal static string ModlistGenerated {
get {
return ResourceManager.GetString("ModlistGenerated", resourceCulture);
}
}
/// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Modlist generated successfully ähnelt.
/// </summary>
internal static string ModlistGenerated_Title {
get {
return ResourceManager.GetString("ModlistGenerated_Title", resourceCulture);
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Zeichenfolge, die Are you sure that you want to delete this update? ähnelt. /// Sucht eine lokalisierte Zeichenfolge, die Are you sure that you want to delete this update? ähnelt.
/// </summary> /// </summary>

View File

@@ -123,6 +123,18 @@
<data name="ChangelogCopiedToClipboard_Title" xml:space="preserve"> <data name="ChangelogCopiedToClipboard_Title" xml:space="preserve">
<value>Changelog generated successfully</value> <value>Changelog generated successfully</value>
</data> </data>
<data name="ModlistCopiedToClipboard" xml:space="preserve">
<value>The modlist has been generated and copied to the clipboard.</value>
</data>
<data name="ModlistCopiedToClipboard_Title" xml:space="preserve">
<value>Modlist generated successfully</value>
</data>
<data name="ModlistGenerated" xml:space="preserve">
<value>The modlist has been generated successfully and saved to the selected location.</value>
</data>
<data name="ModlistGenerated_Title" xml:space="preserve">
<value>Modlist generated successfully</value>
</data>
<data name="RemoveUpdate" xml:space="preserve"> <data name="RemoveUpdate" xml:space="preserve">
<value>Are you sure that you want to delete this update?</value> <value>Are you sure that you want to delete this update?</value>
</data> </data>

View File

@@ -11,15 +11,19 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="NGitLab" Version="6.55.0" /> <PackageReference Include="EPPlus" Version="8.0.8" />
<PackageReference Include="Pilz.Configuration" Version="3.1.3" /> <PackageReference Include="NGitLab" Version="9.2.0" />
<PackageReference Include="Pilz.Plugins.Advanced" Version="2.10.1" /> <PackageReference Include="Pilz.Configuration" Version="3.2.6" />
<PackageReference Include="Pilz.Plugins.Advanced.UI" Version="1.7.0" /> <PackageReference Include="Pilz.Plugins.Advanced" Version="2.10.7" />
<PackageReference Include="Pilz.Plugins.Advanced.UI.Telerik" Version="1.7.0" /> <PackageReference Include="Pilz.Plugins.Advanced.UI.WinForms" Version="1.9.1" />
<PackageReference Include="Pilz.UI" Version="2.3.10" /> <PackageReference Include="Pilz.Plugins.Advanced.UI.WinForms.Telerik" Version="1.8.3" />
<PackageReference Include="Pilz.UI.Telerik" Version="2.7.4" /> <PackageReference Include="Pilz.UI" Version="3.0.0" />
<PackageReference Include="UI.for.WinForms.Common" Version="2024.3.806" /> <PackageReference Include="Pilz.UI.WinForms" Version="2.6.2" />
<PackageReference Include="UI.for.WinForms.GridView" Version="2024.3.806" /> <PackageReference Include="Pilz.UI.WinForms.Telerik" Version="2.13.3" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.2.612-preview" />
<PackageReference Include="UI.for.WinForms.GridView" Version="2025.2.612-preview" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.2.612-preview" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -1,9 +1,8 @@
using OfficeOpenXml;
using Pilz; using Pilz;
using Pilz.Configuration; using Pilz.Configuration;
using Pilz.Plugins.Advanced; using Pilz.Plugins.Advanced;
[assembly: AssemblyAppVersion("1.0.0.0")]
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager;
public static class Program public static class Program
@@ -14,6 +13,7 @@ public static class Program
static Program() static Program()
{ {
ExcelPackage.License.SetNonCommercialPersonal("Pilzinsel64");
settingsManager = new(GetSettingsPath(), true); settingsManager = new(GetSettingsPath(), true);
} }

View File

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://go.microsoft.com/fwlink/?LinkID=208121. -->
<Project>
<PropertyGroup>
<Configuration>Release</Configuration>
<Platform>Any CPU</Platform>
<PublishDir>H:\Applications\Minecraft Modpack Manager</PublishDir>
<PublishProtocol>FileSystem</PublishProtocol>
<_TargetId>Folder</_TargetId>
<TargetFramework>net8.0-windows</TargetFramework>
<SelfContained>false</SelfContained>
</PropertyGroup>
</Project>

View File

@@ -29,46 +29,53 @@ partial class MainForm
/// </summary> /// </summary>
private void InitializeComponent() private void InitializeComponent()
{ {
var tableViewDefinition1 = new Telerik.WinControls.UI.TableViewDefinition(); var tableViewDefinition2 = new Telerik.WinControls.UI.TableViewDefinition();
var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm)); var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer(); radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer();
splitPanel1 = new Telerik.WinControls.UI.SplitPanel(); splitPanel1 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel2 = new TableLayoutPanel(); tableLayoutPanel2 = new TableLayoutPanel();
radListControl_Updates = new Telerik.WinControls.UI.RadListControl(); radTreeView_Sets = new Telerik.WinControls.UI.RadTreeView();
splitPanel2 = new Telerik.WinControls.UI.SplitPanel(); splitPanel2 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel1 = new TableLayoutPanel(); tableLayoutPanel_ActionSet = new TableLayoutPanel();
radGridView_Actions = new Telerik.WinControls.UI.RadGridView(); radGridView_Actions = new Telerik.WinControls.UI.RadGridView();
tableLayoutPanel_ActionSetInfo = new TableLayoutPanel();
radLabel1 = new Telerik.WinControls.UI.RadLabel();
radTextBoxControl_Version = new Telerik.WinControls.UI.RadTextBoxControl();
radCheckBox_IsPublic = new Telerik.WinControls.UI.RadCheckBox();
radMenuItem_Workspace = new Telerik.WinControls.UI.RadMenuItem(); radMenuItem_Workspace = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_WorkspacePreferences = new Telerik.WinControls.UI.RadMenuItem(); radMenuItem_WorkspacePreferences = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_SaveWorkspace = new Telerik.WinControls.UI.RadMenuItem(); radMenuItem_SaveWorkspace = new Telerik.WinControls.UI.RadMenuItem();
radMenuSeparatorItem1 = new Telerik.WinControls.UI.RadMenuSeparatorItem(); radMenuSeparatorItem1 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
radMenuItem_OpenNewWorkspace = new Telerik.WinControls.UI.RadMenuItem(); radMenuHeaderItem_NewWorkspace = new Telerik.WinControls.UI.RadMenuHeaderItem();
radMenuItem_RecentWorkspaces = new Telerik.WinControls.UI.RadMenuItem(); radMenuSeparatorItem3 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
radMenuHeaderItem_RecentWorkspaces = new Telerik.WinControls.UI.RadMenuHeaderItem();
radMenuItem_Tools = new Telerik.WinControls.UI.RadMenuItem(); radMenuItem_Tools = new Telerik.WinControls.UI.RadMenuItem();
radMenu1 = new Telerik.WinControls.UI.RadMenu();
radMenuItem_Updates = new Telerik.WinControls.UI.RadMenuItem(); radMenuItem_Updates = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_EditUpdate = new Telerik.WinControls.UI.RadMenuItem();
radMenuSeparatorItem2 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
radMenuItem_CreateUpdate = new Telerik.WinControls.UI.RadMenuItem(); radMenuItem_CreateUpdate = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_RemoveUpdate = new Telerik.WinControls.UI.RadMenuItem(); radMenuItem_RemoveUpdate = new Telerik.WinControls.UI.RadMenuItem();
radWaitingBar_Updates = new Telerik.WinControls.UI.RadWaitingBar(); radWaitingBar_Updates = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement(); dotsRingWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement();
radWaitingBar_Actions = new Telerik.WinControls.UI.RadWaitingBar(); radWaitingBar_Actions = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement2 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement(); dotsRingWaitingBarIndicatorElement2 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement();
radMenu1 = new Telerik.WinControls.UI.RadMenu();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit(); ((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit();
radSplitContainer1.SuspendLayout(); radSplitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit(); ((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit();
splitPanel1.SuspendLayout(); splitPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout(); tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radListControl_Updates).BeginInit(); ((System.ComponentModel.ISupportInitialize)radTreeView_Sets).BeginInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).BeginInit(); ((System.ComponentModel.ISupportInitialize)splitPanel2).BeginInit();
splitPanel2.SuspendLayout(); splitPanel2.SuspendLayout();
tableLayoutPanel1.SuspendLayout(); tableLayoutPanel_ActionSet.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).BeginInit(); ((System.ComponentModel.ISupportInitialize)radGridView_Actions).BeginInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).BeginInit(); ((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).BeginInit();
((System.ComponentModel.ISupportInitialize)radMenu1).BeginInit(); tableLayoutPanel_ActionSetInfo.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_Version).BeginInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).BeginInit(); ((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).BeginInit(); ((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).BeginInit();
((System.ComponentModel.ISupportInitialize)radMenu1).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit(); ((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout(); SuspendLayout();
// //
@@ -79,10 +86,6 @@ partial class MainForm
radSplitContainer1.Dock = DockStyle.Fill; radSplitContainer1.Dock = DockStyle.Fill;
radSplitContainer1.Location = new Point(0, 28); radSplitContainer1.Location = new Point(0, 28);
radSplitContainer1.Name = "radSplitContainer1"; radSplitContainer1.Name = "radSplitContainer1";
//
//
//
radSplitContainer1.RootElement.MinSize = new Size(25, 25);
radSplitContainer1.Size = new Size(800, 422); radSplitContainer1.Size = new Size(800, 422);
radSplitContainer1.TabIndex = 0; radSplitContainer1.TabIndex = 0;
radSplitContainer1.TabStop = false; radSplitContainer1.TabStop = false;
@@ -92,14 +95,11 @@ partial class MainForm
splitPanel1.Controls.Add(tableLayoutPanel2); splitPanel1.Controls.Add(tableLayoutPanel2);
splitPanel1.Location = new Point(0, 0); splitPanel1.Location = new Point(0, 0);
splitPanel1.Name = "splitPanel1"; splitPanel1.Name = "splitPanel1";
// splitPanel1.Size = new Size(232, 422);
// splitPanel1.SizeInfo.AbsoluteSize = new Size(232, 200);
//
splitPanel1.RootElement.MinSize = new Size(25, 25);
splitPanel1.Size = new Size(200, 422);
splitPanel1.SizeInfo.AutoSizeScale = new SizeF(-0.190954775F, 0F); splitPanel1.SizeInfo.AutoSizeScale = new SizeF(-0.190954775F, 0F);
splitPanel1.SizeInfo.SizeMode = Telerik.WinControls.UI.Docking.SplitPanelSizeMode.Absolute; splitPanel1.SizeInfo.SizeMode = Telerik.WinControls.UI.Docking.SplitPanelSizeMode.Absolute;
splitPanel1.SizeInfo.SplitterCorrection = new Size(-152, 0); splitPanel1.SizeInfo.SplitterCorrection = new Size(-120, 0);
splitPanel1.TabIndex = 0; splitPanel1.TabIndex = 0;
splitPanel1.TabStop = false; splitPanel1.TabStop = false;
// //
@@ -107,57 +107,57 @@ partial class MainForm
// //
tableLayoutPanel2.ColumnCount = 1; tableLayoutPanel2.ColumnCount = 1;
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel2.Controls.Add(radListControl_Updates, 0, 0); tableLayoutPanel2.Controls.Add(radTreeView_Sets, 0, 0);
tableLayoutPanel2.Dock = DockStyle.Fill; tableLayoutPanel2.Dock = DockStyle.Fill;
tableLayoutPanel2.Location = new Point(0, 0); tableLayoutPanel2.Location = new Point(0, 0);
tableLayoutPanel2.Name = "tableLayoutPanel2"; tableLayoutPanel2.Name = "tableLayoutPanel2";
tableLayoutPanel2.RowCount = 1; tableLayoutPanel2.RowCount = 1;
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
tableLayoutPanel2.Size = new Size(200, 422); tableLayoutPanel2.Size = new Size(232, 422);
tableLayoutPanel2.TabIndex = 1; tableLayoutPanel2.TabIndex = 1;
// //
// radListControl_Updates // radTreeView_Sets
// //
radListControl_Updates.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; radTreeView_Sets.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radListControl_Updates.ItemHeight = 24; radTreeView_Sets.ItemHeight = 24;
radListControl_Updates.Location = new Point(3, 3); radTreeView_Sets.LineColor = Color.FromArgb(152, 152, 152);
radListControl_Updates.Name = "radListControl_Updates"; radTreeView_Sets.LineStyle = Telerik.WinControls.UI.TreeLineStyle.Solid;
radListControl_Updates.Size = new Size(194, 416); radTreeView_Sets.Location = new Point(3, 3);
radListControl_Updates.TabIndex = 0; radTreeView_Sets.Name = "radTreeView_Sets";
radListControl_Updates.SelectedIndexChanged += RadListControl_Updates_SelectedIndexChanged; radTreeView_Sets.Size = new Size(226, 416);
radTreeView_Sets.TabIndex = 0;
radTreeView_Sets.SelectedNodeChanged += RadTreeView_Sets_SelectedNodeChanged;
// //
// splitPanel2 // splitPanel2
// //
splitPanel2.Controls.Add(tableLayoutPanel1); splitPanel2.Controls.Add(tableLayoutPanel_ActionSet);
splitPanel2.Location = new Point(204, 0); splitPanel2.Location = new Point(236, 0);
splitPanel2.Name = "splitPanel2"; splitPanel2.Name = "splitPanel2";
// splitPanel2.Size = new Size(564, 422);
// splitPanel2.SizeInfo.AutoSizeScale = new SizeF(-0.0600000024F, 0F);
// splitPanel2.SizeInfo.SplitterCorrection = new Size(120, 0);
splitPanel2.RootElement.MinSize = new Size(25, 25);
splitPanel2.Size = new Size(596, 422);
splitPanel2.SizeInfo.AutoSizeScale = new SizeF(0.190954745F, 0F);
splitPanel2.SizeInfo.SplitterCorrection = new Size(152, 0);
splitPanel2.TabIndex = 1; splitPanel2.TabIndex = 1;
splitPanel2.TabStop = false; splitPanel2.TabStop = false;
// //
// tableLayoutPanel1 // tableLayoutPanel_ActionSet
// //
tableLayoutPanel1.ColumnCount = 1; tableLayoutPanel_ActionSet.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F)); tableLayoutPanel_ActionSet.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(radGridView_Actions, 0, 0); tableLayoutPanel_ActionSet.Controls.Add(radGridView_Actions, 0, 1);
tableLayoutPanel1.Dock = DockStyle.Fill; tableLayoutPanel_ActionSet.Controls.Add(tableLayoutPanel_ActionSetInfo, 0, 0);
tableLayoutPanel1.Location = new Point(0, 0); tableLayoutPanel_ActionSet.Dock = DockStyle.Fill;
tableLayoutPanel1.Name = "tableLayoutPanel1"; tableLayoutPanel_ActionSet.Location = new Point(0, 0);
tableLayoutPanel1.RowCount = 1; tableLayoutPanel_ActionSet.Name = "tableLayoutPanel_ActionSet";
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 50F)); tableLayoutPanel_ActionSet.RowCount = 2;
tableLayoutPanel1.Size = new Size(596, 422); tableLayoutPanel_ActionSet.RowStyles.Add(new RowStyle());
tableLayoutPanel1.TabIndex = 0; tableLayoutPanel_ActionSet.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSet.Size = new Size(564, 422);
tableLayoutPanel_ActionSet.TabIndex = 0;
// //
// radGridView_Actions // radGridView_Actions
// //
radGridView_Actions.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; radGridView_Actions.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radGridView_Actions.Location = new Point(3, 3); radGridView_Actions.Location = new Point(3, 33);
// //
// //
// //
@@ -167,9 +167,9 @@ partial class MainForm
radGridView_Actions.MasterTemplate.AllowRowResize = false; radGridView_Actions.MasterTemplate.AllowRowResize = false;
radGridView_Actions.MasterTemplate.AllowSearchRow = true; radGridView_Actions.MasterTemplate.AllowSearchRow = true;
radGridView_Actions.MasterTemplate.EnableGrouping = false; radGridView_Actions.MasterTemplate.EnableGrouping = false;
radGridView_Actions.MasterTemplate.ViewDefinition = tableViewDefinition1; radGridView_Actions.MasterTemplate.ViewDefinition = tableViewDefinition2;
radGridView_Actions.Name = "radGridView_Actions"; radGridView_Actions.Name = "radGridView_Actions";
radGridView_Actions.Size = new Size(590, 416); radGridView_Actions.Size = new Size(558, 386);
radGridView_Actions.TabIndex = 0; radGridView_Actions.TabIndex = 0;
radGridView_Actions.CellFormatting += RadGridView_Actions_CellFormatting; radGridView_Actions.CellFormatting += RadGridView_Actions_CellFormatting;
radGridView_Actions.UserAddedRow += RadGridView_Actions_UserAddedRow; radGridView_Actions.UserAddedRow += RadGridView_Actions_UserAddedRow;
@@ -177,9 +177,58 @@ partial class MainForm
radGridView_Actions.CellValueChanged += RadGridView_Actions_CellValueChanged; radGridView_Actions.CellValueChanged += RadGridView_Actions_CellValueChanged;
radGridView_Actions.ContextMenuOpening += RadGridView_Actions_ContextMenuOpening; radGridView_Actions.ContextMenuOpening += RadGridView_Actions_ContextMenuOpening;
// //
// tableLayoutPanel_ActionSetInfo
//
tableLayoutPanel_ActionSetInfo.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel_ActionSetInfo.AutoSize = true;
tableLayoutPanel_ActionSetInfo.ColumnCount = 3;
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.Controls.Add(radLabel1, 0, 0);
tableLayoutPanel_ActionSetInfo.Controls.Add(radTextBoxControl_Version, 1, 0);
tableLayoutPanel_ActionSetInfo.Controls.Add(radCheckBox_IsPublic, 2, 0);
tableLayoutPanel_ActionSetInfo.Location = new Point(0, 0);
tableLayoutPanel_ActionSetInfo.Margin = new Padding(0);
tableLayoutPanel_ActionSetInfo.Name = "tableLayoutPanel_ActionSetInfo";
tableLayoutPanel_ActionSetInfo.RowCount = 1;
tableLayoutPanel_ActionSetInfo.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSetInfo.Size = new Size(564, 30);
tableLayoutPanel_ActionSetInfo.TabIndex = 1;
//
// radLabel1
//
radLabel1.Anchor = AnchorStyles.Left;
radLabel1.Location = new Point(3, 4);
radLabel1.Name = "radLabel1";
radLabel1.Size = new Size(58, 22);
radLabel1.TabIndex = 0;
radLabel1.Text = "Version:";
//
// radTextBoxControl_Version
//
radTextBoxControl_Version.Anchor = AnchorStyles.Left;
radTextBoxControl_Version.AutoSize = true;
radTextBoxControl_Version.Location = new Point(67, 3);
radTextBoxControl_Version.Name = "radTextBoxControl_Version";
radTextBoxControl_Version.NullText = "e.g. 1.2.5.0";
radTextBoxControl_Version.Size = new Size(150, 24);
radTextBoxControl_Version.TabIndex = 1;
radTextBoxControl_Version.TextChanged += RadTextBoxControl1_TextChanged;
//
// radCheckBox_IsPublic
//
radCheckBox_IsPublic.Anchor = AnchorStyles.Left;
radCheckBox_IsPublic.Location = new Point(223, 5);
radCheckBox_IsPublic.Name = "radCheckBox_IsPublic";
radCheckBox_IsPublic.Size = new Size(76, 20);
radCheckBox_IsPublic.TabIndex = 2;
radCheckBox_IsPublic.Text = "Is public";
radCheckBox_IsPublic.ToggleStateChanged += RadCheckBox1_ToggleStateChanged;
//
// radMenuItem_Workspace // radMenuItem_Workspace
// //
radMenuItem_Workspace.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_WorkspacePreferences, radMenuItem_SaveWorkspace, radMenuSeparatorItem1, radMenuItem_OpenNewWorkspace, radMenuItem_RecentWorkspaces }); radMenuItem_Workspace.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_WorkspacePreferences, radMenuItem_SaveWorkspace, radMenuSeparatorItem1, radMenuHeaderItem_NewWorkspace, radMenuSeparatorItem3, radMenuHeaderItem_RecentWorkspaces });
radMenuItem_Workspace.Name = "radMenuItem_Workspace"; radMenuItem_Workspace.Name = "radMenuItem_Workspace";
radMenuItem_Workspace.Text = "Workspace"; radMenuItem_Workspace.Text = "Workspace";
// //
@@ -201,48 +250,34 @@ partial class MainForm
radMenuSeparatorItem1.Text = "radMenuSeparatorItem1"; radMenuSeparatorItem1.Text = "radMenuSeparatorItem1";
radMenuSeparatorItem1.TextAlignment = ContentAlignment.MiddleLeft; radMenuSeparatorItem1.TextAlignment = ContentAlignment.MiddleLeft;
// //
// radMenuItem_OpenNewWorkspace // radMenuHeaderItem_NewWorkspace
// //
radMenuItem_OpenNewWorkspace.Name = "radMenuItem_OpenNewWorkspace"; radMenuHeaderItem_NewWorkspace.Name = "radMenuHeaderItem_NewWorkspace";
radMenuItem_OpenNewWorkspace.Text = "Open new workspace"; radMenuHeaderItem_NewWorkspace.Text = "New workspace";
// //
// radMenuItem_RecentWorkspaces // radMenuSeparatorItem3
// //
radMenuItem_RecentWorkspaces.Name = "radMenuItem_RecentWorkspaces"; radMenuSeparatorItem3.Name = "radMenuSeparatorItem3";
radMenuItem_RecentWorkspaces.Text = "Recent workspaces"; radMenuSeparatorItem3.Text = "radMenuSeparatorItem3";
radMenuSeparatorItem3.TextAlignment = ContentAlignment.MiddleLeft;
//
// radMenuHeaderItem_RecentWorkspaces
//
radMenuHeaderItem_RecentWorkspaces.Name = "radMenuHeaderItem_RecentWorkspaces";
radMenuHeaderItem_RecentWorkspaces.Text = "Recent workspaces";
// //
// radMenuItem_Tools // radMenuItem_Tools
// //
radMenuItem_Tools.Name = "radMenuItem_Tools"; radMenuItem_Tools.Name = "radMenuItem_Tools";
radMenuItem_Tools.Text = "Tools"; radMenuItem_Tools.Text = "Tools";
// //
// radMenu1
//
radMenu1.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_Workspace, radMenuItem_Updates, radMenuItem_Tools });
radMenu1.Location = new Point(0, 0);
radMenu1.Name = "radMenu1";
radMenu1.Size = new Size(800, 28);
radMenu1.TabIndex = 1;
//
// radMenuItem_Updates // radMenuItem_Updates
// //
radMenuItem_Updates.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_EditUpdate, radMenuSeparatorItem2, radMenuItem_CreateUpdate, radMenuItem_RemoveUpdate }); radMenuItem_Updates.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_CreateUpdate, radMenuItem_RemoveUpdate });
radMenuItem_Updates.Name = "radMenuItem_Updates"; radMenuItem_Updates.Name = "radMenuItem_Updates";
radMenuItem_Updates.Text = "Updates"; radMenuItem_Updates.Text = "Updates";
radMenuItem_Updates.DropDownOpening += RadMenuItem_Updates_DropDownOpening; radMenuItem_Updates.DropDownOpening += RadMenuItem_Updates_DropDownOpening;
// //
// radMenuItem_EditUpdate
//
radMenuItem_EditUpdate.Name = "radMenuItem_EditUpdate";
radMenuItem_EditUpdate.Text = "Edit";
radMenuItem_EditUpdate.Click += RadMenuItem_EditUpdate_Click;
//
// radMenuSeparatorItem2
//
radMenuSeparatorItem2.Name = "radMenuSeparatorItem2";
radMenuSeparatorItem2.Text = "radMenuSeparatorItem2";
radMenuSeparatorItem2.TextAlignment = ContentAlignment.MiddleLeft;
//
// radMenuItem_CreateUpdate // radMenuItem_CreateUpdate
// //
radMenuItem_CreateUpdate.Name = "radMenuItem_CreateUpdate"; radMenuItem_CreateUpdate.Name = "radMenuItem_CreateUpdate";
@@ -257,7 +292,7 @@ partial class MainForm
// //
// radWaitingBar_Updates // radWaitingBar_Updates
// //
radWaitingBar_Updates.AssociatedControl = radListControl_Updates; radWaitingBar_Updates.AssociatedControl = radTreeView_Sets;
radWaitingBar_Updates.Location = new Point(0, 78); radWaitingBar_Updates.Location = new Point(0, 78);
radWaitingBar_Updates.Name = "radWaitingBar_Updates"; radWaitingBar_Updates.Name = "radWaitingBar_Updates";
radWaitingBar_Updates.Size = new Size(70, 70); radWaitingBar_Updates.Size = new Size(70, 70);
@@ -289,6 +324,14 @@ partial class MainForm
// //
dotsRingWaitingBarIndicatorElement2.Name = "dotsRingWaitingBarIndicatorElement2"; dotsRingWaitingBarIndicatorElement2.Name = "dotsRingWaitingBarIndicatorElement2";
// //
// radMenu1
//
radMenu1.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_Workspace, radMenuItem_Updates, radMenuItem_Tools });
radMenu1.Location = new Point(0, 0);
radMenu1.Name = "radMenu1";
radMenu1.Size = new Size(800, 28);
radMenu1.TabIndex = 1;
//
// MainForm // MainForm
// //
AutoScaleBaseSize = new Size(7, 15); AutoScaleBaseSize = new Size(7, 15);
@@ -310,15 +353,21 @@ partial class MainForm
((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit(); ((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit();
splitPanel1.ResumeLayout(false); splitPanel1.ResumeLayout(false);
tableLayoutPanel2.ResumeLayout(false); tableLayoutPanel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radListControl_Updates).EndInit(); ((System.ComponentModel.ISupportInitialize)radTreeView_Sets).EndInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).EndInit(); ((System.ComponentModel.ISupportInitialize)splitPanel2).EndInit();
splitPanel2.ResumeLayout(false); splitPanel2.ResumeLayout(false);
tableLayoutPanel1.ResumeLayout(false); tableLayoutPanel_ActionSet.ResumeLayout(false);
tableLayoutPanel_ActionSet.PerformLayout();
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).EndInit(); ((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).EndInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).EndInit(); ((System.ComponentModel.ISupportInitialize)radGridView_Actions).EndInit();
((System.ComponentModel.ISupportInitialize)radMenu1).EndInit(); tableLayoutPanel_ActionSetInfo.ResumeLayout(false);
tableLayoutPanel_ActionSetInfo.PerformLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_Version).EndInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).EndInit(); ((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).EndInit(); ((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).EndInit();
((System.ComponentModel.ISupportInitialize)radMenu1).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit(); ((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false); ResumeLayout(false);
PerformLayout(); PerformLayout();
@@ -334,20 +383,23 @@ partial class MainForm
private Telerik.WinControls.UI.RadMenuItem radMenuItem_WorkspacePreferences; private Telerik.WinControls.UI.RadMenuItem radMenuItem_WorkspacePreferences;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Tools; private Telerik.WinControls.UI.RadMenuItem radMenuItem_Tools;
private TableLayoutPanel tableLayoutPanel2; private TableLayoutPanel tableLayoutPanel2;
private TableLayoutPanel tableLayoutPanel1; private TableLayoutPanel tableLayoutPanel_ActionSet;
private Telerik.WinControls.UI.RadGridView radGridView_Actions; private Telerik.WinControls.UI.RadGridView radGridView_Actions;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem1; private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem1;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_OpenNewWorkspace;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_RecentWorkspaces;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_SaveWorkspace; private Telerik.WinControls.UI.RadMenuItem radMenuItem_SaveWorkspace;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Updates; private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Updates;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement1; private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement1;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Actions; private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Actions;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement2; private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement2;
private Telerik.WinControls.UI.RadListControl radListControl_Updates;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Updates; private Telerik.WinControls.UI.RadMenuItem radMenuItem_Updates;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_EditUpdate;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem2;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_CreateUpdate; private Telerik.WinControls.UI.RadMenuItem radMenuItem_CreateUpdate;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_RemoveUpdate; private Telerik.WinControls.UI.RadMenuItem radMenuItem_RemoveUpdate;
private Telerik.WinControls.UI.RadMenuHeaderItem radMenuHeaderItem_NewWorkspace;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem3;
private Telerik.WinControls.UI.RadMenuHeaderItem radMenuHeaderItem_RecentWorkspaces;
private Telerik.WinControls.UI.RadTreeView radTreeView_Sets;
private TableLayoutPanel tableLayoutPanel_ActionSetInfo;
private Telerik.WinControls.UI.RadLabel radLabel1;
private Telerik.WinControls.UI.RadTextBoxControl radTextBoxControl_Version;
private Telerik.WinControls.UI.RadCheckBox radCheckBox_IsPublic;
} }

View File

@@ -4,11 +4,9 @@ using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Settings; using ModpackUpdater.Apps.Manager.Settings;
using Pilz.Plugins.Advanced; using Pilz.Plugins.Advanced;
using Pilz.Plugins.Advanced.UI.Telerik; using Pilz.Plugins.Advanced.UI.WinForms.Telerik;
using Pilz.UI.Extensions;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.UI.Telerik.Dialogs; using Pilz.UI.WinForms.Extensions;
using Pilz.UI.Telerik.Extensions.Extensions;
using Telerik.WinControls; using Telerik.WinControls;
using Telerik.WinControls.UI; using Telerik.WinControls.UI;
@@ -16,17 +14,17 @@ namespace ModpackUpdater.Apps.Manager.Ui;
public partial class MainForm : RadForm, IMainApi public partial class MainForm : RadForm, IMainApi
{ {
private record RecentFilesItemTag(WorkspaceConfig Config, WorkspaceFeature Feature);
private record WorkspaceTag(IWorkspace Workspace, WorkspaceFeature Feature);
private bool loadingMainView;
private WorkspaceTag? wsInfo; private WorkspaceTag? wsInfo;
private InstallAction? tempAction;
Form IMainApi.MainWindow => this; Form IMainApi.MainWindow => this;
IWorkspace? IMainApi.CurWorkspace => wsInfo?.Workspace; IWorkspace? IMainApi.CurWorkspace => wsInfo?.Workspace;
public IActionSetInfos? CurActionSet => radListControl_Updates.SelectedValue as IActionSetInfos; public IActionSetInfos? CurActionSet => radTreeView_Sets.SelectedNode?.Tag as IActionSetInfos;
private record RecentFilesItemTag(WorkspaceConfig Config, WorkspaceFeature Feature);
private record WorkspaceTag(IWorkspace Workspace, WorkspaceFeature Feature);
public MainForm() public MainForm()
{ {
@@ -35,33 +33,36 @@ public partial class MainForm : RadForm, IMainApi
radMenuItem_Workspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.workspace, SymbolSize.Small); radMenuItem_Workspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.workspace, SymbolSize.Small);
radMenuItem_WorkspacePreferences.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.settings, SymbolSize.Small); radMenuItem_WorkspacePreferences.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.settings, SymbolSize.Small);
radMenuItem_SaveWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.save, SymbolSize.Small); radMenuItem_SaveWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.save, SymbolSize.Small);
radMenuItem_OpenNewWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.new_window, SymbolSize.Small); //radMenuItem_OpenNewWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.new_window, SymbolSize.Small);
radMenuItem_RecentWorkspaces.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.time_machine, SymbolSize.Small); //radMenuItem_RecentWorkspaces.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.time_machine, SymbolSize.Small);
radMenuItem_Updates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small); radMenuItem_Updates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small);
radMenuItem_EditUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.edit, SymbolSize.Small);
radMenuItem_CreateUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.add, SymbolSize.Small); radMenuItem_CreateUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.add, SymbolSize.Small);
radMenuItem_RemoveUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.remove, SymbolSize.Small); radMenuItem_RemoveUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.remove, SymbolSize.Small);
radMenuItem_Tools.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.tools, SymbolSize.Small); radMenuItem_Tools.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.tools, SymbolSize.Small);
radMenuItem_SaveWorkspace.Shortcuts.Add(new(Keys.Control, Keys.S)); radMenuItem_SaveWorkspace.Shortcuts.Add(new(Keys.Control, Keys.S));
PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).InsertItemsTo(radMenuItem_OpenNewWorkspace.Items, customClickHandler: RadMenuItem_OpenNewWorkspace_Click); PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).InsertItemsTo(radMenuItem_Workspace.Items,
PluginFeatureController.Instance.Functions.Get(FeatureTypes.Tools).InsertItemsTo(radMenuItem_Tools.Items, customClickHandler: RadMenuItem_ToolsItem_Click); customClickHandler: RadMenuItem_OpenNewWorkspace_Click,
insertPrioSplitters: true,
customDefault: radMenuItem_Workspace.Items.IndexOf(radMenuHeaderItem_NewWorkspace) + 1);
PluginFeatureController.Instance.Functions.Get(FeatureTypes.Tools).InsertItemsTo(radMenuItem_Tools.Items,
customClickHandler: RadMenuItem_ToolsItem_Click,
insertPrioSplitters: true);
} }
private void LoadRecentWorkspaces() private void LoadRecentWorkspaces()
{ {
var settings = Program.Settings.Get<WorkspaceSettings>(); var settings = Program.Settings.Get<WorkspaceSettings>();
var startIndex = radMenuItem_Workspace.Items.IndexOf(radMenuHeaderItem_RecentWorkspaces) + 1;
radMenuItem_RecentWorkspaces.Items.Clear(); foreach (var item in radMenuItem_Workspace.Items.Where(n => n.Tag is RecentFilesItemTag).ToArray())
radMenuItem_Workspace.Items.Remove(item);
foreach (var config in settings.Workspaces.ToArray()) foreach (var config in settings.Workspaces)
{ {
if (PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).OfType<WorkspaceFeature>().FirstOrDefault(n => n.Identifier == config.ProviderId) is not WorkspaceFeature feature) if (PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).OfType<WorkspaceFeature>().FirstOrDefault(n => n.Identifier == config.ProviderId) is not WorkspaceFeature feature)
{
settings.Workspaces.Remove(config);
continue; continue;
}
var item = new RadMenuItem var item = new RadMenuItem
{ {
@@ -72,13 +73,8 @@ public partial class MainForm : RadForm, IMainApi
item.Click += RadMenuItem_OpenRecentWorkspace_Click; item.Click += RadMenuItem_OpenRecentWorkspace_Click;
radMenuItem_RecentWorkspaces.Items.Add(item); radMenuItem_Workspace.Items.Insert(startIndex++, item);
} }
if (radMenuItem_RecentWorkspaces.Items.Any())
radMenuItem_RecentWorkspaces.Visibility = ElementVisibility.Visible;
else
radMenuItem_RecentWorkspaces.Visibility = ElementVisibility.Collapsed;
} }
private void AddToRecentFiles(IWorkspace workspace) private void AddToRecentFiles(IWorkspace workspace)
@@ -121,47 +117,74 @@ public partial class MainForm : RadForm, IMainApi
radWaitingBar_Updates.StartWaiting(); radWaitingBar_Updates.StartWaiting();
Text = wsInfo.Workspace.Config.DisplayText; Text = wsInfo.Workspace.Config.DisplayText;
radListControl_Updates.BeginUpdate(); radTreeView_Sets.BeginUpdate();
radListControl_Updates.Items.Clear(); radTreeView_Sets.Nodes.Clear();
AddUpdateItem(wsInfo.Workspace.InstallInfos); AddUpdateItem(wsInfo.Workspace.InstallInfos);
wsInfo.Workspace.UpdateInfos.Updates.ForEach(n => AddUpdateItem(n)); var nodeUpdates = new RadTreeNode
{
Text = "Updates",
Name = "updates",
SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small),
};
wsInfo.Workspace.UpdateInfos.Updates.ForEach(n => AddUpdateItem(n, nodeUpdates.Nodes));
radTreeView_Sets.Nodes.Add(nodeUpdates);
radListControl_Updates.EndUpdate(); radTreeView_Sets.EndUpdate();
radWaitingBar_Updates.StopWaiting(); radWaitingBar_Updates.StopWaiting();
} }
private RadListDataItem AddUpdateItem(IActionSetInfos infos) private RadTreeNode AddUpdateItem(IActionSetInfos infos)
{
return AddUpdateItem(infos, radTreeView_Sets.Nodes);
}
private RadTreeNode AddUpdateItem(IActionSetInfos infos, RadTreeNodeCollection parent)
{ {
var item = CreateUpdateItem(infos); var item = CreateUpdateItem(infos);
radListControl_Updates.Items.Add(item); parent.Add(item);
return item; return item;
} }
private RadListDataItem InsertUpdateItem(IActionSetInfos infos) private RadTreeNode InsertUpdateItem(IActionSetInfos infos)
{ {
var item = CreateUpdateItem(infos); var item = CreateUpdateItem(infos);
radListControl_Updates.Items.Insert(Math.Min(1, radListControl_Updates.Items.Count), item); var nodeUpdates = radTreeView_Sets.Nodes["updates"];
nodeUpdates.Nodes.Insert(Math.Min(1, nodeUpdates.Nodes.Count), item);
return item; return item;
} }
private RadListDataItem CreateUpdateItem(IActionSetInfos infos) private RadTreeNode CreateUpdateItem(IActionSetInfos infos)
{ {
var item = new RadListDataItem(); var item = new RadTreeNode();
UpdateUpdateItem(item, infos); UpdateUpdateItem(item, infos);
return item; return item;
} }
private void UpdateUpdateItem(RadListDataItem item) private void UpdateUpdateItem(RadTreeNode item)
{ {
if (item.Value is IActionSetInfos infos) if (item.Tag is IActionSetInfos infos)
UpdateUpdateItem(item, infos); UpdateUpdateItem(item, infos);
} }
private void UpdateUpdateItem(RadListDataItem item, IActionSetInfos infos) private void SaveActionsSet()
{ {
if (item.Value != infos) if (loadingMainView || CurActionSet is not IActionSetInfos infos)
item.Value = infos; return;
if (!Version.TryParse(radTextBoxControl_Version.Text.Trim(), out Version? version))
version = new Version("1.0.0.0");
infos.Version = version;
infos.IsPublic = radCheckBox_IsPublic.Checked;
UpdateUpdateItem(radTreeView_Sets.SelectedNode);
}
private void UpdateUpdateItem(RadTreeNode item, IActionSetInfos infos)
{
if (item.Tag != infos)
item.Tag = infos;
if (infos is UpdateInfo) if (infos is UpdateInfo)
item.Text = string.Format(GeneralLangRes.Node_Update, infos.Version?.ToString() ?? "?"); item.Text = string.Format(GeneralLangRes.Node_Update, infos.Version?.ToString() ?? "?");
@@ -175,9 +198,10 @@ public partial class MainForm : RadForm, IMainApi
public void UpdateItem(IActionSetInfos actionSetInfos) public void UpdateItem(IActionSetInfos actionSetInfos)
{ {
RadListDataItem? item = null; RadTreeNode? item = null;
var nodeUpdates = radTreeView_Sets.Nodes["updates"];
foreach (var iitem in radListControl_Updates.Items) foreach (var iitem in nodeUpdates.Nodes)
{ {
if (item == null && iitem.Value == actionSetInfos) if (item == null && iitem.Value == actionSetInfos)
item = iitem; item = iitem;
@@ -186,7 +210,7 @@ public partial class MainForm : RadForm, IMainApi
if (item == null) if (item == null)
InsertUpdateItem(actionSetInfos); InsertUpdateItem(actionSetInfos);
else if (wsInfo?.Workspace.UpdateInfos != null && !wsInfo.Workspace.UpdateInfos.Updates.Contains(actionSetInfos)) else if (wsInfo?.Workspace.UpdateInfos != null && !wsInfo.Workspace.UpdateInfos.Updates.Contains(actionSetInfos))
radListControl_Updates.Items.Remove(item); item.Remove();
else else
UpdateUpdateItem(item); UpdateUpdateItem(item);
} }
@@ -200,7 +224,29 @@ public partial class MainForm : RadForm, IMainApi
} }
} }
private void LoadActionSet(IActionSetInfos infos) private void LoadMainView()
{
loadingMainView = true;
tableLayoutPanel_ActionSet.Visible = false;
tableLayoutPanel_ActionSetInfo.Visible = false;
if (CurActionSet is IActionSet set)
{
if (set is IActionSetInfos infos)
{
radTextBoxControl_Version.Text = infos.Version?.ToString();
radCheckBox_IsPublic.Checked = infos.IsPublic;
tableLayoutPanel_ActionSetInfo.Visible = true;
}
tableLayoutPanel_ActionSet.Visible = true;
LoadActionSet(set);
}
loadingMainView = false;
}
private void LoadActionSet(IActionSet infos)
{ {
radGridView_Actions.BeginUpdate(); radGridView_Actions.BeginUpdate();
radGridView_Actions.Rows.Clear(); radGridView_Actions.Rows.Clear();
@@ -265,6 +311,12 @@ public partial class MainForm : RadForm, IMainApi
Width = 50, Width = 50,
IsVisible = infos is UpdateInfo, IsVisible = infos is UpdateInfo,
}, },
new GridViewTextBoxColumn
{
Name = "destpath",
HeaderText = ActionsListLangRes.Col_DestPath,
Width = 250,
},
new GridViewComboBoxColumn new GridViewComboBoxColumn
{ {
Name = "srctype", Name = "srctype",
@@ -316,12 +368,6 @@ public partial class MainForm : RadForm, IMainApi
IsVisible = infos is UpdateInfo, IsVisible = infos is UpdateInfo,
}, },
new GridViewTextBoxColumn new GridViewTextBoxColumn
{
Name = "destpath",
HeaderText = ActionsListLangRes.Col_DestPath,
Width = 250,
},
new GridViewTextBoxColumn
{ {
Name = "website", Name = "website",
HeaderText = ActionsListLangRes.Col_Website, HeaderText = ActionsListLangRes.Col_Website,
@@ -411,10 +457,9 @@ public partial class MainForm : RadForm, IMainApi
func.Execute(new MainApiParameters(this)); func.Execute(new MainApiParameters(this));
} }
private void RadListControl_Updates_SelectedIndexChanged(object sender, Telerik.WinControls.UI.Data.PositionChangedEventArgs e) private void RadTreeView_Sets_SelectedNodeChanged(object sender, RadTreeViewEventArgs e)
{ {
if (radListControl_Updates.Items.ElementAtOrDefault(e.Position)?.Value is IActionSetInfos infos) LoadMainView();
LoadActionSet(infos);
} }
private void RadGridView_Actions_CellFormatting(object sender, CellFormattingEventArgs e) private void RadGridView_Actions_CellFormatting(object sender, CellFormattingEventArgs e)
@@ -445,9 +490,19 @@ public partial class MainForm : RadForm, IMainApi
private void RadGridView_Actions_CellValueChanged(object sender, GridViewCellEventArgs e) private void RadGridView_Actions_CellValueChanged(object sender, GridViewCellEventArgs e)
{ {
if (e.Row?.Tag is not InstallAction action) if (e.Row is null)
return; return;
if (e.Row.Tag is not InstallAction action)
{
if (CurActionSet is UpdateInfo)
action = tempAction ??= new UpdateAction();
else if (CurActionSet is InstallInfos)
action = tempAction ??= new InstallAction();
else
return;
}
var uaction = action as UpdateAction; var uaction = action as UpdateAction;
var newValue = e.Row.Cells[e.Column.Name].Value; var newValue = e.Row.Cells[e.Column.Name].Value;
var colName = e.Column.Name; var colName = e.Column.Name;
@@ -529,56 +584,39 @@ public partial class MainForm : RadForm, IMainApi
private void RadMenuItem_Updates_DropDownOpening(object sender, System.ComponentModel.CancelEventArgs e) private void RadMenuItem_Updates_DropDownOpening(object sender, System.ComponentModel.CancelEventArgs e)
{ {
radMenuItem_EditUpdate.Enabled = radListControl_Updates.SelectedItem?.Value is IActionSetInfos; radMenuItem_RemoveUpdate.Enabled = radTreeView_Sets.SelectedNode?.Tag is UpdateInfo;
radMenuItem_RemoveUpdate.Enabled = radListControl_Updates.SelectedItem?.Value is UpdateInfo;
}
private void RadMenuItem_EditUpdate_Click(object sender, EventArgs e)
{
if (radListControl_Updates.SelectedItem?.Value is IActionSetInfos infos
&& RadDialogBase.ShowDialog(new UpdatePropertiesEditorFlyout(infos), TitlesLangRes.EditUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.edit, SymbolSize.Small)).IsValid())
UpdateUpdateItem(radListControl_Updates.SelectedItem);
} }
private void RadMenuItem_CreateUpdate_Click(object sender, EventArgs e) private void RadMenuItem_CreateUpdate_Click(object sender, EventArgs e)
{ {
var infos = new UpdateInfo(); if (wsInfo?.Workspace.UpdateInfos is null)
return;
if (wsInfo?.Workspace.UpdateInfos is not null var infos = new UpdateInfo
&& RadDialogBase.ShowDialog(new UpdatePropertiesEditorFlyout(infos), TitlesLangRes.EditUpdate, AppGlobals.Symbols.GetSvgImage(AppSymbols.edit, SymbolSize.Small)).IsValid())
{ {
Version = wsInfo.Workspace.InstallInfos?.Version,
};
wsInfo.Workspace.UpdateInfos.Updates.Insert(0, infos); wsInfo.Workspace.UpdateInfos.Updates.Insert(0, infos);
InsertUpdateItem(infos); InsertUpdateItem(infos);
} }
}
private void RadMenuItem_RemoveUpdate_Click(object sender, EventArgs e) private void RadMenuItem_RemoveUpdate_Click(object sender, EventArgs e)
{ {
if (radListControl_Updates.SelectedItem?.Value is UpdateInfo infos && wsInfo?.Workspace.UpdateInfos is not null if (radTreeView_Sets.SelectedNode?.Tag is UpdateInfo infos && wsInfo?.Workspace.UpdateInfos is not null
&& RadMessageBox.Show(MsgBoxLangRes.RemoveUpdate, MsgBoxLangRes.RemoveUpdate_Title, MessageBoxButtons.YesNo, RadMessageIcon.Exclamation).IsYes()) && RadMessageBox.Show(MsgBoxLangRes.RemoveUpdate, MsgBoxLangRes.RemoveUpdate_Title, MessageBoxButtons.YesNo, RadMessageIcon.Exclamation).IsYes())
{ {
wsInfo.Workspace.UpdateInfos.Updates.Remove(infos); wsInfo.Workspace.UpdateInfos.Updates.Remove(infos);
radListControl_Updates.Items.Remove(radListControl_Updates.SelectedItem); radTreeView_Sets.SelectedNode.Remove();
} }
} }
private void RadGridView_Actions_UserAddedRow(object sender, GridViewRowEventArgs e) private void RadGridView_Actions_UserAddedRow(object sender, GridViewRowEventArgs e)
{ {
foreach (var row in e.Rows) if (tempAction is UpdateAction uaction && CurActionSet is UpdateInfo uinfo)
{ uinfo.Actions.Add(uaction);
if (CurActionSet is UpdateInfo uinfo) else if (tempAction is InstallAction iaction && CurActionSet is InstallInfos iinfo)
{ iinfo.Actions.Add(iaction);
var action = new UpdateAction(); tempAction = null;
// ...
uinfo.Actions.Add(action);
}
if (CurActionSet is InstallInfos iinfo)
{
var action = new InstallAction();
// ...
iinfo.Actions.Add(action);
}
}
} }
private void RadGridView_Actions_UserDeletingRow(object sender, GridViewRowCancelEventArgs e) private void RadGridView_Actions_UserDeletingRow(object sender, GridViewRowCancelEventArgs e)
@@ -594,6 +632,20 @@ public partial class MainForm : RadForm, IMainApi
private void RadGridView_Actions_ContextMenuOpening(object sender, ContextMenuOpeningEventArgs e) private void RadGridView_Actions_ContextMenuOpening(object sender, ContextMenuOpeningEventArgs e)
{ {
PluginFeatureController.Instance.Functions.Get(FeatureTypes.ActionsContextMenu).InsertItemsTo(e.ContextMenu.Items, customClickHandler: RadMenuItem_ToolsItem_Click); if (e.ContextMenuProvider is GridDataCellElement)
{
e.ContextMenu.Items.Add(new RadMenuSeparatorItem());
PluginFeatureController.Instance.Functions.Get(FeatureTypes.ActionsContextMenu).InsertItemsTo(e.ContextMenu.Items, customClickHandler: RadMenuItem_ToolsItem_Click, insertPrioSplitters: true);
}
}
private void RadTextBoxControl1_TextChanged(object sender, EventArgs e)
{
SaveActionsSet();
}
private void RadCheckBox1_ToggleStateChanged(object sender, StateChangedEventArgs args)
{
SaveActionsSet();
} }
} }

View File

@@ -1,114 +0,0 @@
namespace ModpackUpdater.Apps.Manager.Ui;
partial class UpdatePropertiesEditorFlyout
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
tableLayoutPanel1 = new TableLayoutPanel();
radLabel1 = new Telerik.WinControls.UI.RadLabel();
radTextBox_Version = new Telerik.WinControls.UI.RadTextBox();
radCheckBox_IsPublic = new Telerik.WinControls.UI.RadCheckBox();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_Version).BeginInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).BeginInit();
SuspendLayout();
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(radLabel1, 0, 0);
tableLayoutPanel1.Controls.Add(radTextBox_Version, 0, 1);
tableLayoutPanel1.Controls.Add(radCheckBox_IsPublic, 0, 3);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 30);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 4;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel1.Size = new Size(300, 84);
tableLayoutPanel1.TabIndex = 4;
//
// radLabel1
//
radLabel1.Location = new Point(3, 3);
radLabel1.Name = "radLabel1";
radLabel1.Size = new Size(55, 22);
radLabel1.TabIndex = 0;
radLabel1.Text = "Version";
//
// radTextBox_Version
//
radTextBox_Version.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_Version.Location = new Point(3, 31);
radTextBox_Version.Name = "radTextBox_Version";
radTextBox_Version.NullText = "1.5.37.0";
radTextBox_Version.Size = new Size(294, 24);
radTextBox_Version.TabIndex = 1;
//
// radCheckBox_IsPublic
//
radCheckBox_IsPublic.Location = new Point(3, 61);
radCheckBox_IsPublic.Name = "radCheckBox_IsPublic";
radCheckBox_IsPublic.Size = new Size(76, 20);
radCheckBox_IsPublic.TabIndex = 3;
radCheckBox_IsPublic.Text = "Is public";
//
// UpdatePropertiesEditorFlyout
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
BackColor = Color.Transparent;
Controls.Add(tableLayoutPanel1);
MinimumSize = new Size(300, 0);
Name = "UpdatePropertiesEditorFlyout";
Size = new Size(300, 144);
Controls.SetChildIndex(tableLayoutPanel1, 0);
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_Version).EndInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadLabel radLabel1;
private Telerik.WinControls.UI.RadTextBox radTextBox_Version;
private Telerik.WinControls.UI.RadCheckBox radCheckBox_IsPublic;
}

View File

@@ -1,32 +0,0 @@
using Pilz.UI;
using Pilz.UI.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class UpdatePropertiesEditorFlyout : RadFlyoutBase, ILoadContent
{
private readonly IActionSetInfos infos;
public UpdatePropertiesEditorFlyout(IActionSetInfos infos)
{
this.infos = infos;
InitializeComponent();
}
public void LoadContent()
{
radTextBox_Version.Text = infos.Version?.ToString();
radCheckBox_IsPublic.Checked = infos.IsPublic;
}
protected override bool ValidateOK()
{
if (!Version.TryParse(radTextBox_Version.Text.Trim(), out Version? version))
return false;
infos.Version = version;
infos.IsPublic = radCheckBox_IsPublic.Checked;
return base.ValidateOK();
}
}

View File

@@ -1,120 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -36,6 +36,7 @@ partial class UpdatesCollectorUi
var resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdatesCollectorUi)); var resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdatesCollectorUi));
tableLayoutPanel1 = new TableLayoutPanel(); tableLayoutPanel1 = new TableLayoutPanel();
radButton_Continue = new Telerik.WinControls.UI.RadButton(); radButton_Continue = new Telerik.WinControls.UI.RadButton();
radProgressBar1 = new Telerik.WinControls.UI.RadProgressBar();
radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer(); radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer();
splitPanel1 = new Telerik.WinControls.UI.SplitPanel(); splitPanel1 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel2 = new TableLayoutPanel(); tableLayoutPanel2 = new TableLayoutPanel();
@@ -44,9 +45,10 @@ partial class UpdatesCollectorUi
tableLayoutPanel3 = new TableLayoutPanel(); tableLayoutPanel3 = new TableLayoutPanel();
radListView_VersionTags = new Telerik.WinControls.UI.RadListView(); radListView_VersionTags = new Telerik.WinControls.UI.RadListView();
radWaitingBar1 = new Telerik.WinControls.UI.RadWaitingBar(); radWaitingBar1 = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement(); dotsSpinnerWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsSpinnerWaitingBarIndicatorElement();
tableLayoutPanel1.SuspendLayout(); tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radButton_Continue).BeginInit(); ((System.ComponentModel.ISupportInitialize)radButton_Continue).BeginInit();
((System.ComponentModel.ISupportInitialize)radProgressBar1).BeginInit();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit(); ((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit();
radSplitContainer1.SuspendLayout(); radSplitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit(); ((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit();
@@ -64,12 +66,14 @@ partial class UpdatesCollectorUi
// tableLayoutPanel1 // tableLayoutPanel1
// //
tableLayoutPanel1.AutoSize = true; tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.ColumnCount = 2; tableLayoutPanel1.ColumnCount = 3;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 200F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle()); tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel1.Controls.Add(radButton_Continue, 1, 0); tableLayoutPanel1.Controls.Add(radButton_Continue, 2, 0);
tableLayoutPanel1.Controls.Add(radProgressBar1, 0, 0);
tableLayoutPanel1.Dock = DockStyle.Bottom; tableLayoutPanel1.Dock = DockStyle.Bottom;
tableLayoutPanel1.Location = new Point(0, 420); tableLayoutPanel1.Location = new Point(0, 419);
tableLayoutPanel1.Name = "tableLayoutPanel1"; tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 1; tableLayoutPanel1.RowCount = 1;
tableLayoutPanel1.RowStyles.Add(new RowStyle()); tableLayoutPanel1.RowStyles.Add(new RowStyle());
@@ -89,6 +93,15 @@ partial class UpdatesCollectorUi
radButton_Continue.TextAlignment = ContentAlignment.MiddleLeft; radButton_Continue.TextAlignment = ContentAlignment.MiddleLeft;
radButton_Continue.TextImageRelation = TextImageRelation.ImageBeforeText; radButton_Continue.TextImageRelation = TextImageRelation.ImageBeforeText;
// //
// radProgressBar1
//
radProgressBar1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radProgressBar1.Location = new Point(3, 3);
radProgressBar1.Name = "radProgressBar1";
radProgressBar1.Size = new Size(194, 24);
radProgressBar1.TabIndex = 2;
radProgressBar1.Visible = false;
//
// radSplitContainer1 // radSplitContainer1
// //
radSplitContainer1.Controls.Add(splitPanel1); radSplitContainer1.Controls.Add(splitPanel1);
@@ -96,11 +109,7 @@ partial class UpdatesCollectorUi
radSplitContainer1.Dock = DockStyle.Fill; radSplitContainer1.Dock = DockStyle.Fill;
radSplitContainer1.Location = new Point(0, 0); radSplitContainer1.Location = new Point(0, 0);
radSplitContainer1.Name = "radSplitContainer1"; radSplitContainer1.Name = "radSplitContainer1";
// radSplitContainer1.Size = new Size(800, 419);
//
//
radSplitContainer1.RootElement.MinSize = new Size(25, 25);
radSplitContainer1.Size = new Size(800, 420);
radSplitContainer1.TabIndex = 1; radSplitContainer1.TabIndex = 1;
radSplitContainer1.TabStop = false; radSplitContainer1.TabStop = false;
// //
@@ -109,11 +118,7 @@ partial class UpdatesCollectorUi
splitPanel1.Controls.Add(tableLayoutPanel2); splitPanel1.Controls.Add(tableLayoutPanel2);
splitPanel1.Location = new Point(0, 0); splitPanel1.Location = new Point(0, 0);
splitPanel1.Name = "splitPanel1"; splitPanel1.Name = "splitPanel1";
// splitPanel1.Size = new Size(516, 419);
//
//
splitPanel1.RootElement.MinSize = new Size(25, 25);
splitPanel1.Size = new Size(516, 420);
splitPanel1.SizeInfo.AutoSizeScale = new SizeF(0.148241222F, 0F); splitPanel1.SizeInfo.AutoSizeScale = new SizeF(0.148241222F, 0F);
splitPanel1.SizeInfo.SplitterCorrection = new Size(118, 0); splitPanel1.SizeInfo.SplitterCorrection = new Size(118, 0);
splitPanel1.TabIndex = 0; splitPanel1.TabIndex = 0;
@@ -132,7 +137,7 @@ partial class UpdatesCollectorUi
tableLayoutPanel2.RowCount = 1; tableLayoutPanel2.RowCount = 1;
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F)); tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel2.Size = new Size(516, 420); tableLayoutPanel2.Size = new Size(516, 419);
tableLayoutPanel2.TabIndex = 1; tableLayoutPanel2.TabIndex = 1;
// //
// radListView_Updates // radListView_Updates
@@ -148,7 +153,7 @@ partial class UpdatesCollectorUi
radListView_Updates.ItemSpacing = -1; radListView_Updates.ItemSpacing = -1;
radListView_Updates.Location = new Point(3, 3); radListView_Updates.Location = new Point(3, 3);
radListView_Updates.Name = "radListView_Updates"; radListView_Updates.Name = "radListView_Updates";
radListView_Updates.Size = new Size(510, 414); radListView_Updates.Size = new Size(510, 413);
radListView_Updates.TabIndex = 0; radListView_Updates.TabIndex = 0;
radListView_Updates.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView; radListView_Updates.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView;
radListView_Updates.SelectedItemChanged += RadListView_Updates_SelectedItemChanged; radListView_Updates.SelectedItemChanged += RadListView_Updates_SelectedItemChanged;
@@ -159,11 +164,7 @@ partial class UpdatesCollectorUi
splitPanel2.Controls.Add(tableLayoutPanel3); splitPanel2.Controls.Add(tableLayoutPanel3);
splitPanel2.Location = new Point(520, 0); splitPanel2.Location = new Point(520, 0);
splitPanel2.Name = "splitPanel2"; splitPanel2.Name = "splitPanel2";
// splitPanel2.Size = new Size(280, 419);
//
//
splitPanel2.RootElement.MinSize = new Size(25, 25);
splitPanel2.Size = new Size(280, 420);
splitPanel2.SizeInfo.AutoSizeScale = new SizeF(-0.148241192F, 0F); splitPanel2.SizeInfo.AutoSizeScale = new SizeF(-0.148241192F, 0F);
splitPanel2.SizeInfo.SplitterCorrection = new Size(-118, 0); splitPanel2.SizeInfo.SplitterCorrection = new Size(-118, 0);
splitPanel2.TabIndex = 1; splitPanel2.TabIndex = 1;
@@ -182,7 +183,7 @@ partial class UpdatesCollectorUi
tableLayoutPanel3.RowCount = 1; tableLayoutPanel3.RowCount = 1;
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 100F)); tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F)); tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel3.Size = new Size(280, 420); tableLayoutPanel3.Size = new Size(280, 419);
tableLayoutPanel3.TabIndex = 0; tableLayoutPanel3.TabIndex = 0;
// //
// radListView_VersionTags // radListView_VersionTags
@@ -196,7 +197,7 @@ partial class UpdatesCollectorUi
radListView_VersionTags.ItemSpacing = -1; radListView_VersionTags.ItemSpacing = -1;
radListView_VersionTags.Location = new Point(3, 3); radListView_VersionTags.Location = new Point(3, 3);
radListView_VersionTags.Name = "radListView_VersionTags"; radListView_VersionTags.Name = "radListView_VersionTags";
radListView_VersionTags.Size = new Size(274, 414); radListView_VersionTags.Size = new Size(274, 413);
radListView_VersionTags.TabIndex = 0; radListView_VersionTags.TabIndex = 0;
radListView_VersionTags.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView; radListView_VersionTags.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView;
radListView_VersionTags.SelectedIndexChanged += RadListView_VersionTags_SelectedIndexChanged; radListView_VersionTags.SelectedIndexChanged += RadListView_VersionTags_SelectedIndexChanged;
@@ -204,27 +205,26 @@ partial class UpdatesCollectorUi
// radWaitingBar1 // radWaitingBar1
// //
radWaitingBar1.AssociatedControl = radListView_Updates; radWaitingBar1.AssociatedControl = radListView_Updates;
radWaitingBar1.Location = new Point(0, 0); radWaitingBar1.Location = new Point(220, 171);
radWaitingBar1.Name = "radWaitingBar1"; radWaitingBar1.Name = "radWaitingBar1";
radWaitingBar1.Size = new Size(70, 70); radWaitingBar1.Size = new Size(70, 70);
radWaitingBar1.TabIndex = 2; radWaitingBar1.TabIndex = 2;
radWaitingBar1.Text = "radWaitingBar1"; radWaitingBar1.Text = "radWaitingBar1";
radWaitingBar1.WaitingIndicators.Add(dotsRingWaitingBarIndicatorElement1); radWaitingBar1.WaitingIndicators.Add(dotsSpinnerWaitingBarIndicatorElement1);
radWaitingBar1.WaitingIndicatorSize = new Size(100, 14); radWaitingBar1.WaitingIndicatorSize = new Size(100, 14);
radWaitingBar1.WaitingSpeed = 50; radWaitingBar1.WaitingSpeed = 100;
radWaitingBar1.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsRing; radWaitingBar1.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsSpinner;
// //
// dotsRingWaitingBarIndicatorElement1 // dotsSpinnerWaitingBarIndicatorElement1
// //
dotsRingWaitingBarIndicatorElement1.Name = "dotsRingWaitingBarIndicatorElement1"; dotsSpinnerWaitingBarIndicatorElement1.Name = "dotsSpinnerWaitingBarIndicatorElement1";
// //
// UpdatesCollectorUi // UpdatesCollectorUi
// //
AutoScaleBaseSize = new Size(7, 15); AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font; AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450); ClientSize = new Size(800, 449);
Controls.Add(radWaitingBar1);
Controls.Add(radSplitContainer1); Controls.Add(radSplitContainer1);
Controls.Add(tableLayoutPanel1); Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon"); Icon = (Icon)resources.GetObject("$this.Icon");
@@ -234,6 +234,7 @@ partial class UpdatesCollectorUi
Shown += UpdatesCollectorUi_Shown; Shown += UpdatesCollectorUi_Shown;
tableLayoutPanel1.ResumeLayout(false); tableLayoutPanel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radButton_Continue).EndInit(); ((System.ComponentModel.ISupportInitialize)radButton_Continue).EndInit();
((System.ComponentModel.ISupportInitialize)radProgressBar1).EndInit();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).EndInit(); ((System.ComponentModel.ISupportInitialize)radSplitContainer1).EndInit();
radSplitContainer1.ResumeLayout(false); radSplitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit(); ((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit();
@@ -261,6 +262,7 @@ partial class UpdatesCollectorUi
private TableLayoutPanel tableLayoutPanel3; private TableLayoutPanel tableLayoutPanel3;
private Telerik.WinControls.UI.RadListView radListView_Updates; private Telerik.WinControls.UI.RadListView radListView_Updates;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar1; private Telerik.WinControls.UI.RadWaitingBar radWaitingBar1;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement1;
private Telerik.WinControls.UI.RadListView radListView_VersionTags; private Telerik.WinControls.UI.RadListView radListView_VersionTags;
private Telerik.WinControls.UI.RadProgressBar radProgressBar1;
private Telerik.WinControls.UI.DotsSpinnerWaitingBarIndicatorElement dotsSpinnerWaitingBarIndicatorElement1;
} }

View File

@@ -42,6 +42,12 @@ public partial class UpdatesCollectorUi : RadForm
{ {
var updates = await factory.FindUpdates(action, workspace.ModpackConfig?.MinecraftVersion, workspace.ModpackConfig?.ModLoader ?? ModLoader.Any); var updates = await factory.FindUpdates(action, workspace.ModpackConfig?.MinecraftVersion, workspace.ModpackConfig?.ModLoader ?? ModLoader.Any);
BeginInvoke(() =>
{
radProgressBar1.Value1 += 1;
radProgressBar1.Text = $"{radProgressBar1.Value1} / {radProgressBar1.Maximum}";
});
if (updates == null || updates.Length == 0 || updates[0].Value == action.SourceTag) if (updates == null || updates.Length == 0 || updates[0].Value == action.SourceTag)
continue; continue;
@@ -96,8 +102,15 @@ public partial class UpdatesCollectorUi : RadForm
private async void UpdatesCollectorUi_Shown(object sender, EventArgs e) private async void UpdatesCollectorUi_Shown(object sender, EventArgs e)
{ {
radWaitingBar1.StartWaiting(); radWaitingBar1.StartWaiting();
radProgressBar1.Value1 = 0;
radProgressBar1.Maximum = actions.Length;
radProgressBar1.Text = null;
radProgressBar1.Visible = true;
CurrentUpdates = await FindUpdates(); CurrentUpdates = await FindUpdates();
LoadUpdates(CurrentUpdates); LoadUpdates(CurrentUpdates);
radProgressBar1.Visible = false;
radWaitingBar1.StopWaiting(); radWaitingBar1.StopWaiting();
} }

View File

@@ -1,7 +1,7 @@
using Pilz.UI.Telerik.Dialogs; using ModpackUpdater.Apps.Manager;
using Pilz.UI.Telerik.Symbols; using Pilz.UI.WinForms.Telerik.Dialogs;
using Pilz.UI.Telerik.Theming; using Pilz.UI.WinForms.Telerik.Symbols;
using Telerik.WinControls; using Pilz.UI.WinForms.Telerik.Theming;
using Telerik.WinControls.Themes; using Telerik.WinControls.Themes;
namespace ModpackUpdater.Apps; namespace ModpackUpdater.Apps;
@@ -12,10 +12,12 @@ public static class AppGlobals
public static void Initialize() public static void Initialize()
{ {
ThemeHelper.ApplyApplicationTheme(ApplicationTheme.Auto, ThemeHelper.ApplyApplicationTheme(new ThemeDefinition(ApplicationTheme.Auto, HighContrastMode.Auto), n => n.Theme switch
() => new Windows11CompactTheme(), {
() => new Windows11CompactDarkTheme()); ApplicationTheme.Light => new Windows11CompactTheme(),
ApplicationTheme.Gray or ApplicationTheme.Dark => new Windows11CompactDarkTheme(),
_ => 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,18 +1,17 @@
using Pilz.UI.Telerik; using Pilz.UI.WinForms.Telerik.Symbols;
using Pilz.UI.Telerik.Symbols;
using System.Reflection; using System.Reflection;
namespace ModpackUpdater.Apps; namespace ModpackUpdater.Apps.Manager;
internal class AppSymbolFactory : RadSymbolFactory<AppSymbols> internal class AppSymbolFactory : RadSymbolFactory<AppSymbols>
{ {
public override Assembly GetImageResourceAssembly() public override Assembly GetImageResourceAssembly()
{ {
return Assembly.GetExecutingAssembly(); return typeof(AppSymbols).Assembly;
} }
public override string GetImageRessourcePath(AppSymbols svgImage) public override string GetImageRessourcePath(AppSymbols svgImage)
{ {
return $"{GetType().Namespace}.Symbols.{svgImage}.svg"; return $"{typeof(AppSymbols).Namespace}.Symbols.{svgImage}.svg";
} }
} }

View File

@@ -35,4 +35,5 @@ public enum AppSymbols
heart_with_pulse, heart_with_pulse,
broom, broom,
renew, renew,
list_view,
} }

View File

@@ -3,7 +3,6 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <TargetFramework>net8.0-windows</TargetFramework>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<UseWindowsForms>true</UseWindowsForms>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup> </PropertyGroup>
@@ -12,10 +11,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Pilz.UI" Version="2.3.10" /> <PackageReference Include="Pilz.UI" Version="3.0.0" />
<PackageReference Include="Pilz.UI.Telerik" Version="2.7.4" /> <PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2024.3.806" /> <PackageReference Include="UI.for.WinForms.Common" Version="2025.2.612-preview" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2024.3.806" /> <PackageReference Include="UI.for.WinForms.Themes" Version="2025.2.612-preview" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#B2EBF2" d="M7 4H41V44H7z"/><path fill="#00ACC1" d="M13 26H17V30H13zM13 18H17V22H13zM13 34H17V38H13zM13 10H17V14H13zM21 26H35V30H21zM21 18H35V22H21zM21 34H35V38H21zM21 10H35V14H21z"/></svg>

After

Width:  |  Height:  |  Size: 284 B

View File

@@ -40,4 +40,45 @@ public static class Extensions
} }
} }
} }
public static string GetSourceUrl(this InstallAction @this, Version version, string? overwriteVersion = null)
{
if (!string.IsNullOrWhiteSpace(overwriteVersion))
return @this.SourceUrl?.Replace("{version}", overwriteVersion);
if (version is not null)
return @this.SourceUrl?.Replace("{version}", version.ToString());
return @this.SourceUrl;
}
public static string GetInstallUrl(this ModpackConfig @this, string? overwriteRefTag = null)
{
if (!string.IsNullOrWhiteSpace(overwriteRefTag))
return @this.InstallUrl?.Replace("{ref}", overwriteRefTag);
if (!string.IsNullOrWhiteSpace(@this.RefTag))
return @this.InstallUrl?.Replace("{ref}", @this.RefTag);
return @this.InstallUrl;
}
public static string GetUpdateUrl(this ModpackConfig @this, string? overwriteRefTag = null)
{
if (!string.IsNullOrWhiteSpace(overwriteRefTag))
return @this.UpdateUrl?.Replace("{ref}", overwriteRefTag);
if (!string.IsNullOrWhiteSpace(@this.RefTag))
return @this.UpdateUrl?.Replace("{ref}", @this.RefTag);
return @this.UpdateUrl;
}
public static string GetDestPath(this InstallAction @this, string installDir)
{
var path = @this.DestPath;
var root = Path.GetPathRoot(path) ?? string.Empty;
var start = installDir;
while (root.Length == 3 && root.StartsWith(".."))
{
path = path[root.Length..];
root = Path.GetPathRoot(path);
start = Path.GetDirectoryName(start);
}
return Path.Combine(start, path);
}
} }

View File

@@ -24,7 +24,7 @@ public class ModpackFactory
modrinth.Dispose(); modrinth.Dispose();
} }
public async Task<string> ResolveSourceUrl(InstallAction action) public async Task<string> ResolveSourceUrl(InstallAction action, Version? targetVersion = null, string? overwriteVersion = null)
{ {
if (action.SourceType == SourceType.GitHub) if (action.SourceType == SourceType.GitHub)
{ {
@@ -53,7 +53,7 @@ public class ModpackFactory
return file.Url; return file.Url;
} }
return action.SourceUrl; return action.GetSourceUrl(targetVersion, overwriteVersion: overwriteVersion);
} }
public async Task<KeyValuePair<string, string>[]> FindUpdates(InstallAction action, string? gameVersion, ModLoader modLoader) public async Task<KeyValuePair<string, string>[]> FindUpdates(InstallAction action, string? gameVersion, ModLoader modLoader)
@@ -82,7 +82,7 @@ public class ModpackFactory
} }
else if (action.SourceType == SourceType.Modrinth) else if (action.SourceType == SourceType.Modrinth)
{ {
var res = await modrinth.Version.GetProjectVersionListAsync(action.SourceName); 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 KeyValuePair<string, string>($"{v.VersionNumber} {v.ProjectVersionType} {v.Name}", v.Id)).ToArray();
} }
@@ -103,4 +103,26 @@ public class ModpackFactory
_ => null, _ => null,
}; };
} }
private string[] GetModLoaderForModrinth(ModLoader modLoader)
{
return modLoader switch
{
ModLoader.Any => [],
ModLoader.Forge => ["forge"],
ModLoader.NeoForge => ["neoforge"],
ModLoader.Fabric => ["fabric"],
ModLoader.LiteLoader => ["liteloader"],
ModLoader.Cauldron => ["cauldron"],
ModLoader.Quilt => ["quilt"],
_ => null,
};
}
private string[] GetGameVersionForModrinth(string? gameVersion)
{
if (string.IsNullOrWhiteSpace(gameVersion) || gameVersion == "*")
return [];
return [gameVersion];
}
} }

View File

@@ -1,4 +1,6 @@
using Newtonsoft.Json; using Castle.Core.Logging;
using Newtonsoft.Json;
using Pilz.Extensions.Collections;
using System.IO.Compression; using System.IO.Compression;
using FileMode = System.IO.FileMode; using FileMode = System.IO.FileMode;
@@ -19,6 +21,10 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
public delegate void CheckingProgressUpdatedEventHandler(int toCheck, int processed); public delegate void CheckingProgressUpdatedEventHandler(int toCheck, int processed);
public ILogger Log { get; set; } = NullLogger.Instance;
public string? OverwriteRefTag { get; set; }
public string? OverwriteVersion { get; set; }
private readonly HttpClient http = new(); private readonly HttpClient http = new();
private readonly ModpackFactory factory = new(); private readonly ModpackFactory factory = new();
@@ -27,15 +33,15 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
http.Dispose(); http.Dispose();
} }
private async Task<UpdateInfos> DownloadUpdateInfos() public async Task<UpdateInfos> DownloadUpdateInfos()
{ {
var content = await http.GetStringAsync(updateConfig.UpdateUrl); var content = await http.GetStringAsync(updateConfig.GetUpdateUrl(overwriteRefTag: OverwriteRefTag));
return UpdateInfos.Parse(content); return UpdateInfos.Parse(content);
} }
private async Task<InstallInfos> DownloadInstallInfos() public async Task<InstallInfos> DownloadInstallInfos()
{ {
var content = await http.GetStringAsync(updateConfig.InstallUrl); var content = await http.GetStringAsync(updateConfig.GetInstallUrl(overwriteRefTag: OverwriteRefTag));
return InstallInfos.Parse(content); return InstallInfos.Parse(content);
} }
@@ -59,28 +65,32 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
} }
installInfos = await DownloadInstallInfos(); installInfos = await DownloadInstallInfos();
result.CurrentVersion = modpackInfo.Version ?? new Version("0.0.0.0"); if (options.IgnoreInstalledVersion || modpackInfo.Version == null)
var curVersion = result.CurrentVersion; result.CurrentVersion = new Version("0.0.0.0");
else
result.CurrentVersion = modpackInfo.Version;
// Check install actions // Check install actions
if (!exists) if (!exists || options.IgnoreInstalledVersion)
{ {
result.IsInstalled = false; result.IsInstalled = false;
if (installInfos is not null && installInfos.IsPublic && installInfos.Actions.Count != 0) if (installInfos is not null && installInfos.IsPublic && installInfos.Actions.Count != 0)
{ {
var actions = installInfos.Actions.Where(n => n.Side.IsSide(options.Side) && (!n.IsExtra || options.IncludeExtras)); var actions = installInfos.Actions.Where(n => n.Side.IsSide(options.Side) && (!n.IsExtra || options.IncludeExtras) && GetOptionValue(options, installInfos, n.TargetOption));
if (actions.Any()) if (actions.Any())
{ {
result.Actions.AddRange(actions); result.Actions.AddRange(actions);
result.LatestVersion = installInfos.Version; result.LatestVersion = installInfos.Version;
curVersion = installInfos.Version; result.CurrentVersion = installInfos.Version;
} }
} }
if (result.Actions.Count == 0) if (result.Actions.Count == 0)
result.HasError = true; result.HasError = true;
} }
else
result.IsInstalled = true;
// Check update actions // Check update actions
if (!result.HasError && (exists || options.AllowUpdaterAfterInstall)) if (!result.HasError && (exists || options.AllowUpdaterAfterInstall))
@@ -92,10 +102,9 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
var updatesOrderes = updateInfos.Updates.Where(n => n.IsPublic || options.IncludeNonPublic).OrderByDescending(n => n.Version); var updatesOrderes = updateInfos.Updates.Where(n => n.IsPublic || options.IncludeNonPublic).OrderByDescending(n => n.Version);
var checkingVersionIndex = 0; var checkingVersionIndex = 0;
var checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex); var checkingVersion = updatesOrderes.ElementAtOrDefault(checkingVersionIndex);
var actionsZeroIndex = result.Actions.Count; // Ensure we insert update actions behind install actions var actionsZeroIndex = result.Actions.Count; // Ensure we insert update actions BEHIND install actions
result.IsInstalled = true;
while (checkingVersion is not null && checkingVersion.Version > curVersion) while (checkingVersion is not null && checkingVersion.Version > result.CurrentVersion)
{ {
var actionsToAdd = new List<UpdateAction>(); var actionsToAdd = new List<UpdateAction>();
@@ -105,7 +114,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
ResolveInherit(action, installInfos); ResolveInherit(action, installInfos);
// Check & add // Check & add
if (action.Side.IsSide(options.Side) && (!action.IsExtra || options.IncludeExtras) && !result.Actions.Any(n => n.DestPath == action.DestPath)) if (action.Side.IsSide(options.Side) && (!action.IsExtra || options.IncludeExtras) && GetOptionValue(options, installInfos, action.TargetOption) && !result.Actions.Any(n => n.DestPath == action.DestPath))
actionsToAdd.Add(action); actionsToAdd.Add(action);
} }
@@ -122,6 +131,22 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
result.HasError = true; result.HasError = true;
} }
// Check option uninstall actions
result.OptionsAvailable.AddRange(installInfos.OptionSets); // Find used options
result.OptionsEnabled.AddRange(installInfos.OptionSets
.Where(set => set.Side.IsSide(options.Side))
.SelectMany(set => set.Options
.Where(opt => opt.Side.IsSide(options.Side) && options.Options.GetOptionValue(set, opt))
.Select(opt => $"{set.Id}.{opt.Id}"))); // Find used options
var uninstallOptionActions = installInfos.OptionSets
.Where(set => set.Side.IsSide(options.Side))
.SelectMany(set => set.Options
.Where(opt => opt.Side.IsSide(options.Side) && !result.OptionsEnabled.Contains($"{set.Id}.{opt.Id}") && modpackInfo.Options.ContainsKey($"{set.Id}.{opt.Id}"))
.SelectMany(opt => opt.UninstallActions))
.ForEach(action => ResolveInherit(action, installInfos))
.Where(action => !result.Actions.Any(n => n.DestPath == action.DestPath)); // Find actions that are not already there
result.Actions.InsertRange(0, uninstallOptionActions); // Add uninstall update actions BEFORE install actions
return result; return result;
} }
@@ -143,17 +168,18 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
foreach (InstallAction iaction in checkResult.Actions) foreach (InstallAction iaction in checkResult.Actions)
{ {
var destFilePath = Path.Combine(modpackInfo.LocaLPath, iaction.DestPath); var destFilePath = iaction.GetDestPath(modpackInfo.LocaLPath);
var sourceUrl = updateConfig.PreferDirectLinks && !string.IsNullOrWhiteSpace(iaction.SourceUrl) var sourceUrl = updateConfig.PreferDirectLinks && !string.IsNullOrWhiteSpace(iaction.SourceUrl)
? iaction.SourceUrl ? iaction.GetSourceUrl(checkResult.LatestVersion, overwriteVersion: OverwriteVersion)
: await factory.ResolveSourceUrl(iaction); : await factory.ResolveSourceUrl(iaction, targetVersion: checkResult.LatestVersion, overwriteVersion: OverwriteVersion);
if (iaction is UpdateAction uaction) if (iaction is UpdateAction uaction)
{ {
switch (uaction.Type) switch (uaction.Type)
{ {
case UpdateActionType.Update: case UpdateActionType.Update:
await InstallFile(destFilePath, sourceUrl, uaction.IsZip, uaction.ZipPath, localZipCache); if (!await InstallFile(destFilePath, sourceUrl, uaction.IsZip, uaction.ZipPath, localZipCache))
return false;
break; break;
case UpdateActionType.Delete: case UpdateActionType.Delete:
{ {
@@ -198,14 +224,15 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
break; break;
} }
} }
else else if (!await InstallFile(destFilePath, sourceUrl, iaction.IsZip, iaction.ZipPath, localZipCache))
await InstallFile(destFilePath, sourceUrl, iaction.IsZip, iaction.ZipPath, localZipCache); return false;
processed += 1; processed += 1;
InstallProgessUpdated?.Invoke(checkResult, processed); InstallProgessUpdated?.Invoke(checkResult, processed);
} }
// Save new modpack info // Save new modpack info
modpackInfo.Options.Clear();
modpackInfo.Version = checkResult.LatestVersion; modpackInfo.Version = checkResult.LatestVersion;
modpackInfo.ConfigUrl = updateConfig.ConfigUrl; modpackInfo.ConfigUrl = updateConfig.ConfigUrl;
modpackInfo.Save(); modpackInfo.Save();
@@ -217,11 +244,13 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
return true; return true;
} }
private async Task InstallFile(string destFilePath, string sourceUrl, bool isZip, string zipPath, List<LocalZipCacheEntry> localZipCache) private async Task<bool> InstallFile(string destFilePath, string sourceUrl, bool isZip, string zipPath, List<LocalZipCacheEntry> localZipCache)
{ {
Directory.CreateDirectory(Path.GetDirectoryName(destFilePath)); Directory.CreateDirectory(Path.GetDirectoryName(destFilePath));
if (!isZip || localZipCache.FirstOrDefault(n => n.DownloadUrl == sourceUrl) is not LocalZipCacheEntry cachedZipInfo) if (!isZip || localZipCache.FirstOrDefault(n => n.DownloadUrl == sourceUrl) is not LocalZipCacheEntry cachedZipInfo)
{
try
{ {
// Download // Download
var fsDestinationPath = isZip ? Path.Combine(Path.GetTempPath(), $"mc_update_file_{DateTime.Now.ToBinary()}.zip") : destFilePath; var fsDestinationPath = isZip ? Path.Combine(Path.GetTempPath(), $"mc_update_file_{DateTime.Now.ToBinary()}.zip") : destFilePath;
@@ -253,13 +282,53 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf
else else
cachedZipInfo = null; cachedZipInfo = null;
} }
catch (HttpRequestException ex)
{
Log.Error("Could not download file: " + sourceUrl, ex);
return false;
}
catch (Exception ex)
{
Log.Error("Could not install file: " + sourceUrl, ex);
return false;
}
}
// Handle zip file content // Handle zip file content
if (cachedZipInfo != null) if (cachedZipInfo != null)
{ {
// Copy content // Copy content
if (zipPath.StartsWith("{first}"))
{
var firstDirName = Path.GetFileName(Directory.GetDirectories(cachedZipInfo.ExtractedZipPath).First());
zipPath = zipPath.Replace("{first}", firstDirName);
}
var zipSrc = Path.Combine(cachedZipInfo.ExtractedZipPath, zipPath); var zipSrc = Path.Combine(cachedZipInfo.ExtractedZipPath, zipPath);
Extensions.CopyDirectory(zipSrc, destFilePath, true); Extensions.CopyDirectory(zipSrc, destFilePath, true);
} }
return true;
}
private static bool GetOptionValue(UpdateCheckOptions options, InstallInfos installInfos, string optionStr)
{
if (optionStr is null)
return true;
var optionsStr = optionStr.Split(',');
foreach (var set in installInfos.OptionSets)
{
if (!set.Side.IsSide(options.Side))
continue;
foreach (var opt in set.Options)
{
if (opt.Side.IsSide(options.Side) && optionsStr.Contains($"{set.Id}.{opt.Id}") && options.Options.GetOptionValue(set, opt))
return true;
}
}
return false;
} }
} }

View File

@@ -7,11 +7,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CurseForge.APIClient" Version="3.0.0" /> <PackageReference Include="Castle.Core" Version="5.2.1" />
<PackageReference Include="Modrinth.Net" Version="3.4.5" /> <PackageReference Include="CurseForge.APIClient" Version="4.2.0" />
<PackageReference Include="Octokit" Version="13.0.1" /> <PackageReference Include="Modrinth.Net" Version="3.5.1" />
<PackageReference Include="Octokit" Version="14.0.0" />
<PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" /> <PackageReference Include="System.IO.Compression.ZipFile" Version="4.3.0" />
<PackageReference Include="Unleash.Client" Version="4.1.12" /> <PackageReference Include="Unleash.Client" Version="5.3.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -7,4 +7,6 @@ public class UpdateCheckOptions
public bool AllowUpdaterAfterInstall { get; set; } = true; public bool AllowUpdaterAfterInstall { get; set; } = true;
public Side Side { get; set; } = Side.Client; public Side Side { get; set; } = Side.Client;
public bool IncludeExtras { get; set; } public bool IncludeExtras { get; set; }
public bool IgnoreInstalledVersion { get; set; }
public InstallOptionValueDictionary Options { get; } = [];
} }

View File

@@ -5,6 +5,8 @@ public class UpdateCheckResult
public Version CurrentVersion { get; set; } public Version CurrentVersion { get; set; }
public Version LatestVersion { get; set; } public Version LatestVersion { get; set; }
public List<InstallAction> Actions { get; private set; } = []; public List<InstallAction> Actions { get; private set; } = [];
public List<InstallOptionSet> OptionsAvailable { get; } = [];
public List<string> OptionsEnabled { get; } = [];
public bool IsInstalled { get; set; } public bool IsInstalled { get; set; }
public bool HasError { get; set; } public bool HasError { get; set; }
public bool IsInMaintenance { get; set; } public bool IsInMaintenance { get; set; }

View File

@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.2.32526.322 VisualStudioVersion = 17.2.32526.322
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater.Apps.Client", "ModpackUpdater.Apps.Client\ModpackUpdater.Apps.Client.csproj", "{81F9A2F7-D36B-0F08-12D7-9EC2606C9080}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater.Apps.Client.Gui", "ModpackUpdater.Apps.Client.Gui\ModpackUpdater.Apps.Client.Gui.csproj", "{81F9A2F7-D36B-0F08-12D7-9EC2606C9080}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater", "ModpackUpdater\ModpackUpdater.csproj", "{0E6B6470-8C1D-0CDD-3681-461297A01960}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ModpackUpdater", "ModpackUpdater\ModpackUpdater.csproj", "{0E6B6470-8C1D-0CDD-3681-461297A01960}"
EndProject EndProject
@@ -17,6 +17,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps.Manager
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps", "ModpackUpdater.Apps\ModpackUpdater.Apps.csproj", "{EF2EAFAF-01CD-46BD-BE45-0125B51316A4}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps", "ModpackUpdater.Apps\ModpackUpdater.Apps.csproj", "{EF2EAFAF-01CD-46BD-BE45-0125B51316A4}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps.Client", "ModpackUpdater.Apps.Client\ModpackUpdater.Apps.Client.csproj", "{415A7854-C358-4DCD-8C9E-D8413097A06D}"
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
@@ -43,6 +47,14 @@ Global
{EF2EAFAF-01CD-46BD-BE45-0125B51316A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {EF2EAFAF-01CD-46BD-BE45-0125B51316A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF2EAFAF-01CD-46BD-BE45-0125B51316A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {EF2EAFAF-01CD-46BD-BE45-0125B51316A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF2EAFAF-01CD-46BD-BE45-0125B51316A4}.Release|Any CPU.Build.0 = Release|Any CPU {EF2EAFAF-01CD-46BD-BE45-0125B51316A4}.Release|Any CPU.Build.0 = Release|Any CPU
{415A7854-C358-4DCD-8C9E-D8413097A06D}.Debug|Any CPU.ActiveCfg = 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.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
@@ -53,6 +65,8 @@ Global
{D3A92EBD-FF6E-09D0-00A1-20221AAA198E} = {96B711FA-1AF2-469B-BC02-6D1E540E8E9D} {D3A92EBD-FF6E-09D0-00A1-20221AAA198E} = {96B711FA-1AF2-469B-BC02-6D1E540E8E9D}
{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}
{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

@@ -0,0 +1,6 @@
namespace ModpackUpdater;
public interface IActionSet
{
IEnumerable<InstallAction> Actions { get; }
}

View File

@@ -1,10 +1,7 @@
namespace ModpackUpdater; namespace ModpackUpdater;
public interface IActionSetInfos public interface IActionSetInfos : IActionSet
{ {
Version Version { get; set; } Version Version { get; set; }
bool IsPublic { get; set; }
public bool IsPublic { get; set; }
IEnumerable<InstallAction> Actions { get; }
} }

View File

@@ -50,6 +50,9 @@ public class InstallAction
[DefaultValue(false)] [DefaultValue(false)]
public bool IsExtra { get; set; } public bool IsExtra { get; set; }
[DefaultValue(null)]
public string TargetOption { get; set; }
[JsonProperty, Obsolete] [JsonProperty, Obsolete]
private string DownloadUrl private string DownloadUrl
{ {

View File

@@ -13,7 +13,9 @@ public class InstallInfos : IActionSetInfos
public List<InstallAction> Actions { get; } = []; public List<InstallAction> Actions { get; } = [];
IEnumerable<InstallAction> IActionSetInfos.Actions => Actions; public List<InstallOptionSet> OptionSets { get; } = [];
IEnumerable<InstallAction> IActionSet.Actions => Actions;
public static InstallInfos Parse(string content) public static InstallInfos Parse(string content)
{ {

View File

@@ -0,0 +1,24 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.ComponentModel;
namespace ModpackUpdater;
public class InstallOption : IActionSet
{
public string Id { get; set; }
[DefaultValue(null)]
public string Description { get; set; }
[DefaultValue(Side.Both)]
[JsonConverter(typeof(StringEnumConverter))]
public Side Side { get; set; } = Side.Both;
[DefaultValue(false)]
public bool Default { get; }
public List<UpdateAction> UninstallActions { get; } = [];
IEnumerable<InstallAction> IActionSet.Actions => UninstallActions.Cast<InstallAction>();
}

View File

@@ -0,0 +1,22 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.ComponentModel;
namespace ModpackUpdater;
public class InstallOptionSet
{
public string Id { get; set; }
[DefaultValue(null)]
public string Description { get; set; }
[DefaultValue(Side.Both)]
[JsonConverter(typeof(StringEnumConverter))]
public Side Side { get; set; } = Side.Both;
[DefaultValue(false)]
public bool Multiselect { get; set; }
public List<InstallOption> Options { get; } = [];
}

View File

@@ -0,0 +1,28 @@
namespace ModpackUpdater;
public class InstallOptionValueDictionary : Dictionary<string, bool>
{
public void SetOption(InstallOptionSet set, InstallOption option, bool value)
{
if (!set.Options.Contains(option))
throw new KeyNotFoundException("Options seems to be not a part of the option set.");
if (option.Default == value)
UnsetOption(set, option);
else
this[$"{set.Id}.{option.Id}"] = value;
}
public void UnsetOption(InstallOptionSet set, InstallOption option)
{
if (!set.Options.Contains(option))
throw new KeyNotFoundException("Options seems to be not a part of the option set.");
Remove($"{set.Id}.{option.Id}");
}
public bool GetOptionValue(InstallOptionSet set, InstallOption option)
{
if (TryGetValue($"{set.Id}.{option.Id}", out var value))
return value;
return option.Default;
}
}

View File

@@ -6,20 +6,14 @@ 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; }
[JsonConverter(typeof(StringEnumConverter))] [JsonConverter(typeof(StringEnumConverter))]
public ModLoader ModLoader { get; set; } public ModLoader ModLoader { get; set; }

View File

@@ -12,6 +12,7 @@ public class ModpackInfo
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; } = [];
[JsonIgnore] [JsonIgnore]
public string LocaLPath { get; private set; } public string LocaLPath { get; private set; }

View File

@@ -6,7 +6,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Pilz.Cryptography" Version="2.1.1" /> <PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.Extensions" Version="2.1.1" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -13,5 +13,5 @@ public class UpdateInfo : IActionSetInfos
public List<UpdateAction> Actions { get; } = []; public List<UpdateAction> Actions { get; } = [];
IEnumerable<InstallAction> IActionSetInfos.Actions => Actions.Cast<InstallAction>(); IEnumerable<InstallAction> IActionSet.Actions => Actions.Cast<InstallAction>();
} }

3
Version.cs Normal file
View File

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