3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "connection.h"
24 #include "environment.h"
25 #include "irrlichttypes_extrabloated.h"
26 #include "jthread/jmutex.h"
31 #include "clientobject.h"
33 #include "inventorymanager.h"
34 #include "localplayer.h"
36 #include "particles.h"
40 class IWritableTextureSource;
41 class IWritableShaderSource;
42 class IWritableItemDefManager;
43 class IWritableNodeDefManager;
44 //class IWritableCraftDefManager;
45 class ClientMediaDownloader;
46 struct MapDrawControl;
50 struct QueuedMeshUpdate
54 bool ack_block_to_server;
60 enum LocalClientState {
67 A thread-safe queue of mesh update tasks
77 peer_id=0 adds with nobody to send to
79 void addBlock(v3s16 p, MeshMakeData *data,
80 bool ack_block_to_server, bool urgent);
82 // Returned pointer must be deleted
83 // Returns NULL if queue is empty
84 QueuedMeshUpdate * pop();
88 JMutexAutoLock lock(m_mutex);
89 return m_queue.size();
93 std::vector<QueuedMeshUpdate*> m_queue;
94 std::set<v3s16> m_urgents;
98 struct MeshUpdateResult
102 bool ack_block_to_server;
105 p(-1338,-1338,-1338),
107 ack_block_to_server(false)
112 class MeshUpdateThread : public JThread
116 MeshUpdateThread(IGameDef *gamedef):
123 MeshUpdateQueue m_queue_in;
125 MutexedQueue<MeshUpdateResult> m_queue_out;
129 v3s16 m_camera_offset;
136 CE_PLAYER_FORCE_MOVE,
140 CE_ADD_PARTICLESPAWNER,
141 CE_DELETE_PARTICLESPAWNER,
146 CE_OVERRIDE_DAY_NIGHT_RATIO,
151 ClientEventType type;
163 bool set_camera_point_target;
164 f32 camera_point_target_x;
165 f32 camera_point_target_y;
166 f32 camera_point_target_z;
169 std::string *formspec;
170 std::string *formname;
180 bool collisiondetection;
182 std::string *texture;
197 bool collisiondetection;
199 std::string *texture;
201 } add_particlespawner;
204 } delete_particlespawner;
231 video::SColor *bgcolor;
233 std::vector<std::string> *params;
238 } override_day_night_ratio;
253 void add(u16 command)
255 std::map<u16, u16>::iterator n = m_packets.find(command);
256 if(n == m_packets.end())
258 m_packets[command] = 1;
268 for(std::map<u16, u16>::iterator
269 i = m_packets.begin();
270 i != m_packets.end(); ++i)
276 void print(std::ostream &o)
278 for(std::map<u16, u16>::iterator
279 i = m_packets.begin();
280 i != m_packets.end(); ++i)
283 <<" count "<<i->second
290 std::map<u16, u16> m_packets;
293 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
297 NOTE: Nothing is thread-safe here.
301 IrrlichtDevice *device,
302 const char *playername,
303 std::string password,
304 MapDrawControl &control,
305 IWritableTextureSource *tsrc,
306 IWritableShaderSource *shsrc,
307 IWritableItemDefManager *itemdef,
308 IWritableNodeDefManager *nodedef,
309 ISoundManager *sound,
310 MtEventManager *event,
317 request all threads managed by client to be stopped
324 The name of the local player should already be set when
325 calling this, as it is sent in the initialization.
327 void connect(Address address);
330 Stuff that references the environment is valid only as
331 long as this is not called. (eg. Players)
332 If this throws a PeerNotFoundException, the connection has
335 void step(float dtime);
337 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
338 // Returns true if something was received
339 bool AsyncProcessPacket();
340 bool AsyncProcessData();
341 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
343 void interact(u8 action, const PointedThing& pointed);
345 void sendNodemetaFields(v3s16 p, const std::string &formname,
346 const std::map<std::string, std::string> &fields);
347 void sendInventoryFields(const std::string &formname,
348 const std::map<std::string, std::string> &fields);
349 void sendInventoryAction(InventoryAction *a);
350 void sendChatMessage(const std::wstring &message);
351 void sendChangePassword(const std::wstring &oldpassword,
352 const std::wstring &newpassword);
353 void sendDamage(u8 damage);
354 void sendBreath(u16 breath);
358 ClientEnvironment& getEnv()
361 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
362 void removeNode(v3s16 p);
363 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
365 void setPlayerControl(PlayerControl &control);
367 void selectPlayerItem(u16 item);
368 u16 getPlayerItem() const
369 { return m_playeritem; }
371 // Returns true if the inventory of the local player has been
372 // updated from the server. If it is true, it is set to false.
373 bool getLocalInventoryUpdated();
374 // Copies the inventory of the local player to parameter
375 void getLocalInventory(Inventory &dst);
377 /* InventoryManager interface */
378 Inventory* getInventory(const InventoryLocation &loc);
379 void inventoryAction(InventoryAction *a);
381 // Gets closest object pointed by the shootline
382 // Returns NULL if not found
383 ClientActiveObject * getSelectedActiveObject(
385 v3f from_pos_f_on_map,
386 core::line3d<f32> shootline_on_map
389 std::list<std::string> getConnectedPlayerNames();
391 float getAnimationTime();
394 void setCrack(int level, v3s16 pos);
399 bool checkPrivilege(const std::string &priv)
400 { return (m_privileges.count(priv) != 0); }
402 bool getChatMessage(std::wstring &message);
403 void typeChatMessage(const std::wstring& message);
405 u64 getMapSeed(){ return m_map_seed; }
407 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
408 // Including blocks at appropriate edges
409 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
410 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
412 void updateCameraOffset(v3s16 camera_offset)
413 { m_mesh_update_thread.m_camera_offset = camera_offset; }
415 // Get event from queue. CE_NONE is returned if queue is empty.
416 ClientEvent getClientEvent();
419 { return m_access_denied; }
421 std::wstring accessDeniedReason()
422 { return m_access_denied_reason; }
424 bool itemdefReceived()
425 { return m_itemdef_received; }
426 bool nodedefReceived()
427 { return m_nodedef_received; }
429 { return m_media_downloader == NULL; }
431 float mediaReceiveProgress();
433 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
436 float getCurRate(void);
437 float getAvgRate(void);
439 // IGameDef interface
440 virtual IItemDefManager* getItemDefManager();
441 virtual INodeDefManager* getNodeDefManager();
442 virtual ICraftDefManager* getCraftDefManager();
443 virtual ITextureSource* getTextureSource();
444 virtual IShaderSource* getShaderSource();
445 virtual u16 allocateUnknownNodeId(const std::string &name);
446 virtual ISoundManager* getSoundManager();
447 virtual MtEventManager* getEventManager();
448 virtual bool checkLocalPrivilege(const std::string &priv)
449 { return checkPrivilege(priv); }
450 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
452 // The following set of functions is used by ClientMediaDownloader
453 // Insert a media file appropriately into the appropriate manager
454 bool loadMedia(const std::string &data, const std::string &filename);
455 // Send a request for conventional media transfer
456 void request_media(const std::list<std::string> &file_requests);
457 // Send a notification that no conventional media transfer is needed
458 void received_media();
460 LocalClientState getState() { return m_state; }
464 // Virtual methods from con::PeerHandler
465 void peerAdded(con::Peer *peer);
466 void deletingPeer(con::Peer *peer, bool timeout);
471 void sendPlayerPos();
472 // Send the item number 'item' as player item to the server
473 void sendPlayerItem(u16 item);
475 float m_packetcounter_timer;
476 float m_connection_reinit_timer;
477 float m_avg_rtt_timer;
478 float m_playerpos_send_timer;
479 float m_ignore_damage_timer; // Used after server moves player
480 IntervalLimiter m_map_timer_and_unload_interval;
482 IWritableTextureSource *m_tsrc;
483 IWritableShaderSource *m_shsrc;
484 IWritableItemDefManager *m_itemdef;
485 IWritableNodeDefManager *m_nodedef;
486 ISoundManager *m_sound;
487 MtEventManager *m_event;
489 MeshUpdateThread m_mesh_update_thread;
490 ClientEnvironment m_env;
491 con::Connection m_con;
492 IrrlichtDevice *m_device;
493 // Server serialization version
496 bool m_inventory_updated;
497 Inventory *m_inventory_from_server;
498 float m_inventory_from_server_age;
499 std::set<v3s16> m_active_blocks;
500 PacketCounter m_packetcounter;
501 // Block mesh animation parameters
502 float m_animation_time;
505 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
507 //u32 m_daynight_ratio;
508 Queue<std::wstring> m_chat_queue;
509 // The seed returned by the server in TOCLIENT_INIT is stored here
511 std::string m_password;
512 bool m_access_denied;
513 std::wstring m_access_denied_reason;
514 Queue<ClientEvent> m_client_event_queue;
515 bool m_itemdef_received;
516 bool m_nodedef_received;
517 ClientMediaDownloader *m_media_downloader;
519 // time_of_day speed approximation for old protocol
520 bool m_time_of_day_set;
521 float m_last_time_of_day_f;
522 float m_time_of_day_update_timer;
524 // An interval for generally sending object positions and stuff
525 float m_recommended_send_interval;
528 float m_removed_sounds_check_timer;
529 // Mapping from server sound ids to our sound ids
530 std::map<s32, int> m_sounds_server_to_client;
531 // And the other way!
532 std::map<int, s32> m_sounds_client_to_server;
533 // And relations to objects
534 std::map<int, u16> m_sounds_to_objects;
537 std::set<std::string> m_privileges;
539 // Detached inventories
541 std::map<std::string, Inventory*> m_detached_inventories;
543 // Storage for mesh data for creating multiple instances of the same mesh
544 std::map<std::string, std::string> m_mesh_data;
547 LocalClientState m_state;
550 #endif // !CLIENT_HEADER