From c8631d9a9b924c4c4d030bac3ed4e4a869ec2fd8 Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 9 May 2014 23:10:02 +0200 Subject: Add DIG_STATUS_CANCELLED packet and add item resend, when a block can't place/break. --- src/ClientHandle.cpp | 61 +++++++++++++++++++++++++++++++++++++--------------- src/ClientHandle.h | 3 +++ src/Inventory.cpp | 10 +++++++++ src/Inventory.h | 41 +++++++++++++++++++---------------- 4 files changed, 79 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 94f031ed6..1535b0482 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -878,6 +878,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB case DIG_STATUS_CANCELLED: { // Block breaking cancelled by player + HandleBlockDigCancel(); return; } @@ -916,7 +917,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc // It is a duplicate packet, drop it right away return; } - + if ( m_Player->IsGameModeCreative() && ItemCategory::IsSword(m_Player->GetInventory().GetEquippedItem().m_ItemType) @@ -925,14 +926,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc // Players can't destroy blocks with a Sword in the hand. return; } - - if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta)) - { - // A plugin doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows: - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - return; - } - + // Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig/aim bug in the client: m_HasStartedDigging = true; m_LastDigBlockX = a_BlockX; @@ -1004,16 +998,16 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo return; } - m_HasStartedDigging = false; - if (m_BlockDigAnimStage != -1) - { - // End dig animation - m_BlockDigAnimStage = -1; - // It seems that 10 ends block animation - m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_BlockDigAnimX, m_BlockDigAnimY, m_BlockDigAnimZ, 10, this); - } + HandleBlockDigCancel(); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); + + if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta)) + { + // A plugin doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows: + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + return; + } if (a_OldBlock == E_BLOCK_AIR) { @@ -1036,6 +1030,36 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo +void cClientHandle::HandleBlockDigCancel() +{ + if ( + !m_HasStartedDigging || // Hasn't received the DIG_STARTED packet + (m_LastDigBlockX == -1) || + (m_LastDigBlockY == -1) || + (m_LastDigBlockZ == -1) + ) + { + return; + } + + m_HasStartedDigging = false; + if (m_BlockDigAnimStage != -1) + { + // End dig animation + m_BlockDigAnimStage = -1; + // It seems that 10 ends block animation + m_Player->GetWorld()->BroadcastBlockBreakAnimation(m_UniqueID, m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ, 10, this); + } + + m_BlockDigAnimX = -1; + m_BlockDigAnimY = -1; + m_BlockDigAnimZ = -1; +} + + + + + void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, const cItem & a_HeldItem) { LOGD("HandleRightClick: {%d, %d, %d}, face %d, HeldItem: %s", @@ -1058,6 +1082,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); //2 block high things + m_Player->GetInventory().SendEquippedSlot(); } return; } @@ -1246,6 +1271,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e { // Handler refused the placement, send that information back to the client: World->SendBlockTo(a_BlockX, a_BlockY, a_BlockY, m_Player); + m_Player->GetInventory().SendEquippedSlot(); return; } @@ -1255,6 +1281,7 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e { // A plugin doesn't agree with placing the block, revert the block on the client: World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + m_Player->GetInventory().SendEquippedSlot(); return; } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 4dc6ab074..03a716657 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -374,6 +374,9 @@ private: /** Handles the DIG_FINISHED dig packet: */ void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta); + /** Handles the DIG_CANCELLED dig packet: */ + void HandleBlockDigCancel(); + /** Converts the protocol-formatted channel list (NUL-separated) into a proper string vector. */ AStringVector BreakApartPluginChannels(const AString & a_PluginChannels); diff --git a/src/Inventory.cpp b/src/Inventory.cpp index a365e4ed4..bce882c88 100644 --- a/src/Inventory.cpp +++ b/src/Inventory.cpp @@ -243,6 +243,16 @@ void cInventory::SetHotbarSlot(int a_HotBarSlotNum, const cItem & a_Item) +void cInventory::SendEquippedSlot() +{ + int EquippedSlotNum = cInventory::invArmorCount + cInventory::invInventoryCount + GetEquippedSlotNum(); + SendSlot(EquippedSlotNum); +} + + + + + const cItem & cInventory::GetSlot(int a_SlotNum) const { if ((a_SlotNum < 0) || (a_SlotNum >= invNumSlots)) diff --git a/src/Inventory.h b/src/Inventory.h index 1ad7c4776..39aef1538 100644 --- a/src/Inventory.h +++ b/src/Inventory.h @@ -56,13 +56,13 @@ public: // tolua_begin - /// Removes all items from the entire inventory + /** Removes all items from the entire inventory */ void Clear(void); - /// Returns number of items out of a_ItemStack that can fit in the storage + /** Returns number of items out of a_ItemStack that can fit in the storage */ int HowManyCanFit(const cItem & a_ItemStack, bool a_ConsiderEmptySlots); - /// Returns how many items of the specified type would fit into the slot range specified + /** Returns how many items of the specified type would fit into the slot range specified */ int HowManyCanFit(const cItem & a_ItemStack, int a_BeginSlotNum, int a_EndSlotNum, bool a_ConsiderEmptySlots); /** Adds as many items out of a_ItemStack as can fit. @@ -86,33 +86,36 @@ public: */ int AddItems(cItems & a_ItemStackList, bool a_AllowNewStacks, bool a_tryToFillEquippedFirst); - /// Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed + /** Removes one item out of the currently equipped item stack, returns true if successful, false if empty-handed */ bool RemoveOneEquippedItem(void); - /// Returns the number of items of type a_Item that are stored + /** Returns the number of items of type a_Item that are stored */ int HowManyItems(const cItem & a_Item); - /// Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack + /** Returns true if there are at least as many items of type a_ItemStack as in a_ItemStack */ bool HasItems(const cItem & a_ItemStack); + + /** Sends the equipped item slot to the client */ + void SendEquippedSlot(); - /// Returns the cItemGrid object representing the armor slots + /** Returns the cItemGrid object representing the armor slots */ cItemGrid & GetArmorGrid(void) { return m_ArmorSlots; } - /// Returns the cItemGrid object representing the main inventory slots + /** Returns the cItemGrid object representing the main inventory slots */ cItemGrid & GetInventoryGrid(void) { return m_InventorySlots; } - /// Returns the cItemGrid object representing the hotbar slots + /** Returns the cItemGrid object representing the hotbar slots */ cItemGrid & GetHotbarGrid(void) { return m_HotbarSlots; } - /// Returns the player associated with this inventory + /** Returns the player associated with this inventory */ cPlayer & GetOwner(void) { return m_Owner; } - /// Copies the non-empty slots into a_ItemStacks; preserves the original a_Items contents + /** Copies the non-empty slots into a_ItemStacks; preserves the original a_Items contents */ void CopyToItems(cItems & a_Items); // tolua_end - /// Returns the player associated with this inventory (const version) + /** Returns the player associated with this inventory (const version) */ const cPlayer & GetOwner(void) const { return m_Owner; } // tolua_begin @@ -136,10 +139,10 @@ public: */ int ChangeSlotCount(int a_SlotNum, int a_AddToCount); - /// Adds the specified damage to the specified item; deletes the item and returns true if the item broke. + /** Adds the specified damage to the specified item; deletes the item and returns true if the item broke. */ bool DamageItem(int a_SlotNum, short a_Amount); - /// Adds the specified damage to the currently held item; deletes the item and returns true if the item broke. + /** Adds the specified damage to the currently held item; deletes the item and returns true if the item broke. */ bool DamageEquippedItem(short a_Amount = 1); const cItem & GetEquippedHelmet (void) const { return m_ArmorSlots.GetSlot(0); } @@ -149,13 +152,13 @@ public: // tolua_end - /// Sends the slot contents to the owner + /** Sends the slot contents to the owner */ void SendSlot(int a_SlotNum); - /// Update items (e.g. Maps) + /** Update items (e.g. Maps) */ void UpdateItems(void); - /// Converts an armor slot number into the ID for the EntityEquipment packet + /** Converts an armor slot number into the ID for the EntityEquipment packet */ static int ArmorSlotNumToEntityEquipmentID(short a_ArmorSlotNum); void SaveToJson(Json::Value & a_Value); @@ -172,10 +175,10 @@ protected: cPlayer & m_Owner; - /// Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum + /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum */ const cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum) const; - /// Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum + /** Returns the ItemGrid and the (grid-local) slot number for a (global) slot number; return NULL for invalid SlotNum */ cItemGrid * GetGridForSlotNum(int a_SlotNum, int & a_GridSlotNum); // cItemGrid::cListener override: -- cgit v1.2.3 From eb0f713b6a5a7107a97284d1728858b4b2882c3d Mon Sep 17 00:00:00 2001 From: Howaner Date: Fri, 9 May 2014 23:43:00 +0200 Subject: Add block place/break distance check. --- src/ClientHandle.cpp | 21 +++++++++++++++++++++ src/Defines.h | 10 ++++++++++ 2 files changed, 31 insertions(+) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 1535b0482..d1962506d 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -1016,6 +1016,17 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo } cWorld * World = m_Player->GetWorld(); + + if ( + (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || + (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || + (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) + ) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + return; + } + ItemHandler->OnBlockDestroyed(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ); // The ItemHandler is also responsible for spawning the pickups cChunkInterface ChunkInterface(World->GetChunkMap()); @@ -1191,6 +1202,16 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e // The block is being placed outside the world, ignore this packet altogether (#128) return; } + + if ( + (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || + (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || + (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) + ) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + return; + } World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta); diff --git a/src/Defines.h b/src/Defines.h index 9fa3b3a8e..b0b209934 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -3,6 +3,7 @@ #include "ChatColor.h" #include +#include @@ -528,6 +529,15 @@ inline float GetSpecialSignf( float a_Val ) +template inline int Diff(T a_Val1, T a_Val2) +{ + return std::abs(a_Val1 - a_Val2); +} + + + + + // tolua_begin enum eMessageType -- cgit v1.2.3 From 5c9f89526aeca7b32014cd78e323f74baddf1e36 Mon Sep 17 00:00:00 2001 From: Howaner Date: Sun, 11 May 2014 11:56:15 +0200 Subject: Rename HandleBlockDigCancel to FinishDigAnimtion. --- src/ClientHandle.cpp | 6 +++--- src/ClientHandle.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index d1962506d..9238418a4 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -878,7 +878,7 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB case DIG_STATUS_CANCELLED: { // Block breaking cancelled by player - HandleBlockDigCancel(); + FinishDigAnimation(); return; } @@ -998,7 +998,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo return; } - HandleBlockDigCancel(); + FinishDigAnimation(); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); @@ -1041,7 +1041,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo -void cClientHandle::HandleBlockDigCancel() +void cClientHandle::FinishDigAnimation() { if ( !m_HasStartedDigging || // Hasn't received the DIG_STARTED packet diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 03a716657..85d348eee 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -374,8 +374,8 @@ private: /** Handles the DIG_FINISHED dig packet: */ void HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, BLOCKTYPE a_OldBlock, NIBBLETYPE a_OldMeta); - /** Handles the DIG_CANCELLED dig packet: */ - void HandleBlockDigCancel(); + /** The clients will receive a finished dig animation */ + void FinishDigAnimation(); /** Converts the protocol-formatted channel list (NUL-separated) into a proper string vector. */ AStringVector BreakApartPluginChannels(const AString & a_PluginChannels); -- cgit v1.2.3 From 6c5ff597bbbb3abd2985eda6bf35ea2d98cf69a4 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 15 May 2014 19:58:48 +0200 Subject: Move radius check. --- src/ClientHandle.cpp | 65 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 9238418a4..cf9d0bfeb 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -815,6 +815,16 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB return; } + if ( + (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || + (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || + (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) + ) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + return; + } + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (PlgMgr->CallHookPlayerLeftClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_Status)) { @@ -927,6 +937,16 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc return; } + if ( + (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || + (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || + (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) + ) + { + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, this); + return; + } + // Set the last digging coords to the block being dug, so that they can be checked in DIG_FINISHED to avoid dig/aim bug in the client: m_HasStartedDigging = true; m_LastDigBlockX = a_BlockX; @@ -1000,6 +1020,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo FinishDigAnimation(); + cWorld * World = m_Player->GetWorld(); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); if (cRoot::Get()->GetPluginManager()->CallHookPlayerBreakingBlock(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_OldBlock, a_OldMeta)) @@ -1008,24 +1029,12 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); return; } - + if (a_OldBlock == E_BLOCK_AIR) { LOGD("Dug air - what the function?"); return; } - - cWorld * World = m_Player->GetWorld(); - - if ( - (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || - (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || - (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) - ) - { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - return; - } ItemHandler->OnBlockDestroyed(World, m_Player, m_Player->GetEquippedItem(), a_BlockX, a_BlockY, a_BlockZ); // The ItemHandler is also responsible for spawning the pickups @@ -1078,7 +1087,23 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e ); cWorld * World = m_Player->GetWorld(); - + + if ( + (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || + (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || + (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) + ) + { + if (a_BlockFace != BLOCK_FACE_NONE) + { + AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); + World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things + m_Player->GetInventory().SendEquippedSlot(); + } + return; + } + cPluginManager * PlgMgr = cRoot::Get()->GetPluginManager(); if (PlgMgr->CallHookPlayerRightClick(*m_Player, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ)) { @@ -1092,7 +1117,7 @@ void cClientHandle::HandleRightClick(int a_BlockX, int a_BlockY, int a_BlockZ, e { AddFaceDirection(a_BlockX, a_BlockY, a_BlockZ, a_BlockFace); World->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); //2 block high things + World->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // 2 block high things m_Player->GetInventory().SendEquippedSlot(); } return; @@ -1202,16 +1227,6 @@ void cClientHandle::HandlePlaceBlock(int a_BlockX, int a_BlockY, int a_BlockZ, e // The block is being placed outside the world, ignore this packet altogether (#128) return; } - - if ( - (Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || - (Diff(m_Player->GetPosY(), (double)a_BlockY) > 6) || - (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) - ) - { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); - return; - } World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, ClickedBlock, ClickedBlockMeta); -- cgit v1.2.3 From 28a9c16db2212d57cca823a2b122530fdb70f210 Mon Sep 17 00:00:00 2001 From: Howaner Date: Thu, 15 May 2014 19:59:52 +0200 Subject: Fix compile error. --- src/ClientHandle.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index cf9d0bfeb..0c897374b 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -943,7 +943,7 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc (Diff(m_Player->GetPosZ(), (double)a_BlockZ) > 6) ) { - m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, this); + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); return; } -- cgit v1.2.3