2013-07-29 12:13:03 +01:00
// Protocol14x.cpp
/*
Implements the 1.4.x protocol classes representing these protocols:
- cProtocol142:
- release 1.4.2 protocol (#47)
- release 1.4.4 protocol (#49) - the same protocol class is used, because the only difference is in a packet that MCServer doesn't implement yet (ITEM_DATA)
- release 1.4.5 protocol (same as 1.4.4)
- cProtocol146:
- release 1.4.6 protocol (#51)
*/
#include "Globals.h"
#include "Protocol14x.h"
#include "../Root.h"
#include "../Server.h"
#include "../ClientHandle.h"
#include "../Item.h"
#include "ChunkDataSerializer.h"
2013-08-19 11:39:13 +02:00
#include "../Entities/Player.h"
2013-07-29 12:13:03 +01:00
#include "../Mobs/Monster.h"
#include "../UI/Window.h"
2013-08-19 11:39:13 +02:00
#include "../Entities/Pickup.h"
#include "../Entities/FallingBlock.h"
2013-07-29 12:13:03 +01:00
2014-01-05 15:06:17 -07:00
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4127)
#pragma warning(disable:4244)
#pragma warning(disable:4231)
#pragma warning(disable:4189)
#pragma warning(disable:4702)
#endif
2013-07-29 12:13:03 +01:00
2014-01-05 15:06:17 -07:00
#ifdef _MSC_VER
#pragma warning(pop)
#endif
2013-07-29 12:13:03 +01:00
#define HANDLE_PACKET_READ(Proc, Type, Var) \
Type Var; \
{ \
if (!m_ReceivedData.Proc(Var)) \
{ \
m_ReceivedData.CheckValid(); \
return PARSE_INCOMPLETE; \
} \
m_ReceivedData.CheckValid(); \
}
enum
{
PACKET_UPDATE_TIME = 0x04 ,
PACKET_PICKUP_SPAWN = 0x15 ,
PACKET_SPAWN_OBJECT = 0x17 ,
PACKET_ENTITY_METADATA = 0x28 ,
PACKET_SOUND_PARTICLE_EFFECT = 0x3d
} ;
2014-07-17 22:15:34 +02:00
////////////////////////////////////////////////////////////////////////////////
2013-07-29 12:13:03 +01:00
// cProtocol142:
cProtocol142 :: cProtocol142 ( cClientHandle * a_Client ) :
super ( a_Client )
{
}
int cProtocol142 :: ParseLocaleViewDistance ( void )
{
HANDLE_PACKET_READ ( ReadBEUTF16String16 , AString , Locale );
HANDLE_PACKET_READ ( ReadChar , char , ViewDistance );
HANDLE_PACKET_READ ( ReadChar , char , ChatFlags );
HANDLE_PACKET_READ ( ReadChar , char , ClientDifficulty );
HANDLE_PACKET_READ ( ReadChar , char , ShouldShowCape ); // <-- new in 1.4.2
2014-02-16 13:26:07 +01:00
m_Client -> SetLocale ( Locale );
2013-07-29 12:13:03 +01:00
// TODO: m_Client->HandleViewDistance(ViewDistance);
// TODO: m_Client->HandleChatFlags(ChatFlags);
// Ignoring client difficulty
return PARSE_OK ;
}
void cProtocol142 :: SendPickupSpawn ( const cPickup & a_Pickup )
{
cCSLock Lock ( m_CSPacket );
WriteByte ( PACKET_PICKUP_SPAWN );
WriteInt ( a_Pickup . GetUniqueID ());
WriteItem ( a_Pickup . GetItem ());
WriteVectorI (( Vector3i )( a_Pickup . GetPosition () * 32 ));
2014-04-18 22:20:24 +02:00
WriteChar (( char )( a_Pickup . GetSpeedX () * 8 ));
WriteChar (( char )( a_Pickup . GetSpeedY () * 8 ));
WriteChar (( char )( a_Pickup . GetSpeedZ () * 8 ));
2013-07-29 12:13:03 +01:00
Flush ();
}
void cProtocol142 :: SendSoundParticleEffect ( int a_EffectID , int a_SrcX , int a_SrcY , int a_SrcZ , int a_Data )
{
cCSLock Lock ( m_CSPacket );
WriteByte ( PACKET_SOUND_PARTICLE_EFFECT );
WriteInt ( a_EffectID );
2013-11-12 21:43:20 +00:00
WriteInt ( a_SrcX );
2014-04-04 10:13:25 +02:00
WriteByte (( Byte ) a_SrcY );
2013-11-12 21:43:20 +00:00
WriteInt ( a_SrcZ );
2013-07-29 12:13:03 +01:00
WriteInt ( a_Data );
WriteBool ( 0 );
Flush ();
}
2014-08-11 00:20:28 +02:00
void cProtocol142 :: SendTimeUpdate ( Int64 a_WorldAge , Int64 a_TimeOfDay , bool a_DoDaylightCycle )
2013-07-29 12:13:03 +01:00
{
cCSLock Lock ( m_CSPacket );
WriteByte ( PACKET_UPDATE_TIME );
WriteInt64 ( a_WorldAge );
WriteInt64 ( a_TimeOfDay );
Flush ();
}
2014-07-17 22:15:34 +02:00
////////////////////////////////////////////////////////////////////////////////
2013-07-29 12:13:03 +01:00
// cProtocol146:
cProtocol146 :: cProtocol146 ( cClientHandle * a_Client ) :
super ( a_Client )
{
}
void cProtocol146 :: SendPickupSpawn ( const cPickup & a_Pickup )
{
ASSERT ( ! a_Pickup . GetItem (). IsEmpty ());
cCSLock Lock ( m_CSPacket );
// Send a SPAWN_OBJECT packet for the base entity:
WriteByte ( PACKET_SPAWN_OBJECT );
WriteInt ( a_Pickup . GetUniqueID ());
WriteByte ( 0x02 );
WriteInt (( int )( a_Pickup . GetPosX () * 32 ));
WriteInt (( int )( a_Pickup . GetPosY () * 32 ));
WriteInt (( int )( a_Pickup . GetPosZ () * 32 ));
WriteInt ( 1 );
2014-04-18 21:09:44 +02:00
WriteShort (( short )( a_Pickup . GetSpeedX () * 32 ));
2014-04-18 22:20:24 +02:00
WriteShort (( short )( a_Pickup . GetSpeedY () * 32 ));
WriteShort (( short )( a_Pickup . GetSpeedZ () * 32 ));
2013-07-29 12:13:03 +01:00
WriteByte ( 0 );
WriteByte ( 0 );
// Send a ENTITY_METADATA packet with the slot info:
WriteByte ( PACKET_ENTITY_METADATA );
WriteInt ( a_Pickup . GetUniqueID ());
WriteByte ( 0xaa ); // a slot value at index 10
WriteItem ( a_Pickup . GetItem ());
WriteByte ( 0x7f ); // End of metadata
Flush ();
}
void cProtocol146 :: SendSpawnFallingBlock ( const cFallingBlock & a_FallingBlock )
{
// Send a spawn object / vehicle packet
cCSLock Lock ( m_CSPacket );
WriteByte ( PACKET_SPAWN_OBJECT );
WriteInt ( a_FallingBlock . GetUniqueID ());
WriteByte ( 70 );
WriteInt (( int )( a_FallingBlock . GetPosX () * 32 ));
WriteInt (( int )( a_FallingBlock . GetPosY () * 32 ));
WriteInt (( int )( a_FallingBlock . GetPosZ () * 32 ));
WriteByte ( 0 ); // Pitch
WriteByte ( 0 ); // Yaw
WriteInt ( a_FallingBlock . GetBlockType ()); // data indicator = blocktype
WriteShort (( short )( a_FallingBlock . GetSpeedX () * 400 ));
WriteShort (( short )( a_FallingBlock . GetSpeedY () * 400 ));
WriteShort (( short )( a_FallingBlock . GetSpeedZ () * 400 ));
Flush ();
}
void cProtocol146 :: SendSpawnObject ( const cEntity & a_Entity , char a_ObjectType , int a_ObjectData , Byte a_Yaw , Byte a_Pitch )
{
cCSLock Lock ( m_CSPacket );
WriteByte ( PACKET_SPAWN_OBJECT );
WriteInt ( a_Entity . GetUniqueID ());
2014-04-04 10:13:25 +02:00
WriteChar ( a_ObjectType );
2013-07-29 12:13:03 +01:00
WriteInt (( int )( a_Entity . GetPosX () * 32 ));
WriteInt (( int )( a_Entity . GetPosY () * 32 ));
WriteInt (( int )( a_Entity . GetPosZ () * 32 ));
WriteByte ( a_Pitch );
WriteByte ( a_Yaw );
WriteInt ( a_ObjectData );
if ( a_ObjectData != 0 )
{
WriteShort (( short )( a_Entity . GetSpeedX () * 400 ));
WriteShort (( short )( a_Entity . GetSpeedY () * 400 ));
WriteShort (( short )( a_Entity . GetSpeedZ () * 400 ));
}
Flush ();
}
2013-08-29 13:47:22 +01:00
void cProtocol146 :: SendSpawnVehicle ( const cEntity & a_Vehicle , char a_VehicleType , char a_VehicleSubType )
2013-07-29 12:13:03 +01:00
{
cCSLock Lock ( m_CSPacket );
2013-08-28 22:13:27 +01:00
WriteByte ( PACKET_SPAWN_OBJECT );
WriteInt ( a_Vehicle . GetUniqueID ());
2014-04-04 10:13:25 +02:00
WriteChar ( a_VehicleType );
2013-08-28 22:13:27 +01:00
WriteInt (( int )( a_Vehicle . GetPosX () * 32 ));
WriteInt (( int )( a_Vehicle . GetPosY () * 32 ));
WriteInt (( int )( a_Vehicle . GetPosZ () * 32 ));
2013-07-29 12:13:03 +01:00
WriteByte (( Byte )(( a_Vehicle . GetPitch () / 360.f ) * 256 ));
2014-01-17 11:11:17 +01:00
WriteByte (( Byte )(( a_Vehicle . GetYaw () / 360.f ) * 256 ));
2013-08-29 13:47:22 +01:00
WriteInt ( a_VehicleSubType );
if ( a_VehicleSubType != 0 )
2013-08-28 22:13:27 +01:00
{
WriteShort (( short )( a_Vehicle . GetSpeedX () * 400 ));
WriteShort (( short )( a_Vehicle . GetSpeedY () * 400 ));
WriteShort (( short )( a_Vehicle . GetSpeedZ () * 400 ));
}
2013-07-29 12:13:03 +01:00
Flush ();
}