X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fclient.h;h=8bffbd1db9e1c0ada2ab5bb040c6dc95b90da706;hb=58e6d25e033c76dc91aaac18fdeda92ac23fe0e1;hp=625170b174011382c5c099ad1a75a1ac4c682c4e;hpb=7696a385433f815d8af8c905b45e2d7656299329;p=oweals%2Fminetest.git diff --git a/src/client.h b/src/client.h index 625170b17..8bffbd1db 100644 --- a/src/client.h +++ b/src/client.h @@ -1,18 +1,18 @@ /* -Minetest-c55 -Copyright (C) 2010 celeron55, Perttu Ahola +Minetest +Copyright (C) 2013 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 -the Free Software Foundation; either version 2 of the License, or +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. +GNU Lesser General Public License for more details. -You should have received a copy of the GNU General Public License along +You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ @@ -20,30 +20,32 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef CLIENT_HEADER #define CLIENT_HEADER -#ifndef SERVER - #include "connection.h" #include "environment.h" -#include "common_irrlicht.h" -#include "jmutex.h" +#include "irrlichttypes_extrabloated.h" +#include "jthread/jmutex.h" #include +#include +#include +#include #include "clientobject.h" -#include "utility.h" // For IntervalLimiter #include "gamedef.h" +#include "inventorymanager.h" +#include "localplayer.h" +#include "hud.h" +#include "particles.h" struct MeshMakeData; -class IGameDef; +class MapBlockMesh; class IWritableTextureSource; -class IWritableToolDefManager; +class IWritableShaderSource; +class IWritableItemDefManager; class IWritableNodeDefManager; - -class ClientNotReadyException : public BaseException -{ -public: - ClientNotReadyException(const char *s): - BaseException(s) - {} -}; +//class IWritableCraftDefManager; +class ClientMediaDownloader; +struct MapDrawControl; +class MtEventManager; +struct PointedThing; struct QueuedMeshUpdate { @@ -55,6 +57,12 @@ struct QueuedMeshUpdate ~QueuedMeshUpdate(); }; +enum LocalClientState { + LC_Created, + LC_Init, + LC_Ready +}; + /* A thread-safe queue of mesh update tasks */ @@ -68,7 +76,8 @@ public: /* peer_id=0 adds with nobody to send to */ - void addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_server); + void addBlock(v3s16 p, MeshMakeData *data, + bool ack_block_to_server, bool urgent); // Returned pointer must be deleted // Returns NULL if queue is empty @@ -81,14 +90,15 @@ public: } private: - core::list m_queue; + std::vector m_queue; + std::set m_urgents; JMutex m_mutex; }; struct MeshUpdateResult { v3s16 p; - scene::SMesh *mesh; + MapBlockMesh *mesh; bool ack_block_to_server; MeshUpdateResult(): @@ -99,7 +109,7 @@ struct MeshUpdateResult } }; -class MeshUpdateThread : public SimpleThread +class MeshUpdateThread : public JThread { public: @@ -115,6 +125,8 @@ public: MutexedQueue m_queue_out; IGameDef *m_gamedef; + + v3s16 m_camera_offset; }; enum ClientEventType @@ -123,7 +135,15 @@ enum ClientEventType CE_PLAYER_DAMAGE, CE_PLAYER_FORCE_MOVE, CE_DEATHSCREEN, - CE_TEXTURES_UPDATED + CE_SHOW_FORMSPEC, + CE_SPAWN_PARTICLE, + CE_ADD_PARTICLESPAWNER, + CE_DELETE_PARTICLESPAWNER, + CE_HUDADD, + CE_HUDRM, + CE_HUDCHANGE, + CE_SET_SKY, + CE_OVERRIDE_DAY_NIGHT_RATIO, }; struct ClientEvent @@ -145,11 +165,133 @@ struct ClientEvent f32 camera_point_target_y; f32 camera_point_target_z; } deathscreen; + struct{ + std::string *formspec; + std::string *formname; + } show_formspec; struct{ } textures_updated; + struct{ + v3f *pos; + v3f *vel; + v3f *acc; + f32 expirationtime; + f32 size; + bool collisiondetection; + bool vertical; + std::string *texture; + } spawn_particle; + struct{ + u16 amount; + f32 spawntime; + v3f *minpos; + v3f *maxpos; + v3f *minvel; + v3f *maxvel; + v3f *minacc; + v3f *maxacc; + f32 minexptime; + f32 maxexptime; + f32 minsize; + f32 maxsize; + bool collisiondetection; + bool vertical; + std::string *texture; + u32 id; + } add_particlespawner; + struct{ + u32 id; + } delete_particlespawner; + struct{ + u32 id; + u8 type; + v2f *pos; + std::string *name; + v2f *scale; + std::string *text; + u32 number; + u32 item; + u32 dir; + v2f *align; + v2f *offset; + v3f *world_pos; + v2s32 * size; + } hudadd; + struct{ + u32 id; + } hudrm; + struct{ + u32 id; + HudElementStat stat; + v2f *v2fdata; + std::string *sdata; + u32 data; + v3f *v3fdata; + v2s32 * v2s32data; + } hudchange; + struct{ + video::SColor *bgcolor; + std::string *type; + std::vector *params; + } set_sky; + struct{ + bool do_override; + float ratio_f; + } override_day_night_ratio; }; }; +/* + Packet counter +*/ + +class PacketCounter +{ +public: + PacketCounter() + { + } + + void add(u16 command) + { + std::map::iterator n = m_packets.find(command); + if(n == m_packets.end()) + { + m_packets[command] = 1; + } + else + { + n->second++; + } + } + + void clear() + { + for(std::map::iterator + i = m_packets.begin(); + i != m_packets.end(); ++i) + { + i->second = 0; + } + } + + void print(std::ostream &o) + { + for(std::map::iterator + i = m_packets.begin(); + i != m_packets.end(); ++i) + { + o<<"cmd "<first + <<" count "<second + < m_packets; +}; + class Client : public con::PeerHandler, public InventoryManager, public IGameDef { public: @@ -163,24 +305,29 @@ public: std::string password, MapDrawControl &control, IWritableTextureSource *tsrc, - IWritableToolDefManager *tooldef, - IWritableNodeDefManager *nodedef + IWritableShaderSource *shsrc, + IWritableItemDefManager *itemdef, + IWritableNodeDefManager *nodedef, + ISoundManager *sound, + MtEventManager *event, + bool ipv6 ); ~Client(); + + /* + request all threads managed by client to be stopped + */ + void Stop(); + + + bool isShutdown(); /* The name of the local player should already be set when calling this, as it is sent in the initialization. */ void connect(Address address); - /* - returns true when - m_con.Connected() == true - AND m_server_ser_ver != SER_FMT_VER_INVALID - throws con::PeerNotFoundException if connection has been deleted, - eg. timed out. - */ - bool connectedAndInitialized(); + /* Stuff that references the environment is valid only as long as this is not called. (eg. Players) @@ -189,50 +336,39 @@ public: */ void step(float dtime); - // Called from updater thread - // Returns dtime - //float asyncStep(); - void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id); // Returns true if something was received bool AsyncProcessPacket(); bool AsyncProcessData(); void Send(u16 channelnum, SharedBuffer data, bool reliable); - // Pops out a packet from the packet queue - //IncomingPacket getPacket(); - - void groundAction(u8 action, v3s16 nodepos_undersurface, - v3s16 nodepos_oversurface, u16 item); - void clickActiveObject(u8 button, u16 id, u16 item_i); + void interact(u8 action, const PointedThing& pointed); - void sendSignNodeText(v3s16 p, std::string text); + void sendNodemetaFields(v3s16 p, const std::string &formname, + const std::map &fields); + void sendInventoryFields(const std::string &formname, + const std::map &fields); void sendInventoryAction(InventoryAction *a); void sendChatMessage(const std::wstring &message); - void sendChangePassword(const std::wstring oldpassword, - const std::wstring newpassword); + void sendChangePassword(const std::wstring &oldpassword, + const std::wstring &newpassword); void sendDamage(u8 damage); + void sendBreath(u16 breath); void sendRespawn(); + void sendReady(); + + ClientEnvironment& getEnv() + { return m_env; } - // locks envlock + // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent) void removeNode(v3s16 p); - // locks envlock - void addNode(v3s16 p, MapNode n); - - void updateCamera(v3f pos, v3f dir, f32 fov); - - void renderPostFx(); + void addNode(v3s16 p, MapNode n, bool remove_metadata = true); - // Returns InvalidPositionException if not found - MapNode getNode(v3s16 p); - // Wrapper to Map - NodeMetadata* getNodeMetadata(v3s16 p); - - LocalPlayer* getLocalPlayer(); - void setPlayerControl(PlayerControl &control); void selectPlayerItem(u16 item); + u16 getPlayerItem() const + { return m_playeritem; } // Returns true if the inventory of the local player has been // updated from the server. If it is true, it is set to false. @@ -240,9 +376,8 @@ public: // Copies the inventory of the local player to parameter void getLocalInventory(Inventory &dst); - InventoryContext *getInventoryContext(); - - Inventory* getInventory(InventoryContext *c, std::string id); + /* InventoryManager interface */ + Inventory* getInventory(const InventoryLocation &loc); void inventoryAction(InventoryAction *a); // Gets closest object pointed by the shootline @@ -253,54 +388,34 @@ public: core::line3d shootline_on_map ); - // Prints a line or two of info - void printDebugInfo(std::ostream &os); + std::list getConnectedPlayerNames(); - u32 getDayNightRatio(); - - u16 getHP(); + float getAnimationTime(); - void setTempMod(v3s16 p, NodeMod mod); - void clearTempMod(v3s16 p); + int getCrackLevel(); + void setCrack(int level, v3s16 pos); - float getAvgRtt() - { - try{ - return m_con.GetPeerAvgRTT(PEER_ID_SERVER); - } catch(con::PeerNotFoundException){ - return 1337; - } - } + void setHighlighted(v3s16 pos, bool show_hud); + v3s16 getHighlighted(){ return m_highlighted_pos; } - bool getChatMessage(std::wstring &message) - { - if(m_chat_queue.size() == 0) - return false; - message = m_chat_queue.pop_front(); - return true; - } + u16 getHP(); + u16 getBreath(); - void addChatMessage(const std::wstring &message) - { - if (message[0] == L'/') { - m_chat_queue.push_back( - (std::wstring)L"issued command: "+message); - return; - } + bool checkPrivilege(const std::string &priv) + { return (m_privileges.count(priv) != 0); } - //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out - LocalPlayer *player = m_env.getLocalPlayer(); - assert(player != NULL); - std::wstring name = narrow_to_wide(player->getName()); - m_chat_queue.push_back( - (std::wstring)L"<"+name+L"> "+message); - } + bool getChatMessage(std::wstring &message); + void typeChatMessage(const std::wstring& message); u64 getMapSeed(){ return m_map_seed; } - void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false); + void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false); // Including blocks at appropriate edges - void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false); + void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false); + void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false); + + void updateCameraOffset(v3s16 camera_offset) + { m_mesh_update_thread.m_camera_offset = camera_offset; } // Get event from queue. CE_NONE is returned if queue is empty. ClientEvent getClientEvent(); @@ -311,26 +426,46 @@ public: std::wstring accessDeniedReason() { return m_access_denied_reason; } - float textureReceiveProgress() - { return m_texture_receive_progress; } - - bool texturesReceived() - { return m_textures_received; } - bool tooldefReceived() - { return m_tooldef_received; } + bool itemdefReceived() + { return m_itemdef_received; } bool nodedefReceived() { return m_nodedef_received; } - + bool mediaReceived() + { return m_media_downloader == NULL; } + + float mediaReceiveProgress(); + + void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font); + float getRTT(void); + float getCurRate(void); + float getAvgRate(void); // IGameDef interface - // Under envlock - virtual IToolDefManager* getToolDefManager(); + virtual IItemDefManager* getItemDefManager(); virtual INodeDefManager* getNodeDefManager(); + virtual ICraftDefManager* getCraftDefManager(); virtual ITextureSource* getTextureSource(); + virtual IShaderSource* getShaderSource(); + virtual u16 allocateUnknownNodeId(const std::string &name); + virtual ISoundManager* getSoundManager(); + virtual MtEventManager* getEventManager(); + virtual bool checkLocalPrivilege(const std::string &priv) + { return checkPrivilege(priv); } + virtual scene::IAnimatedMesh* getMesh(const std::string &filename); + + // The following set of functions is used by ClientMediaDownloader + // Insert a media file appropriately into the appropriate manager + bool loadMedia(const std::string &data, const std::string &filename); + // Send a request for conventional media transfer + void request_media(const std::list &file_requests); + // Send a notification that no conventional media transfer is needed + void received_media(); + + LocalClientState getState() { return m_state; } private: - + // Virtual methods from con::PeerHandler void peerAdded(con::Peer *peer); void deletingPeer(con::Peer *peer, bool timeout); @@ -339,8 +474,6 @@ private: void Receive(); void sendPlayerPos(); - // This sends the player's current name etc to the server - void sendPlayerInfo(); // Send the item number 'item' as player item to the server void sendPlayerItem(u16 item); @@ -352,20 +485,30 @@ private: IntervalLimiter m_map_timer_and_unload_interval; IWritableTextureSource *m_tsrc; - IWritableToolDefManager *m_tooldef; + IWritableShaderSource *m_shsrc; + IWritableItemDefManager *m_itemdef; IWritableNodeDefManager *m_nodedef; + ISoundManager *m_sound; + MtEventManager *m_event; + MeshUpdateThread m_mesh_update_thread; ClientEnvironment m_env; con::Connection m_con; IrrlichtDevice *m_device; // Server serialization version u8 m_server_ser_ver; - // This is behind m_env_mutex. + u16 m_playeritem; bool m_inventory_updated; - core::map m_active_blocks; + Inventory *m_inventory_from_server; + float m_inventory_from_server_age; + std::set m_active_blocks; PacketCounter m_packetcounter; - // Received from the server. 0-23999 - u32 m_time_of_day; + bool m_show_hud; + // Block mesh animation parameters + float m_animation_time; + int m_crack_level; + v3s16 m_crack_pos; + v3s16 m_highlighted_pos; // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT //s32 m_daynight_i; //u32 m_daynight_ratio; @@ -375,16 +518,41 @@ private: std::string m_password; bool m_access_denied; std::wstring m_access_denied_reason; - InventoryContext m_inventory_context; Queue m_client_event_queue; - float m_texture_receive_progress; - bool m_textures_received; - bool m_tooldef_received; + bool m_itemdef_received; bool m_nodedef_received; - friend class FarMesh; -}; + ClientMediaDownloader *m_media_downloader; + + // time_of_day speed approximation for old protocol + bool m_time_of_day_set; + float m_last_time_of_day_f; + float m_time_of_day_update_timer; + + // An interval for generally sending object positions and stuff + float m_recommended_send_interval; -#endif // !SERVER + // Sounds + float m_removed_sounds_check_timer; + // Mapping from server sound ids to our sound ids + std::map m_sounds_server_to_client; + // And the other way! + std::map m_sounds_client_to_server; + // And relations to objects + std::map m_sounds_to_objects; + + // Privileges + std::set m_privileges; + + // Detached inventories + // key = name + std::map m_detached_inventories; + + // Storage for mesh data for creating multiple instances of the same mesh + std::map m_mesh_data; + + // own state + LocalClientState m_state; +}; #endif // !CLIENT_HEADER