diff options
author | SmallJoker <SmallJoker@users.noreply.github.com> | 2018-10-10 20:48:58 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-10 20:48:58 +0200 |
commit | 0a5e77132ae8c495c50cfc58bbe4ce1bfcd377e3 (patch) | |
tree | d60c7186893663e2556d6d9efc46c14fd4520b0f /src/server.cpp | |
parent | d6f2a1c4b8ab13cee92e2041b3410fe3548e88e6 (diff) | |
download | hax-minetest-server-0a5e77132ae8c495c50cfc58bbe4ce1bfcd377e3.tar.gz hax-minetest-server-0a5e77132ae8c495c50cfc58bbe4ce1bfcd377e3.zip |
Add core.remove_detached_inventory (#7684)
Breaks backwards compatibility for good
Bump protocol version
Diffstat (limited to 'src/server.cpp')
-rw-r--r-- | src/server.cpp | 75 |
1 files changed, 54 insertions, 21 deletions
diff --git a/src/server.cpp b/src/server.cpp index 41248c869..678ee387b 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2478,33 +2478,41 @@ void Server::sendRequestedMedia(session_t peer_id, void Server::sendDetachedInventory(const std::string &name, session_t peer_id) { - if(m_detached_inventories.count(name) == 0) { - errorstream<<FUNCTION_NAME<<": \""<<name<<"\" not found"<<std::endl; - return; - } - Inventory *inv = m_detached_inventories[name]; - std::ostringstream os(std::ios_base::binary); + const auto &inv_it = m_detached_inventories.find(name); + const auto &player_it = m_detached_inventories_player.find(name); - os << serializeString(name); - inv->serialize(os); + if (player_it == m_detached_inventories_player.end() || + player_it->second.empty()) { + // OK. Send to everyone + } else { + RemotePlayer *p = m_env->getPlayer(player_it->second.c_str()); + if (!p) + return; // Player is offline - // Make data buffer - std::string s = os.str(); + if (peer_id != PEER_ID_INEXISTENT && peer_id != p->getPeerId()) + return; // Caller requested send to a different player, so don't send. + + peer_id = p->getPeerId(); + } NetworkPacket pkt(TOCLIENT_DETACHED_INVENTORY, 0, peer_id); - pkt.putRawString(s.c_str(), s.size()); + pkt << name; - const std::string &check = m_detached_inventories_player[name]; - if (peer_id == PEER_ID_INEXISTENT) { - if (check.empty()) - return m_clients.sendToAll(&pkt); - RemotePlayer *p = m_env->getPlayer(check.c_str()); - if (p) - m_clients.send(p->getPeerId(), 0, &pkt, true); + if (inv_it == m_detached_inventories.end()) { + pkt << false; // Remove inventory } else { - if (check.empty() || getPlayerName(peer_id) == check) - Send(&pkt); + pkt << true; // Update inventory + + // Serialization & NetworkPacket isn't a love story + std::ostringstream os(std::ios_base::binary); + inv_it->second->serialize(os); + pkt << os.str(); } + + if (peer_id == PEER_ID_INEXISTENT) + m_clients.sendToAll(&pkt); + else + Send(&pkt); } void Server::sendDetachedInventories(session_t peer_id) @@ -2665,9 +2673,10 @@ void Server::DeleteClient(session_t peer_id, ClientDeletionReason reason) playersao->clearParentAttachment(); // inform connected clients + const std::string &player_name = player->getName(); NetworkPacket notice(TOCLIENT_UPDATE_PLAYER_LIST, 0, PEER_ID_INEXISTENT); // (u16) 1 + std::string represents a vector serialization representation - notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << std::string(playersao->getPlayer()->getName()); + notice << (u8) PLAYER_LIST_REMOVE << (u16) 1 << player_name; m_clients.sendToAll(¬ice); // run scripts m_script->on_leaveplayer(playersao, reason == CDR_TIMEOUT); @@ -3265,6 +3274,30 @@ Inventory* Server::createDetachedInventory(const std::string &name, const std::s return inv; } +bool Server::removeDetachedInventory(const std::string &name) +{ + const auto &inv_it = m_detached_inventories.find(name); + if (inv_it == m_detached_inventories.end()) + return false; + + delete inv_it->second; + m_detached_inventories.erase(inv_it); + + const auto &player_it = m_detached_inventories_player.find(name); + if (player_it != m_detached_inventories_player.end()) { + RemotePlayer *player = m_env->getPlayer(player_it->second.c_str()); + + if (player && player->getPeerId() != PEER_ID_INEXISTENT) + sendDetachedInventory(name, player->getPeerId()); + + m_detached_inventories_player.erase(player_it); + } else { + // Notify all players about the change + sendDetachedInventory(name, PEER_ID_INEXISTENT); + } + return true; +} + // actions: time-reversed list // Return value: success/failure bool Server::rollbackRevertActions(const std::list<RollbackAction> &actions, |