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) {
213 //queue_is_full = true;
214 goto queue_full_break;
217 // Don't send blocks that are currently being transferred
218 if (m_blocks_sending.find(p) != m_blocks_sending.end())
224 if (blockpos_over_limit(p))
227 // If this is true, inexistent block will be made from scratch
228 bool generate = d <= d_max_gen;
231 /*// Limit the generating area vertically to 2/3
232 if(abs(p.Y - center.Y) > d_max_gen - d_max_gen / 3)
235 // Limit the send area vertically to 1/2
236 if (abs(p.Y - center.Y) > full_d_max / 2)
241 Don't generate or send if not in sight
242 FIXME This only works if the client uses a small enough
243 FOV setting. The default of 72 degrees is fine.
246 float camera_fov = (72.0*M_PI/180) * 4./3.;
247 if(isBlockInSight(p, camera_pos, camera_dir, camera_fov, 10000*BS) == false)
253 Don't send already sent blocks
256 if(m_blocks_sent.find(p) != m_blocks_sent.end())
263 Check if map has this block
265 MapBlock *block = env->getMap().getBlockNoCreateNoEx(p);
267 bool surely_not_found_on_disk = false;
268 bool block_is_invalid = false;
271 // Reset usage timer, this block will be of use in the future.
272 block->resetUsageTimer();
274 // Block is dummy if data doesn't exist.
275 // It means it has been not found from disk and not generated
278 surely_not_found_on_disk = true;
281 // Block is valid if lighting is up-to-date and data exists
282 if(block->isValid() == false)
284 block_is_invalid = true;
287 if(block->isGenerated() == false)
288 block_is_invalid = true;
291 If block is not close, don't send it unless it is near
294 Block is near ground level if night-time mesh
295 differs from day-time mesh.
299 if(block->getDayNightDiff() == false)
305 If block has been marked to not exist on disk (dummy)
306 and generating new ones is not wanted, skip block.
308 if(generate == false && surely_not_found_on_disk == true)
315 Add inexistent block to emerge queue.
317 if(block == NULL || surely_not_found_on_disk || block_is_invalid)
319 if (emerge->enqueueBlockEmerge(peer_id, p, generate)) {
320 if (nearest_emerged_d == -1)
321 nearest_emerged_d = d;
323 if (nearest_emergefull_d == -1)
324 nearest_emergefull_d = d;
325 goto queue_full_break;
332 if(nearest_sent_d == -1)
336 Add block to send queue
338 PrioritySortedBlockTransfer q((float)d, p, peer_id);
342 num_blocks_selected += 1;
347 // If nothing was found for sending and nothing was queued for
348 // emerging, continue next time browsing from here
349 if(nearest_emerged_d != -1){
350 new_nearest_unsent_d = nearest_emerged_d;
351 } else if(nearest_emergefull_d != -1){
352 new_nearest_unsent_d = nearest_emergefull_d;
354 if(d > g_settings->getS16("max_block_send_distance")){
355 new_nearest_unsent_d = 0;
356 m_nothing_to_send_pause_timer = 2.0;
358 if(nearest_sent_d != -1)
359 new_nearest_unsent_d = nearest_sent_d;
361 new_nearest_unsent_d = d;
365 if(new_nearest_unsent_d != -1)
366 m_nearest_unsent_d = new_nearest_unsent_d;
369 void RemoteClient::GotBlock(v3s16 p)
371 if(m_blocks_sending.find(p) != m_blocks_sending.end())
372 m_blocks_sending.erase(p);
375 m_excess_gotblocks++;
377 m_blocks_sent.insert(p);
380 void RemoteClient::SentBlock(v3s16 p)
382 if(m_blocks_sending.find(p) == m_blocks_sending.end())
383 m_blocks_sending[p] = 0.0;
385 infostream<<"RemoteClient::SentBlock(): Sent block"
386 " already in m_blocks_sending"<<std::endl;
389 void RemoteClient::SetBlockNotSent(v3s16 p)
391 m_nearest_unsent_d = 0;
393 if(m_blocks_sending.find(p) != m_blocks_sending.end())
394 m_blocks_sending.erase(p);
395 if(m_blocks_sent.find(p) != m_blocks_sent.end())
396 m_blocks_sent.erase(p);
399 void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
401 m_nearest_unsent_d = 0;
403 for(std::map<v3s16, MapBlock*>::iterator
405 i != blocks.end(); ++i)
409 if(m_blocks_sending.find(p) != m_blocks_sending.end())
410 m_blocks_sending.erase(p);
411 if(m_blocks_sent.find(p) != m_blocks_sent.end())
412 m_blocks_sent.erase(p);
416 void RemoteClient::notifyEvent(ClientStateEvent event)
418 std::ostringstream myerror;
422 //intentionally do nothing
427 m_state = CS_HelloSent;
430 m_state = CS_AwaitingInit2;
433 m_state = CS_Disconnecting;
438 /* GotInit2 SetDefinitionsSent SetMediaSent */
440 myerror << "Created: Invalid client state transition! " << event;
441 throw ClientStateError(myerror.str());
445 /* don't do anything if in denied state */
451 m_state = CS_AwaitingInit2;
452 if ((chosen_mech == AUTH_MECHANISM_SRP)
453 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
454 srp_verifier_delete((SRPVerifier *) auth_data);
455 chosen_mech = AUTH_MECHANISM_NONE;
458 m_state = CS_Disconnecting;
462 if ((chosen_mech == AUTH_MECHANISM_SRP)
463 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
464 srp_verifier_delete((SRPVerifier *) auth_data);
465 chosen_mech = AUTH_MECHANISM_NONE;
468 myerror << "HelloSent: Invalid client state transition! " << event;
469 throw ClientStateError(myerror.str());
472 case CS_AwaitingInit2:
476 confirmSerializationVersion();
477 m_state = CS_InitDone;
480 m_state = CS_Disconnecting;
486 /* Init SetDefinitionsSent SetMediaSent */
488 myerror << "InitSent: Invalid client state transition! " << event;
489 throw ClientStateError(myerror.str());
496 case CSE_SetDefinitionsSent:
497 m_state = CS_DefinitionsSent;
500 m_state = CS_Disconnecting;
506 /* Init GotInit2 SetMediaSent */
508 myerror << "InitDone: Invalid client state transition! " << event;
509 throw ClientStateError(myerror.str());
512 case CS_DefinitionsSent:
515 case CSE_SetClientReady:
519 m_state = CS_Disconnecting;
524 /* Init GotInit2 SetDefinitionsSent */
526 myerror << "DefinitionsSent: Invalid client state transition! " << event;
527 throw ClientStateError(myerror.str());
537 m_state = CS_Disconnecting;
539 case CSE_SudoSuccess:
540 m_state = CS_SudoMode;
541 if ((chosen_mech == AUTH_MECHANISM_SRP)
542 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
543 srp_verifier_delete((SRPVerifier *) auth_data);
544 chosen_mech = AUTH_MECHANISM_NONE;
546 /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */
548 myerror << "Active: Invalid client state transition! " << event;
549 throw ClientStateError(myerror.str());
560 m_state = CS_Disconnecting;
566 myerror << "Active: Invalid client state transition! " << event;
567 throw ClientStateError(myerror.str());
571 case CS_Disconnecting:
572 /* we are already disconnecting */
577 u32 RemoteClient::uptime()
579 return getTime(PRECISION_SECONDS) - m_connection_time;
582 ClientInterface::ClientInterface(con::Connection* con)
586 m_print_info_timer(0.0)
590 ClientInterface::~ClientInterface()
596 JMutexAutoLock clientslock(m_clients_mutex);
598 for(std::map<u16, RemoteClient*>::iterator
599 i = m_clients.begin();
600 i != m_clients.end(); ++i)
609 std::vector<u16> ClientInterface::getClientIDs(ClientState min_state)
611 std::vector<u16> reply;
612 JMutexAutoLock clientslock(m_clients_mutex);
614 for(std::map<u16, RemoteClient*>::iterator
615 i = m_clients.begin();
616 i != m_clients.end(); ++i)
618 if (i->second->getState() >= min_state)
619 reply.push_back(i->second->peer_id);
625 std::vector<std::string> ClientInterface::getPlayerNames()
627 return m_clients_names;
631 void ClientInterface::step(float dtime)
633 m_print_info_timer += dtime;
634 if(m_print_info_timer >= 30.0)
636 m_print_info_timer = 0.0;
641 void ClientInterface::UpdatePlayerList()
645 std::vector<u16> clients = getClientIDs();
646 m_clients_names.clear();
650 infostream<<"Players:"<<std::endl;
652 for(std::vector<u16>::iterator
654 i != clients.end(); ++i) {
655 Player *player = m_env->getPlayer(*i);
660 infostream << "* " << player->getName() << "\t";
663 JMutexAutoLock clientslock(m_clients_mutex);
664 RemoteClient* client = lockedGetClientNoEx(*i);
666 client->PrintInfo(infostream);
669 m_clients_names.push_back(player->getName());
674 void ClientInterface::send(u16 peer_id, u8 channelnum,
675 NetworkPacket* pkt, bool reliable)
677 m_con->Send(peer_id, channelnum, pkt, reliable);
680 void ClientInterface::sendToAll(u16 channelnum,
681 NetworkPacket* pkt, bool reliable)
683 JMutexAutoLock clientslock(m_clients_mutex);
684 for(std::map<u16, RemoteClient*>::iterator
685 i = m_clients.begin();
686 i != m_clients.end(); ++i) {
687 RemoteClient *client = i->second;
689 if (client->net_proto_version != 0) {
690 m_con->Send(client->peer_id, channelnum, pkt, reliable);
695 RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
697 JMutexAutoLock clientslock(m_clients_mutex);
698 std::map<u16, RemoteClient*>::iterator n;
699 n = m_clients.find(peer_id);
700 // The client may not exist; clients are immediately removed if their
701 // access is denied, and this event occurs later then.
702 if(n == m_clients.end())
705 if (n->second->getState() >= state_min)
711 RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState state_min)
713 std::map<u16, RemoteClient*>::iterator n;
714 n = m_clients.find(peer_id);
715 // The client may not exist; clients are immediately removed if their
716 // access is denied, and this event occurs later then.
717 if(n == m_clients.end())
720 if (n->second->getState() >= state_min)
726 ClientState ClientInterface::getClientState(u16 peer_id)
728 JMutexAutoLock clientslock(m_clients_mutex);
729 std::map<u16, RemoteClient*>::iterator n;
730 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())
736 return n->second->getState();
739 void ClientInterface::setPlayerName(u16 peer_id,std::string name)
741 JMutexAutoLock clientslock(m_clients_mutex);
742 std::map<u16, RemoteClient*>::iterator n;
743 n = m_clients.find(peer_id);
744 // The client may not exist; clients are immediately removed if their
745 // access is denied, and this event occurs later then.
746 if(n != m_clients.end())
747 n->second->setName(name);
750 void ClientInterface::DeleteClient(u16 peer_id)
752 JMutexAutoLock conlock(m_clients_mutex);
755 std::map<u16, RemoteClient*>::iterator n;
756 n = m_clients.find(peer_id);
757 // The client may not exist; clients are immediately removed if their
758 // access is denied, and this event occurs later then.
759 if(n == m_clients.end())
763 Mark objects to be not known by the client
765 //TODO this should be done by client destructor!!!
766 RemoteClient *client = n->second;
768 for(std::set<u16>::iterator
769 i = client->m_known_objects.begin();
770 i != client->m_known_objects.end(); ++i)
774 ServerActiveObject* obj = m_env->getActiveObject(id);
776 if(obj && obj->m_known_by_count > 0)
777 obj->m_known_by_count--;
781 delete m_clients[peer_id];
782 m_clients.erase(peer_id);
785 void ClientInterface::CreateClient(u16 peer_id)
787 JMutexAutoLock conlock(m_clients_mutex);
790 std::map<u16, RemoteClient*>::iterator n;
791 n = m_clients.find(peer_id);
792 // The client shouldn't already exist
793 if(n != m_clients.end()) return;
796 RemoteClient *client = new RemoteClient();
797 client->peer_id = peer_id;
798 m_clients[client->peer_id] = client;
801 void ClientInterface::event(u16 peer_id, ClientStateEvent event)
804 JMutexAutoLock clientlock(m_clients_mutex);
807 std::map<u16, RemoteClient*>::iterator n;
808 n = m_clients.find(peer_id);
810 // No client to deliver event
811 if (n == m_clients.end())
813 n->second->notifyEvent(event);
816 if ((event == CSE_SetClientReady) ||
817 (event == CSE_Disconnect) ||
818 (event == CSE_SetDenied))
824 u16 ClientInterface::getProtocolVersion(u16 peer_id)
826 JMutexAutoLock conlock(m_clients_mutex);
829 std::map<u16, RemoteClient*>::iterator n;
830 n = m_clients.find(peer_id);
832 // No client to get version
833 if (n == m_clients.end())
836 return n->second->net_proto_version;
839 void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full)
841 JMutexAutoLock conlock(m_clients_mutex);
844 std::map<u16, RemoteClient*>::iterator n;
845 n = m_clients.find(peer_id);
847 // No client to set versions
848 if (n == m_clients.end())
851 n->second->setVersionInfo(major,minor,patch,full);