summaryrefslogtreecommitdiffstats
path: root/Tools/ProtoProxy/Connection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/ProtoProxy/Connection.cpp')
-rw-r--r--Tools/ProtoProxy/Connection.cpp1131
1 files changed, 669 insertions, 462 deletions
diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp
index c4776949e..b99415900 100644
--- a/Tools/ProtoProxy/Connection.cpp
+++ b/Tools/ProtoProxy/Connection.cpp
@@ -52,7 +52,7 @@
#define CLIENTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client")
#define SERVERSEND(...) SendData(m_ServerSocket, __VA_ARGS__, "Server")
-#define CLIENTENCRYPTSEND(...) SendEncryptedData(m_ClientSocket, m_ClientEncryptor, __VA_ARGS__, "Client")
+#define CLIENTENCRYPTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client") // The client conn is always unencrypted
#define SERVERENCRYPTSEND(...) SendEncryptedData(m_ServerSocket, m_ServerEncryptor, __VA_ARGS__, "Server")
#define COPY_TO_SERVER() \
@@ -99,19 +99,20 @@
CLIENTENCRYPTSEND(ToClient.data(), ToClient.size()); \
break; \
} \
- case csWaitingForEncryption: \
+ /* case csWaitingForEncryption: \
{ \
Log("Waiting for client encryption, queued %u bytes", ToClient.size()); \
m_ClientEncryptionBuffer.append(ToClient.data(), ToClient.size()); \
break; \
} \
+ */ \
} \
DebugSleep(50); \
}
#define HANDLE_CLIENT_READ(Proc) \
{ \
- if (!Proc()) \
+ if (!Proc) \
{ \
AString Leftover; \
m_ClientBuffer.ReadAgain(Leftover); \
@@ -123,7 +124,7 @@
#define HANDLE_SERVER_READ(Proc) \
{ \
- if (!Proc()) \
+ if (!Proc) \
{ \
m_ServerBuffer.ResetRead(); \
return true; \
@@ -144,15 +145,20 @@ typedef unsigned char Byte;
enum
{
- PACKET_KEEPALIVE = 0x00,
- PACKET_LOGIN = 0x01,
- PACKET_HANDSHAKE = 0x02,
- PACKET_CHAT_MESSAGE = 0x03,
- PACKET_TIME_UPDATE = 0x04,
- PACKET_ENTITY_EQUIPMENT = 0x05,
- PACKET_COMPASS = 0x06,
+ // client-bound packets:
+ PACKET_C_KEEPALIVE = 0x00,
+ PACKET_C_JOIN_GAME = 0x01,
+ PACKET_C_CHAT_MESSAGE = 0x02,
+
+ // server-bound packets:
+ PACKET_S_KEEPALIVE = 0x00, // Also the initial handshake, as the very first packet
+ PACKET_S_CHAT_MESSAGE = 0x01,
+
+ PACKET_TIME_UPDATE = 0x03,
+ PACKET_ENTITY_EQUIPMENT = 0x04,
+ PACKET_SPAWN_POSITION = 0x05,
+ PACKET_UPDATE_HEALTH = 0x06,
PACKET_USE_ENTITY = 0x07,
- PACKET_UPDATE_HEALTH = 0x08,
PACKET_PLAYER_ON_GROUND = 0x0a,
PACKET_PLAYER_POSITION = 0x0b,
PACKET_PLAYER_LOOK = 0x0c,
@@ -270,7 +276,10 @@ cConnection::cConnection(SOCKET a_ClientSocket, cServer & a_Server) :
m_Nonce(0),
m_ClientBuffer(1024 KiB),
m_ServerBuffer(1024 KiB),
- m_HasClientPinged(false)
+ m_HasClientPinged(false),
+ m_ServerProtocolState(-1),
+ m_ClientProtocolState(-1),
+ m_IsServerEncrypted(false)
{
// Create the Logs subfolder, if not already created:
#if defined(_WIN32)
@@ -279,7 +288,7 @@ cConnection::cConnection(SOCKET a_ClientSocket, cServer & a_Server) :
mkdir("Logs", 0777);
#endif
- Printf(m_LogNameBase, "Logs/Log_%d", (int)time(NULL));
+ Printf(m_LogNameBase, "Logs/Log_%d_%d", (int)time(NULL), a_ClientSocket);
AString fnam(m_LogNameBase);
fnam.append(".log");
m_LogFile = fopen(fnam.c_str(), "w");
@@ -453,7 +462,6 @@ bool cConnection::RelayFromServer(void)
{
m_ServerDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
DataLog(Buffer, res, "Decrypted %d bytes from the SERVER", res);
- m_ClientEncryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
return CLIENTSEND(Buffer, res);
}
}
@@ -486,13 +494,10 @@ bool cConnection::RelayFromClient(void)
}
case csEncryptedUnderstood:
{
- m_ClientDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
- DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res);
return DecodeClientsPackets(Buffer, res);
}
case csEncryptedUnknown:
{
- m_ClientDecryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
DataLog(Buffer, res, "Decrypted %d bytes from the CLIENT", res);
m_ServerEncryptor.ProcessData((byte *)Buffer, (byte *)Buffer, res);
return SERVERSEND(Buffer, res);
@@ -517,7 +522,7 @@ double cConnection::GetRelativeTime(void)
bool cConnection::SendData(SOCKET a_Socket, const char * a_Data, int a_Size, const char * a_Peer)
{
- DataLog(a_Data, a_Size, "Sending data to %s", a_Peer);
+ DataLog(a_Data, a_Size, "Sending data to %s, %d bytes", a_Peer, a_Size);
int res = send(a_Socket, a_Data, a_Size, 0);
if (res <= 0)
@@ -590,66 +595,97 @@ bool cConnection::DecodeClientsPackets(const char * a_Data, int a_Size)
while (m_ClientBuffer.CanReadBytes(1))
{
- unsigned char PacketType;
- m_ClientBuffer.ReadByte(PacketType);
- Log("Decoding client's packets, there are now %d bytes in the queue; next packet is 0x%02x", m_ClientBuffer.GetReadableSpace(), PacketType);
- switch (PacketType)
+ UInt32 PacketLen;
+ if (
+ !m_ClientBuffer.ReadVarInt(PacketLen) ||
+ !m_ClientBuffer.CanReadBytes(PacketLen)
+ )
{
- case PACKET_BLOCK_DIG: HANDLE_CLIENT_READ(HandleClientBlockDig); break;
- case PACKET_BLOCK_PLACE: HANDLE_CLIENT_READ(HandleClientBlockPlace); break;
- case PACKET_CHAT_MESSAGE: HANDLE_CLIENT_READ(HandleClientChatMessage); break;
- case PACKET_CLIENT_STATUSES: HANDLE_CLIENT_READ(HandleClientClientStatuses); break;
- case PACKET_CREATIVE_INVENTORY_ACTION: HANDLE_CLIENT_READ(HandleClientCreativeInventoryAction); break;
- case PACKET_DISCONNECT: HANDLE_CLIENT_READ(HandleClientDisconnect); break;
- case PACKET_ENCRYPTION_KEY_RESPONSE: HANDLE_CLIENT_READ(HandleClientEncryptionKeyResponse); break;
- case PACKET_ENTITY_ACTION: HANDLE_CLIENT_READ(HandleClientEntityAction); break;
- case PACKET_HANDSHAKE: HANDLE_CLIENT_READ(HandleClientHandshake); break;
- case PACKET_KEEPALIVE: HANDLE_CLIENT_READ(HandleClientKeepAlive); break;
- case PACKET_LOCALE_AND_VIEW: HANDLE_CLIENT_READ(HandleClientLocaleAndView); break;
- case PACKET_PING: HANDLE_CLIENT_READ(HandleClientPing); break;
- case PACKET_PLAYER_ABILITIES: HANDLE_CLIENT_READ(HandleClientPlayerAbilities); break;
- case PACKET_PLAYER_ANIMATION: HANDLE_CLIENT_READ(HandleClientAnimation); break;
- case PACKET_PLAYER_LOOK: HANDLE_CLIENT_READ(HandleClientPlayerLook); break;
- case PACKET_PLAYER_ON_GROUND: HANDLE_CLIENT_READ(HandleClientPlayerOnGround); break;
- case PACKET_PLAYER_POSITION: HANDLE_CLIENT_READ(HandleClientPlayerPosition); break;
- case PACKET_PLAYER_POSITION_LOOK: HANDLE_CLIENT_READ(HandleClientPlayerPositionLook); break;
- case PACKET_PLUGIN_MESSAGE: HANDLE_CLIENT_READ(HandleClientPluginMessage); break;
- case PACKET_SLOT_SELECT: HANDLE_CLIENT_READ(HandleClientSlotSelect); break;
- case PACKET_TAB_COMPLETION: HANDLE_CLIENT_READ(HandleClientTabCompletion); break;
- case PACKET_UPDATE_SIGN: HANDLE_CLIENT_READ(HandleClientUpdateSign); break;
- case PACKET_USE_ENTITY: HANDLE_CLIENT_READ(HandleClientUseEntity); break;
- case PACKET_WINDOW_CLICK: HANDLE_CLIENT_READ(HandleClientWindowClick); break;
- case PACKET_WINDOW_CLOSE: HANDLE_CLIENT_READ(HandleClientWindowClose); break;
- default:
+ // Not a complete packet yet
+ break;
+ }
+ UInt32 PacketType, PacketReadSoFar;
+ PacketReadSoFar = m_ClientBuffer.GetReadableSpace();
+ VERIFY(m_ClientBuffer.ReadVarInt(PacketType));
+ PacketReadSoFar -= m_ClientBuffer.GetReadableSpace();
+ Log("Decoding client's packets, there are now %d bytes in the queue; next packet is 0x%0x, %u bytes long", m_ClientBuffer.GetReadableSpace(), PacketType, PacketLen);
+ switch (m_ClientProtocolState)
+ {
+ case -1:
{
- if (m_ClientState == csEncryptedUnderstood)
+ // No initial handshake received yet
+ switch (PacketType)
{
- Log("****************** Unknown packet 0x%02x from the client while encrypted; continuing to relay blind only", PacketType);
- AString Data;
- m_ClientBuffer.ResetRead();
- m_ClientBuffer.ReadAll(Data);
- DataLog(Data.data(), Data.size(), "Current data in the client packet queue: %d bytes", Data.size());
- m_ClientState = csEncryptedUnknown;
- m_ClientBuffer.ResetRead();
- if (m_ServerState == csUnencrypted)
- {
- SERVERSEND(m_ClientBuffer);
- }
- else
- {
- SERVERENCRYPTSEND(m_ClientBuffer);
- }
- return true;
+ case 0x00: HANDLE_CLIENT_READ(HandleClientHandshake()); break;
+ default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break;
}
- else
+ break;
+ } // case -1
+
+ case 1:
+ {
+ // Status query
+ switch (PacketType)
{
- Log("Unknown packet 0x%02x from the client while unencrypted; aborting connection", PacketType);
- return false;
+ case 0x00: HANDLE_CLIENT_READ(HandleClientStatusRequest()); break;
+ case 0x01: HANDLE_CLIENT_READ(HandleClientStatusPing()); break;
+ default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break;
}
+ break;
}
- } // switch (PacketType)
+
+ case 2:
+ {
+ // Login
+ switch (PacketType)
+ {
+ case 0x00: HANDLE_CLIENT_READ(HandleClientLoginStart()); break;
+ case 0x01: HANDLE_CLIENT_READ(HandleClientLoginEncryptionKeyResponse()); break;
+ default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break;
+ }
+ break;
+ }
+
+ case 3:
+ {
+ // Game:
+ switch (PacketType)
+ {
+ case 0x00: HANDLE_CLIENT_READ(HandleClientKeepAlive()); break;
+ case 0x01: HANDLE_CLIENT_READ(HandleClientChatMessage()); break;
+ case 0x02: HANDLE_CLIENT_READ(HandleClientUseEntity()); break;
+ case 0x03: HANDLE_CLIENT_READ(HandleClientPlayerOnGround()); break;
+ case 0x04: HANDLE_CLIENT_READ(HandleClientPlayerPosition()); break;
+ case 0x05: HANDLE_CLIENT_READ(HandleClientPlayerLook()); break;
+ case 0x06: HANDLE_CLIENT_READ(HandleClientPlayerPositionLook()); break;
+ case 0x07: HANDLE_CLIENT_READ(HandleClientBlockDig()); break;
+ case 0x08: HANDLE_CLIENT_READ(HandleClientBlockPlace()); break;
+ case 0x09: HANDLE_CLIENT_READ(HandleClientSlotSelect()); break;
+ case 0x0a: HANDLE_CLIENT_READ(HandleClientAnimation()); break;
+ case 0x0b: HANDLE_CLIENT_READ(HandleClientEntityAction()); break;
+ case 0x0d: HANDLE_CLIENT_READ(HandleClientWindowClose()); break;
+ case 0x0e: HANDLE_CLIENT_READ(HandleClientWindowClick()); break;
+ case 0x10: HANDLE_CLIENT_READ(HandleClientCreativeInventoryAction()); break;
+ case 0x12: HANDLE_CLIENT_READ(HandleClientUpdateSign()); break;
+ case 0x13: HANDLE_CLIENT_READ(HandleClientPlayerAbilities()); break;
+ case 0x14: HANDLE_CLIENT_READ(HandleClientTabCompletion()); break;
+ case 0x15: HANDLE_CLIENT_READ(HandleClientLocaleAndView()); break;
+ case 0x16: HANDLE_CLIENT_READ(HandleClientClientStatuses()); break;
+ case 0x17: HANDLE_CLIENT_READ(HandleClientPluginMessage()); break;
+ default: HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break;
+ }
+ break;
+ } // case 3 - Game
+
+ default:
+ {
+ Log("Receiving server packets while in an unknown protocol state (%d)!", m_ClientProtocolState);
+ HANDLE_CLIENT_READ(HandleClientUnknownPacket(PacketType, PacketLen, PacketReadSoFar));
+ break;
+ }
+ } // switch (m_ProtocolState)
m_ClientBuffer.CommitRead();
- } // while (CanReadBytes(1))
+ } // while (true)
return true;
}
@@ -673,94 +709,128 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
// Client hasn't finished encryption handshake yet, don't send them any data yet
}
- while (m_ServerBuffer.CanReadBytes(1))
+ while (true)
{
- unsigned char PacketType;
- m_ServerBuffer.ReadByte(PacketType);
- Log("Decoding server's packets, there are now %d bytes in the queue; next packet is 0x%02x", m_ServerBuffer.GetReadableSpace(), PacketType);
+ UInt32 PacketLen;
+ if (
+ !m_ServerBuffer.ReadVarInt(PacketLen) ||
+ !m_ServerBuffer.CanReadBytes(PacketLen)
+ )
+ {
+ // Not a complete packet yet
+ break;
+ }
+ UInt32 PacketType, PacketReadSoFar;
+ PacketReadSoFar = m_ServerBuffer.GetReadableSpace();
+ VERIFY(m_ServerBuffer.ReadVarInt(PacketType));
+ PacketReadSoFar -= m_ServerBuffer.GetReadableSpace();
+ Log("Decoding server's packets, there are now %d bytes in the queue; next packet is 0x%0x, %u bytes long", m_ServerBuffer.GetReadableSpace(), PacketType, PacketLen);
LogFlush();
- switch (PacketType)
+ switch (m_ServerProtocolState)
{
- case PACKET_ATTACH_ENTITY: HANDLE_SERVER_READ(HandleServerAttachEntity); break;
- case PACKET_BLOCK_ACTION: HANDLE_SERVER_READ(HandleServerBlockAction); break;
- case PACKET_BLOCK_CHANGE: HANDLE_SERVER_READ(HandleServerBlockChange); break;
- case PACKET_CHANGE_GAME_STATE: HANDLE_SERVER_READ(HandleServerChangeGameState); break;
- case PACKET_CHAT_MESSAGE: HANDLE_SERVER_READ(HandleServerChatMessage); break;
- case PACKET_COLLECT_PICKUP: HANDLE_SERVER_READ(HandleServerCollectPickup); break;
- case PACKET_COMPASS: HANDLE_SERVER_READ(HandleServerCompass); break;
- case PACKET_DESTROY_ENTITIES: HANDLE_SERVER_READ(HandleServerDestroyEntities); break;
- case PACKET_ENCRYPTION_KEY_REQUEST: HANDLE_SERVER_READ(HandleServerEncryptionKeyRequest); break;
- case PACKET_ENCRYPTION_KEY_RESPONSE: HANDLE_SERVER_READ(HandleServerEncryptionKeyResponse); break;
- case PACKET_ENTITY: HANDLE_SERVER_READ(HandleServerEntity); break;
- case PACKET_ENTITY_EQUIPMENT: HANDLE_SERVER_READ(HandleServerEntityEquipment); break;
- case PACKET_ENTITY_HEAD_LOOK: HANDLE_SERVER_READ(HandleServerEntityHeadLook); break;
- case PACKET_ENTITY_LOOK: HANDLE_SERVER_READ(HandleServerEntityLook); break;
- case PACKET_ENTITY_METADATA: HANDLE_SERVER_READ(HandleServerEntityMetadata); break;
- case PACKET_ENTITY_PROPERTIES: HANDLE_SERVER_READ(HandleServerEntityProperties); break;
- case PACKET_ENTITY_RELATIVE_MOVE: HANDLE_SERVER_READ(HandleServerEntityRelativeMove); break;
- case PACKET_ENTITY_RELATIVE_MOVE_LOOK: HANDLE_SERVER_READ(HandleServerEntityRelativeMoveLook); break;
- case PACKET_ENTITY_STATUS: HANDLE_SERVER_READ(HandleServerEntityStatus); break;
- case PACKET_ENTITY_TELEPORT: HANDLE_SERVER_READ(HandleServerEntityTeleport); break;
- case PACKET_ENTITY_VELOCITY: HANDLE_SERVER_READ(HandleServerEntityVelocity); break;
- case PACKET_EXPLOSION: HANDLE_SERVER_READ(HandleServerExplosion); break;
- case PACKET_INCREMENT_STATISTIC: HANDLE_SERVER_READ(HandleServerIncrementStatistic); break;
- case PACKET_KEEPALIVE: HANDLE_SERVER_READ(HandleServerKeepAlive); break;
- case PACKET_KICK: HANDLE_SERVER_READ(HandleServerKick); break;
- case PACKET_LOGIN: HANDLE_SERVER_READ(HandleServerLogin); break;
- case PACKET_MAP_CHUNK: HANDLE_SERVER_READ(HandleServerMapChunk); break;
- case PACKET_MAP_CHUNK_BULK: HANDLE_SERVER_READ(HandleServerMapChunkBulk); break;
- case PACKET_MULTI_BLOCK_CHANGE: HANDLE_SERVER_READ(HandleServerMultiBlockChange); break;
- case PACKET_NAMED_SOUND_EFFECT: HANDLE_SERVER_READ(HandleServerNamedSoundEffect); break;
- case PACKET_PLAYER_ABILITIES: HANDLE_SERVER_READ(HandleServerPlayerAbilities); break;
- case PACKET_PLAYER_ANIMATION: HANDLE_SERVER_READ(HandleServerPlayerAnimation); break;
- case PACKET_PLAYER_LIST_ITEM: HANDLE_SERVER_READ(HandleServerPlayerListItem); break;
- case PACKET_PLAYER_POSITION_LOOK: HANDLE_SERVER_READ(HandleServerPlayerPositionLook); break;
- case PACKET_PLUGIN_MESSAGE: HANDLE_SERVER_READ(HandleServerPluginMessage); break;
- case PACKET_SET_EXPERIENCE: HANDLE_SERVER_READ(HandleServerSetExperience); break;
- case PACKET_SET_SLOT: HANDLE_SERVER_READ(HandleServerSetSlot); break;
- case PACKET_SLOT_SELECT: HANDLE_SERVER_READ(HandleServerSlotSelect); break;
- case PACKET_SOUND_EFFECT: HANDLE_SERVER_READ(HandleServerSoundEffect); break;
- case PACKET_SPAWN_MOB: HANDLE_SERVER_READ(HandleServerSpawnMob); break;
- case PACKET_SPAWN_NAMED_ENTITY: HANDLE_SERVER_READ(HandleServerSpawnNamedEntity); break;
- case PACKET_SPAWN_OBJECT_VEHICLE: HANDLE_SERVER_READ(HandleServerSpawnObjectVehicle); break;
- case PACKET_SPAWN_PAINTING: HANDLE_SERVER_READ(HandleServerSpawnPainting); break;
- case PACKET_SPAWN_PICKUP: HANDLE_SERVER_READ(HandleServerSpawnPickup); break;
- case PACKET_TAB_COMPLETION: HANDLE_SERVER_READ(HandleServerTabCompletion); break;
- case PACKET_TIME_UPDATE: HANDLE_SERVER_READ(HandleServerTimeUpdate); break;
- case PACKET_UPDATE_HEALTH: HANDLE_SERVER_READ(HandleServerUpdateHealth); break;
- case PACKET_UPDATE_SIGN: HANDLE_SERVER_READ(HandleServerUpdateSign); break;
- case PACKET_UPDATE_TILE_ENTITY: HANDLE_SERVER_READ(HandleServerUpdateTileEntity); break;
- case PACKET_WINDOW_CLOSE: HANDLE_SERVER_READ(HandleServerWindowClose); break;
- case PACKET_WINDOW_CONTENTS: HANDLE_SERVER_READ(HandleServerWindowContents); break;
- case PACKET_WINDOW_OPEN: HANDLE_SERVER_READ(HandleServerWindowOpen); break;
- default:
+ case -1:
+ {
+ Log("Receiving data from the server without an initial handshake message!");
+ HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar));
+ break;
+ }
+
+ case 1:
{
- if (m_ServerState == csEncryptedUnderstood)
+ // Status query:
+ switch (PacketType)
{
- Log("********************** Unknown packet 0x%02x from the server while encrypted; continuing to relay blind only", PacketType);
- AString Data;
- m_ServerBuffer.ResetRead();
- m_ServerBuffer.ReadAll(Data);
- DataLog(Data.data(), Data.size(), "Current data in the server packet queue: %d bytes", Data.size());
- m_ServerState = csEncryptedUnknown;
- m_ServerBuffer.ResetRead();
- if (m_ClientState == csUnencrypted)
- {
- CLIENTSEND(m_ServerBuffer);
- }
- else
- {
- CLIENTENCRYPTSEND(m_ServerBuffer);
- }
- return true;
+ case 0x00: HANDLE_SERVER_READ(HandleServerStatusResponse()); break;
+ case 0x01: HANDLE_SERVER_READ(HandleServerStatusPing()); break;
+ default: HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break;
}
- else
+ break;
+ }
+
+ case 2:
+ {
+ // Login:
+ switch (PacketType)
{
- Log("Unknown packet 0x%02x from the server while unencrypted; aborting connection", PacketType);
- return false;
+ case 0x00: HANDLE_SERVER_READ(HandleServerLoginDisconnect()); break;
+ case 0x01: HANDLE_SERVER_READ(HandleServerLoginEncryptionKeyRequest()); break;
+ case 0x02: HANDLE_SERVER_READ(HandleServerLoginSuccess()); break;
+ default: HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break;
}
+ break;
+ }
+
+ case 3:
+ {
+ // Game:
+ switch (PacketType)
+ {
+ case 0x00: HANDLE_SERVER_READ(HandleServerKeepAlive()); break;
+ case 0x01: HANDLE_SERVER_READ(HandleServerJoinGame()); break;
+ case 0x02: HANDLE_SERVER_READ(HandleServerChatMessage()); break;
+ case 0x03: HANDLE_SERVER_READ(HandleServerTimeUpdate()); break;
+ case 0x04: HANDLE_SERVER_READ(HandleServerEntityEquipment()); break;
+ case 0x05: HANDLE_SERVER_READ(HandleServerCompass()); break;
+ case 0x06: HANDLE_SERVER_READ(HandleServerUpdateHealth()); break;
+ case 0x07: HANDLE_SERVER_READ(HandleServerRespawn()); break;
+ case 0x08: HANDLE_SERVER_READ(HandleServerPlayerPositionLook()); break;
+ case 0x09: HANDLE_SERVER_READ(HandleServerSlotSelect()); break;
+ case 0x0a: HANDLE_SERVER_READ(HandleServerUseBed()); break;
+ case 0x0b: HANDLE_SERVER_READ(HandleServerPlayerAnimation()); break;
+ case 0x0c: HANDLE_SERVER_READ(HandleServerSpawnNamedEntity()); break;
+ case 0x0d: HANDLE_SERVER_READ(HandleServerCollectPickup()); break;
+ case 0x0e: HANDLE_SERVER_READ(HandleServerSpawnObjectVehicle()); break;
+ case 0x0f: HANDLE_SERVER_READ(HandleServerSpawnMob()); break;
+ case 0x10: HANDLE_SERVER_READ(HandleServerSpawnPainting()); break;
+ case 0x11: HANDLE_SERVER_READ(HandleServerSpawnExperienceOrbs()); break;
+ case 0x12: HANDLE_SERVER_READ(HandleServerEntityVelocity()); break;
+ case 0x13: HANDLE_SERVER_READ(HandleServerDestroyEntities()); break;
+ case 0x14: HANDLE_SERVER_READ(HandleServerEntity()); break;
+ case 0x15: HANDLE_SERVER_READ(HandleServerEntityRelativeMove()); break;
+ case 0x16: HANDLE_SERVER_READ(HandleServerEntityLook()); break;
+ case 0x17: HANDLE_SERVER_READ(HandleServerEntityRelativeMoveLook()); break;
+ case 0x18: HANDLE_SERVER_READ(HandleServerEntityTeleport()); break;
+ case 0x19: HANDLE_SERVER_READ(HandleServerEntityHeadLook()); break;
+ case 0x1a: HANDLE_SERVER_READ(HandleServerEntityStatus()); break;
+ case 0x1b: HANDLE_SERVER_READ(HandleServerAttachEntity()); break;
+ case 0x1c: HANDLE_SERVER_READ(HandleServerEntityMetadata()); break;
+ case 0x1f: HANDLE_SERVER_READ(HandleServerSetExperience()); break;
+ case 0x20: HANDLE_SERVER_READ(HandleServerEntityProperties()); break;
+ case 0x21: HANDLE_SERVER_READ(HandleServerMapChunk()); break;
+ case 0x22: HANDLE_SERVER_READ(HandleServerMultiBlockChange()); break;
+ case 0x23: HANDLE_SERVER_READ(HandleServerBlockChange()); break;
+ case 0x24: HANDLE_SERVER_READ(HandleServerBlockAction()); break;
+ case 0x26: HANDLE_SERVER_READ(HandleServerMapChunkBulk()); break;
+ case 0x27: HANDLE_SERVER_READ(HandleServerExplosion()); break;
+ case 0x28: HANDLE_SERVER_READ(HandleServerSoundEffect()); break;
+ case 0x29: HANDLE_SERVER_READ(HandleServerNamedSoundEffect()); break;
+ case 0x2b: HANDLE_SERVER_READ(HandleServerChangeGameState()); break;
+ case 0x2d: HANDLE_SERVER_READ(HandleServerWindowOpen()); break;
+ case 0x2e: HANDLE_SERVER_READ(HandleServerWindowClose()); break;
+ case 0x2f: HANDLE_SERVER_READ(HandleServerSetSlot()); break;
+ case 0x30: HANDLE_SERVER_READ(HandleServerWindowContents()); break;
+ case 0x33: HANDLE_SERVER_READ(HandleServerUpdateSign()); break;
+ case 0x35: HANDLE_SERVER_READ(HandleServerUpdateTileEntity()); break;
+ case 0x37: HANDLE_SERVER_READ(HandleServerStatistics()); break;
+ case 0x38: HANDLE_SERVER_READ(HandleServerPlayerListItem()); break;
+ case 0x39: HANDLE_SERVER_READ(HandleServerPlayerAbilities()); break;
+ case 0x3a: HANDLE_SERVER_READ(HandleServerTabCompletion()); break;
+ case 0x3f: HANDLE_SERVER_READ(HandleServerPluginMessage()); break;
+ case 0x40: HANDLE_SERVER_READ(HandleServerKick()); break;
+ default: HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar)); break;
+ } // switch (PacketType)
+ break;
+ } // case 3 - Game
+
+ // TODO: Move this elsewhere
+ default:
+ {
+ Log("Received a packet from the server while in an unknown state: %d", m_ServerProtocolState);
+ HANDLE_SERVER_READ(HandleServerUnknownPacket(PacketType, PacketLen, PacketReadSoFar));
+ break;
}
- } // switch (PacketType)
+ } // switch (m_ProtocolState)
+
m_ServerBuffer.CommitRead();
} // while (CanReadBytes(1))
return true;
@@ -770,6 +840,76 @@ bool cConnection::DecodeServersPackets(const char * a_Data, int a_Size)
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// packet handling, client-side, initial handshake:
+
+bool cConnection::HandleClientHandshake(void)
+{
+ // Read the packet from the client:
+ HANDLE_CLIENT_PACKET_READ(ReadVarInt, UInt32, ProtocolVersion);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, ServerHost);
+ HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, ServerPort);
+ HANDLE_CLIENT_PACKET_READ(ReadVarInt, UInt32, NextState);
+ m_ClientBuffer.CommitRead();
+
+ Log("Received an initial handshake packet from the client:");
+ Log(" ProtocolVersion = %u", ProtocolVersion);
+ Log(" ServerHost = \"%s\"", ServerHost.c_str());
+ Log(" ServerPort = %d", ServerPort);
+ Log(" NextState = %u", NextState);
+
+ // Send the same packet to the server, but with our port:
+ cByteBuffer Packet(512);
+ Packet.WriteVarInt(0); // Packet type - initial handshake
+ Packet.WriteVarInt(ProtocolVersion);
+ Packet.WriteVarUTF8String(ServerHost);
+ Packet.WriteBEShort(m_Server.GetConnectPort());
+ Packet.WriteVarInt(NextState);
+ AString Pkt;
+ Packet.ReadAll(Pkt);
+ cByteBuffer ToServer(512);
+ ToServer.WriteVarUTF8String(Pkt);
+ SERVERSEND(ToServer);
+
+ m_ClientProtocolState = (int)NextState;
+ m_ServerProtocolState = (int)NextState;
+
+ return true;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// packet handling, client-side, login:
+
+bool cConnection::HandleClientLoginEncryptionKeyResponse(void)
+{
+ Log("Client: Unexpected packet: encryption key response");
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleClientLoginStart(void)
+{
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, UserName);
+ Log("Received a login start packet from the client:");
+ Log(" Username = \"%s\"", UserName.c_str());
+ COPY_TO_SERVER();
+ return true;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// packet handling, client-side, game:
+
bool cConnection::HandleClientAnimation(void)
{
HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, EntityID);
@@ -833,7 +973,7 @@ bool cConnection::HandleClientBlockPlace(void)
bool cConnection::HandleClientChatMessage(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Message);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Message);
Log("Received a PACKET_CHAT_MESSAGE from the client:");
Log(" Message = \"%s\"", Message.c_str());
COPY_TO_SERVER();
@@ -879,7 +1019,7 @@ bool cConnection::HandleClientCreativeInventoryAction(void)
bool cConnection::HandleClientDisconnect(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Reason);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Reason);
Log("Received a PACKET_DISCONNECT from the client:");
Log(" Reason = \"%s\"", Reason.c_str());
COPY_TO_SERVER();
@@ -890,42 +1030,15 @@ bool cConnection::HandleClientDisconnect(void)
-bool cConnection::HandleClientEncryptionKeyResponse(void)
-{
- HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, EncKeyLength);
- AString EncKey;
- if (!m_ClientBuffer.ReadString(EncKey, EncKeyLength))
- {
- return true;
- }
- HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, EncNonceLength);
- AString EncNonce;
- if (!m_ClientBuffer.ReadString(EncNonce, EncNonceLength))
- {
- return true;
- }
- if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN))
- {
- Log("Client: Too long encryption params");
- return true;
- }
- StartClientEncryption(EncKey, EncNonce);
- return true;
-}
-
-
-
-
-
bool cConnection::HandleClientEntityAction(void)
{
HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, PlayerID);
HANDLE_CLIENT_PACKET_READ(ReadByte, Byte, ActionType);
- HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, UnknownHorseVal);
+ HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, HorseJumpBoost);
Log("Received a PACKET_ENTITY_ACTION from the client:");
Log(" PlayerID = %d", PlayerID);
Log(" ActionType = %d", ActionType);
- Log(" UnknownHorseVal = %d (0x%08x)", UnknownHorseVal, UnknownHorseVal);
+ Log(" HorseJumpBoost = %d (0x%08x)", HorseJumpBoost, HorseJumpBoost);
COPY_TO_SERVER();
return true;
}
@@ -934,37 +1047,6 @@ bool cConnection::HandleClientEntityAction(void)
-bool cConnection::HandleClientHandshake(void)
-{
- // Read the packet from the client:
- HANDLE_CLIENT_PACKET_READ(ReadByte, Byte, ProtocolVersion);
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Username);
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, ServerHost);
- HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, ServerPort);
- m_ClientBuffer.CommitRead();
-
- Log("Received a PACKET_HANDSHAKE from the client:");
- Log(" ProtocolVersion = %d", ProtocolVersion);
- Log(" Username = \"%s\"", Username.c_str());
- Log(" ServerHost = \"%s\"", ServerHost.c_str());
- Log(" ServerPort = %d", ServerPort);
-
- // Send the same packet to the server, but with our port:
- cByteBuffer ToServer(512);
- ToServer.WriteByte (PACKET_HANDSHAKE);
- ToServer.WriteByte (ProtocolVersion);
- ToServer.WriteBEUTF16String16(Username);
- ToServer.WriteBEUTF16String16(ServerHost);
- ToServer.WriteBEInt (m_Server.GetConnectPort());
- SERVERSEND(ToServer);
-
- return true;
-}
-
-
-
-
-
bool cConnection::HandleClientKeepAlive(void)
{
HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, ID);
@@ -979,11 +1061,12 @@ bool cConnection::HandleClientKeepAlive(void)
bool cConnection::HandleClientLocaleAndView(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Locale);
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, ViewDistance);
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, ChatFlags);
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, Difficulty);
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, ShowCape);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Locale);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, ViewDistance);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, ChatFlags);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, Unused);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, Difficulty);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, ShowCape);
Log("Received a PACKET_LOCALE_AND_VIEW from the client");
COPY_TO_SERVER();
return true;
@@ -1008,7 +1091,7 @@ bool cConnection::HandleClientPing(void)
bool cConnection::HandleClientPlayerAbilities(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, Flags);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, Flags);
HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, FlyingSpeed);
HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, WalkingSpeed);
Log("Receives a PACKET_PLAYER_ABILITIES from the client:");
@@ -1039,7 +1122,7 @@ bool cConnection::HandleClientPlayerLook(void)
bool cConnection::HandleClientPlayerOnGround(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, OnGround);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, OnGround);
Log("Received a PACKET_PLAYER_ON_GROUND from the client");
COPY_TO_SERVER();
return true;
@@ -1052,8 +1135,8 @@ bool cConnection::HandleClientPlayerOnGround(void)
bool cConnection::HandleClientPlayerPosition(void)
{
HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosX);
- HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance);
HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosY);
+ HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance);
HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosZ);
HANDLE_CLIENT_PACKET_READ(ReadChar, char, IsOnGround);
Log("Received a PACKET_PLAYER_POSITION from the client");
@@ -1071,8 +1154,8 @@ bool cConnection::HandleClientPlayerPosition(void)
bool cConnection::HandleClientPlayerPositionLook(void)
{
HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosX);
- HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance);
HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosY);
+ HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, Stance);
HANDLE_CLIENT_PACKET_READ(ReadBEDouble, double, PosZ);
HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, Yaw);
HANDLE_CLIENT_PACKET_READ(ReadBEFloat, float, Pitch);
@@ -1080,7 +1163,7 @@ bool cConnection::HandleClientPlayerPositionLook(void)
Log("Received a PACKET_PLAYER_POSITION_LOOK from the client");
Log(" Pos = {%.03f, %.03f, %.03f}", PosX, PosY, PosZ);
Log(" Stance = %.03f", Stance);
- Log(" Y, P = %.03f, %.03f", Yaw, Pitch);
+ Log(" Yaw, Pitch = <%.03f, %.03f>", Yaw, Pitch);
Log(" IsOnGround = %s", IsOnGround ? "true" : "false");
COPY_TO_SERVER();
@@ -1093,7 +1176,7 @@ bool cConnection::HandleClientPlayerPositionLook(void)
bool cConnection::HandleClientPluginMessage(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, ChannelName);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, ChannelName);
HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, Length);
AString Data;
if (!m_ClientBuffer.ReadString(Data, Length))
@@ -1124,9 +1207,33 @@ bool cConnection::HandleClientSlotSelect(void)
+bool cConnection::HandleClientStatusPing(void)
+{
+ HANDLE_CLIENT_PACKET_READ(ReadBEInt64, Int64, Time);
+ Log("Received the status ping packet from the client:");
+ Log(" Time = %lld", Time);
+ COPY_TO_SERVER();
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleClientStatusRequest(void)
+{
+ Log("Received the status request packet from the client");
+ COPY_TO_SERVER();
+ return true;
+}
+
+
+
+
+
bool cConnection::HandleClientTabCompletion(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Query);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Query);
Log("Received a PACKET_TAB_COMPLETION query from the client");
Log(" Query = \"%s\"", Query.c_str());
COPY_TO_SERVER();
@@ -1139,13 +1246,13 @@ bool cConnection::HandleClientTabCompletion(void)
bool cConnection::HandleClientUpdateSign(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockX);
- HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, BlockY);
- HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockZ);
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line1);
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line2);
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line3);
- HANDLE_CLIENT_PACKET_READ(ReadBEUTF16String16, AString, Line4);
+ HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockX);
+ HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, BlockY);
+ HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, BlockZ);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line1);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line2);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line3);
+ HANDLE_CLIENT_PACKET_READ(ReadVarUTF8String, AString, Line4);
Log("Received a PACKET_UPDATE_SIGN from the client:");
Log(" Block = {%d, %d, %d}", BlockX, BlockY, BlockZ);
Log(" Lines = \"%s\", \"%s\", \"%s\", \"%s\"", Line1.c_str(), Line2.c_str(), Line3.c_str(), Line4.c_str());
@@ -1159,11 +1266,9 @@ bool cConnection::HandleClientUpdateSign(void)
bool cConnection::HandleClientUseEntity(void)
{
- HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, PlayerID);
HANDLE_CLIENT_PACKET_READ(ReadBEInt, int, EntityID);
HANDLE_CLIENT_PACKET_READ(ReadChar, char, MouseButton);
Log("Received a PACKET_USE_ENTITY from the client:");
- Log(" PlayerID = %d", PlayerID);
Log(" EntityID = %d", EntityID);
Log(" MouseButton = %d", MouseButton);
COPY_TO_SERVER();
@@ -1178,9 +1283,9 @@ bool cConnection::HandleClientWindowClick(void)
{
HANDLE_CLIENT_PACKET_READ(ReadChar, char, WindowID);
HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, SlotNum);
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, IsRightClick);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, Button);
HANDLE_CLIENT_PACKET_READ(ReadBEShort, short, TransactionID);
- HANDLE_CLIENT_PACKET_READ(ReadChar, char, IsShiftClick);
+ HANDLE_CLIENT_PACKET_READ(ReadChar, char, Mode);
AString Item;
if (!ParseSlot(m_ClientBuffer, Item))
{
@@ -1189,7 +1294,7 @@ bool cConnection::HandleClientWindowClick(void)
Log("Received a PACKET_WINDOW_CLICK from the client");
Log(" WindowID = %d", WindowID);
Log(" SlotNum = %d", SlotNum);
- Log(" IsRclk = %d, IsShift = %d", IsRightClick, IsShiftClick);
+ Log(" Button = %d, Mode = %d", Button, Mode);
Log(" TransactionID = 0x%x", TransactionID);
Log(" ClickedItem = %s", Item.c_str());
COPY_TO_SERVER();
@@ -1213,6 +1318,100 @@ bool cConnection::HandleClientWindowClose(void)
+bool cConnection::HandleClientUnknownPacket(UInt32 a_PacketType, UInt32 a_PacketLen, UInt32 a_PacketReadSoFar)
+{
+ AString Data;
+ if (!m_ClientBuffer.ReadString(Data, a_PacketLen - a_PacketReadSoFar))
+ {
+ return false;
+ }
+ DataLog(Data.data(), Data.size(), "****************** Unknown packet 0x%x from the client; relaying and ignoring", a_PacketType);
+ COPY_TO_SERVER();
+ return true;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// packet handling, server-side, login:
+
+bool cConnection::HandleServerLoginDisconnect(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Reason);
+ Log("Received a login-disconnect packet from the server:");
+ Log(" Reason = \"%s\"", Reason.c_str());
+ COPY_TO_SERVER();
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleServerLoginEncryptionKeyRequest(void)
+{
+ // Read the packet from the server:
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, ServerID);
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, PublicKeyLength);
+ AString PublicKey;
+ if (!m_ServerBuffer.ReadString(PublicKey, PublicKeyLength))
+ {
+ return false;
+ }
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, NonceLength);
+ AString Nonce;
+ if (!m_ServerBuffer.ReadString(Nonce, NonceLength))
+ {
+ return false;
+ }
+ Log("Got PACKET_ENCRYPTION_KEY_REQUEST from the SERVER:");
+ Log(" ServerID = %s", ServerID.c_str());
+
+ // Reply to the server:
+ SendEncryptionKeyResponse(PublicKey, Nonce);
+
+ // Do not send to client - we want the client connection open
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleServerLoginSuccess(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, UUID);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Username);
+ Log("Received a login success packet from the server:");
+ Log(" UUID = \"%s\"", UUID.c_str());
+ Log(" Username = \"%s\"", Username.c_str());
+
+ Log("Server is now in protocol state Game.");
+ m_ServerProtocolState = 3;
+
+ if (m_IsServerEncrypted)
+ {
+ Log("Server communication is now encrypted");
+ m_ServerState = csEncryptedUnderstood;
+ DataLog(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size(), "Sending the queued data to server (%u bytes):", m_ServerEncryptionBuffer.size());
+ SERVERENCRYPTSEND(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size());
+ m_ServerEncryptionBuffer.clear();
+ }
+ COPY_TO_CLIENT();
+ Log("Client is now in protocol state Game.");
+ m_ClientProtocolState = 3;
+ return true;
+}
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// packet handling, server-side, game:
+
bool cConnection::HandleServerAttachEntity(void)
{
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
@@ -1232,16 +1431,16 @@ bool cConnection::HandleServerAttachEntity(void)
bool cConnection::HandleServerBlockAction(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX);
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockY);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte1);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte2);
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockID);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX);
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte1);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Byte2);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, BlockID);
Log("Received a PACKET_BLOCK_ACTION from the server:");
Log(" Pos = {%d, %d, %d}", BlockX, BlockY, BlockZ);
Log(" Bytes = (%d, %d) == (0x%x, 0x%x)", Byte1, Byte2, Byte1, Byte2);
- Log(" BlockID = %d", BlockID);
+ Log(" BlockID = %u", BlockID);
COPY_TO_CLIENT();
return true;
}
@@ -1252,11 +1451,11 @@ bool cConnection::HandleServerBlockAction(void)
bool cConnection::HandleServerBlockChange(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, BlockY);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ);
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockType);
- HANDLE_SERVER_PACKET_READ(ReadChar, char, BlockMeta);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, BlockY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, BlockType);
+ HANDLE_SERVER_PACKET_READ(ReadChar, char, BlockMeta);
Log("Received a PACKET_BLOCK_CHANGE from the server");
COPY_TO_CLIENT();
return true;
@@ -1283,7 +1482,7 @@ bool cConnection::HandleServerChangeGameState(void)
bool cConnection::HandleServerChatMessage(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Message);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Message);
Log("Received a PACKET_CHAT_MESSAGE from the server:");
Log(" Message = \"%s\"", Message.c_str());
COPY_TO_CLIENT();
@@ -1341,48 +1540,6 @@ bool cConnection::HandleServerDestroyEntities(void)
-bool cConnection::HandleServerEncryptionKeyRequest(void)
-{
- // Read the packet from the server:
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, ServerID);
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, PublicKeyLength);
- AString PublicKey;
- if (!m_ServerBuffer.ReadString(PublicKey, PublicKeyLength))
- {
- return false;
- }
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, NonceLength);
- AString Nonce;
- if (!m_ServerBuffer.ReadString(Nonce, NonceLength))
- {
- return false;
- }
- Log("Got PACKET_ENCRYPTION_KEY_REQUEST from the SERVER:");
- Log(" ServerID = %s", ServerID.c_str());
-
- // Reply to the server:
- SendEncryptionKeyResponse(PublicKey, Nonce);
-
- // Send a 0xFD Encryption Key Request http://wiki.vg/Protocol#0xFD to the client, using our own key:
- Log("Sending PACKET_ENCRYPTION_KEY_REQUEST to the CLIENT");
- AString key;
- StringSink sink(key); // GCC won't allow inline instantiation in the following line, damned temporary refs
- m_Server.GetPublicKey().Save(sink);
- cByteBuffer ToClient(512);
- ToClient.WriteByte (PACKET_ENCRYPTION_KEY_REQUEST);
- ToClient.WriteBEUTF16String16(ServerID);
- ToClient.WriteBEShort ((short)key.size());
- ToClient.WriteBuf (key.data(), key.size());
- ToClient.WriteBEShort (4);
- ToClient.WriteBEInt (m_Nonce); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
- CLIENTSEND(ToClient);
- return true;
-}
-
-
-
-
-
bool cConnection::HandleServerEntity(void)
{
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
@@ -1481,20 +1638,18 @@ bool cConnection::HandleServerEntityProperties(void)
for (int i = 0; i < Count; i++)
{
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Key);
- HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, Value);
- Log(" \"%s\" = %f", Key.c_str(), Value);
- } // for i
-
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, ListLength);
- Log(" ListLength = %d", ListLength);
- for (int i = 0; i < ListLength; i++)
- {
- HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDHi);
- HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDLo);
- HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, DblVal);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, ByteVal);
- Log(" [%d] = {0x%08llx%08llx, %f, %i}", i, UUIDHi, UUIDLo, DblVal, ByteVal);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Key);
+ HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, Value);
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, ListLength);
+ Log(" \"%s\" = %f; %d modifiers", Key.c_str(), Value, ListLength);
+ for (short j = 0; j < ListLength; j++)
+ {
+ HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDHi);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, UUIDLo);
+ HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, DblVal);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, ByteVal);
+ Log(" [%d] = {0x%08llx%08llx, %f, %u}", j, UUIDHi, UUIDLo, DblVal, ByteVal);
+ }
} // for i
COPY_TO_CLIENT();
return true;
@@ -1559,7 +1714,7 @@ bool cConnection::HandleServerEntityStatus(void)
bool cConnection::HandleServerEntityTeleport(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsX);
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsY);
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, AbsZ);
@@ -1567,7 +1722,7 @@ bool cConnection::HandleServerEntityTeleport(void)
HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch);
Log("Received a PACKET_ENTITY_TELEPORT from the server:");
Log(" EntityID = %d", EntityID);
- Log(" Pos = (%d, %d, %d) ~ {%.02f, %.02f, %.02f}", AbsX, AbsY, AbsZ, (double)AbsX / 32, (double)AbsY / 32, (double)AbsZ / 32);
+ Log(" Pos = %s", PrintableAbsIntTriplet(AbsX, AbsY, AbsZ).c_str());
Log(" Yaw = %d", Yaw);
Log(" Pitch = %d", Pitch);
COPY_TO_CLIENT();
@@ -1597,11 +1752,11 @@ bool cConnection::HandleServerEntityVelocity(void)
bool cConnection::HandleServerExplosion(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosX);
- HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosY);
- HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosZ);
- HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Force);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, NumRecords);
+ HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PosX);
+ HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PosY);
+ HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, PosZ);
+ HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Force);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, NumRecords);
struct sCoords
{
int x, y, z;
@@ -1654,12 +1809,22 @@ bool cConnection::HandleServerIncrementStatistic(void)
-bool cConnection::HandleServerKeepAlive(void)
+bool cConnection::HandleServerJoinGame(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PingID);
- Log("Received a PACKET_KEEP_ALIVE from the server:");
- Log(" ID = %d", PingID);
- COPY_TO_CLIENT()
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
+ HANDLE_SERVER_PACKET_READ(ReadChar, char, GameMode);
+ HANDLE_SERVER_PACKET_READ(ReadChar, char, Dimension);
+ HANDLE_SERVER_PACKET_READ(ReadChar, char, Difficulty);
+ HANDLE_SERVER_PACKET_READ(ReadChar, char, MaxPlayers);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, LevelType);
+ Log("Received a PACKET_LOGIN from the server:");
+ Log(" EntityID = %d", EntityID);
+ Log(" GameMode = %d", GameMode);
+ Log(" Dimension = %d", Dimension);
+ Log(" Difficulty = %d", Difficulty);
+ Log(" MaxPlayers = %d", MaxPlayers);
+ Log(" LevelType = \"%s\"", LevelType.c_str());
+ COPY_TO_CLIENT();
return true;
}
@@ -1667,19 +1832,12 @@ bool cConnection::HandleServerKeepAlive(void)
-bool cConnection::HandleServerEncryptionKeyResponse(void)
+bool cConnection::HandleServerKeepAlive(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Lengths);
- if (Lengths != 0)
- {
- Log("Lengths are not zero!");
- return true;
- }
- Log("Server communication is now encrypted");
- m_ServerState = csEncryptedUnderstood;
- DataLog(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size(), "Sending the queued data to server (%u bytes):", m_ServerEncryptionBuffer.size());
- SERVERENCRYPTSEND(m_ServerEncryptionBuffer.data(), m_ServerEncryptionBuffer.size());
- m_ServerEncryptionBuffer.clear();
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PingID);
+ Log("Received a PACKET_KEEP_ALIVE from the server:");
+ Log(" ID = %d", PingID);
+ COPY_TO_CLIENT()
return true;
}
@@ -1689,7 +1847,7 @@ bool cConnection::HandleServerEncryptionKeyResponse(void)
bool cConnection::HandleServerKick(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Reason);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Reason);
Log("Received PACKET_KICK from the SERVER:");
if (m_HasClientPinged)
{
@@ -1759,31 +1917,6 @@ bool cConnection::HandleServerKick(void)
-bool cConnection::HandleServerLogin(void)
-{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, LevelType);
- HANDLE_SERVER_PACKET_READ(ReadChar, char, GameMode);
- HANDLE_SERVER_PACKET_READ(ReadChar, char, Dimension);
- HANDLE_SERVER_PACKET_READ(ReadChar, char, Difficulty);
- HANDLE_SERVER_PACKET_READ(ReadChar, char, Unused);
- HANDLE_SERVER_PACKET_READ(ReadChar, char, MaxPlayers);
- Log("Received a PACKET_LOGIN from the server:");
- Log(" EntityID = %d", EntityID);
- Log(" LevelType = \"%s\"", LevelType.c_str());
- Log(" GameMode = %d", GameMode);
- Log(" Dimension = %d", Dimension);
- Log(" Difficulty = %d", Difficulty);
- Log(" Unused = %d", Unused);
- Log(" MaxPlayers = %d", MaxPlayers);
- COPY_TO_CLIENT();
- return true;
-}
-
-
-
-
-
bool cConnection::HandleServerMapChunk(void)
{
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, ChunkX);
@@ -1894,15 +2027,15 @@ bool cConnection::HandleServerMultiBlockChange(void)
bool cConnection::HandleServerNamedSoundEffect(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, SoundName);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
- HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Volume);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, SoundName);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
+ HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Volume);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch);
Log("Received a PACKET_NAMED_SOUND_EFFECT from the server:");
Log(" SoundName = \"%s\"", SoundName.c_str());
- Log(" Pos = (%d, %d, %d) ~ {%d, %d, %d}", PosX, PosY, PosZ, PosX / 8, PosY / 8, PosZ / 8);
+ Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ, 8).c_str());
Log(" Volume = %f", Volume);
Log(" Pitch = %d", Pitch);
COPY_TO_CLIENT();
@@ -1932,10 +2065,10 @@ bool cConnection::HandleServerPlayerAbilities(void)
bool cConnection::HandleServerPlayerAnimation(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PlayerID);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, AnimationID);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, PlayerID);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, AnimationID);
Log("Received a PACKET_PLAYER_ANIMATION from the server:");
- Log(" PlayerID: %d (0x%x)", PlayerID, PlayerID);
+ Log(" PlayerID: %u (0x%x)", PlayerID, PlayerID);
Log(" Animation: %d", AnimationID);
COPY_TO_CLIENT();
return true;
@@ -1947,7 +2080,7 @@ bool cConnection::HandleServerPlayerAnimation(void)
bool cConnection::HandleServerPlayerListItem(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, PlayerName);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, PlayerName);
HANDLE_SERVER_PACKET_READ(ReadChar, char, IsOnline);
HANDLE_SERVER_PACKET_READ(ReadBEShort, short, Ping);
Log("Received a PACKET_PLAYERLIST_ITEM from the server:");
@@ -1964,7 +2097,6 @@ bool cConnection::HandleServerPlayerListItem(void)
bool cConnection::HandleServerPlayerPositionLook(void)
{
HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosX);
- HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, Stance);
HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosY);
HANDLE_SERVER_PACKET_READ(ReadBEDouble, double, PosZ);
HANDLE_SERVER_PACKET_READ(ReadBEFloat, float, Yaw);
@@ -1984,7 +2116,7 @@ bool cConnection::HandleServerPlayerPositionLook(void)
bool cConnection::HandleServerPluginMessage(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, ChannelName);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, ChannelName);
HANDLE_SERVER_PACKET_READ(ReadBEShort, short, Length);
AString Data;
if (!m_ServerBuffer.ReadString(Data, Length))
@@ -1994,7 +2126,26 @@ bool cConnection::HandleServerPluginMessage(void)
Log("Received a PACKET_PLUGIN_MESSAGE from the server");
Log(" ChannelName = \"%s\"", ChannelName.c_str());
DataLog(Data.data(), Length, " Data: %d bytes", Length);
- COPY_TO_SERVER();
+ COPY_TO_CLIENT();
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleServerRespawn(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Dimension);
+ HANDLE_SERVER_PACKET_READ(ReadChar, char, Difficulty);
+ HANDLE_SERVER_PACKET_READ(ReadChar, char, GameMode);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, LevelType);
+ Log("Received a respawn packet from the server:");
+ Log(" Dimension = %d", Dimension);
+ Log(" Difficulty = %d", Difficulty);
+ Log(" GameMode = %d", GameMode);
+ Log(" LevelType = \"%s\"", LevelType.c_str());
+ COPY_TO_CLIENT();
return true;
}
@@ -2042,7 +2193,7 @@ bool cConnection::HandleServerSetSlot(void)
bool cConnection::HandleServerSlotSelect(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, SlotNum);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, SlotNum);
Log("Received a PACKET_SLOT_SELECT from the server:");
Log(" SlotNum = %d", SlotNum);
COPY_TO_CLIENT();
@@ -2074,6 +2225,25 @@ bool cConnection::HandleServerSoundEffect(void)
+bool cConnection::HandleServerSpawnExperienceOrbs(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, Count);
+ Log("Received a SPAWN_EXPERIENCE_ORBS packet from the server:");
+ Log(" EntityID = %u (0x%x)", EntityID, EntityID);
+ Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str());
+ Log(" Count = %d", Count);
+ COPY_TO_CLIENT();
+ return true;
+}
+
+
+
+
+
bool cConnection::HandleServerSpawnMob(void)
{
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
@@ -2112,14 +2282,15 @@ bool cConnection::HandleServerSpawnMob(void)
bool cConnection::HandleServerSpawnNamedEntity(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, EntityName);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch);
- HANDLE_SERVER_PACKET_READ(ReadBEShort, short, CurrentItem);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, EntityUUID);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, EntityName);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch);
+ HANDLE_SERVER_PACKET_READ(ReadBEShort, short, CurrentItem);
AString Metadata;
if (!ParseMetadata(m_ServerBuffer, Metadata))
{
@@ -2128,7 +2299,8 @@ bool cConnection::HandleServerSpawnNamedEntity(void)
AString HexDump;
CreateHexDump(HexDump, Metadata.data(), Metadata.size(), 32);
Log("Received a PACKET_SPAWN_NAMED_ENTITY from the server:");
- Log(" EntityID = %d (0x%x)", EntityID, EntityID);
+ Log(" EntityID = %u (0x%x)", EntityID, EntityID);
+ Log(" UUID = %s", EntityUUID.c_str());
Log(" Name = %s", EntityName.c_str());
Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str());
Log(" Rotation = <yaw %d, pitch %d>", Yaw, Pitch);
@@ -2161,14 +2333,14 @@ bool cConnection::HandleServerSpawnObjectVehicle(void)
DataLog(Buffer.data(), Buffer.size(), "Buffer while parsing the PACKET_SPAWN_OBJECT_VEHICLE packet (%d bytes):", Buffer.size());
#endif // _DEBUG
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
- HANDLE_SERVER_PACKET_READ(ReadChar, char, ObjType);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw);
- HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, DataIndicator);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, ObjType);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Pitch);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Yaw);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, DataIndicator);
AString ExtraData;
short VelocityX, VelocityY, VelocityZ;
if (DataIndicator != 0)
@@ -2201,7 +2373,7 @@ bool cConnection::HandleServerSpawnObjectVehicle(void)
*/
}
Log("Received a PACKET_SPAWN_OBJECT_VEHICLE from the server:");
- Log(" EntityID = %d (0x%x)", EntityID, EntityID);
+ Log(" EntityID = %u (0x%x)", EntityID, EntityID);
Log(" ObjType = %d (0x%x)", ObjType, ObjType);
Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str());
Log(" Rotation = <yaw %d, pitch %d>", Yaw, Pitch);
@@ -2221,14 +2393,14 @@ bool cConnection::HandleServerSpawnObjectVehicle(void)
bool cConnection::HandleServerSpawnPainting(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, ImageName);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
- HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Direction);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, EntityID);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, ImageName);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosX);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, PosZ);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, Direction);
Log("Received a PACKET_SPAWN_PAINTING from the server:");
- Log(" EntityID = %d", EntityID);
+ Log(" EntityID = %u", EntityID);
Log(" ImageName = \"%s\"", ImageName.c_str());
Log(" Pos = %s", PrintableAbsIntTriplet(PosX, PosY, PosZ).c_str());
Log(" Direction = %d", Direction);
@@ -2267,9 +2439,65 @@ bool cConnection::HandleServerSpawnPickup(void)
+bool cConnection::HandleServerStatistics(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, NumEntries);
+ for (UInt32 i = 0; i < NumEntries; i++)
+ {
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, StatName);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, StatValue);
+ }
+ COPY_TO_CLIENT();
+ return true;
+}
+
+
+
+
+bool cConnection::HandleServerStatusPing(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadBEInt64, Int64, Time);
+ Log("Received server's ping response:");
+ Log(" Time = %lld", Time);
+ COPY_TO_CLIENT();
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleServerStatusResponse(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Response);
+ Log("Received server's status response:");
+ Log(" Response: %s", Response.c_str());
+
+ // Modify the response to show that it's being proto-proxied:
+ size_t idx = Response.find("\"description\":\"");
+ if (idx != AString::npos)
+ {
+ Response.assign(Response.substr(0, idx + 15) + "ProtoProxy: " + Response.substr(idx + 15));
+ }
+ cByteBuffer Packet(1000);
+ Packet.WriteVarInt(0); // Packet type - status response
+ Packet.WriteVarUTF8String(Response);
+ AString Pkt;
+ Packet.ReadAll(Pkt);
+ cByteBuffer ToClient(1000);
+ ToClient.WriteVarUTF8String(Pkt);
+ CLIENTSEND(ToClient);
+ return true;
+}
+
+
+
+
+
bool cConnection::HandleServerTabCompletion(void)
{
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Results);
+ HANDLE_SERVER_PACKET_READ(ReadVarInt, UInt32, NumResults);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Results);
Log("Received a PACKET_TAB_COMPLETION from the server, results given:");
// Parse the zero-terminated list of results:
@@ -2327,10 +2555,10 @@ bool cConnection::HandleServerUpdateSign(void)
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockX);
HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockY);
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line1);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line2);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line3);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Line4);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line1);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line2);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line3);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Line4);
Log("Received a PACKET_UPDATE_SIGN from the server:");
Log(" Block = {%d, %d, %d}", BlockX, BlockY, BlockZ);
Log(" Lines = \"%s\", \"%s\", \"%s\", \"%s\"", Line1.c_str(), Line2.c_str(), Line3.c_str(), Line4.c_str());
@@ -2357,7 +2585,24 @@ bool cConnection::HandleServerUpdateTileEntity(void)
Log("Received a PACKET_UPDATE_TILE_ENTITY from the server:");
Log(" Block = {%d, %d, %d}", BlockX, BlockY, BlockZ);
Log(" Action = %d", Action);
- DataLog(Data.data(), Data.size(), " Data (%d bytes)", Data.size());
+ DataLog(Data.data(), Data.size(), " Data (%u bytes)", Data.size());
+ COPY_TO_CLIENT();
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleServerUseBed(void)
+{
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, EntityID);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BedX);
+ HANDLE_SERVER_PACKET_READ(ReadByte, Byte, BedY);
+ HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BedZ);
+ Log("Received a use bed packet from the server:");
+ Log(" EntityID = %d", EntityID);
+ Log(" Bed = {%d, %d, %d}", BedX, BedY, BedZ);
COPY_TO_CLIENT();
return true;
}
@@ -2409,14 +2654,14 @@ bool cConnection::HandleServerWindowOpen(void)
{
HANDLE_SERVER_PACKET_READ(ReadChar, char, WindowID);
HANDLE_SERVER_PACKET_READ(ReadChar, char, WindowType);
- HANDLE_SERVER_PACKET_READ(ReadBEUTF16String16, AString, Title);
+ HANDLE_SERVER_PACKET_READ(ReadVarUTF8String, AString, Title);
HANDLE_SERVER_PACKET_READ(ReadByte, Byte, NumSlots);
HANDLE_SERVER_PACKET_READ(ReadByte, Byte, UseProvidedTitle);
- int HorseInt = 0;
+ int HorseEntityID = 0;
if (WindowType == 11) // Horse / Donkey / Mule
{
HANDLE_SERVER_PACKET_READ(ReadBEInt, int, intHorseInt);
- HorseInt = intHorseInt;
+ HorseEntityID = intHorseInt;
}
Log("Received a PACKET_WINDOW_OPEN from the server:");
Log(" WindowID = %d", WindowID);
@@ -2425,8 +2670,24 @@ bool cConnection::HandleServerWindowOpen(void)
Log(" NumSlots = %d", NumSlots);
if (WindowType == 11)
{
- Log(" HorseInt = %d (0x%08x)", HorseInt, HorseInt);
+ Log(" HorseEntityID = %d (0x%08x)", HorseEntityID, HorseEntityID);
+ }
+ COPY_TO_CLIENT();
+ return true;
+}
+
+
+
+
+
+bool cConnection::HandleServerUnknownPacket(UInt32 a_PacketType, UInt32 a_PacketLen, UInt32 a_PacketReadSoFar)
+{
+ AString Data;
+ if (!m_ServerBuffer.ReadString(Data, a_PacketLen - a_PacketReadSoFar))
+ {
+ return false;
}
+ DataLog(Data.data(), Data.size(), "****************** Unknown packet 0x%x from the server; relaying and ignoring", a_PacketType);
COPY_TO_CLIENT();
return true;
}
@@ -2674,68 +2935,14 @@ void cConnection::SendEncryptionKeyResponse(const AString & a_ServerPublicKey, c
// Send the packet to the server:
Log("Sending PACKET_ENCRYPTION_KEY_RESPONSE to the SERVER");
cByteBuffer ToServer(1024);
- ToServer.WriteByte(PACKET_ENCRYPTION_KEY_RESPONSE);
+ ToServer.WriteByte(0x01); // To server: Encryption key response
ToServer.WriteBEShort(EncryptedLength);
ToServer.WriteBuf(EncryptedSecret, EncryptedLength);
ToServer.WriteBEShort(EncryptedLength);
ToServer.WriteBuf(EncryptedNonce, EncryptedLength);
SERVERSEND(ToServer);
- m_ServerState = csWaitingForEncryption;
-}
-
-
-
-
-
-void cConnection::StartClientEncryption(const AString & a_EncKey, const AString & a_EncNonce)
-{
- // Decrypt EncNonce using privkey
- RSAES<PKCS1v15>::Decryptor rsaDecryptor(m_Server.GetPrivateKey());
- time_t CurTime = time(NULL);
- RandomPool rng;
- rng.Put((const byte *)&CurTime, sizeof(CurTime));
- byte DecryptedNonce[MAX_ENC_LEN];
- DecodingResult res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncNonce.data(), a_EncNonce.size(), DecryptedNonce);
- if (!res.isValidCoding || (res.messageLength != 4))
- {
- Log("Client: Bad nonce length");
- return;
- }
- if (ntohl(*((int *)DecryptedNonce)) != m_Nonce)
- {
- Log("Bad nonce value");
- return;
- }
-
- // Decrypt the symmetric encryption key using privkey:
- byte SharedSecret[MAX_ENC_LEN];
- res = rsaDecryptor.Decrypt(rng, (const byte *)a_EncKey.data(), a_EncKey.size(), SharedSecret);
- if (!res.isValidCoding || (res.messageLength != 16))
- {
- Log("Bad key length");
- return;
- }
-
- // Send encryption key response:
- cByteBuffer ToClient(6);
- ToClient.WriteByte((char)0xfc);
- ToClient.WriteBEShort(0);
- ToClient.WriteBEShort(0);
- CLIENTSEND(ToClient);
-
- // Start the encryption:
- m_ClientEncryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1));
- m_ClientDecryptor.SetKey(SharedSecret, 16, MakeParameters(Name::IV(), ConstByteArrayParameter(SharedSecret, 16))(Name::FeedbackSize(), 1));
- Log("Client connection is now encrypted");
- m_ClientState = csEncryptedUnderstood;
-
- // Send the queued data:
- DataLog(m_ClientEncryptionBuffer.data(), m_ClientEncryptionBuffer.size(), "Sending the queued data to client (%u bytes):", m_ClientEncryptionBuffer.size());
- CLIENTENCRYPTSEND(m_ClientEncryptionBuffer.data(), m_ClientEncryptionBuffer.size());
- m_ClientEncryptionBuffer.clear();
-
- // Handle all postponed server data
- DecodeServersPackets(NULL, 0);
+ m_ServerState = csEncryptedUnderstood;
+ m_IsServerEncrypted = true;
}