From 7d166fbeb3838893a34b63e9ac4b9064057aff02 Mon Sep 17 00:00:00 2001 From: slxdy Date: Sat, 16 Nov 2024 00:30:02 +0100 Subject: [PATCH 01/10] Version name update; cleanup --- Directory.Build.props | 12 +++++++----- MelonLoader.Installer/App.axaml.cs | 2 +- MelonLoader.Installer/InstallerUtils.cs | 2 +- MelonLoader.Installer/MLManager.cs | 6 +++--- MelonLoader.Installer/MelonLoader.Installer.csproj | 4 +--- MelonLoader.Installer/Program.cs | 12 ++++++------ MelonLoader.Installer/Updater.cs | 10 +++------- MelonLoader.Installer/ViewModels/DetailsViewModel.cs | 4 ++-- MelonLoader.Installer/ViewModels/GameModel.cs | 2 +- MelonLoader.Installer/ViewModels/MainViewModel.cs | 6 +++--- MelonLoader.Installer/Views/DetailsView.axaml | 2 -- MelonLoader.Installer/Views/ErrorBox.axaml | 2 +- MelonLoader.Installer/Views/MainView.axaml | 2 +- MelonLoader.Installer/Views/MainWindow.axaml | 2 -- MelonLoader.Installer/Views/MainWindow.axaml.cs | 6 +++--- MelonLoader.Installer/Views/UpdaterView.axaml | 2 -- MelonLoader.Installer/Views/UpdaterView.axaml.cs | 2 +- 17 files changed, 34 insertions(+), 44 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index ee4489e..6858d78 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,8 @@ - - enable - 11.2.1 - - + + 4.0.0 + + enable + 11.2.1 + + \ No newline at end of file diff --git a/MelonLoader.Installer/App.axaml.cs b/MelonLoader.Installer/App.axaml.cs index 4177f3a..b5fd626 100644 --- a/MelonLoader.Installer/App.axaml.cs +++ b/MelonLoader.Installer/App.axaml.cs @@ -9,7 +9,7 @@ namespace MelonLoader.Installer; -public partial class App : Application +public class App : Application { public override void Initialize() { diff --git a/MelonLoader.Installer/InstallerUtils.cs b/MelonLoader.Installer/InstallerUtils.cs index 050e437..ef8cf31 100644 --- a/MelonLoader.Installer/InstallerUtils.cs +++ b/MelonLoader.Installer/InstallerUtils.cs @@ -9,7 +9,7 @@ public static class InstallerUtils static InstallerUtils() { Http = new(); - Http.DefaultRequestHeaders.Add("User-Agent", $"MelonLoader Installer v{Program.Version.ToString(3)}"); + Http.DefaultRequestHeaders.Add("User-Agent", $"MelonLoader Installer v{Program.VersionName}"); } public static async Task DownloadFileAsync(string url, Stream destination, InstallProgressEventHandler? onProgress) diff --git a/MelonLoader.Installer/MLManager.cs b/MelonLoader.Installer/MLManager.cs index b9a7a4c..8a7fa6e 100644 --- a/MelonLoader.Installer/MLManager.cs +++ b/MelonLoader.Installer/MLManager.cs @@ -81,7 +81,7 @@ private static async Task GetVersionsAsync(List versions) try { - resp = await InstallerUtils.Http.GetAsync(run!["artifacts_url"]!.ToString()).ConfigureAwait(false); + resp = await InstallerUtils.Http.GetAsync(run["artifacts_url"]!.ToString()).ConfigureAwait(false); } catch { @@ -387,7 +387,7 @@ void SetProgress(double progress, string? newStatus = null) onProgress?.Invoke(currentTask / (double)tasks + progress / tasks, newStatus); } - SetProgress(0, "Downloading MelonLoader " + version.ToString()); + SetProgress(0, "Downloading MelonLoader " + version); using var bufferStr = new MemoryStream(); var result = await InstallerUtils.DownloadFileAsync(downloadUrl, bufferStr, SetProgress); @@ -400,7 +400,7 @@ void SetProgress(double progress, string? newStatus = null) currentTask++; - SetProgress(0, "Installing " + version.ToString()); + SetProgress(0, "Installing " + version); var extRes = InstallerUtils.Extract(bufferStr, gameDir, SetProgress); if (extRes != null) diff --git a/MelonLoader.Installer/MelonLoader.Installer.csproj b/MelonLoader.Installer/MelonLoader.Installer.csproj index e7adc02..66f5bb7 100644 --- a/MelonLoader.Installer/MelonLoader.Installer.csproj +++ b/MelonLoader.Installer/MelonLoader.Installer.csproj @@ -10,7 +10,7 @@ latest true Assets/icon.ico - ../Output/win-x64 + ../Output/$(RuntimeIdentifier) true true embedded @@ -21,8 +21,6 @@ Lava Gang discord.gg/2Wn3N2P - - 4.0.0 diff --git a/MelonLoader.Installer/Program.cs b/MelonLoader.Installer/Program.cs index 9984a52..c2697b9 100644 --- a/MelonLoader.Installer/Program.cs +++ b/MelonLoader.Installer/Program.cs @@ -9,7 +9,10 @@ internal static class Program public static event Action? Exiting; - public static Version Version { get; private set; } = typeof(Program).Assembly.GetName().Version!; + public static Version Version { get; } = typeof(Program).Assembly.GetName().Version!; + + public static string VersionName { get; } = + $"v{Version.Major}.{Version.Minor}.{Version.Build}{(Version.Revision > 0 ? $"-ci.{Version.Revision}" : string.Empty)}"; // Initialization code. Don't use any Avalonia, third-party APIs or any // SynchronizationContext-reliant code before AppMain is called: things aren't initialized @@ -69,11 +72,8 @@ private static bool CheckProcessLock() var procId = BitConverter.ToInt32(procIdRaw); var proc = Process.GetProcessById(procId); - if (proc != null) - { - GrabAttention(proc); - return false; - } + GrabAttention(proc); + return false; } catch { return false; } } diff --git a/MelonLoader.Installer/Updater.cs b/MelonLoader.Installer/Updater.cs index 3c6f40f..cb5b506 100644 --- a/MelonLoader.Installer/Updater.cs +++ b/MelonLoader.Installer/Updater.cs @@ -87,11 +87,7 @@ private static async Task UpdateAsync(string downloadUrl) } } - if (Process.Start(newPath, ["-handleupdate", Environment.ProcessPath!, Environment.ProcessId.ToString()]) == null) - { - Finish("Failed to start the new installer."); - return; - } + Process.Start(newPath, ["-handleupdate", Environment.ProcessPath!, Environment.ProcessId.ToString()]); Finish(null); } @@ -101,8 +97,8 @@ public static bool CheckLegacyUpdate() if (!Environment.ProcessPath!.EndsWith(".tmp.exe", StringComparison.OrdinalIgnoreCase)) return false; - var dir = Path.GetDirectoryName(Environment.ProcessPath!)!; - var name = Path.GetFileNameWithoutExtension(Environment.ProcessPath!); + var dir = Path.GetDirectoryName(Environment.ProcessPath)!; + var name = Path.GetFileNameWithoutExtension(Environment.ProcessPath); name = name.Remove(name.Length - 4) + ".exe"; var final = Path.Combine(dir, name); diff --git a/MelonLoader.Installer/ViewModels/DetailsViewModel.cs b/MelonLoader.Installer/ViewModels/DetailsViewModel.cs index be2cc71..1aded3c 100644 --- a/MelonLoader.Installer/ViewModels/DetailsViewModel.cs +++ b/MelonLoader.Installer/ViewModels/DetailsViewModel.cs @@ -14,7 +14,7 @@ public bool Installing set { _installing = value; - OnPropertyChanged(nameof(Installing)); + OnPropertyChanged(); OnPropertyChanged(nameof(CanInstall)); OnPropertyChanged(nameof(EnableSettings)); } @@ -26,7 +26,7 @@ public bool Confirmation set { _confirmation = value; - OnPropertyChanged(nameof(Confirmation)); + OnPropertyChanged(); OnPropertyChanged(nameof(CanInstall)); } } diff --git a/MelonLoader.Installer/ViewModels/GameModel.cs b/MelonLoader.Installer/ViewModels/GameModel.cs index 56633f5..f0b60be 100644 --- a/MelonLoader.Installer/ViewModels/GameModel.cs +++ b/MelonLoader.Installer/ViewModels/GameModel.cs @@ -22,7 +22,7 @@ public SemVersion? MLVersion set { mlVersion = value; - OnPropertyChanged(nameof(MLVersion)); + OnPropertyChanged(); OnPropertyChanged(nameof(MLVersionText)); OnPropertyChanged(nameof(MLStatusText)); OnPropertyChanged(nameof(MLInstalled)); diff --git a/MelonLoader.Installer/ViewModels/MainViewModel.cs b/MelonLoader.Installer/ViewModels/MainViewModel.cs index 8859821..35c81a4 100644 --- a/MelonLoader.Installer/ViewModels/MainViewModel.cs +++ b/MelonLoader.Installer/ViewModels/MainViewModel.cs @@ -2,7 +2,7 @@ namespace MelonLoader.Installer.ViewModels; -public partial class MainViewModel : ViewModelBase +public class MainViewModel : ViewModelBase { private static bool _ready; @@ -12,11 +12,11 @@ public bool Ready set { _ready = value; - OnPropertyChanged(nameof(Ready)); + OnPropertyChanged(); } } public ObservableCollection Games => GameManager.Games; - public string Version => 'v' + Program.Version.ToString(3); + public string Version => Program.VersionName; } diff --git a/MelonLoader.Installer/Views/DetailsView.axaml b/MelonLoader.Installer/Views/DetailsView.axaml index bfe2440..662f8ad 100644 --- a/MelonLoader.Installer/Views/DetailsView.axaml +++ b/MelonLoader.Installer/Views/DetailsView.axaml @@ -3,8 +3,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:MelonLoader.Installer.ViewModels" - xmlns:views="clr-namespace:MelonLoader.Installer.Views" - xmlns:root="clr-namespace:MelonLoader.Installer" mc:Ignorable="d" d:DesignWidth="450" d:DesignHeight="650" x:Class="MelonLoader.Installer.Views.DetailsView" x:DataType="vm:DetailsViewModel"> diff --git a/MelonLoader.Installer/Views/ErrorBox.axaml b/MelonLoader.Installer/Views/ErrorBox.axaml index bb455d6..2888aa5 100644 --- a/MelonLoader.Installer/Views/ErrorBox.axaml +++ b/MelonLoader.Installer/Views/ErrorBox.axaml @@ -15,7 +15,7 @@ RenderOptions.BitmapInterpolationMode="HighQuality"> - + \ No newline at end of file diff --git a/MelonLoader.Installer/Views/MainView.axaml b/MelonLoader.Installer/Views/MainView.axaml index 3fabd96..b60b660 100644 --- a/MelonLoader.Installer/Views/MainView.axaml +++ b/MelonLoader.Installer/Views/MainView.axaml @@ -15,7 +15,7 @@ - diff --git a/MelonLoader.Installer/Views/MainWindow.axaml b/MelonLoader.Installer/Views/MainWindow.axaml index 0b261a4..3bb21a8 100644 --- a/MelonLoader.Installer/Views/MainWindow.axaml +++ b/MelonLoader.Installer/Views/MainWindow.axaml @@ -1,9 +1,7 @@ diff --git a/MelonLoader.Installer/Views/UpdaterView.axaml.cs b/MelonLoader.Installer/Views/UpdaterView.axaml.cs index debc750..691604c 100644 --- a/MelonLoader.Installer/Views/UpdaterView.axaml.cs +++ b/MelonLoader.Installer/Views/UpdaterView.axaml.cs @@ -9,7 +9,7 @@ public UpdaterView() { InitializeComponent(); - Updater.Progress += (progress, newStatus) => Dispatcher.UIThread.Post(() => OnProgress(progress)); + Updater.Progress += (progress, _) => Dispatcher.UIThread.Post(() => OnProgress(progress)); } private void OnProgress(double progress) From 45eee4217457d661bfc63f57d873472ded79840e Mon Sep 17 00:00:00 2001 From: slxdy Date: Sat, 16 Nov 2024 00:50:00 +0100 Subject: [PATCH 02/10] Added workflows --- .github/workflows/build-final.yml | 30 ++++++++++++++++++++++++++++ .github/workflows/build.yml | 33 +++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 .github/workflows/build-final.yml create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build-final.yml b/.github/workflows/build-final.yml new file mode 100644 index 0000000..b795d17 --- /dev/null +++ b/.github/workflows/build-final.yml @@ -0,0 +1,30 @@ +name: Build Installer Final + +run-name: Final Build + +env: + DEVVERSION: "4.0.0" + +on: + push: + branches: [ master ] + +jobs: + build: + name: Build Installer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x + + - name: Build + run: dotnet publish -p:Version="${{ env.DEVVERSION }}" + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: MelonLoader.Installer + path: Output/win-x64/ \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..4604855 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,33 @@ +name: Build Installer + +run-name: 4.0.0-ci.${{ github.run_number }} | ${{ github.event_name != 'workflow_dispatch' && (github.event.head_commit.message || format('`[PR]` {0}', github.event.pull_request.title)) || 'Manual Build' }} + +env: + DEVVERSION: "4.0.0" + +on: + push: + branches: [ development ] + pull_request: + branches: [ development ] + workflow_dispatch: + +jobs: + build: + name: Build Installer + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup dotnet + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 9.0.x + + - name: Build + run: dotnet publish -p:Version="${{ env.DEVVERSION }}.${{ github.run_number }}" + + - name: Upload Artifact + uses: actions/upload-artifact@v4 + with: + name: MelonLoader.Installer + path: Output/win-x64/ \ No newline at end of file From 9131f16d649fdb1a0102e801abc321e13003174d Mon Sep 17 00:00:00 2001 From: slxdy Date: Sat, 16 Nov 2024 00:55:30 +0100 Subject: [PATCH 03/10] Removed explicit version from final workflow --- .github/workflows/build-final.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/build-final.yml b/.github/workflows/build-final.yml index b795d17..ce1b32e 100644 --- a/.github/workflows/build-final.yml +++ b/.github/workflows/build-final.yml @@ -2,9 +2,6 @@ name: Build Installer Final run-name: Final Build -env: - DEVVERSION: "4.0.0" - on: push: branches: [ master ] @@ -21,7 +18,7 @@ jobs: dotnet-version: 9.0.x - name: Build - run: dotnet publish -p:Version="${{ env.DEVVERSION }}" + run: dotnet publish - name: Upload Artifact uses: actions/upload-artifact@v4 From fa21df7c51d00625952c174d21f853fcd7cbd8d2 Mon Sep 17 00:00:00 2001 From: slxdy Date: Sat, 16 Nov 2024 01:01:51 +0100 Subject: [PATCH 04/10] Disable auto-updating on CI builds --- MelonLoader.Installer/Updater.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MelonLoader.Installer/Updater.cs b/MelonLoader.Installer/Updater.cs index cb5b506..c44653b 100644 --- a/MelonLoader.Installer/Updater.cs +++ b/MelonLoader.Installer/Updater.cs @@ -13,6 +13,10 @@ public static class Updater public static bool UpdateIfPossible() { + // Don't auto-update on CI builds + if (Program.Version.Revision > 0) + return false; + var downloadUrl = CheckForUpdateAsync().GetAwaiter().GetResult(); if (downloadUrl == null) return false; From 375d8c586198d08dbac91c44fafe56526742137e Mon Sep 17 00:00:00 2001 From: slxdy Date: Sat, 16 Nov 2024 15:16:31 +0100 Subject: [PATCH 05/10] Update the README --- README.md | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ab6ef45..b540d40 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,16 @@

# MelonLoader Installer -This is the Official Dedicated Installer for [MelonLoader](https://github.com/LavaGang/MelonLoader). + + +The Official Dedicated Installer for [MelonLoader](https://github.com/LavaGang/MelonLoader). ## Report an issue ### Join our official Discord server ## How does it work? -The installer should automatically list installed Unity games found in your Steam library. +The installer should automatically list installed Unity games on your machine. If the game you're trying to mod isn't listed, you can locate it manually by clicking on the `Add Game Manually` button. @@ -22,9 +24,22 @@ To install MelonLoader, click on the game you wish to mod. Next, select your pre Nightly builds are bleeding-edge builds, generated right after any changes are made to the project. They can be enabled with the switch under the version selection menu. -## Compilation -The project can be compiled using the .NET 8.0 compiler.
-To create a single-file build, use the `dotnet publish` command in the repository's root directory. +## Contribution + +Contributions to this project are welcome! If you wish to contribute, please adhere to the following guidelines: + +### Requirements: +Ensure you have the .NET 9.0 SDK installed on your machine. This is required to build the project. + +### Building the Project: +You can build the project locally using the following command: +```bash +dotnet publish +``` + +### Pull Requests: +All pull requests should be made towards the `development` branch. +The master branch contains the source code for the stable release and is protected to ensure stability. ## LICENSING & CREDITS: MelonLoader.Installer is licensed under the Apache License, Version 2.0. See [LICENSE](https://github.com/LavaGang/MelonLoader.Installer/blob/master/LICENSE.md) for the full License. @@ -38,4 +53,4 @@ MelonLoader.Installer is licensed under the Apache License, Version 2.0. See [LI
-> See [MelonLoader Wiki](https://melonwiki.xyz/#/credits) for the full Credits. \ No newline at end of file +> See [MelonLoader Wiki](https://melonwiki.xyz/#/credits) for the full Credits. From 0cc3604de06941bfaf00a1a58d907bb0ca6c5cf0 Mon Sep 17 00:00:00 2001 From: Herp Derpinstine Date: Sat, 16 Nov 2024 09:11:12 -0600 Subject: [PATCH 06/10] Reworked ErrorBox into a Generic DialogBox for multiple use-cases --- .../Views/DetailsView.axaml.cs | 8 +- MelonLoader.Installer/Views/DialogBox.axaml | 27 +++++ .../Views/DialogBox.axaml.cs | 107 ++++++++++++++++++ MelonLoader.Installer/Views/ErrorBox.axaml | 21 ---- MelonLoader.Installer/Views/ErrorBox.axaml.cs | 33 ------ MelonLoader.Installer/Views/MainView.axaml.cs | 2 +- .../Views/MainWindow.axaml.cs | 2 +- 7 files changed, 140 insertions(+), 60 deletions(-) create mode 100644 MelonLoader.Installer/Views/DialogBox.axaml create mode 100644 MelonLoader.Installer/Views/DialogBox.axaml.cs delete mode 100644 MelonLoader.Installer/Views/ErrorBox.axaml delete mode 100644 MelonLoader.Installer/Views/ErrorBox.axaml.cs diff --git a/MelonLoader.Installer/Views/DetailsView.axaml.cs b/MelonLoader.Installer/Views/DetailsView.axaml.cs index 670a249..3559c21 100644 --- a/MelonLoader.Installer/Views/DetailsView.axaml.cs +++ b/MelonLoader.Installer/Views/DetailsView.axaml.cs @@ -49,7 +49,7 @@ protected override void OnDataContextChanged(EventArgs e) if (!MLManager.Init()) { Model.Offline = true; - ErrorBox.Open("Failed to fetch MelonLoader releases. Ensure you're online."); + DialogBox.ShowError("Failed to fetch MelonLoader releases. Ensure you're online."); } } @@ -145,7 +145,7 @@ private void OnInstallFinished(string? errorMessage) if (errorMessage != null) { - ErrorBox.Open(errorMessage); + DialogBox.ShowError(errorMessage); return; } @@ -174,7 +174,7 @@ private void UninstallHandler(object sender, RoutedEventArgs args) if (!MLManager.Uninstall(Path.GetDirectoryName(Model.Game.Path)!, !KeepFilesCheck.IsChecked!.Value, out var error)) { - ErrorBox.Open(error); + DialogBox.ShowError(error); } Model.Game.ValidateGame(); @@ -215,7 +215,7 @@ private async void SelectZipHandler(object sender, TappedEventArgs args) var ver = MLManager.Versions[0]; if ((Model.Game.Is32Bit ? ver.DownloadX86Url : ver.DownloadUrl) == null) { - ErrorBox.Open($"The selected version does not support the architechture of the current game: {(Model.Game.Is32Bit ? "x86" : "x64")}"); + DialogBox.ShowError($"The selected version does not support the architechture of the current game: {(Model.Game.Is32Bit ? "x86" : "x64")}"); } } diff --git a/MelonLoader.Installer/Views/DialogBox.axaml b/MelonLoader.Installer/Views/DialogBox.axaml new file mode 100644 index 0000000..9e9fabc --- /dev/null +++ b/MelonLoader.Installer/Views/DialogBox.axaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/MelonLoader.Installer/Views/DialogBox.axaml.cs b/MelonLoader.Installer/Views/DialogBox.axaml.cs new file mode 100644 index 0000000..ef64d29 --- /dev/null +++ b/MelonLoader.Installer/Views/DialogBox.axaml.cs @@ -0,0 +1,107 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; +using Avalonia.Media.Imaging; +using Avalonia.Platform; + +namespace MelonLoader.Installer.Views; + +public partial class DialogBox : Window +{ + public delegate void dCallback(object sender, RoutedEventArgs args); + private dCallback? OnConfirm; + private dCallback? OnCancel; + + private static Bitmap? ErrorIcon = new Bitmap(AssetLoader.Open(new("avares://" + typeof(GameControl).Assembly.GetName().Name + "/Assets/error.png"))); + + public DialogBox() + => InitializeComponent(); + + public static void ShowError(string message) + { + DialogBox dialogBox = new DialogBox(); + dialogBox.Title = "Error"; + dialogBox.Message.Text = message; + dialogBox.HeaderImage.Source = ErrorIcon; + dialogBox.Open(); + } + + public static void ShowNotice(string message) + => ShowNotice("Notice", message); + public static void ShowNotice(string title, string message) + { + DialogBox dialogBox = new DialogBox(); + dialogBox.Title = title; + dialogBox.Message.Text = message; + dialogBox.Open(); + } + + public static void ShowConfirmation( + string message, + dCallback? onConfirm = null, + dCallback? onCancel = null, + string confirmText = "YES", + string cancelText = "NO") + => ShowConfirmation("Confirmation", + message, + onConfirm, + onCancel, + confirmText, + cancelText); + + public static void ShowConfirmation( + string title, + string message, + dCallback? onConfirm = null, + dCallback? onCancel = null, + string confirmText = "YES", + string cancelText = "NO") + { + DialogBox dialogBox = new DialogBox(); + + dialogBox.Title = title; + dialogBox.Message.Text = message; + + dialogBox.ConfirmButton.Content = confirmText; + + dialogBox.CancelButton.IsVisible = true; + dialogBox.CancelButton.Content = cancelText; + + dialogBox.OnConfirm = onConfirm; + dialogBox.OnCancel = onCancel; + + dialogBox.NoticeGrid.IsVisible = false; + dialogBox.ConfirmationGrid.IsVisible = true; + + dialogBox.Open(); + } + + private void Open() + { + BringToFront(); + + if (MainWindow.Instance.IsVisible) + ShowDialog(MainWindow.Instance); + else + Show(); + } + + private void BringToFront() + { + Topmost = true; + Topmost = false; + Program.GrabAttention(); + Focus(); + } + + private void ConfirmHandler(object sender, RoutedEventArgs args) + { + Close(); + OnConfirm?.Invoke(sender, args); + } + + private void CancelHandler(object sender, RoutedEventArgs args) + { + Close(); + OnCancel?.Invoke(sender, args); + } +} \ No newline at end of file diff --git a/MelonLoader.Installer/Views/ErrorBox.axaml b/MelonLoader.Installer/Views/ErrorBox.axaml deleted file mode 100644 index 2888aa5..0000000 --- a/MelonLoader.Installer/Views/ErrorBox.axaml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/MelonLoader.Installer/Views/ErrorBox.axaml.cs b/MelonLoader.Installer/Views/ErrorBox.axaml.cs deleted file mode 100644 index 7e3812f..0000000 --- a/MelonLoader.Installer/Views/ErrorBox.axaml.cs +++ /dev/null @@ -1,33 +0,0 @@ -using Avalonia.Controls; -using Avalonia.Interactivity; - -namespace MelonLoader.Installer.Views; - -public partial class ErrorBox : Window -{ - public ErrorBox() - { - InitializeComponent(); - } - - public static void Open(string message) - { - var box = new ErrorBox(); - box.Message.Text = message; - box.Topmost = true; - box.Topmost = false; - - Program.GrabAttention(); - box.Focus(); - - if (MainWindow.Instance.IsVisible) - box.ShowDialog(MainWindow.Instance); - else - box.Show(); - } - - private void OkHandler(object sender, RoutedEventArgs args) - { - Close(); - } -} \ No newline at end of file diff --git a/MelonLoader.Installer/Views/MainView.axaml.cs b/MelonLoader.Installer/Views/MainView.axaml.cs index c42f039..141a6cf 100644 --- a/MelonLoader.Installer/Views/MainView.axaml.cs +++ b/MelonLoader.Installer/Views/MainView.axaml.cs @@ -69,7 +69,7 @@ public async void AddGameManuallyHandler(object sender, RoutedEventArgs args) GameManager.TryAddGame(path, null, null, null, out var error); if (error != null) { - ErrorBox.Open(error); + DialogBox.ShowError(error); return; } diff --git a/MelonLoader.Installer/Views/MainWindow.axaml.cs b/MelonLoader.Installer/Views/MainWindow.axaml.cs index 74b462d..4001292 100644 --- a/MelonLoader.Installer/Views/MainWindow.axaml.cs +++ b/MelonLoader.Installer/Views/MainWindow.axaml.cs @@ -36,7 +36,7 @@ private void OnUpdateFinished(string? errorMessage) { if (errorMessage != null) { - ErrorBox.Open(errorMessage); + DialogBox.ShowError(errorMessage); ShowMainView(); return; } From 10143382d3aaa3b8d038b81155cf4ffd9b546e38 Mon Sep 17 00:00:00 2001 From: Herp Derpinstine Date: Sat, 16 Nov 2024 09:16:00 -0600 Subject: [PATCH 07/10] Cleanup --- MelonLoader.Installer/Views/DialogBox.axaml | 2 +- MelonLoader.Installer/Views/DialogBox.axaml.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MelonLoader.Installer/Views/DialogBox.axaml b/MelonLoader.Installer/Views/DialogBox.axaml index 9e9fabc..bfe2697 100644 --- a/MelonLoader.Installer/Views/DialogBox.axaml +++ b/MelonLoader.Installer/Views/DialogBox.axaml @@ -4,7 +4,7 @@ xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MelonLoader.Installer.Views.DialogBox" - Title="Notice" + Title="NOTICE" Icon="/Assets/icon.ico" WindowStartupLocation="CenterScreen" Background="#121217" diff --git a/MelonLoader.Installer/Views/DialogBox.axaml.cs b/MelonLoader.Installer/Views/DialogBox.axaml.cs index ef64d29..c486d2f 100644 --- a/MelonLoader.Installer/Views/DialogBox.axaml.cs +++ b/MelonLoader.Installer/Views/DialogBox.axaml.cs @@ -19,14 +19,14 @@ public DialogBox() public static void ShowError(string message) { DialogBox dialogBox = new DialogBox(); - dialogBox.Title = "Error"; + dialogBox.Title = "ERROR"; dialogBox.Message.Text = message; dialogBox.HeaderImage.Source = ErrorIcon; dialogBox.Open(); } public static void ShowNotice(string message) - => ShowNotice("Notice", message); + => ShowNotice("NOTICE", message); public static void ShowNotice(string title, string message) { DialogBox dialogBox = new DialogBox(); @@ -41,7 +41,7 @@ public static void ShowConfirmation( dCallback? onCancel = null, string confirmText = "YES", string cancelText = "NO") - => ShowConfirmation("Confirmation", + => ShowConfirmation("CONFIRMATION", message, onConfirm, onCancel, From 0b56ba1f28b11411032d04778ef263f2054164ca Mon Sep 17 00:00:00 2001 From: Herp Derpinstine Date: Sat, 16 Nov 2024 09:57:22 -0600 Subject: [PATCH 08/10] Implemented Success Dialog Box --- MelonLoader.Installer/Views/DetailsView.axaml.cs | 5 +++-- MelonLoader.Installer/Views/DialogBox.axaml | 2 +- README.md | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/MelonLoader.Installer/Views/DetailsView.axaml.cs b/MelonLoader.Installer/Views/DetailsView.axaml.cs index 3559c21..699f11b 100644 --- a/MelonLoader.Installer/Views/DetailsView.axaml.cs +++ b/MelonLoader.Installer/Views/DetailsView.axaml.cs @@ -142,6 +142,8 @@ private void OnInstallFinished(string? errorMessage) Model.Game.ValidateGame(); Model.Installing = false; + NightlyCheck.IsEnabled = true; + VersionCombobox.IsEnabled = true; if (errorMessage != null) { @@ -149,8 +151,7 @@ private void OnInstallFinished(string? errorMessage) return; } - InstallStatus.Text = "Done!"; - Model.Confirmation = true; + DialogBox.ShowNotice("SUCCESS!", $"MelonLoader v{((MLVersion)VersionCombobox.SelectedItem!).Version} was Installed Successfully!"); } private void OpenDirHandler(object sender, RoutedEventArgs args) diff --git a/MelonLoader.Installer/Views/DialogBox.axaml b/MelonLoader.Installer/Views/DialogBox.axaml index bfe2697..6d2813b 100644 --- a/MelonLoader.Installer/Views/DialogBox.axaml +++ b/MelonLoader.Installer/Views/DialogBox.axaml @@ -13,7 +13,7 @@ Height="100" SizeToContent="WidthAndHeight" RenderOptions.BitmapInterpolationMode="HighQuality"> - + diff --git a/README.md b/README.md index ab6ef45..64985df 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ To install MelonLoader, click on the game you wish to mod. Next, select your pre Nightly builds are bleeding-edge builds, generated right after any changes are made to the project. They can be enabled with the switch under the version selection menu. ## Compilation -The project can be compiled using the .NET 8.0 compiler.
+The project can be compiled using the .NET 9.0 compiler.
To create a single-file build, use the `dotnet publish` command in the repository's root directory. ## LICENSING & CREDITS: From a93e1da34157618adb5569202dc75d22110bb611 Mon Sep 17 00:00:00 2001 From: Herp Derpinstine Date: Sat, 16 Nov 2024 10:05:16 -0600 Subject: [PATCH 09/10] Update DetailsView.axaml.cs --- MelonLoader.Installer/Views/DetailsView.axaml.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/MelonLoader.Installer/Views/DetailsView.axaml.cs b/MelonLoader.Installer/Views/DetailsView.axaml.cs index 699f11b..1b8b628 100644 --- a/MelonLoader.Installer/Views/DetailsView.axaml.cs +++ b/MelonLoader.Installer/Views/DetailsView.axaml.cs @@ -139,6 +139,7 @@ private void OnInstallFinished(string? errorMessage) if (Model == null) return; + bool wasReinstall = Model.Game.MLInstalled; Model.Game.ValidateGame(); Model.Installing = false; @@ -151,7 +152,7 @@ private void OnInstallFinished(string? errorMessage) return; } - DialogBox.ShowNotice("SUCCESS!", $"MelonLoader v{((MLVersion)VersionCombobox.SelectedItem!).Version} was Installed Successfully!"); + DialogBox.ShowNotice("SUCCESS!", $"{(wasReinstall ? "Reinstall" : "Install")} was Successful!"); } private void OpenDirHandler(object sender, RoutedEventArgs args) @@ -176,9 +177,12 @@ private void UninstallHandler(object sender, RoutedEventArgs args) if (!MLManager.Uninstall(Path.GetDirectoryName(Model.Game.Path)!, !KeepFilesCheck.IsChecked!.Value, out var error)) { DialogBox.ShowError(error); + Model.Game.ValidateGame(); + return; } Model.Game.ValidateGame(); + DialogBox.ShowNotice("SUCCESS!", "Uninstall was Successful!"); } private async void SelectZipHandler(object sender, TappedEventArgs args) From cbdb6982da068a8949d9437fff989c83d3b61416 Mon Sep 17 00:00:00 2001 From: slxdy Date: Sat, 16 Nov 2024 17:56:57 +0100 Subject: [PATCH 10/10] Cleanup --- .../ViewModels/DetailsViewModel.cs | 16 +--- .../ViewModels/DialogBoxModel.cs | 10 ++ MelonLoader.Installer/Views/DetailsView.axaml | 4 +- .../Views/DetailsView.axaml.cs | 8 +- MelonLoader.Installer/Views/DialogBox.axaml | 17 ++-- .../Views/DialogBox.axaml.cs | 95 ++++++++++--------- .../Views/MainWindow.axaml.cs | 2 +- 7 files changed, 75 insertions(+), 77 deletions(-) create mode 100644 MelonLoader.Installer/ViewModels/DialogBoxModel.cs diff --git a/MelonLoader.Installer/ViewModels/DetailsViewModel.cs b/MelonLoader.Installer/ViewModels/DetailsViewModel.cs index 1aded3c..0520f4b 100644 --- a/MelonLoader.Installer/ViewModels/DetailsViewModel.cs +++ b/MelonLoader.Installer/ViewModels/DetailsViewModel.cs @@ -3,7 +3,6 @@ public class DetailsViewModel(GameModel game) : ViewModelBase { private bool _installing; - private bool _confirmation; private bool _offline; public GameModel Game => game; @@ -15,33 +14,20 @@ public bool Installing { _installing = value; OnPropertyChanged(); - OnPropertyChanged(nameof(CanInstall)); OnPropertyChanged(nameof(EnableSettings)); } } - public bool Confirmation - { - get => _confirmation; - set - { - _confirmation = value; - OnPropertyChanged(); - OnPropertyChanged(nameof(CanInstall)); - } - } - public bool Offline { get => _offline; set { _offline = value; - OnPropertyChanged(nameof(Confirmation)); + OnPropertyChanged(); OnPropertyChanged(nameof(EnableSettings)); } } - public bool CanInstall => !Installing && !Confirmation; public bool EnableSettings => !Offline && !Installing; } diff --git a/MelonLoader.Installer/ViewModels/DialogBoxModel.cs b/MelonLoader.Installer/ViewModels/DialogBoxModel.cs new file mode 100644 index 0000000..897c853 --- /dev/null +++ b/MelonLoader.Installer/ViewModels/DialogBoxModel.cs @@ -0,0 +1,10 @@ +namespace MelonLoader.Installer.ViewModels; + +public class DialogBoxModel : ViewModelBase +{ + public required string Message { get; init; } + public string ConfirmText { get; init; } = "YES"; + public string CancelText { get; init; } = "NO"; + public bool IsError { get; init; } + public bool IsConfirmation { get; init; } +} diff --git a/MelonLoader.Installer/Views/DetailsView.axaml b/MelonLoader.Installer/Views/DetailsView.axaml index 662f8ad..1d799e3 100644 --- a/MelonLoader.Installer/Views/DetailsView.axaml +++ b/MelonLoader.Installer/Views/DetailsView.axaml @@ -40,7 +40,7 @@ IsVisible="{Binding Game.MLInstalled}" IsChecked="True">Keep mods and settings
- + - + diff --git a/MelonLoader.Installer/Views/DetailsView.axaml.cs b/MelonLoader.Installer/Views/DetailsView.axaml.cs index 1b8b628..0daba6c 100644 --- a/MelonLoader.Installer/Views/DetailsView.axaml.cs +++ b/MelonLoader.Installer/Views/DetailsView.axaml.cs @@ -89,8 +89,6 @@ public void UpdateVersionInfo() if (Model == null || VersionCombobox.SelectedItem == null) return; - Model.Confirmation = false; - MelonIcon.Opacity = Model.Game.MLInstalled ? 1 : 0.3; if (Model.Game.MLVersion == null) @@ -139,7 +137,7 @@ private void OnInstallFinished(string? errorMessage) if (Model == null) return; - bool wasReinstall = Model.Game.MLInstalled; + var wasReinstall = Model.Game.MLInstalled; Model.Game.ValidateGame(); Model.Installing = false; @@ -152,7 +150,7 @@ private void OnInstallFinished(string? errorMessage) return; } - DialogBox.ShowNotice("SUCCESS!", $"{(wasReinstall ? "Reinstall" : "Install")} was Successful!"); + DialogBox.ShowNotice("Success!", $"{(wasReinstall ? "Reinstall" : "Install")} was Successful!"); } private void OpenDirHandler(object sender, RoutedEventArgs args) @@ -182,7 +180,7 @@ private void UninstallHandler(object sender, RoutedEventArgs args) } Model.Game.ValidateGame(); - DialogBox.ShowNotice("SUCCESS!", "Uninstall was Successful!"); + DialogBox.ShowNotice("Success!", "Uninstall was Successful!"); } private async void SelectZipHandler(object sender, TappedEventArgs args) diff --git a/MelonLoader.Installer/Views/DialogBox.axaml b/MelonLoader.Installer/Views/DialogBox.axaml index 6d2813b..8640116 100644 --- a/MelonLoader.Installer/Views/DialogBox.axaml +++ b/MelonLoader.Installer/Views/DialogBox.axaml @@ -2,8 +2,10 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:vm="clr-namespace:MelonLoader.Installer.ViewModels" mc:Ignorable="d" x:Class="MelonLoader.Installer.Views.DialogBox" + x:DataType="vm:DialogBoxModel" Title="NOTICE" Icon="/Assets/icon.ico" WindowStartupLocation="CenterScreen" @@ -14,14 +16,15 @@ SizeToContent="WidthAndHeight" RenderOptions.BitmapInterpolationMode="HighQuality"> - - - - + + + + + - - - + +