Send ActiveObjects once right after Init2
authorANAND <ClobberXD@gmail.com>
Sun, 25 Aug 2019 00:54:21 +0000 (06:24 +0530)
committersfan5 <sfan5@live.de>
Sat, 14 Sep 2019 18:16:55 +0000 (20:16 +0200)
src/client/client.cpp
src/client/client.h
src/network/clientpackethandler.cpp
src/network/serverpackethandler.cpp
src/server.cpp
src/server.h

index f6be3186fbab0b959c0f63fb62d1f42d6fcc4aa8..ce09f343cb1480eecaf81f7bed6b94847572310b 100644 (file)
@@ -1243,8 +1243,14 @@ void Client::sendPlayerPos()
        u8 camera_fov    = map.getCameraFov();
        u8 wanted_range  = map.getControl().wanted_range;
 
-       // Save bandwidth by only updating position when something changed
-       if(myplayer->last_position        == myplayer->getPosition() &&
+       // Save bandwidth by only updating position when
+       // player is not dead and something changed
+
+       if (m_activeobjects_received && myplayer->isDead())
+               return;
+
+       if (
+                       myplayer->last_position     == myplayer->getPosition() &&
                        myplayer->last_speed        == myplayer->getSpeed()    &&
                        myplayer->last_pitch        == myplayer->getPitch()    &&
                        myplayer->last_yaw          == myplayer->getYaw()      &&
index 6dad48c3df46262d75b23e541a1ad36f8d568cc7..934175ff27b53d6460ea815094e6bb766d6c07f9 100644 (file)
@@ -339,6 +339,8 @@ public:
        { return m_nodedef_received; }
        bool mediaReceived()
        { return !m_media_downloader; }
+       const bool activeObjectsReceived() const
+       { return m_activeobjects_received; }
 
        u16 getProtoVersion()
        { return m_proto_ver; }
@@ -539,6 +541,7 @@ private:
        std::queue<ClientEvent *> m_client_event_queue;
        bool m_itemdef_received = false;
        bool m_nodedef_received = false;
+       bool m_activeobjects_received = false;
        bool m_mods_loaded = false;
        ClientMediaDownloader *m_media_downloader;
 
index a8ae8a5ef46f8eb9bd8fd002d66423917762201f..d47571d1436abace1e1ed3e2222619e09d8b3f11 100644 (file)
@@ -463,6 +463,10 @@ void Client::handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt)
                infostream << "handleCommand_ActiveObjectRemoveAdd: " << e.what()
                                << ". The packet is unreliable, ignoring" << std::endl;
        }
+
+       // m_activeobjects_received is false before the first
+       // TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD packet is received
+       m_activeobjects_received = true;
 }
 
 void Client::handleCommand_ActiveObjectMessages(NetworkPacket* pkt)
index 9999a1690ce4fb54ef180d1b29af060fc12dd495..ecaf2a2a880d397be0f4e3afbfe1c67824aca656 100644 (file)
@@ -298,9 +298,6 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
        infostream << "Server: Sending content to "
                        << getPlayerName(pkt->getPeerId()) << std::endl;
 
-       // Send player movement settings
-       SendMovement(pkt->getPeerId());
-
        // Send item definitions
        SendItemDef(pkt->getPeerId(), m_itemdef, protocol_version);
 
@@ -312,9 +309,25 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
        // Send media announcement
        sendMediaAnnouncement(pkt->getPeerId(), lang);
 
+       RemoteClient *client;
+       {
+               MutexAutoLock(m_con);
+               client = getClient(pkt->getPeerId(), CS_InitDone);
+       }
+
+       // Send active objects
+       {
+               PlayerSAO *sao = getPlayerSAO(pkt->getPeerId());
+               if (client && sao)
+                       SendActiveObjectRemoveAdd(client, sao);
+       }
+
        // Send detached inventories
        sendDetachedInventories(pkt->getPeerId(), false);
 
+       // Send player movement settings
+       SendMovement(pkt->getPeerId());
+
        // Send time of day
        u16 time = m_env->getTimeOfDay();
        float time_speed = g_settings->getFloat("time_speed");
@@ -323,11 +336,10 @@ void Server::handleCommand_Init2(NetworkPacket* pkt)
        SendCSMRestrictionFlags(pkt->getPeerId());
 
        // Warnings about protocol version can be issued here
-       if (getClient(pkt->getPeerId())->net_proto_version < LATEST_PROTOCOL_VERSION) {
+       if (client->net_proto_version < LATEST_PROTOCOL_VERSION) {
                SendChatMessage(pkt->getPeerId(), ChatMessage(CHATMESSAGE_TYPE_SYSTEM,
-                               L"# Server: WARNING: YOUR CLIENT'S VERSION MAY NOT BE FULLY COMPATIBLE "
-                               L"WITH THIS SERVER!"));
-
+                       L"# Server: WARNING: YOUR CLIENT'S VERSION MAY NOT BE FULLY COMPATIBLE "
+                       L"WITH THIS SERVER!"));
        }
 }
 
