summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2014-09-28 22:04:30 +0200
committerMattes D <github@xoft.cz>2014-09-28 22:04:30 +0200
commit8d55cd409e38d8759b61e89a4b3dea678c1e5f98 (patch)
treeb587e2f8d0b1536e1e4ff0d0bc62c998eccd5141
parentMerge pull request #1463 from mc-server/sp_docs (diff)
parentCompilation fix (diff)
downloadcuberite-8d55cd409e38d8759b61e89a4b3dea678c1e5f98.tar
cuberite-8d55cd409e38d8759b61e89a4b3dea678c1e5f98.tar.gz
cuberite-8d55cd409e38d8759b61e89a4b3dea678c1e5f98.tar.bz2
cuberite-8d55cd409e38d8759b61e89a4b3dea678c1e5f98.tar.lz
cuberite-8d55cd409e38d8759b61e89a4b3dea678c1e5f98.tar.xz
cuberite-8d55cd409e38d8759b61e89a4b3dea678c1e5f98.tar.zst
cuberite-8d55cd409e38d8759b61e89a4b3dea678c1e5f98.zip
-rw-r--r--Tools/ProtoProxy/Connection.cpp3
-rw-r--r--src/ByteBuffer.cpp17
-rw-r--r--src/ByteBuffer.h1
-rw-r--r--src/ClientHandle.cpp14
-rw-r--r--src/ClientHandle.h1
-rw-r--r--src/Protocol/CMakeLists.txt10
-rw-r--r--src/Protocol/Protocol.h101
-rw-r--r--src/Protocol/Protocol125.cpp2175
-rw-r--r--src/Protocol/Protocol125.h185
-rw-r--r--src/Protocol/Protocol132.cpp880
-rw-r--r--src/Protocol/Protocol132.h115
-rw-r--r--src/Protocol/Protocol14x.cpp265
-rw-r--r--src/Protocol/Protocol14x.h63
-rw-r--r--src/Protocol/Protocol15x.cpp209
-rw-r--r--src/Protocol/Protocol15x.h42
-rw-r--r--src/Protocol/Protocol16x.cpp312
-rw-r--r--src/Protocol/Protocol16x.h78
-rw-r--r--src/Protocol/Protocol17x.cpp14
-rw-r--r--src/Protocol/Protocol17x.h3
-rw-r--r--src/Protocol/Protocol18x.cpp14
-rw-r--r--src/Protocol/Protocol18x.h3
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp202
-rw-r--r--src/Protocol/ProtocolRecognizer.h32
-rw-r--r--src/Root.cpp12
-rw-r--r--src/Root.h6
-rw-r--r--src/StringUtils.cpp20
-rw-r--r--src/StringUtils.h4
27 files changed, 24 insertions, 4757 deletions
diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp
index c5916c1ca..eaf4fab02 100644
--- a/Tools/ProtoProxy/Connection.cpp
+++ b/Tools/ProtoProxy/Connection.cpp
@@ -1819,8 +1819,7 @@ bool cConnection::HandleServerKick(void)
Reason.append(Split[4]);
Reason.push_back(0);
Reason.append(Split[5]);
- AString ReasonBE16;
- UTF8ToRawBEUTF16(Reason.data(), Reason.size(), ReasonBE16);
+ AString ReasonBE16 = UTF8ToRawBEUTF16(Reason.data(), Reason.size());
AString PacketStart("\xff");
PacketStart.push_back((ReasonBE16.size() / 2) / 256);
PacketStart.push_back((ReasonBE16.size() / 2) % 256);
diff --git a/src/ByteBuffer.cpp b/src/ByteBuffer.cpp
index 70fdc008c..dc6b32a44 100644
--- a/src/ByteBuffer.cpp
+++ b/src/ByteBuffer.cpp
@@ -627,23 +627,6 @@ bool cByteBuffer::WriteBool(bool a_Value)
-bool cByteBuffer::WriteBEUTF16String16(const AString & a_Value)
-{
- CHECK_THREAD;
- CheckValid();
- PUTBYTES(2);
- AString UTF16BE;
- UTF8ToRawBEUTF16(a_Value.data(), a_Value.size(), UTF16BE);
- WriteBEShort((short)(UTF16BE.size() / 2));
- PUTBYTES(UTF16BE.size());
- WriteBuf(UTF16BE.data(), UTF16BE.size());
- return true;
-}
-
-
-
-
-
bool cByteBuffer::WriteVarInt(UInt32 a_Value)
{
CHECK_THREAD;
diff --git a/src/ByteBuffer.h b/src/ByteBuffer.h
index 74dc378d4..70de419f0 100644
--- a/src/ByteBuffer.h
+++ b/src/ByteBuffer.h
@@ -88,7 +88,6 @@ public:
bool WriteBEFloat (float a_Value);
bool WriteBEDouble (double a_Value);
bool WriteBool (bool a_Value);
- bool WriteBEUTF16String16(const AString & a_Value); // string length as BE short, then string as UTF-16BE
bool WriteVarInt (UInt32 a_Value);
bool WriteVarUTF8String (const AString & a_Value); // string length as VarInt, then string as UTF-8
bool WriteLEInt (int a_Value);
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 3bd48eb3d..bd00c0b9e 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -1749,20 +1749,6 @@ void cClientHandle::HandleRespawn(void)
-void cClientHandle::HandleDisconnect(const AString & a_Reason)
-{
- LOGD("Received d/c packet from %s with reason \"%s\"", m_Username.c_str(), a_Reason.c_str());
-
- cRoot::Get()->GetPluginManager()->CallHookDisconnect(*this, a_Reason);
-
- m_HasSentDC = true;
- Destroy();
-}
-
-
-
-
-
void cClientHandle::HandleKeepAlive(int a_KeepAliveID)
{
if (a_KeepAliveID == m_PingID)
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index 0a936a2ca..10cf6ae28 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -239,7 +239,6 @@ public:
void HandleAnimation (char a_Animation);
void HandleChat (const AString & a_Message);
void HandleCreativeInventory(short a_SlotNum, const cItem & a_HeldItem);
- void HandleDisconnect (const AString & a_Reason);
void HandleEntityCrouch (int a_EntityID, bool a_IsCrouching);
void HandleEntityLeaveBed (int a_EntityID);
void HandleEntitySprinting (int a_EntityID, bool a_IsSprinting);
diff --git a/src/Protocol/CMakeLists.txt b/src/Protocol/CMakeLists.txt
index 5426c58fa..7c97e67bc 100644
--- a/src/Protocol/CMakeLists.txt
+++ b/src/Protocol/CMakeLists.txt
@@ -8,11 +8,6 @@ SET (SRCS
Authenticator.cpp
ChunkDataSerializer.cpp
MojangAPI.cpp
- Protocol125.cpp
- Protocol132.cpp
- Protocol14x.cpp
- Protocol15x.cpp
- Protocol16x.cpp
Protocol17x.cpp
Protocol18x.cpp
ProtocolRecognizer.cpp)
@@ -22,11 +17,6 @@ SET (HDRS
ChunkDataSerializer.h
MojangAPI.h
Protocol.h
- Protocol125.h
- Protocol132.h
- Protocol14x.h
- Protocol15x.h
- Protocol16x.h
Protocol17x.h
Protocol18x.h
ProtocolRecognizer.h)
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index b2ee92918..7225f663d 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -138,108 +138,9 @@ public:
protected:
cClientHandle * m_Client;
cCriticalSection m_CSPacket; // Each SendXYZ() function must acquire this CS in order to send the whole packet at once
-
+
/// A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it
virtual void SendData(const char * a_Data, size_t a_Size) = 0;
-
- /// Called after writing each packet, enables descendants to flush their buffers
- virtual void Flush(void) {}
-
- // Helpers for writing partial packet data, write using SendData()
- void WriteByte(Byte a_Value)
- {
- SendData((const char *)&a_Value, 1);
- }
-
- void WriteChar(char a_Value)
- {
- SendData(&a_Value, 1);
- }
-
- void WriteShort(short a_Value)
- {
- u_short Value = htons((u_short)a_Value);
- SendData((const char *)&Value, 2);
- }
-
- /*
- void WriteShort(unsigned short a_Value)
- {
- a_Value = htons(a_Value);
- SendData((const char *)&a_Value, 2);
- }
- */
-
- void WriteInt(int a_Value)
- {
- u_long Value = htonl((u_long)a_Value);
- SendData((const char *)&Value, 4);
- }
-
- void WriteUInt(unsigned int a_Value)
- {
- a_Value = htonl(a_Value);
- SendData((const char *)&a_Value, 4);
- }
-
- void WriteInt64 (Int64 a_Value)
- {
- UInt64 Value = HostToNetwork8(&a_Value);
- SendData((const char *)&Value, 8);
- }
-
- void WriteFloat (float a_Value)
- {
- UInt32 val = HostToNetwork4(&a_Value);
- SendData((const char *)&val, 4);
- }
-
- void WriteDouble(double a_Value)
- {
- UInt64 val = HostToNetwork8(&a_Value);
- SendData((const char *)&val, 8);
- }
-
- void WriteString(const AString & a_Value)
- {
- AString UTF16;
- UTF8ToRawBEUTF16(a_Value.c_str(), a_Value.length(), UTF16);
- WriteShort((short)(UTF16.size() / 2));
- SendData(UTF16.data(), UTF16.size());
- }
-
- void WriteBool(bool a_Value)
- {
- WriteByte(a_Value ? 1 : 0);
- }
-
- void WriteVectorI(const Vector3i & a_Vector)
- {
- WriteInt(a_Vector.x);
- WriteInt(a_Vector.y);
- WriteInt(a_Vector.z);
- }
-
- void WriteVarInt(UInt32 a_Value)
- {
- // A 32-bit integer can be encoded by at most 5 bytes:
- unsigned char b[5];
- size_t idx = 0;
- do
- {
- b[idx] = (a_Value & 0x7f) | ((a_Value > 0x7f) ? 0x80 : 0x00);
- a_Value = a_Value >> 7;
- idx++;
- } while (a_Value > 0);
-
- SendData((const char *)b, idx);
- }
-
- void WriteVarUTF8String(const AString & a_String)
- {
- WriteVarInt((UInt32)a_String.size());
- SendData(a_String.data(), a_String.size());
- }
} ;
diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp
deleted file mode 100644
index 369a35e18..000000000
--- a/src/Protocol/Protocol125.cpp
+++ /dev/null
@@ -1,2175 +0,0 @@
-
-// Protocol125.cpp
-
-// Implements the cProtocol125 class representing the release 1.2.5 protocol (#29)
-/*
-Documentation:
- - protocol: http://wiki.vg/wiki/index.php?title=Protocol&oldid=2513
- - session handling: http://wiki.vg/wiki/index.php?title=Session&oldid=2262
- - slot format: http://wiki.vg/wiki/index.php?title=Slot_Data&oldid=2152
-*/
-
-#include "Globals.h"
-
-#include "Protocol125.h"
-
-#include "../ClientHandle.h"
-#include "../World.h"
-#include "ChunkDataSerializer.h"
-#include "../Entities/Entity.h"
-#include "../Entities/ExpOrb.h"
-#include "../Mobs/Monster.h"
-#include "../Entities/Pickup.h"
-#include "../Entities/Player.h"
-#include "../ChatColor.h"
-#include "../UI/Window.h"
-#include "../Root.h"
-#include "../Server.h"
-
-#include "../Entities/ArrowEntity.h"
-#include "../Entities/Minecart.h"
-#include "../Entities/FallingBlock.h"
-
-#include "../Mobs/IncludeAllMonsters.h"
-
-#include "../CompositeChat.h"
-
-
-
-
-
-enum
-{
- PACKET_KEEP_ALIVE = 0x00,
- PACKET_LOGIN = 0x01,
- PACKET_HANDSHAKE = 0x02,
- PACKET_CHAT = 0x03,
- PACKET_UPDATE_TIME = 0x04,
- PACKET_ENTITY_EQUIPMENT = 0x05,
- PACKET_USE_ENTITY = 0x07,
- PACKET_UPDATE_HEALTH = 0x08,
- PACKET_RESPAWN = 0x09,
- PACKET_PLAYER_ON_GROUND = 0x0a,
- PACKET_PLAYER_POS = 0x0b,
- PACKET_PLAYER_LOOK = 0x0c,
- PACKET_PLAYER_MOVE_LOOK = 0x0d,
- PACKET_BLOCK_DIG = 0x0e,
- PACKET_BLOCK_PLACE = 0x0f,
- PACKET_SLOT_SELECTED = 0x10,
- PACKET_USE_BED = 0x11,
- PACKET_ANIMATION = 0x12,
- PACKET_PACKET_ENTITY_ACTION = 0x13,
- PACKET_PLAYER_SPAWN = 0x14,
- PACKET_PICKUP_SPAWN = 0x15,
- PACKET_COLLECT_PICKUP = 0x16,
- PACKET_SPAWN_OBJECT = 0x17,
- PACKET_SPAWN_MOB = 0x18,
- PACKET_ENTITY_VELOCITY = 0x1c,
- PACKET_DESTROY_ENTITY = 0x1d,
- PACKET_ENTITY = 0x1e,
- PACKET_ENT_REL_MOVE = 0x1f,
- PACKET_ENT_LOOK = 0x20,
- PACKET_ENT_REL_MOVE_LOOK = 0x21,
- PACKET_ENT_TELEPORT = 0x22,
- PACKET_ENT_HEAD_LOOK = 0x23,
- PACKET_ENT_STATUS = 0x26,
- PACKET_ATTACH_ENTITY = 0x27,
- PACKET_METADATA = 0x28,
- PACKET_ENTITY_EFFECT = 0x29,
- PACKET_SPAWN_EXPERIENCE_ORB = 0x1A,
- PACKET_REMOVE_ENTITY_EFFECT = 0x2a,
- PACKET_EXPERIENCE = 0x2b,
- PACKET_PRE_CHUNK = 0x32,
- PACKET_MAP_CHUNK = 0x33,
- PACKET_MULTI_BLOCK = 0x34,
- PACKET_BLOCK_CHANGE = 0x35,
- PACKET_BLOCK_ACTION = 0x36,
- PACKET_EXPLOSION = 0x3C,
- PACKET_SOUND_EFFECT = 0x3e,
- PACKET_SOUND_PARTICLE_EFFECT = 0x3d,
- PACKET_CHANGE_GAME_STATE = 0x46,
- PACKET_THUNDERBOLT = 0x47,
- PACKET_WINDOW_OPEN = 0x64,
- PACKET_WINDOW_CLOSE = 0x65,
- PACKET_WINDOW_CLICK = 0x66,
- PACKET_INVENTORY_SLOT = 0x67,
- PACKET_INVENTORY_WHOLE = 0x68,
- PACKET_WINDOW_PROPERTY = 0x69,
- PACKET_CREATIVE_INVENTORY_ACTION = 0x6B,
- PACKET_ENCHANT_ITEM = 0x6C,
- PACKET_UPDATE_SIGN = 0x82,
- PACKET_ITEM_DATA = 0x83,
- PACKET_INCREMENT_STATISTIC = 0xC8,
- PACKET_PLAYER_LIST_ITEM = 0xC9,
- PACKET_PLAYER_ABILITIES = 0xca,
- PACKET_PLUGIN_MESSAGE = 0xfa,
- PACKET_PING = 0xfe,
- PACKET_DISCONNECT = 0xff
-} ;
-
-
-
-
-
-#define HANDLE_PACKET_READ(Proc, Type, Var) \
- Type Var; \
- { \
- if (!m_ReceivedData.Proc(Var)) \
- { \
- m_ReceivedData.CheckValid(); \
- return PARSE_INCOMPLETE; \
- } \
- m_ReceivedData.CheckValid(); \
- }
-
-
-
-
-typedef unsigned char Byte;
-
-
-
-
-
-cProtocol125::cProtocol125(cClientHandle * a_Client) :
- super(a_Client),
- m_ReceivedData(32 KiB),
- m_LastSentDimension(dimNotSet)
-{
-}
-
-
-
-
-
-void cProtocol125::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ATTACH_ENTITY);
- WriteInt(a_Entity.GetUniqueID());
- WriteInt((a_Vehicle == NULL) ? -1 : a_Vehicle->GetUniqueID());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType)
-{
- UNUSED(a_BlockType);
-
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_BLOCK_ACTION);
- WriteInt (a_BlockX);
- WriteShort((short)a_BlockY);
- WriteInt (a_BlockZ);
- WriteChar (a_Byte1);
- WriteChar (a_Byte2);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage)
-{
- // Not supported in this protocol version
-}
-
-
-
-
-
-void cProtocol125::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_BLOCK_CHANGE);
- WriteInt (a_BlockX);
- WriteByte((unsigned char)a_BlockY);
- WriteInt (a_BlockZ);
- WriteByte(a_BlockType);
- WriteByte(a_BlockMeta);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes)
-{
- cCSLock Lock(m_CSPacket);
- if (a_Changes.size() == 1)
- {
- // Special packet for single-block changes
- const sSetBlock & blk = a_Changes.front();
- SendBlockChange(a_ChunkX * cChunkDef::Width + blk.x, blk.y, a_ChunkZ * cChunkDef::Width + blk.z, blk.BlockType, blk.BlockMeta);
- return;
- }
-
- WriteByte (PACKET_MULTI_BLOCK);
- WriteInt (a_ChunkX);
- WriteInt (a_ChunkZ);
- WriteShort((short)a_Changes.size());
- WriteUInt ((UInt32)(4 * a_Changes.size()));
- for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr)
- {
- UInt32 Coords = ((UInt32)itr->y) | ((UInt32)(itr->z << 8)) | ((UInt32)(itr->x << 12));
- UInt32 Blocks = ((UInt32)itr->BlockMeta) | ((UInt32)(itr->BlockType << 4));
- WriteUInt(Coords << 16 | Blocks);
- }
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendChat(const AString & a_Message)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_CHAT);
- WriteString(a_Message);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendChat(const cCompositeChat & a_Message)
-{
- // This version doesn't support composite messages, just extract each part's text and use it:
-
- // Send the message:
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_CHAT);
- WriteString(a_Message.ExtractText());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
-{
- cCSLock Lock(m_CSPacket);
-
- // Send the pre-chunk:
- SendPreChunk(a_ChunkX, a_ChunkZ, true);
-
- // Send the chunk data:
- AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_2_5, a_ChunkX, a_ChunkZ);
- WriteByte(PACKET_MAP_CHUNK);
- WriteInt (a_ChunkX);
- WriteInt (a_ChunkZ);
- SendData(Serialized.data(), Serialized.size());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_COLLECT_PICKUP);
- WriteInt (a_Entity.GetUniqueID());
- WriteInt (a_Player.GetUniqueID());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendDestroyEntity(const cEntity & a_Entity)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_DESTROY_ENTITY);
- WriteInt (a_Entity.GetUniqueID());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendDisconnect(const AString & a_Reason)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte ((unsigned char)PACKET_DISCONNECT);
- WriteString(a_Reason);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- // This protocol version doesn't support this packet, sign editor is invoked by the client automatically
- UNUSED(a_BlockX);
- UNUSED(a_BlockY);
- UNUSED(a_BlockZ);
-}
-
-
-
-
-
-void cProtocol125::SendEntityEffect(const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_ENTITY_EFFECT);
- WriteInt (a_Entity.GetUniqueID());
- WriteByte ((Byte)a_EffectID);
- WriteByte ((Byte)a_Amplifier);
- WriteShort(a_Duration);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_ENTITY_EQUIPMENT);
- WriteInt (a_Entity.GetUniqueID());
- WriteShort(a_SlotNum);
- WriteShort(a_Item.m_ItemType);
- WriteShort(a_Item.m_ItemDamage);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityHeadLook(const cEntity & a_Entity)
-{
- ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ENT_HEAD_LOOK);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar((char)((a_Entity.GetHeadYaw() / 360.f) * 256));
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityLook(const cEntity & a_Entity)
-{
- ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ENT_LOOK);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar((char)((a_Entity.GetYaw() / 360.f) * 256));
- WriteChar((char)((a_Entity.GetPitch() / 360.f) * 256));
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityMetadata(const cEntity & a_Entity)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_METADATA);
- WriteInt (a_Entity.GetUniqueID());
-
- WriteCommonMetadata(a_Entity);
- if (a_Entity.IsMob())
- {
- WriteMobMetadata(((const cMonster &)a_Entity));
- }
- else
- {
- WriteEntityMetadata(a_Entity);
- }
- WriteByte(0x7f);
-
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityProperties(const cEntity & a_Entity)
-{
- // Not supported in this protocol version
-}
-
-
-
-
-
-void cProtocol125::SendEntityRelMove(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
-{
- ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ENT_REL_MOVE);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar(a_RelX);
- WriteChar(a_RelY);
- WriteChar(a_RelZ);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityRelMoveLook(const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ)
-{
- ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ENT_REL_MOVE_LOOK);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar(a_RelX);
- WriteChar(a_RelY);
- WriteChar(a_RelZ);
- WriteChar((char)((a_Entity.GetYaw() / 360.f) * 256));
- WriteChar((char)((a_Entity.GetPitch() / 360.f) * 256));
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityStatus(const cEntity & a_Entity, char a_Status)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ENT_STATUS);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar(a_Status);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityVelocity(const cEntity & a_Entity)
-{
- ASSERT(a_Entity.GetUniqueID() != m_Client->GetPlayer()->GetUniqueID()); // Must not send for self
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ENTITY_VELOCITY);
- WriteInt (a_Entity.GetUniqueID());
- WriteShort((short) (a_Entity.GetSpeedX() * 400)); // 400 = 8000 / 20
- WriteShort((short) (a_Entity.GetSpeedY() * 400));
- WriteShort((short) (a_Entity.GetSpeedZ() * 400));
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendExplosion(double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_EXPLOSION);
- WriteDouble (a_BlockX);
- WriteDouble (a_BlockY);
- WriteDouble (a_BlockZ);
- WriteFloat (a_Radius);
- WriteInt ((Int32)a_BlocksAffected.size());
- int BlockX = (int)a_BlockX;
- int BlockY = (int)a_BlockY;
- int BlockZ = (int)a_BlockZ;
- for (cVector3iArray::const_iterator itr = a_BlocksAffected.begin(); itr != a_BlocksAffected.end(); ++itr)
- {
- WriteByte((Byte)(itr->x - BlockX));
- WriteByte((Byte)(itr->y - BlockY));
- WriteByte((Byte)(itr->z - BlockZ));
- }
- WriteFloat((float)a_PlayerMotion.x);
- WriteFloat((float)a_PlayerMotion.y);
- WriteFloat((float)a_PlayerMotion.z);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendGameMode(eGameMode a_GameMode)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_CHANGE_GAME_STATE);
- WriteByte(3);
- WriteChar((char)a_GameMode);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendHandshake(const AString & a_ConnectionHash)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_HANDSHAKE);
- WriteString(a_ConnectionHash);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendHealth(void)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_UPDATE_HEALTH);
- cPlayer * Player = m_Client->GetPlayer();
- WriteShort((short)Player->GetHealth());
- WriteShort((short)Player->GetFoodLevel());
- WriteFloat((float)Player->GetFoodSaturationLevel());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_INVENTORY_SLOT);
- WriteChar (a_WindowID);
- WriteShort(a_SlotNum);
- WriteItem (a_Item);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendKeepAlive(int a_PingID)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_KEEP_ALIVE);
- WriteInt (a_PingID);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
-{
- UNUSED(a_World);
- cCSLock Lock(m_CSPacket);
-
- WriteByte (PACKET_LOGIN);
- WriteInt (a_Player.GetUniqueID()); // EntityID of the player
- WriteString(""); // Username, not used
- WriteString("default"); // Level type
- WriteInt ((int)a_Player.GetGameMode());
- WriteInt ((int)(a_World.GetDimension()));
- WriteByte (2); // TODO: Difficulty
- WriteByte (0); // Unused
- WriteByte (60); // Client list width or something
- Flush();
- m_LastSentDimension = a_World.GetDimension();
-}
-
-
-
-
-
-void cProtocol125::SendLoginSuccess(void)
-{
- // Not supported in this protocol version
-}
-
-
-
-
-
-void cProtocol125::SendMapColumn(int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale)
-{
- cCSLock Lock(m_CSPacket);
-
- WriteByte (PACKET_ITEM_DATA);
- WriteShort(E_ITEM_MAP);
- WriteShort((short)a_ID);
- WriteShort((short)(3 + a_Length));
-
- WriteByte(0);
- WriteChar((char)a_X);
- WriteChar((char)a_Y);
-
- SendData((const char *)a_Colors, a_Length);
-
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale)
-{
- cCSLock Lock(m_CSPacket);
-
- WriteByte (PACKET_ITEM_DATA);
- WriteShort(E_ITEM_MAP);
- WriteShort((short)a_ID);
- WriteShort((short)(1 + (3 * a_Decorators.size())));
-
- WriteByte(1);
-
- for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it)
- {
- WriteByte((Byte)(it->GetType() << 4) | (it->GetRot() & 0xf));
- WriteByte((Byte)it->GetPixelX());
- WriteByte((Byte)it->GetPixelZ());
- }
-
- Flush();
-}
-
-
-
-
-
-
-void cProtocol125::SendMapInfo(int a_ID, unsigned int a_Scale)
-{
- // This protocol doesn't support such message
- UNUSED(a_ID);
- UNUSED(a_Scale);
-}
-
-
-
-
-
-void cProtocol125::SendPickupSpawn(const cPickup & a_Pickup)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_PICKUP_SPAWN);
- WriteInt (a_Pickup.GetUniqueID());
- const cItem & Item = a_Pickup.GetItem();
- WriteShort (Item.m_ItemType);
- WriteChar (Item.m_ItemCount);
- WriteShort (Item.m_ItemDamage);
- WriteVectorI((Vector3i)(a_Pickup.GetPosition() * 32));
- WriteByte ((char)(a_Pickup.GetSpeedX() * 8));
- WriteByte ((char)(a_Pickup.GetSpeedY() * 8));
- WriteByte ((char)(a_Pickup.GetSpeedZ() * 8));
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendEntityAnimation(const cEntity & a_Entity, char a_Animation)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ANIMATION);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar(a_Animation);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::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)
-{
- // Not supported by this protocol version
-}
-
-
-
-
-
-void cProtocol125::SendPaintingSpawn(const cPainting & a_Painting)
-{
- // Not implemented in this protocol version
- UNUSED(a_Painting);
-}
-
-
-
-
-
-void cProtocol125::SendPlayerListAddPlayer(const cPlayer & a_Player)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_PLAYER_LIST_ITEM);
- WriteString(a_Player.GetPlayerListName());
- WriteBool (true);
- WriteShort (a_Player.GetClientHandle()->GetPing());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendPlayerListRemovePlayer(const cPlayer & a_Player)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_PLAYER_LIST_ITEM);
- WriteString(a_Player.GetPlayerListName());
- WriteBool (false);
- WriteShort (0);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendPlayerListUpdateGameMode(const cPlayer & a_Player)
-{
- // Not implemented in this protocol version
- UNUSED(a_Player);
-}
-
-
-
-
-
-void cProtocol125::SendPlayerListUpdatePing(const cPlayer & a_Player)
-{
- // It is a simple add player packet in this protocol.
- SendPlayerListAddPlayer(a_Player);
-}
-
-
-
-
-
-void cProtocol125::SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName)
-{
- // Not implemented in this protocol version
- UNUSED(a_Player);
- UNUSED(a_CustomName);
-}
-
-
-
-
-
-void cProtocol125::SendPlayerMaxSpeed(void)
-{
- // Not supported by this protocol version
-}
-
-
-
-
-
-void cProtocol125::SendPlayerMoveLook(void)
-{
- cCSLock Lock(m_CSPacket);
-
- /*
- LOGD("Sending PlayerMoveLook: {%0.2f, %0.2f, %0.2f}, stance %0.2f, OnGround: %d",
- m_Player->GetPosX(), m_Player->GetPosY(), m_Player->GetPosZ(), m_Player->GetStance(), m_Player->IsOnGround() ? 1 : 0
- );
- */
-
- WriteByte(PACKET_PLAYER_MOVE_LOOK);
- cPlayer * Player = m_Client->GetPlayer();
- WriteDouble(Player->GetPosX());
- WriteDouble(Player->GetStance() + 0.03); // Add a small amount so that the player doesn't start inside a block
- WriteDouble(Player->GetPosY() + 0.03); // Add a small amount so that the player doesn't start inside a block
- WriteDouble(Player->GetPosZ());
- WriteFloat ((float)(Player->GetYaw()));
- WriteFloat ((float)(Player->GetPitch()));
- WriteBool (Player->IsOnGround());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendPlayerPosition(void)
-{
- cCSLock Lock(m_CSPacket);
- LOGD("Ignore send PlayerPos"); // PlayerPos is a C->S packet only now
-}
-
-
-
-
-
-void cProtocol125::SendPlayerSpawn(const cPlayer & a_Player)
-{
- const cItem & HeldItem = a_Player.GetEquippedItem();
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_PLAYER_SPAWN);
- WriteInt (a_Player.GetUniqueID());
- if (a_Player.HasCustomName())
- {
- WriteString(a_Player.GetCustomName());
- }
- else
- {
- WriteString(a_Player.GetName());
- }
- WriteInt ((int)(a_Player.GetPosX() * 32));
- WriteInt ((int)(a_Player.GetPosY() * 32));
- WriteInt ((int)(a_Player.GetPosZ() * 32));
- WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256));
- WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256));
- WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendPluginMessage(const AString & a_Channel, const AString & a_Message)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_PLUGIN_MESSAGE);
- WriteString(a_Channel);
- WriteShort((short)a_Message.size());
- SendData(a_Message.data(), a_Message.size());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendRemoveEntityEffect(const cEntity & a_Entity, int a_EffectID)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_REMOVE_ENTITY_EFFECT);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar((char)a_EffectID);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
-{
- cCSLock Lock(m_CSPacket);
- if ((m_LastSentDimension == a_Dimension) && !a_ShouldIgnoreDimensionChecks)
- {
- // Must not send a respawn for the world with the same dimension, the client goes cuckoo if we do (unless we are respawning from death)
- return;
- }
- cPlayer * Player = m_Client->GetPlayer();
- WriteByte (PACKET_RESPAWN);
- WriteInt ((int)(a_Dimension));
- WriteByte (2); // TODO: Difficulty; 2 = Normal
- WriteChar ((char)Player->GetGameMode());
- WriteShort (256); // Current world height
- WriteString("default");
- Flush();
- m_LastSentDimension = a_Dimension;
-}
-
-
-
-
-
-void cProtocol125::SendExperience(void)
-{
- cCSLock Lock(m_CSPacket);
- cPlayer * Player = m_Client->GetPlayer();
- WriteByte (PACKET_EXPERIENCE);
- WriteFloat (Player->GetXpPercentage());
- WriteShort (Player->GetXpLevel());
- WriteShort (Player->GetCurrentXp());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendExperienceOrb(const cExpOrb & a_ExpOrb)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_SPAWN_EXPERIENCE_ORB);
- WriteInt(a_ExpOrb.GetUniqueID());
- WriteInt((int) a_ExpOrb.GetPosX());
- WriteInt((int) a_ExpOrb.GetPosY());
- WriteInt((int) a_ExpOrb.GetPosZ());
- WriteShort((short)a_ExpOrb.GetReward());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode)
-{
- // This protocol version doesn't support such message
- UNUSED(a_Name);
- UNUSED(a_DisplayName);
- UNUSED(a_Mode);
-}
-
-
-
-
-
-void cProtocol125::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
-{
- // Not needed in this protocol version
-}
-
-
-
-
-
-void cProtocol125::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data)
-{
- // Not implemented in this protocol version
-}
-
-
-
-
-
-void cProtocol125::SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock)
-{
- // This protocol version implements falling blocks using the spawn object / vehicle packet:
- SendSpawnObject(a_FallingBlock, 70, a_FallingBlock.GetBlockType(), 0, 0);
-}
-
-
-
-
-
-void cProtocol125::SendSpawnMob(const cMonster & a_Mob)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_SPAWN_MOB);
- WriteInt (a_Mob.GetUniqueID());
- WriteByte ((Byte)a_Mob.GetMobType());
- WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32));
- WriteByte (0);
- WriteByte (0);
- WriteByte (0);
-
- WriteCommonMetadata(a_Mob);
- WriteMobMetadata(a_Mob);
- WriteByte(0x7f);
-
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendSpawnObject(const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch)
-{
- UNUSED(a_Yaw);
- UNUSED(a_Pitch);
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_SPAWN_OBJECT);
- WriteInt (a_Entity.GetUniqueID());
- WriteChar(a_ObjectType);
- 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();
-}
-
-
-
-
-
-void cProtocol125::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_SPAWN_OBJECT);
- WriteInt (a_Vehicle.GetUniqueID());
- WriteChar (a_VehicleType);
- WriteInt ((int)(a_Vehicle.GetPosX() * 32));
- WriteInt ((int)(a_Vehicle.GetPosY() * 32));
- WriteInt ((int)(a_Vehicle.GetPosZ() * 32));
- WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256));
- WriteByte ((Byte)((a_Vehicle.GetYaw() / 360.f) * 256));
- WriteInt (a_VehicleSubType);
- if (a_VehicleSubType != 0)
- {
- WriteShort((short)(a_Vehicle.GetSpeedX() * 400));
- WriteShort((short)(a_Vehicle.GetSpeedY() * 400));
- WriteShort((short)(a_Vehicle.GetSpeedZ() * 400));
- }
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendStatistics(const cStatManager & a_Manager)
-{
- /* NOTE:
- Versions prior to minecraft 1.7 use an incremental statistic sync
- method. The current setup does not allow us to implement that, because
- of performance considerations.
- */
-#if 0
- for (unsigned int i = 0; i < (unsigned int)statCount; ++i)
- {
- StatValue Value = m_Manager->GetValue((eStatistic) i);
-
- unsigned int StatID = cStatInfo::GetID((eStatistic) i);
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_INCREMENT_STATISTIC);
- WriteInt(StatID);
- WriteByte(Value); /* Can overflow! */
- Flush();
- }
-#endif
-}
-
-
-
-
-
-void cProtocol125::SendTabCompletionResults(const AStringVector & a_Results)
-{
- // This protocol version doesn't support tab completion
- UNUSED(a_Results);
-}
-
-
-
-
-
-void cProtocol125::SendTeleportEntity(const cEntity & a_Entity)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_ENT_TELEPORT);
- WriteInt (a_Entity.GetUniqueID());
- WriteInt ((int)(floor(a_Entity.GetPosX() * 32)));
- WriteInt ((int)(floor(a_Entity.GetPosY() * 32)));
- WriteInt ((int)(floor(a_Entity.GetPosZ() * 32)));
- WriteChar ((char)((a_Entity.GetYaw() / 360.f) * 256));
- WriteChar ((char)((a_Entity.GetPitch() / 360.f) * 256));
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_THUNDERBOLT);
- WriteInt (0x7fffffff); // Entity ID of the thunderbolt; we use a constant one
- WriteBool(true); // Unknown bool
- WriteInt (a_BlockX * 32);
- WriteInt (a_BlockY * 32);
- WriteInt (a_BlockZ * 32);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
-{
- // This protocol doesn't support a_DoDaylightCycle on false.
- UNUSED(a_DoDaylightCycle);
-
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_UPDATE_TIME);
- // Use a_WorldAge for daycount, and a_TimeOfDay for the proper time of day:
- WriteInt64((24000 * (a_WorldAge / 24000)) + (a_TimeOfDay % 24000));
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
-{
- cCSLock Lock(m_CSPacket);
- SendPreChunk(a_ChunkX, a_ChunkZ, false);
-}
-
-
-
-
-
-void cProtocol125::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
-)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte ((unsigned char)PACKET_UPDATE_SIGN);
- WriteInt (a_BlockX);
- WriteShort ((short)a_BlockY);
- WriteInt (a_BlockZ);
- WriteString(a_Line1);
- WriteString(a_Line2);
- WriteString(a_Line3);
- WriteString(a_Line4);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendUseBed(const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_USE_BED);
- WriteInt (a_Entity.GetUniqueID());
- WriteByte(0); // Unknown byte only 0 has been observed
- WriteInt (a_BlockX);
- WriteByte((Byte)a_BlockY);
- WriteInt (a_BlockZ);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendWeather(eWeather a_Weather)
-{
- cCSLock Lock(m_CSPacket);
- switch (a_Weather)
- {
- case eWeather_Sunny:
- {
- WriteByte(PACKET_CHANGE_GAME_STATE);
- WriteByte(2); // Stop rain
- WriteByte(0); // Unused
- Flush();
- break;
- }
-
- case eWeather_Rain:
- case eWeather_ThunderStorm:
- {
- WriteByte(PACKET_CHANGE_GAME_STATE);
- WriteByte(1); // Begin rain
- WriteByte(0); // Unused
- Flush();
- break;
- }
- }
-}
-
-
-
-
-
-void cProtocol125::SendWholeInventory(const cWindow & a_Window)
-{
- cCSLock Lock(m_CSPacket);
- cItems Slots;
- a_Window.GetSlots(*(m_Client->GetPlayer()), Slots);
- SendWindowSlots(a_Window.GetWindowID(), (int)Slots.size(), &(Slots[0]));
-}
-
-
-
-
-
-void cProtocol125::SendWindowClose(const cWindow & a_Window)
-{
- if (a_Window.GetWindowType() == cWindow::wtInventory)
- {
- // Do not send inventory-window-close
- return;
- }
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_WINDOW_CLOSE);
- WriteChar(a_Window.GetWindowID());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendWindowOpen(const cWindow & a_Window)
-{
- if (a_Window.GetWindowType() < 0)
- {
- // Do not send for inventory windows
- return;
- }
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_WINDOW_OPEN);
- WriteChar (a_Window.GetWindowID());
- WriteByte ((Byte)a_Window.GetWindowType());
- WriteString(a_Window.GetWindowTitle());
- WriteByte ((Byte)a_Window.GetNumNonInventorySlots());
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendWindowProperty(const cWindow & a_Window, int a_Property, int a_Value)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_WINDOW_PROPERTY);
- WriteChar (a_Window.GetWindowID());
- WriteShort(a_Property);
- WriteShort(a_Value);
- Flush();
-}
-
-
-
-
-
-AString cProtocol125::GetAuthServerID(void)
-{
- // http://wiki.vg/wiki/index.php?title=Session&oldid=2262
- // The server generates a random hash and that is used for all clients, unmodified
- return cRoot::Get()->GetServer()->GetServerID();
-}
-
-
-
-
-
-void cProtocol125::SendData(const char * a_Data, size_t a_Size)
-{
- m_Client->SendData(a_Data, a_Size);
-}
-
-
-
-
-
-void cProtocol125::DataReceived(const char * a_Data, size_t a_Size)
-{
- if (!m_ReceivedData.Write(a_Data, a_Size))
- {
- // Too much data in the incoming queue, report to caller:
- m_Client->PacketBufferFull();
- return;
- }
-
- // Parse and handle all complete packets in m_ReceivedData:
- while (m_ReceivedData.CanReadBytes(1))
- {
- unsigned char PacketType;
- m_ReceivedData.ReadByte(PacketType);
- switch (ParsePacket(PacketType))
- {
- case PARSE_UNKNOWN:
- {
- // An unknown packet has been received, notify the client and abort:
- m_Client->PacketUnknown(PacketType);
- return;
- }
- case PARSE_ERROR:
- {
- // An error occurred while parsing a known packet, notify the client and abort:
- m_Client->PacketError(PacketType);
- return;
- }
- case PARSE_INCOMPLETE:
- {
- // Incomplete packet, bail out and process with the next batch of data
- m_ReceivedData.ResetRead();
- return;
- }
- default:
- {
- // Packet successfully parsed, commit the read data and try again one more packet
- m_ReceivedData.CommitRead();
- break;
- }
- }
- }
-}
-
-
-
-
-
-int cProtocol125::ParsePacket(unsigned char a_PacketType)
-{
- switch (a_PacketType)
- {
- default: return PARSE_UNKNOWN;
- case PACKET_ANIMATION: return ParseArmAnim();
- case PACKET_BLOCK_DIG: return ParseBlockDig();
- case PACKET_BLOCK_PLACE: return ParseBlockPlace();
- case PACKET_CHAT: return ParseChat();
- case PACKET_CREATIVE_INVENTORY_ACTION: return ParseCreativeInventoryAction();
- case PACKET_DISCONNECT: return ParseDisconnect();
- case PACKET_HANDSHAKE: return ParseHandshake();
- case PACKET_KEEP_ALIVE: return ParseKeepAlive();
- case PACKET_LOGIN: return ParseLogin();
- case PACKET_PACKET_ENTITY_ACTION: return ParseEntityAction();
- case PACKET_PING: return ParsePing();
- case PACKET_PLAYER_ABILITIES: return ParsePlayerAbilities();
- case PACKET_PLAYER_LOOK: return ParsePlayerLook();
- case PACKET_PLAYER_MOVE_LOOK: return ParsePlayerMoveLook();
- case PACKET_PLAYER_ON_GROUND: return ParsePlayerOnGround();
- case PACKET_PLAYER_POS: return ParsePlayerPosition();
- case PACKET_PLUGIN_MESSAGE: return ParsePluginMessage();
- case PACKET_RESPAWN: return ParseRespawn();
- case PACKET_SLOT_SELECTED: return ParseSlotSelected();
- case PACKET_UPDATE_SIGN: return ParseUpdateSign();
- case PACKET_USE_ENTITY: return ParseUseEntity();
- case PACKET_ENCHANT_ITEM: return ParseEnchantItem();
- case PACKET_WINDOW_CLICK: return ParseWindowClick();
- case PACKET_WINDOW_CLOSE: return ParseWindowClose();
- }
-}
-
-
-
-
-
-int cProtocol125::ParseArmAnim(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, EntityID);
- HANDLE_PACKET_READ(ReadChar, char, Animation);
- m_Client->HandleAnimation(Animation);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseBlockDig(void)
-{
- HANDLE_PACKET_READ(ReadChar, char, Status);
- HANDLE_PACKET_READ(ReadBEInt, int, PosX);
- HANDLE_PACKET_READ(ReadByte, Byte, PosY);
- HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
- HANDLE_PACKET_READ(ReadChar, char, BlockFace);
- m_Client->HandleLeftClick(PosX, PosY, PosZ, static_cast<eBlockFace>(BlockFace), Status);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseBlockPlace(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, PosX);
- HANDLE_PACKET_READ(ReadByte, Byte, PosY);
- HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
- HANDLE_PACKET_READ(ReadChar, char, BlockFace);
-
- cItem HeldItem;
- int res = ParseItem(HeldItem);
- if (res < 0)
- {
- return res;
- }
-
- // 1.2.5 didn't have any cursor position, so use 8, 8, 8, so that halfslabs and stairs work correctly and the special value is recognizable.
- m_Client->HandleRightClick(PosX, PosY, PosZ, static_cast<eBlockFace>(BlockFace), 8, 8, 8, HeldItem);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseChat(void)
-{
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Message);
- m_Client->HandleChat(Message);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseCreativeInventoryAction(void)
-{
- HANDLE_PACKET_READ(ReadBEShort, short, SlotNum);
- cItem HeldItem;
- int res = ParseItem(HeldItem);
- if (res < 0)
- {
- return res;
- }
- m_Client->HandleCreativeInventory(SlotNum, HeldItem);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseDisconnect(void)
-{
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Reason);
- m_Client->HandleDisconnect(Reason);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseEntityAction(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, EntityID);
- HANDLE_PACKET_READ(ReadChar, char, ActionID);
-
- switch (ActionID)
- {
- case 1: m_Client->HandleEntityCrouch(EntityID, true); break; // Crouch
- case 2: m_Client->HandleEntityCrouch(EntityID, false); break; // Uncrouch
- case 3: m_Client->HandleEntityLeaveBed(EntityID); break; // Leave Bed
- case 4: m_Client->HandleEntitySprinting(EntityID, true); break; // Start sprinting
- case 5: m_Client->HandleEntitySprinting(EntityID, false); break; // Stop sprinting
- }
-
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseHandshake(void)
-{
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Username);
-
- AStringVector UserData = StringSplit(Username, ";"); // "FakeTruth;localhost:25565"
- if (UserData.empty())
- {
- m_Client->Kick("Did not receive username");
- return PARSE_OK;
- }
- m_Username = UserData[0];
-
- LOGD("HANDSHAKE %s", Username.c_str());
-
- if (!m_Client->HandleHandshake( m_Username))
- {
- return PARSE_OK; // Player is not allowed into the server
- }
-
- SendHandshake(cRoot::Get()->GetServer()->GetServerID());
- LOGD("User \"%s\" was sent a handshake response", m_Username.c_str());
-
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseKeepAlive(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, KeepAliveID);
- m_Client->HandleKeepAlive(KeepAliveID);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseLogin(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, ProtocolVersion);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Username);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, LevelType);
- HANDLE_PACKET_READ(ReadBEInt, int, ServerMode);
- HANDLE_PACKET_READ(ReadBEInt, int, Dimension);
- HANDLE_PACKET_READ(ReadChar, char, Difficulty);
- HANDLE_PACKET_READ(ReadByte, Byte, WorldHeight);
- HANDLE_PACKET_READ(ReadByte, Byte, MaxPlayers);
-
- if (ProtocolVersion < 29)
- {
- m_Client->Kick("Your client is outdated!");
- return PARSE_OK;
- }
- else if (ProtocolVersion > 29)
- {
- m_Client->Kick("Your client version is higher than the server!");
- return PARSE_OK;
- }
-
- if (m_Username.compare(Username) != 0)
- {
- LOGWARNING("Login Username (\"%s\") does not match Handshake username (\"%s\") for client @ \"%s\", kicking",
- Username.c_str(),
- m_Username.c_str(),
- m_Client->GetIPString().c_str()
- );
- m_Client->Kick("Hacked client"); // Don't tell them why we don't want them
- return PARSE_OK;
- }
-
- m_Client->HandleLogin(ProtocolVersion, Username);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParsePing(void)
-{
- // Packet has no more data
- m_Client->HandlePing();
- return PARSE_OK;
-}
-
-
-
-
-
-
-int cProtocol125::ParsePlayerAbilities(void)
-{
- HANDLE_PACKET_READ(ReadBool, bool, Invulnerable);
- HANDLE_PACKET_READ(ReadBool, bool, IsFlying);
- HANDLE_PACKET_READ(ReadBool, bool, CanFly);
- HANDLE_PACKET_READ(ReadBool, bool, InstaMine);
- // TODO: m_Client->HandlePlayerAbilities(...);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParsePlayerLook(void)
-{
- HANDLE_PACKET_READ(ReadBEFloat, float, Rotation);
- HANDLE_PACKET_READ(ReadBEFloat, float, Pitch);
- HANDLE_PACKET_READ(ReadBool, bool, IsOnGround);
- m_Client->HandlePlayerLook(Rotation, Pitch, IsOnGround);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParsePlayerMoveLook(void)
-{
- HANDLE_PACKET_READ(ReadBEDouble, double, PosX);
- HANDLE_PACKET_READ(ReadBEDouble, double, PosY);
- HANDLE_PACKET_READ(ReadBEDouble, double, Stance);
- HANDLE_PACKET_READ(ReadBEDouble, double, PosZ);
- HANDLE_PACKET_READ(ReadBEFloat, float, Rotation);
- HANDLE_PACKET_READ(ReadBEFloat, float, Pitch);
- HANDLE_PACKET_READ(ReadBool, bool, IsOnGround);
- // LOGD("Recv PML: {%0.2f, %0.2f, %0.2f}, Stance %0.2f, Gnd: %d", PosX, PosY, PosZ, Stance, IsOnGround ? 1 : 0);
- m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Stance, Rotation, Pitch, IsOnGround);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParsePlayerOnGround(void)
-{
- HANDLE_PACKET_READ(ReadBool, bool, IsOnGround);
- // TODO: m_Client->HandleFlying(IsOnGround);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParsePlayerPosition(void)
-{
- HANDLE_PACKET_READ(ReadBEDouble, double, PosX);
- HANDLE_PACKET_READ(ReadBEDouble, double, PosY);
- HANDLE_PACKET_READ(ReadBEDouble, double, Stance);
- HANDLE_PACKET_READ(ReadBEDouble, double, PosZ);
- HANDLE_PACKET_READ(ReadBool, bool, IsOnGround);
- m_Client->HandlePlayerPos(PosX, PosY, PosZ, Stance, IsOnGround);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParsePluginMessage(void)
-{
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, ChannelName);
- HANDLE_PACKET_READ(ReadBEShort, short, Length);
- AString Data;
- if (!m_ReceivedData.ReadString(Data, (size_t)Length))
- {
- m_ReceivedData.CheckValid();
- return PARSE_INCOMPLETE;
- }
- m_ReceivedData.CheckValid();
-
- // TODO: Process the data
- LOGD("Received %d bytes of plugin data on channel \"%s\".", Length, ChannelName.c_str());
-
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseRespawn(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, Dimension);
- HANDLE_PACKET_READ(ReadChar, char, Difficulty);
- HANDLE_PACKET_READ(ReadChar, char, CreativeMode);
- HANDLE_PACKET_READ(ReadBEShort, short, WorldHeight);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, LevelType);
- m_Client->HandleRespawn();
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseSlotSelected(void)
-{
- HANDLE_PACKET_READ(ReadBEShort, short, SlotNum);
- m_Client->HandleSlotSelected(SlotNum);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseUpdateSign(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, BlockX);
- HANDLE_PACKET_READ(ReadBEShort, short, BlockY);
- HANDLE_PACKET_READ(ReadBEInt, int, BlockZ);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line1);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line2);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line3);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Line4);
- m_Client->HandleUpdateSign(BlockX, BlockY, BlockZ, Line1, Line2, Line3, Line4);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseUseEntity(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, SourceEntityID);
- HANDLE_PACKET_READ(ReadBEInt, int, TargetEntityID);
- HANDLE_PACKET_READ(ReadBool, bool, IsLeftClick);
- m_Client->HandleUseEntity(TargetEntityID, IsLeftClick);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseEnchantItem(void)
-{
- HANDLE_PACKET_READ(ReadByte, Byte, WindowID);
- HANDLE_PACKET_READ(ReadByte, Byte, Enchantment);
-
- m_Client->HandleEnchantItem(WindowID, Enchantment);
-
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseWindowClick(void)
-{
- HANDLE_PACKET_READ(ReadChar, char, WindowID);
- HANDLE_PACKET_READ(ReadBEShort, short, SlotNum);
- HANDLE_PACKET_READ(ReadBool, bool, IsRightClick);
- HANDLE_PACKET_READ(ReadBEShort, short, TransactionID);
- HANDLE_PACKET_READ(ReadBool, bool, IsShiftPressed);
- cItem HeldItem;
- int res = ParseItem(HeldItem);
- if (res < 0)
- {
- return res;
- }
-
- // Convert IsShiftPressed, IsRightClick, SlotNum and HeldItem into eClickAction used in the newer protocols:
- eClickAction Action;
- if (IsRightClick)
- {
- if (IsShiftPressed)
- {
- Action = caShiftRightClick;
- }
- else
- {
- if (SlotNum == -999)
- {
- Action = (HeldItem.IsEmpty()) ? caRightClickOutsideHoldNothing : caRightClickOutside;
- }
- else
- {
- Action = caRightClick;
- }
- }
- }
- else
- {
- // IsLeftClick
- if (IsShiftPressed)
- {
- Action = caShiftLeftClick;
- }
- else
- {
- if (SlotNum == -999)
- {
- Action = (HeldItem.IsEmpty()) ? caLeftClickOutsideHoldNothing : caRightClickOutside;
- }
- else
- {
- Action = caLeftClick;
- }
- }
- }
- m_Client->HandleWindowClick(WindowID, SlotNum, Action, HeldItem);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol125::ParseWindowClose(void)
-{
- HANDLE_PACKET_READ(ReadChar, char, WindowID);
- m_Client->HandleWindowClose(WindowID);
- return PARSE_OK;
-}
-
-
-
-
-
-void cProtocol125::SendPreChunk(int a_ChunkX, int a_ChunkZ, bool a_ShouldLoad)
-{
- WriteByte(PACKET_PRE_CHUNK);
- WriteInt (a_ChunkX);
- WriteInt (a_ChunkZ);
- WriteBool(a_ShouldLoad);
- Flush();
-}
-
-
-
-
-
-void cProtocol125::SendWindowSlots(char a_WindowID, int a_NumItems, const cItem * a_Items)
-{
- WriteByte (PACKET_INVENTORY_WHOLE);
- WriteChar (a_WindowID);
- WriteShort((short)a_NumItems);
-
- for (int j = 0; j < a_NumItems; j++)
- {
- WriteItem(a_Items[j]);
- }
- Flush();
-}
-
-
-
-
-
-void cProtocol125::WriteItem(const cItem & a_Item)
-{
- short ItemType = a_Item.m_ItemType;
- ASSERT(ItemType >= -1); // Check validity of packets in debug runtime
- if (ItemType <= 0)
- {
- // Fix, to make sure no invalid values are sent.
- ItemType = -1;
- }
-
- WriteShort(ItemType);
- if (a_Item.IsEmpty())
- {
- return;
- }
-
- WriteChar (a_Item.m_ItemCount);
- WriteShort(a_Item.m_ItemDamage);
-
- if (cItem::IsEnchantable(a_Item.m_ItemType))
- {
- // TODO: Implement enchantments
- WriteShort(-1);
- }
-}
-
-
-
-
-
-int cProtocol125::ParseItem(cItem & a_Item)
-{
- HANDLE_PACKET_READ(ReadBEShort, short, ItemType);
-
- if (ItemType <= -1)
- {
- a_Item.Empty();
- return PARSE_OK;
- }
- a_Item.m_ItemType = ItemType;
-
- HANDLE_PACKET_READ(ReadChar, char, ItemCount);
- HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage);
- a_Item.m_ItemCount = ItemCount;
- a_Item.m_ItemDamage = ItemDamage;
- if (ItemCount <= 0)
- {
- a_Item.Empty();
- }
-
- if (!cItem::IsEnchantable(ItemType))
- {
- return PARSE_OK;
- }
-
- HANDLE_PACKET_READ(ReadBEShort, short, EnchantNumBytes);
-
- if (EnchantNumBytes <= 0)
- {
- return PARSE_OK;
- }
-
- // TODO: Enchantment not implemented yet!
- if (!m_ReceivedData.SkipRead((size_t)EnchantNumBytes))
- {
- return PARSE_INCOMPLETE;
- }
-
- return PARSE_OK;
-}
-
-
-
-
-
-void cProtocol125::WriteCommonMetadata(const cEntity & a_Entity)
-{
- Byte CommonMetadata = 0;
-
- if (a_Entity.IsOnFire())
- {
- CommonMetadata |= 0x1;
- }
- if (a_Entity.IsCrouched())
- {
- CommonMetadata |= 0x2;
- }
- if (a_Entity.IsRiding())
- {
- CommonMetadata |= 0x4;
- }
- if (a_Entity.IsSprinting())
- {
- CommonMetadata |= 0x8;
- }
- if (a_Entity.IsRclking())
- {
- CommonMetadata |= 0x10;
- }
- if (a_Entity.IsInvisible())
- {
- CommonMetadata |= 0x20;
- }
-
- WriteByte(0x0);
- WriteByte(CommonMetadata);
-}
-
-
-
-
-
-void cProtocol125::WriteEntityMetadata(const cEntity & a_Entity)
-{
- if (a_Entity.IsMinecart())
- {
- WriteByte(0x51);
- // No idea how Mojang makes their carts shakey shakey, so here is a complicated one-liner expression that does something similar
- WriteInt( (((a_Entity.GetMaxHealth() / 2) - (a_Entity.GetHealth() - (a_Entity.GetMaxHealth() / 2))) * ((const cMinecart &)a_Entity).LastDamage()) * 4);
- WriteByte(0x52);
- WriteInt(1); // Shaking direction, doesn't seem to affect anything
- WriteByte(0x73);
- WriteFloat((float)(((const cMinecart &)a_Entity).LastDamage() + 10)); // Damage taken / shake effect multiplyer
-
- if (((cMinecart &)a_Entity).GetPayload() == cMinecart::mpFurnace)
- {
- WriteByte(0x10);
- WriteByte(((const cMinecartWithFurnace &)a_Entity).IsFueled() ? 1 : 0); // Fueled?
- }
- }
- else if ((a_Entity.IsProjectile() && ((cProjectileEntity &)a_Entity).GetProjectileKind() == cProjectileEntity::pkArrow))
- {
- WriteByte(0x10);
- WriteByte(((const cArrowEntity &)a_Entity).IsCritical() ? 1 : 0); // Critical hitting arrow?
- }
-}
-
-
-
-
-
-void cProtocol125::WriteMobMetadata(const cMonster & a_Mob)
-{
- switch (a_Mob.GetMobType())
- {
- case mtCreeper:
- {
- WriteByte(0x10);
- WriteChar(((const cCreeper &)a_Mob).IsBlowing() ? 1 : -1); // Blowing up?
- WriteByte(0x11);
- WriteByte(((const cCreeper &)a_Mob).IsCharged() ? 1 : 0); // Lightning-charged?
- break;
- }
- case mtBat:
- {
- WriteByte(0x10);
- WriteByte(((const cBat &)a_Mob).IsHanging() ? 1 : 0); // Upside down?
- break;
- }
- case mtPig:
- {
- WriteByte(0x10);
- WriteByte(((const cPig &)a_Mob).IsSaddled() ? 1 : 0); // Saddled?
- break;
- }
- case mtVillager:
- {
- WriteByte(0x50);
- WriteInt(((const cVillager &)a_Mob).GetVilType()); // What sort of TESTIFICATE?
- break;
- }
- case mtZombie:
- {
- WriteByte(0xC);
- WriteByte(((const cZombie &)a_Mob).IsBaby() ? 1 : 0); // Baby zombie?
- WriteByte(0xD);
- WriteByte(((const cZombie &)a_Mob).IsVillagerZombie() ? 1 : 0); // Converted zombie?
- WriteByte(0xE);
- WriteByte(((const cZombie &)a_Mob).IsConverting() ? 1 : 0); // Converted-but-converting-back zombllager?
- break;
- }
- case mtGhast:
- {
- WriteByte(0x10);
- WriteByte(((const cGhast &)a_Mob).IsCharging()); // About to spit a flameball?
- break;
- }
- case mtWolf:
- {
- Byte WolfStatus = 0;
- if (((const cWolf &)a_Mob).IsSitting())
- {
- WolfStatus |= 0x1;
- }
- if (((const cWolf &)a_Mob).IsAngry())
- {
- WolfStatus |= 0x2;
- }
- if (((const cWolf &)a_Mob).IsTame())
- {
- WolfStatus |= 0x4;
- }
- WriteByte(0x10);
- WriteByte(WolfStatus);
-
- WriteByte(0x72);
- WriteFloat((float)(a_Mob.GetHealth())); // Tail health-o-meter (only shown when tamed, by the way)
- WriteByte(0x13);
- WriteByte(((const cWolf &)a_Mob).IsBegging() ? 1 : 0); // Ultra cute mode?
- break;
- }
- case mtSheep:
- {
- // [1](1111)
- // [] = Is sheared? () = Color, from 0 to 15
-
- WriteByte(0x10);
- Byte SheepMetadata = 0;
- SheepMetadata = (Byte)((const cSheep &)a_Mob).GetFurColor();
-
- if (((const cSheep &)a_Mob).IsSheared())
- {
- SheepMetadata |= 0x16;
- }
- WriteByte(SheepMetadata);
- break;
- }
- case mtEnderman:
- {
- WriteByte(0x10);
- WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedBlock())); // Block that he stole from your house
- WriteByte(0x11);
- WriteByte((Byte)(((const cEnderman &)a_Mob).GetCarriedMeta())); // Meta of block that he stole from your house
- WriteByte(0x12);
- WriteByte(((const cEnderman &)a_Mob).IsScreaming() ? 1 : 0); // Screaming at your face?
- break;
- }
- case mtSkeleton:
- {
- WriteByte(0xD);
- WriteByte(((const cSkeleton &)a_Mob).IsWither() ? 1 : 0); // It's a skeleton, but it's not
- break;
- }
- case mtWitch:
- {
- WriteByte(0x15);
- WriteByte(((const cWitch &)a_Mob).IsAngry() ? 1 : 0); // Aggravated? Doesn't seem to do anything
- break;
- }
- case mtWither:
- {
- WriteByte(0x54); // Int at index 20
- WriteInt((Int32)((const cWither &)a_Mob).GetWitherInvulnerableTicks());
- WriteByte(0x66); // Float at index 6
- WriteFloat((float)(a_Mob.GetHealth()));
- break;
- }
- case mtSlime:
- case mtMagmaCube:
- {
- WriteByte(0x10);
- if (a_Mob.GetMobType() == mtSlime)
- {
- WriteByte((Byte)((const cSlime &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME
- }
- else
- {
- WriteByte((Byte)((const cMagmaCube &)a_Mob).GetSize()); // Size of slime - HEWGE, meh, cute BABBY SLIME
- }
- break;
- }
- case mtHorse:
- {
- int Flags = 0;
- if (((const cHorse &)a_Mob).IsTame())
- {
- Flags |= 0x2;
- }
- if (((const cHorse &)a_Mob).IsSaddled())
- {
- Flags |= 0x4;
- }
- if (((const cHorse &)a_Mob).IsChested())
- {
- Flags |= 0x8;
- }
- if (((const cHorse &)a_Mob).IsBaby())
- {
- Flags |= 0x10; // IsBred flag, according to wiki.vg - don't think it does anything in multiplayer
- }
- if (((const cHorse &)a_Mob).IsEating())
- {
- Flags |= 0x20;
- }
- if (((const cHorse &)a_Mob).IsRearing())
- {
- Flags |= 0x40;
- }
- if (((const cHorse &)a_Mob).IsMthOpen())
- {
- Flags |= 0x80;
- }
- WriteByte(0x50);
- WriteInt(Flags);
-
- WriteByte(0x13);
- WriteByte((Byte)((const cHorse &)a_Mob).GetHorseType()); // Type of horse (donkey, chestnut, etc.)
-
- WriteByte(0x54);
- int Appearance = 0;
- Appearance = ((const cHorse &)a_Mob).GetHorseColor(); // Mask FF
- Appearance |= ((const cHorse &)a_Mob).GetHorseStyle() * 256; // Mask FF00, so multiply by 256
- WriteInt(Appearance);
-
- WriteByte(0x56);
- WriteInt(((const cHorse &)a_Mob).GetHorseArmour()); // Horshey armour
- break;
- }
- default:
- {
- break;
- }
- }
-}
-
-
-
-
diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h
deleted file mode 100644
index 3ea116c3b..000000000
--- a/src/Protocol/Protocol125.h
+++ /dev/null
@@ -1,185 +0,0 @@
-
-// Protocol125.h
-
-// Interfaces to the cProtocol125 class representing the release 1.2.5 protocol (#29)
-
-
-
-
-
-#pragma once
-
-#include "Protocol.h"
-#include "../ByteBuffer.h"
-#include "../Entities/Painting.h"
-
-
-
-
-
-class cProtocol125 :
- public cProtocol
-{
- typedef cProtocol super;
-public:
- cProtocol125(cClientHandle * a_Client);
-
- /// Called when client sends some data:
- virtual void DataReceived(const char * a_Data, size_t a_Size) override;
-
- /// Sending stuff to clients (alphabetically sorted):
- virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
- virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
- virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
- virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
- virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
- virtual void SendChat (const AString & a_Message) override;
- virtual void SendChat (const cCompositeChat & a_Message) override;
- virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
- virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
- virtual void SendDestroyEntity (const cEntity & a_Entity) override;
- virtual void SendDisconnect (const AString & a_Reason) override;
- virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
- virtual void SendEntityEffect (const cEntity & a_Entity, int a_EffectID, int a_Amplifier, short a_Duration) override;
- virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
- virtual void SendEntityHeadLook (const cEntity & a_Entity) override;
- virtual void SendEntityLook (const cEntity & a_Entity) override;
- virtual void SendEntityMetadata (const cEntity & a_Entity) override;
- virtual void SendEntityProperties (const cEntity & a_Entity) override;
- virtual void SendEntityRelMove (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
- virtual void SendEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ) override;
- virtual void SendEntityStatus (const cEntity & a_Entity, char a_Status) override;
- virtual void SendEntityVelocity (const cEntity & a_Entity) override;
- virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override;
- virtual void SendGameMode (eGameMode a_GameMode) override;
- virtual void SendHealth (void) override;
- virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override;
- virtual void SendKeepAlive (int a_PingID) override;
- virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
- virtual void SendLoginSuccess (void) override;
- virtual void SendMapColumn (int a_ID, int a_X, int a_Y, const Byte * a_Colors, unsigned int a_Length, unsigned int m_Scale) override;
- virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override;
- virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override;
- virtual void 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) override;
- virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
- virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
- virtual void SendPlayerAbilities (void) override {} // This protocol doesn't support such message
- virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
- virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override;
- virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override;
- virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override;
- virtual void SendPlayerListUpdatePing (const cPlayer & a_Player) override;
- virtual void SendPlayerListUpdateDisplayName(const cPlayer & a_Player, const AString & a_CustomName) override;
- virtual void SendPlayerMaxSpeed (void) override;
- virtual void SendPlayerMoveLook (void) override;
- virtual void SendPlayerPosition (void) override;
- virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
- virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
- virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
- virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override;
- virtual void SendExperience (void) override;
- virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
- virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
- virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override {} // This protocol doesn't support such message
- virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override {} // This protocol doesn't support such message
- virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, 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 SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override;
- virtual void SendSpawnMob (const cMonster & a_Mob) override;
- virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override;
- virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override;
- virtual void SendStatistics (const cStatManager & a_Manager) override;
- virtual void SendTabCompletionResults (const AStringVector & a_Results) 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, bool a_DoDaylightCycle) override;
- virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
- virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override {}
- virtual void 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) override;
- virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ) override;
- virtual void SendWeather (eWeather a_Weather) override;
- virtual void SendWholeInventory (const cWindow & a_Window) override;
- virtual void SendWindowClose (const cWindow & a_Window) override;
- virtual void SendWindowOpen (const cWindow & a_Window) override;
- virtual void SendWindowProperty (const cWindow & a_Window, int a_Property, int a_Value) override;
-
- virtual AString GetAuthServerID(void) override;
-
-protected:
- /// Results of packet-parsing:
- enum eParseResult
- {
- PARSE_OK = 1,
- PARSE_ERROR = -1,
- PARSE_UNKNOWN = -2,
- PARSE_INCOMPLETE = -3,
- } ;
-
- cByteBuffer m_ReceivedData; ///< Buffer for the received data
-
- AString m_Username; ///< Stored in ParseHandshake(), compared to Login username
-
- /** The dimension that was last sent to a player in a Respawn or Login packet.
- Used to avoid Respawning into the same dimension, which confuses the client. */
- eDimension m_LastSentDimension;
-
- virtual void SendData(const char * a_Data, size_t a_Size) override;
-
- /// Sends the Handshake packet
- void SendHandshake(const AString & a_ConnectionHash);
-
- /// Parse the packet of the specified type from m_ReceivedData (switch into ParseXYZ())
- virtual int ParsePacket(unsigned char a_PacketType);
-
- // Specific packet parsers:
- virtual int ParseArmAnim (void);
- virtual int ParseBlockDig (void);
- virtual int ParseBlockPlace (void);
- virtual int ParseChat (void);
- virtual int ParseCreativeInventoryAction(void);
- virtual int ParseDisconnect (void);
- virtual int ParseEntityAction (void);
- virtual int ParseHandshake (void);
- virtual int ParseKeepAlive (void);
- virtual int ParseLogin (void);
- virtual int ParsePing (void);
- virtual int ParsePlayerAbilities (void);
- virtual int ParsePlayerLook (void);
- virtual int ParsePlayerMoveLook (void);
- virtual int ParsePlayerOnGround (void);
- virtual int ParsePlayerPosition (void);
- virtual int ParsePluginMessage (void);
- virtual int ParseRespawn (void);
- virtual int ParseSlotSelected (void);
- virtual int ParseUpdateSign (void);
- virtual int ParseUseEntity (void);
- virtual int ParseEnchantItem (void);
- virtual int ParseWindowClick (void);
- virtual int ParseWindowClose (void);
-
- // Utility functions:
- /// Writes a "pre-chunk" packet
- void SendPreChunk(int a_ChunkX, int a_ChunkZ, bool a_ShouldLoad);
-
- /// Writes a "set window items" packet with the specified params
- void SendWindowSlots(char a_WindowID, int a_NumItems, const cItem * a_Items);
-
- /// Writes one item, "slot" as the protocol wiki calls it
- virtual void WriteItem(const cItem & a_Item);
-
- /// Parses one item, "slot" as the protocol wiki calls it, from m_ReceivedData; returns the usual ParsePacket() codes
- virtual int ParseItem(cItem & a_Item);
-
- /// Writes the COMMON entity metadata
- void WriteCommonMetadata(const cEntity & a_Entity);
-
- /// Writes normal entity metadata
- void WriteEntityMetadata(const cEntity & a_Entity);
-
- /// Writes mobile entity metadata
- void WriteMobMetadata(const cMonster & a_Mob);
-} ;
-
-
-
-
diff --git a/src/Protocol/Protocol132.cpp b/src/Protocol/Protocol132.cpp
deleted file mode 100644
index 63a15c082..000000000
--- a/src/Protocol/Protocol132.cpp
+++ /dev/null
@@ -1,880 +0,0 @@
-
-// Protocol132.cpp
-
-// Implements the cProtocol132 class representing the release 1.3.2 protocol (#39)
-
-#include "Globals.h"
-#include "ChunkDataSerializer.h"
-#include "Protocol132.h"
-#include "../Root.h"
-#include "../Server.h"
-#include "../World.h"
-#include "../ClientHandle.h"
-#include "../Item.h"
-#include "../Entities/Player.h"
-#include "../Mobs/Monster.h"
-#include "../UI/Window.h"
-#include "../Entities/Pickup.h"
-#include "../WorldStorage/FastNBT.h"
-#include "../WorldStorage/EnchantmentSerializer.h"
-#include "../StringCompression.h"
-#include "PolarSSL++/Sha1Checksum.h"
-
-
-
-
-
-#define HANDLE_PACKET_READ(Proc, Type, Var) \
- Type Var; \
- { \
- if (!m_ReceivedData.Proc(Var)) \
- { \
- m_ReceivedData.CheckValid(); \
- return PARSE_INCOMPLETE; \
- } \
- m_ReceivedData.CheckValid(); \
- }
-
-
-
-
-
-const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows...
-
-
-
-
-
-enum
-{
- PACKET_KEEP_ALIVE = 0x00,
- PACKET_LOGIN = 0x01,
- PACKET_ENTITY_EQUIPMENT = 0x05,
- PACKET_COMPASS = 0x06,
- PACKET_PLAYER_SPAWN = 0x14,
- PACKET_COLLECT_PICKUP = 0x16,
- PACKET_SPAWN_MOB = 0x18,
- PACKET_DESTROY_ENTITIES = 0x1d,
- PACKET_CHUNK_DATA = 0x33,
- PACKET_BLOCK_CHANGE = 0x35,
- PACKET_BLOCK_ACTION = 0x36,
- PACKET_BLOCK_BREAK_ANIM = 0x37,
- PACKET_SOUND_EFFECT = 0x3e,
- PACKET_SOUND_PARTICLE_EFFECT = 0x3d,
- PACKET_TAB_COMPLETION = 0xcb,
- PACKET_LOCALE_VIEW_DISTANCE = 0xcc,
- PACKET_CLIENT_STATUSES = 0xcd,
- PACKET_ENCRYPTION_KEY_RESP = 0xfc,
-} ;
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cProtocol132:
-
-cProtocol132::cProtocol132(cClientHandle * a_Client) :
- super(a_Client),
- m_IsEncrypted(false)
-{
-}
-
-
-
-
-
-cProtocol132::~cProtocol132()
-{
- if (!m_DataToSend.empty())
- {
- LOGD("There are " SIZE_T_FMT " unsent bytes while deleting cProtocol132", m_DataToSend.size());
- }
-}
-
-
-
-
-
-void cProtocol132::DataReceived(const char * a_Data, size_t a_Size)
-{
- if (m_IsEncrypted)
- {
- Byte Decrypted[512];
- while (a_Size > 0)
- {
- size_t NumBytes = (a_Size > sizeof(Decrypted)) ? sizeof(Decrypted) : a_Size;
- m_Decryptor.ProcessData(Decrypted, (Byte *)a_Data, NumBytes);
- super::DataReceived((const char *)Decrypted, NumBytes);
- a_Size -= NumBytes;
- a_Data += NumBytes;
- }
- }
- else
- {
- super::DataReceived(a_Data, a_Size);
- }
-}
-
-
-
-
-
-void cProtocol132::SendBlockAction(int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_BLOCK_ACTION);
- WriteInt (a_BlockX);
- WriteShort((short)a_BlockY);
- WriteInt (a_BlockZ);
- WriteChar (a_Byte1);
- WriteChar (a_Byte2);
- WriteShort(a_BlockType);
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendBlockBreakAnim(int a_entityID, int a_BlockX, int a_BlockY, int a_BlockZ, char stage)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_BLOCK_BREAK_ANIM);
- WriteInt (a_entityID);
- WriteInt (a_BlockX);
- WriteInt (a_BlockY);
- WriteInt (a_BlockZ);
- WriteChar (stage);
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_BLOCK_CHANGE);
- WriteInt (a_BlockX);
- WriteByte ((unsigned char)a_BlockY);
- WriteInt (a_BlockZ);
- WriteShort(a_BlockType);
- WriteByte (a_BlockMeta);
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
-{
- cCSLock Lock(m_CSPacket);
-
- // Pre-chunk not used in 1.3.2. Finally.
-
- // Send the chunk data:
- AString Serialized = a_Serializer.Serialize(cChunkDataSerializer::RELEASE_1_3_2, a_ChunkX, a_ChunkZ);
- WriteByte(PACKET_CHUNK_DATA);
- WriteInt (a_ChunkX);
- WriteInt (a_ChunkZ);
- SendData(Serialized.data(), Serialized.size());
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendCollectEntity(const cEntity & a_Entity, const cPlayer & a_Player)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_COLLECT_PICKUP);
- WriteInt (a_Entity.GetUniqueID());
- WriteInt (a_Player.GetUniqueID());
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendDestroyEntity(const cEntity & a_Entity)
-{
- if (a_Entity.GetUniqueID() == m_Client->GetPlayer()->GetUniqueID())
- {
- // Do not send "destroy self" to the client, the client would crash (FS #254)
- return;
- }
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_DESTROY_ENTITIES);
- WriteByte(1); // entity count
- WriteInt (a_Entity.GetUniqueID());
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_ENTITY_EQUIPMENT);
- WriteInt (a_Entity.GetUniqueID());
- WriteShort(a_SlotNum);
- WriteItem (a_Item);
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_LOGIN);
- WriteInt (a_Player.GetUniqueID()); // EntityID of the player
- WriteString("default"); // Level type
- WriteByte ((Byte)a_Player.GetGameMode());
- WriteByte ((Byte)(a_World.GetDimension()));
- WriteByte (2); // TODO: Difficulty
- WriteByte (0); // Unused, used to be world height
- WriteByte (8); // Client list width or something
- Flush();
- m_LastSentDimension = a_World.GetDimension();
- SendCompass(a_World);
-}
-
-
-
-
-
-void cProtocol132::SendPlayerSpawn(const cPlayer & a_Player)
-{
- const cItem & HeldItem = a_Player.GetEquippedItem();
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_PLAYER_SPAWN);
- WriteInt (a_Player.GetUniqueID());
- if (a_Player.HasCustomName())
- {
- WriteString(a_Player.GetCustomName());
- }
- else
- {
- WriteString(a_Player.GetName());
- }
- WriteInt ((int)(a_Player.GetPosX() * 32));
- WriteInt ((int)(a_Player.GetPosY() * 32));
- WriteInt ((int)(a_Player.GetPosZ() * 32));
- WriteChar ((char)((a_Player.GetYaw() / 360.f) * 256));
- WriteChar ((char)((a_Player.GetPitch() / 360.f) * 256));
- WriteShort (HeldItem.IsEmpty() ? 0 : HeldItem.m_ItemType);
- // Player metadata: just use a default metadata value, since the client doesn't like starting without any metadata:
- WriteByte (0); // Index 0, byte (flags)
- WriteByte (0); // Flags, empty
- WriteByte (0x7f); // End of metadata
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_SOUND_EFFECT);
- WriteString (a_SoundName);
- WriteInt ((int)(a_X * 8.0));
- WriteInt ((int)(a_Y * 8.0));
- WriteInt ((int)(a_Z * 8.0));
- WriteFloat (a_Volume);
- WriteChar ((char)(a_Pitch * 63.0f));
- Flush();
-}
-
-
-
-
-
-void cProtocol132::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);
- WriteInt (a_SrcX);
- WriteByte((Byte)a_SrcY);
- WriteInt (a_SrcZ);
- WriteInt (a_Data);
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendSpawnMob(const cMonster & a_Mob)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_SPAWN_MOB);
- WriteInt (a_Mob.GetUniqueID());
- WriteByte ((Byte)a_Mob.GetMobType());
- WriteVectorI((Vector3i)(a_Mob.GetPosition() * 32));
- WriteByte ((Byte)((a_Mob.GetYaw() / 360.f) * 256));
- WriteByte ((Byte)((a_Mob.GetPitch() / 360.f) * 256));
- WriteByte ((Byte)((a_Mob.GetHeadYaw() / 360.f) * 256));
- WriteShort ((short)(a_Mob.GetSpeedX() * 400));
- WriteShort ((short)(a_Mob.GetSpeedY() * 400));
- WriteShort ((short)(a_Mob.GetSpeedZ() * 400));
-
- WriteCommonMetadata(a_Mob);
- WriteMobMetadata(a_Mob);
- WriteByte(0x7f);
-
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendTabCompletionResults(const AStringVector & a_Results)
-{
- if (a_Results.empty())
- {
- // No results to send
- return;
- }
-
- AString Serialized(a_Results[0]);
- for (AStringVector::const_iterator itr = a_Results.begin() + 1, end = a_Results.end(); itr != end; ++itr)
- {
- Serialized.push_back(0);
- Serialized.append(*itr);
- } // for itr - a_Results[]
-
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_TAB_COMPLETION);
- WriteString(Serialized);
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
-{
- // Unloading the chunk is done by sending a "map chunk" packet
- // with IncludeInitialize set to true and primary bitmap set to 0:
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_CHUNK_DATA);
- WriteInt (a_ChunkX);
- WriteInt (a_ChunkZ);
- WriteBool(true); // IncludeInitialize
- WriteShort(0); // Primary bitmap
- WriteShort(0); // Add bitmap
- WriteInt(0);
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendWholeInventory(const cWindow & a_Window)
-{
- // 1.3.2 requires player inventory slots to be sent as SetSlot packets,
- // otherwise it sometimes fails to update the window
-
- // Send the entire window:
- super::SendWholeInventory(a_Window);
-
- // Send the player inventory and hotbar:
- cPlayer * Player = m_Client->GetPlayer();
- const cInventory & Inventory = Player->GetInventory();
- int BaseOffset = a_Window.GetNumSlots() - (cInventory::invNumSlots - cInventory::invInventoryOffset); // Number of non-inventory slots
- char WindowID = a_Window.GetWindowID();
- for (short i = 0; i < cInventory::invInventoryCount; i++)
- {
- SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetInventorySlot(i));
- } // for i - Inventory[]
- BaseOffset += cInventory::invInventoryCount;
- for (short i = 0; i < cInventory::invHotbarCount; i++)
- {
- SendInventorySlot(WindowID, BaseOffset + i, Inventory.GetHotbarSlot(i));
- } // for i - Hotbar[]
-
- // Send even the item being dragged:
- SendInventorySlot(-1, -1, Player->GetDraggingItem());
-}
-
-
-
-
-
-AString cProtocol132::GetAuthServerID(void)
-{
- // http://wiki.vg/wiki/index.php?title=Session&oldid=2615
- // Server uses SHA1 to mix ServerID, Client secret and server public key together
- // The mixing is done in StartEncryption, the result is in m_AuthServerID
-
- return m_AuthServerID;
-}
-
-
-
-
-
-int cProtocol132::ParsePacket(unsigned char a_PacketType)
-{
- switch (a_PacketType)
- {
- default: return super::ParsePacket(a_PacketType); // off-load previously known packets into cProtocol125
- case PACKET_CLIENT_STATUSES: return ParseClientStatuses();
- case PACKET_ENCRYPTION_KEY_RESP: return ParseEncryptionKeyResponse();
- case PACKET_LOCALE_VIEW_DISTANCE: return ParseLocaleViewDistance();
- case PACKET_TAB_COMPLETION: return ParseTabCompletion();
- }
-}
-
-
-
-
-
-int cProtocol132::ParseBlockPlace(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, PosX);
- HANDLE_PACKET_READ(ReadByte, Byte, PosY);
- HANDLE_PACKET_READ(ReadBEInt, int, PosZ);
- HANDLE_PACKET_READ(ReadChar, char, BlockFace);
-
- cItem HeldItem;
- int res = ParseItem(HeldItem);
- if (res < 0)
- {
- return res;
- }
-
- HANDLE_PACKET_READ(ReadChar, char, CursorX);
- HANDLE_PACKET_READ(ReadChar, char, CursorY);
- HANDLE_PACKET_READ(ReadChar, char, CursorZ);
-
- m_Client->HandleRightClick(PosX, PosY, PosZ, static_cast<eBlockFace>(BlockFace), CursorX, CursorY, CursorZ, HeldItem);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol132::ParseHandshake(void)
-{
- HANDLE_PACKET_READ(ReadByte, Byte, ProtocolVersion);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Username);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, ServerHost);
- HANDLE_PACKET_READ(ReadBEInt, int, ServerPort);
- m_Username = Username;
-
- if (!m_Client->HandleHandshake( m_Username))
- {
- return PARSE_OK; // Player is not allowed into the server
- }
-
- // Send a 0xfd Encryption Key Request http://wiki.vg/Protocol#0xFD
- SendEncryptionKeyRequest();
-
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol132::ParseClientStatuses(void)
-{
- HANDLE_PACKET_READ(ReadByte, Byte, Status);
- if ((Status & 1) == 0)
- {
- m_Client->HandleLogin(39, m_Username);
- }
- else
- {
- m_Client->HandleRespawn();
- }
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol132::ParseEncryptionKeyResponse(void)
-{
- // Read the encryption key:
- HANDLE_PACKET_READ(ReadBEShort, short, EncKeyLength);
- if (EncKeyLength > MAX_ENC_LEN)
- {
- LOGD("Too long encryption key");
- m_Client->Kick("Hacked client");
- return PARSE_OK;
- }
- AString EncKey;
- if (!m_ReceivedData.ReadString(EncKey, (size_t)EncKeyLength))
- {
- return PARSE_INCOMPLETE;
- }
-
- // Read the encryption nonce:
- HANDLE_PACKET_READ(ReadBEShort, short, EncNonceLength);
- AString EncNonce;
- if (!m_ReceivedData.ReadString(EncNonce, (size_t)EncNonceLength))
- {
- return PARSE_INCOMPLETE;
- }
- if (EncNonceLength > MAX_ENC_LEN)
- {
- LOGD("Too long encryption nonce");
- m_Client->Kick("Hacked client");
- return PARSE_OK;
- }
-
- HandleEncryptionKeyResponse(EncKey, EncNonce);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol132::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);
- m_Client->SetLocale(Locale);
- // TODO: m_Client->HandleViewDistance(ViewDistance);
- // TODO: m_Client->HandleChatFlags(ChatFlags);
- // Ignoring client difficulty
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol132::ParseLogin(void)
-{
- // Login packet not used in 1.3.2
- return PARSE_ERROR;
-}
-
-
-
-
-
-int cProtocol132::ParsePlayerAbilities(void)
-{
- HANDLE_PACKET_READ(ReadBool, bool, Flags);
- HANDLE_PACKET_READ(ReadChar, char, FlyingSpeed);
- HANDLE_PACKET_READ(ReadChar, char, WalkingSpeed);
- // TODO: m_Client->HandlePlayerAbilities(...);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol132::ParseTabCompletion(void)
-{
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, Text);
- m_Client->HandleTabCompletion(Text);
- return PARSE_OK;
-}
-
-
-
-
-
-void cProtocol132::SendData(const char * a_Data, size_t a_Size)
-{
- m_DataToSend.append(a_Data, a_Size);
-}
-
-
-
-
-
-void cProtocol132::Flush(void)
-{
- ASSERT(m_CSPacket.IsLockedByCurrentThread()); // Did all packets lock the CS properly?
-
- if (m_DataToSend.empty())
- {
- LOGD("Flushing empty");
- return;
- }
- const char * Data = m_DataToSend.data();
- size_t Size = m_DataToSend.size();
- if (m_IsEncrypted)
- {
- Byte Encrypted[8192]; // Larger buffer, we may be sending lots of data (chunks)
- while (Size > 0)
- {
- size_t NumBytes = (Size > sizeof(Encrypted)) ? sizeof(Encrypted) : Size;
- m_Encryptor.ProcessData(Encrypted, (Byte *)Data, NumBytes);
- super::SendData((const char *)Encrypted, NumBytes);
- Size -= NumBytes;
- Data += NumBytes;
- }
- }
- else
- {
- super::SendData(Data, Size);
- }
- m_DataToSend.clear();
-}
-
-
-
-
-
-void cProtocol132::WriteItem(const cItem & a_Item)
-{
- short ItemType = a_Item.m_ItemType;
- ASSERT(ItemType >= -1); // Check validity of packets in debug runtime
- if (ItemType <= 0)
- {
- // Fix, to make sure no invalid values are sent.
- ItemType = -1;
- }
-
- if (a_Item.IsEmpty())
- {
- WriteShort(-1);
- return;
- }
-
- WriteShort(ItemType);
- WriteChar (a_Item.m_ItemCount);
- WriteShort(a_Item.m_ItemDamage);
-
- if (a_Item.m_Enchantments.IsEmpty())
- {
- WriteShort(-1);
- return;
- }
-
- // Send the enchantments:
- cFastNBTWriter Writer;
- const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
- EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName);
- Writer.Finish();
- AString Compressed;
- CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
- WriteShort((short)Compressed.size());
- SendData(Compressed.data(), Compressed.size());
-}
-
-
-
-
-
-int cProtocol132::ParseItem(cItem & a_Item)
-{
- HANDLE_PACKET_READ(ReadBEShort, short, ItemType);
-
- if (ItemType <= -1)
- {
- a_Item.Empty();
- return PARSE_OK;
- }
- a_Item.m_ItemType = ItemType;
-
- HANDLE_PACKET_READ(ReadChar, char, ItemCount);
- HANDLE_PACKET_READ(ReadBEShort, short, ItemDamage);
- a_Item.m_ItemCount = ItemCount;
- a_Item.m_ItemDamage = ItemDamage;
- if (ItemCount <= 0)
- {
- a_Item.Empty();
- }
-
- HANDLE_PACKET_READ(ReadBEShort, short, MetadataLength);
- if (MetadataLength <= 0)
- {
- return PARSE_OK;
- }
-
- // Read the metadata
- AString Metadata;
- Metadata.resize((size_t)MetadataLength);
- if (!m_ReceivedData.ReadBuf((void *)Metadata.data(), (size_t)MetadataLength))
- {
- return PARSE_INCOMPLETE;
- }
-
- return ParseItemMetadata(a_Item, Metadata);
-}
-
-
-
-
-
-int cProtocol132::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
-{
- // Uncompress the GZIPped data:
- AString Uncompressed;
- if (UncompressStringGZIP(a_Metadata.data(), a_Metadata.size(), Uncompressed) != Z_OK)
- {
- AString HexDump;
- CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16);
- LOG("Cannot unGZIP item metadata:\n%s", HexDump.c_str());
- return PARSE_ERROR;
- }
-
- // Parse into NBT:
- cParsedNBT NBT(Uncompressed.data(), Uncompressed.size());
- if (!NBT.IsValid())
- {
- AString HexDump;
- CreateHexDump(HexDump, Uncompressed.data(), Uncompressed.size(), 16);
- LOG("Cannot parse NBT item metadata:\n%s", HexDump.c_str());
- return PARSE_ERROR;
- }
-
- // Load enchantments from the NBT:
- for (int tag = NBT.GetFirstChild(NBT.GetRoot()); tag >= 0; tag = NBT.GetNextSibling(tag))
- {
- if (
- (NBT.GetType(tag) == TAG_List) &&
- (
- (NBT.GetName(tag) == "ench") ||
- (NBT.GetName(tag) == "StoredEnchantments")
- )
- )
- {
- EnchantmentSerializer::ParseFromNBT(a_Item.m_Enchantments, NBT, tag);
- }
- }
-
- return PARSE_OK;
-}
-
-
-
-
-
-void cProtocol132::SendCompass(const cWorld & a_World)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_COMPASS);
- WriteInt((int)(a_World.GetSpawnX()));
- WriteInt((int)(a_World.GetSpawnY()));
- WriteInt((int)(a_World.GetSpawnZ()));
- Flush();
-}
-
-
-
-
-
-void cProtocol132::SendEncryptionKeyRequest(void)
-{
- cCSLock Lock(m_CSPacket);
- cServer * Server = cRoot::Get()->GetServer();
- WriteByte(0xfd);
- WriteString(Server->GetServerID());
- const AString & PublicKeyDER = Server->GetPublicKeyDER();
- WriteShort((short)(PublicKeyDER.size()));
- SendData(PublicKeyDER.data(), PublicKeyDER.size());
- WriteShort(4);
- WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
- Flush();
-}
-
-
-
-
-
-void cProtocol132::HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce)
-{
- // Decrypt EncNonce using privkey
- cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey();
-
- Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)];
- int res = rsaDecryptor.Decrypt((const Byte *)a_EncNonce.data(), a_EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce));
- if (res != 4)
- {
- LOGD("Bad nonce length");
- m_Client->Kick("Hacked client");
- return;
- }
- if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this)
- {
- LOGD("Bad nonce value");
- m_Client->Kick("Hacked client");
- return;
- }
-
- // Decrypt the symmetric encryption key using privkey:
- Byte DecryptedKey[MAX_ENC_LEN];
- res = rsaDecryptor.Decrypt((const Byte *)a_EncKey.data(), a_EncKey.size(), DecryptedKey, sizeof(DecryptedKey));
- if (res != 16)
- {
- LOGD("Bad key length");
- m_Client->Kick("Hacked client");
- return;
- }
-
- {
- // Send encryption key response:
- cCSLock Lock(m_CSPacket);
- WriteByte(0xfc);
- WriteShort(0);
- WriteShort(0);
- Flush();
- }
-
- #ifdef _DEBUG
- AString DecryptedKeyHex;
- CreateHexDump(DecryptedKeyHex, DecryptedKey, res, 16);
- LOGD("Received encryption key, %d bytes:\n%s", res, DecryptedKeyHex.c_str());
- #endif
-
- StartEncryption(DecryptedKey);
- return;
-}
-
-
-
-
-
-void cProtocol132::StartEncryption(const Byte * a_Key)
-{
- m_Encryptor.Init(a_Key, a_Key);
- m_Decryptor.Init(a_Key, a_Key);
- m_IsEncrypted = true;
-
- // Prepare the m_AuthServerID:
- cSha1Checksum Checksum;
- cServer * Server = cRoot::Get()->GetServer();
- AString ServerID = Server->GetServerID();
- Checksum.Update((const Byte *)ServerID.c_str(), ServerID.length());
- Checksum.Update(a_Key, 16);
- Checksum.Update((const Byte *)Server->GetPublicKeyDER().data(), Server->GetPublicKeyDER().size());
- Byte Digest[20];
- Checksum.Finalize(Digest);
- cSha1Checksum::DigestToJava(Digest, m_AuthServerID);
-}
-
-
-
-
diff --git a/src/Protocol/Protocol132.h b/src/Protocol/Protocol132.h
deleted file mode 100644
index 1124a7253..000000000
--- a/src/Protocol/Protocol132.h
+++ /dev/null
@@ -1,115 +0,0 @@
-
-// Protocol132.h
-
-// Interfaces to the cProtocol132 class representing the release 1.3.2 protocol (#39)
-
-
-
-
-
-#pragma once
-
-#include "Protocol125.h"
-
-#ifdef _MSC_VER
- #pragma warning(push)
- #pragma warning(disable:4127)
- #pragma warning(disable:4189)
- #pragma warning(disable:4231)
- #pragma warning(disable:4244)
- #pragma warning(disable:4702)
-#endif
-
-#ifdef _MSC_VER
- #pragma warning(pop)
-#endif
-
-#include "PolarSSL++/AesCfb128Decryptor.h"
-#include "PolarSSL++/AesCfb128Encryptor.h"
-
-
-
-
-
-class cProtocol132 :
- public cProtocol125
-{
- typedef cProtocol125 super;
-public:
-
- cProtocol132(cClientHandle * a_Client);
- virtual ~cProtocol132();
-
- /// Called when client sends some data:
- virtual void DataReceived(const char * a_Data, size_t a_Size) override;
-
- // Sending commands (alphabetically sorted):
- virtual void SendBlockAction (int a_BlockX, int a_BlockY, int a_BlockZ, char a_Byte1, char a_Byte2, BLOCKTYPE a_BlockType) override;
- virtual void SendBlockBreakAnim (int a_EntityID, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Stage) override;
- virtual void SendBlockChange (int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
- virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
- virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
- virtual void SendDestroyEntity (const cEntity & a_Entity) override;
- virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
- virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
- virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
- virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, 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 SendTabCompletionResults(const AStringVector & a_Results) override;
- virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
- virtual void SendWholeInventory (const cWindow & a_Window) override;
-
- virtual AString GetAuthServerID(void) override;
-
- /// Handling of the additional packets:
- virtual int ParsePacket(unsigned char a_PacketType) override;
-
- // Modified packets:
- virtual int ParseBlockPlace (void) override;
- virtual int ParseHandshake (void) override;
- virtual int ParseLogin (void) override;
- virtual int ParsePlayerAbilities(void) override;
-
- // New packets:
- virtual int ParseClientStatuses (void);
- virtual int ParseEncryptionKeyResponse(void);
- virtual int ParseLocaleViewDistance (void);
- virtual int ParseTabCompletion (void);
-
-protected:
- bool m_IsEncrypted;
-
- cAesCfb128Decryptor m_Decryptor;
- cAesCfb128Encryptor m_Encryptor;
-
- AString m_DataToSend;
-
- /// The ServerID used for session authentication; set in StartEncryption(), used in GetAuthServerID()
- AString m_AuthServerID;
-
- virtual void SendData(const char * a_Data, size_t a_Size) override;
-
- // DEBUG:
- virtual void Flush(void) override;
-
- // Items in slots are sent differently
- virtual void WriteItem(const cItem & a_Item) override;
- virtual int ParseItem(cItem & a_Item) override;
-
- /// Parses the metadata that may come with the item.
- int ParseItemMetadata(cItem & a_Item, const AString & a_Metadata);
-
- virtual void SendCompass(const cWorld & a_World);
- virtual void SendEncryptionKeyRequest(void);
-
- /// Decrypts the key and nonce, checks nonce, starts the symmetric encryption
- void HandleEncryptionKeyResponse(const AString & a_EncKey, const AString & a_EncNonce);
-
- /// Starts the symmetric encryption with the specified key; also sets m_AuthServerID
- void StartEncryption(const Byte * a_Key);
-} ;
-
-
-
-
diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp
deleted file mode 100644
index d33314a2f..000000000
--- a/src/Protocol/Protocol14x.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-
-// 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"
-#include "../Entities/Player.h"
-#include "../Mobs/Monster.h"
-#include "../UI/Window.h"
-#include "../Entities/Pickup.h"
-#include "../Entities/FallingBlock.h"
-
-#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
-
-#ifdef _MSC_VER
- #pragma warning(pop)
-#endif
-
-
-#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
-} ;
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// 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
- m_Client->SetLocale(Locale);
- // 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));
- WriteChar((char)(a_Pickup.GetSpeedX() * 8));
- WriteChar((char)(a_Pickup.GetSpeedY() * 8));
- WriteChar((char)(a_Pickup.GetSpeedZ() * 8));
- 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);
- WriteInt (a_SrcX);
- WriteByte((Byte)a_SrcY);
- WriteInt (a_SrcZ);
- WriteInt (a_Data);
- WriteBool(0);
- Flush();
-}
-
-
-
-
-
-void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_UPDATE_TIME);
- WriteInt64(a_WorldAge);
- WriteInt64(a_TimeOfDay);
- Flush();
-}
-
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// 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);
- WriteShort((short)(a_Pickup.GetSpeedX() * 32));
- WriteShort((short)(a_Pickup.GetSpeedY() * 32));
- WriteShort((short)(a_Pickup.GetSpeedZ() * 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());
- 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());
- WriteChar(a_ObjectType);
- 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();
-}
-
-
-
-
-
-void cProtocol146::SendSpawnVehicle(const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_SPAWN_OBJECT);
- WriteInt (a_Vehicle.GetUniqueID());
- WriteChar (a_VehicleType);
- WriteInt ((int)(a_Vehicle.GetPosX() * 32));
- WriteInt ((int)(a_Vehicle.GetPosY() * 32));
- WriteInt ((int)(a_Vehicle.GetPosZ() * 32));
- WriteByte ((Byte)((a_Vehicle.GetPitch() / 360.f) * 256));
- WriteByte ((Byte)((a_Vehicle.GetYaw() / 360.f) * 256));
- WriteInt (a_VehicleSubType);
- if (a_VehicleSubType != 0)
- {
- WriteShort((short)(a_Vehicle.GetSpeedX() * 400));
- WriteShort((short)(a_Vehicle.GetSpeedY() * 400));
- WriteShort((short)(a_Vehicle.GetSpeedZ() * 400));
- }
- Flush();
-}
-
-
-
-
-
diff --git a/src/Protocol/Protocol14x.h b/src/Protocol/Protocol14x.h
deleted file mode 100644
index 227cc8cc7..000000000
--- a/src/Protocol/Protocol14x.h
+++ /dev/null
@@ -1,63 +0,0 @@
-
-// 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, bool a_DoDaylightCycle) 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 SendSpawnFallingBlock(const cFallingBlock & a_FallingBlock) override;
- virtual void SendSpawnObject (const cEntity & a_Entity, char a_ObjectType, int a_ObjectData, Byte a_Yaw, Byte a_Pitch) override;
- virtual void SendSpawnVehicle (const cEntity & a_Vehicle, char a_VehicleType, char a_VehicleSubType) override;
-} ;
-
-
-
-
diff --git a/src/Protocol/Protocol15x.cpp b/src/Protocol/Protocol15x.cpp
deleted file mode 100644
index 089296fdf..000000000
--- a/src/Protocol/Protocol15x.cpp
+++ /dev/null
@@ -1,209 +0,0 @@
-
-// Protocol15x.cpp
-
-/*
-Implements the 1.5.x protocol classes:
- - cProtocol150
- - release 1.5 protocol (#60)
- - release 1.5.2 protocol (#61, no relevant changes found)
-*/
-
-#include "Globals.h"
-#include "Protocol15x.h"
-#include "../ClientHandle.h"
-#include "../Item.h"
-#include "../UI/Window.h"
-
-
-
-
-
-#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_WINDOW_OPEN = 0x64,
- PACKET_PARTICLE_EFFECT = 0x3F,
- PACKET_SCOREBOARD_OBJECTIVE = 0xCE,
- PACKET_SCORE_UPDATE = 0xCF,
- PACKET_DISPLAY_OBJECTIVE = 0xD0
-} ;
-
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cProtocol150:
-
-cProtocol150::cProtocol150(cClientHandle * a_Client) :
- super(a_Client)
-{
-}
-
-
-
-
-
-void cProtocol150::SendWindowOpen(const cWindow & a_Window)
-{
- if (a_Window.GetWindowType() < 0)
- {
- // Do not send for inventory windows
- return;
- }
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_WINDOW_OPEN);
- WriteByte (a_Window.GetWindowID());
- WriteByte (a_Window.GetWindowType());
- WriteString(a_Window.GetWindowTitle());
- WriteByte (a_Window.GetNumNonInventorySlots());
- WriteByte (1); // Use title
- Flush();
-}
-
-
-
-
-
-void cProtocol150::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)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_PARTICLE_EFFECT);
- WriteString(a_ParticleName);
- WriteFloat(a_SrcX);
- WriteFloat(a_SrcY);
- WriteFloat(a_SrcZ);
- WriteFloat(a_OffsetX);
- WriteFloat(a_OffsetY);
- WriteFloat(a_OffsetZ);
- WriteFloat(a_ParticleData);
- WriteInt(a_ParticleAmount);
- Flush();
-}
-
-
-
-
-
-void cProtocol150::SendScoreboardObjective(const AString & a_Name, const AString & a_DisplayName, Byte a_Mode)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_SCOREBOARD_OBJECTIVE);
- WriteString(a_Name);
- WriteString(a_DisplayName);
- WriteByte(a_Mode);
- Flush();
-}
-
-
-
-
-
-void cProtocol150::SendScoreUpdate(const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_SCORE_UPDATE);
- WriteString(a_Player);
- WriteByte(a_Mode);
-
- if (a_Mode != 1)
- {
- WriteString(a_Objective);
- WriteInt((int) a_Score);
- }
-
- Flush();
-}
-
-
-
-
-
-void cProtocol150::SendDisplayObjective(const AString & a_Objective, cScoreboard::eDisplaySlot a_Display)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_DISPLAY_OBJECTIVE);
- WriteByte((int) a_Display);
- WriteString(a_Objective);
- Flush();
-}
-
-
-
-
-
-int cProtocol150::ParseWindowClick(void)
-{
- HANDLE_PACKET_READ(ReadChar, char, WindowID);
- HANDLE_PACKET_READ(ReadBEShort, short, SlotNum);
- HANDLE_PACKET_READ(ReadByte, Byte, Button);
- HANDLE_PACKET_READ(ReadBEShort, short, TransactionID);
- HANDLE_PACKET_READ(ReadByte, Byte, Mode);
- cItem HeldItem;
- int res = ParseItem(HeldItem);
- if (res < 0)
- {
- return res;
- }
-
- // Convert Button, Mode, SlotNum and HeldItem into eClickAction:
- eClickAction Action = caUnknown;
- switch ((Mode << 8) | Button)
- {
- case 0x0000: Action = (SlotNum != -999) ? caLeftClick : caLeftClickOutside; break;
- case 0x0001: Action = (SlotNum != -999) ? caRightClick : caRightClickOutside; break;
- case 0x0100: Action = caShiftLeftClick; break;
- case 0x0101: Action = caShiftRightClick; break;
- case 0x0200: Action = caNumber1; break;
- case 0x0201: Action = caNumber2; break;
- case 0x0202: Action = caNumber3; break;
- case 0x0203: Action = caNumber4; break;
- case 0x0204: Action = caNumber5; break;
- case 0x0205: Action = caNumber6; break;
- case 0x0206: Action = caNumber7; break;
- case 0x0207: Action = caNumber8; break;
- case 0x0208: Action = caNumber9; break;
- case 0x0300: Action = caMiddleClick; break;
- case 0x0400: Action = (SlotNum == -999) ? caLeftClickOutsideHoldNothing : caDropKey; break;
- case 0x0401: Action = (SlotNum == -999) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break;
- case 0x0500: Action = (SlotNum == -999) ? caLeftPaintBegin : caUnknown; break;
- case 0x0501: Action = (SlotNum != -999) ? caLeftPaintProgress : caUnknown; break;
- case 0x0502: Action = (SlotNum == -999) ? caLeftPaintEnd : caUnknown; break;
- case 0x0504: Action = (SlotNum == -999) ? caRightPaintBegin : caUnknown; break;
- case 0x0505: Action = (SlotNum != -999) ? caRightPaintProgress : caUnknown; break;
- case 0x0506: Action = (SlotNum == -999) ? caRightPaintEnd : caUnknown; break;
- case 0x0600: Action = caDblClick; break;
- }
-
- if (Action == caUnknown)
- {
- LOGWARNING("Received an unknown click action combination: Mode = %d, Button = %d, Slot = %d, HeldItem = %s. Ignoring packet.",
- Mode, Button, SlotNum, ItemToFullString(HeldItem).c_str()
- );
- ASSERT(!"Unknown click action");
- return PARSE_OK;
- }
-
- m_Client->HandleWindowClick(WindowID, SlotNum, Action, HeldItem);
- return PARSE_OK;
-}
-
-
-
-
-
diff --git a/src/Protocol/Protocol15x.h b/src/Protocol/Protocol15x.h
deleted file mode 100644
index 968d5ebcf..000000000
--- a/src/Protocol/Protocol15x.h
+++ /dev/null
@@ -1,42 +0,0 @@
-
-// Protocol15x.h
-
-/*
-Declares the 1.5.x protocol classes:
- - cProtocol150
- - release 1.5 and 1.5.1 protocol (#60)
- - release 1.5.2 protocol (#61; no relevant changes found)
-*/
-
-
-
-
-
-#pragma once
-
-#include "Protocol14x.h"
-
-
-
-
-
-class cProtocol150 :
- public cProtocol146
-{
- typedef cProtocol146 super;
-
-public:
- cProtocol150(cClientHandle * a_Client);
-
- virtual void SendWindowOpen (const cWindow & a_Window) override;
- virtual void 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) override;
- virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
- virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override;
- virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override;
-
- virtual int ParseWindowClick(void);
-} ;
-
-
-
-
diff --git a/src/Protocol/Protocol16x.cpp b/src/Protocol/Protocol16x.cpp
deleted file mode 100644
index 0d354a030..000000000
--- a/src/Protocol/Protocol16x.cpp
+++ /dev/null
@@ -1,312 +0,0 @@
-
-// Protocol16x.cpp
-
-/*
-Implements the 1.6.x protocol classes:
- - cProtocol161
- - release 1.6.1 protocol (#73)
- - cProtocol162
- - release 1.6.2 protocol (#74)
- - release 1.6.3 protocol (#77) - no relevant changes
- - release 1.6.4 protocol (#78) - no relevant changes
-(others may be added later in the future for the 1.6 release series)
-*/
-
-#include "Globals.h"
-#include "Protocol16x.h"
-#include "../ClientHandle.h"
-#include "../Entities/Entity.h"
-#include "../Entities/Player.h"
-#include "../UI/Window.h"
-#include "../CompositeChat.h"
-
-
-
-
-
-#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_CHAT = 0x03,
- PACKET_UPDATE_HEALTH = 0x08,
- PACKET_STEER_VEHICLE = 0x1b,
- PACKET_ATTACH_ENTITY = 0x27,
- PACKET_ENTITY_PROPERTIES = 0x2c,
- PACKET_WINDOW_OPEN = 0x64,
- PACKET_TILE_EDITOR_OPEN = 0x85,
- PACKET_PLAYER_ABILITIES = 0xca,
-} ;
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cProtocol161:
-
-cProtocol161::cProtocol161(cClientHandle * a_Client) :
- super(a_Client)
-{
-}
-
-
-
-
-
-void cProtocol161::SendAttachEntity(const cEntity & a_Entity, const cEntity * a_Vehicle)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_ATTACH_ENTITY);
- WriteInt(a_Entity.GetUniqueID());
- WriteInt((a_Vehicle == NULL) ? -1 : a_Vehicle->GetUniqueID());
- WriteBool(false); // TODO: "Should use leash?" -> no
- Flush();
-}
-
-
-
-
-
-void cProtocol161::SendChat(const AString & a_Message)
-{
- super::SendChat(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str()));
-}
-
-
-
-
-
-void cProtocol161::SendChat(const cCompositeChat & a_Message)
-{
- // This protocol version doesn't support composite messages to the full
- // Just extract each part's text and use it:
-
- super::SendChat(Printf("{\"text\":\"%s\"}", EscapeString(a_Message.ExtractText()).c_str()));
-}
-
-
-
-
-
-void cProtocol161::SendEditSign(int a_BlockX, int a_BlockY, int a_BlockZ)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte(PACKET_TILE_EDITOR_OPEN);
- WriteByte(0);
- WriteInt(a_BlockX);
- WriteInt(a_BlockY);
- WriteInt(a_BlockZ);
- Flush();
-}
-
-
-
-
-
-void cProtocol161::SendGameMode(eGameMode a_GameMode)
-{
- super::SendGameMode(a_GameMode);
- SendPlayerMaxSpeed();
-}
-
-
-
-
-
-void cProtocol161::SendHealth(void)
-{
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_UPDATE_HEALTH);
- cPlayer * Player = m_Client->GetPlayer();
- WriteFloat((float)Player->GetHealth());
- WriteShort((short)Player->GetFoodLevel());
- WriteFloat((float)Player->GetFoodSaturationLevel());
- Flush();
-}
-
-
-
-
-
-void cProtocol161::SendPlayerMaxSpeed(void)
-{
- cCSLock Lock(m_CSPacket);
- cPlayer * Player = m_Client->GetPlayer();
- WriteByte(PACKET_ENTITY_PROPERTIES);
- WriteInt(Player->GetUniqueID());
- WriteInt(1);
- WriteString("generic.movementSpeed");
- WriteDouble(0.1 * Player->GetMaxSpeed());
- Flush();
-}
-
-
-
-
-
-void cProtocol161::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
-{
- // Besides sending the respawn, we need to also send the player max speed, otherwise the client reverts to super-fast
- super::SendRespawn(a_Dimension, a_ShouldIgnoreDimensionChecks);
- SendPlayerMaxSpeed();
-}
-
-
-
-
-
-void cProtocol161::SendWindowOpen(const cWindow & a_Window)
-{
- if (a_Window.GetWindowType() < 0)
- {
- // Do not send for inventory windows
- return;
- }
- cCSLock Lock(m_CSPacket);
- WriteByte (PACKET_WINDOW_OPEN);
- WriteChar (a_Window.GetWindowID());
- WriteByte ((Byte)a_Window.GetWindowType());
- WriteString(a_Window.GetWindowTitle());
- WriteByte ((Byte)a_Window.GetNumNonInventorySlots());
- WriteByte (1); // Use title
- if (a_Window.GetWindowType() == cWindow::wtAnimalChest)
- {
- WriteInt(0); // TODO: The animal's EntityID
- }
- Flush();
-}
-
-
-
-
-
-int cProtocol161::ParseEntityAction(void)
-{
- HANDLE_PACKET_READ(ReadBEInt, int, EntityID);
- HANDLE_PACKET_READ(ReadChar, char, ActionID);
- HANDLE_PACKET_READ(ReadBEInt, int, UnknownHorseVal);
-
- switch (ActionID)
- {
- case 1: m_Client->HandleEntityCrouch(EntityID, true); break; // Crouch
- case 2: m_Client->HandleEntityCrouch(EntityID, false); break; // Uncrouch
- case 3: m_Client->HandleEntityLeaveBed(EntityID); break; // Leave Bed
- case 4: m_Client->HandleEntitySprinting(EntityID, true); break; // Start sprinting
- case 5: m_Client->HandleEntitySprinting(EntityID, false); break; // Stop sprinting
- }
-
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol161::ParseLogin(void)
-{
- // The login packet is sent by Forge clients only
- // Only parse the packet, do no extra processing
- // Note that the types and the names have been only guessed and are not verified at all!
- HANDLE_PACKET_READ(ReadBEInt, int, Int1);
- HANDLE_PACKET_READ(ReadBEUTF16String16, AString, String1);
- HANDLE_PACKET_READ(ReadChar, char, Char1);
- HANDLE_PACKET_READ(ReadChar, char, Char2);
- HANDLE_PACKET_READ(ReadChar, char, Char3);
- HANDLE_PACKET_READ(ReadByte, Byte, Byte1);
- HANDLE_PACKET_READ(ReadByte, Byte, Byte2);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol161::ParsePlayerAbilities(void)
-{
- HANDLE_PACKET_READ(ReadByte, Byte, Flags);
- HANDLE_PACKET_READ(ReadBEFloat, float, FlyingSpeed);
- HANDLE_PACKET_READ(ReadBEFloat, float, WalkingSpeed);
- // TODO: m_Client->HandlePlayerAbilities(...);
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol161::ParseSteerVehicle(void)
-{
- HANDLE_PACKET_READ(ReadBEFloat, float, Sideways);
- HANDLE_PACKET_READ(ReadBEFloat, float, Forward);
- HANDLE_PACKET_READ(ReadBool, bool, Jump);
- HANDLE_PACKET_READ(ReadBool, bool, Unmount);
- if (Unmount)
- {
- m_Client->HandleUnmount();
- }
- else
- {
- m_Client->HandleSteerVehicle(Forward, Sideways);
- }
- return PARSE_OK;
-}
-
-
-
-
-
-int cProtocol161::ParsePacket(unsigned char a_PacketType)
-{
- switch (a_PacketType)
- {
- case PACKET_STEER_VEHICLE: return ParseSteerVehicle();
- default: return super::ParsePacket(a_PacketType);
- }
-}
-
-
-
-
-
-////////////////////////////////////////////////////////////////////////////////
-// cProtocol162:
-
-cProtocol162::cProtocol162(cClientHandle * a_Client) :
- super(a_Client)
-{
-}
-
-
-
-
-
-void cProtocol162::SendPlayerMaxSpeed(void)
-{
- cCSLock Lock(m_CSPacket);
- cPlayer * Player = m_Client->GetPlayer();
- WriteByte(PACKET_ENTITY_PROPERTIES);
- WriteInt(Player->GetUniqueID());
- WriteInt(1);
- WriteString("generic.movementSpeed");
- WriteDouble(0.1 * Player->GetMaxSpeed());
- WriteShort(0);
- Flush();
-}
-
-
-
-
diff --git a/src/Protocol/Protocol16x.h b/src/Protocol/Protocol16x.h
deleted file mode 100644
index add761d1e..000000000
--- a/src/Protocol/Protocol16x.h
+++ /dev/null
@@ -1,78 +0,0 @@
-
-// Protocol16x.h
-
-/*
-Declares the 1.6.x protocol classes:
- - cProtocol161
- - release 1.6.1 protocol (#73)
- - cProtocol162
- - release 1.6.2 protocol (#74)
- - release 1.6.3 protocol (#77) - no relevant changes
- - release 1.6.4 protocol (#78) - no relevant changes
-(others may be added later in the future for the 1.6 release series)
-*/
-
-
-
-
-
-#pragma once
-
-#include "Protocol15x.h"
-
-
-
-
-
-class cProtocol161 :
- public cProtocol150
-{
- typedef cProtocol150 super;
-
-public:
- cProtocol161(cClientHandle * a_Client);
-
-protected:
-
- // cProtocol150 overrides:
- virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity * a_Vehicle) override;
- virtual void SendChat (const AString & a_Message) override;
- virtual void SendChat (const cCompositeChat & a_Message) override;
- virtual void SendEditSign (int a_BlockX, int a_BlockY, int a_BlockZ) override; ///< Request the client to open up the sign editor for the sign (1.6+)
- virtual void SendGameMode (eGameMode a_GameMode) override;
- virtual void SendHealth (void) override;
- virtual void SendPlayerMaxSpeed(void) override;
- virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override;
- virtual void SendWindowOpen (const cWindow & a_Window) override;
-
- virtual int ParseEntityAction (void) override;
- virtual int ParseLogin (void) override;
- virtual int ParsePlayerAbilities(void) override;
-
- // New packets:
- virtual int ParseSteerVehicle(void);
-
- // Enable new packets' handling
- virtual int ParsePacket(unsigned char a_PacketType) override;
-} ;
-
-
-
-
-
-class cProtocol162 :
- public cProtocol161
-{
- typedef cProtocol161 super;
-
-public:
- cProtocol162(cClientHandle * a_Client);
-
-protected:
- // cProtocol161 overrides:
- virtual void SendPlayerMaxSpeed(void) override;
-} ;
-
-
-
-
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index ac58ef28b..e4c33908a 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -2217,20 +2217,6 @@ void cProtocol172::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer)
-void cProtocol172::WritePacket(cByteBuffer & a_Packet)
-{
- cCSLock Lock(m_CSPacket);
- AString Pkt;
- a_Packet.ReadAll(Pkt);
- WriteVarInt((UInt32)Pkt.size());
- SendData(Pkt.data(), Pkt.size());
- Flush();
-}
-
-
-
-
-
void cProtocol172::SendData(const char * a_Data, size_t a_Size)
{
if (m_IsEncrypted)
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 8f537f5d7..0bc86a72a 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -296,9 +296,6 @@ protected:
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
- /** Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. */
- void WritePacket(cByteBuffer & a_Packet);
-
/** Sends the data to the client, encrypting them if needed. */
virtual void SendData(const char * a_Data, size_t a_Size) override;
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 4ec447401..7a6eb5f28 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -2508,20 +2508,6 @@ void cProtocol180::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer)
-void cProtocol180::WritePacket(cByteBuffer & a_Packet)
-{
- cCSLock Lock(m_CSPacket);
- AString Pkt;
- a_Packet.ReadAll(Pkt);
- WriteVarInt((UInt32)Pkt.size());
- SendData(Pkt.data(), Pkt.size());
- Flush();
-}
-
-
-
-
-
void cProtocol180::SendData(const char * a_Data, size_t a_Size)
{
if (m_IsEncrypted)
diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h
index 554edecc8..acc167a6d 100644
--- a/src/Protocol/Protocol18x.h
+++ b/src/Protocol/Protocol18x.h
@@ -313,9 +313,6 @@ protected:
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
- /** Writes an entire packet into the output stream. a_Packet is expected to start with the packet type; data length is prepended here. */
- void WritePacket(cByteBuffer & a_Packet);
-
/** Sends the data to the client, encrypting them if needed. */
virtual void SendData(const char * a_Data, size_t a_Size) override;
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index fe53aede1..ef6802d2b 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -7,11 +7,6 @@
#include "Globals.h"
#include "ProtocolRecognizer.h"
-#include "Protocol125.h"
-#include "Protocol132.h"
-#include "Protocol14x.h"
-#include "Protocol15x.h"
-#include "Protocol16x.h"
#include "Protocol17x.h"
#include "Protocol18x.h"
#include "../ClientHandle.h"
@@ -50,17 +45,6 @@ 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";
- case PROTO_VERSION_1_6_3: return "1.6.3";
- case PROTO_VERSION_1_6_4: return "1.6.4";
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";
@@ -213,8 +197,13 @@ void cProtocolRecognizer::SendDisconnect(const AString & a_Reason)
else
{
// This is used when the client sends a server-ping, respond with the default packet:
- WriteByte (0xff); // PACKET_DISCONNECT
- WriteString(a_Reason);
+ static const int Packet = 0xff; // PACKET_DISCONNECT
+ SendData((const char *)&Packet, 1); // WriteByte()
+
+ AString UTF16 = UTF8ToRawBEUTF16(a_Reason.c_str(), a_Reason.length());
+ static const short Size = htons((short)(UTF16.size() / 2));
+ SendData((const char *)&Size, 2); // WriteShort()
+ SendData(UTF16.data(), UTF16.size()); // WriteString()
}
}
@@ -873,51 +862,8 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void)
{
// 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
-
- // The first packet should be a Handshake, 0x02:
- unsigned char PacketType;
- if (!m_Buffer.ReadByte(PacketType))
- {
- return false;
- }
- switch (PacketType)
- {
- 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();
+ // Lengthed protocol, try if it has the entire initial handshake packet:
UInt32 PacketLen;
UInt32 ReadSoFar = (UInt32)m_Buffer.GetReadableSpace();
if (!m_Buffer.ReadVarInt(PacketLen))
@@ -938,61 +884,6 @@ bool cProtocolRecognizer::TryRecognizeProtocol(void)
-bool cProtocolRecognizer::TryRecognizeLengthlessProtocol(void)
-{
- // The comm started with 0x02, which is a Handshake packet in the length-less protocol family
- // 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)
- {
- case PROTO_VERSION_1_3_2:
- {
- 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:
- case PROTO_VERSION_1_6_3:
- case PROTO_VERSION_1_6_4:
- {
- m_Protocol = new cProtocol162(m_Client);
- return true;
- }
- }
- m_Protocol = new cProtocol125(m_Client);
- return true;
-}
-
-
-
-
-
bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining)
{
UInt32 PacketType;
@@ -1090,80 +981,3 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
-
-void cProtocolRecognizer::SendLengthlessServerPing(void)
-{
- AString Reply;
- cServer * Server = cRoot::Get()->GetServer();
-
- AString ServerDescription = Server->GetDescription();
- int NumPlayers = Server->GetNumPlayers();
- int MaxPlayers = Server->GetMaxPlayers();
- AString Favicon = Server->GetFaviconData();
- cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon);
-
- switch (cRoot::Get()->GetPrimaryServerVersion())
- {
- 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
- Printf(Reply, "%s%s%i%s%i",
- ServerDescription.c_str(),
- cChatColor::Delimiter,
- NumPlayers,
- cChatColor::Delimiter,
- MaxPlayers
- );
- 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:
- case PROTO_VERSION_1_6_3:
- case PROTO_VERSION_1_6_4:
- {
- // 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.
- m_Buffer.ResetRead();
- if (m_Buffer.CanReadBytes(2))
- {
- Byte val;
- m_Buffer.ReadByte(val); // Packet type - Serverlist ping
- m_Buffer.ReadByte(val); // 0x01 magic value
- ASSERT(val == 0x01);
- }
-
- AString ProtocolVersionNum;
- Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion());
- AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->GetPrimaryServerVersion()));
-
- // 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);
- Reply.append(ServerDescription);
- Reply.push_back(0);
- Reply.append(Printf("%d", NumPlayers));
- Reply.push_back(0);
- Reply.append(Printf("%d", MaxPlayers));
- break;
- }
- } // switch (m_PrimaryServerVersion)
- m_Client->Kick(Reply);
-}
-
-
-
-
diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h
index e4419f6ae..96a7e17d2 100644
--- a/src/Protocol/ProtocolRecognizer.h
+++ b/src/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, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10, 1.8"
-#define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49, 51, 60, 61, 73, 74, 77, 78, 4, 5"
+#define MCS_CLIENT_VERSIONS "1.7.x, 1.8"
+#define MCS_PROTOCOL_VERSIONS "4, 5, 47"
@@ -33,22 +33,6 @@ class cProtocolRecognizer :
public:
enum
{
- PROTO_VERSION_1_2_5 = 29,
- 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_1_5_0 = 60,
- PROTO_VERSION_1_5_2 = 61,
- PROTO_VERSION_1_6_1 = 73,
- PROTO_VERSION_1_6_2 = 74,
- PROTO_VERSION_1_6_3 = 77,
- PROTO_VERSION_1_6_4 = 78,
-
- PROTO_VERSION_NEXT,
- PROTO_VERSION_LATEST = PROTO_VERSION_NEXT - 1, ///< Automatically assigned to the last protocol version, this serves as the default for PrimaryServerVersion
-
- // These will be kept "under" the next / latest, because the next and latest are only needed for previous protocols
PROTO_VERSION_1_7_2 = 4,
PROTO_VERSION_1_7_6 = 5,
PROTO_VERSION_1_8_0 = 47,
@@ -150,23 +134,11 @@ protected:
/// Tries to recognize protocol based on m_Buffer contents; returns true if recognized
bool TryRecognizeProtocol(void);
- /** Tries to recognize a protocol in the length-less family, based on m_Buffer; returns true if recognized.
- Handles protocols before release 1.7, that didn't include packet lengths, and started with a 0x02 handshake packet
- Note that length-less server ping is handled directly in TryRecognizeProtocol(), this function is called only
- when the 0x02 Handshake packet has been received
- */
- bool TryRecognizeLengthlessProtocol(void);
-
/** Tries to recognize a protocol in the leghted family (1.7+), based on m_Buffer; returns true if recognized.
The packet length and type have already been read, type is 0
The number of bytes remaining in the packet is passed as a_PacketLengthRemaining
**/
bool TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRemaining);
-
- /** Called when the recognizer gets a length-less protocol's server ping packet
- Responds with server stats and destroys the client.
- */
- void SendLengthlessServerPing(void);
} ;
diff --git a/src/Root.cpp b/src/Root.cpp
index 966a9b4ba..aa3d43cba 100644
--- a/src/Root.cpp
+++ b/src/Root.cpp
@@ -42,7 +42,6 @@ cRoot* cRoot::s_Root = NULL;
cRoot::cRoot(void) :
- m_PrimaryServerVersion(cProtocolRecognizer::PROTO_VERSION_LATEST),
m_pDefaultWorld(NULL),
m_InputThread(NULL),
m_Server(NULL),
@@ -142,17 +141,6 @@ void cRoot::Start(void)
IniFile.AddHeaderComment(" See: http://wiki.mc-server.org/doku.php?id=configure:settings.ini for further configuration help");
}
- m_PrimaryServerVersion = IniFile.GetValueI("Server", "PrimaryServerVersion", 0);
- if (m_PrimaryServerVersion == 0)
- {
- m_PrimaryServerVersion = cProtocolRecognizer::PROTO_VERSION_LATEST;
- }
- else
- {
- // Make a note in the log that the primary server version is explicitly set in the ini file
- LOGINFO("Primary server version set explicitly to %d.", m_PrimaryServerVersion);
- }
-
LOG("Starting server...");
m_MojangAPI.Start(IniFile); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init
if (!m_Server->InitServer(IniFile))
diff --git a/src/Root.h b/src/Root.h
index 9bc975889..9a482556c 100644
--- a/src/Root.h
+++ b/src/Root.h
@@ -73,9 +73,6 @@ public:
/// Writes chunkstats, for each world and totals, to the output callback
void LogChunkStats(cCommandOutputCallback & a_Output);
- int GetPrimaryServerVersion(void) const { return m_PrimaryServerVersion; } // tolua_export
- void SetPrimaryServerVersion(int a_Version) { m_PrimaryServerVersion = a_Version; } // tolua_export
-
cMonsterConfig * GetMonsterConfig(void) { return m_MonsterConfig; }
cCraftingRecipes * GetCraftingRecipes(void) { return m_CraftingRecipes; } // tolua_export
@@ -169,9 +166,6 @@ private:
typedef std::map<AString, cWorld *> WorldMap;
typedef std::vector<cCommand> cCommandQueue;
-
- /// The version of the protocol that is primary for the server (reported in the server list). All versions are still supported.
- int m_PrimaryServerVersion;
cWorld * m_pDefaultWorld;
WorldMap m_WorldsByName;
diff --git a/src/StringUtils.cpp b/src/StringUtils.cpp
index 73147eebc..21962f832 100644
--- a/src/StringUtils.cpp
+++ b/src/StringUtils.cpp
@@ -441,10 +441,10 @@ static bool isLegalUTF8(const unsigned char * source, int length)
-AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16)
+AString UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length)
{
- a_UTF16.clear();
- a_UTF16.reserve(a_UTF8Length * 3);
+ AString UTF16;
+ UTF16.reserve(a_UTF8Length * 3);
const unsigned char * source = (const unsigned char*)a_UTF8;
const unsigned char * sourceEnd = source + a_UTF8Length;
@@ -458,12 +458,12 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a
unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
if (source + extraBytesToRead >= sourceEnd)
{
- return a_UTF16;
+ return UTF16;
}
// Do this check whether lenient or strict
if (!isLegalUTF8(source, extraBytesToRead + 1))
{
- return a_UTF16;
+ return UTF16;
}
// The cases all fall through. See "Note A" below.
@@ -487,13 +487,13 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a
ch = ' ';
}
unsigned short v = htons((unsigned short)ch);
- a_UTF16.append((const char *)&v, 2);
+ UTF16.append((const char *)&v, 2);
}
else if (ch > UNI_MAX_UTF16)
{
// Invalid value, replace with a space
unsigned short v = htons(' ');
- a_UTF16.append((const char *)&v, 2);
+ UTF16.append((const char *)&v, 2);
}
else
{
@@ -501,11 +501,11 @@ AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a
ch -= halfBase;
unsigned short v1 = htons((ch >> halfShift) + UNI_SUR_HIGH_START);
unsigned short v2 = htons((ch & halfMask) + UNI_SUR_LOW_START);
- a_UTF16.append((const char *)&v1, 2);
- a_UTF16.append((const char *)&v2, 2);
+ UTF16.append((const char *)&v1, 2);
+ UTF16.append((const char *)&v2, 2);
}
}
- return a_UTF16;
+ return UTF16;
}
/*
diff --git a/src/StringUtils.h b/src/StringUtils.h
index a76894d05..159e8ecac 100644
--- a/src/StringUtils.h
+++ b/src/StringUtils.h
@@ -66,8 +66,8 @@ extern void ReplaceString(AString & iHayStack, const AString & iNeedle, const AS
/// Converts a stream of BE shorts into UTF-8 string; returns a ref to a_UTF8
extern AString & RawBEToUTF8(const char * a_RawData, size_t a_NumShorts, AString & a_UTF8);
-/// Converts a UTF-8 string into a UTF-16 BE string, packing that back into AString; return a ref to a_UTF16
-extern AString & UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length, AString & a_UTF16);
+/// Converts a UTF-8 string into a UTF-16 BE string; returns a ref to a_UTF16
+extern AString UTF8ToRawBEUTF16(const char * a_UTF8, size_t a_UTF8Length);
/// Creates a nicely formatted HEX dump of the given memory block. Max a_BytesPerLine is 120
extern AString & CreateHexDump(AString & a_Out, const void * a_Data, size_t a_Size, size_t a_BytesPerLine);