summaryrefslogtreecommitdiffstats
path: root/src/Protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/Protocol')
-rw-r--r--src/Protocol/Authenticator.cpp13
-rw-r--r--src/Protocol/Authenticator.h8
-rw-r--r--src/Protocol/MojangAPI.cpp192
-rw-r--r--src/Protocol/MojangAPI.h50
-rw-r--r--src/Protocol/Packetizer.cpp53
-rw-r--r--src/Protocol/Packetizer.h6
-rw-r--r--src/Protocol/Protocol_1_10.cpp2
-rw-r--r--src/Protocol/Protocol_1_11.cpp2
-rw-r--r--src/Protocol/Protocol_1_8.cpp15
-rw-r--r--src/Protocol/Protocol_1_9.cpp14
10 files changed, 126 insertions, 229 deletions
diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp
index 12e963143..d46127d34 100644
--- a/src/Protocol/Authenticator.cpp
+++ b/src/Protocol/Authenticator.cpp
@@ -6,6 +6,7 @@
#include "../Root.h"
#include "../Server.h"
#include "../ClientHandle.h"
+#include "../UUID.h"
#include "../IniFile.h"
#include "json/json.h"
@@ -119,11 +120,11 @@ void cAuthenticator::Execute(void)
Lock.Unlock();
AString NewUserName = UserName;
- AString UUID;
+ cUUID UUID;
Json::Value Properties;
if (AuthWithYggdrasil(NewUserName, ServerID, UUID, Properties))
{
- LOGINFO("User %s authenticated with UUID %s", NewUserName.c_str(), UUID.c_str());
+ LOGINFO("User %s authenticated with UUID %s", NewUserName.c_str(), UUID.ToShortString().c_str());
cRoot::Get()->AuthenticateUser(ClientID, NewUserName, UUID, Properties);
}
else
@@ -137,7 +138,7 @@ void cAuthenticator::Execute(void)
-bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties)
+bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, cUUID & a_UUID, Json::Value & a_Properties)
{
LOGD("Trying to authenticate user %s", a_UserName.c_str());
@@ -192,8 +193,12 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S
return false;
}
a_UserName = root.get("name", "Unknown").asString();
- a_UUID = cMojangAPI::MakeUUIDShort(root.get("id", "").asString());
a_Properties = root["properties"];
+ if (!a_UUID.FromString(root.get("id", "").asString()))
+ {
+ LOGWARNING("cAuthenticator: Recieved invalid UUID format");
+ return false;
+ }
// Store the player's profile in the MojangAPI caches:
cRoot::Get()->GetMojangAPI().AddPlayerProfile(a_UserName, a_UUID, a_Properties);
diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h
index 5ce06093c..98bf17512 100644
--- a/src/Protocol/Authenticator.h
+++ b/src/Protocol/Authenticator.h
@@ -14,12 +14,10 @@
#include "../OSSupport/IsThread.h"
+// fwd:
+class cUUID;
class cSettingsRepositoryInterface;
-
-
-
-
namespace Json
{
class Value;
@@ -90,7 +88,7 @@ private:
/** Returns true if the user authenticated okay, false on error
Returns the case-corrected username, UUID, and properties (eg. skin). */
- bool AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, AString & a_UUID, Json::Value & a_Properties);
+ bool AuthWithYggdrasil(AString & a_UserName, const AString & a_ServerId, cUUID & a_UUID, Json::Value & a_Properties);
};
diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp
index 4d5361479..5a11356c1 100644
--- a/src/Protocol/MojangAPI.cpp
+++ b/src/Protocol/MojangAPI.cpp
@@ -154,7 +154,7 @@ static const AString & GetCACerts(void)
cMojangAPI::sProfile::sProfile(
const AString & a_PlayerName,
- const AString & a_UUID,
+ const cUUID & a_UUID,
const Json::Value & a_Properties,
Int64 a_DateTime
) :
@@ -291,7 +291,7 @@ void cMojangAPI::Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldA
-AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached)
+cUUID cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached)
{
// Convert the playername to lowercase:
AString lcPlayerName = StrToLower(a_PlayerName);
@@ -299,8 +299,7 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U
// Request the cache to query the name if not yet cached:
if (!a_UseOnlyCached)
{
- AStringVector PlayerNames;
- PlayerNames.push_back(lcPlayerName);
+ AStringVector PlayerNames{ lcPlayerName };
CacheNamesToUUIDs(PlayerNames);
}
@@ -310,7 +309,7 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U
if (itr == m_NameToUUID.end())
{
// No UUID found
- return "";
+ return {};
}
return itr->second.m_UUID;
}
@@ -319,15 +318,12 @@ AString cMojangAPI::GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_U
-AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached)
+AString cMojangAPI::GetPlayerNameFromUUID(const cUUID & a_UUID, bool a_UseOnlyCached)
{
- // Normalize the UUID to lowercase short format that is used as the map key:
- AString UUID = MakeUUIDShort(a_UUID);
-
// Retrieve from caches:
{
cCSLock Lock(m_CSUUIDToProfile);
- cProfileMap::const_iterator itr = m_UUIDToProfile.find(UUID);
+ auto itr = m_UUIDToProfile.find(a_UUID);
if (itr != m_UUIDToProfile.end())
{
return itr->second.m_PlayerName;
@@ -335,7 +331,7 @@ AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnly
}
{
cCSLock Lock(m_CSUUIDToName);
- cProfileMap::const_iterator itr = m_UUIDToName.find(UUID);
+ auto itr = m_UUIDToName.find(a_UUID);
if (itr != m_UUIDToName.end())
{
return itr->second.m_PlayerName;
@@ -345,19 +341,19 @@ AString cMojangAPI::GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnly
// Name not yet cached, request cache and retry:
if (!a_UseOnlyCached)
{
- CacheUUIDToProfile(UUID);
+ CacheUUIDToProfile(a_UUID);
return GetPlayerNameFromUUID(a_UUID, true);
}
// No value found, none queried. Return an error:
- return "";
+ return {};
}
-AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached)
+std::vector<cUUID> cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_PlayerNames, bool a_UseOnlyCached)
{
// Convert all playernames to lowercase:
AStringVector PlayerNames;
@@ -374,7 +370,7 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player
// Retrieve from cache:
size_t idx = 0;
- AStringVector res;
+ std::vector<cUUID> res;
res.resize(PlayerNames.size());
cCSLock Lock(m_CSNameToUUID);
for (AStringVector::const_iterator itr = PlayerNames.begin(), end = PlayerNames.end(); itr != end; ++itr, ++idx)
@@ -392,17 +388,16 @@ AStringVector cMojangAPI::GetUUIDsFromPlayerNames(const AStringVector & a_Player
-void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID)
+void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const cUUID & a_UUID)
{
- AString UUID = MakeUUIDShort(a_UUID);
Int64 Now = time(nullptr);
{
cCSLock Lock(m_CSNameToUUID);
- m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now);
+ m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, a_UUID, "", "", Now);
}
{
cCSLock Lock(m_CSUUIDToName);
- m_UUIDToName[UUID] = sProfile(a_PlayerName, UUID, "", "", Now);
+ m_UUIDToName[a_UUID] = sProfile(a_PlayerName, a_UUID, "", "", Now);
}
NotifyNameUUID(a_PlayerName, a_UUID);
}
@@ -411,21 +406,20 @@ void cMojangAPI::AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const
-void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties)
+void cMojangAPI::AddPlayerProfile(const AString & a_PlayerName, const cUUID & a_UUID, const Json::Value & a_Properties)
{
- AString UUID = MakeUUIDShort(a_UUID);
Int64 Now = time(nullptr);
{
cCSLock Lock(m_CSNameToUUID);
- m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, UUID, "", "", Now);
+ m_NameToUUID[StrToLower(a_PlayerName)] = sProfile(a_PlayerName, a_UUID, "", "", Now);
}
{
cCSLock Lock(m_CSUUIDToName);
- m_UUIDToName[UUID] = sProfile(a_PlayerName, UUID, "", "", Now);
+ m_UUIDToName[a_UUID] = sProfile(a_PlayerName, a_UUID, "", "", Now);
}
{
cCSLock Lock(m_CSUUIDToProfile);
- m_UUIDToProfile[UUID] = sProfile(a_PlayerName, UUID, a_Properties, Now);
+ m_UUIDToProfile[a_UUID] = sProfile(a_PlayerName, a_UUID, a_Properties, Now);
}
NotifyNameUUID(a_PlayerName, a_UUID);
}
@@ -488,74 +482,6 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
-AString cMojangAPI::MakeUUIDShort(const AString & a_UUID)
-{
- // Note: we only check the string's length, not the actual content
- switch (a_UUID.size())
- {
- case 32:
- {
- // Already is a short UUID, only lowercase
- return StrToLower(a_UUID);
- }
-
- case 36:
- {
- // Remove the dashes from the string by appending together the parts between them:
- AString res;
- res.reserve(32);
- res.append(a_UUID, 0, 8);
- res.append(a_UUID, 9, 4);
- res.append(a_UUID, 14, 4);
- res.append(a_UUID, 19, 4);
- res.append(a_UUID, 24, 12);
- return StrToLower(res);
- }
- }
- LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str());
- return "";
-}
-
-
-
-
-
-AString cMojangAPI::MakeUUIDDashed(const AString & a_UUID)
-{
- // Note: we only check the string's length, not the actual content
- switch (a_UUID.size())
- {
- case 36:
- {
- // Already is a dashed UUID, only lowercase
- return StrToLower(a_UUID);
- }
-
- case 32:
- {
- // Insert dashes at the proper positions:
- AString res;
- res.reserve(36);
- res.append(a_UUID, 0, 8);
- res.push_back('-');
- res.append(a_UUID, 8, 4);
- res.push_back('-');
- res.append(a_UUID, 12, 4);
- res.push_back('-');
- res.append(a_UUID, 16, 4);
- res.push_back('-');
- res.append(a_UUID, 20, 12);
- return StrToLower(res);
- }
- }
- LOGWARNING("%s: Not an UUID: \"%s\".", __FUNCTION__, a_UUID.c_str());
- return "";
-}
-
-
-
-
-
void cMojangAPI::LoadCachesFromDisk(void)
{
try
@@ -571,9 +497,15 @@ void cMojangAPI::LoadCachesFromDisk(void)
while (stmt.executeStep())
{
AString PlayerName = stmt.getColumn(0);
- AString UUID = stmt.getColumn(1);
+ AString StringUUID = stmt.getColumn(1);
Int64 DateTime = stmt.getColumn(2);
- UUID = MakeUUIDShort(UUID);
+
+ cUUID UUID;
+ if (!UUID.FromString(StringUUID))
+ {
+ continue; // Invalid UUID
+ }
+
m_NameToUUID[StrToLower(PlayerName)] = sProfile(PlayerName, UUID, "", "", DateTime);
m_UUIDToName[UUID] = sProfile(PlayerName, UUID, "", "", DateTime);
}
@@ -583,11 +515,17 @@ void cMojangAPI::LoadCachesFromDisk(void)
while (stmt.executeStep())
{
AString PlayerName = stmt.getColumn(0);
- AString UUID = stmt.getColumn(1);
+ AString StringUUID = stmt.getColumn(1);
AString Textures = stmt.getColumn(2);
AString TexturesSignature = stmt.getColumn(2);
Int64 DateTime = stmt.getColumn(4);
- UUID = MakeUUIDShort(UUID);
+
+ cUUID UUID;
+ if (!UUID.FromString(StringUUID))
+ {
+ continue; // Invalid UUID
+ }
+
m_UUIDToProfile[UUID] = sProfile(PlayerName, UUID, Textures, TexturesSignature, DateTime);
}
}
@@ -620,16 +558,17 @@ void cMojangAPI::SaveCachesToDisk(void)
{
SQLite::Statement stmt(db, "INSERT INTO PlayerNameToUUID(PlayerName, UUID, DateTime) VALUES (?, ?, ?)");
cCSLock Lock(m_CSNameToUUID);
- for (cProfileMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr)
+ for (auto & NameToUUID : m_NameToUUID)
{
- if (itr->second.m_DateTime < LimitDateTime)
+ auto & Profile = NameToUUID.second;
+ if (Profile.m_DateTime < LimitDateTime)
{
// This item is too old, do not save
continue;
}
- stmt.bind(1, itr->second.m_PlayerName);
- stmt.bind(2, itr->second.m_UUID);
- stmt.bind(3, itr->second.m_DateTime);
+ stmt.bind(1, Profile.m_PlayerName);
+ stmt.bind(2, Profile.m_UUID.ToShortString());
+ stmt.bind(3, Profile.m_DateTime);
stmt.exec();
stmt.reset();
}
@@ -639,18 +578,19 @@ void cMojangAPI::SaveCachesToDisk(void)
{
SQLite::Statement stmt(db, "INSERT INTO UUIDToProfile(UUID, PlayerName, Textures, TexturesSignature, DateTime) VALUES (?, ?, ?, ?, ?)");
cCSLock Lock(m_CSUUIDToProfile);
- for (cProfileMap::const_iterator itr = m_UUIDToProfile.begin(), end = m_UUIDToProfile.end(); itr != end; ++itr)
+ for (auto & UUIDToProfile : m_UUIDToProfile)
{
- if (itr->second.m_DateTime < LimitDateTime)
+ auto & Profile = UUIDToProfile.second;
+ if (Profile.m_DateTime < LimitDateTime)
{
// This item is too old, do not save
continue;
}
- stmt.bind(1, itr->second.m_UUID);
- stmt.bind(2, itr->second.m_PlayerName);
- stmt.bind(3, itr->second.m_Textures);
- stmt.bind(4, itr->second.m_TexturesSignature);
- stmt.bind(5, itr->second.m_DateTime);
+ stmt.bind(1, Profile.m_UUID.ToShortString());
+ stmt.bind(2, Profile.m_PlayerName);
+ stmt.bind(3, Profile.m_Textures);
+ stmt.bind(4, Profile.m_TexturesSignature);
+ stmt.bind(5, Profile.m_DateTime);
stmt.exec();
stmt.reset();
}
@@ -762,8 +702,8 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
{
Json::Value & Val = root[idx];
AString JsonName = Val.get("name", "").asString();
- AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString());
- if (JsonUUID.empty())
+ cUUID JsonUUID;
+ if (!JsonUUID.FromString(Val.get("id", "").asString()))
{
continue;
}
@@ -779,8 +719,8 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
{
Json::Value & Val = root[idx];
AString JsonName = Val.get("name", "").asString();
- AString JsonUUID = MakeUUIDShort(Val.get("id", "").asString());
- if (JsonUUID.empty())
+ cUUID JsonUUID;
+ if (!JsonUUID.FromString(Val.get("id", "").asString()))
{
continue;
}
@@ -794,10 +734,8 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
-void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID)
+void cMojangAPI::CacheUUIDToProfile(const cUUID & a_UUID)
{
- ASSERT(a_UUID.size() == 32);
-
// Check if already present:
{
cCSLock Lock(m_CSUUIDToProfile);
@@ -814,11 +752,11 @@ void cMojangAPI::CacheUUIDToProfile(const AString & a_UUID)
-void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID)
+void cMojangAPI::QueryUUIDToProfile(const cUUID & a_UUID)
{
// Create the request address:
AString Address = m_UUIDToProfileAddress;
- ReplaceString(Address, "%UUID%", a_UUID);
+ ReplaceString(Address, "%UUID%", a_UUID.ToShortString());
// Create the HTTP request:
AString Request;
@@ -909,7 +847,7 @@ void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID)
-void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const AString & a_UUID)
+void cMojangAPI::NotifyNameUUID(const AString & a_PlayerName, const cUUID & a_UUID)
{
// Notify the rank manager:
cCSLock Lock(m_CSRankMgr);
@@ -931,11 +869,11 @@ void cMojangAPI::Update(void)
AStringVector PlayerNames;
{
cCSLock Lock(m_CSNameToUUID);
- for (cProfileMap::const_iterator itr = m_NameToUUID.begin(), end = m_NameToUUID.end(); itr != end; ++itr)
+ for (const auto & NameToUUID : m_NameToUUID)
{
- if (itr->second.m_DateTime < LimitDateTime)
+ if (NameToUUID.second.m_DateTime < LimitDateTime)
{
- PlayerNames.push_back(itr->first);
+ PlayerNames.push_back(NameToUUID.first);
}
} // for itr - m_NameToUUID[]
}
@@ -946,23 +884,23 @@ void cMojangAPI::Update(void)
}
// Re-query all profiles that are stale:
- AStringVector ProfileUUIDs;
+ std::vector<cUUID> ProfileUUIDs;
{
cCSLock Lock(m_CSUUIDToProfile);
- for (cProfileMap::const_iterator itr = m_UUIDToProfile.begin(), end = m_UUIDToProfile.end(); itr != end; ++itr)
+ for (auto & UUIDToProfile : m_UUIDToProfile)
{
- if (itr->second.m_DateTime < LimitDateTime)
+ if (UUIDToProfile.second.m_DateTime < LimitDateTime)
{
- ProfileUUIDs.push_back(itr->first);
+ ProfileUUIDs.push_back(UUIDToProfile.first);
}
} // for itr - m_UUIDToProfile[]
}
if (!ProfileUUIDs.empty())
{
LOG("cMojangAPI: Updating uuid-to-profile cache for %u uuids", static_cast<unsigned>(ProfileUUIDs.size()));
- for (AStringVector::const_iterator itr = ProfileUUIDs.begin(), end = ProfileUUIDs.end(); itr != end; ++itr)
+ for (const auto & UUID : ProfileUUIDs)
{
- QueryUUIDToProfile(*itr);
+ QueryUUIDToProfile(UUID);
}
}
}
diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h
index 3cd0376be..4d1751f1c 100644
--- a/src/Protocol/MojangAPI.h
+++ b/src/Protocol/MojangAPI.h
@@ -11,6 +11,8 @@
#include <time.h>
+#include "../UUID.h"
+
@@ -45,49 +47,38 @@ public:
Returns true if all was successful, false on failure. */
static bool SecureRequest(const AString & a_ServerName, const AString & a_Request, AString & a_Response);
- /** Normalizes the given UUID to its short form (32 bytes, no dashes, lowercase).
- Logs a warning and returns empty string if not a UUID.
- Note: only checks the string's length, not the actual content. */
- static AString MakeUUIDShort(const AString & a_UUID);
-
- /** Normalizes the given UUID to its dashed form (36 bytes, 4 dashes, lowercase).
- Logs a warning and returns empty string if not a UUID.
- Note: only checks the string's length, not the actual content. */
- static AString MakeUUIDDashed(const AString & a_UUID);
-
/** Converts a player name into a UUID.
- The UUID will be empty on error.
+ The UUID will be nil on error.
If a_UseOnlyCached is true, the function only consults the cached values.
If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking
operation, do not use this in world-tick thread!
If you have multiple names to resolve, use the GetUUIDsFromPlayerNames() function, it uses a single request for multiple names. */
- AString GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false);
+ cUUID GetUUIDFromPlayerName(const AString & a_PlayerName, bool a_UseOnlyCached = false);
/** Converts a UUID into a playername.
The returned playername will be empty on error.
- Both short and dashed UUID formats are accepted.
Uses both m_UUIDToName and m_UUIDToProfile to search for the value. Uses m_UUIDToProfile for cache.
If a_UseOnlyCached is true, the function only consults the cached values.
If a_UseOnlyCached is false and the name is not found in the cache, it is looked up online, which is a blocking
operation, do not use this in world-tick thread! */
- AString GetPlayerNameFromUUID(const AString & a_UUID, bool a_UseOnlyCached = false);
+ AString GetPlayerNameFromUUID(const cUUID & a_UUID, bool a_UseOnlyCached = false);
/** Converts the player names into UUIDs.
a_PlayerName[idx] will be converted to UUID and returned as idx-th value
- The UUID will be empty on error.
+ The UUID will be nil on error.
If a_UseOnlyCached is true, only the cached values are returned.
If a_UseOnlyCached is false, the names not found in the cache are looked up online, which is a blocking
operation, do not use this in world-tick thread! */
- AStringVector GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false);
+ std::vector<cUUID> GetUUIDsFromPlayerNames(const AStringVector & a_PlayerName, bool a_UseOnlyCached = false);
/** Called by the Authenticator to add a PlayerName -> UUID mapping that it has received from
authenticating a user. This adds the cache item and "refreshes" it if existing, adjusting its datetime
stamp to now. */
- void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const AString & a_UUID);
+ void AddPlayerNameToUUIDMapping(const AString & a_PlayerName, const cUUID & a_UUID);
/** Called by the Authenticator to add a profile that it has received from authenticating a user. Adds
the profile to the respective mapping caches and updtes their datetime stamp to now. */
- void AddPlayerProfile(const AString & a_PlayerName, const AString & a_UUID, const Json::Value & a_Properties);
+ void AddPlayerProfile(const AString & a_PlayerName, const cUUID & a_UUID, const Json::Value & a_Properties);
/** Sets the m_RankMgr that is used for name-uuid notifications. Accepts nullptr to remove the binding. */
void SetRankManager(cRankManager * a_RankManager) { m_RankMgr = a_RankManager; }
@@ -101,7 +92,7 @@ protected:
struct sProfile
{
AString m_PlayerName; // Case-correct playername
- AString m_UUID; // Short lowercased UUID
+ cUUID m_UUID; // Player UUID
AString m_Textures; // The Textures field of the profile properties
AString m_TexturesSignature; // The signature of the Textures field of the profile properties
Int64 m_DateTime; // UNIXtime of the profile lookup
@@ -119,7 +110,7 @@ protected:
/** Constructor for the storage creation. */
sProfile(
const AString & a_PlayerName,
- const AString & a_UUID,
+ const cUUID & a_UUID,
const AString & a_Textures,
const AString & a_TexturesSignature,
Int64 a_DateTime
@@ -135,12 +126,13 @@ protected:
/** Constructor that parses the values from the Json profile. */
sProfile(
const AString & a_PlayerName,
- const AString & a_UUID,
+ const cUUID & a_UUID,
const Json::Value & a_Properties,
Int64 a_DateTime
);
};
typedef std::map<AString, sProfile> cProfileMap;
+ typedef std::map<cUUID, sProfile> cUUIDProfileMap;
/** The server to connect to when converting player names to UUIDs. For example "api.mojang.com". */
@@ -164,14 +156,14 @@ protected:
cCriticalSection m_CSNameToUUID;
/** Cache for the Name-to-UUID lookups. The map key is lowercased short UUID. Protected by m_CSUUIDToName. */
- cProfileMap m_UUIDToName;
+ cUUIDProfileMap m_UUIDToName;
/** Protects m_UUIDToName against simultaneous multi-threaded access. */
cCriticalSection m_CSUUIDToName;
/** Cache for the UUID-to-profile lookups. The map key is lowercased short UUID.
Protected by m_CSUUIDToProfile. */
- cProfileMap m_UUIDToProfile;
+ cUUIDProfileMap m_UUIDToProfile;
/** Protects m_UUIDToProfile against simultaneous multi-threaded access. */
cCriticalSection m_CSUUIDToProfile;
@@ -204,18 +196,16 @@ protected:
void QueryNamesToUUIDs(AStringVector & a_PlayerNames);
/** Makes sure the specified UUID is in the m_UUIDToProfile cache. If missing, downloads it from Mojang API servers.
- UUIDs that are not valid will not be added into the cache.
- ASSUMEs that a_UUID is a lowercased short UUID. */
- void CacheUUIDToProfile(const AString & a_UUID);
+ UUIDs that are not valid will not be added into the cache. */
+ void CacheUUIDToProfile(const cUUID & a_UUID);
/** Queries the specified UUID's profile and stores it in the m_UUIDToProfile cache. If already present, updates the cache entry.
- UUIDs that are not valid will not be added into the cache.
- ASSUMEs that a_UUID is a lowercased short UUID. */
- void QueryUUIDToProfile(const AString & a_UUID);
+ UUIDs that are not valid will not be added into the cache. */
+ void QueryUUIDToProfile(const cUUID & a_UUID);
/** Called for each name-uuid pairing that is discovered.
If assigned, notifies the m_RankManager of the event. */
- void NotifyNameUUID(const AString & a_PlayerName, const AString & a_PlayerUUID);
+ void NotifyNameUUID(const AString & a_PlayerName, const cUUID & a_PlayerUUID);
/** Updates the stale values in the DB from the Mojang servers. Called from the cUpdateThread, blocks on the HTTPS API calls. */
void Update(void);
diff --git a/src/Protocol/Packetizer.cpp b/src/Protocol/Packetizer.cpp
index 0a84d4678..5cae1fad5 100644
--- a/src/Protocol/Packetizer.cpp
+++ b/src/Protocol/Packetizer.cpp
@@ -5,46 +5,7 @@
#include "Globals.h"
#include "Packetizer.h"
-
-
-
-
-
-/** Converts the hex digit character to its value. */
-static UInt8 HexDigitValue(char a_Character)
-{
- switch (a_Character)
- {
- case '0': return 0;
- case '1': return 1;
- case '2': return 2;
- case '3': return 3;
- case '4': return 4;
- case '5': return 5;
- case '6': return 6;
- case '7': return 7;
- case '8': return 8;
- case '9': return 9;
- case 'a': return 10;
- case 'b': return 11;
- case 'c': return 12;
- case 'd': return 13;
- case 'e': return 14;
- case 'f': return 15;
- case 'A': return 10;
- case 'B': return 11;
- case 'C': return 12;
- case 'D': return 13;
- case 'E': return 14;
- case 'F': return 15;
- default:
- {
- LOGWARNING("Bad hex digit: %c", a_Character);
- ASSERT(!"Bad hex digit");
- return 0;
- }
- }
-}
+#include "UUID.h"
@@ -80,18 +41,10 @@ void cPacketizer::WriteFPInt(double a_Value)
-void cPacketizer::WriteUUID(const AString & a_UUID)
+void cPacketizer::WriteUUID(const cUUID & a_UUID)
{
- if (a_UUID.length() != 32)
- {
- LOGWARNING("%s: Attempt to send a bad uuid (length isn't 32): %s", __FUNCTION__, a_UUID.c_str());
- ASSERT(!"Wrong uuid length!");
- return;
- }
-
- for (size_t i = 0; i < 32; i += 2)
+ for (auto val : a_UUID.ToRaw())
{
- auto val = static_cast<UInt8>(HexDigitValue(a_UUID[i]) << 4 | HexDigitValue(a_UUID[i + 1]));
VERIFY(m_Out.WriteBEUInt8(val));
}
}
diff --git a/src/Protocol/Packetizer.h b/src/Protocol/Packetizer.h
index 26b3a7ec7..6d2284976 100644
--- a/src/Protocol/Packetizer.h
+++ b/src/Protocol/Packetizer.h
@@ -17,6 +17,10 @@
class cByteBuffer;
+// fwd:
+class cUUID;
+
+
@@ -134,7 +138,7 @@ public:
void WriteFPInt(double a_Value);
/** Writes the specified UUID as a 128-bit BigEndian integer. */
- void WriteUUID(const AString & a_UUID);
+ void WriteUUID(const cUUID & a_UUID);
UInt32 GetPacketType(void) const { return m_PacketType; }
diff --git a/src/Protocol/Protocol_1_10.cpp b/src/Protocol/Protocol_1_10.cpp
index 650f9dd32..67b76872a 100644
--- a/src/Protocol/Protocol_1_10.cpp
+++ b/src/Protocol/Protocol_1_10.cpp
@@ -619,7 +619,7 @@ void cProtocol_1_10_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
Writer.BeginCompound("Owner");
- Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
+ Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
Writer.BeginCompound("Properties");
Writer.BeginList("textures", TAG_Compound);
diff --git a/src/Protocol/Protocol_1_11.cpp b/src/Protocol/Protocol_1_11.cpp
index 9212e97ed..c562503bd 100644
--- a/src/Protocol/Protocol_1_11.cpp
+++ b/src/Protocol/Protocol_1_11.cpp
@@ -466,7 +466,7 @@ void cProtocol_1_11_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
Writer.BeginCompound("Owner");
- Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
+ Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
Writer.BeginCompound("Properties");
Writer.BeginList("textures", TAG_Compound);
diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp
index 3e2f084c7..42e69fd43 100644
--- a/src/Protocol/Protocol_1_8.cpp
+++ b/src/Protocol/Protocol_1_8.cpp
@@ -22,6 +22,7 @@ Implements the 1.8 protocol classes:
#include "../StringCompression.h"
#include "../CompositeChat.h"
#include "../Statistics.h"
+#include "../UUID.h"
#include "../WorldStorage/FastNBT.h"
#include "../WorldStorage/EnchantmentSerializer.h"
@@ -118,7 +119,11 @@ cProtocol_1_8_0::cProtocol_1_8_0(cClientHandle * a_Client, const AString & a_Ser
LOGD("Player at %s connected via BungeeCord", Params[1].c_str());
m_ServerAddress = Params[0];
m_Client->SetIPString(Params[1]);
- m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2]));
+
+ cUUID UUID;
+ UUID.FromString(Params[2]);
+ m_Client->SetUUID(UUID);
+
m_Client->SetProperties(Params[3]);
}
@@ -705,7 +710,7 @@ void cProtocol_1_8_0::SendLoginSuccess(void)
{
cPacketizer Pkt(*this, 0x02); // Login success packet
- Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID()));
+ Pkt.WriteString(m_Client->GetUUID().ToLongString());
Pkt.WriteString(m_Client->GetUsername());
}
}
@@ -1071,7 +1076,7 @@ void cProtocol_1_8_0::SendPlayerSpawn(const cPlayer & a_Player)
// Called to spawn another player for the client
cPacketizer Pkt(*this, 0x0c); // Spawn Player packet
Pkt.WriteVarInt32(a_Player.GetUniqueID());
- Pkt.WriteUUID(cMojangAPI::MakeUUIDShort(a_Player.GetUUID()));
+ Pkt.WriteUUID(a_Player.GetUUID());
Pkt.WriteFPInt(a_Player.GetPosX());
Pkt.WriteFPInt(a_Player.GetPosY() + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on.
Pkt.WriteFPInt(a_Player.GetPosZ());
@@ -2551,7 +2556,7 @@ void cProtocol_1_8_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketSpectate(cByteBuffer &a_ByteBuffer)
{
- AString playerUUID;
+ cUUID playerUUID;
if (!a_ByteBuffer.ReadUUID(playerUUID))
{
return;
@@ -3183,7 +3188,7 @@ void cProtocol_1_8_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity &
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
Writer.BeginCompound("Owner");
- Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
+ Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
Writer.BeginCompound("Properties");
Writer.BeginList("textures", TAG_Compound);
diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp
index 7921d3e36..0c5ac58f6 100644
--- a/src/Protocol/Protocol_1_9.cpp
+++ b/src/Protocol/Protocol_1_9.cpp
@@ -133,7 +133,11 @@ cProtocol_1_9_0::cProtocol_1_9_0(cClientHandle * a_Client, const AString & a_Ser
LOGD("Player at %s connected via BungeeCord", Params[1].c_str());
m_ServerAddress = Params[0];
m_Client->SetIPString(Params[1]);
- m_Client->SetUUID(cMojangAPI::MakeUUIDShort(Params[2]));
+
+ cUUID UUID;
+ UUID.FromString(Params[2]);
+ m_Client->SetUUID(UUID);
+
m_Client->SetProperties(Params[3]);
}
@@ -720,7 +724,7 @@ void cProtocol_1_9_0::SendLoginSuccess(void)
{
cPacketizer Pkt(*this, 0x02); // Login success packet
- Pkt.WriteString(cMojangAPI::MakeUUIDDashed(m_Client->GetUUID()));
+ Pkt.WriteString(m_Client->GetUUID().ToLongString());
Pkt.WriteString(m_Client->GetUsername());
}
}
@@ -1094,7 +1098,7 @@ void cProtocol_1_9_0::SendPlayerSpawn(const cPlayer & a_Player)
// Called to spawn another player for the client
cPacketizer Pkt(*this, 0x05); // Spawn Player packet
Pkt.WriteVarInt32(a_Player.GetUniqueID());
- Pkt.WriteUUID(cMojangAPI::MakeUUIDShort(a_Player.GetUUID()));
+ Pkt.WriteUUID(a_Player.GetUUID());
Pkt.WriteBEDouble(a_Player.GetPosX());
Pkt.WriteBEDouble(a_Player.GetPosY() + 0.001); // The "+ 0.001" is there because otherwise the player falls through the block they were standing on.
Pkt.WriteBEDouble(a_Player.GetPosZ());
@@ -2624,7 +2628,7 @@ void cProtocol_1_9_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
void cProtocol_1_9_0::HandlePacketSpectate(cByteBuffer & a_ByteBuffer)
{
- AString playerUUID;
+ cUUID playerUUID;
if (!a_ByteBuffer.ReadUUID(playerUUID))
{
return;
@@ -3513,7 +3517,7 @@ void cProtocol_1_9_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity &
// The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity
Writer.BeginCompound("Owner");
- Writer.AddString("Id", MobHeadEntity.GetOwnerUUID());
+ Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString());
Writer.AddString("Name", MobHeadEntity.GetOwnerName());
Writer.BeginCompound("Properties");
Writer.BeginList("textures", TAG_Compound);