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,
138 CE_OVERRIDE_DAY_NIGHT_RATIO,
143 ClientEventType type;
155 bool set_camera_point_target;
156 f32 camera_point_target_x;
157 f32 camera_point_target_y;
158 f32 camera_point_target_z;
161 std::string *formspec;
162 std::string *formname;
172 bool collisiondetection;
174 std::string *texture;
189 bool collisiondetection;
191 std::string *texture;
193 } add_particlespawner;
196 } delete_particlespawner;
223 video::SColor *bgcolor;
225 std::vector<std::string> *params;
230 } override_day_night_ratio;
245 void add(u16 command)
247 std::map<u16, u16>::iterator n = m_packets.find(command);
248 if(n == m_packets.end())
250 m_packets[command] = 1;
260 for(std::map<u16, u16>::iterator
261 i = m_packets.begin();
262 i != m_packets.end(); ++i)
268 void print(std::ostream &o)
270 for(std::map<u16, u16>::iterator
271 i = m_packets.begin();
272 i != m_packets.end(); ++i)
275 <<" count "<<i->second
282 std::map<u16, u16> m_packets;
285 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
289 NOTE: Nothing is thread-safe here.
293 IrrlichtDevice *device,
294 const char *playername,
295 std::string password,
296 MapDrawControl &control,
297 IWritableTextureSource *tsrc,
298 IWritableShaderSource *shsrc,
299 IWritableItemDefManager *itemdef,
300 IWritableNodeDefManager *nodedef,
301 ISoundManager *sound,
302 MtEventManager *event,
309 request all threads managed by client to be stopped
316 The name of the local player should already be set when
317 calling this, as it is sent in the initialization.
319 void connect(Address address);
322 m_con.Connected() == true
323 AND m_server_ser_ver != SER_FMT_VER_INVALID
324 throws con::PeerNotFoundException if connection has been deleted,
327 bool connectedAndInitialized();
329 Stuff that references the environment is valid only as
330 long as this is not called. (eg. Players)
331 If this throws a PeerNotFoundException, the connection has
334 void step(float dtime);
336 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
337 // Returns true if something was received
338 bool AsyncProcessPacket();
339 bool AsyncProcessData();
340 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
342 void interact(u8 action, const PointedThing& pointed);
344 void sendNodemetaFields(v3s16 p, const std::string &formname,
345 const std::map<std::string, std::string> &fields);
346 void sendInventoryFields(const std::string &formname,
347 const std::map<std::string, std::string> &fields);
348 void sendInventoryAction(InventoryAction *a);
349 void sendChatMessage(const std::wstring &message);
350 void sendChangePassword(const std::wstring oldpassword,
351 const std::wstring newpassword);
352 void sendDamage(u8 damage);
353 void sendBreath(u16 breath);
356 ClientEnvironment& getEnv()
359 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
360 void removeNode(v3s16 p);
361 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
363 void setPlayerControl(PlayerControl &control);
365 void selectPlayerItem(u16 item);
366 u16 getPlayerItem() const
367 { return m_playeritem; }
369 // Returns true if the inventory of the local player has been
370 // updated from the server. If it is true, it is set to false.
371 bool getLocalInventoryUpdated();
372 // Copies the inventory of the local player to parameter
373 void getLocalInventory(Inventory &dst);
375 /* InventoryManager interface */
376 Inventory* getInventory(const InventoryLocation &loc);
377 void inventoryAction(InventoryAction *a);
379 // Gets closest object pointed by the shootline
380 // Returns NULL if not found
381 ClientActiveObject * getSelectedActiveObject(
383 v3f from_pos_f_on_map,
384 core::line3d<f32> shootline_on_map
387 // Prints a line or two of info
388 void printDebugInfo(std::ostream &os);
390 std::list<std::string> getConnectedPlayerNames();
392 float getAnimationTime();
395 void setCrack(int level, v3s16 pos);
400 bool checkPrivilege(const std::string &priv)
401 { return (m_privileges.count(priv) != 0); }
403 bool getChatMessage(std::wstring &message);
404 void typeChatMessage(const std::wstring& message);
406 u64 getMapSeed(){ return m_map_seed; }
408 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
409 // Including blocks at appropriate edges
410 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
411 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
413 // Get event from queue. CE_NONE is returned if queue is empty.
414 ClientEvent getClientEvent();
417 { return m_access_denied; }
419 std::wstring accessDeniedReason()
420 { return m_access_denied_reason; }
422 bool itemdefReceived()
423 { return m_itemdef_received; }
424 bool nodedefReceived()
425 { return m_nodedef_received; }
427 { return m_media_downloader == NULL; }
429 float mediaReceiveProgress();
431 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
435 // IGameDef interface
436 virtual IItemDefManager* getItemDefManager();
437 virtual INodeDefManager* getNodeDefManager();
438 virtual ICraftDefManager* getCraftDefManager();
439 virtual ITextureSource* getTextureSource();
440 virtual IShaderSource* getShaderSource();
441 virtual u16 allocateUnknownNodeId(const std::string &name);
442 virtual ISoundManager* getSoundManager();
443 virtual MtEventManager* getEventManager();
444 virtual bool checkLocalPrivilege(const std::string &priv)
445 { return checkPrivilege(priv); }
446 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
448 // The following set of functions is used by ClientMediaDownloader
449 // Insert a media file appropriately into the appropriate manager
450 bool loadMedia(const std::string &data, const std::string &filename);
451 // Send a request for conventional media transfer
452 void request_media(const std::list<std::string> &file_requests);
453 // Send a notification that no conventional media transfer is needed
454 void received_media();
458 // Virtual methods from con::PeerHandler
459 void peerAdded(con::Peer *peer);
460 void deletingPeer(con::Peer *peer, bool timeout);
465 void sendPlayerPos();
466 // Send the item number 'item' as player item to the server
467 void sendPlayerItem(u16 item);
469 float m_packetcounter_timer;
470 float m_connection_reinit_timer;
471 float m_avg_rtt_timer;
472 float m_playerpos_send_timer;
473 float m_ignore_damage_timer; // Used after server moves player
474 IntervalLimiter m_map_timer_and_unload_interval;
476 IWritableTextureSource *m_tsrc;
477 IWritableShaderSource *m_shsrc;
478 IWritableItemDefManager *m_itemdef;
479 IWritableNodeDefManager *m_nodedef;
480 ISoundManager *m_sound;
481 MtEventManager *m_event;
483 MeshUpdateThread m_mesh_update_thread;
484 ClientEnvironment m_env;
485 con::Connection m_con;
486 IrrlichtDevice *m_device;
487 // Server serialization version
490 bool m_inventory_updated;
491 Inventory *m_inventory_from_server;
492 float m_inventory_from_server_age;
493 std::set<v3s16> m_active_blocks;
494 PacketCounter m_packetcounter;
495 // Block mesh animation parameters
496 float m_animation_time;
499 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
501 //u32 m_daynight_ratio;
502 Queue<std::wstring> m_chat_queue;
503 // The seed returned by the server in TOCLIENT_INIT is stored here
505 std::string m_password;
506 bool m_access_denied;
507 std::wstring m_access_denied_reason;
508 Queue<ClientEvent> m_client_event_queue;
509 bool m_itemdef_received;
510 bool m_nodedef_received;
511 ClientMediaDownloader *m_media_downloader;
513 // time_of_day speed approximation for old protocol
514 bool m_time_of_day_set;
515 float m_last_time_of_day_f;
516 float m_time_of_day_update_timer;
518 // An interval for generally sending object positions and stuff
519 float m_recommended_send_interval;
522 float m_removed_sounds_check_timer;
523 // Mapping from server sound ids to our sound ids
524 std::map<s32, int> m_sounds_server_to_client;
525 // And the other way!
526 std::map<int, s32> m_sounds_client_to_server;
527 // And relations to objects
528 std::map<int, u16> m_sounds_to_objects;
531 std::set<std::string> m_privileges;
533 // Detached inventories
535 std::map<std::string, Inventory*> m_detached_inventories;
537 // Storage for mesh data for creating multiple instances of the same mesh
538 std::map<std::string, std::string> m_mesh_data;
541 #endif // !CLIENT_HEADER