mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Replace legacy custom JSON parser with System.Text.Json
- Rewrite Json.cs to use System.Text.Json.Nodes (JsonNode, JsonObject, JsonArray) - Add JsonNodeExtensions.GetStringValue() for backward-compatible string access - Update all 14 consumer files to use the new JsonNode API - Remove ~300 lines of hand-rolled JSON parsing code from 2013 - Replace KeyUtils.EscapeString with delegation to Json.EscapeString Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> Agent-Logs-Url: https://github.com/milutinke/Minecraft-Console-Client/sessions/afcd1b7b-ea23-4a0d-bb46-a90b623406fc
This commit is contained in:
parent
7893bd7fe4
commit
15aabd9423
15 changed files with 264 additions and 657 deletions
|
|
@ -121,7 +121,7 @@ namespace MinecraftClient.Protocol
|
|||
{
|
||||
Task<string> fetchTask = httpClient.GetStringAsync("https://api.mojang.com/users/profiles/minecraft/" + name);
|
||||
fetchTask.Wait();
|
||||
string result = Json.ParseJson(fetchTask.Result).Properties["id"].StringValue;
|
||||
string result = Json.ParseJson(fetchTask.Result)!["id"]!.GetStringValue();
|
||||
fetchTask.Dispose();
|
||||
return result;
|
||||
}
|
||||
|
|
@ -140,11 +140,11 @@ namespace MinecraftClient.Protocol
|
|||
{
|
||||
Task<string> fetchTask = httpClient.GetStringAsync("https://api.mojang.com/user/profiles/" + uuid + "/names");
|
||||
fetchTask.Wait();
|
||||
var nameChanges = Json.ParseJson(fetchTask.Result).DataArray;
|
||||
var nameChanges = Json.ParseJson(fetchTask.Result)!.AsArray();
|
||||
fetchTask.Dispose();
|
||||
|
||||
// Names are sorted from past to most recent. We need to get the last name in the list
|
||||
return nameChanges[^1].Properties["name"].StringValue;
|
||||
return nameChanges[^1]!["name"]!.GetStringValue();
|
||||
}
|
||||
catch (Exception) { return string.Empty; }
|
||||
}
|
||||
|
|
@ -157,40 +157,32 @@ namespace MinecraftClient.Protocol
|
|||
public static Dictionary<string, DateTime> UuidToNameHistory(string uuid)
|
||||
{
|
||||
Dictionary<string, DateTime> tempDict = new();
|
||||
List<Json.JSONData> jsonDataList;
|
||||
System.Text.Json.Nodes.JsonArray jsonDataList;
|
||||
|
||||
// Perform web request
|
||||
try
|
||||
{
|
||||
Task<string> fetchTask = httpClient.GetStringAsync("https://api.mojang.com/user/profiles/" + uuid + "/names");
|
||||
fetchTask.Wait();
|
||||
jsonDataList = Json.ParseJson(fetchTask.Result).DataArray;
|
||||
jsonDataList = Json.ParseJson(fetchTask.Result)!.AsArray();
|
||||
fetchTask.Dispose();
|
||||
}
|
||||
catch (Exception) { return tempDict; }
|
||||
|
||||
foreach (Json.JSONData jsonData in jsonDataList)
|
||||
foreach (var jsonData in jsonDataList)
|
||||
{
|
||||
if (jsonData.Properties.Count > 1)
|
||||
var obj = jsonData!.AsObject();
|
||||
if (obj.Count > 1)
|
||||
{
|
||||
// Time is saved as long in the Unix format.
|
||||
// Convert it to normal time, before adding it to the dictionary.
|
||||
//
|
||||
// !! FromUnixTimeMilliseconds does not exist in the current version. !!
|
||||
// DateTimeOffset creationDate = DateTimeOffset.FromUnixTimeMilliseconds(Convert.ToInt64(jsonData.Properties["changedToAt"].StringValue));
|
||||
//
|
||||
DateTimeOffset creationDate = UnixTimeStampToDateTime(Convert.ToDouble(jsonData["changedToAt"].GetStringValue()));
|
||||
|
||||
// Workaround for converting Unix time to normal time.
|
||||
DateTimeOffset creationDate = UnixTimeStampToDateTime(Convert.ToDouble(jsonData.Properties["changedToAt"].StringValue));
|
||||
|
||||
// Add Keyvaluepair to dict.
|
||||
tempDict.Add(jsonData.Properties["name"].StringValue, creationDate.DateTime);
|
||||
tempDict.Add(jsonData["name"]!.GetStringValue(), creationDate.DateTime);
|
||||
}
|
||||
// The first entry does not contain a change date.
|
||||
else if (jsonData.Properties.Count > 0)
|
||||
else if (obj.Count > 0)
|
||||
{
|
||||
// Add an undefined time to it.
|
||||
tempDict.Add(jsonData.Properties["name"].StringValue, new DateTime());
|
||||
tempDict.Add(jsonData["name"]!.GetStringValue(), new DateTime());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -203,14 +195,14 @@ namespace MinecraftClient.Protocol
|
|||
/// <returns>Dictionary of the Mojang services</returns>
|
||||
public static MojangServiceStatus GetMojangServiceStatus()
|
||||
{
|
||||
List<Json.JSONData> jsonDataList;
|
||||
System.Text.Json.Nodes.JsonArray jsonDataList;
|
||||
|
||||
// Perform web request
|
||||
try
|
||||
{
|
||||
Task<string> fetchTask = httpClient.GetStringAsync("https://status.mojang.com/check");
|
||||
fetchTask.Wait();
|
||||
jsonDataList = Json.ParseJson(fetchTask.Result).DataArray;
|
||||
jsonDataList = Json.ParseJson(fetchTask.Result)!.AsArray();
|
||||
fetchTask.Dispose();
|
||||
}
|
||||
catch (Exception)
|
||||
|
|
@ -219,14 +211,14 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
|
||||
// Convert string to enum values and store them inside a MojangeServiceStatus object.
|
||||
return new MojangServiceStatus(minecraftNet: StringToServiceStatus(jsonDataList[0].Properties["minecraft.net"].StringValue),
|
||||
sessionMinecraftNet: StringToServiceStatus(jsonDataList[1].Properties["session.minecraft.net"].StringValue),
|
||||
accountMojangCom: StringToServiceStatus(jsonDataList[2].Properties["account.mojang.com"].StringValue),
|
||||
authserverMojangCom: StringToServiceStatus(jsonDataList[3].Properties["authserver.mojang.com"].StringValue),
|
||||
sessionserverMojangCom: StringToServiceStatus(jsonDataList[4].Properties["sessionserver.mojang.com"].StringValue),
|
||||
apiMojangCom: StringToServiceStatus(jsonDataList[5].Properties["api.mojang.com"].StringValue),
|
||||
texturesMinecraftNet: StringToServiceStatus(jsonDataList[6].Properties["textures.minecraft.net"].StringValue),
|
||||
mojangCom: StringToServiceStatus(jsonDataList[7].Properties["mojang.com"].StringValue)
|
||||
return new MojangServiceStatus(minecraftNet: StringToServiceStatus(jsonDataList[0]!["minecraft.net"]!.GetStringValue()),
|
||||
sessionMinecraftNet: StringToServiceStatus(jsonDataList[1]!["session.minecraft.net"]!.GetStringValue()),
|
||||
accountMojangCom: StringToServiceStatus(jsonDataList[2]!["account.mojang.com"]!.GetStringValue()),
|
||||
authserverMojangCom: StringToServiceStatus(jsonDataList[3]!["authserver.mojang.com"]!.GetStringValue()),
|
||||
sessionserverMojangCom: StringToServiceStatus(jsonDataList[4]!["sessionserver.mojang.com"]!.GetStringValue()),
|
||||
apiMojangCom: StringToServiceStatus(jsonDataList[5]!["api.mojang.com"]!.GetStringValue()),
|
||||
texturesMinecraftNet: StringToServiceStatus(jsonDataList[6]!["textures.minecraft.net"]!.GetStringValue()),
|
||||
mojangCom: StringToServiceStatus(jsonDataList[7]!["mojang.com"]!.GetStringValue())
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -237,9 +229,9 @@ namespace MinecraftClient.Protocol
|
|||
/// <returns>Dictionary with a link to the skin and cape of a player.</returns>
|
||||
public static SkinInfo GetSkinInfo(string uuid)
|
||||
{
|
||||
Dictionary<string, Json.JSONData> textureDict;
|
||||
System.Text.Json.Nodes.JsonObject textureObj;
|
||||
string base64SkinInfo;
|
||||
Json.JSONData decodedJsonSkinInfo;
|
||||
System.Text.Json.Nodes.JsonNode? decodedJsonSkinInfo;
|
||||
|
||||
// Perform web request
|
||||
try
|
||||
|
|
@ -247,7 +239,7 @@ namespace MinecraftClient.Protocol
|
|||
Task<string> fetchTask = httpClient.GetStringAsync("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid);
|
||||
fetchTask.Wait();
|
||||
// Obtain the Base64 encoded skin information from the API. Discard the rest, since it can be obtained easier through other requests.
|
||||
base64SkinInfo = Json.ParseJson(fetchTask.Result).Properties["properties"].DataArray[0].Properties["value"].StringValue;
|
||||
base64SkinInfo = Json.ParseJson(fetchTask.Result)!["properties"]![0]!["value"]!.GetStringValue();
|
||||
fetchTask.Dispose();
|
||||
}
|
||||
catch (Exception) { return new SkinInfo(); }
|
||||
|
|
@ -257,23 +249,18 @@ namespace MinecraftClient.Protocol
|
|||
|
||||
// Assert temporary variable for readablity.
|
||||
// Contains skin and cape information.
|
||||
textureDict = decodedJsonSkinInfo.Properties["textures"].Properties;
|
||||
textureObj = decodedJsonSkinInfo!["textures"]!.AsObject();
|
||||
|
||||
// Can apparently be missing, if no custom skin is set.
|
||||
// Probably for completely new accounts.
|
||||
// (Still exists after changing back to Steve or Alex skin.)
|
||||
if (textureDict.ContainsKey("SKIN"))
|
||||
if (textureObj.ContainsKey("SKIN"))
|
||||
{
|
||||
return new SkinInfo(skinUrl: textureDict["SKIN"].Properties.ContainsKey("url") ? textureDict["SKIN"].Properties["url"].StringValue : string.Empty,
|
||||
capeUrl: textureDict.ContainsKey("CAPE") ? textureDict["CAPE"].Properties["url"].StringValue : string.Empty,
|
||||
skinModel: textureDict["SKIN"].Properties.ContainsKey("metadata") ? "Alex" : "Steve");
|
||||
return new SkinInfo(skinUrl: textureObj["SKIN"]!["url"] is not null ? textureObj["SKIN"]!["url"]!.GetStringValue() : string.Empty,
|
||||
capeUrl: textureObj.ContainsKey("CAPE") ? textureObj["CAPE"]!["url"]!.GetStringValue() : string.Empty,
|
||||
skinModel: textureObj["SKIN"]!["metadata"] is not null ? "Alex" : "Steve");
|
||||
}
|
||||
// Tested it on several players, this case never occured.
|
||||
else
|
||||
{
|
||||
// This player has assumingly never changed their skin.
|
||||
// Probably a completely new account.
|
||||
return new SkinInfo(capeUrl: textureDict.ContainsKey("CAPE") ? textureDict["CAPE"].Properties["url"].StringValue : string.Empty,
|
||||
return new SkinInfo(capeUrl: textureObj.ContainsKey("CAPE") ? textureObj["CAPE"]!["url"]!.GetStringValue() : string.Empty,
|
||||
skinModel: DefaultModelAlex(uuid) ? "Alex" : "Steve");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue