3 Copyright (C) 2010-2013 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.
23 #include "connection.h"
28 #include "serialization.h" // For SER_FMT_VER_INVALID
30 #include "inventorymanager.h"
32 #include "rollback_interface.h" // Needed for rollbackRevertActions()
33 #include "util/numeric.h"
34 #include "util/thread.h"
35 #include "environment.h"
41 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
43 class IWritableItemDefManager;
44 class IWritableNodeDefManager;
45 class IWritableCraftDefManager;
51 class IRollbackManager;
54 class ServerEnvironment;
55 struct SimpleSoundSpec;
61 v3f findSpawnPos(ServerMap &map);
64 class MapEditEventIgnorer
67 MapEditEventIgnorer(bool *flag):
76 ~MapEditEventIgnorer()
89 class MapEditEventAreaIgnorer
92 MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
93 m_ignorevariable(ignorevariable)
95 if(m_ignorevariable->getVolume() == 0)
96 *m_ignorevariable = a;
98 m_ignorevariable = NULL;
101 ~MapEditEventAreaIgnorer()
105 assert(m_ignorevariable->getVolume() != 0);
106 *m_ignorevariable = VoxelArea();
111 VoxelArea *m_ignorevariable;
118 Used for queueing and sorting block transfers in containers
120 Lower priority number means higher priority.
122 struct PrioritySortedBlockTransfer
124 PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
126 priority = a_priority;
130 bool operator < (const PrioritySortedBlockTransfer &other) const
132 return priority < other.priority;
142 std::string sha1_digest;
144 MediaInfo(const std::string path_="",
145 const std::string sha1_digest_=""):
147 sha1_digest(sha1_digest_)
152 struct ServerSoundParams
155 std::string to_player;
163 float max_hear_distance;
172 max_hear_distance(32*BS),
176 v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
179 struct ServerPlayingSound
181 ServerSoundParams params;
182 std::set<u16> clients; // peer ids
188 // peer_id=0 means this client has no associated peer
189 // NOTE: If client is made allowed to exist while peer doesn't,
190 // this has to be set to 0 when there is no peer.
191 // Also, the client must be moved to some other container.
193 // The serialization version to use with the client
194 u8 serialization_version;
196 u16 net_proto_version;
197 // Version is stored in here after INIT before INIT2
198 u8 pending_serialization_version;
200 bool definitions_sent;
205 m_time_from_building(9999),
206 m_excess_gotblocks(0)
209 serialization_version = SER_FMT_VER_INVALID;
210 net_proto_version = 0;
211 pending_serialization_version = SER_FMT_VER_INVALID;
212 definitions_sent = false;
214 m_nearest_unsent_d = 0;
215 m_nearest_unsent_reset_timer = 0.0;
216 m_nothing_to_send_counter = 0;
217 m_nothing_to_send_pause_timer = 0;
224 Finds block that should be sent next to the client.
225 Environment should be locked when this is called.
226 dtime is used for resetting send radius at slow interval
228 void GetNextBlocks(Server *server, float dtime,
229 std::vector<PrioritySortedBlockTransfer> &dest);
231 void GotBlock(v3s16 p);
233 void SentBlock(v3s16 p);
235 void SetBlockNotSent(v3s16 p);
236 void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks);
240 return m_blocks_sending.size();
243 // Increments timeouts and removes timed-out blocks from list
244 // NOTE: This doesn't fix the server-not-sending-block bug
245 // because it is related to emerging, not sending.
246 //void RunSendingTimeouts(float dtime, float timeout);
248 void PrintInfo(std::ostream &o)
250 o<<"RemoteClient "<<peer_id<<": "
251 <<"m_blocks_sent.size()="<<m_blocks_sent.size()
252 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
253 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
254 <<", m_excess_gotblocks="<<m_excess_gotblocks
256 m_excess_gotblocks = 0;
259 // Time from last placing or removing blocks
260 float m_time_from_building;
262 /*JMutex m_dig_mutex;
263 float m_dig_time_remaining;
266 v3s16 m_dig_position;*/
269 List of active objects that the client knows of.
272 std::set<u16> m_known_objects;
276 Blocks that have been sent to client.
277 - These don't have to be sent again.
278 - A block is cleared from here when client says it has
279 deleted it from it's memory
281 Key is position, value is dummy.
282 No MapBlock* is stored here because the blocks can get deleted.
284 std::set<v3s16> m_blocks_sent;
285 s16 m_nearest_unsent_d;
287 float m_nearest_unsent_reset_timer;
290 Blocks that are currently on the line.
291 This is used for throttling the sending of blocks.
292 - The size of this list is limited to some value
293 Block is added when it is sent with BLOCKDATA.
294 Block is removed when GOTBLOCKS is received.
295 Value is time from sending. (not used at the moment)
297 std::map<v3s16, float> m_blocks_sending;
300 Count of excess GotBlocks().
301 There is an excess amount because the client sometimes
302 gets a block so late that the server sends it again,
303 and the client then sends two GOTBLOCKs.
304 This is resetted by PrintInfo()
306 u32 m_excess_gotblocks;
308 // CPU usage optimization
309 u32 m_nothing_to_send_counter;
310 float m_nothing_to_send_pause_timer;
313 class Server : public con::PeerHandler, public MapEventReceiver,
314 public InventoryManager, public IGameDef
318 NOTE: Every public method should be thread-safe
322 const std::string &path_world,
323 const SubgameSpec &gamespec,
324 bool simple_singleplayer_mode
327 void start(unsigned short port);
329 // This is mainly a way to pass the time to the server.
330 // Actual processing is done in an another thread.
331 void step(float dtime);
332 // This is run by ServerThread and does the actual processing
335 void ProcessData(u8 *data, u32 datasize, u16 peer_id);
337 // Environment must be locked when called
338 void setTimeOfDay(u32 time);
340 bool getShutdownRequested()
342 return m_shutdown_requested;
346 Shall be called with the environment locked.
347 This is accessed by the map, which is inside the environment,
348 so it shouldn't be a problem.
350 void onMapEditEvent(MapEditEvent *event);
353 Shall be called with the environment and the connection locked.
355 Inventory* getInventory(const InventoryLocation &loc);
356 void setInventoryModified(const InventoryLocation &loc);
358 // Connection must be locked when called
359 std::wstring getStatusString();
361 void requestShutdown(void)
363 m_shutdown_requested = true;
366 // Returns -1 if failed, sound handle on success
368 s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams ¶ms);
369 void stopSound(s32 handle);
372 std::set<std::string> getPlayerEffectivePrivs(const std::string &name);
373 bool checkPriv(const std::string &name, const std::string &priv);
374 void reportPrivsModified(const std::string &name=""); // ""=all
375 void reportInventoryFormspecModified(const std::string &name);
377 void setIpBanned(const std::string &ip, const std::string &name);
378 void unsetIpBanned(const std::string &ip_or_name);
379 std::string getBanDescription(const std::string &ip_or_name);
381 Address getPeerAddress(u16 peer_id)
383 return m_con.GetPeerAddress(peer_id);
386 // Envlock and conlock should be locked when calling this
387 void notifyPlayer(const char *name, const std::wstring msg, const bool prepend);
388 void notifyPlayers(const std::wstring msg);
389 void spawnParticle(const char *playername,
390 v3f pos, v3f velocity, v3f acceleration,
391 float expirationtime, float size,
392 bool collisiondetection, std::string texture);
394 void spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
395 float expirationtime, float size,
396 bool collisiondetection, std::string texture);
398 u32 addParticleSpawner(const char *playername,
399 u16 amount, float spawntime,
400 v3f minpos, v3f maxpos,
401 v3f minvel, v3f maxvel,
402 v3f minacc, v3f maxacc,
403 float minexptime, float maxexptime,
404 float minsize, float maxsize,
405 bool collisiondetection, std::string texture);
407 u32 addParticleSpawnerAll(u16 amount, float spawntime,
408 v3f minpos, v3f maxpos,
409 v3f minvel, v3f maxvel,
410 v3f minacc, v3f maxacc,
411 float minexptime, float maxexptime,
412 float minsize, float maxsize,
413 bool collisiondetection, std::string texture);
415 void deleteParticleSpawner(const char *playername, u32 id);
416 void deleteParticleSpawnerAll(u32 id);
418 // Creates or resets inventory
419 Inventory* createDetachedInventory(const std::string &name);
421 // Envlock and conlock should be locked when using scriptapi
422 GameScripting *getScriptIface(){ return m_script; }
424 // Envlock should be locked when using the rollback manager
425 IRollbackManager *getRollbackManager(){ return m_rollback; }
427 //TODO: determine what (if anything) should be locked to access EmergeManager
428 EmergeManager *getEmergeManager(){ return m_emerge; }
430 // actions: time-reversed list
431 // Return value: success/failure
432 bool rollbackRevertActions(const std::list<RollbackAction> &actions,
433 std::list<std::string> *log);
435 // IGameDef interface
437 virtual IItemDefManager* getItemDefManager();
438 virtual INodeDefManager* getNodeDefManager();
439 virtual ICraftDefManager* getCraftDefManager();
440 virtual ITextureSource* getTextureSource();
441 virtual IShaderSource* getShaderSource();
442 virtual u16 allocateUnknownNodeId(const std::string &name);
443 virtual ISoundManager* getSoundManager();
444 virtual MtEventManager* getEventManager();
445 virtual IRollbackReportSink* getRollbackReportSink();
447 IWritableItemDefManager* getWritableItemDefManager();
448 IWritableNodeDefManager* getWritableNodeDefManager();
449 IWritableCraftDefManager* getWritableCraftDefManager();
451 const ModSpec* getModSpec(const std::string &modname);
452 void getModNames(std::list<std::string> &modlist);
453 std::string getBuiltinLuaPath();
455 std::string getWorldPath(){ return m_path_world; }
457 bool isSingleplayer(){ return m_simple_singleplayer_mode; }
459 void setAsyncFatalError(const std::string &error)
461 m_async_fatal_error.set(error);
464 bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
465 Map & getMap() { return m_env->getMap(); }
466 ServerEnvironment & getEnv() { return *m_env; }
468 u32 hudAdd(Player *player, HudElement *element);
469 bool hudRemove(Player *player, u32 id);
470 bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
471 bool hudSetFlags(Player *player, u32 flags, u32 mask);
472 bool hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount);
473 void hudSetHotbarImage(Player *player, std::string name);
474 void hudSetHotbarSelectedImage(Player *player, std::string name);
478 // con::PeerHandler implementation.
479 // These queue stuff to be processed by handlePeerChanges().
480 // As of now, these create and remove clients and players.
481 void peerAdded(con::Peer *peer);
482 void deletingPeer(con::Peer *peer, bool timeout);
488 static void SendMovement(con::Connection &con, u16 peer_id);
489 static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
490 static void SendBreath(con::Connection &con, u16 peer_id, u16 breath);
491 static void SendAccessDenied(con::Connection &con, u16 peer_id,
492 const std::wstring &reason);
493 static void SendDeathscreen(con::Connection &con, u16 peer_id,
494 bool set_camera_point_target, v3f camera_point_target);
495 static void SendItemDef(con::Connection &con, u16 peer_id,
496 IItemDefManager *itemdef, u16 protocol_version);
497 static void SendNodeDef(con::Connection &con, u16 peer_id,
498 INodeDefManager *nodedef, u16 protocol_version);
501 Non-static send methods.
502 Conlock should be always used.
503 Envlock usage is documented badly but it's easy to figure out
504 which ones access the environment.
507 // Envlock and conlock should be locked when calling these
508 void SendInventory(u16 peer_id);
509 void SendChatMessage(u16 peer_id, const std::wstring &message);
510 void BroadcastChatMessage(const std::wstring &message);
511 void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed);
512 void SendPlayerHP(u16 peer_id);
513 void SendPlayerBreath(u16 peer_id);
514 void SendMovePlayer(u16 peer_id);
515 void SendPlayerPrivileges(u16 peer_id);
516 void SendPlayerInventoryFormspec(u16 peer_id);
517 void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname);
518 void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
519 void SendHUDRemove(u16 peer_id, u32 id);
520 void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
521 void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask);
522 void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value);
525 Send a node removal/addition event to all clients except ignore_id.
526 Additionally, if far_players!=NULL, players further away than
527 far_d_nodes are ignored and their peer_ids are added to far_players
529 // Envlock and conlock should be locked when calling these
530 void sendRemoveNode(v3s16 p, u16 ignore_id=0,
531 std::list<u16> *far_players=NULL, float far_d_nodes=100);
532 void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
533 std::list<u16> *far_players=NULL, float far_d_nodes=100,
534 bool remove_metadata=true);
535 void setBlockNotSent(v3s16 p);
537 // Environment and Connection must be locked when called
538 void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto_version);
540 // Sends blocks to clients (locks env and con on its own)
541 void SendBlocks(float dtime);
543 void fillMediaCache();
544 void sendMediaAnnouncement(u16 peer_id);
545 void sendRequestedMedia(u16 peer_id,
546 const std::list<std::string> &tosend);
548 void sendDetachedInventory(const std::string &name, u16 peer_id);
549 void sendDetachedInventoryToAll(const std::string &name);
550 void sendDetachedInventories(u16 peer_id);
552 // Adds a ParticleSpawner on peer with peer_id
553 void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime,
554 v3f minpos, v3f maxpos,
555 v3f minvel, v3f maxvel,
556 v3f minacc, v3f maxacc,
557 float minexptime, float maxexptime,
558 float minsize, float maxsize,
559 bool collisiondetection, std::string texture, u32 id);
561 // Adds a ParticleSpawner on all peers
562 void SendAddParticleSpawnerAll(u16 amount, float spawntime,
563 v3f minpos, v3f maxpos,
564 v3f minvel, v3f maxvel,
565 v3f minacc, v3f maxacc,
566 float minexptime, float maxexptime,
567 float minsize, float maxsize,
568 bool collisiondetection, std::string texture, u32 id);
570 // Deletes ParticleSpawner on a single client
571 void SendDeleteParticleSpawner(u16 peer_id, u32 id);
573 // Deletes ParticleSpawner on all clients
574 void SendDeleteParticleSpawnerAll(u32 id);
576 // Spawns particle on single client
577 void SendSpawnParticle(u16 peer_id,
578 v3f pos, v3f velocity, v3f acceleration,
579 float expirationtime, float size,
580 bool collisiondetection, std::string texture);
582 // Spawns particle on all clients
583 void SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
584 float expirationtime, float size,
585 bool collisiondetection, std::string texture);
591 void DiePlayer(u16 peer_id);
592 void RespawnPlayer(u16 peer_id);
593 void DenyAccess(u16 peer_id, const std::wstring &reason);
595 enum ClientDeletionReason {
600 void DeleteClient(u16 peer_id, ClientDeletionReason reason);
602 void UpdateCrafting(u16 peer_id);
604 // When called, connection mutex should be locked
605 RemoteClient* getClient(u16 peer_id);
606 RemoteClient* getClientNoEx(u16 peer_id);
608 // When called, environment mutex should be locked
609 std::string getPlayerName(u16 peer_id);
610 PlayerSAO* getPlayerSAO(u16 peer_id);
613 Get a player from memory or creates one.
614 If player is already connected, return NULL
615 Does not verify/modify auth info and password.
617 Call with env and con locked.
619 PlayerSAO *emergePlayer(const char *name, u16 peer_id);
621 // Locks environment and connection by its own
623 void handlePeerChange(PeerChange &c);
624 void handlePeerChanges();
631 std::string m_path_world;
632 // Subgame specification
633 SubgameSpec m_gamespec;
634 // If true, do not allow multiple players and hide some multiplayer
636 bool m_simple_singleplayer_mode;
638 // Thread can set; step() will throw as ServerError
639 MutexedVariable<std::string> m_async_fatal_error;
642 float m_liquid_transform_timer;
643 float m_liquid_transform_every;
644 float m_print_info_timer;
645 float m_masterserver_timer;
646 float m_objectdata_timer;
647 float m_emergethread_trigger_timer;
648 float m_savemap_timer;
649 IntervalLimiter m_map_timer_and_unload_interval;
651 // NOTE: If connection and environment are both to be locked,
652 // environment shall be locked first.
655 ServerEnvironment *m_env;
659 con::Connection m_con;
661 // Connected clients (behind the con mutex)
662 std::map<u16, RemoteClient*> m_clients;
663 std::vector<std::string> m_clients_names; //for announcing masterserver
666 BanManager *m_banmanager;
668 // Rollback manager (behind m_env_mutex)
669 IRollbackManager *m_rollback;
670 bool m_rollback_sink_enabled;
671 bool m_enable_rollback_recording; // Updated once in a while
674 EmergeManager *m_emerge;
677 // Envlock and conlock should be locked when using Lua
678 GameScripting *m_script;
680 // Item definition manager
681 IWritableItemDefManager *m_itemdef;
683 // Node definition manager
684 IWritableNodeDefManager *m_nodedef;
686 // Craft definition manager
687 IWritableCraftDefManager *m_craftdef;
690 EventManager *m_event;
693 std::vector<ModSpec> m_mods;
699 // A buffer for time steps
700 // step() increments and AsyncRunStep() run by m_thread reads it.
702 JMutex m_step_dtime_mutex;
704 // The server mainly operates in this thread
705 ServerThread *m_thread;
711 // Timer for sending time of day over network
712 float m_time_of_day_send_timer;
713 // Uptime of server in seconds
714 MutexedVariable<double> m_uptime;
718 Queues stuff from peerAdded() and deletingPeer() to
732 Queue<PeerChange> m_peer_change_queue;
738 // Mod parent directory paths
739 std::list<std::string> m_modspaths;
741 bool m_shutdown_requested;
744 Map edit event queue. Automatically receives all map edits.
745 The constructor of this class registers us to receive them through
748 NOTE: Should these be moved to actually be members of
753 Queue of map edits from the environment for sending to the clients
754 This is behind m_env_mutex
756 Queue<MapEditEvent*> m_unsent_map_edit_queue;
758 Set to true when the server itself is modifying the map and does
759 all sending of information by itself.
760 This is behind m_env_mutex
762 bool m_ignore_map_edit_events;
764 If a non-empty area, map edit events contained within are left
765 unsent. Done at map generation time to speed up editing of the
766 generated area, as it will be sent anyway.
767 This is behind m_env_mutex
769 VoxelArea m_ignore_map_edit_events_area;
771 If set to !=0, the incoming MapEditEvents are modified to have
772 this peed id as the disabled recipient
773 This is behind m_env_mutex
775 u16 m_ignore_map_edit_events_peer_id;
777 friend class EmergeThread;
778 friend class RemoteClient;
780 std::map<std::string,MediaInfo> m_media;
785 std::map<s32, ServerPlayingSound> m_playing_sounds;
789 Detached inventories (behind m_env_mutex)
792 std::map<std::string, Inventory*> m_detached_inventories;
797 std::vector<u32> m_particlespawner_ids;
801 Runs a simple dedicated server loop.
803 Shuts down when run is set to false.
805 void dedicated_server_loop(Server &server, bool &run);