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"
45 class IWritableTextureSource;
46 class IWritableShaderSource;
47 class IWritableItemDefManager;
48 class IWritableNodeDefManager;
49 //class IWritableCraftDefManager;
50 class ClientMediaDownloader;
51 struct MapDrawControl;
56 struct MinimapMapblock;
60 enum LocalClientState {
73 CE_SHOW_LOCAL_FORMSPEC,
75 CE_ADD_PARTICLESPAWNER,
76 CE_DELETE_PARTICLESPAWNER,
81 CE_OVERRIDE_DAY_NIGHT_RATIO,
99 bool set_camera_point_target;
100 f32 camera_point_target_x;
101 f32 camera_point_target_y;
102 f32 camera_point_target_z;
105 std::string *formspec;
106 std::string *formname;
109 //} textures_updated;
116 bool collisiondetection;
117 bool collision_removal;
119 std::string *texture;
120 struct TileAnimationParams animation;
136 bool collisiondetection;
137 bool collision_removal;
140 std::string *texture;
142 struct TileAnimationParams animation;
144 } add_particlespawner;
147 } delete_particlespawner;
176 video::SColor *bgcolor;
178 std::vector<std::string> *params;
184 } override_day_night_ratio;
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(std::map<u16, u16>::iterator
224 i = m_packets.begin();
225 i != m_packets.end(); ++i)
231 void print(std::ostream &o)
233 for(std::map<u16, u16>::iterator
234 i = m_packets.begin();
235 i != m_packets.end(); ++i)
238 <<" count "<<i->second
245 std::map<u16, u16> m_packets;
248 class ClientScripting;
251 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
255 NOTE: Nothing is thread-safe here.
259 const char *playername,
260 const std::string &password,
261 const std::string &address_name,
262 MapDrawControl &control,
263 IWritableTextureSource *tsrc,
264 IWritableShaderSource *shsrc,
265 IWritableItemDefManager *itemdef,
266 IWritableNodeDefManager *nodedef,
267 ISoundManager *sound,
268 MtEventManager *event,
270 GameUIFlags *game_ui_flags
274 DISABLE_CLASS_COPY(Client);
276 // Load local mods into memory
278 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
279 std::string mod_subpath);
280 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
282 scanModSubfolder(mod_name, mod_path, "");
289 request all threads managed by client to be stopped
297 The name of the local player should already be set when
298 calling this, as it is sent in the initialization.
300 void connect(Address address, bool is_local_server);
303 Stuff that references the environment is valid only as
304 long as this is not called. (eg. Players)
305 If this throws a PeerNotFoundException, the connection has
308 void step(float dtime);
314 void handleCommand(NetworkPacket* pkt);
316 void handleCommand_Null(NetworkPacket* pkt) {};
317 void handleCommand_Deprecated(NetworkPacket* pkt);
318 void handleCommand_Hello(NetworkPacket* pkt);
319 void handleCommand_AuthAccept(NetworkPacket* pkt);
320 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
321 void handleCommand_DenySudoMode(NetworkPacket* pkt);
322 void handleCommand_InitLegacy(NetworkPacket* pkt);
323 void handleCommand_AccessDenied(NetworkPacket* pkt);
324 void handleCommand_RemoveNode(NetworkPacket* pkt);
325 void handleCommand_AddNode(NetworkPacket* pkt);
326 void handleCommand_BlockData(NetworkPacket* pkt);
327 void handleCommand_Inventory(NetworkPacket* pkt);
328 void handleCommand_TimeOfDay(NetworkPacket* pkt);
329 void handleCommand_ChatMessage(NetworkPacket* pkt);
330 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
331 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
332 void handleCommand_Movement(NetworkPacket* pkt);
333 void handleCommand_HP(NetworkPacket* pkt);
334 void handleCommand_Breath(NetworkPacket* pkt);
335 void handleCommand_MovePlayer(NetworkPacket* pkt);
336 void handleCommand_DeathScreen(NetworkPacket* pkt);
337 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
338 void handleCommand_Media(NetworkPacket* pkt);
339 void handleCommand_NodeDef(NetworkPacket* pkt);
340 void handleCommand_ItemDef(NetworkPacket* pkt);
341 void handleCommand_PlaySound(NetworkPacket* pkt);
342 void handleCommand_StopSound(NetworkPacket* pkt);
343 void handleCommand_FadeSound(NetworkPacket *pkt);
344 void handleCommand_Privileges(NetworkPacket* pkt);
345 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
346 void handleCommand_DetachedInventory(NetworkPacket* pkt);
347 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
348 void handleCommand_SpawnParticle(NetworkPacket* pkt);
349 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
350 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
351 void handleCommand_HudAdd(NetworkPacket* pkt);
352 void handleCommand_HudRemove(NetworkPacket* pkt);
353 void handleCommand_HudChange(NetworkPacket* pkt);
354 void handleCommand_HudSetFlags(NetworkPacket* pkt);
355 void handleCommand_HudSetParam(NetworkPacket* pkt);
356 void handleCommand_HudSetSky(NetworkPacket* pkt);
357 void handleCommand_CloudParams(NetworkPacket* pkt);
358 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
359 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
360 void handleCommand_EyeOffset(NetworkPacket* pkt);
361 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
362 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
364 void ProcessData(NetworkPacket *pkt);
366 void Send(NetworkPacket* pkt);
368 void interact(u8 action, const PointedThing& pointed);
370 void sendNodemetaFields(v3s16 p, const std::string &formname,
371 const StringMap &fields);
372 void sendInventoryFields(const std::string &formname,
373 const StringMap &fields);
374 void sendInventoryAction(InventoryAction *a);
375 void sendChatMessage(const std::wstring &message);
376 void sendChangePassword(const std::string &oldpassword,
377 const std::string &newpassword);
378 void sendDamage(u8 damage);
379 void sendBreath(u16 breath);
383 ClientEnvironment& getEnv() { return m_env; }
384 ITextureSource *tsrc() { return getTextureSource(); }
385 ISoundManager *sound() { return getSoundManager(); }
386 static const std::string &getBuiltinLuaPath();
387 static const std::string &getClientModsLuaPath();
389 virtual const std::vector<ModSpec> &getMods() const;
390 virtual const ModSpec* getModSpec(const std::string &modname) const;
392 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
393 void removeNode(v3s16 p);
394 MapNode getNode(v3s16 p, bool *is_valid_position);
395 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
397 void setPlayerControl(PlayerControl &control);
399 void selectPlayerItem(u16 item);
400 u16 getPlayerItem() const
401 { return m_playeritem; }
403 // Returns true if the inventory of the local player has been
404 // updated from the server. If it is true, it is set to false.
405 bool getLocalInventoryUpdated();
406 // Copies the inventory of the local player to parameter
407 void getLocalInventory(Inventory &dst);
409 /* InventoryManager interface */
410 Inventory* getInventory(const InventoryLocation &loc);
411 void inventoryAction(InventoryAction *a);
413 const std::list<std::string> &getConnectedPlayerNames()
415 return m_env.getPlayerNames();
418 float getAnimationTime();
422 void setCrack(int level, v3s16 pos);
426 bool checkPrivilege(const std::string &priv) const
427 { return (m_privileges.count(priv) != 0); }
429 const std::unordered_set<std::string> &getPrivilegeList() const
430 { return m_privileges; }
432 bool getChatMessage(std::wstring &message);
433 void typeChatMessage(const std::wstring& message);
435 u64 getMapSeed(){ return m_map_seed; }
437 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
438 // Including blocks at appropriate edges
439 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
440 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
442 void updateCameraOffset(v3s16 camera_offset)
443 { m_mesh_update_thread.m_camera_offset = camera_offset; }
445 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
446 // Get event from queue. If queue is empty, it triggers an assertion failure.
447 ClientEvent getClientEvent();
449 bool accessDenied() const { return m_access_denied; }
451 bool reconnectRequested() const { return m_access_denied_reconnect; }
453 void setFatalError(const std::string &reason)
455 m_access_denied = true;
456 m_access_denied_reason = reason;
459 // Renaming accessDeniedReason to better name could be good as it's used to
460 // disconnect client when CSM failed.
461 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
463 bool itemdefReceived()
464 { return m_itemdef_received; }
465 bool nodedefReceived()
466 { return m_nodedef_received; }
468 { return !m_media_downloader; }
471 { return m_proto_ver; }
473 bool connectedToServer()
474 { return m_con.Connected(); }
476 float mediaReceiveProgress();
478 void afterContentReceived();
483 Minimap* getMinimap() { return m_minimap; }
484 void setCamera(Camera* camera) { m_camera = camera; }
486 Camera* getCamera () { return m_camera; }
488 bool shouldShowMinimap() const;
490 // IGameDef interface
491 virtual IItemDefManager* getItemDefManager();
492 virtual INodeDefManager* getNodeDefManager();
493 virtual ICraftDefManager* getCraftDefManager();
494 ITextureSource* getTextureSource();
495 virtual IShaderSource* getShaderSource();
496 IShaderSource *shsrc() { return getShaderSource(); }
497 virtual u16 allocateUnknownNodeId(const std::string &name);
498 virtual ISoundManager* getSoundManager();
499 virtual MtEventManager* getEventManager();
500 virtual ParticleManager* getParticleManager();
501 bool checkLocalPrivilege(const std::string &priv)
502 { return checkPrivilege(priv); }
503 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
504 const std::string* getModFile(const std::string &filename);
506 virtual std::string getModStoragePath() const;
507 virtual bool registerModStorage(ModMetadata *meta);
508 virtual void unregisterModStorage(const std::string &name);
510 // The following set of functions is used by ClientMediaDownloader
511 // Insert a media file appropriately into the appropriate manager
512 bool loadMedia(const std::string &data, const std::string &filename);
513 // Send a request for conventional media transfer
514 void request_media(const std::vector<std::string> &file_requests);
516 LocalClientState getState() { return m_state; }
518 void makeScreenshot();
520 inline void pushToChatQueue(const std::wstring &input)
522 m_chat_queue.push(input);
525 ClientScripting *getScript() { return m_script; }
526 const bool moddingEnabled() const { return m_modding_enabled; }
528 inline void pushToEventQueue(const ClientEvent &event)
530 m_client_event_queue.push(event);
533 void showGameChat(const bool show = true);
534 void showGameHud(const bool show = true);
535 void showMinimap(const bool show = true);
536 void showProfiler(const bool show = true);
537 void showGameFog(const bool show = true);
538 void showGameDebug(const bool show = true);
540 const Address getServerAddress()
542 return m_con.GetPeerAddress(PEER_ID_SERVER);
545 const std::string &getAddressName() const
547 return m_address_name;
552 // Virtual methods from con::PeerHandler
553 void peerAdded(con::Peer *peer);
554 void deletingPeer(con::Peer *peer, bool timeout);
556 void initLocalMapSaving(const Address &address,
557 const std::string &hostname,
558 bool is_local_server);
563 void sendPlayerPos();
564 // Send the item number 'item' as player item to the server
565 void sendPlayerItem(u16 item);
567 void deleteAuthData();
568 // helper method shared with clientpackethandler
569 static AuthMechanism choseAuthMech(const u32 mechs);
571 void sendLegacyInit(const char* playerName, const char* playerPassword);
572 void sendInit(const std::string &playerName);
573 void startAuth(AuthMechanism chosen_auth_mechanism);
574 void sendDeletedBlocks(std::vector<v3s16> &blocks);
575 void sendGotBlocks(v3s16 block);
576 void sendRemovedSounds(std::vector<s32> &soundList);
579 inline std::string getPlayerName()
580 { return m_env.getLocalPlayer()->getName(); }
582 float m_packetcounter_timer = 0.0f;
583 float m_connection_reinit_timer = 0.1f;
584 float m_avg_rtt_timer = 0.0f;
585 float m_playerpos_send_timer = 0.0f;
586 float m_ignore_damage_timer = 0.0f; // Used after server moves player
587 IntervalLimiter m_map_timer_and_unload_interval;
589 IWritableTextureSource *m_tsrc;
590 IWritableShaderSource *m_shsrc;
591 IWritableItemDefManager *m_itemdef;
592 IWritableNodeDefManager *m_nodedef;
593 ISoundManager *m_sound;
594 MtEventManager *m_event;
597 MeshUpdateThread m_mesh_update_thread;
598 ClientEnvironment m_env;
599 ParticleManager m_particle_manager;
600 con::Connection m_con;
601 std::string m_address_name;
602 Camera *m_camera = nullptr;
603 Minimap *m_minimap = nullptr;
604 bool m_minimap_disabled_by_server = false;
605 // Server serialization version
608 // Used version of the protocol with server
609 // Values smaller than 25 only mean they are smaller than 25,
610 // and aren't accurate. We simply just don't know, because
611 // the server didn't send the version back then.
612 // If 0, server init hasn't been received yet.
615 u16 m_playeritem = 0;
616 bool m_inventory_updated = false;
617 Inventory *m_inventory_from_server = nullptr;
618 float m_inventory_from_server_age = 0.0f;
619 PacketCounter m_packetcounter;
620 // Block mesh animation parameters
621 float m_animation_time = 0.0f;
622 int m_crack_level = -1;
624 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
626 //u32 m_daynight_ratio;
627 std::queue<std::wstring> m_chat_queue;
629 // The authentication methods we can use to enter sudo mode (=change password)
630 u32 m_sudo_auth_methods;
632 // The seed returned by the server in TOCLIENT_INIT is stored here
636 std::string m_playername;
637 std::string m_password;
638 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
639 std::string m_new_password;
640 // Usable by auth mechanisms.
641 AuthMechanism m_chosen_auth_mech;
642 void *m_auth_data = nullptr;
645 bool m_access_denied = false;
646 bool m_access_denied_reconnect = false;
647 std::string m_access_denied_reason = "";
648 std::queue<ClientEvent> m_client_event_queue;
649 bool m_itemdef_received = false;
650 bool m_nodedef_received = false;
651 ClientMediaDownloader *m_media_downloader;
653 // time_of_day speed approximation for old protocol
654 bool m_time_of_day_set = false;
655 float m_last_time_of_day_f = -1.0f;
656 float m_time_of_day_update_timer = 0.0f;
658 // An interval for generally sending object positions and stuff
659 float m_recommended_send_interval = 0.1f;
662 float m_removed_sounds_check_timer = 0.0f;
663 // Mapping from server sound ids to our sound ids
664 std::unordered_map<s32, int> m_sounds_server_to_client;
665 // And the other way!
666 std::unordered_map<int, s32> m_sounds_client_to_server;
667 // And relations to objects
668 std::unordered_map<int, u16> m_sounds_to_objects;
671 std::unordered_set<std::string> m_privileges;
673 // Detached inventories
675 std::unordered_map<std::string, Inventory*> m_detached_inventories;
677 // Storage for mesh data for creating multiple instances of the same mesh
678 StringMap m_mesh_data;
680 StringMap m_mod_files;
683 LocalClientState m_state;
685 // Used for saving server map to disk client-side
686 MapDatabase *m_localdb = nullptr;
687 IntervalLimiter m_localdb_save_interval;
688 u16 m_cache_save_interval;
690 ClientScripting *m_script = nullptr;
691 bool m_modding_enabled;
692 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
693 float m_mod_storage_save_timer = 10.0f;
694 std::vector<ModSpec> m_mods;
695 GameUIFlags *m_game_ui_flags;
697 bool m_shutdown = false;
700 #endif // !CLIENT_HEADER