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"
43 #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
48 class IWritableTextureSource;
49 class IWritableShaderSource;
50 class IWritableItemDefManager;
51 class IWritableNodeDefManager;
52 //class IWritableCraftDefManager;
53 class ClientMediaDownloader;
54 struct MapDrawControl;
59 struct MinimapMapblock;
63 enum LocalClientState {
76 CE_SHOW_LOCAL_FORMSPEC,
78 CE_ADD_PARTICLESPAWNER,
79 CE_DELETE_PARTICLESPAWNER,
84 CE_OVERRIDE_DAY_NIGHT_RATIO,
102 bool set_camera_point_target;
103 f32 camera_point_target_x;
104 f32 camera_point_target_y;
105 f32 camera_point_target_z;
108 std::string *formspec;
109 std::string *formname;
112 //} textures_updated;
119 bool collisiondetection;
120 bool collision_removal;
122 std::string *texture;
123 struct TileAnimationParams animation;
139 bool collisiondetection;
140 bool collision_removal;
143 std::string *texture;
145 struct TileAnimationParams animation;
147 } add_particlespawner;
150 } delete_particlespawner;
179 video::SColor *bgcolor;
181 std::vector<std::string> *params;
187 } override_day_night_ratio;
211 void add(u16 command)
213 std::map<u16, u16>::iterator n = m_packets.find(command);
214 if(n == m_packets.end())
216 m_packets[command] = 1;
226 for(std::map<u16, u16>::iterator
227 i = m_packets.begin();
228 i != m_packets.end(); ++i)
234 void print(std::ostream &o)
236 for(std::map<u16, u16>::iterator
237 i = m_packets.begin();
238 i != m_packets.end(); ++i)
241 <<" count "<<i->second
248 std::map<u16, u16> m_packets;
251 class ClientScripting;
254 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
258 NOTE: Nothing is thread-safe here.
262 const char *playername,
263 const std::string &password,
264 const std::string &address_name,
265 MapDrawControl &control,
266 IWritableTextureSource *tsrc,
267 IWritableShaderSource *shsrc,
268 IWritableItemDefManager *itemdef,
269 IWritableNodeDefManager *nodedef,
270 ISoundManager *sound,
271 MtEventManager *event,
273 GameUIFlags *game_ui_flags
277 DISABLE_CLASS_COPY(Client);
279 // Load local mods into memory
281 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
282 std::string mod_subpath);
283 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
285 scanModSubfolder(mod_name, mod_path, "");
292 request all threads managed by client to be stopped
300 The name of the local player should already be set when
301 calling this, as it is sent in the initialization.
303 void connect(Address address, bool is_local_server);
306 Stuff that references the environment is valid only as
307 long as this is not called. (eg. Players)
308 If this throws a PeerNotFoundException, the connection has
311 void step(float dtime);
317 void handleCommand(NetworkPacket* pkt);
319 void handleCommand_Null(NetworkPacket* pkt) {};
320 void handleCommand_Deprecated(NetworkPacket* pkt);
321 void handleCommand_Hello(NetworkPacket* pkt);
322 void handleCommand_AuthAccept(NetworkPacket* pkt);
323 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
324 void handleCommand_DenySudoMode(NetworkPacket* pkt);
325 void handleCommand_InitLegacy(NetworkPacket* pkt);
326 void handleCommand_AccessDenied(NetworkPacket* pkt);
327 void handleCommand_RemoveNode(NetworkPacket* pkt);
328 void handleCommand_AddNode(NetworkPacket* pkt);
329 void handleCommand_BlockData(NetworkPacket* pkt);
330 void handleCommand_Inventory(NetworkPacket* pkt);
331 void handleCommand_TimeOfDay(NetworkPacket* pkt);
332 void handleCommand_ChatMessageOld(NetworkPacket *pkt);
333 void handleCommand_ChatMessage(NetworkPacket *pkt);
334 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
335 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
336 void handleCommand_Movement(NetworkPacket* pkt);
337 void handleCommand_HP(NetworkPacket* pkt);
338 void handleCommand_Breath(NetworkPacket* pkt);
339 void handleCommand_MovePlayer(NetworkPacket* pkt);
340 void handleCommand_DeathScreen(NetworkPacket* pkt);
341 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
342 void handleCommand_Media(NetworkPacket* pkt);
343 void handleCommand_NodeDef(NetworkPacket* pkt);
344 void handleCommand_ItemDef(NetworkPacket* pkt);
345 void handleCommand_PlaySound(NetworkPacket* pkt);
346 void handleCommand_StopSound(NetworkPacket* pkt);
347 void handleCommand_FadeSound(NetworkPacket *pkt);
348 void handleCommand_Privileges(NetworkPacket* pkt);
349 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
350 void handleCommand_DetachedInventory(NetworkPacket* pkt);
351 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
352 void handleCommand_SpawnParticle(NetworkPacket* pkt);
353 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
354 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
355 void handleCommand_HudAdd(NetworkPacket* pkt);
356 void handleCommand_HudRemove(NetworkPacket* pkt);
357 void handleCommand_HudChange(NetworkPacket* pkt);
358 void handleCommand_HudSetFlags(NetworkPacket* pkt);
359 void handleCommand_HudSetParam(NetworkPacket* pkt);
360 void handleCommand_HudSetSky(NetworkPacket* pkt);
361 void handleCommand_CloudParams(NetworkPacket* pkt);
362 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
363 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
364 void handleCommand_EyeOffset(NetworkPacket* pkt);
365 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
366 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
367 void handleCommand_CSMFlavourLimits(NetworkPacket *pkt);
369 void ProcessData(NetworkPacket *pkt);
371 void Send(NetworkPacket* pkt);
373 void interact(u8 action, const PointedThing& pointed);
375 void sendNodemetaFields(v3s16 p, const std::string &formname,
376 const StringMap &fields);
377 void sendInventoryFields(const std::string &formname,
378 const StringMap &fields);
379 void sendInventoryAction(InventoryAction *a);
380 void sendChatMessage(const std::wstring &message);
381 void clearOutChatQueue();
382 void sendChangePassword(const std::string &oldpassword,
383 const std::string &newpassword);
384 void sendDamage(u8 damage);
385 void sendBreath(u16 breath);
389 ClientEnvironment& getEnv() { return m_env; }
390 ITextureSource *tsrc() { return getTextureSource(); }
391 ISoundManager *sound() { return getSoundManager(); }
392 static const std::string &getBuiltinLuaPath();
393 static const std::string &getClientModsLuaPath();
395 virtual const std::vector<ModSpec> &getMods() const;
396 virtual const ModSpec* getModSpec(const std::string &modname) const;
398 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
399 void removeNode(v3s16 p);
402 * Helper function for Client Side Modding
403 * Flavour is applied there, this should not be used for core engine
405 * @param is_valid_position
408 MapNode getNode(v3s16 p, bool *is_valid_position);
409 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
411 void setPlayerControl(PlayerControl &control);
413 void selectPlayerItem(u16 item);
414 u16 getPlayerItem() const
415 { return m_playeritem; }
417 // Returns true if the inventory of the local player has been
418 // updated from the server. If it is true, it is set to false.
419 bool getLocalInventoryUpdated();
420 // Copies the inventory of the local player to parameter
421 void getLocalInventory(Inventory &dst);
423 /* InventoryManager interface */
424 Inventory* getInventory(const InventoryLocation &loc);
425 void inventoryAction(InventoryAction *a);
427 const std::list<std::string> &getConnectedPlayerNames()
429 return m_env.getPlayerNames();
432 float getAnimationTime();
436 void setCrack(int level, v3s16 pos);
440 bool checkPrivilege(const std::string &priv) const
441 { return (m_privileges.count(priv) != 0); }
443 const std::unordered_set<std::string> &getPrivilegeList() const
444 { return m_privileges; }
446 bool getChatMessage(std::wstring &message);
447 void typeChatMessage(const std::wstring& message);
449 u64 getMapSeed(){ return m_map_seed; }
451 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
452 // Including blocks at appropriate edges
453 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
454 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
456 void updateCameraOffset(v3s16 camera_offset)
457 { m_mesh_update_thread.m_camera_offset = camera_offset; }
459 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
460 // Get event from queue. If queue is empty, it triggers an assertion failure.
461 ClientEvent getClientEvent();
463 bool accessDenied() const { return m_access_denied; }
465 bool reconnectRequested() const { return m_access_denied_reconnect; }
467 void setFatalError(const std::string &reason)
469 m_access_denied = true;
470 m_access_denied_reason = reason;
473 // Renaming accessDeniedReason to better name could be good as it's used to
474 // disconnect client when CSM failed.
475 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
477 bool itemdefReceived()
478 { return m_itemdef_received; }
479 bool nodedefReceived()
480 { return m_nodedef_received; }
482 { return !m_media_downloader; }
485 { return m_proto_ver; }
487 bool connectedToServer()
488 { return m_con.Connected(); }
490 float mediaReceiveProgress();
492 void afterContentReceived();
497 Minimap* getMinimap() { return m_minimap; }
498 void setCamera(Camera* camera) { m_camera = camera; }
500 Camera* getCamera () { return m_camera; }
502 bool shouldShowMinimap() const;
504 // IGameDef interface
505 virtual IItemDefManager* getItemDefManager();
506 virtual INodeDefManager* getNodeDefManager();
507 virtual ICraftDefManager* getCraftDefManager();
508 ITextureSource* getTextureSource();
509 virtual IShaderSource* getShaderSource();
510 IShaderSource *shsrc() { return getShaderSource(); }
511 virtual u16 allocateUnknownNodeId(const std::string &name);
512 virtual ISoundManager* getSoundManager();
513 virtual MtEventManager* getEventManager();
514 virtual ParticleManager* getParticleManager();
515 bool checkLocalPrivilege(const std::string &priv)
516 { return checkPrivilege(priv); }
517 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
518 const std::string* getModFile(const std::string &filename);
520 virtual std::string getModStoragePath() const;
521 virtual bool registerModStorage(ModMetadata *meta);
522 virtual void unregisterModStorage(const std::string &name);
524 // The following set of functions is used by ClientMediaDownloader
525 // Insert a media file appropriately into the appropriate manager
526 bool loadMedia(const std::string &data, const std::string &filename);
527 // Send a request for conventional media transfer
528 void request_media(const std::vector<std::string> &file_requests);
530 LocalClientState getState() { return m_state; }
532 void makeScreenshot();
534 inline void pushToChatQueue(ChatMessage *cec)
536 m_chat_queue.push(cec);
539 ClientScripting *getScript() { return m_script; }
540 const bool moddingEnabled() const { return m_modding_enabled; }
542 inline void pushToEventQueue(const ClientEvent &event)
544 m_client_event_queue.push(event);
547 void showGameChat(const bool show = true);
548 void showGameHud(const bool show = true);
549 void showMinimap(const bool show = true);
550 void showProfiler(const bool show = true);
551 void showGameFog(const bool show = true);
552 void showGameDebug(const bool show = true);
554 const Address getServerAddress()
556 return m_con.GetPeerAddress(PEER_ID_SERVER);
559 const std::string &getAddressName() const
561 return m_address_name;
564 inline bool checkCSMFlavourLimit(CSMFlavourLimit flag) const
566 return m_csm_flavour_limits & flag;
569 u32 getCSMNodeRangeLimit() const
571 return m_csm_noderange_limit;
576 // Virtual methods from con::PeerHandler
577 void peerAdded(con::Peer *peer);
578 void deletingPeer(con::Peer *peer, bool timeout);
580 void initLocalMapSaving(const Address &address,
581 const std::string &hostname,
582 bool is_local_server);
587 void sendPlayerPos();
588 // Send the item number 'item' as player item to the server
589 void sendPlayerItem(u16 item);
591 void deleteAuthData();
592 // helper method shared with clientpackethandler
593 static AuthMechanism choseAuthMech(const u32 mechs);
595 void sendLegacyInit(const char* playerName, const char* playerPassword);
596 void sendInit(const std::string &playerName);
597 void startAuth(AuthMechanism chosen_auth_mechanism);
598 void sendDeletedBlocks(std::vector<v3s16> &blocks);
599 void sendGotBlocks(v3s16 block);
600 void sendRemovedSounds(std::vector<s32> &soundList);
603 inline std::string getPlayerName()
604 { return m_env.getLocalPlayer()->getName(); }
606 bool canSendChatMessage() const;
608 float m_packetcounter_timer = 0.0f;
609 float m_connection_reinit_timer = 0.1f;
610 float m_avg_rtt_timer = 0.0f;
611 float m_playerpos_send_timer = 0.0f;
612 float m_ignore_damage_timer = 0.0f; // Used after server moves player
613 IntervalLimiter m_map_timer_and_unload_interval;
615 IWritableTextureSource *m_tsrc;
616 IWritableShaderSource *m_shsrc;
617 IWritableItemDefManager *m_itemdef;
618 IWritableNodeDefManager *m_nodedef;
619 ISoundManager *m_sound;
620 MtEventManager *m_event;
623 MeshUpdateThread m_mesh_update_thread;
624 ClientEnvironment m_env;
625 ParticleManager m_particle_manager;
626 con::Connection m_con;
627 std::string m_address_name;
628 Camera *m_camera = nullptr;
629 Minimap *m_minimap = nullptr;
630 bool m_minimap_disabled_by_server = false;
631 // Server serialization version
634 // Used version of the protocol with server
635 // Values smaller than 25 only mean they are smaller than 25,
636 // and aren't accurate. We simply just don't know, because
637 // the server didn't send the version back then.
638 // If 0, server init hasn't been received yet.
641 u16 m_playeritem = 0;
642 bool m_inventory_updated = false;
643 Inventory *m_inventory_from_server = nullptr;
644 float m_inventory_from_server_age = 0.0f;
645 PacketCounter m_packetcounter;
646 // Block mesh animation parameters
647 float m_animation_time = 0.0f;
648 int m_crack_level = -1;
650 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
652 //u32 m_daynight_ratio;
653 std::queue<std::wstring> m_out_chat_queue;
654 u32 m_last_chat_message_sent;
655 float m_chat_message_allowance = 5.0f;
656 std::queue<ChatMessage *> m_chat_queue;
658 // The authentication methods we can use to enter sudo mode (=change password)
659 u32 m_sudo_auth_methods;
661 // The seed returned by the server in TOCLIENT_INIT is stored here
665 std::string m_playername;
666 std::string m_password;
667 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
668 std::string m_new_password;
669 // Usable by auth mechanisms.
670 AuthMechanism m_chosen_auth_mech;
671 void *m_auth_data = nullptr;
674 bool m_access_denied = false;
675 bool m_access_denied_reconnect = false;
676 std::string m_access_denied_reason = "";
677 std::queue<ClientEvent> m_client_event_queue;
678 bool m_itemdef_received = false;
679 bool m_nodedef_received = false;
680 ClientMediaDownloader *m_media_downloader;
682 // time_of_day speed approximation for old protocol
683 bool m_time_of_day_set = false;
684 float m_last_time_of_day_f = -1.0f;
685 float m_time_of_day_update_timer = 0.0f;
687 // An interval for generally sending object positions and stuff
688 float m_recommended_send_interval = 0.1f;
691 float m_removed_sounds_check_timer = 0.0f;
692 // Mapping from server sound ids to our sound ids
693 std::unordered_map<s32, int> m_sounds_server_to_client;
694 // And the other way!
695 std::unordered_map<int, s32> m_sounds_client_to_server;
696 // And relations to objects
697 std::unordered_map<int, u16> m_sounds_to_objects;
700 std::unordered_set<std::string> m_privileges;
702 // Detached inventories
704 std::unordered_map<std::string, Inventory*> m_detached_inventories;
706 // Storage for mesh data for creating multiple instances of the same mesh
707 StringMap m_mesh_data;
709 StringMap m_mod_files;
712 LocalClientState m_state;
714 // Used for saving server map to disk client-side
715 MapDatabase *m_localdb = nullptr;
716 IntervalLimiter m_localdb_save_interval;
717 u16 m_cache_save_interval;
719 ClientScripting *m_script = nullptr;
720 bool m_modding_enabled;
721 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
722 float m_mod_storage_save_timer = 10.0f;
723 std::vector<ModSpec> m_mods;
724 GameUIFlags *m_game_ui_flags;
726 bool m_shutdown = false;
728 // CSM flavour limits byteflag
729 u64 m_csm_flavour_limits = CSMFlavourLimit::CSM_FL_NONE;
730 u32 m_csm_noderange_limit = 8;
733 #endif // !CLIENT_HEADER