diff --git a/MinecraftClient/Program.cs b/MinecraftClient/Program.cs
index 42b559a2..fb8d2549 100644
--- a/MinecraftClient/Program.cs
+++ b/MinecraftClient/Program.cs
@@ -262,6 +262,7 @@ namespace MinecraftClient
case ProtocolHandler.LoginResult.AccountMigrated: failureMessage += "Account migrated, use e-mail as username."; break;
case ProtocolHandler.LoginResult.ServiceUnavailable: failureMessage += "Login servers are unavailable. Please try again later."; break;
case ProtocolHandler.LoginResult.WrongPassword: failureMessage += "Incorrect password, blacklisted IP or too many logins."; break;
+ case ProtocolHandler.LoginResult.InvalidResponse: failureMessage += "Invalid server response."; break;
case ProtocolHandler.LoginResult.NotPremium: failureMessage += "User not premium."; break;
case ProtocolHandler.LoginResult.OtherError: failureMessage += "Network error."; break;
case ProtocolHandler.LoginResult.SSLError: failureMessage += "SSL Error."; break;
diff --git a/MinecraftClient/Protocol/ProtocolHandler.cs b/MinecraftClient/Protocol/ProtocolHandler.cs
index dae126e3..b0e0f047 100644
--- a/MinecraftClient/Protocol/ProtocolHandler.cs
+++ b/MinecraftClient/Protocol/ProtocolHandler.cs
@@ -205,16 +205,14 @@ namespace MinecraftClient.Protocol
}
}
- public enum LoginResult { OtherError, ServiceUnavailable, SSLError, Success, WrongPassword, AccountMigrated, NotPremium, LoginRequired, InvalidToken, NullError };
+ public enum LoginResult { OtherError, ServiceUnavailable, SSLError, Success, WrongPassword, AccountMigrated, NotPremium, LoginRequired, InvalidToken, InvalidResponse, NullError };
///
/// Allows to login to a premium Minecraft account using the Yggdrasil authentication scheme.
///
/// Login
/// Password
- /// Will contain the access token returned by Minecraft.net, if the login is successful
- /// Will contain the client token generated before sending to Minecraft.net
- /// Will contain the player's PlayerID, needed for multiplayer
+ /// In case of successful login, will contain session information for multiplayer
/// Returns the status of the login (Success, Failure, etc.)
public static LoginResult GetLogin(string user, string pass, out SessionToken session)
{
@@ -233,13 +231,18 @@ namespace MinecraftClient.Protocol
}
else
{
- string[] temp = result.Split(new string[] { "accessToken\":\"" }, StringSplitOptions.RemoveEmptyEntries);
- if (temp.Length >= 2) { session.ID = temp[1].Split('"')[0]; }
- temp = result.Split(new string[] { "name\":\"" }, StringSplitOptions.RemoveEmptyEntries);
- if (temp.Length >= 2) { session.PlayerName = temp[1].Split('"')[0]; }
- temp = result.Split(new string[] { "availableProfiles\":[{\"id\":\"" }, StringSplitOptions.RemoveEmptyEntries);
- if (temp.Length >= 2) { session.PlayerID = temp[1].Split('"')[0]; }
- return LoginResult.Success;
+ 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"))
+ {
+ session.ID = loginResponse.Properties["accessToken"].StringValue;
+ session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue;
+ session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"].StringValue;
+ return LoginResult.Success;
+ }
+ else return LoginResult.InvalidResponse;
}
}
else if (code == 403)
@@ -281,8 +284,7 @@ namespace MinecraftClient.Protocol
///
/// Validates whether accessToken must be refreshed
///
- /// Will contain the cached access token previously returned by Minecraft.net
- /// Will contain the cached client token created on login
+ /// Session token to validate
/// Returns the status of the token (Valid, Invalid, etc.)
public static LoginResult GetTokenValidation(SessionToken session)
{
@@ -314,13 +316,11 @@ namespace MinecraftClient.Protocol
/// Refreshes invalid token
///
/// Login
- /// Will contain the new access token returned by Minecraft.net, if the refresh is successful
- /// Will contain the client token generated before sending to Minecraft.net
- /// Will contain the player's PlayerID, needed for multiplayer
+ /// In case of successful token refresh, will contain session information for multiplayer
/// Returns the status of the new token request (Success, Failure, etc.)
- public static LoginResult GetNewToken(SessionToken currentsession, out SessionToken newsession)
+ public static LoginResult GetNewToken(SessionToken currentsession, out SessionToken session)
{
- newsession = new SessionToken();
+ session = new SessionToken();
try
{
string result = "";
@@ -332,16 +332,20 @@ namespace MinecraftClient.Protocol
{
return LoginResult.NullError;
}
- else {
- string[] temp = result.Split(new string[] { "accessToken\":\"" }, StringSplitOptions.RemoveEmptyEntries);
- if (temp.Length >= 2) { newsession.ID = temp[1].Split('"')[0]; }
- temp = result.Split(new string[] { "clientToken\":\"" }, StringSplitOptions.RemoveEmptyEntries);
- if (temp.Length >= 2) { newsession.ClientID = temp[1].Split('"')[0]; }
- temp = result.Split(new string[] { "name\":\"" }, StringSplitOptions.RemoveEmptyEntries);
- if (temp.Length >= 2) { newsession.PlayerName = temp[1].Split('"')[0]; }
- temp = result.Split(new string[] { "selectedProfile\":[{\"id\":\"" }, StringSplitOptions.RemoveEmptyEntries);
- if (temp.Length >= 2) { newsession.PlayerID = temp[1].Split('"')[0]; }
- return LoginResult.Success;
+ 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"))
+ {
+ session.ID = loginResponse.Properties["accessToken"].StringValue;
+ session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue;
+ session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"].StringValue;
+ return LoginResult.Success;
+ }
+ else return LoginResult.InvalidResponse;
}
}
else if (code == 403 && result.Contains("InvalidToken"))