diff --git a/VC2008/MCServer.vcproj b/VC2008/MCServer.vcproj index 0c29a5fc8..711e4c9bc 100644 --- a/VC2008/MCServer.vcproj +++ b/VC2008/MCServer.vcproj @@ -2103,11 +2103,11 @@ > SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData, a_SpeedX, a_SpeedY, a_SpeedZ); + m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData, a_SpeedX, a_SpeedY, a_SpeedZ, a_Yaw, a_Pitch); } diff --git a/source/ClientHandle.h b/source/ClientHandle.h index cefbbd5d8..03367ebac 100644 --- a/source/ClientHandle.h +++ b/source/ClientHandle.h @@ -34,6 +34,7 @@ class cWindow; + class cClientHandle : // tolua_export public cSocketThreads::cCallback { // tolua_export @@ -120,7 +121,7 @@ public: void SendWindowClose (char a_WindowID); void SendWindowOpen (char a_WindowID, char a_WindowType, const AString & a_WindowTitle, char a_NumSlots); void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); - void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ); + void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch); const AString & GetUsername(void) const; //tolua_export void SetUsername( const AString & a_Username ); //tolua_export diff --git a/source/Defines.h b/source/Defines.h index 4f3bb46eb..89cf11266 100644 --- a/source/Defines.h +++ b/source/Defines.h @@ -1,7 +1,10 @@ + #pragma once #include "BlockID.h" +typedef unsigned char Byte; + //tolua_begin // emissive blocks extern unsigned char g_BlockLightValue[]; diff --git a/source/FallingBlock.cpp b/source/FallingBlock.cpp index 1d6ce8959..13342cdef 100644 --- a/source/FallingBlock.cpp +++ b/source/FallingBlock.cpp @@ -32,7 +32,7 @@ void cFallingBlock::Initialize(cWorld * a_World) void cFallingBlock::SpawnOn(cClientHandle & a_ClientHandle) { - a_ClientHandle.SendSpawnObject(*this, 70, m_BlockType, 0, 0, 0); + a_ClientHandle.SendSpawnObject(*this, 70, m_BlockType, 0, 0, 0, 0, 0); } diff --git a/source/Protocol/Protocol.h b/source/Protocol/Protocol.h index b2423c6a2..956d31955 100644 --- a/source/Protocol/Protocol.h +++ b/source/Protocol/Protocol.h @@ -30,6 +30,12 @@ class cWorld; +typedef unsigned char Byte; + + + + + class cProtocol { public: @@ -75,7 +81,7 @@ public: virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) = 0; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0; virtual void SendSpawnMob (const cMonster & a_Mob) = 0; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ) = 0; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) = 0; virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) = 0; @@ -102,7 +108,7 @@ protected: virtual void Flush(void) {}; // Helpers for writing partial packet data, write using SendData() - void WriteByte(char a_Value) + void WriteByte(Byte a_Value) { SendData((const char *)&a_Value, 1); } diff --git a/source/Protocol/Protocol125.cpp b/source/Protocol/Protocol125.cpp index beac46c69..821cebfa1 100644 --- a/source/Protocol/Protocol125.cpp +++ b/source/Protocol/Protocol125.cpp @@ -633,8 +633,11 @@ void cProtocol125::SendSpawnMob(const cMonster & a_Mob) -void cProtocol125::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ) +void cProtocol125::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) { + UNUSED(a_Yaw); + UNUSED(a_Pitch); + cCSLock Lock(m_CSPacket); WriteByte(PACKET_SPAWN_OBJECT); WriteInt (a_Entity.GetUniqueID()); @@ -643,11 +646,11 @@ void cProtocol125::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, WriteInt ((int)(a_Entity.GetPosY() * 32)); WriteInt ((int)(a_Entity.GetPosZ() * 32)); WriteInt (a_ObjectData); - if( a_ObjectData != 0 ) + if (a_ObjectData != 0) { - WriteShort( a_SpeedX ); - WriteShort( a_SpeedY ); - WriteShort( a_SpeedZ ); + WriteShort(a_SpeedX); + WriteShort(a_SpeedY); + WriteShort(a_SpeedZ); } Flush(); } diff --git a/source/Protocol/Protocol125.h b/source/Protocol/Protocol125.h index a9c85ae4d..84d4f7f41 100644 --- a/source/Protocol/Protocol125.h +++ b/source/Protocol/Protocol125.h @@ -59,7 +59,7 @@ public: virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; // a_Src coords are Block * 8 virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; diff --git a/source/Protocol/Protocol132.cpp b/source/Protocol/Protocol132.cpp index 3e28e471d..c6283b638 100644 --- a/source/Protocol/Protocol132.cpp +++ b/source/Protocol/Protocol132.cpp @@ -156,7 +156,6 @@ cProtocol132::cProtocol132(cClientHandle * a_Client) : super(a_Client), m_IsEncrypted(false) { - LOGD("Created cProtocol132 at %p", this); } @@ -169,7 +168,6 @@ cProtocol132::~cProtocol132() { LOGD("There are %d unsent bytes while deleting cProtocol132", m_DataToSend.size()); } - LOGD("Deleted cProtocol132 at %p", this); } diff --git a/source/Protocol/Protocol142.h b/source/Protocol/Protocol142.h deleted file mode 100644 index 4d2e8360c..000000000 --- a/source/Protocol/Protocol142.h +++ /dev/null @@ -1,39 +0,0 @@ - -// Protocol142.h - -// Interfaces to the cProtocol142 class representing the release 1.4.2 protocol (#47) -// The same protocol class is used for 1.4.4 too, because the only difference is in a packet that MCServer doesn't implement yet (ITEM_DATA) - - - - - -#pragma once - -#include "Protocol132.h" - - - - - -class cProtocol142 : - public cProtocol132 -{ - typedef cProtocol132 super; -public: - - cProtocol142(cClientHandle * a_Client); - virtual ~cProtocol142(); - - // Sending commands (alphabetically sorted): - virtual void SendPickupSpawn (const cPickup & a_Pickup) override; - virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; - - // Specific packet parsers: - virtual int ParseLocaleViewDistance(void) override; -} ; - - - - diff --git a/source/Protocol/Protocol142.cpp b/source/Protocol/Protocol14x.cpp similarity index 50% rename from source/Protocol/Protocol142.cpp rename to source/Protocol/Protocol14x.cpp index b0dec0211..5c517cd7f 100644 --- a/source/Protocol/Protocol142.cpp +++ b/source/Protocol/Protocol14x.cpp @@ -1,10 +1,18 @@ -// Protocol142.cpp +// Protocol14x.cpp -// Implements the cProtocol142 class representing the release 1.4.2 protocol (#47) +/* +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 "Protocol142.h" +#include "Protocol14x.h" #include "../Root.h" #include "../Server.h" #include "../ClientHandle.h" @@ -45,6 +53,8 @@ enum { PACKET_UPDATE_TIME = 0x04, PACKET_PICKUP_SPAWN = 0x15, + PACKET_SPAWN_OBJECT = 0x17, + PACKET_ENTITY_METADATA = 0x28, PACKET_SOUND_PARTICLE_EFFECT = 0x3d } ; @@ -58,20 +68,6 @@ enum cProtocol142::cProtocol142(cClientHandle * a_Client) : super(a_Client) { - LOGD("Created cProtocol142 at %p", this); -} - - - - - -cProtocol142::~cProtocol142() -{ - if (!m_DataToSend.empty()) - { - LOGD("There are %d unsent bytes while deleting cProtocol142", m_DataToSend.size()); - } - LOGD("Deleted cProtocol142 at %p", this); } @@ -137,4 +133,79 @@ void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) WriteInt64(a_WorldAge); WriteInt64(a_TimeOfDay); Flush(); -} \ No newline at end of file +} + + + + + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// cProtocol146: + +cProtocol146::cProtocol146(cClientHandle * a_Client) : + super(a_Client) +{ +} + + + + + +void cProtocol146::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) +{ + cCSLock Lock(m_CSPacket); + WriteByte(PACKET_SPAWN_OBJECT); + WriteInt (a_Entity.GetUniqueID()); + WriteByte(a_ObjectType); + WriteInt ((int)(a_Entity.GetPosX() * 32)); + WriteInt ((int)(a_Entity.GetPosY() * 32)); + WriteInt ((int)(a_Entity.GetPosZ() * 32)); + WriteInt (a_ObjectData); + if (a_ObjectData != 0) + { + WriteShort(a_SpeedX); + WriteShort(a_SpeedY); + WriteShort(a_SpeedZ); + WriteByte(a_Yaw); + WriteByte(a_Pitch); + } + Flush(); +} + + + + + +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); + WriteShort((short)(a_Pickup.GetSpeed().x * 32)); + WriteShort((short)(a_Pickup.GetSpeed().y * 32)); + WriteShort((short)(a_Pickup.GetSpeed().z * 32)); + 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()); // TODO: Still not good, needs GZIP! + WriteByte(0x7f); // End of metadata + Flush(); +} + + + + diff --git a/source/Protocol/Protocol14x.h b/source/Protocol/Protocol14x.h new file mode 100644 index 000000000..bd8706f40 --- /dev/null +++ b/source/Protocol/Protocol14x.h @@ -0,0 +1,61 @@ + +// Protocol14x.h + +/* +Interfaces to 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) +*/ + + + + + +#pragma once + +#include "Protocol132.h" + + + + + +class cProtocol142 : + public cProtocol132 +{ + typedef cProtocol132 super; + +public: + cProtocol142(cClientHandle * a_Client); + + // Sending commands (alphabetically sorted): + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + + // Specific packet parsers: + virtual int ParseLocaleViewDistance(void) override; +} ; + + + + + +class cProtocol146 : + public cProtocol142 +{ + typedef cProtocol142 super; + +public: + cProtocol146(cClientHandle * a_Client); + + virtual void SendPickupSpawn (const cPickup & a_Pickup) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) override; +} ; + + + + diff --git a/source/Protocol/ProtocolRecognizer.cpp b/source/Protocol/ProtocolRecognizer.cpp index 19c40c5a3..43ed82a36 100644 --- a/source/Protocol/ProtocolRecognizer.cpp +++ b/source/Protocol/ProtocolRecognizer.cpp @@ -9,7 +9,7 @@ #include "ProtocolRecognizer.h" #include "Protocol125.h" #include "Protocol132.h" -#include "Protocol142.h" +#include "Protocol14x.h" #include "../ClientHandle.h" #include "../Root.h" #include "../World.h" @@ -47,6 +47,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion) case PROTO_VERSION_1_3_2: return "1.3.2"; case PROTO_VERSION_1_4_2: return "1.4.2"; case PROTO_VERSION_1_4_4: return "1.4.4"; + case PROTO_VERSION_1_4_6: return "1.4.6"; } ASSERT(!"Unknown protocol version"); return Printf("Unknown protocol (%d)", a_ProtocolVersion); @@ -415,10 +416,10 @@ void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob) -void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ) +void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) { ASSERT(m_Protocol != NULL); - m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData, a_SpeedX, a_SpeedY, a_SpeedZ); + m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData, a_SpeedX, a_SpeedY, a_SpeedZ, a_Yaw, a_Pitch); } @@ -593,6 +594,11 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void) m_Protocol = new cProtocol142(m_Client); return true; } + case PROTO_VERSION_1_4_6: + { + m_Protocol = new cProtocol146(m_Client); + return true; + } } m_Protocol = new cProtocol125(m_Client); return true; @@ -623,6 +629,7 @@ void cProtocolRecognizer::HandleServerPing(void) case PROTO_VERSION_1_4_2: case PROTO_VERSION_1_4_4: + case PROTO_VERSION_1_4_6: { // The server list ping now has 1 more byte of "magic". Mojang just loves to complicate stuff. // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3101#Server_List_Ping_.280xFE.29 diff --git a/source/Protocol/ProtocolRecognizer.h b/source/Protocol/ProtocolRecognizer.h index d41e20f44..fce5c0ba4 100644 --- a/source/Protocol/ProtocolRecognizer.h +++ b/source/Protocol/ProtocolRecognizer.h @@ -18,8 +18,8 @@ // Adjust these if a new protocol is added or an old one is removed: -#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4" -#define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49" +#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6" +#define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49, 51" @@ -37,8 +37,9 @@ public: PROTO_VERSION_1_3_2 = 39, PROTO_VERSION_1_4_2 = 47, PROTO_VERSION_1_4_4 = 49, + PROTO_VERSION_1_4_6 = 51, - PROTO_VERSION_LATEST = PROTO_VERSION_1_4_4, // Keep this up to date, this serves as the default for PrimaryServerVersion + PROTO_VERSION_LATEST = PROTO_VERSION_1_4_6, // Keep this up to date, this serves as the default for PrimaryServerVersion } ; cProtocolRecognizer(cClientHandle * a_Client); @@ -83,7 +84,7 @@ public: virtual void SendSoundEffect (const AString & a_SoundName, int a_SrcX, int a_SrcY, int a_SrcZ, float a_Volume, float a_Pitch) override; virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; virtual void SendSpawnMob (const cMonster & a_Mob) override; - virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ) override; + virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, short a_SpeedX, short a_SpeedY, short a_SpeedZ, Byte a_Yaw, Byte a_Pitch) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override;