3 Copyright (C) 2010-2014 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #include "clientiface.h"
24 #include "connection.h"
25 #include "environment.h"
28 #include "serverobject.h" // TODO this is used for cleanup of only
30 #include "util/numeric.h"
32 #include "main.h" // for g_settings
34 void RemoteClient::GetNextBlocks(
35 ServerEnvironment *env,
36 EmergeManager * emerge,
38 std::vector<PrioritySortedBlockTransfer> &dest)
40 DSTACK(__FUNCTION_NAME);
44 m_nothing_to_send_pause_timer -= dtime;
45 m_nearest_unsent_reset_timer += dtime;
47 if(m_nothing_to_send_pause_timer >= 0)
50 Player *player = env->getPlayer(peer_id);
51 // This can happen sometimes; clients and players are not in perfect sync.
55 // Won't send anything if already sending
56 if(m_blocks_sending.size() >= g_settings->getU16
57 ("max_simultaneous_block_sends_per_client"))
59 //infostream<<"Not sending any blocks, Queue full."<<std::endl;
63 v3f playerpos = player->getPosition();
64 v3f playerspeed = player->getSpeed();
65 v3f playerspeeddir(0,0,0);
66 if(playerspeed.getLength() > 1.0*BS)
67 playerspeeddir = playerspeed / playerspeed.getLength();
68 // Predict to next block
69 v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS;
71 v3s16 center_nodepos = floatToInt(playerpos_predicted, BS);
73 v3s16 center = getNodeBlockPos(center_nodepos);
75 // Camera position and direction
76 v3f camera_pos = player->getEyePosition();
77 v3f camera_dir = v3f(0,0,1);
78 camera_dir.rotateYZBy(player->getPitch());
79 camera_dir.rotateXZBy(player->getYaw());
81 /*infostream<<"camera_dir=("<<camera_dir.X<<","<<camera_dir.Y<<","
82 <<camera_dir.Z<<")"<<std::endl;*/
85 Get the starting value of the block finder radius.
88 if(m_last_center != center)
90 m_nearest_unsent_d = 0;
91 m_last_center = center;
94 /*infostream<<"m_nearest_unsent_reset_timer="
95 <<m_nearest_unsent_reset_timer<<std::endl;*/
97 // Reset periodically to workaround for some bugs or stuff
98 if(m_nearest_unsent_reset_timer > 20.0)
100 m_nearest_unsent_reset_timer = 0;
101 m_nearest_unsent_d = 0;
102 //infostream<<"Resetting m_nearest_unsent_d for "
103 // <<server->getPlayerName(peer_id)<<std::endl;
106 //s16 last_nearest_unsent_d = m_nearest_unsent_d;
107 s16 d_start = m_nearest_unsent_d;
109 //infostream<<"d_start="<<d_start<<std::endl;
111 u16 max_simul_sends_setting = g_settings->getU16
112 ("max_simultaneous_block_sends_per_client");
113 u16 max_simul_sends_usually = max_simul_sends_setting;
116 Check the time from last addNode/removeNode.
118 Decrease send rate if player is building stuff.
120 m_time_from_building += dtime;
121 if(m_time_from_building < g_settings->getFloat(
122 "full_block_send_enable_min_time_from_building"))
124 max_simul_sends_usually
125 = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
129 Number of blocks sending + number of blocks selected for sending
131 u32 num_blocks_selected = m_blocks_sending.size();
134 next time d will be continued from the d from which the nearest
135 unsent block was found this time.
137 This is because not necessarily any of the blocks found this
138 time are actually sent.
140 s32 new_nearest_unsent_d = -1;
142 s16 d_max = g_settings->getS16("max_block_send_distance");
143 s16 d_max_gen = g_settings->getS16("max_block_generate_distance");
145 // Don't loop very much at a time
146 s16 max_d_increment_at_time = 2;
147 if(d_max > d_start + max_d_increment_at_time)
148 d_max = d_start + max_d_increment_at_time;
150 s32 nearest_emerged_d = -1;
151 s32 nearest_emergefull_d = -1;
152 s32 nearest_sent_d = -1;
153 bool queue_is_full = false;
156 for(d = d_start; d <= d_max; d++)
159 Get the border/face dot coordinates of a "d-radiused"
162 std::list<v3s16> list;
163 getFacePositions(list, d);
165 std::list<v3s16>::iterator li;
166 for(li=list.begin(); li!=list.end(); ++li)
168 v3s16 p = *li + center;
172 - Don't allow too many simultaneous transfers
173 - EXCEPT when the blocks are very close
175 Also, don't send blocks that are already flying.
178 // Start with the usual maximum
179 u16 max_simul_dynamic = max_simul_sends_usually;
181 // If block is very close, allow full maximum
182 if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
183 max_simul_dynamic = max_simul_sends_setting;
185 // Don't select too many blocks for sending
186 if(num_blocks_selected >= max_simul_dynamic)
188 queue_is_full = true;
189 goto queue_full_break;
192 // Don't send blocks that are currently being transferred
193 if(m_blocks_sending.find(p) != m_blocks_sending.end())
199 if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
200 || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
201 || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
202 || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
203 || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
204 || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE)
207 // If this is true, inexistent block will be made from scratch
208 bool generate = d <= d_max_gen;
211 /*// Limit the generating area vertically to 2/3
212 if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
215 // Limit the send area vertically to 1/2
216 if(abs(p.Y - center.Y) > d_max / 2)
221 Don't generate or send if not in sight
222 FIXME This only works if the client uses a small enough
223 FOV setting. The default of 72 degrees is fine.
226 float camera_fov = (72.0*M_PI/180) * 4./3.;
227 if(isBlockInSight(p, camera_pos, camera_dir, camera_fov, 10000*BS) == false)
233 Don't send already sent blocks
236 if(m_blocks_sent.find(p) != m_blocks_sent.end())
243 Check if map has this block
245 MapBlock *block = env->getMap().getBlockNoCreateNoEx(p);
247 bool surely_not_found_on_disk = false;
248 bool block_is_invalid = false;
251 // Reset usage timer, this block will be of use in the future.
252 block->resetUsageTimer();
254 // Block is dummy if data doesn't exist.
255 // It means it has been not found from disk and not generated
258 surely_not_found_on_disk = true;
261 // Block is valid if lighting is up-to-date and data exists
262 if(block->isValid() == false)
264 block_is_invalid = true;
267 if(block->isGenerated() == false)
268 block_is_invalid = true;
271 If block is not close, don't send it unless it is near
274 Block is near ground level if night-time mesh
275 differs from day-time mesh.
279 if(block->getDayNightDiff() == false)
285 If block has been marked to not exist on disk (dummy)
286 and generating new ones is not wanted, skip block.
288 if(generate == false && surely_not_found_on_disk == true)
295 Add inexistent block to emerge queue.
297 if(block == NULL || surely_not_found_on_disk || block_is_invalid)
299 if (emerge->enqueueBlockEmerge(peer_id, p, generate)) {
300 if (nearest_emerged_d == -1)
301 nearest_emerged_d = d;
303 if (nearest_emergefull_d == -1)
304 nearest_emergefull_d = d;
305 goto queue_full_break;
312 if(nearest_sent_d == -1)
316 Add block to send queue
318 PrioritySortedBlockTransfer q((float)d, p, peer_id);
322 num_blocks_selected += 1;
327 // If nothing was found for sending and nothing was queued for
328 // emerging, continue next time browsing from here
329 if(nearest_emerged_d != -1){
330 new_nearest_unsent_d = nearest_emerged_d;
331 } else if(nearest_emergefull_d != -1){
332 new_nearest_unsent_d = nearest_emergefull_d;
334 if(d > g_settings->getS16("max_block_send_distance")){
335 new_nearest_unsent_d = 0;
336 m_nothing_to_send_pause_timer = 2.0;
338 if(nearest_sent_d != -1)
339 new_nearest_unsent_d = nearest_sent_d;
341 new_nearest_unsent_d = d;
345 if(new_nearest_unsent_d != -1)
346 m_nearest_unsent_d = new_nearest_unsent_d;
349 void RemoteClient::GotBlock(v3s16 p)
351 if(m_blocks_sending.find(p) != m_blocks_sending.end())
352 m_blocks_sending.erase(p);
355 m_excess_gotblocks++;
357 m_blocks_sent.insert(p);
360 void RemoteClient::SentBlock(v3s16 p)
362 if(m_blocks_sending.find(p) == m_blocks_sending.end())
363 m_blocks_sending[p] = 0.0;
365 infostream<<"RemoteClient::SentBlock(): Sent block"
366 " already in m_blocks_sending"<<std::endl;
369 void RemoteClient::SetBlockNotSent(v3s16 p)
371 m_nearest_unsent_d = 0;
373 if(m_blocks_sending.find(p) != m_blocks_sending.end())
374 m_blocks_sending.erase(p);
375 if(m_blocks_sent.find(p) != m_blocks_sent.end())
376 m_blocks_sent.erase(p);
379 void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
381 m_nearest_unsent_d = 0;
383 for(std::map<v3s16, MapBlock*>::iterator
385 i != blocks.end(); ++i)
389 if(m_blocks_sending.find(p) != m_blocks_sending.end())
390 m_blocks_sending.erase(p);
391 if(m_blocks_sent.find(p) != m_blocks_sent.end())
392 m_blocks_sent.erase(p);
396 void RemoteClient::notifyEvent(ClientStateEvent event)
401 assert("State update for client in invalid state" != 0);
412 m_state = Disconnecting;
419 /* GotInit2 SetDefinitionsSent SetMediaSent */
421 assert("Invalid client state transition!" == 0);
426 /* don't do anything if in denied state */
433 confirmSerializationVersion();
438 m_state = Disconnecting;
445 /* Init SetDefinitionsSent SetMediaSent */
447 assert("Invalid client state transition!" == 0);
454 case SetDefinitionsSent:
455 m_state = DefinitionsSent;
459 m_state = Disconnecting;
466 /* Init GotInit2 SetMediaSent */
468 assert("Invalid client state transition!" == 0);
472 case DefinitionsSent:
480 m_state = Disconnecting;
487 /* Init GotInit2 SetDefinitionsSent */
489 assert("Invalid client state transition!" == 0);
501 m_state = Disconnecting;
504 /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */
506 assert("Invalid client state transition!" == 0);
512 /* we are already disconnecting */
517 ClientInterface::ClientInterface(con::Connection* con)
521 m_print_info_timer(0.0)
525 ClientInterface::~ClientInterface()
531 JMutexAutoLock clientslock(m_clients_mutex);
533 for(std::map<u16, RemoteClient*>::iterator
534 i = m_clients.begin();
535 i != m_clients.end(); ++i)
544 std::list<u16> ClientInterface::getClientIDs(ClientState min_state)
546 std::list<u16> reply;
547 JMutexAutoLock clientslock(m_clients_mutex);
549 for(std::map<u16, RemoteClient*>::iterator
550 i = m_clients.begin();
551 i != m_clients.end(); ++i)
553 if (i->second->getState() >= min_state)
554 reply.push_back(i->second->peer_id);
560 std::vector<std::string> ClientInterface::getPlayerNames()
562 return m_clients_names;
566 void ClientInterface::step(float dtime)
568 m_print_info_timer += dtime;
569 if(m_print_info_timer >= 30.0)
571 m_print_info_timer = 0.0;
576 void ClientInterface::UpdatePlayerList()
580 std::list<u16> clients = getClientIDs();
581 m_clients_names.clear();
584 if(clients.size() != 0)
585 infostream<<"Players:"<<std::endl;
586 for(std::list<u16>::iterator
588 i != clients.end(); ++i)
590 Player *player = m_env->getPlayer(*i);
593 infostream<<"* "<<player->getName()<<"\t";
596 JMutexAutoLock clientslock(m_clients_mutex);
597 RemoteClient* client = lockedGetClientNoEx(*i);
599 client->PrintInfo(infostream);
601 m_clients_names.push_back(player->getName());
606 void ClientInterface::send(u16 peer_id,u8 channelnum,
607 SharedBuffer<u8> data, bool reliable)
609 m_con->Send(peer_id, channelnum, data, reliable);
612 void ClientInterface::sendToAll(u16 channelnum,
613 SharedBuffer<u8> data, bool reliable)
615 JMutexAutoLock clientslock(m_clients_mutex);
616 for(std::map<u16, RemoteClient*>::iterator
617 i = m_clients.begin();
618 i != m_clients.end(); ++i)
620 RemoteClient *client = i->second;
622 if (client->net_proto_version != 0)
624 m_con->Send(client->peer_id, channelnum, data, reliable);
629 RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
631 JMutexAutoLock clientslock(m_clients_mutex);
632 std::map<u16, RemoteClient*>::iterator n;
633 n = m_clients.find(peer_id);
634 // The client may not exist; clients are immediately removed if their
635 // access is denied, and this event occurs later then.
636 if(n == m_clients.end())
639 if (n->second->getState() >= state_min)
645 RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState state_min)
647 std::map<u16, RemoteClient*>::iterator n;
648 n = m_clients.find(peer_id);
649 // The client may not exist; clients are immediately removed if their
650 // access is denied, and this event occurs later then.
651 if(n == m_clients.end())
654 if (n->second->getState() >= state_min)
660 ClientState ClientInterface::getClientState(u16 peer_id)
662 JMutexAutoLock clientslock(m_clients_mutex);
663 std::map<u16, RemoteClient*>::iterator n;
664 n = m_clients.find(peer_id);
665 // The client may not exist; clients are immediately removed if their
666 // access is denied, and this event occurs later then.
667 if(n == m_clients.end())
670 return n->second->getState();
673 void ClientInterface::setPlayerName(u16 peer_id,std::string name)
675 JMutexAutoLock clientslock(m_clients_mutex);
676 std::map<u16, RemoteClient*>::iterator n;
677 n = m_clients.find(peer_id);
678 // The client may not exist; clients are immediately removed if their
679 // access is denied, and this event occurs later then.
680 if(n != m_clients.end())
681 n->second->setName(name);
684 void ClientInterface::DeleteClient(u16 peer_id)
686 JMutexAutoLock conlock(m_clients_mutex);
689 std::map<u16, RemoteClient*>::iterator n;
690 n = m_clients.find(peer_id);
691 // The client may not exist; clients are immediately removed if their
692 // access is denied, and this event occurs later then.
693 if(n == m_clients.end())
697 Mark objects to be not known by the client
699 //TODO this should be done by client destructor!!!
700 RemoteClient *client = n->second;
702 for(std::set<u16>::iterator
703 i = client->m_known_objects.begin();
704 i != client->m_known_objects.end(); ++i)
708 ServerActiveObject* obj = m_env->getActiveObject(id);
710 if(obj && obj->m_known_by_count > 0)
711 obj->m_known_by_count--;
715 delete m_clients[peer_id];
716 m_clients.erase(peer_id);
719 void ClientInterface::CreateClient(u16 peer_id)
721 JMutexAutoLock conlock(m_clients_mutex);
724 std::map<u16, RemoteClient*>::iterator n;
725 n = m_clients.find(peer_id);
726 // The client shouldn't already exist
727 if(n != m_clients.end()) return;
730 RemoteClient *client = new RemoteClient();
731 client->peer_id = peer_id;
732 m_clients[client->peer_id] = client;
735 void ClientInterface::event(u16 peer_id, ClientStateEvent event)
738 JMutexAutoLock clientlock(m_clients_mutex);
741 std::map<u16, RemoteClient*>::iterator n;
742 n = m_clients.find(peer_id);
744 // No client to deliver event
745 if (n == m_clients.end())
747 n->second->notifyEvent(event);
750 if ((event == SetMediaSent) || (event == Disconnect) || (event == SetDenied))
756 u16 ClientInterface::getProtocolVersion(u16 peer_id)
758 JMutexAutoLock conlock(m_clients_mutex);
761 std::map<u16, RemoteClient*>::iterator n;
762 n = m_clients.find(peer_id);
764 // No client to deliver event
765 if (n == m_clients.end())
768 return n->second->net_proto_version;