]> git.lizzy.rs Git - minetest.git/blob - src/server.h
5f3905005560a26161ca66bee4420a883fa5a7d8
[minetest.git] / src / server.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #ifndef SERVER_HEADER
21 #define SERVER_HEADER
22
23 #include "network/connection.h"
24 #include "irr_v3d.h"
25 #include "map.h"
26 #include "hud.h"
27 #include "gamedef.h"
28 #include "serialization.h" // For SER_FMT_VER_INVALID
29 #include "mods.h"
30 #include "inventorymanager.h"
31 #include "subgame.h"
32 #include "util/numeric.h"
33 #include "util/thread.h"
34 #include "environment.h"
35 #include "clientiface.h"
36 #include "network/networkpacket.h"
37 #include <string>
38 #include <list>
39 #include <map>
40 #include <vector>
41
42 #define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")"
43
44 class IWritableItemDefManager;
45 class IWritableNodeDefManager;
46 class IWritableCraftDefManager;
47 class BanManager;
48 class EventManager;
49 class Inventory;
50 class Player;
51 class PlayerSAO;
52 class IRollbackManager;
53 struct RollbackAction;
54 class EmergeManager;
55 class GameScripting;
56 class ServerEnvironment;
57 struct SimpleSoundSpec;
58 class ServerThread;
59
60 enum ClientDeletionReason {
61         CDR_LEAVE,
62         CDR_TIMEOUT,
63         CDR_DENY
64 };
65
66 class MapEditEventIgnorer
67 {
68 public:
69         MapEditEventIgnorer(bool *flag):
70                 m_flag(flag)
71         {
72                 if(*m_flag == false)
73                         *m_flag = true;
74                 else
75                         m_flag = NULL;
76         }
77
78         ~MapEditEventIgnorer()
79         {
80                 if(m_flag)
81                 {
82                         assert(*m_flag);
83                         *m_flag = false;
84                 }
85         }
86
87 private:
88         bool *m_flag;
89 };
90
91 class MapEditEventAreaIgnorer
92 {
93 public:
94         MapEditEventAreaIgnorer(VoxelArea *ignorevariable, const VoxelArea &a):
95                 m_ignorevariable(ignorevariable)
96         {
97                 if(m_ignorevariable->getVolume() == 0)
98                         *m_ignorevariable = a;
99                 else
100                         m_ignorevariable = NULL;
101         }
102
103         ~MapEditEventAreaIgnorer()
104         {
105                 if(m_ignorevariable)
106                 {
107                         assert(m_ignorevariable->getVolume() != 0);
108                         *m_ignorevariable = VoxelArea();
109                 }
110         }
111
112 private:
113         VoxelArea *m_ignorevariable;
114 };
115
116 struct MediaInfo
117 {
118         std::string path;
119         std::string sha1_digest;
120
121         MediaInfo(const std::string &path_="",
122                   const std::string &sha1_digest_=""):
123                 path(path_),
124                 sha1_digest(sha1_digest_)
125         {
126         }
127 };
128
129 struct ServerSoundParams
130 {
131         float gain;
132         std::string to_player;
133         enum Type{
134                 SSP_LOCAL=0,
135                 SSP_POSITIONAL=1,
136                 SSP_OBJECT=2
137         } type;
138         v3f pos;
139         u16 object;
140         float max_hear_distance;
141         bool loop;
142
143         ServerSoundParams():
144                 gain(1.0),
145                 to_player(""),
146                 type(SSP_LOCAL),
147                 pos(0,0,0),
148                 object(0),
149                 max_hear_distance(32*BS),
150                 loop(false)
151         {}
152
153         v3f getPos(ServerEnvironment *env, bool *pos_exists) const;
154 };
155
156 struct ServerPlayingSound
157 {
158         ServerSoundParams params;
159         std::set<u16> clients; // peer ids
160 };
161
162 class Server : public con::PeerHandler, public MapEventReceiver,
163                 public InventoryManager, public IGameDef
164 {
165 public:
166         /*
167                 NOTE: Every public method should be thread-safe
168         */
169
170         Server(
171                 const std::string &path_world,
172                 const SubgameSpec &gamespec,
173                 bool simple_singleplayer_mode,
174                 bool ipv6
175         );
176         ~Server();
177         void start(Address bind_addr);
178         void stop();
179         // This is mainly a way to pass the time to the server.
180         // Actual processing is done in an another thread.
181         void step(float dtime);
182         // This is run by ServerThread and does the actual processing
183         void AsyncRunStep(bool initial_step=false);
184         void Receive();
185         PlayerSAO* StageTwoClientInit(u16 peer_id);
186
187         /*
188          * Command Handlers
189          */
190
191         void handleCommand(NetworkPacket* pkt);
192
193         void handleCommand_Null(NetworkPacket* pkt) {};
194         void handleCommand_Deprecated(NetworkPacket* pkt);
195         void handleCommand_Init(NetworkPacket* pkt);
196         void handleCommand_Init_Legacy(NetworkPacket* pkt);
197         void handleCommand_Init2(NetworkPacket* pkt);
198         void handleCommand_RequestMedia(NetworkPacket* pkt);
199         void handleCommand_ReceivedMedia(NetworkPacket* pkt);
200         void handleCommand_ClientReady(NetworkPacket* pkt);
201         void handleCommand_GotBlocks(NetworkPacket* pkt);
202         void handleCommand_PlayerPos(NetworkPacket* pkt);
203         void handleCommand_DeletedBlocks(NetworkPacket* pkt);
204         void handleCommand_InventoryAction(NetworkPacket* pkt);
205         void handleCommand_ChatMessage(NetworkPacket* pkt);
206         void handleCommand_Damage(NetworkPacket* pkt);
207         void handleCommand_Breath(NetworkPacket* pkt);
208         void handleCommand_Password(NetworkPacket* pkt);
209         void handleCommand_PlayerItem(NetworkPacket* pkt);
210         void handleCommand_Respawn(NetworkPacket* pkt);
211         void handleCommand_Interact(NetworkPacket* pkt);
212         void handleCommand_RemovedSounds(NetworkPacket* pkt);
213         void handleCommand_NodeMetaFields(NetworkPacket* pkt);
214         void handleCommand_InventoryFields(NetworkPacket* pkt);
215         void handleCommand_FirstSrp(NetworkPacket* pkt);
216         void handleCommand_SrpBytesA(NetworkPacket* pkt);
217         void handleCommand_SrpBytesM(NetworkPacket* pkt);
218
219         void ProcessData(NetworkPacket *pkt);
220
221         void Send(NetworkPacket* pkt);
222
223         // Environment must be locked when called
224         void setTimeOfDay(u32 time);
225
226         /*
227                 Shall be called with the environment locked.
228                 This is accessed by the map, which is inside the environment,
229                 so it shouldn't be a problem.
230         */
231         void onMapEditEvent(MapEditEvent *event);
232
233         /*
234                 Shall be called with the environment and the connection locked.
235         */
236         Inventory* getInventory(const InventoryLocation &loc);
237         void setInventoryModified(const InventoryLocation &loc, bool playerSend = true);
238
239         // Connection must be locked when called
240         std::wstring getStatusString();
241
242         // read shutdown state
243         inline bool getShutdownRequested()
244                         { return m_shutdown_requested; }
245
246         // request server to shutdown
247         inline void requestShutdown() { m_shutdown_requested = true; }
248         void requestShutdown(const std::string &msg, bool reconnect)
249         {
250                 m_shutdown_requested = true;
251                 m_shutdown_msg = msg;
252                 m_shutdown_ask_reconnect = reconnect;
253         }
254
255         // Returns -1 if failed, sound handle on success
256         // Envlock
257         s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams &params);
258         void stopSound(s32 handle);
259
260         // Envlock
261         std::set<std::string> getPlayerEffectivePrivs(const std::string &name);
262         bool checkPriv(const std::string &name, const std::string &priv);
263         void reportPrivsModified(const std::string &name=""); // ""=all
264         void reportInventoryFormspecModified(const std::string &name);
265
266         void setIpBanned(const std::string &ip, const std::string &name);
267         void unsetIpBanned(const std::string &ip_or_name);
268         std::string getBanDescription(const std::string &ip_or_name);
269
270         void notifyPlayer(const char *name, const std::wstring &msg);
271         void notifyPlayers(const std::wstring &msg);
272         void spawnParticle(const char *playername,
273                 v3f pos, v3f velocity, v3f acceleration,
274                 float expirationtime, float size,
275                 bool collisiondetection, bool vertical, const std::string &texture);
276
277         void spawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
278                 float expirationtime, float size,
279                 bool collisiondetection, bool vertical, const std::string &texture);
280
281         u32 addParticleSpawner(const char *playername,
282                 u16 amount, float spawntime,
283                 v3f minpos, v3f maxpos,
284                 v3f minvel, v3f maxvel,
285                 v3f minacc, v3f maxacc,
286                 float minexptime, float maxexptime,
287                 float minsize, float maxsize,
288                 bool collisiondetection, bool vertical, const std::string &texture);
289
290         u32 addParticleSpawnerAll(u16 amount, float spawntime,
291                 v3f minpos, v3f maxpos,
292                 v3f minvel, v3f maxvel,
293                 v3f minacc, v3f maxacc,
294                 float minexptime, float maxexptime,
295                 float minsize, float maxsize,
296                 bool collisiondetection, bool vertical, const std::string &texture);
297
298         void deleteParticleSpawner(const char *playername, u32 id);
299         void deleteParticleSpawnerAll(u32 id);
300
301         // Creates or resets inventory
302         Inventory* createDetachedInventory(const std::string &name);
303
304         // Envlock and conlock should be locked when using scriptapi
305         GameScripting *getScriptIface(){ return m_script; }
306
307         // actions: time-reversed list
308         // Return value: success/failure
309         bool rollbackRevertActions(const std::list<RollbackAction> &actions,
310                         std::list<std::string> *log);
311
312         // IGameDef interface
313         // Under envlock
314         virtual IItemDefManager* getItemDefManager();
315         virtual INodeDefManager* getNodeDefManager();
316         virtual ICraftDefManager* getCraftDefManager();
317         virtual ITextureSource* getTextureSource();
318         virtual IShaderSource* getShaderSource();
319         virtual u16 allocateUnknownNodeId(const std::string &name);
320         virtual ISoundManager* getSoundManager();
321         virtual MtEventManager* getEventManager();
322         virtual scene::ISceneManager* getSceneManager();
323         virtual IRollbackManager *getRollbackManager() { return m_rollback; }
324         virtual EmergeManager *getEmergeManager() { return m_emerge; }
325
326         IWritableItemDefManager* getWritableItemDefManager();
327         IWritableNodeDefManager* getWritableNodeDefManager();
328         IWritableCraftDefManager* getWritableCraftDefManager();
329
330         const ModSpec* getModSpec(const std::string &modname) const;
331         void getModNames(std::vector<std::string> &modlist);
332         std::string getBuiltinLuaPath();
333         inline std::string getWorldPath() const
334                         { return m_path_world; }
335
336         inline bool isSingleplayer()
337                         { return m_simple_singleplayer_mode; }
338
339         inline void setAsyncFatalError(const std::string &error)
340                         { m_async_fatal_error.set(error); }
341
342         bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
343         Map & getMap() { return m_env->getMap(); }
344         ServerEnvironment & getEnv() { return *m_env; }
345
346         u32 hudAdd(Player *player, HudElement *element);
347         bool hudRemove(Player *player, u32 id);
348         bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
349         bool hudSetFlags(Player *player, u32 flags, u32 mask);
350         bool hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount);
351         s32 hudGetHotbarItemcount(Player *player);
352         void hudSetHotbarImage(Player *player, std::string name);
353         std::string hudGetHotbarImage(Player *player);
354         void hudSetHotbarSelectedImage(Player *player, std::string name);
355         std::string hudGetHotbarSelectedImage(Player *player);
356
357         inline Address getPeerAddress(u16 peer_id)
358                         { return m_con.GetPeerAddress(peer_id); }
359
360         bool setLocalPlayerAnimations(Player *player, v2s32 animation_frames[4], f32 frame_speed);
361         bool setPlayerEyeOffset(Player *player, v3f first, v3f third);
362
363         bool setSky(Player *player, const video::SColor &bgcolor,
364                         const std::string &type, const std::vector<std::string> &params);
365
366         bool overrideDayNightRatio(Player *player, bool do_override,
367                         float brightness);
368
369         /* con::PeerHandler implementation. */
370         void peerAdded(con::Peer *peer);
371         void deletingPeer(con::Peer *peer, bool timeout);
372
373         void DenySudoAccess(u16 peer_id);
374         void DenyAccessVerCompliant(u16 peer_id, u16 proto_ver, AccessDeniedCode reason,
375                 const std::string &str_reason = "", bool reconnect = false);
376         void DenyAccess(u16 peer_id, AccessDeniedCode reason, const std::string &custom_reason="");
377         void acceptAuth(u16 peer_id, bool forSudoMode);
378         void DenyAccess_Legacy(u16 peer_id, const std::wstring &reason);
379         bool getClientConInfo(u16 peer_id, con::rtt_stat_type type,float* retval);
380         bool getClientInfo(u16 peer_id,ClientState* state, u32* uptime,
381                         u8* ser_vers, u16* prot_vers, u8* major, u8* minor, u8* patch,
382                         std::string* vers_string);
383
384         void SendPlayerHPOrDie(PlayerSAO *player);
385         void SendPlayerBreath(u16 peer_id);
386         void SendInventory(PlayerSAO* playerSAO);
387         void SendMovePlayer(u16 peer_id);
388
389         // Bind address
390         Address m_bind_addr;
391
392 private:
393
394         friend class EmergeThread;
395         friend class RemoteClient;
396
397         void SendMovement(u16 peer_id);
398         void SendHP(u16 peer_id, u8 hp);
399         void SendBreath(u16 peer_id, u16 breath);
400         void SendAccessDenied(u16 peer_id, AccessDeniedCode reason,
401                 const std::string &custom_reason, bool reconnect = false);
402         void SendAccessDenied_Legacy(u16 peer_id, const std::wstring &reason);
403         void SendDeathscreen(u16 peer_id,bool set_camera_point_target, v3f camera_point_target);
404         void SendItemDef(u16 peer_id,IItemDefManager *itemdef, u16 protocol_version);
405         void SendNodeDef(u16 peer_id,INodeDefManager *nodedef, u16 protocol_version);
406
407         /* mark blocks not sent for all clients */
408         void SetBlocksNotSent(std::map<v3s16, MapBlock *>& block);
409
410
411         void SendChatMessage(u16 peer_id, const std::wstring &message);
412         void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed);
413         void SendPlayerHP(u16 peer_id);
414
415         void SendLocalPlayerAnimations(u16 peer_id, v2s32 animation_frames[4], f32 animation_speed);
416         void SendEyeOffset(u16 peer_id, v3f first, v3f third);
417         void SendPlayerPrivileges(u16 peer_id);
418         void SendPlayerInventoryFormspec(u16 peer_id);
419         void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname);
420         void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
421         void SendHUDRemove(u16 peer_id, u32 id);
422         void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
423         void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask);
424         void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value);
425         void SendSetSky(u16 peer_id, const video::SColor &bgcolor,
426                         const std::string &type, const std::vector<std::string> &params);
427         void SendOverrideDayNightRatio(u16 peer_id, bool do_override, float ratio);
428
429         /*
430                 Send a node removal/addition event to all clients except ignore_id.
431                 Additionally, if far_players!=NULL, players further away than
432                 far_d_nodes are ignored and their peer_ids are added to far_players
433         */
434         // Envlock and conlock should be locked when calling these
435         void sendRemoveNode(v3s16 p, u16 ignore_id=0,
436                         std::vector<u16> *far_players=NULL, float far_d_nodes=100);
437         void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0,
438                         std::vector<u16> *far_players=NULL, float far_d_nodes=100,
439                         bool remove_metadata=true);
440         void setBlockNotSent(v3s16 p);
441
442         // Environment and Connection must be locked when called
443         void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver, u16 net_proto_version);
444
445         // Sends blocks to clients (locks env and con on its own)
446         void SendBlocks(float dtime);
447
448         void fillMediaCache();
449         void sendMediaAnnouncement(u16 peer_id);
450         void sendRequestedMedia(u16 peer_id,
451                         const std::vector<std::string> &tosend);
452
453         void sendDetachedInventory(const std::string &name, u16 peer_id);
454         void sendDetachedInventories(u16 peer_id);
455
456         // Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all)
457         void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime,
458                 v3f minpos, v3f maxpos,
459                 v3f minvel, v3f maxvel,
460                 v3f minacc, v3f maxacc,
461                 float minexptime, float maxexptime,
462                 float minsize, float maxsize,
463                 bool collisiondetection, bool vertical, std::string texture, u32 id);
464
465         void SendDeleteParticleSpawner(u16 peer_id, u32 id);
466
467         // Spawns particle on peer with peer_id (PEER_ID_INEXISTENT == all)
468         void SendSpawnParticle(u16 peer_id,
469                 v3f pos, v3f velocity, v3f acceleration,
470                 float expirationtime, float size,
471                 bool collisiondetection, bool vertical, std::string texture);
472
473         u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas);
474         void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true);
475         /*
476                 Something random
477         */
478
479         void DiePlayer(u16 peer_id);
480         void RespawnPlayer(u16 peer_id);
481         void DeleteClient(u16 peer_id, ClientDeletionReason reason);
482         void UpdateCrafting(Player *player);
483
484         v3f findSpawnPos();
485
486         // When called, connection mutex should be locked
487         RemoteClient* getClient(u16 peer_id,ClientState state_min=CS_Active);
488         RemoteClient* getClientNoEx(u16 peer_id,ClientState state_min=CS_Active);
489
490         // When called, environment mutex should be locked
491         std::string getPlayerName(u16 peer_id);
492         PlayerSAO* getPlayerSAO(u16 peer_id);
493
494         /*
495                 Get a player from memory or creates one.
496                 If player is already connected, return NULL
497                 Does not verify/modify auth info and password.
498
499                 Call with env and con locked.
500         */
501         PlayerSAO *emergePlayer(const char *name, u16 peer_id, u16 proto_version);
502
503         void handlePeerChanges();
504
505         /*
506                 Variables
507         */
508
509         // World directory
510         std::string m_path_world;
511         // Subgame specification
512         SubgameSpec m_gamespec;
513         // If true, do not allow multiple players and hide some multiplayer
514         // functionality
515         bool m_simple_singleplayer_mode;
516
517         // Thread can set; step() will throw as ServerError
518         MutexedVariable<std::string> m_async_fatal_error;
519
520         // Some timers
521         float m_liquid_transform_timer;
522         float m_liquid_transform_every;
523         float m_print_info_timer;
524         float m_masterserver_timer;
525         float m_objectdata_timer;
526         float m_emergethread_trigger_timer;
527         float m_savemap_timer;
528         IntervalLimiter m_map_timer_and_unload_interval;
529
530         // Environment
531         ServerEnvironment *m_env;
532         JMutex m_env_mutex;
533
534         // server connection
535         con::Connection m_con;
536
537         // Ban checking
538         BanManager *m_banmanager;
539
540         // Rollback manager (behind m_env_mutex)
541         IRollbackManager *m_rollback;
542         bool m_enable_rollback_recording; // Updated once in a while
543
544         // Emerge manager
545         EmergeManager *m_emerge;
546
547         // Scripting
548         // Envlock and conlock should be locked when using Lua
549         GameScripting *m_script;
550
551         // Item definition manager
552         IWritableItemDefManager *m_itemdef;
553
554         // Node definition manager
555         IWritableNodeDefManager *m_nodedef;
556
557         // Craft definition manager
558         IWritableCraftDefManager *m_craftdef;
559
560         // Event manager
561         EventManager *m_event;
562
563         // Mods
564         std::vector<ModSpec> m_mods;
565
566         /*
567                 Threads
568         */
569
570         // A buffer for time steps
571         // step() increments and AsyncRunStep() run by m_thread reads it.
572         float m_step_dtime;
573         JMutex m_step_dtime_mutex;
574
575         // current server step lag counter
576         float m_lag;
577
578         // The server mainly operates in this thread
579         ServerThread *m_thread;
580
581         /*
582                 Time related stuff
583         */
584
585         // Timer for sending time of day over network
586         float m_time_of_day_send_timer;
587         // Uptime of server in seconds
588         MutexedVariable<double> m_uptime;
589
590         /*
591          Client interface
592          */
593         ClientInterface m_clients;
594
595         /*
596                 Peer change queue.
597                 Queues stuff from peerAdded() and deletingPeer() to
598                 handlePeerChanges()
599         */
600         std::queue<con::PeerChange> m_peer_change_queue;
601
602         /*
603                 Random stuff
604         */
605
606         bool m_shutdown_requested;
607         std::string m_shutdown_msg;
608         bool m_shutdown_ask_reconnect;
609
610         /*
611                 Map edit event queue. Automatically receives all map edits.
612                 The constructor of this class registers us to receive them through
613                 onMapEditEvent
614
615                 NOTE: Should these be moved to actually be members of
616                 ServerEnvironment?
617         */
618
619         /*
620                 Queue of map edits from the environment for sending to the clients
621                 This is behind m_env_mutex
622         */
623         std::queue<MapEditEvent*> m_unsent_map_edit_queue;
624         /*
625                 Set to true when the server itself is modifying the map and does
626                 all sending of information by itself.
627                 This is behind m_env_mutex
628         */
629         bool m_ignore_map_edit_events;
630         /*
631                 If a non-empty area, map edit events contained within are left
632                 unsent. Done at map generation time to speed up editing of the
633                 generated area, as it will be sent anyway.
634                 This is behind m_env_mutex
635         */
636         VoxelArea m_ignore_map_edit_events_area;
637         /*
638                 If set to !=0, the incoming MapEditEvents are modified to have
639                 this peed id as the disabled recipient
640                 This is behind m_env_mutex
641         */
642         u16 m_ignore_map_edit_events_peer_id;
643
644         // media files known to server
645         std::map<std::string,MediaInfo> m_media;
646
647         /*
648                 Sounds
649         */
650         std::map<s32, ServerPlayingSound> m_playing_sounds;
651         s32 m_next_sound_id;
652
653         /*
654                 Detached inventories (behind m_env_mutex)
655         */
656         // key = name
657         std::map<std::string, Inventory*> m_detached_inventories;
658
659         /*
660                 Particles
661         */
662         std::vector<u32> m_particlespawner_ids;
663 };
664
665 /*
666         Runs a simple dedicated server loop.
667
668         Shuts down when run is set to false.
669 */
670 void dedicated_server_loop(Server &server, bool &run);
671
672 #endif
673