// 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;
}
}
-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,
far_d_nodes are ignored and their peer_ids are added to far_players
*/
// Envlock and conlock should be locked when calling these
- void sendRemoveNode(v3s16 p, u16 ignore_id=0,
- std::vector<u16> *far_players=NULL, float far_d_nodes=100);
- void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
- std::vector<u16> *far_players=NULL, float far_d_nodes=100,
- bool remove_metadata=true);
+ void sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players = nullptr,
+ float far_d_nodes = 100);
+ void sendAddNode(v3s16 p, MapNode n,
+ std::unordered_set<u16> *far_players = nullptr,
+ float far_d_nodes = 100, bool remove_metadata = true);
// Environment and Connection must be locked when called
void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, u16 net_proto_version);