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 "network/connection.h"
24 #include "clientenvironment.h"
25 #include "irrlichttypes_extrabloated.h"
26 #include "threading/mutex.h"
31 #include "clientobject.h"
33 #include "inventorymanager.h"
34 #include "localplayer.h"
36 #include "particles.h"
38 #include "tileanimation.h"
42 class IWritableTextureSource;
43 class IWritableShaderSource;
44 class IWritableItemDefManager;
45 class IWritableNodeDefManager;
46 //class IWritableCraftDefManager;
47 class ClientMediaDownloader;
48 struct MapDrawControl;
53 struct MinimapMapblock;
57 struct QueuedMeshUpdate
61 bool ack_block_to_server;
67 enum LocalClientState {
74 A thread-safe queue of mesh update tasks
84 peer_id=0 adds with nobody to send to
86 void addBlock(v3s16 p, MeshMakeData *data,
87 bool ack_block_to_server, bool urgent);
89 // Returned pointer must be deleted
90 // Returns NULL if queue is empty
91 QueuedMeshUpdate * pop();
95 MutexAutoLock lock(m_mutex);
96 return m_queue.size();
100 std::vector<QueuedMeshUpdate*> m_queue;
101 std::set<v3s16> m_urgents;
105 struct MeshUpdateResult
109 bool ack_block_to_server;
112 p(-1338,-1338,-1338),
114 ack_block_to_server(false)
119 class MeshUpdateThread : public UpdateThread
122 MeshUpdateQueue m_queue_in;
125 virtual void doUpdate();
129 MeshUpdateThread() : UpdateThread("Mesh") {}
131 void enqueueUpdate(v3s16 p, MeshMakeData *data,
132 bool ack_block_to_server, bool urgent);
133 MutexedQueue<MeshUpdateResult> m_queue_out;
135 v3s16 m_camera_offset;
142 CE_PLAYER_FORCE_MOVE,
145 CE_SHOW_LOCAL_FORMSPEC,
147 CE_ADD_PARTICLESPAWNER,
148 CE_DELETE_PARTICLESPAWNER,
153 CE_OVERRIDE_DAY_NIGHT_RATIO,
158 ClientEventType type;
170 bool set_camera_point_target;
171 f32 camera_point_target_x;
172 f32 camera_point_target_y;
173 f32 camera_point_target_z;
176 std::string *formspec;
177 std::string *formname;
180 //} textures_updated;
187 bool collisiondetection;
188 bool collision_removal;
190 std::string *texture;
191 struct TileAnimationParams animation;
207 bool collisiondetection;
208 bool collision_removal;
211 std::string *texture;
213 struct TileAnimationParams animation;
215 } add_particlespawner;
218 } delete_particlespawner;
247 video::SColor *bgcolor;
249 std::vector<std::string> *params;
254 } override_day_night_ratio;
269 void add(u16 command)
271 std::map<u16, u16>::iterator n = m_packets.find(command);
272 if(n == m_packets.end())
274 m_packets[command] = 1;
284 for(std::map<u16, u16>::iterator
285 i = m_packets.begin();
286 i != m_packets.end(); ++i)
292 void print(std::ostream &o)
294 for(std::map<u16, u16>::iterator
295 i = m_packets.begin();
296 i != m_packets.end(); ++i)
299 <<" count "<<i->second
306 std::map<u16, u16> m_packets;
309 class ClientScripting;
311 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
315 NOTE: Nothing is thread-safe here.
319 IrrlichtDevice *device,
320 const char *playername,
321 std::string password,
322 MapDrawControl &control,
323 IWritableTextureSource *tsrc,
324 IWritableShaderSource *shsrc,
325 IWritableItemDefManager *itemdef,
326 IWritableNodeDefManager *nodedef,
327 ISoundManager *sound,
328 MtEventManager *event,
337 request all threads managed by client to be stopped
345 The name of the local player should already be set when
346 calling this, as it is sent in the initialization.
348 void connect(Address address,
349 const std::string &address_name,
350 bool is_local_server);
353 Stuff that references the environment is valid only as
354 long as this is not called. (eg. Players)
355 If this throws a PeerNotFoundException, the connection has
358 void step(float dtime);
364 void handleCommand(NetworkPacket* pkt);
366 void handleCommand_Null(NetworkPacket* pkt) {};
367 void handleCommand_Deprecated(NetworkPacket* pkt);
368 void handleCommand_Hello(NetworkPacket* pkt);
369 void handleCommand_AuthAccept(NetworkPacket* pkt);
370 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
371 void handleCommand_DenySudoMode(NetworkPacket* pkt);
372 void handleCommand_InitLegacy(NetworkPacket* pkt);
373 void handleCommand_AccessDenied(NetworkPacket* pkt);
374 void handleCommand_RemoveNode(NetworkPacket* pkt);
375 void handleCommand_AddNode(NetworkPacket* pkt);
376 void handleCommand_BlockData(NetworkPacket* pkt);
377 void handleCommand_Inventory(NetworkPacket* pkt);
378 void handleCommand_TimeOfDay(NetworkPacket* pkt);
379 void handleCommand_ChatMessage(NetworkPacket* pkt);
380 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
381 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
382 void handleCommand_Movement(NetworkPacket* pkt);
383 void handleCommand_HP(NetworkPacket* pkt);
384 void handleCommand_Breath(NetworkPacket* pkt);
385 void handleCommand_MovePlayer(NetworkPacket* pkt);
386 void handleCommand_PlayerItem(NetworkPacket* pkt);
387 void handleCommand_DeathScreen(NetworkPacket* pkt);
388 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
389 void handleCommand_Media(NetworkPacket* pkt);
390 void handleCommand_ToolDef(NetworkPacket* pkt);
391 void handleCommand_NodeDef(NetworkPacket* pkt);
392 void handleCommand_CraftItemDef(NetworkPacket* pkt);
393 void handleCommand_ItemDef(NetworkPacket* pkt);
394 void handleCommand_PlaySound(NetworkPacket* pkt);
395 void handleCommand_StopSound(NetworkPacket* pkt);
396 void handleCommand_Privileges(NetworkPacket* pkt);
397 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
398 void handleCommand_DetachedInventory(NetworkPacket* pkt);
399 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
400 void handleCommand_SpawnParticle(NetworkPacket* pkt);
401 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
402 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
403 void handleCommand_HudAdd(NetworkPacket* pkt);
404 void handleCommand_HudRemove(NetworkPacket* pkt);
405 void handleCommand_HudChange(NetworkPacket* pkt);
406 void handleCommand_HudSetFlags(NetworkPacket* pkt);
407 void handleCommand_HudSetParam(NetworkPacket* pkt);
408 void handleCommand_HudSetSky(NetworkPacket* pkt);
409 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
410 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
411 void handleCommand_EyeOffset(NetworkPacket* pkt);
412 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
414 void ProcessData(NetworkPacket *pkt);
416 void Send(NetworkPacket* pkt);
418 void interact(u8 action, const PointedThing& pointed);
420 void sendNodemetaFields(v3s16 p, const std::string &formname,
421 const StringMap &fields);
422 void sendInventoryFields(const std::string &formname,
423 const StringMap &fields);
424 void sendInventoryAction(InventoryAction *a);
425 void sendChatMessage(const std::wstring &message);
426 void sendChangePassword(const std::string &oldpassword,
427 const std::string &newpassword);
428 void sendDamage(u8 damage);
429 void sendBreath(u16 breath);
433 ClientEnvironment& getEnv() { return m_env; }
434 ITextureSource *tsrc() { return getTextureSource(); }
435 ISoundManager *sound() { return getSoundManager(); }
436 static const std::string &getBuiltinLuaPath();
437 static const std::string &getClientModsLuaPath();
439 virtual const std::vector<ModSpec> &getMods() const;
440 virtual const ModSpec* getModSpec(const std::string &modname) const;
442 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
443 void removeNode(v3s16 p);
444 MapNode getNode(v3s16 p, bool *is_valid_position);
445 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
447 void setPlayerControl(PlayerControl &control);
449 void selectPlayerItem(u16 item);
450 u16 getPlayerItem() const
451 { return m_playeritem; }
453 // Returns true if the inventory of the local player has been
454 // updated from the server. If it is true, it is set to false.
455 bool getLocalInventoryUpdated();
456 // Copies the inventory of the local player to parameter
457 void getLocalInventory(Inventory &dst);
459 /* InventoryManager interface */
460 Inventory* getInventory(const InventoryLocation &loc);
461 void inventoryAction(InventoryAction *a);
463 const std::list<std::string> &getConnectedPlayerNames()
465 return m_env.getPlayerNames();
468 float getAnimationTime();
471 void setCrack(int level, v3s16 pos);
475 bool checkPrivilege(const std::string &priv) const
476 { return (m_privileges.count(priv) != 0); }
478 bool getChatMessage(std::wstring &message);
479 void typeChatMessage(const std::wstring& message);
481 u64 getMapSeed(){ return m_map_seed; }
483 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
484 // Including blocks at appropriate edges
485 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
486 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
488 void updateCameraOffset(v3s16 camera_offset)
489 { m_mesh_update_thread.m_camera_offset = camera_offset; }
491 // Get event from queue. CE_NONE is returned if queue is empty.
492 ClientEvent getClientEvent();
494 bool accessDenied() const { return m_access_denied; }
496 bool reconnectRequested() const { return m_access_denied_reconnect; }
498 void setFatalError(const std::string &reason)
500 m_access_denied = true;
501 m_access_denied_reason = reason;
504 // Renaming accessDeniedReason to better name could be good as it's used to
505 // disconnect client when CSM failed.
506 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
508 bool itemdefReceived()
509 { return m_itemdef_received; }
510 bool nodedefReceived()
511 { return m_nodedef_received; }
513 { return m_media_downloader == NULL; }
516 { return m_proto_ver; }
518 bool connectedToServer()
519 { return m_con.Connected(); }
521 float mediaReceiveProgress();
523 void afterContentReceived(IrrlichtDevice *device);
526 float getCurRate(void);
527 float getAvgRate(void);
532 void setCamera(Camera* camera)
533 { m_camera = camera; }
538 bool isMinimapDisabledByServer()
539 { return m_minimap_disabled_by_server; }
541 // IGameDef interface
542 virtual IItemDefManager* getItemDefManager();
543 virtual INodeDefManager* getNodeDefManager();
544 virtual ICraftDefManager* getCraftDefManager();
545 ITextureSource* getTextureSource();
546 virtual IShaderSource* getShaderSource();
547 IShaderSource *shsrc() { return getShaderSource(); }
548 scene::ISceneManager* getSceneManager();
549 virtual u16 allocateUnknownNodeId(const std::string &name);
550 virtual ISoundManager* getSoundManager();
551 virtual MtEventManager* getEventManager();
552 virtual ParticleManager* getParticleManager();
553 bool checkLocalPrivilege(const std::string &priv)
554 { return checkPrivilege(priv); }
555 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
557 virtual std::string getModStoragePath() const;
558 virtual bool registerModStorage(ModMetadata *meta);
559 virtual void unregisterModStorage(const std::string &name);
561 // The following set of functions is used by ClientMediaDownloader
562 // Insert a media file appropriately into the appropriate manager
563 bool loadMedia(const std::string &data, const std::string &filename);
564 // Send a request for conventional media transfer
565 void request_media(const std::vector<std::string> &file_requests);
566 // Send a notification that no conventional media transfer is needed
567 void received_media();
569 LocalClientState getState() { return m_state; }
571 void makeScreenshot(IrrlichtDevice *device);
573 inline void pushToChatQueue(const std::wstring &input)
575 m_chat_queue.push(input);
578 ClientScripting *getScript() { return m_script; }
579 const bool moddingEnabled() const { return m_modding_enabled; }
581 inline void pushToEventQueue(const ClientEvent &event)
583 m_client_event_queue.push(event);
588 // Virtual methods from con::PeerHandler
589 void peerAdded(con::Peer *peer);
590 void deletingPeer(con::Peer *peer, bool timeout);
592 void initLocalMapSaving(const Address &address,
593 const std::string &hostname,
594 bool is_local_server);
599 void sendPlayerPos();
600 // Send the item number 'item' as player item to the server
601 void sendPlayerItem(u16 item);
603 void deleteAuthData();
604 // helper method shared with clientpackethandler
605 static AuthMechanism choseAuthMech(const u32 mechs);
607 void sendLegacyInit(const char* playerName, const char* playerPassword);
608 void sendInit(const std::string &playerName);
609 void startAuth(AuthMechanism chosen_auth_mechanism);
610 void sendDeletedBlocks(std::vector<v3s16> &blocks);
611 void sendGotBlocks(v3s16 block);
612 void sendRemovedSounds(std::vector<s32> &soundList);
615 inline std::string getPlayerName()
616 { return m_env.getLocalPlayer()->getName(); }
618 float m_packetcounter_timer;
619 float m_connection_reinit_timer;
620 float m_avg_rtt_timer;
621 float m_playerpos_send_timer;
622 float m_ignore_damage_timer; // Used after server moves player
623 IntervalLimiter m_map_timer_and_unload_interval;
625 IWritableTextureSource *m_tsrc;
626 IWritableShaderSource *m_shsrc;
627 IWritableItemDefManager *m_itemdef;
628 IWritableNodeDefManager *m_nodedef;
629 ISoundManager *m_sound;
630 MtEventManager *m_event;
633 MeshUpdateThread m_mesh_update_thread;
634 ClientEnvironment m_env;
635 ParticleManager m_particle_manager;
636 con::Connection m_con;
637 IrrlichtDevice *m_device;
640 bool m_minimap_disabled_by_server;
641 // Server serialization version
644 // Used version of the protocol with server
645 // Values smaller than 25 only mean they are smaller than 25,
646 // and aren't accurate. We simply just don't know, because
647 // the server didn't send the version back then.
648 // If 0, server init hasn't been received yet.
652 bool m_inventory_updated;
653 Inventory *m_inventory_from_server;
654 float m_inventory_from_server_age;
655 PacketCounter m_packetcounter;
656 // Block mesh animation parameters
657 float m_animation_time;
660 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
662 //u32 m_daynight_ratio;
663 std::queue<std::wstring> m_chat_queue;
665 // The authentication methods we can use to enter sudo mode (=change password)
666 u32 m_sudo_auth_methods;
668 // The seed returned by the server in TOCLIENT_INIT is stored here
672 std::string m_playername;
673 std::string m_password;
674 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
675 std::string m_new_password;
676 // Usable by auth mechanisms.
677 AuthMechanism m_chosen_auth_mech;
681 bool m_access_denied;
682 bool m_access_denied_reconnect;
683 std::string m_access_denied_reason;
684 std::queue<ClientEvent> m_client_event_queue;
685 bool m_itemdef_received;
686 bool m_nodedef_received;
687 ClientMediaDownloader *m_media_downloader;
689 // time_of_day speed approximation for old protocol
690 bool m_time_of_day_set;
691 float m_last_time_of_day_f;
692 float m_time_of_day_update_timer;
694 // An interval for generally sending object positions and stuff
695 float m_recommended_send_interval;
698 float m_removed_sounds_check_timer;
699 // Mapping from server sound ids to our sound ids
700 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
701 // And the other way!
702 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
703 // And relations to objects
704 UNORDERED_MAP<int, u16> m_sounds_to_objects;
707 UNORDERED_SET<std::string> m_privileges;
709 // Detached inventories
711 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
713 // Storage for mesh data for creating multiple instances of the same mesh
714 StringMap m_mesh_data;
717 LocalClientState m_state;
719 // Used for saving server map to disk client-side
721 IntervalLimiter m_localdb_save_interval;
722 u16 m_cache_save_interval;
724 // TODO: Add callback to update these when g_settings changes
725 bool m_cache_smooth_lighting;
726 bool m_cache_enable_shaders;
727 bool m_cache_use_tangent_vertices;
729 ClientScripting *m_script;
730 bool m_modding_enabled;
731 UNORDERED_MAP<std::string, ModMetadata *> m_mod_storages;
732 float m_mod_storage_save_timer;
734 DISABLE_CLASS_COPY(Client);
737 #endif // !CLIENT_HEADER