More cProtocol cleanup
* Alpha sort functions * Simplify hand handling * Fix left handed mode client-side display
This commit is contained in:
parent
63ded9f6b4
commit
a999c5d845
@ -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.*",
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -211,26 +211,6 @@ enum eMobHeadRotation
|
||||
|
||||
|
||||
|
||||
enum eHand
|
||||
{
|
||||
hMain = 0,
|
||||
hOff = 1,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum eMainHand
|
||||
{
|
||||
mhLeft = 0,
|
||||
mhRight = 1,
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
enum eSkinPart
|
||||
{
|
||||
spCape = 0x01,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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)
|
||||
|
@ -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 {}
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
} ;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
} ;
|
||||
|
Loading…
x
Reference in New Issue
Block a user