summaryrefslogtreecommitdiff
path: root/src/server.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/server.cpp')
-rw-r--r--src/server.cpp103
1 files changed, 54 insertions, 49 deletions
diff --git a/src/server.cpp b/src/server.cpp
index 04338df57..37aad4bce 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -868,20 +868,20 @@ void Server::AsyncRunStep(bool initial_step)
// Players far away from the change are stored here.
// Instead of sending the changes, MapBlocks are set not sent
// for them.
- std::vector<u16> far_players;
+ std::unordered_set<u16> far_players;
switch (event->type) {
case MEET_ADDNODE:
case MEET_SWAPNODE:
prof.add("MEET_ADDNODE", 1);
- sendAddNode(event->p, event->n, event->already_known_by_peer,
- &far_players, disable_single_change_sending ? 5 : 30,
+ sendAddNode(event->p, event->n, &far_players,
+ disable_single_change_sending ? 5 : 30,
event->type == MEET_ADDNODE);
break;
case MEET_REMOVENODE:
prof.add("MEET_REMOVENODE", 1);
- sendRemoveNode(event->p, event->already_known_by_peer,
- &far_players, disable_single_change_sending ? 5 : 30);
+ sendRemoveNode(event->p, &far_players,
+ disable_single_change_sending ? 5 : 30);
break;
case MEET_BLOCK_NODE_METADATA_CHANGED:
infostream << "Server: MEET_BLOCK_NODE_METADATA_CHANGED" << std::endl;
@@ -2079,76 +2079,81 @@ void Server::fadeSound(s32 handle, float step, float gain)
}
}
-void Server::sendRemoveNode(v3s16 p, u16 ignore_id,
- std::vector<u16> *far_players, float far_d_nodes)
+void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
+ float far_d_nodes)
{
- float maxd = far_d_nodes*BS;
+ float maxd = far_d_nodes * BS;
v3f p_f = intToFloat(p, BS);
+ v3s16 block_pos = getNodeBlockPos(p);
NetworkPacket pkt(TOCLIENT_REMOVENODE, 6);
pkt << p;
std::vector<session_t> clients = m_clients.getClientIDs();
+ m_clients.lock();
+
for (session_t client_id : clients) {
- if (far_players) {
- // Get player
- if (RemotePlayer *player = m_env->getPlayer(client_id)) {
- PlayerSAO *sao = player->getPlayerSAO();
- if (!sao)
- continue;
+ RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
+ if (!client)
+ continue;
- // If player is far away, only set modified blocks not sent
- v3f player_pos = sao->getBasePosition();
- if (player_pos.getDistanceFrom(p_f) > maxd) {
- far_players->push_back(client_id);
- continue;
- }
- }
+ RemotePlayer *player = m_env->getPlayer(client_id);
+ PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;
+
+ // If player is far away, only set modified blocks not sent
+ if (!client->isBlockSent(block_pos) || (sao &&
+ sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
+ if (far_players)
+ far_players->emplace(client_id);
+ else
+ client->SetBlockNotSent(block_pos);
+ continue;
}
// Send as reliable
m_clients.send(client_id, 0, &pkt, true);
}
+
+ m_clients.unlock();
}
-void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id,
- std::vector<u16> *far_players, float far_d_nodes,
- bool remove_metadata)
+void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
+ float far_d_nodes, bool remove_metadata)
{
- float maxd = far_d_nodes*BS;
+ float maxd = far_d_nodes * BS;
v3f p_f = intToFloat(p, BS);
+ v3s16 block_pos = getNodeBlockPos(p);
+
+ NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1);
+ pkt << p << n.param0 << n.param1 << n.param2
+ << (u8) (remove_metadata ? 0 : 1);
std::vector<session_t> clients = m_clients.getClientIDs();
- for (const session_t client_id : clients) {
- if (far_players) {
- // Get player
- if (RemotePlayer *player = m_env->getPlayer(client_id)) {
- PlayerSAO *sao = player->getPlayerSAO();
- if (!sao)
- continue;
+ m_clients.lock();
- // If player is far away, only set modified blocks not sent
- v3f player_pos = sao->getBasePosition();
- if(player_pos.getDistanceFrom(p_f) > maxd) {
- far_players->push_back(client_id);
- continue;
- }
- }
- }
+ for (session_t client_id : clients) {
+ RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
+ if (!client)
+ continue;
- NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1);
- m_clients.lock();
- RemoteClient* client = m_clients.lockedGetClientNoEx(client_id);
- if (client) {
- pkt << p << n.param0 << n.param1 << n.param2
- << (u8) (remove_metadata ? 0 : 1);
+ RemotePlayer *player = m_env->getPlayer(client_id);
+ PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;
+
+ // If player is far away, only set modified blocks not sent
+ if (!client->isBlockSent(block_pos) || (sao &&
+ sao->getBasePosition().getDistanceFrom(p_f) > maxd)) {
+ if (far_players)
+ far_players->emplace(client_id);
+ else
+ client->SetBlockNotSent(block_pos);
+ continue;
}
- m_clients.unlock();
// Send as reliable
- if (pkt.getSize() > 0)
- m_clients.send(client_id, 0, &pkt, true);
+ m_clients.send(client_id, 0, &pkt, true);
}
+
+ m_clients.unlock();
}
void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,