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;
61 A thread-safe queue of mesh update tasks
71 peer_id=0 adds with nobody to send to
73 void addBlock(v3s16 p, MeshMakeData *data,
74 bool ack_block_to_server, bool urgent);
76 // Returned pointer must be deleted
77 // Returns NULL if queue is empty
78 QueuedMeshUpdate * pop();
82 JMutexAutoLock lock(m_mutex);
83 return m_queue.size();
87 std::vector<QueuedMeshUpdate*> m_queue;
88 std::set<v3s16> m_urgents;
92 struct MeshUpdateResult
96 bool ack_block_to_server;
101 ack_block_to_server(false)
106 class MeshUpdateThread : public JThread
110 MeshUpdateThread(IGameDef *gamedef):
117 MeshUpdateQueue m_queue_in;
119 MutexedQueue<MeshUpdateResult> m_queue_out;
128 CE_PLAYER_FORCE_MOVE,
132 CE_ADD_PARTICLESPAWNER,
133 CE_DELETE_PARTICLESPAWNER,
142 ClientEventType type;
154 bool set_camera_point_target;
155 f32 camera_point_target_x;
156 f32 camera_point_target_y;
157 f32 camera_point_target_z;
160 std::string *formspec;
161 std::string *formname;
171 bool collisiondetection;
173 std::string *texture;
188 bool collisiondetection;
190 std::string *texture;
192 } add_particlespawner;
195 } delete_particlespawner;
222 video::SColor *bgcolor;
224 std::vector<std::string> *params;
240 void add(u16 command)
242 std::map<u16, u16>::iterator n = m_packets.find(command);
243 if(n == m_packets.end())
245 m_packets[command] = 1;
255 for(std::map<u16, u16>::iterator
256 i = m_packets.begin();
257 i != m_packets.end(); ++i)
263 void print(std::ostream &o)
265 for(std::map<u16, u16>::iterator
266 i = m_packets.begin();
267 i != m_packets.end(); ++i)
270 <<" count "<<i->second
277 std::map<u16, u16> m_packets;
280 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
284 NOTE: Nothing is thread-safe here.
288 IrrlichtDevice *device,
289 const char *playername,
290 std::string password,
291 MapDrawControl &control,
292 IWritableTextureSource *tsrc,
293 IWritableShaderSource *shsrc,
294 IWritableItemDefManager *itemdef,
295 IWritableNodeDefManager *nodedef,
296 ISoundManager *sound,
297 MtEventManager *event,
304 request all threads managed by client to be stopped
311 The name of the local player should already be set when
312 calling this, as it is sent in the initialization.
314 void connect(Address address);
317 m_con.Connected() == true
318 AND m_server_ser_ver != SER_FMT_VER_INVALID
319 throws con::PeerNotFoundException if connection has been deleted,
322 bool connectedAndInitialized();
324 Stuff that references the environment is valid only as
325 long as this is not called. (eg. Players)
326 If this throws a PeerNotFoundException, the connection has
329 void step(float dtime);
331 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
332 // Returns true if something was received
333 bool AsyncProcessPacket();
334 bool AsyncProcessData();
335 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
337 void interact(u8 action, const PointedThing& pointed);
339 void sendNodemetaFields(v3s16 p, const std::string &formname,
340 const std::map<std::string, std::string> &fields);
341 void sendInventoryFields(const std::string &formname,
342 const std::map<std::string, std::string> &fields);
343 void sendInventoryAction(InventoryAction *a);
344 void sendChatMessage(const std::wstring &message);
345 void sendChangePassword(const std::wstring oldpassword,
346 const std::wstring newpassword);
347 void sendDamage(u8 damage);
348 void sendBreath(u16 breath);
351 ClientEnvironment& getEnv()
354 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
355 void removeNode(v3s16 p);
356 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
358 void setPlayerControl(PlayerControl &control);
360 void selectPlayerItem(u16 item);
361 u16 getPlayerItem() const
362 { return m_playeritem; }
364 // Returns true if the inventory of the local player has been
365 // updated from the server. If it is true, it is set to false.
366 bool getLocalInventoryUpdated();
367 // Copies the inventory of the local player to parameter
368 void getLocalInventory(Inventory &dst);
370 /* InventoryManager interface */
371 Inventory* getInventory(const InventoryLocation &loc);
372 void inventoryAction(InventoryAction *a);
374 // Gets closest object pointed by the shootline
375 // Returns NULL if not found
376 ClientActiveObject * getSelectedActiveObject(
378 v3f from_pos_f_on_map,
379 core::line3d<f32> shootline_on_map
382 // Prints a line or two of info
383 void printDebugInfo(std::ostream &os);
385 std::list<std::string> getConnectedPlayerNames();
387 float getAnimationTime();
390 void setCrack(int level, v3s16 pos);
395 bool checkPrivilege(const std::string &priv)
396 { return (m_privileges.count(priv) != 0); }
398 bool getChatMessage(std::wstring &message);
399 void typeChatMessage(const std::wstring& message);
401 u64 getMapSeed(){ return m_map_seed; }
403 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
404 // Including blocks at appropriate edges
405 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
406 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
408 // Get event from queue. CE_NONE is returned if queue is empty.
409 ClientEvent getClientEvent();
412 { return m_access_denied; }
414 std::wstring accessDeniedReason()
415 { return m_access_denied_reason; }
417 bool itemdefReceived()
418 { return m_itemdef_received; }
419 bool nodedefReceived()
420 { return m_nodedef_received; }
422 { return m_media_downloader == NULL; }
424 float mediaReceiveProgress();
426 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
430 // IGameDef interface
431 virtual IItemDefManager* getItemDefManager();
432 virtual INodeDefManager* getNodeDefManager();
433 virtual ICraftDefManager* getCraftDefManager();
434 virtual ITextureSource* getTextureSource();
435 virtual IShaderSource* getShaderSource();
436 virtual u16 allocateUnknownNodeId(const std::string &name);
437 virtual ISoundManager* getSoundManager();
438 virtual MtEventManager* getEventManager();
439 virtual bool checkLocalPrivilege(const std::string &priv)
440 { return checkPrivilege(priv); }
441 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
443 // The following set of functions is used by ClientMediaDownloader
444 // Insert a media file appropriately into the appropriate manager
445 bool loadMedia(const std::string &data, const std::string &filename);
446 // Send a request for conventional media transfer
447 void request_media(const std::list<std::string> &file_requests);
448 // Send a notification that no conventional media transfer is needed
449 void received_media();
453 // Virtual methods from con::PeerHandler
454 void peerAdded(con::Peer *peer);
455 void deletingPeer(con::Peer *peer, bool timeout);
460 void sendPlayerPos();
461 // Send the item number 'item' as player item to the server
462 void sendPlayerItem(u16 item);
464 float m_packetcounter_timer;
465 float m_connection_reinit_timer;
466 float m_avg_rtt_timer;
467 float m_playerpos_send_timer;
468 float m_ignore_damage_timer; // Used after server moves player
469 IntervalLimiter m_map_timer_and_unload_interval;
471 IWritableTextureSource *m_tsrc;
472 IWritableShaderSource *m_shsrc;
473 IWritableItemDefManager *m_itemdef;
474 IWritableNodeDefManager *m_nodedef;
475 ISoundManager *m_sound;
476 MtEventManager *m_event;
478 MeshUpdateThread m_mesh_update_thread;
479 ClientEnvironment m_env;
480 con::Connection m_con;
481 IrrlichtDevice *m_device;
482 // Server serialization version
485 bool m_inventory_updated;
486 Inventory *m_inventory_from_server;
487 float m_inventory_from_server_age;
488 std::set<v3s16> m_active_blocks;
489 PacketCounter m_packetcounter;
490 // Block mesh animation parameters
491 float m_animation_time;
494 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
496 //u32 m_daynight_ratio;
497 Queue<std::wstring> m_chat_queue;
498 // The seed returned by the server in TOCLIENT_INIT is stored here
500 std::string m_password;
501 bool m_access_denied;
502 std::wstring m_access_denied_reason;
503 Queue<ClientEvent> m_client_event_queue;
504 bool m_itemdef_received;
505 bool m_nodedef_received;
506 ClientMediaDownloader *m_media_downloader;
508 // time_of_day speed approximation for old protocol
509 bool m_time_of_day_set;
510 float m_last_time_of_day_f;
511 float m_time_of_day_update_timer;
513 // An interval for generally sending object positions and stuff
514 float m_recommended_send_interval;
517 float m_removed_sounds_check_timer;
518 // Mapping from server sound ids to our sound ids
519 std::map<s32, int> m_sounds_server_to_client;
520 // And the other way!
521 std::map<int, s32> m_sounds_client_to_server;
522 // And relations to objects
523 std::map<int, u16> m_sounds_to_objects;
526 std::set<std::string> m_privileges;
528 // Detached inventories
530 std::map<std::string, Inventory*> m_detached_inventories;
532 // Storage for mesh data for creating multiple instances of the same mesh
533 std::map<std::string, std::string> m_mesh_data;
536 #endif // !CLIENT_HEADER