1
0
Fork 0

More cProtocol cleanup

* Alpha sort functions
* Simplify hand handling
* Fix left handed mode client-side display
This commit is contained in:
Tiger Wang 2021-04-10 15:57:16 +01:00
parent 63ded9f6b4
commit a999c5d845
21 changed files with 1297 additions and 1375 deletions

View File

@ -3831,6 +3831,16 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
},
Notes = "(<b>DEPRECATED</b>) Please use cEntity:IsTicking().",
},
IsElytraFlying =
{
Returns =
{
{
Type = "boolean",
},
},
Notes = "Returns true if the entity is flying with an elytra. Entities that cannot fly with an elytra return always false.",
},
IsEnderCrystal =
{
Returns =
@ -3881,6 +3891,16 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
},
Notes = "Returns true if the entity represents a fishing rod floater",
},
IsHeadInWater =
{
Returns =
{
{
Type = "boolean",
},
},
Notes = "Returns true if the entity's head is in a water block",
},
IsInvisible =
{
Returns =
@ -3889,7 +3909,7 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
Type = "boolean",
},
},
Notes = "Returns true if the entity is invisible",
Notes = "Returns true if the entity is invisible.",
},
IsInFire =
{
@ -3921,16 +3941,6 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
},
Notes = "Returns true if any part of the entity is in a water block",
},
IsHeadInWater =
{
Returns =
{
{
Type = "boolean",
},
},
Notes = "Returns true if the entity's head is in a water block",
},
IsItemFrame =
{
Returns =
@ -4071,16 +4081,6 @@ local Hash = cCryptoHash.sha1HexString("DataToHash")
},
Notes = "Returns true if the entity is sprinting. Entities that cannot sprint return always false",
},
IsElytraFlying =
{
Returns =
{
{
Type = "boolean",
},
},
Notes = "Returns true if the entity is flying with an elytra. Entities that cannot fly with an elytra return always false",
},
IsSubmerged =
{
Returns =
@ -10449,16 +10449,6 @@ a_Player:OpenWindow(Window);
},
Notes = "Returns the player's current maximum speed, relative to the game default speed. Takes into account the sprinting / flying status.",
},
GetMainHand =
{
Returns =
{
{
Type = "eMainHand",
},
},
Notes = "Returns the player's main hand.",
},
GetName =
{
Returns =
@ -10771,6 +10761,16 @@ a_Player:OpenWindow(Window);
},
Notes = "Returns true if the player is currently lying in a bed.",
},
IsLeftHanded =
{
Returns =
{
{
Type = "boolean",
},
},
Notes = "Returns true if the player's left hand is dominant.",
},
IsSatiated =
{
Returns =
@ -11101,6 +11101,17 @@ a_Player:OpenWindow(Window);
},
Notes = "Sets the item that the player is dragging in a UI window. If no UI window is open, this function does nothing."
},
SetElytraFlight =
{
Params =
{
{
Name = "IsElytraFlying",
Type = "boolean",
},
},
Notes = "Sets whether the player is elytra flying or not.",
},
SetFlying =
{
Params =
@ -11194,16 +11205,16 @@ a_Player:OpenWindow(Window);
},
Notes = "Sets the 'IsFishing' flag for the player. The floater entity ID is expected for the true variant, it can be omitted when IsFishing is false. FIXME: Undefined behavior when multiple fishing rods are used simultanously",
},
SetMainHand =
SetLeftHanded =
{
Params =
{
{
Name = "Hand",
Type = "eMainHand",
Name = "IsLeftHanded",
Type = "boolean",
},
},
Notes = "Sets the main hand of the player.",
Notes = "Sets the dominant hand of the player.",
},
SetName =
{
@ -11249,17 +11260,6 @@ a_Player:OpenWindow(Window);
},
Notes = "Sets the skin part flags of the player. The value should be a bitwise OR of several {{Globals#eSkinPart|eSkinPart}} constants.",
},
SetElytraFlight =
{
Params =
{
{
Name = "IsElytraFlying",
Type = "boolean",
},
},
Notes = "Sets whether the player is elytra flying or not.",
},
SetSprintingMaxSpeed =
{
Params =
@ -17925,32 +17925,6 @@ end
gmXXX constants, the eGameMode_ constants are deprecated and will be removed from the API.
]],
},
eHand =
{
Include =
{
"hMain",
"hOff",
},
TextBefore = [[
These constants represent the main and off hand. Currently, these constants are not used, but
are provided for future use when dual-wielding is functional. An action or item can be in the
main hand or the off hand. The main hand can be either the left or the right hand - use
{{cPlayer}}:GetMainHand() to determine which (see {{Globals#eMainHand|eMainHand}}).
]],
},
eMainHand =
{
Include =
{
"^mh.*",
},
TextBefore = [[
These constants identify which hand is the main hand. The main hand can either be the left hand
or the right hand. Note that this is only visual, as the client behaves the same regardless of the
main hand setting. See {{cPlayer}}:GetMainHand().
]],
},
EMCSBiome =
{
Include = "^bi.*",

View File

@ -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
// 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::HandleAnimation(int a_Animation)
void cClientHandle::HandlePlayerMoveLook(double a_PosX, double a_PosY, double a_PosZ, float a_Rotation, float a_Pitch, bool a_IsOnGround)
{
if (cPluginManager::Get()->CallHookPlayerAnimation(*m_Player, a_Animation))
{
// Plugin disagrees, bail out
return;
}
m_Player->GetWorld()->BroadcastEntityAnimation(*m_Player, static_cast<char>(a_Animation), this);
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))
{

View File

@ -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);

View File

@ -211,26 +211,6 @@ enum eMobHeadRotation
enum eHand
{
hMain = 0,
hOff = 1,
} ;
enum eMainHand
{
mhLeft = 0,
mhRight = 1,
} ;
enum eSkinPart
{
spCape = 0x01,

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -329,16 +329,7 @@ void cProtocol_1_10_0::SendSoundEffect(const AString & a_SoundName, double a_X,
cProtocol::Version cProtocol_1_10_0::GetProtocolVersion()
{
return Version::v1_10_0;
}
UInt32 cProtocol_1_10_0::GetProtocolMobType(const eMonsterType a_MobType)
UInt32 cProtocol_1_10_0::GetProtocolMobType(const eMonsterType a_MobType) const
{
switch (a_MobType)
{
@ -351,6 +342,15 @@ UInt32 cProtocol_1_10_0::GetProtocolMobType(const eMonsterType a_MobType)
cProtocol::Version cProtocol_1_10_0::GetProtocolVersion() const
{
return Version::v1_10_0;
}
void cProtocol_1_10_0::HandlePacketResourcePackStatus(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadBEUInt8, UInt8, Status);
@ -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;

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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;
}

View File

@ -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;

View File

@ -238,257 +238,7 @@ void cProtocol_1_13::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity)
bool cProtocol_1_13::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
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);
}
void cProtocol_1_13::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
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;
// 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);
}
cProtocol::Version cProtocol_1_13::GetProtocolVersion()
{
return Version::v1_13;
}
UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType)
{
switch (a_PacketType)
{
case pktAttachEntity: return 0x46;
case pktBlockChanges: return 0x0f;
case pktCameraSetTo: return 0x3c;
case pktChatRaw: return 0x0e;
case pktCollectEntity: return 0x4f;
case pktDestroyEntity: return 0x35;
case pktDisconnectDuringGame: return 0x1b;
case pktEditSign: return 0x2c;
case pktEntityEffect: return 0x53;
case pktEntityEquipment: return 0x42;
case pktEntityHeadLook: return 0x39;
case pktEntityLook: return 0x2a;
case pktEntityMeta: return 0x3f;
case pktEntityProperties: return 0x52;
case pktEntityRelMove: return 0x28;
case pktEntityRelMoveLook: return 0x29;
case pktEntityStatus: return 0x1c;
case pktEntityVelocity: return 0x41;
case pktExperience: return 0x43;
case pktExplosion: return 0x1e;
case pktGameMode: return 0x20;
case pktHeldItemChange: return 0x3d;
case pktInventorySlot: return 0x17;
case pktJoinGame: return 0x25;
case pktKeepAlive: return 0x21;
case pktLeashEntity: return 0x40;
case pktMapData: return 0x26;
case pktParticleEffect: return 0x24;
case pktPlayerAbilities: return 0x2e;
case pktPlayerList: return 0x30;
case pktPlayerListHeaderFooter: return 0x4e;
case pktPlayerMoveLook: return 0x32;
case pktPluginMessage: return 0x19;
case pktRemoveEntityEffect: return 0x36;
case pktRespawn: return 0x38;
case pktScoreboardObjective: return 0x45;
case pktSoundEffect: return 0x1a;
case pktSoundParticleEffect: return 0x23;
case pktSpawnPosition: return 0x49;
case pktTabCompletionResults: return 0x10;
case pktTeleportEntity: return 0x50;
case pktTimeUpdate: return 0x4a;
case pktTitle: return 0x4b;
case pktUnloadChunk: return 0x1f;
case pktUnlockRecipe: return 0x32;
case pktUpdateHealth: return 0x44;
case pktUpdateScore: return 0x48;
case pktUpdateSign: return GetPacketID(pktUpdateBlockEntity);
case pktUseBed: return 0x33;
case pktWindowClose: return 0x13;
case pktWindowItems: return 0x15;
case pktWindowOpen: return 0x14;
case pktWindowProperty: return 0x16;
default: return Super::GetPacketID(a_PacketType);
}
}
signed char cProtocol_1_13::GetProtocolEntityStatus(const EntityAnimation a_Animation) const
{
switch (a_Animation)
{
case EntityAnimation::DolphinShowsHappiness: return 38;
default: return Super::GetProtocolEntityStatus(a_Animation);
}
}
UInt32 cProtocol_1_13::GetProtocolMobType(eMonsterType a_MobType)
{
switch (a_MobType)
{
// Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong)
case mtInvalidType: return 27;
case mtBat: return 3;
case mtCat: return 48;
case mtBlaze: return 4;
case mtCaveSpider: return 6;
case mtChicken: return 7;
case mtCod: return 8;
case mtCow: return 9;
case mtCreeper: return 10;
case mtDonkey: return 11;
case mtDolphin: return 12;
case mtDrowned: return 14;
case mtElderGuardian: return 15;
case mtEnderDragon: return 17;
case mtEnderman: return 18;
case mtEndermite: return 19;
case mtEvoker: return 21;
case mtGhast: return 26;
case mtGiant: return 27;
case mtGuardian: return 28;
case mtHorse: return 29;
case mtHusk: return 30;
case mtIllusioner: return 31;
case mtIronGolem: return 80;
case mtLlama: return 36;
case mtMagmaCube: return 38;
case mtMule: return 46;
case mtMooshroom: return 47;
case mtOcelot: return 48;
case mtParrot: return 50;
case mtPhantom: return 90;
case mtPig: return 51;
case mtPufferfish: return 52;
case mtPolarBear: return 54;
case mtRabbit: return 56;
case mtSalmon: return 57;
case mtSheep: return 58;
case mtShulker: return 59;
case mtSilverfish: return 61;
case mtSkeleton: return 62;
case mtSkeletonHorse: return 63;
case mtSlime: return 64;
case mtSnowGolem: return 66;
case mtSpider: return 69;
case mtSquid: return 70;
case mtStray: return 71;
case mtTropicalFish: return 72;
case mtTurtle: return 73;
case mtVex: return 78;
case mtVillager: return 79;
case mtVindicator: return 81;
case mtWitch: return 82;
case mtWither: return 83;
case mtWitherSkeleton: return 84;
case mtWolf: return 86;
case mtZombie: return 87;
case mtZombiePigman: return 53;
case mtZombieHorse: return 88;
case mtZombieVillager: return 89;
default: return 0;
}
}
UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadata a_Metadata)
UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadata a_Metadata) const
{
const UInt8 Entity = 6;
const UInt8 Living = Entity + 5;
@ -621,7 +371,7 @@ UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadata a_Metadata)
UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadataType a_FieldType)
UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadataType a_FieldType) const
{
switch (a_FieldType)
{
@ -652,7 +402,7 @@ UInt8 cProtocol_1_13::GetEntityMetadataID(EntityMetadataType a_FieldType)
std::pair<short, short> cProtocol_1_13::GetItemFromProtocolID(UInt32 a_ProtocolID)
std::pair<short, short> cProtocol_1_13::GetItemFromProtocolID(UInt32 a_ProtocolID) const
{
return PaletteUpgrade::ToItem(Palette_1_13::ToItem(a_ProtocolID));
}
@ -661,7 +411,72 @@ std::pair<short, short> cProtocol_1_13::GetItemFromProtocolID(UInt32 a_ProtocolI
UInt32 cProtocol_1_13::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
UInt32 cProtocol_1_13::GetPacketID(ePacketType a_PacketType) const
{
switch (a_PacketType)
{
case pktAttachEntity: return 0x46;
case pktBlockChanges: return 0x0f;
case pktCameraSetTo: return 0x3c;
case pktChatRaw: return 0x0e;
case pktCollectEntity: return 0x4f;
case pktDestroyEntity: return 0x35;
case pktDisconnectDuringGame: return 0x1b;
case pktEditSign: return 0x2c;
case pktEntityEffect: return 0x53;
case pktEntityEquipment: return 0x42;
case pktEntityHeadLook: return 0x39;
case pktEntityLook: return 0x2a;
case pktEntityMeta: return 0x3f;
case pktEntityProperties: return 0x52;
case pktEntityRelMove: return 0x28;
case pktEntityRelMoveLook: return 0x29;
case pktEntityStatus: return 0x1c;
case pktEntityVelocity: return 0x41;
case pktExperience: return 0x43;
case pktExplosion: return 0x1e;
case pktGameMode: return 0x20;
case pktHeldItemChange: return 0x3d;
case pktInventorySlot: return 0x17;
case pktJoinGame: return 0x25;
case pktKeepAlive: return 0x21;
case pktLeashEntity: return 0x40;
case pktMapData: return 0x26;
case pktParticleEffect: return 0x24;
case pktPlayerAbilities: return 0x2e;
case pktPlayerList: return 0x30;
case pktPlayerListHeaderFooter: return 0x4e;
case pktPlayerMoveLook: return 0x32;
case pktPluginMessage: return 0x19;
case pktRemoveEntityEffect: return 0x36;
case pktRespawn: return 0x38;
case pktScoreboardObjective: return 0x45;
case pktSoundEffect: return 0x1a;
case pktSoundParticleEffect: return 0x23;
case pktSpawnPosition: return 0x49;
case pktTabCompletionResults: return 0x10;
case pktTeleportEntity: return 0x50;
case pktTimeUpdate: return 0x4a;
case pktTitle: return 0x4b;
case pktUnloadChunk: return 0x1f;
case pktUnlockRecipe: return 0x32;
case pktUpdateHealth: return 0x44;
case pktUpdateScore: return 0x48;
case pktUpdateSign: return GetPacketID(pktUpdateBlockEntity);
case pktUseBed: return 0x33;
case pktWindowClose: return 0x13;
case pktWindowItems: return 0x15;
case pktWindowOpen: return 0x14;
case pktWindowProperty: return 0x16;
default: return Super::GetPacketID(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));
}
@ -670,7 +485,20 @@ UInt32 cProtocol_1_13::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_
UInt32 cProtocol_1_13::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
signed char cProtocol_1_13::GetProtocolEntityStatus(const EntityAnimation a_Animation) const
{
switch (a_Animation)
{
case EntityAnimation::DolphinShowsHappiness: return 38;
default: return Super::GetProtocolEntityStatus(a_Animation);
}
}
UInt32 cProtocol_1_13::GetProtocolItemType(short a_ItemID, short a_ItemDamage) const
{
return Palette_1_13::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
}
@ -679,7 +507,79 @@ UInt32 cProtocol_1_13::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
UInt32 cProtocol_1_13::GetProtocolStatisticType(Statistic a_Statistic)
UInt32 cProtocol_1_13::GetProtocolMobType(eMonsterType a_MobType) const
{
switch (a_MobType)
{
// Map invalid type to Giant for easy debugging (if this ever spawns, something has gone very wrong)
case mtInvalidType: return 27;
case mtBat: return 3;
case mtCat: return 48;
case mtBlaze: return 4;
case mtCaveSpider: return 6;
case mtChicken: return 7;
case mtCod: return 8;
case mtCow: return 9;
case mtCreeper: return 10;
case mtDonkey: return 11;
case mtDolphin: return 12;
case mtDrowned: return 14;
case mtElderGuardian: return 15;
case mtEnderDragon: return 17;
case mtEnderman: return 18;
case mtEndermite: return 19;
case mtEvoker: return 21;
case mtGhast: return 26;
case mtGiant: return 27;
case mtGuardian: return 28;
case mtHorse: return 29;
case mtHusk: return 30;
case mtIllusioner: return 31;
case mtIronGolem: return 80;
case mtLlama: return 36;
case mtMagmaCube: return 38;
case mtMule: return 46;
case mtMooshroom: return 47;
case mtOcelot: return 48;
case mtParrot: return 50;
case mtPhantom: return 90;
case mtPig: return 51;
case mtPufferfish: return 52;
case mtPolarBear: return 54;
case mtRabbit: return 56;
case mtSalmon: return 57;
case mtSheep: return 58;
case mtShulker: return 59;
case mtSilverfish: return 61;
case mtSkeleton: return 62;
case mtSkeletonHorse: return 63;
case mtSlime: return 64;
case mtSnowGolem: return 66;
case mtSpider: return 69;
case mtSquid: return 70;
case mtStray: return 71;
case mtTropicalFish: return 72;
case mtTurtle: return 73;
case mtVex: return 78;
case mtVillager: return 79;
case mtVindicator: return 81;
case mtWitch: return 82;
case mtWither: return 83;
case mtWitherSkeleton: return 84;
case mtWolf: return 86;
case mtZombie: return 87;
case mtZombiePigman: return 53;
case mtZombieHorse: return 88;
case mtZombieVillager: return 89;
default: return 0;
}
}
UInt32 cProtocol_1_13::GetProtocolStatisticType(Statistic a_Statistic) const
{
return Palette_1_13::From(a_Statistic);
}
@ -688,7 +588,107 @@ UInt32 cProtocol_1_13::GetProtocolStatisticType(Statistic a_Statistic)
bool cProtocol_1_13::ReadItem(cByteBuffer & a_ByteBuffer, cItem & a_Item, size_t a_KeepRemainingBytes)
cProtocol::Version cProtocol_1_13::GetProtocolVersion() const
{
return Version::v1_13;
}
bool cProtocol_1_13::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
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);
}
void cProtocol_1_13::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
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;
// 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);
}
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,16 +1444,7 @@ void cProtocol_1_13_1::SendBossBarUpdateFlags(UInt32 a_UniqueID, bool a_DarkenSk
cProtocol::Version cProtocol_1_13_1::GetProtocolVersion()
{
return Version::v1_13_1;
}
std::pair<short, short> cProtocol_1_13_1::GetItemFromProtocolID(UInt32 a_ProtocolID)
std::pair<short, short> cProtocol_1_13_1::GetItemFromProtocolID(UInt32 a_ProtocolID) const
{
return PaletteUpgrade::ToItem(Palette_1_13_1::ToItem(a_ProtocolID));
}
@ -1462,7 +1453,7 @@ std::pair<short, short> cProtocol_1_13_1::GetItemFromProtocolID(UInt32 a_Protoco
UInt32 cProtocol_1_13_1::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta)
UInt32 cProtocol_1_13_1::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE a_Meta) const
{
return Palette_1_13_1::From(PaletteUpgrade::FromBlock(a_BlockType, a_Meta));
}
@ -1471,7 +1462,7 @@ UInt32 cProtocol_1_13_1::GetProtocolBlockType(BLOCKTYPE a_BlockType, NIBBLETYPE
UInt32 cProtocol_1_13_1::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
UInt32 cProtocol_1_13_1::GetProtocolItemType(short a_ItemID, short a_ItemDamage) const
{
return Palette_1_13_1::From(PaletteUpgrade::FromItem(a_ItemID, a_ItemDamage));
}
@ -1480,7 +1471,7 @@ UInt32 cProtocol_1_13_1::GetProtocolItemType(short a_ItemID, short a_ItemDamage)
UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic)
UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic) const
{
return Palette_1_13_1::From(a_Statistic);
}
@ -1489,10 +1480,19 @@ UInt32 cProtocol_1_13_1::GetProtocolStatisticType(Statistic a_Statistic)
cProtocol::Version cProtocol_1_13_1::GetProtocolVersion() const
{
return Version::v1_13_1;
}
////////////////////////////////////////////////////////////////////////////////
// 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

