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.
21 #include "clientiface.h"
22 #include "network/connection.h"
23 #include "network/serveropcodes.h"
24 #include "remoteplayer.h"
27 #include "serverenvironment.h"
30 #include "content_sao.h" // TODO this is used for cleanup of only
33 #include "face_position_cache.h"
35 const char *ClientInterface::statenames[] = {
50 std::string ClientInterface::state2Name(ClientState state)
52 return statenames[state];
55 void RemoteClient::ResendBlockIfOnWire(v3s16 p)
57 // if this block is on wire, mark it for sending again as soon as possible
58 if (m_blocks_sending.find(p) != m_blocks_sending.end()) {
63 void RemoteClient::GetNextBlocks (
64 ServerEnvironment *env,
65 EmergeManager * emerge,
67 std::vector<PrioritySortedBlockTransfer> &dest)
69 DSTACK(FUNCTION_NAME);
73 m_nothing_to_send_pause_timer -= dtime;
74 m_nearest_unsent_reset_timer += dtime;
76 if(m_nothing_to_send_pause_timer >= 0)
79 RemotePlayer *player = env->getPlayer(peer_id);
80 // This can happen sometimes; clients and players are not in perfect sync.
84 PlayerSAO *sao = player->getPlayerSAO();
88 // Won't send anything if already sending
89 if(m_blocks_sending.size() >= g_settings->getU16
90 ("max_simultaneous_block_sends_per_client"))
92 //infostream<<"Not sending any blocks, Queue full."<<std::endl;
96 v3f playerpos = sao->getBasePosition();
97 const v3f &playerspeed = player->getSpeed();
98 v3f playerspeeddir(0,0,0);
99 if(playerspeed.getLength() > 1.0*BS)
100 playerspeeddir = playerspeed / playerspeed.getLength();
101 // Predict to next block
102 v3f playerpos_predicted = playerpos + playerspeeddir*MAP_BLOCKSIZE*BS;
104 v3s16 center_nodepos = floatToInt(playerpos_predicted, BS);
106 v3s16 center = getNodeBlockPos(center_nodepos);
108 // Camera position and direction
109 v3f camera_pos = sao->getEyePosition();
110 v3f camera_dir = v3f(0,0,1);
111 camera_dir.rotateYZBy(sao->getPitch());
112 camera_dir.rotateXZBy(sao->getYaw());
114 /*infostream<<"camera_dir=("<<camera_dir.X<<","<<camera_dir.Y<<","
115 <<camera_dir.Z<<")"<<std::endl;*/
118 Get the starting value of the block finder radius.
121 if(m_last_center != center)
123 m_nearest_unsent_d = 0;
124 m_last_center = center;
127 /*infostream<<"m_nearest_unsent_reset_timer="
128 <<m_nearest_unsent_reset_timer<<std::endl;*/
130 // Reset periodically to workaround for some bugs or stuff
131 if(m_nearest_unsent_reset_timer > 20.0)
133 m_nearest_unsent_reset_timer = 0;
134 m_nearest_unsent_d = 0;
135 //infostream<<"Resetting m_nearest_unsent_d for "
136 // <<server->getPlayerName(peer_id)<<std::endl;
139 //s16 last_nearest_unsent_d = m_nearest_unsent_d;
140 s16 d_start = m_nearest_unsent_d;
142 //infostream<<"d_start="<<d_start<<std::endl;
144 u16 max_simul_sends_setting = g_settings->getU16
145 ("max_simultaneous_block_sends_per_client");
146 u16 max_simul_sends_usually = max_simul_sends_setting;
149 Check the time from last addNode/removeNode.
151 Decrease send rate if player is building stuff.
153 m_time_from_building += dtime;
154 if(m_time_from_building < g_settings->getFloat(
155 "full_block_send_enable_min_time_from_building"))
157 max_simul_sends_usually
158 = LIMITED_MAX_SIMULTANEOUS_BLOCK_SENDS;
162 Number of blocks sending + number of blocks selected for sending
164 u32 num_blocks_selected = m_blocks_sending.size();
167 next time d will be continued from the d from which the nearest
168 unsent block was found this time.
170 This is because not necessarily any of the blocks found this
171 time are actually sent.
173 s32 new_nearest_unsent_d = -1;
175 // get view range and camera fov from the client
176 s16 wanted_range = sao->getWantedRange();
177 float camera_fov = sao->getFov();
178 // if FOV, wanted_range are not available (old client), fall back to old default
179 if (wanted_range <= 0) wanted_range = 1000;
180 if (camera_fov <= 0) camera_fov = (72.0*M_PI/180) * 4./3.;
182 const s16 full_d_max = MYMIN(g_settings->getS16("max_block_send_distance"), wanted_range);
183 const s16 d_opt = MYMIN(g_settings->getS16("block_send_optimize_distance"), wanted_range);
184 const s16 d_blocks_in_sight = full_d_max * BS * MAP_BLOCKSIZE;
185 //infostream << "Fov from client " << camera_fov << " full_d_max " << full_d_max << std::endl;
187 s16 d_max = full_d_max;
188 s16 d_max_gen = MYMIN(g_settings->getS16("max_block_generate_distance"), wanted_range);
190 // Don't loop very much at a time
191 s16 max_d_increment_at_time = 2;
192 if(d_max > d_start + max_d_increment_at_time)
193 d_max = d_start + max_d_increment_at_time;
195 s32 nearest_emerged_d = -1;
196 s32 nearest_emergefull_d = -1;
197 s32 nearest_sent_d = -1;
198 //bool queue_is_full = false;
200 const v3s16 cam_pos_nodes = floatToInt(camera_pos, BS);
201 const bool occ_cull = g_settings->getBool("server_side_occlusion_culling");
204 for(d = d_start; d <= d_max; d++) {
206 Get the border/face dot coordinates of a "d-radiused"
209 std::vector<v3s16> list = FacePositionCache::getFacePositions(d);
211 std::vector<v3s16>::iterator li;
212 for(li = list.begin(); li != list.end(); ++li) {
213 v3s16 p = *li + center;
217 - Don't allow too many simultaneous transfers
218 - EXCEPT when the blocks are very close
220 Also, don't send blocks that are already flying.
223 // Start with the usual maximum
224 u16 max_simul_dynamic = max_simul_sends_usually;
226 // If block is very close, allow full maximum
227 if(d <= BLOCK_SEND_DISABLE_LIMITS_MAX_D)
228 max_simul_dynamic = max_simul_sends_setting;
230 // Don't select too many blocks for sending
231 if (num_blocks_selected >= max_simul_dynamic) {
232 //queue_is_full = true;
233 goto queue_full_break;
236 // Don't send blocks that are currently being transferred
237 if (m_blocks_sending.find(p) != m_blocks_sending.end())
241 Do not go over max mapgen limit
243 if (blockpos_over_max_limit(p))
246 // If this is true, inexistent block will be made from scratch
247 bool generate = d <= d_max_gen;
250 Don't generate or send if not in sight
251 FIXME This only works if the client uses a small enough
252 FOV setting. The default of 72 degrees is fine.
256 if (!isBlockInSight(p, camera_pos, camera_dir, camera_fov, d_blocks_in_sight, &dist)) {
261 Don't send already sent blocks
264 if(m_blocks_sent.find(p) != m_blocks_sent.end())
271 Check if map has this block
273 MapBlock *block = env->getMap().getBlockNoCreateNoEx(p);
275 bool surely_not_found_on_disk = false;
276 bool block_is_invalid = false;
278 // Reset usage timer, this block will be of use in the future.
279 block->resetUsageTimer();
281 // Block is dummy if data doesn't exist.
282 // It means it has been not found from disk and not generated
285 surely_not_found_on_disk = true;
288 if(block->isGenerated() == false)
289 block_is_invalid = true;
292 If block is not close, don't send it unless it is near
295 Block is near ground level if night-time mesh
296 differs from day-time mesh.
300 if(block->getDayNightDiff() == false)
304 if (occ_cull && !block_is_invalid &&
305 env->getMap().isBlockOccluded(block, cam_pos_nodes)) {
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)dist, 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;
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 u64 RemoteClient::uptime() const
593 return porting::getTimeS() - 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 (RemoteClientMap::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 (const auto &m_client : m_clients) {
626 if (m_client.second->getState() >= min_state)
627 reply.push_back(m_client.second->peer_id);
634 * Verify if user limit was reached.
635 * User limit count all clients from HelloSent state (MT protocol user) to Active state
636 * @return true if user limit was reached
638 bool ClientInterface::isUserLimitReached()
640 return getClientIDs(CS_HelloSent).size() >= g_settings->getU16("max_users");
643 void ClientInterface::step(float dtime)
645 m_print_info_timer += dtime;
646 if(m_print_info_timer >= 30.0)
648 m_print_info_timer = 0.0;
653 void ClientInterface::UpdatePlayerList()
656 std::vector<u16> clients = getClientIDs();
657 m_clients_names.clear();
661 infostream<<"Players:"<<std::endl;
663 for (std::vector<u16>::iterator i = clients.begin(); i != clients.end(); ++i) {
664 RemotePlayer *player = m_env->getPlayer(*i);
669 infostream << "* " << player->getName() << "\t";
672 MutexAutoLock clientslock(m_clients_mutex);
673 RemoteClient* client = lockedGetClientNoEx(*i);
675 client->PrintInfo(infostream);
678 m_clients_names.push_back(player->getName());
683 void ClientInterface::send(u16 peer_id, u8 channelnum,
684 NetworkPacket* pkt, bool reliable)
686 m_con->Send(peer_id, channelnum, pkt, reliable);
689 void ClientInterface::sendToAll(NetworkPacket *pkt)
691 MutexAutoLock clientslock(m_clients_mutex);
692 for (RemoteClientMap::iterator i = m_clients.begin();
693 i != m_clients.end(); ++i) {
694 RemoteClient *client = i->second;
696 if (client->net_proto_version != 0) {
697 m_con->Send(client->peer_id,
698 clientCommandFactoryTable[pkt->getCommand()].channel, pkt,
699 clientCommandFactoryTable[pkt->getCommand()].reliable);
704 void ClientInterface::sendToAllCompat(NetworkPacket *pkt, NetworkPacket *legacypkt,
707 MutexAutoLock clientslock(m_clients_mutex);
708 for (std::unordered_map<u16, RemoteClient*>::iterator i = m_clients.begin();
709 i != m_clients.end(); ++i) {
710 RemoteClient *client = i->second;
711 NetworkPacket *pkt_to_send = nullptr;
713 if (client->net_proto_version >= min_proto_ver) {
715 } else if (client->net_proto_version != 0) {
716 pkt_to_send = legacypkt;
718 warningstream << "Client with unhandled version to handle: '"
719 << client->net_proto_version << "'";
723 m_con->Send(client->peer_id,
724 clientCommandFactoryTable[pkt_to_send->getCommand()].channel,
726 clientCommandFactoryTable[pkt_to_send->getCommand()].reliable);
730 RemoteClient* ClientInterface::getClientNoEx(u16 peer_id, ClientState state_min)
732 MutexAutoLock clientslock(m_clients_mutex);
733 RemoteClientMap::const_iterator n = m_clients.find(peer_id);
734 // The client may not exist; clients are immediately removed if their
735 // access is denied, and this event occurs later then.
736 if (n == m_clients.end())
739 if (n->second->getState() >= state_min)
745 RemoteClient* ClientInterface::lockedGetClientNoEx(u16 peer_id, ClientState state_min)
747 RemoteClientMap::const_iterator n = m_clients.find(peer_id);
748 // The client may not exist; clients are immediately removed if their
749 // access is denied, and this event occurs later then.
750 if (n == m_clients.end())
753 if (n->second->getState() >= state_min)
759 ClientState ClientInterface::getClientState(u16 peer_id)
761 MutexAutoLock clientslock(m_clients_mutex);
762 RemoteClientMap::const_iterator 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())
768 return n->second->getState();
771 void ClientInterface::setPlayerName(u16 peer_id,std::string name)
773 MutexAutoLock clientslock(m_clients_mutex);
774 RemoteClientMap::iterator n = m_clients.find(peer_id);
775 // The client may not exist; clients are immediately removed if their
776 // access is denied, and this event occurs later then.
777 if (n != m_clients.end())
778 n->second->setName(name);
781 void ClientInterface::DeleteClient(u16 peer_id)
783 MutexAutoLock conlock(m_clients_mutex);
786 RemoteClientMap::iterator n = m_clients.find(peer_id);
787 // The client may not exist; clients are immediately removed if their
788 // access is denied, and this event occurs later then.
789 if (n == m_clients.end())
793 Mark objects to be not known by the client
795 //TODO this should be done by client destructor!!!
796 RemoteClient *client = n->second;
798 for (std::set<u16>::iterator i = client->m_known_objects.begin();
799 i != client->m_known_objects.end(); ++i) {
802 ServerActiveObject* obj = m_env->getActiveObject(id);
804 if(obj && obj->m_known_by_count > 0)
805 obj->m_known_by_count--;
809 delete m_clients[peer_id];
810 m_clients.erase(peer_id);
813 void ClientInterface::CreateClient(u16 peer_id)
815 MutexAutoLock conlock(m_clients_mutex);
818 RemoteClientMap::iterator n = m_clients.find(peer_id);
819 // The client shouldn't already exist
820 if (n != m_clients.end()) return;
823 RemoteClient *client = new RemoteClient();
824 client->peer_id = peer_id;
825 m_clients[client->peer_id] = client;
828 void ClientInterface::event(u16 peer_id, ClientStateEvent event)
831 MutexAutoLock clientlock(m_clients_mutex);
834 RemoteClientMap::iterator n = m_clients.find(peer_id);
836 // No client to deliver event
837 if (n == m_clients.end())
839 n->second->notifyEvent(event);
842 if ((event == CSE_SetClientReady) ||
843 (event == CSE_Disconnect) ||
844 (event == CSE_SetDenied))
850 u16 ClientInterface::getProtocolVersion(u16 peer_id)
852 MutexAutoLock conlock(m_clients_mutex);
855 RemoteClientMap::iterator n = m_clients.find(peer_id);
857 // No client to get version
858 if (n == m_clients.end())
861 return n->second->net_proto_version;
864 void ClientInterface::setClientVersion(u16 peer_id, u8 major, u8 minor, u8 patch, std::string full)
866 MutexAutoLock conlock(m_clients_mutex);
869 RemoteClientMap::iterator n = m_clients.find(peer_id);
871 // No client to set versions
872 if (n == m_clients.end())
875 n->second->setVersionInfo(major,minor,patch,full);