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,
141 ClientEventType type;
153 bool set_camera_point_target;
154 f32 camera_point_target_x;
155 f32 camera_point_target_y;
156 f32 camera_point_target_z;
159 std::string *formspec;
160 std::string *formname;
170 bool collisiondetection;
172 std::string *texture;
187 bool collisiondetection;
189 std::string *texture;
191 } add_particlespawner;
194 } delete_particlespawner;
234 void add(u16 command)
236 std::map<u16, u16>::iterator n = m_packets.find(command);
237 if(n == m_packets.end())
239 m_packets[command] = 1;
249 for(std::map<u16, u16>::iterator
250 i = m_packets.begin();
251 i != m_packets.end(); ++i)
257 void print(std::ostream &o)
259 for(std::map<u16, u16>::iterator
260 i = m_packets.begin();
261 i != m_packets.end(); ++i)
264 <<" count "<<i->second
271 std::map<u16, u16> m_packets;
274 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
278 NOTE: Nothing is thread-safe here.
282 IrrlichtDevice *device,
283 const char *playername,
284 std::string password,
285 MapDrawControl &control,
286 IWritableTextureSource *tsrc,
287 IWritableShaderSource *shsrc,
288 IWritableItemDefManager *itemdef,
289 IWritableNodeDefManager *nodedef,
290 ISoundManager *sound,
291 MtEventManager *event,
298 request all threads managed by client to be stopped
305 The name of the local player should already be set when
306 calling this, as it is sent in the initialization.
308 void connect(Address address);
311 m_con.Connected() == true
312 AND m_server_ser_ver != SER_FMT_VER_INVALID
313 throws con::PeerNotFoundException if connection has been deleted,
316 bool connectedAndInitialized();
318 Stuff that references the environment is valid only as
319 long as this is not called. (eg. Players)
320 If this throws a PeerNotFoundException, the connection has
323 void step(float dtime);
325 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
326 // Returns true if something was received
327 bool AsyncProcessPacket();
328 bool AsyncProcessData();
329 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
331 void interact(u8 action, const PointedThing& pointed);
333 void sendNodemetaFields(v3s16 p, const std::string &formname,
334 const std::map<std::string, std::string> &fields);
335 void sendInventoryFields(const std::string &formname,
336 const std::map<std::string, std::string> &fields);
337 void sendInventoryAction(InventoryAction *a);
338 void sendChatMessage(const std::wstring &message);
339 void sendChangePassword(const std::wstring oldpassword,
340 const std::wstring newpassword);
341 void sendDamage(u8 damage);
342 void sendBreath(u16 breath);
345 ClientEnvironment& getEnv()
348 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
349 void removeNode(v3s16 p);
350 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
352 void setPlayerControl(PlayerControl &control);
354 void selectPlayerItem(u16 item);
355 u16 getPlayerItem() const
356 { return m_playeritem; }
358 // Returns true if the inventory of the local player has been
359 // updated from the server. If it is true, it is set to false.
360 bool getLocalInventoryUpdated();
361 // Copies the inventory of the local player to parameter
362 void getLocalInventory(Inventory &dst);
364 /* InventoryManager interface */
365 Inventory* getInventory(const InventoryLocation &loc);
366 void inventoryAction(InventoryAction *a);
368 // Gets closest object pointed by the shootline
369 // Returns NULL if not found
370 ClientActiveObject * getSelectedActiveObject(
372 v3f from_pos_f_on_map,
373 core::line3d<f32> shootline_on_map
376 // Prints a line or two of info
377 void printDebugInfo(std::ostream &os);
379 std::list<std::string> getConnectedPlayerNames();
381 float getAnimationTime();
384 void setCrack(int level, v3s16 pos);
389 bool checkPrivilege(const std::string &priv)
390 { return (m_privileges.count(priv) != 0); }
392 bool getChatMessage(std::wstring &message);
393 void typeChatMessage(const std::wstring& message);
395 u64 getMapSeed(){ return m_map_seed; }
397 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
398 // Including blocks at appropriate edges
399 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
400 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
402 // Get event from queue. CE_NONE is returned if queue is empty.
403 ClientEvent getClientEvent();
406 { return m_access_denied; }
408 std::wstring accessDeniedReason()
409 { return m_access_denied_reason; }
411 bool itemdefReceived()
412 { return m_itemdef_received; }
413 bool nodedefReceived()
414 { return m_nodedef_received; }
416 { return m_media_downloader == NULL; }
418 float mediaReceiveProgress();
420 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
424 // IGameDef interface
425 virtual IItemDefManager* getItemDefManager();
426 virtual INodeDefManager* getNodeDefManager();
427 virtual ICraftDefManager* getCraftDefManager();
428 virtual ITextureSource* getTextureSource();
429 virtual IShaderSource* getShaderSource();
430 virtual u16 allocateUnknownNodeId(const std::string &name);
431 virtual ISoundManager* getSoundManager();
432 virtual MtEventManager* getEventManager();
433 virtual bool checkLocalPrivilege(const std::string &priv)
434 { return checkPrivilege(priv); }
435 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
437 // The following set of functions is used by ClientMediaDownloader
438 // Insert a media file appropriately into the appropriate manager
439 bool loadMedia(const std::string &data, const std::string &filename);
440 // Send a request for conventional media transfer
441 void request_media(const std::list<std::string> &file_requests);
442 // Send a notification that no conventional media transfer is needed
443 void received_media();
447 // Virtual methods from con::PeerHandler
448 void peerAdded(con::Peer *peer);
449 void deletingPeer(con::Peer *peer, bool timeout);
454 void sendPlayerPos();
455 // Send the item number 'item' as player item to the server
456 void sendPlayerItem(u16 item);
458 float m_packetcounter_timer;
459 float m_connection_reinit_timer;
460 float m_avg_rtt_timer;
461 float m_playerpos_send_timer;
462 float m_ignore_damage_timer; // Used after server moves player
463 IntervalLimiter m_map_timer_and_unload_interval;
465 IWritableTextureSource *m_tsrc;
466 IWritableShaderSource *m_shsrc;
467 IWritableItemDefManager *m_itemdef;
468 IWritableNodeDefManager *m_nodedef;
469 ISoundManager *m_sound;
470 MtEventManager *m_event;
472 MeshUpdateThread m_mesh_update_thread;
473 ClientEnvironment m_env;
474 con::Connection m_con;
475 IrrlichtDevice *m_device;
476 // Server serialization version
479 bool m_inventory_updated;
480 Inventory *m_inventory_from_server;
481 float m_inventory_from_server_age;
482 std::set<v3s16> m_active_blocks;
483 PacketCounter m_packetcounter;
484 // Block mesh animation parameters
485 float m_animation_time;
488 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
490 //u32 m_daynight_ratio;
491 Queue<std::wstring> m_chat_queue;
492 // The seed returned by the server in TOCLIENT_INIT is stored here
494 std::string m_password;
495 bool m_access_denied;
496 std::wstring m_access_denied_reason;
497 Queue<ClientEvent> m_client_event_queue;
498 bool m_itemdef_received;
499 bool m_nodedef_received;
500 ClientMediaDownloader *m_media_downloader;
502 // time_of_day speed approximation for old protocol
503 bool m_time_of_day_set;
504 float m_last_time_of_day_f;
505 float m_time_of_day_update_timer;
507 // An interval for generally sending object positions and stuff
508 float m_recommended_send_interval;
511 float m_removed_sounds_check_timer;
512 // Mapping from server sound ids to our sound ids
513 std::map<s32, int> m_sounds_server_to_client;
514 // And the other way!
515 std::map<int, s32> m_sounds_client_to_server;
516 // And relations to objects
517 std::map<int, u16> m_sounds_to_objects;
520 std::set<std::string> m_privileges;
522 // Detached inventories
524 std::map<std::string, Inventory*> m_detached_inventories;
526 // Storage for mesh data for creating multiple instances of the same mesh
527 std::map<std::string, std::string> m_mesh_data;
530 #endif // !CLIENT_HEADER