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;
232 void add(u16 command)
234 std::map<u16, u16>::iterator n = m_packets.find(command);
235 if(n == m_packets.end())
237 m_packets[command] = 1;
247 for(std::map<u16, u16>::iterator
248 i = m_packets.begin();
249 i != m_packets.end(); ++i)
255 void print(std::ostream &o)
257 for(std::map<u16, u16>::iterator
258 i = m_packets.begin();
259 i != m_packets.end(); ++i)
262 <<" count "<<i->second
269 std::map<u16, u16> m_packets;
272 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
276 NOTE: Nothing is thread-safe here.
280 IrrlichtDevice *device,
281 const char *playername,
282 std::string password,
283 MapDrawControl &control,
284 IWritableTextureSource *tsrc,
285 IWritableShaderSource *shsrc,
286 IWritableItemDefManager *itemdef,
287 IWritableNodeDefManager *nodedef,
288 ISoundManager *sound,
289 MtEventManager *event,
296 request all threads managed by client to be stopped
303 The name of the local player should already be set when
304 calling this, as it is sent in the initialization.
306 void connect(Address address);
309 m_con.Connected() == true
310 AND m_server_ser_ver != SER_FMT_VER_INVALID
311 throws con::PeerNotFoundException if connection has been deleted,
314 bool connectedAndInitialized();
316 Stuff that references the environment is valid only as
317 long as this is not called. (eg. Players)
318 If this throws a PeerNotFoundException, the connection has
321 void step(float dtime);
323 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
324 // Returns true if something was received
325 bool AsyncProcessPacket();
326 bool AsyncProcessData();
327 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
329 void interact(u8 action, const PointedThing& pointed);
331 void sendNodemetaFields(v3s16 p, const std::string &formname,
332 const std::map<std::string, std::string> &fields);
333 void sendInventoryFields(const std::string &formname,
334 const std::map<std::string, std::string> &fields);
335 void sendInventoryAction(InventoryAction *a);
336 void sendChatMessage(const std::wstring &message);
337 void sendChangePassword(const std::wstring oldpassword,
338 const std::wstring newpassword);
339 void sendDamage(u8 damage);
340 void sendBreath(u16 breath);
343 ClientEnvironment& getEnv()
346 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
347 void removeNode(v3s16 p);
348 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
350 void setPlayerControl(PlayerControl &control);
352 void selectPlayerItem(u16 item);
353 u16 getPlayerItem() const
354 { return m_playeritem; }
356 // Returns true if the inventory of the local player has been
357 // updated from the server. If it is true, it is set to false.
358 bool getLocalInventoryUpdated();
359 // Copies the inventory of the local player to parameter
360 void getLocalInventory(Inventory &dst);
362 /* InventoryManager interface */
363 Inventory* getInventory(const InventoryLocation &loc);
364 void inventoryAction(InventoryAction *a);
366 // Gets closest object pointed by the shootline
367 // Returns NULL if not found
368 ClientActiveObject * getSelectedActiveObject(
370 v3f from_pos_f_on_map,
371 core::line3d<f32> shootline_on_map
374 // Prints a line or two of info
375 void printDebugInfo(std::ostream &os);
377 std::list<std::string> getConnectedPlayerNames();
379 float getAnimationTime();
382 void setCrack(int level, v3s16 pos);
387 bool checkPrivilege(const std::string &priv)
388 { return (m_privileges.count(priv) != 0); }
390 bool getChatMessage(std::wstring &message);
391 void typeChatMessage(const std::wstring& message);
393 u64 getMapSeed(){ return m_map_seed; }
395 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
396 // Including blocks at appropriate edges
397 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
398 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
400 // Get event from queue. CE_NONE is returned if queue is empty.
401 ClientEvent getClientEvent();
404 { return m_access_denied; }
406 std::wstring accessDeniedReason()
407 { return m_access_denied_reason; }
409 bool itemdefReceived()
410 { return m_itemdef_received; }
411 bool nodedefReceived()
412 { return m_nodedef_received; }
414 { return m_media_downloader == NULL; }
416 float mediaReceiveProgress();
418 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
422 // IGameDef interface
423 virtual IItemDefManager* getItemDefManager();
424 virtual INodeDefManager* getNodeDefManager();
425 virtual ICraftDefManager* getCraftDefManager();
426 virtual ITextureSource* getTextureSource();
427 virtual IShaderSource* getShaderSource();
428 virtual u16 allocateUnknownNodeId(const std::string &name);
429 virtual ISoundManager* getSoundManager();
430 virtual MtEventManager* getEventManager();
431 virtual bool checkLocalPrivilege(const std::string &priv)
432 { return checkPrivilege(priv); }
433 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
435 // The following set of functions is used by ClientMediaDownloader
436 // Insert a media file appropriately into the appropriate manager
437 bool loadMedia(const std::string &data, const std::string &filename);
438 // Send a request for conventional media transfer
439 void request_media(const std::list<std::string> &file_requests);
440 // Send a notification that no conventional media transfer is needed
441 void received_media();
445 // Virtual methods from con::PeerHandler
446 void peerAdded(con::Peer *peer);
447 void deletingPeer(con::Peer *peer, bool timeout);
452 void sendPlayerPos();
453 // Send the item number 'item' as player item to the server
454 void sendPlayerItem(u16 item);
456 float m_packetcounter_timer;
457 float m_connection_reinit_timer;
458 float m_avg_rtt_timer;
459 float m_playerpos_send_timer;
460 float m_ignore_damage_timer; // Used after server moves player
461 IntervalLimiter m_map_timer_and_unload_interval;
463 IWritableTextureSource *m_tsrc;
464 IWritableShaderSource *m_shsrc;
465 IWritableItemDefManager *m_itemdef;
466 IWritableNodeDefManager *m_nodedef;
467 ISoundManager *m_sound;
468 MtEventManager *m_event;
470 MeshUpdateThread m_mesh_update_thread;
471 ClientEnvironment m_env;
472 con::Connection m_con;
473 IrrlichtDevice *m_device;
474 // Server serialization version
477 bool m_inventory_updated;
478 Inventory *m_inventory_from_server;
479 float m_inventory_from_server_age;
480 std::set<v3s16> m_active_blocks;
481 PacketCounter m_packetcounter;
482 // Block mesh animation parameters
483 float m_animation_time;
486 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
488 //u32 m_daynight_ratio;
489 Queue<std::wstring> m_chat_queue;
490 // The seed returned by the server in TOCLIENT_INIT is stored here
492 std::string m_password;
493 bool m_access_denied;
494 std::wstring m_access_denied_reason;
495 Queue<ClientEvent> m_client_event_queue;
496 bool m_itemdef_received;
497 bool m_nodedef_received;
498 ClientMediaDownloader *m_media_downloader;
500 // time_of_day speed approximation for old protocol
501 bool m_time_of_day_set;
502 float m_last_time_of_day_f;
503 float m_time_of_day_update_timer;
505 // An interval for generally sending object positions and stuff
506 float m_recommended_send_interval;
509 float m_removed_sounds_check_timer;
510 // Mapping from server sound ids to our sound ids
511 std::map<s32, int> m_sounds_server_to_client;
512 // And the other way!
513 std::map<int, s32> m_sounds_client_to_server;
514 // And relations to objects
515 std::map<int, u16> m_sounds_to_objects;
518 std::set<std::string> m_privileges;
520 // Detached inventories
522 std::map<std::string, Inventory*> m_detached_inventories;
524 // Storage for mesh data for creating multiple instances of the same mesh
525 std::map<std::string, std::string> m_mesh_data;
528 #endif // !CLIENT_HEADER