index 6a51139d9ed6a0db83d00cc36ab3ababe3af482e..df3b816f7f8661890113e44925afb07c116da57a 100644 (file)
@@ -620,124 +620,27 @@ void Server::AsyncRunStep(bool initial_step)
 
                m_clients.lock();
                const RemoteClientMap &clients = m_clients.getClientList();
-               ScopeProfiler sp(g_profiler, "Server: update visible objects");
-
-               // Radius inside which objects are active
-               static thread_local const s16 radius =
-                       g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE;
-
-               // Radius inside which players are active
-               static thread_local const bool is_transfer_limited =
-                       g_settings->exists("unlimited_player_transfer_distance") &&
-                       !g_settings->getBool("unlimited_player_transfer_distance");
-               static thread_local const s16 player_transfer_dist =
-                       g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE;
-               s16 player_radius = player_transfer_dist;
-               if (player_radius == 0 && is_transfer_limited)
-                       player_radius = radius;
+               ScopeProfiler sp(g_profiler, "Server: update objects within range");
 
                for (const auto &client_it : clients) {
                        RemoteClient *client = client_it.second;
 
-                       // If definitions and textures have not been sent, don't
-                       // send objects either
                        if (client->getState() < CS_DefinitionsSent)
                                continue;
 
-                       RemotePlayer *player = m_env->getPlayer(client->peer_id);
-                       if (!player) {
-                               // This can happen if the client timeouts somehow
+                       // This can happen if the client times out somehow
+                       if (!m_env->getPlayer(client->peer_id))
                                continue;
-                       }
 
-                       PlayerSAO *playersao = player->getPlayerSAO();
+                       PlayerSAO *playersao = getPlayerSAO(client->peer_id);
                        if (!playersao)
                                continue;
 
-                       s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
-                       if (my_radius <= 0) my_radius = radius;
-                       //infostream << "Server: Active Radius " << my_radius << std::endl;
-
-                       std::queue<u16> removed_objects;
-                       std::queue<u16> added_objects;
-                       m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
-                                       client->m_known_objects, removed_objects);
-                       m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
-                                       client->m_known_objects, added_objects);
-
-                       // Ignore if nothing happened
-                       if (removed_objects.empty() && added_objects.empty()) {
-                               continue;
-                       }
-
-                       std::string data_buffer;
-
-                       char buf[4];
-
-                       // Handle removed objects
-                       writeU16((u8*)buf, removed_objects.size());
-                       data_buffer.append(buf, 2);
-                       while (!removed_objects.empty()) {
-                               // Get object
-                               u16 id = removed_objects.front();
-                               ServerActiveObject* obj = m_env->getActiveObject(id);
-
-                               // Add to data buffer for sending
-                               writeU16((u8*)buf, id);
-                               data_buffer.append(buf, 2);
-
-                               // Remove from known objects
-                               client->m_known_objects.erase(id);
-
-                               if(obj && obj->m_known_by_count > 0)
-                                       obj->m_known_by_count--;
-                               removed_objects.pop();
-                       }
-
-                       // Handle added objects
-                       writeU16((u8*)buf, added_objects.size());
-                       data_buffer.append(buf, 2);
-                       while (!added_objects.empty()) {
-                               // Get object
-                               u16 id = added_objects.front();
-                               ServerActiveObject* obj = m_env->getActiveObject(id);
-
-                               // Get object type
-                               u8 type = ACTIVEOBJECT_TYPE_INVALID;
-                               if (!obj)
-                                       warningstream << FUNCTION_NAME << ": NULL object" << std::endl;
-                               else
-                                       type = obj->getSendType();
-
-                               // Add to data buffer for sending
-                               writeU16((u8*)buf, id);
-                               data_buffer.append(buf, 2);
-                               writeU8((u8*)buf, type);
-                               data_buffer.append(buf, 1);
-
-                               if(obj)
-                                       data_buffer.append(serializeLongString(
-                                                       obj->getClientInitializationData(client->net_proto_version)));
-                               else
-                                       data_buffer.append(serializeLongString(""));
-
-                               // Add to known objects
-                               client->m_known_objects.insert(id);
-
-                               if(obj)
-                                       obj->m_known_by_count++;
-
-                               added_objects.pop();
-                       }
-
-                       u32 pktSize = SendActiveObjectRemoveAdd(client->peer_id, data_buffer);
-                       verbosestream << "Server: Sent object remove/add: "
-                                       << removed_objects.size() << " removed, "
-                                       << added_objects.size() << " added, "
-                                       << "packet size is " << pktSize << std::endl;
+                       SendActiveObjectRemoveAdd(client, playersao);
                }
                m_clients.unlock();
 
+               // Save mod storages if modified
                m_mod_storage_save_timer -= dtime;
                if (m_mod_storage_save_timer <= 0.0f) {
                        infostream << "Saving registered mod storages." << std::endl;
@@ -1089,9 +992,9 @@ PlayerSAO* Server::StageTwoClientInit(session_t peer_id)
        return playersao;
 }
 
