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"
30 #include <unordered_set>
31 #include "clientobject.h"
33 #include "inventorymanager.h"
34 #include "localplayer.h"
36 #include "particles.h"
38 #include "tileanimation.h"
39 #include "mesh_generator_thread.h"
42 #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
47 class IWritableTextureSource;
48 class IWritableShaderSource;
49 class IWritableItemDefManager;
50 class IWritableNodeDefManager;
51 //class IWritableCraftDefManager;
52 class ClientMediaDownloader;
53 struct MapDrawControl;
58 struct MinimapMapblock;
62 enum LocalClientState {
75 CE_SHOW_LOCAL_FORMSPEC,
77 CE_ADD_PARTICLESPAWNER,
78 CE_DELETE_PARTICLESPAWNER,
83 CE_OVERRIDE_DAY_NIGHT_RATIO,
101 bool set_camera_point_target;
102 f32 camera_point_target_x;
103 f32 camera_point_target_y;
104 f32 camera_point_target_z;
107 std::string *formspec;
108 std::string *formname;
111 //} textures_updated;
118 bool collisiondetection;
119 bool collision_removal;
121 std::string *texture;
122 struct TileAnimationParams animation;
138 bool collisiondetection;
139 bool collision_removal;
142 std::string *texture;
144 struct TileAnimationParams animation;
146 } add_particlespawner;
149 } delete_particlespawner;
178 video::SColor *bgcolor;
180 std::vector<std::string> *params;
186 } override_day_night_ratio;
206 PacketCounter() = default;
208 void add(u16 command)
210 std::map<u16, u16>::iterator n = m_packets.find(command);
211 if(n == m_packets.end())
213 m_packets[command] = 1;
223 for (auto &m_packet : m_packets) {
228 void print(std::ostream &o)
230 for (const auto &m_packet : m_packets) {
231 o << "cmd "<< m_packet.first <<" count "<< m_packet.second << std::endl;
237 std::map<u16, u16> m_packets;
240 class ClientScripting;
243 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
247 NOTE: Nothing is thread-safe here.
251 const char *playername,
252 const std::string &password,
253 const std::string &address_name,
254 MapDrawControl &control,
255 IWritableTextureSource *tsrc,
256 IWritableShaderSource *shsrc,
257 IWritableItemDefManager *itemdef,
258 IWritableNodeDefManager *nodedef,
259 ISoundManager *sound,
260 MtEventManager *event,
262 GameUIFlags *game_ui_flags
266 DISABLE_CLASS_COPY(Client);
268 // Load local mods into memory
270 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
271 std::string mod_subpath);
272 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
274 scanModSubfolder(mod_name, mod_path, "");
281 request all threads managed by client to be stopped
289 The name of the local player should already be set when
290 calling this, as it is sent in the initialization.
292 void connect(Address address, bool is_local_server);
295 Stuff that references the environment is valid only as
296 long as this is not called. (eg. Players)
297 If this throws a PeerNotFoundException, the connection has
300 void step(float dtime);
306 void handleCommand(NetworkPacket* pkt);
308 void handleCommand_Null(NetworkPacket* pkt) {};
309 void handleCommand_Deprecated(NetworkPacket* pkt);
310 void handleCommand_Hello(NetworkPacket* pkt);
311 void handleCommand_AuthAccept(NetworkPacket* pkt);
312 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
313 void handleCommand_DenySudoMode(NetworkPacket* pkt);
314 void handleCommand_InitLegacy(NetworkPacket* pkt);
315 void handleCommand_AccessDenied(NetworkPacket* pkt);
316 void handleCommand_RemoveNode(NetworkPacket* pkt);
317 void handleCommand_AddNode(NetworkPacket* pkt);
318 void handleCommand_BlockData(NetworkPacket* pkt);
319 void handleCommand_Inventory(NetworkPacket* pkt);
320 void handleCommand_TimeOfDay(NetworkPacket* pkt);
321 void handleCommand_ChatMessageOld(NetworkPacket *pkt);
322 void handleCommand_ChatMessage(NetworkPacket *pkt);
323 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
324 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
325 void handleCommand_Movement(NetworkPacket* pkt);
326 void handleCommand_HP(NetworkPacket* pkt);
327 void handleCommand_Breath(NetworkPacket* pkt);
328 void handleCommand_MovePlayer(NetworkPacket* pkt);
329 void handleCommand_DeathScreen(NetworkPacket* pkt);
330 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
331 void handleCommand_Media(NetworkPacket* pkt);
332 void handleCommand_NodeDef(NetworkPacket* pkt);
333 void handleCommand_ItemDef(NetworkPacket* pkt);
334 void handleCommand_PlaySound(NetworkPacket* pkt);
335 void handleCommand_StopSound(NetworkPacket* pkt);
336 void handleCommand_FadeSound(NetworkPacket *pkt);
337 void handleCommand_Privileges(NetworkPacket* pkt);
338 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
339 void handleCommand_DetachedInventory(NetworkPacket* pkt);
340 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
341 void handleCommand_SpawnParticle(NetworkPacket* pkt);
342 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
343 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
344 void handleCommand_HudAdd(NetworkPacket* pkt);
345 void handleCommand_HudRemove(NetworkPacket* pkt);
346 void handleCommand_HudChange(NetworkPacket* pkt);
347 void handleCommand_HudSetFlags(NetworkPacket* pkt);
348 void handleCommand_HudSetParam(NetworkPacket* pkt);
349 void handleCommand_HudSetSky(NetworkPacket* pkt);
350 void handleCommand_CloudParams(NetworkPacket* pkt);
351 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
352 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
353 void handleCommand_EyeOffset(NetworkPacket* pkt);
354 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
355 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
356 void handleCommand_CSMFlavourLimits(NetworkPacket *pkt);
358 void ProcessData(NetworkPacket *pkt);
360 void Send(NetworkPacket* pkt);
362 void interact(u8 action, const PointedThing& pointed);
364 void sendNodemetaFields(v3s16 p, const std::string &formname,
365 const StringMap &fields);
366 void sendInventoryFields(const std::string &formname,
367 const StringMap &fields);
368 void sendInventoryAction(InventoryAction *a);
369 void sendChatMessage(const std::wstring &message);
370 void clearOutChatQueue();
371 void sendChangePassword(const std::string &oldpassword,
372 const std::string &newpassword);
373 void sendDamage(u8 damage);
374 void sendBreath(u16 breath);
378 ClientEnvironment& getEnv() { return m_env; }
379 ITextureSource *tsrc() { return getTextureSource(); }
380 ISoundManager *sound() { return getSoundManager(); }
381 static const std::string &getBuiltinLuaPath();
382 static const std::string &getClientModsLuaPath();
384 virtual const std::vector<ModSpec> &getMods() const;
385 virtual const ModSpec* getModSpec(const std::string &modname) const;
387 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
388 void removeNode(v3s16 p);
391 * Helper function for Client Side Modding
392 * Flavour is applied there, this should not be used for core engine
394 * @param is_valid_position
397 MapNode getNode(v3s16 p, bool *is_valid_position);
398 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
400 void setPlayerControl(PlayerControl &control);
402 void selectPlayerItem(u16 item);
403 u16 getPlayerItem() const
404 { return m_playeritem; }
406 // Returns true if the inventory of the local player has been
407 // updated from the server. If it is true, it is set to false.
408 bool getLocalInventoryUpdated();
409 // Copies the inventory of the local player to parameter
410 void getLocalInventory(Inventory &dst);
412 /* InventoryManager interface */
413 Inventory* getInventory(const InventoryLocation &loc);
414 void inventoryAction(InventoryAction *a);
416 const std::list<std::string> &getConnectedPlayerNames()
418 return m_env.getPlayerNames();
421 float getAnimationTime();
425 void setCrack(int level, v3s16 pos);
429 bool checkPrivilege(const std::string &priv) const
430 { return (m_privileges.count(priv) != 0); }
432 const std::unordered_set<std::string> &getPrivilegeList() const
433 { return m_privileges; }
435 bool getChatMessage(std::wstring &message);
436 void typeChatMessage(const std::wstring& message);
438 u64 getMapSeed(){ return m_map_seed; }
440 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
441 // Including blocks at appropriate edges
442 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
443 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
445 void updateCameraOffset(v3s16 camera_offset)
446 { m_mesh_update_thread.m_camera_offset = camera_offset; }
448 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
449 // Get event from queue. If queue is empty, it triggers an assertion failure.
450 ClientEvent getClientEvent();
452 bool accessDenied() const { return m_access_denied; }
454 bool reconnectRequested() const { return m_access_denied_reconnect; }
456 void setFatalError(const std::string &reason)
458 m_access_denied = true;
459 m_access_denied_reason = reason;
462 // Renaming accessDeniedReason to better name could be good as it's used to
463 // disconnect client when CSM failed.
464 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
466 bool itemdefReceived()
467 { return m_itemdef_received; }
468 bool nodedefReceived()
469 { return m_nodedef_received; }
471 { return !m_media_downloader; }
474 { return m_proto_ver; }
476 bool connectedToServer()
477 { return m_con.Connected(); }
479 float mediaReceiveProgress();
481 void afterContentReceived();
486 Minimap* getMinimap() { return m_minimap; }
487 void setCamera(Camera* camera) { m_camera = camera; }
489 Camera* getCamera () { return m_camera; }
491 bool shouldShowMinimap() const;
493 // IGameDef interface
494 virtual IItemDefManager* getItemDefManager();
495 virtual INodeDefManager* getNodeDefManager();
496 virtual ICraftDefManager* getCraftDefManager();
497 ITextureSource* getTextureSource();
498 virtual IShaderSource* getShaderSource();
499 IShaderSource *shsrc() { return getShaderSource(); }
500 virtual u16 allocateUnknownNodeId(const std::string &name);
501 virtual ISoundManager* getSoundManager();
502 virtual MtEventManager* getEventManager();
503 virtual ParticleManager* getParticleManager();
504 bool checkLocalPrivilege(const std::string &priv)
505 { return checkPrivilege(priv); }
506 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
507 const std::string* getModFile(const std::string &filename);
509 virtual std::string getModStoragePath() const;
510 virtual bool registerModStorage(ModMetadata *meta);
511 virtual void unregisterModStorage(const std::string &name);
513 // The following set of functions is used by ClientMediaDownloader
514 // Insert a media file appropriately into the appropriate manager
515 bool loadMedia(const std::string &data, const std::string &filename);
516 // Send a request for conventional media transfer
517 void request_media(const std::vector<std::string> &file_requests);
519 LocalClientState getState() { return m_state; }
521 void makeScreenshot();
523 inline void pushToChatQueue(ChatMessage *cec)
525 m_chat_queue.push(cec);
528 ClientScripting *getScript() { return m_script; }
529 const bool moddingEnabled() const { return m_modding_enabled; }
531 inline void pushToEventQueue(const ClientEvent &event)
533 m_client_event_queue.push(event);
536 void showGameChat(bool show = true);
537 void showGameHud(bool show = true);
538 void showMinimap(bool show = true);
539 void showProfiler(bool show = true);
540 void showGameFog(bool show = true);
541 void showGameDebug(bool show = true);
543 const Address getServerAddress()
545 return m_con.GetPeerAddress(PEER_ID_SERVER);
548 const std::string &getAddressName() const
550 return m_address_name;
553 inline bool checkCSMFlavourLimit(CSMFlavourLimit flag) const
555 return m_csm_flavour_limits & flag;
558 u32 getCSMNodeRangeLimit() const
560 return m_csm_noderange_limit;
565 // Virtual methods from con::PeerHandler
566 void peerAdded(con::Peer *peer);
567 void deletingPeer(con::Peer *peer, bool timeout);
569 void initLocalMapSaving(const Address &address,
570 const std::string &hostname,
571 bool is_local_server);
576 void sendPlayerPos();
577 // Send the item number 'item' as player item to the server
578 void sendPlayerItem(u16 item);
580 void deleteAuthData();
581 // helper method shared with clientpackethandler
582 static AuthMechanism choseAuthMech(const u32 mechs);
584 void sendLegacyInit(const char* playerName, const char* playerPassword);
585 void sendInit(const std::string &playerName);
586 void startAuth(AuthMechanism chosen_auth_mechanism);
587 void sendDeletedBlocks(std::vector<v3s16> &blocks);
588 void sendGotBlocks(v3s16 block);
589 void sendRemovedSounds(std::vector<s32> &soundList);
592 inline std::string getPlayerName()
593 { return m_env.getLocalPlayer()->getName(); }
595 bool canSendChatMessage() const;
597 float m_packetcounter_timer = 0.0f;
598 float m_connection_reinit_timer = 0.1f;
599 float m_avg_rtt_timer = 0.0f;
600 float m_playerpos_send_timer = 0.0f;
601 float m_ignore_damage_timer = 0.0f; // Used after server moves player
602 IntervalLimiter m_map_timer_and_unload_interval;
604 IWritableTextureSource *m_tsrc;
605 IWritableShaderSource *m_shsrc;
606 IWritableItemDefManager *m_itemdef;
607 IWritableNodeDefManager *m_nodedef;
608 ISoundManager *m_sound;
609 MtEventManager *m_event;
612 MeshUpdateThread m_mesh_update_thread;
613 ClientEnvironment m_env;
614 ParticleManager m_particle_manager;
615 con::Connection m_con;
616 std::string m_address_name;
617 Camera *m_camera = nullptr;
618 Minimap *m_minimap = nullptr;
619 bool m_minimap_disabled_by_server = false;
620 // Server serialization version
623 // Used version of the protocol with server
624 // Values smaller than 25 only mean they are smaller than 25,
625 // and aren't accurate. We simply just don't know, because
626 // the server didn't send the version back then.
627 // If 0, server init hasn't been received yet.
630 u16 m_playeritem = 0;
631 bool m_inventory_updated = false;
632 Inventory *m_inventory_from_server = nullptr;
633 float m_inventory_from_server_age = 0.0f;
634 PacketCounter m_packetcounter;
635 // Block mesh animation parameters
636 float m_animation_time = 0.0f;
637 int m_crack_level = -1;
639 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
641 //u32 m_daynight_ratio;
642 std::queue<std::wstring> m_out_chat_queue;
643 u32 m_last_chat_message_sent;
644 float m_chat_message_allowance = 5.0f;
645 std::queue<ChatMessage *> m_chat_queue;
647 // The authentication methods we can use to enter sudo mode (=change password)
648 u32 m_sudo_auth_methods;
650 // The seed returned by the server in TOCLIENT_INIT is stored here
654 std::string m_playername;
655 std::string m_password;
656 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
657 std::string m_new_password;
658 // Usable by auth mechanisms.
659 AuthMechanism m_chosen_auth_mech;
660 void *m_auth_data = nullptr;
663 bool m_access_denied = false;
664 bool m_access_denied_reconnect = false;
665 std::string m_access_denied_reason = "";
666 std::queue<ClientEvent> m_client_event_queue;
667 bool m_itemdef_received = false;
668 bool m_nodedef_received = false;
669 ClientMediaDownloader *m_media_downloader;
671 // time_of_day speed approximation for old protocol
672 bool m_time_of_day_set = false;
673 float m_last_time_of_day_f = -1.0f;
674 float m_time_of_day_update_timer = 0.0f;
676 // An interval for generally sending object positions and stuff
677 float m_recommended_send_interval = 0.1f;
680 float m_removed_sounds_check_timer = 0.0f;
681 // Mapping from server sound ids to our sound ids
682 std::unordered_map<s32, int> m_sounds_server_to_client;
683 // And the other way!
684 std::unordered_map<int, s32> m_sounds_client_to_server;
685 // And relations to objects
686 std::unordered_map<int, u16> m_sounds_to_objects;
689 std::unordered_set<std::string> m_privileges;
691 // Detached inventories
693 std::unordered_map<std::string, Inventory*> m_detached_inventories;
695 // Storage for mesh data for creating multiple instances of the same mesh
696 StringMap m_mesh_data;
698 StringMap m_mod_files;
701 LocalClientState m_state;
703 // Used for saving server map to disk client-side
704 MapDatabase *m_localdb = nullptr;
705 IntervalLimiter m_localdb_save_interval;
706 u16 m_cache_save_interval;
708 ClientScripting *m_script = nullptr;
709 bool m_modding_enabled;
710 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
711 float m_mod_storage_save_timer = 10.0f;
712 std::vector<ModSpec> m_mods;
713 GameUIFlags *m_game_ui_flags;
715 bool m_shutdown = false;
717 // CSM flavour limits byteflag
718 u64 m_csm_flavour_limits = CSMFlavourLimit::CSM_FL_NONE;
719 u32 m_csm_noderange_limit = 8;
722 #endif // !CLIENT_HEADER