View File

@ -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;
};

View File

@ -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)

View File

@ -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 {}
};

View File

@ -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,41 +2937,92 @@ 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);
}
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);
}
}
@ -3004,9 +3030,6 @@ eBlockFace cProtocol_1_8_0::FaceIntToBlockFace(const Int32 a_BlockFace)
////////////////////////////////////////////////////////////////////////////////
// cProtocol_1_8_0::cPacketizer:
void cProtocol_1_8_0::SendPacket(cPacketizer & a_Pkt)
{
ASSERT(m_OutPacketBuffer.GetReadableSpace() == m_OutPacketBuffer.GetUsedSpace());
@ -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);
}

View File

@ -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);
/** 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) 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);
/** 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;
/** 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);
/** 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);
/** Writes the item data into a packet. */
virtual void WriteItem(cPacketizer & a_Pkt, const cItem & a_Item);
virtual void WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) const;
/** Writes the metadata for the specified entity, not including the terminating 0x7f. */
virtual void WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity);
/** Writes the mob-specific metadata for the specified mob */
virtual void WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob);
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);
} ;

View File

@ -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,16 +728,7 @@ signed char cProtocol_1_9_0::GetProtocolEntityStatus(const EntityAnimation a_Ani
cProtocol::Version cProtocol_1_9_0::GetProtocolVersion()
{
return Version::v1_9_0;
}
UInt32 cProtocol_1_9_0::GetProtocolMobType(const eMonsterType a_MobType)
UInt32 cProtocol_1_9_0::GetProtocolMobType(const eMonsterType a_MobType) const
{
switch (a_MobType)
{
@ -748,6 +741,15 @@ UInt32 cProtocol_1_9_0::GetProtocolMobType(const eMonsterType a_MobType)
cProtocol::Version cProtocol_1_9_0::GetProtocolVersion() const
{
return Version::v1_9_0;
}
bool cProtocol_1_9_0::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
{
switch (m_State)
@ -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,7 +1452,229 @@ void cProtocol_1_9_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEn
void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item)
void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) const
{
// Common metadata:
Int8 Flags = 0;
if (a_Entity.IsOnFire())
{
Flags |= 0x01;
}
if (a_Entity.IsCrouched())
{
Flags |= 0x02;
}
if (a_Entity.IsSprinting())
{
Flags |= 0x08;
}
if (a_Entity.IsRclking())
{
Flags |= 0x10;
}
if (a_Entity.IsInvisible())
{
Flags |= 0x20;
}
if (a_Entity.IsElytraFlying())
{
Flags |= 0x80;
}
a_Pkt.WriteBEUInt8(0); // Index 0
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
a_Pkt.WriteBEInt8(Flags);
switch (a_Entity.GetEntityType())
{
case cEntity::etPlayer:
{
auto & Player = static_cast<const cPlayer &>(a_Entity);
// TODO Set player custom name to their name.
// Then it's possible to move the custom name of mobs to the entities
// and to remove the "special" player custom name.
a_Pkt.WriteBEUInt8(2); // Index 2: Custom name
a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
a_Pkt.WriteString(Player.GetName());
a_Pkt.WriteBEUInt8(6); // Index 6: Health
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
a_Pkt.WriteBEUInt8(12);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
a_Pkt.WriteBEUInt8(13);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEUInt8(Player.IsLeftHanded() ? 0 : 1);
break;
}
case cEntity::etPickup:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Item
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, static_cast<const cPickup &>(a_Entity).GetItem());
break;
}
case cEntity::etMinecart:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Shaking power
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
// The following expression makes Minecarts shake more with less health or higher damage taken
auto & Minecart = static_cast<const cMinecart &>(a_Entity);
auto maxHealth = a_Entity.GetMaxHealth();
auto curHealth = a_Entity.GetHealth();
a_Pkt.WriteVarInt32(static_cast<UInt32>((maxHealth - curHealth) * Minecart.LastDamage() * 4));
a_Pkt.WriteBEUInt8(6); // Index 6: Shaking direction (doesn't seem to effect anything)
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(1);
a_Pkt.WriteBEUInt8(7); // Index 7: Shake multiplier / damage taken
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
a_Pkt.WriteBEFloat(static_cast<float>(Minecart.LastDamage() + 10));
if (Minecart.GetPayload() == cMinecart::mpNone)
{
auto & RideableMinecart = static_cast<const cRideableMinecart &>(Minecart);
const cItem & MinecartContent = RideableMinecart.GetContent();
if (!MinecartContent.IsEmpty())
{
a_Pkt.WriteBEUInt8(8); // Index 8: Block ID and damage
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
int Content = MinecartContent.m_ItemType;
Content |= MinecartContent.m_ItemDamage << 8;
a_Pkt.WriteVarInt32(static_cast<UInt32>(Content));
a_Pkt.WriteBEUInt8(9); // Index 9: Block ID and damage
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(RideableMinecart.GetBlockHeight()));
a_Pkt.WriteBEUInt8(10); // Index 10: Show block
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(true);
}
}
else if (Minecart.GetPayload() == cMinecart::mpFurnace)
{
a_Pkt.WriteBEUInt8(11); // Index 11: Is powered
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(static_cast<const cMinecartWithFurnace &>(Minecart).IsFueled());
}
break;
} // case etMinecart
case cEntity::etProjectile:
{
auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity);
switch (Projectile.GetProjectileKind())
{
case cProjectileEntity::pkArrow:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Is critical
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEInt8(static_cast<const cArrowEntity &>(Projectile).IsCritical() ? 1 : 0);
break;
}
case cProjectileEntity::pkFirework:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Firework item used for this firework
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, static_cast<const cFireworkEntity &>(Projectile).GetItem());
break;
}
case cProjectileEntity::pkSplashPotion:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Potion item which was thrown
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, static_cast<const cSplashPotionEntity &>(Projectile).GetItem());
}
default:
{
break;
}
}
break;
} // case etProjectile
case cEntity::etMonster:
{
WriteMobMetadata(a_Pkt, static_cast<const cMonster &>(a_Entity));
break;
}
case cEntity::etBoat:
{
auto & Boat = static_cast<const cBoat &>(a_Entity);
a_Pkt.WriteBEInt8(5); // Index 6: Time since last hit
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetLastDamage()));
a_Pkt.WriteBEInt8(6); // Index 7: Forward direction
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetForwardDirection()));
a_Pkt.WriteBEInt8(7); // Index 8: Damage taken
a_Pkt.WriteBEInt8(METADATA_TYPE_FLOAT);
a_Pkt.WriteBEFloat(Boat.GetDamageTaken());
a_Pkt.WriteBEInt8(8); // Index 9: Type
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetMaterial()));
a_Pkt.WriteBEInt8(9); // Index 10: Right paddle turning
a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Boat.IsRightPaddleUsed());
a_Pkt.WriteBEInt8(10); // Index 11: Left paddle turning
a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Boat.IsLeftPaddleUsed());
break;
} // case etBoat
case cEntity::etItemFrame:
{
auto & Frame = static_cast<const cItemFrame &>(a_Entity);
a_Pkt.WriteBEUInt8(5); // Index 5: Item
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, Frame.GetItem());
a_Pkt.WriteBEUInt8(6); // Index 6: Rotation
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(Frame.GetItemRotation());
break;
} // case etItemFrame
case cEntity::etEnderCrystal:
{
const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
a_Pkt.WriteBEUInt8(5);
a_Pkt.WriteBEUInt8(METADATA_TYPE_OPTIONAL_POSITION);
a_Pkt.WriteBool(EnderCrystal.DisplaysBeam());
if (EnderCrystal.DisplaysBeam())
{
a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
}
a_Pkt.WriteBEUInt8(6);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
break;
} // case etEnderCrystal
default:
{
break;
}
}
}
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
@ -1637,229 +1844,7 @@ void cProtocol_1_9_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item)
void cProtocol_1_9_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity)
{
// Common metadata:
Int8 Flags = 0;
if (a_Entity.IsOnFire())
{
Flags |= 0x01;
}
if (a_Entity.IsCrouched())
{
Flags |= 0x02;
}
if (a_Entity.IsSprinting())
{
Flags |= 0x08;
}
if (a_Entity.IsRclking())
{
Flags |= 0x10;
}
if (a_Entity.IsInvisible())
{
Flags |= 0x20;
}
if (a_Entity.IsElytraFlying())
{
Flags |= 0x80;
}
a_Pkt.WriteBEUInt8(0); // Index 0
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE); // Type
a_Pkt.WriteBEInt8(Flags);
switch (a_Entity.GetEntityType())
{
case cEntity::etPlayer:
{
auto & Player = static_cast<const cPlayer &>(a_Entity);
// TODO Set player custom name to their name.
// Then it's possible to move the custom name of mobs to the entities
// and to remove the "special" player custom name.
a_Pkt.WriteBEUInt8(2); // Index 2: Custom name
a_Pkt.WriteBEUInt8(METADATA_TYPE_STRING);
a_Pkt.WriteString(Player.GetName());
a_Pkt.WriteBEUInt8(6); // Index 6: Health
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
a_Pkt.WriteBEFloat(static_cast<float>(Player.GetHealth()));
a_Pkt.WriteBEUInt8(12);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetSkinParts()));
a_Pkt.WriteBEUInt8(13);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEUInt8(static_cast<UInt8>(Player.GetMainHand()));
break;
}
case cEntity::etPickup:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Item
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, static_cast<const cPickup &>(a_Entity).GetItem());
break;
}
case cEntity::etMinecart:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Shaking power
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
// The following expression makes Minecarts shake more with less health or higher damage taken
auto & Minecart = static_cast<const cMinecart &>(a_Entity);
auto maxHealth = a_Entity.GetMaxHealth();
auto curHealth = a_Entity.GetHealth();
a_Pkt.WriteVarInt32(static_cast<UInt32>((maxHealth - curHealth) * Minecart.LastDamage() * 4));
a_Pkt.WriteBEUInt8(6); // Index 6: Shaking direction (doesn't seem to effect anything)
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(1);
a_Pkt.WriteBEUInt8(7); // Index 7: Shake multiplier / damage taken
a_Pkt.WriteBEUInt8(METADATA_TYPE_FLOAT);
a_Pkt.WriteBEFloat(static_cast<float>(Minecart.LastDamage() + 10));
if (Minecart.GetPayload() == cMinecart::mpNone)
{
auto & RideableMinecart = static_cast<const cRideableMinecart &>(Minecart);
const cItem & MinecartContent = RideableMinecart.GetContent();
if (!MinecartContent.IsEmpty())
{
a_Pkt.WriteBEUInt8(8); // Index 8: Block ID and damage
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
int Content = MinecartContent.m_ItemType;
Content |= MinecartContent.m_ItemDamage << 8;
a_Pkt.WriteVarInt32(static_cast<UInt32>(Content));
a_Pkt.WriteBEUInt8(9); // Index 9: Block ID and damage
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(RideableMinecart.GetBlockHeight()));
a_Pkt.WriteBEUInt8(10); // Index 10: Show block
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(true);
}
}
else if (Minecart.GetPayload() == cMinecart::mpFurnace)
{
a_Pkt.WriteBEUInt8(11); // Index 11: Is powered
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(static_cast<const cMinecartWithFurnace &>(Minecart).IsFueled());
}
break;
} // case etMinecart
case cEntity::etProjectile:
{
auto & Projectile = static_cast<const cProjectileEntity &>(a_Entity);
switch (Projectile.GetProjectileKind())
{
case cProjectileEntity::pkArrow:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Is critical
a_Pkt.WriteBEUInt8(METADATA_TYPE_BYTE);
a_Pkt.WriteBEInt8(static_cast<const cArrowEntity &>(Projectile).IsCritical() ? 1 : 0);
break;
}
case cProjectileEntity::pkFirework:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Firework item used for this firework
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, static_cast<const cFireworkEntity &>(Projectile).GetItem());
break;
}
case cProjectileEntity::pkSplashPotion:
{
a_Pkt.WriteBEUInt8(5); // Index 5: Potion item which was thrown
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, static_cast<const cSplashPotionEntity &>(Projectile).GetItem());
}
default:
{
break;
}
}
break;
} // case etProjectile
case cEntity::etMonster:
{
WriteMobMetadata(a_Pkt, static_cast<const cMonster &>(a_Entity));
break;
}
case cEntity::etBoat:
{
auto & Boat = static_cast<const cBoat &>(a_Entity);
a_Pkt.WriteBEInt8(5); // Index 6: Time since last hit
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetLastDamage()));
a_Pkt.WriteBEInt8(6); // Index 7: Forward direction
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetForwardDirection()));
a_Pkt.WriteBEInt8(7); // Index 8: Damage taken
a_Pkt.WriteBEInt8(METADATA_TYPE_FLOAT);
a_Pkt.WriteBEFloat(Boat.GetDamageTaken());
a_Pkt.WriteBEInt8(8); // Index 9: Type
a_Pkt.WriteBEInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(static_cast<UInt32>(Boat.GetMaterial()));
a_Pkt.WriteBEInt8(9); // Index 10: Right paddle turning
a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Boat.IsRightPaddleUsed());
a_Pkt.WriteBEInt8(10); // Index 11: Left paddle turning
a_Pkt.WriteBEInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(Boat.IsLeftPaddleUsed());
break;
} // case etBoat
case cEntity::etItemFrame:
{
auto & Frame = static_cast<const cItemFrame &>(a_Entity);
a_Pkt.WriteBEUInt8(5); // Index 5: Item
a_Pkt.WriteBEUInt8(METADATA_TYPE_ITEM);
WriteItem(a_Pkt, Frame.GetItem());
a_Pkt.WriteBEUInt8(6); // Index 6: Rotation
a_Pkt.WriteBEUInt8(METADATA_TYPE_VARINT);
a_Pkt.WriteVarInt32(Frame.GetItemRotation());
break;
} // case etItemFrame
case cEntity::etEnderCrystal:
{
const auto & EnderCrystal = static_cast<const cEnderCrystal &>(a_Entity);
a_Pkt.WriteBEUInt8(5);
a_Pkt.WriteBEUInt8(METADATA_TYPE_OPTIONAL_POSITION);
a_Pkt.WriteBool(EnderCrystal.DisplaysBeam());
if (EnderCrystal.DisplaysBeam())
{
a_Pkt.WriteXYZPosition64(EnderCrystal.GetBeamTarget());
}
a_Pkt.WriteBEUInt8(6);
a_Pkt.WriteBEUInt8(METADATA_TYPE_BOOL);
a_Pkt.WriteBool(EnderCrystal.ShowsBottom());
break;
} // case etEnderCrystal
default:
{
break;
}
}
}
void cProtocol_1_9_0::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
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;
}

View File

@ -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;
/** Whether the current teleport ID has been confirmed by the client. */
UInt32 m_OutstandingTeleportId;
/** Get the packet ID for a given packet. */
virtual UInt32 GetPacketID(ePacketType a_Packet) override;
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;
} ;