3 Copyright (C) 2010-2017 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.
22 #include "activeobject.h"
23 #include "environment.h"
26 #include "server/activeobjectmgr.h"
27 #include "util/numeric.h"
39 class ServerEnvironment
;
40 class ActiveBlockModifier
;
42 class ServerActiveObject
;
44 class ServerScripting
;
47 {Active, Loading} block modifier interface.
49 These are fed into ServerEnvironment at initialization time;
50 ServerEnvironment handles deleting them.
53 class ActiveBlockModifier
56 ActiveBlockModifier() = default;
57 virtual ~ActiveBlockModifier() = default;
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
71 virtual void trigger(ServerEnvironment
*env
, v3s16 p
, MapNode n
){};
72 virtual void trigger(ServerEnvironment
*env
, v3s16 p
, MapNode n
,
73 u32 active_object_count
, u32 active_object_count_wider
){};
78 ActiveBlockModifier
*abm
;
81 ABMWithState(ActiveBlockModifier
*abm_
);
84 struct LoadingBlockModifierDef
86 // Set of contents to trigger on
87 std::set
<std::string
> trigger_contents
;
89 bool run_at_every_load
= false;
91 virtual ~LoadingBlockModifierDef() = default;
93 virtual void trigger(ServerEnvironment
*env
, v3s16 p
, MapNode n
){};
96 struct LBMContentMapping
98 typedef std::unordered_map
<content_t
, std::vector
<LoadingBlockModifierDef
*>> lbm_map
;
101 std::vector
<LoadingBlockModifierDef
*> lbm_list
;
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;
114 LBMManager() = default;
117 // Don't call this after loadIntroductionTimes() ran.
118 void addLBMDef(LoadingBlockModifierDef
*lbm_def
);
120 void loadIntroductionTimes(const std::string
×
,
121 IGameDef
*gamedef
, u32 now
);
123 // Don't call this before loadIntroductionTimes() ran.
124 std::string
createIntroductionTimesString();
126 // Don't call this before loadIntroductionTimes() ran.
127 void applyLBMs(ServerEnvironment
*env
, MapBlock
*block
, u32 stamp
);
129 // Warning: do not make this std::unordered_map, order is relevant here
130 typedef std::map
<u32
, LBMContentMapping
> lbm_lookup_map
;
133 // Once we set this to true, we can only query,
135 bool m_query_mode
= false;
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
;
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
;
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
149 lbm_lookup_map::const_iterator
getLBMsIntroducedAfter(u32 time
)
150 { return m_lbm_lookup
.lower_bound(time
); }
154 List of active blocks, used by ServerEnvironment
157 class ActiveBlockList
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
);
166 bool contains(v3s16 p
){
167 return (m_list
.find(p
) != m_list
.end());
174 std::set
<v3s16
> m_list
;
175 std::set
<v3s16
> m_abm_list
;
176 std::set
<v3s16
> m_forceloaded_list
;
182 Operation mode for ServerEnvironment::clearObjects()
184 enum ClearObjectsMode
{
185 // Load and go through every mapblock, clearing objects
186 CLEAR_OBJECTS_MODE_FULL
,
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
,
194 The server-side environment.
196 This is not thread-safe. Server uses an environment mutex.
199 typedef std::unordered_map
<u16
, ServerActiveObject
*> ServerActiveObjectMap
;
201 class ServerEnvironment
: public Environment
204 ServerEnvironment(ServerMap
*map
, ServerScripting
*scriptIface
,
205 Server
*server
, const std::string
&path_world
);
206 ~ServerEnvironment();
210 ServerMap
& getServerMap();
212 //TODO find way to remove this fct!
213 ServerScripting
* getScriptIface()
219 float getSendRecommendedInterval()
220 { return m_recommended_send_interval
; }
222 void kickAllPlayers(AccessDeniedCode reason
,
223 const std::string
&str_reason
, bool reconnect
);
225 void saveLoadedPlayers(bool force
= false);
226 void savePlayer(RemotePlayer
*player
);
227 PlayerSAO
*loadPlayer(RemotePlayer
*player
, bool *new_player
, session_t peer_id
,
228 bool is_singleplayer
);
229 void addPlayer(RemotePlayer
*player
);
230 void removePlayer(RemotePlayer
*player
);
231 bool removePlayerFromDatabase(const std::string
&name
);
234 Save and load time of day and game timer
239 u32
addParticleSpawner(float exptime
);
240 u32
addParticleSpawner(float exptime
, u16 attached_id
);
241 void deleteParticleSpawner(u32 id
, bool remove_from_object
= true);
244 External ActiveObject interface
245 -------------------------------------------
248 ServerActiveObject
* getActiveObject(u16 id
)
250 return m_ao_manager
.getActiveObject(id
);
254 Add an active object to the environment.
255 Environment handles deletion of object.
256 Object may be deleted by environment immediately.
257 If id of object is 0, assigns a free id to it.
258 Returns the id of the object.
259 Returns 0 if not added and thus deleted.
261 u16
addActiveObject(ServerActiveObject
*object
);
264 Add an active object as a static object to the corresponding
266 Caller allocates memory, ServerEnvironment frees memory.
267 Return value: true if succeeded, false if failed.
268 (note: not used, pending removal from engine)
270 //bool addActiveObjectAsStatic(ServerActiveObject *object);
273 Find out what new objects have been added to
274 inside a radius around a position
276 void getAddedActiveObjects(PlayerSAO
*playersao
, s16 radius
,
278 std::set
<u16
> ¤t_objects
,
279 std::queue
<u16
> &added_objects
);
282 Find out what new objects have been removed from
283 inside a radius around a position
285 void getRemovedActiveObjects(PlayerSAO
*playersao
, s16 radius
,
287 std::set
<u16
> ¤t_objects
,
288 std::queue
<u16
> &removed_objects
);
291 Get the next message emitted by some active object.
292 Returns false if no messages are available, true otherwise.
294 bool getActiveObjectMessage(ActiveObjectMessage
*dest
);
296 virtual void getSelectedActiveObjects(
297 const core::line3d
<f32
> &shootline_on_map
,
298 std::vector
<PointedThing
> &objects
302 Activate objects and dynamically modify for the dtime determined
303 from timestamp and additional_dtime
305 void activateBlock(MapBlock
*block
, u32 additional_dtime
=0);
308 {Active,Loading}BlockModifiers
309 -------------------------------------------
312 void addActiveBlockModifier(ActiveBlockModifier
*abm
);
313 void addLoadingBlockModifierDef(LoadingBlockModifierDef
*lbm
);
317 -------------------------------------------
320 // Script-aware node setters
321 bool setNode(v3s16 p
, const MapNode
&n
);
322 bool removeNode(v3s16 p
);
323 bool swapNode(v3s16 p
, const MapNode
&n
);
325 // Find the daylight value at pos with a Depth First Search
326 u8
findSunlight(v3s16 pos
) const;
328 // Find all active objects inside a radius around a point
329 void getObjectsInsideRadius(std::vector
<ServerActiveObject
*> &objects
, const v3f
&pos
, float radius
,
330 std::function
<bool(ServerActiveObject
*obj
)> include_obj_cb
)
332 return m_ao_manager
.getObjectsInsideRadius(pos
, radius
, objects
, include_obj_cb
);
335 // Clear objects, loading and going through every MapBlock
336 void clearObjects(ClearObjectsMode mode
);
338 // This makes stuff happen
339 void step(f32 dtime
);
341 u32
getGameTime() const { return m_game_time
; }
343 void reportMaxLagEstimate(float f
) { m_max_lag_estimate
= f
; }
344 float getMaxLagEstimate() { return m_max_lag_estimate
; }
346 std::set
<v3s16
>* getForceloadedBlocks() { return &m_active_blocks
.m_forceloaded_list
; };
348 // Sets the static object status all the active objects in the specified block
349 // This is only really needed for deleting blocks from the map
350 void setStaticForActiveObjectsInBlock(v3s16 blockpos
,
351 bool static_exists
, v3s16 static_block
=v3s16(0,0,0));
353 RemotePlayer
*getPlayer(const session_t peer_id
);
354 RemotePlayer
*getPlayer(const char* name
);
355 const std::vector
<RemotePlayer
*> getPlayers() const { return m_players
; }
356 u32
getPlayerCount() const { return m_players
.size(); }
358 static bool migratePlayersDatabase(const GameParams
&game_params
,
359 const Settings
&cmd_args
);
361 AuthDatabase
*getAuthDatabase() { return m_auth_database
; }
362 static bool migrateAuthDatabase(const GameParams
&game_params
,
363 const Settings
&cmd_args
);
367 * called if env_meta.txt doesn't exist (e.g. new world)
369 void loadDefaultMeta();
371 static PlayerDatabase
*openPlayerDatabase(const std::string
&name
,
372 const std::string
&savedir
, const Settings
&conf
);
373 static AuthDatabase
*openAuthDatabase(const std::string
&name
,
374 const std::string
&savedir
, const Settings
&conf
);
376 Internal ActiveObject interface
377 -------------------------------------------
381 Add an active object to the environment.
383 Called by addActiveObject.
385 Object may be deleted by environment immediately.
386 If id of object is 0, assigns a free id to it.
387 Returns the id of the object.
388 Returns 0 if not added and thus deleted.
390 u16
addActiveObjectRaw(ServerActiveObject
*object
, bool set_changed
, u32 dtime_s
);
393 Remove all objects that satisfy (isGone() && m_known_by_count==0)
395 void removeRemovedObjects();
398 Convert stored objects from block to active
400 void activateObjects(MapBlock
*block
, u32 dtime_s
);
403 Convert objects that are not in active blocks to static.
405 If m_known_by_count != 0, active object is not deleted, but static
406 data is still updated.
408 If force_delete is set, active object is deleted nevertheless. It
409 shall only be set so in the destructor of the environment.
411 void deactivateFarObjects(bool force_delete
);
414 A few helpers used by the three above methods
416 void deleteStaticFromBlock(
417 ServerActiveObject
*obj
, u16 id
, u32 mod_reason
, bool no_emerge
);
418 bool saveStaticToBlock(v3s16 blockpos
, u16 store_id
,
419 ServerActiveObject
*obj
, const StaticObject
&s_obj
, u32 mod_reason
);
428 ServerScripting
* m_script
;
431 // Active Object Manager
432 server::ActiveObjectMgr m_ao_manager
;
434 const std::string m_path_world
;
435 // Outgoing network message buffer for active objects
436 std::queue
<ActiveObjectMessage
> m_active_object_messages
;
438 float m_send_recommended_timer
= 0.0f
;
439 IntervalLimiter m_object_management_interval
;
440 // List of active blocks
441 ActiveBlockList m_active_blocks
;
442 IntervalLimiter m_active_blocks_management_interval
;
443 IntervalLimiter m_active_block_modifier_interval
;
444 IntervalLimiter m_active_blocks_nodemetadata_interval
;
445 // Whether the variables below have been read from file yet
446 bool m_meta_loaded
= false;
447 // Time from the beginning of the game in seconds.
448 // Incremented in step().
450 // A helper variable for incrementing the latter
451 float m_game_time_fraction_counter
= 0.0f
;
452 // Time of last clearObjects call (game time).
453 // When a mapblock older than this is loaded, its objects are cleared.
454 u32 m_last_clear_objects_time
= 0;
455 // Active block modifiers
456 std::vector
<ABMWithState
> m_abms
;
457 LBMManager m_lbm_mgr
;
458 // An interval for generally sending object positions and stuff
459 float m_recommended_send_interval
= 0.1f
;
460 // Estimate for general maximum lag as determined by server.
461 // Can raise to high values like 15s with eg. map generation mods.
462 float m_max_lag_estimate
= 0.1f
;
464 // peer_ids in here should be unique, except that there may be many 0s
465 std::vector
<RemotePlayer
*> m_players
;
467 PlayerDatabase
*m_player_database
= nullptr;
468 AuthDatabase
*m_auth_database
= nullptr;
470 // Pseudo random generator for shuffling, etc.
474 IntervalLimiter m_particle_management_interval
;
475 std::unordered_map
<u32
, float> m_particle_spawners
;
476 std::unordered_map
<u32
, u16
> m_particle_spawner_attachments
;
478 ServerActiveObject
* createSAO(ActiveObjectType type
, v3f pos
, const std::string
&data
);