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;
60 enum LocalClientState {
67 A thread-safe queue of mesh update tasks
77 peer_id=0 adds with nobody to send to
79 void addBlock(v3s16 p, MeshMakeData *data,
80 bool ack_block_to_server, bool urgent);
82 // Returned pointer must be deleted
83 // Returns NULL if queue is empty
84 QueuedMeshUpdate * pop();
88 JMutexAutoLock lock(m_mutex);
89 return m_queue.size();
93 std::vector<QueuedMeshUpdate*> m_queue;
94 std::set<v3s16> m_urgents;
98 struct MeshUpdateResult
102 bool ack_block_to_server;
105 p(-1338,-1338,-1338),
107 ack_block_to_server(false)
112 class MeshUpdateThread : public JThread
116 MeshUpdateThread(IGameDef *gamedef):
123 MeshUpdateQueue m_queue_in;
125 MutexedQueue<MeshUpdateResult> m_queue_out;
129 v3s16 m_camera_offset;
136 CE_PLAYER_FORCE_MOVE,
140 CE_ADD_PARTICLESPAWNER,
141 CE_DELETE_PARTICLESPAWNER,
146 CE_OVERRIDE_DAY_NIGHT_RATIO,
151 ClientEventType type;
163 bool set_camera_point_target;
164 f32 camera_point_target_x;
165 f32 camera_point_target_y;
166 f32 camera_point_target_z;
169 std::string *formspec;
170 std::string *formname;
180 bool collisiondetection;
182 std::string *texture;
197 bool collisiondetection;
199 std::string *texture;
201 } add_particlespawner;
204 } delete_particlespawner;
233 video::SColor *bgcolor;
235 std::vector<std::string> *params;
240 } override_day_night_ratio;
255 void add(u16 command)
257 std::map<u16, u16>::iterator n = m_packets.find(command);
258 if(n == m_packets.end())
260 m_packets[command] = 1;
270 for(std::map<u16, u16>::iterator
271 i = m_packets.begin();
272 i != m_packets.end(); ++i)
278 void print(std::ostream &o)
280 for(std::map<u16, u16>::iterator
281 i = m_packets.begin();
282 i != m_packets.end(); ++i)
285 <<" count "<<i->second
292 std::map<u16, u16> m_packets;
295 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
299 NOTE: Nothing is thread-safe here.
303 IrrlichtDevice *device,
304 const char *playername,
305 std::string password,
306 MapDrawControl &control,
307 IWritableTextureSource *tsrc,
308 IWritableShaderSource *shsrc,
309 IWritableItemDefManager *itemdef,
310 IWritableNodeDefManager *nodedef,
311 ISoundManager *sound,
312 MtEventManager *event,
319 request all threads managed by client to be stopped
326 The name of the local player should already be set when
327 calling this, as it is sent in the initialization.
329 void connect(Address address);
332 Stuff that references the environment is valid only as
333 long as this is not called. (eg. Players)
334 If this throws a PeerNotFoundException, the connection has
337 void step(float dtime);
339 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
340 // Returns true if something was received
341 bool AsyncProcessPacket();
342 bool AsyncProcessData();
343 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
345 void interact(u8 action, const PointedThing& pointed);
347 void sendNodemetaFields(v3s16 p, const std::string &formname,
348 const std::map<std::string, std::string> &fields);
349 void sendInventoryFields(const std::string &formname,
350 const std::map<std::string, std::string> &fields);
351 void sendInventoryAction(InventoryAction *a);
352 void sendChatMessage(const std::wstring &message);
353 void sendChangePassword(const std::wstring &oldpassword,
354 const std::wstring &newpassword);
355 void sendDamage(u8 damage);
356 void sendBreath(u16 breath);
360 ClientEnvironment& getEnv()
363 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
364 void removeNode(v3s16 p);
365 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
367 void setPlayerControl(PlayerControl &control);
369 void selectPlayerItem(u16 item);
370 u16 getPlayerItem() const
371 { return m_playeritem; }
373 // Returns true if the inventory of the local player has been
374 // updated from the server. If it is true, it is set to false.
375 bool getLocalInventoryUpdated();
376 // Copies the inventory of the local player to parameter
377 void getLocalInventory(Inventory &dst);
379 /* InventoryManager interface */
380 Inventory* getInventory(const InventoryLocation &loc);
381 void inventoryAction(InventoryAction *a);
383 // Gets closest object pointed by the shootline
384 // Returns NULL if not found
385 ClientActiveObject * getSelectedActiveObject(
387 v3f from_pos_f_on_map,
388 core::line3d<f32> shootline_on_map
391 std::list<std::string> getConnectedPlayerNames();
393 float getAnimationTime();
396 void setCrack(int level, v3s16 pos);
401 bool checkPrivilege(const std::string &priv)
402 { return (m_privileges.count(priv) != 0); }
404 bool getChatMessage(std::wstring &message);
405 void typeChatMessage(const std::wstring& message);
407 u64 getMapSeed(){ return m_map_seed; }
409 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
410 // Including blocks at appropriate edges
411 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
412 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
414 void updateCameraOffset(v3s16 camera_offset)
415 { m_mesh_update_thread.m_camera_offset = camera_offset; }
417 // Get event from queue. CE_NONE is returned if queue is empty.
418 ClientEvent getClientEvent();
421 { return m_access_denied; }
423 std::wstring accessDeniedReason()
424 { return m_access_denied_reason; }
426 bool itemdefReceived()
427 { return m_itemdef_received; }
428 bool nodedefReceived()
429 { return m_nodedef_received; }
431 { return m_media_downloader == NULL; }
433 float mediaReceiveProgress();
435 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
438 float getCurRate(void);
439 float getAvgRate(void);
441 // IGameDef interface
442 virtual IItemDefManager* getItemDefManager();
443 virtual INodeDefManager* getNodeDefManager();
444 virtual ICraftDefManager* getCraftDefManager();
445 virtual ITextureSource* getTextureSource();
446 virtual IShaderSource* getShaderSource();
447 virtual u16 allocateUnknownNodeId(const std::string &name);
448 virtual ISoundManager* getSoundManager();
449 virtual MtEventManager* getEventManager();
450 virtual bool checkLocalPrivilege(const std::string &priv)
451 { return checkPrivilege(priv); }
452 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
454 // The following set of functions is used by ClientMediaDownloader
455 // Insert a media file appropriately into the appropriate manager
456 bool loadMedia(const std::string &data, const std::string &filename);
457 // Send a request for conventional media transfer
458 void request_media(const std::list<std::string> &file_requests);
459 // Send a notification that no conventional media transfer is needed
460 void received_media();
462 LocalClientState getState() { return m_state; }
466 // Virtual methods from con::PeerHandler
467 void peerAdded(con::Peer *peer);
468 void deletingPeer(con::Peer *peer, bool timeout);
473 void sendPlayerPos();
474 // Send the item number 'item' as player item to the server
475 void sendPlayerItem(u16 item);
477 float m_packetcounter_timer;
478 float m_connection_reinit_timer;
479 float m_avg_rtt_timer;
480 float m_playerpos_send_timer;
481 float m_ignore_damage_timer; // Used after server moves player
482 IntervalLimiter m_map_timer_and_unload_interval;
484 IWritableTextureSource *m_tsrc;
485 IWritableShaderSource *m_shsrc;
486 IWritableItemDefManager *m_itemdef;
487 IWritableNodeDefManager *m_nodedef;
488 ISoundManager *m_sound;
489 MtEventManager *m_event;
491 MeshUpdateThread m_mesh_update_thread;
492 ClientEnvironment m_env;
493 con::Connection m_con;
494 IrrlichtDevice *m_device;
495 // Server serialization version
498 bool m_inventory_updated;
499 Inventory *m_inventory_from_server;
500 float m_inventory_from_server_age;
501 std::set<v3s16> m_active_blocks;
502 PacketCounter m_packetcounter;
503 // Block mesh animation parameters
504 float m_animation_time;
507 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
509 //u32 m_daynight_ratio;
510 Queue<std::wstring> m_chat_queue;
511 // The seed returned by the server in TOCLIENT_INIT is stored here
513 std::string m_password;
514 bool m_access_denied;
515 std::wstring m_access_denied_reason;
516 Queue<ClientEvent> m_client_event_queue;
517 bool m_itemdef_received;
518 bool m_nodedef_received;
519 ClientMediaDownloader *m_media_downloader;
521 // time_of_day speed approximation for old protocol
522 bool m_time_of_day_set;
523 float m_last_time_of_day_f;
524 float m_time_of_day_update_timer;
526 // An interval for generally sending object positions and stuff
527 float m_recommended_send_interval;
530 float m_removed_sounds_check_timer;
531 // Mapping from server sound ids to our sound ids
532 std::map<s32, int> m_sounds_server_to_client;
533 // And the other way!
534 std::map<int, s32> m_sounds_client_to_server;
535 // And relations to objects
536 std::map<int, u16> m_sounds_to_objects;
539 std::set<std::string> m_privileges;
541 // Detached inventories
543 std::map<std::string, Inventory*> m_detached_inventories;
545 // Storage for mesh data for creating multiple instances of the same mesh
546 std::map<std::string, std::string> m_mesh_data;
549 LocalClientState m_state;
552 #endif // !CLIENT_HEADER