From d505ffc704d85cc1b31ae87647ba979fda84f46f Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 14 Apr 2014 20:21:00 +0200 Subject: [PATCH] A client UUID is generated when the server is in offline mode. 1.7.9 client works with these changes in offline mode. --- src/ClientHandle.cpp | 24 ++++++++++++++++++++++++ src/ClientHandle.h | 7 ++++++- src/Protocol/Protocol17x.cpp | 14 ++++++++++---- 3 files changed, 40 insertions(+), 5 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 615039949..7e8c11d67 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -31,6 +31,8 @@ #include "CompositeChat.h" #include "Items/ItemSword.h" +#include "md5/md5.h" + /** Maximum number of explosions to send this tick, server will start dropping if exceeded */ @@ -175,6 +177,28 @@ void cClientHandle::Destroy(void) +void cClientHandle::GenerateOfflineUUID(void) +{ + // Proper format for a version 3 UUID is: + // xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B + + // Generate an md5 checksum, and use it as base for the ID: + MD5 Checksum(m_Username); + m_UUID = Checksum.hexdigest(); + m_UUID[12] = '3'; // Version 3 UUID + m_UUID[16] = '8'; // Variant 1 UUID + + // Now the digest doesn't have the UUID slashes, but the client requires them, so add them into the appropriate positions: + m_UUID.insert(8, "-"); + m_UUID.insert(13, "-"); + m_UUID.insert(18, "-"); + m_UUID.insert(23, "-"); +} + + + + + void cClientHandle::Kick(const AString & a_Reason) { if (m_State >= csAuthenticating) // Don't log pings diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 0f07c980b..90b971e16 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -63,7 +63,12 @@ public: cPlayer* GetPlayer() { return m_Player; } // tolua_export const AString & GetUUID(void) const { return m_UUID; } // tolua_export - void setUUID(const AString & a_UUID) { m_UUID = a_UUID; } + void SetUUID(const AString & a_UUID) { m_UUID = a_UUID; } + + /** Generates an UUID based on the player name provided. + This is used for the offline (non-auth) mode, when there's no UUID source. + Each username generates a unique and constant UUID, so that when the player reconnects with the same name, their UUID is the same. */ + void GenerateOfflineUUID(void); void Kick(const AString & a_Reason); // tolua_export void Authenticate(const AString & a_Name, const AString & a_UUID); // Called by cAuthenticator when the user passes authentication diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 278b29485..b44c9f919 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -88,8 +88,9 @@ cProtocol172::cProtocol172(cClientHandle * a_Client, const AString & a_ServerAdd // Create the comm log file, if so requested: if (g_ShouldLogCommIn || g_ShouldLogCommOut) { + static int sCounter = 0; cFile::CreateFolder("CommLogs"); - AString FileName = Printf("CommLogs/%x__%s.log", (unsigned)time(NULL), a_Client->GetIPString().c_str()); + AString FileName = Printf("CommLogs/%x_%d__%s.log", (unsigned)time(NULL), sCounter++, a_Client->GetIPString().c_str()); m_CommLogFile.Open(FileName, cFile::fmWrite); } } @@ -796,7 +797,7 @@ void cProtocol172::SendPlayerSpawn(const cPlayer & a_Player) // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt(a_Player.GetUniqueID()); - Pkt.WriteString(Printf("%d", a_Player.GetUniqueID())); // TODO: Proper UUID + Pkt.WriteString(a_Player.GetClientHandle()->GetUUID()); Pkt.WriteString(a_Player.GetName()); Pkt.WriteFPInt(a_Player.GetPosX()); Pkt.WriteFPInt(a_Player.GetPosY()); @@ -1556,6 +1557,7 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe StartEncryption(DecryptedKey); + /* // Send login success: { cPacketizer Pkt(*this, 0x02); // Login success packet @@ -1565,6 +1567,7 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe m_State = 3; // State = Game m_Client->HandleLogin(4, m_Client->GetUsername()); + */ } @@ -1596,10 +1599,13 @@ void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) return; } + // Generate an offline UUID for the player: + m_Client->GenerateOfflineUUID(); + // Send login success: { cPacketizer Pkt(*this, 0x02); // Login success packet - Pkt.WriteString(Printf("%d", m_Client->GetUniqueID())); // TODO: proper UUID + Pkt.WriteString(m_Client->GetUUID()); Pkt.WriteString(Username); } @@ -2773,7 +2779,7 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player) // Called to spawn another player for the client cPacketizer Pkt(*this, 0x0c); // Spawn Player packet Pkt.WriteVarInt(a_Player.GetUniqueID()); - Pkt.WriteString(Printf("00000000-0000-3000-8000-aaaa%08x", a_Player.GetUniqueID())); // TODO: Proper UUID + Pkt.WriteString(a_Player.GetClientHandle()->GetUUID()); Pkt.WriteString(a_Player.GetName()); Pkt.WriteVarInt(0); // We have no data to send here Pkt.WriteFPInt(a_Player.GetPosX());