From 81c7f0ae044b1131ad082e5e705c5276f82ac6ce Mon Sep 17 00:00:00 2001 From: ANAND Date: Sun, 25 Aug 2019 06:24:21 +0530 Subject: [PATCH] Send ActiveObjects once right after Init2 --- src/client/client.cpp | 10 +- src/client/client.h | 3 + src/network/clientpackethandler.cpp | 4 + src/network/serverpackethandler.cpp | 26 +++- src/server.cpp | 215 ++++++++++++++-------------- src/server.h | 2 +- 6 files changed, 141 insertions(+), 119 deletions(-) diff --git a/src/client/client.cpp b/src/client/client.cpp index f6be3186f..ce09f343c 100644 --- a/src/client/client.cpp +++ b/src/client/client.cpp @@ -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() && diff --git a/src/client/client.h b/src/client/client.h index 6dad48c3d..934175ff2 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -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 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; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index a8ae8a5ef..d47571d14 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -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) diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 9999a1690..ecaf2a2a8 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -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!")); } } diff --git a/src/server.cpp b/src/server.cpp index 6a51139d9..df3b816f7 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -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 removed_objects; - std::queue 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(NetworkPacket* pkt) +inline void Server::handleCommand(NetworkPacket *pkt) { - const ToServerCommandHandler& opHandle = 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 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, diff --git a/src/server.h b/src/server.h index 86f82b6d7..aa7d6385a 100644 --- a/src/server.h +++ b/src/server.h @@ -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);