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 std::list<std::string> getConnectedPlayerNames();
389 float getAnimationTime();
392 void setCrack(int level, v3s16 pos);
397 bool checkPrivilege(const std::string &priv)
398 { return (m_privileges.count(priv) != 0); }
400 bool getChatMessage(std::wstring &message);
401 void typeChatMessage(const std::wstring& message);
403 u64 getMapSeed(){ return m_map_seed; }
405 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
406 // Including blocks at appropriate edges
407 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
408 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
410 // Get event from queue. CE_NONE is returned if queue is empty.
411 ClientEvent getClientEvent();
414 { return m_access_denied; }
416 std::wstring accessDeniedReason()
417 { return m_access_denied_reason; }
419 bool itemdefReceived()
420 { return m_itemdef_received; }
421 bool nodedefReceived()
422 { return m_nodedef_received; }
424 { return m_media_downloader == NULL; }
426 float mediaReceiveProgress();
428 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
432 // IGameDef interface
433 virtual IItemDefManager* getItemDefManager();
434 virtual INodeDefManager* getNodeDefManager();
435 virtual ICraftDefManager* getCraftDefManager();
436 virtual ITextureSource* getTextureSource();
437 virtual IShaderSource* getShaderSource();
438 virtual u16 allocateUnknownNodeId(const std::string &name);
439 virtual ISoundManager* getSoundManager();
440 virtual MtEventManager* getEventManager();
441 virtual bool checkLocalPrivilege(const std::string &priv)
442 { return checkPrivilege(priv); }
443 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
445 // The following set of functions is used by ClientMediaDownloader
446 // Insert a media file appropriately into the appropriate manager
447 bool loadMedia(const std::string &data, const std::string &filename);
448 // Send a request for conventional media transfer
449 void request_media(const std::list<std::string> &file_requests);
450 // Send a notification that no conventional media transfer is needed
451 void received_media();
455 // Virtual methods from con::PeerHandler
456 void peerAdded(con::Peer *peer);
457 void deletingPeer(con::Peer *peer, bool timeout);
462 void sendPlayerPos();
463 // Send the item number 'item' as player item to the server
464 void sendPlayerItem(u16 item);
466 float m_packetcounter_timer;
467 float m_connection_reinit_timer;
468 float m_avg_rtt_timer;
469 float m_playerpos_send_timer;
470 float m_ignore_damage_timer; // Used after server moves player
471 IntervalLimiter m_map_timer_and_unload_interval;
473 IWritableTextureSource *m_tsrc;
474 IWritableShaderSource *m_shsrc;
475 IWritableItemDefManager *m_itemdef;
476 IWritableNodeDefManager *m_nodedef;
477 ISoundManager *m_sound;
478 MtEventManager *m_event;
480 MeshUpdateThread m_mesh_update_thread;
481 ClientEnvironment m_env;
482 con::Connection m_con;
483 IrrlichtDevice *m_device;
484 // Server serialization version
487 bool m_inventory_updated;
488 Inventory *m_inventory_from_server;
489 float m_inventory_from_server_age;
490 std::set<v3s16> m_active_blocks;
491 PacketCounter m_packetcounter;
492 // Block mesh animation parameters
493 float m_animation_time;
496 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
498 //u32 m_daynight_ratio;
499 Queue<std::wstring> m_chat_queue;
500 // The seed returned by the server in TOCLIENT_INIT is stored here
502 std::string m_password;
503 bool m_access_denied;
504 std::wstring m_access_denied_reason;
505 Queue<ClientEvent> m_client_event_queue;
506 bool m_itemdef_received;
507 bool m_nodedef_received;
508 ClientMediaDownloader *m_media_downloader;
510 // time_of_day speed approximation for old protocol
511 bool m_time_of_day_set;
512 float m_last_time_of_day_f;
513 float m_time_of_day_update_timer;
515 // An interval for generally sending object positions and stuff
516 float m_recommended_send_interval;
519 float m_removed_sounds_check_timer;
520 // Mapping from server sound ids to our sound ids
521 std::map<s32, int> m_sounds_server_to_client;
522 // And the other way!
523 std::map<int, s32> m_sounds_client_to_server;
524 // And relations to objects
525 std::map<int, u16> m_sounds_to_objects;
528 std::set<std::string> m_privileges;
530 // Detached inventories
532 std::map<std::string, Inventory*> m_detached_inventories;
534 // Storage for mesh data for creating multiple instances of the same mesh
535 std::map<std::string, std::string> m_mesh_data;
538 #endif // !CLIENT_HEADER