X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fclient.h;h=222f83ab739615c24e7e0d0ca05651db4cbd04a9;hb=4a6b9a6ac1b07239474bce8d3ebf772ce75e862e;hp=d6496d9dfd471982aaff5e260709ee39108700ae;hpb=c8be58a65ce5f06bc23353b41caf9495e3b9d484;p=dragonfireclient.git diff --git a/src/client.h b/src/client.h index d6496d9df..222f83ab7 100644 --- a/src/client.h +++ b/src/client.h @@ -37,80 +37,177 @@ class ClientNotReadyException : public BaseException {} }; -class Client; - -class ClientUpdateThread : public SimpleThread +struct QueuedMeshUpdate { - Client *m_client; + v3s16 p; + MeshMakeData *data; + bool ack_block_to_server; + + QueuedMeshUpdate(): + p(-1337,-1337,-1337), + data(NULL), + ack_block_to_server(false) + { + } + + ~QueuedMeshUpdate() + { + if(data) + delete data; + } +}; +/* + A thread-safe queue of mesh update tasks +*/ +class MeshUpdateQueue +{ public: - - ClientUpdateThread(Client *client): - SimpleThread(), - m_client(client) + MeshUpdateQueue() { + m_mutex.Init(); } - void * Thread(); -}; + ~MeshUpdateQueue() + { + JMutexAutoLock lock(m_mutex); -struct IncomingPacket -{ - IncomingPacket() + core::list::Iterator i; + for(i=m_queue.begin(); i!=m_queue.end(); i++) + { + QueuedMeshUpdate *q = *i; + delete q; + } + } + + /* + peer_id=0 adds with nobody to send to + */ + void addBlock(v3s16 p, MeshMakeData *data, bool ack_block_to_server) { - m_data = NULL; - m_datalen = 0; - m_refcount = NULL; + DSTACK(__FUNCTION_NAME); + + assert(data); + + JMutexAutoLock lock(m_mutex); + + /* + Find if block is already in queue. + If it is, update the data and quit. + */ + core::list::Iterator i; + for(i=m_queue.begin(); i!=m_queue.end(); i++) + { + QueuedMeshUpdate *q = *i; + if(q->p == p) + { + if(q->data) + delete q->data; + q->data = data; + if(ack_block_to_server) + q->ack_block_to_server = true; + return; + } + } + + /* + Add the block + */ + QueuedMeshUpdate *q = new QueuedMeshUpdate; + q->p = p; + q->data = data; + q->ack_block_to_server = ack_block_to_server; + m_queue.push_back(q); } - IncomingPacket(const IncomingPacket &a) + + // Returned pointer must be deleted + // Returns NULL if queue is empty + QueuedMeshUpdate * pop() { - m_data = a.m_data; - m_datalen = a.m_datalen; - m_refcount = a.m_refcount; - if(m_refcount != NULL) - (*m_refcount)++; + JMutexAutoLock lock(m_mutex); + + core::list::Iterator i = m_queue.begin(); + if(i == m_queue.end()) + return NULL; + QueuedMeshUpdate *q = *i; + m_queue.erase(i); + return q; } - IncomingPacket(u8 *data, u32 datalen) + + u32 size() { - m_data = new u8[datalen]; - memcpy(m_data, data, datalen); - m_datalen = datalen; - m_refcount = new s32(1); + JMutexAutoLock lock(m_mutex); + return m_queue.size(); } - ~IncomingPacket() + +private: + core::list m_queue; + JMutex m_mutex; +}; + +struct MeshUpdateResult +{ + v3s16 p; + scene::SMesh *mesh; + bool ack_block_to_server; + + MeshUpdateResult(): + p(-1338,-1338,-1338), + mesh(NULL), + ack_block_to_server(false) { - if(m_refcount != NULL){ - assert(*m_refcount > 0); - (*m_refcount)--; - if(*m_refcount == 0){ - if(m_data != NULL) - delete[] m_data; - delete m_refcount; - } - } } - /*IncomingPacket & operator=(IncomingPacket a) +}; + +class MeshUpdateThread : public SimpleThread +{ +public: + + MeshUpdateThread() { - m_data = a.m_data; - m_datalen = a.m_datalen; - m_refcount = a.m_refcount; - (*m_refcount)++; - return *this; - }*/ - u8 *m_data; - u32 m_datalen; - s32 *m_refcount; + } + + void * Thread(); + + MeshUpdateQueue m_queue_in; + + MutexedQueue m_queue_out; +}; + +enum ClientEventType +{ + CE_NONE, + CE_PLAYER_DAMAGE, + CE_PLAYER_FORCE_MOVE +}; + +struct ClientEvent +{ + ClientEventType type; + union{ + struct{ + } none; + struct{ + u8 amount; + } player_damage; + struct{ + f32 pitch; + f32 yaw; + } player_force_move; + }; }; -class Client : public con::PeerHandler +class Client : public con::PeerHandler, public InventoryManager { public: /* - NOTE: Every public method should be thread-safe + NOTE: Nothing is thread-safe here. */ + Client( IrrlichtDevice *device, const char *playername, + std::string password, MapDrawControl &control ); @@ -138,7 +235,7 @@ class Client : public con::PeerHandler // Called from updater thread // Returns dtime - float asyncStep(); + //float asyncStep(); void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id); // Returns true if something was received @@ -147,15 +244,18 @@ class Client : public con::PeerHandler void Send(u16 channelnum, SharedBuffer data, bool reliable); // Pops out a packet from the packet queue - IncomingPacket getPacket(); + //IncomingPacket getPacket(); void groundAction(u8 action, v3s16 nodepos_undersurface, v3s16 nodepos_oversurface, u16 item); void clickObject(u8 button, v3s16 blockpos, s16 id, u16 item); + void clickActiveObject(u8 button, u16 id, u16 item); void sendSignText(v3s16 blockpos, s16 id, std::string text); + void sendSignNodeText(v3s16 p, std::string text); void sendInventoryAction(InventoryAction *a); void sendChatMessage(const std::wstring &message); + void sendDamage(u8 damage); // locks envlock void removeNode(v3s16 p); @@ -166,6 +266,8 @@ class Client : public con::PeerHandler // Returns InvalidPositionException if not found MapNode getNode(v3s16 p); + // Wrapper to Map + NodeMetadata* getNodeMetadata(v3s16 p); v3f getPlayerPosition(); @@ -177,6 +279,11 @@ class Client : public con::PeerHandler // Copies the inventory of the local player to parameter void getLocalInventory(Inventory &dst); + InventoryContext *getInventoryContext(); + + Inventory* getInventory(InventoryContext *c, std::string id); + void inventoryAction(InventoryAction *a); + // Gets closest object pointed by the shootline // Returns NULL if not found MapBlockObject * getSelectedObject( @@ -185,16 +292,26 @@ class Client : public con::PeerHandler core::line3d shootline_on_map ); + // Gets closest object pointed by the shootline + // Returns NULL if not found + ClientActiveObject * getSelectedActiveObject( + f32 max_d, + v3f from_pos_f_on_map, + core::line3d shootline_on_map + ); + // Prints a line or two of info void printDebugInfo(std::ostream &os); u32 getDayNightRatio(); + u16 getHP(); + //void updateSomeExpiredMeshes(); void setTempMod(v3s16 p, NodeMod mod) { - JMutexAutoLock envlock(m_env_mutex); + //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); core::map affected_blocks; @@ -210,7 +327,7 @@ class Client : public con::PeerHandler } void clearTempMod(v3s16 p) { - JMutexAutoLock envlock(m_env_mutex); + //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out assert(m_env.getMap().mapType() == MAPTYPE_CLIENT); core::map affected_blocks; @@ -227,7 +344,7 @@ class Client : public con::PeerHandler float getAvgRtt() { - JMutexAutoLock lock(m_con_mutex); + //JMutexAutoLock lock(m_con_mutex); //bulk comment-out con::Peer *peer = m_con.GetPeerNoEx(PEER_ID_SERVER); if(peer == NULL) return 0.0; @@ -244,7 +361,7 @@ class Client : public con::PeerHandler void addChatMessage(const std::wstring &message) { - JMutexAutoLock envlock(m_env_mutex); + //JMutexAutoLock envlock(m_env_mutex); //bulk comment-out LocalPlayer *player = m_env.getLocalPlayer(); assert(player != NULL); std::wstring name = narrow_to_wide(player->getName()); @@ -254,6 +371,18 @@ class Client : public con::PeerHandler u64 getMapSeed(){ return m_map_seed; } + void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false); + // Including blocks at appropriate edges + void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false); + + // Get event from queue. CE_NONE is returned if queue is empty. + ClientEvent getClientEvent(); + + inline bool accessDenied() + { + return m_access_denied; + } + private: // Virtual methods from con::PeerHandler @@ -272,20 +401,13 @@ class Client : public con::PeerHandler float m_connection_reinit_timer; float m_avg_rtt_timer; float m_playerpos_send_timer; + float m_ignore_damage_timer; // Used after server moves player - ClientUpdateThread m_thread; + MeshUpdateThread m_mesh_update_thread; - // NOTE: If connection and environment are both to be locked, - // environment shall be locked first. - ClientEnvironment m_env; - JMutex m_env_mutex; con::Connection m_con; - JMutex m_con_mutex; - - core::list m_incoming_queue; - JMutex m_incoming_queue_mutex; IrrlichtDevice *m_device; @@ -295,9 +417,6 @@ class Client : public con::PeerHandler // Server serialization version u8 m_server_ser_ver; - float m_step_dtime; - JMutex m_step_dtime_mutex; - // This is behind m_env_mutex. bool m_inventory_updated; @@ -306,7 +425,7 @@ class Client : public con::PeerHandler PacketCounter m_packetcounter; // Received from the server. 0-23999 - MutexedVariable m_time_of_day; + u32 m_time_of_day; // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT //s32 m_daynight_i; @@ -316,6 +435,13 @@ class Client : public con::PeerHandler // The seed returned by the server in TOCLIENT_INIT is stored here u64 m_map_seed; + + std::string m_password; + bool m_access_denied; + + InventoryContext m_inventory_context; + + Queue m_client_event_queue; }; #endif // !SERVER