Check node updates whether the blocks are known (#7568)

* Remove unused ignore_id
master
SmallJoker 2018-08-16 20:10:34 +02:00 committed by GitHub
parent 325bf68041
commit 297beea5bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 56 deletions

View File

@ -274,6 +274,11 @@ public:
u32 getSendingCount() const { return m_blocks_sending.size(); } u32 getSendingCount() const { return m_blocks_sending.size(); }
bool isBlockSent(v3s16 p) const
{
return m_blocks_sent.find(p) != m_blocks_sent.end();
}
// Increments timeouts and removes timed-out blocks from list // Increments timeouts and removes timed-out blocks from list
// NOTE: This doesn't fix the server-not-sending-block bug // NOTE: This doesn't fix the server-not-sending-block bug
// because it is related to emerging, not sending. // because it is related to emerging, not sending.

View File

@ -76,7 +76,6 @@ struct MapEditEvent
v3s16 p; v3s16 p;
MapNode n = CONTENT_AIR; MapNode n = CONTENT_AIR;
std::set<v3s16> modified_blocks; std::set<v3s16> modified_blocks;
u16 already_known_by_peer = 0;
MapEditEvent() = default; MapEditEvent() = default;

View File

@ -868,20 +868,20 @@ void Server::AsyncRunStep(bool initial_step)
// Players far away from the change are stored here. // Players far away from the change are stored here.
// Instead of sending the changes, MapBlocks are set not sent // Instead of sending the changes, MapBlocks are set not sent
// for them. // for them.
std::vector<u16> far_players; std::unordered_set<u16> far_players;
switch (event->type) { switch (event->type) {
case MEET_ADDNODE: case MEET_ADDNODE:
case MEET_SWAPNODE: case MEET_SWAPNODE:
prof.add("MEET_ADDNODE", 1); prof.add("MEET_ADDNODE", 1);
sendAddNode(event->p, event->n, event->already_known_by_peer, sendAddNode(event->p, event->n, &far_players,
&far_players, disable_single_change_sending ? 5 : 30, disable_single_change_sending ? 5 : 30,
event->type == MEET_ADDNODE); event->type == MEET_ADDNODE);
break; break;
case MEET_REMOVENODE: case MEET_REMOVENODE:
prof.add("MEET_REMOVENODE", 1); prof.add("MEET_REMOVENODE", 1);
sendRemoveNode(event->p, event->already_known_by_peer, sendRemoveNode(event->p, &far_players,
&far_players, disable_single_change_sending ? 5 : 30); disable_single_change_sending ? 5 : 30);
break; break;
case MEET_BLOCK_NODE_METADATA_CHANGED: case MEET_BLOCK_NODE_METADATA_CHANGED:
infostream << "Server: MEET_BLOCK_NODE_METADATA_CHANGED" << std::endl; 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, void Server::sendRemoveNode(v3s16 p, std::unordered_set<u16> *far_players,
std::vector<u16> *far_players, float far_d_nodes) float far_d_nodes)
{ {
float maxd = far_d_nodes*BS; float maxd = far_d_nodes * BS;
v3f p_f = intToFloat(p, BS); v3f p_f = intToFloat(p, BS);
v3s16 block_pos = getNodeBlockPos(p);
NetworkPacket pkt(TOCLIENT_REMOVENODE, 6); NetworkPacket pkt(TOCLIENT_REMOVENODE, 6);
pkt << p; pkt << p;
std::vector<session_t> clients = m_clients.getClientIDs(); std::vector<session_t> clients = m_clients.getClientIDs();
for (session_t client_id : clients) { m_clients.lock();
if (far_players) {
// Get player
if (RemotePlayer *player = m_env->getPlayer(client_id)) {
PlayerSAO *sao = player->getPlayerSAO();
if (!sao)
continue;
// If player is far away, only set modified blocks not sent for (session_t client_id : clients) {
v3f player_pos = sao->getBasePosition(); RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
if (player_pos.getDistanceFrom(p_f) > maxd) { if (!client)
far_players->push_back(client_id); continue;
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 // Send as reliable
m_clients.send(client_id, 0, &pkt, true); m_clients.send(client_id, 0, &pkt, true);
} }
m_clients.unlock();
} }
void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, void Server::sendAddNode(v3s16 p, MapNode n, std::unordered_set<u16> *far_players,
std::vector<u16> *far_players, float far_d_nodes, float far_d_nodes, bool remove_metadata)
bool remove_metadata)
{ {
float maxd = far_d_nodes*BS; float maxd = far_d_nodes * BS;
v3f p_f = intToFloat(p, 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(); std::vector<session_t> clients = m_clients.getClientIDs();
for (const session_t client_id : clients) { m_clients.lock();
if (far_players) {
// Get player
if (RemotePlayer *player = m_env->getPlayer(client_id)) {
PlayerSAO *sao = player->getPlayerSAO();
if (!sao)
continue;
// If player is far away, only set modified blocks not sent for (session_t client_id : clients) {
v3f player_pos = sao->getBasePosition(); RemoteClient *client = m_clients.lockedGetClientNoEx(client_id);
if(player_pos.getDistanceFrom(p_f) > maxd) { if (!client)
far_players->push_back(client_id); continue;
continue;
}
}
}
NetworkPacket pkt(TOCLIENT_ADDNODE, 6 + 2 + 1 + 1 + 1); RemotePlayer *player = m_env->getPlayer(client_id);
m_clients.lock(); PlayerSAO *sao = player ? player->getPlayerSAO() : nullptr;
RemoteClient* client = m_clients.lockedGetClientNoEx(client_id);
if (client) { // If player is far away, only set modified blocks not sent
pkt << p << n.param0 << n.param1 << n.param2 if (!client->isBlockSent(block_pos) || (sao &&
<< (u8) (remove_metadata ? 0 : 1); 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 // 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, void Server::SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver,

View File

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