diff --git a/builtin/settingtypes.txt b/builtin/settingtypes.txt index a5484fb4fe..651e05b308 100644 --- a/builtin/settingtypes.txt +++ b/builtin/settingtypes.txt @@ -2213,10 +2213,10 @@ client_mapblock_limit (Mapblock limit) [client] int 7500 -1 2147483647 # Maximum number of blocks that are simultaneously sent per client. # The maximum total count is calculated dynamically: # max_total = ceil((#clients + max_users) * per_client / 4) -max_simultaneous_block_sends_per_client (Maximum simultaneous block sends per client) [server] int 40 1 4294967295 +max_simultaneous_block_sends_per_client (Maximum simultaneous block sends per client) [server] int 40 1 -# To reduce lag, block transfers are slowed down when a player is building something. -# This determines how long they are slowed down after placing or removing a node. +# To save bandwidth, block transfers are slowed down when a player is building something. +# This determines how long the throttling lasts after placing a node. full_block_send_enable_min_time_from_building (Delay in sending blocks after building) [server] float 2.0 0.0 # Maximum number of packets sent per send step in the low-level networking code. diff --git a/src/constants.h b/src/constants.h index e97bd0507b..0825d19176 100644 --- a/src/constants.h +++ b/src/constants.h @@ -31,10 +31,10 @@ Server */ -// This many blocks are sent when player is building -#define LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS 0 -// Override for the previous one when distance of block is very low -#define BLOCK_SEND_DISABLE_LIMITS_MAX_D 1 +// Reduces block send rate while player is building +#define LIMITED_BLOCK_SENDS_FACTOR 0.33f +// Override for the previous one for blocks that are close by +#define BLOCK_ALWAYS_SEND_MAX_D 1 /* Client/Server diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 0bd6797c95..3683ed8c0a 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -1173,11 +1173,6 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) std::optional selected_item; getWieldedItem(playersao, selected_item); - // Reset build time counter - if (pointed.type == POINTEDTHING_NODE && - selected_item->getDefinition(m_itemdef).type == ITEM_NODE) - getClient(peer_id)->m_time_from_building = 0.0; - const bool had_prediction = !selected_item->getDefinition(m_itemdef). node_placement_prediction.empty(); @@ -1214,6 +1209,8 @@ void Server::handleCommand_Interact(NetworkPacket *pkt) if (pointed.type != POINTEDTHING_NODE) return; + getClient(peer_id)->m_time_from_building = 0; + // If item has node placement prediction, always send the // blocks to make sure the client knows what exactly happened RemoteClient *client = getClient(peer_id); diff --git a/src/server/clientiface.cpp b/src/server/clientiface.cpp index 8cbe8cc623..74337628be 100644 --- a/src/server/clientiface.cpp +++ b/src/server/clientiface.cpp @@ -56,7 +56,8 @@ const char *ClientInterface::state2Name(ClientState state) RemoteClient::RemoteClient() : serialization_version(SER_FMT_VER_INVALID), m_pending_serialization_version(SER_FMT_VER_INVALID), - m_max_simul_sends(g_settings->getU16("max_simultaneous_block_sends_per_client")), + m_max_simul_sends(std::max(1, + g_settings->getU16("max_simultaneous_block_sends_per_client"))), m_min_time_from_building( g_settings->getFloat("full_block_send_enable_min_time_from_building")), m_max_send_distance(g_settings->getS16("max_block_send_distance")), @@ -149,14 +150,15 @@ void RemoteClient::GetNextBlocks ( u16 max_simul_sends_usually = m_max_simul_sends; /* - Check the time from last addNode/removeNode. - Decrease send rate if player is building stuff. + + The idea is that we can save some bandwidth since the player is busy + and not looking around. */ m_time_from_building += dtime; if (m_time_from_building < m_min_time_from_building) { - max_simul_sends_usually - = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS; + max_simul_sends_usually *= LIMITED_BLOCK_SENDS_FACTOR; + max_simul_sends_usually = MYMAX(1, max_simul_sends_usually); } /* @@ -223,17 +225,19 @@ void RemoteClient::GetNextBlocks ( s16 d_max = full_d_max; // Don't loop very much at a time - s16 max_d_increment_at_time = 2; + const 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; - // cos(angle between velocity and camera) * |velocity| - // Limit to 0.0f in case player moves backwards. - f32 dot = rangelim(camera_dir.dotProduct(playerspeed), 0.0f, 300.0f); + { + // cos(angle between velocity and camera) * |velocity| + // Limit to 0.0f in case player moves backwards. + f32 dot = rangelim(camera_dir.dotProduct(playerspeed), 0.0f, 300.0f); - // Reduce the field of view when a player moves and looks forward. - // limit max fov effect to 50%, 60% at 20n/s fly speed - camera_fov = camera_fov / (1 + dot / 300.0f); + // Reduce the field of view when a player moves and looks forward. + // limit max fov effect to 50%, 60% at 20n/s fly speed + camera_fov = camera_fov / (1 + dot / 300.0f); + } s32 nearest_emerged_d = -1; s32 nearest_sent_d = -1; @@ -260,11 +264,9 @@ void RemoteClient::GetNextBlocks ( Also, don't send blocks that are already flying. */ - // Start with the usual maximum u16 max_simul_dynamic = max_simul_sends_usually; - // If block is very close, allow full maximum - if (d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D) + if (d <= BLOCK_ALWAYS_SEND_MAX_D) max_simul_dynamic = m_max_simul_sends; /* @@ -388,8 +390,8 @@ queue_full_break: new_nearest_unsent_d = 0; m_nothing_to_send_pause_timer = 2.0f; infostream << "Server: Player " << m_name << ", peer_id=" << peer_id - << ": full map send completed after " << m_map_send_completion_timer - << "s, restarting" << std::endl; + << ": full map send (d=" << d << ") completed after " + << m_map_send_completion_timer << "s, restarting" << std::endl; m_map_send_completion_timer = 0.0f; } else { if (nearest_sent_d != -1) diff --git a/src/util/numeric.cpp b/src/util/numeric.cpp index 59dd0a204e..37b41ace24 100644 --- a/src/util/numeric.cpp +++ b/src/util/numeric.cpp @@ -100,7 +100,7 @@ bool isBlockInSight(v3s16 blockpos_b, v3f camera_pos, v3f camera_dir, v3f blockpos_relative = blockpos - camera_pos; // Total distance - f32 d = MYMAX(0, blockpos_relative.getLength() - BLOCK_MAX_RADIUS); + f32 d = std::max(0.0f, blockpos_relative.getLength() - BLOCK_MAX_RADIUS); if (distance_ptr) *distance_ptr = d;