1
0
Fork 0
cuberite-2a/src/Protocol/ProtocolRecognizer.cpp

997 lines
19 KiB
C++
Raw Normal View History

// ProtocolRecognizer.cpp
2014-07-17 20:50:58 +00:00
// Implements the cProtocolRecognizer class representing the meta-protocol that recognizes possibly multiple
// protocol versions and redirects everything to them
#include "Globals.h"
#include "ProtocolRecognizer.h"
#include "Protocol17x.h"
#include "Protocol18x.h"
#include "../ClientHandle.h"
#include "../Root.h"
#include "../Server.h"
#include "../World.h"
#include "../ChatColor.h"
#include "Bindings/PluginManager.h"
cProtocolRecognizer::cProtocolRecognizer(cClientHandle * a_Client) :
super(a_Client),
2014-10-20 20:55:07 +00:00
m_Protocol(nullptr),
m_Buffer(8192) // We need a larger buffer to support BungeeCord - it sends one huge packet at the start
{
}
cProtocolRecognizer::~cProtocolRecognizer()
{
delete m_Protocol;
2014-10-20 20:55:07 +00:00
m_Protocol = nullptr;
}
AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion)
{
switch (a_ProtocolVersion)
{
2013-11-08 21:09:39 +00:00
case PROTO_VERSION_1_7_2: return "1.7.2";
case PROTO_VERSION_1_7_6: return "1.7.6";
case PROTO_VERSION_1_8_0: return "1.8";
}
ASSERT(!"Unknown protocol version");
return Printf("Unknown protocol (%d)", a_ProtocolVersion);
}
2014-03-07 19:04:25 +00:00
void cProtocolRecognizer::DataReceived(const char * a_Data, size_t a_Size)
{
2014-10-20 20:55:07 +00:00
if (m_Protocol == nullptr)
{
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)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
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)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendBlockAction(a_BlockX, a_BlockY, a_BlockZ, a_Byte1, a_Byte2, a_BlockType);
}
2015-03-21 15:11:57 +00:00
void cProtocolRecognizer::SendBlockBreakAnim(UInt32 a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2015-03-21 15:11:57 +00:00
m_Protocol->SendBlockBreakAnim(a_EntityID, a_BlockX, a_BlockY, a_BlockZ, a_Stage);
}
void cProtocolRecognizer::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
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)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendBlockChanges(a_ChunkX, a_ChunkZ, a_Changes);
}
void cProtocolRecognizer::SendChat(const AString & a_Message)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChat(a_Message);
}
void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChat(a_Message);
}
void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendChunkData(a_ChunkX, a_ChunkZ, a_Serializer);
}
void cProtocolRecognizer::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendCollectEntity(a_Entity, a_Player);
}
void cProtocolRecognizer::SendDestroyEntity(const cEntity & a_Entity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendDestroyEntity(a_Entity);
}
void cProtocolRecognizer::SendDisconnect(const AString & a_Reason)
{
2014-10-20 20:55:07 +00:00
if (m_Protocol != nullptr)
2014-09-27 21:13:37 +00:00
{
m_Protocol->SendDisconnect(a_Reason);
}
else
{
// This is used when the client sends a server-ping, respond with the default packet:
static const int Packet = 0xff; // PACKET_DISCONNECT
SendData((const char *)&Packet, 1); // WriteByte()
2014-09-28 12:08:00 +00:00
AString UTF16 = UTF8ToRawBEUTF16(a_Reason.c_str(), a_Reason.length());
2014-09-29 19:38:11 +00:00
static const u_short Size = htons((u_short)(UTF16.size() / 2));
SendData((const char *)&Size, 2); // WriteShort()
SendData(UTF16.data(), UTF16.size()); // WriteString()
2014-09-27 21:13:37 +00:00
}
}
void cProtocolRecognizer::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEditSign(a_BlockX, a_BlockY, a_BlockZ);
}
void cProtocolRecognizer::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityEffect(a_Entity, a_EffectID, a_Amplifier, a_Duration);
}
void cProtocolRecognizer::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityEquipment(a_Entity, a_SlotNum, a_Item);
}
void cProtocolRecognizer::SendEntityHeadLook(const cEntity & a_Entity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityHeadLook(a_Entity);
}
void cProtocolRecognizer::SendEntityLook(const cEntity & a_Entity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityLook(a_Entity);
}
void cProtocolRecognizer::SendEntityMetadata(const cEntity & a_Entity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityMetadata(a_Entity);
}
void cProtocolRecognizer::SendEntityProperties(const cEntity & a_Entity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityProperties(a_Entity);
}
void cProtocolRecognizer::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
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)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityRelMoveLook(a_Entity, a_RelX, a_RelY, a_RelZ);
}
void cProtocolRecognizer::SendEntityStatus(const cEntity & a_Entity, char a_Status)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityStatus(a_Entity, a_Status);
}
void cProtocolRecognizer::SendEntityVelocity(const cEntity & a_Entity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
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)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-07-19 12:53:41 +00:00
m_Protocol->SendExplosion(a_BlockX, a_BlockY, a_BlockZ, a_Radius, a_BlocksAffected, a_PlayerMotion);
}
void cProtocolRecognizer::SendGameMode(eGameMode a_GameMode)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendGameMode(a_GameMode);
}
void cProtocolRecognizer::SendHealth(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendHealth();
}
void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendWindowProperty(a_Window, a_Property, a_Value);
}
void cProtocolRecognizer::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendInventorySlot(a_WindowID, a_SlotNum, a_Item);
}
void cProtocolRecognizer::SendKeepAlive(int a_PingID)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendKeepAlive(a_PingID);
}
void cProtocolRecognizer::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendLogin(a_Player, a_World);
}
void cProtocolRecognizer::SendLoginSuccess(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendLoginSuccess();
}
2014-09-13 00:20:04 +00:00
void cProtocolRecognizer::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale)
2014-02-13 15:13:09 +00:00
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-09-13 00:20:04 +00:00
m_Protocol->SendMapColumn(a_ID, a_X, a_Y, a_Colors, a_Length, m_Scale);
2014-02-13 15:13:09 +00:00
}
2014-09-13 00:20:04 +00:00
void cProtocolRecognizer::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale)
2014-02-18 18:50:08 +00:00
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-09-13 00:20:04 +00:00
m_Protocol->SendMapDecorators(a_ID, a_Decorators, m_Scale);
2014-02-18 18:50:08 +00:00
}
2014-02-13 15:13:09 +00:00
void cProtocolRecognizer::SendMapInfo(int a_ID, unsigned int a_Scale)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-02-13 15:13:09 +00:00
m_Protocol->SendMapInfo(a_ID, a_Scale);
}
2014-09-11 15:03:09 +00: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_ParticleAmount)
2013-12-22 13:45:25 +00:00
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-09-11 15:03:09 +00:00
m_Protocol->SendParticleEffect(a_ParticleName, a_SrcX, a_SrcY, a_SrcZ, a_OffsetX, a_OffsetY, a_OffsetZ, a_ParticleData, a_ParticleAmount);
2013-12-22 13:45:25 +00:00
}
void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting)
{
m_Protocol->SendPaintingSpawn(a_Painting);
}
2013-12-22 13:45:25 +00:00
void cProtocolRecognizer::SendPickupSpawn(const cPickup & a_Pickup)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPickupSpawn(a_Pickup);
}
void cProtocolRecognizer::SendPlayerAbilities(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerAbilities();
}
void cProtocolRecognizer::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendEntityAnimation(a_Entity, a_Animation);
}
void cProtocolRecognizer::SendPlayerListAddPlayer(const cPlayer & a_Player)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerListAddPlayer(a_Player);
}
void cProtocolRecognizer::SendPlayerListRemovePlayer(const cPlayer & a_Player)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerListRemovePlayer(a_Player);
}
void cProtocolRecognizer::SendPlayerListUpdateGameMode(const cPlayer & a_Player)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerListUpdateGameMode(a_Player);
}
void cProtocolRecognizer::SendPlayerListUpdatePing(const cPlayer & a_Player)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerListUpdatePing(a_Player);
}
2014-09-26 15:37:19 +00:00
void cProtocolRecognizer::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-09-26 15:37:19 +00:00
m_Protocol->SendPlayerListUpdateDisplayName(a_Player, a_CustomName);
}
void cProtocolRecognizer::SendPlayerMaxSpeed(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerMaxSpeed();
}
void cProtocolRecognizer::SendPlayerMoveLook(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerMoveLook();
}
void cProtocolRecognizer::SendPlayerPosition(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerPosition();
}
void cProtocolRecognizer::SendPlayerSpawn(const cPlayer & a_Player)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPlayerSpawn(a_Player);
}
void cProtocolRecognizer::SendPluginMessage(const AString & a_Channel, const AString & a_Message)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendPluginMessage(a_Channel, a_Message);
}
void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendRemoveEntityEffect(a_Entity, a_EffectID);
}
void cProtocolRecognizer::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendRespawn(a_Dimension, a_ShouldIgnoreDimensionChecks);
}
2013-11-15 15:23:50 +00:00
void cProtocolRecognizer::SendExperience(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2013-11-15 15:23:50 +00:00
m_Protocol->SendExperience();
}
void cProtocolRecognizer::SendExperienceOrb(const cExpOrb & a_ExpOrb)
2013-11-25 19:04:01 +00:00
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendExperienceOrb(a_ExpOrb);
2013-11-25 19:04:01 +00:00
}
2014-01-21 13:58:17 +00:00
void cProtocolRecognizer::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-01-21 13:58:17 +00:00
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)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-01-21 13:58:17 +00:00
m_Protocol->SendScoreUpdate(a_Objective, a_Player, a_Score, a_Mode);
}
void cProtocolRecognizer::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-01-21 13:58:17 +00:00
m_Protocol->SendDisplayObjective(a_Objective, a_Display);
}
void cProtocolRecognizer::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSoundEffect(a_SoundName, a_X, a_Y, a_Z, a_Volume, a_Pitch);
}
void cProtocolRecognizer::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSoundParticleEffect(a_EffectID, a_SrcX, a_SrcY, a_SrcZ, a_Data);
}
void cProtocolRecognizer::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSpawnFallingBlock(a_FallingBlock);
}
void cProtocolRecognizer::SendSpawnMob(const cMonster & a_Mob)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSpawnMob(a_Mob);
}
void cProtocolRecognizer::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSpawnObject(a_Entity, a_ObjectType, a_ObjectData, a_Yaw, a_Pitch);
}
void cProtocolRecognizer::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendSpawnVehicle(a_Vehicle, a_VehicleType, a_VehicleSubType);
}
2014-05-11 11:57:06 +00:00
void cProtocolRecognizer::SendStatistics(const cStatManager & a_Manager)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-05-11 11:57:06 +00:00
m_Protocol->SendStatistics(a_Manager);
}
void cProtocolRecognizer::SendTabCompletionResults(const AStringVector & a_Results)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendTabCompletionResults(a_Results);
}
void cProtocolRecognizer::SendTeleportEntity(const cEntity & a_Entity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendTeleportEntity(a_Entity);
}
void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendThunderbolt(a_BlockX, a_BlockY, a_BlockZ);
}
void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle);
}
void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendUnloadChunk(a_ChunkX, a_ChunkZ);
}
2014-01-19 19:42:25 +00:00
void cProtocolRecognizer::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
2014-01-19 19:42:25 +00:00
m_Protocol->SendUpdateBlockEntity(a_BlockEntity);
}
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)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendUpdateSign(a_BlockX, a_BlockY, a_BlockZ, a_Line1, a_Line2, a_Line3, a_Line4);
}
void cProtocolRecognizer::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendUseBed(a_Entity, a_BlockX, a_BlockY, a_BlockZ);
}
void cProtocolRecognizer::SendWeather(eWeather a_Weather)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendWeather(a_Weather);
}
void cProtocolRecognizer::SendWholeInventory(const cWindow & a_Window)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendWholeInventory(a_Window);
}
void cProtocolRecognizer::SendWindowClose(const cWindow & a_Window)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendWindowClose(a_Window);
}
void cProtocolRecognizer::SendWindowOpen(const cWindow & a_Window)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
m_Protocol->SendWindowOpen(a_Window);
}
AString cProtocolRecognizer::GetAuthServerID(void)
{
2014-10-20 20:55:07 +00:00
ASSERT(m_Protocol != nullptr);
return m_Protocol->GetAuthServerID();
}
void cProtocolRecognizer::SendData(const char * a_Data, size_t a_Size)
{
// This is used only when handling the server ping
m_Client->SendData(a_Data, a_Size);
}
bool cProtocolRecognizer::TryRecognizeProtocol(void)
{
2014-07-17 20:50:58 +00:00
// NOTE: If a new protocol is added or an old one is removed, adjust MCS_CLIENT_VERSIONS and
// MCS_PROTOCOL_VERSIONS macros in the header file, as well as PROTO_VERSION_LATEST macro
2014-09-27 13:28:14 +00:00
// Lengthed protocol, try if it has the entire initial handshake packet:
UInt32 PacketLen;
UInt32 ReadSoFar = (UInt32)m_Buffer.GetReadableSpace();
if (!m_Buffer.ReadVarInt(PacketLen))
{
// Not enough bytes for the packet length, keep waiting
return false;
}
2014-05-08 18:16:35 +00:00
ReadSoFar -= (UInt32)m_Buffer.GetReadableSpace();
if (!m_Buffer.CanReadBytes(PacketLen))
{
// Not enough bytes for the packet, keep waiting
return false;
}
return TryRecognizeLengthedProtocol(PacketLen - ReadSoFar);
}
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;
}
m_Client->SetProtocolVersion(ProtocolVersion);
switch (ProtocolVersion)
{
case PROTO_VERSION_1_7_2:
{
AString ServerAddress;
UInt16 ServerPort;
UInt32 NextState;
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
{
break;
}
if (!m_Buffer.ReadBEUInt16(ServerPort))
{
break;
}
if (!m_Buffer.ReadVarInt(NextState))
{
break;
}
m_Buffer.CommitRead();
m_Protocol = new cProtocol172(m_Client, ServerAddress, ServerPort, NextState);
return true;
}
case PROTO_VERSION_1_7_6:
{
AString ServerAddress;
UInt16 ServerPort;
UInt32 NextState;
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
{
break;
}
if (!m_Buffer.ReadBEUInt16(ServerPort))
{
break;
}
if (!m_Buffer.ReadVarInt(NextState))
{
break;
}
m_Buffer.CommitRead();
m_Protocol = new cProtocol176(m_Client, ServerAddress, ServerPort, NextState);
return true;
}
case PROTO_VERSION_1_8_0:
{
AString ServerAddress;
UInt16 ServerPort;
UInt32 NextState;
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
{
break;
}
if (!m_Buffer.ReadBEUInt16(ServerPort))
{
break;
}
if (!m_Buffer.ReadVarInt(NextState))
{
break;
}
m_Buffer.CommitRead();
m_Protocol = new cProtocol180(m_Client, ServerAddress, ServerPort, NextState);
return true;
}
}
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u (0x%x))",
m_Client->GetIPString().c_str(), ProtocolVersion, ProtocolVersion
);
m_Client->Kick("Unsupported protocol version");
return false;
}
void cProtocolRecognizer::SendPacket(cPacketizer & a_Pkt)
{
// This function should never be called - it needs to exists so that cProtocolRecognizer can be instantiated,
// but the actual sending is done by the internal m_Protocol itself.
LOGWARNING("%s: This function shouldn't ever be called.", __FUNCTION__);
ASSERT(!"Function not to be called");
}