diff options
author | sfan5 <sfan5@live.de> | 2021-10-25 20:30:27 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-25 20:30:27 +0200 |
commit | 660e63dbae5901f8178b39ab40e6f770b8d7a215 (patch) | |
tree | 6b17279e1583716684b9d97bb8d56c8e7b8655f4 /src/network | |
parent | d4b89eb106220f43838b039b13a0e356d366c259 (diff) | |
download | minetest-660e63dbae5901f8178b39ab40e6f770b8d7a215.tar.gz minetest-660e63dbae5901f8178b39ab40e6f770b8d7a215.tar.bz2 minetest-660e63dbae5901f8178b39ab40e6f770b8d7a215.zip |
Fix item duplication if player dies during interact callback (alternative) (#11662)
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/serverpackethandler.cpp | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index dc7be0e23..d4bef3ca2 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -921,6 +921,13 @@ bool Server::checkInteractDistance(RemotePlayer *player, const f32 d, const std: return true; } +// Tiny helper to retrieve the selected item into an Optional +static inline void getWieldedItem(const PlayerSAO *playersao, Optional<ItemStack> &ret) +{ + ret = ItemStack(); + playersao->getWieldedItem(&(*ret)); +} + void Server::handleCommand_Interact(NetworkPacket *pkt) { /* @@ -1228,14 +1235,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) // Place block or right-click object case INTERACT_PLACE: { - ItemStack selected_item; - playersao->getWieldedItem(&selected_item, nullptr); + Optional<ItemStack> selected_item; + getWieldedItem(playersao, selected_item); // Reset build time counter if (pointed.type == POINTEDTHING_NODE && - selected_item.getDefinition(m_itemdef).type == ITEM_NODE) + selected_item->getDefinition(m_itemdef).type == ITEM_NODE) getClient(peer_id)->m_time_from_building = 0.0; + const bool had_prediction = !selected_item->getDefinition(m_itemdef). + node_placement_prediction.empty(); + if (pointed.type == POINTEDTHING_OBJECT) { // Right click object @@ -1248,11 +1258,9 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) << pointed_object->getDescription() << std::endl; // Do stuff - if (m_script->item_OnSecondaryUse( - selected_item, playersao, pointed)) { - if (playersao->setWieldedItem(selected_item)) { + if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) { + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) SendInventory(playersao, true); - } } pointed_object->rightClick(playersao); @@ -1260,7 +1268,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) // Placement was handled in lua // Apply returned ItemStack - if (playersao->setWieldedItem(selected_item)) + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) SendInventory(playersao, true); } @@ -1272,8 +1280,7 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) RemoteClient *client = getClient(peer_id); v3s16 blockpos = getNodeBlockPos(pointed.node_abovesurface); v3s16 blockpos2 = getNodeBlockPos(pointed.node_undersurface); - if (!selected_item.getDefinition(m_itemdef - ).node_placement_prediction.empty()) { + if (had_prediction) { client->SetBlockNotSent(blockpos); if (blockpos2 != blockpos) client->SetBlockNotSent(blockpos2); @@ -1287,15 +1294,15 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) } // action == INTERACT_PLACE case INTERACT_USE: { - ItemStack selected_item; - playersao->getWieldedItem(&selected_item, nullptr); + Optional<ItemStack> selected_item; + getWieldedItem(playersao, selected_item); - actionstream << player->getName() << " uses " << selected_item.name + actionstream << player->getName() << " uses " << selected_item->name << ", pointing at " << pointed.dump() << std::endl; if (m_script->item_OnUse(selected_item, playersao, pointed)) { // Apply returned ItemStack - if (playersao->setWieldedItem(selected_item)) + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) SendInventory(playersao, true); } @@ -1304,16 +1311,17 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) // Rightclick air case INTERACT_ACTIVATE: { - ItemStack selected_item; - playersao->getWieldedItem(&selected_item, nullptr); + Optional<ItemStack> selected_item; + getWieldedItem(playersao, selected_item); actionstream << player->getName() << " activates " - << selected_item.name << std::endl; + << selected_item->name << std::endl; pointed.type = POINTEDTHING_NOTHING; // can only ever be NOTHING if (m_script->item_OnSecondaryUse(selected_item, playersao, pointed)) { - if (playersao->setWieldedItem(selected_item)) + // Apply returned ItemStack + if (selected_item.has_value() && playersao->setWieldedItem(*selected_item)) SendInventory(playersao, true); } |