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);
398 void setHighlighted(v3s16 pos, bool show_hud);
399 v3s16 getHighlighted(){ return m_highlighted_pos; }
404 bool checkPrivilege(const std::string &priv)
405 { return (m_privileges.count(priv) != 0); }
407 bool getChatMessage(std::wstring &message);
408 void typeChatMessage(const std::wstring& message);
410 u64 getMapSeed(){ return m_map_seed; }
412 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
413 // Including blocks at appropriate edges
414 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
415 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
417 void updateCameraOffset(v3s16 camera_offset)
418 { m_mesh_update_thread.m_camera_offset = camera_offset; }
420 // Get event from queue. CE_NONE is returned if queue is empty.
421 ClientEvent getClientEvent();
424 { return m_access_denied; }
426 std::wstring accessDeniedReason()
427 { return m_access_denied_reason; }
429 bool itemdefReceived()
430 { return m_itemdef_received; }
431 bool nodedefReceived()
432 { return m_nodedef_received; }
434 { return m_media_downloader == NULL; }
436 float mediaReceiveProgress();
438 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
441 float getCurRate(void);
442 float getAvgRate(void);
444 // IGameDef interface
445 virtual IItemDefManager* getItemDefManager();
446 virtual INodeDefManager* getNodeDefManager();
447 virtual ICraftDefManager* getCraftDefManager();
448 virtual ITextureSource* getTextureSource();
449 virtual IShaderSource* getShaderSource();
450 virtual u16 allocateUnknownNodeId(const std::string &name);
451 virtual ISoundManager* getSoundManager();
452 virtual MtEventManager* getEventManager();
453 virtual bool checkLocalPrivilege(const std::string &priv)
454 { return checkPrivilege(priv); }
455 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
457 // The following set of functions is used by ClientMediaDownloader
458 // Insert a media file appropriately into the appropriate manager
459 bool loadMedia(const std::string &data, const std::string &filename);
460 // Send a request for conventional media transfer
461 void request_media(const std::list<std::string> &file_requests);
462 // Send a notification that no conventional media transfer is needed
463 void received_media();
465 LocalClientState getState() { return m_state; }
469 // Virtual methods from con::PeerHandler
470 void peerAdded(con::Peer *peer);
471 void deletingPeer(con::Peer *peer, bool timeout);
476 void sendPlayerPos();
477 // Send the item number 'item' as player item to the server
478 void sendPlayerItem(u16 item);
480 float m_packetcounter_timer;
481 float m_connection_reinit_timer;
482 float m_avg_rtt_timer;
483 float m_playerpos_send_timer;
484 float m_ignore_damage_timer; // Used after server moves player
485 IntervalLimiter m_map_timer_and_unload_interval;
487 IWritableTextureSource *m_tsrc;
488 IWritableShaderSource *m_shsrc;
489 IWritableItemDefManager *m_itemdef;
490 IWritableNodeDefManager *m_nodedef;
491 ISoundManager *m_sound;
492 MtEventManager *m_event;
494 MeshUpdateThread m_mesh_update_thread;
495 ClientEnvironment m_env;
496 con::Connection m_con;
497 IrrlichtDevice *m_device;
498 // Server serialization version
501 bool m_inventory_updated;
502 Inventory *m_inventory_from_server;
503 float m_inventory_from_server_age;
504 std::set<v3s16> m_active_blocks;
505 PacketCounter m_packetcounter;
507 // Block mesh animation parameters
508 float m_animation_time;
511 v3s16 m_highlighted_pos;
512 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
514 //u32 m_daynight_ratio;
515 Queue<std::wstring> m_chat_queue;
516 // The seed returned by the server in TOCLIENT_INIT is stored here
518 std::string m_password;
519 bool m_access_denied;
520 std::wstring m_access_denied_reason;
521 Queue<ClientEvent> m_client_event_queue;
522 bool m_itemdef_received;
523 bool m_nodedef_received;
524 ClientMediaDownloader *m_media_downloader;
526 // time_of_day speed approximation for old protocol
527 bool m_time_of_day_set;
528 float m_last_time_of_day_f;
529 float m_time_of_day_update_timer;
531 // An interval for generally sending object positions and stuff
532 float m_recommended_send_interval;
535 float m_removed_sounds_check_timer;
536 // Mapping from server sound ids to our sound ids
537 std::map<s32, int> m_sounds_server_to_client;
538 // And the other way!
539 std::map<int, s32> m_sounds_client_to_server;
540 // And relations to objects
541 std::map<int, u16> m_sounds_to_objects;
544 std::set<std::string> m_privileges;
546 // Detached inventories
548 std::map<std::string, Inventory*> m_detached_inventories;
550 // Storage for mesh data for creating multiple instances of the same mesh
551 std::map<std::string, std::string> m_mesh_data;
554 LocalClientState m_state;
557 #endif // !CLIENT_HEADER