2017-09-19 10:34:08 +02:00
2013-07-29 12:13:03 +01:00
// Connection.cpp
// Interfaces to the cConnection class representing a single pair of connected sockets
#include "Globals.h"
#include "Connection.h"
#include "Server.h"
#include <iostream>
2017-08-30 15:00:06 +01:00
#include "mbedTLS++/CryptoKey.h"
2015-03-22 15:00:51 +01:00
#include "../../src/Logger.h"
2013-07-29 12:13:03 +01:00
2018-01-03 17:41:16 +00:00
#include "fmt/printf.h"
2013-09-08 11:27:49 +02:00
#ifdef _WIN32
#include <direct.h> // For _mkdir()
#endif
2013-07-29 12:13:03 +01:00
2017-12-23 12:49:08 +00:00
/** When defined, the following macro causes a sleep after each parsed packet (DEBUG-mode only) */
2013-09-19 21:35:33 +02:00
// #define SLEEP_AFTER_PACKET
#if defined(_DEBUG) && defined(SLEEP_AFTER_PACKET)
2013-07-29 12:13:03 +01:00
#define DebugSleep Sleep
#else
#define DebugSleep(X)
#endif // else _DEBUG
#define HANDLE_CLIENT_PACKET_READ(Proc, Type, Var) \
Type Var; \
{ \
if (!m_ClientBuffer.Proc(Var)) \
{ \
return false; \
} \
}
#define HANDLE_SERVER_PACKET_READ(Proc, Type, Var) \
Type Var; \
{ \
if (!m_ServerBuffer.Proc(Var)) \
{ \
return false; \
} \
}
#define CLIENTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client")
#define SERVERSEND(...) SendData(m_ServerSocket, __VA_ARGS__, "Server")
2013-10-29 15:47:22 +01:00
#define CLIENTENCRYPTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client") // The client conn is always unencrypted
2013-07-29 12:13:03 +01:00
#define SERVERENCRYPTSEND(...) SendEncryptedData(m_ServerSocket, m_ServerEncryptor, __VA_ARGS__, "Server")
#define COPY_TO_SERVER() \
{ \
AString ToServer; \
m_ClientBuffer.ReadAgain(ToServer); \
switch (m_ServerState) \
{ \
case csUnencrypted: \
{ \
SERVERSEND(ToServer.data(), ToServer.size()); \
break; \
} \
case csEncryptedUnderstood: \
case csEncryptedUnknown: \
{ \
SERVERENCRYPTSEND(ToServer.data(), ToServer.size()); \
break; \
} \
case csWaitingForEncryption: \
{ \
Log("Waiting for server encryption, queued %u bytes", ToServer.size()); \
m_ServerEncryptionBuffer.append(ToServer.data(), ToServer.size()); \
break; \
} \
} \
DebugSleep(50); \
}
#define COPY_TO_CLIENT() \
{ \
AString ToClient; \
m_ServerBuffer.ReadAgain(ToClient); \
switch (m_ClientState) \
{ \
case csUnencrypted: \
{ \
CLIENTSEND(ToClient.data(), ToClient.size()); \
break; \
} \
case csEncryptedUnderstood: \
case csEncryptedUnknown: \
{ \
CLIENTENCRYPTSEND(ToClient.data(), ToClient.size()); \
break; \
} \
2015-01-21 14:15:35 +01:00
case csWaitingForEncryption: \
2013-07-29 12:13:03 +01:00
{ \
break; \
} \
2015-01-21 14:15:35 +01:00
\
2013-07-29 12:13:03 +01:00
} \
DebugSleep(50); \
}
#define HANDLE_CLIENT_READ(Proc) \
{ \
2013-10-29 22:55:00 +01:00
if (!Proc) \
2013-07-29 12:13:03 +01:00
{ \
AString Leftover; \
m_ClientBuffer.ReadAgain(Leftover); \
DataLog(Leftover.data(), Leftover.size(), "Leftover data after client packet parsing, %d bytes:", Leftover.size()); \
m_ClientBuffer.ResetRead(); \
return true; \
} \
}
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
#define HANDLE_SERVER_READ(Proc) \
{ \
2013-10-29 22:55:00 +01:00
if (!Proc) \
2013-07-29 12:13:03 +01:00
{ \
m_ServerBuffer.ResetRead(); \
return true; \
} \
}
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
typedef unsigned char Byte ;
2015-01-21 11:24:32 +01:00
// fwd declarations, to avoid clang warnings:
AString PrintableAbsIntTriplet ( int a_X , int a_Y , int a_Z , double a_Divisor = 32 );
2013-07-29 12:13:03 +01:00
2015-01-21 11:24:32 +01:00
AString PrintableAbsIntTriplet ( int a_X , int a_Y , int a_Z , double a_Divisor )
2013-09-04 20:42:37 +02:00
{
return Printf ( "<%d, %d, %d> ~ {%.02f, %.02f, %.02f}" ,
a_X , a_Y , a_Z ,
2016-08-24 21:45:03 +02:00
static_cast < double > ( a_X ) / a_Divisor , static_cast < double > ( a_Y ) / a_Divisor , static_cast < double > ( a_Z ) / a_Divisor
2013-09-04 20:42:37 +02:00
);
}
2014-01-17 13:15:54 +01:00
struct sCoords
{
int x , y , z ;
2017-12-23 12:49:08 +00:00
2014-01-17 13:15:54 +01:00
sCoords ( int a_X , int a_Y , int a_Z ) : x ( a_X ), y ( a_Y ), z ( a_Z ) {}
} ;
struct sChunkMeta
{
int m_ChunkX , m_ChunkZ ;
short m_PrimaryBitmap ;
short m_AddBitmap ;
sChunkMeta ( int a_ChunkX , int a_ChunkZ , short a_PrimaryBitmap , short a_AddBitmap ) :
m_ChunkX ( a_ChunkX ), m_ChunkZ ( a_ChunkZ ), m_PrimaryBitmap ( a_PrimaryBitmap ), m_AddBitmap ( a_AddBitmap )
{
}
} ;
2017-12-23 12:49:08 +00:00
////////////////////////////////////////////////////////////////////////////////
2013-07-29 12:13:03 +01:00
// cConnection:
cConnection :: cConnection ( SOCKET a_ClientSocket , cServer & a_Server ) :
m_ItemIdx ( 0 ),
2017-12-22 18:25:46 +00:00
m_LogFile ( nullptr ),
2013-07-29 12:13:03 +01:00
m_Server ( a_Server ),
m_ClientSocket ( a_ClientSocket ),
m_ServerSocket ( - 1 ),
2014-11-23 14:22:05 +00:00
m_BeginTick ( std :: chrono :: steady_clock :: now ()),
2013-07-29 12:13:03 +01:00
m_ClientState ( csUnencrypted ),
m_ServerState ( csUnencrypted ),
m_Nonce ( 0 ),
m_ClientBuffer ( 1024 KiB ),
m_ServerBuffer ( 1024 KiB ),
2013-10-28 23:05:53 +01:00
m_HasClientPinged ( false ),
2013-10-29 15:47:22 +01:00
m_ServerProtocolState ( - 1 ),
m_ClientProtocolState ( - 1 ),
m_IsServerEncrypted ( false )
2013-07-29 12:13:03 +01:00
{
2013-09-08 11:27:49 +02:00
// Create the Logs subfolder, if not already created:
#if defined(_WIN32)
_mkdir ( "Logs" );
#else
mkdir ( "Logs" , 0777 );
#endif
2016-08-24 21:45:03 +02:00
Printf ( m_LogNameBase , "Logs/Log_%d_%d" , static_cast < int > ( time ( nullptr )), static_cast < int > ( a_ClientSocket ));
2013-07-29 12:13:03 +01:00
AString fnam ( m_LogNameBase );
fnam . append ( ".log" );
2015-03-21 13:00:20 +01:00
#ifdef _WIN32
fopen_s ( & m_LogFile , fnam . c_str (), "w" );
#else
m_LogFile = fopen ( fnam . c_str (), "w" );
#endif
2013-07-29 12:13:03 +01:00
Log ( "Log file created" );
printf ( "Connection is logged to file \" %s \"\n " , fnam . c_str ());
}
cConnection ::~ cConnection ()
{
fclose ( m_LogFile );
}
void cConnection :: Run ( void )
{
if ( ! ConnectToServer ())
{
Log ( "Cannot connect to server; aborting" );
return ;
}
2013-09-19 21:35:33 +02:00
2013-07-29 12:13:03 +01:00
while ( true )
{
fd_set ReadFDs ;
FD_ZERO ( & ReadFDs );
FD_SET ( m_ServerSocket , & ReadFDs );
FD_SET ( m_ClientSocket , & ReadFDs );
2014-01-24 18:51:15 +01:00
SOCKET MaxSocket = std :: max ( m_ServerSocket , m_ClientSocket );
2017-12-22 18:25:46 +00:00
int res = select ( MaxSocket + 1 , & ReadFDs , nullptr , nullptr , nullptr );
2013-07-29 12:13:03 +01:00
if ( res <= 0 )
{
2014-01-17 13:15:54 +01:00
printf ( "select() failed: %d; aborting client" , SocketError );
2013-07-29 12:13:03 +01:00
break ;
}
if ( FD_ISSET ( m_ServerSocket , & ReadFDs ))
{
if ( ! RelayFromServer ())
{
break ;
}
}
if ( FD_ISSET ( m_ClientSocket , & ReadFDs ))
{
if ( ! RelayFromClient ())
{
break ;
}
}
}
Log ( "Relaying ended, closing sockets" );
closesocket ( m_ServerSocket );
closesocket ( m_ClientSocket );
}
2018-01-03 17:41:16 +00:00
void cConnection :: Log ( const char * a_Format , fmt :: ArgList a_Args )
2013-07-29 12:13:03 +01:00
{
2018-01-03 17:41:16 +00:00
fmt :: MemoryWriter FullMsg ;
fmt :: printf ( FullMsg , "[%5.3f] " , GetRelativeTime ());
fmt :: printf ( FullMsg , a_Format , a_Args );
fmt :: printf ( FullMsg , " \n " );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
// Log to file:
cCSLock Lock ( m_CSLog );
fputs ( FullMsg . c_str (), m_LogFile );
2013-12-05 12:20:37 +01:00
#ifdef _DEBUG
fflush ( m_LogFile );
#endif // _DEBUG
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
// Log to screen:
// std::cout << FullMsg;
}
2018-01-03 17:41:16 +00:00
void cConnection :: DataLog ( const void * a_Data , size_t a_Size , const char * a_Format , fmt :: ArgList a_Args )
2013-07-29 12:13:03 +01:00
{
2018-01-03 17:41:16 +00:00
fmt :: MemoryWriter FullMsg ;
fmt :: printf ( FullMsg , "[%5.3f] " , GetRelativeTime ());
fmt :: printf ( FullMsg , a_Format , a_Args );
2013-07-29 12:13:03 +01:00
AString Hex ;
2018-01-03 17:41:16 +00:00
fmt :: printf ( FullMsg , " \n %s \n " , CreateHexDump ( Hex , a_Data , a_Size , 16 ));
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
// Log to file:
cCSLock Lock ( m_CSLog );
fputs ( FullMsg . c_str (), m_LogFile );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
/*
// Log to screen:
std::cout << FullMsg;
//*/
}
void cConnection :: LogFlush ( void )
{
fflush ( m_LogFile );
}
bool cConnection :: ConnectToServer ( void )
{
m_ServerSocket = socket ( AF_INET , SOCK_STREAM , IPPROTO_TCP );
if ( m_ServerSocket == INVALID_SOCKET )
{
return false ;
}
sockaddr_in localhost ;
localhost . sin_family = AF_INET ;
localhost . sin_port = htons ( m_Server . GetConnectPort ());
localhost . sin_addr . s_addr = htonl ( 0x7f000001 ); // localhost
2016-08-24 21:45:03 +02:00
if ( connect ( m_ServerSocket , reinterpret_cast < const sockaddr *> ( & localhost ), sizeof ( localhost )) != 0 )
2013-07-29 12:13:03 +01:00
{
2014-01-17 13:15:54 +01:00
printf ( "connection to server failed: %d \n " , SocketError );
2013-07-29 12:13:03 +01:00
return false ;
}
Log ( "Connected to SERVER" );
return true ;
}
bool cConnection :: RelayFromServer ( void )
{
char Buffer [ 64 KiB ];
2015-01-21 11:24:32 +01:00
int res = static_cast < int > ( recv ( m_ServerSocket , Buffer , sizeof ( Buffer ), 0 )); // recv returns int on windows, ssize_t on linux
2013-07-29 12:13:03 +01:00
if ( res <= 0 )
{
2014-01-17 13:15:54 +01:00
Log ( "Server closed the socket: %d; %d; aborting connection" , res , SocketError );
2013-07-29 12:13:03 +01:00
return false ;
}
2017-12-23 12:49:08 +00:00
2015-01-21 11:24:32 +01:00
DataLog ( Buffer , static_cast < size_t > ( res ), "Received %d bytes from the SERVER" , res );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
switch ( m_ServerState )
{
case csUnencrypted :
case csWaitingForEncryption :
{
return DecodeServersPackets ( Buffer , res );
}
case csEncryptedUnderstood :
{
2015-01-21 11:24:32 +01:00
m_ServerDecryptor . ProcessData ( reinterpret_cast < Byte *> ( Buffer ), reinterpret_cast < Byte *> ( Buffer ), static_cast < size_t > ( res ));
2015-01-21 14:15:35 +01:00
DataLog ( Buffer , static_cast < size_t > ( res ), "Decrypted %d bytes from the SERVER" , res );
2013-07-29 12:13:03 +01:00
return DecodeServersPackets ( Buffer , res );
}
case csEncryptedUnknown :
{
2015-01-21 11:24:32 +01:00
m_ServerDecryptor . ProcessData ( reinterpret_cast < Byte *> ( Buffer ), reinterpret_cast < Byte *> ( Buffer ), static_cast < size_t > ( res ));
2015-01-21 14:15:35 +01:00
DataLog ( Buffer , static_cast < size_t > ( res ), "Decrypted %d bytes from the SERVER" , res );
2015-01-21 11:24:32 +01:00
return CLIENTSEND ( Buffer , static_cast < size_t > ( res ));
2013-07-29 12:13:03 +01:00
}
}
2014-04-04 08:55:48 +02:00
ASSERT ( ! "Unhandled server state while relaying from server" );
return false ;
2013-07-29 12:13:03 +01:00
}
bool cConnection :: RelayFromClient ( void )
{
char Buffer [ 64 KiB ];
2015-01-21 11:24:32 +01:00
int res = static_cast < int > ( recv ( m_ClientSocket , Buffer , sizeof ( Buffer ), 0 )); // recv returns int on Windows, ssize_t on Linux
2013-07-29 12:13:03 +01:00
if ( res <= 0 )
{
2014-01-17 13:15:54 +01:00
Log ( "Client closed the socket: %d; %d; aborting connection" , res , SocketError );
2013-07-29 12:13:03 +01:00
return false ;
}
2017-12-23 12:49:08 +00:00
2015-01-21 14:15:35 +01:00
DataLog ( Buffer , static_cast < size_t > ( res ), "Received %d bytes from the CLIENT" , res );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
switch ( m_ClientState )
{
case csUnencrypted :
case csWaitingForEncryption :
{
return DecodeClientsPackets ( Buffer , res );
}
case csEncryptedUnderstood :
{
return DecodeClientsPackets ( Buffer , res );
}
case csEncryptedUnknown :
{
2015-01-21 14:15:35 +01:00
DataLog ( Buffer , static_cast < size_t > ( res ), "Decrypted %d bytes from the CLIENT" , res );
2015-01-21 11:24:32 +01:00
m_ServerEncryptor . ProcessData ( reinterpret_cast < Byte *> ( Buffer ), reinterpret_cast < Byte *> ( Buffer ), static_cast < size_t > ( res ));
return SERVERSEND ( Buffer , static_cast < size_t > ( res ));
2013-07-29 12:13:03 +01:00
}
}
2014-04-04 08:55:48 +02:00
ASSERT ( ! "Unhandled server state while relaying from client" );
return false ;
2013-07-29 12:13:03 +01:00
}
double cConnection :: GetRelativeTime ( void )
{
2014-12-07 15:46:27 +01:00
Int64 msec = std :: chrono :: duration_cast < std :: chrono :: milliseconds > ( std :: chrono :: steady_clock :: now () - m_BeginTick ). count ();
return static_cast < double > ( msec ) / 1000 ;
2013-07-29 12:13:03 +01:00
}
2014-04-04 08:55:48 +02:00
bool cConnection :: SendData ( SOCKET a_Socket , const char * a_Data , size_t a_Size , const char * a_Peer )
2013-07-29 12:13:03 +01:00
{
2015-01-21 11:24:32 +01:00
DataLog ( a_Data , a_Size , "Sending data to %s, %u bytes" , a_Peer , static_cast < unsigned > ( a_Size ));
2017-12-23 12:49:08 +00:00
2015-01-21 14:15:35 +01:00
int res = static_cast < int > ( send ( a_Socket , a_Data , a_Size , 0 )); // Windows uses int for a_Size, Linux uses size_t; but Windows doesn't complain. Return type is int on Windows and ssize_t on Linux
2013-07-29 12:13:03 +01:00
if ( res <= 0 )
{
2014-01-17 13:15:54 +01:00
Log ( "%s closed the socket: %d, %d; aborting connection" , a_Peer , res , SocketError );
2013-07-29 12:13:03 +01:00
return false ;
}
return true ;
}
bool cConnection :: SendData ( SOCKET a_Socket , cByteBuffer & a_Data , const char * a_Peer )
{
AString All ;
a_Data . ReadAll ( All );
a_Data . CommitRead ();
return SendData ( a_Socket , All . data (), All . size (), a_Peer );
}
2014-04-29 17:37:15 +02:00
bool cConnection :: SendEncryptedData ( SOCKET a_Socket , cAesCfb128Encryptor & a_Encryptor , const char * a_Data , size_t a_Size , const char * a_Peer )
2013-07-29 12:13:03 +01:00
{
DataLog ( a_Data , a_Size , "Encrypting %d bytes to %s" , a_Size , a_Peer );
2016-08-24 21:45:03 +02:00
const Byte * Data = reinterpret_cast < const Byte *> ( a_Data );
2013-07-29 12:13:03 +01:00
while ( a_Size > 0 )
{
2014-01-25 19:19:37 +01:00
Byte Buffer [ 64 KiB ];
2014-03-10 12:21:18 -07:00
size_t NumBytes = ( a_Size > sizeof ( Buffer )) ? sizeof ( Buffer ) : a_Size ;
2013-07-29 12:13:03 +01:00
a_Encryptor . ProcessData ( Buffer , Data , NumBytes );
2016-08-24 21:45:03 +02:00
bool res = SendData ( a_Socket , reinterpret_cast < const char *> ( Buffer ), NumBytes , a_Peer );
2013-07-29 12:13:03 +01:00
if ( ! res )
{
return false ;
}
Data += NumBytes ;
a_Size -= NumBytes ;
}
return true ;
}
2014-04-29 17:37:15 +02:00
bool cConnection :: SendEncryptedData ( SOCKET a_Socket , cAesCfb128Encryptor & a_Encryptor , cByteBuffer & a_Data , const char * a_Peer )
2013-07-29 12:13:03 +01:00
{
AString All ;
a_Data . ReadAll ( All );
a_Data . CommitRead ();
return SendEncryptedData ( a_Socket , a_Encryptor , All . data (), All . size (), a_Peer );
}
bool cConnection :: DecodeClientsPackets ( const char * a_Data , int a_Size )
{
2015-01-21 11:24:32 +01:00
if ( ! m_ClientBuffer . Write ( a_Data , static_cast < size_t > ( a_Size )))
2013-07-29 12:13:03 +01:00
{
Log ( "Too much queued data for the server, aborting connection" );
return false ;
}
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
while ( m_ClientBuffer . CanReadBytes ( 1 ))
{
2013-10-28 23:05:53 +01:00
UInt32 PacketLen ;
if (
! m_ClientBuffer . ReadVarInt ( PacketLen ) ||
! m_ClientBuffer . CanReadBytes ( PacketLen )
)
2013-07-29 12:13:03 +01:00
{
2013-10-28 23:05:53 +01:00
// Not a complete packet yet
break ;
}
2013-10-29 22:55:00 +01:00
UInt32 PacketType , PacketReadSoFar ;
2015-01-21 11:24:32 +01:00
PacketReadSoFar = static_cast < UInt32 > ( m_ClientBuffer . GetReadableSpace ());
2013-10-28 23:05:53 +01:00
VERIFY ( m_ClientBuffer . ReadVarInt ( PacketType ));
2013-10-29 22:55:00 +01:00
PacketReadSoFar -= m_ClientBuffer . GetReadableSpace ();
2015-01-21 11:24:32 +01:00
Log ( "Decoding client's packets, there are now %u bytes in the queue; next packet is 0x%02x, %u bytes long" ,
static_cast < unsigned > ( m_ClientBuffer . GetReadableSpace ()), PacketType , PacketLen
);
2013-10-29 15:47:22 +01:00
switch ( m_ClientProtocolState )
2013-10-28 23:05:53 +01:00
{
case - 1 :
{
// No initial handshake received yet
switch ( PacketType )
{
2013-10-29 22:55:00 +01:00
case 0x00 : HANDLE_CLIENT_READ ( HandleClientHandshake ()); break ;
default : HANDLE_CLIENT_READ ( HandleClientUnknownPacket ( PacketType , PacketLen , PacketReadSoFar )); break ;
2013-10-28 23:05:53 +01:00
}
break ;
} // case -1
2017-12-23 12:49:08 +00:00
2013-10-28 23:05:53 +01:00
case 1 :
{
// Status query
switch ( PacketType )
{
2013-10-29 22:55:00 +01:00
case 0x00 : HANDLE_CLIENT_READ ( HandleClientStatusRequest ()); break ;
case 0x01 : HANDLE_CLIENT_READ ( HandleClientStatusPing ()); break ;
default : HANDLE_CLIENT_READ ( HandleClientUnknownPacket ( PacketType , PacketLen , PacketReadSoFar )); break ;
2013-10-28 23:05:53 +01:00
}
break ;
}
2017-12-23 12:49:08 +00:00
2013-10-28 23:05:53 +01:00
case 2 :
{
2013-10-29 15:47:22 +01:00
// Login
switch ( PacketType )
{
2013-10-29 22:55:00 +01:00
case 0x00 : HANDLE_CLIENT_READ ( HandleClientLoginStart ()); break ;
case 0x01 : HANDLE_CLIENT_READ ( HandleClientLoginEncryptionKeyResponse ()); break ;
default : HANDLE_CLIENT_READ ( HandleClientUnknownPacket ( PacketType , PacketLen , PacketReadSoFar )); break ;
2013-10-29 15:47:22 +01:00
}
break ;
}
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
case 3 :
{
// Game:
2013-10-28 23:05:53 +01:00
switch ( PacketType )
{
2013-10-29 22:55:00 +01:00
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 ;
2013-10-28 23:05:53 +01:00
}
break ;
2013-10-29 22:06:15 +01:00
} // case 3 - Game
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
default :
{
2013-10-29 22:55:00 +01:00
Log ( "Receiving server packets while in an unknown protocol state (%d)!" , m_ClientProtocolState );
HANDLE_CLIENT_READ ( HandleClientUnknownPacket ( PacketType , PacketLen , PacketReadSoFar ));
break ;
}
2013-10-28 23:05:53 +01:00
} // switch (m_ProtocolState)
2013-07-29 12:13:03 +01:00
m_ClientBuffer . CommitRead ();
2013-10-28 23:05:53 +01:00
} // while (true)
2013-07-29 12:13:03 +01:00
return true ;
}
bool cConnection :: DecodeServersPackets ( const char * a_Data , int a_Size )
{
2015-01-21 14:15:35 +01:00
if ( ! m_ServerBuffer . Write ( a_Data , static_cast < size_t > ( a_Size )))
2013-07-29 12:13:03 +01:00
{
Log ( "Too much queued data for the client, aborting connection" );
return false ;
}
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
if (
( m_ServerState == csEncryptedUnderstood ) &&
( m_ClientState == csUnencrypted )
)
{
// Client hasn't finished encryption handshake yet, don't send them any data yet
}
2017-12-23 12:49:08 +00:00
2013-10-28 23:05:53 +01:00
while ( true )
2013-07-29 12:13:03 +01:00
{
2013-10-28 23:05:53 +01:00
UInt32 PacketLen ;
if (
! m_ServerBuffer . ReadVarInt ( PacketLen ) ||
! m_ServerBuffer . CanReadBytes ( PacketLen )
)
{
// Not a complete packet yet
2013-11-02 17:46:37 +01:00
m_ServerBuffer . ResetRead ();
2013-10-28 23:05:53 +01:00
break ;
}
2013-11-03 00:01:56 +01:00
if ( PacketLen == 0 )
{
m_ServerBuffer . ResetRead ();
AString All ;
m_ServerBuffer . ReadAll ( All );
DataLog ( All . data (), All . size (), "====== Received a bad packet length? Inspect the contents below ======" );
m_ServerBuffer . CommitRead (); // Try to recover by marking everything as read
break ;
}
2013-10-29 22:55:00 +01:00
UInt32 PacketType , PacketReadSoFar ;
2015-01-21 14:15:35 +01:00
PacketReadSoFar = static_cast < UInt32 > ( m_ServerBuffer . GetReadableSpace ());
2013-10-28 23:05:53 +01:00
VERIFY ( m_ServerBuffer . ReadVarInt ( PacketType ));
2013-10-29 22:55:00 +01:00
PacketReadSoFar -= m_ServerBuffer . GetReadableSpace ();
2013-10-28 23:05:53 +01:00
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 );
2013-07-29 12:13:03 +01:00
LogFlush ();
2013-10-29 15:47:22 +01:00
switch ( m_ServerProtocolState )
2013-07-29 12:13:03 +01:00
{
2013-10-28 23:05:53 +01:00
case - 1 :
{
Log ( "Receiving data from the server without an initial handshake message!" );
2013-10-29 22:55:00 +01:00
HANDLE_SERVER_READ ( HandleServerUnknownPacket ( PacketType , PacketLen , PacketReadSoFar ));
2013-10-28 23:05:53 +01:00
break ;
}
2017-12-23 12:49:08 +00:00
2013-10-28 23:05:53 +01:00
case 1 :
{
// Status query:
switch ( PacketType )
{
2013-10-29 22:55:00 +01:00
case 0x00 : HANDLE_SERVER_READ ( HandleServerStatusResponse ()); break ;
case 0x01 : HANDLE_SERVER_READ ( HandleServerStatusPing ()); break ;
default : HANDLE_SERVER_READ ( HandleServerUnknownPacket ( PacketType , PacketLen , PacketReadSoFar )); break ;
2013-10-28 23:05:53 +01:00
}
break ;
}
2017-12-23 12:49:08 +00:00
2013-10-28 23:05:53 +01:00
case 2 :
{
2013-10-29 15:47:22 +01:00
// Login:
2013-10-28 23:05:53 +01:00
switch ( PacketType )
{
2013-10-29 22:55:00 +01:00
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 ;
2013-10-29 15:47:22 +01:00
}
break ;
}
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
case 3 :
{
// Game:
switch ( PacketType )
{
2013-10-29 22:55:00 +01:00
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 ;
2013-10-28 23:05:53 +01:00
} // switch (PacketType)
break ;
2013-10-29 22:06:15 +01:00
} // case 3 - Game
2017-12-23 12:49:08 +00:00
2013-10-28 23:05:53 +01:00
// TODO: Move this elsewhere
2013-07-29 12:13:03 +01:00
default :
{
2013-10-29 22:55:00 +01:00
Log ( "Received a packet from the server while in an unknown state: %d" , m_ServerProtocolState );
HANDLE_SERVER_READ ( HandleServerUnknownPacket ( PacketType , PacketLen , PacketReadSoFar ));
break ;
2013-07-29 12:13:03 +01:00
}
2013-10-28 23:05:53 +01:00
} // switch (m_ProtocolState)
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
m_ServerBuffer . CommitRead ();
} // while (CanReadBytes(1))
return true ;
}
2017-12-23 12:49:08 +00:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 15:47:22 +01:00
// 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 );
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , ServerPort );
2013-10-29 15:47:22 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadVarInt , UInt32 , NextState );
m_ClientBuffer . CommitRead ();
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
Log ( "Received an initial handshake packet from the client:" );
Log ( " ProtocolVersion = %u" , ProtocolVersion );
Log ( " ServerHost = \" %s \" " , ServerHost . c_str ());
2015-03-21 13:00:20 +01:00
Log ( " ServerPort = %u" , ServerPort );
2013-10-29 15:47:22 +01:00
Log ( " NextState = %u" , NextState );
// Send the same packet to the server, but with our port:
cByteBuffer Packet ( 512 );
2015-03-22 23:09:23 +01:00
Packet . WriteVarInt32 ( 0 ); // Packet type - initial handshake
Packet . WriteVarInt32 ( ProtocolVersion );
2013-10-29 15:47:22 +01:00
Packet . WriteVarUTF8String ( ServerHost );
2015-03-21 13:00:20 +01:00
Packet . WriteBEUInt16 ( m_Server . GetConnectPort ());
2015-03-22 23:09:23 +01:00
Packet . WriteVarInt32 ( NextState );
2013-10-29 15:47:22 +01:00
AString Pkt ;
Packet . ReadAll ( Pkt );
cByteBuffer ToServer ( 512 );
ToServer . WriteVarUTF8String ( Pkt );
SERVERSEND ( ToServer );
2017-12-23 12:49:08 +00:00
2015-03-21 13:00:20 +01:00
m_ClientProtocolState = static_cast < int > ( NextState );
m_ServerProtocolState = static_cast < int > ( NextState );
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
return true ;
}
2017-12-23 12:49:08 +00:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 15:47:22 +01:00
// 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 ;
}
2017-12-23 12:49:08 +00:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 15:47:22 +01:00
// packet handling, client-side, game:
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleClientAnimation ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt8 , Int8 , Animation );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ANIMATION from the client:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID: %u" , EntityID );
2013-07-29 12:13:03 +01:00
Log ( " Animation: %d" , Animation );
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientBlockDig ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Status );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , BlockX );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , BlockY );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , BlockZ );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , BlockFace );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_BLOCK_DIG from the client:" );
2015-03-21 13:00:20 +01:00
Log ( " Status = %u (0x%02x)" , Status , Status );
Log ( " Pos = <%d, %u, %d>" , BlockX , BlockY , BlockZ );
Log ( " BlockFace = %u (0x%02x)" , BlockFace , BlockFace );
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientBlockPlace ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , BlockX );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , BlockY );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , BlockZ );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Face );
2013-07-29 12:13:03 +01:00
AString Desc ;
if ( ! ParseSlot ( m_ClientBuffer , Desc ))
{
return false ;
}
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , CursorX );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , CursorY );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , CursorZ );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_BLOCK_PLACE from the client:" );
2015-03-21 13:00:20 +01:00
Log ( " Block = {%d, %u, %d}" , BlockX , BlockY , BlockZ );
Log ( " Face = %u (0x%02x)" , Face , Face );
2013-07-29 12:13:03 +01:00
Log ( " Item = %s" , Desc . c_str ());
2015-03-21 13:00:20 +01:00
Log ( " Cursor = <%u, %u, %u>" , CursorX , CursorY , CursorZ );
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientChatMessage ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Message );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_CHAT_MESSAGE from the client:" );
Log ( " Message = \" %s \" " , Message . c_str ());
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientClientStatuses ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Statuses );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_CLIENT_STATUSES from the CLIENT:" );
2015-03-21 13:00:20 +01:00
Log ( " Statuses = %u (0x%02x)" , Statuses , Statuses );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientCreativeInventoryAction ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , SlotNum );
2013-07-29 12:13:03 +01:00
AString Item ;
if ( ! ParseSlot ( m_ClientBuffer , Item ))
{
return false ;
}
Log ( "Received a PACKET_CREATIVE_INVENTORY_ACTION from the client:" );
2015-03-21 13:00:20 +01:00
Log ( " SlotNum = %u" , SlotNum );
2013-07-29 12:13:03 +01:00
Log ( " Item = %s" , Item . c_str ());
COPY_TO_SERVER ();
return true ;
}
2013-08-25 21:57:12 +02:00
bool cConnection :: HandleClientDisconnect ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Reason );
2013-08-25 21:57:12 +02:00
Log ( "Received a PACKET_DISCONNECT from the client:" );
Log ( " Reason = \" %s \" " , Reason . c_str ());
COPY_TO_SERVER ();
return true ;
}
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleClientEntityAction ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , PlayerID );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , ActionType );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , HorseJumpBoost );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_ACTION from the client:" );
Log ( " PlayerID = %d" , PlayerID );
2015-03-21 13:00:20 +01:00
Log ( " ActionType = %u" , ActionType );
2013-10-29 22:55:00 +01:00
Log ( " HorseJumpBoost = %d (0x%08x)" , HorseJumpBoost , HorseJumpBoost );
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientKeepAlive ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , ID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_KEEPALIVE from the client" );
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientLocaleAndView ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Locale );
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt8 , Int8 , ViewDistance );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt8 , Int8 , ChatFlags );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt8 , Int8 , Unused );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt8 , Int8 , Difficulty );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt8 , Int8 , ShowCape );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_LOCALE_AND_VIEW from the client" );
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientPing ( void )
{
m_HasClientPinged = true ;
Log ( "Received a PACKET_PING from the client" );
m_ClientBuffer . ResetRead ();
SERVERSEND ( m_ClientBuffer );
return true ;
}
bool cConnection :: HandleClientPlayerAbilities ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Flags );
2013-07-29 12:13:03 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEFloat , float , FlyingSpeed );
HANDLE_CLIENT_PACKET_READ ( ReadBEFloat , float , WalkingSpeed );
Log ( "Receives a PACKET_PLAYER_ABILITIES from the client:" );
2015-03-21 13:00:20 +01:00
Log ( " Flags = %u (0x%02x)" , Flags , Flags );
2013-07-29 12:13:03 +01:00
Log ( " FlyingSpeed = %f" , FlyingSpeed );
Log ( " WalkingSpeed = %f" , WalkingSpeed );
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientPlayerLook ( void )
{
HANDLE_CLIENT_PACKET_READ ( ReadBEFloat , float , Yaw );
HANDLE_CLIENT_PACKET_READ ( ReadBEFloat , float , Pitch );
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , OnGround );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_PLAYER_LOOK from the client" );
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientPlayerOnGround ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , OnGround );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_PLAYER_ON_GROUND from the client" );
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientPlayerPosition ( void )
{
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , PosX );
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , PosY );
2013-10-29 22:55:00 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , Stance );
2013-07-29 12:13:03 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , PosZ );
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , IsOnGround );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_PLAYER_POSITION from the client" );
// TODO: list packet contents
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientPlayerPositionLook ( void )
{
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , PosX );
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , PosY );
2013-10-29 22:55:00 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , Stance );
2013-07-29 12:13:03 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , PosZ );
HANDLE_CLIENT_PACKET_READ ( ReadBEFloat , float , Yaw );
HANDLE_CLIENT_PACKET_READ ( ReadBEFloat , float , Pitch );
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , IsOnGround );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_PLAYER_POSITION_LOOK from the client" );
Log ( " Pos = {%.03f, %.03f, %.03f}" , PosX , PosY , PosZ );
Log ( " Stance = %.03f" , Stance );
2013-10-29 22:55:00 +01:00
Log ( " Yaw, Pitch = <%.03f, %.03f>" , Yaw , Pitch );
2013-07-29 12:13:03 +01:00
Log ( " IsOnGround = %s" , IsOnGround ? "true" : "false" );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientPluginMessage ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , ChannelName );
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , Length );
2013-07-29 12:13:03 +01:00
AString Data ;
if ( ! m_ClientBuffer . ReadString ( Data , Length ))
{
return false ;
}
Log ( "Received a PACKET_PLUGIN_MESSAGE from the client" );
Log ( " ChannelName = \" %s \" " , ChannelName . c_str ());
2015-01-21 14:15:35 +01:00
DataLog ( Data . data (), Length , " Data: %u bytes" , Length );
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientSlotSelect ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt16 , Int16 , SlotNum );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_SLOT_SELECT from the client" );
Log ( " SlotNum = %d" , SlotNum );
COPY_TO_SERVER ();
return true ;
}
2013-10-28 23:05:53 +01:00
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 ;
}
2013-07-31 14:32:05 +02:00
bool cConnection :: HandleClientTabCompletion ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Query );
2013-07-31 14:32:05 +02:00
Log ( "Received a PACKET_TAB_COMPLETION query from the client" );
Log ( " Query = \" %s \" " , Query . c_str ());
COPY_TO_SERVER ();
return true ;
}
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleClientUpdateSign ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , BlockX );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt16 , Int16 , BlockY );
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , BlockZ );
2013-10-29 22:06:15 +01:00
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 );
2013-07-29 12:13:03 +01:00
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 ());
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientUseEntity ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , MouseButton );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_USE_ENTITY from the client:" );
Log ( " EntityID = %d" , EntityID );
2015-03-21 13:00:20 +01:00
Log ( " MouseButton = %u" , MouseButton );
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientWindowClick ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , SlotNum );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Button );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , TransactionID );
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Mode );
2013-07-29 12:13:03 +01:00
AString Item ;
if ( ! ParseSlot ( m_ClientBuffer , Item ))
{
return false ;
}
Log ( "Received a PACKET_WINDOW_CLICK from the client" );
2015-03-21 13:00:20 +01:00
Log ( " WindowID = %u" , WindowID );
Log ( " SlotNum = %u" , SlotNum );
Log ( " Button = %u, Mode = %u" , Button , Mode );
2013-07-29 12:13:03 +01:00
Log ( " TransactionID = 0x%x" , TransactionID );
Log ( " ClickedItem = %s" , Item . c_str ());
COPY_TO_SERVER ();
return true ;
}
bool cConnection :: HandleClientWindowClose ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_WINDOW_CLOSE from the client:" );
2015-03-21 13:00:20 +01:00
Log ( " WindowID = %u" , WindowID );
2013-07-29 12:13:03 +01:00
COPY_TO_SERVER ();
return true ;
}
2013-10-29 22:55:00 +01:00
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 ;
}
2017-12-23 12:49:08 +00:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 15:47:22 +01:00
// 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 ());
2014-01-13 20:31:08 +01:00
COPY_TO_CLIENT ();
2013-10-29 15:47:22 +01:00
return true ;
}
bool cConnection :: HandleServerLoginEncryptionKeyRequest ( void )
{
// Read the packet from the server:
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , ServerID );
2015-01-21 14:15:35 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , PublicKeyLength );
2013-10-29 15:47:22 +01:00
AString PublicKey ;
if ( ! m_ServerBuffer . ReadString ( PublicKey , PublicKeyLength ))
{
return false ;
}
2015-01-21 14:15:35 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , NonceLength );
2013-10-29 15:47:22 +01:00
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 ());
2016-08-24 21:45:03 +02:00
DataLog ( PublicKey . data (), PublicKey . size (), " Public key (%u bytes)" , static_cast < unsigned > ( PublicKey . size ()));
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
// Reply to the server:
SendEncryptionKeyResponse ( PublicKey , Nonce );
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
// 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 ());
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
Log ( "Server is now in protocol state Game." );
m_ServerProtocolState = 3 ;
2017-12-23 12:49:08 +00:00
2013-10-29 15:47:22 +01:00
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 ;
}
2017-12-23 12:49:08 +00:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 15:47:22 +01:00
// packet handling, server-side, game:
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleServerAttachEntity ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , VehicleID );
HANDLE_SERVER_PACKET_READ ( ReadBool , bool , IsOnLeash );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ATTACH_ENTITY from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u (0x%x)" , EntityID , EntityID );
Log ( " VehicleID = %u (0x%x)" , VehicleID , VehicleID );
Log ( " IsOnLeash = %s" , IsOnLeash ? "true" : "false" );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerBlockAction ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , BlockY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Byte1 );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Byte2 );
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , BlockID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_BLOCK_ACTION from the server:" );
Log ( " Pos = {%d, %d, %d}" , BlockX , BlockY , BlockZ );
2015-03-21 13:00:20 +01:00
Log ( " Bytes = (%u, %u) == (0x%x, 0x%x)" , Byte1 , Byte2 , Byte1 , Byte2 );
2013-10-29 22:06:15 +01:00
Log ( " BlockID = %u" , BlockID );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerBlockChange ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockX );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , BlockY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockZ );
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , BlockType );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , BlockMeta );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_BLOCK_CHANGE from the server" );
2015-03-21 13:00:20 +01:00
Log ( " Pos = {%d, %u, %d}" , BlockX , BlockY , BlockZ );
Log ( " BlockType = %u (0x%x" , BlockType , BlockType );
Log ( " BlockMeta = %u" , BlockMeta );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerChangeGameState ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Reason );
2013-11-02 20:59:29 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , Data );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_CHANGE_GAME_STATE from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " Reason = %u" , Reason );
2013-11-02 20:59:29 +01:00
Log ( " Data = %f" , Data );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerChatMessage ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Message );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_CHAT_MESSAGE from the server:" );
Log ( " Message = \" %s \" " , Message . c_str ());
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerCollectPickup ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , CollectedID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , CollectorID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_COLLECT_PICKUP from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " CollectedID = %u" , CollectedID );
Log ( " CollectorID = %u" , CollectorID );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerCompass ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , SpawnX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , SpawnY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , SpawnZ );
2013-07-29 12:13:03 +01:00
Log ( "Received PACKET_COMPASS from the server:" );
Log ( " Spawn = {%d, %d, %d}" , SpawnX , SpawnY , SpawnZ );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerDestroyEntities ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , NumEntities );
2015-01-21 14:15:35 +01:00
if ( ! m_ServerBuffer . SkipRead ( static_cast < size_t > ( NumEntities ) * 4 ))
2013-07-29 12:13:03 +01:00
{
return false ;
}
Log ( "Received PACKET_DESTROY_ENTITIES from the server:" );
2015-01-21 14:15:35 +01:00
Log ( " NumEntities = %u" , NumEntities );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntity ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityEquipment ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , SlotNum );
2013-07-29 12:13:03 +01:00
AString Item ;
if ( ! ParseSlot ( m_ServerBuffer , Item ))
{
return false ;
}
Log ( "Received a PACKET_ENTITY_EQUIPMENT from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
Log ( " SlotNum = %u" , SlotNum );
2013-07-29 12:13:03 +01:00
Log ( " Item = %s" , Item . c_str ());
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityHeadLook ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , HeadYaw );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_HEAD_LOOK from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
Log ( " HeadYaw = %u" , HeadYaw );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityLook ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_LOOK from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
Log ( " Yaw = %u" , Yaw );
Log ( " Pitch = %u" , Pitch );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityMetadata ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
2013-07-29 12:13:03 +01:00
AString Metadata ;
if ( ! ParseMetadata ( m_ServerBuffer , Metadata ))
{
return false ;
}
AString HexDump ;
CreateHexDump ( HexDump , Metadata . data (), Metadata . size (), 32 );
Log ( "Received a PACKET_ENTITY_METADATA from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
auto len = static_cast < unsigned > ( Metadata . length ());
Log ( " Metadata, length = %u (0x%x): \n %s" , len , len , HexDump . c_str ());
2013-07-29 12:13:03 +01:00
LogMetadata ( Metadata , 4 );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityProperties ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , Count );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_PROPERTIES from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
Log ( " Count = %u" , Count );
2017-12-23 12:49:08 +00:00
2015-03-21 13:00:20 +01:00
for ( UInt32 i = 0 ; i < Count ; i ++ )
2013-07-29 12:13:03 +01:00
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Key );
HANDLE_SERVER_PACKET_READ ( ReadBEDouble , double , Value );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , ListLength );
Log ( " \" %s \" = %f; %u modifiers" , Key . c_str (), Value , ListLength );
for ( UInt16 j = 0 ; j < ListLength ; j ++ )
2013-10-29 22:06:15 +01:00
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , UUIDHi );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , UUIDLo );
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEDouble , double , DblVal );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , ByteVal );
2013-10-29 22:06:15 +01:00
Log ( " [%d] = {0x%08llx%08llx, %f, %u}" , j , UUIDHi , UUIDLo , DblVal , ByteVal );
}
2013-07-29 12:13:03 +01:00
} // for i
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityRelativeMove ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , dx );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , dy );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , dz );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_RELATIVE_MOVE from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
2013-09-04 20:42:37 +02:00
Log ( " RelMove = %s" , PrintableAbsIntTriplet ( dx , dy , dz ). c_str ());
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityRelativeMoveLook ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , dx );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , dy );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , dz );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_RELATIVE_MOVE_LOOK from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
2013-09-04 20:42:37 +02:00
Log ( " RelMove = %s" , PrintableAbsIntTriplet ( dx , dy , dz ). c_str ());
2015-03-21 13:00:20 +01:00
Log ( " Yaw = %u" , Yaw );
Log ( " Pitch = %u" , Pitch );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityStatus ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Status );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_STATUS from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
Log ( " Status = %u (0x%02x)" , Status , Status );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityTeleport ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , AbsX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , AbsY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , AbsZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_TELEPORT from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
2013-10-29 22:06:15 +01:00
Log ( " Pos = %s" , PrintableAbsIntTriplet ( AbsX , AbsY , AbsZ ). c_str ());
2015-03-21 13:00:20 +01:00
Log ( " Yaw = %u" , Yaw );
Log ( " Pitch = %u" , Pitch );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerEntityVelocity ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , VelocityX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , VelocityY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , VelocityZ );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_ENTITY_VELOCITY from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
2013-09-04 20:42:37 +02:00
Log ( " Velocity = %s" , PrintableAbsIntTriplet ( VelocityX , VelocityY , VelocityZ , 8000 ). c_str ());
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
2013-09-19 21:51:59 +02:00
}
bool cConnection :: HandleServerExplosion ( void )
{
2015-01-21 14:15:35 +01:00
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 ( ReadBEUInt32 , UInt32 , NumRecords );
2013-09-19 21:51:59 +02:00
std :: vector < sCoords > Records ;
Records . reserve ( NumRecords );
2015-03-21 13:00:20 +01:00
int PosXI = static_cast < int > ( PosX ), PosYI = static_cast < int > ( PosY ), PosZI = static_cast < int > ( PosZ );
2015-01-21 14:15:35 +01:00
for ( UInt32 i = 0 ; i < NumRecords ; i ++ )
2013-09-19 21:51:59 +02:00
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , rx );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , ry );
HANDLE_SERVER_PACKET_READ ( ReadBEInt8 , Int8 , rz );
2013-09-19 21:51:59 +02:00
Records . push_back ( sCoords ( PosXI + rx , PosYI + ry , PosZI + rz ));
}
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , PlayerMotionX );
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , PlayerMotionY );
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , PlayerMotionZ );
Log ( "Received a PACKET_EXPLOSION from the server:" );
Log ( " Pos = {%.02f, %.02f, %.02f}" , PosX , PosY , PosZ );
Log ( " Force = %.02f" , Force );
2015-01-21 14:15:35 +01:00
Log ( " NumRecords = %u" , NumRecords );
for ( UInt32 i = 0 ; i < NumRecords ; i ++ )
2013-09-19 21:51:59 +02:00
{
2015-01-21 14:15:35 +01:00
Log ( " Records[%u] = {%d, %d, %d}" , i , Records [ i ]. x , Records [ i ]. y , Records [ i ]. z );
2013-09-19 21:51:59 +02:00
}
Log ( " Player motion = <%.02f, %.02f, %.02f>" , PlayerMotionX , PlayerMotionY , PlayerMotionZ );
COPY_TO_CLIENT ();
return true ;
2013-07-29 12:13:03 +01:00
}
bool cConnection :: HandleServerIncrementStatistic ( void )
{
// 0xc8
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , StatisticID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , Amount );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_INCREMENT_STATISTIC from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " StatisticID = %u (0x%x)" , StatisticID , StatisticID );
2013-07-29 12:13:03 +01:00
Log ( " Amount = %d" , Amount );
COPY_TO_CLIENT ();
return true ;
}
2013-10-29 22:06:15 +01:00
bool cConnection :: HandleServerJoinGame ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , GameMode );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Dimension );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Difficulty );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , MaxPlayers );
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , LevelType );
Log ( "Received a PACKET_LOGIN from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
Log ( " GameMode = %u" , GameMode );
Log ( " Dimension = %u" , Dimension );
Log ( " Difficulty = %u" , Difficulty );
Log ( " MaxPlayers = %u" , MaxPlayers );
2013-10-29 22:06:15 +01:00
Log ( " LevelType = \" %s \" " , LevelType . c_str ());
COPY_TO_CLIENT ();
return true ;
}
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleServerKeepAlive ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , PingID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_KEEP_ALIVE from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " ID = %u" , PingID );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ()
return true ;
}
bool cConnection :: HandleServerKick ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Reason );
2013-07-29 12:13:03 +01:00
Log ( "Received PACKET_KICK from the SERVER:" );
if ( m_HasClientPinged )
{
Log ( " This was a std reply to client's PING" );
AStringVector Split ;
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
// Split by NULL chars (StringSplit() won't work here):
size_t Last = 0 ;
2013-09-08 11:12:34 +02:00
size_t Len = Reason . size ();
for ( size_t i = 0 ; i < Len ; i ++ )
2013-07-29 12:13:03 +01:00
{
if ( Reason [ i ] == 0 )
{
Split . push_back ( Reason . substr ( Last , i - Last ));
Last = i + 1 ;
}
}
2013-09-08 11:12:34 +02:00
if ( Last < Len )
{
Split . push_back ( Reason . substr ( Last ));
}
2017-12-23 12:49:08 +00:00
2013-09-08 11:12:34 +02:00
if ( Split . size () == 6 )
2013-07-29 12:13:03 +01:00
{
2013-09-08 11:12:34 +02:00
Log ( " Preamble: \" %s \" " , Split [ 0 ]. c_str ());
Log ( " Protocol version: \" %s \" " , Split [ 1 ]. c_str ());
Log ( " Server version: \" %s \" " , Split [ 2 ]. c_str ());
Log ( " MOTD: \" %s \" " , Split [ 3 ]. c_str ());
Log ( " Cur players: \" %s \" " , Split [ 4 ]. c_str ());
Log ( " Max players: \" %s \" " , Split [ 5 ]. c_str ());
2017-12-23 12:49:08 +00:00
2013-09-08 11:12:34 +02:00
// Modify the MOTD to show that it's being ProtoProxied:
Reason . assign ( Split [ 0 ]);
Reason . push_back ( 0 );
Reason . append ( Split [ 1 ]);
Reason . push_back ( 0 );
Reason . append ( Split [ 2 ]);
Reason . push_back ( 0 );
Reason . append ( Printf ( "ProtoProxy: %s" , Split [ 3 ]. c_str ()));
Reason . push_back ( 0 );
Reason . append ( Split [ 4 ]);
Reason . push_back ( 0 );
Reason . append ( Split [ 5 ]);
2015-09-29 16:08:40 +01:00
auto ReasonBE16 = UTF8ToRawBEUTF16 ( Reason );
2013-09-08 11:12:34 +02:00
AString PacketStart ( " \xff " );
2015-09-29 16:08:40 +01:00
PacketStart . push_back ( static_cast < char > ( ReasonBE16 . size () / 256 ));
PacketStart . push_back ( static_cast < char > ( ReasonBE16 . size () % 256 ));
2013-09-08 11:12:34 +02:00
CLIENTSEND ( PacketStart . data (), PacketStart . size ());
2015-09-29 16:08:40 +01:00
CLIENTSEND ( reinterpret_cast < const char *> ( ReasonBE16 . data ()), ReasonBE16 . size () * sizeof ( char16_t ));
2013-09-08 11:12:34 +02:00
return true ;
2013-07-29 12:13:03 +01:00
}
else
{
DataLog ( Reason . data (), Reason . size (), " Unknown reply format, dumping hex:" );
}
}
else
{
Log ( " Reason = \" %s \" " , Reason . c_str ());
}
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerMapChunk ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , IsContiguous );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , PrimaryBitmap );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , AdditionalBitmap );
2015-01-21 14:15:35 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , CompressedSize );
2013-07-29 12:13:03 +01:00
AString CompressedData ;
if ( ! m_ServerBuffer . ReadString ( CompressedData , CompressedSize ))
{
return false ;
}
Log ( "Received a PACKET_MAP_CHUNK from the server:" );
Log ( " ChunkPos = [%d, %d]" , ChunkX , ChunkZ );
2015-01-21 14:15:35 +01:00
Log ( " Compressed size = %u (0x%x)" , CompressedSize , CompressedSize );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
// TODO: Save the compressed data into a file for later analysis
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ()
return true ;
}
bool cConnection :: HandleServerMapChunkBulk ( void )
{
2015-01-21 14:15:35 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , ChunkCount );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , CompressedSize );
HANDLE_SERVER_PACKET_READ ( ReadBool , bool , IsSkyLightSent );
2013-07-29 12:13:03 +01:00
AString CompressedData ;
if ( ! m_ServerBuffer . ReadString ( CompressedData , CompressedSize ))
{
return false ;
}
2017-12-23 12:49:08 +00:00
2013-08-30 16:38:24 +02:00
// Read individual chunk metas.
// Need to read them first and only then start logging (in case we don't have the full packet yet)
typedef std :: vector < sChunkMeta > sChunkMetas ;
sChunkMetas ChunkMetas ;
ChunkMetas . reserve ( ChunkCount );
for ( short i = 0 ; i < ChunkCount ; i ++ )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkZ );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , PrimaryBitmap );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , AddBitmap );
2013-08-30 16:38:24 +02:00
ChunkMetas . push_back ( sChunkMeta ( ChunkX , ChunkZ , PrimaryBitmap , AddBitmap ));
2013-07-29 12:13:03 +01:00
}
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_MAP_CHUNK_BULK from the server:" );
2015-01-21 14:15:35 +01:00
Log ( " ChunkCount = %u" , ChunkCount );
Log ( " Compressed size = %u (0x%x)" , CompressedSize , CompressedSize );
2013-07-29 12:13:03 +01:00
Log ( " IsSkyLightSent = %s" , IsSkyLightSent ? "true" : "false" );
2017-12-23 12:49:08 +00:00
2013-08-30 16:38:24 +02:00
// Log individual chunk coords:
int idx = 0 ;
for ( sChunkMetas :: iterator itr = ChunkMetas . begin (), end = ChunkMetas . end (); itr != end ; ++ itr , ++ idx )
{
Log ( " [%d]: [%d, %d], primary bitmap 0x%02x, add bitmap 0x%02x" ,
idx , itr -> m_ChunkX , itr -> m_ChunkZ , itr -> m_PrimaryBitmap , itr -> m_AddBitmap
);
} // for itr - ChunkMetas[]
2013-07-29 12:13:03 +01:00
// TODO: Save the compressed data into a file for later analysis
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerMultiBlockChange ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkZ );
2015-01-21 14:15:35 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , NumBlocks );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , DataSize );
2013-07-29 12:13:03 +01:00
AString BlockChangeData ;
if ( ! m_ServerBuffer . ReadString ( BlockChangeData , DataSize ))
{
return false ;
}
Log ( "Received a PACKET_MULTI_BLOCK_CHANGE packet from the server:" );
Log ( " Chunk = [%d, %d]" , ChunkX , ChunkZ );
2015-01-21 14:15:35 +01:00
Log ( " NumBlocks = %u" , NumBlocks );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerNamedSoundEffect ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , SoundName );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , Volume );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_NAMED_SOUND_EFFECT from the server:" );
Log ( " SoundName = \" %s \" " , SoundName . c_str ());
2013-10-29 22:06:15 +01:00
Log ( " Pos = %s" , PrintableAbsIntTriplet ( PosX , PosY , PosZ , 8 ). c_str ());
2013-07-29 12:13:03 +01:00
Log ( " Volume = %f" , Volume );
2015-03-21 13:00:20 +01:00
Log ( " Pitch = %u" , Pitch );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerPlayerAbilities ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Flags );
2013-07-29 12:13:03 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , FlyingSpeed );
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , WalkingSpeed );
Log ( "Received a PACKET_PLAYER_ABILITIES from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " Flags = %u (0x%02x)" , Flags , Flags );
2013-07-29 12:13:03 +01:00
Log ( " FlyingSpeed = %f" , FlyingSpeed );
Log ( " WalkingSpeed = %f" , WalkingSpeed );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerPlayerAnimation ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , PlayerID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , AnimationID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_PLAYER_ANIMATION from the server:" );
2013-10-29 22:06:15 +01:00
Log ( " PlayerID: %u (0x%x)" , PlayerID , PlayerID );
2015-03-21 13:00:20 +01:00
Log ( " Animation: %u" , AnimationID );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerPlayerListItem ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , PlayerName );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBool , bool , IsOnline );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , Ping );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_PLAYERLIST_ITEM from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " PlayerName = \" %s \" (%s)" , PlayerName . c_str (), IsOnline ? "online" : "offline" );
2013-07-29 12:13:03 +01:00
Log ( " Ping = %d" , Ping );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerPlayerPositionLook ( 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 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , Pitch );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBool , bool , IsOnGround );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_PLAYER_POSITION_LOOK from the server" );
// TODO: list packet contents
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerPluginMessage ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , ChannelName );
2015-01-21 14:15:35 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , Length );
2013-07-29 12:13:03 +01:00
AString Data ;
if ( ! m_ServerBuffer . ReadString ( Data , Length ))
{
return false ;
}
Log ( "Received a PACKET_PLUGIN_MESSAGE from the server" );
Log ( " ChannelName = \" %s \" " , ChannelName . c_str ());
2015-01-21 14:15:35 +01:00
DataLog ( Data . data (), Length , " Data: %u bytes" , Length );
2013-10-29 22:06:15 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerRespawn ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , Dimension );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Difficulty );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , GameMode );
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , LevelType );
Log ( "Received a respawn packet from the server:" );
Log ( " Dimension = %d" , Dimension );
2015-03-21 13:00:20 +01:00
Log ( " Difficulty = %u" , Difficulty );
Log ( " GameMode = %u" , GameMode );
2013-10-29 22:06:15 +01:00
Log ( " LevelType = \" %s \" " , LevelType . c_str ());
COPY_TO_CLIENT ();
2013-07-29 12:13:03 +01:00
return true ;
}
bool cConnection :: HandleServerSetExperience ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , ExperienceBar );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , Level );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , TotalExperience );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_SET_EXPERIENCE from the server:" );
Log ( " ExperienceBar = %.05f" , ExperienceBar );
2015-03-21 13:00:20 +01:00
Log ( " Level = %u" , Level );
Log ( " TotalExperience = %u" , TotalExperience );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerSetSlot ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , SlotNum );
2013-07-29 12:13:03 +01:00
AString Item ;
if ( ! ParseSlot ( m_ServerBuffer , Item ))
{
return false ;
}
Log ( "Received a PACKET_SET_SLOT from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " WindowID = %u" , WindowID );
Log ( " SlotNum = %u" , SlotNum );
2013-07-29 12:13:03 +01:00
Log ( " Item = %s" , Item . c_str ());
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerSlotSelect ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , SlotNum );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_SLOT_SELECT from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " SlotNum = %u" , SlotNum );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerSoundEffect ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , EffectID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , Data );
HANDLE_SERVER_PACKET_READ ( ReadBool , bool , NoVolumeDecrease );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_SOUND_EFFECT from the server:" );
Log ( " EffectID = %d" , EffectID );
Log ( " Pos = {%d, %d, %d}" , PosX , PosY , PosZ );
Log ( " Data = %d" , Data );
2015-03-21 13:00:20 +01:00
Log ( " NoVolumeDecrease = %s" , NoVolumeDecrease ? "true" : "false" );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
2013-10-29 22:06:15 +01:00
bool cConnection :: HandleServerSpawnExperienceOrbs ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , Count );
2013-10-29 22:06:15 +01:00
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 ());
2015-03-21 13:00:20 +01:00
Log ( " Count = %u" , Count );
2013-10-29 22:06:15 +01:00
COPY_TO_CLIENT ();
return true ;
}
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleServerSpawnMob ( void )
{
2013-11-07 17:13:25 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , EntityID );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , MobType );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , HeadYaw );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , VelocityX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , VelocityY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , VelocityZ );
2013-07-29 12:13:03 +01:00
AString Metadata ;
if ( ! ParseMetadata ( m_ServerBuffer , Metadata ))
{
return false ;
}
AString HexDump ;
CreateHexDump ( HexDump , Metadata . data (), Metadata . size (), 32 );
Log ( "Received a PACKET_SPAWN_MOB from the server:" );
2013-11-07 17:13:25 +01:00
Log ( " EntityID = %u (0x%x)" , EntityID , EntityID );
2015-03-21 13:00:20 +01:00
Log ( " MobType = %u (0x%x)" , MobType , MobType );
2013-09-04 20:42:37 +02:00
Log ( " Pos = %s" , PrintableAbsIntTriplet ( PosX , PosY , PosZ ). c_str ());
2015-03-21 13:00:20 +01:00
Log ( " Angles = [%u, %u, %u]" , Yaw , Pitch , HeadYaw );
2013-09-04 20:42:37 +02:00
Log ( " Velocity = %s" , PrintableAbsIntTriplet ( VelocityX , VelocityY , VelocityZ , 8000 ). c_str ());
2015-03-21 13:00:20 +01:00
auto len = static_cast < unsigned > ( Metadata . length ());
Log ( " Metadata, length = %u (0x%x): \n %s" , len , len , HexDump . c_str ());
2013-07-29 12:13:03 +01:00
LogMetadata ( Metadata , 4 );
COPY_TO_CLIENT ();
return true ;
}
2014-04-14 18:50:44 +02:00
struct sSpawnData
{
AString m_Name ;
AString m_Value ;
AString m_Signature ;
sSpawnData ( const AString & a_Name , const AString & a_Value , const AString & a_Signature ) :
m_Name ( a_Name ),
m_Value ( a_Value ),
m_Signature ( a_Signature )
{
}
};
typedef std :: vector < sSpawnData > sSpawnDatas ;
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleServerSpawnNamedEntity ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , EntityUUID );
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , EntityName );
2014-04-14 18:24:44 +02:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , DataCount );
2014-04-14 18:50:44 +02:00
sSpawnDatas Data ;
2014-04-14 18:24:44 +02:00
for ( UInt32 i = 0 ; i < DataCount ; i ++ )
{
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Name )
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Value )
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Signature )
2014-04-14 18:50:44 +02:00
Data . push_back ( sSpawnData ( Name , Value , Signature ));
2014-04-14 18:24:44 +02:00
}
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , SelectedItem );
2013-07-29 12:13:03 +01:00
AString Metadata ;
if ( ! ParseMetadata ( m_ServerBuffer , Metadata ))
{
return false ;
}
AString HexDump ;
CreateHexDump ( HexDump , Metadata . data (), Metadata . size (), 32 );
Log ( "Received a PACKET_SPAWN_NAMED_ENTITY from the server:" );
2013-10-29 22:06:15 +01:00
Log ( " EntityID = %u (0x%x)" , EntityID , EntityID );
2013-11-10 22:54:58 +01:00
Log ( " UUID = \" %s \" " , EntityUUID . c_str ());
Log ( " Name = \" %s \" " , EntityName . c_str ());
2014-04-14 18:24:44 +02:00
Log ( " NumData = %u" , DataCount );
2014-04-14 18:50:44 +02:00
for ( sSpawnDatas :: const_iterator itr = Data . begin (), end = Data . end (); itr != end ; ++ itr )
2014-04-14 18:24:44 +02:00
{
Log ( " Name = \" %s \" , Value = \" %s \" , Signature = \" %s \" " ,
itr -> m_Name . c_str (), itr -> m_Value . c_str (), itr -> m_Signature . c_str ()
);
} // for itr - Data[]
2013-09-04 20:42:37 +02:00
Log ( " Pos = %s" , PrintableAbsIntTriplet ( PosX , PosY , PosZ ). c_str ());
2015-03-21 13:00:20 +01:00
Log ( " Rotation = <yaw %u, pitch %u>" , Yaw , Pitch );
Log ( " SelectedItem = %u" , SelectedItem );
auto len = static_cast < unsigned > ( Metadata . length ());
Log ( " Metadata, length = %u (0x%x): \n %s" , len , len , HexDump . c_str ());
2013-07-29 12:13:03 +01:00
LogMetadata ( Metadata , 4 );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerSpawnObjectVehicle ( void )
{
#ifdef _DEBUG
// DEBUG:
// This packet is still troublesome when DataIndicator != 0
AString Buffer ;
m_ServerBuffer . ResetRead ();
m_ServerBuffer . ReadAll ( Buffer );
m_ServerBuffer . ResetRead ();
2013-11-03 00:01:56 +01:00
UInt32 PacketLen , PacketType ;
m_ServerBuffer . ReadVarInt ( PacketLen );
m_ServerBuffer . ReadVarInt ( PacketType );
2013-07-29 12:13:03 +01:00
if ( Buffer . size () > 128 )
{
// Only log up to 128 bytes
Buffer . erase ( 128 , AString :: npos );
}
2015-03-21 13:00:20 +01:00
DataLog ( Buffer . data (), Buffer . size (), "Buffer while parsing the PACKET_SPAWN_OBJECT_VEHICLE packet (%u bytes):" , static_cast < unsigned > ( Buffer . size ()));
2013-07-29 12:13:03 +01:00
#endif // _DEBUG
2017-12-23 12:49:08 +00:00
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , ObjType );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , DataIndicator );
2013-07-29 12:13:03 +01:00
AString ExtraData ;
2015-03-21 13:00:20 +01:00
Int16 VelocityX = 0 ;
Int16 VelocityY = 0 ;
Int16 VelocityZ = 0 ;
2013-07-29 12:13:03 +01:00
if ( DataIndicator != 0 )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , SpeedX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , SpeedY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , SpeedZ );
2013-07-29 12:13:03 +01:00
VelocityX = SpeedX ; VelocityY = SpeedY ; VelocityZ = SpeedZ ; // Speed vars are local to this scope, but we need them available later
/*
// This doesn't seem to work - for a falling block I'm getting no extra data at all
int ExtraLen = 0;
switch (ObjType)
{
case OBJECT_FALLING_BLOCK: ExtraLen = 4; break; // int: BlockType | (BlockMeta << 12)
case OBJECT_ARROW:
case OBJECT_SNOWBALL:
case OBJECT_EGG:
case OBJECT_EYE_OF_ENDER:
case OBJECT_DRAGON_EGG:
case OBJECT_FISHING_FLOAT:
{
ExtraLen = 4; break; // int: EntityID of the thrower
}
// TODO: Splash potions
}
if ((ExtraLen > 0) && !m_ServerBuffer.ReadString(ExtraData, ExtraLen))
{
return false;
}
*/
}
Log ( "Received a PACKET_SPAWN_OBJECT_VEHICLE from the server:" );
2013-10-29 22:06:15 +01:00
Log ( " EntityID = %u (0x%x)" , EntityID , EntityID );
2015-03-21 13:00:20 +01:00
Log ( " ObjType = %u (0x%x)" , ObjType , ObjType );
2013-09-04 20:42:37 +02:00
Log ( " Pos = %s" , PrintableAbsIntTriplet ( PosX , PosY , PosZ ). c_str ());
2015-03-21 13:00:20 +01:00
Log ( " Rotation = <yaw %u, pitch %u>" , Yaw , Pitch );
Log ( " DataIndicator = %u (0x%x)" , DataIndicator , DataIndicator );
2013-07-29 12:13:03 +01:00
if ( DataIndicator != 0 )
{
2013-09-04 20:42:37 +02:00
Log ( " Velocity = %s" , PrintableAbsIntTriplet ( VelocityX , VelocityY , VelocityZ , 8000 ). c_str ());
2015-03-21 13:00:20 +01:00
DataLog ( ExtraData . data (), ExtraData . size (), " ExtraData size = %u:" , static_cast < unsigned > ( ExtraData . size ()));
2013-07-29 12:13:03 +01:00
}
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerSpawnPainting ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , ImageName );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , Direction );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_SPAWN_PAINTING from the server:" );
2013-10-29 22:06:15 +01:00
Log ( " EntityID = %u" , EntityID );
2013-07-29 12:13:03 +01:00
Log ( " ImageName = \" %s \" " , ImageName . c_str ());
2013-09-04 20:42:37 +02:00
Log ( " Pos = %s" , PrintableAbsIntTriplet ( PosX , PosY , PosZ ). c_str ());
2013-07-29 12:13:03 +01:00
Log ( " Direction = %d" , Direction );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerSpawnPickup ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
2013-07-29 12:13:03 +01:00
AString ItemDesc ;
if ( ! ParseSlot ( m_ServerBuffer , ItemDesc ))
{
return false ;
}
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , PosZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Yaw );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Roll );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_SPAWN_PICKUP from the server:" );
Log ( " EntityID = %d" , EntityID );
Log ( " Item = %s" , ItemDesc . c_str ());
2013-09-04 20:42:37 +02:00
Log ( " Pos = %s" , PrintableAbsIntTriplet ( PosX , PosY , PosZ ). c_str ());
2015-03-21 13:00:20 +01:00
Log ( " Angles = [%u, %u, %u]" , Yaw , Pitch , Roll );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
2013-10-29 22:06:15 +01:00
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 ;
}
2013-10-28 23:05:53 +01:00
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 ());
2017-12-23 12:49:08 +00:00
2013-10-28 23:05:53 +01:00
// Modify the response to show that it's being proto-proxied:
2013-12-15 20:41:35 +01:00
const char DescSearch [] = " \" description \" :{ \" text \" : \" " ;
size_t idx = Response . find ( DescSearch );
2013-10-28 23:05:53 +01:00
if ( idx != AString :: npos )
{
2013-12-15 20:41:35 +01:00
Response . assign ( Response . substr ( 0 , idx + sizeof ( DescSearch ) - 1 ) + "ProtoProxy: " + Response . substr ( idx + sizeof ( DescSearch ) - 1 ));
2013-10-28 23:05:53 +01:00
}
2015-03-21 13:00:20 +01:00
else
{
Log ( "Cannot find the description json element, ProtoProxy signature not inserted" );
}
2014-01-08 17:17:37 +01:00
cByteBuffer Packet ( Response . size () + 50 );
2015-03-22 23:09:23 +01:00
Packet . WriteVarInt32 ( 0 ); // Packet type - status response
2013-10-28 23:05:53 +01:00
Packet . WriteVarUTF8String ( Response );
AString Pkt ;
Packet . ReadAll ( Pkt );
2014-01-08 17:17:37 +01:00
cByteBuffer ToClient ( Response . size () + 50 );
2013-10-28 23:05:53 +01:00
ToClient . WriteVarUTF8String ( Pkt );
CLIENTSEND ( ToClient );
return true ;
}
2013-07-31 14:32:05 +02:00
bool cConnection :: HandleServerTabCompletion ( void )
{
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , NumResults );
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Results );
2013-07-31 14:32:05 +02:00
Log ( "Received a PACKET_TAB_COMPLETION from the server, results given:" );
// Parse the zero-terminated list of results:
size_t len = Results . size ();
size_t last = 0 ;
for ( size_t i = 0 ; i < len ; i ++ )
{
if ( Results [ i ] == 0 )
{
Log ( " \" %s \" " , Results . substr ( last , i - last ). c_str ());
last = i + 1 ;
}
}
2013-07-31 14:35:48 +02:00
if ( last < len )
{
Log ( " \" %s \" " , Results . substr ( last , len - last ). c_str ());
}
2013-07-31 14:32:05 +02:00
COPY_TO_CLIENT ();
return true ;
}
2013-07-29 12:13:03 +01:00
bool cConnection :: HandleServerTimeUpdate ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , WorldAge );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , TimeOfDay );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_TIME_UPDATE from the server" );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerUpdateHealth ( void )
{
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , Health );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , Food );
2013-07-29 12:13:03 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , Saturation );
Log ( "Received a PACKET_UPDATE_HEALTH from the server" );
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerUpdateSign ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , BlockY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockZ );
2013-10-29 22:06:15 +01:00
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 );
2013-07-29 12:13:03 +01:00
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 ());
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerUpdateTileEntity ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockX );
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , BlockY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BlockZ );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Action );
2017-12-23 12:49:08 +00:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , DataLength );
2014-01-19 00:55:08 +00:00
2013-07-29 12:13:03 +01:00
AString Data ;
if (( DataLength > 0 ) && ! m_ServerBuffer . ReadString ( Data , DataLength ))
{
return false ;
}
Log ( "Received a PACKET_UPDATE_TILE_ENTITY from the server:" );
Log ( " Block = {%d, %d, %d}" , BlockX , BlockY , BlockZ );
2015-03-21 13:00:20 +01:00
Log ( " Action = %u" , Action );
DataLog ( Data . data (), Data . size (), " Data (%u bytes)" , DataLength );
2014-01-19 00:55:08 +00:00
// Save metadata to a file:
AString fnam ;
2015-01-21 14:15:35 +01:00
Printf ( fnam , "%s_tile_%08x.nbt" , m_LogNameBase . c_str (), m_ItemIdx ++ );
2014-01-19 00:55:08 +00:00
FILE * f = fopen ( fnam . c_str (), "wb" );
2017-12-22 18:25:46 +00:00
if ( f != nullptr )
2014-01-19 00:55:08 +00:00
{
fwrite ( Data . data (), 1 , Data . size (), f );
fclose ( f );
Log ( "(saved to file \" %s \" )" , fnam . c_str ());
}
2013-10-29 22:06:15 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerUseBed ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BedX );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , BedY );
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , BedZ );
2013-10-29 22:06:15 +01:00
Log ( "Received a use bed packet from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " EntityID = %u" , EntityID );
Log ( " Bed = {%d, %u, %d}" , BedX , BedY , BedZ );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerWindowClose ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_WINDOW_CLOSE from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " WindowID = %u" , WindowID );
2013-07-29 12:13:03 +01:00
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerWindowContents ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , NumSlots );
2013-07-29 12:13:03 +01:00
Log ( "Received a PACKET_WINDOW_CONTENTS from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " WindowID = %u" , WindowID );
Log ( " NumSlots = %u" , NumSlots );
2013-07-29 12:13:03 +01:00
AStringVector Items ;
2015-03-21 13:00:20 +01:00
for ( UInt16 i = 0 ; i < NumSlots ; i ++ )
2013-07-29 12:13:03 +01:00
{
AString Item ;
if ( ! ParseSlot ( m_ServerBuffer , Item ))
{
return false ;
}
2015-03-21 13:00:20 +01:00
Log ( " %u: %s" , i , Item . c_str ());
2013-07-29 12:13:03 +01:00
}
COPY_TO_CLIENT ();
return true ;
}
bool cConnection :: HandleServerWindowOpen ( void )
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowType );
2013-10-29 22:06:15 +01:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Title );
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , NumSlots );
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , UseProvidedTitle );
UInt32 HorseEntityID = 0 ;
2013-07-29 12:13:03 +01:00
if ( WindowType == 11 ) // Horse / Donkey / Mule
{
2015-03-21 13:00:20 +01:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , intHorseInt );
2013-10-29 22:06:15 +01:00
HorseEntityID = intHorseInt ;
2013-07-29 12:13:03 +01:00
}
Log ( "Received a PACKET_WINDOW_OPEN from the server:" );
2015-03-21 13:00:20 +01:00
Log ( " WindowID = %u" , WindowID );
Log ( " WindowType = %u (0x%02x)" , WindowType , WindowType );
Log ( " Title = \" %s \" , Use = %u" , Title . c_str (), UseProvidedTitle );
Log ( " NumSlots = %u" , NumSlots );
2013-07-29 12:13:03 +01:00
if ( WindowType == 11 )
{
2015-03-21 13:00:20 +01:00
Log ( " HorseEntityID = %u (0x%08x)" , HorseEntityID , HorseEntityID );
2013-07-29 12:13:03 +01:00
}
COPY_TO_CLIENT ();
return true ;
}
2013-10-29 22:55:00 +01:00
bool cConnection :: HandleServerUnknownPacket ( UInt32 a_PacketType , UInt32 a_PacketLen , UInt32 a_PacketReadSoFar )
{
AString Data ;
2013-11-02 17:46:37 +01:00
ASSERT ( a_PacketLen >= a_PacketReadSoFar );
2013-10-29 22:55:00 +01:00
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 ;
}
2013-07-29 12:13:03 +01:00
bool cConnection :: ParseSlot ( cByteBuffer & a_Buffer , AString & a_ItemDesc )
{
short ItemType ;
2015-03-21 13:00:20 +01:00
if ( ! a_Buffer . ReadBEInt16 ( ItemType ))
2013-07-29 12:13:03 +01:00
{
return false ;
}
if ( ItemType <= 0 )
{
a_ItemDesc = "<empty>" ;
return true ;
}
if ( ! a_Buffer . CanReadBytes ( 5 ))
{
return false ;
}
2015-03-21 13:00:20 +01:00
Int8 ItemCount ;
Int16 ItemDamage ;
2015-01-21 14:15:35 +01:00
UInt16 MetadataLength ;
2015-03-21 13:00:20 +01:00
a_Buffer . ReadBEInt8 ( ItemCount ); // We already know we can read these bytes - we checked before.
a_Buffer . ReadBEInt16 ( ItemDamage );
2015-01-21 14:15:35 +01:00
a_Buffer . ReadBEUInt16 ( MetadataLength );
2013-07-29 12:13:03 +01:00
Printf ( a_ItemDesc , "%d:%d * %d" , ItemType , ItemDamage , ItemCount );
if ( MetadataLength <= 0 )
{
return true ;
}
AString Metadata ;
Metadata . resize ( MetadataLength );
2015-01-21 14:15:35 +01:00
if ( ! a_Buffer . ReadBuf ( const_cast < char *> ( Metadata . data ()), MetadataLength ))
2013-07-29 12:13:03 +01:00
{
return false ;
}
AString MetaHex ;
CreateHexDump ( MetaHex , Metadata . data (), Metadata . size (), 16 );
2015-01-21 14:15:35 +01:00
AppendPrintf ( a_ItemDesc , "; %u bytes of meta: \n %s" , MetadataLength , MetaHex . c_str ());
2013-07-29 12:13:03 +01:00
// Save metadata to a file:
AString fnam ;
Printf ( fnam , "%s_item_%08x.nbt" , m_LogNameBase . c_str (), m_ItemIdx ++ );
FILE * f = fopen ( fnam . c_str (), "wb" );
2017-12-22 18:25:46 +00:00
if ( f != nullptr )
2013-07-29 12:13:03 +01:00
{
fwrite ( Metadata . data (), 1 , Metadata . size (), f );
fclose ( f );
AppendPrintf ( a_ItemDesc , " \n (saved to file \" %s \" )" , fnam . c_str ());
}
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
return true ;
}
bool cConnection :: ParseMetadata ( cByteBuffer & a_Buffer , AString & a_Metadata )
{
2015-03-21 13:00:20 +01:00
UInt8 x ;
if ( ! a_Buffer . ReadBEUInt8 ( x ))
2013-07-29 12:13:03 +01:00
{
return false ;
}
2015-01-21 14:15:35 +01:00
a_Metadata . push_back ( static_cast < char > ( x ));
2013-07-29 12:13:03 +01:00
while ( x != 0x7f )
{
2015-01-21 14:15:35 +01:00
// int Index = static_cast<unsigned>(x) & 0x1f; // Lower 5 bits = index
int Type = static_cast < unsigned > ( x ) >> 5 ; // Upper 3 bits = type
// Get the length of the data for this item:
UInt32 Length = 0 ;
2013-07-29 12:13:03 +01:00
switch ( Type )
{
2014-01-25 19:19:37 +01:00
case 0 : Length = 1 ; break ; // Byte
2013-07-29 12:13:03 +01:00
case 1 : Length = 2 ; break ; // short
case 2 : Length = 4 ; break ; // int
case 3 : Length = 4 ; break ; // float
2013-12-05 12:20:37 +01:00
case 4 : // UTF-8 string with VarInt length
2013-07-29 12:13:03 +01:00
{
2013-12-05 12:20:37 +01:00
UInt32 Len ;
2015-01-21 14:15:35 +01:00
int rs = static_cast < int > ( a_Buffer . GetReadableSpace ());
2013-12-05 12:20:37 +01:00
if ( ! a_Buffer . ReadVarInt ( Len ))
2013-07-29 12:13:03 +01:00
{
return false ;
}
2015-01-21 14:15:35 +01:00
rs = rs - static_cast < int > ( a_Buffer . GetReadableSpace ());
2013-12-05 12:20:37 +01:00
cByteBuffer LenBuf ( 8 );
2015-03-22 23:09:23 +01:00
LenBuf . WriteVarInt32 ( Len );
2013-12-05 12:20:37 +01:00
AString VarLen ;
LenBuf . ReadAll ( VarLen );
a_Metadata . append ( VarLen );
2013-07-29 12:13:03 +01:00
Length = Len ;
break ;
}
2015-01-21 14:15:35 +01:00
case 5 : // Item, in "slot" format
2013-07-29 12:13:03 +01:00
{
2015-01-21 14:15:35 +01:00
size_t Before = a_Buffer . GetReadableSpace ();
2013-07-29 12:13:03 +01:00
AString ItemDesc ;
if ( ! ParseSlot ( a_Buffer , ItemDesc ))
{
return false ;
}
2015-01-21 14:15:35 +01:00
size_t After = a_Buffer . GetReadableSpace ();
2013-07-29 12:13:03 +01:00
a_Buffer . ResetRead ();
a_Buffer . SkipRead ( a_Buffer . GetReadableSpace () - Before );
2015-01-21 14:15:35 +01:00
Length = static_cast < UInt32 > ( Before - After );
2013-07-29 12:13:03 +01:00
break ;
}
case 6 : Length = 12 ; break ; // 3 * int
2013-11-07 17:13:25 +01:00
case 7 :
2013-07-29 12:13:03 +01:00
default :
{
ASSERT ( ! "Unknown metadata type" );
break ;
}
} // switch (Type)
2015-01-21 14:15:35 +01:00
// Read the data in this item:
2013-07-29 12:13:03 +01:00
AString data ;
if ( ! a_Buffer . ReadString ( data , Length ))
{
return false ;
}
a_Metadata . append ( data );
2015-03-21 13:00:20 +01:00
if ( ! a_Buffer . ReadBEUInt8 ( x ))
2013-07-29 12:13:03 +01:00
{
return false ;
}
2015-01-21 14:15:35 +01:00
a_Metadata . push_back ( static_cast < char > ( x ));
2013-07-29 12:13:03 +01:00
} // while (x != 0x7f)
return true ;
}
void cConnection :: LogMetadata ( const AString & a_Metadata , size_t a_IndentCount )
{
AString Indent ( a_IndentCount , ' ' );
2015-01-21 14:15:35 +01:00
size_t pos = 0 ;
2013-07-29 12:13:03 +01:00
while ( a_Metadata [ pos ] != 0x7f )
{
2015-01-21 14:15:35 +01:00
unsigned Index = static_cast < unsigned > ( static_cast < unsigned char > ( a_Metadata [ pos ])) & 0x1f ; // Lower 5 bits = index
unsigned Type = static_cast < unsigned > ( static_cast < unsigned char > ( a_Metadata [ pos ])) >> 5 ; // Upper 3 bits = type
2014-03-12 09:49:37 -07:00
// int Length = 0;
2013-07-29 12:13:03 +01:00
switch ( Type )
{
case 0 :
{
2015-03-21 13:00:20 +01:00
Log ( "%sbyte[%u] = %u" , Indent . c_str (), Index , static_cast < unsigned char > ( a_Metadata [ pos + 1 ]));
2013-07-29 12:13:03 +01:00
pos += 1 ;
break ;
}
case 1 :
{
2015-01-21 14:15:35 +01:00
Log ( "%sshort[%u] = %d" , Indent . c_str (), Index , ( a_Metadata [ pos + 1 ] << 8 ) | a_Metadata [ pos + 2 ]);
2013-07-29 12:13:03 +01:00
pos += 2 ;
break ;
}
case 2 :
{
2015-01-21 14:15:35 +01:00
Log ( "%sint[%u] = %d" , Indent . c_str (), Index , ( a_Metadata [ pos + 1 ] << 24 ) | ( a_Metadata [ pos + 2 ] << 16 ) | ( a_Metadata [ pos + 3 ] << 8 ) | a_Metadata [ pos + 4 ]);
2013-07-29 12:13:03 +01:00
pos += 4 ;
break ;
}
case 3 :
{
2015-01-21 14:15:35 +01:00
Log ( "%sfloat[%u] = 0x%x" , Indent . c_str (), Index , ( a_Metadata [ pos + 1 ] << 24 ) | ( a_Metadata [ pos + 2 ] << 16 ) | ( a_Metadata [ pos + 3 ] << 8 ) | a_Metadata [ pos + 4 ]);
2013-07-29 12:13:03 +01:00
pos += 4 ;
break ;
}
2013-12-05 12:20:37 +01:00
case 4 : // UTF-8 string with VarInt length
2013-07-29 12:13:03 +01:00
{
2013-12-05 12:20:37 +01:00
cByteBuffer bb ( 10 );
2015-01-21 14:15:35 +01:00
size_t RestLen = a_Metadata . size () - pos - 1 ;
2013-12-05 12:20:37 +01:00
if ( RestLen > 8 )
{
RestLen = 8 ;
}
bb . Write ( a_Metadata . data () + pos + 1 , RestLen );
UInt32 Length ;
2015-01-21 14:15:35 +01:00
size_t rs = bb . GetReadableSpace ();
2014-12-21 22:51:17 +01:00
if ( ! bb . ReadVarInt ( Length ))
{
Log ( "Invalid metadata value, was supposed to be a varint-prefixed string, but cannot read the varint" );
break ;
}
2013-12-05 12:20:37 +01:00
rs = rs - bb . GetReadableSpace ();
2015-01-21 14:15:35 +01:00
Log ( "%sstring[%u] = \" %*s \" " , Indent . c_str (), Index , Length , a_Metadata . c_str () + pos + rs + 1 );
2013-12-05 12:20:37 +01:00
pos += Length + rs + 2 ;
2013-07-29 12:13:03 +01:00
break ;
}
case 5 :
{
2015-01-21 14:15:35 +01:00
size_t BytesLeft = a_Metadata . size () - pos - 1 ;
2013-07-29 12:13:03 +01:00
cByteBuffer bb ( BytesLeft );
bb . Write ( a_Metadata . data () + pos + 1 , BytesLeft );
AString ItemDesc ;
if ( ! ParseSlot ( bb , ItemDesc ))
{
ASSERT ( ! "Cannot parse item description from metadata" );
return ;
}
2015-01-21 14:15:35 +01:00
// size_t After = bb.GetReadableSpace();
size_t BytesConsumed = BytesLeft - bb . GetReadableSpace ();
2013-07-29 12:13:03 +01:00
2015-01-21 14:15:35 +01:00
Log ( "%sslot[%u] = %s (%u bytes)" , Indent . c_str (), Index , ItemDesc . c_str (), static_cast < unsigned > ( BytesConsumed ));
2013-07-29 12:13:03 +01:00
pos += BytesConsumed ;
break ;
}
case 6 :
{
2017-12-23 12:49:08 +00:00
Log ( "%spos[%u] = <%d, %d, %d>" , Indent . c_str (), Index ,
2013-07-29 12:13:03 +01:00
( a_Metadata [ pos + 1 ] << 24 ) | ( a_Metadata [ pos + 2 ] << 16 ) | ( a_Metadata [ pos + 3 ] << 8 ) | a_Metadata [ pos + 4 ],
( a_Metadata [ pos + 5 ] << 24 ) | ( a_Metadata [ pos + 6 ] << 16 ) | ( a_Metadata [ pos + 7 ] << 8 ) | a_Metadata [ pos + 8 ],
( a_Metadata [ pos + 9 ] << 24 ) | ( a_Metadata [ pos + 10 ] << 16 ) | ( a_Metadata [ pos + 11 ] << 8 ) | a_Metadata [ pos + 12 ]
);
pos += 12 ;
break ;
}
default :
{
ASSERT ( ! "Unknown metadata type" );
break ;
}
} // switch (Type)
pos += 1 ;
} // while (x != 0x7f)
}
void cConnection :: SendEncryptionKeyResponse ( const AString & a_ServerPublicKey , const AString & a_Nonce )
{
// Generate the shared secret and encrypt using the server's public key
2014-01-25 19:19:37 +01:00
Byte SharedSecret [ 16 ];
Byte EncryptedSecret [ 128 ];
2013-07-29 12:13:03 +01:00
memset ( SharedSecret , 0 , sizeof ( SharedSecret )); // Use all zeroes for the initial secret
2014-05-01 20:20:12 +02:00
cCryptoKey PubKey ( a_ServerPublicKey );
2014-01-28 23:53:33 +01:00
int res = PubKey . Encrypt ( SharedSecret , sizeof ( SharedSecret ), EncryptedSecret , sizeof ( EncryptedSecret ));
if ( res < 0 )
{
Log ( "Shared secret encryption failed: %d (0x%x)" , res , res );
return ;
}
2014-01-25 19:19:37 +01:00
m_ServerEncryptor . Init ( SharedSecret , SharedSecret );
m_ServerDecryptor . Init ( SharedSecret , SharedSecret );
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
// Encrypt the nonce:
2014-01-25 19:19:37 +01:00
Byte EncryptedNonce [ 128 ];
2016-08-24 21:45:03 +02:00
res = PubKey . Encrypt ( reinterpret_cast < const Byte *> ( a_Nonce . data ()), a_Nonce . size (), EncryptedNonce , sizeof ( EncryptedNonce ));
2014-01-28 23:53:33 +01:00
if ( res < 0 )
{
Log ( "Nonce encryption failed: %d (0x%x)" , res , res );
return ;
}
2017-12-23 12:49:08 +00:00
2013-07-29 12:13:03 +01:00
// Send the packet to the server:
Log ( "Sending PACKET_ENCRYPTION_KEY_RESPONSE to the SERVER" );
cByteBuffer ToServer ( 1024 );
2015-03-21 13:00:20 +01:00
ToServer . WriteBEUInt8 ( 0x01 ); // To server: Encryption key response
ToServer . WriteBEUInt16 ( static_cast < UInt16 > ( sizeof ( EncryptedSecret )));
2014-01-25 19:19:37 +01:00
ToServer . WriteBuf ( EncryptedSecret , sizeof ( EncryptedSecret ));
2015-03-21 13:00:20 +01:00
ToServer . WriteBEUInt16 ( static_cast < UInt16 > ( sizeof ( EncryptedNonce )));
2014-01-25 19:19:37 +01:00
ToServer . WriteBuf ( EncryptedNonce , sizeof ( EncryptedNonce ));
2015-03-21 13:00:20 +01:00
DataLog ( EncryptedSecret , sizeof ( EncryptedSecret ), "Encrypted secret (%u bytes)" , static_cast < unsigned > ( sizeof ( EncryptedSecret )));
DataLog ( EncryptedNonce , sizeof ( EncryptedNonce ), "Encrypted nonce (%u bytes)" , static_cast < unsigned > ( sizeof ( EncryptedNonce )));
2014-01-28 23:53:33 +01:00
cByteBuffer Len ( 5 );
2015-03-22 23:09:23 +01:00
Len . WriteVarInt32 ( static_cast < UInt32 > ( ToServer . GetReadableSpace ()));
2014-01-28 23:53:33 +01:00
SERVERSEND ( Len );
2013-07-29 12:13:03 +01:00
SERVERSEND ( ToServer );
2013-10-29 15:47:22 +01:00
m_ServerState = csEncryptedUnderstood ;
m_IsServerEncrypted = true ;
2013-07-29 12:13:03 +01:00
}