浏览代码

settings refactoring

Veloe 1 年之前
父节点
当前提交
158aca9421

+ 4 - 5
VeloeMinecraftLauncher/Program.cs

@@ -1,7 +1,6 @@
 using Avalonia;
 using Avalonia.ReactiveUI;
 using Serilog;
-using Serilog.Events;
 using System;
 using System.Diagnostics;
 using VeloeMinecraftLauncher.Utils;
@@ -20,13 +19,13 @@ namespace VeloeMinecraftLauncher
         // Avalonia configuration, don't remove; also used by visual designer.
         public static AppBuilder BuildAvaloniaApp()
         {
-            Settings.LoadSettings();
-            var logger = new Serilog.LoggerConfiguration()
+            SettingsService.LoadSettings();
+            var logger = new LoggerConfiguration()
                .MinimumLevel.Debug()
-               .WriteTo.File("avalonia.log", Settings.fileLogEventLevel, fileSizeLimitBytes: Settings.maxLog * 1024, rollOnFileSizeLimit: true)// restricted... is Optional
+               .WriteTo.File("avalonia.log", SettingsService.Instance.FileLogEventLevel, fileSizeLimitBytes: SettingsService.Instance.MaxLog * 1024, rollOnFileSizeLimit: true)// restricted... is Optional
                .CreateLogger();
             
-            Settings.avaloniaLogger = logger;
+            SettingsService.avaloniaLogger = logger;
             TraceListener listener = new SerilogTraceListener.SerilogTraceListener(logger);
             Trace.Listeners.Add(listener);
             

+ 53 - 53
VeloeMinecraftLauncher/Utils/Downloader/Downloader.cs

@@ -181,28 +181,28 @@ internal class Downloader
         else
             modpackUrl = $"https://files.veloe.link/launcher/modpacks/{Parameters.Data.SelectedModpack.Name}.zip";
 
-        if (!Directory.Exists($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}"))
+        if (!Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}"))
         {
-            _logger.Debug("Creating path: {0}", $"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}");
-            Directory.CreateDirectory($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}");
+            _logger.Debug("Creating path: {0}", $"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}");
+            Directory.CreateDirectory($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}");
         }
 
         _logger.Debug("Downloading: {0}", $"{Parameters.Data.SelectedModpack.Name}.zip");
         Parameters.Action.DownloadingFileName($"{Parameters.Data.SelectedModpack.Name}.zip");
-        await DownloadFileAsync(modpackUrl, Settings.minecraftForlderPath + $"versions/{Parameters.Data.SelectedModpack.Name}.zip", cancellationToken, httpClient);
+        await DownloadFileAsync(modpackUrl, SettingsService.Instance.MinecraftForlderPath + $"versions/{Parameters.Data.SelectedModpack.Name}.zip", cancellationToken, httpClient);
 
         FileStream? stream = null;
 
-        if (Directory.Exists($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
+        if (Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
         {
-            foreach (var file in Directory.GetFiles($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
+            foreach (var file in Directory.GetFiles($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
             {
                 try { stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None); }
                 finally { stream?.Close(); }
             }
         }
-        if (Directory.Exists($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/config"))
-            foreach (var file in Directory.GetFiles($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
+        if (Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/config"))
+            foreach (var file in Directory.GetFiles($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
             {
                 try { stream = File.Open(file, FileMode.Open, FileAccess.Read, FileShare.None); }
                 finally { stream?.Close(); }
@@ -210,30 +210,30 @@ internal class Downloader
 
         stream?.Dispose();
 
-        if (Directory.Exists($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
-            Directory.Delete($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods", true);
-        if (Directory.Exists($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/config"))
-            Directory.Delete($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/config", true);
+        if (Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods"))
+            Directory.Delete($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/mods", true);
+        if (Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/config"))
+            Directory.Delete($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/config", true);
 
         _logger.Debug("Extracting: {0}", $"{Parameters.Data.SelectedModpack.Name}.zip");
         Parameters.Action.DownloadingFileName($"Unpacking {Parameters.Data.SelectedModpack.Name}.zip");
-        ZipFile.ExtractToDirectory($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}.zip", Settings.minecraftForlderPath + $"versions/{Parameters.Data.SelectedModpack.Name}", true);
-        File.Delete($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}.zip");
+        ZipFile.ExtractToDirectory($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}.zip", SettingsService.Instance.MinecraftForlderPath + $"versions/{Parameters.Data.SelectedModpack.Name}", true);
+        File.Delete($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}.zip");
 
-        File.WriteAllText($"{Settings.minecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/revision.json", JsonSerializer.Serialize(Parameters.Data.SelectedModpack.Revision));
+        File.WriteAllText($"{SettingsService.Instance.MinecraftForlderPath}versions/{Parameters.Data.SelectedModpack.Name}/revision.json", JsonSerializer.Serialize(Parameters.Data.SelectedModpack.Revision));
     }
 
     private async Task DownloadForgeOptifine(HttpClient httpClient, Entity.Version.Version versionJson, CancellationToken cancellationToken)
     {
-        if (!Directory.Exists($"{Settings.minecraftForlderPath}versions/Forge{versionJson.Id}/mods"))
+        if (!Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/Forge{versionJson.Id}/mods"))
         {
-            _logger.Debug("Creating path: {0}", $"{Settings.minecraftForlderPath}versions/Forge" + versionJson.Id + "/mods");
-            Directory.CreateDirectory($"{Settings.minecraftForlderPath}versions/Forge" + versionJson.Id + "/mods");
+            _logger.Debug("Creating path: {0}", $"{SettingsService.Instance.MinecraftForlderPath}versions/Forge" + versionJson.Id + "/mods");
+            Directory.CreateDirectory($"{SettingsService.Instance.MinecraftForlderPath}versions/Forge" + versionJson.Id + "/mods");
         }
 
         _logger.Debug("Downloading: {0}", $"Optifine{versionJson.Id}.jar");
         Parameters.Action.DownloadingFileName($"Optifine{versionJson.Id}.jar");
-        await DownloadFileAsync($@"https://files.veloe.link/launcher/forge/Forge{versionJson.Id}/Optifine{versionJson.Id}.jar", Settings.minecraftForlderPath + "versions/Forge" + versionJson.Id + "/mods/" + "Optifine" + versionJson.Id + ".jar", cancellationToken, httpClient);
+        await DownloadFileAsync($@"https://files.veloe.link/launcher/forge/Forge{versionJson.Id}/Optifine{versionJson.Id}.jar", SettingsService.Instance.MinecraftForlderPath + "versions/Forge" + versionJson.Id + "/mods/" + "Optifine" + versionJson.Id + ".jar", cancellationToken, httpClient);
     }
 
     private async Task DownloadOptifine(HttpClient httpClient, Entity.Version.Version versionJson, CancellationToken cancellationToken)
@@ -241,31 +241,31 @@ internal class Downloader
         var optifinePath = $"Optifine{versionJson.Id}";
         var optifineUrl = $"https://files.veloe.link/launcher/optifine/Optifine{versionJson.Id}/";
 
-        if (!Directory.Exists($"{Settings.minecraftForlderPath}versions/{optifinePath}"))
+        if (!Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{optifinePath}"))
         {
-            _logger.Debug("Creating path: {0}", $"{Settings.minecraftForlderPath}versions/" + optifinePath);
-            Directory.CreateDirectory($"{Settings.minecraftForlderPath}versions/" + optifinePath);
+            _logger.Debug("Creating path: {0}", $"{SettingsService.Instance.MinecraftForlderPath}versions/" + optifinePath);
+            Directory.CreateDirectory($"{SettingsService.Instance.MinecraftForlderPath}versions/" + optifinePath);
         }
 
         _logger.Debug("Downloading: {0}", $"Optifine{versionJson.Id}.json");
         Parameters.Action.DownloadingFileName($"Optifine{versionJson.Id}.json");
-        await DownloadFileAsync($"{optifineUrl}Optifine{versionJson.Id}.json", Settings.minecraftForlderPath + "versions/" + optifinePath + "/" + optifinePath + ".json", cancellationToken, httpClient);
+        await DownloadFileAsync($"{optifineUrl}Optifine{versionJson.Id}.json", SettingsService.Instance.MinecraftForlderPath + "versions/" + optifinePath + "/" + optifinePath + ".json", cancellationToken, httpClient);
 
 
         _logger.Debug("Downloading: {0}", $"Optifine{versionJson.Id}.jar");
         Parameters.Action.DownloadingFileName($"Optifine{versionJson.Id}.json");
-        await DownloadFileAsync($"{optifineUrl}Optifine{versionJson.Id}.jar", Settings.minecraftForlderPath + "versions/" + optifinePath + "/" + optifinePath + ".jar", cancellationToken, httpClient);
+        await DownloadFileAsync($"{optifineUrl}Optifine{versionJson.Id}.jar", SettingsService.Instance.MinecraftForlderPath + "versions/" + optifinePath + "/" + optifinePath + ".jar", cancellationToken, httpClient);
 
 
         _logger.Debug("Downloading: {0}", "libraries.zip");
         Parameters.Action.DownloadingFileName("libraries.zip");
-        await DownloadFileAsync(optifineUrl + "libraries.zip", Settings.minecraftForlderPath + "versions/" + optifinePath + "/libraries.zip", cancellationToken, httpClient);
+        await DownloadFileAsync(optifineUrl + "libraries.zip", SettingsService.Instance.MinecraftForlderPath + "versions/" + optifinePath + "/libraries.zip", cancellationToken, httpClient);
 
 
         _logger.Debug("Extracting: {0}", "libraries.zip");
         Parameters.Action.DownloadingFileName("Unpacking libraries.zip");
-        ZipFile.ExtractToDirectory($"{Settings.minecraftForlderPath}versions/Optifine{versionJson.Id}/libraries.zip", Settings.minecraftForlderPath, true);
-        File.Delete($"{Settings.minecraftForlderPath}versions/Optifine{versionJson.Id}/libraries.zip");
+        ZipFile.ExtractToDirectory($"{SettingsService.Instance.MinecraftForlderPath}versions/Optifine{versionJson.Id}/libraries.zip", SettingsService.Instance.MinecraftForlderPath, true);
+        File.Delete($"{SettingsService.Instance.MinecraftForlderPath}versions/Optifine{versionJson.Id}/libraries.zip");
     }
 
     private async Task DownloadForge(HttpClient httpClient, Entity.Version.Version versionJson, CancellationToken cancellationToken)
@@ -273,42 +273,42 @@ internal class Downloader
         var forgePath = $"Forge{versionJson.Id}";
         var forgeUrl = $"https://files.veloe.link/launcher/forge/Forge{versionJson.Id}/";
 
-        if (!Directory.Exists($"{Settings.minecraftForlderPath}versions/Forge{versionJson.Id}"))
+        if (!Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/Forge{versionJson.Id}"))
         {
-            _logger.Debug("Creating path: {0}", $"{Settings.minecraftForlderPath}versions/" + forgePath);
-            Directory.CreateDirectory($"{Settings.minecraftForlderPath}versions/" + forgePath);
+            _logger.Debug("Creating path: {0}", $"{SettingsService.Instance.MinecraftForlderPath}versions/" + forgePath);
+            Directory.CreateDirectory($"{SettingsService.Instance.MinecraftForlderPath}versions/" + forgePath);
         }
 
 
         _logger.Debug("Downloading: {0}", $"Forge{versionJson.Id}.json");
         Parameters.Action.DownloadingFileName($"Forge{versionJson.Id}.json");
-        await DownloadFileAsync($"{forgeUrl}Forge{versionJson.Id}.json", Settings.minecraftForlderPath + "versions/" + forgePath + "/" + forgePath + ".json", cancellationToken, httpClient);
+        await DownloadFileAsync($"{forgeUrl}Forge{versionJson.Id}.json", SettingsService.Instance.MinecraftForlderPath + "versions/" + forgePath + "/" + forgePath + ".json", cancellationToken, httpClient);
 
 
         _logger.Debug("Downloading: {0}", "libraries.zip");
         Parameters.Action.DownloadingFileName("libraries.zip");
-        await DownloadFileAsync(forgeUrl + "libraries.zip", Settings.minecraftForlderPath + "versions/" + forgePath + "/libraries.zip", cancellationToken, httpClient);
+        await DownloadFileAsync(forgeUrl + "libraries.zip", SettingsService.Instance.MinecraftForlderPath + "versions/" + forgePath + "/libraries.zip", cancellationToken, httpClient);
 
 
         _logger.Debug("Extracting: {0}", "libraries.zip");
         Parameters.Action.DownloadingFileName("Unpacking libraries.zip");
-        ZipFile.ExtractToDirectory($"{Settings.minecraftForlderPath}versions/Forge{versionJson.Id}/libraries.zip", Settings.minecraftForlderPath, true);
-        File.Delete($"{Settings.minecraftForlderPath}versions/Forge{versionJson.Id}/libraries.zip");
+        ZipFile.ExtractToDirectory($"{SettingsService.Instance.MinecraftForlderPath}versions/Forge{versionJson.Id}/libraries.zip", SettingsService.Instance.MinecraftForlderPath, true);
+        File.Delete($"{SettingsService.Instance.MinecraftForlderPath}versions/Forge{versionJson.Id}/libraries.zip");
     }
 
     private async Task DownloadAssets(Entity.Version.Version versionJson, CancellationToken cancellationToken)
     {
         using var httpClient = new HttpClient();
         var assetsJson = await DownloadAndDeserializeJsonData<AssetsManifest>(versionJson.AssetIndex.Url);
-        var assetsPath = $"{Settings.minecraftForlderPath}{(versionJson.Assets == "pre-1.6" ? "resources" : $"assets/{versionJson.Assets}/objects")}";
+        var assetsPath = $"{SettingsService.Instance.MinecraftForlderPath}{(versionJson.Assets == "pre-1.6" ? "resources" : $"assets/{versionJson.Assets}/objects")}";
         var assetsUrl = "https://resources.download.minecraft.net/";
 
         //download assets json
         _logger.Debug("Downloading: {0}", versionJson.Assets + ".json");
 
-        if (!Directory.Exists(Settings.minecraftForlderPath + "/assets/" + versionJson.Assets + "/indexes/"))
-            Directory.CreateDirectory(Settings.minecraftForlderPath + "/assets/" + versionJson.Assets + "/indexes/");
-        await DownloadFileAsync(versionJson.AssetIndex.Url, Settings.minecraftForlderPath + "/assets/" + versionJson.Assets + "/indexes/" + versionJson.Assets + ".json", cancellationToken);
+        if (!Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "/assets/" + versionJson.Assets + "/indexes/"))
+            Directory.CreateDirectory(SettingsService.Instance.MinecraftForlderPath + "/assets/" + versionJson.Assets + "/indexes/");
+        await DownloadFileAsync(versionJson.AssetIndex.Url, SettingsService.Instance.MinecraftForlderPath + "/assets/" + versionJson.Assets + "/indexes/" + versionJson.Assets + ".json", cancellationToken);
 
         _logger.Debug("Downloading assets.");
         Parameters.Action.SetProgress(0);
@@ -332,7 +332,7 @@ internal class Downloader
                     Path.GetFileName(asset.Key) :
                     asset.Value.Hash;
 
-                var assetRoot = folder.Contains("icons") ? $"{Settings.minecraftForlderPath}assets/{versionJson.Assets}" : assetsPath;
+                var assetRoot = folder.Contains("icons") ? $"{SettingsService.Instance.MinecraftForlderPath}assets/{versionJson.Assets}" : assetsPath;
 
                 var chksum = string.Empty;
                 //here hash check
@@ -378,7 +378,7 @@ internal class Downloader
 
         foreach (var library in versionJson.Libraries)
         {
-            var libPath = Settings.minecraftForlderPath + "libraries/";
+            var libPath = SettingsService.Instance.MinecraftForlderPath + "libraries/";
             string libUrl = string.Empty;
             string sha1 = string.Empty;
             // getting path and url if universal lib
@@ -533,13 +533,13 @@ internal class Downloader
                         library.Downloads.Classifiers.NativesLinux is not null && OperatingSystem.IsLinux())))
                         continue;
 
-                    if (!Directory.Exists(Settings.minecraftForlderPath + "versions/" + versionJson.Id + "/natives/"))
+                    if (!Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "versions/" + versionJson.Id + "/natives/"))
                     {
-                        _logger.Debug("Creating path: {0}", Settings.minecraftForlderPath + "versions/" + versionJson.Id + "/natives/");
-                        Directory.CreateDirectory(Settings.minecraftForlderPath + "versions/" + versionJson.Id + "/natives/");
+                        _logger.Debug("Creating path: {0}", SettingsService.Instance.MinecraftForlderPath + "versions/" + versionJson.Id + "/natives/");
+                        Directory.CreateDirectory(SettingsService.Instance.MinecraftForlderPath + "versions/" + versionJson.Id + "/natives/");
                     }
-                    _logger.Debug("Extracting {0} to {1}", libName, Settings.minecraftForlderPath + "versions/" + versionJson.Id + "/natives/");
-                    ZipFile.ExtractToDirectory(libDir + "/" + libName, Settings.minecraftForlderPath + "versions/" + versionJson.Id + "/natives/", true);
+                    _logger.Debug("Extracting {0} to {1}", libName, SettingsService.Instance.MinecraftForlderPath + "versions/" + versionJson.Id + "/natives/");
+                    ZipFile.ExtractToDirectory(libDir + "/" + libName, SettingsService.Instance.MinecraftForlderPath + "versions/" + versionJson.Id + "/natives/", true);
                 }
                 catch (IOException)
                 {
@@ -553,7 +553,7 @@ internal class Downloader
     private async Task DownloadMainJar(HttpClient httpClient, Entity.Version.Version versionJson, CancellationToken cancellationToken)
     {
         //download json
-        var path = Settings.minecraftForlderPath + "/versions/" + versionJson.Id;
+        var path = SettingsService.Instance.MinecraftForlderPath + "/versions/" + versionJson.Id;
 
         //download jar
         if (!Directory.Exists(path))
@@ -597,12 +597,12 @@ internal class Downloader
         {
             _logger.Debug("Downloading Java");
             Parameters.Action.DownloadingFileName("java.zip");
-            await DownloadFileAsync(javaUrl, Settings.minecraftForlderPath + "java.zip", cancellationToken, httpClient);
+            await DownloadFileAsync(javaUrl, SettingsService.Instance.MinecraftForlderPath + "java.zip", cancellationToken, httpClient);
 
             _logger.Debug("Unpacking Java");
             Parameters.Action.DownloadingFileName("Unpacking java.zip");
-            ZipFile.ExtractToDirectory($"{Settings.minecraftForlderPath}java.zip", Settings.minecraftForlderPath, true);
-            File.Delete($"{Settings.minecraftForlderPath}java.zip");
+            ZipFile.ExtractToDirectory($"{SettingsService.Instance.MinecraftForlderPath}java.zip", SettingsService.Instance.MinecraftForlderPath, true);
+            File.Delete($"{SettingsService.Instance.MinecraftForlderPath}java.zip");
         }
         else
             throw new HttpRequestException("Required Java version was not found on server.");
@@ -626,13 +626,13 @@ internal class Downloader
 
             _logger.Debug("Downloading {0}.json", Parameters.Data.SelectedVersion.Id);
             Parameters.Action.DownloadingFileName($"{Parameters.Data.SelectedVersion.Id}.json");
-            return await DownloadAndDeserializeJsonData<Entity.Version.Version>(Parameters.Data.SelectedVersion.Url, Settings.minecraftForlderPath + "versions/" + Parameters.Data.SelectedVersion.Id + "/", Parameters.Data.SelectedVersion.Id + ".json");
+            return await DownloadAndDeserializeJsonData<Entity.Version.Version>(Parameters.Data.SelectedVersion.Url, SettingsService.Instance.MinecraftForlderPath + "versions/" + Parameters.Data.SelectedVersion.Id + "/", Parameters.Data.SelectedVersion.Id + ".json");
         }
         else
         {
             Parameters.Action.DownloadingFileName($"{Parameters.Data.SelectedVersion.Id}.json");
             _logger.Debug("Downloading {0}.json", Parameters.Data.SelectedVersion.Id);
-            return await DownloadAndDeserializeJsonData<Entity.Version.Version>(Parameters.Data.SelectedVersion.Url, Settings.minecraftForlderPath + "versions/" + Parameters.Data.SelectedVersion.Id + "/", Parameters.Data.SelectedVersion.Id + ".json");
+            return await DownloadAndDeserializeJsonData<Entity.Version.Version>(Parameters.Data.SelectedVersion.Url, SettingsService.Instance.MinecraftForlderPath + "versions/" + Parameters.Data.SelectedVersion.Id + "/", Parameters.Data.SelectedVersion.Id + ".json");
         }
     }
 
@@ -640,7 +640,7 @@ internal class Downloader
     {
         string jsonData;
 
-        if (logger is null) logger = Settings.logger;
+        if (logger is null) logger = SettingsService.logger;
 
         try
         {
@@ -713,7 +713,7 @@ internal class Downloader
                 continue;
 
             var relativePath = StartCommandBuilder.GetLibRelativePathFromName(library.Name);
-            var libPath = Settings.minecraftForlderPath + "libraries/" + relativePath;
+            var libPath = SettingsService.Instance.MinecraftForlderPath + "libraries/" + relativePath;
             var dirPath = Path.GetDirectoryName(libPath);
 
             ArgumentNullException.ThrowIfNullOrEmpty(dirPath);

+ 15 - 105
VeloeMinecraftLauncher/Utils/Settings.cs

@@ -1,4 +1,6 @@
-using Serilog.Events;
+using Avalonia.Controls.Templates;
+using ReactiveUI;
+using Serilog.Events;
 using System;
 using System.IO;
 using System.Linq;
@@ -7,54 +9,14 @@ using VeloeMinecraftLauncher.Utils.Logger;
 
 namespace VeloeMinecraftLauncher.Utils;
 
-internal static class Settings
+internal static class SettingsService
 {
     //public static readonly string JavaPath = "C:\\Program Files\\Microsoft\\jdk-11.0.12.7-hotspot\\bin\\java.exe";
-    public static string javaPath = string.Empty;
-    public static string minecraftForlderPath = Directory.GetCurrentDirectory() + '/';
-    public static UInt32 maxRam = 2048;
-    public static bool useCustomJava = false;
-    public static bool setMaxRam = false;
-    public static bool setPath = true;
-    public static bool checkGameAssets = false;
-    public static bool gameLogToLauncher = false;
-    public static string username = string.Empty;
-    public static string lastChosenVersion = string.Empty;
+    public static SettingsSerializable Instance { get; set; }
+
     public static Serilog.ILogger? logger;
     public static CaptureFilePathHook? logFilePath;
     public static Serilog.ILogger? avaloniaLogger;
-    public static bool setMaxLog = false;
-    public static UInt32 maxLog = 1024;
-    public static LogEventLevel consoleLogEventLevel = LogEventLevel.Debug;
-    public static LogEventLevel fileLogEventLevel = LogEventLevel.Debug;
-    public static bool fullscreen = false;
-    public static bool customsize = false;
-    public static UInt32 clientwidth = 0;
-    public static UInt32 clientheight = 0;
-
-    public static void UpdateSettings(SettingsSerializable settings)
-    {
-        if (settings is null)
-            return;
-        javaPath = settings.JavaPath;
-        minecraftForlderPath = settings.MinecraftForlderPath;
-        maxRam = settings.MaxRam;
-        useCustomJava = settings.UseCustomJava;
-        setMaxRam = settings.SetMaxRam;
-        setPath = settings.SetPath;
-        checkGameAssets = settings.CheckGameAssets;
-        gameLogToLauncher = settings.GameLogToLauncher;
-        lastChosenVersion = settings.LastChosenVersion;
-        username = settings.Username;
-        setMaxLog = settings.SetMaxLog;
-        maxLog = settings.MaxLog;
-        consoleLogEventLevel = settings.ConsoleLogEventLevel;
-        fileLogEventLevel = settings.FileLogEventLevel;
-        fullscreen = settings.FullScreen;
-        customsize = settings.CustomSize;
-        clientheight = settings.ClientHeight;
-        clientwidth = settings.ClientWidth;
-    }
 
     public static void LoadSettings()
     {
@@ -71,9 +33,7 @@ internal static class Settings
         {
             try
             {
-                var settingsSerializable = JsonSerializer.Deserialize<SettingsSerializable>(settings, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
-                if (settingsSerializable is not null)
-                    Settings.UpdateSettings(settingsSerializable);
+                Instance = JsonSerializer.Deserialize<SettingsSerializable>(settings, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new SettingsSerializable();
             }
             catch (JsonException ex)
             {
@@ -84,67 +44,17 @@ internal static class Settings
 
     public static void SaveSettings()
     {
-        if(minecraftForlderPath == string.Empty)
-            minecraftForlderPath = Directory.GetCurrentDirectory();
+        if(string.IsNullOrWhiteSpace(Instance.MinecraftForlderPath))
+            Instance.MinecraftForlderPath = Directory.GetCurrentDirectory();
 
-        if(minecraftForlderPath.Last() is not ('/' or '\\'))
-            minecraftForlderPath += "/";
+        if(Instance.MinecraftForlderPath.Last() is not ('/' or '\\'))
+            Instance.MinecraftForlderPath += "/";
 
-        if (!Directory.Exists(minecraftForlderPath))
-            Directory.CreateDirectory(minecraftForlderPath);
+        if (!Directory.Exists(Instance.MinecraftForlderPath))
+            Directory.CreateDirectory(Instance.MinecraftForlderPath);
 
-        var settings = JsonSerializer.Serialize(new SettingsSerializable());
+        var settings = JsonSerializer.Serialize(Instance);
 
         File.WriteAllText($"settings.json", settings);
     }
-}
-
-public class SettingsSerializable
-{
-    public string JavaPath {get; set;}
-    public string MinecraftForlderPath { get; set;}
-    public UInt32 MaxRam { get; set; }
-    public bool UseCustomJava { get; set; }
-    public bool SetMaxRam { get; set; }
-    public bool SetPath { get; set; }
-    public bool CheckGameAssets { get; set; }
-
-    public bool GameLogToLauncher { get; set; }
-
-    public string Username { get; set; }
-
-    public string LastChosenVersion { get; set; }
-
-    public bool SetMaxLog { get; set; }
-    public UInt32 MaxLog { get; set; }
-
-    public bool FullScreen { get; set; }
-    public bool CustomSize { set; get; }
-    public UInt32 ClientWidth { get; set; }
-    public UInt32 ClientHeight { get; set; }
-
-    public LogEventLevel ConsoleLogEventLevel { get; set; }
-    public LogEventLevel FileLogEventLevel { get; set; }
-
-    public SettingsSerializable()
-    {
-        JavaPath = Settings.javaPath;
-        MinecraftForlderPath= Settings.minecraftForlderPath;
-        MaxRam= Settings.maxRam;
-        UseCustomJava= Settings.useCustomJava;
-        SetMaxRam= Settings.setMaxRam;
-        SetPath = Settings.setPath;
-        CheckGameAssets= Settings.checkGameAssets;
-        GameLogToLauncher= Settings.gameLogToLauncher;
-        Username = Settings.username;
-        LastChosenVersion= Settings.lastChosenVersion;
-        SetMaxLog= Settings.setMaxLog;
-        MaxLog = Settings.maxLog;
-        ConsoleLogEventLevel= Settings.consoleLogEventLevel;
-        FileLogEventLevel= Settings.fileLogEventLevel;
-        FullScreen = Settings.fullscreen;
-        CustomSize = Settings.customsize;
-        ClientHeight = Settings.clientheight;
-        ClientWidth = Settings.clientwidth;
-    }
-}
+}

+ 89 - 0
VeloeMinecraftLauncher/Utils/SettingsSerializable.cs

@@ -0,0 +1,89 @@
+using Serilog.Events;
+using System;
+using System.IO;
+
+namespace VeloeMinecraftLauncher.Utils;
+
+public class SettingsSerializable : ICloneable
+{
+    public string JavaPath {get; set;} = string.Empty;
+    public string MinecraftForlderPath { get; set; } = Directory.GetCurrentDirectory() + Path.DirectorySeparatorChar;
+    public UInt32 MaxRam { get; set; } = 2048;
+    public bool UseCustomJava { get; set; } = false;
+    public bool SetMaxRam { get; set; } = false;
+    public bool SetPath { get; set; } = true;
+    public bool CheckGameAssets { get; set; } = false;
+
+    public bool GameLogToLauncher { get; set; } = false;
+
+    public string Username { get; set; } = string.Empty;
+
+    public string LastChosenVersion { get; set; } = string.Empty;
+
+    public bool SetMaxLog { get; set; } = false;
+    public UInt32 MaxLog { get; set; } = 1024;
+
+    public bool FullScreen { get; set; } = false;
+    public bool CustomSize { set; get; } = false;
+    public UInt32 ClientWidth { get; set; } = 1280;
+    public UInt32 ClientHeight { get; set; } = 720;
+
+    public bool HideLauncher { get; set; } = false;
+
+    public LogEventLevel ConsoleLogEventLevel { get; set; } = LogEventLevel.Debug;
+    public LogEventLevel FileLogEventLevel { get; set; } = LogEventLevel.Debug;
+
+    public object Clone()
+    {
+        return MemberwiseClone();
+    }
+
+    public override bool Equals(object? obj)
+    {
+        return obj is SettingsSerializable serializable &&
+               MaxRam == serializable.MaxRam &&
+               UseCustomJava == serializable.UseCustomJava &&
+               SetMaxRam == serializable.SetMaxRam &&
+               SetPath == serializable.SetPath &&
+               CheckGameAssets == serializable.CheckGameAssets &&
+               GameLogToLauncher == serializable.GameLogToLauncher &&
+               SetMaxLog == serializable.SetMaxLog &&
+               MaxLog == serializable.MaxLog &&
+               FullScreen == serializable.FullScreen &&
+               LastChosenVersion == serializable.LastChosenVersion &&
+               Username == serializable.Username &&
+               CustomSize == serializable.CustomSize &&
+               ClientWidth == serializable.ClientWidth &&
+               ClientHeight == serializable.ClientHeight &&
+               HideLauncher == serializable.HideLauncher &&
+               ConsoleLogEventLevel == serializable.ConsoleLogEventLevel &&
+               FileLogEventLevel == serializable.FileLogEventLevel &&
+               MinecraftForlderPath == serializable.MinecraftForlderPath &&
+               JavaPath == serializable.JavaPath;
+    }
+
+    public override int GetHashCode()
+    {
+        HashCode hash = new HashCode();
+        hash.Add(JavaPath);
+        hash.Add(MinecraftForlderPath);
+        hash.Add(MaxRam);
+        hash.Add(UseCustomJava);
+        hash.Add(SetMaxRam);
+        hash.Add(SetPath);
+        hash.Add(CheckGameAssets);
+        hash.Add(GameLogToLauncher);
+        hash.Add(Username);
+        hash.Add(LastChosenVersion);
+        hash.Add(SetMaxLog);
+        hash.Add(MaxLog);
+        hash.Add(FullScreen);
+        hash.Add(CustomSize);
+        hash.Add(ClientWidth);
+        hash.Add(ClientHeight);
+        hash.Add(HideLauncher);
+        hash.Add(ConsoleLogEventLevel);
+        hash.Add(FileLogEventLevel);
+        return hash.ToHashCode();
+    }
+}

+ 24 - 24
VeloeMinecraftLauncher/Utils/Starter/StartCommandBuilder.cs

@@ -25,9 +25,9 @@ internal static class StartCommandBuilder
 
         // setting natives folder
         if (version.InheritsFrom is null)
-            returnString.Append($"-Djava.library.path=\"{Path.GetDirectoryName(Settings.minecraftForlderPath + "versions/" + version.Id + "/natives/")}\"");
+            returnString.Append($"-Djava.library.path=\"{Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath + "versions/" + version.Id + "/natives/")}\"");
         else
-            returnString.Append($"-Djava.library.path=\"{Path.GetDirectoryName(Settings.minecraftForlderPath + "versions/" + version.InheritsFrom + "/natives/")}\""); //for forge, vanilla optifine, fabric
+            returnString.Append($"-Djava.library.path=\"{Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath + "versions/" + version.InheritsFrom + "/natives/")}\""); //for forge, vanilla optifine, fabric
 
         returnString.Append(" -cp \"");
 
@@ -67,24 +67,24 @@ internal static class StartCommandBuilder
             {
                 var libPath = GetLibPathFromName(library.Name);
                 if (rulesVaild)
-                    returnString.Append(Path.GetFullPath(Settings.minecraftForlderPath + "libraries/" + libPath) + separator);
+                    returnString.Append(Path.GetFullPath(SettingsService.Instance.MinecraftForlderPath + "libraries/" + libPath) + separator);
 
                 continue;
             }
 
             if (rulesVaild)
-                returnString.Append(Path.GetFullPath(Settings.minecraftForlderPath + "libraries/" + library.Downloads.Artifact.Path) + separator);
+                returnString.Append(Path.GetFullPath(SettingsService.Instance.MinecraftForlderPath + "libraries/" + library.Downloads.Artifact.Path) + separator);
 
         }
 
         Entity.Version.Version? inheritsFrom = null;
         if (version.InheritsFrom is null)
-            returnString.Append(Path.GetFullPath(Settings.minecraftForlderPath + "versions/" + version.Id + "/" + version.Id + ".jar")); //main jar file
+            returnString.Append(Path.GetFullPath(SettingsService.Instance.MinecraftForlderPath + "versions/" + version.Id + "/" + version.Id + ".jar")); //main jar file
         else
         {
             //for forge, vanilla optifine, fabric
             //add libraries from inherited version
-            var inheritsJsonString = File.ReadAllText(Settings.minecraftForlderPath + "versions/" + version.InheritsFrom + "/" + version.InheritsFrom + ".json");
+            var inheritsJsonString = File.ReadAllText(SettingsService.Instance.MinecraftForlderPath + "versions/" + version.InheritsFrom + "/" + version.InheritsFrom + ".json");
 
             inheritsFrom = JsonSerializer.Deserialize<Entity.Version.Version>(inheritsJsonString, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
 
@@ -121,19 +121,19 @@ internal static class StartCommandBuilder
                 }
 
                 if (rulesVaild)
-                    returnString.Append(Path.GetFullPath(Settings.minecraftForlderPath + "libraries/" + library.Downloads.Artifact.Path) + separator);
+                    returnString.Append(Path.GetFullPath(SettingsService.Instance.MinecraftForlderPath + "libraries/" + library.Downloads.Artifact.Path) + separator);
 
             }
 
             //main jar file
             //check here if there is jar file not inherited
             //check if it is not 0kb size (fabric)
-            var fileInfo = new FileInfo($"{Settings.minecraftForlderPath}versions/{version.Id}/{version.Id}.jar");
+            var fileInfo = new FileInfo($"{SettingsService.Instance.MinecraftForlderPath}versions/{version.Id}/{version.Id}.jar");
 
             if (fileInfo.Exists && fileInfo.Length > 0)
-                returnString.Append(Path.GetFullPath(Settings.minecraftForlderPath + "versions/" + version.Id + "/" + version.Id + ".jar"));//for optifine
+                returnString.Append(Path.GetFullPath(SettingsService.Instance.MinecraftForlderPath + "versions/" + version.Id + "/" + version.Id + ".jar"));//for optifine
             else
-                returnString.Append(Path.GetFullPath(Settings.minecraftForlderPath + "versions/" + version.InheritsFrom + "/" + version.InheritsFrom + ".jar"));//for forge
+                returnString.Append(Path.GetFullPath(SettingsService.Instance.MinecraftForlderPath + "versions/" + version.InheritsFrom + "/" + version.InheritsFrom + ".jar"));//for forge
         }
 
         returnString.Append('"');
@@ -161,7 +161,7 @@ internal static class StartCommandBuilder
                     }
                     if (value.Contains("${library_directory}"))
                     {
-                        value = value.Replace("${library_directory}", Path.GetDirectoryName(Settings.minecraftForlderPath + "libraries/"));
+                        value = value.Replace("${library_directory}", Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath + "libraries/"));
                     }
                     if (value.Contains("${classpath_separator}"))
                     {
@@ -169,7 +169,7 @@ internal static class StartCommandBuilder
                     }
 
                     bool containsArgWithValue = value.Contains('=');
-                    bool containsPathValueOnly = value.StartsWith(Path.GetDirectoryName(Settings.minecraftForlderPath + "libraries/")!);
+                    bool containsPathValueOnly = value.StartsWith(Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath + "libraries/")!);
                     //value = value.Replace(" ", "");
                     if (containsArgWithValue)
                         value = value.Replace("=", "=\"");
@@ -183,8 +183,8 @@ internal static class StartCommandBuilder
         }
 
         //max ram
-        if (Settings.setMaxRam)
-            returnString.Append($" -Xmx{Settings.maxRam}M ");
+        if (SettingsService.Instance.SetMaxRam)
+            returnString.Append($" -Xmx{SettingsService.Instance.MaxRam}M ");
 
 
         returnString.Append(" " + version.MainClass);
@@ -310,16 +310,16 @@ internal static class StartCommandBuilder
                 case "--gameDir":
                     //for forge
                     if (!(argsValues.Any(x => x.Contains("forge")) || version.MainClass.Contains("fabric") || version.Id.ToLower().Contains("fabric")))
-                        returnString.Append(" --gameDir " + "\"" + Path.GetDirectoryName(Settings.minecraftForlderPath) + "\"");
+                        returnString.Append(" --gameDir " + "\"" + Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath) + "\"");
                     else
-                        returnString.Append(" --gameDir " + "\"" + Path.GetDirectoryName(Settings.minecraftForlderPath + "versions/" + version.Id + "/") + "\"");
+                        returnString.Append(" --gameDir " + "\"" + Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath + "versions/" + version.Id + "/") + "\"");
                     break;
                 case "--assetsDir":
                     //for forge
                     if (version.InheritsFrom is null)
-                        returnString.Append(" --assetsDir " + "\"" + Path.GetDirectoryName(Settings.minecraftForlderPath + "assets/" + version.Assets + "/") + "\"");
+                        returnString.Append(" --assetsDir " + "\"" + Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath + "assets/" + version.Assets + "/") + "\"");
                     else if (inheritsFrom is not null)
-                        returnString.Append(" --assetsDir " + "\"" + Path.GetDirectoryName(Settings.minecraftForlderPath + "assets/" + inheritsFrom.Assets + "/") + "\"");
+                        returnString.Append(" --assetsDir " + "\"" + Path.GetDirectoryName(SettingsService.Instance.MinecraftForlderPath + "assets/" + inheritsFrom.Assets + "/") + "\"");
                     break;
                 case "--assetIndex":
                     //for forge
@@ -356,11 +356,11 @@ internal static class StartCommandBuilder
             }
         }
 
-        if (Settings.fullscreen)
+        if (SettingsService.Instance.FullScreen)
             returnString.Append(" --fullscreen");
 
-        if (Settings.customsize && !Settings.fullscreen)
-            returnString.Append($" --width {Settings.clientwidth} --height {Settings.clientheight}");
+        if (SettingsService.Instance.CustomSize && !SettingsService.Instance.FullScreen)
+            returnString.Append($" --width {SettingsService.Instance.ClientWidth} --height {SettingsService.Instance.ClientHeight}");
 
         return returnString.ToString();
     }
@@ -370,10 +370,10 @@ internal static class StartCommandBuilder
         string libPath = GetLibRelativePathFromName(name);
 
 #if DEBUG
-        if (File.Exists(Settings.minecraftForlderPath + "libraries/" + libPath))
-            Debug.WriteLine($"Lib exists: {Settings.minecraftForlderPath + "libraries/" + libPath}");
+        if (File.Exists(SettingsService.Instance.MinecraftForlderPath + "libraries/" + libPath))
+            Debug.WriteLine($"Lib exists: {SettingsService.Instance.MinecraftForlderPath + "libraries/" + libPath}");
         else
-            Debug.WriteLine($"Lib not exists: {Settings.minecraftForlderPath + "libraries/" + libPath}");
+            Debug.WriteLine($"Lib not exists: {SettingsService.Instance.MinecraftForlderPath + "libraries/" + libPath}");
 #endif
         return libPath;
     }

+ 12 - 2
VeloeMinecraftLauncher/VeloeMinecraftLauncher.csproj

@@ -10,8 +10,8 @@
 		<DebugType>embedded</DebugType>
 		<StartupObject>VeloeMinecraftLauncher.Program</StartupObject>
 		<PlatformTarget>x64</PlatformTarget>
-		<AssemblyVersion>1.5.1.79</AssemblyVersion>
-		<FileVersion>1.5.1.79</FileVersion>
+		<AssemblyVersion>1.6.0.69</AssemblyVersion>
+		<FileVersion>1.6.0.69</FileVersion>
 		<Configurations>Debug;Release</Configurations>
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
@@ -20,6 +20,16 @@
 	</PropertyGroup>
 	<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
 		<NoWarn>NU1605</NoWarn>
+		<ShouldCreateLogs>True</ShouldCreateLogs>
+		<AdvancedSettingsExpanded>False</AdvancedSettingsExpanded>
+		<UpdateAssemblyVersion>True</UpdateAssemblyVersion>
+		<UpdateAssemblyFileVersion>True</UpdateAssemblyFileVersion>
+		<UpdateAssemblyInfoVersion>False</UpdateAssemblyInfoVersion>
+		<AssemblyFileVersionSettings>None.None.None.None</AssemblyFileVersionSettings>
+		<UpdatePackageVersion>False</UpdatePackageVersion>
+		<AssemblyInfoVersionType>SettingsVersion</AssemblyInfoVersionType>
+		<InheritWinAppVersionFrom>None</InheritWinAppVersionFrom>
+		<AssemblyVersionSettings>None.None.None.None</AssemblyVersionSettings>
 	</PropertyGroup>
 	<ItemGroup>
 		<AvaloniaResource Include="Assets\**" />

+ 36 - 35
VeloeMinecraftLauncher/ViewModels/MainWindowViewModel.cs

@@ -46,15 +46,15 @@ public class MainWindowViewModel : ViewModelBase
             var hook = new CaptureFilePathHook();
             _logger = new LoggerConfiguration()
                 .MinimumLevel.Debug()
-                .WriteTo.Sink(eventSink, Settings.consoleLogEventLevel)
-                .WriteTo.File("launcher.log", Settings.fileLogEventLevel, fileSizeLimitBytes: Settings.maxLog * 1024, rollOnFileSizeLimit: true, hooks: hook)// restricted... is Optional
+                .WriteTo.Sink(eventSink, SettingsService.Instance.ConsoleLogEventLevel)
+                .WriteTo.File("launcher.log", SettingsService.Instance.FileLogEventLevel, fileSizeLimitBytes: SettingsService.Instance.MaxLog * 1024, rollOnFileSizeLimit: true, hooks: hook)// restricted... is Optional
                 .CreateLogger();
-            Settings.logger = _logger;
-            Settings.logFilePath = hook;
+            SettingsService.logger = _logger;
+            SettingsService.logFilePath = hook;
             //loading settings
             _logger.Debug("Loading settings.");
-            Settings.LoadSettings();
-            _username = Settings.username;
+            //SettingsService.LoadSettings();
+            _username = SettingsService.Instance.Username;
 
             //loading local verions
             _logger.Debug("Loading local versions.");
@@ -403,7 +403,7 @@ public class MainWindowViewModel : ViewModelBase
                     if (versionJson is null)
                         throw new ArgumentNullException(nameof(versionJson));
 
-                    if (Settings.checkGameAssets)
+                    if (SettingsService.Instance.CheckGameAssets)
                     {
                         TaskStatus result;
 
@@ -426,7 +426,7 @@ public class MainWindowViewModel : ViewModelBase
                                 await downloader.DownloadFabricLibraries(_tokenSource.Token);
                             }
 
-                            using StreamReader inheritsFromReader = new(Settings.minecraftForlderPath + "versions/" + versionJson.InheritsFrom + "/" + versionJson.InheritsFrom + ".json");
+                            using StreamReader inheritsFromReader = new(SettingsService.Instance.MinecraftForlderPath + "versions/" + versionJson.InheritsFrom + "/" + versionJson.InheritsFrom + ".json");
                             string jsonInheritsFrom = inheritsFromReader.ReadToEnd();
                             var inheritsFromJson = JsonSerializer.Deserialize<Entity.Version.Version>(jsonInheritsFrom, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
 
@@ -450,7 +450,7 @@ public class MainWindowViewModel : ViewModelBase
 
                     arguments = StartCommandBuilder.Build(versionJson, Username);
 
-                    if (!Settings.useCustomJava)
+                    if (!SettingsService.Instance.UseCustomJava)
                     {
                         if (versionJson?.JavaVersion?.MajorVersion is not null)
                         {
@@ -461,7 +461,7 @@ public class MainWindowViewModel : ViewModelBase
                         {
                             if (!string.IsNullOrEmpty(versionJson?.InheritsFrom))
                             {
-                                using StreamReader inheritsFromReader = new(Settings.minecraftForlderPath + "versions/" + versionJson.InheritsFrom + "/" + versionJson.InheritsFrom + ".json");
+                                using StreamReader inheritsFromReader = new(SettingsService.Instance.MinecraftForlderPath + "versions/" + versionJson.InheritsFrom + "/" + versionJson.InheritsFrom + ".json");
                                 string jsonInheritsFrom = inheritsFromReader.ReadToEnd();
                                 var inheritsFromJson = JsonSerializer.Deserialize<Entity.Version.Version>(jsonInheritsFrom, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
                                 if (inheritsFromJson?.JavaVersion?.MajorVersion is not null)
@@ -481,22 +481,22 @@ public class MainWindowViewModel : ViewModelBase
                 if (DownloadedVersion is null)
                     return;
 
-                string javaPath = Settings.javaPath;
+                string javaPath = SettingsService.Instance.JavaPath;
 
-                if (!Settings.useCustomJava)
+                if (!SettingsService.Instance.UseCustomJava)
                 {
-                    javaPath = Path.GetFullPath(Settings.minecraftForlderPath + "javaruntime/" + version + "/bin/java");
+                    javaPath = Path.GetFullPath(SettingsService.Instance.MinecraftForlderPath + "javaruntime/" + version + "/bin/java");
                     if (OperatingSystem.IsWindows())
                         javaPath += ".exe";
                 }
                 else
                 {
-                    javaPath = Path.Combine(Settings.javaPath, "bin/java");
+                    javaPath = Path.Combine(SettingsService.Instance.JavaPath, "bin/java");
                     if (OperatingSystem.IsWindows())
                         javaPath += ".exe";
                 }
 
-                _logger.Debug("Java version path: {0}", Path.Combine(Settings.minecraftForlderPath, javaPath));
+                _logger.Debug("Java version path: {0}", Path.Combine(SettingsService.Instance.MinecraftForlderPath, javaPath));
                 _logger.Debug("Minecraft arguments: {0}", arguments);
 
                 ProcessStartInfo proc;
@@ -506,9 +506,9 @@ public class MainWindowViewModel : ViewModelBase
                     RedirectStandardOutput = true,
                     RedirectStandardError = true,
                     CreateNoWindow = true,
-                    FileName = Path.GetFullPath(Path.Combine(Settings.minecraftForlderPath, javaPath)),
+                    FileName = Path.GetFullPath(Path.Combine(SettingsService.Instance.MinecraftForlderPath, javaPath)),
                     StandardErrorEncoding = Encoding.UTF8,
-                    WorkingDirectory = Path.GetDirectoryName(Path.Combine(Settings.minecraftForlderPath, javaPath)),
+                    WorkingDirectory = Path.GetDirectoryName(Path.Combine(SettingsService.Instance.MinecraftForlderPath, javaPath)),
                     Arguments = arguments
                 };
 
@@ -517,10 +517,10 @@ public class MainWindowViewModel : ViewModelBase
                     StartInfo = proc
                 };
 
-                if (!Settings.useCustomJava)
-                    minecraft.StartInfo.EnvironmentVariables["JAVA_HOME"] = $"{Settings.minecraftForlderPath}javaruntime/{version}";
+                if (!SettingsService.Instance.UseCustomJava)
+                    minecraft.StartInfo.EnvironmentVariables["JAVA_HOME"] = $"{SettingsService.Instance.MinecraftForlderPath}javaruntime/{version}";
                 else
-                    minecraft.StartInfo.EnvironmentVariables["JAVA_HOME"] = Settings.javaPath;
+                    minecraft.StartInfo.EnvironmentVariables["JAVA_HOME"] = SettingsService.Instance.JavaPath;
                 minecraft.StartInfo.EnvironmentVariables["PATH"] = "%JAVA_HOME%\bin;%PATH%";
 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                 Task.Run(() =>
@@ -541,13 +541,14 @@ public class MainWindowViewModel : ViewModelBase
                         _startedVersion = DownloadedVersion;
                         minecraft.Start();
 
-                        _hide();
+                        if (SettingsService.Instance.HideLauncher)
+                            _hide();
                         minecraft.Exited += ProcessExited;
 
                         minecraft.BeginOutputReadLine();
                         minecraft.BeginErrorReadLine();
 
-                        if (!Settings.gameLogToLauncher)
+                        if (!SettingsService.Instance.GameLogToLauncher)
                         {
                             minecraft.OutputDataReceived -= OutputHandler;
                             minecraft.CancelOutputRead();
@@ -564,9 +565,9 @@ public class MainWindowViewModel : ViewModelBase
                 });
 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                 _logger.Debug("Updating Settings");
-                Settings.username = _username;
-                Settings.lastChosenVersion = DownloadedVersion.Version;
-                Settings.SaveSettings();
+                SettingsService.Instance.Username = _username;
+                SettingsService.Instance.LastChosenVersion = DownloadedVersion.Version;
+                SettingsService.SaveSettings();
 
             }
             catch (Exception ex)
@@ -631,10 +632,10 @@ public class MainWindowViewModel : ViewModelBase
 
             StartButtonOutput = "";
             IsNoGameRunning = true;
-
-            _show();
+            if (SettingsService.Instance.HideLauncher)
+                _show();
             if (minecraftProcess.ExitCode is not (0 or 2))
-                OpenErrorWindow(new JavaProcessException($"Minecraft process exited with an error code {minecraftProcess.ExitCode}.\nCheck log in game folder or launcher console.", $"{Settings.minecraftForlderPath}versions/{_startedVersion?.Version ?? "NULL"}/crash-reports"));
+                OpenErrorWindow(new JavaProcessException($"Minecraft process exited with an error code {minecraftProcess.ExitCode}.\nCheck log in game folder or launcher console.", $"{SettingsService.Instance.MinecraftForlderPath}versions/{_startedVersion?.Version ?? "NULL"}/crash-reports"));
             else if (minecraftProcess.ExitCode is 2)
             {
                 OpenErrorWindow(new Exception("JVM exited on the startup (Exit code 2). Check your Java installation. Get more info in the laucher console."));
@@ -650,7 +651,7 @@ public class MainWindowViewModel : ViewModelBase
         DownloadedVersions ??= new();
 
         DownloadedVersions.Clear();
-        DirectoryInfo versions = new( Settings.minecraftForlderPath + "versions");
+        DirectoryInfo versions = new( Path.Combine(SettingsService.Instance.MinecraftForlderPath,"versions"));
         try
         {
             var dirs = versions.GetDirectories("*", SearchOption.TopDirectoryOnly);
@@ -672,12 +673,12 @@ public class MainWindowViewModel : ViewModelBase
 
             }
 
-            if (Settings.lastChosenVersion != null)
+            if (SettingsService.Instance.LastChosenVersion != null)
             {
                 DownloadedIndex = 0;
                 for (int i = 0; i < DownloadedVersions.Count; i++)
                 {
-                    if (DownloadedVersions[i].Version == Settings.lastChosenVersion)
+                    if (DownloadedVersions[i].Version == SettingsService.Instance.LastChosenVersion)
                     {
                         DownloadedIndex = i;
                         break;
@@ -685,18 +686,18 @@ public class MainWindowViewModel : ViewModelBase
                 }
                 
             }
-            if (!File.Exists(Settings.minecraftForlderPath + "launcher_profiles.json"))
+            if (!File.Exists(SettingsService.Instance.MinecraftForlderPath + "launcher_profiles.json"))
             {
-                var file = File.Create(Settings.minecraftForlderPath + "launcher_profiles.json");
+                var file = File.Create(SettingsService.Instance.MinecraftForlderPath + "launcher_profiles.json");
                 file.Close();
                 file.Dispose();
             }
             var lpString = JsonSerializer.Serialize(profiles, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
-            File.WriteAllText(Settings.minecraftForlderPath + "launcher_profiles.json", lpString);
+            File.WriteAllText(SettingsService.Instance.MinecraftForlderPath + "launcher_profiles.json", lpString);
         }
         catch (DirectoryNotFoundException)
         {
-            Directory.CreateDirectory(Settings.minecraftForlderPath + "versions");
+            Directory.CreateDirectory(SettingsService.Instance.MinecraftForlderPath + "versions");
             return;
         }
         

+ 264 - 151
VeloeMinecraftLauncher/ViewModels/SettingsWindowViewModel.cs

@@ -9,8 +9,9 @@ using System.Threading.Tasks;
 using System.Collections.ObjectModel;
 using Serilog.Events;
 using System.Linq;
-using ReactiveUI.Validation.Components;
 using Avalonia.Platform.Storage;
+using DynamicData.Binding;
+using System.Reactive.Linq;
 
 namespace VeloeMinecraftLauncher.ViewModels;
 
@@ -20,251 +21,363 @@ public class SettingsWindowViewModel : ViewModelBase
     { }
     public SettingsWindowViewModel(Serilog.ILogger logger)
     {
-        LauncherVersion = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown";
-
         _logger = logger;
 
-        var helper = this.ValidationRule(
-            viewModel => viewModel.JavaPath,
-            value => { if (value is null) return false; string path = Path.Combine(value , "bin/java"); if (OperatingSystem.IsWindows()) path += ".exe"; bool resultb = File.Exists(path); return resultb; },
-            "Can't find java executable.");
+        Settings = SettingsService.Instance.Clone() as SettingsSerializable ?? new();
+        ResetValidationRules();
 
+        ValidationContext.Changed.Subscribe(x => this.RaisePropertyChanged(nameof(IsValid)));
+        AllSettingsProprtiesObservable().Subscribe(x=>this.RaisePropertyChanged(nameof(IsValid)));
+        AllSettingsProprtiesObservable().Subscribe(x => this.RaisePropertyChanged(nameof(IsModified)));
+
+        
+        //AllSettingsProprtiesObservable().Subscribe(x => this.RaisePropertyChanged(nameof(IsValid)));
     }
 
-    private string _launcherVersion = string.Empty;
-    private string _minecraftFolderPath = Settings.minecraftForlderPath;
-    private string _javaPath = Settings.javaPath;
-    private string _maxRam = Settings.maxRam.ToString();
-    private bool _isValid;
-    private LogEventLevel _fileLogEventLevel = Settings.fileLogEventLevel;
-    private LogEventLevel _consoleLogEventLevel = Settings.consoleLogEventLevel;
-    private string _maxLog = Settings.maxLog.ToString();
-    
-    private ObservableCollection<LogEventLevel> _logEventLevels = new() {LogEventLevel.Debug, LogEventLevel.Information, LogEventLevel.Warning, LogEventLevel.Error };
+    private ObservableAsPropertyHelper<bool> _isModified;
+    private ObservableAsPropertyHelper<bool> _isValid;
 
-    public bool UseCustomJava
+    private ObservableCollection<LogEventLevel> _logEventLevels = new() { LogEventLevel.Debug, LogEventLevel.Information, LogEventLevel.Warning, LogEventLevel.Error };
+
+    public SettingsSerializable Settings { get; private set; }
+
+    public bool IsModified => Settings.GetHashCode() != SettingsService.Instance.GetHashCode();
+
+    public bool IsValid => IsModified && ValidationContext.IsValid;
+
+    public string LauncherVersion => Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown";
+
+    public ObservableCollection<LogEventLevel> LogEventLevels => _logEventLevels;
+
+    private void ResetValidationRules()
     {
-        get => Settings.useCustomJava;
-        set 
-        {
-            this.RaiseAndSetIfChanged(ref Settings.useCustomJava, value);
-            this.RaisePropertyChanged(nameof(IsValid));
-        }
+        this.ClearValidationRules();
+        this.ValidationRule(
+            viewModel => viewModel.JavaPath,
+            value => { if (value is null) return false; if (!UseCustomJava) return true; var path = Path.Combine(value, "bin/java"); if (OperatingSystem.IsWindows()) path += ".exe"; return File.Exists(path); },
+            "Can't find java executable.");
     }
 
-    public bool SetMaxRam
+    public void SaveSettings()
     {
-        get => Settings.setMaxRam;
-        set => this.RaiseAndSetIfChanged(ref Settings.setMaxRam, value);
+        SettingsService.Instance = (SettingsSerializable)Settings.Clone();
+        SettingsService.SaveSettings();
+        this.RaisePropertyChanged(nameof(SetMinecraftFolder));
     }
 
-    public bool SetMinecraftFolder
+    public void SaveSettingsAndClose(Window window)
     {
-        get => Settings.setPath;
-        set 
-        { 
-            this.RaiseAndSetIfChanged(ref Settings.setPath, value); 
-            this.RaisePropertyChanged(nameof(IsValid)); 
-        }
+        SettingsService.Instance = (SettingsSerializable)Settings.Clone();
+        SettingsService.SaveSettings();
+        ((Window)window).Close();
     }
 
-    public bool CheckAssets
+    public void OpenMinecraftPathDialog(Window window)
     {
-        get => Settings.checkGameAssets;
-        set => this.RaiseAndSetIfChanged(ref Settings.checkGameAssets, value);
+        Task.Run(async() =>
+        {
+            var storageProvider = ((Window)window).StorageProvider;
+            var initPath = String.Empty;
+
+            if (!string.IsNullOrEmpty(Settings.MinecraftForlderPath))
+                initPath = Path.GetFullPath(Settings.MinecraftForlderPath);
+
+            var folderPickerOpenOptions = new FolderPickerOpenOptions() 
+            {
+                AllowMultiple = false,
+                SuggestedStartLocation = await storageProvider.TryGetFolderFromPathAsync(initPath)
+            };
+
+            var result = await storageProvider.OpenFolderPickerAsync(folderPickerOpenOptions);
+
+            if (result is null || result.Count != 1 || result.First().Path.AbsolutePath == String.Empty)
+                return;
+
+            MinecraftFolderPath = result.First().Path.LocalPath;
+        });
     }
 
-    public string JavaPath
+    public void OpenJavaPathDialog(Window window)
     {
-        get => _javaPath;
-        set 
-        { 
-            this.RaiseAndSetIfChanged(ref _javaPath, value); 
-            this.RaisePropertyChanged(nameof(IsValid)); 
-        }
+        Task.Run(async() =>
+        {
+            var storageProvider = ((Window)window).StorageProvider;
+            var initPath = String.Empty;
+
+            if (!string.IsNullOrEmpty(Settings.JavaPath))
+                initPath = Path.GetFullPath(Settings.JavaPath);
+
+            var folderPickerOpenOptions = new FolderPickerOpenOptions()
+            {
+                AllowMultiple = false,
+                SuggestedStartLocation = await storageProvider.TryGetFolderFromPathAsync(initPath)
+            };
+
+            var result = await storageProvider.OpenFolderPickerAsync(folderPickerOpenOptions);
+
+            if (result is null || result.Count != 1 || result.First().Path.AbsolutePath == String.Empty)
+                return;
+
+            JavaPath = result.First().Path.LocalPath;
+        });
     }
 
-    public string MaxRam
+    public void OpenLogFile()
     {
-        get => _maxRam;
-        set 
-        { 
-            this.RaiseAndSetIfChanged(ref _maxRam, value); 
-            this.RaisePropertyChanged(nameof(IsValid)); 
+        if (Path.Exists(SettingsService.logFilePath?.Path))
+        {
+            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo() { FileName = SettingsService.logFilePath.Path, UseShellExecute = true });
         }
     }
 
-    public bool FullScreen
+    private IObservable<SettingsWindowViewModel?> AllSettingsProprtiesObservable()
     {
-        get => Settings.fullscreen;
+        return this.WhenAnyPropertyChanged(
+                    nameof(SetMinecraftFolder),
+                    nameof(MinecraftFolderPath),
+                    nameof(UseCustomJava),
+                    nameof(CheckAssets),
+                    nameof(HideLauncher),
+                    nameof(JavaPath),
+                    nameof(GameLogToLauncher),
+                    nameof(SetMaxRam),
+                    nameof(MaxRam),
+                    nameof(FileLogEventLevel),
+                    nameof(ConsoleLogEventLevel),
+                    nameof(SetMaxLog),
+                    nameof(FullScreen),
+                    nameof(CustomSize),
+                    nameof(ClientHeight),
+                    nameof(ClientWidth));
+    }
+
+    #region Settings Proprties
+
+    public bool SetMinecraftFolder
+    {
+        get => Settings.SetPath;
         set
         {
-            this.RaiseAndSetIfChanged(ref Settings.customsize, !value, nameof(CustomSize));
-            this.RaiseAndSetIfChanged(ref Settings.fullscreen, value);
+            if (Settings.SetPath != value)
+            {
+                Settings.SetPath = value;
+                this.RaisePropertyChanged();
+            }
         }
     }
 
-    public bool CustomSize
+    public string MinecraftFolderPath
     {
-        get => Settings.customsize;
+        get => Settings.MinecraftForlderPath;
         set
         {
-            this.RaiseAndSetIfChanged(ref Settings.fullscreen, !value, nameof(FullScreen));
-            this.RaiseAndSetIfChanged(ref Settings.customsize, value);
+            if (Settings.MinecraftForlderPath != value)
+            {
+                Settings.MinecraftForlderPath = value;
+                this.RaisePropertyChanged();
+            }
         }
     }
 
-    public uint ClientWidth
+    public bool UseCustomJava
     {
-        get => Settings.clientwidth;
-        set => this.RaiseAndSetIfChanged(ref Settings.clientwidth, value);
-        /*{
-            if (uint.TryParse(value, out var result) && result != Settings.clientwidth)
+        get => Settings.UseCustomJava;
+        set
+        {
+            if (Settings.UseCustomJava != value)
             {
-                Settings.clientwidth = result;
-                if (!string.IsNullOrEmpty(value))
-                    this.RaisePropertyChanged();
+                Settings.UseCustomJava = value;
+                ResetValidationRules();
+                this.RaisePropertyChanged();
             }
-        }*/
+        }
     }
 
-    public uint ClientHeight
+    public bool CheckAssets
     {
-        get => Settings.clientheight;
-        set => this.RaiseAndSetIfChanged(ref Settings.clientheight, value);
+        get => Settings.CheckGameAssets;
+        set
+        {
+            if (Settings.CheckGameAssets != value)
+            {
+                Settings.CheckGameAssets = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public bool IsValid
+    public bool HideLauncher
     {
-        get
+        get => Settings.HideLauncher;
+        set
         {
-            _isValid = true;
-            if (!UseCustomJava)
+            if (Settings.HideLauncher != value)
             {
-                var rules = ValidationContext.Validations.Where(r => !((BasePropertyValidation<SettingsWindowViewModel>)r).Properties.Contains(nameof(JavaPath)));
-                foreach (var rule in rules)
-                    _isValid &= rule.IsValid;  
+                Settings.HideLauncher = value;
+                this.RaisePropertyChanged();
             }
-            else
-                 _isValid = ValidationContext.GetIsValid();
-            return _isValid;
         }
     }
 
-    public string MinecraftFolderPath
+    public string JavaPath
     {
-        get => _minecraftFolderPath;
-        set => this.RaiseAndSetIfChanged(ref _minecraftFolderPath, value);
+        get => Settings.JavaPath;
+        set
+        {
+            if (Settings.JavaPath != value)
+            {
+                Settings.JavaPath = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public string LauncherVersion
+    public bool GameLogToLauncher
     {
-        get => _launcherVersion;
-        set => this.RaiseAndSetIfChanged(ref _launcherVersion, value);
+        get => Settings.GameLogToLauncher;
+        set
+        {
+            if (Settings.GameLogToLauncher != value)
+            {
+                Settings.GameLogToLauncher = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public bool GameLogToLauncher
+    public bool SetMaxRam
     {
-        get => Settings.gameLogToLauncher;
-        set => this.RaiseAndSetIfChanged(ref Settings.gameLogToLauncher, value);
+        get => Settings.SetMaxRam;
+        set
+        {
+            if (Settings.SetMaxRam != value)
+            {
+                Settings.SetMaxRam = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public ObservableCollection<LogEventLevel> LogEventLevels
+    public uint MaxRam
     {
-        get => _logEventLevels;
-        set => this.RaiseAndSetIfChanged(ref _logEventLevels, value);
+        get => Settings.MaxRam;
+        set
+        {
+            if (Settings.MaxRam != value)
+            {
+                Settings.MaxRam = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
     public LogEventLevel FileLogEventLevel
     {
-        get =>_fileLogEventLevel;
-        set => this.RaiseAndSetIfChanged(ref _fileLogEventLevel, value);
+        get => Settings.FileLogEventLevel;
+        set
+        {
+            if (Settings.FileLogEventLevel != value)
+            {
+                Settings.FileLogEventLevel = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
     public LogEventLevel ConsoleLogEventLevel
     {
-        get => _consoleLogEventLevel;
-        set => this.RaiseAndSetIfChanged(ref _consoleLogEventLevel, value);
+        get => Settings.ConsoleLogEventLevel;
+        set
+        {
+            if (Settings.ConsoleLogEventLevel != value)
+            {
+                Settings.ConsoleLogEventLevel = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
     public bool SetMaxLog
     {
-        get => Settings.setMaxLog;
-        set => this.RaiseAndSetIfChanged(ref Settings.setMaxLog, value);
+        get => Settings.SetMaxLog;
+        set
+        {
+            if (Settings.SetMaxLog != value)
+            {
+                Settings.SetMaxLog = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public string MaxLog
+    public uint MaxLog
     {
-        get => _maxLog;
-        set => this.RaiseAndSetIfChanged(ref _maxLog, value);
+        get => Settings.MaxLog;
+        set
+        {
+            if (Settings.MaxLog != value)
+            {
+                Settings.MaxLog = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public void SaveSettings()
+    public bool FullScreen
     {
-        Settings.javaPath = _javaPath;
-        Settings.minecraftForlderPath = _minecraftFolderPath;
-        Settings.maxRam = UInt32.Parse(_maxRam);
-        Settings.maxLog = UInt32.Parse(_maxLog);
-        Settings.consoleLogEventLevel = _consoleLogEventLevel;
-        Settings.fileLogEventLevel = _fileLogEventLevel;
-        Settings.SaveSettings();
+        get => Settings.FullScreen;
+        set
+        {
+            if (Settings.FullScreen != value)
+            {
+                if (value && Settings.CustomSize) CustomSize = !value;
+                Settings.FullScreen = value;
+
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public void OpenMinecraftPathDialog(object window)
+    public bool CustomSize
     {
-        Task.Run(async() =>
+        get => Settings.CustomSize;
+        set
         {
-            var storageProvider = ((Window)window).StorageProvider;
-            var initPath = String.Empty;
-
-            if (!string.IsNullOrEmpty(Settings.minecraftForlderPath))
-                initPath = Path.GetFullPath(Settings.minecraftForlderPath);
-
-            var folderPickerOpenOptions = new FolderPickerOpenOptions() 
+            if (Settings.CustomSize != value)
             {
-                AllowMultiple = false,
-                SuggestedStartLocation = await storageProvider.TryGetFolderFromPathAsync(initPath)
-            };
+                if (value && Settings.FullScreen) FullScreen = !value;
+                Settings.CustomSize = value;
 
-            var result = await storageProvider.OpenFolderPickerAsync(folderPickerOpenOptions);
-
-            if (result is null || result.Count != 1 || result.First().Path.AbsolutePath == String.Empty)
-                return;
-
-            MinecraftFolderPath = result.First().Path.AbsolutePath;
-        });
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public void OpenJavaPathDialog(object window)
+    public uint ClientWidth
     {
-        Task.Run(async() =>
+        get => Settings.ClientWidth;
+        set
         {
-            var storageProvider = ((Window)window).StorageProvider;
-            var initPath = String.Empty;
-
-            if (!string.IsNullOrEmpty(Settings.javaPath))
-                initPath = Path.GetFullPath(Settings.javaPath);
-
-            var folderPickerOpenOptions = new FolderPickerOpenOptions()
+            if (Settings.ClientWidth != value)
             {
-                AllowMultiple = false,
-                SuggestedStartLocation = await storageProvider.TryGetFolderFromPathAsync(initPath)
-            };
-
-            var result = await storageProvider.OpenFolderPickerAsync(folderPickerOpenOptions);
-
-            if (result is null || result.Count != 1 || result.First().Path.AbsolutePath == String.Empty)
-                return;
-
-            JavaPath = result.First().Path.AbsolutePath;
-        });
+                Settings.ClientWidth = value;
+                this.RaisePropertyChanged();
+            }
+        }
     }
 
-    public void OpenLogFile()
+    public uint ClientHeight
     {
-        if (Path.Exists(Settings.logFilePath?.Path))
+        get => Settings.ClientHeight;
+        set
         {
-            System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo() { FileName = Settings.logFilePath.Path, UseShellExecute = true });
+            if (Settings.ClientHeight != value)
+            {
+                Settings.ClientHeight = value;
+                this.RaisePropertyChanged();
+            }
         }
     }
+
+    #endregion
 }

+ 32 - 32
VeloeMinecraftLauncher/ViewModels/VersionsDownloaderViewModel.cs

@@ -324,15 +324,15 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
         {
             try
             {
-                if (System.IO.File.Exists(Settings.minecraftForlderPath + $"versions/{value.Id}/revision.json"))
+                if (System.IO.File.Exists(SettingsService.Instance.MinecraftForlderPath + $"versions/{value.Id}/revision.json"))
                 {
-                    if (value.ComplianceLevel > JsonSerializer.Deserialize<int>(System.IO.File.ReadAllText(Settings.minecraftForlderPath + $"versions/{value.Id}/revision.json")))
+                    if (value.ComplianceLevel > JsonSerializer.Deserialize<int>(System.IO.File.ReadAllText(SettingsService.Instance.MinecraftForlderPath + $"versions/{value.Id}/revision.json")))
                         DownloadButtonText = "Update Modpack";
                     else
                         DownloadButtonText = "Reinstall Modpack";
                 }
                 else
-                    if (System.IO.Directory.Exists($"{Settings.minecraftForlderPath}versions/{value.Id}") && System.IO.File.Exists($"{Settings.minecraftForlderPath}versions/{value.Id}/{value.Id}.json"))
+                    if (System.IO.Directory.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{value.Id}") && System.IO.File.Exists($"{SettingsService.Instance.MinecraftForlderPath}versions/{value.Id}/{value.Id}.json"))
                     DownloadButtonText = "Update Modpack";
                 else
                     DownloadButtonText = "Download Modpack";
@@ -344,7 +344,7 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
         }
         else
         {
-            if (System.IO.File.Exists(Settings.minecraftForlderPath + $"versions/{value.Id}/{value.Id}.json"))
+            if (System.IO.File.Exists(SettingsService.Instance.MinecraftForlderPath + $"versions/{value.Id}/{value.Id}.json"))
                 DownloadButtonText = "Reinstall";
             else
                 DownloadButtonText = "Download";
@@ -506,7 +506,7 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
 
                 if (version.InheritsFrom is null)
                 {
-                    dirInfo = new DirectoryInfo(Settings.minecraftForlderPath);
+                    dirInfo = new DirectoryInfo(SettingsService.Instance.MinecraftForlderPath);
                     sizeTreeNode.SubNode.AddRange(
                         DirectoryToTreeNode(
                             dirInfo,
@@ -535,8 +535,8 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
 
                 dirInfo = null;
 
-                if (version.InheritsFrom is null && Directory.Exists(Settings.minecraftForlderPath + "saves"))
-                    dirInfo = new DirectoryInfo(Settings.minecraftForlderPath + "saves");
+                if (version.InheritsFrom is null && Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "saves"))
+                    dirInfo = new DirectoryInfo(SettingsService.Instance.MinecraftForlderPath + "saves");
                 else
                     if (Directory.Exists(versionDir + "/saves"))
                     dirInfo = new DirectoryInfo(versionDir + "/saves");
@@ -584,8 +584,8 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
 
                 dirInfo = null;
 
-                if (version.InheritsFrom is null && Directory.Exists(Settings.minecraftForlderPath + "resourcepacks"))
-                    dirInfo = new DirectoryInfo(Settings.minecraftForlderPath + "resourcepacks");
+                if (version.InheritsFrom is null && Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "resourcepacks"))
+                    dirInfo = new DirectoryInfo(SettingsService.Instance.MinecraftForlderPath + "resourcepacks");
                 else
                     if (Directory.Exists(versionDir + "/resourcepacks"))
                     dirInfo = new DirectoryInfo(versionDir + "/resourcepacks");
@@ -614,9 +614,9 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
                     assetsFolderName = outVersion.Assets;
                 }
 
-                if (Directory.Exists(Settings.minecraftForlderPath + "assets/" + assetsFolderName))
+                if (Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "assets/" + assetsFolderName))
                 {
-                    dirInfo = new DirectoryInfo(Settings.minecraftForlderPath + "assets/" + assetsFolderName);
+                    dirInfo = new DirectoryInfo(SettingsService.Instance.MinecraftForlderPath + "assets/" + assetsFolderName);
                     allSize = 0;
                     foreach (var file in dirInfo.EnumerateFiles("*", SearchOption.AllDirectories))
                     { allSize += file.Length; }
@@ -658,12 +658,12 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
                 usedLibraries =
                     usedLibraries
                         .Where(l =>
-                            File.Exists(Path.Combine(Settings.minecraftForlderPath + "libraries/" + l.Downloads?.Artifact?.Path)) ||
-                            File.Exists(Path.Combine(Settings.minecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesLinux?.Path)) ||
-                            File.Exists(Path.Combine(Settings.minecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesWindows?.Path)) ||
-                            File.Exists(Path.Combine(Settings.minecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesWindows64?.Path)) ||
-                            File.Exists(Path.Combine(Settings.minecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesWindows32?.Path)) ||
-                            File.Exists(Path.Combine(Settings.minecraftForlderPath + "libraries/" + StartCommandBuilder.GetLibPathFromName(l.Name)))
+                            File.Exists(Path.Combine(SettingsService.Instance.MinecraftForlderPath + "libraries/" + l.Downloads?.Artifact?.Path)) ||
+                            File.Exists(Path.Combine(SettingsService.Instance.MinecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesLinux?.Path)) ||
+                            File.Exists(Path.Combine(SettingsService.Instance.MinecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesWindows?.Path)) ||
+                            File.Exists(Path.Combine(SettingsService.Instance.MinecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesWindows64?.Path)) ||
+                            File.Exists(Path.Combine(SettingsService.Instance.MinecraftForlderPath + "libraries/" + l.Downloads?.Classifiers?.NativesWindows32?.Path)) ||
+                            File.Exists(Path.Combine(SettingsService.Instance.MinecraftForlderPath + "libraries/" + StartCommandBuilder.GetLibPathFromName(l.Name)))
                         )
                         .ToList();
 
@@ -693,7 +693,7 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
                     {
                         subLibTreeNode.Tag = lib.LibraryUniqueInstances.Where(l => l.Downloads?.Artifact?.Path is not null).Select(l => l.Downloads?.Artifact?.Path).FirstOrDefault() ?? string.Empty;
                         //if fabric library
-                        if (File.Exists(Settings.minecraftForlderPath + "libraries/" + StartCommandBuilder.GetLibPathFromName(lib.Name)))
+                        if (File.Exists(SettingsService.Instance.MinecraftForlderPath + "libraries/" + StartCommandBuilder.GetLibPathFromName(lib.Name)))
                             subLibTreeNode.Tag = StartCommandBuilder.GetLibPathFromName(lib.Name);
                     }
 
@@ -821,14 +821,14 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
                     //if vanilla
                     Debug.WriteLine("Vanilla root directories deleted!");
                     
-                    if (Directory.Exists(Settings.minecraftForlderPath + "saves"))
-                        Directory.Delete(Settings.minecraftForlderPath + "saves", true);
+                    if (Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "saves"))
+                        Directory.Delete(SettingsService.Instance.MinecraftForlderPath + "saves", true);
 
-                    if (Directory.Exists(Settings.minecraftForlderPath + "resourcepacks"))
-                        Directory.Delete(Settings.minecraftForlderPath + "resourcepacks", true);
+                    if (Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "resourcepacks"))
+                        Directory.Delete(SettingsService.Instance.MinecraftForlderPath + "resourcepacks", true);
 
-                    if (Directory.Exists(Settings.minecraftForlderPath + "shaderpacks"))
-                        Directory.Delete(Settings.minecraftForlderPath + "shaderpacks", true);
+                    if (Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "shaderpacks"))
+                        Directory.Delete(SettingsService.Instance.MinecraftForlderPath + "shaderpacks", true);
                 }
 
                 //calc assets
@@ -843,7 +843,7 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
                     assetsFolderName = outVersion.Assets;
                 }
 
-                if (Directory.Exists(Settings.minecraftForlderPath + "assets/" + assetsFolderName))
+                if (Directory.Exists(SettingsService.Instance.MinecraftForlderPath + "assets/" + assetsFolderName))
                 {
                     var usedByVersionCount = 0;
 
@@ -862,8 +862,8 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
                     //delete assets if only deleting version used it
                     if (usedByVersionCount == 1)
                     {
-                        Debug.WriteLine(Settings.minecraftForlderPath + "assets/" + assetsFolderName);
-                        Directory.Delete(Settings.minecraftForlderPath + "assets/" + assetsFolderName,true);
+                        Debug.WriteLine(SettingsService.Instance.MinecraftForlderPath + "assets/" + assetsFolderName);
+                        Directory.Delete(SettingsService.Instance.MinecraftForlderPath + "assets/" + assetsFolderName,true);
                     }
                 }
 
@@ -943,7 +943,7 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
         
         if (!string.IsNullOrEmpty(library.Tag))
         {
-            var libFileInfo = new FileInfo(Settings.minecraftForlderPath + "libraries/" + library.Tag);
+            var libFileInfo = new FileInfo(SettingsService.Instance.MinecraftForlderPath + "libraries/" + library.Tag);
             var libDir = libFileInfo.Directory;
 
             if(libDir?.Exists == false)
@@ -994,7 +994,7 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
             DownloadedVersions = new();
         }
 
-        DirectoryInfo versions = new(Settings.minecraftForlderPath + "versions");
+        DirectoryInfo versions = new(SettingsService.Instance.MinecraftForlderPath + "versions");
         try
         {
             var dirs = versions.GetDirectories("*", SearchOption.TopDirectoryOnly);
@@ -1017,7 +1017,7 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
         }
         catch (DirectoryNotFoundException)
         {
-            Directory.CreateDirectory(Settings.minecraftForlderPath + "versions");
+            Directory.CreateDirectory(SettingsService.Instance.MinecraftForlderPath + "versions");
             return;
         }
 
@@ -1025,8 +1025,8 @@ public class VersionsDownloaderViewModel : ViewModelBase, IDisposable
 
     public void OnOpenForlder()
     {       
-        if (DownloadedVersion?.Version is not null && Path.Exists(Settings.minecraftForlderPath + "versions/" + DownloadedVersion.Version))
-            Process.Start(new System.Diagnostics.ProcessStartInfo() { FileName = Settings.minecraftForlderPath + "versions/" + DownloadedVersion.Version, UseShellExecute = true });   
+        if (DownloadedVersion?.Version is not null && Path.Exists(SettingsService.Instance.MinecraftForlderPath + "versions/" + DownloadedVersion.Version))
+            Process.Start(new System.Diagnostics.ProcessStartInfo() { FileName = SettingsService.Instance.MinecraftForlderPath + "versions/" + DownloadedVersion.Version, UseShellExecute = true });   
     }
 
     public void OnClosing(object sender, CancelEventArgs args)

+ 23 - 8
VeloeMinecraftLauncher/Views/SettingsWindow.axaml

@@ -54,7 +54,7 @@
 					<Grid 
 						Margin="10 0 10 5" 
 						ShowGridLines="false" 
-						RowDefinitions="Auto, Auto, Auto, Auto, Auto, Auto, Auto">
+						RowDefinitions="Auto, Auto, Auto, Auto, Auto, Auto, Auto, Auto">
 						<Grid.ColumnDefinitions>
 							<ColumnDefinition Width="250"></ColumnDefinition>
 							<ColumnDefinition Width="*"></ColumnDefinition>
@@ -89,8 +89,8 @@
 						<TextBox 
 							Grid.Row="2" Grid.Column="1" 
 							Margin="5" 
-							Text="{Binding JavaPath}" 
-							IsEnabled="{Binding UseCustomJava}"/>
+							Text="{Binding JavaPath, Mode=TwoWay}"
+							IsEnabled="{Binding UseCustomJava}" />
 						<Button 
 							Grid.Row="2" Grid.Column="2" 
 							Content="Open" 
@@ -181,6 +181,12 @@
 							IsEnabled="True">
 							Check vanilla game files before start
 						</CheckBox>
+						<CheckBox
+							Grid.Row="7" Grid.ColumnSpan="2"
+							IsChecked="{Binding HideLauncher}"
+							IsEnabled="True">
+							Hide launcher on game start
+						</CheckBox>
 					</Grid>
 				</TabItem>
 				<TabItem
@@ -260,13 +266,22 @@
 				HorizontalAlignment="Left"
 				VerticalAlignment="Bottom"
 				Margin="10 0 0 10"/>
-			<Button 
-				Command="{Binding SaveSettings}" 
-				IsEnabled="{Binding IsValid}" 
-				Content="Save" 
+			<StackPanel
+				Orientation="Horizontal"
 				HorizontalAlignment="Right"
 				VerticalAlignment="Bottom" 
-				Margin="0 0 10 10"/>	
+				Margin="0 0 10 10">
+				<Button 
+					Content="Save"
+					Command="{Binding SaveSettings}" 
+					IsEnabled="{Binding IsValid}"
+					Margin="0 0 10 0"/>
+				<Button
+					Content="Save &amp; close"
+					Command="{Binding SaveSettingsAndClose}"
+					CommandParameter="{Binding $parent[Window]}"
+					IsEnabled="{Binding IsValid}"/>
+			</StackPanel>
 		</DockPanel>
 	</Panel>
 </Window>