diff --git a/MinecraftLaunch.Test/Program.cs b/MinecraftLaunch.Test/Program.cs index e33ab41..e47b49b 100644 --- a/MinecraftLaunch.Test/Program.cs +++ b/MinecraftLaunch.Test/Program.cs @@ -1,15 +1,15 @@ using MinecraftLaunch.Components.Authenticator; +using MinecraftLaunch.Components.Checker; +using MinecraftLaunch.Components.Resolver; +using System.Diagnostics; -MicrosoftAuthenticator authenticator = new("9fd44410-8ed7-4eb3-a160-9f1cc62c824c"); +string gameFolder = "C:\\Users\\w\\Desktop\\temp\\.minecraft"; -var result = await authenticator.DeviceFlowAuthAsync(x => { - Console.WriteLine(x.UserCode); -}); +GameResolver resolver = new(gameFolder); +var gameEntry = resolver.GetGameEntity("1.12.2"); -if(result != null) { - var account = await authenticator.AuthenticateAsync(); - Console.WriteLine(account.Name); - Console.WriteLine(account.Uuid); -} +ResourceChecker checker = new(gameEntry); +var result = await checker.CheckAsync(); +Console.WriteLine(result); Console.ReadKey(); \ No newline at end of file diff --git a/MinecraftLaunch/Components/Authenticator/MicrosoftAuthenticator.cs b/MinecraftLaunch/Components/Authenticator/MicrosoftAuthenticator.cs index 99b300c..a79de89 100644 --- a/MinecraftLaunch/Components/Authenticator/MicrosoftAuthenticator.cs +++ b/MinecraftLaunch/Components/Authenticator/MicrosoftAuthenticator.cs @@ -100,8 +100,8 @@ public async ValueTask AuthenticateAsync() { using var authenticateMinecraftPostRes = await $"https://api.minecraftservices.com/authentication/login_with_xbox" .PostJsonAsync(authenticateMinecraftContent); - string access_token = JsonNode.Parse(await authenticateMinecraftPostRes.GetStringAsync())!["access_token"]! - .GetValue(); + string access_token = JsonNode.Parse(await authenticateMinecraftPostRes.GetStringAsync()) + .GetString("access_token"); /* * Check player's minecraft ownership (optional steps) @@ -192,7 +192,7 @@ public async Task DeviceFlowAuthAsync(Action() is "Bearer") { + if (tempTokenResponse.GetString("token_type") is "Bearer") { _oAuth2TokenResponse = tokenResponse; return tokenResponse; } diff --git a/MinecraftLaunch/Components/Converter/PlatformEnumToStringJsonConverter.cs b/MinecraftLaunch/Components/Converter/PlatformEnumToStringJsonConverter.cs new file mode 100644 index 0000000..0880b80 --- /dev/null +++ b/MinecraftLaunch/Components/Converter/PlatformEnumToStringJsonConverter.cs @@ -0,0 +1,21 @@ +using MinecraftLaunch.Classes.Enums; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace MinecraftLaunch.Components.Converter { + public class PlatformEnumToStringJsonConverter : JsonConverter { + public override Platform Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { + var platform = reader.GetString(); + return platform switch { + "osx" => Platform.osx, + "linux" => Platform.linux, + "windows" => Platform.windows, + _ => Platform.windows, + }; + } + + public override void Write(Utf8JsonWriter writer, Platform value, JsonSerializerOptions options) { + writer.WriteStringValue(value.ToString()); + } + } +} diff --git a/MinecraftLaunch/Components/Fetcher/CurseForgeFetcher.cs b/MinecraftLaunch/Components/Fetcher/CurseForgeFetcher.cs index b661424..7a3be28 100644 --- a/MinecraftLaunch/Components/Fetcher/CurseForgeFetcher.cs +++ b/MinecraftLaunch/Components/Fetcher/CurseForgeFetcher.cs @@ -1,7 +1,8 @@ -using MinecraftLaunch.Classes.Interfaces; -using MinecraftLaunch.Classes.Models.Download; -using System.Text.Json; +using System.Text.Json; using System.Text.Json.Nodes; +using MinecraftLaunch.Extensions; +using MinecraftLaunch.Classes.Interfaces; +using MinecraftLaunch.Classes.Models.Download; namespace MinecraftLaunch.Components.Fetcher { public class CurseForgeFetcher : IFetcher> { @@ -16,11 +17,11 @@ public ValueTask> FetchAsync() { private CurseForgeResourceEntry ResolveFromJsonNode(JsonNode node) { var entry = node.Deserialize(); - entry.WebLink = node["links"]?["websiteUrl"]?.GetValue(); - entry.IconUrl = node["logo"]?["url"]?.GetValue(); - entry.Authors = node["authors"]?.AsArray().Select(x => x["name"].GetValue()); - entry.ScreenshotUrls = node["screenshots"]?.AsArray().Select(x => x["url"].GetValue()); - entry.Categories = node["categories"]?.AsArray().Select(x => x["name"].GetValue()); + entry.IconUrl = node["logo"]?.GetString("url"); + entry.WebLink = node["links"]?.GetString("websiteUrl"); + entry.Authors = node?.GetEnumerable("authors", "name"); + entry.Categories = node?.GetEnumerable("categories", "name"); + entry.ScreenshotUrls = node?.GetEnumerable("screenshots", "url"); entry.Files = entry.Files.Select(x => { x.ModId = entry.Id; return x; diff --git a/MinecraftLaunch/Components/Resolver/GameResolver.cs b/MinecraftLaunch/Components/Resolver/GameResolver.cs index b6e1293..30d5b13 100644 --- a/MinecraftLaunch/Components/Resolver/GameResolver.cs +++ b/MinecraftLaunch/Components/Resolver/GameResolver.cs @@ -181,10 +181,11 @@ string GetVersion(GameEntry gameInfo, GameJsonEntry jsonEntity, string path) { var clientVersion = json["clientVersion"]; // pcl合并核心版本号读取 if (patches != null) { - return patches[0]["version"].GetValue(); + return patches[0].GetString("version"); } + if (clientVersion != null) { - return clientVersion.GetValue(); + return clientVersion.GetString(); } } diff --git a/MinecraftLaunch/Components/Resolver/LibrariesResolver.cs b/MinecraftLaunch/Components/Resolver/LibrariesResolver.cs index f786f0d..50e6ae4 100644 --- a/MinecraftLaunch/Components/Resolver/LibrariesResolver.cs +++ b/MinecraftLaunch/Components/Resolver/LibrariesResolver.cs @@ -18,7 +18,8 @@ public LibraryEntry Resolve(JsonNode libNode) { var jsonRules = libNode["rules"]; var jsonNatives = libNode["natives"]; - if (jsonRules != null && !GetLibraryEnable(jsonRules.Deserialize>()!)) { + if (jsonRules != null && !GetLibraryEnable(jsonRules.Deserialize>(JsonConverterUtil + .DefaultJsonConverterOptions)!)) { return null!; } @@ -74,9 +75,9 @@ private LibraryEntry GetJarEntry() { if (jsonClient != null) return new LibraryEntry { Path = GameEntry.JarPath, - Size = jsonClient["size"]!.GetValue(), - Url = jsonClient["url"]!.GetValue(), - Checksum = jsonClient["sha1"]!.GetValue() + Url = jsonClient.GetString("url"), + Size = jsonClient.GetInt32("size"), + Checksum = jsonClient.GetString("sha1") }; return null; @@ -199,7 +200,7 @@ private void GetLibraryChecksumAndUrl(ref LibraryEntry libraryEntry, JsonNode js libraryEntry.Url = libraryJsonNode.Downloads.Classifiers[nativeName].Url; } - if (jsonNode["name"]!.GetValue().Contains("natives")) { + if (jsonNode.GetString("name").Contains("natives")) { libraryEntry.Checksum = libraryJsonNode.Downloads.Artifact.Sha1; libraryEntry.Size = libraryJsonNode.Downloads.Artifact.Size; libraryEntry.Url = libraryJsonNode.Downloads.Artifact.Url; @@ -216,15 +217,14 @@ private void GetLibraryChecksumAndUrl(ref LibraryEntry libraryEntry, JsonNode js } if (libraryEntry.Url == null && jsonNode["url"] != null) { - libraryEntry.Url = (jsonNode["url"] - .GetValue() + libraryEntry.RelativePath) + libraryEntry.Url = (jsonNode.GetString("url") + libraryEntry.RelativePath) .Replace('\\', '/'); } if (libraryEntry.Checksum == null && jsonNode["checksums"] != null) { libraryEntry.Checksum = jsonNode["checksums"]! .AsArray()[0]! - .GetValue(); + .GetString(); } } } \ No newline at end of file diff --git a/MinecraftLaunch/Components/Resolver/ModResolver.cs b/MinecraftLaunch/Components/Resolver/ModResolver.cs index 89459ae..a523960 100644 --- a/MinecraftLaunch/Components/Resolver/ModResolver.cs +++ b/MinecraftLaunch/Components/Resolver/ModResolver.cs @@ -73,11 +73,11 @@ private void OfLegacyForgeModEntry(string text, ref ModEntry entry) { ?? throw new InvalidDataException("Invalid mcmod.info"); try { - entry.DisplayName = jsonNode["name"].GetValue(); - entry.Version = jsonNode["version"]?.GetValue(); - entry.Description = jsonNode["description"]?.GetValue(); - entry.Authors = (jsonNode["authorList"] ?? jsonNode["authors"]).AsArray() - .Select(x => x.GetValue()) + entry.DisplayName = jsonNode.GetString("name"); + entry.Version = jsonNode.GetString("version"); + entry.Description = jsonNode.GetString("description"); + entry.Authors = (jsonNode["authorList"] ?? jsonNode["authors"]) + .GetEnumerable() .ToImmutableArray(); } catch (Exception) { @@ -92,11 +92,11 @@ private void OfFabricModEntry(ZipArchive zipArchive, ref ModEntry entry) { try { var jsonNode = JsonNode.Parse(reader.ReadToEnd()); - entry.DisplayName = jsonNode["name"].GetValue(); - entry.Version = jsonNode["version"]?.GetValue(); - entry.Description = jsonNode["description"]?.GetValue(); - entry.Authors = jsonNode["authors"].AsArray() - .Select(x => x.GetValue()) + entry.DisplayName = jsonNode.GetString("name"); + entry.Version = jsonNode.GetString("version"); + entry.Description = jsonNode.GetString("description"); + entry.Authors = jsonNode["authors"] + .GetEnumerable() .ToImmutableArray(); } catch (Exception) { @@ -136,11 +136,11 @@ private void OfQulitModEntry(ZipArchive zipArchive, ref ModEntry entry) { var jsonNode = JsonNode.Parse(reader.ReadToEnd()); jsonNode = jsonNode["quilt_loader"]["metadata"]; - entry.DisplayName = jsonNode["name"].GetValue(); - entry.Version = jsonNode["version"]?.GetValue(); - entry.Description = jsonNode["description"]?.GetValue(); - entry.Authors = jsonNode["authors"].AsArray() - .Select(x => x.GetValue()) + entry.DisplayName = jsonNode?.GetString("name"); + entry.Version = jsonNode?.GetString("version"); + entry.Description = jsonNode?.GetString("description"); + entry.Authors = jsonNode["authors"] + .GetEnumerable() .ToImmutableArray(); } catch (Exception) { diff --git a/MinecraftLaunch/Extensions/JsonExtension.cs b/MinecraftLaunch/Extensions/JsonExtension.cs index 2160e7b..59db7fe 100644 --- a/MinecraftLaunch/Extensions/JsonExtension.cs +++ b/MinecraftLaunch/Extensions/JsonExtension.cs @@ -1,5 +1,6 @@ using System.Text.Json; using System.Text.Json.Nodes; +using System.Xml.Linq; namespace MinecraftLaunch.Extensions { public static class JsonExtension { @@ -11,16 +12,45 @@ public static T AsJsonEntry(this string json) { return JsonSerializer.Deserialize(json); } + public static int GetInt32(this JsonNode node) { + return node.GetValue(); + } + public static int GetInt32(this JsonNode node, string name) { return node[name].GetValue(); } + public static bool GetBool(this JsonNode node) { + return node.GetValue(); + } + public static bool GetBool(this JsonNode node, string name) { return node[name].GetValue(); } + public static string GetString(this JsonNode node) { + return node.GetValue(); + } + public static string GetString(this JsonNode node, string name) { return node[name].GetValue(); } + + public static IEnumerable GetEnumerable(this JsonNode node) { + return node.AsArray() + .Select(x => x.GetValue()); + } + + public static IEnumerable GetEnumerable(this JsonNode node, string name) { + return node[name] + .AsArray() + .Select(x => x.GetValue()); + } + + public static IEnumerable GetEnumerable(this JsonNode node, string name, string elementName) { + return node[name] + .AsArray() + .Select(x => x[elementName].GetValue()); + } } } diff --git a/MinecraftLaunch/Utilities/JsonConverterUtil.cs b/MinecraftLaunch/Utilities/JsonConverterUtil.cs new file mode 100644 index 0000000..b50184e --- /dev/null +++ b/MinecraftLaunch/Utilities/JsonConverterUtil.cs @@ -0,0 +1,19 @@ +using MinecraftLaunch.Components.Converter; +using System.Text.Encodings.Web; +using System.Text.Json; + +namespace MinecraftLaunch.Utilities { + public class JsonConverterUtil { + public static JsonSerializerOptions DefaultJsonConverterOptions => Get(); + + private static JsonSerializerOptions Get() { + var options = new JsonSerializerOptions() { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping, + }; + + options.Converters.Add(new PlatformEnumToStringJsonConverter()); + + return options; + } + } +}