From 2e18317f3f2b3147e60313bfbacaa219c3c30e6c Mon Sep 17 00:00:00 2001 From: BruceChen Date: Fri, 7 Oct 2022 15:40:38 +0800 Subject: [PATCH] Trim & Bug fix --- MinecraftClient/ChatBots/Map.cs | 33 +++++-- MinecraftClient/Program.cs | 67 +++++++------- MinecraftClient/Resources/lang/en.ini | 1 + MinecraftClient/Resources/lang/zh-Hans.ini | 1 + MinecraftClient/Resources/lang/zh-Hant.ini | 1 + MinecraftClient/Translations.cs | 14 --- MinecraftClient/WinAPI/ConsoleIcon.cs | 71 +++++++------- MinecraftClient/WinAPI/WindowsVersion.cs | 102 --------------------- README.md | 8 +- 9 files changed, 102 insertions(+), 196 deletions(-) delete mode 100644 MinecraftClient/WinAPI/WindowsVersion.cs diff --git a/MinecraftClient/ChatBots/Map.cs b/MinecraftClient/ChatBots/Map.cs index 83fc3dc1..299c48a6 100644 --- a/MinecraftClient/ChatBots/Map.cs +++ b/MinecraftClient/ChatBots/Map.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.Versioning; using MinecraftClient.Mapping; using MinecraftClient.Protocol.Handlers; using Tomlet.Attributes; @@ -94,15 +96,22 @@ namespace MinecraftClient.ChatBots if (!cachedMaps.ContainsKey(mapId)) return Translations.TryGet("bot.map.cmd.not_found", mapId); - try + if (OperatingSystem.IsWindows()) { - McMap map = cachedMaps[mapId]; - GenerateMapImage(map); + try + { + McMap map = cachedMaps[mapId]; + GenerateMapImage(map); + } + catch (Exception e) + { + LogDebugToConsole(e.StackTrace!); + return Translations.TryGet("bot.map.failed_to_render", mapId); + } } - catch (Exception e) + else { - LogDebugToConsole(e.StackTrace!); - return Translations.TryGet("bot.map.failed_to_render", mapId); + LogToConsoleTranslated("bot.map.windows_only"); } return ""; @@ -152,9 +161,15 @@ namespace MinecraftClient.ChatBots } if (Config.Auto_Render_On_Update) - GenerateMapImage(map); + { + if (OperatingSystem.IsWindows()) + GenerateMapImage(map); + else + LogToConsoleTranslated("bot.map.windows_only"); + } } + [SupportedOSPlatform("windows")] private void GenerateMapImage(McMap map) { string fileName = baseDirectory + "/Map_" + map.MapId + ".jpg"; @@ -162,6 +177,8 @@ namespace MinecraftClient.ChatBots if (File.Exists(fileName)) File.Delete(fileName); + /** Warning CA1416: Bitmap is only support Windows **/ + /* https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only */ Bitmap image = new(map.Width, map.Height); for (int x = 0; x < map.Width; ++x) @@ -189,6 +206,8 @@ namespace MinecraftClient.ChatBots image.Save(fileName); LogToConsole(Translations.TryGet("bot.map.rendered", map.MapId, fileName)); } + + [SupportedOSPlatform("windows")] private Bitmap ResizeBitmap(Bitmap sourceBMP, int width, int height) { Bitmap result = new(width, height); diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs index 03d898c3..211b4acc 100644 --- a/MinecraftClient/Program.cs +++ b/MinecraftClient/Program.cs @@ -64,10 +64,10 @@ namespace MinecraftClient _ = "a".ToLower(); //Take advantage of Windows 10 / Mac / Linux UTF-8 console - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (OperatingSystem.IsWindows()) { // If we're on windows, check if our version is Win10 or greater. - if (WindowsVersion.WinMajorVersion >= 10) + if (OperatingSystem.IsWindowsVersionAtLeast(10)) Console.OutputEncoding = Console.InputEncoding = Encoding.UTF8; } else @@ -429,43 +429,13 @@ namespace MinecraftClient if (result == ProtocolHandler.LoginResult.Success) { - if (Config.Main.General.AccountType == LoginType.microsoft && InternalConfig.Password != "-" && Config.Signature.LoginWithSecureProfile) - { - // Load cached profile key from disk if necessary - if (Config.Main.Advanced.ProfileKeyCache == CacheType.disk) - { - bool cacheKeyLoaded = KeysCache.InitializeDiskCache(); - if (Config.Logging.DebugMessages) - Translations.WriteLineFormatted(cacheKeyLoaded ? "debug.keys_cache_ok" : "debug.keys_cache_fail"); - } - - if (Config.Main.Advanced.ProfileKeyCache != CacheType.none && KeysCache.Contains(loginLower)) - { - playerKeyPair = KeysCache.Get(loginLower); - if (playerKeyPair.NeedRefresh()) - Translations.WriteLineFormatted("mcc.profile_key_invalid"); - else - ConsoleIO.WriteLineFormatted(Translations.Get("mcc.profile_key_valid", session.PlayerName)); - } - - if (playerKeyPair == null || playerKeyPair.NeedRefresh()) - { - Translations.WriteLineFormatted("mcc.fetching_key"); - playerKeyPair = KeyUtils.GetNewProfileKeys(session.ID); - if (Config.Main.Advanced.ProfileKeyCache != CacheType.none && playerKeyPair != null) - { - KeysCache.Store(loginLower, playerKeyPair); - } - } - } - InternalConfig.Username = session.PlayerName; bool isRealms = false; if (Config.Main.Advanced.ConsoleTitle != "") Console.Title = Config.AppVar.ExpandVars(Config.Main.Advanced.ConsoleTitle); - if (Config.Main.Advanced.PlayerHeadAsIcon) + if (Config.Main.Advanced.PlayerHeadAsIcon && OperatingSystem.IsWindows()) ConsoleIcon.SetPlayerIconAsync(InternalConfig.Username); if (Config.Logging.DebugMessages) @@ -555,6 +525,37 @@ namespace MinecraftClient } } + if (Config.Main.General.AccountType == LoginType.microsoft && InternalConfig.Password != "-" && + Config.Signature.LoginWithSecureProfile && protocolversion >= 759 /* 1.19 and above */) + { + // Load cached profile key from disk if necessary + if (Config.Main.Advanced.ProfileKeyCache == CacheType.disk) + { + bool cacheKeyLoaded = KeysCache.InitializeDiskCache(); + if (Config.Logging.DebugMessages) + Translations.WriteLineFormatted(cacheKeyLoaded ? "debug.keys_cache_ok" : "debug.keys_cache_fail"); + } + + if (Config.Main.Advanced.ProfileKeyCache != CacheType.none && KeysCache.Contains(loginLower)) + { + playerKeyPair = KeysCache.Get(loginLower); + if (playerKeyPair.NeedRefresh()) + Translations.WriteLineFormatted("mcc.profile_key_invalid"); + else + ConsoleIO.WriteLineFormatted(Translations.Get("mcc.profile_key_valid", session.PlayerName)); + } + + if (playerKeyPair == null || playerKeyPair.NeedRefresh()) + { + Translations.WriteLineFormatted("mcc.fetching_key"); + playerKeyPair = KeyUtils.GetNewProfileKeys(session.ID); + if (Config.Main.Advanced.ProfileKeyCache != CacheType.none && playerKeyPair != null) + { + KeysCache.Store(loginLower, playerKeyPair); + } + } + } + //Force-enable Forge support? if (!isRealms && (Config.Main.Advanced.EnableForge == ForgeConfigType.force) && forgeInfo == null) { diff --git a/MinecraftClient/Resources/lang/en.ini b/MinecraftClient/Resources/lang/en.ini index 16027d07..e1dd2175 100644 --- a/MinecraftClient/Resources/lang/en.ini +++ b/MinecraftClient/Resources/lang/en.ini @@ -584,6 +584,7 @@ bot.map.received_map=Received a new Map, with Id: {0} bot.map.rendered=Succesfully rendered a map with id '{0}' to: '{1}' bot.map.failed_to_render=Failed to render the map with id: '{0}' bot.map.list_item=- Map id: {0} (Last Updated: {1}) +bot.map.windows_only=Save to file is currently only available for the windows platform. # ReplayCapture bot.replayCapture.cmd=replay command diff --git a/MinecraftClient/Resources/lang/zh-Hans.ini b/MinecraftClient/Resources/lang/zh-Hans.ini index 7c657036..d2cee54b 100644 --- a/MinecraftClient/Resources/lang/zh-Hans.ini +++ b/MinecraftClient/Resources/lang/zh-Hans.ini @@ -584,6 +584,7 @@ bot.map.received_map=收到一个编号为 {0} 的新地图。 bot.map.rendered=成功接收到地图 '{0}' ,保存为 '{1}' bot.map.failed_to_render=无法渲染编号为 '{0}' 的地图。 bot.map.list_item=- 地图编号:{0}(最近更新于:{1}) +bot.map.windows_only=保存地图到文件功能目前仅可用于Windows平台。 # ReplayCapture bot.replayCapture.cmd=replay 命令 diff --git a/MinecraftClient/Resources/lang/zh-Hant.ini b/MinecraftClient/Resources/lang/zh-Hant.ini index d45f10f7..cdebf7e7 100644 --- a/MinecraftClient/Resources/lang/zh-Hant.ini +++ b/MinecraftClient/Resources/lang/zh-Hant.ini @@ -584,6 +584,7 @@ bot.map.received_map=收到一個編號為 {0} 的新地圖。 bot.map.rendered=成功接收到地圖 '{0}' ,儲存為 '{1}' bot.map.failed_to_render=無法渲染編號為 '{0}' 的地圖。 bot.map.list_item=- 地圖編號:{0}(最近更新於:{1}) +bot.map.windows_only=儲存地圖到檔案功能目前僅可用於Windows平臺。 # ReplayCapture bot.replayCapture.cmd=replay 命令 diff --git a/MinecraftClient/Translations.cs b/MinecraftClient/Translations.cs index 20b0f89a..e6ee6628 100644 --- a/MinecraftClient/Translations.cs +++ b/MinecraftClient/Translations.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Drawing.Drawing2D; using System.Globalization; using System.IO; using System.Text; @@ -18,7 +17,6 @@ namespace MinecraftClient { private static readonly Dictionary translations = new(); private static readonly string translationFilePath = "lang" + Path.DirectorySeparatorChar + "mcc"; - private static readonly string defaultTranslation = "en.ini"; private static readonly Regex translationKeyRegex = new(@"\(\[(.*?)\]\)", RegexOptions.Compiled); // Extract string inside ([ ]) /// @@ -645,18 +643,6 @@ namespace MinecraftClient return translations; } - /// - /// Write the default translation file (English) to the disk. - /// - private static void WriteDefaultTranslation() - { - string defaultPath = AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + translationFilePath + Path.DirectorySeparatorChar + defaultTranslation; - - if (!Directory.Exists(translationFilePath)) - Directory.CreateDirectory(translationFilePath); - File.WriteAllText(defaultPath, DefaultConfigResource.Translation_en, Encoding.UTF8); - } - public static void TrimAllTranslations() { string[] transEn = DefaultConfigResource.ResourceManager.GetString("Translation_en")! diff --git a/MinecraftClient/WinAPI/ConsoleIcon.cs b/MinecraftClient/WinAPI/ConsoleIcon.cs index 36492f7c..f3f574e1 100644 --- a/MinecraftClient/WinAPI/ConsoleIcon.cs +++ b/MinecraftClient/WinAPI/ConsoleIcon.cs @@ -3,6 +3,7 @@ using System.Drawing; using System.IO; using System.Net.Http; using System.Runtime.InteropServices; +using System.Runtime.Versioning; using System.Threading; using System.Threading.Tasks; @@ -42,56 +43,54 @@ namespace MinecraftClient.WinAPI /// /// Asynchronously download the player's skin and set the head as console icon /// + [SupportedOSPlatform("windows")] public static void SetPlayerIconAsync(string playerName) { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + Thread t = new(new ThreadStart(delegate { - Thread t = new(new ThreadStart(delegate + HttpClient httpClient = new(); + try { - HttpClient httpClient = new(); + Task httpWebRequest = httpClient.GetStreamAsync("https://minotar.net/helm/" + playerName + "/100.png"); + httpWebRequest.Wait(); + Stream imageStream = httpWebRequest.Result; try { - Task httpWebRequest = httpClient.GetStreamAsync("https://minotar.net/helm/" + playerName + "/100.png"); - httpWebRequest.Wait(); - Stream imageStream = httpWebRequest.Result; - try - { - Bitmap skin = new(Image.FromStream(imageStream)); //Read skin from network - SetWindowIcon(Icon.FromHandle(skin.GetHicon())); // Windows 10+ (New console) - SetConsoleIcon(skin.GetHicon()); // Windows 8 and lower (Older console) - } - catch (ArgumentException) - { - /* Invalid image in HTTP response */ - } - imageStream.Dispose(); - httpWebRequest.Dispose(); + Bitmap skin = new(Image.FromStream(imageStream)); //Read skin from network + SetWindowIcon(Icon.FromHandle(skin.GetHicon())); // Windows 10+ (New console) + SetConsoleIcon(skin.GetHicon()); // Windows 8 and lower (Older console) } - catch (AggregateException ae) + catch (ArgumentException) { - foreach (var ex in ae.InnerExceptions) - { - if (ex is HttpRequestException) //Skin not found? Reset to default icon - RevertToMCCIcon(); - else - throw ex; - } + /* Invalid image in HTTP response */ } - catch (HttpRequestException) //Skin not found? Reset to default icon + imageStream.Dispose(); + httpWebRequest.Dispose(); + } + catch (AggregateException ae) + { + foreach (var ex in ae.InnerExceptions) { - RevertToMCCIcon(); - } - finally - { - httpClient.Dispose(); + if (ex is HttpRequestException) //Skin not found? Reset to default icon + RevertToMCCIcon(); + else + throw ex; } } - )) + catch (HttpRequestException) //Skin not found? Reset to default icon { - Name = "Player skin icon setter" - }; - t.Start(); + RevertToMCCIcon(); + } + finally + { + httpClient.Dispose(); + } } + )) + { + Name = "Player skin icon setter" + }; + t.Start(); } /// diff --git a/MinecraftClient/WinAPI/WindowsVersion.cs b/MinecraftClient/WinAPI/WindowsVersion.cs deleted file mode 100644 index 414c7d49..00000000 --- a/MinecraftClient/WinAPI/WindowsVersion.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.Globalization; -using System.Runtime.InteropServices; -using Microsoft.Win32; - -namespace MinecraftClient.WinAPI -{ - /// - /// Retrieve information about the current Windows version - /// - /// - /// Environment.OSVersion does not work with Windows 10. - /// It returns 6.2 which is Windows 8 - /// - /// - /// https://stackoverflow.com/a/37755503 - /// - class WindowsVersion - { - /// - /// Returns the Windows major version number for this computer. - /// - public static uint WinMajorVersion - { - get - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // The 'CurrentMajorVersionNumber' string value in the CurrentVersion key is new for Windows 10, - // and will most likely (hopefully) be there for some time before MS decides to change this - again... - if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMajorVersionNumber", out dynamic? major)) - return (uint)major; - - // When the 'CurrentMajorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' - if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out dynamic? version)) - return 0; - - var versionParts = ((string)version!).Split('.'); - if (versionParts.Length != 2) return 0; - return uint.TryParse(versionParts[0], NumberStyles.Any, CultureInfo.CurrentCulture, out uint majorAsUInt) ? majorAsUInt : 0; - } - - return 0; - } - } - - /// - /// Returns the Windows minor version number for this computer. - /// - public static uint WinMinorVersion - { - get - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - // The 'CurrentMinorVersionNumber' string value in the CurrentVersion key is new for Windows 10, - // and will most likely (hopefully) be there for some time before MS decides to change this - again... - if (TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentMinorVersionNumber", out dynamic? minor)) - return (uint)minor; - - // When the 'CurrentMinorVersionNumber' value is not present we fallback to reading the previous key used for this: 'CurrentVersion' - if (!TryGetRegistryKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion", "CurrentVersion", out dynamic? version)) - return 0; - - var versionParts = ((string)version!).Split('.'); - if (versionParts.Length != 2) return 0; - return uint.TryParse(versionParts[1], NumberStyles.Any, CultureInfo.CurrentCulture, out uint minorAsUInt) ? minorAsUInt : 0; - } - - return 0; - } - } - - /// - /// Try retrieving a registry key - /// - /// key path - /// Key - /// Value (output) - /// TRUE if successfully retrieved - private static bool TryGetRegistryKey(string path, string key, out dynamic? value) - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - value = null; - try - { - var rk = Registry.LocalMachine.OpenSubKey(path); - if (rk == null) return false; - value = rk.GetValue(key); - return value != null; - } - catch - { - return false; - } - } - - value = null; - return false; - } - } -} diff --git a/README.md b/README.md index 579e45df..d70d0414 100644 --- a/README.md +++ b/README.md @@ -50,11 +50,11 @@ If you'd like to contribute to Minecraft Console Client, great, just fork the re Check out: [How to update or add translations for MCC](https://mccteam.github.io/guide/contibuting.html#translations). MCC now supports the following languages (Alphabetical order) : - * `de.ini` (57.69% translated) : Deutsch - German + * `de.ini` (57.30% translated) : Deutsch - German * `en.ini` : English - English - * `fr.ini` (57.69% translated) : Français (France) - French - * `ru.ini` (56.77% translated) : Русский (Russkiy) - Russian - * `vi.ini` (56.77% translated) : Tiếng Việt (Việt Nam) - Vietnamese + * `fr.ini` (57.30% translated) : Français (France) - French + * `ru.ini` (56.36% translated) : Русский (Russkiy) - Russian + * `vi.ini` (56.36% translated) : Tiếng Việt (Việt Nam) - Vietnamese * `zh-Hans.ini` (100.00% translated) : 简体中文 - Chinese Simplified * `zh-Hant.ini` (100.00% translated) : 繁體中文 - Chinese Traditional