1 /* 2 Minetest 3 Copyright (C) 2010-2017 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 #pragma once 21 22 #include "activeobject.h" 23 #include "environment.h" 24 #include "mapnode.h" 25 #include "settings.h" 26 #include "server/activeobjectmgr.h" 27 #include "util/numeric.h" 28 #include <set> 29 #include <random> 30 31 class IGameDef; 32 class ServerMap; 33 struct GameParams; 34 class MapBlock; 35 class RemotePlayer; 36 class PlayerDatabase; 37 class AuthDatabase; 38 class PlayerSAO; 39 class ServerEnvironment; 40 class ActiveBlockModifier; 41 struct StaticObject; 42 class ServerActiveObject; 43 class Server; 44 class ServerScripting; 45 46 /* 47 {Active, Loading} block modifier interface. 48 49 These are fed into ServerEnvironment at initialization time; 50 ServerEnvironment handles deleting them. 51 */ 52 53 class ActiveBlockModifier 54 { 55 public: 56 ActiveBlockModifier() = default; 57 virtual ~ActiveBlockModifier() = default; 58 59 // Set of contents to trigger on 60 virtual const std::vector<std::string> &getTriggerContents() const = 0; 61 // Set of required neighbors (trigger doesn't happen if none are found) 62 // Empty = do not check neighbors 63 virtual const std::vector<std::string> &getRequiredNeighbors() const = 0; 64 // Trigger interval in seconds 65 virtual float getTriggerInterval() = 0; 66 // Random chance of (1 / return value), 0 is disallowed 67 virtual u32 getTriggerChance() = 0; 68 // Whether to modify chance to simulate time lost by an unnattended block 69 virtual bool getSimpleCatchUp() = 0; 70 // This is called usually at interval for 1/chance of the nodes trigger(ServerEnvironment * env,v3s16 p,MapNode n)71 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n){}; trigger(ServerEnvironment * env,v3s16 p,MapNode n,u32 active_object_count,u32 active_object_count_wider)72 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n, 73 u32 active_object_count, u32 active_object_count_wider){}; 74 }; 75 76 struct ABMWithState 77 { 78 ActiveBlockModifier *abm; 79 float timer = 0.0f; 80 81 ABMWithState(ActiveBlockModifier *abm_); 82 }; 83 84 struct LoadingBlockModifierDef 85 { 86 // Set of contents to trigger on 87 std::set<std::string> trigger_contents; 88 std::string name; 89 bool run_at_every_load = false; 90 91 virtual ~LoadingBlockModifierDef() = default; 92 triggerLoadingBlockModifierDef93 virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n){}; 94 }; 95 96 struct LBMContentMapping 97 { 98 typedef std::unordered_map<content_t, std::vector<LoadingBlockModifierDef *>> lbm_map; 99 lbm_map map; 100 101 std::vector<LoadingBlockModifierDef *> lbm_list; 102 103 // Needs to be separate method (not inside destructor), 104 // because the LBMContentMapping may be copied and destructed 105 // many times during operation in the lbm_lookup_map. 106 void deleteContents(); 107 void addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamedef); 108 const std::vector<LoadingBlockModifierDef *> *lookup(content_t c) const; 109 }; 110 111 class LBMManager 112 { 113 public: 114 LBMManager() = default; 115 ~LBMManager(); 116 117 // Don't call this after loadIntroductionTimes() ran. 118 void addLBMDef(LoadingBlockModifierDef *lbm_def); 119 120 void loadIntroductionTimes(const std::string ×, 121 IGameDef *gamedef, u32 now); 122 123 // Don't call this before loadIntroductionTimes() ran. 124 std::string createIntroductionTimesString(); 125 126 // Don't call this before loadIntroductionTimes() ran. 127 void applyLBMs(ServerEnvironment *env, MapBlock *block, u32 stamp); 128 129 // Warning: do not make this std::unordered_map, order is relevant here 130 typedef std::map<u32, LBMContentMapping> lbm_lookup_map; 131 132 private: 133 // Once we set this to true, we can only query, 134 // not modify 135 bool m_query_mode = false; 136 137 // For m_query_mode == false: 138 // The key of the map is the LBM def's name. 139 // TODO make this std::unordered_map 140 std::map<std::string, LoadingBlockModifierDef *> m_lbm_defs; 141 142 // For m_query_mode == true: 143 // The key of the map is the LBM def's first introduction time. 144 lbm_lookup_map m_lbm_lookup; 145 146 // Returns an iterator to the LBMs that were introduced 147 // after the given time. This is guaranteed to return 148 // valid values for everything getLBMsIntroducedAfter(u32 time)149 lbm_lookup_map::const_iterator getLBMsIntroducedAfter(u32 time) 150 { return m_lbm_lookup.lower_bound(time); } 151 }; 152 153 /* 154 List of active blocks, used by ServerEnvironment 155 */ 156 157 class ActiveBlockList 158 { 159 public: 160 void update(std::vector<PlayerSAO*> &active_players, 161 s16 active_block_range, 162 s16 active_object_range, 163 std::set<v3s16> &blocks_removed, 164 std::set<v3s16> &blocks_added); 165 contains(v3s16 p)166 bool contains(v3s16 p){ 167 return (m_list.find(p) != m_list.end()); 168 } 169 clear()170 void clear(){ 171 m_list.clear(); 172 } 173 174 std::set<v3s16> m_list; 175 std::set<v3s16> m_abm_list; 176 std::set<v3s16> m_forceloaded_list; 177 178 private: 179 }; 180 181 /* 182 Operation mode for ServerEnvironment::clearObjects() 183 */ 184 enum ClearObjectsMode { 185 // Load and go through every mapblock, clearing objects 186 CLEAR_OBJECTS_MODE_FULL, 187 188 // Clear objects immediately in loaded mapblocks; 189 // clear objects in unloaded mapblocks only when the mapblocks are next activated. 190 CLEAR_OBJECTS_MODE_QUICK, 191 }; 192 193 class ServerEnvironment : public Environment 194 { 195 public: 196 ServerEnvironment(ServerMap *map, ServerScripting *scriptIface, 197 Server *server, const std::string &path_world); 198 ~ServerEnvironment(); 199 200 Map & getMap(); 201 202 ServerMap & getServerMap(); 203 204 //TODO find way to remove this fct! getScriptIface()205 ServerScripting* getScriptIface() 206 { return m_script; } 207 getGameDef()208 Server *getGameDef() 209 { return m_server; } 210 getSendRecommendedInterval()211 float getSendRecommendedInterval() 212 { return m_recommended_send_interval; } 213 214 void kickAllPlayers(AccessDeniedCode reason, 215 const std::string &str_reason, bool reconnect); 216 // Save players 217 void saveLoadedPlayers(bool force = false); 218 void savePlayer(RemotePlayer *player); 219 PlayerSAO *loadPlayer(RemotePlayer *player, bool *new_player, session_t peer_id, 220 bool is_singleplayer); 221 void addPlayer(RemotePlayer *player); 222 void removePlayer(RemotePlayer *player); 223 bool removePlayerFromDatabase(const std::string &name); 224 225 /* 226 Save and load time of day and game timer 227 */ 228 void saveMeta(); 229 void loadMeta(); 230 231 u32 addParticleSpawner(float exptime); 232 u32 addParticleSpawner(float exptime, u16 attached_id); 233 void deleteParticleSpawner(u32 id, bool remove_from_object = true); 234 235 /* 236 External ActiveObject interface 237 ------------------------------------------- 238 */ 239 getActiveObject(u16 id)240 ServerActiveObject* getActiveObject(u16 id) 241 { 242 return m_ao_manager.getActiveObject(id); 243 } 244 245 /* 246 Add an active object to the environment. 247 Environment handles deletion of object. 248 Object may be deleted by environment immediately. 249 If id of object is 0, assigns a free id to it. 250 Returns the id of the object. 251 Returns 0 if not added and thus deleted. 252 */ 253 u16 addActiveObject(ServerActiveObject *object); 254 255 /* 256 Add an active object as a static object to the corresponding 257 MapBlock. 258 Caller allocates memory, ServerEnvironment frees memory. 259 Return value: true if succeeded, false if failed. 260 (note: not used, pending removal from engine) 261 */ 262 //bool addActiveObjectAsStatic(ServerActiveObject *object); 263 264 /* 265 Find out what new objects have been added to 266 inside a radius around a position 267 */ 268 void getAddedActiveObjects(PlayerSAO *playersao, s16 radius, 269 s16 player_radius, 270 std::set<u16> ¤t_objects, 271 std::queue<u16> &added_objects); 272 273 /* 274 Find out what new objects have been removed from 275 inside a radius around a position 276 */ 277 void getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, 278 s16 player_radius, 279 std::set<u16> ¤t_objects, 280 std::queue<u16> &removed_objects); 281 282 /* 283 Get the next message emitted by some active object. 284 Returns false if no messages are available, true otherwise. 285 */ 286 bool getActiveObjectMessage(ActiveObjectMessage *dest); 287 288 virtual void getSelectedActiveObjects( 289 const core::line3d<f32> &shootline_on_map, 290 std::vector<PointedThing> &objects 291 ); 292 293 /* 294 Activate objects and dynamically modify for the dtime determined 295 from timestamp and additional_dtime 296 */ 297 void activateBlock(MapBlock *block, u32 additional_dtime=0); 298 299 /* 300 {Active,Loading}BlockModifiers 301 ------------------------------------------- 302 */ 303 304 void addActiveBlockModifier(ActiveBlockModifier *abm); 305 void addLoadingBlockModifierDef(LoadingBlockModifierDef *lbm); 306 307 /* 308 Other stuff 309 ------------------------------------------- 310 */ 311 312 // Script-aware node setters 313 bool setNode(v3s16 p, const MapNode &n); 314 bool removeNode(v3s16 p); 315 bool swapNode(v3s16 p, const MapNode &n); 316 317 // Find the daylight value at pos with a Depth First Search 318 u8 findSunlight(v3s16 pos) const; 319 320 // Find all active objects inside a radius around a point getObjectsInsideRadius(std::vector<ServerActiveObject * > & objects,const v3f & pos,float radius,std::function<bool (ServerActiveObject * obj)> include_obj_cb)321 void getObjectsInsideRadius(std::vector<ServerActiveObject *> &objects, const v3f &pos, float radius, 322 std::function<bool(ServerActiveObject *obj)> include_obj_cb) 323 { 324 return m_ao_manager.getObjectsInsideRadius(pos, radius, objects, include_obj_cb); 325 } 326 327 // Find all active objects inside a box getObjectsInArea(std::vector<ServerActiveObject * > & objects,const aabb3f & box,std::function<bool (ServerActiveObject * obj)> include_obj_cb)328 void getObjectsInArea(std::vector<ServerActiveObject *> &objects, const aabb3f &box, 329 std::function<bool(ServerActiveObject *obj)> include_obj_cb) 330 { 331 return m_ao_manager.getObjectsInArea(box, objects, include_obj_cb); 332 } 333 334 // Clear objects, loading and going through every MapBlock 335 void clearObjects(ClearObjectsMode mode); 336 337 // This makes stuff happen 338 void step(f32 dtime); 339 getGameTime()340 u32 getGameTime() const { return m_game_time; } 341 reportMaxLagEstimate(float f)342 void reportMaxLagEstimate(float f) { m_max_lag_estimate = f; } getMaxLagEstimate()343 float getMaxLagEstimate() { return m_max_lag_estimate; } 344 getForceloadedBlocks()345 std::set<v3s16>* getForceloadedBlocks() { return &m_active_blocks.m_forceloaded_list; }; 346 347 // Sets the static object status all the active objects in the specified block 348 // This is only really needed for deleting blocks from the map 349 void setStaticForActiveObjectsInBlock(v3s16 blockpos, 350 bool static_exists, v3s16 static_block=v3s16(0,0,0)); 351 352 RemotePlayer *getPlayer(const session_t peer_id); 353 RemotePlayer *getPlayer(const char* name); getPlayers()354 const std::vector<RemotePlayer *> getPlayers() const { return m_players; } getPlayerCount()355 u32 getPlayerCount() const { return m_players.size(); } 356 357 static bool migratePlayersDatabase(const GameParams &game_params, 358 const Settings &cmd_args); 359 getAuthDatabase()360 AuthDatabase *getAuthDatabase() { return m_auth_database; } 361 static bool migrateAuthDatabase(const GameParams &game_params, 362 const Settings &cmd_args); 363 private: 364 365 /** 366 * called if env_meta.txt doesn't exist (e.g. new world) 367 */ 368 void loadDefaultMeta(); 369 370 static PlayerDatabase *openPlayerDatabase(const std::string &name, 371 const std::string &savedir, const Settings &conf); 372 static AuthDatabase *openAuthDatabase(const std::string &name, 373 const std::string &savedir, const Settings &conf); 374 /* 375 Internal ActiveObject interface 376 ------------------------------------------- 377 */ 378 379 /* 380 Add an active object to the environment. 381 382 Called by addActiveObject. 383 384 Object may be deleted by environment immediately. 385 If id of object is 0, assigns a free id to it. 386 Returns the id of the object. 387 Returns 0 if not added and thus deleted. 388 */ 389 u16 addActiveObjectRaw(ServerActiveObject *object, bool set_changed, u32 dtime_s); 390 391 /* 392 Remove all objects that satisfy (isGone() && m_known_by_count==0) 393 */ 394 void removeRemovedObjects(); 395 396 /* 397 Convert stored objects from block to active 398 */ 399 void activateObjects(MapBlock *block, u32 dtime_s); 400 401 /* 402 Convert objects that are not in active blocks to static. 403 404 If m_known_by_count != 0, active object is not deleted, but static 405 data is still updated. 406 407 If force_delete is set, active object is deleted nevertheless. It 408 shall only be set so in the destructor of the environment. 409 */ 410 void deactivateFarObjects(bool force_delete); 411 412 /* 413 A few helpers used by the three above methods 414 */ 415 void deleteStaticFromBlock( 416 ServerActiveObject *obj, u16 id, u32 mod_reason, bool no_emerge); 417 bool saveStaticToBlock(v3s16 blockpos, u16 store_id, 418 ServerActiveObject *obj, const StaticObject &s_obj, u32 mod_reason); 419 420 /* 421 Member variables 422 */ 423 424 // The map 425 ServerMap *m_map; 426 // Lua state 427 ServerScripting* m_script; 428 // Server definition 429 Server *m_server; 430 // Active Object Manager 431 server::ActiveObjectMgr m_ao_manager; 432 // World path 433 const std::string m_path_world; 434 // Outgoing network message buffer for active objects 435 std::queue<ActiveObjectMessage> m_active_object_messages; 436 // Some timers 437 float m_send_recommended_timer = 0.0f; 438 IntervalLimiter m_object_management_interval; 439 // List of active blocks 440 ActiveBlockList m_active_blocks; 441 IntervalLimiter m_active_blocks_management_interval; 442 IntervalLimiter m_active_block_modifier_interval; 443 IntervalLimiter m_active_blocks_nodemetadata_interval; 444 // Whether the variables below have been read from file yet 445 bool m_meta_loaded = false; 446 // Time from the beginning of the game in seconds. 447 // Incremented in step(). 448 u32 m_game_time = 0; 449 // A helper variable for incrementing the latter 450 float m_game_time_fraction_counter = 0.0f; 451 // Time of last clearObjects call (game time). 452 // When a mapblock older than this is loaded, its objects are cleared. 453 u32 m_last_clear_objects_time = 0; 454 // Active block modifiers 455 std::vector<ABMWithState> m_abms; 456 LBMManager m_lbm_mgr; 457 // An interval for generally sending object positions and stuff 458 float m_recommended_send_interval = 0.1f; 459 // Estimate for general maximum lag as determined by server. 460 // Can raise to high values like 15s with eg. map generation mods. 461 float m_max_lag_estimate = 0.1f; 462 463 // peer_ids in here should be unique, except that there may be many 0s 464 std::vector<RemotePlayer*> m_players; 465 466 PlayerDatabase *m_player_database = nullptr; 467 AuthDatabase *m_auth_database = nullptr; 468 469 // Pseudo random generator for shuffling, etc. 470 std::mt19937 m_rgen; 471 472 // Particles 473 IntervalLimiter m_particle_management_interval; 474 std::unordered_map<u32, float> m_particle_spawners; 475 std::unordered_map<u32, u16> m_particle_spawner_attachments; 476 477 ServerActiveObject* createSAO(ActiveObjectType type, v3f pos, const std::string &data); 478 }; 479