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 s16 d_max = full_d_max;
178 s16 d_max_gen = g_settings->getS16("max_block_generate_distance");
180 // Don't loop very much at a time
181 s16 max_d_increment_at_time = 2;
182 if(d_max > d_start + max_d_increment_at_time)
183 d_max = d_start + max_d_increment_at_time;
185 s32 nearest_emerged_d = -1;
186 s32 nearest_emergefull_d = -1;
187 s32 nearest_sent_d = -1;
188 //bool queue_is_full = false;
191 for(d = d_start; d <= d_max; d++) {
193 Get the border/face dot coordinates of a "d-radiused"
196 std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
198 std::vector<v3s16>::iterator li;
199 for(li = list.begin(); li != list.end(); ++li) {
200 v3s16 p = *li + center;
204 - Don't allow too many simultaneous transfers
205 - EXCEPT when the blocks are very close
207 Also, don't send blocks that are already flying.
210 // Start with the usual maximum
211 u16 max_simul_dynamic = max_simul_sends_usually;
213 // If block is very close, allow full maximum
214 if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
215 max_simul_dynamic = max_simul_sends_setting;
217 // Don't select too many blocks for sending
218 if (num_blocks_selected >= max_simul_dynamic) {
219 //queue_is_full = true;
220 goto queue_full_break;
223 // Don't send blocks that are currently being transferred
224 if (m_blocks_sending.find(p) != m_blocks_sending.end())
230 if (blockpos_over_limit(p))
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_modified.find(p) == m_blocks_modified.end()) {
378 if (m_blocks_sending.find(p) != m_blocks_sending.end())
379 m_blocks_sending.erase(p);
381 m_excess_gotblocks++;
383 m_blocks_sent.insert(p);
387 void RemoteClient::SentBlock(v3s16 p)
389 if (m_blocks_modified.find(p) != m_blocks_modified.end())
390 m_blocks_modified.erase(p);
392 if(m_blocks_sending.find(p) == m_blocks_sending.end())
393 m_blocks_sending[p] = 0.0;
395 infostream<<"RemoteClient::SentBlock(): Sent block"
396 " already in m_blocks_sending"<<std::endl;
399 void RemoteClient::SetBlockNotSent(v3s16 p)
401 m_nearest_unsent_d = 0;
402 m_nothing_to_send_pause_timer = 0;
404 if(m_blocks_sending.find(p) != m_blocks_sending.end())
405 m_blocks_sending.erase(p);
406 if(m_blocks_sent.find(p) != m_blocks_sent.end())
407 m_blocks_sent.erase(p);
408 m_blocks_modified.insert(p);
411 void RemoteClient::SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks)
413 m_nearest_unsent_d = 0;
414 m_nothing_to_send_pause_timer = 0;
416 for(std::map<v3s16, MapBlock*>::iterator
418 i != blocks.end(); ++i)
421 m_blocks_modified.insert(p);
423 if(m_blocks_sending.find(p) != m_blocks_sending.end())
424 m_blocks_sending.erase(p);
425 if(m_blocks_sent.find(p) != m_blocks_sent.end())
426 m_blocks_sent.erase(p);
430 void RemoteClient::notifyEvent(ClientStateEvent event)
432 std::ostringstream myerror;
436 //intentionally do nothing
441 m_state = CS_HelloSent;
444 m_state = CS_AwaitingInit2;
447 m_state = CS_Disconnecting;
452 /* GotInit2 SetDefinitionsSent SetMediaSent */
454 myerror << "Created: Invalid client state transition! " << event;
455 throw ClientStateError(myerror.str());
459 /* don't do anything if in denied state */
465 m_state = CS_AwaitingInit2;
466 if ((chosen_mech == AUTH_MECHANISM_SRP)
467 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
468 srp_verifier_delete((SRPVerifier *) auth_data);
469 chosen_mech = AUTH_MECHANISM_NONE;
472 m_state = CS_Disconnecting;
476 if ((chosen_mech == AUTH_MECHANISM_SRP)
477 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
478 srp_verifier_delete((SRPVerifier *) auth_data);
479 chosen_mech = AUTH_MECHANISM_NONE;
482 myerror << "HelloSent: Invalid client state transition! " << event;
483 throw ClientStateError(myerror.str());
486 case CS_AwaitingInit2:
490 confirmSerializationVersion();
491 m_state = CS_InitDone;
494 m_state = CS_Disconnecting;
500 /* Init SetDefinitionsSent SetMediaSent */
502 myerror << "InitSent: Invalid client state transition! " << event;
503 throw ClientStateError(myerror.str());
510 case CSE_SetDefinitionsSent:
511 m_state = CS_DefinitionsSent;
514 m_state = CS_Disconnecting;
520 /* Init GotInit2 SetMediaSent */
522 myerror << "InitDone: Invalid client state transition! " << event;
523 throw ClientStateError(myerror.str());
526 case CS_DefinitionsSent:
529 case CSE_SetClientReady:
533 m_state = CS_Disconnecting;
538 /* Init GotInit2 SetDefinitionsSent */
540 myerror << "DefinitionsSent: Invalid client state transition! " << event;
541 throw ClientStateError(myerror.str());
551 m_state = CS_Disconnecting;
553 case CSE_SudoSuccess:
554 m_state = CS_SudoMode;
555 if ((chosen_mech == AUTH_MECHANISM_SRP)
556 || (chosen_mech == AUTH_MECHANISM_LEGACY_PASSWORD))
557 srp_verifier_delete((SRPVerifier *) auth_data);
558 chosen_mech = AUTH_MECHANISM_NONE;
560 /* Init GotInit2 SetDefinitionsSent SetMediaSent SetDenied */
562 myerror << "Active: Invalid client state transition! " << event;
563 throw ClientStateError(myerror.str());
574 m_state = CS_Disconnecting;
580 myerror << "Active: Invalid client state transition! " << event;
581 throw ClientStateError(myerror.str());
585 case CS_Disconnecting:
586 /* we are already disconnecting */
591 u32 RemoteClient::uptime()
593 return getTime(PRECISION_SECONDS) - m_connection_time;
596 ClientInterface::ClientInterface(con::Connection* con)
600 m_print_info_timer(0.0)
604 ClientInterface::~ClientInterface()
610 MutexAutoLock clientslock(m_clients_mutex);
612 for (UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
613 i != m_clients.end(); ++i) {
620 std::vector<u16> ClientInterface::getClientIDs(ClientState min_state)
622 std::vector<u16> reply;
623 MutexAutoLock clientslock(m_clients_mutex);
625 for(UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
626 i != m_clients.end(); ++i) {
627 if (i->second->getState() >= min_state)
628 reply.push_back(i->second->peer_id);
634 void ClientInterface::step(float dtime)
636 m_print_info_timer += dtime;
637 if(m_print_info_timer >= 30.0)
639 m_print_info_timer = 0.0;
644 void ClientInterface::UpdatePlayerList()
647 std::vector<u16> clients = getClientIDs();
648 m_clients_names.clear();
652 infostream<<"Players:"<<std::endl;
654 for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
655 RemotePlayer *player = m_env->getPlayer(*i);
660 infostream << "* " << player->getName() << "\t";
663 MutexAutoLock 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 MutexAutoLock clientslock(m_clients_mutex);
684 for(UNORDERED_MAP<u16, RemoteClient*>::iterator i = m_clients.begin();
685 i != m_clients.end(); ++i) {
686 RemoteClient *client = i->second;
688 if (client->net_proto_version != 0) {
689 m_con->Send(client->peer_id, channelnum, pkt, reliable);
694 RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
696 MutexAutoLock clientslock(m_clients_mutex);
697 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
698 // The client may not exist; clients are immediately removed if their
699 // access is denied, and this event occurs later then.
700 if (n == m_clients.end())
703 if (n->second->getState() >= state_min)
709 RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState state_min)
711 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
712 // The client may not exist; clients are immediately removed if their
713 // access is denied, and this event occurs later then.
714 if (n == m_clients.end())
717 if (n->second->getState() >= state_min)
723 ClientState ClientInterface::getClientState(u16 peer_id)
725 MutexAutoLock clientslock(m_clients_mutex);
726 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
727 // The client may not exist; clients are immediately removed if their
728 // access is denied, and this event occurs later then.
729 if (n == m_clients.end())
732 return n->second->getState();
735 void ClientInterface::setPlayerName(u16 peer_id,std::string name)
737 MutexAutoLock clientslock(m_clients_mutex);
738 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
739 // The client may not exist; clients are immediately removed if their
740 // access is denied, and this event occurs later then.
741 if (n != m_clients.end())
742 n->second->setName(name);
745 void ClientInterface::DeleteClient(u16 peer_id)
747 MutexAutoLock conlock(m_clients_mutex);
750 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
751 // The client may not exist; clients are immediately removed if their
752 // access is denied, and this event occurs later then.
753 if (n == m_clients.end())
757 Mark objects to be not known by the client
759 //TODO this should be done by client destructor!!!
760 RemoteClient *client = n->second;
762 for(std::set<u16>::iterator
763 i = client->m_known_objects.begin();
764 i != client->m_known_objects.end(); ++i)
768 ServerActiveObject* obj = m_env->getActiveObject(id);
770 if(obj && obj->m_known_by_count > 0)
771 obj->m_known_by_count--;
775 delete m_clients[peer_id];
776 m_clients.erase(peer_id);
779 void ClientInterface::CreateClient(u16 peer_id)
781 MutexAutoLock conlock(m_clients_mutex);
784 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
785 // The client shouldn't already exist
786 if (n != m_clients.end()) return;
789 RemoteClient *client = new RemoteClient();
790 client->peer_id = peer_id;
791 m_clients[client->peer_id] = client;
794 void ClientInterface::event(u16 peer_id, ClientStateEvent event)
797 MutexAutoLock clientlock(m_clients_mutex);
800 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
802 // No client to deliver event
803 if (n == m_clients.end())
805 n->second->notifyEvent(event);
808 if ((event == CSE_SetClientReady) ||
809 (event == CSE_Disconnect) ||
810 (event == CSE_SetDenied))
816 u16 ClientInterface::getProtocolVersion(u16 peer_id)
818 MutexAutoLock conlock(m_clients_mutex);
821 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
823 // No client to get version
824 if (n == m_clients.end())
827 return n->second->net_proto_version;
830 void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full)
832 MutexAutoLock conlock(m_clients_mutex);
835 UNORDERED_MAP<u16, RemoteClient*>::iterator n = m_clients.find(peer_id);
837 // No client to set versions
838 if (n == m_clients.end())
841 n->second->setVersionInfo(major,minor,patch,full);