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;
52 struct QueuedMeshUpdate
56 bool ack_block_to_server;
62 enum LocalClientState {
69 A thread-safe queue of mesh update tasks
79 peer_id=0 adds with nobody to send to
81 void addBlock(v3s16 p, MeshMakeData *data,
82 bool ack_block_to_server, bool urgent);
84 // Returned pointer must be deleted
85 // Returns NULL if queue is empty
86 QueuedMeshUpdate * pop();
90 JMutexAutoLock lock(m_mutex);
91 return m_queue.size();
95 std::vector<QueuedMeshUpdate*> m_queue;
96 std::set<v3s16> m_urgents;
100 struct MeshUpdateResult
104 bool ack_block_to_server;
107 p(-1338,-1338,-1338),
109 ack_block_to_server(false)
114 class MeshUpdateThread : public JThread
118 MeshUpdateThread(IGameDef *gamedef):
125 MeshUpdateQueue m_queue_in;
127 MutexedQueue<MeshUpdateResult> m_queue_out;
131 v3s16 m_camera_offset;
138 CE_PLAYER_FORCE_MOVE,
142 CE_ADD_PARTICLESPAWNER,
143 CE_DELETE_PARTICLESPAWNER,
148 CE_OVERRIDE_DAY_NIGHT_RATIO,
153 ClientEventType type;
165 bool set_camera_point_target;
166 f32 camera_point_target_x;
167 f32 camera_point_target_y;
168 f32 camera_point_target_z;
171 std::string *formspec;
172 std::string *formname;
175 //} textures_updated;
182 bool collisiondetection;
184 std::string *texture;
199 bool collisiondetection;
201 std::string *texture;
203 } add_particlespawner;
206 } delete_particlespawner;
235 video::SColor *bgcolor;
237 std::vector<std::string> *params;
242 } override_day_night_ratio;
257 void add(u16 command)
259 std::map<u16, u16>::iterator n = m_packets.find(command);
260 if(n == m_packets.end())
262 m_packets[command] = 1;
272 for(std::map<u16, u16>::iterator
273 i = m_packets.begin();
274 i != m_packets.end(); ++i)
280 void print(std::ostream &o)
282 for(std::map<u16, u16>::iterator
283 i = m_packets.begin();
284 i != m_packets.end(); ++i)
287 <<" count "<<i->second
294 std::map<u16, u16> m_packets;
297 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
301 NOTE: Nothing is thread-safe here.
305 IrrlichtDevice *device,
306 const char *playername,
307 std::string password,
308 bool is_simple_singleplayer_game,
309 MapDrawControl &control,
310 IWritableTextureSource *tsrc,
311 IWritableShaderSource *shsrc,
312 IWritableItemDefManager *itemdef,
313 IWritableNodeDefManager *nodedef,
314 ISoundManager *sound,
315 MtEventManager *event,
322 request all threads managed by client to be stopped
329 The name of the local player should already be set when
330 calling this, as it is sent in the initialization.
332 void connect(Address address);
335 Stuff that references the environment is valid only as
336 long as this is not called. (eg. Players)
337 If this throws a PeerNotFoundException, the connection has
340 void step(float dtime);
342 void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
343 // Returns true if something was received
344 bool AsyncProcessPacket();
345 bool AsyncProcessData();
346 void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
348 void interact(u8 action, const PointedThing& pointed);
350 void sendNodemetaFields(v3s16 p, const std::string &formname,
351 const std::map<std::string, std::string> &fields);
352 void sendInventoryFields(const std::string &formname,
353 const std::map<std::string, std::string> &fields);
354 void sendInventoryAction(InventoryAction *a);
355 void sendChatMessage(const std::wstring &message);
356 void sendChangePassword(const std::wstring &oldpassword,
357 const std::wstring &newpassword);
358 void sendDamage(u8 damage);
359 void sendBreath(u16 breath);
363 ClientEnvironment& getEnv()
366 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
367 void removeNode(v3s16 p);
368 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
370 void setPlayerControl(PlayerControl &control);
372 void selectPlayerItem(u16 item);
373 u16 getPlayerItem() const
374 { return m_playeritem; }
376 // Returns true if the inventory of the local player has been
377 // updated from the server. If it is true, it is set to false.
378 bool getLocalInventoryUpdated();
379 // Copies the inventory of the local player to parameter
380 void getLocalInventory(Inventory &dst);
382 /* InventoryManager interface */
383 Inventory* getInventory(const InventoryLocation &loc);
384 void inventoryAction(InventoryAction *a);
386 // Gets closest object pointed by the shootline
387 // Returns NULL if not found
388 ClientActiveObject * getSelectedActiveObject(
390 v3f from_pos_f_on_map,
391 core::line3d<f32> shootline_on_map
394 std::list<std::string> getConnectedPlayerNames();
396 float getAnimationTime();
399 void setCrack(int level, v3s16 pos);
401 void setHighlighted(v3s16 pos, bool show_higlighted);
402 v3s16 getHighlighted(){ return m_highlighted_pos; }
407 bool checkPrivilege(const std::string &priv)
408 { return (m_privileges.count(priv) != 0); }
410 bool getChatMessage(std::wstring &message);
411 void typeChatMessage(const std::wstring& message);
413 u64 getMapSeed(){ return m_map_seed; }
415 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
416 // Including blocks at appropriate edges
417 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
418 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
420 void updateCameraOffset(v3s16 camera_offset)
421 { m_mesh_update_thread.m_camera_offset = camera_offset; }
423 // Get event from queue. CE_NONE is returned if queue is empty.
424 ClientEvent getClientEvent();
427 { return m_access_denied; }
429 std::wstring accessDeniedReason()
430 { return m_access_denied_reason; }
432 bool itemdefReceived()
433 { return m_itemdef_received; }
434 bool nodedefReceived()
435 { return m_nodedef_received; }
437 { return m_media_downloader == NULL; }
439 float mediaReceiveProgress();
441 void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
444 float getCurRate(void);
445 float getAvgRate(void);
447 // IGameDef interface
448 virtual IItemDefManager* getItemDefManager();
449 virtual INodeDefManager* getNodeDefManager();
450 virtual ICraftDefManager* getCraftDefManager();
451 virtual ITextureSource* getTextureSource();
452 virtual IShaderSource* getShaderSource();
453 virtual scene::ISceneManager* getSceneManager();
454 virtual u16 allocateUnknownNodeId(const std::string &name);
455 virtual ISoundManager* getSoundManager();
456 virtual MtEventManager* getEventManager();
457 virtual ParticleManager* getParticleManager();
458 virtual bool checkLocalPrivilege(const std::string &priv)
459 { return checkPrivilege(priv); }
460 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
462 // The following set of functions is used by ClientMediaDownloader
463 // Insert a media file appropriately into the appropriate manager
464 bool loadMedia(const std::string &data, const std::string &filename);
465 // Send a request for conventional media transfer
466 void request_media(const std::list<std::string> &file_requests);
467 // Send a notification that no conventional media transfer is needed
468 void received_media();
470 LocalClientState getState() { return m_state; }
472 void makeScreenshot(IrrlichtDevice *device);
476 // Virtual methods from con::PeerHandler
477 void peerAdded(con::Peer *peer);
478 void deletingPeer(con::Peer *peer, bool timeout);
483 void sendPlayerPos();
484 // Send the item number 'item' as player item to the server
485 void sendPlayerItem(u16 item);
487 float m_packetcounter_timer;
488 float m_connection_reinit_timer;
489 float m_avg_rtt_timer;
490 float m_playerpos_send_timer;
491 float m_ignore_damage_timer; // Used after server moves player
492 IntervalLimiter m_map_timer_and_unload_interval;
494 IWritableTextureSource *m_tsrc;
495 IWritableShaderSource *m_shsrc;
496 IWritableItemDefManager *m_itemdef;
497 IWritableNodeDefManager *m_nodedef;
498 ISoundManager *m_sound;
499 MtEventManager *m_event;
502 MeshUpdateThread m_mesh_update_thread;
503 ClientEnvironment m_env;
504 ParticleManager m_particle_manager;
505 con::Connection m_con;
506 IrrlichtDevice *m_device;
507 // Server serialization version
510 bool m_inventory_updated;
511 Inventory *m_inventory_from_server;
512 float m_inventory_from_server_age;
513 std::set<v3s16> m_active_blocks;
514 PacketCounter m_packetcounter;
515 bool m_show_highlighted;
516 // Block mesh animation parameters
517 float m_animation_time;
520 v3s16 m_highlighted_pos;
521 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
523 //u32 m_daynight_ratio;
524 Queue<std::wstring> m_chat_queue;
525 // The seed returned by the server in TOCLIENT_INIT is stored here
527 std::string m_password;
528 bool m_access_denied;
529 std::wstring m_access_denied_reason;
530 Queue<ClientEvent> m_client_event_queue;
531 bool m_itemdef_received;
532 bool m_nodedef_received;
533 ClientMediaDownloader *m_media_downloader;
535 // time_of_day speed approximation for old protocol
536 bool m_time_of_day_set;
537 float m_last_time_of_day_f;
538 float m_time_of_day_update_timer;
540 // An interval for generally sending object positions and stuff
541 float m_recommended_send_interval;
544 float m_removed_sounds_check_timer;
545 // Mapping from server sound ids to our sound ids
546 std::map<s32, int> m_sounds_server_to_client;
547 // And the other way!
548 std::map<int, s32> m_sounds_client_to_server;
549 // And relations to objects
550 std::map<int, u16> m_sounds_to_objects;
553 std::set<std::string> m_privileges;
555 // Detached inventories
557 std::map<std::string, Inventory*> m_detached_inventories;
559 // Storage for mesh data for creating multiple instances of the same mesh
560 std::map<std::string, std::string> m_mesh_data;
563 LocalClientState m_state;
565 // Used for saving server map to disk client-side
569 // TODO: Add callback to update this when g_settings changes
570 bool m_cache_smooth_lighting;
573 #endif // !CLIENT_HEADER