diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index fcd8d2bcd..c749d41ab 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -290,7 +290,7 @@ void cClientHandle::Kick(const AString & a_Reason) -void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, const AString & a_Properties) +void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties) { if (m_State != csAuthenticating) { diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 478da5b3c..7bd286a05 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -20,6 +20,7 @@ #include "Map.h" #include "Enchantments.h" #include "UI/SlotArea.h" +#include "json/json.h" @@ -68,7 +69,7 @@ public: const AString & GetUUID(void) const { return m_UUID; } // tolua_export void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; } - const AString & GetProperties(void) const { return m_Properties; } + const Json::Value & GetProperties(void) const { return m_Properties; } /** Generates an UUID based on the username stored for this client, and stores it in the m_UUID member. This is used for the offline (non-auth) mode, when there's no UUID source. @@ -93,8 +94,10 @@ public: static AString FormatChatPrefix(bool ShouldAppendChatPrefixes, AString a_ChatPrefixS, AString m_Color1, AString m_Color2); - void Kick(const AString & a_Reason); // tolua_export - void Authenticate(const AString & a_Name, const AString & a_UUID, const AString & a_Properties); // Called by cAuthenticator when the user passes authentication + void Kick(const AString & a_Reason); // tolua_export + + /** Authenticates the specified user, called by cAuthenticator */ + void Authenticate(const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties); void StreamChunks(void); @@ -282,7 +285,7 @@ private: AString m_Username; AString m_Password; - AString m_Properties; + Json::Value m_Properties; cCriticalSection m_CSChunkLists; cChunkCoordsList m_LoadedChunks; // Chunks that the player belongs to diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index 8fd8952e8..c01d748c6 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -115,7 +115,8 @@ void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, co { if (!m_ShouldAuthenticate) { - cRoot::Get()->AuthenticateUser(a_ClientID, a_UserName, cClientHandle::GenerateOfflineUUID(a_UserName)); + Json::Value Value; + cRoot::Get()->AuthenticateUser(a_ClientID, a_UserName, cClientHandle::GenerateOfflineUUID(a_UserName), Value); return; } @@ -177,7 +178,7 @@ void cAuthenticator::Execute(void) AString UUID; if (AuthWithYggdrasil(NewUserName, ServerID, UUID)) { - AString Properties; + Json::Value Properties; if (!GetPlayerProperties(UUID, Properties)) { LOGINFO("User %s authenticated with UUID %s but property getting failed", NewUserName.c_str(), UUID.c_str()); @@ -329,7 +330,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S -bool cAuthenticator::GetPlayerProperties(const AString & a_UUID, AString & a_Properties) +bool cAuthenticator::GetPlayerProperties(const AString & a_UUID, Json::Value & a_Properties) { LOGD("Trying to get properties for user %s", a_UUID.c_str()); @@ -383,6 +384,10 @@ bool cAuthenticator::GetPlayerProperties(const AString & a_UUID, AString & a_Pro return false; } - a_Properties = root["properties"].toStyledString(); + a_Properties = root["properties"]; return true; -} \ No newline at end of file +} + + + + diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h index 04fa3e09c..9f6dd60ca 100644 --- a/src/Protocol/Authenticator.h +++ b/src/Protocol/Authenticator.h @@ -23,6 +23,11 @@ // fwd: "cRoot.h" class cRoot; +namespace Json +{ + class Value; +} + @@ -79,12 +84,14 @@ private: /** cIsThread override: */ virtual void Execute(void) override; + /** Connects to a hostname using SSL, sends given data, and sets the response, returning whether all was successful or not */ bool ConnectSecurelyToAddress(const AString & a_CACerts, const AString & a_ExpectedPeerName, const AString & a_Data, AString & a_Response); /** Returns true if the user authenticated okay, false on error; iLevel is the recursion deptht (bails out if too deep) */ bool AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID); - bool GetPlayerProperties(const AString & a_UUID, AString & a_Properties); + /** Gets the properties, such as skin, of a player based on their UUID via Mojang's API */ + bool GetPlayerProperties(const AString & a_UUID, Json::Value & a_Properties); }; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index ae800e9cf..d3b1cf946 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -3016,12 +3016,8 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) Pkt.WriteString(a_Player.GetClientHandle()->GetUUID()); Pkt.WriteString(a_Player.GetName()); - Json::Value root; - Json::Reader reader; - reader.parse(m_Client->GetProperties(), root); - - Pkt.WriteVarInt(root.size()); - for (Json::Value::iterator itr = root.begin(); itr != root.end(); ++itr) + Pkt.WriteVarInt(m_Client->GetProperties().size()); + for (Json::Value::iterator itr = m_Client->GetProperties().begin(); itr != m_Client->GetProperties().end(); ++itr) { Pkt.WriteString(((Json::Value)*itr).get("name", "").toStyledString()); Pkt.WriteString(((Json::Value)*itr).get("value", "").toStyledString()); diff --git a/src/Root.cpp b/src/Root.cpp index c578fe6a3..ec1351ef1 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -499,7 +499,7 @@ void cRoot::KickUser(int a_ClientID, const AString & a_Reason) -void cRoot::AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const AString & a_Properties) +void cRoot::AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties) { m_Server->AuthenticateUser(a_ClientID, a_Name, a_UUID, a_Properties); } diff --git a/src/Root.h b/src/Root.h index a9e985656..4a3c205d3 100644 --- a/src/Root.h +++ b/src/Root.h @@ -26,6 +26,11 @@ class cCompositeChat; typedef cItemCallback cPlayerListCallback; typedef cItemCallback cWorldListCallback; +namespace Json +{ + class Value; +} + @@ -89,7 +94,7 @@ public: void KickUser(int a_ClientID, const AString & a_Reason); /// Called by cAuthenticator to auth the specified user - void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const AString & a_Properties = ""); + void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties); /// Executes commands queued in the command queue void TickCommands(void); diff --git a/src/Server.cpp b/src/Server.cpp index 8b479292e..17551eeb1 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -656,7 +656,7 @@ void cServer::KickUser(int a_ClientID, const AString & a_Reason) -void cServer::AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const AString & a_Properties) +void cServer::AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties) { cCSLock Lock(m_CSClients); for (ClientList::iterator itr = m_Clients.begin(); itr != m_Clients.end(); ++itr) diff --git a/src/Server.h b/src/Server.h index 672dc26c0..cf5fa524f 100644 --- a/src/Server.h +++ b/src/Server.h @@ -41,6 +41,11 @@ class cCommandOutputCallback; typedef std::list cClientHandleList; +namespace Json +{ + class Value; +} + @@ -83,7 +88,9 @@ public: // tolua_export void Shutdown(void); void KickUser(int a_ClientID, const AString & a_Reason); - void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const AString & a_Properties); // Called by cAuthenticator to auth the specified user + + /** Authenticates the specified user, called by cAuthenticator */ + void AuthenticateUser(int a_ClientID, const AString & a_Name, const AString & a_UUID, const Json::Value & a_Properties); const AString & GetServerID(void) const { return m_ServerID; } // tolua_export