From 41536e44cb56687100ac120d3bfb19aabb367b4a Mon Sep 17 00:00:00 2001 From: ElaXan Date: Sun, 28 Jul 2024 13:28:04 +0700 Subject: [PATCH 1/7] refactor: Improve code structure and readability - Refactor Config, Profile, and GameType classes for better encapsulation - Update API calls to use more robust error handling and logging - Improve exception handling throughout the codebase feat: Enhance update process and UI - Implement a more robust update checking and installation process - Add a new MD5 hash display dialog with improved UI - Update the main form layout for better user experience style: Update UI elements and improve visual consistency - Modify button styles and colors for a more modern look - Adjust form layouts and control positioning - Update font sizes and styles for better readability fix: Address various bugs and improve error handling - Fix issues with proxy startup and shutdown - Improve error messages and logging for better diagnostics - Resolve issues with game patching and version checking perf: Optimize file operations and API calls - Improve file reading and writing operations - Optimize API calls to reduce unnecessary requests - Enhance performance of MD5 calculation and checking docs: Update comments and improve code documentation - Add more descriptive comments to complex methods - Improve method and property documentation --- Download.Designer.cs | 53 ++- Download.cs | 66 +++- Game/Genshin/Patch/HexUtility.cs | 90 +++-- Game/Genshin/Patch/Metadata.cs | 13 +- Game/Genshin/Patch/Methods.cs | 2 +- Game/Genshin/Patch/UserAssembly.cs | 12 +- Game/Genshin/ServerRegionID.cs | 24 +- Game/Genshin/Settings.cs | 6 +- Json/Config.cs | 25 +- Json/GameClient/Client.cs | 159 ++++---- Json/GameClient/Patch.cs | 41 ++- Json/GameType.cs | 67 ++-- Json/Mod/Cheat.cs | 43 ++- Json/Nightly.cs | 54 +-- Json/Profile.cs | 4 +- Json/Update.cs | 93 +---- Main.Designer.cs | 416 ++++++++++++--------- Main.cs | 570 +++++++++++++++++------------ Main.resx | 6 +- Utils/Logger.cs | 4 +- Yuuki/API.cs | 60 +-- Yuuki/Proxy.cs | 20 +- Yuuki/Server.cs | 22 +- Yuuki/Tool.cs | 42 +-- YuukiPS Launcher.csproj | 4 +- 25 files changed, 1053 insertions(+), 843 deletions(-) diff --git a/Download.Designer.cs b/Download.Designer.cs index a835dcd..2b28362 100644 --- a/Download.Designer.cs +++ b/Download.Designer.cs @@ -38,24 +38,27 @@ private void InitializeComponent() // // DLBar // - this.DLBar.Location = new System.Drawing.Point(12, 12); + this.DLBar.Location = new System.Drawing.Point(20, 70); this.DLBar.Name = "DLBar"; - this.DLBar.Size = new System.Drawing.Size(532, 28); + this.DLBar.Size = new System.Drawing.Size(460, 8); + this.DLBar.Style = System.Windows.Forms.ProgressBarStyle.Continuous; this.DLBar.TabIndex = 0; // // label1 // this.label1.AutoSize = true; - this.label1.Location = new System.Drawing.Point(12, 43); + this.label1.Font = new System.Drawing.Font("Segoe UI", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.label1.Location = new System.Drawing.Point(20, 20); this.label1.Name = "label1"; - this.label1.Size = new System.Drawing.Size(67, 15); + this.label1.Size = new System.Drawing.Size(200, 25); this.label1.TabIndex = 1; - this.label1.Text = "Download: "; + this.label1.Text = "Updating YuukiPS..."; // // GetNameDownload // this.GetNameDownload.AutoSize = true; - this.GetNameDownload.Location = new System.Drawing.Point(75, 43); + this.GetNameDownload.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.GetNameDownload.Location = new System.Drawing.Point(20, 50); this.GetNameDownload.Name = "GetNameDownload"; this.GetNameDownload.Size = new System.Drawing.Size(19, 15); this.GetNameDownload.TabIndex = 2; @@ -64,47 +67,59 @@ private void InitializeComponent() // GetNumDownload // this.GetNumDownload.AutoSize = true; - this.GetNumDownload.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); - this.GetNumDownload.Location = new System.Drawing.Point(12, 87); + this.GetNumDownload.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.GetNumDownload.Location = new System.Drawing.Point(20, 85); this.GetNumDownload.Name = "GetNumDownload"; - this.GetNumDownload.Size = new System.Drawing.Size(16, 20); + this.GetNumDownload.Size = new System.Drawing.Size(16, 15); this.GetNumDownload.TabIndex = 3; this.GetNumDownload.Text = "?"; // // btDownload // - this.btDownload.Location = new System.Drawing.Point(12, 61); + this.btDownload.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(0)))), ((int)(((byte)(122)))), ((int)(((byte)(204))))); + this.btDownload.FlatAppearance.BorderSize = 0; + this.btDownload.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btDownload.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.btDownload.ForeColor = System.Drawing.Color.White; + this.btDownload.Location = new System.Drawing.Point(320, 110); this.btDownload.Name = "btDownload"; - this.btDownload.Size = new System.Drawing.Size(75, 23); + this.btDownload.Size = new System.Drawing.Size(75, 30); this.btDownload.TabIndex = 4; this.btDownload.Text = "Start"; - this.btDownload.UseVisualStyleBackColor = true; + this.btDownload.UseVisualStyleBackColor = false; this.btDownload.Click += new System.EventHandler(this.btDownload_Click); // // btCancel // - this.btCancel.Location = new System.Drawing.Point(93, 61); + this.btCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(231)))), ((int)(((byte)(76)))), ((int)(((byte)(60))))); + this.btCancel.FlatAppearance.BorderSize = 0; + this.btCancel.FlatStyle = System.Windows.Forms.FlatStyle.Flat; + this.btCancel.Font = new System.Drawing.Font("Segoe UI", 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point); + this.btCancel.ForeColor = System.Drawing.Color.White; + this.btCancel.Location = new System.Drawing.Point(405, 110); this.btCancel.Name = "btCancel"; - this.btCancel.Size = new System.Drawing.Size(75, 23); + this.btCancel.Size = new System.Drawing.Size(75, 30); this.btCancel.TabIndex = 5; this.btCancel.Text = "Cancel"; - this.btCancel.UseVisualStyleBackColor = true; - this.btCancel.Click += new System.EventHandler(this.btCancel_Click); + this.btCancel.UseVisualStyleBackColor = false; + this.btCancel.Click += new System.EventHandler(this.BTCancel_Click); // // Download // this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(556, 111); + this.BackColor = System.Drawing.Color.White; + this.ClientSize = new System.Drawing.Size(500, 160); this.Controls.Add(this.btCancel); this.Controls.Add(this.btDownload); this.Controls.Add(this.GetNumDownload); this.Controls.Add(this.GetNameDownload); this.Controls.Add(this.label1); this.Controls.Add(this.DLBar); - this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Name = "Download"; - this.Text = "Download"; + this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; + this.Text = "YuukiPS Updater"; this.Load += new System.EventHandler(this.Download_Load); this.ResumeLayout(false); this.PerformLayout(); diff --git a/Download.cs b/Download.cs index 9c6efe4..8d3c98b 100644 --- a/Download.cs +++ b/Download.cs @@ -7,41 +7,43 @@ namespace YuukiPS_Launcher { public partial class Download : Form { - private string set_download = ""; - private string set_folder = ""; + private readonly string SetDownload = ""; + private readonly string SetFolder = ""; private DownloadService? dl = null; public Download(string url_download = "", string folder_download = "") { - set_download = url_download; - set_folder = folder_download; + SetDownload = url_download; + SetFolder = folder_download; InitializeComponent(); } private void btDownload_Click(object sender, EventArgs e) { - if (string.IsNullOrEmpty(set_download)) + if (string.IsNullOrEmpty(SetDownload)) { - MessageBox.Show("Download failed because no url was found"); + Logger.Error("Download", "Download failed: No URL provided"); + MessageBox.Show("Download failed because no URL was found.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - if (Directory.Exists(set_folder)) + if (!Directory.Exists(Path.GetDirectoryName(SetFolder))) { - MessageBox.Show("Can't save file because folder can't be found or can't be accessed"); + Logger.Error("Download", $"Download failed: Folder not found or inaccessible - {SetFolder}"); + MessageBox.Show("Can't save file because the destination folder can't be found or accessed.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } - if (File.Exists(set_folder)) + if (File.Exists(SetFolder)) { - Logger.Info("Download", $"File old found {set_folder} remove for redownload?"); - File.Delete(set_folder); + Logger.Info("Download", $"File old found {SetFolder} remove for redownload?"); + File.Delete(SetFolder); } btDownload.Enabled = false; - GetNameDownload.Text = set_download; + GetNameDownload.Text = SetDownload; if (dl == null) { @@ -58,7 +60,7 @@ private void btDownload_Click(object sender, EventArgs e) dl.ChunkDownloadProgressChanged += Dl_ChunkDownloadProgressChanged; try { - dl.DownloadFileTaskAsync(set_download, set_folder); + dl.DownloadFileTaskAsync(SetDownload, SetFolder); } catch (Exception ek) { @@ -74,11 +76,11 @@ private void btDownload_Click(object sender, EventArgs e) private void Dl_DownloadFileCompleted(object? sender, AsyncCompletedEventArgs e) { - btDownload.Invoke((Action)delegate + btDownload.Invoke(delegate { btDownload.Enabled = true; }); - GetNumDownload.Invoke((Action)delegate + GetNumDownload.Invoke(delegate { GetNumDownload.Text = "Done"; }); @@ -92,6 +94,7 @@ private void Dl_ChunkDownloadProgressChanged(object? sender, DownloadProgressCha private void Dl_DownloadProgressChanged(object? sender, DownloadProgressChangedEventArgs e) { + if (dl == null || dl.IsCancelled) return; double nonZeroSpeed = e.BytesPerSecondSpeed + 0.0001; int estimateTime = (int)((e.TotalBytesToReceive - e.ReceivedBytesSize) / nonZeroSpeed); bool isMinutes = estimateTime >= 60; @@ -127,15 +130,40 @@ private void Dl_DownloadProgressChanged(object? sender, DownloadProgressChangedE private void Dl_DownloadStarted(object? sender, DownloadStartedEventArgs e) { - Console.WriteLine("Start Download: " + set_download); + Logger.Info("Download", $"Starting download - URL: {SetDownload}, Destination: {SetFolder}"); } - private void btCancel_Click(object sender, EventArgs e) + private async void BTCancel_Click(object sender, EventArgs e) { if (dl != null) { - dl.CancelAsync(); - dl.Dispose(); + // dl.CancelAsync(); + // dl.Dispose(); + try + { + btCancel.Enabled = false; + btDownload.Enabled = false; + GetNumDownload.Text = "Canceling..."; + + dl.CancelAsync(); + await Task.Delay(1000); // give some time to cancel + + dl.Dispose(); + dl = null; + + GetNumDownload.Text = "Canceled"; + DLBar.Value = 0; + } + catch (Exception ex) + { + Logger.Error("Download", $"Error during canceling download: {ex.Message}"); + MessageBox.Show($"Error during canceling download: {ex.Message}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + finally + { + btCancel.Enabled = true; + btDownload.Enabled = true; + } } DialogResult = DialogResult.Cancel; } diff --git a/Game/Genshin/Patch/HexUtility.cs b/Game/Genshin/Patch/HexUtility.cs index f368700..91b6171 100644 --- a/Game/Genshin/Patch/HexUtility.cs +++ b/Game/Genshin/Patch/HexUtility.cs @@ -1,62 +1,72 @@ -public class HexUtility + +namespace YuukiPS_Launcher.Game.Genshin.Patch { - public static bool EqualsBytes(byte[] b1, params byte[] b2) + public class HexUtility { - if (b1.Length != b2.Length) - return false; - for (int i = 0; i < b1.Length; i++) + public static bool EqualsBytes(byte[] b1, params byte[] b2) { - if (b1[i] != b2[i]) + if (b1.Length != b2.Length) return false; - } - return true; - } - - public static byte[] Replace(byte[] sourceByteArray, List replaces) - { - byte[] newByteArray = new byte[sourceByteArray.Length]; - Buffer.BlockCopy(sourceByteArray, 0, newByteArray, 0, sourceByteArray.Length); - int offset = 0; - foreach (HexReplaceEntity rep in replaces) - { - if (EqualsBytes(rep.oldValue, rep.newValue)) + for (int i = 0; i < b1.Length; i++) { - continue; + if (b1[i] != b2[i]) + return false; } + return true; + } - for (; offset < sourceByteArray.Length; offset++) + public static byte[] Replace(byte[] sourceByteArray, List replaces) + { + byte[] newByteArray = new byte[sourceByteArray.Length]; + Buffer.BlockCopy(sourceByteArray, 0, newByteArray, 0, sourceByteArray.Length); + int offset = 0; + foreach (HexReplaceEntity rep in replaces) { - if (sourceByteArray[offset] == rep.oldValue[0]) + if (EqualsBytes(rep.OldValue, rep.NewValue)) { - if (sourceByteArray.Length - offset < rep.oldValue.Length) - break; + continue; + } - bool find = true; - for (int i = 1; i < rep.oldValue.Length - 1; i++) + for (; offset < sourceByteArray.Length; offset++) + { + if (sourceByteArray[offset] == rep.OldValue[0]) { - if (sourceByteArray[offset + i] != rep.oldValue[i]) + if (sourceByteArray.Length - offset < rep.OldValue.Length) + break; + + bool find = true; + for (int i = 1; i < rep.OldValue.Length - 1; i++) { - find = false; + if (sourceByteArray[offset + i] != rep.OldValue[i]) + { + find = false; + break; + } + } + if (find) + { + Buffer.BlockCopy(rep.NewValue, 0, newByteArray, offset, rep.NewValue.Length); + offset += (rep.NewValue.Length - 1); break; } } - if (find) - { - Buffer.BlockCopy(rep.newValue, 0, newByteArray, offset, rep.newValue.Length); - offset += (rep.newValue.Length - 1); - break; - } } } + return newByteArray; } - return newByteArray; } -} -public class HexReplaceEntity -{ - public byte[] oldValue { get; set; } + public class HexReplaceEntity + { + public byte[] OldValue { get; set; } = null!; + public byte[] NewValue { get; set; } = null!; - public byte[] newValue { get; set; } + public HexReplaceEntity() { } -} \ No newline at end of file + public HexReplaceEntity(byte[] oldValue, byte[] newValue) + { + OldValue = oldValue; + NewValue = newValue; + } + } +} diff --git a/Game/Genshin/Patch/Metadata.cs b/Game/Genshin/Patch/Metadata.cs index 0f98e29..4cdae9e 100644 --- a/Game/Genshin/Patch/Metadata.cs +++ b/Game/Genshin/Patch/Metadata.cs @@ -1,11 +1,10 @@ using System.Text; -using YuukiPS_Launcher.patch; namespace YuukiPS_Launcher.Game.Genshin.Patch { public static class Metadata { - public static byte[] bytes = { 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; + public static readonly byte[] bytes = { 0x0D, 0x0A, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }; public static string Do(string original_file, string patch_file, string key1nopatch, string key1patch, string key2nopatch, string key2patch) { @@ -14,7 +13,7 @@ public static string Do(string original_file, string patch_file, string key1nopa return "Metadata file not found"; } byte[] filebytes = File.ReadAllBytes(original_file); - byte[] data = decrypt(filebytes); + byte[] data = Decrypt(filebytes); Array.Resize(ref data, data.Length - 16384); @@ -32,7 +31,7 @@ public static string Do(string original_file, string patch_file, string key1nopa if (count != 0) { Array.Resize(ref data, data.Length + 16384); - filebytes = encrypt(data); + filebytes = Encrypt(data); str = ""; FileStream stream = File.Create(patch_file); @@ -54,7 +53,7 @@ public static string Decrypt(string original_file, string patch_file) return "Metadata file not found"; } byte[] filebytes = File.ReadAllBytes(original_file); - byte[] data = decrypt(filebytes); + byte[] data = Decrypt(filebytes); Array.Resize(ref data, data.Length - 16384); FileStream stream = File.Create(patch_file); stream.Write(data, 0, data.Length); @@ -75,7 +74,7 @@ public static byte[] ToFixBytesP1(string key) } - unsafe static public byte[] decrypt(byte[] bytes) + unsafe static public byte[] Decrypt(byte[] bytes) { fixed (byte* d1 = bytes) { @@ -84,7 +83,7 @@ unsafe static public byte[] decrypt(byte[] bytes) return bytes; } } - unsafe static public byte[] encrypt(byte[] bytes) + unsafe static public byte[] Encrypt(byte[] bytes) { fixed (byte* d1 = bytes) { diff --git a/Game/Genshin/Patch/Methods.cs b/Game/Genshin/Patch/Methods.cs index 6c8bed3..35bb5cb 100644 --- a/Game/Genshin/Patch/Methods.cs +++ b/Game/Genshin/Patch/Methods.cs @@ -1,6 +1,6 @@ using System.Diagnostics; -namespace YuukiPS_Launcher.patch +namespace YuukiPS_Launcher.Game.Genshin.Patch { public static class Methods { diff --git a/Game/Genshin/Patch/UserAssembly.cs b/Game/Genshin/Patch/UserAssembly.cs index 4211740..1796f77 100644 --- a/Game/Genshin/Patch/UserAssembly.cs +++ b/Game/Genshin/Patch/UserAssembly.cs @@ -27,20 +27,18 @@ public static string Do(string original_file, string patch_file, string keynopat int Offset = 0; int DataLength; - List UA_list = new List(); + List UA_list = new(); while ((DataLength = UA_Original.Length - Offset) > 0) { if (DataLength > 8) DataLength = 8; - HexReplaceEntity hexReplaceEntity = new HexReplaceEntity(); + HexReplaceEntity hexReplaceEntity = new(); + Buffer.BlockCopy(UA_Original, Offset, hexReplaceEntity.OldValue, 0, DataLength); - hexReplaceEntity.oldValue = new byte[8]; - Buffer.BlockCopy(UA_Original, Offset, hexReplaceEntity.oldValue, 0, DataLength); - - hexReplaceEntity.newValue = new byte[8]; - Buffer.BlockCopy(UA_key, Offset, hexReplaceEntity.newValue, 0, DataLength); + hexReplaceEntity.NewValue = new byte[8]; + Buffer.BlockCopy(UA_key, Offset, hexReplaceEntity.NewValue, 0, DataLength); UA_list.Add(hexReplaceEntity); Offset += DataLength; diff --git a/Game/Genshin/ServerRegionID.cs b/Game/Genshin/ServerRegionID.cs index 1d393a4..6ed1a6d 100644 --- a/Game/Genshin/ServerRegionID.cs +++ b/Game/Genshin/ServerRegionID.cs @@ -3,23 +3,27 @@ using System; using static YuukiPS_Launcher.Game.Genshin.Settings; -public class ServerRegionIDConverter : StringEnumConverter +namespace YuukiPS_Launcher.Game.Genshin { - public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) + public class ServerRegionIDConverter : StringEnumConverter { - if (reader.TokenType == JsonToken.String) + public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { - string enumText = reader.Value.ToString(); - foreach (ServerRegionID enumValue in Enum.GetValues(typeof(ServerRegionID))) + if (reader.TokenType == JsonToken.String) { - if (enumValue.ToString().Equals(enumText, StringComparison.OrdinalIgnoreCase)) + string? enumText = reader.Value?.ToString(); + foreach (ServerRegionID enumValue in Enum.GetValues(typeof(ServerRegionID))) { - return enumValue; + if (enumValue.ToString().Equals(enumText, StringComparison.OrdinalIgnoreCase)) + { + return enumValue; + } } + // Handle unknown value here + return ServerRegionID.os_usa; // Default value } - // Handle unknown value here - return ServerRegionID.os_usa; // Default value + return base.ReadJson(reader, objectType, existingValue, serializer); } - return base.ReadJson(reader, objectType, existingValue, serializer); } } + diff --git a/Game/Genshin/Settings.cs b/Game/Genshin/Settings.cs index 1e0a08c..c43cefe 100644 --- a/Game/Genshin/Settings.cs +++ b/Game/Genshin/Settings.cs @@ -8,10 +8,10 @@ namespace YuukiPS_Launcher.Game.Genshin public class Settings { // Source Code: https://github.com/neon-nyan/CollapseLauncher - private static string OsPathKey = @"Software\miHoYo\Genshin Impact"; - private static string CnPathKey = @"Software\miHoYo\原神"; + private static readonly string OsPathKey = @"Software\miHoYo\Genshin Impact"; + private static readonly string CnPathKey = @"Software\miHoYo\原神"; - private int ch = 1; + private readonly int ch = 1; public Settings(int ch) { diff --git a/Json/Config.cs b/Json/Config.cs index b5c2060..634e504 100644 --- a/Json/Config.cs +++ b/Json/Config.cs @@ -1,27 +1,28 @@ using Newtonsoft.Json; +using YuukiPS_Launcher.Utils; namespace YuukiPS_Launcher.Json { public class Config { // Folder - public static string CurrentlyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""); - public static string DataConfig = Path.Combine(CurrentlyPath, "data"); - public static string Modfolder = Path.Combine(CurrentlyPath, "mod"); + public static string CurrentlyPath { get; } = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ""); + public static string DataConfig { get; } = Path.Combine(CurrentlyPath, "data"); + public static string Modfolder { get; } = Path.Combine(CurrentlyPath, "mod"); // File Config - public static string ConfigPath = Path.Combine(DataConfig, "config.json"); + public static string ConfigPath { get; } = Path.Combine(DataConfig, "config.json"); public string profile_default = "Default"; - public List profile { get; set; } = new List(); + public List Profile { get; set; } = new List(); public static Config LoadConfig(string load_file = "") { // Create missing folder - Directory.CreateDirectory(Config.DataConfig); - Directory.CreateDirectory(Config.Modfolder); + Directory.CreateDirectory(DataConfig); + Directory.CreateDirectory(Modfolder); - Config config = new Config(); + Config config = new(); if (string.IsNullOrEmpty(load_file)) { @@ -41,17 +42,17 @@ public static Config LoadConfig(string load_file = "") } catch (Exception ex) { - Console.WriteLine("Error load config: " + ex.Message + ", so make new profile"); + Logger.Error("Config", "Error load config: " + ex.Message); } } else { - Console.WriteLine("No config file found, so make new profile"); + Logger.Warning("Config", "No config file found. Creating a new default profile."); } - if (config.profile.Count == 0) + if (config.Profile.Count == 0) { - config.profile.Add(new Profile() { name = "Default" }); + config.Profile.Add(new Profile() { name = "Default" }); } return config; diff --git a/Json/GameClient/Client.cs b/Json/GameClient/Client.cs index 7f372a2..c9410f4 100644 --- a/Json/GameClient/Client.cs +++ b/Json/GameClient/Client.cs @@ -1,91 +1,92 @@ namespace YuukiPS_Launcher.Json.GameClient { - public class Data - { - public Game game { get; set; } - public Plugin plugin { get; set; } - public string web_url { get; set; } - public object force_update { get; set; } - public object pre_download_game { get; set; } - public List deprecated_packages { get; set; } - public object sdk { get; set; } - public List deprecated_files { get; set; } - } + // Commented out code because it's not used by any part of the codebase. It would be better to remove this file entirely. + //public class Data + //{ + // public required Game game { get; set; } + // public required Plugin plugin { get; set; } + // public required string web_url { get; set; } + // public required object force_update { get; set; } + // public required object pre_download_game { get; set; } + // public required List deprecated_packages { get; set; } + // public required object sdk { get; set; } + // public required List deprecated_files { get; set; } + //} - public class DeprecatedFile - { - public string name { get; set; } - public string md5 { get; set; } - } + //public class DeprecatedFile + //{ + // public required string name { get; set; } + // public required string md5 { get; set; } + //} - public class DeprecatedPackage - { - public string name { get; set; } - public string md5 { get; set; } - } + //public class DeprecatedPackage + //{ + // public required string name { get; set; } + // public required string md5 { get; set; } + //} - public class Diff - { - public string name { get; set; } - public string version { get; set; } = "0.0.0"; - public string path { get; set; } - public string size { get; set; } - public string md5 { get; set; } - public bool is_recommended_update { get; set; } - public List voice_packs { get; set; } - public string package_size { get; set; } - } + //public class Diff + //{ + // public required string name { get; set; } + // public string version { get; set; } = "0.0.0"; + // public required string path { get; set; } + // public required string size { get; set; } + // public required string md5 { get; set; } + // public required bool is_recommended_update { get; set; } + // public required List voice_packs { get; set; } + // public required string package_size { get; set; } + //} - public class Game - { - public Latest latest { get; set; } - public List diffs { get; set; } - } + //public class Game + //{ + // public required Latest latest { get; set; } + // public required List diffs { get; set; } + //} - public class Latest - { - public string name { get; set; } - public string version { get; set; } - public string path { get; set; } - public string size { get; set; } - public string md5 { get; set; } - public string entry { get; set; } - public List voice_packs { get; set; } - public string decompressed_path { get; set; } - public List segments { get; set; } - public string package_size { get; set; } - } + //public class Latest + //{ + // public required string name { get; set; } + // public required string version { get; set; } + // public required string path { get; set; } + // public required string size { get; set; } + // public required string md5 { get; set; } + // public required string entry { get; set; } + // public required List voice_packs { get; set; } + // public required string decompressed_path { get; set; } + // public required List segments { get; set; } + // public required string package_size { get; set; } + //} - public class Plugin - { - public List plugins { get; set; } - public string version { get; set; } - } + //public class Plugin + //{ + // public required List plugins { get; set; } + // public required string version { get; set; } + //} - public class Plugin2 - { - public string name { get; set; } - public string version { get; set; } - public string path { get; set; } - public string size { get; set; } - public string md5 { get; set; } - public string entry { get; set; } - } + //public class Plugin2 + //{ + // public required string name { get; set; } + // public required string version { get; set; } + // public required string path { get; set; } + // public required string size { get; set; } + // public required string md5 { get; set; } + // public required string entry { get; set; } + //} - public class Client - { - public int retcode { get; set; } - public string message { get; set; } - public Data data { get; set; } - } + //public class Client + //{ + // public required int retcode { get; set; } + // public required string message { get; set; } + // public required Data data { get; set; } + //} - public class VoicePack - { - public string language { get; set; } - public string name { get; set; } - public string path { get; set; } - public string size { get; set; } - public string md5 { get; set; } - public string package_size { get; set; } - } + //public class VoicePack + //{ + // public required string language { get; set; } + // public required string name { get; set; } + // public required string path { get; set; } + // public required string size { get; set; } + // public required string md5 { get; set; } + // public required string package_size { get; set; } + //} } diff --git a/Json/GameClient/Patch.cs b/Json/GameClient/Patch.cs index 40516c4..a67ac95 100644 --- a/Json/GameClient/Patch.cs +++ b/Json/GameClient/Patch.cs @@ -1,27 +1,40 @@ -namespace YuukiPS_Launcher.Json.GameClient +using System.Text.Json.Serialization; + +namespace YuukiPS_Launcher.Json.GameClient { public class Original { - public string file { get; set; } - public string location { get; set; } - public string md5 { get; set; } + [JsonPropertyName("file")] + public required string File { get; set; } + [JsonPropertyName("location")] + public required string Location { get; set; } + [JsonPropertyName("md5")] + public required string MD5 { get; set; } } public class Patched { - public string file { get; set; } - public string location { get; set; } - public string md5 { get; set; } + [JsonPropertyName("file")] + public required string File { get; set; } + [JsonPropertyName("location")] + public required string Location { get; set; } + [JsonPropertyName("md5")] + public required string MD5 { get; set; } } public class Patch { - public string version { get; set; } = "0.0.0"; - public string channel { get; set; } = "Global"; - public string release { get; set; } = "Official"; - public string method { get; set; } = "copy"; // rare use - public string nosupport { get; set; } = ""; - public List patched { get; set; } - public List original { get; set; } + [JsonPropertyName("version")] + public string Version { get; set; } = "0.0.0"; + [JsonPropertyName("channel")] + public string Channel { get; set; } = "Global"; + [JsonPropertyName("release")] + public string Release { get; set; } = "Official"; + [JsonPropertyName("nosupport")] + public string NoSupport { get; set; } = ""; + [JsonPropertyName("patched")] + public List Patched { get; set; } = new(); + [JsonPropertyName("original")] + public List Original { get; set; } = new(); } } diff --git a/Json/GameType.cs b/Json/GameType.cs index 199fa20..6c0e434 100644 --- a/Json/GameType.cs +++ b/Json/GameType.cs @@ -1,41 +1,52 @@ using System.Reflection; using System.Text.RegularExpressions; -public enum GameType +namespace YuukiPS_Launcher.Json { - [StringValue("Genshin Impact")] - GenshinImpact = 1, - - [StringValue("Star Rail")] - StarRail = 2 -} + public enum GameType + { + [StringValue("Genshin Impact")] + GenshinImpact = 1, -public class StringValueAttribute : Attribute -{ - public string Value { get; } + [StringValue("Star Rail")] + StarRail = 2 + } - public StringValueAttribute(string value) + [AttributeUsage(AttributeTargets.Field)] + public class StringValueAttribute : Attribute { - Value = value; + public string Value { get; } + + public StringValueAttribute(string value) + { + Value = value; + } } -} -public static class EnumExtensions -{ - public static string GetStringValue(this Enum value) + public static class EnumExtensions { - Type type = value.GetType(); - string name = Enum.GetName(type, value); + public static string GetStringValue(this Enum value) + { + Type type = value.GetType(); + string? name = Enum.GetName(type, value); - MemberInfo member = type.GetField(name); - StringValueAttribute attribute = member.GetCustomAttribute(); + if (name == null) + return value.ToString(); - return attribute != null ? attribute.Value : value.ToString(); - } - public static string SEOUrl(this GameType gameType) - { - string gameTypeName = gameType.ToString(); - string kebabCase = Regex.Replace(gameTypeName, "([a-z])([A-Z])", "$1-$2").ToLower(); - return kebabCase; + FieldInfo? field = type.GetField(name); + if (field == null) + return value.ToString(); + + StringValueAttribute? attribute = field.GetCustomAttribute(); + return attribute?.Value ?? value.ToString(); + } + + public static string SEOUrl(this GameType gameType) + { + string gameTypeName = gameType.ToString(); + string kebabCase = Regex.Replace(gameTypeName, "([a-z])([A-Z])", "$1-$2").ToLower(); + return kebabCase; + } } -} \ No newline at end of file +} + diff --git a/Json/Mod/Cheat.cs b/Json/Mod/Cheat.cs index 5471e0b..7c8f395 100644 --- a/Json/Mod/Cheat.cs +++ b/Json/Mod/Cheat.cs @@ -1,31 +1,40 @@ -namespace YuukiPS_Launcher.Json.Mod +using System.Text.Json.Serialization; + +namespace YuukiPS_Launcher.Json.Mod { public class Archive { - public string url { get; set; } - public string md5 { get; set; } - public string version { get; set; } - public string support { get; set; } - public List channel { get; set; } - public Config config { get; set; } - public string comment { get; set; } + [JsonPropertyName("url")] + public required string Url { get; set; } + [JsonPropertyName("md5")] + public required string Md5 { get; set; } + [JsonPropertyName("support")] + public required string Support { get; set; } + [JsonPropertyName("channel")] + public required List Channel { get; set; } + public required Config Config { get; set; } + [JsonPropertyName("comment")] + public required string Comment { get; set; } } public class Config { - public string injection { get; set; } - public string launcher { get; set; } - public string save { get; set; } - public int format { get; set; } // 1-cfg,2-json + [JsonPropertyName("launcher")] + public required string Launcher { get; set; } + [JsonPropertyName("save")] + public required string Save { get; set; } + [JsonPropertyName("format")] + public int Format { get; set; } // 1-cfg,2-json } public class Cheat { - public string nama { get; set; } - public string link { get; set; } - public string comment { get; set; } - public int game { get; set; } - public List archives { get; set; } + [JsonPropertyName("nama")] + public required string Nama { get; set; } + [JsonPropertyName("game")] + public int Game { get; set; } + [JsonPropertyName("archives")] + public required List Archives { get; set; } } } diff --git a/Json/Nightly.cs b/Json/Nightly.cs index ead25b8..4a51592 100644 --- a/Json/Nightly.cs +++ b/Json/Nightly.cs @@ -1,32 +1,32 @@ namespace YuukiPS_Launcher.Json { - public class Artifact - { - public int id { get; set; } - public string node_id { get; set; } - public string name { get; set; } - public int size_in_bytes { get; set; } - public string url { get; set; } - public string archive_download_url { get; set; } - public bool expired { get; set; } - public DateTime created_at { get; set; } - public DateTime updated_at { get; set; } - public DateTime expires_at { get; set; } - public WorkflowRun workflow_run { get; set; } - } + // public class Artifact + // { + // public int id { get; set; } + // public string node_id { get; set; } + // public string name { get; set; } + // public int size_in_bytes { get; set; } + // public string url { get; set; } + // public string archive_download_url { get; set; } + // public bool expired { get; set; } + // public DateTime created_at { get; set; } + // public DateTime updated_at { get; set; } + // public DateTime expires_at { get; set; } + // public WorkflowRun workflow_run { get; set; } + // } - public class Nightly - { - public int total_count { get; set; } - public List artifacts { get; set; } - } + // public class Nightly + // { + // public int total_count { get; set; } + // public List artifacts { get; set; } + // } - public class WorkflowRun - { - public long id { get; set; } - public int repository_id { get; set; } - public int head_repository_id { get; set; } - public string head_branch { get; set; } - public string head_sha { get; set; } - } + // public class WorkflowRun + // { + // public long id { get; set; } + // public int repository_id { get; set; } + // public int head_repository_id { get; set; } + // public string head_branch { get; set; } + // public string head_sha { get; set; } + // } } diff --git a/Json/Profile.cs b/Json/Profile.cs index 8479265..7efa4f9 100644 --- a/Json/Profile.cs +++ b/Json/Profile.cs @@ -39,8 +39,8 @@ public class Extra //public int patch_metode = 1; // 1=NO PATCH, 2=RSA ()this should not be necessary because it is controlled by game server } - public Server server = new(); + public Server ServerConfig { get; set; } = new(); - public Game game = new(); + public Game GameConfig { get; set; } = new(); } } diff --git a/Json/Update.cs b/Json/Update.cs index 7dbf504..b72a41b 100644 --- a/Json/Update.cs +++ b/Json/Update.cs @@ -1,87 +1,28 @@ -namespace YuukiPS_Launcher.Json +using System.Text.Json.Serialization; + +namespace YuukiPS_Launcher.Json { - public class Asset + public class Assets { - public string url { get; set; } - public int id { get; set; } - public string node_id { get; set; } - public string name { get; set; } - public object label { get; set; } - public Uploader uploader { get; set; } - public string content_type { get; set; } - public string state { get; set; } - public int size { get; set; } - public int download_count { get; set; } - public DateTime created_at { get; set; } - public DateTime updated_at { get; set; } - public string browser_download_url { get; set; } - } + [JsonPropertyName("name")] + public required string Name { get; set; } - public class Author - { - public string login { get; set; } - public int id { get; set; } - public string node_id { get; set; } - public string avatar_url { get; set; } - public string gravatar_id { get; set; } - public string url { get; set; } - public string html_url { get; set; } - public string followers_url { get; set; } - public string following_url { get; set; } - public string gists_url { get; set; } - public string starred_url { get; set; } - public string subscriptions_url { get; set; } - public string organizations_url { get; set; } - public string repos_url { get; set; } - public string events_url { get; set; } - public string received_events_url { get; set; } - public string type { get; set; } - public bool site_admin { get; set; } + [JsonPropertyName("browser_download_url")] + public required string BrowserDownloadUrl { get; set; } } public class Update { - public string url { get; set; } - public string assets_url { get; set; } - public string upload_url { get; set; } - public string html_url { get; set; } - public int id { get; set; } - public Author author { get; set; } - public string node_id { get; set; } - public string tag_name { get; set; } - public string target_commitish { get; set; } - public string name { get; set; } - public bool draft { get; set; } - public bool prerelease { get; set; } - public DateTime created_at { get; set; } - public DateTime published_at { get; set; } - public List assets { get; set; } - public string tarball_url { get; set; } - public string zipball_url { get; set; } - public string body { get; set; } - } + [JsonPropertyName("tag_name")] + public required string TagName { get; set; } - public class Uploader - { - public string login { get; set; } - public int id { get; set; } - public string node_id { get; set; } - public string avatar_url { get; set; } - public string gravatar_id { get; set; } - public string url { get; set; } - public string html_url { get; set; } - public string followers_url { get; set; } - public string following_url { get; set; } - public string gists_url { get; set; } - public string starred_url { get; set; } - public string subscriptions_url { get; set; } - public string organizations_url { get; set; } - public string repos_url { get; set; } - public string events_url { get; set; } - public string received_events_url { get; set; } - public string type { get; set; } - public bool site_admin { get; set; } - } + [JsonPropertyName("name")] + public required string Name { get; set; } + [JsonPropertyName("assets")] + public required List Assets { get; set; } + [JsonPropertyName("body")] + public required string Body { get; set; } + } } diff --git a/Main.Designer.cs b/Main.Designer.cs index 4478487..853cce2 100644 --- a/Main.Designer.cs +++ b/Main.Designer.cs @@ -71,6 +71,7 @@ private void InitializeComponent() Server_DL_RES = new Button(); comboBox2 = new ComboBox(); Server_Start = new Button(); + SetVersion = new Label(); groupBox5 = new GroupBox(); Server_DL_GC = new Button(); comboBox1 = new ComboBox(); @@ -85,7 +86,6 @@ private void InitializeComponent() label15 = new Label(); textBox1 = new TextBox(); label14 = new Label(); - Set_Version = new Label(); linkDiscord = new LinkLabel(); linkGithub = new LinkLabel(); linkWeb = new LinkLabel(); @@ -110,39 +110,43 @@ private void InitializeComponent() // // btStartNormal // - btStartNormal.Font = new Font("Segoe UI", 18F, FontStyle.Regular, GraphicsUnit.Point); - btStartNormal.Location = new Point(6, 61); + btStartNormal.BackColor = Color.FromArgb(52, 152, 219); + btStartNormal.FlatStyle = FlatStyle.Flat; + btStartNormal.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + btStartNormal.ForeColor = Color.White; + btStartNormal.Location = new Point(10, 54); btStartNormal.Name = "btStartNormal"; - btStartNormal.Size = new Size(105, 38); + btStartNormal.Size = new Size(120, 40); btStartNormal.TabIndex = 0; btStartNormal.Text = "Launch"; - btStartNormal.UseVisualStyleBackColor = true; + btStartNormal.UseVisualStyleBackColor = false; btStartNormal.Click += btStartNormal_Click; // // GetServerHost // - GetServerHost.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point); - GetServerHost.Location = new Point(6, 20); + GetServerHost.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + GetServerHost.Location = new Point(10, 20); GetServerHost.Name = "GetServerHost"; - GetServerHost.Size = new Size(232, 35); + GetServerHost.PlaceholderText = "https://ps.yuuki.me"; + GetServerHost.Size = new Size(250, 29); GetServerHost.TabIndex = 2; // // label2 // label2.AutoSize = true; - label2.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - label2.Location = new Point(111, 14); + label2.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + label2.Location = new Point(270, 25); label2.Name = "label2"; - label2.Size = new Size(41, 21); + label2.Size = new Size(37, 19); label2.TabIndex = 4; label2.Text = "Port:"; // // GetProxyPort // - GetProxyPort.Font = new Font("Segoe UI", 9.75F, FontStyle.Regular, GraphicsUnit.Point); - GetProxyPort.Location = new Point(158, 12); + GetProxyPort.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + GetProxyPort.Location = new Point(310, 22); GetProxyPort.Name = "GetProxyPort"; - GetProxyPort.Size = new Size(51, 25); + GetProxyPort.Size = new Size(60, 25); GetProxyPort.TabIndex = 5; GetProxyPort.Text = "2242"; // @@ -150,15 +154,16 @@ private void InitializeComponent() // TabMain.Controls.Add(tabPage1); TabMain.Controls.Add(tabPage2); - TabMain.Dock = DockStyle.Top; + TabMain.Dock = DockStyle.Fill; TabMain.Location = new Point(0, 0); TabMain.Name = "TabMain"; TabMain.SelectedIndex = 0; - TabMain.Size = new Size(662, 411); + TabMain.Size = new Size(720, 396); TabMain.TabIndex = 7; // // tabPage1 // + tabPage1.BackColor = Color.White; tabPage1.Controls.Add(grConfigGameLite); tabPage1.Controls.Add(stIsRunProxy); tabPage1.Controls.Add(groupBox8); @@ -169,59 +174,61 @@ private void InitializeComponent() tabPage1.Location = new Point(4, 24); tabPage1.Name = "tabPage1"; tabPage1.Padding = new Padding(3); - tabPage1.Size = new Size(654, 383); + tabPage1.Size = new Size(712, 368); tabPage1.TabIndex = 0; tabPage1.Text = "Connect"; - tabPage1.UseVisualStyleBackColor = true; // // grConfigGameLite // grConfigGameLite.Controls.Add(Set_LA_Select); grConfigGameLite.Controls.Add(Set_LA_GameFolder); grConfigGameLite.Controls.Add(label5); - grConfigGameLite.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - grConfigGameLite.Location = new Point(8, 111); + grConfigGameLite.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + grConfigGameLite.Location = new Point(10, 110); grConfigGameLite.Name = "grConfigGameLite"; - grConfigGameLite.Size = new Size(420, 59); + grConfigGameLite.Size = new Size(457, 60); grConfigGameLite.TabIndex = 19; grConfigGameLite.TabStop = false; grConfigGameLite.Text = "Game Config"; // // Set_LA_Select // - Set_LA_Select.Location = new Point(331, 16); + Set_LA_Select.BackColor = Color.FromArgb(46, 204, 113); + Set_LA_Select.FlatStyle = FlatStyle.Flat; + Set_LA_Select.ForeColor = Color.White; + Set_LA_Select.Location = new Point(381, 20); Set_LA_Select.Name = "Set_LA_Select"; - Set_LA_Select.Size = new Size(76, 30); + Set_LA_Select.Size = new Size(70, 30); Set_LA_Select.TabIndex = 9; Set_LA_Select.Text = "Choose"; - Set_LA_Select.UseVisualStyleBackColor = true; + Set_LA_Select.UseVisualStyleBackColor = false; Set_LA_Select.Click += Set_LA_Select_Click; // // Set_LA_GameFolder // - Set_LA_GameFolder.Location = new Point(117, 17); + Set_LA_GameFolder.Location = new Point(110, 20); Set_LA_GameFolder.Name = "Set_LA_GameFolder"; Set_LA_GameFolder.ReadOnly = true; - Set_LA_GameFolder.Size = new Size(208, 29); + Set_LA_GameFolder.Size = new Size(200, 25); Set_LA_GameFolder.TabIndex = 1; // // label5 // label5.AutoSize = true; - label5.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - label5.Location = new Point(9, 25); + label5.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + label5.Location = new Point(10, 23); label5.Name = "label5"; - label5.Size = new Size(102, 21); + label5.Size = new Size(90, 19); label5.TabIndex = 0; label5.Text = "Game Folder:"; // // stIsRunProxy // stIsRunProxy.AutoSize = true; - stIsRunProxy.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - stIsRunProxy.Location = new Point(3, 359); + stIsRunProxy.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + stIsRunProxy.Location = new Point(10, 340); stIsRunProxy.Name = "stIsRunProxy"; - stIsRunProxy.Size = new Size(87, 21); + stIsRunProxy.Size = new Size(79, 19); stIsRunProxy.TabIndex = 8; stIsRunProxy.Text = "Status: OFF"; // @@ -232,44 +239,50 @@ private void InitializeComponent() groupBox8.Controls.Add(btStartNormal); groupBox8.Controls.Add(GetTypeGame); groupBox8.Controls.Add(btStartOfficialServer); - groupBox8.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - groupBox8.Location = new Point(8, 6); + groupBox8.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + groupBox8.Location = new Point(10, 10); groupBox8.Name = "groupBox8"; - groupBox8.Size = new Size(420, 106); + groupBox8.Size = new Size(457, 100); groupBox8.TabIndex = 18; groupBox8.TabStop = false; groupBox8.Text = "Connect to server"; // // btStartYuukiServer // - btStartYuukiServer.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - btStartYuukiServer.Location = new Point(326, 20); + btStartYuukiServer.BackColor = Color.FromArgb(52, 152, 219); + btStartYuukiServer.FlatStyle = FlatStyle.Flat; + btStartYuukiServer.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + btStartYuukiServer.ForeColor = Color.White; + btStartYuukiServer.Location = new Point(360, 20); btStartYuukiServer.Name = "btStartYuukiServer"; btStartYuukiServer.Size = new Size(91, 35); btStartYuukiServer.TabIndex = 20; btStartYuukiServer.Text = "YuukiPS"; - btStartYuukiServer.UseVisualStyleBackColor = true; + btStartYuukiServer.UseVisualStyleBackColor = false; btStartYuukiServer.Click += btStartYuukiServer_Click; // // GetTypeGame // - GetTypeGame.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point); + GetTypeGame.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); GetTypeGame.FormattingEnabled = true; - GetTypeGame.Location = new Point(117, 61); + GetTypeGame.Location = new Point(151, 61); GetTypeGame.Name = "GetTypeGame"; - GetTypeGame.Size = new Size(300, 38); + GetTypeGame.Size = new Size(300, 29); GetTypeGame.TabIndex = 14; GetTypeGame.SelectedIndexChanged += GetTypeGame_SelectedIndexChanged; // // btStartOfficialServer // - btStartOfficialServer.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - btStartOfficialServer.Location = new Point(244, 20); + btStartOfficialServer.BackColor = Color.FromArgb(46, 204, 113); + btStartOfficialServer.FlatStyle = FlatStyle.Flat; + btStartOfficialServer.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + btStartOfficialServer.ForeColor = Color.White; + btStartOfficialServer.Location = new Point(273, 20); btStartOfficialServer.Name = "btStartOfficialServer"; btStartOfficialServer.Size = new Size(81, 35); btStartOfficialServer.TabIndex = 13; btStartOfficialServer.Text = "Official"; - btStartOfficialServer.UseVisualStyleBackColor = true; + btStartOfficialServer.UseVisualStyleBackColor = false; btStartOfficialServer.Click += btStartOfficialServer_Click; // // grProfile @@ -281,62 +294,71 @@ private void InitializeComponent() grProfile.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); grProfile.Location = new Point(6, 176); grProfile.Name = "grProfile"; - grProfile.Size = new Size(420, 108); + grProfile.Size = new Size(461, 108); grProfile.TabIndex = 17; grProfile.TabStop = false; grProfile.Text = "Profile"; // // GetProfileServer // - GetProfileServer.Font = new Font("Segoe UI", 15.75F, FontStyle.Regular, GraphicsUnit.Point); + GetProfileServer.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); GetProfileServer.FormattingEnabled = true; - GetProfileServer.Location = new Point(6, 28); + GetProfileServer.Location = new Point(14, 33); GetProfileServer.Name = "GetProfileServer"; - GetProfileServer.Size = new Size(234, 38); + GetProfileServer.Size = new Size(234, 29); GetProfileServer.TabIndex = 15; GetProfileServer.SelectedIndexChanged += GetProfileServer_SelectedIndexChanged; // // btload // - btload.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - btload.Location = new Point(332, 28); + btload.BackColor = Color.FromArgb(52, 152, 219); + btload.FlatStyle = FlatStyle.Flat; + btload.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + btload.ForeColor = Color.White; + btload.Location = new Point(380, 28); btload.Name = "btload"; btload.Size = new Size(75, 38); btload.TabIndex = 16; btload.Text = "Load"; - btload.UseVisualStyleBackColor = true; + btload.UseVisualStyleBackColor = false; btload.Click += btload_Click; // // btsave // - btsave.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - btsave.Location = new Point(246, 28); + btsave.BackColor = Color.FromArgb(46, 204, 113); + btsave.FlatStyle = FlatStyle.Flat; + btsave.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + btsave.ForeColor = Color.White; + btsave.Location = new Point(294, 28); btsave.Name = "btsave"; btsave.Size = new Size(80, 38); btsave.TabIndex = 2; btsave.Text = "Save"; - btsave.UseVisualStyleBackColor = true; + btsave.UseVisualStyleBackColor = false; btsave.Click += Set_LA_Save_Click; // // label8 // label8.AutoSize = true; - label8.Font = new Font("Segoe UI", 11.25F, FontStyle.Regular, GraphicsUnit.Point); - label8.Location = new Point(176, 78); + label8.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + label8.Location = new Point(118, 69); label8.Name = "label8"; - label8.Size = new Size(231, 20); + label8.Size = new Size(269, 19); label8.TabIndex = 13; - label8.Text = "Click Save to save current settings"; + label8.Text = "Click 'Save' to store current profile settings"; // // grExtra // + grExtra.BackColor = Color.FromArgb(240, 240, 240); grExtra.Controls.Add(Enable_WipeLoginCache); grExtra.Controls.Add(Enable_SendLog); grExtra.Controls.Add(Extra_Cheat); grExtra.Controls.Add(Enable_RPC); - grExtra.Location = new Point(431, 183); + grExtra.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + grExtra.ForeColor = Color.FromArgb(60, 60, 60); + grExtra.Location = new Point(487, 158); grExtra.Name = "grExtra"; - grExtra.Size = new Size(217, 101); + grExtra.Size = new Size(217, 139); grExtra.TabIndex = 12; grExtra.TabStop = false; grExtra.Text = "Extra"; @@ -344,11 +366,12 @@ private void InitializeComponent() // Enable_WipeLoginCache // Enable_WipeLoginCache.AutoSize = true; - Enable_WipeLoginCache.Location = new Point(7, 80); + Enable_WipeLoginCache.ForeColor = Color.FromArgb(60, 60, 60); + Enable_WipeLoginCache.Location = new Point(10, 80); Enable_WipeLoginCache.Name = "Enable_WipeLoginCache"; - Enable_WipeLoginCache.Size = new Size(91, 19); + Enable_WipeLoginCache.Size = new Size(97, 23); Enable_WipeLoginCache.TabIndex = 20; - Enable_WipeLoginCache.Text = "WIPE LOGIN"; + Enable_WipeLoginCache.Text = "Wipe Login"; Enable_WipeLoginCache.UseVisualStyleBackColor = true; // // Enable_SendLog @@ -356,9 +379,10 @@ private void InitializeComponent() Enable_SendLog.AutoSize = true; Enable_SendLog.Checked = true; Enable_SendLog.CheckState = CheckState.Checked; - Enable_SendLog.Location = new Point(7, 61); + Enable_SendLog.ForeColor = Color.FromArgb(60, 60, 60); + Enable_SendLog.Location = new Point(10, 55); Enable_SendLog.Name = "Enable_SendLog"; - Enable_SendLog.Size = new Size(80, 19); + Enable_SendLog.Size = new Size(91, 23); Enable_SendLog.TabIndex = 2; Enable_SendLog.Text = "Send Logs"; Enable_SendLog.UseVisualStyleBackColor = true; @@ -366,9 +390,10 @@ private void InitializeComponent() // Extra_Cheat // Extra_Cheat.AutoSize = true; - Extra_Cheat.Location = new Point(7, 22); + Extra_Cheat.ForeColor = Color.FromArgb(60, 60, 60); + Extra_Cheat.Location = new Point(10, 30); Extra_Cheat.Name = "Extra_Cheat"; - Extra_Cheat.Size = new Size(57, 19); + Extra_Cheat.Size = new Size(64, 23); Extra_Cheat.TabIndex = 0; Extra_Cheat.Text = "Cheat"; Extra_Cheat.UseVisualStyleBackColor = true; @@ -376,9 +401,10 @@ private void InitializeComponent() // Enable_RPC // Enable_RPC.AutoSize = true; - Enable_RPC.Location = new Point(7, 41); + Enable_RPC.ForeColor = Color.FromArgb(60, 60, 60); + Enable_RPC.Location = new Point(10, 105); Enable_RPC.Name = "Enable_RPC"; - Enable_RPC.Size = new Size(150, 19); + Enable_RPC.Size = new Size(169, 23); Enable_RPC.TabIndex = 1; Enable_RPC.Text = "Rich Presence (Discord)"; Enable_RPC.UseVisualStyleBackColor = true; @@ -386,10 +412,13 @@ private void InitializeComponent() // // grProxy // + grProxy.BackColor = Color.FromArgb(240, 240, 240); grProxy.Controls.Add(GetProxyPort); grProxy.Controls.Add(CheckProxyEnable); grProxy.Controls.Add(label2); - grProxy.Location = new Point(431, 127); + grProxy.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + grProxy.ForeColor = Color.FromArgb(60, 60, 60); + grProxy.Location = new Point(487, 308); grProxy.Name = "grProxy"; grProxy.Size = new Size(217, 51); grProxy.TabIndex = 11; @@ -401,129 +430,142 @@ private void InitializeComponent() CheckProxyEnable.AutoSize = true; CheckProxyEnable.Checked = true; CheckProxyEnable.CheckState = CheckState.Checked; - CheckProxyEnable.Location = new Point(6, 18); + CheckProxyEnable.ForeColor = Color.FromArgb(60, 60, 60); + CheckProxyEnable.Location = new Point(10, 25); CheckProxyEnable.Name = "CheckProxyEnable"; - CheckProxyEnable.Size = new Size(61, 19); + CheckProxyEnable.Size = new Size(68, 23); CheckProxyEnable.TabIndex = 7; CheckProxyEnable.Text = "Enable"; CheckProxyEnable.UseVisualStyleBackColor = true; // // groupBox3 // + groupBox3.BackColor = Color.FromArgb(240, 240, 240); groupBox3.Controls.Add(Get_LA_Version); groupBox3.Controls.Add(Get_LA_MD5); groupBox3.Controls.Add(Get_LA_CH); groupBox3.Controls.Add(Get_LA_REL); - groupBox3.Location = new Point(431, 8); + groupBox3.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + groupBox3.ForeColor = Color.FromArgb(60, 60, 60); + groupBox3.Location = new Point(487, 8); groupBox3.Name = "groupBox3"; - groupBox3.Size = new Size(217, 114); + groupBox3.Size = new Size(217, 144); groupBox3.TabIndex = 8; groupBox3.TabStop = false; - groupBox3.Text = "Game"; + groupBox3.Text = "Game Info"; + groupBox3.Enter += groupBox3_Enter; // // Get_LA_Version // Get_LA_Version.AutoSize = true; - Get_LA_Version.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - Get_LA_Version.Location = new Point(6, 19); + Get_LA_Version.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + Get_LA_Version.ForeColor = Color.FromArgb(60, 60, 60); + Get_LA_Version.Location = new Point(10, 30); Get_LA_Version.Name = "Get_LA_Version"; - Get_LA_Version.Size = new Size(136, 21); + Get_LA_Version.Size = new Size(120, 19); Get_LA_Version.TabIndex = 3; Get_LA_Version.Text = "Version: Unknown"; // // Get_LA_MD5 // Get_LA_MD5.AutoSize = true; - Get_LA_MD5.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - Get_LA_MD5.Location = new Point(6, 82); + Get_LA_MD5.Cursor = Cursors.Hand; + Get_LA_MD5.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + Get_LA_MD5.ForeColor = Color.FromArgb(60, 60, 60); + Get_LA_MD5.Location = new Point(10, 110); Get_LA_MD5.Name = "Get_LA_MD5"; - Get_LA_MD5.Size = new Size(118, 21); + Get_LA_MD5.Size = new Size(106, 19); Get_LA_MD5.TabIndex = 7; Get_LA_MD5.Text = "MD5: Unknown"; + Get_LA_MD5.Click += Get_LA_MD5_Click; // // Get_LA_CH // Get_LA_CH.AutoSize = true; - Get_LA_CH.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - Get_LA_CH.Location = new Point(6, 40); + Get_LA_CH.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + Get_LA_CH.ForeColor = Color.FromArgb(60, 60, 60); + Get_LA_CH.Location = new Point(10, 55); Get_LA_CH.Name = "Get_LA_CH"; - Get_LA_CH.Size = new Size(141, 21); + Get_LA_CH.Size = new Size(125, 19); Get_LA_CH.TabIndex = 4; Get_LA_CH.Text = "Channel: Unknown"; // // Get_LA_REL // Get_LA_REL.AutoSize = true; - Get_LA_REL.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - Get_LA_REL.Location = new Point(6, 61); + Get_LA_REL.Font = new Font("Segoe UI", 11F, FontStyle.Regular, GraphicsUnit.Point); + Get_LA_REL.ForeColor = Color.FromArgb(50, 50, 50); + Get_LA_REL.Location = new Point(10, 80); Get_LA_REL.Name = "Get_LA_REL"; - Get_LA_REL.Size = new Size(137, 21); + Get_LA_REL.Size = new Size(128, 20); Get_LA_REL.TabIndex = 5; Get_LA_REL.Text = "Release: Unknown"; // // tabPage2 // + tabPage2.BackColor = Color.White; tabPage2.Controls.Add(tabControl2); tabPage2.Location = new Point(4, 24); tabPage2.Name = "tabPage2"; tabPage2.Padding = new Padding(3); - tabPage2.Size = new Size(654, 383); + tabPage2.Size = new Size(712, 368); tabPage2.TabIndex = 1; tabPage2.Text = "Server"; - tabPage2.UseVisualStyleBackColor = true; // // tabControl2 // tabControl2.Controls.Add(tabPage10); tabControl2.Controls.Add(tabPage11); tabControl2.Dock = DockStyle.Fill; + tabControl2.Font = new Font("Segoe UI", 11F, FontStyle.Regular, GraphicsUnit.Point); tabControl2.Location = new Point(3, 3); tabControl2.Name = "tabControl2"; tabControl2.SelectedIndex = 0; - tabControl2.Size = new Size(648, 377); + tabControl2.Size = new Size(706, 362); tabControl2.TabIndex = 8; // // tabPage10 // + tabPage10.BackColor = Color.White; tabPage10.Controls.Add(groupBox4); tabPage10.Controls.Add(groupBox6); tabPage10.Controls.Add(Server_Start); + tabPage10.Controls.Add(SetVersion); tabPage10.Controls.Add(groupBox5); tabPage10.Controls.Add(Server_Config_OpenFolder); - tabPage10.Location = new Point(4, 24); + tabPage10.Location = new Point(4, 29); tabPage10.Name = "tabPage10"; tabPage10.Padding = new Padding(3); - tabPage10.Size = new Size(640, 349); + tabPage10.Size = new Size(698, 329); tabPage10.TabIndex = 0; tabPage10.Text = "Home"; - tabPage10.UseVisualStyleBackColor = true; // // groupBox4 // groupBox4.Controls.Add(Server_DL_DB); groupBox4.Controls.Add(Server_DL_JAVA); groupBox4.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); - groupBox4.Location = new Point(6, 6); + groupBox4.Location = new Point(10, 10); groupBox4.Name = "groupBox4"; - groupBox4.Size = new Size(155, 100); + groupBox4.Size = new Size(170, 120); groupBox4.TabIndex = 5; groupBox4.TabStop = false; groupBox4.Text = "Download Package"; // // Server_DL_DB // - Server_DL_DB.Location = new Point(6, 63); + Server_DL_DB.Location = new Point(10, 73); Server_DL_DB.Name = "Server_DL_DB"; - Server_DL_DB.Size = new Size(143, 29); + Server_DL_DB.Size = new Size(150, 35); Server_DL_DB.TabIndex = 1; Server_DL_DB.Text = "MongoDB"; Server_DL_DB.UseVisualStyleBackColor = true; // // Server_DL_JAVA // - Server_DL_JAVA.Location = new Point(6, 28); + Server_DL_JAVA.Location = new Point(10, 29); Server_DL_JAVA.Name = "Server_DL_JAVA"; - Server_DL_JAVA.Size = new Size(143, 29); + Server_DL_JAVA.Size = new Size(150, 35); Server_DL_JAVA.TabIndex = 0; Server_DL_JAVA.Text = "Java"; Server_DL_JAVA.UseVisualStyleBackColor = true; @@ -533,19 +575,19 @@ private void InitializeComponent() // groupBox6.Controls.Add(Server_DL_RES); groupBox6.Controls.Add(comboBox2); - groupBox6.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - groupBox6.Location = new Point(367, 6); + groupBox6.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + groupBox6.Location = new Point(196, 10); groupBox6.Name = "groupBox6"; - groupBox6.Size = new Size(200, 100); + groupBox6.Size = new Size(180, 120); groupBox6.TabIndex = 7; groupBox6.TabStop = false; - groupBox6.Text = "Version Resources:"; + groupBox6.Text = "Version Resources"; // // Server_DL_RES // - Server_DL_RES.Location = new Point(6, 56); + Server_DL_RES.Location = new Point(10, 73); Server_DL_RES.Name = "Server_DL_RES"; - Server_DL_RES.Size = new Size(188, 38); + Server_DL_RES.Size = new Size(160, 35); Server_DL_RES.TabIndex = 8; Server_DL_RES.Text = "Download"; Server_DL_RES.UseVisualStyleBackColor = true; @@ -554,65 +596,92 @@ private void InitializeComponent() // comboBox2.FormattingEnabled = true; comboBox2.Items.AddRange(new object[] { "Yuuki Gitlab 3.1", "Yuuki Gitlab 3.0", "Yuuki Gitlab 2.8", "Yuuki Gitlab 2.7", "Yuuki Gitlab 2.6" }); - comboBox2.Location = new Point(6, 23); + comboBox2.Location = new Point(10, 29); comboBox2.Name = "comboBox2"; - comboBox2.Size = new Size(188, 33); + comboBox2.Size = new Size(160, 29); comboBox2.TabIndex = 3; comboBox2.Text = "Yuuki Gitlab 3.1"; // // Server_Start // - Server_Start.Location = new Point(107, 218); + Server_Start.BackColor = Color.FromArgb(52, 152, 219); + Server_Start.Cursor = Cursors.Hand; + Server_Start.FlatStyle = FlatStyle.Flat; + Server_Start.Font = new Font("Segoe UI", 12F, FontStyle.Bold, GraphicsUnit.Point); + Server_Start.ForeColor = Color.White; + Server_Start.Location = new Point(10, 10); Server_Start.Name = "Server_Start"; - Server_Start.Size = new Size(93, 23); + Server_Start.Size = new Size(120, 40); Server_Start.TabIndex = 0; - Server_Start.Text = "Start"; - Server_Start.UseVisualStyleBackColor = true; + Server_Start.Text = "Start Server"; + Server_Start.UseVisualStyleBackColor = false; Server_Start.Click += Server_Start_Click; // + // SetVersion + // + SetVersion.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + SetVersion.Location = new Point(10, 306); + SetVersion.Name = "SetVersion"; + SetVersion.Size = new Size(94, 20); + SetVersion.TabIndex = 12; + SetVersion.Text = "Version: 0.0.0"; + // // groupBox5 // groupBox5.Controls.Add(Server_DL_GC); groupBox5.Controls.Add(comboBox1); - groupBox5.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - groupBox5.Location = new Point(167, 6); + groupBox5.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + groupBox5.Location = new Point(382, 10); groupBox5.Name = "groupBox5"; - groupBox5.Size = new Size(200, 100); + groupBox5.Size = new Size(300, 120); groupBox5.TabIndex = 6; groupBox5.TabStop = false; - groupBox5.Text = "Version Grasscutter:"; + groupBox5.Text = "Grasscutter Version"; // // Server_DL_GC // - Server_DL_GC.Location = new Point(6, 57); + Server_DL_GC.BackColor = Color.FromArgb(46, 204, 113); + Server_DL_GC.Cursor = Cursors.Hand; + Server_DL_GC.FlatStyle = FlatStyle.Flat; + Server_DL_GC.Font = new Font("Segoe UI", 12F, FontStyle.Bold, GraphicsUnit.Point); + Server_DL_GC.ForeColor = Color.White; + Server_DL_GC.Location = new Point(10, 70); Server_DL_GC.Name = "Server_DL_GC"; - Server_DL_GC.Size = new Size(188, 38); + Server_DL_GC.Size = new Size(280, 40); Server_DL_GC.TabIndex = 3; Server_DL_GC.Text = "Download"; - Server_DL_GC.UseVisualStyleBackColor = true; + Server_DL_GC.UseVisualStyleBackColor = false; // // comboBox1 // + comboBox1.FlatStyle = FlatStyle.Flat; + comboBox1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); comboBox1.FormattingEnabled = true; comboBox1.Items.AddRange(new object[] { "DockerGS 2.6", "DockerGS 2.7", "DockerGS 2.8", "DockerGS 3.0", "DockerGS 3.1" }); - comboBox1.Location = new Point(6, 23); + comboBox1.Location = new Point(10, 28); comboBox1.Name = "comboBox1"; - comboBox1.Size = new Size(188, 33); + comboBox1.Size = new Size(280, 29); comboBox1.TabIndex = 2; comboBox1.Text = "DockerGC 3.1"; // // Server_Config_OpenFolder // - Server_Config_OpenFolder.Location = new Point(12, 218); + Server_Config_OpenFolder.BackColor = Color.FromArgb(52, 152, 219); + Server_Config_OpenFolder.Cursor = Cursors.Hand; + Server_Config_OpenFolder.Enabled = false; + Server_Config_OpenFolder.FlatStyle = FlatStyle.Flat; + Server_Config_OpenFolder.Font = new Font("Segoe UI", 10F, FontStyle.Regular, GraphicsUnit.Point); + Server_Config_OpenFolder.ForeColor = Color.White; + Server_Config_OpenFolder.Location = new Point(10, 141); Server_Config_OpenFolder.Name = "Server_Config_OpenFolder"; - Server_Config_OpenFolder.Size = new Size(89, 23); + Server_Config_OpenFolder.Size = new Size(150, 35); Server_Config_OpenFolder.TabIndex = 1; - Server_Config_OpenFolder.Text = "Folder Server"; - Server_Config_OpenFolder.UseVisualStyleBackColor = true; - Server_Config_OpenFolder.Click += Server_Config_OpenFolder_Click; + Server_Config_OpenFolder.Text = "Open Server Folder"; + Server_Config_OpenFolder.UseVisualStyleBackColor = false; // // tabPage11 // + tabPage11.BackColor = Color.FromArgb(236, 240, 241); tabPage11.Controls.Add(textBox4); tabPage11.Controls.Add(label17); tabPage11.Controls.Add(textBox3); @@ -622,106 +691,112 @@ private void InitializeComponent() tabPage11.Controls.Add(label15); tabPage11.Controls.Add(textBox1); tabPage11.Controls.Add(label14); - tabPage11.Location = new Point(4, 24); + tabPage11.Location = new Point(4, 29); tabPage11.Name = "tabPage11"; - tabPage11.Padding = new Padding(3); - tabPage11.Size = new Size(640, 349); + tabPage11.Padding = new Padding(10); + tabPage11.Size = new Size(698, 329); tabPage11.TabIndex = 1; - tabPage11.Text = "Custom"; - tabPage11.UseVisualStyleBackColor = true; + tabPage11.Text = "Custom Settings"; // // textBox4 // - textBox4.Location = new Point(6, 192); + textBox4.BackColor = Color.White; + textBox4.BorderStyle = BorderStyle.None; + textBox4.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + textBox4.Location = new Point(10, 220); textBox4.Name = "textBox4"; - textBox4.Size = new Size(626, 23); + textBox4.Size = new Size(620, 22); textBox4.TabIndex = 8; // // label17 // label17.AutoSize = true; - label17.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - label17.Location = new Point(6, 165); + label17.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + label17.Location = new Point(10, 195); label17.Name = "label17"; - label17.Size = new Size(206, 25); + label17.Size = new Size(170, 21); label17.TabIndex = 7; - label17.Text = "Folder MongoDB (BIN):"; + label17.Text = "MongoDB Folder (BIN):"; // // textBox3 // - textBox3.Location = new Point(6, 139); + textBox3.BackColor = Color.White; + textBox3.BorderStyle = BorderStyle.None; + textBox3.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + textBox3.Location = new Point(10, 165); textBox3.Name = "textBox3"; - textBox3.Size = new Size(626, 23); + textBox3.Size = new Size(620, 22); textBox3.TabIndex = 6; // // label16 // label16.AutoSize = true; - label16.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - label16.Location = new Point(6, 111); + label16.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + label16.Location = new Point(10, 140); label16.Name = "label16"; - label16.Size = new Size(157, 25); + label16.Size = new Size(130, 21); label16.TabIndex = 5; - label16.Text = "Folder Java (BIN):"; + label16.Text = "Java Folder (BIN):"; // // button1 // - button1.Location = new Point(557, 221); + button1.BackColor = Color.FromArgb(52, 152, 219); + button1.Cursor = Cursors.Hand; + button1.FlatStyle = FlatStyle.Flat; + button1.Font = new Font("Segoe UI", 12F, FontStyle.Bold, GraphicsUnit.Point); + button1.ForeColor = Color.White; + button1.Location = new Point(530, 260); button1.Name = "button1"; - button1.Size = new Size(75, 23); + button1.Size = new Size(100, 40); button1.TabIndex = 4; button1.Text = "Save"; - button1.UseVisualStyleBackColor = true; + button1.UseVisualStyleBackColor = false; // // textBox2 // - textBox2.Location = new Point(6, 85); + textBox2.BackColor = Color.White; + textBox2.BorderStyle = BorderStyle.None; + textBox2.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + textBox2.Location = new Point(10, 110); textBox2.Name = "textBox2"; - textBox2.Size = new Size(626, 23); + textBox2.Size = new Size(620, 22); textBox2.TabIndex = 3; // // label15 // label15.AutoSize = true; - label15.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - label15.Location = new Point(6, 57); + label15.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + label15.Location = new Point(10, 85); label15.Name = "label15"; - label15.Size = new Size(258, 25); + label15.Size = new Size(215, 21); label15.TabIndex = 2; label15.Text = "Grasscutter Resources Folder:"; // // textBox1 // - textBox1.Location = new Point(6, 31); + textBox1.BackColor = Color.White; + textBox1.BorderStyle = BorderStyle.None; + textBox1.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + textBox1.Location = new Point(10, 55); textBox1.Name = "textBox1"; - textBox1.Size = new Size(626, 23); + textBox1.Size = new Size(620, 22); textBox1.TabIndex = 1; // // label14 // label14.AutoSize = true; - label14.Font = new Font("Segoe UI", 14.25F, FontStyle.Regular, GraphicsUnit.Point); - label14.Location = new Point(3, 3); + label14.Font = new Font("Segoe UI", 12F, FontStyle.Regular, GraphicsUnit.Point); + label14.Location = new Point(10, 30); label14.Name = "label14"; - label14.Size = new Size(169, 25); + label14.Size = new Size(140, 21); label14.TabIndex = 0; label14.Text = "Grasscutter Folder:"; // - // Set_Version - // - Set_Version.AutoSize = true; - Set_Version.Dock = DockStyle.Left; - Set_Version.Location = new Point(0, 411); - Set_Version.Name = "Set_Version"; - Set_Version.Size = new Size(75, 15); - Set_Version.TabIndex = 12; - Set_Version.Text = "Version: 0.0.0"; - // // linkDiscord // linkDiscord.AutoSize = true; linkDiscord.Dock = DockStyle.Right; - linkDiscord.Location = new Point(615, 411); + linkDiscord.Location = new Point(673, 0); linkDiscord.Name = "linkDiscord"; linkDiscord.Size = new Size(47, 15); linkDiscord.TabIndex = 13; @@ -733,7 +808,7 @@ private void InitializeComponent() // linkGithub.AutoSize = true; linkGithub.Dock = DockStyle.Right; - linkGithub.Location = new Point(572, 411); + linkGithub.Location = new Point(630, 0); linkGithub.Name = "linkGithub"; linkGithub.Size = new Size(43, 15); linkGithub.TabIndex = 14; @@ -745,7 +820,7 @@ private void InitializeComponent() // linkWeb.AutoSize = true; linkWeb.Dock = DockStyle.Right; - linkWeb.Location = new Point(541, 411); + linkWeb.Location = new Point(599, 0); linkWeb.Name = "linkWeb"; linkWeb.Size = new Size(31, 15); linkWeb.TabIndex = 15; @@ -769,11 +844,10 @@ private void InitializeComponent() // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(662, 431); + ClientSize = new Size(720, 396); Controls.Add(linkWeb); Controls.Add(linkGithub); Controls.Add(linkDiscord); - Controls.Add(Set_Version); Controls.Add(TabMain); FormBorderStyle = FormBorderStyle.FixedSingle; MaximizeBox = false; @@ -820,7 +894,7 @@ private void InitializeComponent() private Button Server_Start; private GroupBox grProxy; private CheckBox CheckProxyEnable; - private Label Set_Version; + private Label SetVersion; private Label stIsRunProxy; private LinkLabel linkDiscord; private LinkLabel linkGithub; diff --git a/Main.cs b/Main.cs index 3f5e851..3aa8e0f 100644 --- a/Main.cs +++ b/Main.cs @@ -12,13 +12,13 @@ namespace YuukiPS_Launcher { public partial class Main : Form - { + { // Main Function private Proxy? proxy; private Process? progress; - Json.Config configdata = new Json.Config(); - Profile default_profile = new Profile(); + Config ConfigData = new(); + Profile DefaultProfile = new(); // Stats default public string WatchFile = ""; @@ -33,7 +33,7 @@ public partial class Main : Form public string PathfileGame = ""; // Extra - Extra.Discord discord = new Extra.Discord(); + readonly Extra.Discord discord = new(); // Game public Game.Genshin.Settings? settings_genshin = null; @@ -41,7 +41,7 @@ public partial class Main : Form // Patch Patch? get_patch = null; - Logger logger = new Logger(); + Logger logger = new(); public Main() { @@ -58,7 +58,7 @@ private void Main_Load(object sender, EventArgs e) Directory.CreateDirectory(logsFolderPath); - logger.initLogging($"Platform: {os.Platform}\nPlatform Version: {os.Version}\nService pack: {os.ServicePack}\n\n", logFilePath); + Logger.InitLogging($"Platform: {os.Platform}\nPlatform Version: {os.Version}\nService pack: {os.ServicePack}\n\n", logFilePath); Logger.Info("Boot", "Loading...."); @@ -71,17 +71,17 @@ private void Main_Load(object sender, EventArgs e) LoadConfig("Boot"); // if found config // Load Profile by profile_default - LoadProfile(configdata.profile_default); + LoadProfile(ConfigData.profile_default); // Extra if (Enable_RPC.Checked) { - Logger.Info("Boot", "Discord RPC enable"); + Logger.Info("Boot", "Discord RPC enabled"); discord.Ready(); } else { - Logger.Info("Boot", "Discord RPC disable"); + Logger.Info("Boot", "Discord RPC disabled"); } } @@ -106,21 +106,21 @@ private void GetProfileServer_SelectedIndexChanged(object? sender, EventArgs e) private void GetTypeGame_SelectedIndexChanged(object? sender, EventArgs e) { - default_profile.game.type = (GameType)GetTypeGame.SelectedItem; + DefaultProfile.GameConfig.type = (GameType)GetTypeGame.SelectedItem; } - public void LoadConfig(string load_by) + public void LoadConfig(string LoadBy) { - configdata = Json.Config.LoadConfig(); + ConfigData = Json.Config.LoadConfig(); - Logger.Info("Config", "load config by " + load_by); + Logger.Info("Config", $"Configuration loaded by: {LoadBy}"); // Unsubscribe from SelectedIndexChanged event GetProfileServer.SelectedIndexChanged -= GetProfileServer_SelectedIndexChanged; // Profile GetProfileServer.DisplayMember = "name"; - GetProfileServer.DataSource = configdata.profile; + GetProfileServer.DataSource = ConfigData.Profile; // GameType GetTypeGame.DataSource = Enum.GetValues(typeof(GameType)); @@ -129,9 +129,9 @@ public void LoadConfig(string load_by) for (int i = 0; i < GetProfileServer.Items.Count; i++) { Profile profile = (Profile)GetProfileServer.Items[i]; - if (profile.name == configdata.profile_default) + if (profile.name == ConfigData.profile_default) { - Logger.Info("Profiles", "Set index " + i + " name profile " + configdata.profile_default); + Logger.Info("Profiles", $"Setting selected profile: '{ConfigData.profile_default}' at index {i}"); GetProfileServer.SelectedIndex = i; break; } @@ -141,29 +141,29 @@ public void LoadConfig(string load_by) GetProfileServer.SelectedIndexChanged += GetProfileServer_SelectedIndexChanged; } - public void LoadProfile(string load_profile = "") + public void LoadProfile(string LoadProfile = "") { - if (string.IsNullOrEmpty(load_profile)) + if (string.IsNullOrEmpty(LoadProfile)) { Logger.Info("Profiles", "No profile"); return; } - Logger.Info("Profiles", "Profile: " + load_profile); + Logger.Info("Profiles", "Profile: " + LoadProfile); try { - var tmp_profile = configdata.profile.Find(p => p.name == load_profile); + var tmp_profile = ConfigData.Profile.Find(p => p.name == LoadProfile); if (tmp_profile != null) { - default_profile = tmp_profile; + DefaultProfile = tmp_profile; } else { // use default data } - Logger.Info("Profiles", "Server: " + default_profile.server.url); + Logger.Info("Profiles", "Server: " + DefaultProfile.ServerConfig.url); } catch (Exception e) { @@ -173,82 +173,84 @@ public void LoadProfile(string load_profile = "") // Data Set // Game - Set_LA_GameFolder.Text = default_profile.game.path; - GetTypeGame.SelectedIndex = Array.IndexOf(Enum.GetValues(typeof(GameType)), default_profile.game.type); + Set_LA_GameFolder.Text = DefaultProfile.GameConfig.path; + GetTypeGame.SelectedIndex = Array.IndexOf(Enum.GetValues(typeof(GameType)), DefaultProfile.GameConfig.type); // Server - CheckProxyEnable.Checked = default_profile.server.proxy.enable; - GetServerHost.Text = default_profile.server.url; + CheckProxyEnable.Checked = DefaultProfile.ServerConfig.proxy.enable; + GetServerHost.Text = DefaultProfile.ServerConfig.url; // Extra - Extra_Cheat.Checked = default_profile.game.extra.Akebi; - Enable_RPC.Checked = default_profile.game.extra.RPC; + Extra_Cheat.Checked = DefaultProfile.GameConfig.extra.Akebi; + Enable_RPC.Checked = DefaultProfile.GameConfig.extra.RPC; // Get Data Game - if (!CheckVersionGame(default_profile.game.type)) + if (!CheckVersionGame(DefaultProfile.GameConfig.type)) { - MessageBox.Show("No game folder detected, please manually input game folder then play"); + var message = "No game folder detected. Please manually input the game folder before playing."; + Logger.Warning("Game", message); + MessageBox.Show(message, "Game Folder Not Found", MessageBoxButtons.OK, MessageBoxIcon.Information); } } - public void SaveProfile(string name_save = "Default") + public void SaveProfile(string NameSave = "Default") { try { var tmp_profile = new Profile(); // Game - tmp_profile.game.path = Set_LA_GameFolder.Text; - tmp_profile.game.type = (GameType)GetTypeGame.SelectedItem; - tmp_profile.game.wipeLogin = Enable_WipeLoginCache.Checked; + tmp_profile.GameConfig.path = Set_LA_GameFolder.Text; + tmp_profile.GameConfig.type = (GameType)GetTypeGame.SelectedItem; + tmp_profile.GameConfig.wipeLogin = Enable_WipeLoginCache.Checked; // Server - tmp_profile.server.url = GetServerHost.Text; + tmp_profile.ServerConfig.url = GetServerHost.Text; int myInt; bool isValid = int.TryParse(GetProxyPort.Text, out myInt); if (isValid) { - tmp_profile.server.proxy.port = myInt; + tmp_profile.ServerConfig.proxy.port = myInt; } // Extra - tmp_profile.game.extra.Akebi = Extra_Cheat.Checked; - tmp_profile.game.extra.RPC = Enable_RPC.Checked; + tmp_profile.GameConfig.extra.Akebi = Extra_Cheat.Checked; + tmp_profile.GameConfig.extra.RPC = Enable_RPC.Checked; // Nama Profile - tmp_profile.name = name_save; + tmp_profile.name = NameSave; try { - int indexToUpdate = configdata.profile.FindIndex(profile => profile.name == name_save); + int indexToUpdate = ConfigData.Profile.FindIndex(profile => profile.name == NameSave); if (indexToUpdate != -1) { - Logger.Info("Profiles", "Profile save: " + name_save); - configdata.profile[indexToUpdate] = tmp_profile; + Logger.Info("Profiles", $"Updating existing profile: {NameSave}"); + ConfigData.Profile[indexToUpdate] = tmp_profile; } else { - Logger.Info("Profiles", "Add new profile: " + name_save); - configdata.profile.Add(tmp_profile); + Logger.Info("Profiles", $"Creating new profile: {NameSave}"); + ConfigData.Profile.Add(tmp_profile); } } catch (Exception ex) { - Logger.Info("Profiles", "Error save config (" + ex.Message + "), so reload it"); - configdata = new Json.Config() { profile = new List() { tmp_profile } }; + Logger.Error("Profiles", $"Failed to save profile '{NameSave}'. Error: {ex.Message}. Reinitializing configuration."); + ConfigData = new Json.Config() { Profile = new List() { tmp_profile } }; } - configdata.profile_default = name_save; + ConfigData.profile_default = NameSave; - File.WriteAllText(Json.Config.ConfigPath, JsonConvert.SerializeObject(configdata)); + File.WriteAllText(Json.Config.ConfigPath, JsonConvert.SerializeObject(ConfigData)); - Logger.Info("Config", "Done save config..."); + Logger.Info("Config", "Configuration saved successfully."); LoadConfig("SaveProfile"); } catch (Exception ex) { - Console.WriteLine(ex); + Logger.Error("Profiles", $"Failed to save profile: {ex.Message}. Reverting to default configuration."); } } @@ -329,9 +331,9 @@ public void DoStart() } else { - if (get_patch != null && get_patch.nosupport != "") + if (get_patch != null && get_patch.NoSupport != "") { - MessageBox.Show(get_patch.nosupport, "Game version not supported"); + MessageBox.Show(get_patch.NoSupport, "Game version not supported"); Process.Start(new ProcessStartInfo(API.WEB_LINK) { UseShellExecute = true }); return; } @@ -339,11 +341,13 @@ public void DoStart() // run patch var startPatch = PatchGame(patch); - if (!string.IsNullOrEmpty(startPatch)) + if (!startPatch) { - MessageBox.Show(startPatch, "Error Patch"); + MessageBox.Show("Failed to patch a game file. See console for more details."); return; } + + } // For Proxy @@ -357,16 +361,25 @@ public void DoStart() proxy = new Proxy(set_proxy_port, set_server_host, isSendLog); if (!proxy.Start()) { - MessageBox.Show("Maybe port is already use or Windows Firewall does not allow using port " + set_proxy_port + " or Windows Update sometimes takes that range, or try again it might magically work again.", "Proxy port cannot be used"); + MessageBox.Show($"Unable to start proxy on port {set_proxy_port}. Possible reasons:\n\n" + + "1. The port is already in use by another application.\n" + + "2. Windows Firewall is blocking access to this port.\n" + + "3. Windows Update may be using ports in this range.\n\n" + + "Please try the following:\n" + + "- Close any applications that might be using this port.\n" + + "- Check your firewall settings.\n" + + "- Try restarting the application.\n" + + "- If the issue persists, consider using a different port.", + "Proxy Port Error"); try { Process.Start(new ProcessStartInfo("cmd", $"/c net stop winnat") { CreateNoWindow = true, UseShellExecute = false }); } - catch + catch (Exception ex) { - // skip + Logger.Error("Proxy", $"Error stopping WinNAT service: {ex.Message}"); } - StopProxy(); + proxy.Stop(); return; } else @@ -375,9 +388,9 @@ public void DoStart() { if (!API.isYuuki(set_proxy_port)) { - StopProxy(); + proxy.Stop(); InstallCert(); - MessageBox.Show("Try closing this program then opening it again, if there is still an error, please report it to admin with a screenshot console", "Not yet connected to YuukiPS server"); + MessageBox.Show("Unable to connect to YuukiPS server. Please try the following steps:\n\n1. Close this program completely\n2. Reopen the program and try again\n\nIf the issue persists, please report it to an admin and include a screenshot of the console.", "Connection Error"); return; } } @@ -385,17 +398,17 @@ public void DoStart() } else { - Logger.Info("Proxy", "Proxy is ignored, because you turned it off"); + Logger.Info("Proxy", "Proxy is disabled as per user settings"); } } else { - Logger.Info("Proxy", "Proxy is ignored, because use official server"); + Logger.Info("Proxy", "Proxy is bypassed when using the official server"); } } else { - Logger.Info("Proxy", " Proxy is still running..."); + Logger.Info("Proxy", "Proxy is currently active and running"); } // For Cheat (tmp) @@ -407,11 +420,11 @@ public void DoStart() var get_file_cheat = API.GetCheat(selectedGame, GameChannel, VersionGame, cst_gamefile); if (get_file_cheat == null) { - MessageBox.Show("No cheats found for this version, please turn off the cheat feature to run the game."); + MessageBox.Show("No cheats are available for this game version. Please disable the cheat feature in the settings to launch the game.", "Cheat Unavailable", MessageBoxButtons.OK, MessageBoxIcon.Information); Extra_Cheat.Checked = false; return; } - cst_gamefile = get_file_cheat.launcher; + cst_gamefile = get_file_cheat.Launcher; WatchCheat = Path.GetFileNameWithoutExtension(cst_gamefile); Logger.Info("Cheat", $"RUN: Monitor {WatchCheat} at {cst_gamefile}"); @@ -425,13 +438,15 @@ public void DoStart() // For Game if (progress == null) { - progress = new Process(); - progress.StartInfo = new ProcessStartInfo + progress = new() { - FileName = cst_gamefile, - //UseShellExecute = true, - Arguments = "-server=" + set_server_host, // TODO: custom mod - WorkingDirectory = Path.GetDirectoryName(cst_gamefile), + StartInfo = new ProcessStartInfo + { + FileName = cst_gamefile, + //UseShellExecute = true, + Arguments = "-server=" + set_server_host, // TODO: custom mod + WorkingDirectory = Path.GetDirectoryName(cst_gamefile), + } }; try { @@ -445,7 +460,7 @@ public void DoStart() } else { - Logger.Info("Game", "Progress is still running..."); + Logger.Info("Game", "Game process is already running. Skipping launch."); } } @@ -469,12 +484,12 @@ public void InstallCert() // Close the store store.Close(); - Console.WriteLine("Certificate installed successfully."); + Logger.Info("Certificate", "Certificate installed successfully."); installationSucceeded = true; // Set flag to true to exit the loop } catch (Exception ex) { - Console.WriteLine("Error: " + ex.Message); + Logger.Error("Certificate", "Error: " + ex.Message); } } } @@ -488,7 +503,7 @@ public bool CheckVersionGame(GameType game_type) { var Get_Launcher = GetLauncherPath(game_type); - Logger.Info("Launcher", "Folder Launcher: " + Get_Launcher); + Logger.Info("Launcher", "Folder Launcher: " + (Get_Launcher == "" ? "Not Found" : Get_Launcher)); if (string.IsNullOrEmpty(Get_Launcher)) { @@ -546,7 +561,7 @@ public bool CheckVersionGame(GameType game_type) else { // jika game versi tidak di dukung atau tidak ada file - Logger.Error("Game", "No game files found!!!"); + Logger.Error("Game", $"No game executable found in the specified folder: {cst_folder_game}. Please ensure the game is properly installed."); return false; } @@ -556,9 +571,7 @@ public bool CheckVersionGame(GameType game_type) settings_genshin = new Game.Genshin.Settings(GameChannel); if (settings_genshin != null) { - Logger.Info("Game", "Game Text Language: " + settings_genshin.GetGameLanguage()); - Logger.Info("Game", "Game Voice Language: " + settings_genshin.GetVoiceLanguageID()); - Logger.Info("Game", "Game Server: " + settings_genshin.GetRegServerNameID()); + Logger.Info("Game", $"Game Settings - Text Language: {settings_genshin.GetGameLanguage()}, Voice Language: {settings_genshin.GetVoiceLanguageID()}, Server: {settings_genshin.GetRegServerNameID()}"); } } catch (Exception ex) @@ -582,15 +595,15 @@ public bool CheckVersionGame(GameType game_type) get_patch = API.GetMD5Game(Game_LOC_Original_MD5, game_type); if (get_patch == null) { - Logger.Error("Game", "No Support Game with MD5: " + Game_LOC_Original_MD5 + " (Send this log to admin)"); + Logger.Error("Game", $"Unsupported game version detected. MD5: {Game_LOC_Original_MD5}. Please report this to the admin."); return false; } - VersionGame = get_patch.version; + VersionGame = get_patch.Version; if (VersionGame == "0.0.0") { - Logger.Error("Game", "Version not supported: MD5 " + Game_LOC_Original_MD5); + Logger.Error("Game", $"Unsupported game version detected. MD5: {Game_LOC_Original_MD5}."); Get_LA_Version.Text = "Version: Unknown"; Get_LA_CH.Text = "Channel: Unknown"; @@ -600,103 +613,114 @@ public bool CheckVersionGame(GameType game_type) return false; } - var get_channel = get_patch.channel; + var get_channel = get_patch.Channel; // IF ALL OK Set_LA_GameFolder.Text = cst_folder_game; // Set Version - Get_LA_Version.Text = "Version: " + get_patch.version; + Get_LA_Version.Text = "Version: " + get_patch.Version; Get_LA_CH.Text = "Channel: " + get_channel; - Get_LA_REL.Text = "Release: " + get_patch.release; + Get_LA_REL.Text = "Release: " + get_patch.Release; - Logger.Info("Game", "Currently using version game " + VersionGame); - Logger.Info("Game", "File Game: " + PathfileGame); - Logger.Info("Game", "MD5 Game Currently: " + Game_LOC_Original_MD5); + Logger.Info("Game", $"Game version: {VersionGame}"); + Logger.Info("Game", $"Game executable path: {PathfileGame}"); + Logger.Info("Game", $"Game executable MD5 hash: {Game_LOC_Original_MD5}"); Get_LA_MD5.Text = "MD5: " + Game_LOC_Original_MD5; return true; } - public string PatchGame(bool patchit = true) + public bool PatchGame(bool patchit = true) { // check folder game (root) var root_folder = Set_LA_GameFolder.Text; - if (String.IsNullOrEmpty(root_folder)) + if (string.IsNullOrEmpty(root_folder)) { - return "No game folder found (1)"; + Logger.Error("PatchGame", "Game folder path is empty or null"); + return false; } if (!Directory.Exists(root_folder)) { - return "No game folder found (2)"; + Logger.Error("PatchGame", $"Game folder not found at path: {root_folder}"); + return false; } // check version if (get_patch == null) { - return "Can't find version, try clicking 'Get Key' in config tab"; - } + Logger.Error("PatchGame", "Unable to determine game version. Please click 'Get Key' in the config tab to retrieve version information."); + return false; + } if (VersionGame == "0.0.0") { - return "This Game Version is not compatible with this method patch"; + Logger.Error("PatchGame", "The current game version is not compatible with this patching method. Please ensure you have a supported game version."); + return false; } if (patchit) { // for patch - if (get_patch.patched != null && get_patch.patched.Any()) + if (get_patch.Patched != null && get_patch.Patched.Any()) { - foreach (var data in get_patch.patched) + foreach (var data in get_patch.Patched) { - var iss = PatchCopy(root_folder, data.file, data.location, data.md5, "patch", get_patch.version); - if (!String.IsNullOrEmpty(iss)) + var iss = PatchCopy(root_folder, data.File, data.Location, data.MD5, "patch", get_patch.Version); + if (!string.IsNullOrEmpty(iss)) { - return iss; + Logger.Error("PatchGame", $"Failed to patch file: {data.File}. Error: {iss}"); + return false; } } + Logger.Info("PatchGame", "Successfully patched all files"); } else { - Logger.Info("Patch", "no need for any patch"); + Logger.Info("PatchGame", "No files needed patching"); } } else { // for unpatch - if (get_patch.patched != null && get_patch.patched.Any()) + if (get_patch.Patched != null && get_patch.Patched.Any()) { - foreach (var data in get_patch.patched) + foreach (var data in get_patch.Patched) { - var iss = PatchCopy(root_folder, data.file, data.location, data.md5, "unpatch", get_patch.version); + var iss = PatchCopy(root_folder, data.File, data.Location, data.MD5, "unpatch", get_patch.Version); if (!String.IsNullOrEmpty(iss)) { - return iss; + Logger.Error("PatchGame", $"Failed to unpatch file: {data.File}. Error: {iss}"); + return false; } } + Logger.Info("PatchGame", "Successfully unpatched all files"); } else { - Logger.Info("Patch", "no files deleted"); + Logger.Info("PatchGame", "No files needed unpatching"); } - if (get_patch.original != null && get_patch.original.Any()) + if (get_patch.Original != null && get_patch.Original.Any()) { - foreach (var data in get_patch.original) + foreach (var data in get_patch.Original) { - var iss = PatchCopy(root_folder, data.file, data.location, data.md5, "original", get_patch.version); - if (!String.IsNullOrEmpty(iss)) + var iss = PatchCopy(root_folder, data.File, data.Location, data.MD5, "original", get_patch.Version); + if (!string.IsNullOrEmpty(iss)) { - return iss; + Logger.Error("PatchGame", $"Failed to restore original file: {data.File}. Error: {iss}"); + return false; } } + Logger.Info("PatchGame", "Successfully restored all original files"); } else { - Logger.Info("Patch", "no files restored to original"); + Logger.Info("PatchGame", "No original files needed restoring"); } } - return ""; + Logger.Info("PatchGame", $"Game {(patchit ? "patched" : "unpatched")} successfully"); + return true; } private void Set_LA_Select_Click(object sender, EventArgs e) @@ -705,19 +729,30 @@ private void Set_LA_Select_Click(object sender, EventArgs e) if (!string.IsNullOrEmpty(Folder_Game_Now)) { Set_LA_GameFolder.Text = Folder_Game_Now; - if (!CheckVersionGame(default_profile.game.type)) + Logger.Info("Game Folder", $"Selected game folder: {Folder_Game_Now}"); + if (!CheckVersionGame(DefaultProfile.GameConfig.type)) { - MessageBox.Show("This game version may not be supported please check your console!!!"); - Process.Start(new ProcessStartInfo(API.WEB_LINK + "/game/" + default_profile.game.type.SEOUrl()) { UseShellExecute = true }); + string message = $"The game version in {Folder_Game_Now} may not be supported. Please check the console for more details."; + Logger.Warning("Game Version", message); + MessageBox.Show(message, "Game Version", MessageBoxButtons.OK, MessageBoxIcon.Error); + + string url = API.WEB_LINK + "/game/" + DefaultProfile.GameConfig.type.SEOUrl(); + Logger.Info("Browser", $"Opening URL for game support: {url}"); + Process.Start(new ProcessStartInfo(url) { UseShellExecute = true }); + } + else + { + Logger.Info("Game Version", "Game version check passed successfully."); } } else { - MessageBox.Show("No game folder found"); + Logger.Error("Game Folder", "No game folder was selected or found."); + MessageBox.Show("No game folder found. Please select a valid game folder."); } } - public string PatchCopy(string root_folder, string url_file, string file_name, string file_md5, string iscopy, string version) + public static string PatchCopy(string root_folder, string url_file, string file_name, string file_md5, string iscopy, string version) { string fileSave = Path.Combine(root_folder, file_name); @@ -726,12 +761,12 @@ public string PatchCopy(string root_folder, string url_file, string file_name, s try { File.Delete(fileSave); - Logger.Info("Patch", $"File remove {fileSave}"); + Logger.Info("Patch", $"Successfully removed file: {fileSave}"); return ""; } catch (Exception e) { - Logger.Error("Patch", $"File remove error {fileSave} > {e.Message}"); + Logger.Error("Patch", $"Failed to remove file: {fileSave}. Error: {e.Message}"); return e.Message; } } @@ -739,23 +774,23 @@ public string PatchCopy(string root_folder, string url_file, string file_name, s if (File.Exists(fileSave)) { var md5_file_raw = Tool.CalculateMD5(fileSave); - if(md5_file_raw == file_md5) + if (md5_file_raw == file_md5) { - Logger.Info("Patch", $"File {fileSave} this already exists and md5 is accurate so no action is needed for {iscopy}"); + Logger.Info("Patch", $"File '{fileSave}' already exists with matching MD5. No action needed for '{iscopy}' operation."); return ""; } - } + } var backupPatch = Path.Combine(Config.Modfolder, "i", version, iscopy, file_name); if (File.Exists(backupPatch)) { var md5_file_raw = Tool.CalculateMD5(backupPatch); - if(md5_file_raw == file_md5) + if (md5_file_raw == file_md5) { Logger.Info("Patch", $"Found backup {iscopy} > {backupPatch} > {fileSave}"); - string saveDir = Path.GetDirectoryName(fileSave); - if (!Directory.Exists(saveDir)) + string saveDir = Path.GetDirectoryName(fileSave) ?? string.Empty; + if (!string.IsNullOrEmpty(saveDir) && !Directory.Exists(saveDir)) { Directory.CreateDirectory(saveDir); } @@ -766,9 +801,9 @@ public string PatchCopy(string root_folder, string url_file, string file_name, s { // skip ? } - } + } - Logger.Info("Patch", $"Start download {url_file} and save to {fileSave} for {iscopy}"); + Logger.Info("Patch", $"Initiating download for {iscopy}: URL: {url_file}, Destination: {fileSave}"); var CEKDL1 = new Download(url_file, fileSave); if (CEKDL1.ShowDialog() != DialogResult.OK) @@ -777,11 +812,11 @@ public string PatchCopy(string root_folder, string url_file, string file_name, s } else { - var md5_file = Tool.CalculateMD5(fileSave); + var md5_file = Tool.CalculateMD5(fileSave); if (md5_file == file_md5) { - string backupDir = Path.GetDirectoryName(backupPatch); - if (!Directory.Exists(backupDir)) + string backupDir = Path.GetDirectoryName(backupPatch) ?? string.Empty; + if (!string.IsNullOrEmpty(backupDir) && !Directory.Exists(backupDir)) { Directory.CreateDirectory(backupDir); } @@ -800,101 +835,97 @@ public string PatchCopy(string root_folder, string url_file, string file_name, s public void CheckUpdate() { - Logger.Info("Game", "Check update..."); - var version = Assembly.GetExecutingAssembly().GetName().Version; - string ver = ""; - if (version != null) + try { - ver = version.ToString(); - Set_Version.Text = "Version: " + ver; - var GetDataUpdate = API.GetUpdate(); - if (GetDataUpdate != null) + Logger.Info("Game", "Checking for launcher updates..."); + var version = Assembly.GetExecutingAssembly().GetName().Version; + if (version == null) { - var judul = "New Update: " + GetDataUpdate.name; // is dev or nightly or name update - var name_version = GetDataUpdate.tag_name; // version name - var infobody = GetDataUpdate.body; // info + SetVersion.Text = "Version: Unknown"; + return; + } - var version1 = new Version(name_version); - var version2 = new Version(ver); + string ver = version.ToString(); + SetVersion.Text = "Version: " + ver; - var result = version1.CompareTo(version2); + var GetDataUpdate = API.GetUpdate(); + if (GetDataUpdate == null) return; - if (result > 0) - { - // versi 1 lebih besar - Set_Version.Text = "Version: " + ver + " (New Update: " + name_version + " )"; - var tes = MessageBox.Show(infobody, judul, MessageBoxButtons.YesNo, MessageBoxIcon.Question); - if (tes == DialogResult.Yes) - { - var url_dl = ""; - foreach (var file in GetDataUpdate.assets) - { - if (file.name == "YuukiPSLauncherPC.zip" || file.name == "YuukiPS.zip" || file.name == "update.zip") - { - url_dl = file.browser_download_url; - break; - } - } - if (!string.IsNullOrEmpty(url_dl)) - { - var DL1 = new Download(url_dl, Json.Config.CurrentlyPath + @"\update.zip"); - if (DL1.ShowDialog() == DialogResult.OK) - { - // update - var file_update = Json.Config.CurrentlyPath + @"\update.bat"; - try - { - //buat bat - var w = new StreamWriter(file_update); - w.WriteLine("@echo off"); - - //kill all - w.WriteLine("Taskkill /IM YuukiPS.exe /F"); - //w.WriteLine("Taskkill /IM YuukiPS.vshost.exe /F"); - - // Unzip file - w.WriteLine("echo unzip file..."); - w.WriteLine("tar -xf update.zip"); - - //delete file old - w.WriteLine("echo delete file old"); - w.WriteLine("del update.zip"); - - //start bot - w.WriteLine("echo Update done, start back..."); - w.WriteLine("timeout 5 > NUL"); - w.WriteLine("start YuukiPS.exe"); - w.WriteLine("del Update.bat"); - w.Close(); - //open bat - Process.Start(file_update); - } - catch (Exception ex) - { - MessageBox.Show(ex.Message); - } - } - } - else - { - // update batal - } + var name_version = GetDataUpdate.TagName; + if (!Version.TryParse(name_version, out var version1) || !Version.TryParse(ver, out var version2)) + { + Logger.Error("Update", "Unable to compare version numbers. This might be due to an unexpected version format."); + MessageBox.Show("We encountered an issue while checking for updates. The version numbers couldn't be compared correctly.", "Update Check Error", MessageBoxButtons.OK, MessageBoxIcon.Warning); + return; + } - } - } - else if (result < 0) - { - Set_Version.Text = "Version: " + ver + " (latest nightly) (Official: " + name_version + ")"; - } - else + var result = version1.CompareTo(version2); + + if (result > 0) + { + SetVersion.Text = $"Version: {ver} (New Update: {name_version})"; + var tes = MessageBox.Show(GetDataUpdate.Body, $"New Update: {GetDataUpdate.Name}", MessageBoxButtons.YesNo, MessageBoxIcon.Question); + if (tes == DialogResult.Yes) { - Set_Version.Text = "Version: " + ver + " (latest public)"; + PerformUpdate(GetDataUpdate.Assets); } } + else if (result < 0) + { + SetVersion.Text = $"Version: {ver} (latest nightly) (Official: {name_version})"; + } + else + { + SetVersion.Text = $"Version: {ver} (latest public)"; + } } - else + catch (Exception ex) + { + Logger.Error("Update", $"Error checking for updates: {ex.Message}"); + MessageBox.Show($"An error occurred while checking for updates: {ex.Message}", "Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private static void PerformUpdate(IEnumerable assets) + { + try + { + var url_dl = assets.FirstOrDefault(file => + file.Name == "YuukiPSLauncherPC.zip" || + file.Name == "YuukiPS.zip" || + file.Name == "update.zip")?.BrowserDownloadUrl; + + if (string.IsNullOrEmpty(url_dl)) + { + MessageBox.Show("Update file not found.", "Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + var updateZipPath = Path.Combine(Json.Config.CurrentlyPath, "update.zip"); + var DL1 = new Download(url_dl, updateZipPath); + if (DL1.ShowDialog() != DialogResult.OK) return; + + var file_update = Path.Combine(Json.Config.CurrentlyPath, "update.bat"); + using (var w = new StreamWriter(file_update)) + { + w.WriteLine("@echo off"); + w.WriteLine("Taskkill /IM YuukiPS.exe /F"); + Logger.Info("Update", "Extracting update files..."); + w.WriteLine("tar -xf update.zip"); + Logger.Info("Update", "Removing temporary update file..."); + w.WriteLine("del update.zip"); + Logger.Info("Update", "Update completed. Restarting application..."); + w.WriteLine("timeout 5 > NUL"); + w.WriteLine("start YuukiPS.exe"); + w.WriteLine("del Update.bat"); + } + + Process.Start(file_update); + } + catch (Exception ex) { - Set_Version.Text = "Version: Unknown"; + Logger.Error("Update", $"Error performing update: {ex.Message}"); + MessageBox.Show($"An error occurred during the update process: {ex.Message}", "Update Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } @@ -968,7 +999,7 @@ private static string SelectGamePath() return foldPath; } - public void IsAcess(bool onoff) + public void IsAccess(bool onoff) { GetTypeGame.Enabled = onoff; btStartOfficialServer.Enabled = onoff; @@ -989,9 +1020,8 @@ private void CheckGameRun_Tick(object sender, EventArgs e) // Jika Game tidak berjalan.... IsGameRun = false; btStartNormal.Text = "Launch"; - IsAcess(true); - - AllStop(); + IsAccess(true); + // AllStop(); // Revert to original version every game close if (!DoneCheck) @@ -999,16 +1029,13 @@ private void CheckGameRun_Tick(object sender, EventArgs e) Console.WriteLine("Game detected stopped"); DoneCheck = true; StopGame(); // this shouldn't be necessary but just let it be - - var unpatch = PatchGame(false); - if (!string.IsNullOrEmpty(unpatch)) - { - Logger.Info("Game", unpatch); - } + StopProxy(); + + PatchGame(false); if (Enable_WipeLoginCache.Checked) { - Tool.WipeLogin(default_profile.game.type); + Tool.WipeLogin(DefaultProfile.GameConfig.type); } if (Enable_RPC.Checked) @@ -1023,7 +1050,7 @@ private void CheckGameRun_Tick(object sender, EventArgs e) IsGameRun = true; btStartNormal.Text = "Stop"; DoneCheck = false; - IsAcess(false); + IsAccess(false); if (Enable_RPC.Checked) { @@ -1035,20 +1062,30 @@ private void CheckGameRun_Tick(object sender, EventArgs e) public void AllStop() { - StopProxy(); - StopGame(); + try + { + StopProxy(); + StopGame(); + } + catch (Exception e) + { + Logger.Error("AllStop", "There was an error occurred when stopping the game and proxy: " + e.Message); + } } + public void StopProxy() { try { + if (proxy == null) return; proxy.Stop(); proxy = null; - Logger.Info("Proxy", "Proxy Stop...."); + Logger.Info("Proxy", "Proxy stopped"); } - catch (Exception ex) { - // skip + catch (Exception e) + { + Logger.Error("Proxy", "There was an error stopping the proxy: " + e.Message); } } @@ -1216,5 +1253,74 @@ private void wipeLoginCacheInfo_Click(object sender, EventArgs e) { MessageBox.Show("This deletes the login cache every time the game closes (logs you out).\nThis is useful if you use the guest account on HSR servers, since you don't have to remember to log out.", "Information.", MessageBoxButtons.OK, MessageBoxIcon.Question); } + + private void Get_LA_MD5_Click(object sender, EventArgs e) + { + string md5 = Tool.CalculateMD5(PathfileGame); + if (string.IsNullOrEmpty(md5)) + { + MessageBox.Show("Failed to get MD5 hash. Please try again."); + return; + }; + + using var md5Form = new Form + { + Text = "Game Executable MD5", + Size = new Size(400, 200), + FormBorderStyle = FormBorderStyle.FixedDialog, + StartPosition = FormStartPosition.CenterScreen, + BackColor = Color.FromArgb(45, 45, 48) + }; + + var label = new Label + { + Text = "MD5 Hash", + Font = new Font("Segoe UI", 16, FontStyle.Bold), + ForeColor = Color.White, + AutoSize = true + }; + + var textBox = new TextBox + { + Text = md5, + Font = new Font("Consolas", 12), + ForeColor = Color.LightGreen, + BackColor = Color.FromArgb(30, 30, 30), + BorderStyle = BorderStyle.None, + Size = new Size(360, 30), + ReadOnly = true + }; + + var button = new Button + { + Text = "Copy to Clipboard", + FlatStyle = FlatStyle.Flat, + ForeColor = Color.White, + BackColor = Color.FromArgb(0, 122, 204), + Size = new Size(360, 40), + Cursor = Cursors.Hand + }; + + md5Form.Controls.AddRange(new Control[] { label, textBox, button }); + + // Center the controls + int startY = (md5Form.ClientSize.Height - (label.Height + textBox.Height + button.Height + 20)) / 2; + label.Location = new Point((md5Form.ClientSize.Width - label.Width) / 2, startY); + textBox.Location = new Point((md5Form.ClientSize.Width - textBox.Width) / 2, label.Bottom + 10); + button.Location = new Point((md5Form.ClientSize.Width - button.Width) / 2, textBox.Bottom + 10); + + button.Click += (_, _) => + { + Clipboard.SetText(md5); + MessageBox.Show("MD5 hash copied to clipboard.", "Copied", MessageBoxButtons.OK, MessageBoxIcon.Information); + }; + + md5Form.ShowDialog(); + } + + private void groupBox3_Enter(object sender, EventArgs e) + { + + } } } diff --git a/Main.resx b/Main.resx index ab8a6d3..1385230 100644 --- a/Main.resx +++ b/Main.resx @@ -1,7 +1,7 @@