diff --git a/src/server.cpp b/src/server.cpp index c775f5d07..013c039c3 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -891,7 +891,7 @@ void Server::AsyncRunStep(bool initial_step) // We'll log the amount of each Profiler prof; - std::list node_meta_updates; + std::unordered_set node_meta_updates; while (!m_unsent_map_edit_queue.empty()) { MapEditEvent* event = m_unsent_map_edit_queue.front(); @@ -918,9 +918,7 @@ void Server::AsyncRunStep(bool initial_step) case MEET_BLOCK_NODE_METADATA_CHANGED: { prof.add("MEET_BLOCK_NODE_METADATA_CHANGED", 1); if (!event->is_private_change) { - // Don't send the change yet. Collect them to eliminate dupes. - node_meta_updates.remove(event->p); - node_meta_updates.push_back(event->p); + node_meta_updates.emplace(event->p); } if (MapBlock *block = m_env->getMap().getBlockNoCreateNoEx( @@ -973,7 +971,7 @@ void Server::AsyncRunStep(bool initial_step) } // Send all metadata updates - if (node_meta_updates.size()) + if (!node_meta_updates.empty()) sendMetadataChanged(node_meta_updates); } @@ -2290,12 +2288,12 @@ void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set *far_player } } -void Server::sendMetadataChanged(const std::list &meta_updates, float far_d_nodes) +void Server::sendMetadataChanged(const std::unordered_set &positions, float far_d_nodes) { - float maxd = far_d_nodes * BS; NodeMetadataList meta_updates_list(false); - std::vector clients = m_clients.getClientIDs(); + std::ostringstream os(std::ios::binary); + std::vector clients = m_clients.getClientIDs(); ClientInterface::AutoLock clientlock(m_clients); for (session_t i : clients) { @@ -2303,18 +2301,20 @@ void Server::sendMetadataChanged(const std::list &meta_updates, float far if (!client) continue; - ServerActiveObject *player = m_env->getActiveObject(i); - v3f player_pos = player ? player->getBasePosition() : v3f(); + ServerActiveObject *player = getPlayerSAO(i); + v3s16 player_pos; + if (player) + player_pos = floatToInt(player->getBasePosition(), BS); - for (const v3s16 &pos : meta_updates) { + for (const v3s16 pos : positions) { NodeMetadata *meta = m_env->getMap().getNodeMetadata(pos); if (!meta) continue; v3s16 block_pos = getNodeBlockPos(pos); - if (!client->isBlockSent(block_pos) || (player && - player_pos.getDistanceFrom(intToFloat(pos, BS)) > maxd)) { + if (!client->isBlockSent(block_pos) || + player_pos.getDistanceFrom(pos) > far_d_nodes) { client->SetBlockNotSent(block_pos); continue; } @@ -2326,14 +2326,15 @@ void Server::sendMetadataChanged(const std::list &meta_updates, float far continue; // Send the meta changes - std::ostringstream os(std::ios::binary); + os.str(""); meta_updates_list.serialize(os, client->serialization_version, false, true, true); - std::ostringstream oss(std::ios::binary); - compressZlib(os.str(), oss); + std::string raw = os.str(); + os.str(""); + compressZlib(raw, os); - NetworkPacket pkt(TOCLIENT_NODEMETA_CHANGED, 0); - pkt.putLongString(oss.str()); - m_clients.send(i, 0, &pkt, true); + NetworkPacket pkt(TOCLIENT_NODEMETA_CHANGED, 0, i); + pkt.putLongString(os.str()); + Send(&pkt); meta_updates_list.clear(); } diff --git a/src/server.h b/src/server.h index a9c5bcb5f..f1958701f 100644 --- a/src/server.h +++ b/src/server.h @@ -492,7 +492,7 @@ private: std::unordered_set *far_players = nullptr, float far_d_nodes = 100, bool remove_metadata = true); - void sendMetadataChanged(const std::list &meta_updates, + void sendMetadataChanged(const std::unordered_set &positions, float far_d_nodes = 100); // Environment and Connection must be locked when called