2013-07-29 07:13:03 -04:00
|
|
|
|
|
|
|
// ProtocolRecognizer.cpp
|
|
|
|
|
2014-07-17 16:50:58 -04:00
|
|
|
// Implements the cProtocolRecognizer class representing the meta-protocol that recognizes possibly multiple
|
2013-07-29 07:13:03 -04:00
|
|
|
// protocol versions and redirects everything to them
|
|
|
|
|
|
|
|
#include "Globals.h"
|
|
|
|
|
|
|
|
#include "ProtocolRecognizer.h"
|
|
|
|
#include "Protocol125.h"
|
|
|
|
#include "Protocol132.h"
|
|
|
|
#include "Protocol14x.h"
|
|
|
|
#include "Protocol15x.h"
|
|
|
|
#include "Protocol16x.h"
|
2013-10-30 18:24:46 -04:00
|
|
|
#include "Protocol17x.h"
|
2013-07-29 07:13:03 -04:00
|
|
|
#include "../ClientHandle.h"
|
|
|
|
#include "../Root.h"
|
2013-08-11 13:18:06 -04:00
|
|
|
#include "../Server.h"
|
2013-07-29 07:13:03 -04:00
|
|
|
#include "../World.h"
|
|
|
|
#include "../ChatColor.h"
|
2014-08-20 16:19:50 -04:00
|
|
|
#include "Bindings/PluginManager.h"
|
2013-07-29 07:13:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) :
|
|
|
|
super(a_Client),
|
|
|
|
m_Protocol(NULL),
|
|
|
|
m_Buffer(512)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cProtocolRecognizer::~cProtocolRecognizer()
|
|
|
|
{
|
|
|
|
delete m_Protocol;
|
2014-06-19 04:49:56 -04:00
|
|
|
m_Protocol = NULL;
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion)
|
|
|
|
{
|
|
|
|
switch (a_ProtocolVersion)
|
|
|
|
{
|
|
|
|
case PROTO_VERSION_1_2_5: return "1.2.5";
|
|
|
|
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";
|
|
|
|
case PROTO_VERSION_1_5_0: return "1.5";
|
|
|
|
case PROTO_VERSION_1_5_2: return "1.5.2";
|
|
|
|
case PROTO_VERSION_1_6_1: return "1.6.1";
|
|
|
|
case PROTO_VERSION_1_6_2: return "1.6.2";
|
2013-09-19 14:49:09 -04:00
|
|
|
case PROTO_VERSION_1_6_3: return "1.6.3";
|
|
|
|
case PROTO_VERSION_1_6_4: return "1.6.4";
|
2013-11-08 16:09:39 -05:00
|
|
|
case PROTO_VERSION_1_7_2: return "1.7.2";
|
2014-04-14 12:52:21 -04:00
|
|
|
case PROTO_VERSION_1_7_6: return "1.7.6";
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
ASSERT(!"Unknown protocol version");
|
|
|
|
return Printf("Unknown protocol (%d)", a_ProtocolVersion);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-03-07 14:04:25 -05:00
|
|
|
void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
if (m_Protocol == NULL)
|
|
|
|
{
|
|
|
|
if (!m_Buffer.Write(a_Data, a_Size))
|
|
|
|
{
|
|
|
|
m_Client->Kick("Unsupported protocol version");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!TryRecognizeProtocol())
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The protocol has just been recognized, dump the whole m_Buffer contents into it for parsing:
|
|
|
|
AString Dump;
|
|
|
|
m_Buffer.ResetRead();
|
|
|
|
m_Buffer.ReadAll(Dump);
|
|
|
|
m_Protocol->DataReceived(Dump.data(), Dump.size());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_Protocol->DataReceived(a_Data, a_Size);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendAttachEntity(a_Entity, a_Vehicle);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2, a_BlockType);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendBlockBreakAnim(a_entityID, a_BlockX, a_BlockY, a_BlockZ, stage);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendBlockChange(a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendChat(const AString & a_Message)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendChat(a_Message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-15 17:16:44 -05:00
|
|
|
void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendChat(a_Message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-06-27 14:56:29 -04:00
|
|
|
void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2014-06-27 14:56:29 -04:00
|
|
|
m_Protocol->SendCollectEntity(a_Entity, a_Player);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendDestroyEntity(const cEntity & a_Entity)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendDestroyEntity(a_Entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendDisconnect(const AString & a_Reason)
|
|
|
|
{
|
|
|
|
if (m_Protocol != NULL)
|
|
|
|
{
|
|
|
|
m_Protocol->SendDisconnect(a_Reason);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// This is used when the client sends a server-ping, respond with the default packet:
|
2014-01-06 16:22:33 -05:00
|
|
|
WriteByte (0xff); // PACKET_DISCONNECT
|
2013-07-29 07:13:03 -04:00
|
|
|
WriteString(a_Reason);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-29 15:42:05 -04:00
|
|
|
void cProtocolRecognizer::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-12-14 12:03:00 -05:00
|
|
|
void cProtocolRecognizer::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
void cProtocolRecognizer::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityEquipment(a_Entity, a_SlotNum, a_Item);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityHeadLook(const cEntity & a_Entity)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityHeadLook(a_Entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityLook(const cEntity & a_Entity)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityLook(a_Entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityMetadata(const cEntity & a_Entity)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityMetadata(a_Entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityProperties(const cEntity & a_Entity)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityProperties(a_Entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityRelMove(a_Entity, a_RelX, a_RelY, a_RelZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityStatus(const cEntity & a_Entity, char a_Status)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityStatus(a_Entity, a_Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendEntityVelocity(const cEntity & a_Entity)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendEntityVelocity(a_Entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2014-07-19 08:53:41 -04:00
|
|
|
m_Protocol->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_Radius, a_BlocksAffected, a_PlayerMotion);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendGameMode(eGameMode a_GameMode)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendGameMode(a_GameMode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendHealth(void)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendHealth();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-05-01 16:58:58 -04:00
|
|
|
void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2013-08-18 07:26:37 -04:00
|
|
|
m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendInventorySlot(a_WindowID, a_SlotNum, a_Item);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendKeepAlive(int a_PingID)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendKeepAlive(a_PingID);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendLogin(a_Player, a_World);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-04-14 16:52:59 -04:00
|
|
|
void cProtocolRecognizer::SendLoginSuccess(void)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendLoginSuccess();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-13 10:13:09 -05:00
|
|
|
void cProtocolRecognizer::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-18 13:50:08 -05:00
|
|
|
void cProtocolRecognizer::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendMapDecorators(a_ID, a_Decorators);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-13 10:13:09 -05:00
|
|
|
void cProtocolRecognizer::SendMapInfo(int a_ID, unsigned int a_Scale)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendMapInfo(a_ID, a_Scale);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-12-22 08:45:25 -05:00
|
|
|
void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmmount);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-02-17 19:16:03 -05:00
|
|
|
void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting)
|
|
|
|
{
|
|
|
|
m_Protocol->SendPaintingSpawn(a_Painting);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-12-22 08:45:25 -05:00
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPickupSpawn(a_Pickup);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-01 11:20:15 -04:00
|
|
|
void cProtocolRecognizer::SendPlayerAbilities(void)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPlayerAbilities();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-12-06 18:47:07 -05:00
|
|
|
void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2013-12-06 18:47:07 -05:00
|
|
|
m_Protocol->SendEntityAnimation(a_Entity, a_Animation);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPlayerListItem(a_Player, a_IsOnline);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendPlayerMaxSpeed(void)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPlayerMaxSpeed();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendPlayerMoveLook(void)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPlayerMoveLook();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendPlayerPosition(void)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPlayerPosition();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendPlayerSpawn(const cPlayer & a_Player)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPlayerSpawn(a_Player);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-01-09 05:39:42 -05:00
|
|
|
void cProtocolRecognizer::SendPluginMessage(const AString & a_Channel, const AString & a_Message)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendPluginMessage(a_Channel, a_Message);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-12-14 12:03:00 -05:00
|
|
|
void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-18 15:10:51 -04:00
|
|
|
void cProtocolRecognizer::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2014-07-18 15:10:51 -04:00
|
|
|
m_Protocol->SendRespawn(a_Dimension, a_ShouldIgnoreDimensionChecks);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-15 10:23:50 -05:00
|
|
|
void cProtocolRecognizer::SendExperience(void)
|
2013-11-14 16:35:02 -05:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2013-11-15 10:23:50 -05:00
|
|
|
m_Protocol->SendExperience();
|
2013-11-14 16:35:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-25 15:43:43 -05:00
|
|
|
void cProtocolRecognizer::SendExperienceOrb(const cExpOrb & a_ExpOrb)
|
2013-11-25 14:04:01 -05:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2013-11-25 15:43:43 -05:00
|
|
|
m_Protocol->SendExperienceOrb(a_ExpOrb);
|
2013-11-25 14:04:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-01-21 08:58:17 -05:00
|
|
|
void cProtocolRecognizer::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendScoreboardObjective(a_Name, a_DisplayName, a_Mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendScoreUpdate(a_Objective, a_Player, a_Score, a_Mode);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendDisplayObjective(a_Objective, a_Display);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-12 20:08:02 -04:00
|
|
|
void cProtocolRecognizer::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2014-07-12 20:08:02 -04:00
|
|
|
m_Protocol->SendSoundEffect(a_SoundName, a_X, a_Y, a_Z, a_Volume, a_Pitch);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendSoundParticleEffect(a_EffectID, a_SrcX, a_SrcY, a_SrcZ, a_Data);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendSpawnFallingBlock(a_FallingBlock);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendSpawnMob(a_Mob);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData, a_Yaw, a_Pitch);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-08-29 08:47:22 -04:00
|
|
|
void cProtocolRecognizer::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2013-08-29 08:47:22 -04:00
|
|
|
m_Protocol->SendSpawnVehicle(a_Vehicle, a_VehicleType, a_VehicleSubType);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-05-11 07:57:06 -04:00
|
|
|
void cProtocolRecognizer::SendStatistics(const cStatManager & a_Manager)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendStatistics(a_Manager);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-30 16:48:59 -04:00
|
|
|
void cProtocolRecognizer::SendTabCompletionResults(const AStringVector & a_Results)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendTabCompletionResults(a_Results);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
void cProtocolRecognizer::SendTeleportEntity(const cEntity & a_Entity)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendTeleportEntity(a_Entity);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendThunderbolt(a_BlockX, a_BlockY, a_BlockZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-08-10 18:20:28 -04:00
|
|
|
void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2014-08-10 18:20:28 -04:00
|
|
|
m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-01-19 14:42:25 -05:00
|
|
|
void cProtocolRecognizer::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
|
2014-01-18 19:54:38 -05:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2014-01-19 14:42:25 -05:00
|
|
|
m_Protocol->SendUpdateBlockEntity(a_BlockEntity);
|
2014-01-18 19:54:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
void cProtocolRecognizer::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendUpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-07-21 09:19:48 -04:00
|
|
|
void cProtocolRecognizer::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendWeather(eWeather a_Weather)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendWeather(a_Weather);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendWholeInventory(const cWindow & a_Window)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendWholeInventory(a_Window);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendWindowClose(const cWindow & a_Window)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
m_Protocol->SendWindowClose(a_Window);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-08 15:32:14 -05:00
|
|
|
void cProtocolRecognizer::SendWindowOpen(const cWindow & a_Window)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
2013-11-08 15:32:14 -05:00
|
|
|
m_Protocol->SendWindowOpen(a_Window);
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AString cProtocolRecognizer::GetAuthServerID(void)
|
|
|
|
{
|
|
|
|
ASSERT(m_Protocol != NULL);
|
|
|
|
return m_Protocol->GetAuthServerID();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-04-04 04:13:25 -04:00
|
|
|
void cProtocolRecognizer::SendData(const char * a_Data, size_t a_Size)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
// This is used only when handling the server ping
|
|
|
|
m_Client->SendData(a_Data, a_Size);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool cProtocolRecognizer::TryRecognizeProtocol(void)
|
|
|
|
{
|
2014-07-17 16:50:58 -04:00
|
|
|
// NOTE: If a new protocol is added or an old one is removed, adjust MCS_CLIENT_VERSIONS and
|
2013-07-29 07:13:03 -04:00
|
|
|
// MCS_PROTOCOL_VERSIONS macros in the header file, as well as PROTO_VERSION_LATEST macro
|
|
|
|
|
|
|
|
// The first packet should be a Handshake, 0x02:
|
|
|
|
unsigned char PacketType;
|
|
|
|
if (!m_Buffer.ReadByte(PacketType))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
switch (PacketType)
|
|
|
|
{
|
2013-10-30 18:24:46 -04:00
|
|
|
case 0x02: return TryRecognizeLengthlessProtocol(); // Handshake, continue recognizing
|
|
|
|
case 0xfe:
|
|
|
|
{
|
|
|
|
// This may be either a packet length or the length-less Ping packet
|
|
|
|
Byte NextByte;
|
|
|
|
if (!m_Buffer.ReadByte(NextByte))
|
|
|
|
{
|
|
|
|
// Not enough data for either protocol
|
|
|
|
// This could actually happen with the 1.2 / 1.3 client, but their support is fading out anyway
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (NextByte != 0x01)
|
|
|
|
{
|
|
|
|
// This is definitely NOT a length-less Ping packet, handle as lengthed protocol:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!m_Buffer.ReadByte(NextByte))
|
|
|
|
{
|
|
|
|
// There is no more data. Although this *could* mean TCP fragmentation, it is highly unlikely
|
|
|
|
// and rather this is a 1.4 client sending a regular Ping packet (without the following Plugin message)
|
|
|
|
SendLengthlessServerPing();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (NextByte == 0xfa)
|
|
|
|
{
|
|
|
|
// Definitely a length-less Ping followed by a Plugin message
|
|
|
|
SendLengthlessServerPing();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Definitely a lengthed Initial handshake, handle below:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} // switch (PacketType)
|
|
|
|
|
|
|
|
// This must be a lengthed protocol, try if it has the entire initial handshake packet:
|
|
|
|
m_Buffer.ResetRead();
|
|
|
|
UInt32 PacketLen;
|
2014-04-04 05:47:46 -04:00
|
|
|
UInt32 ReadSoFar = (UInt32)m_Buffer.GetReadableSpace();
|
2013-10-30 18:24:46 -04:00
|
|
|
if (!m_Buffer.ReadVarInt(PacketLen))
|
|
|
|
{
|
|
|
|
// Not enough bytes for the packet length, keep waiting
|
|
|
|
return false;
|
2013-07-29 07:13:03 -04:00
|
|
|
}
|
2014-05-08 14:16:35 -04:00
|
|
|
ReadSoFar -= (UInt32)m_Buffer.GetReadableSpace();
|
2013-10-30 18:24:46 -04:00
|
|
|
if (!m_Buffer.CanReadBytes(PacketLen))
|
|
|
|
{
|
|
|
|
// Not enough bytes for the packet, keep waiting
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return TryRecognizeLengthedProtocol(PacketLen - ReadSoFar);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool cProtocolRecognizer::TryRecognizeLengthlessProtocol(void)
|
|
|
|
{
|
|
|
|
// The comm started with 0x02, which is a Handshake packet in the length-less protocol family
|
2013-07-29 07:13:03 -04:00
|
|
|
// 1.3.2 starts with 0x02 0x39 <name-length-short>
|
|
|
|
// 1.2.5 starts with 0x02 <name-length-short> and name is expected to less than 0x3900 long :)
|
|
|
|
char ch;
|
|
|
|
if (!m_Buffer.ReadChar(ch))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
switch (ch)
|
|
|
|
{
|
2014-01-21 08:58:17 -05:00
|
|
|
case PROTO_VERSION_1_3_2:
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
m_Protocol = new cProtocol132(m_Client);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case PROTO_VERSION_1_4_2:
|
|
|
|
case PROTO_VERSION_1_4_4:
|
|
|
|
{
|
|
|
|
m_Protocol = new cProtocol142(m_Client);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case PROTO_VERSION_1_4_6:
|
|
|
|
{
|
|
|
|
m_Protocol = new cProtocol146(m_Client);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case PROTO_VERSION_1_5_0:
|
|
|
|
case PROTO_VERSION_1_5_2:
|
|
|
|
{
|
|
|
|
m_Protocol = new cProtocol150(m_Client);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case PROTO_VERSION_1_6_1:
|
|
|
|
{
|
|
|
|
m_Protocol = new cProtocol161(m_Client);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
case PROTO_VERSION_1_6_2:
|
2013-09-19 14:49:09 -04:00
|
|
|
case PROTO_VERSION_1_6_3:
|
|
|
|
case PROTO_VERSION_1_6_4:
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
m_Protocol = new cProtocol162(m_Client);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_Protocol = new cProtocol125(m_Client);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-10-30 18:24:46 -04:00
|
|
|
bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining)
|
|
|
|
{
|
|
|
|
UInt32 PacketType;
|
|
|
|
if (!m_Buffer.ReadVarInt(PacketType))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (PacketType != 0x00)
|
|
|
|
{
|
|
|
|
// Not an initial handshake packet, we don't know how to talk to them
|
|
|
|
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, initial packet %u)",
|
|
|
|
m_Client->GetIPString().c_str(), PacketType
|
|
|
|
);
|
|
|
|
m_Client->Kick("Unsupported protocol version");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
UInt32 ProtocolVersion;
|
|
|
|
if (!m_Buffer.ReadVarInt(ProtocolVersion))
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
switch (ProtocolVersion)
|
|
|
|
{
|
|
|
|
case PROTO_VERSION_1_7_2:
|
|
|
|
{
|
|
|
|
AString ServerAddress;
|
|
|
|
short ServerPort;
|
|
|
|
UInt32 NextState;
|
2014-09-01 13:18:07 -04:00
|
|
|
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!m_Buffer.ReadBEShort(ServerPort))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!m_Buffer.ReadVarInt(NextState))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2013-10-30 18:24:46 -04:00
|
|
|
m_Buffer.CommitRead();
|
2014-04-04 05:47:46 -04:00
|
|
|
m_Protocol = new cProtocol172(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
2013-10-30 18:24:46 -04:00
|
|
|
return true;
|
|
|
|
}
|
2014-04-14 12:52:21 -04:00
|
|
|
case PROTO_VERSION_1_7_6:
|
|
|
|
{
|
|
|
|
AString ServerAddress;
|
|
|
|
short ServerPort;
|
|
|
|
UInt32 NextState;
|
2014-09-01 13:18:07 -04:00
|
|
|
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!m_Buffer.ReadBEShort(ServerPort))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!m_Buffer.ReadVarInt(NextState))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
2014-04-14 12:52:21 -04:00
|
|
|
m_Buffer.CommitRead();
|
|
|
|
m_Protocol = new cProtocol176(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
|
|
|
return true;
|
|
|
|
}
|
2013-10-30 18:24:46 -04:00
|
|
|
}
|
|
|
|
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u)",
|
|
|
|
m_Client->GetIPString().c_str(), ProtocolVersion
|
|
|
|
);
|
|
|
|
m_Client->Kick("Unsupported protocol version");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void cProtocolRecognizer::SendLengthlessServerPing(void)
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
AString Reply;
|
2014-04-18 15:09:44 -04:00
|
|
|
cServer * Server = cRoot::Get()->GetServer();
|
2014-08-20 10:12:05 -04:00
|
|
|
|
2014-08-20 16:22:38 -04:00
|
|
|
AString ServerDescription = Server->GetDescription();
|
2014-08-20 10:12:05 -04:00
|
|
|
int NumPlayers = Server->GetNumPlayers();
|
|
|
|
int MaxPlayers = Server->GetMaxPlayers();
|
2014-08-20 16:19:50 -04:00
|
|
|
AString Favicon = Server->GetFaviconData();
|
2014-08-20 16:22:38 -04:00
|
|
|
cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon);
|
2014-08-20 10:12:05 -04:00
|
|
|
|
2013-10-23 05:06:39 -04:00
|
|
|
switch (cRoot::Get()->GetPrimaryServerVersion())
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
case PROTO_VERSION_1_2_5:
|
|
|
|
case PROTO_VERSION_1_3_2:
|
|
|
|
{
|
|
|
|
// http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29
|
2014-07-17 16:50:58 -04:00
|
|
|
Printf(Reply, "%s%s%i%s%i",
|
2014-08-20 16:22:38 -04:00
|
|
|
ServerDescription.c_str(),
|
2014-07-19 14:15:21 -04:00
|
|
|
cChatColor::Delimiter,
|
2014-08-20 10:12:05 -04:00
|
|
|
NumPlayers,
|
2014-07-19 14:15:21 -04:00
|
|
|
cChatColor::Delimiter,
|
2014-08-20 10:12:05 -04:00
|
|
|
MaxPlayers
|
2013-07-29 07:13:03 -04:00
|
|
|
);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case PROTO_VERSION_1_4_2:
|
|
|
|
case PROTO_VERSION_1_4_4:
|
|
|
|
case PROTO_VERSION_1_4_6:
|
|
|
|
case PROTO_VERSION_1_5_0:
|
|
|
|
case PROTO_VERSION_1_5_2:
|
|
|
|
case PROTO_VERSION_1_6_1:
|
|
|
|
case PROTO_VERSION_1_6_2:
|
2013-09-19 14:49:09 -04:00
|
|
|
case PROTO_VERSION_1_6_3:
|
|
|
|
case PROTO_VERSION_1_6_4:
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
|
|
|
// 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
|
|
|
|
// _X 2012_10_31: I know that this needn't eat the byte, since it still may be in transit.
|
|
|
|
// Who cares? We're disconnecting anyway.
|
2013-10-30 18:24:46 -04:00
|
|
|
m_Buffer.ResetRead();
|
|
|
|
if (m_Buffer.CanReadBytes(2))
|
2013-07-29 07:13:03 -04:00
|
|
|
{
|
2014-01-23 17:35:23 -05:00
|
|
|
Byte val;
|
2013-10-30 18:24:46 -04:00
|
|
|
m_Buffer.ReadByte(val); // Packet type - Serverlist ping
|
|
|
|
m_Buffer.ReadByte(val); // 0x01 magic value
|
2013-07-29 07:13:03 -04:00
|
|
|
ASSERT(val == 0x01);
|
|
|
|
}
|
2014-08-20 10:12:05 -04:00
|
|
|
|
2013-07-29 07:13:03 -04:00
|
|
|
AString ProtocolVersionNum;
|
2013-10-23 05:06:39 -04:00
|
|
|
Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion());
|
|
|
|
AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->GetPrimaryServerVersion()));
|
2013-07-29 07:13:03 -04:00
|
|
|
|
|
|
|
// Cannot use Printf() because of in-string NUL bytes.
|
|
|
|
Reply = cChatColor::Delimiter;
|
|
|
|
Reply.append("1");
|
|
|
|
Reply.push_back(0);
|
|
|
|
Reply.append(ProtocolVersionNum);
|
|
|
|
Reply.push_back(0);
|
|
|
|
Reply.append(ProtocolVersionTxt);
|
|
|
|
Reply.push_back(0);
|
2014-08-20 16:22:38 -04:00
|
|
|
Reply.append(ServerDescription);
|
2013-07-29 07:13:03 -04:00
|
|
|
Reply.push_back(0);
|
2014-08-20 10:12:05 -04:00
|
|
|
Reply.append(Printf("%d", NumPlayers));
|
2013-07-29 07:13:03 -04:00
|
|
|
Reply.push_back(0);
|
2014-08-20 10:12:05 -04:00
|
|
|
Reply.append(Printf("%d", MaxPlayers));
|
2013-07-29 07:13:03 -04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
} // switch (m_PrimaryServerVersion)
|
|
|
|
m_Client->Kick(Reply);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|