1
0

Merge remote-tracking branch 'origin/master' into potions

Conflicts:
	src/Entities/Player.cpp
	src/Entities/ProjectileEntity.cpp
This commit is contained in:
archshift
2014-07-09 23:28:27 -07:00
156 changed files with 7471 additions and 5259 deletions

View File

@@ -30,7 +30,7 @@
#include "CompositeChat.h"
#include "Items/ItemSword.h"
#include "md5/md5.h"
#include "polarssl/md5.h"
@@ -232,22 +232,49 @@ AString cClientHandle::FormatMessageType(bool ShouldAppendChatPrefixes, eMessage
AString cClientHandle::GenerateOfflineUUID(const AString & a_Username)
{
// Online UUIDs are always version 4 (random)
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
// This guarantees that they will never collide with an online UUID and can be distinguished.
// 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(a_Username);
AString UUID = Checksum.hexdigest();
UUID[12] = '3'; // Version 3 UUID
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:
UUID.insert(8, "-");
UUID.insert(13, "-");
UUID.insert(18, "-");
UUID.insert(23, "-");
return UUID;
unsigned char MD5[16];
md5((const unsigned char *)a_Username.c_str(), a_Username.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%02x-3%01x%02x-8%01x%02x-%02x%02x%02x%02x%02x%02x",
MD5[0], MD5[1], MD5[2], MD5[3],
MD5[4], MD5[5], MD5[6], MD5[7],
MD5[8], MD5[9], MD5[10], MD5[11],
MD5[12], MD5[13], MD5[14], MD5[15]
);
}
bool cClientHandle::IsUUIDOnline(const AString & a_UUID)
{
// Online UUIDs are always version 4 (random)
// We use Version 3 (MD5 hash) UUIDs for the offline UUIDs
// This guarantees that they will never collide with an online UUID and can be distinguished.
// The version-specifying char is at pos #12 of raw UUID, pos #14 in dashed-UUID.
switch (a_UUID.size())
{
case 32:
{
// This is the UUID format without dashes, the version char is at pos #12:
return (a_UUID[12] == '4');
}
case 36:
{
// This is the UUID format with dashes, the version char is at pos #14:
return (a_UUID[14] == '4');
}
}
return false;
}
@@ -336,6 +363,9 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID)
// Send scoreboard data
World->GetScoreBoard().SendTo(*this);
// Send statistics
SendStatistics(m_Player->GetStatManager());
// Delay the first ping until the client "settles down"
// This should fix #889, "BadCast exception, cannot convert bit to fm" error in client
cTimer t1;
@@ -953,6 +983,26 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
m_LastDigBlockY = a_BlockY;
m_LastDigBlockZ = a_BlockZ;
// Check for clickthrough-blocks:
/* When the user breaks a fire block, the client send the wrong block location.
We must find the right block with the face direction. */
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
return;
}
}
if (
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too
@@ -979,22 +1029,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem());
ItemHandler->OnDiggingBlock(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ, a_BlockFace);
// Check for clickthrough-blocks:
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
Handler = cBlockInfo::GetHandler(World->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
Handler->OnDigging(ChunkInterface, *World, m_Player, pX, pY, pZ);
}
}
}
@@ -1052,12 +1086,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo
void cClientHandle::FinishDigAnimation()
{
if (
!m_HasStartedDigging || // Hasn't received the DIG_STARTED packet
(m_LastDigBlockX == -1) ||
(m_LastDigBlockY == -1) ||
(m_LastDigBlockZ == -1)
)
if (!m_HasStartedDigging) // Hasn't received the DIG_STARTED packet
{
return;
}
@@ -1195,9 +1224,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
{
// A plugin won't let us eat, abort (send the proper packets to the client, too):
m_Player->AbortEating();
return;
}
return;
}
else
{
@@ -2045,9 +2072,9 @@ void cClientHandle::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializ
void cClientHandle::SendCollectPickup(const cPickup & a_Pickup, const cPlayer & a_Player)
void cClientHandle::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
{
m_Protocol->SendCollectPickup(a_Pickup, a_Player);
m_Protocol->SendCollectEntity(a_Entity, a_Player);
}
@@ -2369,9 +2396,9 @@ void cClientHandle::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effec
void cClientHandle::SendRespawn(const cWorld & a_World)
void cClientHandle::SendRespawn(const cWorld & a_World, bool a_ShouldIgnoreDimensionChecks)
{
m_Protocol->SendRespawn(a_World);
m_Protocol->SendRespawn(a_World, a_ShouldIgnoreDimensionChecks);
}