]> git.lizzy.rs Git - minetest.git/blobdiff - src/clientiface.cpp
Fix race condition in registration leading to duplicate create_auth calls
[minetest.git] / src / clientiface.cpp
index 4f954342af50ba033904e1ed5373abb40bd774c8..a1c3e1187384349de0717b8bef79b2459423c792 100644 (file)
@@ -80,10 +80,11 @@ LuaEntitySAO *getAttachedObject(PlayerSAO *sao, ServerEnvironment *env)
        int id;
        std::string bone;
        v3f dummy;
-       sao->getAttachment(&id, &bone, &dummy, &dummy);
+       bool force_visible;
+       sao->getAttachment(&id, &bone, &dummy, &dummy, &force_visible);
        ServerActiveObject *ao = env->getActiveObject(id);
        while (id && ao) {
-               ao->getAttachment(&id, &bone, &dummy, &dummy);
+               ao->getAttachment(&id, &bone, &dummy, &dummy, &force_visible);
                if (id)
                        ao = env->getActiveObject(id);
        }
@@ -98,7 +99,6 @@ void RemoteClient::GetNextBlocks (
 {
        // Increment timers
        m_nothing_to_send_pause_timer -= dtime;
-       m_nearest_unsent_reset_timer += dtime;
 
        if (m_nothing_to_send_pause_timer >= 0)
                return;
@@ -138,34 +138,6 @@ void RemoteClient::GetNextBlocks (
        camera_dir.rotateYZBy(sao->getLookPitch());
        camera_dir.rotateXZBy(sao->getRotation().Y);
 
-       /*infostream<<"camera_dir=("<<camera_dir.X<<","<<camera_dir.Y<<","
-                       <<camera_dir.Z<<")"<<std::endl;*/
-
-       /*
-               Get the starting value of the block finder radius.
-       */
-
-       if (m_last_center != center) {
-               m_nearest_unsent_d = 0;
-               m_last_center = center;
-       }
-
-       /*infostream<<"m_nearest_unsent_reset_timer="
-                       <<m_nearest_unsent_reset_timer<<std::endl;*/
-
-       // Reset periodically to workaround for some bugs or stuff
-       if (m_nearest_unsent_reset_timer > 20.0f) {
-               m_nearest_unsent_reset_timer = 0.0f;
-               m_nearest_unsent_d = 0;
-               //infostream<<"Resetting m_nearest_unsent_d for "
-               //              <<server->getPlayerName(peer_id)<<std::endl;
-       }
-
-       //s16 last_nearest_unsent_d = m_nearest_unsent_d;
-       s16 d_start = m_nearest_unsent_d;
-
-       //infostream<<"d_start="<<d_start<<std::endl;
-
        u16 max_simul_sends_usually = m_max_simul_sends;
 
        /*
@@ -197,6 +169,29 @@ void RemoteClient::GetNextBlocks (
        s16 wanted_range = sao->getWantedRange() + 1;
        float camera_fov = sao->getFov();
 
+       /*
+               Get the starting value of the block finder radius.
+       */
+       if (m_last_center != center) {
+               m_nearest_unsent_d = 0;
+               m_last_center = center;
+       }
+       // reset the unsent distance if the view angle has changed more that 10% of the fov
+       // (this matches isBlockInSight which allows for an extra 10%)
+       if (camera_dir.dotProduct(m_last_camera_dir) < std::cos(camera_fov * 0.1f)) {
+               m_nearest_unsent_d = 0;
+               m_last_camera_dir = camera_dir;
+       }
+       if (m_nearest_unsent_d > 0) {
+               // make sure any blocks modified since the last time we sent blocks are resent
+               for (const v3s16 &p : m_blocks_modified) {
+                       m_nearest_unsent_d = std::min(m_nearest_unsent_d, center.getDistanceFrom(p));
+               }
+       }
+       m_blocks_modified.clear();
+
+       s16 d_start = m_nearest_unsent_d;
+
        // Distrust client-sent FOV and get server-set player object property
        // zoom FOV (degrees) as a check to avoid hacked clients using FOV to load
        // distant world.
@@ -211,13 +206,13 @@ void RemoteClient::GetNextBlocks (
                wanted_range);
        const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE;
 
-       s16 d_max = full_d_max;
        s16 d_max_gen = std::min(adjustDist(m_max_gen_distance, prop_zoom_fov),
                wanted_range);
 
-       // Don't loop very much at a time, adjust with distance,
-       // do more work per RTT with greater distances.
-       s16 max_d_increment_at_time = full_d_max / 9 + 1;
+       s16 d_max = full_d_max;
+
+       // Don't loop very much at a time
+       s16 max_d_increment_at_time = 2;
        if (d_max > d_start + max_d_increment_at_time)
                d_max = d_start + max_d_increment_at_time;
 
@@ -310,20 +305,14 @@ void RemoteClient::GetNextBlocks (
                        */
                        MapBlock *block = env->getMap().getBlockNoCreateNoEx(p);
 
-                       bool surely_not_found_on_disk = false;
-                       bool block_is_invalid = false;
+                       bool block_not_found = false;
                        if (block) {
                                // Reset usage timer, this block will be of use in the future.
                                block->resetUsageTimer();
 
-                               // Block is dummy if data doesn't exist.
-                               // It means it has been not found from disk and not generated
-                               if (block->isDummy()) {
-                                       surely_not_found_on_disk = true;
-                               }
-
-                               if (!block->isGenerated())
-                                       block_is_invalid = true;
+                               // Check whether the block exists (with data)
+                               if (block->isDummy() || !block->isGenerated())
+                                       block_not_found = true;
 
                                /*
                                        If block is not close, don't send it unless it is near
@@ -337,17 +326,17 @@ void RemoteClient::GetNextBlocks (
                                                continue;
                                }
 
-                               if (m_occ_cull && !block_is_invalid &&
+                               if (m_occ_cull && !block_not_found &&
                                                env->getMap().isBlockOccluded(block, cam_pos_nodes)) {
                                        continue;
                                }
                        }
 
                        /*
-                               If block has been marked to not exist on disk (dummy)
-                               and generating new ones is not wanted, skip block.
+                               If block has been marked to not exist on disk (dummy) or is
+                               not generated and generating new ones is not wanted, skip block.
                        */
-                       if (!generate && surely_not_found_on_disk) {
+                       if (!generate && block_not_found) {
                                // get next one.
                                continue;
                        }
@@ -355,7 +344,7 @@ void RemoteClient::GetNextBlocks (
                        /*
                                Add inexistent block to emerge queue.
                        */
-                       if (block == NULL || surely_not_found_on_disk || block_is_invalid) {
+                       if (block == NULL || block_not_found) {
                                if (emerge->enqueueBlockEmerge(peer_id, p, generate)) {
                                        if (nearest_emerged_d == -1)
                                                nearest_emerged_d = d;
@@ -408,21 +397,18 @@ void RemoteClient::GetNextBlocks (
 
 void RemoteClient::GotBlock(v3s16 p)
 {
-       if (m_blocks_modified.find(p) == m_blocks_modified.end()) {
-               if (m_blocks_sending.find(p) != m_blocks_sending.end())
-                       m_blocks_sending.erase(p);
-               else
-                       m_excess_gotblocks++;
-
+       if (m_blocks_sending.find(p) != m_blocks_sending.end()) {
+               m_blocks_sending.erase(p);
+               // only add to sent blocks if it actually was sending
+               // (it might have been modified since)
                m_blocks_sent.insert(p);
+       } else {
+               m_excess_gotblocks++;
        }
 }
 
 void RemoteClient::SentBlock(v3s16 p)
 {
-       if (m_blocks_modified.find(p) != m_blocks_modified.end())
-               m_blocks_modified.erase(p);
-
        if (m_blocks_sending.find(p) == m_blocks_sending.end())
                m_blocks_sending[p] = 0.0f;
        else
@@ -432,29 +418,24 @@ void RemoteClient::SentBlock(v3s16 p)
 
 void RemoteClient::SetBlockNotSent(v3s16 p)
 {
-       m_nearest_unsent_d = 0;
        m_nothing_to_send_pause_timer = 0;
 
-       if (m_blocks_sending.find(p) != m_blocks_sending.end())
-               m_blocks_sending.erase(p);
-       if (m_blocks_sent.find(p) != m_blocks_sent.end())
-               m_blocks_sent.erase(p);
-       m_blocks_modified.insert(p);
+       // remove the block from sending and sent sets,
+       // and mark as modified if found
+       if (m_blocks_sending.erase(p) + m_blocks_sent.erase(p) > 0)
+               m_blocks_modified.insert(p);
 }
 
 void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
 {
-       m_nearest_unsent_d = 0;
        m_nothing_to_send_pause_timer = 0;
 
        for (auto &block : blocks) {
                v3s16 p = block.first;
-               m_blocks_modified.insert(p);
-
-               if (m_blocks_sending.find(p) != m_blocks_sending.end())
-                       m_blocks_sending.erase(p);
-               if (m_blocks_sent.find(p) != m_blocks_sent.end())
-                       m_blocks_sent.erase(p);
+               // remove the block from sending and sent sets,
+               // and mark as modified if found
+               if (m_blocks_sending.erase(p) + m_blocks_sent.erase(p) > 0)
+                       m_blocks_modified.insert(p);
        }
 }
 
@@ -471,9 +452,6 @@ void RemoteClient::notifyEvent(ClientStateEvent event)
                case CSE_Hello:
                        m_state = CS_HelloSent;
                        break;
-               case CSE_InitLegacy:
-                       m_state = CS_AwaitingInit2;
-                       break;
                case CSE_Disconnect:
                        m_state = CS_Disconnecting;
                        break;
@@ -693,7 +671,6 @@ void ClientInterface::UpdatePlayerList()
                std::vector<session_t> clients = getClientIDs();
                m_clients_names.clear();
 
-
                if (!clients.empty())
                        infostream<<"Players:"<<std::endl;
 
@@ -737,31 +714,6 @@ void ClientInterface::sendToAll(NetworkPacket *pkt)
        }
 }
 
-void ClientInterface::sendToAllCompat(NetworkPacket *pkt, NetworkPacket *legacypkt,
-               u16 min_proto_ver)
-{
-       RecursiveMutexAutoLock clientslock(m_clients_mutex);
-       for (auto &client_it : m_clients) {
-               RemoteClient *client = client_it.second;
-               NetworkPacket *pkt_to_send = nullptr;
-
-               if (client->net_proto_version >= min_proto_ver) {
-                       pkt_to_send = pkt;
-               } else if (client->net_proto_version != 0) {
-                       pkt_to_send = legacypkt;
-               } else {
-                       warningstream << "Client with unhandled version to handle: '"
-                               << client->net_proto_version << "'";
-                       continue;
-               }
-
-               m_con->Send(client->peer_id,
-                       clientCommandFactoryTable[pkt_to_send->getCommand()].channel,
-                       pkt_to_send,
-                       clientCommandFactoryTable[pkt_to_send->getCommand()].reliable);
-       }
-}
-
 RemoteClient* ClientInterface::getClientNoEx(session_t peer_id, ClientState state_min)
 {
        RecursiveMutexAutoLock clientslock(m_clients_mutex);