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