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.
22 #include "clientiface.h"
23 #include "util/numeric.h"
24 #include "util/mathconstants.h"
28 #include "network/connection.h"
29 #include "environment.h"
32 #include "serverobject.h" // TODO this is used for cleanup of only
36 const char *ClientInterface::statenames[] = {
49 std::string ClientInterface::state2Name(ClientState state)
51 return statenames[state];
54 void RemoteClient::ResendBlockIfOnWire(v3s16 p)
56 // if this block is on wire, mark it for sending again as soon as possible
57 if (m_blocks_sending.find(p) != m_blocks_sending.end()) {
62 void RemoteClient::GetNextBlocks (
63 ServerEnvironment *env,
64 EmergeManager * emerge,
66 std::vector<PrioritySortedBlockTransfer> &dest)
68 DSTACK(__FUNCTION_NAME);
72 m_nothing_to_send_pause_timer -= dtime;
73 m_nearest_unsent_reset_timer += dtime;
75 if(m_nothing_to_send_pause_timer >= 0)
78 Player *player = env->getPlayer(peer_id);
79 // This can happen sometimes; clients and players are not in perfect sync.
83 // Won't send anything if already sending
84 if(m_blocks_sending.size() >= g_settings->getU16
85 ("max_simultaneous_block_sends_per_client"))
87 //infostream<<"Not sending any blocks, Queue full."<<std::endl;
91 v3f playerpos = player->getPosition();
92 v3f playerspeed = player->getSpeed();
93 v3f playerspeeddir(0,0,0);
94 if(playerspeed.getLength() > 1.0*BS)
95 playerspeeddir = playerspeed / playerspeed.getLength();
96 // Predict to next block
97 v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS;
99 v3s16 center_nodepos = floatToInt(playerpos_predicted, BS);
101 v3s16 center = getNodeBlockPos(center_nodepos);
103 // Camera position and direction
104 v3f camera_pos = player->getEyePosition();
105 v3f camera_dir = v3f(0,0,1);
106 camera_dir.rotateYZBy(player->getPitch());
107 camera_dir.rotateXZBy(player->getYaw());
109 /*infostream<<"camera_dir=("<<camera_dir.X<<","<<camera_dir.Y<<","
110 <<camera_dir.Z<<")"<<std::endl;*/
113 Get the starting value of the block finder radius.
116 if(m_last_center != center)
118 m_nearest_unsent_d = 0;
119 m_last_center = center;
122 /*infostream<<"m_nearest_unsent_reset_timer="
123 <<m_nearest_unsent_reset_timer<<std::endl;*/
125 // Reset periodically to workaround for some bugs or stuff
126 if(m_nearest_unsent_reset_timer > 20.0)
128 m_nearest_unsent_reset_timer = 0;
129 m_nearest_unsent_d = 0;
130 //infostream<<"Resetting m_nearest_unsent_d for "
131 // <<server->getPlayerName(peer_id)<<std::endl;
134 //s16 last_nearest_unsent_d = m_nearest_unsent_d;
135 s16 d_start = m_nearest_unsent_d;
137 //infostream<<"d_start="<<d_start<<std::endl;
139 u16 max_simul_sends_setting = g_settings->getU16
140 ("max_simultaneous_block_sends_per_client");
141 u16 max_simul_sends_usually = max_simul_sends_setting;
144 Check the time from last addNode/removeNode.
146 Decrease send rate if player is building stuff.
148 m_time_from_building += dtime;
149 if(m_time_from_building < g_settings->getFloat(
150 "full_block_send_enable_min_time_from_building"))
152 max_simul_sends_usually
153 = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
157 Number of blocks sending + number of blocks selected for sending
159 u32 num_blocks_selected = m_blocks_sending.size();
162 next time d will be continued from the d from which the nearest
163 unsent block was found this time.
165 This is because not necessarily any of the blocks found this
166 time are actually sent.
168 s32 new_nearest_unsent_d = -1;
170 const s16 full_d_max = g_settings->getS16("max_block_send_distance");
171 s16 d_max = full_d_max;
172 s16 d_max_gen = g_settings->getS16("max_block_generate_distance");
174 // Don't loop very much at a time
175 s16 max_d_increment_at_time = 2;
176 if(d_max > d_start + max_d_increment_at_time)
177 d_max = d_start + max_d_increment_at_time;
179 s32 nearest_emerged_d = -1;
180 s32 nearest_emergefull_d = -1;
181 s32 nearest_sent_d = -1;
182 //bool queue_is_full = false;
185 for(d = d_start; d <= d_max; d++) {
187 Get the border/face dot coordinates of a "d-radiused"
190 std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
192 std::vector<v3s16>::iterator li;
193 for(li = list.begin(); li != list.end(); ++li) {
194 v3s16 p = *li + center;
198 - Don't allow too many simultaneous transfers
199 - EXCEPT when the blocks are very close
201 Also, don't send blocks that are already flying.
204 // Start with the usual maximum
205 u16 max_simul_dynamic = max_simul_sends_usually;
207 // If block is very close, allow full maximum
208 if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
209 max_simul_dynamic = max_simul_sends_setting;
211 // Don't select too many blocks for sending
212 if(num_blocks_selected >= max_simul_dynamic)
214 //queue_is_full = true;
215 goto queue_full_break;
218 // Don't send blocks that are currently being transferred
219 if(m_blocks_sending.find(p) != m_blocks_sending.end())
225 if(p.X < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
226 || p.X > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
227 || p.Y < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
228 || p.Y > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
229 || p.Z < -MAP_GENERATION_LIMIT / MAP_BLOCKSIZE
230 || p.Z > MAP_GENERATION_LIMIT / MAP_BLOCKSIZE)
233 // If this is true, inexistent block will be made from scratch
234 bool generate = d <= d_max_gen;
237 /*// Limit the generating area vertically to 2/3
238 if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
241 // Limit the send area vertically to 1/2
242 if(abs(p.Y - center.Y) > full_d_max / 2)
247 Don't generate or send if not in sight
248 FIXME This only works if the client uses a small enough
249 FOV setting. The default of 72 degrees is fine.
252 float camera_fov = (72.0*M_PI/180) * 4./3.;
253 if(isBlockInSight(p, camera_pos, camera_dir, camera_fov, 10000*BS) == false)
259 Don't send already sent blocks
262 if(m_blocks_sent.find(p) != m_blocks_sent.end())
269 Check if map has this block
271 MapBlock *block = env->getMap().getBlockNoCreateNoEx(p);
273 bool surely_not_found_on_disk = false;
274 bool block_is_invalid = false;
277 // Reset usage timer, this block will be of use in the future.
278 block->resetUsageTimer();
280 // Block is dummy if data doesn't exist.
281 // It means it has been not found from disk and not generated
284 surely_not_found_on_disk = true;
287 // Block is valid if lighting is up-to-date and data exists
288 if(block->isValid() == false)
290 block_is_invalid = true;
293 if(block->isGenerated() == false)
294 block_is_invalid = true;
297 If block is not close, don't send it unless it is near
300 Block is near ground level if night-time mesh
301 differs from day-time mesh.
305 if(block->getDayNightDiff() == false)
311 If block has been marked to not exist on disk (dummy)
312 and generating new ones is not wanted, skip block.
314 if(generate == false && surely_not_found_on_disk == true)
321 Add inexistent block to emerge queue.
323 if(block == NULL || surely_not_found_on_disk || block_is_invalid)
325 if (emerge->enqueueBlockEmerge(peer_id, p, generate)) {
326 if (nearest_emerged_d == -1)
327 nearest_emerged_d = d;
329 if (nearest_emergefull_d == -1)
330 nearest_emergefull_d = d;
331 goto queue_full_break;
338 if(nearest_sent_d == -1)
342 Add block to send queue
344 PrioritySortedBlockTransfer q((float)d, p, peer_id);
348 num_blocks_selected += 1;
353 // If nothing was found for sending and nothing was queued for
354 // emerging, continue next time browsing from here
355 if(nearest_emerged_d != -1){
356 new_nearest_unsent_d = nearest_emerged_d;
357 } else if(nearest_emergefull_d != -1){
358 new_nearest_unsent_d = nearest_emergefull_d;
360 if(d > g_settings->getS16("max_block_send_distance")){
361 new_nearest_unsent_d = 0;
362 m_nothing_to_send_pause_timer = 2.0;
364 if(nearest_sent_d != -1)
365 new_nearest_unsent_d = nearest_sent_d;
367 new_nearest_unsent_d = d;
371 if(new_nearest_unsent_d != -1)
372 m_nearest_unsent_d = new_nearest_unsent_d;
375 void RemoteClient::GotBlock(v3s16 p)
377 if(m_blocks_sending.find(p) != m_blocks_sending.end())
378 m_blocks_sending.erase(p);
381 m_excess_gotblocks++;
383 m_blocks_sent.insert(p);
386 void RemoteClient::SentBlock(v3s16 p)
388 if(m_blocks_sending.find(p) == m_blocks_sending.end())
389 m_blocks_sending[p] = 0.0;
391 infostream<<"RemoteClient::SentBlock(): Sent block"
392 " already in m_blocks_sending"<<std::endl;
395 void RemoteClient::SetBlockNotSent(v3s16 p)
397 m_nearest_unsent_d = 0;
399 if(m_blocks_sending.find(p) != m_blocks_sending.end())
400 m_blocks_sending.erase(p);
401 if(m_blocks_sent.find(p) != m_blocks_sent.end())
402 m_blocks_sent.erase(p);
405 void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
407 m_nearest_unsent_d = 0;
409 for(std::map<v3s16, MapBlock*>::iterator
411 i != blocks.end(); ++i)
415 if(m_blocks_sending.find(p) != m_blocks_sending.end())
416 m_blocks_sending.erase(p);
417 if(m_blocks_sent.find(p) != m_blocks_sent.end())
418 m_blocks_sent.erase(p);
422 void RemoteClient::notifyEvent(ClientStateEvent event)
424 std::ostringstream myerror;
428 //intentionally do nothing
433 m_state = CS_HelloSent;
436 m_state = CS_AwaitingInit2;
439 m_state = CS_Disconnecting;
444 /* GotInit2 SetDefinitionsSent SetMediaSent */
446 myerror << "Created: Invalid client state transition! " << event;
447 throw ClientStateError(myerror.str());
451 /* don't do anything if in denied state */
457 m_state = CS_AwaitingInit2;
458 if ((chosen_mech == AUTH_MECHANISM_SRP)
459 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
460 srp_verifier_delete((SRPVerifier *) auth_data);
461 chosen_mech = AUTH_MECHANISM_NONE;
464 m_state = CS_Disconnecting;
468 if ((chosen_mech == AUTH_MECHANISM_SRP)
469 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
470 srp_verifier_delete((SRPVerifier *) auth_data);
471 chosen_mech = AUTH_MECHANISM_NONE;
474 myerror << "HelloSent: Invalid client state transition! " << event;
475 throw ClientStateError(myerror.str());
478 case CS_AwaitingInit2:
482 confirmSerializationVersion();
483 m_state = CS_InitDone;
486 m_state = CS_Disconnecting;
492 /* Init SetDefinitionsSent SetMediaSent */
494 myerror << "InitSent: Invalid client state transition! " << event;
495 throw ClientStateError(myerror.str());
502 case CSE_SetDefinitionsSent:
503 m_state = CS_DefinitionsSent;
506 m_state = CS_Disconnecting;
512 /* Init GotInit2 SetMediaSent */
514 myerror << "InitDone: Invalid client state transition! " << event;
515 throw ClientStateError(myerror.str());
518 case CS_DefinitionsSent:
521 case CSE_SetClientReady:
525 m_state = CS_Disconnecting;
530 /* Init GotInit2 SetDefinitionsSent */
532 myerror << "DefinitionsSent: Invalid client state transition! " << event;
533 throw ClientStateError(myerror.str());
543 m_state = CS_Disconnecting;
545 case CSE_SudoSuccess:
546 m_state = CS_SudoMode;
547 if ((chosen_mech == AUTH_MECHANISM_SRP)
548 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
549 srp_verifier_delete((SRPVerifier *) auth_data);
550 chosen_mech = AUTH_MECHANISM_NONE;
552 /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */
554 myerror << "Active: Invalid client state transition! " << event;
555 throw ClientStateError(myerror.str());
566 m_state = CS_Disconnecting;
572 myerror << "Active: Invalid client state transition! " << event;
573 throw ClientStateError(myerror.str());
577 case CS_Disconnecting:
578 /* we are already disconnecting */
583 u32 RemoteClient::uptime()
585 return getTime(PRECISION_SECONDS) - m_connection_time;
588 ClientInterface::ClientInterface(con::Connection* con)
592 m_print_info_timer(0.0)
596 ClientInterface::~ClientInterface()
602 JMutexAutoLock clientslock(m_clients_mutex);
604 for(std::map<u16, RemoteClient*>::iterator
605 i = m_clients.begin();
606 i != m_clients.end(); ++i)
615 std::vector<u16> ClientInterface::getClientIDs(ClientState min_state)
617 std::vector<u16> reply;
618 JMutexAutoLock clientslock(m_clients_mutex);
620 for(std::map<u16, RemoteClient*>::iterator
621 i = m_clients.begin();
622 i != m_clients.end(); ++i)
624 if (i->second->getState() >= min_state)
625 reply.push_back(i->second->peer_id);
631 std::vector<std::string> ClientInterface::getPlayerNames()
633 return m_clients_names;
637 void ClientInterface::step(float dtime)
639 m_print_info_timer += dtime;
640 if(m_print_info_timer >= 30.0)
642 m_print_info_timer = 0.0;
647 void ClientInterface::UpdatePlayerList()
651 std::vector<u16> clients = getClientIDs();
652 m_clients_names.clear();
656 infostream<<"Players:"<<std::endl;
658 for(std::vector<u16>::iterator
660 i != clients.end(); ++i) {
661 Player *player = m_env->getPlayer(*i);
666 infostream << "* " << player->getName() << "\t";
669 JMutexAutoLock clientslock(m_clients_mutex);
670 RemoteClient* client = lockedGetClientNoEx(*i);
672 client->PrintInfo(infostream);
675 m_clients_names.push_back(player->getName());
680 void ClientInterface::send(u16 peer_id, u8 channelnum,
681 NetworkPacket* pkt, bool reliable)
683 m_con->Send(peer_id, channelnum, pkt, reliable);
686 void ClientInterface::sendToAll(u16 channelnum,
687 NetworkPacket* pkt, bool reliable)
689 JMutexAutoLock clientslock(m_clients_mutex);
690 for(std::map<u16, RemoteClient*>::iterator
691 i = m_clients.begin();
692 i != m_clients.end(); ++i) {
693 RemoteClient *client = i->second;
695 if (client->net_proto_version != 0) {
696 m_con->Send(client->peer_id, channelnum, pkt, reliable);
701 RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
703 JMutexAutoLock clientslock(m_clients_mutex);
704 std::map<u16, RemoteClient*>::iterator n;
705 n = m_clients.find(peer_id);
706 // The client may not exist; clients are immediately removed if their
707 // access is denied, and this event occurs later then.
708 if(n == m_clients.end())
711 if (n->second->getState() >= state_min)
717 RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState state_min)
719 std::map<u16, RemoteClient*>::iterator n;
720 n = m_clients.find(peer_id);
721 // The client may not exist; clients are immediately removed if their
722 // access is denied, and this event occurs later then.
723 if(n == m_clients.end())
726 if (n->second->getState() >= state_min)
732 ClientState ClientInterface::getClientState(u16 peer_id)
734 JMutexAutoLock clientslock(m_clients_mutex);
735 std::map<u16, RemoteClient*>::iterator n;
736 n = m_clients.find(peer_id);
737 // The client may not exist; clients are immediately removed if their
738 // access is denied, and this event occurs later then.
739 if(n == m_clients.end())
742 return n->second->getState();
745 void ClientInterface::setPlayerName(u16 peer_id,std::string name)
747 JMutexAutoLock clientslock(m_clients_mutex);
748 std::map<u16, RemoteClient*>::iterator n;
749 n = m_clients.find(peer_id);
750 // The client may not exist; clients are immediately removed if their
751 // access is denied, and this event occurs later then.
752 if(n != m_clients.end())
753 n->second->setName(name);
756 void ClientInterface::DeleteClient(u16 peer_id)
758 JMutexAutoLock conlock(m_clients_mutex);
761 std::map<u16, RemoteClient*>::iterator n;
762 n = m_clients.find(peer_id);
763 // The client may not exist; clients are immediately removed if their
764 // access is denied, and this event occurs later then.
765 if(n == m_clients.end())
769 Mark objects to be not known by the client
771 //TODO this should be done by client destructor!!!
772 RemoteClient *client = n->second;
774 for(std::set<u16>::iterator
775 i = client->m_known_objects.begin();
776 i != client->m_known_objects.end(); ++i)
780 ServerActiveObject* obj = m_env->getActiveObject(id);
782 if(obj && obj->m_known_by_count > 0)
783 obj->m_known_by_count--;
787 delete m_clients[peer_id];
788 m_clients.erase(peer_id);
791 void ClientInterface::CreateClient(u16 peer_id)
793 JMutexAutoLock conlock(m_clients_mutex);
796 std::map<u16, RemoteClient*>::iterator n;
797 n = m_clients.find(peer_id);
798 // The client shouldn't already exist
799 if(n != m_clients.end()) return;
802 RemoteClient *client = new RemoteClient();
803 client->peer_id = peer_id;
804 m_clients[client->peer_id] = client;
807 void ClientInterface::event(u16 peer_id, ClientStateEvent event)
810 JMutexAutoLock clientlock(m_clients_mutex);
813 std::map<u16, RemoteClient*>::iterator n;
814 n = m_clients.find(peer_id);
816 // No client to deliver event
817 if (n == m_clients.end())
819 n->second->notifyEvent(event);
822 if ((event == CSE_SetClientReady) ||
823 (event == CSE_Disconnect) ||
824 (event == CSE_SetDenied))
830 u16 ClientInterface::getProtocolVersion(u16 peer_id)
832 JMutexAutoLock conlock(m_clients_mutex);
835 std::map<u16, RemoteClient*>::iterator n;
836 n = m_clients.find(peer_id);
838 // No client to get version
839 if (n == m_clients.end())
842 return n->second->net_proto_version;
845 void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full)
847 JMutexAutoLock conlock(m_clients_mutex);
850 std::map<u16, RemoteClient*>::iterator n;
851 n = m_clients.find(peer_id);
853 // No client to set versions
854 if (n == m_clients.end())
857 n->second->setVersionInfo(major,minor,patch,full);