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
|
|
@ -21,13 +21,13 @@ namespace MinecraftClient.Protocol
|
|||
/// <returns></returns>
|
||||
private static Dictionary<int, string> LoadRegistry(string registriesJsonFile, string jsonRegistryName)
|
||||
{
|
||||
Json.JSONData rawJson = Json.ParseJson(File.ReadAllText(registriesJsonFile));
|
||||
Json.JSONData rawRegistry = rawJson.Properties[jsonRegistryName].Properties["entries"];
|
||||
var rawJson = Json.ParseJson(File.ReadAllText(registriesJsonFile));
|
||||
var rawRegistry = rawJson![jsonRegistryName]!["entries"]!.AsObject();
|
||||
Dictionary<int, string> registry = new();
|
||||
|
||||
foreach (KeyValuePair<string, Json.JSONData> entry in rawRegistry.Properties)
|
||||
foreach (var entry in rawRegistry)
|
||||
{
|
||||
int entryId = int.Parse(entry.Value.Properties["protocol_id"].StringValue, NumberStyles.Any, CultureInfo.CurrentCulture);
|
||||
int entryId = int.Parse(entry.Value!["protocol_id"].GetStringValue(), NumberStyles.Any, CultureInfo.CurrentCulture);
|
||||
|
||||
//minecraft:item_name => ItemName
|
||||
string entryName = String.Concat(
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
/// </summary>
|
||||
/// <param name="data">The modinfo JSON tag.</param>
|
||||
/// <param name="fmlVersion">Forge protocol version</param>
|
||||
internal ForgeInfo(Json.JSONData data, FMLVersion fmlVersion)
|
||||
internal ForgeInfo(System.Text.Json.Nodes.JsonObject data, FMLVersion fmlVersion)
|
||||
{
|
||||
Mods = new List<ForgeMod>();
|
||||
Version = fmlVersion;
|
||||
|
|
@ -91,10 +91,10 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
// }]
|
||||
// }
|
||||
|
||||
foreach (Json.JSONData mod in data.Properties["modList"].DataArray)
|
||||
foreach (var mod in data["modList"]!.AsArray())
|
||||
{
|
||||
String modid = mod.Properties["modid"].StringValue;
|
||||
String modversion = mod.Properties["version"].StringValue;
|
||||
String modid = mod!["modid"]!.GetStringValue();
|
||||
String modversion = mod["version"]!.GetStringValue();
|
||||
|
||||
Mods.Add(new ForgeMod(modid, modversion));
|
||||
}
|
||||
|
|
@ -131,10 +131,10 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
// "fmlNetworkVersion": 2
|
||||
// }
|
||||
|
||||
foreach (Json.JSONData mod in data.Properties["mods"].DataArray)
|
||||
foreach (var mod in data["mods"]!.AsArray())
|
||||
{
|
||||
String modid = mod.Properties["modId"].StringValue;
|
||||
String modmarker = mod.Properties["modmarker"].StringValue;
|
||||
String modid = mod!["modId"]!.GetStringValue();
|
||||
String modmarker = mod["modmarker"]!.GetStringValue();
|
||||
|
||||
Mods.Add(new ForgeMod(modid, modmarker));
|
||||
}
|
||||
|
|
@ -157,7 +157,7 @@ namespace MinecraftClient.Protocol.Handlers.Forge
|
|||
// - Here is the discussion:
|
||||
// see https://github.com/MinecraftForge/MinecraftForge/pull/8169
|
||||
|
||||
string encodedData = data.Properties["d"].StringValue;
|
||||
string encodedData = data["d"]!.GetStringValue();
|
||||
Queue<byte> dataPackage = decodeOptimized(encodedData);
|
||||
DataTypes dataTypes = new DataTypes(Protocol18Handler.MC_1_18_1_Version);
|
||||
|
||||
|
|
|
|||
|
|
@ -1031,10 +1031,10 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
? dataTypes.ReadNextString(packetData)
|
||||
: null;
|
||||
|
||||
var chatInfo = Json.ParseJson(chatName).Properties;
|
||||
var senderDisplayName = chatInfo != null && chatInfo.Count > 0
|
||||
var chatInfo = Json.ParseJson(chatName)?.AsObject();
|
||||
var senderDisplayName = chatInfo is not null && chatInfo.Count > 0
|
||||
? (chatInfo.ContainsKey("insertion") ? chatInfo["insertion"] : chatInfo["text"])
|
||||
.StringValue
|
||||
.GetStringValue()
|
||||
: "";
|
||||
string? senderTeamName = null;
|
||||
var messageTypeEnum =
|
||||
|
|
@ -1043,8 +1043,8 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
if (targetName != null &&
|
||||
(messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_INCOMING ||
|
||||
messageTypeEnum == ChatParser.MessageType.TEAM_MSG_COMMAND_OUTGOING))
|
||||
senderTeamName = Json.ParseJson(targetName).Properties["with"].DataArray[0]
|
||||
.Properties["text"].StringValue;
|
||||
senderTeamName = Json.ParseJson(targetName)!["with"]![0]!
|
||||
["text"]!.GetStringValue();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(senderDisplayName))
|
||||
{
|
||||
|
|
@ -3574,22 +3574,22 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
if (string.IsNullOrEmpty(result) || !result.StartsWith("{") || !result.EndsWith("}")) return false;
|
||||
|
||||
var jsonData = Json.ParseJson(result);
|
||||
if (jsonData.Type != Json.JSONData.DataType.Object || !jsonData.Properties.ContainsKey("version"))
|
||||
if (jsonData is not System.Text.Json.Nodes.JsonObject jsonObj || !jsonObj.ContainsKey("version"))
|
||||
return false;
|
||||
|
||||
var versionData = jsonData.Properties["version"];
|
||||
var versionData = jsonObj["version"]!.AsObject();
|
||||
|
||||
//Retrieve display name of the Minecraft version
|
||||
if (versionData.Properties.TryGetValue("name", out var property))
|
||||
version = property.StringValue;
|
||||
if (versionData["name"] is { } nameNode)
|
||||
version = nameNode.GetStringValue();
|
||||
|
||||
//Retrieve protocol version number for handling this server
|
||||
if (versionData.Properties.TryGetValue("protocol", out var dataProperty))
|
||||
protocolVersion = int.Parse(dataProperty.StringValue,
|
||||
if (versionData["protocol"] is { } protocolNode)
|
||||
protocolVersion = int.Parse(protocolNode.GetStringValue(),
|
||||
NumberStyles.Any, CultureInfo.CurrentCulture);
|
||||
|
||||
// Check for forge on the server.
|
||||
Protocol18Forge.ServerInfoCheckForge(jsonData, ref forgeInfo);
|
||||
Protocol18Forge.ServerInfoCheckForge(jsonObj, ref forgeInfo);
|
||||
|
||||
ConsoleIO.WriteLineFormatted("§8" + string.Format(Translations.mcc_server_protocol, version,
|
||||
protocolVersion + (forgeInfo != null ? Translations.mcc_with_forge : "")));
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
/// <param name="jsonData">JSON data returned by the server</param>
|
||||
/// <param name="forgeInfo">ForgeInfo to populate</param>
|
||||
/// <returns>True if the server is running Forge</returns>
|
||||
public static bool ServerInfoCheckForge(Json.JSONData jsonData, ref ForgeInfo? forgeInfo)
|
||||
public static bool ServerInfoCheckForge(System.Text.Json.Nodes.JsonObject jsonData, ref ForgeInfo? forgeInfo)
|
||||
{
|
||||
return ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML) // MC 1.12 and lower
|
||||
|| ServerInfoCheckForgeSub(jsonData, ref forgeInfo, FMLVersion.FML2) // MC 1.13 to 1.17
|
||||
|
|
@ -530,7 +530,7 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
/// <param name="forgeInfo">ForgeInfo to populate</param>
|
||||
/// <param name="fmlVersion">Forge protocol version</param>
|
||||
/// <returns>True if the server is running Forge</returns>
|
||||
private static bool ServerInfoCheckForgeSub(Json.JSONData jsonData, ref ForgeInfo? forgeInfo, FMLVersion fmlVersion)
|
||||
private static bool ServerInfoCheckForgeSub(System.Text.Json.Nodes.JsonObject jsonData, ref ForgeInfo? forgeInfo, FMLVersion fmlVersion)
|
||||
{
|
||||
string forgeDataTag;
|
||||
string versionField;
|
||||
|
|
@ -557,10 +557,9 @@ namespace MinecraftClient.Protocol.Handlers
|
|||
throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!");
|
||||
}
|
||||
|
||||
if (jsonData.Properties.ContainsKey(forgeDataTag) && jsonData.Properties[forgeDataTag].Type == Json.JSONData.DataType.Object)
|
||||
if (jsonData[forgeDataTag] is System.Text.Json.Nodes.JsonObject modData)
|
||||
{
|
||||
Json.JSONData modData = jsonData.Properties[forgeDataTag];
|
||||
if (modData.Properties.ContainsKey(versionField) && modData.Properties[versionField].StringValue == versionString)
|
||||
if (modData[versionField] is not null && modData[versionField]!.GetStringValue() == versionString)
|
||||
{
|
||||
forgeInfo = new ForgeInfo(modData, fmlVersion);
|
||||
if (forgeInfo.Mods.Any())
|
||||
|
|
|
|||
|
|
@ -436,74 +436,70 @@ namespace MinecraftClient.Protocol.Message
|
|||
/// <param name="colorcode">Allow parent color code to affect child elements (set to "" for function init)</param>
|
||||
/// <param name="links">Container for links from JSON serialized text</param>
|
||||
/// <returns>returns the Minecraft-formatted string</returns>
|
||||
private static string JSONData2String(Json.JSONData data, string colorcode, List<string>? links)
|
||||
private static string JSONData2String(System.Text.Json.Nodes.JsonNode? data, string colorcode, List<string>? links)
|
||||
{
|
||||
string extra_result = "";
|
||||
switch (data.Type)
|
||||
switch (data)
|
||||
{
|
||||
case Json.JSONData.DataType.Object:
|
||||
if (data.Properties.ContainsKey("color"))
|
||||
case System.Text.Json.Nodes.JsonObject obj:
|
||||
if (obj.ContainsKey("color"))
|
||||
{
|
||||
colorcode = Color2tag(JSONData2String(data.Properties["color"], "", links));
|
||||
colorcode = Color2tag(JSONData2String(obj["color"], "", links));
|
||||
}
|
||||
|
||||
if (data.Properties.ContainsKey("clickEvent") && links != null)
|
||||
if (obj.ContainsKey("clickEvent") && links is not null)
|
||||
{
|
||||
Json.JSONData clickEvent = data.Properties["clickEvent"];
|
||||
if (clickEvent.Properties.ContainsKey("action")
|
||||
&& clickEvent.Properties.ContainsKey("value")
|
||||
&& clickEvent.Properties["action"].StringValue == "open_url"
|
||||
&& !string.IsNullOrEmpty(clickEvent.Properties["value"].StringValue))
|
||||
var clickEvent = obj["clickEvent"]!.AsObject();
|
||||
if (clickEvent.ContainsKey("action")
|
||||
&& clickEvent.ContainsKey("value")
|
||||
&& clickEvent["action"]!.GetStringValue() == "open_url"
|
||||
&& !string.IsNullOrEmpty(clickEvent["value"]!.GetStringValue()))
|
||||
{
|
||||
links.Add(clickEvent.Properties["value"].StringValue);
|
||||
links.Add(clickEvent["value"]!.GetStringValue());
|
||||
}
|
||||
}
|
||||
|
||||
if (data.Properties.ContainsKey("extra"))
|
||||
if (obj.ContainsKey("extra"))
|
||||
{
|
||||
Json.JSONData[] extras = data.Properties["extra"].DataArray.ToArray();
|
||||
foreach (Json.JSONData item in extras)
|
||||
foreach (var item in obj["extra"]!.AsArray())
|
||||
extra_result = extra_result + JSONData2String(item, colorcode, links) + "§r";
|
||||
}
|
||||
|
||||
if (data.Properties.ContainsKey("text"))
|
||||
if (obj.ContainsKey("text"))
|
||||
{
|
||||
return colorcode + JSONData2String(data.Properties["text"], colorcode, links) + extra_result;
|
||||
return colorcode + JSONData2String(obj["text"], colorcode, links) + extra_result;
|
||||
}
|
||||
else if (data.Properties.ContainsKey("translate"))
|
||||
else if (obj.ContainsKey("translate"))
|
||||
{
|
||||
List<string> using_data = new();
|
||||
if (data.Properties.ContainsKey("using") && !data.Properties.ContainsKey("with"))
|
||||
data.Properties["with"] = data.Properties["using"];
|
||||
if (data.Properties.ContainsKey("with"))
|
||||
if (obj.ContainsKey("using") && !obj.ContainsKey("with"))
|
||||
obj["with"] = System.Text.Json.Nodes.JsonNode.Parse(obj["using"]!.ToJsonString());
|
||||
if (obj.ContainsKey("with"))
|
||||
{
|
||||
Json.JSONData[] array = data.Properties["with"].DataArray.ToArray();
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
foreach (var item in obj["with"]!.AsArray())
|
||||
{
|
||||
using_data.Add(JSONData2String(array[i], colorcode, links));
|
||||
using_data.Add(JSONData2String(item, colorcode, links));
|
||||
}
|
||||
}
|
||||
|
||||
return colorcode +
|
||||
TranslateString(JSONData2String(data.Properties["translate"], "", links), using_data) +
|
||||
TranslateString(JSONData2String(obj["translate"], "", links), using_data) +
|
||||
extra_result;
|
||||
}
|
||||
else return extra_result;
|
||||
|
||||
case Json.JSONData.DataType.Array:
|
||||
case System.Text.Json.Nodes.JsonArray arr:
|
||||
string result = "";
|
||||
foreach (Json.JSONData item in data.DataArray)
|
||||
foreach (var item in arr)
|
||||
{
|
||||
result += JSONData2String(item, colorcode, links);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
case Json.JSONData.DataType.String:
|
||||
return colorcode + data.StringValue;
|
||||
default:
|
||||
return colorcode + data.GetStringValue();
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private static string NbtToString(Dictionary<string, object> nbt)
|
||||
|
|
|
|||
|
|
@ -68,20 +68,20 @@ namespace MinecraftClient.Protocol
|
|||
var jsonData = Json.ParseJson(response.Body);
|
||||
|
||||
// Error handling
|
||||
if (jsonData.Properties.ContainsKey("error"))
|
||||
if (jsonData?["error"] is not null)
|
||||
{
|
||||
throw new Exception(jsonData.Properties["error_description"].StringValue);
|
||||
throw new Exception(jsonData["error_description"].GetStringValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
string accessToken = jsonData.Properties["access_token"].StringValue;
|
||||
string refreshToken = jsonData.Properties["refresh_token"].StringValue;
|
||||
int expiresIn = int.Parse(jsonData.Properties["expires_in"].StringValue, NumberStyles.Any, CultureInfo.CurrentCulture);
|
||||
string accessToken = jsonData!["access_token"]!.GetStringValue();
|
||||
string refreshToken = jsonData["refresh_token"]!.GetStringValue();
|
||||
int expiresIn = int.Parse(jsonData["expires_in"].GetStringValue(), NumberStyles.Any, CultureInfo.CurrentCulture);
|
||||
|
||||
// Extract email from JWT
|
||||
string payload = JwtPayloadDecode.GetPayload(jsonData.Properties["id_token"].StringValue);
|
||||
string payload = JwtPayloadDecode.GetPayload(jsonData["id_token"]!.GetStringValue());
|
||||
var jsonPayload = Json.ParseJson(payload);
|
||||
string email = jsonPayload.Properties["email"].StringValue;
|
||||
string email = jsonPayload!["email"]!.GetStringValue();
|
||||
return new LoginResponse()
|
||||
{
|
||||
Email = email,
|
||||
|
|
@ -299,9 +299,9 @@ namespace MinecraftClient.Protocol
|
|||
string jsonString = response.Body;
|
||||
//Console.WriteLine(jsonString);
|
||||
|
||||
Json.JSONData json = Json.ParseJson(jsonString);
|
||||
string token = json.Properties["Token"].StringValue;
|
||||
string userHash = json.Properties["DisplayClaims"].Properties["xui"].DataArray[0].Properties["uhs"].StringValue;
|
||||
var json = Json.ParseJson(jsonString);
|
||||
string token = json!["Token"]!.GetStringValue();
|
||||
string userHash = json["DisplayClaims"]!["xui"]![0]!["uhs"]!.GetStringValue();
|
||||
return new XblAuthenticateResponse()
|
||||
{
|
||||
Token = token,
|
||||
|
|
@ -347,9 +347,9 @@ namespace MinecraftClient.Protocol
|
|||
if (response.StatusCode == 200)
|
||||
{
|
||||
string jsonString = response.Body;
|
||||
Json.JSONData json = Json.ParseJson(jsonString);
|
||||
string token = json.Properties["Token"].StringValue;
|
||||
string userHash = json.Properties["DisplayClaims"].Properties["xui"].DataArray[0].Properties["uhs"].StringValue;
|
||||
var json = Json.ParseJson(jsonString);
|
||||
string token = json!["Token"]!.GetStringValue();
|
||||
string userHash = json["DisplayClaims"]!["xui"]![0]!["uhs"]!.GetStringValue();
|
||||
return new XSTSAuthenticateResponse()
|
||||
{
|
||||
Token = token,
|
||||
|
|
@ -360,16 +360,16 @@ namespace MinecraftClient.Protocol
|
|||
{
|
||||
if (response.StatusCode == 401)
|
||||
{
|
||||
Json.JSONData json = Json.ParseJson(response.Body);
|
||||
if (json.Properties["XErr"].StringValue == "2148916233")
|
||||
var json = Json.ParseJson(response.Body);
|
||||
if (json!["XErr"]!.GetStringValue() == "2148916233")
|
||||
{
|
||||
throw new Exception("The account doesn't have an Xbox account");
|
||||
}
|
||||
else if (json.Properties["XErr"].StringValue == "2148916238")
|
||||
else if (json["XErr"]!.GetStringValue() == "2148916238")
|
||||
{
|
||||
throw new Exception("The account is a child (under 18) and cannot proceed unless the account is added to a Family by an adult");
|
||||
}
|
||||
else throw new Exception("Unknown XSTS error code: " + json.Properties["XErr"].StringValue);
|
||||
else throw new Exception("Unknown XSTS error code: " + json["XErr"]!.GetStringValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -426,9 +426,9 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
|
||||
string jsonString = response.Body;
|
||||
Json.JSONData json = Json.ParseJson(jsonString);
|
||||
var json = Json.ParseJson(jsonString);
|
||||
|
||||
return json.Properties["access_token"].StringValue;
|
||||
return json!["access_token"]!.GetStringValue();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -448,8 +448,8 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
|
||||
string jsonString = response.Body;
|
||||
Json.JSONData json = Json.ParseJson(jsonString);
|
||||
return json.Properties["items"].DataArray.Count > 0;
|
||||
var json = Json.ParseJson(jsonString);
|
||||
return json!["items"]!.AsArray().Count > 0;
|
||||
}
|
||||
|
||||
public static UserProfile GetUserProfile(string accessToken)
|
||||
|
|
@ -464,11 +464,11 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
|
||||
string jsonString = response.Body;
|
||||
Json.JSONData json = Json.ParseJson(jsonString);
|
||||
var json = Json.ParseJson(jsonString);
|
||||
return new UserProfile()
|
||||
{
|
||||
UUID = json.Properties["id"].StringValue,
|
||||
UserName = json.Properties["name"].StringValue
|
||||
UUID = json!["id"]!.GetStringValue(),
|
||||
UserName = json["name"]!.GetStringValue()
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.Json.Nodes;
|
||||
using MinecraftClient.Protocol.Handlers;
|
||||
using MinecraftClient.Protocol.Message;
|
||||
using static MinecraftClient.Protocol.Message.LastSeenMessageList;
|
||||
|
|
@ -37,17 +38,17 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
|
||||
// see https://github.com/yushijinhun/authlib-injector/blob/da910956eaa30d2f6c2c457222d188aeb53b0d1f/src/main/java/moe/yushi/authlibinjector/httpd/ProfileKeyFilter.java#L49
|
||||
// POST to "https://api.minecraftservices.com/player/certificates" with authlib-injector will get a dummy response
|
||||
Json.JSONData json = isYggdrasil ? MakeDummyResponse() : Json.ParseJson(response!.Body);
|
||||
var json = isYggdrasil ? MakeDummyResponse() : Json.ParseJson(response!.Body);
|
||||
// Error here
|
||||
PublicKey publicKey = new(pemKey: json.Properties["keyPair"].Properties["publicKey"].StringValue,
|
||||
sig: json.Properties["publicKeySignature"].StringValue,
|
||||
sigV2: json.Properties["publicKeySignatureV2"].StringValue);
|
||||
PublicKey publicKey = new(pemKey: json!["keyPair"]!["publicKey"]!.GetStringValue(),
|
||||
sig: json["publicKeySignature"]!.GetStringValue(),
|
||||
sigV2: json["publicKeySignatureV2"]!.GetStringValue());
|
||||
|
||||
PrivateKey privateKey = new(pemKey: json.Properties["keyPair"].Properties["privateKey"].StringValue);
|
||||
PrivateKey privateKey = new(pemKey: json["keyPair"]!["privateKey"]!.GetStringValue());
|
||||
|
||||
return new PlayerKeyPair(publicKey, privateKey,
|
||||
expiresAt: json.Properties["expiresAt"].StringValue,
|
||||
refreshedAfter: json.Properties["refreshedAfter"].StringValue);
|
||||
expiresAt: json["expiresAt"]!.GetStringValue(),
|
||||
refreshedAfter: json["refreshedAfter"]!.GetStringValue());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
@ -191,51 +192,10 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
return data.ToArray();
|
||||
}
|
||||
|
||||
// https://github.com/mono/mono/blob/master/mcs/class/System.Json/System.Json/JsonValue.cs
|
||||
public static string EscapeString(string src)
|
||||
{
|
||||
StringBuilder sb = new();
|
||||
// Delegate to the shared Json.EscapeString backed by System.Text.Json
|
||||
public static string EscapeString(string src) => Json.EscapeString(src);
|
||||
|
||||
int start = 0;
|
||||
for (int i = 0; i < src.Length; i++)
|
||||
{
|
||||
char c = src[i];
|
||||
bool needEscape = c < 32 || c == '"' || c == '\\';
|
||||
// Broken lead surrogate
|
||||
needEscape = needEscape || c >= '\uD800' && c <= '\uDBFF' &&
|
||||
(i == src.Length - 1 || src[i + 1] < '\uDC00' || src[i + 1] > '\uDFFF');
|
||||
// Broken tail surrogate
|
||||
needEscape = needEscape || c >= '\uDC00' && c <= '\uDFFF' &&
|
||||
(i == 0 || src[i - 1] < '\uD800' || src[i - 1] > '\uDBFF');
|
||||
// To produce valid JavaScript
|
||||
needEscape = needEscape || c == '\u2028' || c == '\u2029';
|
||||
|
||||
if (needEscape)
|
||||
{
|
||||
sb.Append(src, start, i - start);
|
||||
switch (src[i])
|
||||
{
|
||||
case '\b': sb.Append("\\b"); break;
|
||||
case '\f': sb.Append("\\f"); break;
|
||||
case '\n': sb.Append("\\n"); break;
|
||||
case '\r': sb.Append("\\r"); break;
|
||||
case '\t': sb.Append("\\t"); break;
|
||||
case '\"': sb.Append("\\\""); break;
|
||||
case '\\': sb.Append("\\\\"); break;
|
||||
default:
|
||||
sb.Append("\\u");
|
||||
sb.Append(((int)src[i]).ToString("x04"));
|
||||
break;
|
||||
}
|
||||
start = i + 1;
|
||||
}
|
||||
|
||||
}
|
||||
sb.Append(src, start, src.Length - start);
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public static Json.JSONData MakeDummyResponse()
|
||||
public static JsonNode MakeDummyResponse()
|
||||
{
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(2048);
|
||||
var mimePublicKey = Convert.ToBase64String(rsa.ExportSubjectPublicKeyInfo());
|
||||
|
|
@ -245,19 +205,20 @@ namespace MinecraftClient.Protocol.ProfileKey
|
|||
DateTime now = DateTime.UtcNow;
|
||||
DateTime expiresAt = now.AddHours(48);
|
||||
DateTime refreshedAfter = now.AddHours(36);
|
||||
Json.JSONData response = new(Json.JSONData.DataType.Object);
|
||||
Json.JSONData keyPairObj = new(Json.JSONData.DataType.Object);
|
||||
keyPairObj.Properties["privateKey"] = new(Json.JSONData.DataType.String){ StringValue = privateKeyPEM };
|
||||
keyPairObj.Properties["publicKey"] = new(Json.JSONData.DataType.String){ StringValue = publicKeyPEM };
|
||||
|
||||
response.Properties["keyPair"] = keyPairObj;
|
||||
response.Properties["publicKeySignature"] = new(Json.JSONData.DataType.String){ StringValue = "AA==" };
|
||||
response.Properties["publicKeySignatureV2"] = new(Json.JSONData.DataType.String){ StringValue = "AA==" };
|
||||
string format = "yyyy-MM-ddTHH:mm:ss.ffffffZ";
|
||||
response.Properties["expiresAt"] = new(Json.JSONData.DataType.String){ StringValue = expiresAt.ToString(format) };
|
||||
response.Properties["refreshedAfter"] = new(Json.JSONData.DataType.String){ StringValue = refreshedAfter.ToString(format) };
|
||||
|
||||
return response;
|
||||
return new JsonObject
|
||||
{
|
||||
["keyPair"] = new JsonObject
|
||||
{
|
||||
["privateKey"] = privateKeyPEM,
|
||||
["publicKey"] = publicKeyPEM
|
||||
},
|
||||
["publicKeySignature"] = "AA==",
|
||||
["publicKeySignatureV2"] = "AA==",
|
||||
["expiresAt"] = expiresAt.ToString(format),
|
||||
["refreshedAfter"] = refreshedAfter.ToString(format)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -581,16 +581,15 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
else
|
||||
{
|
||||
Json.JSONData loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse.Properties.ContainsKey("accessToken")
|
||||
&& loginResponse.Properties.ContainsKey("selectedProfile")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("id")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("name"))
|
||||
var loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse?["accessToken"] is not null
|
||||
&& loginResponse["selectedProfile"]?["id"] is not null
|
||||
&& loginResponse["selectedProfile"]?["name"] is not null)
|
||||
{
|
||||
session.ID = loginResponse.Properties["accessToken"].StringValue;
|
||||
session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue;
|
||||
session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"]
|
||||
.StringValue;
|
||||
session.ID = loginResponse["accessToken"]!.GetStringValue();
|
||||
session.PlayerID = loginResponse["selectedProfile"]!["id"]!.GetStringValue();
|
||||
session.PlayerName = loginResponse["selectedProfile"]!["name"]!
|
||||
.GetStringValue();
|
||||
return LoginResult.Success;
|
||||
}
|
||||
else return LoginResult.InvalidResponse;
|
||||
|
|
@ -667,27 +666,25 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
else
|
||||
{
|
||||
Json.JSONData loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse.Properties.ContainsKey("accessToken"))
|
||||
var loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse?["accessToken"] is not null)
|
||||
{
|
||||
session.ID = loginResponse.Properties["accessToken"].StringValue;
|
||||
if (loginResponse.Properties.ContainsKey("selectedProfile")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("id")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("name"))
|
||||
session.ID = loginResponse["accessToken"]!.GetStringValue();
|
||||
if (loginResponse["selectedProfile"]?["id"] is not null
|
||||
&& loginResponse["selectedProfile"]?["name"] is not null)
|
||||
{
|
||||
session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"]
|
||||
.StringValue;
|
||||
session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"]
|
||||
.StringValue;
|
||||
session.PlayerID = loginResponse["selectedProfile"]!["id"]!
|
||||
.GetStringValue();
|
||||
session.PlayerName = loginResponse["selectedProfile"]!["name"]!
|
||||
.GetStringValue();
|
||||
return LoginResult.Success;
|
||||
}
|
||||
else
|
||||
{
|
||||
string availableProfiles = "";
|
||||
foreach (Json.JSONData profile in loginResponse.Properties["availableProfiles"]
|
||||
.DataArray)
|
||||
foreach (var profile in loginResponse["availableProfiles"]!.AsArray())
|
||||
{
|
||||
availableProfiles += " " + profile.Properties["name"].StringValue;
|
||||
availableProfiles += " " + profile!["name"]!.GetStringValue();
|
||||
}
|
||||
|
||||
ConsoleIO.WriteLine(Translations.mcc_avaliable_profiles + availableProfiles);
|
||||
|
|
@ -703,19 +700,18 @@ namespace MinecraftClient.Protocol
|
|||
|
||||
ConsoleIO.WriteLine(Translations.mcc_selected_profile + " " + selectedProfileName);
|
||||
|
||||
Json.JSONData? selectedProfile = null;
|
||||
foreach (Json.JSONData profile in loginResponse.Properties["availableProfiles"]
|
||||
.DataArray)
|
||||
System.Text.Json.Nodes.JsonNode? selectedProfile = null;
|
||||
foreach (var profile in loginResponse["availableProfiles"]!.AsArray())
|
||||
{
|
||||
selectedProfile = profile.Properties["name"].StringValue == selectedProfileName
|
||||
selectedProfile = profile!["name"]!.GetStringValue() == selectedProfileName
|
||||
? profile
|
||||
: selectedProfile;
|
||||
}
|
||||
|
||||
if (selectedProfile != null)
|
||||
if (selectedProfile is not null)
|
||||
{
|
||||
session.PlayerID = selectedProfile.Properties["id"].StringValue;
|
||||
session.PlayerName = selectedProfile.Properties["name"].StringValue;
|
||||
session.PlayerID = selectedProfile["id"]!.GetStringValue();
|
||||
session.PlayerName = selectedProfile["name"]!.GetStringValue();
|
||||
SessionToken currentsession = session;
|
||||
return GetNewYggdrasilToken(currentsession, out session);
|
||||
}
|
||||
|
|
@ -889,7 +885,7 @@ namespace MinecraftClient.Protocol
|
|||
{
|
||||
var payload = JwtPayloadDecode.GetPayload(session.ID);
|
||||
var json = Json.ParseJson(payload);
|
||||
var expTimestamp = long.Parse(json.Properties["exp"].StringValue, NumberStyles.Any,
|
||||
var expTimestamp = long.Parse(json!["exp"]!.GetStringValue(), NumberStyles.Any,
|
||||
CultureInfo.CurrentCulture);
|
||||
var now = DateTime.Now;
|
||||
var tokenExp = UnixTimeStampToDateTime(expTimestamp);
|
||||
|
|
@ -935,16 +931,15 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
else
|
||||
{
|
||||
Json.JSONData loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse.Properties.ContainsKey("accessToken")
|
||||
&& loginResponse.Properties.ContainsKey("selectedProfile")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("id")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("name"))
|
||||
var loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse?["accessToken"] is not null
|
||||
&& loginResponse["selectedProfile"]?["id"] is not null
|
||||
&& loginResponse["selectedProfile"]?["name"] is not null)
|
||||
{
|
||||
session.ID = loginResponse.Properties["accessToken"].StringValue;
|
||||
session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue;
|
||||
session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"]
|
||||
.StringValue;
|
||||
session.ID = loginResponse["accessToken"]!.GetStringValue();
|
||||
session.PlayerID = loginResponse["selectedProfile"]!["id"]!.GetStringValue();
|
||||
session.PlayerName = loginResponse["selectedProfile"]!["name"]!
|
||||
.GetStringValue();
|
||||
return LoginResult.Success;
|
||||
}
|
||||
else return LoginResult.InvalidResponse;
|
||||
|
|
@ -986,16 +981,15 @@ namespace MinecraftClient.Protocol
|
|||
}
|
||||
else
|
||||
{
|
||||
Json.JSONData loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse.Properties.ContainsKey("accessToken")
|
||||
&& loginResponse.Properties.ContainsKey("selectedProfile")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("id")
|
||||
&& loginResponse.Properties["selectedProfile"].Properties.ContainsKey("name"))
|
||||
var loginResponse = Json.ParseJson(result);
|
||||
if (loginResponse?["accessToken"] is not null
|
||||
&& loginResponse["selectedProfile"]?["id"] is not null
|
||||
&& loginResponse["selectedProfile"]?["name"] is not null)
|
||||
{
|
||||
session.ID = loginResponse.Properties["accessToken"].StringValue;
|
||||
session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue;
|
||||
session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"]
|
||||
.StringValue;
|
||||
session.ID = loginResponse["accessToken"]!.GetStringValue();
|
||||
session.PlayerID = loginResponse["selectedProfile"]!["id"]!.GetStringValue();
|
||||
session.PlayerName = loginResponse["selectedProfile"]!["name"]!
|
||||
.GetStringValue();
|
||||
return LoginResult.Success;
|
||||
}
|
||||
else return LoginResult.InvalidResponse;
|
||||
|
|
@ -1065,28 +1059,27 @@ namespace MinecraftClient.Protocol
|
|||
string cookies = String.Format("sid=token:{0}:{1};user={2};version={3}", accesstoken, uuid, username,
|
||||
Program.MCHighestVersion);
|
||||
DoHTTPSGet("pc.realms.minecraft.net", 443, "/worlds", cookies, ref result);
|
||||
Json.JSONData realmsWorlds = Json.ParseJson(result);
|
||||
if (realmsWorlds.Properties.ContainsKey("servers")
|
||||
&& realmsWorlds.Properties["servers"].Type == Json.JSONData.DataType.Array
|
||||
&& realmsWorlds.Properties["servers"].DataArray.Count > 0)
|
||||
var realmsWorlds = Json.ParseJson(result);
|
||||
if (realmsWorlds?["servers"] is System.Text.Json.Nodes.JsonArray serversArray
|
||||
&& serversArray.Count > 0)
|
||||
{
|
||||
List<string> availableWorlds = new(); // Store string to print
|
||||
int index = 0;
|
||||
foreach (Json.JSONData realmsServer in realmsWorlds.Properties["servers"].DataArray)
|
||||
foreach (var realmsServer in serversArray)
|
||||
{
|
||||
if (realmsServer.Properties.ContainsKey("name")
|
||||
&& realmsServer.Properties.ContainsKey("owner")
|
||||
&& realmsServer.Properties.ContainsKey("id")
|
||||
&& realmsServer.Properties.ContainsKey("expired"))
|
||||
if (realmsServer?["name"] is not null
|
||||
&& realmsServer["owner"] is not null
|
||||
&& realmsServer["id"] is not null
|
||||
&& realmsServer["expired"] is not null)
|
||||
{
|
||||
if (realmsServer.Properties["expired"].StringValue == "false")
|
||||
if (realmsServer["expired"].GetStringValue() == "false")
|
||||
{
|
||||
availableWorlds.Add(String.Format("[{0}] {2} ({3}) - {1}",
|
||||
index++,
|
||||
realmsServer.Properties["id"].StringValue,
|
||||
realmsServer.Properties["name"].StringValue,
|
||||
realmsServer.Properties["owner"].StringValue));
|
||||
realmsWorldsResult.Add(realmsServer.Properties["id"].StringValue);
|
||||
realmsServer["id"]!.GetStringValue(),
|
||||
realmsServer["name"]!.GetStringValue(),
|
||||
realmsServer["owner"]!.GetStringValue()));
|
||||
realmsWorldsResult.Add(realmsServer["id"]!.GetStringValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1132,9 +1125,9 @@ namespace MinecraftClient.Protocol
|
|||
cookies, ref result);
|
||||
if (statusCode == 200)
|
||||
{
|
||||
Json.JSONData serverAddress = Json.ParseJson(result);
|
||||
if (serverAddress.Properties.ContainsKey("address"))
|
||||
return serverAddress.Properties["address"].StringValue;
|
||||
var serverAddress = Json.ParseJson(result);
|
||||
if (serverAddress?["address"] is not null)
|
||||
return serverAddress["address"]!.GetStringValue();
|
||||
else
|
||||
{
|
||||
ConsoleIO.WriteLine(Translations.error_realms_ip_error);
|
||||
|
|
|
|||
|
|
@ -123,35 +123,36 @@ namespace MinecraftClient.Protocol.Session
|
|||
{
|
||||
if (Config.Logging.DebugMessages)
|
||||
ConsoleIO.WriteLineFormatted(string.Format(Translations.cache_loading, Path.GetFileName(SessionCacheFileMinecraft)));
|
||||
Json.JSONData mcSession = new(Json.JSONData.DataType.String);
|
||||
System.Text.Json.Nodes.JsonNode? mcSession = null;
|
||||
try
|
||||
{
|
||||
mcSession = Json.ParseJson(File.ReadAllText(SessionCacheFileMinecraft));
|
||||
}
|
||||
catch (IOException) { /* Failed to read file from disk -- ignoring */ }
|
||||
if (mcSession.Type == Json.JSONData.DataType.Object
|
||||
&& mcSession.Properties.ContainsKey("clientToken")
|
||||
&& mcSession.Properties.ContainsKey("authenticationDatabase"))
|
||||
if (mcSession is System.Text.Json.Nodes.JsonObject mcSessionObj
|
||||
&& mcSessionObj.ContainsKey("clientToken")
|
||||
&& mcSessionObj.ContainsKey("authenticationDatabase"))
|
||||
{
|
||||
string clientID = mcSession.Properties["clientToken"].StringValue.Replace("-", "");
|
||||
Dictionary<string, Json.JSONData> sessionItems = mcSession.Properties["authenticationDatabase"].Properties;
|
||||
foreach (string key in sessionItems.Keys)
|
||||
string clientID = mcSession["clientToken"]!.GetStringValue().Replace("-", "");
|
||||
var sessionItems = mcSession["authenticationDatabase"]!.AsObject();
|
||||
foreach (var kvp in sessionItems)
|
||||
{
|
||||
string key = kvp.Key;
|
||||
if (Guid.TryParseExact(key, "N", out Guid temp))
|
||||
{
|
||||
Dictionary<string, Json.JSONData> sessionItem = sessionItems[key].Properties;
|
||||
var sessionItem = kvp.Value!.AsObject();
|
||||
if (sessionItem.ContainsKey("displayName")
|
||||
&& sessionItem.ContainsKey("accessToken")
|
||||
&& sessionItem.ContainsKey("username")
|
||||
&& sessionItem.ContainsKey("uuid"))
|
||||
{
|
||||
string login = Settings.ToLowerIfNeed(sessionItem["username"].StringValue);
|
||||
string login = Settings.ToLowerIfNeed(sessionItem["username"]!.GetStringValue());
|
||||
try
|
||||
{
|
||||
SessionToken session = SessionToken.FromString(String.Join(",",
|
||||
sessionItem["accessToken"].StringValue,
|
||||
sessionItem["displayName"].StringValue,
|
||||
sessionItem["uuid"].StringValue.Replace("-", ""),
|
||||
sessionItem["accessToken"]!.GetStringValue(),
|
||||
sessionItem["displayName"]!.GetStringValue(),
|
||||
sessionItem["uuid"]!.GetStringValue().Replace("-", ""),
|
||||
clientID
|
||||
));
|
||||
if (Config.Logging.DebugMessages)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue