X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fserver.h;h=2e735e77c62abeded92d77f5f6f30a4fe3618a0c;hb=9b8ca3a746cdb9478a46939d36c30484a97255e1;hp=28678f59c7e4f8dbbceb638d683fda526cb3e7df;hpb=49cec3f78240ed6310a9b5dd05ce09a79ed5a12e;p=oweals%2Fminetest.git diff --git a/src/server.h b/src/server.h index 28678f59c..2e735e77c 100644 --- a/src/server.h +++ b/src/server.h @@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef SERVER_HEADER #define SERVER_HEADER -#include "connection.h" +#include "network/connection.h" #include "irr_v3d.h" #include "map.h" #include "hud.h" @@ -29,61 +29,39 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "mods.h" #include "inventorymanager.h" #include "subgame.h" -#include "rollback_interface.h" // Needed for rollbackRevertActions() +#include "tileanimation.h" // struct TileAnimationParams #include "util/numeric.h" #include "util/thread.h" -#include "environment.h" +#include "util/basic_macros.h" +#include "serverenvironment.h" +#include "chat_interface.h" +#include "clientiface.h" +#include "remoteplayer.h" +#include "network/networkpacket.h" #include #include #include #include -#define PP(x) "("<<(x).X<<","<<(x).Y<<","<<(x).Z<<")" - class IWritableItemDefManager; class IWritableNodeDefManager; class IWritableCraftDefManager; class BanManager; class EventManager; class Inventory; -class Player; class PlayerSAO; class IRollbackManager; +struct RollbackAction; class EmergeManager; -class GameScripting; +class ServerScripting; class ServerEnvironment; struct SimpleSoundSpec; +class ServerThread; - -/* - Some random functions -*/ -v3f findSpawnPos(ServerMap &map); - - -class MapEditEventIgnorer -{ -public: - MapEditEventIgnorer(bool *flag): - m_flag(flag) - { - if(*m_flag == false) - *m_flag = true; - else - m_flag = NULL; - } - - ~MapEditEventIgnorer() - { - if(m_flag) - { - assert(*m_flag); - *m_flag = false; - } - } - -private: - bool *m_flag; +enum ClientDeletionReason { + CDR_LEAVE, + CDR_TIMEOUT, + CDR_DENY }; class MapEditEventAreaIgnorer @@ -111,38 +89,13 @@ private: VoxelArea *m_ignorevariable; }; -class Server; -class ServerThread; - -/* - Used for queueing and sorting block transfers in containers - - Lower priority number means higher priority. -*/ -struct PrioritySortedBlockTransfer -{ - PrioritySortedBlockTransfer(float a_priority, v3s16 a_pos, u16 a_peer_id) - { - priority = a_priority; - pos = a_pos; - peer_id = a_peer_id; - } - bool operator < (const PrioritySortedBlockTransfer &other) const - { - return priority < other.priority; - } - float priority; - v3s16 pos; - u16 peer_id; -}; - struct MediaInfo { std::string path; std::string sha1_digest; - MediaInfo(const std::string path_="", - const std::string sha1_digest_=""): + MediaInfo(const std::string &path_="", + const std::string &sha1_digest_=""): path(path_), sha1_digest(sha1_digest_) { @@ -162,6 +115,7 @@ struct ServerSoundParams u16 object; float max_hear_distance; bool loop; + float fade; ServerSoundParams(): gain(1.0), @@ -170,7 +124,8 @@ struct ServerSoundParams pos(0,0,0), object(0), max_hear_distance(32*BS), - loop(false) + loop(false), + fade(0) {} v3f getPos(ServerEnvironment *env, bool *pos_exists) const; @@ -179,135 +134,8 @@ struct ServerSoundParams struct ServerPlayingSound { ServerSoundParams params; - std::set clients; // peer ids -}; - -class RemoteClient -{ -public: - // peer_id=0 means this client has no associated peer - // NOTE: If client is made allowed to exist while peer doesn't, - // this has to be set to 0 when there is no peer. - // Also, the client must be moved to some other container. - u16 peer_id; - // The serialization version to use with the client - u8 serialization_version; - // - u16 net_proto_version; - // Version is stored in here after INIT before INIT2 - u8 pending_serialization_version; - - bool definitions_sent; - - bool denied; - - RemoteClient(): - m_time_from_building(9999), - m_excess_gotblocks(0) - { - peer_id = 0; - serialization_version = SER_FMT_VER_INVALID; - net_proto_version = 0; - pending_serialization_version = SER_FMT_VER_INVALID; - definitions_sent = false; - denied = false; - m_nearest_unsent_d = 0; - m_nearest_unsent_reset_timer = 0.0; - m_nothing_to_send_counter = 0; - m_nothing_to_send_pause_timer = 0; - } - ~RemoteClient() - { - } - - /* - Finds block that should be sent next to the client. - Environment should be locked when this is called. - dtime is used for resetting send radius at slow interval - */ - void GetNextBlocks(Server *server, float dtime, - std::vector &dest); - - void GotBlock(v3s16 p); - - void SentBlock(v3s16 p); - - void SetBlockNotSent(v3s16 p); - void SetBlocksNotSent(std::map &blocks); - - s32 SendingCount() - { - return m_blocks_sending.size(); - } - - // Increments timeouts and removes timed-out blocks from list - // NOTE: This doesn't fix the server-not-sending-block bug - // because it is related to emerging, not sending. - //void RunSendingTimeouts(float dtime, float timeout); - - void PrintInfo(std::ostream &o) - { - o<<"RemoteClient "< &modlist); + virtual const std::vector &getMods() const { return m_mods; } + virtual const ModSpec* getModSpec(const std::string &modname) const; + void getModNames(std::vector &modlist); std::string getBuiltinLuaPath(); + virtual std::string getWorldPath() const { return m_path_world; } + virtual std::string getModStoragePath() const; - std::string getWorldPath(){ return m_path_world; } + inline bool isSingleplayer() + { return m_simple_singleplayer_mode; } - bool isSingleplayer(){ return m_simple_singleplayer_mode; } - - void setAsyncFatalError(const std::string &error) - { - m_async_fatal_error.set(error); - } + inline void setAsyncFatalError(const std::string &error) + { m_async_fatal_error.set(error); } bool showFormspec(const char *name, const std::string &formspec, const std::string &formname); Map & getMap() { return m_env->getMap(); } ServerEnvironment & getEnv() { return *m_env; } - - u32 hudAdd(Player *player, HudElement *element); - bool hudRemove(Player *player, u32 id); - bool hudChange(Player *player, u32 id, HudElementStat stat, void *value); - bool hudSetFlags(Player *player, u32 flags, u32 mask); - bool hudSetHotbarItemcount(Player *player, s32 hotbar_itemcount); - void hudSetHotbarImage(Player *player, std::string name); - void hudSetHotbarSelectedImage(Player *player, std::string name); + v3f findSpawnPos(); + + u32 hudAdd(RemotePlayer *player, HudElement *element); + bool hudRemove(RemotePlayer *player, u32 id); + bool hudChange(RemotePlayer *player, u32 id, HudElementStat stat, void *value); + bool hudSetFlags(RemotePlayer *player, u32 flags, u32 mask); + bool hudSetHotbarItemcount(RemotePlayer *player, s32 hotbar_itemcount); + s32 hudGetHotbarItemcount(RemotePlayer *player) const + { return player->getHotbarItemcount(); } + void hudSetHotbarImage(RemotePlayer *player, std::string name); + std::string hudGetHotbarImage(RemotePlayer *player); + void hudSetHotbarSelectedImage(RemotePlayer *player, std::string name); + const std::string &hudGetHotbarSelectedImage(RemotePlayer *player) const + { + return player->getHotbarSelectedImage(); + } -private: + inline Address getPeerAddress(u16 peer_id) + { return m_con.GetPeerAddress(peer_id); } + + bool setLocalPlayerAnimations(RemotePlayer *player, v2s32 animation_frames[4], + f32 frame_speed); + bool setPlayerEyeOffset(RemotePlayer *player, v3f first, v3f third); + + bool setSky(RemotePlayer *player, const video::SColor &bgcolor, + const std::string &type, const std::vector ¶ms, + bool &clouds); + bool setClouds(RemotePlayer *player, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed); - // con::PeerHandler implementation. - // These queue stuff to be processed by handlePeerChanges(). - // As of now, these create and remove clients and players. + bool overrideDayNightRatio(RemotePlayer *player, bool do_override, float brightness); + + /* con::PeerHandler implementation. */ void peerAdded(con::Peer *peer); void deletingPeer(con::Peer *peer, bool timeout); - /* - Static send methods - */ + void DenySudoAccess(u16 peer_id); + void DenyAccessVerCompliant(u16 peer_id, u16 proto_ver, AccessDeniedCode reason, + const std::string &str_reason = "", bool reconnect = false); + void DenyAccess(u16 peer_id, AccessDeniedCode reason, const std::string &custom_reason=""); + void acceptAuth(u16 peer_id, bool forSudoMode); + void DenyAccess_Legacy(u16 peer_id, const std::wstring &reason); + bool getClientConInfo(u16 peer_id, con::rtt_stat_type type,float* retval); + bool getClientInfo(u16 peer_id,ClientState* state, u32* uptime, + u8* ser_vers, u16* prot_vers, u8* major, u8* minor, u8* patch, + std::string* vers_string); + + void printToConsoleOnly(const std::string &text); + + void SendPlayerHPOrDie(PlayerSAO *player); + void SendPlayerBreath(PlayerSAO *sao); + void SendInventory(PlayerSAO* playerSAO); + void SendMovePlayer(u16 peer_id); - static void SendMovement(con::Connection &con, u16 peer_id); - static void SendHP(con::Connection &con, u16 peer_id, u8 hp); - static void SendBreath(con::Connection &con, u16 peer_id, u16 breath); - static void SendAccessDenied(con::Connection &con, u16 peer_id, - const std::wstring &reason); - static void SendDeathscreen(con::Connection &con, u16 peer_id, - bool set_camera_point_target, v3f camera_point_target); - static void SendItemDef(con::Connection &con, u16 peer_id, - IItemDefManager *itemdef, u16 protocol_version); - static void SendNodeDef(con::Connection &con, u16 peer_id, - INodeDefManager *nodedef, u16 protocol_version); + virtual bool registerModStorage(ModMetadata *storage); + virtual void unregisterModStorage(const std::string &name); + + // Bind address + Address m_bind_addr; + + // Environment mutex (envlock) + Mutex m_env_mutex; + +private: + + friend class EmergeThread; + friend class RemoteClient; + + void SendMovement(u16 peer_id); + void SendHP(u16 peer_id, u8 hp); + void SendBreath(u16 peer_id, u16 breath); + void SendAccessDenied(u16 peer_id, AccessDeniedCode reason, + const std::string &custom_reason, bool reconnect = false); + void SendAccessDenied_Legacy(u16 peer_id, const std::wstring &reason); + void SendDeathscreen(u16 peer_id,bool set_camera_point_target, v3f camera_point_target); + void SendItemDef(u16 peer_id,IItemDefManager *itemdef, u16 protocol_version); + void SendNodeDef(u16 peer_id,INodeDefManager *nodedef, u16 protocol_version); + + /* mark blocks not sent for all clients */ + void SetBlocksNotSent(std::map& block); - /* - Non-static send methods. - Conlock should be always used. - Envlock usage is documented badly but it's easy to figure out - which ones access the environment. - */ - // Envlock and conlock should be locked when calling these - void SendInventory(u16 peer_id); void SendChatMessage(u16 peer_id, const std::wstring &message); - void BroadcastChatMessage(const std::wstring &message); void SendTimeOfDay(u16 peer_id, u16 time, f32 time_speed); void SendPlayerHP(u16 peer_id); - void SendPlayerBreath(u16 peer_id); - void SendMovePlayer(u16 peer_id); + + void SendLocalPlayerAnimations(u16 peer_id, v2s32 animation_frames[4], f32 animation_speed); + void SendEyeOffset(u16 peer_id, v3f first, v3f third); void SendPlayerPrivileges(u16 peer_id); void SendPlayerInventoryFormspec(u16 peer_id); - void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname); + void SendShowFormspecMessage(u16 peer_id, const std::string &formspec, const std::string &formname); void SendHUDAdd(u16 peer_id, u32 id, HudElement *form); void SendHUDRemove(u16 peer_id, u32 id); void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value); void SendHUDSetFlags(u16 peer_id, u32 flags, u32 mask); void SendHUDSetParam(u16 peer_id, u16 param, const std::string &value); + void SendSetSky(u16 peer_id, const video::SColor &bgcolor, + const std::string &type, const std::vector ¶ms, + bool &clouds); + void SendCloudParams(u16 peer_id, float density, + const video::SColor &color_bright, + const video::SColor &color_ambient, + float height, + float thickness, + const v2f &speed); + void SendOverrideDayNightRatio(u16 peer_id, bool do_override, float ratio); /* Send a node removal/addition event to all clients except ignore_id. @@ -528,9 +428,9 @@ private: */ // Envlock and conlock should be locked when calling these void sendRemoveNode(v3s16 p, u16 ignore_id=0, - std::list *far_players=NULL, float far_d_nodes=100); + std::vector *far_players=NULL, float far_d_nodes=100); void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0, - std::list *far_players=NULL, float far_d_nodes=100, + std::vector *far_players=NULL, float far_d_nodes=100, bool remove_metadata=true); void setBlockNotSent(v3s16 p); @@ -543,67 +443,57 @@ private: void fillMediaCache(); void sendMediaAnnouncement(u16 peer_id); void sendRequestedMedia(u16 peer_id, - const std::list &tosend); + const std::vector &tosend); void sendDetachedInventory(const std::string &name, u16 peer_id); - void sendDetachedInventoryToAll(const std::string &name); void sendDetachedInventories(u16 peer_id); - // Adds a ParticleSpawner on peer with peer_id - void SendAddParticleSpawner(u16 peer_id, u16 amount, float spawntime, - v3f minpos, v3f maxpos, - v3f minvel, v3f maxvel, - v3f minacc, v3f maxacc, - float minexptime, float maxexptime, - float minsize, float maxsize, - bool collisiondetection, std::string texture, u32 id); - - // Adds a ParticleSpawner on all peers - void SendAddParticleSpawnerAll(u16 amount, float spawntime, + // Adds a ParticleSpawner on peer with peer_id (PEER_ID_INEXISTENT == all) + void SendAddParticleSpawner(u16 peer_id, u16 protocol_version, + u16 amount, float spawntime, v3f minpos, v3f maxpos, v3f minvel, v3f maxvel, v3f minacc, v3f maxacc, float minexptime, float maxexptime, float minsize, float maxsize, - bool collisiondetection, std::string texture, u32 id); + bool collisiondetection, bool collision_removal, + u16 attached_id, + bool vertical, const std::string &texture, u32 id, + const struct TileAnimationParams &animation, u8 glow); - // Deletes ParticleSpawner on a single client void SendDeleteParticleSpawner(u16 peer_id, u32 id); - // Deletes ParticleSpawner on all clients - void SendDeleteParticleSpawnerAll(u32 id); - - // Spawns particle on single client - void SendSpawnParticle(u16 peer_id, + // Spawns particle on peer with peer_id (PEER_ID_INEXISTENT == all) + void SendSpawnParticle(u16 peer_id, u16 protocol_version, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, - bool collisiondetection, std::string texture); - - // Spawns particle on all clients - void SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration, - float expirationtime, float size, - bool collisiondetection, std::string texture); + bool collisiondetection, bool collision_removal, + bool vertical, const std::string &texture, + const struct TileAnimationParams &animation, u8 glow); + u32 SendActiveObjectRemoveAdd(u16 peer_id, const std::string &datas); + void SendActiveObjectMessages(u16 peer_id, const std::string &datas, bool reliable = true); /* Something random */ void DiePlayer(u16 peer_id); void RespawnPlayer(u16 peer_id); - void DenyAccess(u16 peer_id, const std::wstring &reason); - - enum ClientDeletionReason { - CDR_LEAVE, - CDR_TIMEOUT, - CDR_DENY - }; void DeleteClient(u16 peer_id, ClientDeletionReason reason); + void UpdateCrafting(RemotePlayer *player); - void UpdateCrafting(u16 peer_id); + 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, + const std::wstring &wmessage, + bool check_shout_priv = false, + RemotePlayer *player = NULL); + void handleAdminChat(const ChatEventChat *evt); // When called, connection mutex should be locked - RemoteClient* getClient(u16 peer_id); - RemoteClient* getClientNoEx(u16 peer_id); + RemoteClient* getClient(u16 peer_id,ClientState state_min=CS_Active); + RemoteClient* getClientNoEx(u16 peer_id,ClientState state_min=CS_Active); // When called, environment mutex should be locked std::string getPlayerName(u16 peer_id); @@ -616,11 +506,8 @@ private: Call with env and con locked. */ - PlayerSAO *emergePlayer(const char *name, u16 peer_id); + PlayerSAO *emergePlayer(const char *name, u16 peer_id, u16 proto_version); - // Locks environment and connection by its own - struct PeerChange; - void handlePeerChange(PeerChange &c); void handlePeerChanges(); /* @@ -634,6 +521,9 @@ private: // If true, do not allow multiple players and hide some multiplayer // functionality bool m_simple_singleplayer_mode; + u16 m_max_chatmessage_length; + // For "dedicated" server list flag + bool m_dedicated; // Thread can set; step() will throw as ServerError MutexedVariable m_async_fatal_error; @@ -641,33 +531,22 @@ private: // Some timers float m_liquid_transform_timer; float m_liquid_transform_every; - float m_print_info_timer; float m_masterserver_timer; - float m_objectdata_timer; float m_emergethread_trigger_timer; float m_savemap_timer; IntervalLimiter m_map_timer_and_unload_interval; - // NOTE: If connection and environment are both to be locked, - // environment shall be locked first. - // Environment ServerEnvironment *m_env; - JMutex m_env_mutex; - // Connection + // server connection con::Connection m_con; - JMutex m_con_mutex; - // Connected clients (behind the con mutex) - std::map m_clients; - std::vector m_clients_names; //for announcing masterserver // Ban checking BanManager *m_banmanager; // Rollback manager (behind m_env_mutex) IRollbackManager *m_rollback; - bool m_rollback_sink_enabled; bool m_enable_rollback_recording; // Updated once in a while // Emerge manager @@ -675,7 +554,7 @@ private: // Scripting // Envlock and conlock should be locked when using Lua - GameScripting *m_script; + ServerScripting *m_script; // Item definition manager IWritableItemDefManager *m_itemdef; @@ -699,7 +578,10 @@ private: // A buffer for time steps // step() increments and AsyncRunStep() run by m_thread reads it. float m_step_dtime; - JMutex m_step_dtime_mutex; + Mutex m_step_dtime_mutex; + + // current server step lag counter + float m_lag; // The server mainly operates in this thread ServerThread *m_thread; @@ -712,33 +594,29 @@ private: float m_time_of_day_send_timer; // Uptime of server in seconds MutexedVariable m_uptime; + /* + Client interface + */ + ClientInterface m_clients; /* Peer change queue. Queues stuff from peerAdded() and deletingPeer() to handlePeerChanges() */ - enum PeerChangeType - { - PEER_ADDED, - PEER_REMOVED - }; - struct PeerChange - { - PeerChangeType type; - u16 peer_id; - bool timeout; - }; - Queue m_peer_change_queue; + std::queue m_peer_change_queue; /* Random stuff */ - // Mod parent directory paths - std::list m_modspaths; - bool m_shutdown_requested; + std::string m_shutdown_msg; + bool m_shutdown_ask_reconnect; + float m_shutdown_timer; + + ChatInterface *m_admin_chat; + std::string m_admin_nick; /* Map edit event queue. Automatically receives all map edits. @@ -753,7 +631,7 @@ private: Queue of map edits from the environment for sending to the clients This is behind m_env_mutex */ - Queue m_unsent_map_edit_queue; + std::queue m_unsent_map_edit_queue; /* Set to true when the server itself is modifying the map and does all sending of information by itself. @@ -774,15 +652,13 @@ private: */ u16 m_ignore_map_edit_events_peer_id; - friend class EmergeThread; - friend class RemoteClient; - - std::map m_media; + // media files known to server + UNORDERED_MAP m_media; /* Sounds */ - std::map m_playing_sounds; + UNORDERED_MAP m_playing_sounds; s32 m_next_sound_id; /* @@ -790,19 +666,21 @@ private: */ // key = name std::map m_detached_inventories; + // value = "" (visible to all players) or player name + std::map m_detached_inventories_player; - /* - Particles - */ - std::vector m_particlespawner_ids; + UNORDERED_MAP m_mod_storages; + float m_mod_storage_save_timer; + + DISABLE_CLASS_COPY(Server); }; /* Runs a simple dedicated server loop. - Shuts down when run is set to false. + Shuts down when kill is set to true. */ -void dedicated_server_loop(Server &server, bool &run); +void dedicated_server_loop(Server &server, bool &kill); #endif