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"
25 #include "remoteplayer.h"
28 #include "network/connection.h"
29 #include "environment.h"
32 #include "content_sao.h" // TODO this is used for cleanup of only
36 const char *ClientInterface::statenames[] = {
51 std::string ClientInterface::state2Name(ClientState state)
53 return statenames[state];
56 void RemoteClient::ResendBlockIfOnWire(v3s16 p)
58 // if this block is on wire, mark it for sending again as soon as possible
59 if (m_blocks_sending.find(p) != m_blocks_sending.end()) {
64 void RemoteClient::GetNextBlocks (
65 ServerEnvironment *env,
66 EmergeManager * emerge,
68 std::vector<PrioritySortedBlockTransfer> &dest)
70 DSTACK(FUNCTION_NAME);
74 m_nothing_to_send_pause_timer -= dtime;
75 m_nearest_unsent_reset_timer += dtime;
77 if(m_nothing_to_send_pause_timer >= 0)
80 RemotePlayer *player = env->getPlayer(peer_id);
81 // This can happen sometimes; clients and players are not in perfect sync.
85 PlayerSAO *sao = player->getPlayerSAO();
89 // Won't send anything if already sending
90 if(m_blocks_sending.size() >= g_settings->getU16
91 ("max_simultaneous_block_sends_per_client"))
93 //infostream<<"Not sending any blocks, Queue full."<<std::endl;
97 v3f playerpos = sao->getBasePosition();
98 v3f playerspeed = player->getSpeed();
99 v3f playerspeeddir(0,0,0);
100 if(playerspeed.getLength() > 1.0*BS)
101 playerspeeddir = playerspeed / playerspeed.getLength();
102 // Predict to next block
103 v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS;
105 v3s16 center_nodepos = floatToInt(playerpos_predicted, BS);
107 v3s16 center = getNodeBlockPos(center_nodepos);
109 // Camera position and direction
110 v3f camera_pos = sao->getEyePosition();
111 v3f camera_dir = v3f(0,0,1);
112 camera_dir.rotateYZBy(sao->getPitch());
113 camera_dir.rotateXZBy(sao->getYaw());
115 /*infostream<<"camera_dir=("<<camera_dir.X<<","<<camera_dir.Y<<","
116 <<camera_dir.Z<<")"<<std::endl;*/
119 Get the starting value of the block finder radius.
122 if(m_last_center != center)
124 m_nearest_unsent_d = 0;
125 m_last_center = center;
128 /*infostream<<"m_nearest_unsent_reset_timer="
129 <<m_nearest_unsent_reset_timer<<std::endl;*/
131 // Reset periodically to workaround for some bugs or stuff
132 if(m_nearest_unsent_reset_timer > 20.0)
134 m_nearest_unsent_reset_timer = 0;
135 m_nearest_unsent_d = 0;
136 //infostream<<"Resetting m_nearest_unsent_d for "
137 // <<server->getPlayerName(peer_id)<<std::endl;
140 //s16 last_nearest_unsent_d = m_nearest_unsent_d;
141 s16 d_start = m_nearest_unsent_d;
143 //infostream<<"d_start="<<d_start<<std::endl;
145 u16 max_simul_sends_setting = g_settings->getU16
146 ("max_simultaneous_block_sends_per_client");
147 u16 max_simul_sends_usually = max_simul_sends_setting;
150 Check the time from last addNode/removeNode.
152 Decrease send rate if player is building stuff.
154 m_time_from_building += dtime;
155 if(m_time_from_building < g_settings->getFloat(
156 "full_block_send_enable_min_time_from_building"))
158 max_simul_sends_usually
159 = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
163 Number of blocks sending + number of blocks selected for sending
165 u32 num_blocks_selected = m_blocks_sending.size();
168 next time d will be continued from the d from which the nearest
169 unsent block was found this time.
171 This is because not necessarily any of the blocks found this
172 time are actually sent.
174 s32 new_nearest_unsent_d = -1;
176 const s16 full_d_max = g_settings->getS16("max_block_send_distance");
177 const s16 d_opt = g_settings->getS16("block_send_optimize_distance");
179 s16 d_max = full_d_max;
180 s16 d_max_gen = g_settings->getS16("max_block_generate_distance");
182 // Don't loop very much at a time
183 s16 max_d_increment_at_time = 2;
184 if(d_max > d_start + max_d_increment_at_time)
185 d_max = d_start + max_d_increment_at_time;
187 s32 nearest_emerged_d = -1;
188 s32 nearest_emergefull_d = -1;
189 s32 nearest_sent_d = -1;
190 //bool queue_is_full = false;
193 for(d = d_start; d <= d_max; d++) {
195 Get the border/face dot coordinates of a "d-radiused"
198 std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
200 std::vector<v3s16>::iterator li;
201 for(li = list.begin(); li != list.end(); ++li) {
202 v3s16 p = *li + center;
206 - Don't allow too many simultaneous transfers
207 - EXCEPT when the blocks are very close
209 Also, don't send blocks that are already flying.
212 // Start with the usual maximum
213 u16 max_simul_dynamic = max_simul_sends_usually;
215 // If block is very close, allow full maximum
216 if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
217 max_simul_dynamic = max_simul_sends_setting;
219 // Don't select too many blocks for sending
220 if (num_blocks_selected >= max_simul_dynamic) {
221 //queue_is_full = true;
222 goto queue_full_break;
225 // Don't send blocks that are currently being transferred
226 if (m_blocks_sending.find(p) != m_blocks_sending.end())
232 if (blockpos_over_limit(p))
235 // If this is true, inexistent block will be made from scratch
236 bool generate = d <= d_max_gen;
239 Don't generate or send if not in sight
240 FIXME This only works if the client uses a small enough
241 FOV setting. The default of 72 degrees is fine.
244 float camera_fov = (72.0*M_PI/180) * 4./3.;
245 if(isBlockInSight(p, camera_pos, camera_dir, camera_fov, 10000*BS) == false)
251 Don't send already sent blocks
254 if(m_blocks_sent.find(p) != m_blocks_sent.end())
261 Check if map has this block
263 MapBlock *block = env->getMap().getBlockNoCreateNoEx(p);
265 bool surely_not_found_on_disk = false;
266 bool block_is_invalid = false;
269 // Reset usage timer, this block will be of use in the future.
270 block->resetUsageTimer();
272 // Block is dummy if data doesn't exist.
273 // It means it has been not found from disk and not generated
276 surely_not_found_on_disk = true;
279 // Block is valid if lighting is up-to-date and data exists
280 if(block->isValid() == false)
282 block_is_invalid = true;
285 if(block->isGenerated() == false)
286 block_is_invalid = true;
289 If block is not close, don't send it unless it is near
292 Block is near ground level if night-time mesh
293 differs from day-time mesh.
297 if(block->getDayNightDiff() == false)
303 If block has been marked to not exist on disk (dummy)
304 and generating new ones is not wanted, skip block.
306 if(generate == false && surely_not_found_on_disk == true)
313 Add inexistent block to emerge queue.
315 if(block == NULL || surely_not_found_on_disk || block_is_invalid)
317 if (emerge->enqueueBlockEmerge(peer_id, p, generate)) {
318 if (nearest_emerged_d == -1)
319 nearest_emerged_d = d;
321 if (nearest_emergefull_d == -1)
322 nearest_emergefull_d = d;
323 goto queue_full_break;
330 if(nearest_sent_d == -1)
334 Add block to send queue
336 PrioritySortedBlockTransfer q((float)d, p, peer_id);
340 num_blocks_selected += 1;
345 // If nothing was found for sending and nothing was queued for
346 // emerging, continue next time browsing from here
347 if(nearest_emerged_d != -1){
348 new_nearest_unsent_d = nearest_emerged_d;
349 } else if(nearest_emergefull_d != -1){
350 new_nearest_unsent_d = nearest_emergefull_d;
352 if(d > g_settings->getS16("max_block_send_distance")){
353 new_nearest_unsent_d = 0;
354 m_nothing_to_send_pause_timer = 2.0;
356 if(nearest_sent_d != -1)
357 new_nearest_unsent_d = nearest_sent_d;
359 new_nearest_unsent_d = d;
363 if(new_nearest_unsent_d != -1)
364 m_nearest_unsent_d = new_nearest_unsent_d;
367 void RemoteClient::GotBlock(v3s16 p)
369 if (m_blocks_modified.find(p) == m_blocks_modified.end()) {
370 if (m_blocks_sending.find(p) != m_blocks_sending.end())
371 m_blocks_sending.erase(p);
373 m_excess_gotblocks++;
375 m_blocks_sent.insert(p);
379 void RemoteClient::SentBlock(v3s16 p)
381 if (m_blocks_modified.find(p) != m_blocks_modified.end())
382 m_blocks_modified.erase(p);
384 if(m_blocks_sending.find(p) == m_blocks_sending.end())
385 m_blocks_sending[p] = 0.0;
387 infostream<<"RemoteClient::SentBlock(): Sent block"
388 " already in m_blocks_sending"<<std::endl;
391 void RemoteClient::SetBlockNotSent(v3s16 p)
393 m_nearest_unsent_d = 0;
394 m_nothing_to_send_pause_timer = 0;
396 if(m_blocks_sending.find(p) != m_blocks_sending.end())
397 m_blocks_sending.erase(p);
398 if(m_blocks_sent.find(p) != m_blocks_sent.end())
399 m_blocks_sent.erase(p);
400 m_blocks_modified.insert(p);
403 void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
405 m_nearest_unsent_d = 0;
406 m_nothing_to_send_pause_timer = 0;
408 for(std::map<v3s16, MapBlock*>::iterator
410 i != blocks.end(); ++i)
413 m_blocks_modified.insert(p);
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 MutexAutoLock clientslock(m_clients_mutex);
604 for (UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
605 i != m_clients.end(); ++i) {
612 std::vector<u16> ClientInterface::getClientIDs(ClientState min_state)
614 std::vector<u16> reply;
615 MutexAutoLock clientslock(m_clients_mutex);
617 for(UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
618 i != m_clients.end(); ++i) {
619 if (i->second->getState() >= min_state)
620 reply.push_back(i->second->peer_id);
626 void ClientInterface::step(float dtime)
628 m_print_info_timer += dtime;
629 if(m_print_info_timer >= 30.0)
631 m_print_info_timer = 0.0;
636 void ClientInterface::UpdatePlayerList()
639 std::vector<u16> clients = getClientIDs();
640 m_clients_names.clear();
644 infostream<<"Players:"<<std::endl;
646 for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
647 RemotePlayer *player = m_env->getPlayer(*i);
652 infostream << "* " << player->getName() << "\t";
655 MutexAutoLock clientslock(m_clients_mutex);
656 RemoteClient* client = lockedGetClientNoEx(*i);
658 client->PrintInfo(infostream);
661 m_clients_names.push_back(player->getName());
666 void ClientInterface::send(u16 peer_id, u8 channelnum,
667 NetworkPacket* pkt, bool reliable)
669 m_con->Send(peer_id, channelnum, pkt, reliable);
672 void ClientInterface::sendToAll(u16 channelnum,
673 NetworkPacket* pkt, bool reliable)
675 MutexAutoLock clientslock(m_clients_mutex);
676 for(UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
677 i != m_clients.end(); ++i) {
678 RemoteClient *client = i->second;
680 if (client->net_proto_version != 0) {
681 m_con->Send(client->peer_id, channelnum, pkt, reliable);
686 RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
688 MutexAutoLock clientslock(m_clients_mutex);
689 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
690 // The client may not exist; clients are immediately removed if their
691 // access is denied, and this event occurs later then.
692 if (n == m_clients.end())
695 if (n->second->getState() >= state_min)
701 RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState state_min)
703 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
704 // The client may not exist; clients are immediately removed if their
705 // access is denied, and this event occurs later then.
706 if (n == m_clients.end())
709 if (n->second->getState() >= state_min)
715 ClientState ClientInterface::getClientState(u16 peer_id)
717 MutexAutoLock clientslock(m_clients_mutex);
718 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
719 // The client may not exist; clients are immediately removed if their
720 // access is denied, and this event occurs later then.
721 if (n == m_clients.end())
724 return n->second->getState();
727 void ClientInterface::setPlayerName(u16 peer_id,std::string name)
729 MutexAutoLock clientslock(m_clients_mutex);
730 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
731 // The client may not exist; clients are immediately removed if their
732 // access is denied, and this event occurs later then.
733 if (n != m_clients.end())
734 n->second->setName(name);
737 void ClientInterface::DeleteClient(u16 peer_id)
739 MutexAutoLock conlock(m_clients_mutex);
742 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
743 // The client may not exist; clients are immediately removed if their
744 // access is denied, and this event occurs later then.
745 if (n == m_clients.end())
749 Mark objects to be not known by the client
751 //TODO this should be done by client destructor!!!
752 RemoteClient *client = n->second;
754 for(std::set<u16>::iterator
755 i = client->m_known_objects.begin();
756 i != client->m_known_objects.end(); ++i)
760 ServerActiveObject* obj = m_env->getActiveObject(id);
762 if(obj && obj->m_known_by_count > 0)
763 obj->m_known_by_count--;
767 delete m_clients[peer_id];
768 m_clients.erase(peer_id);
771 void ClientInterface::CreateClient(u16 peer_id)
773 MutexAutoLock conlock(m_clients_mutex);
776 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
777 // The client shouldn't already exist
778 if (n != m_clients.end()) return;
781 RemoteClient *client = new RemoteClient();
782 client->peer_id = peer_id;
783 m_clients[client->peer_id] = client;
786 void ClientInterface::event(u16 peer_id, ClientStateEvent event)
789 MutexAutoLock clientlock(m_clients_mutex);
792 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
794 // No client to deliver event
795 if (n == m_clients.end())
797 n->second->notifyEvent(event);
800 if ((event == CSE_SetClientReady) ||
801 (event == CSE_Disconnect) ||
802 (event == CSE_SetDenied))
808 u16 ClientInterface::getProtocolVersion(u16 peer_id)
810 MutexAutoLock conlock(m_clients_mutex);
813 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
815 // No client to get version
816 if (n == m_clients.end())
819 return n->second->net_proto_version;
822 void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full)
824 MutexAutoLock conlock(m_clients_mutex);
827 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
829 // No client to set versions
830 if (n == m_clients.end())
833 n->second->setVersionInfo(major,minor,patch,full);