diff options
Diffstat (limited to 'src/ClientHandle.cpp')
-rw-r--r-- | src/ClientHandle.cpp | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index b7e85cb32..1daa398bd 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -248,9 +248,12 @@ AString cClientHandle::GenerateOfflineUUID(const AString & a_Username) // xxxxxxxx-xxxx-3xxx-yxxx-xxxxxxxxxxxx where x is any hexadecimal digit and y is one of 8, 9, A, or B // Note that we generate a short UUID (without the dashes) + // First make the username lowercase: + AString lcUsername = StrToLower(a_Username); + // Generate an md5 checksum, and use it as base for the ID: unsigned char MD5[16]; - md5((const unsigned char *)a_Username.c_str(), a_Username.length(), MD5); + md5((const unsigned char *)lcUsername.c_str(), lcUsername.length(), MD5); MD5[6] &= 0x0f; // Need to trim to 4 bits only... MD5[8] &= 0x0f; // ... otherwise %01x overflows into two chars return Printf("%02x%02x%02x%02x%02x%02x3%01x%02x8%01x%02x%02x%02x%02x%02x%02x%02x", @@ -537,9 +540,11 @@ void cClientHandle::RemoveFromAllChunks() } { + // Reset all chunk lists: cCSLock Lock(m_CSChunkLists); m_LoadedChunks.clear(); m_ChunksToSend.clear(); + m_SentChunks.clear(); // Also reset the LastStreamedChunk coords to bogus coords, // so that all chunks are streamed in subsequent StreamChunks() call (FS #407) @@ -593,7 +598,7 @@ bool cClientHandle::HandleLogin(int a_ProtocolVersion, const AString & a_Usernam m_Username = a_Username; // Let the plugins know about this event, they may refuse the player: - if (cRoot::Get()->GetPluginManager()->CallHookLogin(this, a_ProtocolVersion, a_Username)) + if (cRoot::Get()->GetPluginManager()->CallHookLogin(*this, a_ProtocolVersion, a_Username)) { Destroy(); return false; @@ -1712,7 +1717,7 @@ void cClientHandle::HandleKeepAlive(int a_KeepAliveID) bool cClientHandle::HandleHandshake(const AString & a_Username) { - if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(this, a_Username)) + if (!cRoot::Get()->GetPluginManager()->CallHookHandshake(*this, a_Username)) { if (cRoot::Get()->GetServer()->GetNumPlayers() >= cRoot::Get()->GetServer()->GetMaxPlayers()) { @@ -2024,7 +2029,17 @@ void cClientHandle::SendBlockBreakAnim(int a_EntityID, int a_BlockX, int a_Block void cClientHandle::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) { - m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + int ChunkX, ChunkZ = 0; + cChunkDef::BlockToChunk(a_BlockX, a_BlockZ, ChunkX, ChunkZ); + cChunkCoords ChunkCoords = cChunkCoords(ChunkX, ChunkZ); + + // Do not send block changes in chunks that weren't sent to the client yet: + cCSLock Lock(m_CSChunkLists); + if (std::find(m_SentChunks.begin(), m_SentChunks.end(), ChunkCoords) != m_SentChunks.end()) + { + Lock.Unlock(); + m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta); + } } @@ -2034,8 +2049,15 @@ void cClientHandle::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BL void cClientHandle::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) { ASSERT(!a_Changes.empty()); // We don't want to be sending empty change packets! - - m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes); + + // Do not send block changes in chunks that weren't sent to the client yet: + cChunkCoords ChunkCoords = cChunkCoords(a_ChunkX, a_ChunkZ); + cCSLock Lock(m_CSChunkLists); + if (std::find(m_SentChunks.begin(), m_SentChunks.end(), ChunkCoords) != m_SentChunks.end()) + { + Lock.Unlock(); + m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes); + } } @@ -2099,6 +2121,12 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer); + // Add the chunk to the list of chunks sent to the player: + { + cCSLock Lock(m_CSChunkLists); + m_SentChunks.push_back(cChunkCoords(a_ChunkX, a_ChunkZ)); + } + // If it is the chunk the player's in, make them spawn (in the tick thread): if ((m_State == csAuthenticated) || (m_State == csDownloadingWorld)) { @@ -2628,6 +2656,12 @@ void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_D void cClientHandle::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) { + // Remove the chunk from the list of chunks sent to the client: + { + cCSLock Lock(m_CSChunkLists); + m_SentChunks.remove(cChunkCoords(a_ChunkX, a_ChunkZ)); + } + m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ); } @@ -2702,7 +2736,7 @@ void cClientHandle::SendWindowOpen(const cWindow & a_Window) -void cClientHandle::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value) +void cClientHandle::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value) { m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value); } |