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"
24 #include "environment.h"
25 #include "irrlichttypes_bloated.h"
29 #include "inventory.h"
33 #include "serialization.h" // For SER_FMT_VER_INVALID
35 #include "inventorymanager.h"
38 #include "util/thread.h"
39 #include "util/string.h"
40 #include "rollback_interface.h" // Needed for rollbackRevertActions()
41 #include <list> // Needed for rollbackRevertActions()
44 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
47 typedef struct lua_State lua_State;
48 class IWritableItemDefManager;
49 class IWritableNodeDefManager;
50 class IWritableCraftDefManager;
53 class IRollbackManager;
57 class ServerError : public std::exception
60 ServerError(const std::string &s)
62 m_s = "ServerError: ";
65 virtual ~ServerError() throw()
67 virtual const char * what() const throw()
77 v3f findSpawnPos(ServerMap &map);
80 class MapEditEventIgnorer
83 MapEditEventIgnorer(bool *flag):
92 ~MapEditEventIgnorer()
105 class MapEditEventAreaIgnorer
108 MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
109 m_ignorevariable(ignorevariable)
111 if(m_ignorevariable->getVolume() == 0)
112 *m_ignorevariable = a;
114 m_ignorevariable = NULL;
117 ~MapEditEventAreaIgnorer()
121 assert(m_ignorevariable->getVolume() != 0);
122 *m_ignorevariable = VoxelArea();
127 VoxelArea *m_ignorevariable;
132 class ServerThread : public SimpleThread
138 ServerThread(Server *server):
150 char name[PLAYERNAME_SIZE];
156 void PrintLine(std::ostream *s);
160 Used for queueing and sorting block transfers in containers
162 Lower priority number means higher priority.
164 struct PrioritySortedBlockTransfer
166 PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id)
168 priority = a_priority;
172 bool operator < (const PrioritySortedBlockTransfer &other) const
174 return priority < other.priority;
185 MediaRequest(const std::string &name_=""):
193 std::string sha1_digest;
195 MediaInfo(const std::string path_="",
196 const std::string sha1_digest_=""):
198 sha1_digest(sha1_digest_)
203 struct ServerSoundParams
206 std::string to_player;
214 float max_hear_distance;
223 max_hear_distance(32*BS),
227 v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
230 struct ServerPlayingSound
232 ServerSoundParams params;
233 std::set<u16> clients; // peer ids
239 // peer_id=0 means this client has no associated peer
240 // NOTE: If client is made allowed to exist while peer doesn't,
241 // this has to be set to 0 when there is no peer.
242 // Also, the client must be moved to some other container.
244 // The serialization version to use with the client
245 u8 serialization_version;
247 u16 net_proto_version;
248 // Version is stored in here after INIT before INIT2
249 u8 pending_serialization_version;
251 bool definitions_sent;
254 m_time_from_building(9999),
255 m_excess_gotblocks(0)
258 serialization_version = SER_FMT_VER_INVALID;
259 net_proto_version = 0;
260 pending_serialization_version = SER_FMT_VER_INVALID;
261 definitions_sent = false;
262 m_nearest_unsent_d = 0;
263 m_nearest_unsent_reset_timer = 0.0;
264 m_nothing_to_send_counter = 0;
265 m_nothing_to_send_pause_timer = 0;
272 Finds block that should be sent next to the client.
273 Environment should be locked when this is called.
274 dtime is used for resetting send radius at slow interval
276 void GetNextBlocks(Server *server, float dtime,
277 std::vector<PrioritySortedBlockTransfer> &dest);
279 void GotBlock(v3s16 p);
281 void SentBlock(v3s16 p);
283 void SetBlockNotSent(v3s16 p);
284 void SetBlocksNotSent(std::map<v3s16, MapBlock*> &blocks);
288 return m_blocks_sending.size();
291 // Increments timeouts and removes timed-out blocks from list
292 // NOTE: This doesn't fix the server-not-sending-block bug
293 // because it is related to emerging, not sending.
294 //void RunSendingTimeouts(float dtime, float timeout);
296 void PrintInfo(std::ostream &o)
298 o<<"RemoteClient "<<peer_id<<": "
299 <<"m_blocks_sent.size()="<<m_blocks_sent.size()
300 <<", m_blocks_sending.size()="<<m_blocks_sending.size()
301 <<", m_nearest_unsent_d="<<m_nearest_unsent_d
302 <<", m_excess_gotblocks="<<m_excess_gotblocks
304 m_excess_gotblocks = 0;
307 // Time from last placing or removing blocks
308 float m_time_from_building;
310 /*JMutex m_dig_mutex;
311 float m_dig_time_remaining;
314 v3s16 m_dig_position;*/
317 List of active objects that the client knows of.
320 std::set<u16> m_known_objects;
324 Blocks that have been sent to client.
325 - These don't have to be sent again.
326 - A block is cleared from here when client says it has
327 deleted it from it's memory
329 Key is position, value is dummy.
330 No MapBlock* is stored here because the blocks can get deleted.
332 std::set<v3s16> m_blocks_sent;
333 s16 m_nearest_unsent_d;
335 float m_nearest_unsent_reset_timer;
338 Blocks that are currently on the line.
339 This is used for throttling the sending of blocks.
340 - The size of this list is limited to some value
341 Block is added when it is sent with BLOCKDATA.
342 Block is removed when GOTBLOCKS is received.
343 Value is time from sending. (not used at the moment)
345 std::map<v3s16, float> m_blocks_sending;
348 Count of excess GotBlocks().
349 There is an excess amount because the client sometimes
350 gets a block so late that the server sends it again,
351 and the client then sends two GOTBLOCKs.
352 This is resetted by PrintInfo()
354 u32 m_excess_gotblocks;
356 // CPU usage optimization
357 u32 m_nothing_to_send_counter;
358 float m_nothing_to_send_pause_timer;
361 class Server : public con::PeerHandler, public MapEventReceiver,
362 public InventoryManager, public IGameDef,
363 public IBackgroundBlockEmerger
367 NOTE: Every public method should be thread-safe
371 const std::string &path_world,
372 const std::string &path_config,
373 const SubgameSpec &gamespec,
374 bool simple_singleplayer_mode
377 void start(unsigned short port);
379 // This is mainly a way to pass the time to the server.
380 // Actual processing is done in an another thread.
381 void step(float dtime);
382 // This is run by ServerThread and does the actual processing
385 void ProcessData(u8 *data, u32 datasize, u16 peer_id);
387 std::list<PlayerInfo> getPlayerInfo();
389 // Environment must be locked when called
390 void setTimeOfDay(u32 time)
392 m_env->setTimeOfDay(time);
393 m_time_of_day_send_timer = 0;
396 bool getShutdownRequested()
398 return m_shutdown_requested;
402 Shall be called with the environment locked.
403 This is accessed by the map, which is inside the environment,
404 so it shouldn't be a problem.
406 void onMapEditEvent(MapEditEvent *event);
409 Shall be called with the environment and the connection locked.
411 Inventory* getInventory(const InventoryLocation &loc);
412 void setInventoryModified(const InventoryLocation &loc);
414 // Connection must be locked when called
415 std::wstring getStatusString();
417 void requestShutdown(void)
419 m_shutdown_requested = true;
422 // Returns -1 if failed, sound handle on success
424 s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams ¶ms);
425 void stopSound(s32 handle);
428 std::set<std::string> getPlayerEffectivePrivs(const std::string &name);
429 bool checkPriv(const std::string &name, const std::string &priv);
430 void reportPrivsModified(const std::string &name=""); // ""=all
431 void reportInventoryFormspecModified(const std::string &name);
433 // Saves g_settings to configpath given at initialization
436 void setIpBanned(const std::string &ip, const std::string &name)
438 m_banmanager.add(ip, name);
442 void unsetIpBanned(const std::string &ip_or_name)
444 m_banmanager.remove(ip_or_name);
448 std::string getBanDescription(const std::string &ip_or_name)
450 return m_banmanager.getBanDescription(ip_or_name);
453 Address getPeerAddress(u16 peer_id)
455 return m_con.GetPeerAddress(peer_id);
458 // Envlock and conlock should be locked when calling this
459 void notifyPlayer(const char *name, const std::wstring msg);
460 void notifyPlayers(const std::wstring msg);
461 void spawnParticle(const char *playername,
462 v3f pos, v3f velocity, v3f acceleration,
463 float expirationtime, float size,
464 bool collisiondetection, std::string texture);
466 void spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
467 float expirationtime, float size,
468 bool collisiondetection, std::string texture);
470 u32 addParticleSpawner(const char *playername,
471 u16 amount, float spawntime,
472 v3f minpos, v3f maxpos,
473 v3f minvel, v3f maxvel,
474 v3f minacc, v3f maxacc,
475 float minexptime, float maxexptime,
476 float minsize, float maxsize,
477 bool collisiondetection, std::string texture);
479 u32 addParticleSpawnerAll(u16 amount, float spawntime,
480 v3f minpos, v3f maxpos,
481 v3f minvel, v3f maxvel,
482 v3f minacc, v3f maxacc,
483 float minexptime, float maxexptime,
484 float minsize, float maxsize,
485 bool collisiondetection, std::string texture);
487 void deleteParticleSpawner(const char *playername, u32 id);
488 void deleteParticleSpawnerAll(u32 id);
490 void queueBlockEmerge(v3s16 blockpos, bool allow_generate);
492 // Creates or resets inventory
493 Inventory* createDetachedInventory(const std::string &name);
495 // Envlock and conlock should be locked when using Lua
496 lua_State *getLua(){ return m_lua; }
498 // Envlock should be locked when using the rollback manager
499 IRollbackManager *getRollbackManager(){ return m_rollback; }
501 //TODO: determine what (if anything) should be locked to access EmergeManager
502 EmergeManager *getEmergeManager(){ return m_emerge; }
504 // actions: time-reversed list
505 // Return value: success/failure
506 bool rollbackRevertActions(const std::list<RollbackAction> &actions,
507 std::list<std::string> *log);
509 // IGameDef interface
511 virtual IItemDefManager* getItemDefManager();
512 virtual INodeDefManager* getNodeDefManager();
513 virtual ICraftDefManager* getCraftDefManager();
514 virtual ITextureSource* getTextureSource();
515 virtual IShaderSource* getShaderSource();
516 virtual u16 allocateUnknownNodeId(const std::string &name);
517 virtual ISoundManager* getSoundManager();
518 virtual MtEventManager* getEventManager();
519 virtual IRollbackReportSink* getRollbackReportSink();
521 IWritableItemDefManager* getWritableItemDefManager();
522 IWritableNodeDefManager* getWritableNodeDefManager();
523 IWritableCraftDefManager* getWritableCraftDefManager();
525 const ModSpec* getModSpec(const std::string &modname);
526 void getModNames(std::list<std::string> &modlist);
527 std::string getBuiltinLuaPath();
529 std::string getWorldPath(){ return m_path_world; }
531 bool isSingleplayer(){ return m_simple_singleplayer_mode; }
533 void setAsyncFatalError(const std::string &error)
535 m_async_fatal_error.set(error);
538 bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
540 u32 hudAdd(Player *player, HudElement *element);
541 bool hudRemove(Player *player, u32 id);
542 bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
546 // con::PeerHandler implementation.
547 // These queue stuff to be processed by handlePeerChanges().
548 // As of now, these create and remove clients and players.
549 void peerAdded(con::Peer *peer);
550 void deletingPeer(con::Peer *peer, bool timeout);
556 static void SendMovement(con::Connection &con, u16 peer_id);
557 static void SendHP(con::Connection &con, u16 peer_id, u8 hp);
558 static void SendAccessDenied(con::Connection &con, u16 peer_id,
559 const std::wstring &reason);
560 static void SendDeathscreen(con::Connection &con, u16 peer_id,
561 bool set_camera_point_target, v3f camera_point_target);
562 static void SendItemDef(con::Connection &con, u16 peer_id,
563 IItemDefManager *itemdef, u16 protocol_version);
564 static void SendNodeDef(con::Connection &con, u16 peer_id,
565 INodeDefManager *nodedef, u16 protocol_version);
568 Non-static send methods.
569 Conlock should be always used.
570 Envlock usage is documented badly but it's easy to figure out
571 which ones access the environment.
574 // Envlock and conlock should be locked when calling these
575 void SendInventory(u16 peer_id);
576 void SendChatMessage(u16 peer_id, const std::wstring &message);
577 void BroadcastChatMessage(const std::wstring &message);
578 void SendPlayerHP(u16 peer_id);
579 void SendMovePlayer(u16 peer_id);
580 void SendPlayerPrivileges(u16 peer_id);
581 void SendPlayerInventoryFormspec(u16 peer_id);
582 void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname);
583 void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
584 void SendHUDRemove(u16 peer_id, u32 id);
585 void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
587 Send a node removal/addition event to all clients except ignore_id.
588 Additionally, if far_players!=NULL, players further away than
589 far_d_nodes are ignored and their peer_ids are added to far_players
591 // Envlock and conlock should be locked when calling these
592 void sendRemoveNode(v3s16 p, u16 ignore_id=0,
593 std::list<u16> *far_players=NULL, float far_d_nodes=100);
594 void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
595 std::list<u16> *far_players=NULL, float far_d_nodes=100);
596 void setBlockNotSent(v3s16 p);
598 // Environment and Connection must be locked when called
599 void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver);
601 // Sends blocks to clients (locks env and con on its own)
602 void SendBlocks(float dtime);
604 void fillMediaCache();
605 void sendMediaAnnouncement(u16 peer_id);
606 void sendRequestedMedia(u16 peer_id,
607 const std::list<MediaRequest> &tosend);
609 void sendDetachedInventory(const std::string &name, u16 peer_id);
610 void sendDetachedInventoryToAll(const std::string &name);
611 void sendDetachedInventories(u16 peer_id);
613 // Adds a ParticleSpawner on peer with peer_id
614 void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime,
615 v3f minpos, v3f maxpos,
616 v3f minvel, v3f maxvel,
617 v3f minacc, v3f maxacc,
618 float minexptime, float maxexptime,
619 float minsize, float maxsize,
620 bool collisiondetection, std::string texture, u32 id);
622 // Adds a ParticleSpawner on all peers
623 void SendAddParticleSpawnerAll(u16 amount, float spawntime,
624 v3f minpos, v3f maxpos,
625 v3f minvel, v3f maxvel,
626 v3f minacc, v3f maxacc,
627 float minexptime, float maxexptime,
628 float minsize, float maxsize,
629 bool collisiondetection, std::string texture, u32 id);
631 // Deletes ParticleSpawner on a single client
632 void SendDeleteParticleSpawner(u16 peer_id, u32 id);
634 // Deletes ParticleSpawner on all clients
635 void SendDeleteParticleSpawnerAll(u32 id);
637 // Spawns particle on single client
638 void SendSpawnParticle(u16 peer_id,
639 v3f pos, v3f velocity, v3f acceleration,
640 float expirationtime, float size,
641 bool collisiondetection, std::string texture);
643 // Spawns particle on all clients
644 void SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
645 float expirationtime, float size,
646 bool collisiondetection, std::string texture);
652 void DiePlayer(u16 peer_id);
653 void RespawnPlayer(u16 peer_id);
655 void UpdateCrafting(u16 peer_id);
657 // When called, connection mutex should be locked
658 RemoteClient* getClient(u16 peer_id);
660 // When called, environment mutex should be locked
661 std::string getPlayerName(u16 peer_id)
663 Player *player = m_env->getPlayer(peer_id);
665 return "[id="+itos(peer_id)+"]";
666 return player->getName();
669 // When called, environment mutex should be locked
670 PlayerSAO* getPlayerSAO(u16 peer_id)
672 Player *player = m_env->getPlayer(peer_id);
675 return player->getPlayerSAO();
679 Get a player from memory or creates one.
680 If player is already connected, return NULL
681 Does not verify/modify auth info and password.
683 Call with env and con locked.
685 PlayerSAO *emergePlayer(const char *name, u16 peer_id);
687 // Locks environment and connection by its own
689 void handlePeerChange(PeerChange &c);
690 void handlePeerChanges();
697 std::string m_path_world;
698 // Path to user's configuration file ("" = no configuration file)
699 std::string m_path_config;
700 // Subgame specification
701 SubgameSpec m_gamespec;
702 // If true, do not allow multiple players and hide some multiplayer
704 bool m_simple_singleplayer_mode;
706 // Thread can set; step() will throw as ServerError
707 MutexedVariable<std::string> m_async_fatal_error;
710 float m_liquid_transform_timer;
711 float m_liquid_transform_every;
712 float m_print_info_timer;
713 float m_masterserver_timer;
714 float m_objectdata_timer;
715 float m_emergethread_trigger_timer;
716 float m_savemap_timer;
717 IntervalLimiter m_map_timer_and_unload_interval;
719 // NOTE: If connection and environment are both to be locked,
720 // environment shall be locked first.
723 ServerEnvironment *m_env;
727 con::Connection m_con;
729 // Connected clients (behind the con mutex)
730 std::map<u16, RemoteClient*> m_clients;
731 u16 m_clients_number; //for announcing masterserver
734 BanManager m_banmanager;
736 // Rollback manager (behind m_env_mutex)
737 IRollbackManager *m_rollback;
738 bool m_rollback_sink_enabled;
739 bool m_enable_rollback_recording; // Updated once in a while
742 EmergeManager *m_emerge;
745 // Envlock and conlock should be locked when using Lua
748 // Item definition manager
749 IWritableItemDefManager *m_itemdef;
751 // Node definition manager
752 IWritableNodeDefManager *m_nodedef;
754 // Craft definition manager
755 IWritableCraftDefManager *m_craftdef;
758 EventManager *m_event;
761 std::vector<ModSpec> m_mods;
767 // A buffer for time steps
768 // step() increments and AsyncRunStep() run by m_thread reads it.
770 JMutex m_step_dtime_mutex;
772 // The server mainly operates in this thread
773 ServerThread m_thread;
779 // Timer for sending time of day over network
780 float m_time_of_day_send_timer;
781 // Uptime of server in seconds
782 MutexedVariable<double> m_uptime;
786 Queues stuff from peerAdded() and deletingPeer() to
800 Queue<PeerChange> m_peer_change_queue;
806 // Mod parent directory paths
807 std::list<std::string> m_modspaths;
809 bool m_shutdown_requested;
812 Map edit event queue. Automatically receives all map edits.
813 The constructor of this class registers us to receive them through
816 NOTE: Should these be moved to actually be members of
821 Queue of map edits from the environment for sending to the clients
822 This is behind m_env_mutex
824 Queue<MapEditEvent*> m_unsent_map_edit_queue;
826 Set to true when the server itself is modifying the map and does
827 all sending of information by itself.
828 This is behind m_env_mutex
830 bool m_ignore_map_edit_events;
832 If a non-empty area, map edit events contained within are left
833 unsent. Done at map generation time to speed up editing of the
834 generated area, as it will be sent anyway.
835 This is behind m_env_mutex
837 VoxelArea m_ignore_map_edit_events_area;
839 If set to !=0, the incoming MapEditEvents are modified to have
840 this peed id as the disabled recipient
841 This is behind m_env_mutex
843 u16 m_ignore_map_edit_events_peer_id;
845 friend class EmergeThread;
846 friend class RemoteClient;
848 std::map<std::string,MediaInfo> m_media;
853 std::map<s32, ServerPlayingSound> m_playing_sounds;
857 Detached inventories (behind m_env_mutex)
860 std::map<std::string, Inventory*> m_detached_inventories;
865 std::vector<u32> m_particlespawner_ids;
869 Runs a simple dedicated server loop.
871 Shuts down when run is set to false.
873 void dedicated_server_loop(Server &server, bool &run);