summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ClientHandle.cpp146
-rw-r--r--src/ClientHandle.h20
-rw-r--r--src/Defines.h20
-rw-r--r--src/Entities/Player.cpp33
-rw-r--r--src/Entities/Player.h15
-rw-r--r--src/Protocol/Protocol.h13
-rw-r--r--src/Protocol/Protocol_1_10.cpp22
-rw-r--r--src/Protocol/Protocol_1_10.h10
-rw-r--r--src/Protocol/Protocol_1_11.cpp38
-rw-r--r--src/Protocol/Protocol_1_11.h17
-rw-r--r--src/Protocol/Protocol_1_12.cpp34
-rw-r--r--src/Protocol/Protocol_1_12.h21
-rw-r--r--src/Protocol/Protocol_1_13.cpp566
-rw-r--r--src/Protocol/Protocol_1_13.h51
-rw-r--r--src/Protocol/Protocol_1_14.cpp28
-rw-r--r--src/Protocol/Protocol_1_14.h16
-rw-r--r--src/Protocol/Protocol_1_8.cpp724
-rw-r--r--src/Protocol/Protocol_1_8.h74
-rw-r--r--src/Protocol/Protocol_1_9.cpp433
-rw-r--r--src/Protocol/Protocol_1_9.h109
20 files changed, 1169 insertions, 1221 deletions
diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp
index 1a99fa300..2a1ae2357 100644
--- a/src/ClientHandle.cpp
+++ b/src/ClientHandle.cpp
@@ -566,6 +566,21 @@ void cClientHandle::StreamChunk(int a_ChunkX, int a_ChunkZ, cChunkSender::Priori
+void cClientHandle::HandleAnimation(const bool a_SwingMainHand)
+{
+ if (cPluginManager::Get()->CallHookPlayerAnimation(*m_Player, a_SwingMainHand ? 0 : 1))
+ {
+ // Plugin disagrees, bail out:
+ return;
+ }
+
+ m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, a_SwingMainHand ? EntityAnimation::PlayerMainHandSwings : EntityAnimation::PlayerOffHandSwings, this);
+}
+
+
+
+
+
void cClientHandle::HandleNPCTrade(int a_SlotNum)
{
// TODO
@@ -757,62 +772,6 @@ void cClientHandle::HandlePlayerAbilities(bool a_IsFlying, float FlyingSpeed, fl
-void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround)
-{
- if (m_Player->IsFrozen())
- {
- // Ignore client-side updates if the player is frozen
- return;
- }
-
- Vector3d NewPosition(a_PosX, a_PosY, a_PosZ);
- Vector3d OldPosition = GetPlayer()->GetPosition();
- auto PreviousIsOnGround = GetPlayer()->IsOnGround();
-
- #ifdef __clang__
- #pragma clang diagnostic push
- #pragma clang diagnostic ignored "-Wfloat-equal"
- #endif
-
- if (
- (OldPosition == NewPosition) &&
- (PreviousIsOnGround == a_IsOnGround)
- )
- {
- // Nothing changed, no need to do anything
- return;
- }
-
- #ifdef __clang__
- #pragma clang diagnostic pop
- #endif
-
- // If the player has moved too far, "repair" them:
- if ((OldPosition - NewPosition).SqrLength() > 100 * 100)
- {
- LOGD("Too far away (%0.2f), \"repairing\" the client", (OldPosition - NewPosition).Length());
- SendPlayerMoveLook();
- return;
- }
-
- if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*m_Player, OldPosition, NewPosition, PreviousIsOnGround))
- {
- SendPlayerMoveLook();
- return;
- }
-
- // TODO: should do some checks to see if player is not moving through terrain
- // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
-
- m_Player->SetPosition(NewPosition);
- m_Player->SetTouchGround(a_IsOnGround);
- m_Player->UpdateMovementStats(NewPosition - OldPosition, PreviousIsOnGround);
-}
-
-
-
-
-
void cClientHandle::HandlePluginMessage(const AString & a_Channel, const ContiguousByteBufferView a_Message)
{
if (a_Channel == "REGISTER")
@@ -1342,7 +1301,7 @@ void cClientHandle::FinishDigAnimation()
-void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, eHand a_Hand)
+void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, bool a_UsedMainHand)
{
// This function handles three actions:
// (1) Place a block;
@@ -1359,8 +1318,8 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
// E.g., when opening a chest with a dirt in hand, if the plugin rejects opening the chest, the dirt will not be placed.
// TODO: We are still consuming the items in main hand. Remove this override when the off-hand consumption is handled correctly.
- a_Hand = eHand::hMain;
- const cItem & HeldItem = (a_Hand == eHand::hOff) ? m_Player->GetInventory().GetShieldSlot() : m_Player->GetEquippedItem();
+ a_UsedMainHand = true;
+ const cItem & HeldItem = a_UsedMainHand ? m_Player->GetEquippedItem() : m_Player->GetInventory().GetShieldSlot();
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(HeldItem.m_ItemType);
// TODO: This distance should be calculated from the point that the cursor pointing at, instead of the center of the block
@@ -1369,7 +1328,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e
auto CursorPos = Vector3i(a_CursorX, a_CursorY, a_CursorZ);
double Dist = (Vector3d(ClickedBlockPos) + Vector3d(0.5, 0.5, 0.5) - m_Player->GetEyePosition()).Length();
FLOGD("HandleRightClick: {0}, face {1}, Cursor {2}, Hand: {3}, HeldItem: {4}; Dist: {5:.02f}",
- ClickedBlockPos, a_BlockFace, CursorPos, a_Hand, ItemToFullString(HeldItem), Dist
+ ClickedBlockPos, a_BlockFace, CursorPos, a_UsedMainHand, ItemToFullString(HeldItem), Dist
);
// Check the reach distance:
@@ -1518,25 +1477,66 @@ void cClientHandle::HandlePlayerLook(float a_Rotation, float a_Pitch, bool a_IsO
-void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround)
+void cClientHandle::HandlePlayerMove(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround)
{
- HandlePlayerPos(a_PosX, a_PosY, a_PosZ, a_IsOnGround);
- HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround);
-}
+ if (m_Player->IsFrozen())
+ {
+ // Ignore client-side updates if the player is frozen:
+ return;
+ }
+ const Vector3d NewPosition(a_PosX, a_PosY, a_PosZ);
+ const Vector3d OldPosition = GetPlayer()->GetPosition();
+ const auto PreviousIsOnGround = GetPlayer()->IsOnGround();
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wfloat-equal"
+#endif
+ if (
+ (OldPosition == NewPosition) &&
+ (PreviousIsOnGround == a_IsOnGround)
+ )
+ {
+ // Nothing changed, no need to do anything:
+ return;
+ }
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
-void cClientHandle::HandleAnimation(int a_Animation)
-{
- if (cPluginManager::Get()->CallHookPlayerAnimation(*m_Player, a_Animation))
+ // If the player has moved too far, "repair" them:
+ if ((OldPosition - NewPosition).SqrLength() > 100 * 100)
{
- // Plugin disagrees, bail out
+ LOGD("Too far away (%0.2f), \"repairing\" the client", (OldPosition - NewPosition).Length());
+ SendPlayerMoveLook();
+ return;
+ }
+
+ if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*m_Player, OldPosition, NewPosition, PreviousIsOnGround))
+ {
+ SendPlayerMoveLook();
return;
}
- m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, static_cast<char>(a_Animation), this);
+ // TODO: should do some checks to see if player is not moving through terrain
+ // TODO: Official server refuses position packets too far away from each other, kicking "hacked" clients; we should, too
+
+ m_Player->SetPosition(NewPosition);
+ m_Player->SetTouchGround(a_IsOnGround);
+ m_Player->UpdateMovementStats(NewPosition - OldPosition, PreviousIsOnGround);
+}
+
+
+
+
+
+void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround)
+{
+ HandlePlayerMove(a_PosX, a_PosY, a_PosZ, a_IsOnGround);
+ HandlePlayerLook(a_Rotation, a_Pitch, a_IsOnGround);
}
@@ -1717,20 +1717,20 @@ void cClientHandle::HandleUseEntity(UInt32 a_TargetEntityID, bool a_IsLeftClick)
-void cClientHandle::HandleUseItem(eHand a_Hand)
+void cClientHandle::HandleUseItem(bool a_UsedMainHand)
{
// Use the held item without targeting a block: eating, drinking, charging a bow, using buckets
// In version 1.8.x, this function shares the same packet id with HandleRightClick.
// In version >= 1.9, there is a new packet id for "Use Item".
// TODO: We are still consuming the items in main hand. Remove this override when the off-hand consumption is handled correctly.
- a_Hand = eHand::hMain;
- const cItem & HeldItem = (a_Hand == eHand::hOff) ? m_Player->GetInventory().GetShieldSlot() : m_Player->GetEquippedItem();
+ a_UsedMainHand = true;
+ const cItem & HeldItem = a_UsedMainHand ? m_Player->GetEquippedItem() : m_Player->GetInventory().GetShieldSlot();
cItemHandler * ItemHandler = cItemHandler::GetItemHandler(HeldItem.m_ItemType);
cWorld * World = m_Player->GetWorld();
cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager();
- LOGD("HandleUseItem: Hand: %d; HeldItem: %s", a_Hand, ItemToFullString(HeldItem).c_str());
+ LOGD("HandleUseItem: Hand: %d; HeldItem: %s", a_UsedMainHand, ItemToFullString(HeldItem).c_str());
if (PlgMgr->CallHookPlayerRightClick(*m_Player, -1, 255, -1, BLOCK_FACE_NONE, 0, 0, 0))
{
diff --git a/src/ClientHandle.h b/src/ClientHandle.h
index cb0ea508a..00d5051d2 100644
--- a/src/ClientHandle.h
+++ b/src/ClientHandle.h
@@ -294,8 +294,8 @@ public: // tolua_export
void PacketUnknown(UInt32 a_PacketType);
void PacketError(UInt32 a_PacketType);
- // Calls that cProtocol descendants use for handling packets:
- void HandleAnimation(int a_Animation);
+ /** Called when the protocol receives a (hand swing) animation packet. */
+ void HandleAnimation(bool a_SwingMainHand);
/** Called when the protocol receives a MC|ItemName plugin message, indicating that the player named
an item in the anvil UI. */
@@ -352,18 +352,18 @@ public: // tolua_export
void HandlePing (void);
void HandlePlayerAbilities (bool a_IsFlying, float FlyingSpeed, float WalkingSpeed);
void HandlePlayerLook (float a_Rotation, float a_Pitch, bool a_IsOnGround);
- void HandlePlayerMoveLook (double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround); // While m_bPositionConfirmed (normal gameplay)
- /** Verifies and sets player position, performing relevant checks
- Calls relevant methods to process movement related statistics
- Requires state of previous position and on-ground status, so must be called when these are still intact
- */
- void HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround);
+ /** Verifies and sets player position, performing relevant checks.
+ Calls relevant methods to process movement related statistics.
+ Requires state of previous position and on-ground status, so must be called when these are still intact. */
+ void HandlePlayerMove(double a_PosX, double a_PosY, double a_PosZ, bool a_IsOnGround);
+
+ void HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround);
void HandlePluginMessage (const AString & a_Channel, ContiguousByteBufferView a_Message);
void HandleRespawn (void);
- void HandleRightClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, eHand a_Hand);
+ void HandleRightClick (int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, bool a_UsedMainHand);
void HandleSlotSelected (Int16 a_SlotNum);
void HandleSpectate (const cUUID & a_PlayerUUID);
@@ -382,7 +382,7 @@ public: // tolua_export
);
void HandleUnmount (void);
void HandleUseEntity (UInt32 a_TargetEntityID, bool a_IsLeftClick);
- void HandleUseItem (eHand a_Hand);
+ void HandleUseItem (bool a_UsedMainHand);
void HandleWindowClick (UInt8 a_WindowID, Int16 a_SlotNum, eClickAction a_ClickAction, const cItem & a_HeldItem);
void HandleWindowClose (UInt8 a_WindowID);
diff --git a/src/Defines.h b/src/Defines.h
index a1c1d1cf8..1dbcdda34 100644
--- a/src/Defines.h
+++ b/src/Defines.h
@@ -211,26 +211,6 @@ enum eMobHeadRotation
-enum eHand
-{
- hMain = 0,
- hOff = 1,
-} ;
-
-
-
-
-
-enum eMainHand
-{
- mhLeft = 0,
- mhRight = 1,
-} ;
-
-
-
-
-
enum eSkinPart
{
spCape = 0x01,
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 3b005d8eb..1bfeea6e2 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -123,6 +123,7 @@ cPlayer::cPlayer(const std::shared_ptr<cClientHandle> & a_Client) :
m_IsFlightCapable(false),
m_IsFlying(false),
m_IsFrozen(false),
+ m_IsLeftHanded(false),
m_IsTeleporting(false),
m_IsVisible(true),
m_EatingFinishTick(-1),
@@ -132,8 +133,7 @@ cPlayer::cPlayer(const std::shared_ptr<cClientHandle> & a_Client) :
m_FloaterID(cEntity::INVALID_ID),
m_Team(nullptr),
m_TicksUntilNextSave(PLAYER_INVENTORY_SAVE_INTERVAL),
- m_SkinParts(0),
- m_MainHand(mhRight)
+ m_SkinParts(0)
{
ASSERT(GetName().length() <= 16); // Otherwise this player could crash many clients...
@@ -449,6 +449,15 @@ bool cPlayer::IsInBed(void) const
+bool cPlayer::IsLeftHanded() const
+{
+ return m_IsLeftHanded;
+}
+
+
+
+
+
bool cPlayer::IsStanding() const
{
return std::holds_alternative<BodyStanceStanding>(m_BodyStance);
@@ -692,6 +701,16 @@ void cPlayer::SetFlying(const bool a_ShouldFly)
+void cPlayer::SetLeftHanded(const bool a_IsLeftHanded)
+{
+ m_IsLeftHanded = a_IsLeftHanded;
+ m_World->BroadcastEntityMetadata(*this);
+}
+
+
+
+
+
void cPlayer::SetSprint(const bool a_ShouldSprint)
{
if (a_ShouldSprint && IsStanding())
@@ -2544,16 +2563,6 @@ void cPlayer::SetSkinParts(int a_Parts)
-void cPlayer::SetMainHand(eMainHand a_Hand)
-{
- m_MainHand = a_Hand;
- m_World->BroadcastEntityMetadata(*this, m_ClientHandle.get());
-}
-
-
-
-
-
void cPlayer::AttachTo(cEntity * a_AttachTo)
{
// Different attach, if this is a spectator
diff --git a/src/Entities/Player.h b/src/Entities/Player.h
index 8969099a1..7c8922dbf 100644
--- a/src/Entities/Player.h
+++ b/src/Entities/Player.h
@@ -376,6 +376,9 @@ public:
/** Returns true if a player is sleeping in a bed. */
bool IsInBed(void) const;
+ /** Returns true if the player's left hand is dominant. */
+ bool IsLeftHanded() const;
+
/** Returns true if the player has thrown out a floater */
bool IsFishing(void) const { return m_IsFishing; }
@@ -491,6 +494,9 @@ public:
/** Starts or stops flying, broadcasting the state change. */
void SetFlying(bool a_ShouldFly);
+ /** Sets the dominant hand of the player. */
+ void SetLeftHanded(bool a_IsLeftHanded);
+
/** Starts or stops sprinting, if our current body stance permits, broadcasting the state change. */
void SetSprint(bool a_ShouldSprint);
@@ -557,9 +563,6 @@ public:
int GetSkinParts(void) const { return m_SkinParts; }
void SetSkinParts(int a_Parts);
- eMainHand GetMainHand(void) const { return m_MainHand; }
- void SetMainHand(eMainHand a_Hand);
-
// tolua_end
/** Calls the block placement hooks and places the blocks in the world.
@@ -715,6 +718,9 @@ private:
/** If true, we are locking m_Position to m_FrozenPosition. */
bool m_IsFrozen;
+ /** Whether the player is left-handed, or right-handed. */
+ bool m_IsLeftHanded;
+
/** Was the player frozen manually by a plugin or automatically by the server? */
bool m_IsManuallyFrozen;
@@ -749,9 +755,6 @@ private:
/** Displayed skin part bit mask */
int m_SkinParts;
- /** The main hand of the player */
- eMainHand m_MainHand;
-
/** List on known recipes as Ids */
std::set<UInt32> m_KnownRecipes;
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index 75ebb92d4..c87ab4a7d 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -25,12 +25,9 @@ class cExpOrb;
class cPlayer;
class cEntity;
class cWindow;
-class cPickup;
class cPainting;
class cWorld;
class cMonster;
-class cChunkDataSerializer;
-class cFallingBlock;
class cCompositeChat;
class cStatManager;
class cPacketizer;
@@ -39,12 +36,6 @@ class cPacketizer;
-typedef unsigned char Byte;
-
-
-
-
-
class cProtocol
{
public:
@@ -469,10 +460,10 @@ protected:
cByteBuffer m_OutPacketLenBuffer;
/** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */
- virtual UInt32 GetPacketID(ePacketType a_Packet) = 0;
+ virtual UInt32 GetPacketID(ePacketType a_Packet) const = 0;
/** Returns the current protocol's version, for handling status requests. */
- virtual Version GetProtocolVersion() = 0;
+ virtual Version GetProtocolVersion() const = 0;
/** A generic data-sending routine, all outgoing packet data needs to be routed through this so that descendants may override it. */
virtual void SendData(ContiguousByteBufferView a_Data) = 0;
diff --git a/src/Protocol/Protocol_1_10.cpp b/src/Protocol/Protocol_1_10.cpp
index 6db08c916..9f4413576 100644
--- a/src/Protocol/Protocol_1_10.cpp
+++ b/src/Protocol/Protocol_1_10.cpp
@@ -329,22 +329,22 @@ void cProtocol_1_10_0::SendSoundEffect(const AString & a_SoundName, double a_X,
-cProtocol::Version cProtocol_1_10_0::GetProtocolVersion()
+UInt32 cProtocol_1_10_0::GetProtocolMobType(const eMonsterType a_MobType) const
{
- return Version::v1_10_0;
+ switch (a_MobType)
+ {
+ case mtPolarBear: return 102;
+ default: return Super::GetProtocolMobType(a_MobType);
+ }
}
-UInt32 cProtocol_1_10_0::GetProtocolMobType(const eMonsterType a_MobType)
+cProtocol::Version cProtocol_1_10_0::GetProtocolVersion() const
{
- switch (a_MobType)
- {
- case mtPolarBear: return 102;
- default: return Super::GetProtocolMobType(a_MobType);
- }
+ return Version::v1_10_0;
}
@@ -360,7 +360,7 @@ void cProtocol_1_10_0::HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer
-void cProtocol_1_10_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
+void cProtocol_1_10_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
{
using namespace Metadata;
@@ -413,7 +413,7 @@ void cProtocol_1_10_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity &
a_Pkt.WriteBEUInt8(PLAYER_MAIN_HAND);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
- a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
+ a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
break;
}
case cEntity::etPickup:
@@ -581,7 +581,7 @@ void cProtocol_1_10_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity &
-void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
+void cProtocol_1_10_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
{
using namespace Metadata;
diff --git a/src/Protocol/Protocol_1_10.h b/src/Protocol/Protocol_1_10.h
index 639658eb8..f4ede2949 100644
--- a/src/Protocol/Protocol_1_10.h
+++ b/src/Protocol/Protocol_1_10.h
@@ -32,9 +32,11 @@ protected:
virtual void SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
- virtual Version GetProtocolVersion() override;
- virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override;
+ virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override;
+ virtual Version GetProtocolVersion() const override;
+
virtual void HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer) override;
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
- virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override;
+
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const override;
+ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const override;
};
diff --git a/src/Protocol/Protocol_1_11.cpp b/src/Protocol/Protocol_1_11.cpp
index e2436e04c..1bce409f4 100644
--- a/src/Protocol/Protocol_1_11.cpp
+++ b/src/Protocol/Protocol_1_11.cpp
@@ -492,16 +492,24 @@ void cProtocol_1_11_0::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
-cProtocol::Version cProtocol_1_11_0::GetProtocolVersion()
+signed char cProtocol_1_11_0::GetProtocolEntityStatus(const EntityAnimation a_Animation) const
{
- return Version::v1_11_0;
+ switch (a_Animation)
+ {
+ case EntityAnimation::EggCracks: return 3;
+ case EntityAnimation::EvokerFangsAttacks: return 4;
+ case EntityAnimation::IronGolemStashesGift: return 34;
+ case EntityAnimation::PawnTotemActivates: return 35;
+ case EntityAnimation::SnowballPoofs: return 3;
+ default: return Super::GetProtocolEntityStatus(a_Animation);
+ }
}
-UInt32 cProtocol_1_11_0::GetProtocolMobType(const eMonsterType a_MobType)
+UInt32 cProtocol_1_11_0::GetProtocolMobType(const eMonsterType a_MobType) const
{
switch (a_MobType)
{
@@ -561,17 +569,9 @@ UInt32 cProtocol_1_11_0::GetProtocolMobType(const eMonsterType a_MobType)
-signed char cProtocol_1_11_0::GetProtocolEntityStatus(const EntityAnimation a_Animation) const
+cProtocol::Version cProtocol_1_11_0::GetProtocolVersion() const
{
- switch (a_Animation)
- {
- case EntityAnimation::EggCracks: return 3;
- case EntityAnimation::EvokerFangsAttacks: return 4;
- case EntityAnimation::IronGolemStashesGift: return 34;
- case EntityAnimation::PawnTotemActivates: return 35;
- case EntityAnimation::SnowballPoofs: return 3;
- default: return Super::GetProtocolEntityStatus(a_Animation);
- }
+ return Version::v1_11_0;
}
@@ -592,14 +592,14 @@ void cProtocol_1_11_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorY);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, CursorZ);
- m_Client->HandleRightClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), FloorC(CursorX * 16), FloorC(CursorY * 16), FloorC(CursorZ * 16), HandIntToEnum(Hand));
+ m_Client->HandleRightClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), FloorC(CursorX * 16), FloorC(CursorY * 16), FloorC(CursorZ * 16), Hand == 0);
}
-void cProtocol_1_11_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity)
+void cProtocol_1_11_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const
{
a_Writer.AddInt("x", a_BlockEntity.GetPosX());
a_Writer.AddInt("y", a_BlockEntity.GetPosY());
@@ -632,7 +632,7 @@ void cProtocol_1_11_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockE
-void cProtocol_1_11_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
+void cProtocol_1_11_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
{
using namespace Metadata_1_11;
@@ -685,7 +685,7 @@ void cProtocol_1_11_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity &
a_Pkt.WriteBEUInt8(PLAYER_MAIN_HAND);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
- a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
+ a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
break;
}
case cEntity::etPickup:
@@ -855,7 +855,7 @@ void cProtocol_1_11_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity &
-void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
+void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
{
using namespace Metadata_1_11;
@@ -1273,7 +1273,7 @@ void cProtocol_1_11_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_
////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_11_1:
-cProtocol::Version cProtocol_1_11_1::GetProtocolVersion()
+cProtocol::Version cProtocol_1_11_1::GetProtocolVersion() const
{
return Version::v1_11_1;
}
diff --git a/src/Protocol/Protocol_1_11.h b/src/Protocol/Protocol_1_11.h
index f5ed73187..5bf03a9dd 100644
--- a/src/Protocol/Protocol_1_11.h
+++ b/src/Protocol/Protocol_1_11.h
@@ -40,18 +40,15 @@ protected:
virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
virtual void SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) override;
- /** Returns 1.11. */
- virtual Version GetProtocolVersion() override;
-
- /** Converts eMonsterType to protocol-specific mob IDs */
- virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override;
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override;
+ virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override;
+ virtual Version GetProtocolVersion() const override;
- virtual void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer) override;
+ virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override;
- virtual void WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) override;
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
- virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override;
+ virtual void WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const override;
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const override;
+ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const override;
};
@@ -69,5 +66,5 @@ public:
protected:
- virtual Version GetProtocolVersion() override;
+ virtual Version GetProtocolVersion() const override;
};
diff --git a/src/Protocol/Protocol_1_12.cpp b/src/Protocol/Protocol_1_12.cpp
index 31daa96f7..d0e77ae80 100644
--- a/src/Protocol/Protocol_1_12.cpp
+++ b/src/Protocol/Protocol_1_12.cpp
@@ -323,7 +323,7 @@ namespace Metadata_1_12
////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_12:
-void cProtocol_1_12::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
+void cProtocol_1_12::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
{
using namespace Metadata_1_12;
@@ -380,7 +380,7 @@ void cProtocol_1_12::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_
a_Pkt.WriteBEUInt8(PLAYER_MAIN_HAND);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
- a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
+ a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
break;
}
case cEntity::etPickup:
@@ -550,7 +550,7 @@ void cProtocol_1_12::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_
-void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
+void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
{
using namespace Metadata_1_12;
@@ -982,7 +982,7 @@ void cProtocol_1_12::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mo
-UInt32 cProtocol_1_12::GetPacketID(cProtocol::ePacketType a_Packet)
+UInt32 cProtocol_1_12::GetPacketID(cProtocol::ePacketType a_Packet) const
{
switch (a_Packet)
{
@@ -1061,15 +1061,6 @@ void cProtocol_1_12::HandlePacketAdvancementTab(cByteBuffer & a_ByteBuffer)
-cProtocol::Version cProtocol_1_12::GetProtocolVersion()
-{
- return Version::v1_12;
-}
-
-
-
-
-
signed char cProtocol_1_12::GetProtocolEntityStatus(EntityAnimation a_Animation) const
{
switch (a_Animation)
@@ -1084,7 +1075,7 @@ signed char cProtocol_1_12::GetProtocolEntityStatus(EntityAnimation a_Animation)
-UInt32 cProtocol_1_12::GetProtocolMobType(const eMonsterType a_MobType)
+UInt32 cProtocol_1_12::GetProtocolMobType(const eMonsterType a_MobType) const
{
switch (a_MobType)
{
@@ -1098,6 +1089,15 @@ UInt32 cProtocol_1_12::GetProtocolMobType(const eMonsterType a_MobType)
+cProtocol::Version cProtocol_1_12::GetProtocolVersion() const
+{
+ return Version::v1_12;
+}
+
+
+
+
+
bool cProtocol_1_12::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
switch (m_State)
@@ -1176,7 +1176,7 @@ bool cProtocol_1_12::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketTyp
////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_12_1:
-UInt32 cProtocol_1_12_1::GetPacketID(ePacketType a_Packet)
+UInt32 cProtocol_1_12_1::GetPacketID(ePacketType a_Packet) const
{
switch (a_Packet)
{
@@ -1219,7 +1219,7 @@ UInt32 cProtocol_1_12_1::GetPacketID(ePacketType a_Packet)
-cProtocol::Version cProtocol_1_12_1::GetProtocolVersion()
+cProtocol::Version cProtocol_1_12_1::GetProtocolVersion() const
{
return Version::v1_12_1;
}
@@ -1305,7 +1305,7 @@ bool cProtocol_1_12_1::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketT
////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_12_2::
-cProtocol::Version cProtocol_1_12_2::GetProtocolVersion()
+cProtocol::Version cProtocol_1_12_2::GetProtocolVersion() const
{
return Version::v1_12_2;
}
diff --git a/src/Protocol/Protocol_1_12.h b/src/Protocol/Protocol_1_12.h
index 65bc23bcd..0d18c2ae5 100644
--- a/src/Protocol/Protocol_1_12.h
+++ b/src/Protocol/Protocol_1_12.h
@@ -34,16 +34,18 @@ public:
protected:
- virtual UInt32 GetPacketID(ePacketType a_Packet) override;
- virtual Version GetProtocolVersion() override;
+ virtual UInt32 GetPacketID(ePacketType a_Packet) const override;
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override;
- virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override;
+ virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override;
+ virtual Version GetProtocolVersion() const override;
+
virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
virtual void HandlePacketAdvancementTab(cByteBuffer & a_ByteBuffer);
virtual void HandleCraftRecipe(cByteBuffer & a_ByteBuffer);
virtual void HandlePacketCraftingBookData(cByteBuffer & a_ByteBuffer);
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
- virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override;
+
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const override;
+ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const override;
};
@@ -61,8 +63,9 @@ public:
protected:
- virtual UInt32 GetPacketID(ePacketType a_Packet) override;
- virtual Version GetProtocolVersion() override;
+ virtual UInt32 GetPacketID(ePacketType a_Packet) const override;
+ virtual Version GetProtocolVersion() const override;
+
virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
};
@@ -81,8 +84,10 @@ public:
protected:
- virtual Version GetProtocolVersion() override;
+ virtual Version GetProtocolVersion() const override;
+
virtual void HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer) override;
+
virtual void SendKeepAlive(UInt32 a_PingID) override;
virtual void SendUnlockRecipe(UInt32 a_RecipeID) override;
virtual void SendInitRecipes(UInt32 a_RecipeID) override;
diff --git a/src/Protocol/Protocol_1_13.cpp b/src/Protocol/Protocol_1_13.cpp
index a802f0074..400dd62b1 100644
--- a/src/Protocol/Protocol_1_13.cpp
+++ b/src/Protocol/Protocol_1_13.cpp
@@ -238,107 +238,180 @@ void cProtocol_1_13::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
-bool cProtocol_1_13::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
+UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadata a_Metadata) const
{
- if (m_State != 3)
- {
- return Super::HandlePacket(a_ByteBuffer, a_PacketType);
- }
+ const UInt8 Entity = 6;
+ const UInt8 Living = Entity + 5;
+ const UInt8 Insentient = Living + 1;
+ const UInt8 Ageable = Insentient + 1;
+ const UInt8 AbstractHorse = Ageable + 2;
+ const UInt8 ChestedHorse = AbstractHorse + 1;
+ const UInt8 TameableAnimal = Ageable + 2;
+ const UInt8 Minecart = Entity + 6;
- // Game
- switch (a_PacketType)
+ switch (a_Metadata)
{
- case 0x00: HandleConfirmTeleport(a_ByteBuffer); return true;
- case 0x05: HandlePacketTabComplete(a_ByteBuffer); return true;
- case 0x02: HandlePacketChatMessage(a_ByteBuffer); return true;
- case 0x03: HandlePacketClientStatus(a_ByteBuffer); return true;
- case 0x04: HandlePacketClientSettings(a_ByteBuffer); return true;
- case 0x06: break; // Confirm transaction - not used in Cuberite
- case 0x07: HandlePacketEnchantItem(a_ByteBuffer); return true;
- case 0x08: HandlePacketWindowClick(a_ByteBuffer); return true;
- case 0x09: HandlePacketWindowClose(a_ByteBuffer); return true;
- case 0x0a: HandlePacketPluginMessage(a_ByteBuffer); return true;
- case 0x0d: HandlePacketUseEntity(a_ByteBuffer); return true;
- case 0x0e: HandlePacketKeepAlive(a_ByteBuffer); return true;
- case 0x0f: HandlePacketPlayer(a_ByteBuffer); return true;
- case 0x10: HandlePacketPlayerPos(a_ByteBuffer); return true;
- case 0x11: HandlePacketPlayerPosLook(a_ByteBuffer); return true;
- case 0x12: HandlePacketPlayerLook(a_ByteBuffer); return true;
- case 0x13: HandlePacketVehicleMove(a_ByteBuffer); return true;
- case 0x14: HandlePacketBoatSteer(a_ByteBuffer); return true;
- case 0x15: break; // Pick item - not yet implemented
- case 0x16: break; // Craft Recipe Request - not yet implemented
- case 0x17: HandlePacketPlayerAbilities(a_ByteBuffer); return true;
- case 0x18: HandlePacketBlockDig(a_ByteBuffer); return true;
- case 0x19: HandlePacketEntityAction(a_ByteBuffer); return true;
- case 0x1a: HandlePacketSteerVehicle(a_ByteBuffer); return true;
- case 0x1b: HandlePacketCraftingBookData(a_ByteBuffer); return true;
- case 0x1d: break; // Resource pack status - not yet implemented
- case 0x1e: HandlePacketAdvancementTab(a_ByteBuffer); return true;
- case 0x20: HandlePacketSetBeaconEffect(a_ByteBuffer); return true;
- case 0x21: HandlePacketSlotSelect(a_ByteBuffer); return true;
- case 0x24: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;
- case 0x26: HandlePacketUpdateSign(a_ByteBuffer); return true;
- case 0x27: HandlePacketAnimation(a_ByteBuffer); return true;
- case 0x28: HandlePacketSpectate(a_ByteBuffer); return true;
- case 0x29: HandlePacketBlockPlace(a_ByteBuffer); return true;
- case 0x2a: HandlePacketUseItem(a_ByteBuffer); return true;
- }
+ case EntityMetadata::EntityFlags: return 0;
+ case EntityMetadata::EntityAir: return 1;
+ case EntityMetadata::EntityCustomName: return 2;
+ case EntityMetadata::EntityCustomNameVisible: return 3;
+ case EntityMetadata::EntitySilent: return 4;
+ case EntityMetadata::EntityNoGravity: return 5;
+ case EntityMetadata::PotionThrown: return Entity;
+ case EntityMetadata::FallingBlockPosition: return Entity;
+ case EntityMetadata::AreaEffectCloudRadius: return Entity;
+ case EntityMetadata::AreaEffectCloudColor: return Entity + 1;
+ case EntityMetadata::AreaEffectCloudSinglePointEffect: return Entity + 2;
+ case EntityMetadata::AreaEffectCloudParticleId: return Entity + 3;
+ case EntityMetadata::ArrowFlags: return Entity;
+ case EntityMetadata::TippedArrowColor: return Entity + 1;
+ case EntityMetadata::BoatLastHitTime: return Entity;
+ case EntityMetadata::BoatForwardDirection: return Entity + 1;
+ case EntityMetadata::BoatDamageTaken: return Entity + 2;
+ case EntityMetadata::BoatType: return Entity + 3;
+ case EntityMetadata::BoatLeftPaddleTurning: return Entity + 4;
+ case EntityMetadata::BoatRightPaddleTurning: return Entity + 5;
+ case EntityMetadata::BoatSplashTimer: return Entity + 6;
+ case EntityMetadata::EnderCrystalBeamTarget: return Entity;
+ case EntityMetadata::EnderCrystalShowBottom: return Entity + 1;
+ case EntityMetadata::WitherSkullInvulnerable: return Entity;
+ case EntityMetadata::FireworkInfo: return Entity;
+ case EntityMetadata::FireworkBoostedEntityId: return Entity + 1;
+ case EntityMetadata::ItemFrameItem: return Entity;
+ case EntityMetadata::ItemFrameRotation: return Entity + 1;
+ case EntityMetadata::ItemItem: return Entity;
+ case EntityMetadata::LivingActiveHand: return Entity;
+ case EntityMetadata::LivingHealth: return Entity + 1;
+ case EntityMetadata::LivingPotionEffectColor: return Entity + 2;
+ case EntityMetadata::LivingPotionEffectAmbient: return Entity + 3;
+ case EntityMetadata::LivingNumberOfArrows: return Entity + 4;
+ case EntityMetadata::PlayerAdditionalHearts: return Living;
+ case EntityMetadata::PlayerScore: return Living + 1;
+ case EntityMetadata::PlayerDisplayedSkinParts: return Living + 2;
+ case EntityMetadata::PlayerMainHand: return Living + 3;
+ case EntityMetadata::ArmorStandStatus: return Living;
+ case EntityMetadata::ArmorStandHeadRotation: return Living + 1;
+ case EntityMetadata::ArmorStandBodyRotation: return Living + 2;
+ case EntityMetadata::ArmorStandLeftArmRotation: return Living + 3;
+ case EntityMetadata::ArmorStandRightArmRotation: return Living + 4;
+ case EntityMetadata::ArmorStandLeftLegRotation: return Living + 5;
+ case EntityMetadata::ArmorStandRightLegRotation: return Living + 6;
+ case EntityMetadata::InsentientFlags: return Living;
+ case EntityMetadata::BatHanging: return Insentient;
+ case EntityMetadata::AgeableIsBaby: return Insentient;
+ case EntityMetadata::AbstractHorseFlags: return Ageable;
+ case EntityMetadata::AbstractHorseOwner: return Ageable + 1;
+ case EntityMetadata::HorseVariant: return AbstractHorse;
+ case EntityMetadata::HorseArmour: return AbstractHorse + 1;
+ case EntityMetadata::ChestedHorseChested: return AbstractHorse;
+ case EntityMetadata::LlamaStrength: return ChestedHorse;
+ case EntityMetadata::LlamaCarpetColor: return ChestedHorse + 1;
+ case EntityMetadata::LlamaVariant: return ChestedHorse + 2;
+ case EntityMetadata::PigHasSaddle: return Ageable;
+ case EntityMetadata::PigTotalCarrotOnAStickBoost: return Ageable + 1;
+ case EntityMetadata::RabbitType: return Ageable;
+ case EntityMetadata::PolarBearStanding: return Ageable;
+ case EntityMetadata::SheepFlags: return Ageable;
+ case EntityMetadata::TameableAnimalFlags: return Ageable;
+ case EntityMetadata::TameableAnimalOwner: return Ageable + 1;
+ case EntityMetadata::OcelotType: return TameableAnimal;
+ case EntityMetadata::WolfDamageTaken: return TameableAnimal;
+ case EntityMetadata::WolfBegging: return TameableAnimal + 1;
+ case EntityMetadata::WolfCollarColour: return TameableAnimal + 2;
+ case EntityMetadata::VillagerProfession: return Ageable;
+ case EntityMetadata::IronGolemPlayerCreated: return Insentient;
+ case EntityMetadata::ShulkerFacingDirection: return Insentient;
+ case EntityMetadata::ShulkerAttachmentFallingBlockPosition: return Insentient + 1;
+ case EntityMetadata::ShulkerShieldHeight: return Insentient + 2;
+ case EntityMetadata::BlazeOnFire: return Insentient;
+ case EntityMetadata::CreeperState: return Insentient;
+ case EntityMetadata::CreeperPowered: return Insentient + 1;
+ case EntityMetadata::CreeperIgnited: return Insentient + 2;
+ case EntityMetadata::GuardianStatus: return Insentient;
+ case EntityMetadata::GuardianTarget: return Insentient + 1;
+ case EntityMetadata::IllagerFlags: return Insentient;
+ case EntityMetadata::SpeIlagerSpell: return Insentient + 1;
+ case EntityMetadata::VexFlags: return Insentient;
+ case EntityMetadata::SpiderClimbing: return Insentient;
+ case EntityMetadata::WitchAggresive: return Insentient;
+ case EntityMetadata::WitherFirstHeadTarget: return Insentient;
+ case EntityMetadata::WitherSecondHeadTarget: return Insentient + 1;
+ case EntityMetadata::WitherThirdHeadTarget: return Insentient + 2;
+ case EntityMetadata::WitherInvulnerableTimer: return Insentient + 3;
+ case EntityMetadata::ZombieIsBaby: return Insentient;
+ case EntityMetadata::ZombieHandsRisedUp: return Insentient + 2;
+ case EntityMetadata::ZombieVillagerConverting: return Insentient + 4;
+ case EntityMetadata::ZombieVillagerProfession: return Insentient + 5;
+ case EntityMetadata::EndermanCarriedBlock: return Insentient;
+ case EntityMetadata::EndermanScreaming: return Insentient + 1;
+ case EntityMetadata::EnderDragonDragonPhase: return Insentient;
+ case EntityMetadata::GhastAttacking: return Insentient;
+ case EntityMetadata::SlimeSize: return Insentient;
+ case EntityMetadata::MinecartShakingPower: return Entity;
+ case EntityMetadata::MinecartShakingDirection: return Entity + 1;
+ case EntityMetadata::MinecartShakingMultiplier: return Entity + 2;
+ case EntityMetadata::MinecartBlockIDMeta: return Entity + 3;
+ case EntityMetadata::MinecartBlockY: return Entity + 4;
+ case EntityMetadata::MinecartShowBlock: return Entity + 5;
+ case EntityMetadata::MinecartCommandBlockCommand: return Minecart;
+ case EntityMetadata::MinecartCommandBlockLastOutput: return Minecart + 1;
+ case EntityMetadata::MinecartFurnacePowered: return Minecart;
+ case EntityMetadata::TNTPrimedFuseTime: return Entity;
- return Super::HandlePacket(a_ByteBuffer, a_PacketType);
+ case EntityMetadata::EntityPose:
+ case EntityMetadata::AreaEffectCloudParticleParameter1:
+ case EntityMetadata::AreaEffectCloudParticleParameter2:
+ case EntityMetadata::AbstractSkeletonArmsSwinging:
+ case EntityMetadata::ZombieUnusedWasType: break;
+ }
+ UNREACHABLE("Retrieved invalid metadata for protocol");
}
-void cProtocol_1_13::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
+UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadataType a_FieldType) const
{
- HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
-
- // If the plugin channel is recognized vanilla, handle it directly:
- if (Channel.substr(0, 15) == "minecraft:brand")
+ switch (a_FieldType)
{
- HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand);
- m_Client->SetClientBrand(Brand);
-
- // Send back our brand, including the length:
- m_Client->SendPluginMessage("minecraft:brand", "\x08""Cuberite");
- return;
+ case EntityMetadataType::Byte: return 0;
+ case EntityMetadataType::VarInt: return 1;
+ case EntityMetadataType::Float: return 2;
+ case EntityMetadataType::String: return 3;
+ case EntityMetadataType::Chat: return 4;
+ case EntityMetadataType::OptChat: return 5;
+ case EntityMetadataType::Item: return 6;
+ case EntityMetadataType::Boolean: return 7;
+ case EntityMetadataType::Rotation: return 8;
+ case EntityMetadataType::Position: return 9;
+ case EntityMetadataType::OptPosition: return 10;
+ case EntityMetadataType::Direction: return 11;
+ case EntityMetadataType::OptUUID: return 12;
+ case EntityMetadataType::OptBlockID: return 13;
+ case EntityMetadataType::NBT: return 14;
+ case EntityMetadataType::Particle: return 15;
+ case EntityMetadataType::VillagerData: return 16;
+ case EntityMetadataType::OptVarInt: return 17;
+ case EntityMetadataType::Pose: return 18;
}
-
- ContiguousByteBuffer Data;
-
- // Read the plugin message and relay to clienthandle:
- VERIFY(a_ByteBuffer.ReadSome(Data, a_ByteBuffer.GetReadableSpace())); // Always succeeds
- m_Client->HandlePluginMessage(Channel, Data);
-}
-
-
-
-
-
-void cProtocol_1_13::HandlePacketSetBeaconEffect(cByteBuffer & a_ByteBuffer)
-{
- HANDLE_READ(a_ByteBuffer, ReadVarInt32, UInt32, Effect1);
- HANDLE_READ(a_ByteBuffer, ReadVarInt32, UInt32, Effect2);
- m_Client->HandleBeaconSelection(Effect1, Effect2);
+ UNREACHABLE("Translated invalid metadata type for protocol");
}
-cProtocol::Version cProtocol_1_13::GetProtocolVersion()
+std::pair<short, short> cProtocol_1_13::GetItemFromProtocolID(UInt32 a_ProtocolID) const
{
- return Version::v1_13;
+ return PaletteUpgrade::ToItem(Palette_1_13::ToItem(a_ProtocolID));
}
-UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType)
+UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType) const
{
switch (a_PacketType)
{
@@ -403,6 +476,15 @@ UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType)
+UInt32 cProtocol_1_13::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const
+{
+ return Palette_1_13::From(PaletteUpgrade::FromBlock(a_BlockType, a_Meta));
+}
+
+
+
+
+
signed char cProtocol_1_13::GetProtocolEntityStatus(const EntityAnimation a_Animation) const
{
switch (a_Animation)
@@ -416,7 +498,16 @@ signed char cProtocol_1_13::GetProtocolEntityStatus(const EntityAnimation a_Anim
-UInt32 cProtocol_1_13::GetProtocolMobType(eMonsterType a_MobType)
+UInt32 cProtocol_1_13::GetProtocolItemType(short a_ItemID, short a_ItemDamage) const
+{
+ return Palette_1_13::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
+}
+
+
+
+
+
+UInt32 cProtocol_1_13::GetProtocolMobType(eMonsterType a_MobType) const
{
switch (a_MobType)
{
@@ -488,207 +579,116 @@ UInt32 cProtocol_1_13::GetProtocolMobType(eMonsterType a_MobType)
-UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadata a_Metadata)
+UInt32 cProtocol_1_13::GetProtocolStatisticType(Statistic a_Statistic) const
{
- const UInt8 Entity = 6;
- const UInt8 Living = Entity + 5;
- const UInt8 Insentient = Living + 1;
- const UInt8 Ageable = Insentient + 1;
- const UInt8 AbstractHorse = Ageable + 2;
- const UInt8 ChestedHorse = AbstractHorse + 1;
- const UInt8 TameableAnimal = Ageable + 2;
- const UInt8 Minecart = Entity + 6;
-
- switch (a_Metadata)
- {
- case EntityMetadata::EntityFlags: return 0;
- case EntityMetadata::EntityAir: return 1;
- case EntityMetadata::EntityCustomName: return 2;
- case EntityMetadata::EntityCustomNameVisible: return 3;
- case EntityMetadata::EntitySilent: return 4;
- case EntityMetadata::EntityNoGravity: return 5;
- case EntityMetadata::PotionThrown: return Entity;
- case EntityMetadata::FallingBlockPosition: return Entity;
- case EntityMetadata::AreaEffectCloudRadius: return Entity;
- case EntityMetadata::AreaEffectCloudColor: return Entity + 1;
- case EntityMetadata::AreaEffectCloudSinglePointEffect: return Entity + 2;
- case EntityMetadata::AreaEffectCloudParticleId: return Entity + 3;
- case EntityMetadata::ArrowFlags: return Entity;
- case EntityMetadata::TippedArrowColor: return Entity + 1;
- case EntityMetadata::BoatLastHitTime: return Entity;
- case EntityMetadata::BoatForwardDirection: return Entity + 1;
- case EntityMetadata::BoatDamageTaken: return Entity + 2;
- case EntityMetadata::BoatType: return Entity + 3;
- case EntityMetadata::BoatLeftPaddleTurning: return Entity + 4;
- case EntityMetadata::BoatRightPaddleTurning: return Entity + 5;
- case EntityMetadata::BoatSplashTimer: return Entity + 6;
- case EntityMetadata::EnderCrystalBeamTarget: return Entity;
- case EntityMetadata::EnderCrystalShowBottom: return Entity + 1;
- case EntityMetadata::WitherSkullInvulnerable: return Entity;
- case EntityMetadata::FireworkInfo: return Entity;
- case EntityMetadata::FireworkBoostedEntityId: return Entity + 1;
- case EntityMetadata::ItemFrameItem: return Entity;
- case EntityMetadata::ItemFrameRotation: return Entity + 1;
- case EntityMetadata::ItemItem: return Entity;
- case EntityMetadata::LivingActiveHand: return Entity;
- case EntityMetadata::LivingHealth: return Entity + 1;
- case EntityMetadata::LivingPotionEffectColor: return Entity + 2;
- case EntityMetadata::LivingPotionEffectAmbient: return Entity + 3;
- case EntityMetadata::LivingNumberOfArrows: return Entity + 4;
- case EntityMetadata::PlayerAdditionalHearts: return Living;
- case EntityMetadata::PlayerScore: return Living + 1;
- case EntityMetadata::PlayerDisplayedSkinParts: return Living + 2;
- case EntityMetadata::PlayerMainHand: return Living + 3;
- case EntityMetadata::ArmorStandStatus: return Living;
- case EntityMetadata::ArmorStandHeadRotation: return Living + 1;
- case EntityMetadata::ArmorStandBodyRotation: return Living + 2;
- case EntityMetadata::ArmorStandLeftArmRotation: return Living + 3;
- case EntityMetadata::ArmorStandRightArmRotation: return Living + 4;
- case EntityMetadata::ArmorStandLeftLegRotation: return Living + 5;
- case EntityMetadata::ArmorStandRightLegRotation: return Living + 6;
- case EntityMetadata::InsentientFlags: return Living;
- case EntityMetadata::BatHanging: return Insentient;
- case EntityMetadata::AgeableIsBaby: return Insentient;
- case EntityMetadata::AbstractHorseFlags: return Ageable;
- case EntityMetadata::AbstractHorseOwner: return Ageable + 1;
- case EntityMetadata::HorseVariant: return AbstractHorse;
- case EntityMetadata::HorseArmour: return AbstractHorse + 1;
- case EntityMetadata::ChestedHorseChested: return AbstractHorse;
- case EntityMetadata::LlamaStrength: return ChestedHorse;
- case EntityMetadata::LlamaCarpetColor: return ChestedHorse + 1;
- case EntityMetadata::LlamaVariant: return ChestedHorse + 2;
- case EntityMetadata::PigHasSaddle: return Ageable;
- case EntityMetadata::PigTotalCarrotOnAStickBoost: return Ageable + 1;
- case EntityMetadata::RabbitType: return Ageable;
- case EntityMetadata::PolarBearStanding: return Ageable;
- case EntityMetadata::SheepFlags: return Ageable;
- case EntityMetadata::TameableAnimalFlags: return Ageable;
- case EntityMetadata::TameableAnimalOwner: return Ageable + 1;
- case EntityMetadata::OcelotType: return TameableAnimal;
- case EntityMetadata::WolfDamageTaken: return TameableAnimal;
- case EntityMetadata::WolfBegging: return TameableAnimal + 1;
- case EntityMetadata::WolfCollarColour: return TameableAnimal + 2;
- case EntityMetadata::VillagerProfession: return Ageable;
- case EntityMetadata::IronGolemPlayerCreated: return Insentient;
- case EntityMetadata::ShulkerFacingDirection: return Insentient;
- case EntityMetadata::ShulkerAttachmentFallingBlockPosition: return Insentient + 1;
- case EntityMetadata::ShulkerShieldHeight: return Insentient + 2;
- case EntityMetadata::BlazeOnFire: return Insentient;
- case EntityMetadata::CreeperState: return Insentient;
- case EntityMetadata::CreeperPowered: return Insentient + 1;
- case EntityMetadata::CreeperIgnited: return Insentient + 2;
- case EntityMetadata::GuardianStatus: return Insentient;
- case EntityMetadata::GuardianTarget: return Insentient + 1;
- case EntityMetadata::IllagerFlags: return Insentient;
- case EntityMetadata::SpeIlagerSpell: return Insentient + 1;
- case EntityMetadata::VexFlags: return Insentient;
- case EntityMetadata::SpiderClimbing: return Insentient;
- case EntityMetadata::WitchAggresive: return Insentient;
- case EntityMetadata::WitherFirstHeadTarget: return Insentient;
- case EntityMetadata::WitherSecondHeadTarget: return Insentient + 1;
- case EntityMetadata::WitherThirdHeadTarget: return Insentient + 2;
- case EntityMetadata::WitherInvulnerableTimer: return Insentient + 3;
- case EntityMetadata::ZombieIsBaby: return Insentient;
- case EntityMetadata::ZombieHandsRisedUp: return Insentient + 2;
- case EntityMetadata::ZombieVillagerConverting: return Insentient + 4;
- case EntityMetadata::ZombieVillagerProfession: return Insentient + 5;
- case EntityMetadata::EndermanCarriedBlock: return Insentient;
- case EntityMetadata::EndermanScreaming: return Insentient + 1;
- case EntityMetadata::EnderDragonDragonPhase: return Insentient;
- case EntityMetadata::GhastAttacking: return Insentient;
- case EntityMetadata::SlimeSize: return Insentient;
- case EntityMetadata::MinecartShakingPower: return Entity;
- case EntityMetadata::MinecartShakingDirection: return Entity + 1;
- case EntityMetadata::MinecartShakingMultiplier: return Entity + 2;
- case EntityMetadata::MinecartBlockIDMeta: return Entity + 3;
- case EntityMetadata::MinecartBlockY: return Entity + 4;
- case EntityMetadata::MinecartShowBlock: return Entity + 5;
- case EntityMetadata::MinecartCommandBlockCommand: return Minecart;
- case EntityMetadata::MinecartCommandBlockLastOutput: return Minecart + 1;
- case EntityMetadata::MinecartFurnacePowered: return Minecart;
- case EntityMetadata::TNTPrimedFuseTime: return Entity;
-
- case EntityMetadata::EntityPose:
- case EntityMetadata::AreaEffectCloudParticleParameter1:
- case EntityMetadata::AreaEffectCloudParticleParameter2:
- case EntityMetadata::AbstractSkeletonArmsSwinging:
- case EntityMetadata::ZombieUnusedWasType: break;
- }
- UNREACHABLE("Retrieved invalid metadata for protocol");
+ return Palette_1_13::From(a_Statistic);
}
-UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadataType a_FieldType)
+cProtocol::Version cProtocol_1_13::GetProtocolVersion() const
{
- switch (a_FieldType)
- {
- case EntityMetadataType::Byte: return 0;
- case EntityMetadataType::VarInt: return 1;
- case EntityMetadataType::Float: return 2;
- case EntityMetadataType::String: return 3;
- case EntityMetadataType::Chat: return 4;
- case EntityMetadataType::OptChat: return 5;
- case EntityMetadataType::Item: return 6;
- case EntityMetadataType::Boolean: return 7;
- case EntityMetadataType::Rotation: return 8;
- case EntityMetadataType::Position: return 9;
- case EntityMetadataType::OptPosition: return 10;
- case EntityMetadataType::Direction: return 11;
- case EntityMetadataType::OptUUID: return 12;
- case EntityMetadataType::OptBlockID: return 13;
- case EntityMetadataType::NBT: return 14;
- case EntityMetadataType::Particle: return 15;
- case EntityMetadataType::VillagerData: return 16;
- case EntityMetadataType::OptVarInt: return 17;
- case EntityMetadataType::Pose: return 18;
- }
- UNREACHABLE("Translated invalid metadata type for protocol");
+ return Version::v1_13;
}
-std::pair<short, short> cProtocol_1_13::GetItemFromProtocolID(UInt32 a_ProtocolID)
+bool cProtocol_1_13::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
- return PaletteUpgrade::ToItem(Palette_1_13::ToItem(a_ProtocolID));
+ if (m_State != 3)
+ {
+ return Super::HandlePacket(a_ByteBuffer, a_PacketType);
+ }
+
+ // Game
+ switch (a_PacketType)
+ {
+ case 0x00: HandleConfirmTeleport(a_ByteBuffer); return true;
+ case 0x05: HandlePacketTabComplete(a_ByteBuffer); return true;
+ case 0x02: HandlePacketChatMessage(a_ByteBuffer); return true;
+ case 0x03: HandlePacketClientStatus(a_ByteBuffer); return true;
+ case 0x04: HandlePacketClientSettings(a_ByteBuffer); return true;
+ case 0x06: break; // Confirm transaction - not used in Cuberite
+ case 0x07: HandlePacketEnchantItem(a_ByteBuffer); return true;
+ case 0x08: HandlePacketWindowClick(a_ByteBuffer); return true;
+ case 0x09: HandlePacketWindowClose(a_ByteBuffer); return true;
+ case 0x0a: HandlePacketPluginMessage(a_ByteBuffer); return true;
+ case 0x0d: HandlePacketUseEntity(a_ByteBuffer); return true;
+ case 0x0e: HandlePacketKeepAlive(a_ByteBuffer); return true;
+ case 0x0f: HandlePacketPlayer(a_ByteBuffer); return true;
+ case 0x10: HandlePacketPlayerPos(a_ByteBuffer); return true;
+ case 0x11: HandlePacketPlayerPosLook(a_ByteBuffer); return true;
+ case 0x12: HandlePacketPlayerLook(a_ByteBuffer); return true;
+ case 0x13: HandlePacketVehicleMove(a_ByteBuffer); return true;
+ case 0x14: HandlePacketBoatSteer(a_ByteBuffer); return true;
+ case 0x15: break; // Pick item - not yet implemented
+ case 0x16: break; // Craft Recipe Request - not yet implemented
+ case 0x17: HandlePacketPlayerAbilities(a_ByteBuffer); return true;
+ case 0x18: HandlePacketBlockDig(a_ByteBuffer); return true;
+ case 0x19: HandlePacketEntityAction(a_ByteBuffer); return true;
+ case 0x1a: HandlePacketSteerVehicle(a_ByteBuffer); return true;
+ case 0x1b: HandlePacketCraftingBookData(a_ByteBuffer); return true;
+ case 0x1d: break; // Resource pack status - not yet implemented
+ case 0x1e: HandlePacketAdvancementTab(a_ByteBuffer); return true;
+ case 0x20: HandlePacketSetBeaconEffect(a_ByteBuffer); return true;
+ case 0x21: HandlePacketSlotSelect(a_ByteBuffer); return true;
+ case 0x24: HandlePacketCreativeInventoryAction(a_ByteBuffer); return true;
+ case 0x26: HandlePacketUpdateSign(a_ByteBuffer); return true;
+ case 0x27: HandlePacketAnimation(a_ByteBuffer); return true;
+ case 0x28: HandlePacketSpectate(a_ByteBuffer); return true;
+ case 0x29: HandlePacketBlockPlace(a_ByteBuffer); return true;
+ case 0x2a: HandlePacketUseItem(a_ByteBuffer); return true;
+ }
+
+ return Super::HandlePacket(a_ByteBuffer, a_PacketType);
}
-UInt32 cProtocol_1_13::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
+void cProtocol_1_13::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
- return Palette_1_13::From(PaletteUpgrade::FromBlock(a_BlockType, a_Meta));
-}
-
+ HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
+ // If the plugin channel is recognized vanilla, handle it directly:
+ if (Channel.substr(0, 15) == "minecraft:brand")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand);
+ m_Client->SetClientBrand(Brand);
+ // Send back our brand, including the length:
+ m_Client->SendPluginMessage("minecraft:brand", "\x08""Cuberite");
+ return;
+ }
+ ContiguousByteBuffer Data;
-UInt32 cProtocol_1_13::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
-{
- return Palette_1_13::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
+ // Read the plugin message and relay to clienthandle:
+ VERIFY(a_ByteBuffer.ReadSome(Data, a_ByteBuffer.GetReadableSpace())); // Always succeeds
+ m_Client->HandlePluginMessage(Channel, Data);
}
-UInt32 cProtocol_1_13::GetProtocolStatisticType(Statistic a_Statistic)
+void cProtocol_1_13::HandlePacketSetBeaconEffect(cByteBuffer & a_ByteBuffer)
{
- return Palette_1_13::From(a_Statistic);
+ HANDLE_READ(a_ByteBuffer, ReadVarInt32, UInt32, Effect1);
+ HANDLE_READ(a_ByteBuffer, ReadVarInt32, UInt32, Effect2);
+ m_Client->HandleBeaconSelection(Effect1, Effect2);
}
-bool cProtocol_1_13::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes)
+bool cProtocol_1_13::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) const
{
HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemID);
if (ItemID == -1)
@@ -724,35 +724,7 @@ bool cProtocol_1_13::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t
-void cProtocol_1_13::WriteItem(cPacketizer & a_Pkt, 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())
- {
- a_Pkt.WriteBEInt16(-1);
- return;
- }
-
- // Normal item
- a_Pkt.WriteBEInt16(static_cast<Int16>(GetProtocolItemType(a_Item.m_ItemType, a_Item.m_ItemDamage)));
- a_Pkt.WriteBEInt8(a_Item.m_ItemCount);
-
- // TODO: NBT
- a_Pkt.WriteBEInt8(0);
-}
-
-
-
-
-
-void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const EntityMetadata a_Metadata, const EntityMetadataType a_FieldType)
+void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const EntityMetadata a_Metadata, const EntityMetadataType a_FieldType) const
{
a_Pkt.WriteBEUInt8(GetEntityMetadataID(a_Metadata)); // Index
a_Pkt.WriteBEUInt8(GetEntityMetadataID(a_FieldType)); // Type
@@ -762,7 +734,7 @@ void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const EntityMetada
-void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
+void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
{
// Common metadata:
Int8 Flags = 0;
@@ -809,7 +781,7 @@ void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
WriteEntityMetadata(a_Pkt, EntityMetadata::PlayerMainHand, EntityMetadataType::Byte);
- a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
+ a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
break;
}
case cEntity::etPickup:
@@ -953,7 +925,35 @@ void cProtocol_1_13::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_
-void cProtocol_1_13::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
+void cProtocol_1_13::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const
+{
+ 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())
+ {
+ a_Pkt.WriteBEInt16(-1);
+ return;
+ }
+
+ // Normal item
+ a_Pkt.WriteBEInt16(static_cast<Int16>(GetProtocolItemType(a_Item.m_ItemType, a_Item.m_ItemDamage)));
+ a_Pkt.WriteBEInt8(a_Item.m_ItemCount);
+
+ // TODO: NBT
+ a_Pkt.WriteBEInt8(0);
+}
+
+
+
+
+
+void cProtocol_1_13::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
{
// Living Enitiy Metadata
if (a_Mob.HasCustomName())
@@ -1444,45 +1444,45 @@ void cProtocol_1_13_1::SendBossBarUpdateFlags(UInt32 a_UniqueID, bool a_DarkenSk
-cProtocol::Version cProtocol_1_13_1::GetProtocolVersion()
+std::pair<short, short> cProtocol_1_13_1::GetItemFromProtocolID(UInt32 a_ProtocolID) const
{
- return Version::v1_13_1;
+ return PaletteUpgrade::ToItem(Palette_1_13_1::ToItem(a_ProtocolID));
}
-std::pair<short, short> cProtocol_1_13_1::GetItemFromProtocolID(UInt32 a_ProtocolID)
+UInt32 cProtocol_1_13_1::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const
{
- return PaletteUpgrade::ToItem(Palette_1_13_1::ToItem(a_ProtocolID));
+ return Palette_1_13_1::From(PaletteUpgrade::FromBlock(a_BlockType, a_Meta));
}
-UInt32 cProtocol_1_13_1::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
+UInt32 cProtocol_1_13_1::GetProtocolItemType(short a_ItemID, short a_ItemDamage) const
{
- return Palette_1_13_1::From(PaletteUpgrade::FromBlock(a_BlockType, a_Meta));
+ return Palette_1_13_1::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
}
-UInt32 cProtocol_1_13_1::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
+UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic) const
{
- return Palette_1_13_1::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
+ return Palette_1_13_1::From(a_Statistic);
}
-UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic)
+cProtocol::Version cProtocol_1_13_1::GetProtocolVersion() const
{
- return Palette_1_13_1::From(a_Statistic);
+ return Version::v1_13_1;
}
@@ -1492,7 +1492,7 @@ UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic)
////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_13_2:
-cProtocol::Version cProtocol_1_13_2::GetProtocolVersion()
+cProtocol::Version cProtocol_1_13_2::GetProtocolVersion() const
{
return Version::v1_13_2;
}
@@ -1501,7 +1501,7 @@ cProtocol::Version cProtocol_1_13_2::GetProtocolVersion()
-bool cProtocol_1_13_2::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes)
+bool cProtocol_1_13_2::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) const
{
HANDLE_PACKET_READ(a_ByteBuffer, ReadBool, bool, Present);
if (!Present)
@@ -1538,7 +1538,7 @@ bool cProtocol_1_13_2::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size
-void cProtocol_1_13_2::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item)
+void cProtocol_1_13_2::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const
{
short ItemType = a_Item.m_ItemType;
ASSERT(ItemType >= -1); // Check validity of packets in debug runtime
diff --git a/src/Protocol/Protocol_1_13.h b/src/Protocol/Protocol_1_13.h
index 53de8bbc1..970625877 100644
--- a/src/Protocol/Protocol_1_13.h
+++ b/src/Protocol/Protocol_1_13.h
@@ -46,33 +46,26 @@ protected:
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override;
- /** Translates outgoing packet types. */
- virtual UInt32 GetPacketID(ePacketType a_PacketType) override;
-
+ virtual UInt8 GetEntityMetadataID(EntityMetadata a_Metadata) const;
+ virtual UInt8 GetEntityMetadataID(EntityMetadataType a_FieldType) const;
+ virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID) const;
+ virtual UInt32 GetPacketID(ePacketType a_PacketType) const override;
+ virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const;
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override;
-
- /** Returns 1.13. */
- virtual Version GetProtocolVersion() override;
-
- /** Converts eMonsterType to protocol-specific mob types */
- virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override;
-
- virtual UInt8 GetEntityMetadataID(EntityMetadata a_Metadata);
- virtual UInt8 GetEntityMetadataID(EntityMetadataType a_FieldType);
- virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID);
- virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta);
- virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage);
- virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic);
+ virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const;
+ virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override;
+ virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const;
+ virtual Version GetProtocolVersion() const override;
virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
virtual void HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketSetBeaconEffect(cByteBuffer & a_ByteBuffer);
- virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) override;
- virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) override;
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, EntityMetadata a_Metadata, EntityMetadataType a_FieldType);
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
- virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override;
+ virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) const override;
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, EntityMetadata a_Metadata, EntityMetadataType a_FieldType) const;
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const override;
+ virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const override;
+ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const override;
};
@@ -93,11 +86,11 @@ protected:
virtual void SendBossBarAdd(UInt32 a_UniqueID, const cCompositeChat & a_Title, float a_FractionFilled, BossBarColor a_Color, BossBarDivisionType a_DivisionType, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog) override;
virtual void SendBossBarUpdateFlags(UInt32 a_UniqueID, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog) override;
- virtual Version GetProtocolVersion() override;
- virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID) override;
- virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) override;
- virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) override;
- virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) override;
+ virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID) const override;
+ virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override;
+ virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const override;
+ virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const override;
+ virtual Version GetProtocolVersion() const override;
};
@@ -115,7 +108,7 @@ public:
protected:
- virtual Version GetProtocolVersion() override;
- virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) override;
- virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) override;
+ virtual Version GetProtocolVersion() const override;
+ virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) const override;
+ virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const override;
};
diff --git a/src/Protocol/Protocol_1_14.cpp b/src/Protocol/Protocol_1_14.cpp
index 77918c7eb..f2bbdd955 100644
--- a/src/Protocol/Protocol_1_14.cpp
+++ b/src/Protocol/Protocol_1_14.cpp
@@ -131,7 +131,7 @@ void cProtocol_1_14::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, co
-UInt32 cProtocol_1_14::GetPacketID(ePacketType a_PacketType)
+UInt32 cProtocol_1_14::GetPacketID(ePacketType a_PacketType) const
{
switch (a_PacketType)
{
@@ -184,16 +184,7 @@ UInt32 cProtocol_1_14::GetPacketID(ePacketType a_PacketType)
-cProtocol::Version cProtocol_1_14::GetProtocolVersion()
-{
- return Version::v1_14;
-}
-
-
-
-
-
-std::pair<short, short> cProtocol_1_14::GetItemFromProtocolID(UInt32 a_ProtocolID)
+std::pair<short, short> cProtocol_1_14::GetItemFromProtocolID(UInt32 a_ProtocolID) const
{
return PaletteUpgrade::ToItem(Palette_1_14::ToItem(a_ProtocolID));
}
@@ -202,7 +193,7 @@ std::pair<short, short> cProtocol_1_14::GetItemFromProtocolID(UInt32 a_ProtocolI
-UInt32 cProtocol_1_14::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
+UInt32 cProtocol_1_14::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const
{
return Palette_1_14::From(PaletteUpgrade::FromBlock(a_BlockType, a_Meta));
}
@@ -238,7 +229,7 @@ signed char cProtocol_1_14::GetProtocolEntityStatus(EntityAnimation a_Animation)
-UInt32 cProtocol_1_14::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
+UInt32 cProtocol_1_14::GetProtocolItemType(short a_ItemID, short a_ItemDamage) const
{
return Palette_1_14::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
}
@@ -247,7 +238,7 @@ UInt32 cProtocol_1_14::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
-UInt32 cProtocol_1_14::GetProtocolStatisticType(Statistic a_Statistic)
+UInt32 cProtocol_1_14::GetProtocolStatisticType(Statistic a_Statistic) const
{
return Palette_1_14::From(a_Statistic);
}
@@ -256,6 +247,15 @@ UInt32 cProtocol_1_14::GetProtocolStatisticType(Statistic a_Statistic)
+cProtocol::Version cProtocol_1_14::GetProtocolVersion() const
+{
+ return Version::v1_14;
+}
+
+
+
+
+
bool cProtocol_1_14::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
if (m_State != State::Game)
diff --git a/src/Protocol/Protocol_1_14.h b/src/Protocol/Protocol_1_14.h
index d1e5b5a4f..32ae6640e 100644
--- a/src/Protocol/Protocol_1_14.h
+++ b/src/Protocol/Protocol_1_14.h
@@ -40,19 +40,19 @@ protected:
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 UInt32 GetPacketID(ePacketType a_PacketType) override;
- virtual Version GetProtocolVersion() override;
- virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID) override;
- virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) override;
+ virtual UInt32 GetPacketID(ePacketType a_PacketType) const override;
+ virtual std::pair<short, short> GetItemFromProtocolID(UInt32 a_ProtocolID) const override;
+ virtual UInt32 GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const override;
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override;
- virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) override;
- virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) override;
+ virtual UInt32 GetProtocolItemType(short a_ItemID, short a_ItemDamage) const override;
+ virtual UInt32 GetProtocolStatisticType(Statistic a_Statistic) const override;
+ virtual Version GetProtocolVersion() const override;
virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
virtual void HandlePacketBlockDig(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer) override;
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override {}
- virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override {}
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const override {}
+ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const override {}
};
diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp
index f815bbd29..4d15d8978 100644
--- a/src/Protocol/Protocol_1_8.cpp
+++ b/src/Protocol/Protocol_1_8.cpp
@@ -1004,10 +1004,6 @@ void cProtocol_1_8_0::SendParticleEffect(const AString & a_ParticleName, Vector3
Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0]));
break;
}
- default:
- {
- break;
- }
}
}
@@ -1832,7 +1828,27 @@ void cProtocol_1_8_0::CompressPacket(CircularBufferCompressor & a_Packet, Contig
-UInt32 cProtocol_1_8_0::GetPacketID(ePacketType a_PacketType)
+eBlockFace cProtocol_1_8_0::FaceIntToBlockFace(const Int32 a_BlockFace)
+{
+ // Normalize the blockface values returned from the protocol
+ // Anything known gets mapped 1:1, everything else returns BLOCK_FACE_NONE
+ switch (a_BlockFace)
+ {
+ case BLOCK_FACE_XM: return BLOCK_FACE_XM;
+ case BLOCK_FACE_XP: return BLOCK_FACE_XP;
+ case BLOCK_FACE_YM: return BLOCK_FACE_YM;
+ case BLOCK_FACE_YP: return BLOCK_FACE_YP;
+ case BLOCK_FACE_ZM: return BLOCK_FACE_ZM;
+ case BLOCK_FACE_ZP: return BLOCK_FACE_ZP;
+ default: return BLOCK_FACE_NONE;
+ }
+}
+
+
+
+
+
+UInt32 cProtocol_1_8_0::GetPacketID(ePacketType a_PacketType) const
{
switch (a_PacketType)
{
@@ -1923,15 +1939,6 @@ UInt32 cProtocol_1_8_0::GetPacketID(ePacketType a_PacketType)
-cProtocol::Version cProtocol_1_8_0::GetProtocolVersion()
-{
- return Version::v1_8_0;
-}
-
-
-
-
-
unsigned char cProtocol_1_8_0::GetProtocolEntityAnimation(const EntityAnimation a_Animation) const
{
switch (a_Animation)
@@ -1990,7 +1997,7 @@ signed char cProtocol_1_8_0::GetProtocolEntityStatus(const EntityAnimation a_Ani
-UInt32 cProtocol_1_8_0::GetProtocolMobType(const eMonsterType a_MobType)
+UInt32 cProtocol_1_8_0::GetProtocolMobType(const eMonsterType a_MobType) const
{
switch (a_MobType)
{
@@ -2048,6 +2055,15 @@ UInt32 cProtocol_1_8_0::GetProtocolMobType(const eMonsterType a_MobType)
+cProtocol::Version cProtocol_1_8_0::GetProtocolVersion() const
+{
+ return Version::v1_8_0;
+}
+
+
+
+
+
bool cProtocol_1_8_0::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
switch (m_State)
@@ -2275,7 +2291,7 @@ void cProtocol_1_8_0::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketAnimation(cByteBuffer & a_ByteBuffer)
{
- m_Client->HandleAnimation(0); // Packet exists solely for arm-swing notification
+ m_Client->HandleAnimation(true); // Packet exists solely for arm-swing notification (main hand).
}
@@ -2293,6 +2309,7 @@ void cProtocol_1_8_0::HandlePacketBlockDig(cByteBuffer & a_ByteBuffer)
}
HANDLE_READ(a_ByteBuffer, ReadBEInt8, Int8, Face);
+
m_Client->HandleLeftClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), Status);
}
@@ -2316,14 +2333,15 @@ void cProtocol_1_8_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorX);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorY);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorZ);
+
eBlockFace blockFace = FaceIntToBlockFace(Face);
if (blockFace == eBlockFace::BLOCK_FACE_NONE)
{
- m_Client->HandleUseItem(eHand::hMain);
+ m_Client->HandleUseItem(true);
}
else
{
- m_Client->HandleRightClick(BlockX, BlockY, BlockZ, blockFace, CursorX, CursorY, CursorZ, eHand::hMain);
+ m_Client->HandleRightClick(BlockX, BlockY, BlockZ, blockFace, CursorX, CursorY, CursorZ, true);
}
}
@@ -2334,6 +2352,7 @@ void cProtocol_1_8_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketChatMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Message);
+
m_Client->HandleChat(Message);
}
@@ -2362,6 +2381,7 @@ void cProtocol_1_8_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ActionID);
+
switch (ActionID)
{
case 0:
@@ -2394,6 +2414,7 @@ void cProtocol_1_8_0::HandlePacketClientStatus(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum);
+
cItem Item;
if (!ReadItem(a_ByteBuffer, Item))
{
@@ -2436,6 +2457,7 @@ void cProtocol_1_8_0::HandlePacketEntityAction(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketKeepAlive(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, KeepAliveID);
+
m_Client->HandleKeepAlive(KeepAliveID);
}
@@ -2478,6 +2500,7 @@ void cProtocol_1_8_0::HandlePacketPlayerLook(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
+
m_Client->HandlePlayerLook(Yaw, Pitch, IsOnGround);
}
@@ -2491,7 +2514,8 @@ void cProtocol_1_8_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
- m_Client->HandlePlayerPos(PosX, PosY, PosZ, IsOnGround);
+
+ m_Client->HandlePlayerMove(PosX, PosY, PosZ, IsOnGround);
}
@@ -2506,6 +2530,7 @@ void cProtocol_1_8_0::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Yaw);
HANDLE_READ(a_ByteBuffer, ReadBEFloat, float, Pitch);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
+
m_Client->HandlePlayerMoveLook(PosX, PosY, PosZ, Yaw, Pitch, IsOnGround);
}
@@ -2557,6 +2582,7 @@ void cProtocol_1_8_0::HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketSlotSelect(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEInt16, Int16, SlotNum);
+
m_Client->HandleSlotSelected(SlotNum);
}
@@ -2633,6 +2659,7 @@ void cProtocol_1_8_0::HandlePacketUpdateSign(cByteBuffer & a_ByteBuffer)
for (int i = 0; i < 4; i++)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Line);
+
if (JsonUtils::ParseString(Line, root) && root.isString())
{
Lines[i] = root.asString();
@@ -2703,6 +2730,7 @@ void cProtocol_1_8_0::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Button);
HANDLE_READ(a_ByteBuffer, ReadBEUInt16, UInt16, TransactionID);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Mode);
+
cItem Item;
ReadItem(a_ByteBuffer, Item);
@@ -2757,6 +2785,7 @@ void cProtocol_1_8_0::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
void cProtocol_1_8_0::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, WindowID);
+
m_Client->HandleWindowClose(WindowID);
}
@@ -2769,6 +2798,7 @@ void cProtocol_1_8_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, con
if (a_Channel == "MC|AdvCdm")
{
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Mode);
+
switch (Mode)
{
case 0x00:
@@ -2777,6 +2807,7 @@ void cProtocol_1_8_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, con
HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockY);
HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, BlockZ);
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Command);
+
m_Client->HandleCommandBlockBlockChange(BlockX, BlockY, BlockZ, Command);
break;
}
@@ -2793,6 +2824,7 @@ void cProtocol_1_8_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, con
else if (a_Channel == "MC|Brand")
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand);
+
m_Client->SetClientBrand(Brand);
// Send back our brand, including the length:
m_Client->SendPluginMessage("MC|Brand", "\x08""Cuberite");
@@ -2802,18 +2834,21 @@ void cProtocol_1_8_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, con
{
HANDLE_READ(a_ByteBuffer, ReadBEUInt32, UInt32, Effect1);
HANDLE_READ(a_ByteBuffer, ReadBEUInt32, UInt32, Effect2);
+
m_Client->HandleBeaconSelection(Effect1, Effect2);
return;
}
else if (a_Channel == "MC|ItemName")
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, ItemName);
+
m_Client->HandleAnvilItemName(ItemName);
return;
}
else if (a_Channel == "MC|TrSel")
{
HANDLE_READ(a_ByteBuffer, ReadBEInt32, Int32, SlotNum);
+
m_Client->HandleNPCTrade(SlotNum);
return;
}
@@ -2829,67 +2864,7 @@ void cProtocol_1_8_0::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, con
-void cProtocol_1_8_0::SendData(ContiguousByteBufferView a_Data)
-{
- if (m_IsEncrypted)
- {
- std::byte Encrypted[8 KiB]; // Larger buffer, we may be sending lots of data (chunks)
-
- while (a_Data.size() > 0)
- {
- const auto NumBytes = (a_Data.size() > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Data.size();
- m_Encryptor.ProcessData(Encrypted, a_Data.data(), NumBytes);
- m_Client->SendData({ Encrypted, NumBytes });
-
- a_Data = a_Data.substr(NumBytes);
- }
- }
- else
- {
- m_Client->SendData(a_Data);
- }
-}
-
-
-
-
-
-bool cProtocol_1_8_0::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes)
-{
- HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemType);
- if (ItemType == -1)
- {
- // The item is empty, no more data follows
- a_Item.Empty();
- return true;
- }
- a_Item.m_ItemType = ItemType;
-
- HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt8, Int8, ItemCount);
- HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemDamage);
- a_Item.m_ItemCount = ItemCount;
- a_Item.m_ItemDamage = ItemDamage;
- if (ItemCount <= 0)
- {
- a_Item.Empty();
- }
-
- ContiguousByteBuffer Metadata;
- if (!a_ByteBuffer.ReadSome(Metadata, a_ByteBuffer.GetReadableSpace() - a_KeepRemainingBytes) || Metadata.empty() || (Metadata[0] == std::byte(0)))
- {
- // No metadata
- return true;
- }
-
- ParseItemMetadata(a_Item, Metadata);
- return true;
-}
-
-
-
-
-
-void cProtocol_1_8_0::ParseItemMetadata(cItem & a_Item, const ContiguousByteBufferView a_Metadata)
+void cProtocol_1_8_0::ParseItemMetadata(cItem & a_Item, const ContiguousByteBufferView a_Metadata) const
{
// Parse into NBT:
cParsedNBT NBT(a_Metadata);
@@ -2962,50 +2937,98 @@ void cProtocol_1_8_0::ParseItemMetadata(cItem & a_Item, const ContiguousByteBuff
-void cProtocol_1_8_0::StartEncryption(const Byte * a_Key)
+bool cProtocol_1_8_0::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes) const
{
- m_Encryptor.Init(a_Key, a_Key);
- m_Decryptor.Init(a_Key, a_Key);
- m_IsEncrypted = true;
+ HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemType);
- // Prepare the m_AuthServerID:
- cSha1Checksum Checksum;
- cServer * Server = cRoot::Get()->GetServer();
- const AString & ServerID = Server->GetServerID();
- Checksum.Update(reinterpret_cast<const Byte *>(ServerID.c_str()), ServerID.length());
- Checksum.Update(a_Key, 16);
- Checksum.Update(reinterpret_cast<const Byte *>(Server->GetPublicKeyDER().data()), Server->GetPublicKeyDER().size());
- Byte Digest[20];
- Checksum.Finalize(Digest);
- cSha1Checksum::DigestToJava(Digest, m_AuthServerID);
+ if (ItemType == -1)
+ {
+ // The item is empty, no more data follows
+ a_Item.Empty();
+ return true;
+ }
+ a_Item.m_ItemType = ItemType;
+
+ HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt8, Int8, ItemCount);
+ HANDLE_PACKET_READ(a_ByteBuffer, ReadBEInt16, Int16, ItemDamage);
+
+ a_Item.m_ItemCount = ItemCount;
+ a_Item.m_ItemDamage = ItemDamage;
+ if (ItemCount <= 0)
+ {
+ a_Item.Empty();
+ }
+
+ ContiguousByteBuffer Metadata;
+ if (!a_ByteBuffer.ReadSome(Metadata, a_ByteBuffer.GetReadableSpace() - a_KeepRemainingBytes) || Metadata.empty() || (Metadata[0] == std::byte(0)))
+ {
+ // No metadata
+ return true;
+ }
+
+ ParseItemMetadata(a_Item, Metadata);
+ return true;
}
-eBlockFace cProtocol_1_8_0::FaceIntToBlockFace(const Int32 a_BlockFace)
+void cProtocol_1_8_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
{
- // Normalize the blockface values returned from the protocol
- // Anything known gets mapped 1:1, everything else returns BLOCK_FACE_NONE
- switch (a_BlockFace)
+ ASSERT(m_State == 3); // In game mode?
+
{
- case BLOCK_FACE_XM: return BLOCK_FACE_XM;
- case BLOCK_FACE_XP: return BLOCK_FACE_XP;
- case BLOCK_FACE_YM: return BLOCK_FACE_YM;
- case BLOCK_FACE_YP: return BLOCK_FACE_YP;
- case BLOCK_FACE_ZM: return BLOCK_FACE_ZM;
- case BLOCK_FACE_ZP: return BLOCK_FACE_ZP;
- default: return BLOCK_FACE_NONE;
+ cPacketizer Pkt(*this, pktSpawnObject);
+ Pkt.WriteVarInt32(a_Entity.GetUniqueID());
+ Pkt.WriteBEUInt8(a_ObjectType);
+ Pkt.WriteFPInt(a_Entity.GetPosX()); // Position appears to be ignored...
+ Pkt.WriteFPInt(a_Entity.GetPosY());
+ Pkt.WriteFPInt(a_Entity.GetPosY());
+ Pkt.WriteByteAngle(a_Entity.GetPitch());
+ Pkt.WriteByteAngle(a_Entity.GetYaw());
+ Pkt.WriteBEInt32(a_ObjectData);
+
+ if (a_ObjectData != 0)
+ {
+ Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
+ Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
+ Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
+ }
}
+
+ // Otherwise 1.8 clients don't show the entity
+ SendEntityTeleport(a_Entity);
}
-////////////////////////////////////////////////////////////////////////////////
-// cProtocol_1_8_0::cPacketizer:
+void cProtocol_1_8_0::SendData(ContiguousByteBufferView a_Data)
+{
+ if (m_IsEncrypted)
+ {
+ std::byte Encrypted[8 KiB]; // Larger buffer, we may be sending lots of data (chunks)
+
+ while (a_Data.size() > 0)
+ {
+ const auto NumBytes = (a_Data.size() > sizeof(Encrypted)) ? sizeof(Encrypted) : a_Data.size();
+ m_Encryptor.ProcessData(Encrypted, a_Data.data(), NumBytes);
+ m_Client->SendData({ Encrypted, NumBytes });
+
+ a_Data = a_Data.substr(NumBytes);
+ }
+ }
+ else
+ {
+ m_Client->SendData(a_Data);
+ }
+}
+
+
+
+
void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
{
@@ -3067,38 +3090,7 @@ void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
-void cProtocol_1_8_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
-{
- ASSERT(m_State == 3); // In game mode?
-
- {
- cPacketizer Pkt(*this, pktSpawnObject);
- Pkt.WriteVarInt32(a_Entity.GetUniqueID());
- Pkt.WriteBEUInt8(a_ObjectType);
- Pkt.WriteFPInt(a_Entity.GetPosX()); // Position appears to be ignored...
- Pkt.WriteFPInt(a_Entity.GetPosY());
- Pkt.WriteFPInt(a_Entity.GetPosY());
- Pkt.WriteByteAngle(a_Entity.GetPitch());
- Pkt.WriteByteAngle(a_Entity.GetYaw());
- Pkt.WriteBEInt32(a_ObjectData);
-
- if (a_ObjectData != 0)
- {
- Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedX() * 400));
- Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedY() * 400));
- Pkt.WriteBEInt16(static_cast<Int16>(a_Entity.GetSpeedZ() * 400));
- }
- }
-
- // Otherwise 1.8 clients don't show the entity
- SendEntityTeleport(a_Entity);
-}
-
-
-
-
-
-void cProtocol_1_8_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity)
+void cProtocol_1_8_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const
{
a_Writer.AddInt("x", a_BlockEntity.GetPosX());
a_Writer.AddInt("y", a_BlockEntity.GetPosY());
@@ -3205,89 +3197,7 @@ void cProtocol_1_8_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEn
-void cProtocol_1_8_0::WriteItem(cPacketizer & a_Pkt, 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())
- {
- a_Pkt.WriteBEInt16(-1);
- return;
- }
-
- a_Pkt.WriteBEInt16(ItemType);
- a_Pkt.WriteBEInt8(a_Item.m_ItemCount);
- a_Pkt.WriteBEInt16(a_Item.m_ItemDamage);
-
- if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid())
- {
- a_Pkt.WriteBEInt8(0);
- return;
- }
-
-
- // Send the enchantments and custom names:
- cFastNBTWriter Writer;
- if (a_Item.m_RepairCost != 0)
- {
- Writer.AddInt("RepairCost", a_Item.m_RepairCost);
- }
- if (!a_Item.m_Enchantments.IsEmpty())
- {
- const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
- EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName);
- }
- if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid())
- {
- Writer.BeginCompound("display");
- if (a_Item.m_ItemColor.IsValid())
- {
- Writer.AddInt("color", static_cast<Int32>(a_Item.m_ItemColor.m_Color));
- }
-
- if (!a_Item.IsCustomNameEmpty())
- {
- Writer.AddString("Name", a_Item.m_CustomName);
- }
- if (!a_Item.IsLoreEmpty())
- {
- Writer.BeginList("Lore", TAG_String);
-
- for (const auto & Line : a_Item.m_LoreTable)
- {
- Writer.AddString("", Line);
- }
-
- Writer.EndList();
- }
- Writer.EndCompound();
- }
- if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))
- {
- cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, static_cast<ENUM_ITEM_TYPE>(a_Item.m_ItemType));
- }
- Writer.Finish();
-
- const auto Result = Writer.GetResult();
- if (Result.empty())
- {
- a_Pkt.WriteBEInt8(0);
- return;
- }
- a_Pkt.WriteBuf(Result);
-}
-
-
-
-
-
-void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
+void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
{
// Common metadata:
Byte Flags = 0;
@@ -3438,7 +3348,129 @@ void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
-void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
+void cProtocol_1_8_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) const
+{
+ if (a_Entity.IsPlayer())
+ {
+ const auto & Player = static_cast<const cPlayer &>(a_Entity);
+
+ a_Pkt.WriteBEInt32(1); // Count.
+ a_Pkt.WriteString("generic.movementSpeed");
+ a_Pkt.WriteBEDouble(0.1 * Player.GetNormalMaxSpeed()); // The default game speed is 0.1, multiply that value by the relative speed.
+
+ // It seems the modifiers aren't conditionally activated; their effects are applied immediately!
+ // We have to keep on re-sending this packet when the client notifies us of sprint start and end, and so on. Strange.
+
+ if (Player.IsSprinting())
+ {
+ a_Pkt.WriteVarInt32(1); // Modifier count.
+ a_Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c);
+ a_Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier (sprinting speed boost).
+ a_Pkt.WriteBEDouble(Player.GetSprintingMaxSpeed() - Player.GetNormalMaxSpeed());
+ a_Pkt.WriteBEUInt8(2);
+ }
+ else
+ {
+ a_Pkt.WriteVarInt32(0);
+ }
+ }
+ else
+ {
+ // const cMonster & Mob = (const cMonster &)a_Entity;
+
+ // TODO: Send properties and modifiers based on the mob type
+
+ a_Pkt.WriteBEInt32(0);
+ }
+}
+
+
+
+
+
+void cProtocol_1_8_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const
+{
+ 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())
+ {
+ a_Pkt.WriteBEInt16(-1);
+ return;
+ }
+
+ a_Pkt.WriteBEInt16(ItemType);
+ a_Pkt.WriteBEInt8(a_Item.m_ItemCount);
+ a_Pkt.WriteBEInt16(a_Item.m_ItemDamage);
+
+ if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (a_Item.m_ItemType != E_ITEM_FIREWORK_ROCKET) && (a_Item.m_ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid())
+ {
+ a_Pkt.WriteBEInt8(0);
+ return;
+ }
+
+
+ // Send the enchantments and custom names:
+ cFastNBTWriter Writer;
+ if (a_Item.m_RepairCost != 0)
+ {
+ Writer.AddInt("RepairCost", a_Item.m_RepairCost);
+ }
+ if (!a_Item.m_Enchantments.IsEmpty())
+ {
+ const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
+ EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName);
+ }
+ if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid())
+ {
+ Writer.BeginCompound("display");
+ if (a_Item.m_ItemColor.IsValid())
+ {
+ Writer.AddInt("color", static_cast<Int32>(a_Item.m_ItemColor.m_Color));
+ }
+
+ if (!a_Item.IsCustomNameEmpty())
+ {
+ Writer.AddString("Name", a_Item.m_CustomName);
+ }
+ if (!a_Item.IsLoreEmpty())
+ {
+ Writer.BeginList("Lore", TAG_String);
+
+ for (const auto & Line : a_Item.m_LoreTable)
+ {
+ Writer.AddString("", Line);
+ }
+
+ Writer.EndList();
+ }
+ Writer.EndCompound();
+ }
+ if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))
+ {
+ cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, static_cast<ENUM_ITEM_TYPE>(a_Item.m_ItemType));
+ }
+ Writer.Finish();
+
+ const auto Result = Writer.GetResult();
+ if (Result.empty())
+ {
+ a_Pkt.WriteBEInt8(0);
+ return;
+ }
+ a_Pkt.WriteBuf(Result);
+}
+
+
+
+
+
+void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
{
// Living Enitiy Metadata
if (a_Mob.HasCustomName())
@@ -3764,46 +3796,6 @@ void cProtocol_1_8_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_M
-void cProtocol_1_8_0::WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity)
-{
- if (a_Entity.IsPlayer())
- {
- const auto & Player = static_cast<const cPlayer &>(a_Entity);
-
- a_Pkt.WriteBEInt32(1); // Count.
- a_Pkt.WriteString("generic.movementSpeed");
- a_Pkt.WriteBEDouble(0.1 * Player.GetNormalMaxSpeed()); // The default game speed is 0.1, multiply that value by the relative speed.
-
- // It seems the modifiers aren't conditionally activated; their effects are applied immediately!
- // We have to keep on re-sending this packet when the client notifies us of sprint start and end, and so on. Strange.
-
- if (Player.IsSprinting())
- {
- a_Pkt.WriteVarInt32(1); // Modifier count.
- a_Pkt.WriteBEUInt64(0x662a6b8dda3e4c1c);
- a_Pkt.WriteBEUInt64(0x881396ea6097278d); // UUID of the modifier (sprinting speed boost).
- a_Pkt.WriteBEDouble(Player.GetSprintingMaxSpeed() - Player.GetNormalMaxSpeed());
- a_Pkt.WriteBEUInt8(2);
- }
- else
- {
- a_Pkt.WriteVarInt32(0);
- }
- }
- else
- {
- // const cMonster & Mob = (const cMonster &)a_Entity;
-
- // TODO: Send properties and modifiers based on the mob type
-
- a_Pkt.WriteBEInt32(0);
- }
-}
-
-
-
-
-
void cProtocol_1_8_0::AddReceivedData(cByteBuffer & a_Buffer, const ContiguousByteBufferView a_Data)
{
// Write the incoming data into the comm log file:
@@ -3921,98 +3913,6 @@ void cProtocol_1_8_0::AddReceivedData(cByteBuffer & a_Buffer, const ContiguousBy
-void cProtocol_1_8_0::HandlePacket(cByteBuffer & a_Buffer)
-{
- UInt32 PacketType;
- if (!a_Buffer.ReadVarInt(PacketType))
- {
- // Not enough data
- return;
- }
-
- // Log the packet info into the comm log file:
- if (g_ShouldLogCommIn && m_CommLogFile.IsOpen())
- {
- ContiguousByteBuffer PacketData;
- a_Buffer.ReadAll(PacketData);
- a_Buffer.ResetRead();
- a_Buffer.ReadVarInt(PacketType); // We have already read the packet type once, it will be there again
- ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read
- PacketData.resize(PacketData.size() - 1);
- AString PacketDataHex;
- CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16);
- m_CommLogFile.Printf("Next incoming packet is type %u (0x%x), length %u (0x%x) at state %d. Payload:\n%s\n",
- PacketType, PacketType, a_Buffer.GetUsedSpace(), a_Buffer.GetUsedSpace(), m_State, PacketDataHex.c_str()
- );
- }
-
- if (!HandlePacket(a_Buffer, PacketType))
- {
- // Unknown packet, already been reported, but without the length. Log the length here:
- LOGWARNING("Unhandled packet: type 0x%x, state %d, length %u", PacketType, m_State, a_Buffer.GetUsedSpace());
-
-#ifndef NDEBUG
- // Dump the packet contents into the log:
- a_Buffer.ResetRead();
- ContiguousByteBuffer Packet;
- a_Buffer.ReadAll(Packet);
- Packet.resize(Packet.size() - 1); // Drop the final NUL pushed there for over-read detection
- AString Out;
- CreateHexDump(Out, Packet.data(), Packet.size(), 24);
- LOGD("Packet contents:\n%s", Out.c_str());
-#endif // !NDEBUG
-
- // Put a message in the comm log:
- if (g_ShouldLogCommIn && m_CommLogFile.IsOpen())
- {
- m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n");
- }
-
- return;
- }
-
- // The packet should have nothing left in the buffer:
- if (a_Buffer.GetReadableSpace() != 0)
- {
- // Read more or less than packet length, report as error
- LOGWARNING("Protocol 1.8: Wrong number of bytes read for packet 0x%x, state %d. Read %zu bytes, packet contained %u bytes",
- PacketType, m_State, a_Buffer.GetUsedSpace() - a_Buffer.GetReadableSpace(), a_Buffer.GetUsedSpace()
- );
-
- // Put a message in the comm log:
- if (g_ShouldLogCommIn && m_CommLogFile.IsOpen())
- {
- m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got %zu left) ^^^^^^\n\n\n",
- 1, a_Buffer.GetReadableSpace()
- );
- m_CommLogFile.Flush();
- }
-
- ASSERT(!"Read wrong number of bytes!");
- m_Client->PacketError(PacketType);
- }
-}
-
-
-
-
-
-void cProtocol_1_8_0::SendEntityTeleport(const cEntity & a_Entity)
-{
- cPacketizer Pkt(*this, pktTeleportEntity);
- Pkt.WriteVarInt32(a_Entity.GetUniqueID());
- Pkt.WriteFPInt(a_Entity.GetPosX());
- Pkt.WriteFPInt(a_Entity.GetPosY());
- Pkt.WriteFPInt(a_Entity.GetPosZ());
- Pkt.WriteByteAngle(a_Entity.GetYaw());
- Pkt.WriteByteAngle(a_Entity.GetPitch());
- Pkt.WriteBool(a_Entity.IsOnGround());
-}
-
-
-
-
-
UInt8 cProtocol_1_8_0::GetProtocolEntityType(const cEntity & a_Entity)
{
using Type = cEntity::eEntityType;
@@ -4230,3 +4130,117 @@ const char * cProtocol_1_8_0::GetProtocolStatisticName(Statistic a_Statistic)
default: return "";
}
}
+
+
+
+
+
+void cProtocol_1_8_0::HandlePacket(cByteBuffer & a_Buffer)
+{
+ UInt32 PacketType;
+ if (!a_Buffer.ReadVarInt(PacketType))
+ {
+ // Not enough data
+ return;
+ }
+
+ // Log the packet info into the comm log file:
+ if (g_ShouldLogCommIn && m_CommLogFile.IsOpen())
+ {
+ ContiguousByteBuffer PacketData;
+ a_Buffer.ReadAll(PacketData);
+ a_Buffer.ResetRead();
+ a_Buffer.ReadVarInt(PacketType); // We have already read the packet type once, it will be there again
+ ASSERT(PacketData.size() > 0); // We have written an extra NUL, so there had to be at least one byte read
+ PacketData.resize(PacketData.size() - 1);
+ AString PacketDataHex;
+ CreateHexDump(PacketDataHex, PacketData.data(), PacketData.size(), 16);
+ m_CommLogFile.Printf("Next incoming packet is type %u (0x%x), length %u (0x%x) at state %d. Payload:\n%s\n",
+ PacketType, PacketType, a_Buffer.GetUsedSpace(), a_Buffer.GetUsedSpace(), m_State, PacketDataHex.c_str()
+ );
+ }
+
+ if (!HandlePacket(a_Buffer, PacketType))
+ {
+ // Unknown packet, already been reported, but without the length. Log the length here:
+ LOGWARNING("Unhandled packet: type 0x%x, state %d, length %u", PacketType, m_State, a_Buffer.GetUsedSpace());
+
+#ifndef NDEBUG
+ // Dump the packet contents into the log:
+ a_Buffer.ResetRead();
+ ContiguousByteBuffer Packet;
+ a_Buffer.ReadAll(Packet);
+ Packet.resize(Packet.size() - 1); // Drop the final NUL pushed there for over-read detection
+ AString Out;
+ CreateHexDump(Out, Packet.data(), Packet.size(), 24);
+ LOGD("Packet contents:\n%s", Out.c_str());
+#endif // !NDEBUG
+
+ // Put a message in the comm log:
+ if (g_ShouldLogCommIn && m_CommLogFile.IsOpen())
+ {
+ m_CommLogFile.Printf("^^^^^^ Unhandled packet ^^^^^^\n\n\n");
+ }
+
+ return;
+ }
+
+ // The packet should have nothing left in the buffer:
+ if (a_Buffer.GetReadableSpace() != 0)
+ {
+ // Read more or less than packet length, report as error
+ LOGWARNING("Protocol 1.8: Wrong number of bytes read for packet 0x%x, state %d. Read %zu bytes, packet contained %u bytes",
+ PacketType, m_State, a_Buffer.GetUsedSpace() - a_Buffer.GetReadableSpace(), a_Buffer.GetUsedSpace()
+ );
+
+ // Put a message in the comm log:
+ if (g_ShouldLogCommIn && m_CommLogFile.IsOpen())
+ {
+ m_CommLogFile.Printf("^^^^^^ Wrong number of bytes read for this packet (exp %d left, got %zu left) ^^^^^^\n\n\n",
+ 1, a_Buffer.GetReadableSpace()
+ );
+ m_CommLogFile.Flush();
+ }
+
+ ASSERT(!"Read wrong number of bytes!");
+ m_Client->PacketError(PacketType);
+ }
+}
+
+
+
+
+
+void cProtocol_1_8_0::SendEntityTeleport(const cEntity & a_Entity)
+{
+ cPacketizer Pkt(*this, pktTeleportEntity);
+ Pkt.WriteVarInt32(a_Entity.GetUniqueID());
+ Pkt.WriteFPInt(a_Entity.GetPosX());
+ Pkt.WriteFPInt(a_Entity.GetPosY());
+ Pkt.WriteFPInt(a_Entity.GetPosZ());
+ Pkt.WriteByteAngle(a_Entity.GetYaw());
+ Pkt.WriteByteAngle(a_Entity.GetPitch());
+ Pkt.WriteBool(a_Entity.IsOnGround());
+}
+
+
+
+
+
+void cProtocol_1_8_0::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();
+ const AString & ServerID = Server->GetServerID();
+ Checksum.Update(reinterpret_cast<const Byte *>(ServerID.c_str()), ServerID.length());
+ Checksum.Update(a_Key, 16);
+ Checksum.Update(reinterpret_cast<const Byte *>(Server->GetPublicKeyDER().data()), Server->GetPublicKeyDER().size());
+ Byte Digest[20];
+ Checksum.Finalize(Digest);
+ cSha1Checksum::DigestToJava(Digest, m_AuthServerID);
+}
diff --git a/src/Protocol/Protocol_1_8.h b/src/Protocol/Protocol_1_8.h
index d4aa0c899..652ef69c5 100644
--- a/src/Protocol/Protocol_1_8.h
+++ b/src/Protocol/Protocol_1_8.h
@@ -141,11 +141,12 @@ protected:
/** State of the protocol. */
State m_State;
- /** Get the packet ID for a given packet. */
- virtual UInt32 GetPacketID(ePacketType a_Packet) override;
+ /** Converts the BlockFace received by the protocol into eBlockFace constants.
+ If the received value doesn't match any of our eBlockFace constants, BLOCK_FACE_NONE is returned. */
+ static eBlockFace FaceIntToBlockFace(Int32 a_FaceInt);
- /** Returns 1.8. */
- virtual Version GetProtocolVersion() override;
+ /** Get the packet ID for a given packet. */
+ virtual UInt32 GetPacketID(ePacketType a_Packet) const override;
/** Converts an animation into an ID suitable for use with the Entity Animation packet.
Returns (uchar)-1 if the protocol version doesn't support this animation. */
@@ -156,7 +157,10 @@ protected:
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const;
/** Converts eMonsterType to protocol-specific mob types */
- virtual UInt32 GetProtocolMobType(eMonsterType a_MobType);
+ virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const;
+
+ /** Returns the protocol version. */
+ virtual Version GetProtocolVersion() const override;
/** Reads and handles the packet. The packet length and type have already been read.
Returns true if the packet was understood, false if it was an unknown packet. */
@@ -201,43 +205,37 @@ protected:
The message payload is still in the bytebuffer, the handler reads it specifically for each handled channel */
virtual void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel);
- /** Sends the data to the client, encrypting them if needed. */
- virtual void SendData(ContiguousByteBufferView a_Size) override;
-
- /** Sends the packet to the client. Called by the cPacketizer's destructor. */
- virtual void SendPacket(cPacketizer & a_Packet) override;
+ /** Parses item metadata as read by ReadItem(), into the item enchantments. */
+ virtual void ParseItemMetadata(cItem & a_Item, ContiguousByteBufferView a_Metadata) const;
/** Reads an item out of the received data, sets a_Item to the values read.
Returns false if not enough received data.
a_KeepRemainingBytes tells the function to keep that many bytes at the end of the buffer. */
- virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes = 0);
-
- /** Parses item metadata as read by ReadItem(), into the item enchantments. */
- virtual void ParseItemMetadata(cItem & a_Item, ContiguousByteBufferView a_Metadata);
-
- virtual void StartEncryption(const Byte * a_Key);
-
- /** Converts the BlockFace received by the protocol into eBlockFace constants.
- If the received value doesn't match any of our eBlockFace constants, BLOCK_FACE_NONE is returned. */
- static eBlockFace FaceIntToBlockFace(Int32 a_FaceInt);
+ virtual bool ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes = 0) const;
/** Sends the entity type and entity-dependent data required for the entity to initially spawn. */
virtual void SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData);
- /** Writes the block entity data for the specified block entity into the packet. */
- virtual void WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity);
+ /** Sends the data to the client, encrypting them if needed. */
+ virtual void SendData(ContiguousByteBufferView a_Size) override;
- /** Writes the item data into a packet. */
- virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item);
+ /** Sends the packet to the client. Called by the cPacketizer's destructor. */
+ virtual void SendPacket(cPacketizer & a_Packet) override;
- /** Writes the metadata for the specified entity, not including the terminating 0x7f. */
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity);
+ /** Writes the block entity data for the specified block entity into the packet. */
+ virtual void WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const;
- /** Writes the mob-specific metadata for the specified mob */
- virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob);
+ /** Writes the metadata for the specified entity, not including the terminating 0x7f. */
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const;
/** Writes the entity properties for the specified entity, including the Count field. */
- virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity);
+ virtual void WriteEntityProperties(cPacketizer & a_Pkt, const cEntity & a_Entity) const;
+
+ /** Writes the item data into a packet. */
+ virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const;
+
+ /** Writes the mob-specific metadata for the specified mob */
+ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const;
private:
@@ -259,14 +257,6 @@ private:
/** Adds the received (unencrypted) data to m_ReceivedData, parses complete packets */
void AddReceivedData(cByteBuffer & a_Buffer, ContiguousByteBufferView a_Data);
- /** Handle a complete packet stored in the given buffer. */
- void HandlePacket(cByteBuffer & a_Buffer);
-
- /** Sends an entity teleport packet.
- Mitigates a 1.8 bug where the position in the entity spawn packet is ignored,
- and so entities don't show up until a teleport is sent. */
- void SendEntityTeleport(const cEntity & a_Entity);
-
/** Converts an entity to a protocol-specific entity type.
Only entities that the Send Spawn Entity packet supports are valid inputs to this method */
static UInt8 GetProtocolEntityType(const cEntity & a_Entity);
@@ -278,4 +268,14 @@ private:
Protocols <= 1.12 use strings, hence this is a static as the string-mapping was append-only for the versions that used it.
Returns an empty string, handled correctly by the client, for newer, unsupported statistics. */
static const char * GetProtocolStatisticName(Statistic a_Statistic);
+
+ /** Handle a complete packet stored in the given buffer. */
+ void HandlePacket(cByteBuffer & a_Buffer);
+
+ /** Sends an entity teleport packet.
+ Mitigates a 1.8 bug where the position in the entity spawn packet is ignored,
+ and so entities don't show up until a teleport is sent. */
+ void SendEntityTeleport(const cEntity & a_Entity);
+
+ void StartEncryption(const Byte * a_Key);
} ;
diff --git a/src/Protocol/Protocol_1_9.cpp b/src/Protocol/Protocol_1_9.cpp
index 6b240b235..e6f774bdf 100644
--- a/src/Protocol/Protocol_1_9.cpp
+++ b/src/Protocol/Protocol_1_9.cpp
@@ -51,9 +51,11 @@ Implements the 1.9 protocol classes:
-/** Value for main hand in Hand parameter for Protocol 1.9. */
-static const UInt32 MAIN_HAND = 0;
-static const UInt32 OFF_HAND = 1;
+// Value for main hand in Hand parameter for Protocol 1.9.
+#define MAIN_HAND 0
+
+// Value for left hand in MainHand parameter for Protocol 1.9.
+#define LEFT_HAND 0
@@ -602,7 +604,7 @@ void cProtocol_1_9_0::SendUnloadChunk(int a_ChunkX, int a_ChunkZ)
-UInt32 cProtocol_1_9_0::GetPacketID(cProtocol::ePacketType a_Packet)
+UInt32 cProtocol_1_9_0::GetPacketID(cProtocol::ePacketType a_Packet) const
{
switch (a_Packet)
{
@@ -726,22 +728,22 @@ signed char cProtocol_1_9_0::GetProtocolEntityStatus(const EntityAnimation a_Ani
-cProtocol::Version cProtocol_1_9_0::GetProtocolVersion()
+UInt32 cProtocol_1_9_0::GetProtocolMobType(const eMonsterType a_MobType) const
{
- return Version::v1_9_0;
+ switch (a_MobType)
+ {
+ case mtShulker: return 69;
+ default: return Super::GetProtocolMobType(a_MobType);
+ }
}
-UInt32 cProtocol_1_9_0::GetProtocolMobType(const eMonsterType a_MobType)
+cProtocol::Version cProtocol_1_9_0::GetProtocolVersion() const
{
- switch (a_MobType)
- {
- case mtShulker: return 69;
- default: return Super::GetProtocolMobType(a_MobType);
- }
+ return Version::v1_9_0;
}
@@ -824,7 +826,7 @@ void cProtocol_1_9_0::HandlePacketAnimation(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Hand);
- m_Client->HandleAnimation(0); // Packet exists solely for arm-swing notification
+ m_Client->HandleAnimation(Hand == MAIN_HAND); // Packet exists solely for arm-swing notification (main and off-hand).
}
@@ -862,7 +864,8 @@ void cProtocol_1_9_0::HandlePacketBlockPlace(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorX);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorY);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, CursorZ);
- m_Client->HandleRightClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), CursorX, CursorY, CursorZ, HandIntToEnum(Hand));
+
+ m_Client->HandleRightClick(BlockX, BlockY, BlockZ, FaceIntToBlockFace(Face), CursorX, CursorY, CursorZ, Hand == MAIN_HAND);
}
@@ -899,12 +902,12 @@ void cProtocol_1_9_0::HandlePacketClientSettings(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, ChatFlags);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, ChatColors);
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, SkinParts);
- HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, MainHand);
+ HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, MainHand);
m_Client->SetLocale(Locale);
m_Client->SetViewDistance(ViewDistance);
m_Client->GetPlayer()->SetSkinParts(SkinParts);
- m_Client->GetPlayer()->SetMainHand(static_cast<eMainHand>(MainHand));
+ m_Client->GetPlayer()->SetLeftHanded(MainHand == LEFT_HAND);
// TODO: Handle chat flags and chat colors
}
@@ -964,7 +967,7 @@ void cProtocol_1_9_0::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
if (m_IsTeleportIdConfirmed)
{
- m_Client->HandlePlayerPos(PosX, PosY, PosZ, IsOnGround);
+ m_Client->HandlePlayerMove(PosX, PosY, PosZ, IsOnGround);
}
}
@@ -1065,6 +1068,7 @@ void cProtocol_1_9_0::HandlePacketUseEntity(cByteBuffer & a_ByteBuffer)
case 0:
{
HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, Hand);
+
if (Hand == MAIN_HAND) // TODO: implement handling of off-hand actions; ignore them for now to avoid processing actions twice
{
m_Client->HandleUseEntity(EntityID, false);
@@ -1102,7 +1106,7 @@ void cProtocol_1_9_0::HandlePacketUseItem(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarInt, Int32, Hand);
- m_Client->HandleUseItem(HandIntToEnum(Hand));
+ m_Client->HandleUseItem(Hand == MAIN_HAND);
}
@@ -1193,7 +1197,7 @@ void cProtocol_1_9_0::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
-void cProtocol_1_9_0::ParseItemMetadata(cItem & a_Item, const ContiguousByteBufferView a_Metadata)
+void cProtocol_1_9_0::ParseItemMetadata(cItem & a_Item, const ContiguousByteBufferView a_Metadata) const
{
// Parse into NBT:
cParsedNBT NBT(a_Metadata);
@@ -1397,25 +1401,6 @@ void cProtocol_1_9_0::ParseItemMetadata(cItem & a_Item, const ContiguousByteBuff
-eHand cProtocol_1_9_0::HandIntToEnum(Int32 a_Hand)
-{
- // Convert hand parameter into eHand enum
- switch (a_Hand)
- {
- case MAIN_HAND: return eHand::hMain;
- case OFF_HAND: return eHand::hOff;
- default:
- {
- ASSERT(!"Unknown hand value");
- return eHand::hMain;
- }
- }
-}
-
-
-
-
-
void cProtocol_1_9_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData)
{
ASSERT(m_State == 3); // In game mode?
@@ -1443,7 +1428,7 @@ void cProtocol_1_9_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_Ob
-void cProtocol_1_9_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity)
+void cProtocol_1_9_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const
{
a_Writer.AddInt("x", a_BlockEntity.GetPosX());
a_Writer.AddInt("y", a_BlockEntity.GetPosY());
@@ -1467,177 +1452,7 @@ void cProtocol_1_9_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEn
-void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, 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())
- {
- a_Pkt.WriteBEInt16(-1);
- return;
- }
-
- if ((ItemType == E_ITEM_POTION) && ((a_Item.m_ItemDamage & 0x4000) != 0))
- {
- // Ugly special case for splash potion ids which changed in 1.9; this can be removed when the new 1.9 ids are implemented
- a_Pkt.WriteBEInt16(438); // minecraft:splash_potion
- }
- else
- {
- // Normal item
- a_Pkt.WriteBEInt16(ItemType);
- }
- a_Pkt.WriteBEInt8(a_Item.m_ItemCount);
- if ((ItemType == E_ITEM_POTION) || (ItemType == E_ITEM_SPAWN_EGG))
- {
- // These items lost their metadata; if it is sent they don't render correctly.
- a_Pkt.WriteBEInt16(0);
- }
- else
- {
- a_Pkt.WriteBEInt16(a_Item.m_ItemDamage);
- }
-
- if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (ItemType != E_ITEM_FIREWORK_ROCKET) && (ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid() && (ItemType != E_ITEM_POTION) && (ItemType != E_ITEM_SPAWN_EGG))
- {
- a_Pkt.WriteBEInt8(0);
- return;
- }
-
-
- // Send the enchantments and custom names:
- cFastNBTWriter Writer;
- if (a_Item.m_RepairCost != 0)
- {
- Writer.AddInt("RepairCost", a_Item.m_RepairCost);
- }
- if (!a_Item.m_Enchantments.IsEmpty())
- {
- const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
- EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName);
- }
- if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid())
- {
- Writer.BeginCompound("display");
- if (a_Item.m_ItemColor.IsValid())
- {
- Writer.AddInt("color", static_cast<Int32>(a_Item.m_ItemColor.m_Color));
- }
-
- if (!a_Item.IsCustomNameEmpty())
- {
- Writer.AddString("Name", a_Item.m_CustomName);
- }
- if (!a_Item.IsLoreEmpty())
- {
- Writer.BeginList("Lore", TAG_String);
-
- for (const auto & Line : a_Item.m_LoreTable)
- {
- Writer.AddString("", Line);
- }
-
- Writer.EndList();
- }
- Writer.EndCompound();
- }
- if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))
- {
- cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, static_cast<ENUM_ITEM_TYPE>(a_Item.m_ItemType));
- }
- if (a_Item.m_ItemType == E_ITEM_POTION)
- {
- // 1.9 potions use a different format. In the future (when only 1.9+ is supported) this should be its own class
- AString PotionID = "empty"; // Fallback of "Uncraftable potion" for unhandled cases
-
- cEntityEffect::eType Type = cEntityEffect::GetPotionEffectType(a_Item.m_ItemDamage);
- if (Type != cEntityEffect::effNoEffect)
- {
- switch (Type)
- {
- case cEntityEffect::effRegeneration: PotionID = "regeneration"; break;
- case cEntityEffect::effSpeed: PotionID = "swiftness"; break;
- case cEntityEffect::effFireResistance: PotionID = "fire_resistance"; break;
- case cEntityEffect::effPoison: PotionID = "poison"; break;
- case cEntityEffect::effInstantHealth: PotionID = "healing"; break;
- case cEntityEffect::effNightVision: PotionID = "night_vision"; break;
- case cEntityEffect::effWeakness: PotionID = "weakness"; break;
- case cEntityEffect::effStrength: PotionID = "strength"; break;
- case cEntityEffect::effSlowness: PotionID = "slowness"; break;
- case cEntityEffect::effJumpBoost: PotionID = "leaping"; break;
- case cEntityEffect::effInstantDamage: PotionID = "harming"; break;
- case cEntityEffect::effWaterBreathing: PotionID = "water_breathing"; break;
- case cEntityEffect::effInvisibility: PotionID = "invisibility"; break;
- default: ASSERT(!"Unknown potion effect"); break;
- }
- if (cEntityEffect::GetPotionEffectIntensity(a_Item.m_ItemDamage) == 1)
- {
- PotionID = "strong_" + PotionID;
- }
- else if (a_Item.m_ItemDamage & 0x40)
- {
- // Extended potion bit
- PotionID = "long_" + PotionID;
- }
- }
- else
- {
- // Empty potions: Water bottles and other base ones
- if (a_Item.m_ItemDamage == 0)
- {
- // No other bits set; thus it's a water bottle
- PotionID = "water";
- }
- else
- {
- switch (a_Item.m_ItemDamage & 0x3f)
- {
- case 0x00: PotionID = "mundane"; break;
- case 0x10: PotionID = "awkward"; break;
- case 0x20: PotionID = "thick"; break;
- }
- // Default cases will use "empty" from before.
- }
- }
-
- PotionID = "minecraft:" + PotionID;
-
- Writer.AddString("Potion", PotionID);
- }
- if (a_Item.m_ItemType == E_ITEM_SPAWN_EGG)
- {
- // Convert entity ID to the name.
- eMonsterType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(a_Item.m_ItemDamage);
- if (MonsterType != eMonsterType::mtInvalidType)
- {
- Writer.BeginCompound("EntityTag");
- Writer.AddString("id", "minecraft:" + cMonster::MobTypeToVanillaNBT(MonsterType));
- Writer.EndCompound();
- }
- }
-
- Writer.Finish();
-
- const auto Result = Writer.GetResult();
- if (Result.empty())
- {
- a_Pkt.WriteBEInt8(0);
- return;
- }
- a_Pkt.WriteBuf(Result);
-}
-
-
-
-
-
-void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
+void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
{
// Common metadata:
Int8 Flags = 0;
@@ -1692,7 +1507,7 @@ void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
a_Pkt.WriteBEUInt8(13);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
- a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
+ a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
break;
}
case cEntity::etPickup:
@@ -1859,7 +1674,177 @@ void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a
-void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
+void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const
+{
+ 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())
+ {
+ a_Pkt.WriteBEInt16(-1);
+ return;
+ }
+
+ if ((ItemType == E_ITEM_POTION) && ((a_Item.m_ItemDamage & 0x4000) != 0))
+ {
+ // Ugly special case for splash potion ids which changed in 1.9; this can be removed when the new 1.9 ids are implemented
+ a_Pkt.WriteBEInt16(438); // minecraft:splash_potion
+ }
+ else
+ {
+ // Normal item
+ a_Pkt.WriteBEInt16(ItemType);
+ }
+ a_Pkt.WriteBEInt8(a_Item.m_ItemCount);
+ if ((ItemType == E_ITEM_POTION) || (ItemType == E_ITEM_SPAWN_EGG))
+ {
+ // These items lost their metadata; if it is sent they don't render correctly.
+ a_Pkt.WriteBEInt16(0);
+ }
+ else
+ {
+ a_Pkt.WriteBEInt16(a_Item.m_ItemDamage);
+ }
+
+ if (a_Item.m_Enchantments.IsEmpty() && a_Item.IsBothNameAndLoreEmpty() && (ItemType != E_ITEM_FIREWORK_ROCKET) && (ItemType != E_ITEM_FIREWORK_STAR) && !a_Item.m_ItemColor.IsValid() && (ItemType != E_ITEM_POTION) && (ItemType != E_ITEM_SPAWN_EGG))
+ {
+ a_Pkt.WriteBEInt8(0);
+ return;
+ }
+
+
+ // Send the enchantments and custom names:
+ cFastNBTWriter Writer;
+ if (a_Item.m_RepairCost != 0)
+ {
+ Writer.AddInt("RepairCost", a_Item.m_RepairCost);
+ }
+ if (!a_Item.m_Enchantments.IsEmpty())
+ {
+ const char * TagName = (a_Item.m_ItemType == E_ITEM_BOOK) ? "StoredEnchantments" : "ench";
+ EnchantmentSerializer::WriteToNBTCompound(a_Item.m_Enchantments, Writer, TagName);
+ }
+ if (!a_Item.IsBothNameAndLoreEmpty() || a_Item.m_ItemColor.IsValid())
+ {
+ Writer.BeginCompound("display");
+ if (a_Item.m_ItemColor.IsValid())
+ {
+ Writer.AddInt("color", static_cast<Int32>(a_Item.m_ItemColor.m_Color));
+ }
+
+ if (!a_Item.IsCustomNameEmpty())
+ {
+ Writer.AddString("Name", a_Item.m_CustomName);
+ }
+ if (!a_Item.IsLoreEmpty())
+ {
+ Writer.BeginList("Lore", TAG_String);
+
+ for (const auto & Line : a_Item.m_LoreTable)
+ {
+ Writer.AddString("", Line);
+ }
+
+ Writer.EndList();
+ }
+ Writer.EndCompound();
+ }
+ if ((a_Item.m_ItemType == E_ITEM_FIREWORK_ROCKET) || (a_Item.m_ItemType == E_ITEM_FIREWORK_STAR))
+ {
+ cFireworkItem::WriteToNBTCompound(a_Item.m_FireworkItem, Writer, static_cast<ENUM_ITEM_TYPE>(a_Item.m_ItemType));
+ }
+ if (a_Item.m_ItemType == E_ITEM_POTION)
+ {
+ // 1.9 potions use a different format. In the future (when only 1.9+ is supported) this should be its own class
+ AString PotionID = "empty"; // Fallback of "Uncraftable potion" for unhandled cases
+
+ cEntityEffect::eType Type = cEntityEffect::GetPotionEffectType(a_Item.m_ItemDamage);
+ if (Type != cEntityEffect::effNoEffect)
+ {
+ switch (Type)
+ {
+ case cEntityEffect::effRegeneration: PotionID = "regeneration"; break;
+ case cEntityEffect::effSpeed: PotionID = "swiftness"; break;
+ case cEntityEffect::effFireResistance: PotionID = "fire_resistance"; break;
+ case cEntityEffect::effPoison: PotionID = "poison"; break;
+ case cEntityEffect::effInstantHealth: PotionID = "healing"; break;
+ case cEntityEffect::effNightVision: PotionID = "night_vision"; break;
+ case cEntityEffect::effWeakness: PotionID = "weakness"; break;
+ case cEntityEffect::effStrength: PotionID = "strength"; break;
+ case cEntityEffect::effSlowness: PotionID = "slowness"; break;
+ case cEntityEffect::effJumpBoost: PotionID = "leaping"; break;
+ case cEntityEffect::effInstantDamage: PotionID = "harming"; break;
+ case cEntityEffect::effWaterBreathing: PotionID = "water_breathing"; break;
+ case cEntityEffect::effInvisibility: PotionID = "invisibility"; break;
+ default: ASSERT(!"Unknown potion effect"); break;
+ }
+ if (cEntityEffect::GetPotionEffectIntensity(a_Item.m_ItemDamage) == 1)
+ {
+ PotionID = "strong_" + PotionID;
+ }
+ else if (a_Item.m_ItemDamage & 0x40)
+ {
+ // Extended potion bit
+ PotionID = "long_" + PotionID;
+ }
+ }
+ else
+ {
+ // Empty potions: Water bottles and other base ones
+ if (a_Item.m_ItemDamage == 0)
+ {
+ // No other bits set; thus it's a water bottle
+ PotionID = "water";
+ }
+ else
+ {
+ switch (a_Item.m_ItemDamage & 0x3f)
+ {
+ case 0x00: PotionID = "mundane"; break;
+ case 0x10: PotionID = "awkward"; break;
+ case 0x20: PotionID = "thick"; break;
+ }
+ // Default cases will use "empty" from before.
+ }
+ }
+
+ PotionID = "minecraft:" + PotionID;
+
+ Writer.AddString("Potion", PotionID);
+ }
+ if (a_Item.m_ItemType == E_ITEM_SPAWN_EGG)
+ {
+ // Convert entity ID to the name.
+ eMonsterType MonsterType = cItemSpawnEggHandler::ItemDamageToMonsterType(a_Item.m_ItemDamage);
+ if (MonsterType != eMonsterType::mtInvalidType)
+ {
+ Writer.BeginCompound("EntityTag");
+ Writer.AddString("id", "minecraft:" + cMonster::MobTypeToVanillaNBT(MonsterType));
+ Writer.EndCompound();
+ }
+ }
+
+ Writer.Finish();
+
+ const auto Result = Writer.GetResult();
+ if (Result.empty())
+ {
+ a_Pkt.WriteBEInt8(0);
+ return;
+ }
+ a_Pkt.WriteBuf(Result);
+}
+
+
+
+
+
+void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const
{
// Living entity metadata
if (a_Mob.HasCustomName())
@@ -2294,7 +2279,7 @@ void cProtocol_1_9_1::SendLogin(const cPlayer & a_Player, const cWorld & a_World
-cProtocol::Version cProtocol_1_9_1::GetProtocolVersion()
+cProtocol::Version cProtocol_1_9_1::GetProtocolVersion() const
{
return Version::v1_9_1;
}
@@ -2306,7 +2291,7 @@ cProtocol::Version cProtocol_1_9_1::GetProtocolVersion()
////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_9_2:
-cProtocol::Version cProtocol_1_9_2::GetProtocolVersion()
+cProtocol::Version cProtocol_1_9_2::GetProtocolVersion() const
{
return Version::v1_9_2;
}
@@ -2354,16 +2339,7 @@ void cProtocol_1_9_4::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, c
-cProtocol::Version cProtocol_1_9_4::GetProtocolVersion()
-{
- return Version::v1_9_4;
-}
-
-
-
-
-
-UInt32 cProtocol_1_9_4::GetPacketID(cProtocol::ePacketType a_Packet)
+UInt32 cProtocol_1_9_4::GetPacketID(cProtocol::ePacketType a_Packet) const
{
switch (a_Packet)
{
@@ -2376,3 +2352,12 @@ UInt32 cProtocol_1_9_4::GetPacketID(cProtocol::ePacketType a_Packet)
default: return Super::GetPacketID(a_Packet);
}
}
+
+
+
+
+
+cProtocol::Version cProtocol_1_9_4::GetProtocolVersion() const
+{
+ return Version::v1_9_4;
+}
diff --git a/src/Protocol/Protocol_1_9.h b/src/Protocol/Protocol_1_9.h
index 00d6c477a..c2005c4b9 100644
--- a/src/Protocol/Protocol_1_9.h
+++ b/src/Protocol/Protocol_1_9.h
@@ -21,10 +21,6 @@ Declares the 1.9 protocol classes:
#include "Protocol.h"
#include "Protocol_1_8.h"
-#include "../ByteBuffer.h"
-
-#include "../mbedTLS++/AesCfb128Decryptor.h"
-#include "../mbedTLS++/AesCfb128Encryptor.h"
@@ -39,54 +35,45 @@ public:
cProtocol_1_9_0(cClientHandle * a_Client, const AString & a_ServerAddress, State a_State);
- /** Sending stuff to clients (alphabetically sorted): */
- virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) override;
- virtual void SendBossBarAdd (UInt32 a_UniqueID, const cCompositeChat & a_Title, float a_FractionFilled, BossBarColor a_Color, BossBarDivisionType a_DivisionType, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog) override;
- virtual void SendBossBarRemove (UInt32 a_UniqueID) override;
- virtual void SendBossBarUpdateFlags (UInt32 a_UniqueID, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog) override;
- virtual void SendBossBarUpdateHealth (UInt32 a_UniqueID, float a_FractionFilled) override;
- virtual void SendBossBarUpdateStyle (UInt32 a_UniqueID, BossBarColor a_Color, BossBarDivisionType a_DivisionType) override;
- virtual void SendBossBarUpdateTitle (UInt32 a_UniqueID, const cCompositeChat & a_Title) override;
- virtual void SendDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override;
- virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
- virtual void SendEntityMetadata (const cEntity & a_Entity) override;
- virtual void SendEntityPosition (const cEntity & a_Entity) override;
- virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
- virtual void SendKeepAlive (UInt32 a_PingID) override;
- virtual void SendLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) override;
- virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override;
- virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
- virtual void SendPlayerMoveLook (void) 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 SendSpawnMob (const cMonster & a_Mob) override;
- virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
- virtual void SendUnleashEntity (const cEntity & a_Entity) override;
- virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
+ virtual void SendAttachEntity (const cEntity & a_Entity, const cEntity & a_Vehicle) override;
+ virtual void SendBossBarAdd (UInt32 a_UniqueID, const cCompositeChat & a_Title, float a_FractionFilled, BossBarColor a_Color, BossBarDivisionType a_DivisionType, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog) override;
+ virtual void SendBossBarRemove (UInt32 a_UniqueID) override;
+ virtual void SendBossBarUpdateFlags (UInt32 a_UniqueID, bool a_DarkenSky, bool a_PlayEndMusic, bool a_CreateFog) override;
+ virtual void SendBossBarUpdateHealth(UInt32 a_UniqueID, float a_FractionFilled) override;
+ virtual void SendBossBarUpdateStyle (UInt32 a_UniqueID, BossBarColor a_Color, BossBarDivisionType a_DivisionType) override;
+ virtual void SendBossBarUpdateTitle (UInt32 a_UniqueID, const cCompositeChat & a_Title) override;
+ virtual void SendDetachEntity (const cEntity & a_Entity, const cEntity & a_PreviousVehicle) override;
+ virtual void SendEntityEquipment (const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
+ virtual void SendEntityMetadata (const cEntity & a_Entity) override;
+ virtual void SendEntityPosition (const cEntity & a_Entity) override;
+ virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
+ virtual void SendKeepAlive (UInt32 a_PingID) override;
+ virtual void SendLeashEntity (const cEntity & a_Entity, const cEntity & a_EntityLeashedTo) override;
+ virtual void SendMapData (const cMap & a_Map, int a_DataStartX, int a_DataStartY) override;
+ virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
+ virtual void SendPlayerMoveLook (void) 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 SendSpawnMob (const cMonster & a_Mob) override;
+ virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ virtual void SendUnleashEntity (const cEntity & a_Entity) override;
+ virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
protected:
- /** The current teleport ID, and whether it has been confirmed by the client */
+ /** The current teleport ID. */
bool m_IsTeleportIdConfirmed;
- UInt32 m_OutstandingTeleportId;
- /** Get the packet ID for a given packet. */
- virtual UInt32 GetPacketID(ePacketType a_Packet) override;
+ /** Whether the current teleport ID has been confirmed by the client. */
+ UInt32 m_OutstandingTeleportId;
+ virtual UInt32 GetPacketID(ePacketType a_Packet) const override;
virtual unsigned char GetProtocolEntityAnimation(EntityAnimation a_Animation) const override;
virtual signed char GetProtocolEntityStatus(EntityAnimation a_Animation) const override;
+ virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) const override;
+ virtual Version GetProtocolVersion() const override;
- /** Returns 1.9. */
- virtual Version GetProtocolVersion() override;
-
- /** Converts eMonsterType to protocol-specific mob types */
- virtual UInt32 GetProtocolMobType(eMonsterType a_MobType) override;
-
- /** Reads and handles the packet. The packet length and type have already been read.
- Returns true if the packet was understood, false if it was an unknown packet. */
- virtual bool HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
-
- // Packet handlers while in the Game state (m_State == 3):
+ virtual bool HandlePacket (cByteBuffer & a_ByteBuffer, UInt32 a_PacketType) override;
virtual void HandlePacketAnimation (cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketBlockDig (cByteBuffer & a_ByteBuffer) override;
virtual void HandlePacketBlockPlace (cByteBuffer & a_ByteBuffer) override;
@@ -104,27 +91,12 @@ protected:
virtual void HandlePacketVehicleMove (cByteBuffer & a_ByteBuffer);
virtual void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer) override;
- /** Parses item metadata as read by ReadItem(), into the item enchantments. */
- virtual void ParseItemMetadata(cItem & a_Item, ContiguousByteBufferView a_Metadata) override;
-
- /** Converts the hand parameter received by the protocol into eHand constants.
- If the received value doesn't match any of the know value, raise an assertion fail or return hMain. */
- static eHand HandIntToEnum(Int32 a_Hand);
-
- /** Sends the entity type and entity-dependent data required for the entity to initially spawn. */
+ virtual void ParseItemMetadata(cItem & a_Item, ContiguousByteBufferView a_Metadata) const override;
virtual void SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_ObjectType, const Int32 a_ObjectData) override;
-
- /** Writes the block entity data for the specified block entity into the packet. */
- virtual void WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) override;
-
- /** Writes the item data into a packet. */
- virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) override;
-
- /** Writes the metadata for the specified entity, not including the terminating 0xff. */
- virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) override;
-
- /** Writes the mob-specific metadata for the specified mob */
- virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) override;
+ virtual void WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const override;
+ virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const override;
+ virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) const override;
+ virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob) const override;
/** Types used within metadata */
enum eMetadataType
@@ -163,8 +135,7 @@ protected:
virtual void SendLogin(const cPlayer & a_Player, const cWorld & a_World) override;
- /** Returns 1.9.1. */
- virtual Version GetProtocolVersion() override;
+ virtual Version GetProtocolVersion() const override;
} ;
@@ -183,8 +154,7 @@ public:
protected:
- /** Returns 1.9.2. */
- virtual Version GetProtocolVersion() override;
+ virtual Version GetProtocolVersion() const override;
} ;
@@ -205,7 +175,6 @@ protected:
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;
- /** Returns 1.9.4. */
- virtual Version GetProtocolVersion() override;
- virtual UInt32 GetPacketID(ePacketType a_Packet) override;
+ virtual UInt32 GetPacketID(ePacketType a_Packet) const override;
+ virtual Version GetProtocolVersion() const override;
} ;