2017-09-19 04:34:08 -04:00
2013-07-29 07:13:03 -04: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 10:00:06 -04:00
# include "mbedTLS++/CryptoKey.h"
2015-03-22 10:00:51 -04:00
# include "../../src/Logger.h"
2013-07-29 07:13:03 -04:00
2018-01-03 12:41:16 -05:00
# include "fmt/printf.h"
2013-09-08 05:27:49 -04:00
# ifdef _WIN32
# include <direct.h> // For _mkdir()
# endif
2013-07-29 07:13:03 -04:00
2017-12-23 07:49:08 -05:00
/** When defined, the following macro causes a sleep after each parsed packet (DEBUG-mode only) */
2013-09-19 15:35:33 -04:00
// #define SLEEP_AFTER_PACKET
# if defined(_DEBUG) && defined(SLEEP_AFTER_PACKET)
2013-07-29 07:13:03 -04: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 10:47:22 -04:00
# define CLIENTENCRYPTSEND(...) SendData(m_ClientSocket, __VA_ARGS__, "Client") // The client conn is always unencrypted
2013-07-29 07:13:03 -04: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 08:15:35 -05:00
case csWaitingForEncryption : \
2013-07-29 07:13:03 -04:00
{ \
break ; \
} \
2015-01-21 08:15:35 -05:00
\
2013-07-29 07:13:03 -04:00
} \
DebugSleep ( 50 ) ; \
}
# define HANDLE_CLIENT_READ(Proc) \
{ \
2013-10-29 17:55:00 -04:00
if ( ! Proc ) \
2013-07-29 07:13:03 -04: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 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
# define HANDLE_SERVER_READ(Proc) \
{ \
2013-10-29 17:55:00 -04:00
if ( ! Proc ) \
2013-07-29 07:13:03 -04:00
{ \
m_ServerBuffer . ResetRead ( ) ; \
return true ; \
} \
}
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
typedef unsigned char Byte ;
2015-01-21 05:24:32 -05: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 07:13:03 -04:00
2015-01-21 05:24:32 -05:00
AString PrintableAbsIntTriplet ( int a_X , int a_Y , int a_Z , double a_Divisor )
2013-09-04 14:42:37 -04:00
{
return Printf ( " <%d, %d, %d> ~ {%.02f, %.02f, %.02f} " ,
a_X , a_Y , a_Z ,
2016-08-24 15:45:03 -04: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 14:42:37 -04:00
) ;
}
2014-01-17 07:15:54 -05:00
struct sCoords
{
int x , y , z ;
2017-12-23 07:49:08 -05:00
2014-01-17 07:15:54 -05: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 07:49:08 -05:00
////////////////////////////////////////////////////////////////////////////////
2013-07-29 07:13:03 -04:00
// cConnection:
cConnection : : cConnection ( SOCKET a_ClientSocket , cServer & a_Server ) :
m_ItemIdx ( 0 ) ,
2017-12-22 13:25:46 -05:00
m_LogFile ( nullptr ) ,
2013-07-29 07:13:03 -04:00
m_Server ( a_Server ) ,
m_ClientSocket ( a_ClientSocket ) ,
m_ServerSocket ( - 1 ) ,
2014-11-23 09:22:05 -05:00
m_BeginTick ( std : : chrono : : steady_clock : : now ( ) ) ,
2013-07-29 07:13:03 -04:00
m_ClientState ( csUnencrypted ) ,
m_ServerState ( csUnencrypted ) ,
m_Nonce ( 0 ) ,
m_ClientBuffer ( 1024 KiB ) ,
m_ServerBuffer ( 1024 KiB ) ,
2013-10-28 18:05:53 -04:00
m_HasClientPinged ( false ) ,
2013-10-29 10:47:22 -04:00
m_ServerProtocolState ( - 1 ) ,
m_ClientProtocolState ( - 1 ) ,
m_IsServerEncrypted ( false )
2013-07-29 07:13:03 -04:00
{
2013-09-08 05:27:49 -04:00
// Create the Logs subfolder, if not already created:
# if defined(_WIN32)
_mkdir ( " Logs " ) ;
# else
mkdir ( " Logs " , 0777 ) ;
# endif
2016-08-24 15:45:03 -04:00
Printf ( m_LogNameBase , " Logs/Log_%d_%d " , static_cast < int > ( time ( nullptr ) ) , static_cast < int > ( a_ClientSocket ) ) ;
2013-07-29 07:13:03 -04:00
AString fnam ( m_LogNameBase ) ;
fnam . append ( " .log " ) ;
2015-03-21 08:00:20 -04:00
# ifdef _WIN32
fopen_s ( & m_LogFile , fnam . c_str ( ) , " w " ) ;
# else
m_LogFile = fopen ( fnam . c_str ( ) , " w " ) ;
# endif
2013-07-29 07:13:03 -04: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 15:35:33 -04:00
2013-07-29 07:13:03 -04:00
while ( true )
{
fd_set ReadFDs ;
FD_ZERO ( & ReadFDs ) ;
FD_SET ( m_ServerSocket , & ReadFDs ) ;
FD_SET ( m_ClientSocket , & ReadFDs ) ;
2014-01-24 12:51:15 -05:00
SOCKET MaxSocket = std : : max ( m_ServerSocket , m_ClientSocket ) ;
2017-12-22 13:25:46 -05:00
int res = select ( MaxSocket + 1 , & ReadFDs , nullptr , nullptr , nullptr ) ;
2013-07-29 07:13:03 -04:00
if ( res < = 0 )
{
2014-01-17 07:15:54 -05:00
printf ( " select() failed: %d; aborting client " , SocketError ) ;
2013-07-29 07:13:03 -04: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 12:41:16 -05:00
void cConnection : : Log ( const char * a_Format , fmt : : ArgList a_Args )
2013-07-29 07:13:03 -04:00
{
2018-01-03 12:41:16 -05:00
fmt : : MemoryWriter FullMsg ;
fmt : : printf ( FullMsg , " [%5.3f] " , GetRelativeTime ( ) ) ;
fmt : : printf ( FullMsg , a_Format , a_Args ) ;
fmt : : printf ( FullMsg , " \n " ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
// Log to file:
cCSLock Lock ( m_CSLog ) ;
fputs ( FullMsg . c_str ( ) , m_LogFile ) ;
2013-12-05 06:20:37 -05:00
# ifdef _DEBUG
fflush ( m_LogFile ) ;
# endif // _DEBUG
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
// Log to screen:
// std::cout << FullMsg;
}
2018-01-03 12:41:16 -05:00
void cConnection : : DataLog ( const void * a_Data , size_t a_Size , const char * a_Format , fmt : : ArgList a_Args )
2013-07-29 07:13:03 -04:00
{
2018-01-03 12:41:16 -05:00
fmt : : MemoryWriter FullMsg ;
fmt : : printf ( FullMsg , " [%5.3f] " , GetRelativeTime ( ) ) ;
fmt : : printf ( FullMsg , a_Format , a_Args ) ;
2013-07-29 07:13:03 -04:00
AString Hex ;
2018-01-03 12:41:16 -05:00
fmt : : printf ( FullMsg , " \n %s \n " , CreateHexDump ( Hex , a_Data , a_Size , 16 ) ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
// Log to file:
cCSLock Lock ( m_CSLog ) ;
fputs ( FullMsg . c_str ( ) , m_LogFile ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04: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 15:45:03 -04:00
if ( connect ( m_ServerSocket , reinterpret_cast < const sockaddr * > ( & localhost ) , sizeof ( localhost ) ) ! = 0 )
2013-07-29 07:13:03 -04:00
{
2014-01-17 07:15:54 -05:00
printf ( " connection to server failed: %d \n " , SocketError ) ;
2013-07-29 07:13:03 -04:00
return false ;
}
Log ( " Connected to SERVER " ) ;
return true ;
}
bool cConnection : : RelayFromServer ( void )
{
char Buffer [ 64 KiB ] ;
2015-01-21 05:24:32 -05: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 07:13:03 -04:00
if ( res < = 0 )
{
2014-01-17 07:15:54 -05:00
Log ( " Server closed the socket: %d; %d; aborting connection " , res , SocketError ) ;
2013-07-29 07:13:03 -04:00
return false ;
}
2017-12-23 07:49:08 -05:00
2015-01-21 05:24:32 -05:00
DataLog ( Buffer , static_cast < size_t > ( res ) , " Received %d bytes from the SERVER " , res ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
switch ( m_ServerState )
{
case csUnencrypted :
case csWaitingForEncryption :
{
return DecodeServersPackets ( Buffer , res ) ;
}
case csEncryptedUnderstood :
{
2015-01-21 05:24:32 -05:00
m_ServerDecryptor . ProcessData ( reinterpret_cast < Byte * > ( Buffer ) , reinterpret_cast < Byte * > ( Buffer ) , static_cast < size_t > ( res ) ) ;
2015-01-21 08:15:35 -05:00
DataLog ( Buffer , static_cast < size_t > ( res ) , " Decrypted %d bytes from the SERVER " , res ) ;
2013-07-29 07:13:03 -04:00
return DecodeServersPackets ( Buffer , res ) ;
}
case csEncryptedUnknown :
{
2015-01-21 05:24:32 -05:00
m_ServerDecryptor . ProcessData ( reinterpret_cast < Byte * > ( Buffer ) , reinterpret_cast < Byte * > ( Buffer ) , static_cast < size_t > ( res ) ) ;
2015-01-21 08:15:35 -05:00
DataLog ( Buffer , static_cast < size_t > ( res ) , " Decrypted %d bytes from the SERVER " , res ) ;
2015-01-21 05:24:32 -05:00
return CLIENTSEND ( Buffer , static_cast < size_t > ( res ) ) ;
2013-07-29 07:13:03 -04:00
}
}
2014-04-04 02:55:48 -04:00
ASSERT ( ! " Unhandled server state while relaying from server " ) ;
return false ;
2013-07-29 07:13:03 -04:00
}
bool cConnection : : RelayFromClient ( void )
{
char Buffer [ 64 KiB ] ;
2015-01-21 05:24:32 -05: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 07:13:03 -04:00
if ( res < = 0 )
{
2014-01-17 07:15:54 -05:00
Log ( " Client closed the socket: %d; %d; aborting connection " , res , SocketError ) ;
2013-07-29 07:13:03 -04:00
return false ;
}
2017-12-23 07:49:08 -05:00
2015-01-21 08:15:35 -05:00
DataLog ( Buffer , static_cast < size_t > ( res ) , " Received %d bytes from the CLIENT " , res ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
switch ( m_ClientState )
{
case csUnencrypted :
case csWaitingForEncryption :
{
return DecodeClientsPackets ( Buffer , res ) ;
}
case csEncryptedUnderstood :
{
return DecodeClientsPackets ( Buffer , res ) ;
}
case csEncryptedUnknown :
{
2015-01-21 08:15:35 -05:00
DataLog ( Buffer , static_cast < size_t > ( res ) , " Decrypted %d bytes from the CLIENT " , res ) ;
2015-01-21 05:24:32 -05: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 07:13:03 -04:00
}
}
2014-04-04 02:55:48 -04:00
ASSERT ( ! " Unhandled server state while relaying from client " ) ;
return false ;
2013-07-29 07:13:03 -04:00
}
double cConnection : : GetRelativeTime ( void )
{
2014-12-07 09:46:27 -05: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 07:13:03 -04:00
}
2014-04-04 02:55:48 -04:00
bool cConnection : : SendData ( SOCKET a_Socket , const char * a_Data , size_t a_Size , const char * a_Peer )
2013-07-29 07:13:03 -04:00
{
2015-01-21 05:24:32 -05:00
DataLog ( a_Data , a_Size , " Sending data to %s, %u bytes " , a_Peer , static_cast < unsigned > ( a_Size ) ) ;
2017-12-23 07:49:08 -05:00
2015-01-21 08:15:35 -05: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 07:13:03 -04:00
if ( res < = 0 )
{
2014-01-17 07:15:54 -05:00
Log ( " %s closed the socket: %d, %d; aborting connection " , a_Peer , res , SocketError ) ;
2013-07-29 07:13:03 -04: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 11:37:15 -04: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 07:13:03 -04:00
{
DataLog ( a_Data , a_Size , " Encrypting %d bytes to %s " , a_Size , a_Peer ) ;
2016-08-24 15:45:03 -04:00
const Byte * Data = reinterpret_cast < const Byte * > ( a_Data ) ;
2013-07-29 07:13:03 -04:00
while ( a_Size > 0 )
{
2014-01-25 13:19:37 -05:00
Byte Buffer [ 64 KiB ] ;
2014-03-10 15:21:18 -04:00
size_t NumBytes = ( a_Size > sizeof ( Buffer ) ) ? sizeof ( Buffer ) : a_Size ;
2013-07-29 07:13:03 -04:00
a_Encryptor . ProcessData ( Buffer , Data , NumBytes ) ;
2016-08-24 15:45:03 -04:00
bool res = SendData ( a_Socket , reinterpret_cast < const char * > ( Buffer ) , NumBytes , a_Peer ) ;
2013-07-29 07:13:03 -04:00
if ( ! res )
{
return false ;
}
Data + = NumBytes ;
a_Size - = NumBytes ;
}
return true ;
}
2014-04-29 11:37:15 -04:00
bool cConnection : : SendEncryptedData ( SOCKET a_Socket , cAesCfb128Encryptor & a_Encryptor , cByteBuffer & a_Data , const char * a_Peer )
2013-07-29 07:13:03 -04: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 05:24:32 -05:00
if ( ! m_ClientBuffer . Write ( a_Data , static_cast < size_t > ( a_Size ) ) )
2013-07-29 07:13:03 -04:00
{
Log ( " Too much queued data for the server, aborting connection " ) ;
return false ;
}
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
while ( m_ClientBuffer . CanReadBytes ( 1 ) )
{
2013-10-28 18:05:53 -04:00
UInt32 PacketLen ;
if (
! m_ClientBuffer . ReadVarInt ( PacketLen ) | |
! m_ClientBuffer . CanReadBytes ( PacketLen )
)
2013-07-29 07:13:03 -04:00
{
2013-10-28 18:05:53 -04:00
// Not a complete packet yet
break ;
}
2013-10-29 17:55:00 -04:00
UInt32 PacketType , PacketReadSoFar ;
2015-01-21 05:24:32 -05:00
PacketReadSoFar = static_cast < UInt32 > ( m_ClientBuffer . GetReadableSpace ( ) ) ;
2013-10-28 18:05:53 -04:00
VERIFY ( m_ClientBuffer . ReadVarInt ( PacketType ) ) ;
2013-10-29 17:55:00 -04:00
PacketReadSoFar - = m_ClientBuffer . GetReadableSpace ( ) ;
2015-01-21 05:24:32 -05: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 10:47:22 -04:00
switch ( m_ClientProtocolState )
2013-10-28 18:05:53 -04:00
{
case - 1 :
{
// No initial handshake received yet
switch ( PacketType )
{
2013-10-29 17:55:00 -04:00
case 0x00 : HANDLE_CLIENT_READ ( HandleClientHandshake ( ) ) ; break ;
default : HANDLE_CLIENT_READ ( HandleClientUnknownPacket ( PacketType , PacketLen , PacketReadSoFar ) ) ; break ;
2013-10-28 18:05:53 -04:00
}
break ;
} // case -1
2017-12-23 07:49:08 -05:00
2013-10-28 18:05:53 -04:00
case 1 :
{
// Status query
switch ( PacketType )
{
2013-10-29 17:55:00 -04: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 18:05:53 -04:00
}
break ;
}
2017-12-23 07:49:08 -05:00
2013-10-28 18:05:53 -04:00
case 2 :
{
2013-10-29 10:47:22 -04:00
// Login
switch ( PacketType )
{
2013-10-29 17:55:00 -04: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 10:47:22 -04:00
}
break ;
}
2017-12-23 07:49:08 -05:00
2013-10-29 10:47:22 -04:00
case 3 :
{
// Game:
2013-10-28 18:05:53 -04:00
switch ( PacketType )
{
2013-10-29 17:55:00 -04: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 18:05:53 -04:00
}
break ;
2013-10-29 17:06:15 -04:00
} // case 3 - Game
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
default :
{
2013-10-29 17:55:00 -04: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 18:05:53 -04:00
} // switch (m_ProtocolState)
2013-07-29 07:13:03 -04:00
m_ClientBuffer . CommitRead ( ) ;
2013-10-28 18:05:53 -04:00
} // while (true)
2013-07-29 07:13:03 -04:00
return true ;
}
bool cConnection : : DecodeServersPackets ( const char * a_Data , int a_Size )
{
2015-01-21 08:15:35 -05:00
if ( ! m_ServerBuffer . Write ( a_Data , static_cast < size_t > ( a_Size ) ) )
2013-07-29 07:13:03 -04:00
{
Log ( " Too much queued data for the client, aborting connection " ) ;
return false ;
}
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04: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 07:49:08 -05:00
2013-10-28 18:05:53 -04:00
while ( true )
2013-07-29 07:13:03 -04:00
{
2013-10-28 18:05:53 -04:00
UInt32 PacketLen ;
if (
! m_ServerBuffer . ReadVarInt ( PacketLen ) | |
! m_ServerBuffer . CanReadBytes ( PacketLen )
)
{
// Not a complete packet yet
2013-11-02 12:46:37 -04:00
m_ServerBuffer . ResetRead ( ) ;
2013-10-28 18:05:53 -04:00
break ;
}
2013-11-02 19:01:56 -04: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 17:55:00 -04:00
UInt32 PacketType , PacketReadSoFar ;
2015-01-21 08:15:35 -05:00
PacketReadSoFar = static_cast < UInt32 > ( m_ServerBuffer . GetReadableSpace ( ) ) ;
2013-10-28 18:05:53 -04:00
VERIFY ( m_ServerBuffer . ReadVarInt ( PacketType ) ) ;
2013-10-29 17:55:00 -04:00
PacketReadSoFar - = m_ServerBuffer . GetReadableSpace ( ) ;
2013-10-28 18:05:53 -04: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 07:13:03 -04:00
LogFlush ( ) ;
2013-10-29 10:47:22 -04:00
switch ( m_ServerProtocolState )
2013-07-29 07:13:03 -04:00
{
2013-10-28 18:05:53 -04:00
case - 1 :
{
Log ( " Receiving data from the server without an initial handshake message! " ) ;
2013-10-29 17:55:00 -04:00
HANDLE_SERVER_READ ( HandleServerUnknownPacket ( PacketType , PacketLen , PacketReadSoFar ) ) ;
2013-10-28 18:05:53 -04:00
break ;
}
2017-12-23 07:49:08 -05:00
2013-10-28 18:05:53 -04:00
case 1 :
{
// Status query:
switch ( PacketType )
{
2013-10-29 17:55:00 -04: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 18:05:53 -04:00
}
break ;
}
2017-12-23 07:49:08 -05:00
2013-10-28 18:05:53 -04:00
case 2 :
{
2013-10-29 10:47:22 -04:00
// Login:
2013-10-28 18:05:53 -04:00
switch ( PacketType )
{
2013-10-29 17:55:00 -04: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 10:47:22 -04:00
}
break ;
}
2017-12-23 07:49:08 -05:00
2013-10-29 10:47:22 -04:00
case 3 :
{
// Game:
switch ( PacketType )
{
2013-10-29 17:55:00 -04: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 18:05:53 -04:00
} // switch (PacketType)
break ;
2013-10-29 17:06:15 -04:00
} // case 3 - Game
2017-12-23 07:49:08 -05:00
2013-10-28 18:05:53 -04:00
// TODO: Move this elsewhere
2013-07-29 07:13:03 -04:00
default :
{
2013-10-29 17:55:00 -04: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 07:13:03 -04:00
}
2013-10-28 18:05:53 -04:00
} // switch (m_ProtocolState)
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
m_ServerBuffer . CommitRead ( ) ;
} // while (CanReadBytes(1))
return true ;
}
2017-12-23 07:49:08 -05:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 10:47:22 -04: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 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , ServerPort ) ;
2013-10-29 10:47:22 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadVarInt , UInt32 , NextState ) ;
m_ClientBuffer . CommitRead ( ) ;
2017-12-23 07:49:08 -05:00
2013-10-29 10:47:22 -04:00
Log ( " Received an initial handshake packet from the client: " ) ;
Log ( " ProtocolVersion = %u " , ProtocolVersion ) ;
Log ( " ServerHost = \" %s \" " , ServerHost . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
Log ( " ServerPort = %u " , ServerPort ) ;
2013-10-29 10:47:22 -04:00
Log ( " NextState = %u " , NextState ) ;
// Send the same packet to the server, but with our port:
cByteBuffer Packet ( 512 ) ;
2015-03-22 18:09:23 -04:00
Packet . WriteVarInt32 ( 0 ) ; // Packet type - initial handshake
Packet . WriteVarInt32 ( ProtocolVersion ) ;
2013-10-29 10:47:22 -04:00
Packet . WriteVarUTF8String ( ServerHost ) ;
2015-03-21 08:00:20 -04:00
Packet . WriteBEUInt16 ( m_Server . GetConnectPort ( ) ) ;
2015-03-22 18:09:23 -04:00
Packet . WriteVarInt32 ( NextState ) ;
2013-10-29 10:47:22 -04:00
AString Pkt ;
Packet . ReadAll ( Pkt ) ;
cByteBuffer ToServer ( 512 ) ;
ToServer . WriteVarUTF8String ( Pkt ) ;
SERVERSEND ( ToServer ) ;
2017-12-23 07:49:08 -05:00
2015-03-21 08:00:20 -04:00
m_ClientProtocolState = static_cast < int > ( NextState ) ;
m_ServerProtocolState = static_cast < int > ( NextState ) ;
2017-12-23 07:49:08 -05:00
2013-10-29 10:47:22 -04:00
return true ;
}
2017-12-23 07:49:08 -05:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 10:47:22 -04: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 07:49:08 -05:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 10:47:22 -04:00
// packet handling, client-side, game:
2013-07-29 07:13:03 -04:00
bool cConnection : : HandleClientAnimation ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
HANDLE_CLIENT_PACKET_READ ( ReadBEInt8 , Int8 , Animation ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_ANIMATION from the client: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID: %u " , EntityID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Animation: %d " , Animation ) ;
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientBlockDig ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_BLOCK_DIG from the client: " ) ;
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientBlockPlace ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
AString Desc ;
if ( ! ParseSlot ( m_ClientBuffer , Desc ) )
{
return false ;
}
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_BLOCK_PLACE from the client: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " Block = {%d, %u, %d} " , BlockX , BlockY , BlockZ ) ;
Log ( " Face = %u (0x%02x) " , Face , Face ) ;
2013-07-29 07:13:03 -04:00
Log ( " Item = %s " , Desc . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
Log ( " Cursor = <%u, %u, %u> " , CursorX , CursorY , CursorZ ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientChatMessage ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Message ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Statuses ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_CLIENT_STATUSES from the CLIENT: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " Statuses = %u (0x%02x) " , Statuses , Statuses ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientCreativeInventoryAction ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , SlotNum ) ;
2013-07-29 07:13:03 -04:00
AString Item ;
if ( ! ParseSlot ( m_ClientBuffer , Item ) )
{
return false ;
}
Log ( " Received a PACKET_CREATIVE_INVENTORY_ACTION from the client: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " SlotNum = %u " , SlotNum ) ;
2013-07-29 07:13:03 -04:00
Log ( " Item = %s " , Item . c_str ( ) ) ;
COPY_TO_SERVER ( ) ;
return true ;
}
2013-08-25 15:57:12 -04:00
bool cConnection : : HandleClientDisconnect ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Reason ) ;
2013-08-25 15:57:12 -04:00
Log ( " Received a PACKET_DISCONNECT from the client: " ) ;
Log ( " Reason = \" %s \" " , Reason . c_str ( ) ) ;
COPY_TO_SERVER ( ) ;
return true ;
}
2013-07-29 07:13:03 -04:00
bool cConnection : : HandleClientEntityAction ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_ACTION from the client: " ) ;
Log ( " PlayerID = %d " , PlayerID ) ;
2015-03-21 08:00:20 -04:00
Log ( " ActionType = %u " , ActionType ) ;
2013-10-29 17:55:00 -04:00
Log ( " HorseJumpBoost = %d (0x%08x) " , HorseJumpBoost , HorseJumpBoost ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientKeepAlive ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt32 , Int32 , ID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_KEEPALIVE from the client " ) ;
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientLocaleAndView ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Locale ) ;
2015-03-21 08:00:20 -04: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 07:13:03 -04: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 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , Flags ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
Log ( " Flags = %u (0x%02x) " , Flags , Flags ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , OnGround ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_PLAYER_LOOK from the client " ) ;
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientPlayerOnGround ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , OnGround ) ;
2013-07-29 07:13:03 -04: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 17:55:00 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , Stance ) ;
2013-07-29 07:13:03 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , PosZ ) ;
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , IsOnGround ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_PLAYER_POSITION from the client " ) ;
// TODO: list packet contents
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04: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 17:55:00 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEDouble , double , Stance ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , IsOnGround ) ;
2013-07-29 07:13:03 -04: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 17:55:00 -04:00
Log ( " Yaw, Pitch = <%.03f, %.03f> " , Yaw , Pitch ) ;
2013-07-29 07:13:03 -04:00
Log ( " IsOnGround = %s " , IsOnGround ? " true " : " false " ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientPluginMessage ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , ChannelName ) ;
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt16 , UInt16 , Length ) ;
2013-07-29 07:13:03 -04: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 08:15:35 -05:00
DataLog ( Data . data ( ) , Length , " Data: %u bytes " , Length ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientSlotSelect ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEInt16 , Int16 , SlotNum ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_SLOT_SELECT from the client " ) ;
Log ( " SlotNum = %d " , SlotNum ) ;
COPY_TO_SERVER ( ) ;
return true ;
}
2013-10-28 18:05:53 -04: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 08:32:05 -04:00
bool cConnection : : HandleClientTabCompletion ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadVarUTF8String , AString , Query ) ;
2013-07-31 08:32:05 -04: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 07:13:03 -04:00
bool cConnection : : HandleClientUpdateSign ( void )
{
2015-03-21 08:00:20 -04: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 17:06:15 -04: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 07:13:03 -04: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 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , MouseButton ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_USE_ENTITY from the client: " ) ;
Log ( " EntityID = %d " , EntityID ) ;
2015-03-21 08:00:20 -04:00
Log ( " MouseButton = %u " , MouseButton ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientWindowClick ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
AString Item ;
if ( ! ParseSlot ( m_ClientBuffer , Item ) )
{
return false ;
}
Log ( " Received a PACKET_WINDOW_CLICK from the client " ) ;
2015-03-21 08:00:20 -04:00
Log ( " WindowID = %u " , WindowID ) ;
Log ( " SlotNum = %u " , SlotNum ) ;
Log ( " Button = %u, Mode = %u " , Button , Mode ) ;
2013-07-29 07:13:03 -04:00
Log ( " TransactionID = 0x%x " , TransactionID ) ;
Log ( " ClickedItem = %s " , Item . c_str ( ) ) ;
COPY_TO_SERVER ( ) ;
return true ;
}
bool cConnection : : HandleClientWindowClose ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_CLIENT_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_WINDOW_CLOSE from the client: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " WindowID = %u " , WindowID ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_SERVER ( ) ;
return true ;
}
2013-10-29 17:55:00 -04: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 07:49:08 -05:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 10:47:22 -04: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 14:31:08 -05:00
COPY_TO_CLIENT ( ) ;
2013-10-29 10:47:22 -04:00
return true ;
}
bool cConnection : : HandleServerLoginEncryptionKeyRequest ( void )
{
// Read the packet from the server:
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , ServerID ) ;
2015-01-21 08:15:35 -05:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , PublicKeyLength ) ;
2013-10-29 10:47:22 -04:00
AString PublicKey ;
if ( ! m_ServerBuffer . ReadString ( PublicKey , PublicKeyLength ) )
{
return false ;
}
2015-01-21 08:15:35 -05:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , NonceLength ) ;
2013-10-29 10:47:22 -04: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 15:45:03 -04:00
DataLog ( PublicKey . data ( ) , PublicKey . size ( ) , " Public key (%u bytes) " , static_cast < unsigned > ( PublicKey . size ( ) ) ) ;
2017-12-23 07:49:08 -05:00
2013-10-29 10:47:22 -04:00
// Reply to the server:
SendEncryptionKeyResponse ( PublicKey , Nonce ) ;
2017-12-23 07:49:08 -05:00
2013-10-29 10:47:22 -04: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 07:49:08 -05:00
2013-10-29 10:47:22 -04:00
Log ( " Server is now in protocol state Game. " ) ;
m_ServerProtocolState = 3 ;
2017-12-23 07:49:08 -05:00
2013-10-29 10:47:22 -04: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 07:49:08 -05:00
////////////////////////////////////////////////////////////////////////////////
2013-10-29 10:47:22 -04:00
// packet handling, server-side, game:
2013-07-29 07:13:03 -04:00
bool cConnection : : HandleServerAttachEntity ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_ATTACH_ENTITY from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u (0x%x) " , EntityID , EntityID ) ;
Log ( " VehicleID = %u (0x%x) " , VehicleID , VehicleID ) ;
Log ( " IsOnLeash = %s " , IsOnLeash ? " true " : " false " ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerBlockAction ( void )
{
2015-03-21 08:00:20 -04: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 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , BlockID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_BLOCK_ACTION from the server: " ) ;
Log ( " Pos = {%d, %d, %d} " , BlockX , BlockY , BlockZ ) ;
2015-03-21 08:00:20 -04:00
Log ( " Bytes = (%u, %u) == (0x%x, 0x%x) " , Byte1 , Byte2 , Byte1 , Byte2 ) ;
2013-10-29 17:06:15 -04:00
Log ( " BlockID = %u " , BlockID ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerBlockChange ( void )
{
2015-03-21 08:00:20 -04: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 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , BlockType ) ;
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , BlockMeta ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_BLOCK_CHANGE from the server " ) ;
2015-03-21 08:00:20 -04:00
Log ( " Pos = {%d, %u, %d} " , BlockX , BlockY , BlockZ ) ;
Log ( " BlockType = %u (0x%x " , BlockType , BlockType ) ;
Log ( " BlockMeta = %u " , BlockMeta ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerChangeGameState ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Reason ) ;
2013-11-02 15:59:29 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , Data ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_CHANGE_GAME_STATE from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " Reason = %u " , Reason ) ;
2013-11-02 15:59:29 -04:00
Log ( " Data = %f " , Data ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerChatMessage ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Message ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , CollectedID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , CollectorID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_COLLECT_PICKUP from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " CollectedID = %u " , CollectedID ) ;
Log ( " CollectorID = %u " , CollectorID ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerCompass ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04: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 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , NumEntities ) ;
2015-01-21 08:15:35 -05:00
if ( ! m_ServerBuffer . SkipRead ( static_cast < size_t > ( NumEntities ) * 4 ) )
2013-07-29 07:13:03 -04:00
{
return false ;
}
Log ( " Received PACKET_DESTROY_ENTITIES from the server: " ) ;
2015-01-21 08:15:35 -05:00
Log ( " NumEntities = %u " , NumEntities ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntity ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityEquipment ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , SlotNum ) ;
2013-07-29 07:13:03 -04:00
AString Item ;
if ( ! ParseSlot ( m_ServerBuffer , Item ) )
{
return false ;
}
Log ( " Received a PACKET_ENTITY_EQUIPMENT from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
Log ( " SlotNum = %u " , SlotNum ) ;
2013-07-29 07:13:03 -04:00
Log ( " Item = %s " , Item . c_str ( ) ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityHeadLook ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , HeadYaw ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_HEAD_LOOK from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
Log ( " HeadYaw = %u " , HeadYaw ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityLook ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_LOOK from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
Log ( " Yaw = %u " , Yaw ) ;
Log ( " Pitch = %u " , Pitch ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityMetadata ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04: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 07:13:03 -04:00
LogMetadata ( Metadata , 4 ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityProperties ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , Count ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_PROPERTIES from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
Log ( " Count = %u " , Count ) ;
2017-12-23 07:49:08 -05:00
2015-03-21 08:00:20 -04:00
for ( UInt32 i = 0 ; i < Count ; i + + )
2013-07-29 07:13:03 -04:00
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Key ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEDouble , double , Value ) ;
2015-03-21 08:00:20 -04: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 17:06:15 -04:00
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , UUIDHi ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , UUIDLo ) ;
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEDouble , double , DblVal ) ;
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , ByteVal ) ;
2013-10-29 17:06:15 -04:00
Log ( " [%d] = {0x%08llx%08llx, %f, %u} " , j , UUIDHi , UUIDLo , DblVal , ByteVal ) ;
}
2013-07-29 07:13:03 -04:00
} // for i
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityRelativeMove ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_RELATIVE_MOVE from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
2013-09-04 14:42:37 -04:00
Log ( " RelMove = %s " , PrintableAbsIntTriplet ( dx , dy , dz ) . c_str ( ) ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityRelativeMoveLook ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_RELATIVE_MOVE_LOOK from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
2013-09-04 14:42:37 -04:00
Log ( " RelMove = %s " , PrintableAbsIntTriplet ( dx , dy , dz ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
Log ( " Yaw = %u " , Yaw ) ;
Log ( " Pitch = %u " , Pitch ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityStatus ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Status ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_STATUS from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
Log ( " Status = %u (0x%02x) " , Status , Status ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityTeleport ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_TELEPORT from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
2013-10-29 17:06:15 -04:00
Log ( " Pos = %s " , PrintableAbsIntTriplet ( AbsX , AbsY , AbsZ ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
Log ( " Yaw = %u " , Yaw ) ;
Log ( " Pitch = %u " , Pitch ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerEntityVelocity ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_ENTITY_VELOCITY from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
2013-09-04 14:42:37 -04:00
Log ( " Velocity = %s " , PrintableAbsIntTriplet ( VelocityX , VelocityY , VelocityZ , 8000 ) . c_str ( ) ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
2013-09-19 15:51:59 -04:00
}
bool cConnection : : HandleServerExplosion ( void )
{
2015-01-21 08:15:35 -05: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 15:51:59 -04:00
std : : vector < sCoords > Records ;
Records . reserve ( NumRecords ) ;
2015-03-21 08:00:20 -04:00
int PosXI = static_cast < int > ( PosX ) , PosYI = static_cast < int > ( PosY ) , PosZI = static_cast < int > ( PosZ ) ;
2015-01-21 08:15:35 -05:00
for ( UInt32 i = 0 ; i < NumRecords ; i + + )
2013-09-19 15:51:59 -04:00
{
2015-03-21 08:00:20 -04: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 15:51:59 -04: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 08:15:35 -05:00
Log ( " NumRecords = %u " , NumRecords ) ;
for ( UInt32 i = 0 ; i < NumRecords ; i + + )
2013-09-19 15:51:59 -04:00
{
2015-01-21 08:15:35 -05:00
Log ( " Records[%u] = {%d, %d, %d} " , i , Records [ i ] . x , Records [ i ] . y , Records [ i ] . z ) ;
2013-09-19 15:51:59 -04:00
}
Log ( " Player motion = <%.02f, %.02f, %.02f> " , PlayerMotionX , PlayerMotionY , PlayerMotionZ ) ;
COPY_TO_CLIENT ( ) ;
return true ;
2013-07-29 07:13:03 -04:00
}
bool cConnection : : HandleServerIncrementStatistic ( void )
{
// 0xc8
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , StatisticID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , Amount ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_INCREMENT_STATISTIC from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " StatisticID = %u (0x%x) " , StatisticID , StatisticID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Amount = %d " , Amount ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
2013-10-29 17:06:15 -04:00
bool cConnection : : HandleServerJoinGame ( void )
{
2015-03-21 08:00:20 -04: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 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , LevelType ) ;
Log ( " Received a PACKET_LOGIN from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
Log ( " GameMode = %u " , GameMode ) ;
Log ( " Dimension = %u " , Dimension ) ;
Log ( " Difficulty = %u " , Difficulty ) ;
Log ( " MaxPlayers = %u " , MaxPlayers ) ;
2013-10-29 17:06:15 -04:00
Log ( " LevelType = \" %s \" " , LevelType . c_str ( ) ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
2013-07-29 07:13:03 -04:00
bool cConnection : : HandleServerKeepAlive ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , PingID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_KEEP_ALIVE from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " ID = %u " , PingID ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( )
return true ;
}
bool cConnection : : HandleServerKick ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Reason ) ;
2013-07-29 07:13:03 -04: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 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
// Split by NULL chars (StringSplit() won't work here):
size_t Last = 0 ;
2013-09-08 05:12:34 -04:00
size_t Len = Reason . size ( ) ;
for ( size_t i = 0 ; i < Len ; i + + )
2013-07-29 07:13:03 -04:00
{
if ( Reason [ i ] = = 0 )
{
Split . push_back ( Reason . substr ( Last , i - Last ) ) ;
Last = i + 1 ;
}
}
2013-09-08 05:12:34 -04:00
if ( Last < Len )
{
Split . push_back ( Reason . substr ( Last ) ) ;
}
2017-12-23 07:49:08 -05:00
2013-09-08 05:12:34 -04:00
if ( Split . size ( ) = = 6 )
2013-07-29 07:13:03 -04:00
{
2013-09-08 05:12:34 -04: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 07:49:08 -05:00
2013-09-08 05:12:34 -04: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 11:08:40 -04:00
auto ReasonBE16 = UTF8ToRawBEUTF16 ( Reason ) ;
2013-09-08 05:12:34 -04:00
AString PacketStart ( " \xff " ) ;
2015-09-29 11:08:40 -04:00
PacketStart . push_back ( static_cast < char > ( ReasonBE16 . size ( ) / 256 ) ) ;
PacketStart . push_back ( static_cast < char > ( ReasonBE16 . size ( ) % 256 ) ) ;
2013-09-08 05:12:34 -04:00
CLIENTSEND ( PacketStart . data ( ) , PacketStart . size ( ) ) ;
2015-09-29 11:08:40 -04:00
CLIENTSEND ( reinterpret_cast < const char * > ( ReasonBE16 . data ( ) ) , ReasonBE16 . size ( ) * sizeof ( char16_t ) ) ;
2013-09-08 05:12:34 -04:00
return true ;
2013-07-29 07:13:03 -04: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 08:00:20 -04: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 08:15:35 -05:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , CompressedSize ) ;
2013-07-29 07:13:03 -04: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 08:15:35 -05:00
Log ( " Compressed size = %u (0x%x) " , CompressedSize , CompressedSize ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
// TODO: Save the compressed data into a file for later analysis
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( )
return true ;
}
bool cConnection : : HandleServerMapChunkBulk ( void )
{
2015-01-21 08:15:35 -05: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 07:13:03 -04:00
AString CompressedData ;
if ( ! m_ServerBuffer . ReadString ( CompressedData , CompressedSize ) )
{
return false ;
}
2017-12-23 07:49:08 -05:00
2013-08-30 10:38:24 -04: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 08:00:20 -04: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 10:38:24 -04:00
ChunkMetas . push_back ( sChunkMeta ( ChunkX , ChunkZ , PrimaryBitmap , AddBitmap ) ) ;
2013-07-29 07:13:03 -04:00
}
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_MAP_CHUNK_BULK from the server: " ) ;
2015-01-21 08:15:35 -05:00
Log ( " ChunkCount = %u " , ChunkCount ) ;
Log ( " Compressed size = %u (0x%x) " , CompressedSize , CompressedSize ) ;
2013-07-29 07:13:03 -04:00
Log ( " IsSkyLightSent = %s " , IsSkyLightSent ? " true " : " false " ) ;
2017-12-23 07:49:08 -05:00
2013-08-30 10:38:24 -04: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 07:13:03 -04:00
// TODO: Save the compressed data into a file for later analysis
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerMultiBlockChange ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkX ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEInt32 , Int32 , ChunkZ ) ;
2015-01-21 08:15:35 -05:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , NumBlocks ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , DataSize ) ;
2013-07-29 07:13:03 -04: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 08:15:35 -05:00
Log ( " NumBlocks = %u " , NumBlocks ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerNamedSoundEffect ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , SoundName ) ;
2015-03-21 08:00:20 -04: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 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEFloat , float , Volume ) ;
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Pitch ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_NAMED_SOUND_EFFECT from the server: " ) ;
Log ( " SoundName = \" %s \" " , SoundName . c_str ( ) ) ;
2013-10-29 17:06:15 -04:00
Log ( " Pos = %s " , PrintableAbsIntTriplet ( PosX , PosY , PosZ , 8 ) . c_str ( ) ) ;
2013-07-29 07:13:03 -04:00
Log ( " Volume = %f " , Volume ) ;
2015-03-21 08:00:20 -04:00
Log ( " Pitch = %u " , Pitch ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerPlayerAbilities ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , Flags ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
Log ( " Flags = %u (0x%02x) " , Flags , Flags ) ;
2013-07-29 07:13:03 -04:00
Log ( " FlyingSpeed = %f " , FlyingSpeed ) ;
Log ( " WalkingSpeed = %f " , WalkingSpeed ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerPlayerAnimation ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , PlayerID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , AnimationID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_PLAYER_ANIMATION from the server: " ) ;
2013-10-29 17:06:15 -04:00
Log ( " PlayerID: %u (0x%x) " , PlayerID , PlayerID ) ;
2015-03-21 08:00:20 -04:00
Log ( " Animation: %u " , AnimationID ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerPlayerListItem ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , PlayerName ) ;
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBool , bool , IsOnline ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , Ping ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_PLAYERLIST_ITEM from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " PlayerName = \" %s \" (%s) " , PlayerName . c_str ( ) , IsOnline ? " online " : " offline " ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBool , bool , IsOnGround ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_PLAYER_POSITION_LOOK from the server " ) ;
// TODO: list packet contents
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerPluginMessage ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , ChannelName ) ;
2015-01-21 08:15:35 -05:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , Length ) ;
2013-07-29 07:13:03 -04: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 08:15:35 -05:00
DataLog ( Data . data ( ) , Length , " Data: %u bytes " , Length ) ;
2013-10-29 17:06:15 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerRespawn ( void )
{
2015-03-21 08:00:20 -04: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 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , LevelType ) ;
Log ( " Received a respawn packet from the server: " ) ;
Log ( " Dimension = %d " , Dimension ) ;
2015-03-21 08:00:20 -04:00
Log ( " Difficulty = %u " , Difficulty ) ;
Log ( " GameMode = %u " , GameMode ) ;
2013-10-29 17:06:15 -04:00
Log ( " LevelType = \" %s \" " , LevelType . c_str ( ) ) ;
COPY_TO_CLIENT ( ) ;
2013-07-29 07:13:03 -04:00
return true ;
}
bool cConnection : : HandleServerSetExperience ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_SET_EXPERIENCE from the server: " ) ;
Log ( " ExperienceBar = %.05f " , ExperienceBar ) ;
2015-03-21 08:00:20 -04:00
Log ( " Level = %u " , Level ) ;
Log ( " TotalExperience = %u " , TotalExperience ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerSetSlot ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , SlotNum ) ;
2013-07-29 07:13:03 -04:00
AString Item ;
if ( ! ParseSlot ( m_ServerBuffer , Item ) )
{
return false ;
}
Log ( " Received a PACKET_SET_SLOT from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " WindowID = %u " , WindowID ) ;
Log ( " SlotNum = %u " , SlotNum ) ;
2013-07-29 07:13:03 -04:00
Log ( " Item = %s " , Item . c_str ( ) ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerSlotSelect ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , SlotNum ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_SLOT_SELECT from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " SlotNum = %u " , SlotNum ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerSoundEffect ( void )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04: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 08:00:20 -04:00
Log ( " NoVolumeDecrease = %s " , NoVolumeDecrease ? " true " : " false " ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
2013-10-29 17:06:15 -04:00
bool cConnection : : HandleServerSpawnExperienceOrbs ( void )
{
2015-03-21 08:00:20 -04: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 17:06:15 -04: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 08:00:20 -04:00
Log ( " Count = %u " , Count ) ;
2013-10-29 17:06:15 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
2013-07-29 07:13:03 -04:00
bool cConnection : : HandleServerSpawnMob ( void )
{
2013-11-07 11:13:25 -05:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , EntityID ) ;
2015-03-21 08:00:20 -04: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 07:13:03 -04: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 11:13:25 -05:00
Log ( " EntityID = %u (0x%x) " , EntityID , EntityID ) ;
2015-03-21 08:00:20 -04:00
Log ( " MobType = %u (0x%x) " , MobType , MobType ) ;
2013-09-04 14:42:37 -04:00
Log ( " Pos = %s " , PrintableAbsIntTriplet ( PosX , PosY , PosZ ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
Log ( " Angles = [%u, %u, %u] " , Yaw , Pitch , HeadYaw ) ;
2013-09-04 14:42:37 -04:00
Log ( " Velocity = %s " , PrintableAbsIntTriplet ( VelocityX , VelocityY , VelocityZ , 8000 ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
auto len = static_cast < unsigned > ( Metadata . length ( ) ) ;
Log ( " Metadata, length = %u (0x%x): \n %s " , len , len , HexDump . c_str ( ) ) ;
2013-07-29 07:13:03 -04:00
LogMetadata ( Metadata , 4 ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
2014-04-14 12:50:44 -04: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 07:13:03 -04:00
bool cConnection : : HandleServerSpawnNamedEntity ( void )
{
2013-10-29 17:06:15 -04: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 12:24:44 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , DataCount ) ;
2014-04-14 12:50:44 -04:00
sSpawnDatas Data ;
2014-04-14 12:24:44 -04: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 12:50:44 -04:00
Data . push_back ( sSpawnData ( Name , Value , Signature ) ) ;
2014-04-14 12:24:44 -04:00
}
2015-03-21 08:00:20 -04: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 07:13:03 -04: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 17:06:15 -04:00
Log ( " EntityID = %u (0x%x) " , EntityID , EntityID ) ;
2013-11-10 16:54:58 -05:00
Log ( " UUID = \" %s \" " , EntityUUID . c_str ( ) ) ;
Log ( " Name = \" %s \" " , EntityName . c_str ( ) ) ;
2014-04-14 12:24:44 -04:00
Log ( " NumData = %u " , DataCount ) ;
2014-04-14 12:50:44 -04:00
for ( sSpawnDatas : : const_iterator itr = Data . begin ( ) , end = Data . end ( ) ; itr ! = end ; + + itr )
2014-04-14 12:24:44 -04: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 14:42:37 -04:00
Log ( " Pos = %s " , PrintableAbsIntTriplet ( PosX , PosY , PosZ ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04: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 07:13:03 -04: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-02 19:01:56 -04:00
UInt32 PacketLen , PacketType ;
m_ServerBuffer . ReadVarInt ( PacketLen ) ;
m_ServerBuffer . ReadVarInt ( PacketType ) ;
2013-07-29 07:13:03 -04:00
if ( Buffer . size ( ) > 128 )
{
// Only log up to 128 bytes
Buffer . erase ( 128 , AString : : npos ) ;
}
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
# endif // _DEBUG
2017-12-23 07:49:08 -05:00
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
AString ExtraData ;
2015-03-21 08:00:20 -04:00
Int16 VelocityX = 0 ;
Int16 VelocityY = 0 ;
Int16 VelocityZ = 0 ;
2013-07-29 07:13:03 -04:00
if ( DataIndicator ! = 0 )
{
2015-03-21 08:00:20 -04: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 07:13:03 -04: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 17:06:15 -04:00
Log ( " EntityID = %u (0x%x) " , EntityID , EntityID ) ;
2015-03-21 08:00:20 -04:00
Log ( " ObjType = %u (0x%x) " , ObjType , ObjType ) ;
2013-09-04 14:42:37 -04:00
Log ( " Pos = %s " , PrintableAbsIntTriplet ( PosX , PosY , PosZ ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
Log ( " Rotation = <yaw %u, pitch %u> " , Yaw , Pitch ) ;
Log ( " DataIndicator = %u (0x%x) " , DataIndicator , DataIndicator ) ;
2013-07-29 07:13:03 -04:00
if ( DataIndicator ! = 0 )
{
2013-09-04 14:42:37 -04:00
Log ( " Velocity = %s " , PrintableAbsIntTriplet ( VelocityX , VelocityY , VelocityZ , 8000 ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
DataLog ( ExtraData . data ( ) , ExtraData . size ( ) , " ExtraData size = %u: " , static_cast < unsigned > ( ExtraData . size ( ) ) ) ;
2013-07-29 07:13:03 -04:00
}
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerSpawnPainting ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , EntityID ) ;
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , ImageName ) ;
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_SPAWN_PAINTING from the server: " ) ;
2013-10-29 17:06:15 -04:00
Log ( " EntityID = %u " , EntityID ) ;
2013-07-29 07:13:03 -04:00
Log ( " ImageName = \" %s \" " , ImageName . c_str ( ) ) ;
2013-09-04 14:42:37 -04:00
Log ( " Pos = %s " , PrintableAbsIntTriplet ( PosX , PosY , PosZ ) . c_str ( ) ) ;
2013-07-29 07:13:03 -04:00
Log ( " Direction = %d " , Direction ) ;
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerSpawnPickup ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , EntityID ) ;
2013-07-29 07:13:03 -04:00
AString ItemDesc ;
if ( ! ParseSlot ( m_ServerBuffer , ItemDesc ) )
{
return false ;
}
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
Log ( " Received a PACKET_SPAWN_PICKUP from the server: " ) ;
Log ( " EntityID = %d " , EntityID ) ;
Log ( " Item = %s " , ItemDesc . c_str ( ) ) ;
2013-09-04 14:42:37 -04:00
Log ( " Pos = %s " , PrintableAbsIntTriplet ( PosX , PosY , PosZ ) . c_str ( ) ) ;
2015-03-21 08:00:20 -04:00
Log ( " Angles = [%u, %u, %u] " , Yaw , Pitch , Roll ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
2013-10-29 17:06:15 -04: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 18:05:53 -04: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 07:49:08 -05:00
2013-10-28 18:05:53 -04:00
// Modify the response to show that it's being proto-proxied:
2013-12-15 14:41:35 -05:00
const char DescSearch [ ] = " \" description \" :{ \" text \" : \" " ;
size_t idx = Response . find ( DescSearch ) ;
2013-10-28 18:05:53 -04:00
if ( idx ! = AString : : npos )
{
2013-12-15 14:41:35 -05:00
Response . assign ( Response . substr ( 0 , idx + sizeof ( DescSearch ) - 1 ) + " ProtoProxy: " + Response . substr ( idx + sizeof ( DescSearch ) - 1 ) ) ;
2013-10-28 18:05:53 -04:00
}
2015-03-21 08:00:20 -04:00
else
{
Log ( " Cannot find the description json element, ProtoProxy signature not inserted " ) ;
}
2014-01-08 11:17:37 -05:00
cByteBuffer Packet ( Response . size ( ) + 50 ) ;
2015-03-22 18:09:23 -04:00
Packet . WriteVarInt32 ( 0 ) ; // Packet type - status response
2013-10-28 18:05:53 -04:00
Packet . WriteVarUTF8String ( Response ) ;
AString Pkt ;
Packet . ReadAll ( Pkt ) ;
2014-01-08 11:17:37 -05:00
cByteBuffer ToClient ( Response . size ( ) + 50 ) ;
2013-10-28 18:05:53 -04:00
ToClient . WriteVarUTF8String ( Pkt ) ;
CLIENTSEND ( ToClient ) ;
return true ;
}
2013-07-31 08:32:05 -04:00
bool cConnection : : HandleServerTabCompletion ( void )
{
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarInt , UInt32 , NumResults ) ;
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Results ) ;
2013-07-31 08:32:05 -04: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 08:35:48 -04:00
if ( last < len )
{
Log ( " \" %s \" " , Results . substr ( last , len - last ) . c_str ( ) ) ;
}
2013-07-31 08:32:05 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
2013-07-29 07:13:03 -04:00
bool cConnection : : HandleServerTimeUpdate ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , WorldAge ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt64 , UInt64 , TimeOfDay ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEInt16 , Int16 , Food ) ;
2013-07-29 07:13:03 -04: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 08:00:20 -04: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 17:06:15 -04: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 07:13:03 -04: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 08:00:20 -04: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 07:49:08 -05:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , DataLength ) ;
2014-01-18 19:55:08 -05:00
2013-07-29 07:13:03 -04: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 08:00:20 -04:00
Log ( " Action = %u " , Action ) ;
DataLog ( Data . data ( ) , Data . size ( ) , " Data (%u bytes) " , DataLength ) ;
2014-01-18 19:55:08 -05:00
// Save metadata to a file:
AString fnam ;
2015-01-21 08:15:35 -05:00
Printf ( fnam , " %s_tile_%08x.nbt " , m_LogNameBase . c_str ( ) , m_ItemIdx + + ) ;
2014-01-18 19:55:08 -05:00
FILE * f = fopen ( fnam . c_str ( ) , " wb " ) ;
2017-12-22 13:25:46 -05:00
if ( f ! = nullptr )
2014-01-18 19:55:08 -05:00
{
fwrite ( Data . data ( ) , 1 , Data . size ( ) , f ) ;
fclose ( f ) ;
Log ( " (saved to file \" %s \" ) " , fnam . c_str ( ) ) ;
}
2013-10-29 17:06:15 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerUseBed ( void )
{
2015-03-21 08:00:20 -04: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 17:06:15 -04:00
Log ( " Received a use bed packet from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " EntityID = %u " , EntityID ) ;
Log ( " Bed = {%d, %u, %d} " , BedX , BedY , BedZ ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerWindowClose ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_WINDOW_CLOSE from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " WindowID = %u " , WindowID ) ;
2013-07-29 07:13:03 -04:00
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerWindowContents ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt16 , UInt16 , NumSlots ) ;
2013-07-29 07:13:03 -04:00
Log ( " Received a PACKET_WINDOW_CONTENTS from the server: " ) ;
2015-03-21 08:00:20 -04:00
Log ( " WindowID = %u " , WindowID ) ;
Log ( " NumSlots = %u " , NumSlots ) ;
2013-07-29 07:13:03 -04:00
AStringVector Items ;
2015-03-21 08:00:20 -04:00
for ( UInt16 i = 0 ; i < NumSlots ; i + + )
2013-07-29 07:13:03 -04:00
{
AString Item ;
if ( ! ParseSlot ( m_ServerBuffer , Item ) )
{
return false ;
}
2015-03-21 08:00:20 -04:00
Log ( " %u: %s " , i , Item . c_str ( ) ) ;
2013-07-29 07:13:03 -04:00
}
COPY_TO_CLIENT ( ) ;
return true ;
}
bool cConnection : : HandleServerWindowOpen ( void )
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowID ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , WindowType ) ;
2013-10-29 17:06:15 -04:00
HANDLE_SERVER_PACKET_READ ( ReadVarUTF8String , AString , Title ) ;
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , NumSlots ) ;
HANDLE_SERVER_PACKET_READ ( ReadBEUInt8 , UInt8 , UseProvidedTitle ) ;
UInt32 HorseEntityID = 0 ;
2013-07-29 07:13:03 -04:00
if ( WindowType = = 11 ) // Horse / Donkey / Mule
{
2015-03-21 08:00:20 -04:00
HANDLE_SERVER_PACKET_READ ( ReadBEUInt32 , UInt32 , intHorseInt ) ;
2013-10-29 17:06:15 -04:00
HorseEntityID = intHorseInt ;
2013-07-29 07:13:03 -04:00
}
Log ( " Received a PACKET_WINDOW_OPEN from the server: " ) ;
2015-03-21 08:00:20 -04: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 07:13:03 -04:00
if ( WindowType = = 11 )
{
2015-03-21 08:00:20 -04:00
Log ( " HorseEntityID = %u (0x%08x) " , HorseEntityID , HorseEntityID ) ;
2013-07-29 07:13:03 -04:00
}
COPY_TO_CLIENT ( ) ;
return true ;
}
2013-10-29 17:55:00 -04:00
bool cConnection : : HandleServerUnknownPacket ( UInt32 a_PacketType , UInt32 a_PacketLen , UInt32 a_PacketReadSoFar )
{
AString Data ;
2013-11-02 12:46:37 -04:00
ASSERT ( a_PacketLen > = a_PacketReadSoFar ) ;
2013-10-29 17:55:00 -04: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 07:13:03 -04:00
bool cConnection : : ParseSlot ( cByteBuffer & a_Buffer , AString & a_ItemDesc )
{
short ItemType ;
2015-03-21 08:00:20 -04:00
if ( ! a_Buffer . ReadBEInt16 ( ItemType ) )
2013-07-29 07:13:03 -04:00
{
return false ;
}
if ( ItemType < = 0 )
{
a_ItemDesc = " <empty> " ;
return true ;
}
if ( ! a_Buffer . CanReadBytes ( 5 ) )
{
return false ;
}
2015-03-21 08:00:20 -04:00
Int8 ItemCount ;
Int16 ItemDamage ;
2015-01-21 08:15:35 -05:00
UInt16 MetadataLength ;
2015-03-21 08:00:20 -04:00
a_Buffer . ReadBEInt8 ( ItemCount ) ; // We already know we can read these bytes - we checked before.
a_Buffer . ReadBEInt16 ( ItemDamage ) ;
2015-01-21 08:15:35 -05:00
a_Buffer . ReadBEUInt16 ( MetadataLength ) ;
2013-07-29 07:13:03 -04:00
Printf ( a_ItemDesc , " %d:%d * %d " , ItemType , ItemDamage , ItemCount ) ;
if ( MetadataLength < = 0 )
{
return true ;
}
AString Metadata ;
Metadata . resize ( MetadataLength ) ;
2015-01-21 08:15:35 -05:00
if ( ! a_Buffer . ReadBuf ( const_cast < char * > ( Metadata . data ( ) ) , MetadataLength ) )
2013-07-29 07:13:03 -04:00
{
return false ;
}
AString MetaHex ;
CreateHexDump ( MetaHex , Metadata . data ( ) , Metadata . size ( ) , 16 ) ;
2015-01-21 08:15:35 -05:00
AppendPrintf ( a_ItemDesc , " ; %u bytes of meta: \n %s " , MetadataLength , MetaHex . c_str ( ) ) ;
2013-07-29 07:13:03 -04: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 13:25:46 -05:00
if ( f ! = nullptr )
2013-07-29 07:13:03 -04:00
{
fwrite ( Metadata . data ( ) , 1 , Metadata . size ( ) , f ) ;
fclose ( f ) ;
AppendPrintf ( a_ItemDesc , " \n (saved to file \" %s \" ) " , fnam . c_str ( ) ) ;
}
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
return true ;
}
bool cConnection : : ParseMetadata ( cByteBuffer & a_Buffer , AString & a_Metadata )
{
2015-03-21 08:00:20 -04:00
UInt8 x ;
if ( ! a_Buffer . ReadBEUInt8 ( x ) )
2013-07-29 07:13:03 -04:00
{
return false ;
}
2015-01-21 08:15:35 -05:00
a_Metadata . push_back ( static_cast < char > ( x ) ) ;
2013-07-29 07:13:03 -04:00
while ( x ! = 0x7f )
{
2015-01-21 08:15:35 -05: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 07:13:03 -04:00
switch ( Type )
{
2014-01-25 13:19:37 -05:00
case 0 : Length = 1 ; break ; // Byte
2013-07-29 07:13:03 -04:00
case 1 : Length = 2 ; break ; // short
case 2 : Length = 4 ; break ; // int
case 3 : Length = 4 ; break ; // float
2013-12-05 06:20:37 -05:00
case 4 : // UTF-8 string with VarInt length
2013-07-29 07:13:03 -04:00
{
2013-12-05 06:20:37 -05:00
UInt32 Len ;
2015-01-21 08:15:35 -05:00
int rs = static_cast < int > ( a_Buffer . GetReadableSpace ( ) ) ;
2013-12-05 06:20:37 -05:00
if ( ! a_Buffer . ReadVarInt ( Len ) )
2013-07-29 07:13:03 -04:00
{
return false ;
}
2015-01-21 08:15:35 -05:00
rs = rs - static_cast < int > ( a_Buffer . GetReadableSpace ( ) ) ;
2013-12-05 06:20:37 -05:00
cByteBuffer LenBuf ( 8 ) ;
2015-03-22 18:09:23 -04:00
LenBuf . WriteVarInt32 ( Len ) ;
2013-12-05 06:20:37 -05:00
AString VarLen ;
LenBuf . ReadAll ( VarLen ) ;
a_Metadata . append ( VarLen ) ;
2013-07-29 07:13:03 -04:00
Length = Len ;
break ;
}
2015-01-21 08:15:35 -05:00
case 5 : // Item, in "slot" format
2013-07-29 07:13:03 -04:00
{
2015-01-21 08:15:35 -05:00
size_t Before = a_Buffer . GetReadableSpace ( ) ;
2013-07-29 07:13:03 -04:00
AString ItemDesc ;
if ( ! ParseSlot ( a_Buffer , ItemDesc ) )
{
return false ;
}
2015-01-21 08:15:35 -05:00
size_t After = a_Buffer . GetReadableSpace ( ) ;
2013-07-29 07:13:03 -04:00
a_Buffer . ResetRead ( ) ;
a_Buffer . SkipRead ( a_Buffer . GetReadableSpace ( ) - Before ) ;
2015-01-21 08:15:35 -05:00
Length = static_cast < UInt32 > ( Before - After ) ;
2013-07-29 07:13:03 -04:00
break ;
}
case 6 : Length = 12 ; break ; // 3 * int
2013-11-07 11:13:25 -05:00
case 7 :
2013-07-29 07:13:03 -04:00
default :
{
ASSERT ( ! " Unknown metadata type " ) ;
break ;
}
} // switch (Type)
2015-01-21 08:15:35 -05:00
// Read the data in this item:
2013-07-29 07:13:03 -04:00
AString data ;
if ( ! a_Buffer . ReadString ( data , Length ) )
{
return false ;
}
a_Metadata . append ( data ) ;
2015-03-21 08:00:20 -04:00
if ( ! a_Buffer . ReadBEUInt8 ( x ) )
2013-07-29 07:13:03 -04:00
{
return false ;
}
2015-01-21 08:15:35 -05:00
a_Metadata . push_back ( static_cast < char > ( x ) ) ;
2013-07-29 07:13:03 -04:00
} // while (x != 0x7f)
return true ;
}
void cConnection : : LogMetadata ( const AString & a_Metadata , size_t a_IndentCount )
{
AString Indent ( a_IndentCount , ' ' ) ;
2015-01-21 08:15:35 -05:00
size_t pos = 0 ;
2013-07-29 07:13:03 -04:00
while ( a_Metadata [ pos ] ! = 0x7f )
{
2015-01-21 08:15:35 -05: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 12:49:37 -04:00
// int Length = 0;
2013-07-29 07:13:03 -04:00
switch ( Type )
{
case 0 :
{
2015-03-21 08:00:20 -04:00
Log ( " %sbyte[%u] = %u " , Indent . c_str ( ) , Index , static_cast < unsigned char > ( a_Metadata [ pos + 1 ] ) ) ;
2013-07-29 07:13:03 -04:00
pos + = 1 ;
break ;
}
case 1 :
{
2015-01-21 08:15:35 -05:00
Log ( " %sshort[%u] = %d " , Indent . c_str ( ) , Index , ( a_Metadata [ pos + 1 ] < < 8 ) | a_Metadata [ pos + 2 ] ) ;
2013-07-29 07:13:03 -04:00
pos + = 2 ;
break ;
}
case 2 :
{
2015-01-21 08:15:35 -05: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 07:13:03 -04:00
pos + = 4 ;
break ;
}
case 3 :
{
2015-01-21 08:15:35 -05: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 07:13:03 -04:00
pos + = 4 ;
break ;
}
2013-12-05 06:20:37 -05:00
case 4 : // UTF-8 string with VarInt length
2013-07-29 07:13:03 -04:00
{
2013-12-05 06:20:37 -05:00
cByteBuffer bb ( 10 ) ;
2015-01-21 08:15:35 -05:00
size_t RestLen = a_Metadata . size ( ) - pos - 1 ;
2013-12-05 06:20:37 -05:00
if ( RestLen > 8 )
{
RestLen = 8 ;
}
bb . Write ( a_Metadata . data ( ) + pos + 1 , RestLen ) ;
UInt32 Length ;
2015-01-21 08:15:35 -05:00
size_t rs = bb . GetReadableSpace ( ) ;
2014-12-21 16:51:17 -05: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 06:20:37 -05:00
rs = rs - bb . GetReadableSpace ( ) ;
2015-01-21 08:15:35 -05:00
Log ( " %sstring[%u] = \" %*s \" " , Indent . c_str ( ) , Index , Length , a_Metadata . c_str ( ) + pos + rs + 1 ) ;
2013-12-05 06:20:37 -05:00
pos + = Length + rs + 2 ;
2013-07-29 07:13:03 -04:00
break ;
}
case 5 :
{
2015-01-21 08:15:35 -05:00
size_t BytesLeft = a_Metadata . size ( ) - pos - 1 ;
2013-07-29 07:13:03 -04: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 08:15:35 -05:00
// size_t After = bb.GetReadableSpace();
size_t BytesConsumed = BytesLeft - bb . GetReadableSpace ( ) ;
2013-07-29 07:13:03 -04:00
2015-01-21 08:15:35 -05:00
Log ( " %sslot[%u] = %s (%u bytes) " , Indent . c_str ( ) , Index , ItemDesc . c_str ( ) , static_cast < unsigned > ( BytesConsumed ) ) ;
2013-07-29 07:13:03 -04:00
pos + = BytesConsumed ;
break ;
}
case 6 :
{
2017-12-23 07:49:08 -05:00
Log ( " %spos[%u] = <%d, %d, %d> " , Indent . c_str ( ) , Index ,
2013-07-29 07:13:03 -04: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 13:19:37 -05:00
Byte SharedSecret [ 16 ] ;
Byte EncryptedSecret [ 128 ] ;
2013-07-29 07:13:03 -04:00
memset ( SharedSecret , 0 , sizeof ( SharedSecret ) ) ; // Use all zeroes for the initial secret
2014-05-01 14:20:12 -04:00
cCryptoKey PubKey ( a_ServerPublicKey ) ;
2014-01-28 17:53:33 -05: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 13:19:37 -05:00
m_ServerEncryptor . Init ( SharedSecret , SharedSecret ) ;
m_ServerDecryptor . Init ( SharedSecret , SharedSecret ) ;
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
// Encrypt the nonce:
2014-01-25 13:19:37 -05:00
Byte EncryptedNonce [ 128 ] ;
2016-08-24 15:45:03 -04:00
res = PubKey . Encrypt ( reinterpret_cast < const Byte * > ( a_Nonce . data ( ) ) , a_Nonce . size ( ) , EncryptedNonce , sizeof ( EncryptedNonce ) ) ;
2014-01-28 17:53:33 -05:00
if ( res < 0 )
{
Log ( " Nonce encryption failed: %d (0x%x) " , res , res ) ;
return ;
}
2017-12-23 07:49:08 -05:00
2013-07-29 07:13:03 -04:00
// Send the packet to the server:
Log ( " Sending PACKET_ENCRYPTION_KEY_RESPONSE to the SERVER " ) ;
cByteBuffer ToServer ( 1024 ) ;
2015-03-21 08:00:20 -04:00
ToServer . WriteBEUInt8 ( 0x01 ) ; // To server: Encryption key response
ToServer . WriteBEUInt16 ( static_cast < UInt16 > ( sizeof ( EncryptedSecret ) ) ) ;
2014-01-25 13:19:37 -05:00
ToServer . WriteBuf ( EncryptedSecret , sizeof ( EncryptedSecret ) ) ;
2015-03-21 08:00:20 -04:00
ToServer . WriteBEUInt16 ( static_cast < UInt16 > ( sizeof ( EncryptedNonce ) ) ) ;
2014-01-25 13:19:37 -05:00
ToServer . WriteBuf ( EncryptedNonce , sizeof ( EncryptedNonce ) ) ;
2015-03-21 08:00:20 -04: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 17:53:33 -05:00
cByteBuffer Len ( 5 ) ;
2015-03-22 18:09:23 -04:00
Len . WriteVarInt32 ( static_cast < UInt32 > ( ToServer . GetReadableSpace ( ) ) ) ;
2014-01-28 17:53:33 -05:00
SERVERSEND ( Len ) ;
2013-07-29 07:13:03 -04:00
SERVERSEND ( ToServer ) ;
2013-10-29 10:47:22 -04:00
m_ServerState = csEncryptedUnderstood ;
m_IsServerEncrypted = true ;
2013-07-29 07:13:03 -04:00
}