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;
171 std::string *texture;
186 bool collisiondetection;
187 std::string *texture;
189 } add_particlespawner;
192 } delete_particlespawner;
230 void add(u16 command)
232 std::map<u16, u16>::iterator n = m_packets.find(command);
233 if(n == m_packets.end())
235 m_packets[command] = 1;
245 for(std::map<u16, u16>::iterator
246 i = m_packets.begin();
247 i != m_packets.end(); ++i)
253 void print(std::ostream &o)
255 for(std::map<u16, u16>::iterator
256 i = m_packets.begin();
257 i != m_packets.end(); ++i)
260 <<" count "<<i->second
267 std::map<u16, u16> m_packets;
270 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
274 NOTE: Nothing is thread-safe here.
278 IrrlichtDevice *device,
279 const char *playername,
280 std::string password,
281 MapDrawControl &control,
282 IWritableTextureSource *tsrc,
283 IWritableShaderSource *shsrc,
284 IWritableItemDefManager *itemdef,
285 IWritableNodeDefManager *nodedef,
286 ISoundManager *sound,
287 MtEventManager *event,
294 request all threads managed by client to be stopped
301 The name of the local player should already be set when
302 calling this, as it is sent in the initialization.
304 void connect(Address address);
307 m_con.Connected() == true
308 AND m_server_ser_ver != SER_FMT_VER_INVALID
309 throws con::PeerNotFoundException if connection has been deleted,
312 bool connectedAndInitialized();
314 Stuff that references the environment is valid only as
315 long as this is not called. (eg. Players)
316 If this throws a PeerNotFoundException, the connection has
319 void step(float dtime);
321 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
322 // Returns true if something was received
323 bool AsyncProcessPacket();
324 bool AsyncProcessData();
325 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
327 void interact(u8 action, const PointedThing& pointed);
329 void sendNodemetaFields(v3s16 p, const std::string &formname,
330 const std::map<std::string, std::string> &fields);
331 void sendInventoryFields(const std::string &formname,
332 const std::map<std::string, std::string> &fields);
333 void sendInventoryAction(InventoryAction *a);
334 void sendChatMessage(const std::wstring &message);
335 void sendChangePassword(const std::wstring oldpassword,
336 const std::wstring newpassword);
337 void sendDamage(u8 damage);
338 void sendBreath(u16 breath);
341 ClientEnvironment& getEnv()
344 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
345 void removeNode(v3s16 p);
346 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
348 void setPlayerControl(PlayerControl &control);
350 void selectPlayerItem(u16 item);
351 u16 getPlayerItem() const
352 { return m_playeritem; }
354 // Returns true if the inventory of the local player has been
355 // updated from the server. If it is true, it is set to false.
356 bool getLocalInventoryUpdated();
357 // Copies the inventory of the local player to parameter
358 void getLocalInventory(Inventory &dst);
360 /* InventoryManager interface */
361 Inventory* getInventory(const InventoryLocation &loc);
362 void inventoryAction(InventoryAction *a);
364 // Gets closest object pointed by the shootline
365 // Returns NULL if not found
366 ClientActiveObject * getSelectedActiveObject(
368 v3f from_pos_f_on_map,
369 core::line3d<f32> shootline_on_map
372 // Prints a line or two of info
373 void printDebugInfo(std::ostream &os);
375 std::list<std::string> getConnectedPlayerNames();
377 float getAnimationTime();
380 void setCrack(int level, v3s16 pos);
385 bool checkPrivilege(const std::string &priv)
386 { return (m_privileges.count(priv) != 0); }
388 bool getChatMessage(std::wstring &message);
389 void typeChatMessage(const std::wstring& message);
391 u64 getMapSeed(){ return m_map_seed; }
393 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
394 // Including blocks at appropriate edges
395 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
396 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
398 // Get event from queue. CE_NONE is returned if queue is empty.
399 ClientEvent getClientEvent();
402 { return m_access_denied; }
404 std::wstring accessDeniedReason()
405 { return m_access_denied_reason; }
407 bool itemdefReceived()
408 { return m_itemdef_received; }
409 bool nodedefReceived()
410 { return m_nodedef_received; }
412 { return m_media_downloader == NULL; }
414 float mediaReceiveProgress();
416 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
420 // IGameDef interface
421 virtual IItemDefManager* getItemDefManager();
422 virtual INodeDefManager* getNodeDefManager();
423 virtual ICraftDefManager* getCraftDefManager();
424 virtual ITextureSource* getTextureSource();
425 virtual IShaderSource* getShaderSource();
426 virtual u16 allocateUnknownNodeId(const std::string &name);
427 virtual ISoundManager* getSoundManager();
428 virtual MtEventManager* getEventManager();
429 virtual bool checkLocalPrivilege(const std::string &priv)
430 { return checkPrivilege(priv); }
431 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
433 // The following set of functions is used by ClientMediaDownloader
434 // Insert a media file appropriately into the appropriate manager
435 bool loadMedia(const std::string &data, const std::string &filename);
436 // Send a request for conventional media transfer
437 void request_media(const std::list<std::string> &file_requests);
438 // Send a notification that no conventional media transfer is needed
439 void received_media();
443 // Virtual methods from con::PeerHandler
444 void peerAdded(con::Peer *peer);
445 void deletingPeer(con::Peer *peer, bool timeout);
450 void sendPlayerPos();
451 // Send the item number 'item' as player item to the server
452 void sendPlayerItem(u16 item);
454 float m_packetcounter_timer;
455 float m_connection_reinit_timer;
456 float m_avg_rtt_timer;
457 float m_playerpos_send_timer;
458 float m_ignore_damage_timer; // Used after server moves player
459 IntervalLimiter m_map_timer_and_unload_interval;
461 IWritableTextureSource *m_tsrc;
462 IWritableShaderSource *m_shsrc;
463 IWritableItemDefManager *m_itemdef;
464 IWritableNodeDefManager *m_nodedef;
465 ISoundManager *m_sound;
466 MtEventManager *m_event;
468 MeshUpdateThread m_mesh_update_thread;
469 ClientEnvironment m_env;
470 con::Connection m_con;
471 IrrlichtDevice *m_device;
472 // Server serialization version
475 bool m_inventory_updated;
476 Inventory *m_inventory_from_server;
477 float m_inventory_from_server_age;
478 std::set<v3s16> m_active_blocks;
479 PacketCounter m_packetcounter;
480 // Block mesh animation parameters
481 float m_animation_time;
484 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
486 //u32 m_daynight_ratio;
487 Queue<std::wstring> m_chat_queue;
488 // The seed returned by the server in TOCLIENT_INIT is stored here
490 std::string m_password;
491 bool m_access_denied;
492 std::wstring m_access_denied_reason;
493 Queue<ClientEvent> m_client_event_queue;
494 bool m_itemdef_received;
495 bool m_nodedef_received;
496 ClientMediaDownloader *m_media_downloader;
498 // time_of_day speed approximation for old protocol
499 bool m_time_of_day_set;
500 float m_last_time_of_day_f;
501 float m_time_of_day_update_timer;
503 // An interval for generally sending object positions and stuff
504 float m_recommended_send_interval;
507 float m_removed_sounds_check_timer;
508 // Mapping from server sound ids to our sound ids
509 std::map<s32, int> m_sounds_server_to_client;
510 // And the other way!
511 std::map<int, s32> m_sounds_client_to_server;
512 // And relations to objects
513 std::map<int, u16> m_sounds_to_objects;
516 std::set<std::string> m_privileges;
518 // Detached inventories
520 std::map<std::string, Inventory*> m_detached_inventories;
522 // Storage for mesh data for creating multiple instances of the same mesh
523 std::map<std::string, std::string> m_mesh_data;
526 #endif // !CLIENT_HEADER