-inline void Server::handleCommand(NetworkPacketpkt)
+inline void Server::handleCommand(NetworkPacket *pkt)
 {
-       const ToServerCommandHandleropHandle = toServerCommandTable[pkt->getCommand()];
+       const ToServerCommandHandler &opHandle = toServerCommandTable[pkt->getCommand()];
        (this->*opHandle.handler)(pkt);
 }
 
@@ -1925,12 +1828,106 @@ void Server::SendPlayerFormspecPrepend(session_t peer_id)
        Send(&pkt);
 }
 
-u32 Server::SendActiveObjectRemoveAdd(session_t peer_id, const std::string &datas)
+void Server::SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao)
 {
-       NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, datas.size(), peer_id);
-       pkt.putRawString(datas.c_str(), datas.size());
+       // Radius inside which objects are active
+       static thread_local const s16 radius =
+               g_settings->getS16("active_object_send_range_blocks") * MAP_BLOCKSIZE;
+
+       // Radius inside which players are active
+       static thread_local const bool is_transfer_limited =
+               g_settings->exists("unlimited_player_transfer_distance") &&
+               !g_settings->getBool("unlimited_player_transfer_distance");
+
+       static thread_local const s16 player_transfer_dist =
+               g_settings->getS16("player_transfer_distance") * MAP_BLOCKSIZE;
+
+       s16 player_radius = player_transfer_dist == 0 && is_transfer_limited ?
+               radius : player_transfer_dist;
+
+       s16 my_radius = MYMIN(radius, playersao->getWantedRange() * MAP_BLOCKSIZE);
+       if (my_radius <= 0)
+               my_radius = radius;
+
+       std::queue<u16> removed_objects, added_objects;
+       m_env->getRemovedActiveObjects(playersao, my_radius, player_radius,
+               client->m_known_objects, removed_objects);
+       m_env->getAddedActiveObjects(playersao, my_radius, player_radius,
+               client->m_known_objects, added_objects);
+
+       int removed_count = removed_objects.size();
+       int added_count   = added_objects.size();
+
+       if (removed_objects.empty() && added_objects.empty())
+               return;
+
+       char buf[4];
+       std::string data;
+
+       // Handle removed objects
+       writeU16((u8*)buf, removed_objects.size());
+       data.append(buf, 2);
+       while (!removed_objects.empty()) {
+               // Get object
+               u16 id = removed_objects.front();
+               ServerActiveObject* obj = m_env->getActiveObject(id);
+
+               // Add to data buffer for sending
+               writeU16((u8*)buf, id);
+               data.append(buf, 2);
+
+               // Remove from known objects
+               client->m_known_objects.erase(id);
+
+               if (obj && obj->m_known_by_count > 0)
+                       obj->m_known_by_count--;
+
+               removed_objects.pop();
+       }
+
+       // Handle added objects
+       writeU16((u8*)buf, added_objects.size());
+       data.append(buf, 2);
+       while (!added_objects.empty()) {
+               // Get object
+               u16 id = added_objects.front();
+               ServerActiveObject* obj = m_env->getActiveObject(id);
+
+               // Get object type
+               u8 type = ACTIVEOBJECT_TYPE_INVALID;
+               if (!obj)
+                       warningstream << FUNCTION_NAME << ": NULL object" << std::endl;
+               else
+                       type = obj->getSendType();
+
+               // Add to data buffer for sending
+               writeU16((u8*)buf, id);
+               data.append(buf, 2);
+               writeU8((u8*)buf, type);
+               data.append(buf, 1);
+
+               if (obj)
+                       data.append(serializeLongString(
+                               obj->getClientInitializationData(client->net_proto_version)));
+               else
+                       data.append(serializeLongString(""));
+
+               // Add to known objects
+               client->m_known_objects.insert(id);
+
+               if (obj)
+                       obj->m_known_by_count++;
+
+               added_objects.pop();
+       }
+
+       NetworkPacket pkt(TOCLIENT_ACTIVE_OBJECT_REMOVE_ADD, data.size(), client->peer_id);
+       pkt.putRawString(data.c_str(), data.size());
        Send(&pkt);
-       return pkt.getSize();
+
+       verbosestream << "Server::SendActiveObjectRemoveAdd: "
+               << removed_count << " removed, " << added_count << " added, "
+               << "packet size is " << pkt.getSize() << std::endl;
 }
 
 void Server::SendActiveObjectMessages(session_t peer_id, const std::string &datas,
index 86f82b6d7ca396cf7dc6184f2882461b5fe4c4da..aa7d6385a225806c9250993716d9a9ec4a24dc04 100644 (file)
@@ -469,7 +469,7 @@ private:
                bool vertical, const std::string &texture,
                const struct TileAnimationParams &animation, u8 glow);
 
-       u32 SendActiveObjectRemoveAdd(session_t peer_id, const std::string &datas);
+       void SendActiveObjectRemoveAdd(RemoteClient *client, PlayerSAO *playersao);
        void SendActiveObjectMessages(session_t peer_id, const std::string &datas,
                bool reliable = true);
        void SendCSMRestrictionFlags(session_t peer_id);