-void RemoteClient::GetNextBlocks(Server *server, float dtime,
- std::vector<PrioritySortedBlockTransfer> &dest)
-{
- DSTACK(__FUNCTION_NAME);
-
- /*u32 timer_result;
- TimeTaker timer("RemoteClient::GetNextBlocks", &timer_result);*/
-
- // Increment timers
- m_nothing_to_send_pause_timer -= dtime;
- m_nearest_unsent_reset_timer += dtime;
-
- if(m_nothing_to_send_pause_timer >= 0)
- return;
-
- Player *player = server->m_env->getPlayer(peer_id);
- // This can happen sometimes; clients and players are not in perfect sync.
- if(player == NULL)
- return;
-
- // Won't send anything if already sending
- if(m_blocks_sending.size() >= g_settings->getU16
- ("max_simultaneous_block_sends_per_client"))
- {
- //infostream<<"Not sending any blocks, Queue full."<<std::endl;
- return;
- }
-
- //TimeTaker timer("RemoteClient::GetNextBlocks");
-
- v3f playerpos = player->getPosition();
- v3f playerspeed = player->getSpeed();
- v3f playerspeeddir(0,0,0);
- if(playerspeed.getLength() > 1.0*BS)
- playerspeeddir = playerspeed / playerspeed.getLength();
- // Predict to next block
- v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS;
-
- v3s16 center_nodepos = floatToInt(playerpos_predicted, BS);
-
- v3s16 center = getNodeBlockPos(center_nodepos);
-
- // Camera position and direction
- v3f camera_pos = player->getEyePosition();
- v3f camera_dir = v3f(0,0,1);
- camera_dir.rotateYZBy(player->getPitch());
- camera_dir.rotateXZBy(player->getYaw());
-
- /*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.0)
- {
- m_nearest_unsent_reset_timer = 0;
- 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_setting = g_settings->getU16
- ("max_simultaneous_block_sends_per_client");
- u16 max_simul_sends_usually = max_simul_sends_setting;
-
- /*
- Check the time from last addNode/removeNode.
-
- Decrease send rate if player is building stuff.
- */
- m_time_from_building += dtime;
- if(m_time_from_building < g_settings->getFloat(
- "full_block_send_enable_min_time_from_building"))
- {
- max_simul_sends_usually
- = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
- }
-
- /*
- Number of blocks sending + number of blocks selected for sending
- */
- u32 num_blocks_selected = m_blocks_sending.size();
-
- /*
- next time d will be continued from the d from which the nearest
- unsent block was found this time.
-
- This is because not necessarily any of the blocks found this
- time are actually sent.
- */
- s32 new_nearest_unsent_d = -1;
-
- s16 d_max = g_settings->getS16("max_block_send_distance");
- s16 d_max_gen = g_settings->getS16("max_block_generate_distance");
-
- // 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;
- /*if(d_max_gen > d_start+2)
- d_max_gen = d_start+2;*/
-
- //infostream<<"Starting from "<<d_start<<std::endl;
-
- s32 nearest_emerged_d = -1;
- s32 nearest_emergefull_d = -1;
- s32 nearest_sent_d = -1;
- bool queue_is_full = false;
-
- s16 d;
- for(d = d_start; d <= d_max; d++)
- {
- /*errorstream<<"checking d="<<d<<" for "
- <<server->getPlayerName(peer_id)<<std::endl;*/
- //infostream<<"RemoteClient::SendBlocks(): d="<<d<<std::endl;
-
- /*
- If m_nearest_unsent_d was changed by the EmergeThread
- (it can change it to 0 through SetBlockNotSent),
- update our d to it.
- Else update m_nearest_unsent_d
- */
- /*if(m_nearest_unsent_d != last_nearest_unsent_d)
- {
- d = m_nearest_unsent_d;
- last_nearest_unsent_d = m_nearest_unsent_d;
- }*/
-
- /*
- Get the border/face dot coordinates of a "d-radiused"
- box
- */
- std::list<v3s16> list;
- getFacePositions(list, d);
-
- std::list<v3s16>::iterator li;
- for(li=list.begin(); li!=list.end(); ++li)
- {
- v3s16 p = *li + center;
-
- /*
- Send throttling
- - Don't allow too many simultaneous transfers
- - EXCEPT when the blocks are very close
-
- 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)
- max_simul_dynamic = max_simul_sends_setting;
-
- // Don't select too many blocks for sending
- if(num_blocks_selected >= max_simul_dynamic)
- {
- queue_is_full = true;
- goto queue_full_break;
- }
-
- // Don't send blocks that are currently being transferred
- if(m_blocks_sending.find(p) != m_blocks_sending.end())
- continue;
-
- /*
- Do not go over-limit
- */
- if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
- || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
- || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
- || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
- || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
- || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE)
- continue;
-
- // If this is true, inexistent block will be made from scratch
- bool generate = d <= d_max_gen;
-
- {
- /*// Limit the generating area vertically to 2/3
- if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
- generate = false;*/
-
- // Limit the send area vertically to 1/2
- if(abs(p.Y - center.Y) > d_max / 2)
- continue;
- }
-
-#if 0
- /*
- If block is far away, don't generate it unless it is
- near ground level.
- */
- if(d >= 4)
- {
- #if 1
- // Block center y in nodes
- f32 y = (f32)(p.Y * MAP_BLOCKSIZE + MAP_BLOCKSIZE/2);
- // Don't generate if it's very high or very low
- if(y < -64 || y > 64)
- generate = false;
- #endif
- #if 0
- v2s16 p2d_nodes_center(
- MAP_BLOCKSIZE*p.X,
- MAP_BLOCKSIZE*p.Z);
-
- // Get ground height in nodes
- s16 gh = server->m_env->getServerMap().findGroundLevel(
- p2d_nodes_center);
-
- // If differs a lot, don't generate
- if(fabs(gh - y) > MAP_BLOCKSIZE*2)
- generate = false;
- // Actually, don't even send it
- //continue;
- #endif
- }
-#endif