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"
41 #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
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);
279 request all threads managed by client to be stopped
287 The name of the local player should already be set when
288 calling this, as it is sent in the initialization.
290 void connect(Address address, bool is_local_server);
293 Stuff that references the environment is valid only as
294 long as this is not called. (eg. Players)
295 If this throws a PeerNotFoundException, the connection has
298 void step(float dtime);
304 void handleCommand(NetworkPacket* pkt);
306 void handleCommand_Null(NetworkPacket* pkt) {};
307 void handleCommand_Deprecated(NetworkPacket* pkt);
308 void handleCommand_Hello(NetworkPacket* pkt);
309 void handleCommand_AuthAccept(NetworkPacket* pkt);
310 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
311 void handleCommand_DenySudoMode(NetworkPacket* pkt);
312 void handleCommand_InitLegacy(NetworkPacket* pkt);
313 void handleCommand_AccessDenied(NetworkPacket* pkt);
314 void handleCommand_RemoveNode(NetworkPacket* pkt);
315 void handleCommand_AddNode(NetworkPacket* pkt);
316 void handleCommand_BlockData(NetworkPacket* pkt);
317 void handleCommand_Inventory(NetworkPacket* pkt);
318 void handleCommand_TimeOfDay(NetworkPacket* pkt);
319 void handleCommand_ChatMessage(NetworkPacket* pkt);
320 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
321 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
322 void handleCommand_Movement(NetworkPacket* pkt);
323 void handleCommand_HP(NetworkPacket* pkt);
324 void handleCommand_Breath(NetworkPacket* pkt);
325 void handleCommand_MovePlayer(NetworkPacket* pkt);
326 void handleCommand_DeathScreen(NetworkPacket* pkt);
327 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
328 void handleCommand_Media(NetworkPacket* pkt);
329 void handleCommand_NodeDef(NetworkPacket* pkt);
330 void handleCommand_ItemDef(NetworkPacket* pkt);
331 void handleCommand_PlaySound(NetworkPacket* pkt);
332 void handleCommand_StopSound(NetworkPacket* pkt);
333 void handleCommand_FadeSound(NetworkPacket *pkt);
334 void handleCommand_Privileges(NetworkPacket* pkt);
335 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
336 void handleCommand_DetachedInventory(NetworkPacket* pkt);
337 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
338 void handleCommand_SpawnParticle(NetworkPacket* pkt);
339 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
340 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
341 void handleCommand_HudAdd(NetworkPacket* pkt);
342 void handleCommand_HudRemove(NetworkPacket* pkt);
343 void handleCommand_HudChange(NetworkPacket* pkt);
344 void handleCommand_HudSetFlags(NetworkPacket* pkt);
345 void handleCommand_HudSetParam(NetworkPacket* pkt);
346 void handleCommand_HudSetSky(NetworkPacket* pkt);
347 void handleCommand_CloudParams(NetworkPacket* pkt);
348 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
349 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
350 void handleCommand_EyeOffset(NetworkPacket* pkt);
351 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
352 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
354 void ProcessData(NetworkPacket *pkt);
356 void Send(NetworkPacket* pkt);
358 void interact(u8 action, const PointedThing& pointed);
360 void sendNodemetaFields(v3s16 p, const std::string &formname,
361 const StringMap &fields);
362 void sendInventoryFields(const std::string &formname,
363 const StringMap &fields);
364 void sendInventoryAction(InventoryAction *a);
365 void sendChatMessage(const std::wstring &message);
366 void clearOutChatQueue();
367 void sendChangePassword(const std::string &oldpassword,
368 const std::string &newpassword);
369 void sendDamage(u8 damage);
370 void sendBreath(u16 breath);
374 ClientEnvironment& getEnv() { return m_env; }
375 ITextureSource *tsrc() { return getTextureSource(); }
376 ISoundManager *sound() { return getSoundManager(); }
377 static const std::string &getBuiltinLuaPath();
378 static const std::string &getClientModsLuaPath();
380 virtual const std::vector<ModSpec> &getMods() const;
381 virtual const ModSpec* getModSpec(const std::string &modname) const;
383 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
384 void removeNode(v3s16 p);
385 MapNode getNode(v3s16 p, bool *is_valid_position);
386 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
388 void setPlayerControl(PlayerControl &control);
390 void selectPlayerItem(u16 item);
391 u16 getPlayerItem() const
392 { return m_playeritem; }
394 // Returns true if the inventory of the local player has been
395 // updated from the server. If it is true, it is set to false.
396 bool getLocalInventoryUpdated();
397 // Copies the inventory of the local player to parameter
398 void getLocalInventory(Inventory &dst);
400 /* InventoryManager interface */
401 Inventory* getInventory(const InventoryLocation &loc);
402 void inventoryAction(InventoryAction *a);
404 const std::list<std::string> &getConnectedPlayerNames()
406 return m_env.getPlayerNames();
409 float getAnimationTime();
413 void setCrack(int level, v3s16 pos);
417 bool checkPrivilege(const std::string &priv) const
418 { return (m_privileges.count(priv) != 0); }
420 const std::unordered_set<std::string> &getPrivilegeList() const
421 { return m_privileges; }
423 bool getChatMessage(std::wstring &message);
424 void typeChatMessage(const std::wstring& message);
426 u64 getMapSeed(){ return m_map_seed; }
428 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
429 // Including blocks at appropriate edges
430 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
431 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
433 void updateCameraOffset(v3s16 camera_offset)
434 { m_mesh_update_thread.m_camera_offset = camera_offset; }
436 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
437 // Get event from queue. If queue is empty, it triggers an assertion failure.
438 ClientEvent getClientEvent();
440 bool accessDenied() const { return m_access_denied; }
442 bool reconnectRequested() const { return m_access_denied_reconnect; }
444 void setFatalError(const std::string &reason)
446 m_access_denied = true;
447 m_access_denied_reason = reason;
450 // Renaming accessDeniedReason to better name could be good as it's used to
451 // disconnect client when CSM failed.
452 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
454 bool itemdefReceived()
455 { return m_itemdef_received; }
456 bool nodedefReceived()
457 { return m_nodedef_received; }
459 { return !m_media_downloader; }
462 { return m_proto_ver; }
464 bool connectedToServer()
465 { return m_con.Connected(); }
467 float mediaReceiveProgress();
469 void afterContentReceived();
474 Minimap* getMinimap() { return m_minimap; }
475 void setCamera(Camera* camera) { m_camera = camera; }
477 Camera* getCamera () { return m_camera; }
479 bool shouldShowMinimap() const;
481 // IGameDef interface
482 virtual IItemDefManager* getItemDefManager();
483 virtual INodeDefManager* getNodeDefManager();
484 virtual ICraftDefManager* getCraftDefManager();
485 ITextureSource* getTextureSource();
486 virtual IShaderSource* getShaderSource();
487 IShaderSource *shsrc() { return getShaderSource(); }
488 virtual u16 allocateUnknownNodeId(const std::string &name);
489 virtual ISoundManager* getSoundManager();
490 virtual MtEventManager* getEventManager();
491 virtual ParticleManager* getParticleManager();
492 bool checkLocalPrivilege(const std::string &priv)
493 { return checkPrivilege(priv); }
494 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
496 virtual std::string getModStoragePath() const;
497 virtual bool registerModStorage(ModMetadata *meta);
498 virtual void unregisterModStorage(const std::string &name);
500 // The following set of functions is used by ClientMediaDownloader
501 // Insert a media file appropriately into the appropriate manager
502 bool loadMedia(const std::string &data, const std::string &filename);
503 // Send a request for conventional media transfer
504 void request_media(const std::vector<std::string> &file_requests);
506 LocalClientState getState() { return m_state; }
508 void makeScreenshot();
510 inline void pushToChatQueue(const std::wstring &input)
512 m_chat_queue.push(input);
515 ClientScripting *getScript() { return m_script; }
516 const bool moddingEnabled() const { return m_modding_enabled; }
518 inline void pushToEventQueue(const ClientEvent &event)
520 m_client_event_queue.push(event);
523 void showGameChat(const bool show = true);
524 void showGameHud(const bool show = true);
525 void showMinimap(const bool show = true);
526 void showProfiler(const bool show = true);
527 void showGameFog(const bool show = true);
528 void showGameDebug(const bool show = true);
530 const Address getServerAddress()
532 return m_con.GetPeerAddress(PEER_ID_SERVER);
535 const std::string &getAddressName() const
537 return m_address_name;
542 // Virtual methods from con::PeerHandler
543 void peerAdded(con::Peer *peer);
544 void deletingPeer(con::Peer *peer, bool timeout);
546 void initLocalMapSaving(const Address &address,
547 const std::string &hostname,
548 bool is_local_server);
553 void sendPlayerPos();
554 // Send the item number 'item' as player item to the server
555 void sendPlayerItem(u16 item);
557 void deleteAuthData();
558 // helper method shared with clientpackethandler
559 static AuthMechanism choseAuthMech(const u32 mechs);
561 void sendLegacyInit(const char* playerName, const char* playerPassword);
562 void sendInit(const std::string &playerName);
563 void startAuth(AuthMechanism chosen_auth_mechanism);
564 void sendDeletedBlocks(std::vector<v3s16> &blocks);
565 void sendGotBlocks(v3s16 block);
566 void sendRemovedSounds(std::vector<s32> &soundList);
569 inline std::string getPlayerName()
570 { return m_env.getLocalPlayer()->getName(); }
572 bool canSendChatMessage() const;
574 float m_packetcounter_timer = 0.0f;
575 float m_connection_reinit_timer = 0.1f;
576 float m_avg_rtt_timer = 0.0f;
577 float m_playerpos_send_timer = 0.0f;
578 float m_ignore_damage_timer = 0.0f; // Used after server moves player
579 IntervalLimiter m_map_timer_and_unload_interval;
581 IWritableTextureSource *m_tsrc;
582 IWritableShaderSource *m_shsrc;
583 IWritableItemDefManager *m_itemdef;
584 IWritableNodeDefManager *m_nodedef;
585 ISoundManager *m_sound;
586 MtEventManager *m_event;
589 MeshUpdateThread m_mesh_update_thread;
590 ClientEnvironment m_env;
591 ParticleManager m_particle_manager;
592 con::Connection m_con;
593 std::string m_address_name;
594 Camera *m_camera = nullptr;
595 Minimap *m_minimap = nullptr;
596 bool m_minimap_disabled_by_server = false;
597 // Server serialization version
600 // Used version of the protocol with server
601 // Values smaller than 25 only mean they are smaller than 25,
602 // and aren't accurate. We simply just don't know, because
603 // the server didn't send the version back then.
604 // If 0, server init hasn't been received yet.
607 u16 m_playeritem = 0;
608 bool m_inventory_updated = false;
609 Inventory *m_inventory_from_server = nullptr;
610 float m_inventory_from_server_age = 0.0f;
611 PacketCounter m_packetcounter;
612 // Block mesh animation parameters
613 float m_animation_time = 0.0f;
614 int m_crack_level = -1;
616 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
618 //u32 m_daynight_ratio;
619 std::queue<std::wstring> m_chat_queue;
620 std::queue<std::wstring> m_out_chat_queue;
621 u32 m_last_chat_message_sent;
622 float m_chat_message_allowance = 5.0f;
624 // The authentication methods we can use to enter sudo mode (=change password)
625 u32 m_sudo_auth_methods;
627 // The seed returned by the server in TOCLIENT_INIT is stored here
631 std::string m_playername;
632 std::string m_password;
633 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
634 std::string m_new_password;
635 // Usable by auth mechanisms.
636 AuthMechanism m_chosen_auth_mech;
637 void *m_auth_data = nullptr;
640 bool m_access_denied = false;
641 bool m_access_denied_reconnect = false;
642 std::string m_access_denied_reason = "";
643 std::queue<ClientEvent> m_client_event_queue;
644 bool m_itemdef_received = false;
645 bool m_nodedef_received = false;
646 ClientMediaDownloader *m_media_downloader;
648 // time_of_day speed approximation for old protocol
649 bool m_time_of_day_set = false;
650 float m_last_time_of_day_f = -1.0f;
651 float m_time_of_day_update_timer = 0.0f;
653 // An interval for generally sending object positions and stuff
654 float m_recommended_send_interval = 0.1f;
657 float m_removed_sounds_check_timer = 0.0f;
658 // Mapping from server sound ids to our sound ids
659 std::unordered_map<s32, int> m_sounds_server_to_client;
660 // And the other way!
661 std::unordered_map<int, s32> m_sounds_client_to_server;
662 // And relations to objects
663 std::unordered_map<int, u16> m_sounds_to_objects;
666 std::unordered_set<std::string> m_privileges;
668 // Detached inventories
670 std::unordered_map<std::string, Inventory*> m_detached_inventories;
672 // Storage for mesh data for creating multiple instances of the same mesh
673 StringMap m_mesh_data;
676 LocalClientState m_state;
678 // Used for saving server map to disk client-side
679 MapDatabase *m_localdb = nullptr;
680 IntervalLimiter m_localdb_save_interval;
681 u16 m_cache_save_interval;
683 ClientScripting *m_script = nullptr;
684 bool m_modding_enabled;
685 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
686 float m_mod_storage_save_timer = 10.0f;
687 GameUIFlags *m_game_ui_flags;
689 bool m_shutdown = false;
692 #endif // !CLIENT_HEADER