From 6cf27b4867ab965553c95d90355769713281c8ef Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Mon, 10 Nov 2025 18:28:20 +0100 Subject: [PATCH] manager: migrate base project structure & deps --- Directory.Build.props | 7 +++ .../ModpackUpdater.Apps.AppUpdates.csproj | 15 ----- .../MainForm.axaml.cs | 51 ++++++++--------- .../ModpackUpdater.Apps.Client.Gui.csproj | 20 +------ ModpackUpdater.Apps.Client.Gui/Program.cs | 1 + ModpackUpdater.Apps.Client/Assets/app.ico | Bin 0 -> 110554 bytes ModpackUpdater.Apps.Client/Assets/app.svg | 25 ++++++++ .../ModpackUpdater.Apps.Client.csproj | 9 +-- .../Api/Model/IMainApi.cs | 10 ++-- ModpackUpdater.Apps.Manager/App.axaml | 12 ++++ ModpackUpdater.Apps.Manager/App.axaml.cs | 21 +++++++ ModpackUpdater.Apps.Manager/Assets/app.ico | Bin 0 -> 110554 bytes ModpackUpdater.Apps.Manager/Assets/app.svg | 25 ++++++++ .../ModpackUpdater.Apps.Manager.csproj | 54 +++++++++++++----- ModpackUpdater.Apps.Manager/Program.cs | 18 ++++-- .../Ui/MainWindow.axaml | 9 +++ .../Ui/MainWindow.axaml.cs | 13 +++++ .../Ui/UpdatesCollectorUi.cs | 3 - .../Ui/UpdatesCollectorWindow.axaml | 10 ++++ .../Ui/UpdatesCollectorWindow.axaml.cs | 33 +++++++++++ ModpackUpdater.Apps.Manager/app.config | 6 -- ModpackUpdater.Apps/AppGlobals.cs | 24 ++++---- ModpackUpdater.Apps/AppSymbolFactory.cs | 8 +-- .../ModpackUpdater.Apps.csproj | 25 ++++++-- ModpackUpdater.Manager/ModpackInstaller.cs | 8 +-- ModpackUpdater.sln | 7 --- ModpackUpdater/ModpackConfig.cs | 20 +++---- ModpackUpdater/ModpackInfo.cs | 25 ++++---- 28 files changed, 304 insertions(+), 155 deletions(-) delete mode 100644 ModpackUpdater.Apps.AppUpdates/ModpackUpdater.Apps.AppUpdates.csproj create mode 100644 ModpackUpdater.Apps.Client/Assets/app.ico create mode 100644 ModpackUpdater.Apps.Client/Assets/app.svg create mode 100644 ModpackUpdater.Apps.Manager/App.axaml create mode 100644 ModpackUpdater.Apps.Manager/App.axaml.cs create mode 100644 ModpackUpdater.Apps.Manager/Assets/app.ico create mode 100644 ModpackUpdater.Apps.Manager/Assets/app.svg create mode 100644 ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml create mode 100644 ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml.cs create mode 100644 ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml create mode 100644 ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml.cs delete mode 100644 ModpackUpdater.Apps.Manager/app.config diff --git a/Directory.Build.props b/Directory.Build.props index d8283d3..d2cac91 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,5 +1,12 @@ + + net8.0 + latest + true + enable + + https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater MIT diff --git a/ModpackUpdater.Apps.AppUpdates/ModpackUpdater.Apps.AppUpdates.csproj b/ModpackUpdater.Apps.AppUpdates/ModpackUpdater.Apps.AppUpdates.csproj deleted file mode 100644 index 7cf82d3..0000000 --- a/ModpackUpdater.Apps.AppUpdates/ModpackUpdater.Apps.AppUpdates.csproj +++ /dev/null @@ -1,15 +0,0 @@ - - - - net8.0 - enable - enable - - - - - - - - - diff --git a/ModpackUpdater.Apps.Client.Gui/MainForm.axaml.cs b/ModpackUpdater.Apps.Client.Gui/MainForm.axaml.cs index 55aa8f3..6d3f967 100644 --- a/ModpackUpdater.Apps.Client.Gui/MainForm.axaml.cs +++ b/ModpackUpdater.Apps.Client.Gui/MainForm.axaml.cs @@ -12,8 +12,6 @@ using MsBox.Avalonia.Enums; using Pilz; using Pilz.Extensions; using Pilz.Runtime; -using Pilz.SymbolPacks.Sets; -using Pilz.UI.AvaloniaUI.Symbols; using Pilz.UI.Symbols; using Pilz.Updating.Client; @@ -39,10 +37,10 @@ public partial class MainForm : Window Closing += MainForm_Closing; Loaded += MainForm_Loaded; - ButtonSearchProfileFolder.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.opened_folder); - ButtonCheckForUpdates.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.update); - ButtonInstall.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer); - MenuItemRepair.Icon = Symbols.Fluent.GetImage(SymbolsFluent.wrench, SymbolSize.Small); + ButtonSearchProfileFolder.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.opened_folder); + ButtonCheckForUpdates.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done); + ButtonInstall.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer); + MenuItemRepair.Icon = AppGlobals.Symbols.GetImage(AppSymbols.wrench, SymbolSize.Small); ClearStatus(); LoadProfileToUi(); @@ -66,7 +64,7 @@ public partial class MainForm : Window { loadingData = true; - TextBoxMinecraftProfileFolder.Text = modpackInfo.LocaLPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text; + TextBoxMinecraftProfileFolder.Text = modpackInfo.LocalPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text; TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text; TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text; @@ -110,36 +108,33 @@ public partial class MainForm : Window // Ignore } - if (modpackInfo != null) + features = new(updateConfig); + modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim(); + if (!features.IsInvalid() && !string.IsNullOrWhiteSpace(TextBoxInstallKey.Text) && !AllowExtras()) { - features = new(updateConfig); - modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim(); - if (!features.IsInvalid() && !string.IsNullOrWhiteSpace(TextBoxInstallKey.Text) && !AllowExtras()) - { - SetStatus(GeneralLangRes.InstallationKeyNotValid, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield)); - return false; - } + SetStatus(GeneralLangRes.InstallationKeyNotValid, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign)); + return false; } LabelInstallKey.IsVisible = TextBoxInstallKey.IsVisible = !string.IsNullOrWhiteSpace(updateConfig.UnleashApiUrl); - if (modpackInfo == null || string.IsNullOrWhiteSpace(TextBoxMinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/) + if (string.IsNullOrWhiteSpace(TextBoxMinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/) { - SetStatus(GeneralLangRes.MinecraftProfileFolderSeemsInvalid, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield)); + SetStatus(GeneralLangRes.MinecraftProfileFolderSeemsInvalid, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign)); ButtonCheckForUpdates.IsEnabled = false; ButtonInstall.IsEnabled = false; return false; } else if (string.IsNullOrWhiteSpace(TextBoxModpackConfig.Text)) { - SetStatus(GeneralLangRes.ConfigIncompleteOrNotLoaded, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield)); + SetStatus(GeneralLangRes.ConfigIncompleteOrNotLoaded, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign)); ButtonCheckForUpdates.IsEnabled = false; ButtonInstall.IsEnabled = false; return false; } else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance) { - SetStatus(GeneralLangRes.UpdateServerInMaintenance, Symbols.Fluent.GetImageSource(SymbolsFluent.services)); + SetStatus(GeneralLangRes.UpdateServerInMaintenance, AppGlobals.Symbols.GetImageSource(AppSymbols.services)); ButtonCheckForUpdates.IsEnabled = false; ButtonInstall.IsEnabled = false; return false; @@ -161,28 +156,28 @@ public partial class MainForm : Window void error() { - SetStatus(GeneralLangRes.ErrorOnUpdateCheckOrUpdating, Symbols.Fluent.GetImageSource(SymbolsFluent.close)); + SetStatus(GeneralLangRes.ErrorOnUpdateCheckOrUpdating, AppGlobals.Symbols.GetImageSource(AppSymbols.close)); currentUpdating = false; } void installing() { - SetStatus(GeneralLangRes.Installing, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); + SetStatus(GeneralLangRes.Installing, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer)); currentUpdating = true; } void updatesAvailable() { - SetStatus(GeneralLangRes.AnUpdateIsAvailable, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); + SetStatus(GeneralLangRes.AnUpdateIsAvailable, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer)); } void everythingOk() { - SetStatus(GeneralLangRes.EverythingIsRightAndUpToDate, Symbols.Fluent.GetImageSource(SymbolsFluent.done)); + SetStatus(GeneralLangRes.EverythingIsRightAndUpToDate, AppGlobals.Symbols.GetImageSource(AppSymbols.done)); currentUpdating = false; } // Check only if not pressed "install", not really needed otherwise. if (lastUpdateCheckResult is null || !doInstall || repair) { - SetStatus(GeneralLangRes.CheckingForUpdates, Symbols.Fluent.GetImageSource(SymbolsFluent.update)); + SetStatus(GeneralLangRes.CheckingForUpdates, AppGlobals.Symbols.GetImageSource(AppSymbols.update_done)); // Check for extras once again updateOptions.IncludeExtras = AllowExtras(); @@ -259,13 +254,13 @@ public partial class MainForm : Window private void Updated_CheckingProgresssUpdated(int toCheck, int processed) { - SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.update)); + SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppGlobals.Symbols.GetImageSource(AppSymbols.update_done)); } private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs) { var actionCount = result.Actions.Count; - SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); + SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer)); } #endregion @@ -291,7 +286,7 @@ public partial class MainForm : Window if (await updater.CheckForUpdate() is {} packageToInstall && await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, MsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowDialogAsync(this) == ButtonResult.Yes) { - SetStatus(GeneralLangRes.DownloadProgramUpdate, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); + SetStatus(GeneralLangRes.DownloadProgramUpdate, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer)); IsEnabled = false; if (await updater.DownloadPackageAsync(packageToInstall) && await updater.InstallPackageAsync(packageToInstall, myAppPath)) @@ -314,7 +309,7 @@ public partial class MainForm : Window } catch (Exception ex) { - await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowAsync(); + await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowAsync(); IsEnabled = true; } #endif diff --git a/ModpackUpdater.Apps.Client.Gui/ModpackUpdater.Apps.Client.Gui.csproj b/ModpackUpdater.Apps.Client.Gui/ModpackUpdater.Apps.Client.Gui.csproj index 940077c..456ef75 100644 --- a/ModpackUpdater.Apps.Client.Gui/ModpackUpdater.Apps.Client.Gui.csproj +++ b/ModpackUpdater.Apps.Client.Gui/ModpackUpdater.Apps.Client.Gui.csproj @@ -2,22 +2,13 @@ WinExe - net8.0 Assets\app.ico MinecraftModpackUpdater - true - enable true true true - latest - - - - - @@ -64,10 +55,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - - - @@ -75,9 +62,8 @@ - - - + + @@ -93,7 +79,7 @@ - + diff --git a/ModpackUpdater.Apps.Client.Gui/Program.cs b/ModpackUpdater.Apps.Client.Gui/Program.cs index ec99e14..e66b401 100644 --- a/ModpackUpdater.Apps.Client.Gui/Program.cs +++ b/ModpackUpdater.Apps.Client.Gui/Program.cs @@ -25,6 +25,7 @@ public static class Program [STAThread] internal static void Main(string[] args) { + AppGlobals.Initialize(); BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); } diff --git a/ModpackUpdater.Apps.Client/Assets/app.ico b/ModpackUpdater.Apps.Client/Assets/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..57d4be932f072de40931b34065ca75f19d77dc5f GIT binary patch literal 110554 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 + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ModpackUpdater.Apps.Client/ModpackUpdater.Apps.Client.csproj b/ModpackUpdater.Apps.Client/ModpackUpdater.Apps.Client.csproj index 7feb1fb..362b937 100644 --- a/ModpackUpdater.Apps.Client/ModpackUpdater.Apps.Client.csproj +++ b/ModpackUpdater.Apps.Client/ModpackUpdater.Apps.Client.csproj @@ -2,9 +2,7 @@ Exe - net8.0 - enable - enable + Assets\app.ico MinecraftModpackUpdaterCli @@ -12,6 +10,10 @@ + + + + @@ -21,7 +23,6 @@ - diff --git a/ModpackUpdater.Apps.Manager/Api/Model/IMainApi.cs b/ModpackUpdater.Apps.Manager/Api/Model/IMainApi.cs index 4350cda..4cc22f3 100644 --- a/ModpackUpdater.Apps.Manager/Api/Model/IMainApi.cs +++ b/ModpackUpdater.Apps.Manager/Api/Model/IMainApi.cs @@ -1,14 +1,12 @@ -namespace ModpackUpdater.Apps.Manager.Api.Model; +using Avalonia.Controls; + +namespace ModpackUpdater.Apps.Manager.Api.Model; public interface IMainApi { IWorkspace? CurWorkspace { get; } - IActionSetInfos? CurActionSet { get; } - - Form MainWindow { get; } - + Window MainWindow { get; } void UpdateItem(InstallAction action); - void UpdateItem(IActionSetInfos actionSetInfos); } diff --git a/ModpackUpdater.Apps.Manager/App.axaml b/ModpackUpdater.Apps.Manager/App.axaml new file mode 100644 index 0000000..7d2cc14 --- /dev/null +++ b/ModpackUpdater.Apps.Manager/App.axaml @@ -0,0 +1,12 @@ + + + + + + + + + \ No newline at end of file diff --git a/ModpackUpdater.Apps.Manager/App.axaml.cs b/ModpackUpdater.Apps.Manager/App.axaml.cs new file mode 100644 index 0000000..9e46992 --- /dev/null +++ b/ModpackUpdater.Apps.Manager/App.axaml.cs @@ -0,0 +1,21 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Markup.Xaml; +using ModpackUpdater.Apps.Manager.Ui; + +namespace ModpackUpdater.Apps.Manager; + +public partial class App : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + desktop.MainWindow = new MainWindow(); + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/ModpackUpdater.Apps.Manager/Assets/app.ico b/ModpackUpdater.Apps.Manager/Assets/app.ico new file mode 100644 index 0000000000000000000000000000000000000000..57d4be932f072de40931b34065ca75f19d77dc5f GIT binary patch literal 110554 zcmeEP2RxPE8-G!0QXv%?WmS?=p)yl;lw|KcLU!hDkx@ty*{jGF8D(X(Xz!FJ8cH$} z&i}lZtLt{dZR+>G_wzaTjQ5P^dA`qc-uFH0MGy*P5;Aip0(~~bd;)@)A_&69HV{7v z)9YaxKmTBy6G5CA5JX&jAkHI+AS~+;1cMojPo_XNdBO_d53SF734++{r$BgM999KW z2GXI2@WXmZ`IVW@rza&pe%^9pdW~`u`o=Qj+06LqgyE%E01MAW(8zNM0Gw0Kt^{Yz znLxP-132Nd76_bg9l8ed^e?^yQgQWgUk2N7<#7JCjA9V$A%iXN8R`k73UA|=$A*W> zUj(YSa`^rsUqftpt<;=v%A)yxcX{jRFo4n^d-}=`wU5sWu`rH)_6lG`?E3f8v`)2v z<9qAC1@oe&ix$PIQ%?e8)(QZ)YrX*9s;*&fDU2_!_=I)KNn*@v?J$VajRS(7PeGhO za!)o-RDBL-lqf7OgO(R?&IBfV_5#yGp1?fD30P!V1JiU1Ah}Nts0V0(VzX?ZCTauH zc;nvsiJaJ$!0NFtiOpRIDFYLbc;G9)`_KpTR9j%4v=f-+?C94&x4TuVHK|GEam0OJ zAHOdF?)yOKYJU*H7wnY4>V7Yt&Er546J|)ab&on;&_9c5)q0oMtO0TXzKe}L1NNRy zYf9&h0NxTi_QUd}2kGU!{Tbw-m4E%IgPau_AkPn$ZNw|z2gCK6AQy6xBO@LgJNavg z?}PxLPzTv-H9^i+U64ulom|*tRFnIm!%%(4Q4FS|{zT}eAV@jP`+*ff(6VSh!v>u= zbZGyB{xE3A^B?(@8#5Rb=`c?F8|;*uGN{5nu&>;BPBIiVMBvZ;%1jy7!?wH7K6t>< z`~7U|0$0F9*w=@0UjpyH*T10YB4-;xo(<1nySVllfKg%+(Y_F`uFo)BviJgkcg=5q z@Lu7BmzQW==)ES@QRthtQ5lq)&I4OBONo{vsJHgp))54~ZxQ7CrY@JT{ooiz1thzO z4x=H@W-&HBWWNsK{qUPQU>kiz+rJFbMr$8;9lh^;#hw9sFT!0Li%)L6;CCGNF#I{}F zPzltMn!%g`0GJN9fh?Zr9ogK`Avs*p_Cqwl_R(i`oRhXb`t_L~_w0}F+Xe!Y{kwtM z0ZXt}MI8u=>wxtJ+rV07b+A@K51i0T#KNg(C@s9c`7J*;ehwYh#y8>hQ-eXy81}rjc zfcbIfVeO0UR0bQ5ZUWnUwuAF#1)$cv2&l>0gU#zKz^SFNy(r(|!f92Ri^Au`vSB92 zv+fd3V)k4%)P5ZBz;9p8+#eXb`2vevD`4yn{X9!x8tj2>6XhG{Q2sYXNr8=rrGa$Z z2H>}AFP8UXwxK{sOczA*24nfo;))7I+k)>_R`4CC4LXp(=KfXwNq`2ne;G%Ej;${+ z_TGnW2iHEXP1HBdw(Hfa@_nuG>12~~oqvODymBAfey;5aZ2P7`2Ea(s8ryaTcjS{Y zam<87R(CgSyJ*|!dm5|T;ONMp6w&|{k^okr@0}JomcSx&2ey6m-OsYv6qse(^y?Sx zY1L{=X~KI4!@bY7X_X#qKyAEqM>ddwv;>Op#kTLieqRLSdogVD3v~U7Y#s(fawis0 zRi#4PL;18gZP{;F=+UPACZ1TExVEvr-IF{l@423NUD9zXUlP|0$X>%#F9^PqVo=@_ zS={4-=;Rj%GRVFSWRSBZ+WbCuCWBn}w>obVMr{*c4j%RS*!EMx&!F`5Wi1}CwT&)Y zjzRuUVB3ehW80^feHp+YXG5%gGz|kVl<*x@R2}4n!Ma}Kw=>3YCwyNnfzEYHrt{+O zwKJA_x)DSPx@pic z^&=Djl+(ht1{y}kDbT?deduuG6v{;35@81N?>{AhGGlr>)cuQ0l^fA3!uRlAtb^fy ziHC9%y48^GPk7@9Fif}lU*O@qA>%?wcMBfvxbct{^xB``f$K6@1IMhg;CsN^vAhf5 z@{BZwh4O=rZxPI?5F0}xOhakN!W$l zyrkBT(uB%&H2h$`Tcp;#&4jvy=0(ep+78TrV+{27ky`JbLylvn9mmV= zLry1o+$pwPr_--B{EP@*Rik%4x^*!0^N? zz*W%)P}&IP{Y@OsuTdlbFf#{$xy1u>o(swVSe4xf1aqGLkmFCg4|tPrjp!7Q)q`@Y zvqN&Pwk!cV!k+-At`O_JSsYux^{~O5R%mzipy=Z0B22dhiES`%?B$Ew_@jODPsG< z2K)OUdQ}Q`zKdXvbUVfBcJTuye%=E- z!Z}^jKrbxq=sX`vzf^!MmVR_D8Kobc&y?^|04`g6hG<9Ub@dfoz^aX=fX)BiH!{y$ z9Ni4{#~04Gu1Q-OHTxUd(FDACc3gN`*gK-KH+J-c^S>}>}6u5K(S@! z5dGE`4p`Zn2s+}^{yCE;MhvAfncbZ=fz9m_N;AIuhW-S=0_kqW(T@6D-sMB|TVz@f z$Q+M;d|HRXMP|Sx%b`d2>Y-N}9j9I>mU+C`6!%s3rlER6w3k|EgH1=Ifta2uNLm~= zL_cl~2}(Ph&wq(eH!l1Q{b&Np!vGF%Q2N*UrU0`D7hvo3G(xXj_a zyh-NHUcK|aEgD_v?+E9D)qAs>70-D+m5!6`_uGpZqCec@AQlq?2fZQMGk7B3l(EH5 zMs`>12+XgU0!{$bk(LwYf2qvpBR{RYKe zAK<$AvC&Mhw!X--Xh{D0p~l$tArX=XhUhmoG&zUT0BMG{I;it3?p|nGAibPFblnFT zWDlV6(SC;Ewy#k7(RDIL1#a!yjgc=2b%WG+#m=wvo3!S3q3c{uto*9`N{*_PC|!{D zCLH~!&Y)?5^z!YHegNG^G(Or-H_|Ot`$hCaQfVA1KTda0U$bvu-vjQRiuxNc3Uw%5 zINDJ^4N-+V2!`a}I#&6kWlTZDL^Y5r3)e@)LAu_LMB7hZYtrb;Ns&u;(m>n&9Y1tE z#~9a~3|j+4j4!xWqyt?G1AQ0huSezdJ81r1om!xP2IU2%0n*n?j7EaAFED-uuBADk z39_ZoH80<*`%kB!ba3bxYYn0&HA))akUm|3V zo1}r&Lg?Nm^oQ?%9*ln&^c%g=>mN|cq2Gx5-f(Xe>WlqlANHQ6BG)<+k5(E=zUxF~Bto(T1TKOjFSO!z~u z4fyCfEpg~D(Bal;A(Ajc{*fi{mnHBs`=S3b=|A0kg)xH~x}UqskbeG8SN4xpP+`U( z3g_Os2j}0eUDz?3<{x9>hsmupo4o|`-HMxg9Q2E?m?D4l`SOPu_=$p*ru6erohRTO zw?--+-nPc{-u@FL{I#Oc&S${=$MxUg9V-LaC;0v~0tp(1dyA*S`3DEM#}?gV)%7!T z5lb)hfUw=$aX63Y8z&_EiaC;Zi!Z_DTmZ~)Z{eMv;TczUF`V=A3A7oJ zXMCMN_e7)TZQ#oP0zU#i3{sLJ2H0lVFK8FbgHyQQn0d#^q1ciYNEclFWisHt2+YUI z|I!O!$*tnis!D*Vm!vEfdf?5Q8KiK73K4Lju`$7XMoSY#y=lCr_n9^5vao3C-Xg?@zaU%KRFrbLmT*Q9Jam?Xah{FOa``UJWnY>dCb^W#w&jAuQtiG51c&e45tdMBIUIWYa$GdZWGLEhsA z_(#t(%v}<>G>1D{BAY8l3VU8Yp;!j_N6S#beQ`74`JRl0@C?qg1CF)mGgzN~|Cc)c z*ehUJ)WtD7Tc7hpG4~F<3)l;L0RucUbb1EduLpTx4E_jI%&wv9_e-Jcz+X!a&(r+o z{)hX109IzG+z1@Qp+`e|R`BFHtESHN>iRn-p;@lF-f2eb^X zfV8Et!+6EV9T)x){_*!L{V3+9@LX2>eJd#c=sqm`y_6{b*u7aWUCdDl2t(aCIe0!T z?jBZcRtR+EodLgs1D5|8;oV^Gru>ok?uWcThVEiE&+!uM_bx`Te?r|yYY?(M6vylTi1EMLDQ#r_;hsnIjA3-|qp_187H4#S4|*P~S+o~e?LR8cc9A2044e#*$;MP-1qP5VyVnh6m z7KjH*#Q4UgiP*({%fBt$!wPL0wFm6Ew{TCBG2Bmy;~&Q>y2sD_lnvJAacQWJum33j zIK9XDo;F|i#G$;GnVbfjq)f5=3yJA~z~z45@D9&OK9jaEV%T}A@H|;|c#f_G++%qN zJx3V(y%s`w!~%XCuf%+*9T7wP8}B**_lLqWl}}p$)4@Hu7U_^b9RJP(_~Y|RER5q{ zDo6(I;r)s`%0GH0aG}N5{g^2KUV1)5*qg3#{)YD~?x^TABn_^rANVD*doG9jq|QOt zkH2p!fyMpX`yae*LcSjm;~hL-wf|;XF~qbZ{}DQSPav1V!WeiIR0^X4Es!s;}T(ipf;t`pM-@k@>p@E=`Wz;SqJ?+@JHiGE)PJwtie{#0z782_lq;(-+8 zwU?L-lr0X8iU05Mic7bEvN6te>C}A?_CoDb>SOsl+qat_*7&@m;V`d&Vf-KQ_Q&=Q zX#eOS;6cE9)Q2>V7=}UE;T}1t=fwENrG1Zow1POW9lAC`8Em&XfZfN9+WJWNDcqt3(be?Jlr#Gk^%SrR{1q+_GGpa@=PqQ-ktGGKHvG3M!4!Q z-cj9`jopal-(Zi%FznNLBD>O-9>t!|pTh3O2zehkFCB+9t9uLFFDyNbzaNO0!!yo@ zVG4OC7B|na?K7y{`$pqa>NoqHiSbM<&GSMY_ADB-&qH03Ys8RVc(c`_WT9(+E{+t?lx;tp5giWc>A?;`U&a&Rq@#PGsEnEPi;PS z->!OpZd>}YDD+u=NCy-!N?84mWB1rZz<()@H^}oLeEtv7DUh`1Udw0K678BpMUcNw zzlz6^>Pd_o&c9dP0RLzieBROU#sIliluz`T2A}^#R<~0){s;75t^&%Sf14 zDQs`)pX7I>wzNUUyx$~?kGQ?~n(#}P2>OgZ&VP{3g-{k4h|ldG&EluY1Lp-0{r@tU+BWDn4*KQZ0|AT}^n0;fQ3LGx4e(nrjo3KOM+W2L-lra*8yWJ; z5$q2a{~jN>>)-PS%TW#b)J=^D`lF?8L_LIsdO&VM)ZN&)5G#8A1A^FLKkNg)vID=p zgT@VN2Yp`xzZN|Y0v?zFk$@gN5dxqsp;34N8-*9d&?o?11K#j|^qdF`bm$J;p>rbO zx6sKyvINKyAWMKO0kQg%q{I0Ab%Os7Lij)Bao}t&hW-i@ zhID{I{^_x||5FHmm~Dcy$>8}da}ND*W#oeYlmse_=@!F1sf1^B=S+apm1=s&7f8Ucg_hk^p z@eok|45ni(%X1l+LOS}tN6X(zUvjYz1o`Oy7VL34kY%?V2$jDYmpTCDo&&$<@LRtx z0>3ZL2iy7U_jh7C<{9GtTd~LKK$43XSW*3Pyy}40Snc>n@nvn-0AD)!3u;!SRN)@q)j=`Bs2_H;536zY#xc&IFWl&W|e{_^;#d z61E>4!>Ekvl3hf9N=Nc+7LVEnN=L|kcs>`@$?;+z|8@MwDrfXt13%Lzpy$_*wXN}# zkBtAo`~w;PU#AJ<>Ha@fTO;F7#-H5({~8@2+yCF4(;jP|hvxe=h!3xYj6WHFQgm=U z9)1=Tqw*Q~8_~B*A_D{BdQfzNLk=FitUYuykz?yZo@wlBildO{>Ot&lR^X8{(r{ehnFSWKiU3C zvAyw-mu&yTZTM$mWcw%E|9G%zQfMIC|Ib+b@Umq4C)+~Q3MO^l2`8UMej)8w|tu7AJA;)mBlw*Rrq|8MK+aO8eXjEw)kgMXQ2 z+4Ne|BEbt5MWz?bi$gA0l$^Y1UR(~tx1s+U`e4wdja56y_>W)wh0D8vQOYZDDDWo8 zb*@6O?Zd+uhcz*uj6d-+RLA|ik7UUw;C=Ky$aJYDhU-|<$oT(5_%E;S1;)uQL8AAi zvEn;gJ~ICQ0RDV6y}%~+DJZnB7!6NSua6mj_VeJ{-+r$Be`|kb)feCr(Ev(q%1Fg^ ztog@`|AI2`Lf z%=pu0gNpwb4E`3M=smv5>MW@k63gFPYhHW_zW>KxFe~=DXi=hh(d?{njcF0j1>>`f zw^h?f|E_I3IJKyH{JsPKEzEvJyXbTMVgDP%a2#_Qdav*az5_NLX#rR5%4UvrTxZPr z;z1fs78(Cvfj52~=zIK+zQd!>g$IJ}0HxekumpaKi0Ldm`!(+Ood1eI{L#7@i^w{F zkKfOPH|Mqf(6fDkLnW||dj^)(_6?0w!S^#jmH7Md$Lc^KSqFXwceJclS_?Q&;=LYy z|F=wd4tVi!N9$s%1YknaAojo6{;~ZFY-8Ff02Wq}_25VJzye}eV^K2ZdpnwU_mTU6 zzxvCNy`$}NT>yaYGyoJR=J*cprk=?YPnX4WTs(&-N-vxHxO)~?RA@GLR2u4XxT5Xx zvW^@a?EibjvAlB9p-~4Q@sAlMc5!{&H|8V#JVff?g91NrPpNS~|Og{OoTM+gT zs9}=EwUe|w2v%u%{x+wfdk|Ea7mkWKZtl)~_Z=`Jr4K95Nhb#ScnWB9gcwXe)(sS` zZh^z=Ge*Li*tK7ZKOtTC@kP66ZWT# zGQb*(6C+~3&h;^fUzt1-rlef^WB9MLPx|}#qnPj81I**TVvgdDb6EW2HUMeVL2QL& zw7zTKSp0E$p)VCI14N9r0YQo3_YZHCfH7g8X^;veHyDFOM#qTaPj~ne@RiCV1>3RY z{bTq`*c|`s_#5vG7{VHdIley(e~2k5_+xbjmJ!C&8Fg8EP-|W^D*mY5Z;~>_>KeDs z!Ef+iytf&|2&9Y!Pg3*zG5n>ij{aZaFD#)4GW1W5iv2m0Jg`~XdZ?dSqPk}o{xY_A zLFVFUQgOx4-vi(OF6VF`Plf)0EbeGKI0m4T!yToX$rCL+@=HJ7Rbub|1n+-@&!_lt zMa$sdj=zcLeqgeD-*?;jllJea;y)_()n!_~V|)*6eyrr{M*@W$o6jA9-k5Haz` zf&Na(pTu9y;wuh6g*U+%g0Y9suzR{$lru01@B$Vm?6B!3yZ8PQ{MV|efsIF`fr$RV zGu}w}hie`m75iB2IDozz;Bd$Jt0fJ9lI0B?o@4T}c%mPpxB~=Gdx@{oU{X2yB^d7Lj3Wc=g{yl{9O(V(-p$JBR&72_~UF`>W~bO*sU-W$EBnG z7DX#iV>a^mZmG#>uyOEt4~IL>HxP0FSv(_-*$(Lh%=ZP3?PJQ=VkiGRz@yX<2U79x z=cI=9tbW}7O+(#)WwF^1cE&ESUmqj>rvBc*EZ769H-vZ-#>a|3KHh}kP@V8mZQpUr z{%`Ca#b0{82}oUhYzW^G#_iEOPqVp>i;RNWu**@*nAr&n+<4>V5{g7U;k*$L2ov z_rEycF@z@x&;4kb$;Unn!xLw_Lq6VEoCO?+@fZ6xjck#E#vHAwTQSo;@ zFf?{=Q8-+8eh2wbe`uMb-95}P$ZF2Hx{ zT^Y~h^K9R4g75P-(!L3xIO8{7_vR4#;AkC%3K}lkFD~!ybcRDC5~YQhylx zAH^RfCKhaj__vN#2iEOO7#H|k@h!p{byL_ULvbU74%EuS=~H|)jg)P zM8E;@uN;dGNZCaK6W`syJl+AI<1zTp|3C8lM@oNho@WIN^F2OlKaY71aqj;f)+46( zX0<4u^Ln}|R<55Af0FN$Yz(@tCHLQAZ^pGu1dN>B%Kq3igbE@&Tj9eTz$g=4rV{>E;;!1M?l*CX=$ zj(h$`$AV1JvHYxoxt+1%ZgJWY7-qY5>f8^1rU7!kjEF5k-#=1b&HkMCn=AJaPJ&Yhz#H2QNs zkA&kdxYnjr>-$hTR;kzi(8%w7S#aGG4s(3pZ=3sw_`~`7a$-0ovUwPc348c#A2A;@ zl~^5rI?XhBM-M)}zbss2228RYdh{;&H*0>$>i7k?4tow9wZ8t`uF&ukt;Fmemv#uQ zN5ID&4Wsvrlodxt#2>EHFe1ch!1g_!j*h?E5yG;6Gj5h<-S^8dhx0(DIkvsJH3wQW zdotQb#fXId{YUCb4j*|vzf+*iH~6auZXFT(OrGN)Y?<#YLd>A;E02!7`#Drk2+RJ> zxOui^|IgxYo@3i*P`USwW=Gn)AHnH&l_~ZZd3~S3QLS(Aw;JW%A1Uq+B;8e+2r-Li zbx#=u|DL!79*YRe9b}M^J4i2E7f3Jn(}N6hJ{UIf-#=$ONQgzjkB!j|y`#6K zeDjX}yYM8n-fHWS$9*+o@m5HOtxv2Pn0f44*UWzcW{ zovby)y&pP&?*i!M^8teVzV#x5gs7@wCXr(M*!Q(Uk2W|i(?lv3e>%TzSMG?<{^wkZ zfa=@i2Xd(fpYWdnf)sa;h`)`4F_3gp*1*Ryk=1SG$k@AsST|Mgj%i%xPviW(_RQYqjfj8#-ol~h$?YFcK9mz1vQU z82;!z!8p&QOXoq@3;2%yW8*Tv`PuG!xZ~388c&aif0qAO{BdQ};Mj7KaCq-XYkRha zD#H0@#Q=OPAohDl!atGK{UCmRG<=9bPKFS3{P>^1UkkI-3x~f2d`Cwy*S#J3627DN z;AHZz`tH|9UgMh@@-6--ubI3fukTZgfa?q06%+9BgxDvIgg<;X{AMrzVE^BSk2!w$ zPxSxV2kj3Up>}>BJ1*1vuVPJ%Zm+tL@lTF8Gt~d%mmkUY(Q7g>Qb596A%7VDa6D%u z{Gt78;pfMN4>HIaLd^f#^B)3_r_ca->oq}c2<+$4F?gaf`4`hi!#^?d$M8p=6*ugb ztHoi6`siAXk?@D}z^eH9@xyrUf2~j#8vpeBA3iN=Aa5nq1AmBjJfKDQ>+P z{7~w!_IZ4{{nx_cplkx{7ZhQ?kN{=c`rGCDZ}dA2>L52l6XdAsgREbFhTk|p$KolrcTLN7zE!s)Bm(H^&svwMADT9S1Z)wiN8INIzHmKaSP!W)Hqg zGUDk%-*4_0P+h~~jXtlUebVpdk6i!QC7=y5=ApWPV)P63VCbC;-ow9HlQDMc$T|O{ z1Rz!mp)O#c9^58T7aGtp3G^9V3luQ_Nt(%R{T>Ox=SI#EbfE?JPNoBL*?$iOJ~HZ0zVunvotBeb}9Hy#4sFtHpj&I;ogyf{iFUKD{;_7lW= z@#B!{VR1+`VI04C1YRe{@dZeh$Dh@QM%Ll&A%8f|`iu3yUu-x(m_N)91pz-|!{e}j z7)BrLUxvkDCp9cCMiBS@z&fly0hnQNihg8RoT?XL#qY1EKMar4qTM8(`O%icIOb~t zD+YF}<@j+(@Q1H)F_;}cK@8gqf6d^9?WOVKFgsoa9u(c)!{Z;shQ+BG3FEBz*M+DW zhsUYW{Eb5d3Q?o=eU+#XHQL@+j^Rc0H&kFCI@Dzk-7+u(H4a|JQ809Q@SZSqdElM` zMK$z8N$?(u!2p8bUq%ZIy9~OAU&b%`lVLyQ&C)Zb&PVqS&ybao+B&dJhyt06&TeVj zpEQLYg~L{9NhGtLxdlchm`Nx~AV^Nov|a=BaE$u{Hi$ zR1$kl`c`%7X1F5k^vEom)n!ZT_kVJqdpZIsSs=d0HIQZrrVn`%C-I9kCvvxeO z6>d2}DZ?1lB6)E7y^4x8GUYxEbF;G!Fjzd3;OJCF_FZ2nsY#`b*-Gl$0C)$I#K+*6 z6+B4q=_6wI)b{kwjs7HBVo9@S;_8Q7c~_5D@0BrEM!NNdy?J6K+@?1Qv?S5aF*R${ zyUx7tLmbjvW#-|QN!h;liU{c6gdBFAK4l54Pm&&C;e8rpa#@+xM!2PxGPv4E=E61R zeSA_B*9>RH+8p%#EK$hVa7~sq-ke6#Zr)mCeR^sTT@d@MpjT`Y%Izo`pGUgQ_B5y2 zLpyyIBB80Glt5c2(JXaklKA91w?dmYILw@|f&nqmg%|3N3QwNy;l6mQvuK@ZNmZhu zhQfsMsr`*SlUgdm=*mvq+bko!ZGU*{BWtr01^4@n+E~|IrF&?kv2Bw0k<3)?Sv9&@ zF^>y!R`jW79IlzCFY+R)_(i^AtY2+)?#U?_buAUv%U2w@Havc)$NT10PmASA!Kj&+ zS&q`WDf50de)|4#QEyk0=cQ~0TkGD=G%C&B(xyEv`sy5aoQ%|aZ$v~0ROPaS-q6d5 zG`Sf%{jDy|{5?!tw(2SVd%N3n?P3LgOwjjk?J0yYS-WGRv`glhFX3l*-K&feZ|xMO?ny=x%{Xb{=!)=2rhMwwL?n(+II`ATh>}ucrE!1n7hGWy**{}#@V6Ccl(6I+_@{; zmgd}>rRObfUZlJ%tZ>3D?ua_>H;3)-SfA#y(TI7wHvfs^mYd?V1qWuX&ye8#T;t1v ziDJ4}C90BFLd{m>>PxqWgKy$0(Q@J3>PW$o+{3lIjZUiH-T&OIHAum8;W}hnhBj}0 zwTVv;N8V={6S>C^@-4#NojM#TS1J&0Ur*nrK3j6}?&u>|lEsiDn?so5)|4<7M8(y& z>~ug*s9~M7XYBkHmwD%iJY_x;u$q-#p{4V#gyHq$lW7qzUEW=Zk@GB{Eo-Be4{aCI zGg|GLzvQAaxS8(C)F#-Pk!S$D&&uw%$-)UXb5$ z>AtiTvdZ6y^;oegM@zBbC0BiyqQWXC+GEm=$Oo?5SvKLOrY8@b;b;{Ni7azgo&Tk$ zy~;~Rexn=(PYl!)$QgIcPUH8?P<}WYp+v4=<&}=ga2W?-GuFahHHTmioGMi{H zt+X6U#wiU;?wq~Wu%C9D6g8&i_H)BJHM#X0l7;zpb@|=uby}L?(bdykTs;5tVOQoU zEG(?|Tq9qwBiePny#=c~7;L@OkGI$Df3-gU<;uGu^Y6KCuuOJ8I9KI*O9N+p_llfX z(`cHfA~oH@FqD!rJLi?66t(ysKi1h+yY0AS-p-cKws{yD`EdTEjy0+0cTRfd`vS48 zzoj-t*GI<2gGHZ$IuC2LQ?OwGwyaPZw6c~O5g{Yb7k8yB5oaw!g9 z_GNdwuwm+=Sql)mCo!|+C0uqLs^~m@`ry*7x86G+yUZ|g_qn|3fhSh?tXsVRiBnC| zufNeFD*fhBfa6+2`7AnlQQ1scs+)7mueX@QZ`@jHao@PgHmV&gx+Arb=Y~*{nO5iW z57jwI6Fz4d<}3-24xQxn5`y#tPEue@QK{nl8l@mj&6PnvEdEck3_j<{) z_FA&`Ubpwp+QE&d?-aIFQ6mm*+3PtH-t9|tV!AOq>&lAe2lI?_7GArIS>;=LPJ3JE zo|;=U?;D+#e9>lMlP#X~c-03?_%y5O8#nU2{`5#or=wR(zn8uK+WqdT%^I(a?r!U^ zX_C0K+1t-9G)mNE@1D&9Pd_s6U2S!v?x7mz>S!^8V&qWvK9yCC!mAB0a%*%l=e$sL zvS|u`zu=-s!-B{fr-M=Q^Ys?q@u(KsR5bOA=%PC!8ai!R0owjI!l}w8-CKj)Mox!m z9S#txJ$?J=)hC6yZ}pS{^iD~0tEoTjI<-sb!CR4K#Z6m$52r>fQnX+5sW|0+n99jl zIXtc+8>&w~<2okF${FVLFuZ-noeo{jFp>FZ9fW+mcP6UeQOqgKephUACrGqM=BhT* zTWVLqf(RaPV!fTF&C&*~GN9T=*}t0wiP8*J_otWBJ}x}zRJ!%u2NSduIqOy+NX!Ct zTDFoEYP`Etk22ni)(*WH=;xmDCdU1$P(S;f-e4|)j++U(?+ao-&6I=~^Re7J_;}{d zYI&aU=PGC3m#wTV-@f#yU+uh!S83iJvJ6{9ot~$KEL$?|Qk*&^Q)I}h{%qJwZV3Q0 z#r3B&IiCx-96QG#)P3XDxl&#T&-&~y>kY20t<`^HV^v?nu>DAw05Zr(V{*M8xRkVdIVq&hin@3@f@n9T1We z5G(7;>zQU-rWbwgousFis)znwhlw3McdL$cUSI8VHzaU^#^+M?Pc`YsbSc;BiYGCh zzpBgAtAEjXHkRVQZuI8c<|Ttj%vMoHYHue)b-hvo7FmnwD>Ck&Ru+v`Qf+ z>7WIhSD9Wuc{Ti6@UqW+-k~K=_P>yyKmQ}=EvNA7NBEp9SOjLsI2URQf3AOBdUsuD z9T$gRtrVRaomf}LE1zyElS`^9PA8(yvTj)FtK*cuy!7(=14sKr87{MM-cETI&<*s-q)gn=Q*_wQAM}jZwioS?yX%OzMkcR z8`40jDgSPU-oAYasjgEk)F=DsQ5MpCc(0OKc{Gqp!?Sv&LY=tg#iJS#hhNj|zcp=s zdeiEAc^oHqzI$>chC}bhOxu!=T%kJRlB=bAEEr6wuLVEcuO>Hp@6Cmmk9HOwxhehp zrGMfTc84RJW|n@ulFP5ZK6TW{D*R4_AdCHr?Q7aymAJ(ae*Wo8S=qy!1guP>6vX^D z1(eEeT)f(%d3&07KZcr1!|;KBn$nsBGh(a@GVB7CVz<|0zEl+;90J+W+)0Whov%K* zJ9}!Btk1rFYx4vVr2EUUsf^nxTvyEvdbM&LLzD>rWYcxNrj$n}bRAcmjwvu^RE}L< zakTmK!Ns$w8kbBzxpaEZ(iL`uHR^$-R>CQ@XQ$#kD?bDU z*FQObqEUU`6~;x2u2bYS^jSP|D4BMypfGsn*4;(dFHd1w^uWe4*K7aLce)E~PnE{m z7F!0VCRf+f1&F3Pm6p}4=?+x6DY97JXg*)kgwCa1neVv6&Zb>j?z@aLd$%+q8)?03 zJFi=9VOs8q-FzDBO(#7MvdZmz_kJ4V+dj{y)MZ}rU0?1_Y(FHSTsq5}bz-ABRd-Q{ z0k`hM_6Z!Xw6;f=T%7JM=&85p5XI@+#wI)wGlj!n&hfn@@GQEZe^C^TmCqd;yHy8{ z+%RlvS*G`J+GU-{C(Fx^-Pl?9@@-dDu1(a=E5-fGPv$k3Fs<*sSuxk+*_@oWr{>>& z`L@roZMvrzefhL=bJkZ0&GGNx+e&lDGw|t5>gBJP*GzKW)p1ngs58AzcYJ0;z^7>T z1&!|$7==pTriHR1g|CZF*-F(14U#BCO`TVZtDKRil|_+!XTvph{m?x~(sACf@G3)TT~UE{I!vENx=V;P|D%h$ zn(9=e6v6emK7~@s;ibdZbt9#h$0rkaJZ9anB6&Xz4@XJ$T1slRArrTU7?( zy^%)c!pzcLYyF#+pUmfda#QH!)NA>BcbLhk@WoXytG{=(dzo*T8of_ov+?r03deYs zqiv$g{jGc*dOcb($%)l&($=pc8RuqiOqX6+MuoB6lls!YPom^;mrompPUKa-jpfH` zXRG4n$0O|y74KcQfU{lfq@R}iwd*Hhth~y&*FWdke6uS~$=05!J>>C=UF+{_CognR zq`D#a&>**H`Ex!lH;>X2SseT=POaxVI*)UE-?z3G=A!DBvkutS4~)VaIg#hp_G-bD z?{CcWd90|YdFFOZhlJB>M(G9nXGDDgy3JJ=r#EQb+EpcVKKo;c+HH;!pHDlSjWet< zFK^rysnV36V*P5G+U?%+wRKFV4O7(L$!ux4>C6|=NzMaP5-m>`f+tRH0SL^#vraVNSNd;)@#qFf!wkmB1p)3hx(iEP) zRelpEtIej)TsMv=`^twL@i!N1RUh^i@;2(ncz4daykOVoPm4^nS01FwRzC035p*M*`SmoLoXEubbgNd5sL=#<^ z>W)YAZfR1MOuS#2w&JsQ2Oqs<$Hx}wOIJF(ry!1sOQtf$DjD{(*ifIB%6WYBnL-E? zVk%v0EA`Bo$DvI9*-amnDak;eqtxT=d}5ic)rfK%fIHA4?Z%uVV-<*AI^QPtI)C$eZ8n-kY z8))9sQ+Yc-#w5G=bzp0BEqamD5|vj=F`<*vks_87b5)ua5iOg%TW*!K4T4}UUN=p7 z#>HK{KuzBwE=EFYiONpi=h^C=_fN_f+wP=7{8h?6tliwWsAis)kZt+wvM|9?kItNl zv(N89D4Ax>SQ$%+Oz-;KyILZczCr}qqD>|JY6ZhNLE(^HtFm`z$yBZ?-$r+DU-|}( z-FlNgWw8Wq3+UgNyrzAkw#=hNVSOeq6&~%9>0Eg7PSQSN(wvl-qWfKX>z?uNU-VgDz<$nc_Rj}^ zdmoj!#m8ORax`x{qpCQkUyWQCw$72uWNGBf#74LxQJrbc5i6Nnc1|?BzjUMJrk$6#a+nXWr1>p(_r5l}tc$|6 ztv8Wdmv5K#+Esy*%-&RWDqmlK^corW_Jmc3PadCZ_%wnC6G%mMw1P_F5YLwyHm>JnN!6m!5AF$CLVVDyeVcWhDA)TQe+Q*L>~^ zYthbl(GbwYD$@2WqSpK2qkWH|W(j9c5D$NUAVUnnU^+FY?$g*>k>99yq4vH|?jatT zCA9rrhqkAOPFYj&LGiJg@}BHcBZW>!83kavj7DYIA+5coH@DL&))W*`g+Jk4)BQX@ zH{#&(SWoMU%bWt<`lgm#R4M$2#P%3?1{W+W^Y2HL`ySp{s$Mu}-J;iS#`LGuYL*%D z#?G&s!Q(vP@wDukmvP>awxN5MJPT^{xWSjhd~!O*HbTJM;`&0~8?iFcJZsyfZU%4) zsFk@oznZo@I$~F?Jg0!bwvmp4O>?g|5WCI91m}Hg^beNZYf3;moEZV{LBelh=PIF62Y5~j{ClPx8<5`G~KQ* z^c?%279_l|2P`3#+p^e=jHp(s-KKhUhVi+0wb`}8rpG?Zr>bO0OXS)zZC!maU+8ct z^I`h#t6gm20tIf5%S{5BK7BF!P%=+~el>-D*g`Xj;G{y^rOr=YN_u1fZlel8zNBbX zc3;7Vy$gkf(@U5yXj*RQ6$Wk`9hpm*vl{rq`s^KA7s>EzRNMQ$p1t|$9g8ey)yWtt zTJf-;tMg8uZf?*$UfDBK**1Y2NoeD3kup5$6Gb((C&OaX)pvYJjHiMZaW}2MiAh>i zccK55PtyBHDweqQ+W9R0bGplRL@l0T+e2)W1?m)q`e@Dv%MkIS6{qGDCe!};p)DN-gO7A^4mZ2HFQwksXz1i z+vlxRzKmBF6!vQ9bul(C*+Pd*nN_;*T4?v$LzNkuW5cGM(beS$ck;46S$*^rzZ!K} ziN{Gx5$pO!1q@S!$c+1bJ+IO^t96PT=Q-azQD|EA`qYCG8TN7z$+NC3TF|Z~>+yn* z8frH09;d?bNDhZj9f)SW4&Nj9Joh5Ibg_F?jPuoU&Ui$qcLr1$D_j7xW-F!|s;t{V zg&;O(jn-^x$Zbs1WSn1K(Vws+Gr)nG@1clG<43cmE-m_xsh!v9kg(=A6t0G;F3TBP z+xOEM6z9zgsb9@pSzYto@c!~CDcc?$=~6%OoI>_h=edYCHrjixpE<|)sOhSU&4hB0 zb}8&I6mUlDI`hx(U(u+qU3)Cl|EymmB6Dzme*T_orL_y69155gZ(h;T@{)5#`N3VZ zelJfQ5W#G}dq~4)ipt}+xg}JO3#q5Cm=aYsy~g>$B+ax}G@1pLk1;Q^>K2@S+agS* z_GnGn`&^b%Yt_f|8lLbx5}*jMDmJ*^qA$8{wcFyI(@(U1c)wd@_mv566Z7N-(V2?>#SPAAW9>ZBgB>tkZw) zj?R86nn`z%xR?#6OafQiHGb?{l#&a)K31J8ULzG4$s!)f>P{Kl?2!ISe%tC@v^;t< zu0{n`-g;BL5@EaetcdzrnqB#3g)eOm7cS7eZ8NQ?!A!uIQJkfvDxqMen_HW7M=Ut* z%e)pS?kUc(W|1My=PPphp4Cc3z)i;bvuj?0nNZ0NER*qnbM}N$T_MJu1qe=OW+@O^ zSG?`k1Wc8ya>~IP%KH~XJk@8I&oL~NQDjbaXAWjM3tFA(7;{eXx~{X3=Ql8{P2rc>-o)75nxj(a?)F~njR?(^iIrP37s4(lH~e0( zV|qJXS;hiJu}z6vmxc9l2~4wD>N@|k>|P31H)My&tC-5uvAt7`xa;-`PqI;zRz+ka z?rr1>i&$VT`1E9A6P@;B@Lq)}ecb|nr)$f)rcgh-S`_?w7wpaMmM~7+1y-N6PouFu z_kraWn<&d;j)e))dA?FfU<}ooDES}a|mEm|qzqWe6p)lL* z&=omfLQiJ4xW15KM$%rLNX4r}MJ)8ZEZwW=#3p&oIo$PJ<1k88eNGm9!-)TR4CEe6&uCf*U zx9)9yvdp zFjnN?@%L^_vZ<=i*k>(Hqh!;isb95aw&yCI?q|Kcw^mVmpE~Cs+1B0DNV)1>N5;ap zGFCI!fA}OYcbx@G`n+UVh_jdyv*v@~s*P4PuiD!imErSG)@5eJiQTV0@E*B4q3L25 zmx_Q-pr#*njMtRgYTl*Z0tY-@JCa-@8D6qC_jMDbQS=4wS3bvmyyhsl9S z+LwhgDWqv-(h=r~$lCk;Ld+Dwk(4i96lS$enGzovus7TGyo0iiPRUi%O|7%0&n=m` zc;4FZr4QeUw{W_!xjtQntj(PqVEk~VI%jy)qzj%^&bKRR`afMeXJXhu*C6)D9pPsa zeAt(&By((=&fGmzOtJgZ9P5sWFXc*Y-c>j06HCF?CnmeoD3X)K&ovqKO~L3-O^@Z1 z70+UE{1}@3X1m?oyHDEID$IdTL))}Nx7ast_9$vr;(6@CO0TxZ^}=oADb3dxG>5Sl zNKF7#m=$r-6v1;_ErRwHCO5I1Z%$plkeyRVE6_!1CuifW(k~xgK2zJ-Q{G^=nmfQ( zdl~mb5q=f}M;EaNI+XM;DDG^oSvYwLm6^(tPTOvV*OwmZu(-^-|3XT)Z21-;;{~%b z!mC~_t&c8yZO`^794YqhR;37zne<|R$F52H9A#9N37vh%UAS%iChOOlfr}QspIl7) zC@?+7o&92^F}vzS|EtM1_fKS|3!T1A)zn}$KVdmy?_ho{Na|=>``u@auVT-?oc_dB)nn`GT=#dIwg>ge zTo$Hjd9=8^^*}Dde|%27o?e4{8Qtu~%pLcI3SXMBFJSyoV{9Y2sguGn&${MmUKx{H zlU8D>(eC%n&5R9ZE4>+SUSHPGK*h!}b*ExYs%O{JD`!+H?Pag+o^R(dQJ;}YEa_73 z!>l}8UcMzCUBYMgc}&AR7Gb=;Lu~fDwB<8uo@OW|q{bh=M=$%fQK)XN*o^GFsJ1+X zP(J$)a(waA6_&WPy_)2(A+5ch)@QZ9UV1n!1)JEuioQ8pyJD*-Z!`GPxu-nu4SBdQ zLvW^0jp?Jd`nft*6rVt>mdeNG7u-3LYXpt1-J@M$dFisu=4t(W8?H-wBUM`F&9PO? zR-Lke(VeVw*Ba39wpBc_;JML4i^wJfc+U=@qsVKumQi!mg`UCR29Y>(3GBq^OQfpoLqrE65rh41zJZm$Dmt_t(5sip6u zm}!<1CEDDv-l>@-?{*}a&IzbnA>ob8G!zfCxX_Y6&8YP=Rn6lsu@~NSsVW?t zrHsr>P?0;62WeYl(^K(YS;%qOm7QK!%lzijBm25}V4p#?X?fK?-{lq4C35vmOl};TRXQsdnrGA6_dLT-;(+n8|tbnPA+CbIO*MIcW2MRP-22-KGl}= zRHeP8J^z2*omW(oTNcN^Btqx}L3%>Gl+dLMW*`xeVgPAgLXi>>%SF0Ug@}}dA|OR1 z6t4mo7mOGj5kz_tV5DD>jPxJ@?~N2iia?mpyXI|P=V@N|DeJ%gd!2`~*KeJZ{^1M% z`NgfX9>H=vS)L6rrVgAu*;|(RZs<6;XHL+oL*$amf!x({t?HO+JK4MYHIv0Nw_0eb?V8Qoys|FckRgo6VuEpr45#{|VC><|0f zEI<5ZD%f`W8r|tNzV)=gL@1^_m>fZb`U(} zjvH9qK+tq~c~JZRbI3_IzAsLqLV_hrz4^p9HC$8qd<9Wr;D>`3yd&t!M!5EHRl88R zoMrOX%hDhRRsuaNK5WZvb|uhj?1!6wn~o3HMEUNE$+%Q%MSQOP};Ca$HtYA&a)?E9N%JYG2 zwoDOdO;8VV9qn?9>dbf{qIN#0%jJt6V2ARCEu<4Qs`B1qGrc1GHA{nCezvx>+T+t= zo95+mheK^7u*~TCJsBYPEG+m)>pe9tUu@=Hz&v8R%Kw3*33hXQ=jdLQRtZUZ^O=Zq z-4v5#zAFQE`3mi2?*#uw)R;T`Q@mkgjLfE~29gxHGgeA{#sr4O1W2%iEJ@liH0h&| zg*Ab)I#|8zH04Te)Eg_l&5Zj-C0l0Fzb)Zp=hRXGQ3L5qEwrCQD)aAsLp{?BqfbKpj%CHw27>x#894#q-ATKyWPx{01af$P z*qOL{xLU2cfj_F;9d#oxjXoi8@Suj2wL;av>PVA+h7U84HB=!L=F?RRoR-*>J`A%iQWX4Q1zgx7ugJP{*Dftqu`ESu z-8m8S2Ulq8LVJ2!5!ZHh9T`ga^);)xFl#hhyb!$rCSta|ifY|`xv(n=B*v{q#_*%w z7)G6amwZ1I!`>LY1eO3^8^{YX`@VV@#&e{x<+ai}m4xRlt^)E$ux=E9&iVZDdg=$` z6R97t7j^B6)nbfGoo^%ij8wna=uUXT;>Dv%yXZmlcF8`1mVnP@)Beq@kQC_H8k`+T zuk_pGy?;oI=Yj1*DJQ4CH0&I!rYg3*3Ff?TAZn1D%i^Xs`;OWUmk}Qb;C+*K3aZA6 zg@N#6Y#?$AY9k9Y#5YQ{nJD1=_C>?aq~@_@ZlzXjKvK*j+lgk{0(d?7^F2|53veJg zqqX(M_{Oz$M+Yc5R{v{%K%Ig2zeLc{iG+#{cf&Z&I>U&H1c5g-aEME2ZoUh%WVX02 zb;C@=R?uGo}=X($SgB) z{0p}1Pw0KE6Y_;?lg)gqJuv~ns;aGIn+&=JjM)4PqGkbY?P;~ZR38~!*KyZbU z8(94~{LXh_0etb(GSes>^Q4(|3#izNiFa+%;ju>m#pOf{hJVVOf2r|LSIpDo=t*37 z7upOF{1~9PpNNS_P{{34f8P;AE;4q~p~dOw@h}hE09$%?dG-|xb~JrW7`~sd%=0y) z-Xw*|0OMhsVw1i1QHy~{tEW^*YJHh;R3{OW&V?|@jaST;dzrU@RrMA~d=qJeq4N7@ zD~|9tfP`mGzw)0jrwx6;J-cy9fRK{ylEM)ez~|PNV>g9Xu43&M059j*rs`M<6rJfg z)Nxs + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ModpackUpdater.Apps.Manager/ModpackUpdater.Apps.Manager.csproj b/ModpackUpdater.Apps.Manager/ModpackUpdater.Apps.Manager.csproj index 51fba62..2081f96 100644 --- a/ModpackUpdater.Apps.Manager/ModpackUpdater.Apps.Manager.csproj +++ b/ModpackUpdater.Apps.Manager/ModpackUpdater.Apps.Manager.csproj @@ -2,26 +2,46 @@ WinExe - net8.0-windows - enable - true - enable - icons8_Windows_Update.ico - Minecraft Modpack Update Manager + Assets\app.ico + MinecraftModpackUpdateManager + true + true + true + + + App.axaml + Code + + + + + + + + + - + + + + - - - - - - - + + + + + + + + + + None + All + @@ -81,4 +101,10 @@ + + + ..\..\..\.nuget\packages\pilz\2.6.1\lib\net8.0\Pilz.dll + + + \ No newline at end of file diff --git a/ModpackUpdater.Apps.Manager/Program.cs b/ModpackUpdater.Apps.Manager/Program.cs index 4600abb..97b88cf 100644 --- a/ModpackUpdater.Apps.Manager/Program.cs +++ b/ModpackUpdater.Apps.Manager/Program.cs @@ -1,3 +1,4 @@ +using Avalonia; using OfficeOpenXml; using Pilz.Configuration; using Pilz.Features; @@ -20,24 +21,31 @@ public static class Program /// The main entry point for the application. /// [STAThread] - internal static void Main() + internal static void Main(string[] args) { // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. - ApplicationConfiguration.Initialize(); AppGlobals.Initialize(); PluginFeatureController.Instance.RegisterAllOwn(); - Application.Run(new Ui.MainForm()); + BuildAvaloniaApp().StartWithClassicDesktopLifetime(args); + } + + public static AppBuilder BuildAvaloniaApp() + { + return AppBuilder.Configure() + .UsePlatformDetect() + .WithInterFont() + .LogToTrace(); } private static string GetSettingsPath() { const string AppDataDirectoryName = "MinecraftModpackUpdateManager"; - var SettingsFileName = $"Settings.json"; + const string settingsFileName = "Settings.json"; var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName); Directory.CreateDirectory(settingsPath); - settingsPath = Path.Combine(settingsPath, SettingsFileName); + settingsPath = Path.Combine(settingsPath, settingsFileName); return settingsPath; } diff --git a/ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml b/ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml new file mode 100644 index 0000000..9c59c26 --- /dev/null +++ b/ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml @@ -0,0 +1,9 @@ + + Welcome to Avalonia! + diff --git a/ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml.cs b/ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml.cs new file mode 100644 index 0000000..31356f6 --- /dev/null +++ b/ModpackUpdater.Apps.Manager/Ui/MainWindow.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace ModpackUpdater.Apps.Manager.Ui; + +public partial class MainWindow : Window +{ + public MainWindow() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorUi.cs b/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorUi.cs index eae243b..5d8b5d5 100644 --- a/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorUi.cs +++ b/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorUi.cs @@ -1,6 +1,5 @@ using ModpackUpdater.Apps.Manager.Api.Model; using ModpackUpdater.Manager; -using Telerik.WinControls.UI; namespace ModpackUpdater.Apps.Manager.Ui; @@ -18,9 +17,7 @@ public partial class UpdatesCollectorUi : RadForm private readonly InstallAction[] actions; public ModUpdates? CurrentUpdates { get; private set; } - public ModUpdateInfo? SelectedUpdate => radListView_Updates.SelectedItem?.Value as ModUpdateInfo; - public int SelectedVersion => radListView_VersionTags.SelectedIndex; public UpdatesCollectorUi(IWorkspace workspace, params InstallAction[] actions) diff --git a/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml b/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml new file mode 100644 index 0000000..386e82e --- /dev/null +++ b/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml @@ -0,0 +1,10 @@ + + + diff --git a/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml.cs b/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml.cs new file mode 100644 index 0000000..6322a53 --- /dev/null +++ b/ModpackUpdater.Apps.Manager/Ui/UpdatesCollectorWindow.axaml.cs @@ -0,0 +1,33 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using ModpackUpdater.Apps.Manager.Api.Model; +using ModpackUpdater.Manager; + +namespace ModpackUpdater.Apps.Manager.Ui; + +public partial class UpdatesCollectorWindow : Window +{ + public record ModUpdateInfo(KeyValuePair[] AvailableVersions, InstallAction Origin) + { + public int NewVersion { get; set; } = 0; + } + + public record ModUpdates(List List); + + private readonly IWorkspace workspace; + private readonly ModpackFactory factory = new(); + private readonly InstallAction[] actions; + + public ModUpdates? CurrentUpdates { get; private set; } + public ModUpdateInfo? SelectedUpdate => radListView_Updates.SelectedItem?.Value as ModUpdateInfo; + public int SelectedVersion => radListView_VersionTags.SelectedIndex; + + public UpdatesCollectorWindow(IWorkspace workspace, params InstallAction[] actions) + { + this.workspace = workspace; + this.actions = actions; + + InitializeComponent(); + } +} \ No newline at end of file diff --git a/ModpackUpdater.Apps.Manager/app.config b/ModpackUpdater.Apps.Manager/app.config deleted file mode 100644 index 61807c2..0000000 --- a/ModpackUpdater.Apps.Manager/app.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/ModpackUpdater.Apps/AppGlobals.cs b/ModpackUpdater.Apps/AppGlobals.cs index 21fb39b..0b82110 100644 --- a/ModpackUpdater.Apps/AppGlobals.cs +++ b/ModpackUpdater.Apps/AppGlobals.cs @@ -1,24 +1,20 @@ -using ModpackUpdater.Apps.Manager; -using Pilz.UI.WinForms.Telerik.Dialogs; -using Pilz.UI.WinForms.Telerik.Symbols; -using Pilz.UI.WinForms.Telerik.Theming; -using Telerik.WinControls.Themes; +using Pilz.UI.AvaloniaUI.Symbols; namespace ModpackUpdater.Apps; public static class AppGlobals { - public static IRadSymbolFactory Symbols { get; } = new AppSymbolFactory(); + public static ISymbolFactory Symbols { get; } = new AppSymbolFactory(); public static void Initialize() { - ThemeHelper.ApplyApplicationTheme(new ThemeDefinition(ApplicationTheme.Auto, HighContrastMode.Auto), n => n.Theme switch - { - 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.CancelSvg = Symbols.GetSvgImage(AppSymbols.cancel, Pilz.UI.Symbols.SymbolSize.Small); + // ThemeHelper.ApplyApplicationTheme(new ThemeDefinition(ApplicationTheme.Auto, HighContrastMode.Auto), n => n.Theme switch + // { + // 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.CancelSvg = Symbols.GetSvgImage(AppSymbols.cancel, Pilz.UI.Symbols.SymbolSize.Small); } } diff --git a/ModpackUpdater.Apps/AppSymbolFactory.cs b/ModpackUpdater.Apps/AppSymbolFactory.cs index 77ab514..7f43b31 100644 --- a/ModpackUpdater.Apps/AppSymbolFactory.cs +++ b/ModpackUpdater.Apps/AppSymbolFactory.cs @@ -1,9 +1,9 @@ -using Pilz.UI.WinForms.Telerik.Symbols; -using System.Reflection; +using System.Reflection; +using Pilz.UI.AvaloniaUI.Symbols; -namespace ModpackUpdater.Apps.Manager; +namespace ModpackUpdater.Apps; -internal class AppSymbolFactory : RadSymbolFactory +internal class AppSymbolFactory : SymbolFactory { public override Assembly GetImageResourceAssembly() { diff --git a/ModpackUpdater.Apps/ModpackUpdater.Apps.csproj b/ModpackUpdater.Apps/ModpackUpdater.Apps.csproj index 3196552..87d8763 100644 --- a/ModpackUpdater.Apps/ModpackUpdater.Apps.csproj +++ b/ModpackUpdater.Apps/ModpackUpdater.Apps.csproj @@ -1,20 +1,33 @@  - net8.0-windows - enable - enable + true + true + true + + + + + - - - + + + + + + + + + None + All + diff --git a/ModpackUpdater.Manager/ModpackInstaller.cs b/ModpackUpdater.Manager/ModpackInstaller.cs index 18c857d..1999a99 100644 --- a/ModpackUpdater.Manager/ModpackInstaller.cs +++ b/ModpackUpdater.Manager/ModpackInstaller.cs @@ -58,7 +58,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf return result; } - if (modpackInfo == null || !Directory.Exists(modpackInfo.LocaLPath)) + if (modpackInfo == null || !Directory.Exists(modpackInfo.LocalPath)) { result.HasError = true; return result; @@ -168,7 +168,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf foreach (InstallAction iaction in checkResult.Actions) { - var destFilePath = iaction.GetDestPath(modpackInfo.LocaLPath); + var destFilePath = iaction.GetDestPath(modpackInfo.LocalPath); var sourceUrl = updateConfig.PreferDirectLinks && !string.IsNullOrWhiteSpace(iaction.SourceUrl) ? iaction.GetSourceUrl(checkResult.LatestVersion, overwriteVersion: OverwriteVersion) : await factory.ResolveSourceUrl(iaction, targetVersion: checkResult.LatestVersion, overwriteVersion: OverwriteVersion); @@ -194,7 +194,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf break; case UpdateActionType.Copy: { - var srcFilePath = Path.Combine(modpackInfo.LocaLPath, uaction.SrcPath); + var srcFilePath = Path.Combine(modpackInfo.LocalPath, uaction.SrcPath); if (uaction.IsDirectory) { if (Directory.Exists(srcFilePath)) @@ -209,7 +209,7 @@ public class ModpackInstaller(ModpackConfig updateConfig, ModpackInfo modpackInf break; case UpdateActionType.Move: { - var srcFilePath = Path.Combine(modpackInfo.LocaLPath, uaction.SrcPath); + var srcFilePath = Path.Combine(modpackInfo.LocalPath, uaction.SrcPath); if (uaction.IsDirectory) { if (Directory.Exists(srcFilePath)) diff --git a/ModpackUpdater.sln b/ModpackUpdater.sln index 54645c8..90cea92 100644 --- a/ModpackUpdater.sln +++ b/ModpackUpdater.sln @@ -19,8 +19,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModpackUpdater.Apps", "Modp 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 GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,10 +49,6 @@ Global {415A7854-C358-4DCD-8C9E-D8413097A06D}.Debug|Any CPU.Build.0 = Debug|Any CPU {415A7854-C358-4DCD-8C9E-D8413097A06D}.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 GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -66,7 +60,6 @@ Global {227A37AA-73F0-431D-B976-B9B3A8ADD8C2} = {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 GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {322E6A6B-9F3E-4E88-8945-C98A9EF613BF} diff --git a/ModpackUpdater/ModpackConfig.cs b/ModpackUpdater/ModpackConfig.cs index 9d53935..c95841e 100644 --- a/ModpackUpdater/ModpackConfig.cs +++ b/ModpackUpdater/ModpackConfig.cs @@ -6,25 +6,25 @@ namespace ModpackUpdater; public class ModpackConfig { public bool Maintenance { get; set; } - public string Name { get; set; } - public string UpdateUrl { get; set; } - public string InstallUrl { get; set; } - public string UnleashApiUrl { get; set; } - public string UnleashInstanceId { get; set; } + public string? Name { get; set; } + public string? UpdateUrl { get; set; } + public string? InstallUrl { get; set; } + public string? UnleashApiUrl { get; set; } + public string? UnleashInstanceId { get; set; } public bool PreferDirectLinks { get; set; } - public string MinecraftVersion { get; set; } - public string RefTag { get; set; } + public string? MinecraftVersion { get; set; } + public string? RefTag { get; set; } [JsonConverter(typeof(StringEnumConverter))] public ModLoader ModLoader { get; set; } [JsonIgnore] - public string ConfigUrl { get; private set; } + public string? ConfigUrl { get; private set; } - public static ModpackConfig LoadFromUrl(string url) + public static ModpackConfig LoadFromUrl(string? url) { var result = new HttpClient().GetStringAsync(url).Result; - var config = JsonConvert.DeserializeObject(result); + var config = JsonConvert.DeserializeObject(result) ?? new(); config.ConfigUrl = url; return config; } diff --git a/ModpackUpdater/ModpackInfo.cs b/ModpackUpdater/ModpackInfo.cs index bfa9a80..c749056 100644 --- a/ModpackUpdater/ModpackInfo.cs +++ b/ModpackUpdater/ModpackInfo.cs @@ -9,41 +9,42 @@ public class ModpackInfo private const string FILENAME_MODPACKINFO = "modpack-info.json"; [JsonConverter(typeof(VersionConverter))] - public Version Version { get; set; } - public string ConfigUrl { get; set; } - public string ExtrasKey { get; set; } + public Version? Version { get; set; } + public string? ConfigUrl { get; set; } + public string? ExtrasKey { get; set; } public InstallOptionValueDictionary Options { get; } = []; [JsonIgnore] - public string LocaLPath { get; private set; } + public string? LocalPath { get; private set; } [JsonIgnore] - public bool Exists => File.Exists(GetFilePath(LocaLPath)); + public bool Exists => LocalPath != null && File.Exists(GetFilePath(LocalPath)); public void Save() { - File.WriteAllText(GetFilePath(LocaLPath), JsonConvert.SerializeObject(this)); + if (LocalPath != null) + File.WriteAllText(GetFilePath(LocalPath), JsonConvert.SerializeObject(this)); } public void Save(string mcRoot) { - LocaLPath = mcRoot; + LocalPath = mcRoot; Save(); } - public static ModpackInfo TryLoad(string mcRoot) + public static ModpackInfo TryLoad(string? mcRoot) { - if (HasModpackInfo(mcRoot)) + if (mcRoot != null && HasModpackInfo(mcRoot)) return Load(mcRoot); return new() { - LocaLPath = mcRoot + LocalPath = mcRoot }; } public static ModpackInfo Load(string mcRoot) { - var info = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath(mcRoot))); - info.LocaLPath = mcRoot; + var info = JsonConvert.DeserializeObject(File.ReadAllText(GetFilePath(mcRoot))) ?? new(); + info.LocalPath = mcRoot; return info; }