X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fserver.h;h=abe466b16f957e042810ff0f7d62aa03d4475f69;hb=13159c1a48690d4ede3dbabc7699ea3d49072860;hp=cd6f78c628cb704678fb2f4e1fd675df5b390a55;hpb=a26c92d7dda327f2b1483fe7250cb27580a0a039;p=dragonfireclient.git diff --git a/src/server.h b/src/server.h index cd6f78c62..abe466b16 100644 --- a/src/server.h +++ b/src/server.h @@ -1,6 +1,6 @@ /* Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Copyright (C) 2010-2011 celeron55, Perttu Ahola This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,10 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* -(c) 2010 Perttu Ahola -*/ - #ifndef SERVER_HEADER #define SERVER_HEADER @@ -28,9 +24,50 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "environment.h" #include "common_irrlicht.h" #include -#include "utility.h" #include "porting.h" +#include "map.h" +#include "inventory.h" +#include "ban.h" +#include "gamedef.h" +#include "serialization.h" // For SER_FMT_VER_INVALID +#include "mods.h" +#include "inventorymanager.h" +#include "subgame.h" +#include "sound.h" +struct LuaState; +typedef struct lua_State lua_State; +class IWritableItemDefManager; +class IWritableNodeDefManager; +class IWritableCraftDefManager; +class EventManager; +class PlayerSAO; + +class ServerError : public std::exception +{ +public: + ServerError(const std::string &s) + { + m_s = "ServerError: "; + m_s += s; + } + virtual ~ServerError() throw() + {} + virtual const char * what() const throw() + { + return m_s.c_str(); + } + std::string m_s; +}; + +/* + Some random functions +*/ +v3f findSpawnPos(ServerMap &map); +/* + A structure containing the data needed for queueing the fetching + of blocks. +*/ struct QueuedBlockEmerge { v3s16 pos; @@ -193,8 +230,6 @@ struct PlayerInfo void PrintLine(std::ostream *s); }; -u32 PIChecksum(core::list &l); - /* Used for queueing and sorting block transfers in containers @@ -217,6 +252,61 @@ struct PrioritySortedBlockTransfer u16 peer_id; }; +struct MediaRequest +{ + std::string name; + + MediaRequest(const std::string &name_=""): + name(name_) + {} +}; + +struct MediaInfo +{ + std::string path; + std::string sha1_digest; + + MediaInfo(const std::string path_="", + const std::string sha1_digest_=""): + path(path_), + sha1_digest(sha1_digest_) + { + } +}; + +struct ServerSoundParams +{ + float gain; + std::string to_player; + enum Type{ + SSP_LOCAL=0, + SSP_POSITIONAL=1, + SSP_OBJECT=2 + } type; + v3f pos; + u16 object; + float max_hear_distance; + bool loop; + + ServerSoundParams(): + gain(1.0), + to_player(""), + type(SSP_LOCAL), + pos(0,0,0), + object(0), + max_hear_distance(32*BS), + loop(false) + {} + + v3f getPos(ServerEnvironment *env, bool *pos_exists) const; +}; + +struct ServerPlayingSound +{ + ServerSoundParams params; + std::set clients; // peer ids +}; + class RemoteClient { public: @@ -227,24 +317,26 @@ class RemoteClient 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; + RemoteClient(): - m_time_from_building(9999) + 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; m_nearest_unsent_d = 0; m_nearest_unsent_reset_timer = 0.0; - - m_blocks_sent_mutex.Init(); - m_blocks_sending_mutex.Init(); - - /*m_dig_mutex.Init(); - m_dig_time_remaining = 0; - m_dig_tool_item = -1;*/ + m_nothing_to_send_counter = 0; + m_nothing_to_send_pause_timer = 0; } ~RemoteClient() { @@ -258,17 +350,6 @@ class RemoteClient void GetNextBlocks(Server *server, float dtime, core::array &dest); - /* - Connection and environment should be locked when this is called. - steps() objects of blocks not found in active_blocks, then - adds those blocks to active_blocks - */ - void SendObjectData( - Server *server, - float dtime, - core::map &stepped_blocks - ); - void GotBlock(v3s16 p); void SentBlock(v3s16 p); @@ -278,7 +359,6 @@ class RemoteClient s32 SendingCount() { - JMutexAutoLock lock(m_blocks_sending_mutex); return m_blocks_sending.size(); } @@ -289,40 +369,31 @@ class RemoteClient void PrintInfo(std::ostream &o) { - JMutexAutoLock l2(m_blocks_sent_mutex); - JMutexAutoLock l3(m_blocks_sending_mutex); o<<"RemoteClient "< (d-d/4)) - return 300; - else - return 1000; + return m_banmanager.getBanDescription(ip_or_name); } + + Address getPeerAddress(u16 peer_id) + { + return m_con.GetPeerAddress(peer_id); + } + + // Envlock and conlock should be locked when calling this + void notifyPlayer(const char *name, const std::wstring msg); + void notifyPlayers(const std::wstring msg); + + void queueBlockEmerge(v3s16 blockpos, bool allow_generate); + + // Envlock and conlock should be locked when using Lua + lua_State *getLua(){ return m_lua; } + // IGameDef interface + // Under envlock + virtual IItemDefManager* getItemDefManager(); + virtual INodeDefManager* getNodeDefManager(); + virtual ICraftDefManager* getCraftDefManager(); + virtual ITextureSource* getTextureSource(); + virtual u16 allocateUnknownNodeId(const std::string &name); + virtual ISoundManager* getSoundManager(); + virtual MtEventManager* getEventManager(); + + IWritableItemDefManager* getWritableItemDefManager(); + IWritableNodeDefManager* getWritableNodeDefManager(); + IWritableCraftDefManager* getWritableCraftDefManager(); + + const ModSpec* getModSpec(const std::string &modname); + + std::string getWorldPath(){ return m_path_world; } + + bool isSingleplayer(){ return m_simple_singleplayer_mode; } + + void setAsyncFatalError(const std::string &error) + { + m_async_fatal_error.set(error); + } + private: - // Virtual methods from con::PeerHandler. + // con::PeerHandler implementation. + // These queue stuff to be processed by handlePeerChanges(). // As of now, these create and remove clients and players. - // TODO: Make it possible to leave players on server. void peerAdded(con::Peer *peer); void deletingPeer(con::Peer *peer, bool timeout); + /* + Static send methods + */ + + static void SendHP(con::Connection &con, u16 peer_id, u8 hp); + 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); + static void SendNodeDef(con::Connection &con, u16 peer_id, + INodeDefManager *nodedef); + + /* + 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 SendObjectData(float dtime); - void SendPlayerInfos(); void SendInventory(u16 peer_id); void SendChatMessage(u16 peer_id, const std::wstring &message); void BroadcastChatMessage(const std::wstring &message); + void SendPlayerHP(u16 peer_id); + void SendMovePlayer(u16 peer_id); + void SendPlayerPrivileges(u16 peer_id); + /* + Send a node removal/addition event to all clients except ignore_id. + Additionally, if far_players!=NULL, players further away than + far_d_nodes are ignored and their peer_ids are added to far_players + */ + // Envlock and conlock should be locked when calling these + void sendRemoveNode(v3s16 p, u16 ignore_id=0, + core::list *far_players=NULL, float far_d_nodes=100); + void sendAddNode(v3s16 p, MapNode n, u16 ignore_id=0, + core::list *far_players=NULL, float far_d_nodes=100); + void setBlockNotSent(v3s16 p); - // Sends blocks to clients + // Environment and Connection must be locked when called + void SendBlockNoLock(u16 peer_id, MapBlock *block, u8 ver); + + // Sends blocks to clients (locks env and con on its own) void SendBlocks(float dtime); + void fillMediaCache(); + void sendMediaAnnouncement(u16 peer_id); + void sendRequestedMedia(u16 peer_id, + const core::list &tosend); + + /* + Something random + */ + + void DiePlayer(u16 peer_id); + void RespawnPlayer(u16 peer_id); + + void UpdateCrafting(u16 peer_id); + // When called, connection mutex should be locked RemoteClient* getClient(u16 peer_id); + + // When called, environment mutex should be locked + std::string getPlayerName(u16 peer_id) + { + Player *player = m_env->getPlayer(peer_id); + if(player == NULL) + return "[id="+itos(peer_id)+"]"; + return player->getName(); + } + + // When called, environment mutex should be locked + PlayerSAO* getPlayerSAO(u16 peer_id) + { + Player *player = m_env->getPlayer(peer_id); + if(player == NULL) + return NULL; + return player->getPlayerSAO(); + } /* - Update water pressure. - This also adds suitable nodes to active_nodes. + Get a player from memory or creates one. + If player is already connected, return NULL + Does not verify/modify auth info and password. - environment has to be locked when calling. + Call with env and con locked. */ - void UpdateBlockWaterPressure(MapBlock *block, - core::map &modified_blocks); + PlayerSAO *emergePlayer(const char *name, u16 peer_id); // Locks environment and connection by its own struct PeerChange; void handlePeerChange(PeerChange &c); void handlePeerChanges(); + + /* + Variables + */ + + // World directory + std::string m_path_world; + // Path to user's configuration file ("" = no configuration file) + std::string m_path_config; + // Subgame specification + SubgameSpec m_gamespec; + // If true, do not allow multiple players and hide some multiplayer + // functionality + bool m_simple_singleplayer_mode; + + // Thread can set; step() will throw as ServerError + MutexedVariable m_async_fatal_error; - float m_flowwater_timer; + // Some timers + float m_liquid_transform_timer; float m_print_info_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. - JMutex m_env_mutex; - Environment m_env; - JMutex m_con_mutex; + // Environment + ServerEnvironment *m_env; + JMutex m_env_mutex; + + // Connection con::Connection m_con; - core::map m_clients; // Behind the con mutex + JMutex m_con_mutex; + // Connected clients (behind the con mutex) + core::map m_clients; + + // Bann checking + BanManager m_banmanager; + // Scripting + // Envlock and conlock should be locked when using Lua + lua_State *m_lua; + + // Item definition manager + IWritableItemDefManager *m_itemdef; + + // Node definition manager + IWritableNodeDefManager *m_nodedef; + + // Craft definition manager + IWritableCraftDefManager *m_craftdef; + + // Event manager + EventManager *m_event; + + // Mods + core::list m_mods; + + /* + Threads + */ + + // A buffer for time steps + // step() increments and AsyncRunStep() run by m_thread reads it. float m_step_dtime; JMutex m_step_dtime_mutex; + // The server mainly operates in this thread ServerThread m_thread; + // This thread fetches and generates map EmergeThread m_emergethread; - + // Queue of block coordinates to be processed by the emerge thread BlockEmergeQueue m_emerge_queue; - // Nodes that are destinations of flowing liquid at the moment - core::map m_flow_active_nodes; + /* + Time related stuff + */ - // 0-23999 - MutexedVariable m_time_of_day; - // Used to buffer dtime for adding to m_time_of_day - float m_time_counter; + // Timer for sending time of day over network float m_time_of_day_send_timer; + // Uptime of server in seconds + MutexedVariable m_uptime; - MutexedVariable m_uptime; - + /* + 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; + /* + Random stuff + */ + + // Mod parent directory paths + core::list m_modspaths; + + bool m_shutdown_requested; + + /* + Map edit event queue. Automatically receives all map edits. + The constructor of this class registers us to receive them through + onMapEditEvent + + NOTE: Should these be moved to actually be members of + ServerEnvironment? + */ + + /* + Queue of map edits from the environment for sending to the clients + This is behind m_env_mutex + */ + 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. + This is behind m_env_mutex + */ + bool m_ignore_map_edit_events; + /* + If a non-empty area, map edit events contained within are left + unsent. Done at map generation time to speed up editing of the + generated area, as it will be sent anyway. + This is behind m_env_mutex + */ + VoxelArea m_ignore_map_edit_events_area; + /* + If set to !=0, the incoming MapEditEvents are modified to have + this peed id as the disabled recipient + This is behind m_env_mutex + */ + u16 m_ignore_map_edit_events_peer_id; + friend class EmergeThread; friend class RemoteClient; + + std::map m_media; + + /* + Sounds + */ + std::map m_playing_sounds; + s32 m_next_sound_id; }; +/* + Runs a simple dedicated server loop. + + Shuts down when run is set to false. +*/ +void dedicated_server_loop(Server &server, bool &run); + #endif