X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=inline;f=src%2Fserver.h;h=168680694affe2a3e418f1f1f273d9182a88606a;hb=7701e70dc92262c41d68cf1c9f7fbd0c333e5c52;hp=f44716531f2d3c6cf49576f6ee2f64ed8bc42ac7;hpb=2424dfe007e451bb02f87884c2b272cf307d6e7c;p=minetest.git diff --git a/src/server.h b/src/server.h index f44716531..168680694 100644 --- a/src/server.h +++ b/src/server.h @@ -38,10 +38,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverenvironment.h" #include "clientiface.h" #include "chatmessage.h" +#include "translation.h" #include #include #include #include +#include class ChatEvent; struct ChatEventChat; @@ -67,9 +69,11 @@ struct SkyboxParams; struct SunParams; struct MoonParams; struct StarParams; +struct Lighting; class ServerThread; class ServerModManager; class ServerInventoryManager; +struct PackedValue; enum ClientDeletionReason { CDR_LEAVE, @@ -80,43 +84,56 @@ enum ClientDeletionReason { struct MediaInfo { std::string path; - std::string sha1_digest; + std::string sha1_digest; // base64-encoded + bool no_announce; // true: not announced in TOCLIENT_ANNOUNCE_MEDIA (at player join) MediaInfo(const std::string &path_="", const std::string &sha1_digest_=""): path(path_), - sha1_digest(sha1_digest_) + sha1_digest(sha1_digest_), + no_announce(false) { } }; -struct ServerSoundParams +// Combines the pure sound (SimpleSoundSpec) with positional information +struct ServerPlayingSound { - enum Type { - SSP_LOCAL, - SSP_POSITIONAL, - SSP_OBJECT - } type = SSP_LOCAL; - float gain = 1.0f; - float fade = 0.0f; - float pitch = 1.0f; - bool loop = false; + SoundLocation type = SoundLocation::Local; + + float gain = 1.0f; // for amplification of the base sound float max_hear_distance = 32 * BS; v3f pos; u16 object = 0; - std::string to_player = ""; - std::string exclude_player = ""; + std::string to_player; + std::string exclude_player; v3f getPos(ServerEnvironment *env, bool *pos_exists) const; -}; -struct ServerPlayingSound -{ - ServerSoundParams params; SimpleSoundSpec spec; + std::unordered_set clients; // peer ids }; +struct MinimapMode { + MinimapType type = MINIMAP_TYPE_OFF; + std::string label; + u16 size = 0; + std::string texture; + u16 scale = 1; +}; + +// structure for everything getClientInfo returns, for convenience +struct ClientInfo { + ClientState state; + Address addr; + u32 uptime; + u8 ser_vers; + u16 prot_vers; + u8 major, minor, patch; + std::string vers_string, lang_code; +}; + class Server : public con::PeerHandler, public MapEventReceiver, public IGameDef { @@ -131,7 +148,8 @@ class Server : public con::PeerHandler, public MapEventReceiver, bool simple_singleplayer_mode, Address bind_addr, bool dedicated, - ChatInterface *iface = nullptr + ChatInterface *iface = nullptr, + std::string *on_shutdown_errmsg = nullptr ); ~Server(); DISABLE_CLASS_COPY(Server); @@ -139,7 +157,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, void start(); void stop(); // This is mainly a way to pass the time to the server. - // Actual processing is done in an another thread. + // Actual processing is done in another thread. void step(float dtime); // This is run by ServerThread and does the actual processing void AsyncRunStep(bool initial_step=false); @@ -176,6 +194,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, void handleCommand_FirstSrp(NetworkPacket* pkt); void handleCommand_SrpBytesA(NetworkPacket* pkt); void handleCommand_SrpBytesM(NetworkPacket* pkt); + void handleCommand_HaveMedia(NetworkPacket *pkt); void ProcessData(NetworkPacket *pkt); @@ -198,7 +217,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, void onMapEditEvent(const MapEditEvent &event); // Connection must be locked when called - std::wstring getStatusString(); + std::string getStatusString(); inline double getUptime() const { return m_uptime_counter->get(); } // read shutdown state @@ -209,8 +228,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, // Returns -1 if failed, sound handle on success // Envlock - s32 playSound(const SimpleSoundSpec &spec, const ServerSoundParams ¶ms, - bool ephemeral=false); + s32 playSound(ServerPlayingSound ¶ms, bool ephemeral=false); void stopSound(s32 handle); void fadeSound(s32 handle, float step, float gain); @@ -236,7 +254,8 @@ class Server : public con::PeerHandler, public MapEventReceiver, void deleteParticleSpawner(const std::string &playername, u32 id); - bool dynamicAddMedia(const std::string &filepath); + bool dynamicAddMedia(std::string filepath, u32 token, + const std::string &to_player, bool ephemeral); ServerInventoryManager *getInventoryMgr() const { return m_inventory_mgr.get(); } void sendDetachedInventory(Inventory *inventory, const std::string &name, session_t peer_id); @@ -257,6 +276,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, virtual u16 allocateUnknownNodeId(const std::string &name); IRollbackManager *getRollbackManager() { return m_rollback; } virtual EmergeManager *getEmergeManager() { return m_emerge; } + virtual ModStorageDatabase *getModStorageDatabase() { return m_mod_storage_database; } IWritableItemDefManager* getWritableItemDefManager(); NodeDefManager* getWritableNodeDefManager(); @@ -264,16 +284,19 @@ class Server : public con::PeerHandler, public MapEventReceiver, virtual const std::vector &getMods() const; virtual const ModSpec* getModSpec(const std::string &modname) const; - void getModNames(std::vector &modlist); - std::string getBuiltinLuaPath(); + virtual const SubgameSpec* getGameSpec() const { return &m_gamespec; } + static std::string getBuiltinLuaPath(); virtual std::string getWorldPath() const { return m_path_world; } - virtual std::string getModStoragePath() const; - inline bool isSingleplayer() + inline bool isSingleplayer() const { return m_simple_singleplayer_mode; } inline void setAsyncFatalError(const std::string &error) { m_async_fatal_error.set(error); } + inline void setAsyncFatalError(const LuaError &e) + { + setAsyncFatalError(std::string("Lua: ") + e.what()); + } bool showFormspec(const char *name, const std::string &formspec, const std::string &formname); Map & getMap() { return m_env->getMap(); } @@ -303,36 +326,37 @@ class Server : public con::PeerHandler, public MapEventReceiver, void overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness); + void setLighting(RemotePlayer *player, const Lighting &lighting); + + void RespawnPlayer(session_t peer_id); + /* con::PeerHandler implementation. */ void peerAdded(con::Peer *peer); void deletingPeer(con::Peer *peer, bool timeout); void DenySudoAccess(session_t peer_id); - void DenyAccessVerCompliant(session_t peer_id, u16 proto_ver, AccessDeniedCode reason, - const std::string &str_reason = "", bool reconnect = false); void DenyAccess(session_t peer_id, AccessDeniedCode reason, - const std::string &custom_reason = ""); + const std::string &custom_reason = "", bool reconnect = false); void acceptAuth(session_t peer_id, bool forSudoMode); - void DenyAccess_Legacy(session_t peer_id, const std::wstring &reason); void DisconnectPeer(session_t peer_id); bool getClientConInfo(session_t peer_id, con::rtt_stat_type type, float *retval); - bool getClientInfo(session_t peer_id, ClientState *state, u32 *uptime, - u8* ser_vers, u16* prot_vers, u8* major, u8* minor, u8* patch, - std::string* vers_string, std::string* lang_code); + bool getClientInfo(session_t peer_id, ClientInfo &ret); void printToConsoleOnly(const std::string &text); - void SendPlayerHPOrDie(PlayerSAO *player, const PlayerHPChangeReason &reason); + void HandlePlayerHPChange(PlayerSAO *sao, const PlayerHPChangeReason &reason); + void SendPlayerHP(PlayerSAO *sao, bool effect); void SendPlayerBreath(PlayerSAO *sao); void SendInventory(PlayerSAO *playerSAO, bool incremental); void SendMovePlayer(session_t peer_id); void SendPlayerSpeed(session_t peer_id, const v3f &added_vel); void SendPlayerFov(session_t peer_id); - void sendDetachedInventories(session_t peer_id, bool incremental); + void SendMinimapModes(session_t peer_id, + std::vector &modes, + size_t wanted_mode); - virtual bool registerModStorage(ModMetadata *storage); - virtual void unregisterModStorage(const std::string &name); + void sendDetachedInventories(session_t peer_id, bool incremental); bool joinModChannel(const std::string &channel); bool leaveModChannel(const std::string &channel); @@ -342,8 +366,22 @@ class Server : public con::PeerHandler, public MapEventReceiver, // Send block to specific player only bool SendBlock(session_t peer_id, const v3s16 &blockpos); - // Load translations for a language - void loadTranslationLanguage(const std::string &lang_code); + // Get or load translations for a language + Translations *getTranslationLanguage(const std::string &lang_code); + + static ModStorageDatabase *openModStorageDatabase(const std::string &world_path); + + static ModStorageDatabase *openModStorageDatabase(const std::string &backend, + const std::string &world_path, const Settings &world_mt); + + static bool migrateModStorageDatabase(const GameParams &game_params, + const Settings &cmd_args); + + // Lua files registered for init of async env, pair of modname + path + std::vector> m_async_init_files; + + // Data transferred into async envs at init time + std::unique_ptr m_async_globals_data; // Bind address Address m_bind_addr; @@ -372,10 +410,25 @@ class Server : public con::PeerHandler, public MapEventReceiver, float m_timer = 0.0f; }; + struct PendingDynamicMediaCallback { + std::string filename; // only set if media entry and file is to be deleted + float expiry_timer; + std::unordered_set waiting_players; + }; + + // The standard library does not implement std::hash for pairs so we have this: + struct SBCHash { + size_t operator() (const std::pair &p) const { + return std::hash()(p.first) ^ p.second; + } + }; + + typedef std::unordered_map, std::string, SBCHash> SerializedBlockCache; + void init(); void SendMovement(session_t peer_id); - void SendHP(session_t peer_id, u16 hp); + void SendHP(session_t peer_id, u16 hp, bool effect); void SendBreath(session_t peer_id, u16 breath); void SendAccessDenied(session_t peer_id, AccessDeniedCode reason, const std::string &custom_reason, bool reconnect = false); @@ -386,13 +439,9 @@ class Server : public con::PeerHandler, public MapEventReceiver, void SendNodeDef(session_t peer_id, const NodeDefManager *nodedef, u16 protocol_version); - /* mark blocks not sent for all clients */ - void SetBlocksNotSent(std::map& block); - virtual void SendChatMessage(session_t peer_id, const ChatMessage &message); void SendTimeOfDay(session_t peer_id, u16 time, f32 time_speed); - void SendPlayerHP(session_t peer_id); void SendLocalPlayerAnimations(session_t peer_id, v2s32 animation_frames[4], f32 animation_speed); @@ -413,6 +462,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, void SendSetStars(session_t peer_id, const StarParams ¶ms); void SendCloudParams(session_t peer_id, const CloudParams ¶ms); void SendOverrideDayNightRatio(session_t peer_id, bool do_override, float ratio); + void SendSetLighting(session_t peer_id, const Lighting &lighting); void broadcastModChannelMessage(const std::string &channel, const std::string &message, session_t from_peer); @@ -427,12 +477,16 @@ class Server : public con::PeerHandler, public MapEventReceiver, void sendAddNode(v3s16 p, MapNode n, std::unordered_set *far_players = nullptr, float far_d_nodes = 100, bool remove_metadata = true); + void sendNodeChangePkt(NetworkPacket &pkt, v3s16 block_pos, + v3f p, float far_d_nodes, std::unordered_set *far_players); - void sendMetadataChanged(const std::list &meta_updates, + void sendMetadataChanged(const std::unordered_set &positions, float far_d_nodes = 100); // Environment and Connection must be locked when called - void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, u16 net_proto_version); + // `cache` may only be very short lived! (invalidation not handeled) + void SendBlockNoLock(session_t peer_id, MapBlock *block, u8 ver, + u16 net_proto_version, SerializedBlockCache *cache = nullptr); // Sends blocks to clients (locks env and con on its own) void SendBlocks(float dtime); @@ -443,6 +497,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, void sendMediaAnnouncement(session_t peer_id, const std::string &lang_code); void sendRequestedMedia(session_t peer_id, const std::vector &tosend); + void stepPendingDynMediaCallbacks(float dtime); // Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all) void SendAddParticleSpawner(session_t peer_id, u16 protocol_version, @@ -463,8 +518,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, Something random */ - void DiePlayer(session_t peer_id, const PlayerHPChangeReason &reason); - void RespawnPlayer(session_t peer_id); + void HandlePlayerDeath(PlayerSAO* sao, const PlayerHPChangeReason &reason); void DeleteClient(session_t peer_id, ClientDeletionReason reason); void UpdateCrafting(RemotePlayer *player); bool checkInteractDistance(RemotePlayer *player, const f32 d, const std::string &what); @@ -472,10 +526,8 @@ class Server : public con::PeerHandler, public MapEventReceiver, void handleChatInterfaceEvent(ChatEvent *evt); // This returns the answer to the sender of wmessage, or "" if there is none - std::wstring handleChat(const std::string &name, const std::wstring &wname, - std::wstring wmessage_input, - bool check_shout_priv = false, - RemotePlayer *player = NULL); + std::wstring handleChat(const std::string &name, std::wstring wmessage_input, + bool check_shout_priv = false, RemotePlayer *player = nullptr); void handleAdminChat(const ChatEventChat *evt); // When called, connection mutex should be locked @@ -510,6 +562,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, u16 m_max_chatmessage_length; // For "dedicated" server list flag bool m_dedicated; + Settings *m_game_settings = nullptr; // Thread can set; step() will throw as ServerError MutexedVariable m_async_fatal_error; @@ -525,6 +578,10 @@ class Server : public con::PeerHandler, public MapEventReceiver, // Environment ServerEnvironment *m_env = nullptr; + // Reference to the server map until ServerEnvironment is initialized + // after that this variable must be a nullptr + ServerMap *m_startup_server_map = nullptr; + // server connection std::shared_ptr m_con; @@ -550,12 +607,11 @@ class Server : public con::PeerHandler, public MapEventReceiver, // Craft definition manager IWritableCraftDefManager *m_craftdef; - // Event manager - EventManager *m_event; - // Mods std::unique_ptr m_modmgr; + std::unordered_map server_translations; + /* Threads */ @@ -596,6 +652,10 @@ class Server : public con::PeerHandler, public MapEventReceiver, ChatInterface *m_admin_chat; std::string m_admin_nick; + // if a mod-error occurs in the on_shutdown callback, the error message will + // be written into this + std::string *const m_on_shutdown_errmsg; + /* Map edit event queue. Automatically receives all map edits. The constructor of this class registers us to receive them through @@ -621,6 +681,10 @@ class Server : public con::PeerHandler, public MapEventReceiver, // media files known to server std::unordered_map m_media; + // pending dynamic media callbacks, clients inform the server when they have a file fetched + std::unordered_map m_pending_dyn_media; + float m_step_pending_dyn_media_timer = 0.0f; + /* Sounds */ @@ -628,7 +692,7 @@ class Server : public con::PeerHandler, public MapEventReceiver, s32 m_next_sound_id = 0; // positive values only s32 nextSoundId(); - std::unordered_map m_mod_storages; + ModStorageDatabase *m_mod_storage_database = nullptr; float m_mod_storage_save_timer = 10.0f; // CSM restrictions byteflag @@ -648,11 +712,11 @@ class Server : public con::PeerHandler, public MapEventReceiver, MetricCounterPtr m_uptime_counter; MetricGaugePtr m_player_gauge; MetricGaugePtr m_timeofday_gauge; - // current server step lag MetricGaugePtr m_lag_gauge; - MetricCounterPtr m_aom_buffer_counter; + MetricCounterPtr m_aom_buffer_counter[2]; // [0] = rel, [1] = unrel MetricCounterPtr m_packet_recv_counter; MetricCounterPtr m_packet_recv_processed_counter; + MetricCounterPtr m_map_edit_event_counter; }; /*