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);
368 void ProcessData(NetworkPacket *pkt);
370 void Send(NetworkPacket* pkt);
372 void interact(u8 action, const PointedThing& pointed);
374 void sendNodemetaFields(v3s16 p, const std::string &formname,
375 const StringMap &fields);
376 void sendInventoryFields(const std::string &formname,
377 const StringMap &fields);
378 void sendInventoryAction(InventoryAction *a);
379 void sendChatMessage(const std::wstring &message);
380 void clearOutChatQueue();
381 void sendChangePassword(const std::string &oldpassword,
382 const std::string &newpassword);
383 void sendDamage(u8 damage);
384 void sendBreath(u16 breath);
388 ClientEnvironment& getEnv() { return m_env; }
389 ITextureSource *tsrc() { return getTextureSource(); }
390 ISoundManager *sound() { return getSoundManager(); }
391 static const std::string &getBuiltinLuaPath();
392 static const std::string &getClientModsLuaPath();
394 virtual const std::vector<ModSpec> &getMods() const;
395 virtual const ModSpec* getModSpec(const std::string &modname) const;
397 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
398 void removeNode(v3s16 p);
399 MapNode getNode(v3s16 p, bool *is_valid_position);
400 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
402 void setPlayerControl(PlayerControl &control);
404 void selectPlayerItem(u16 item);
405 u16 getPlayerItem() const
406 { return m_playeritem; }
408 // Returns true if the inventory of the local player has been
409 // updated from the server. If it is true, it is set to false.
410 bool getLocalInventoryUpdated();
411 // Copies the inventory of the local player to parameter
412 void getLocalInventory(Inventory &dst);
414 /* InventoryManager interface */
415 Inventory* getInventory(const InventoryLocation &loc);
416 void inventoryAction(InventoryAction *a);
418 const std::list<std::string> &getConnectedPlayerNames()
420 return m_env.getPlayerNames();
423 float getAnimationTime();
427 void setCrack(int level, v3s16 pos);
431 bool checkPrivilege(const std::string &priv) const
432 { return (m_privileges.count(priv) != 0); }
434 const std::unordered_set<std::string> &getPrivilegeList() const
435 { return m_privileges; }
437 bool getChatMessage(std::wstring &message);
438 void typeChatMessage(const std::wstring& message);
440 u64 getMapSeed(){ return m_map_seed; }
442 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
443 // Including blocks at appropriate edges
444 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
445 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
447 void updateCameraOffset(v3s16 camera_offset)
448 { m_mesh_update_thread.m_camera_offset = camera_offset; }
450 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
451 // Get event from queue. If queue is empty, it triggers an assertion failure.
452 ClientEvent getClientEvent();
454 bool accessDenied() const { return m_access_denied; }
456 bool reconnectRequested() const { return m_access_denied_reconnect; }
458 void setFatalError(const std::string &reason)
460 m_access_denied = true;
461 m_access_denied_reason = reason;
464 // Renaming accessDeniedReason to better name could be good as it's used to
465 // disconnect client when CSM failed.
466 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
468 bool itemdefReceived()
469 { return m_itemdef_received; }
470 bool nodedefReceived()
471 { return m_nodedef_received; }
473 { return !m_media_downloader; }
476 { return m_proto_ver; }
478 bool connectedToServer()
479 { return m_con.Connected(); }
481 float mediaReceiveProgress();
483 void afterContentReceived();
488 Minimap* getMinimap() { return m_minimap; }
489 void setCamera(Camera* camera) { m_camera = camera; }
491 Camera* getCamera () { return m_camera; }
493 bool shouldShowMinimap() const;
495 // IGameDef interface
496 virtual IItemDefManager* getItemDefManager();
497 virtual INodeDefManager* getNodeDefManager();
498 virtual ICraftDefManager* getCraftDefManager();
499 ITextureSource* getTextureSource();
500 virtual IShaderSource* getShaderSource();
501 IShaderSource *shsrc() { return getShaderSource(); }
502 virtual u16 allocateUnknownNodeId(const std::string &name);
503 virtual ISoundManager* getSoundManager();
504 virtual MtEventManager* getEventManager();
505 virtual ParticleManager* getParticleManager();
506 bool checkLocalPrivilege(const std::string &priv)
507 { return checkPrivilege(priv); }
508 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
509 const std::string* getModFile(const std::string &filename);
511 virtual std::string getModStoragePath() const;
512 virtual bool registerModStorage(ModMetadata *meta);
513 virtual void unregisterModStorage(const std::string &name);
515 // The following set of functions is used by ClientMediaDownloader
516 // Insert a media file appropriately into the appropriate manager
517 bool loadMedia(const std::string &data, const std::string &filename);
518 // Send a request for conventional media transfer
519 void request_media(const std::vector<std::string> &file_requests);
521 LocalClientState getState() { return m_state; }
523 void makeScreenshot();
525 inline void pushToChatQueue(ChatMessage *cec)
527 m_chat_queue.push(cec);
530 ClientScripting *getScript() { return m_script; }
531 const bool moddingEnabled() const { return m_modding_enabled; }
533 inline void pushToEventQueue(const ClientEvent &event)
535 m_client_event_queue.push(event);
538 void showGameChat(const bool show = true);
539 void showGameHud(const bool show = true);
540 void showMinimap(const bool show = true);
541 void showProfiler(const bool show = true);
542 void showGameFog(const bool show = true);
543 void showGameDebug(const bool show = true);
545 const Address getServerAddress()
547 return m_con.GetPeerAddress(PEER_ID_SERVER);
550 const std::string &getAddressName() const
552 return m_address_name;
557 // Virtual methods from con::PeerHandler
558 void peerAdded(con::Peer *peer);
559 void deletingPeer(con::Peer *peer, bool timeout);
561 void initLocalMapSaving(const Address &address,
562 const std::string &hostname,
563 bool is_local_server);
568 void sendPlayerPos();
569 // Send the item number 'item' as player item to the server
570 void sendPlayerItem(u16 item);
572 void deleteAuthData();
573 // helper method shared with clientpackethandler
574 static AuthMechanism choseAuthMech(const u32 mechs);
576 void sendLegacyInit(const char* playerName, const char* playerPassword);
577 void sendInit(const std::string &playerName);
578 void startAuth(AuthMechanism chosen_auth_mechanism);
579 void sendDeletedBlocks(std::vector<v3s16> &blocks);
580 void sendGotBlocks(v3s16 block);
581 void sendRemovedSounds(std::vector<s32> &soundList);
584 inline std::string getPlayerName()
585 { return m_env.getLocalPlayer()->getName(); }
587 bool canSendChatMessage() const;
589 float m_packetcounter_timer = 0.0f;
590 float m_connection_reinit_timer = 0.1f;
591 float m_avg_rtt_timer = 0.0f;
592 float m_playerpos_send_timer = 0.0f;
593 float m_ignore_damage_timer = 0.0f; // Used after server moves player
594 IntervalLimiter m_map_timer_and_unload_interval;
596 IWritableTextureSource *m_tsrc;
597 IWritableShaderSource *m_shsrc;
598 IWritableItemDefManager *m_itemdef;
599 IWritableNodeDefManager *m_nodedef;
600 ISoundManager *m_sound;
601 MtEventManager *m_event;
604 MeshUpdateThread m_mesh_update_thread;
605 ClientEnvironment m_env;
606 ParticleManager m_particle_manager;
607 con::Connection m_con;
608 std::string m_address_name;
609 Camera *m_camera = nullptr;
610 Minimap *m_minimap = nullptr;
611 bool m_minimap_disabled_by_server = false;
612 // Server serialization version
615 // Used version of the protocol with server
616 // Values smaller than 25 only mean they are smaller than 25,
617 // and aren't accurate. We simply just don't know, because
618 // the server didn't send the version back then.
619 // If 0, server init hasn't been received yet.
622 u16 m_playeritem = 0;
623 bool m_inventory_updated = false;
624 Inventory *m_inventory_from_server = nullptr;
625 float m_inventory_from_server_age = 0.0f;
626 PacketCounter m_packetcounter;
627 // Block mesh animation parameters
628 float m_animation_time = 0.0f;
629 int m_crack_level = -1;
631 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
633 //u32 m_daynight_ratio;
634 std::queue<std::wstring> m_out_chat_queue;
635 u32 m_last_chat_message_sent;
636 float m_chat_message_allowance = 5.0f;
637 std::queue<ChatMessage *> m_chat_queue;
639 // The authentication methods we can use to enter sudo mode (=change password)
640 u32 m_sudo_auth_methods;
642 // The seed returned by the server in TOCLIENT_INIT is stored here
646 std::string m_playername;
647 std::string m_password;
648 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
649 std::string m_new_password;
650 // Usable by auth mechanisms.
651 AuthMechanism m_chosen_auth_mech;
652 void *m_auth_data = nullptr;
655 bool m_access_denied = false;
656 bool m_access_denied_reconnect = false;
657 std::string m_access_denied_reason = "";
658 std::queue<ClientEvent> m_client_event_queue;
659 bool m_itemdef_received = false;
660 bool m_nodedef_received = false;
661 ClientMediaDownloader *m_media_downloader;
663 // time_of_day speed approximation for old protocol
664 bool m_time_of_day_set = false;
665 float m_last_time_of_day_f = -1.0f;
666 float m_time_of_day_update_timer = 0.0f;
668 // An interval for generally sending object positions and stuff
669 float m_recommended_send_interval = 0.1f;
672 float m_removed_sounds_check_timer = 0.0f;
673 // Mapping from server sound ids to our sound ids
674 std::unordered_map<s32, int> m_sounds_server_to_client;
675 // And the other way!
676 std::unordered_map<int, s32> m_sounds_client_to_server;
677 // And relations to objects
678 std::unordered_map<int, u16> m_sounds_to_objects;
681 std::unordered_set<std::string> m_privileges;
683 // Detached inventories
685 std::unordered_map<std::string, Inventory*> m_detached_inventories;
687 // Storage for mesh data for creating multiple instances of the same mesh
688 StringMap m_mesh_data;
690 StringMap m_mod_files;
693 LocalClientState m_state;
695 // Used for saving server map to disk client-side
696 MapDatabase *m_localdb = nullptr;
697 IntervalLimiter m_localdb_save_interval;
698 u16 m_cache_save_interval;
700 ClientScripting *m_script = nullptr;
701 bool m_modding_enabled;
702 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
703 float m_mod_storage_save_timer = 10.0f;
704 std::vector<ModSpec> m_mods;
705 GameUIFlags *m_game_ui_flags;
707 bool m_shutdown = false;
710 #endif // !CLIENT_HEADER