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 IrrlichtDevice *device,
260 const char *playername,
261 const std::string &password,
262 const std::string &address_name,
263 MapDrawControl &control,
264 IWritableTextureSource *tsrc,
265 IWritableShaderSource *shsrc,
266 IWritableItemDefManager *itemdef,
267 IWritableNodeDefManager *nodedef,
268 ISoundManager *sound,
269 MtEventManager *event,
271 GameUIFlags *game_ui_flags
275 DISABLE_CLASS_COPY(Client);
280 request all threads managed by client to be stopped
288 The name of the local player should already be set when
289 calling this, as it is sent in the initialization.
291 void connect(Address address, bool is_local_server);
294 Stuff that references the environment is valid only as
295 long as this is not called. (eg. Players)
296 If this throws a PeerNotFoundException, the connection has
299 void step(float dtime);
305 void handleCommand(NetworkPacket* pkt);
307 void handleCommand_Null(NetworkPacket* pkt) {};
308 void handleCommand_Deprecated(NetworkPacket* pkt);
309 void handleCommand_Hello(NetworkPacket* pkt);
310 void handleCommand_AuthAccept(NetworkPacket* pkt);
311 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
312 void handleCommand_DenySudoMode(NetworkPacket* pkt);
313 void handleCommand_InitLegacy(NetworkPacket* pkt);
314 void handleCommand_AccessDenied(NetworkPacket* pkt);
315 void handleCommand_RemoveNode(NetworkPacket* pkt);
316 void handleCommand_AddNode(NetworkPacket* pkt);
317 void handleCommand_BlockData(NetworkPacket* pkt);
318 void handleCommand_Inventory(NetworkPacket* pkt);
319 void handleCommand_TimeOfDay(NetworkPacket* pkt);
320 void handleCommand_ChatMessage(NetworkPacket* pkt);
321 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
322 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
323 void handleCommand_Movement(NetworkPacket* pkt);
324 void handleCommand_HP(NetworkPacket* pkt);
325 void handleCommand_Breath(NetworkPacket* pkt);
326 void handleCommand_MovePlayer(NetworkPacket* pkt);
327 void handleCommand_DeathScreen(NetworkPacket* pkt);
328 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
329 void handleCommand_Media(NetworkPacket* pkt);
330 void handleCommand_NodeDef(NetworkPacket* pkt);
331 void handleCommand_ItemDef(NetworkPacket* pkt);
332 void handleCommand_PlaySound(NetworkPacket* pkt);
333 void handleCommand_StopSound(NetworkPacket* pkt);
334 void handleCommand_FadeSound(NetworkPacket *pkt);
335 void handleCommand_Privileges(NetworkPacket* pkt);
336 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
337 void handleCommand_DetachedInventory(NetworkPacket* pkt);
338 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
339 void handleCommand_SpawnParticle(NetworkPacket* pkt);
340 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
341 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
342 void handleCommand_HudAdd(NetworkPacket* pkt);
343 void handleCommand_HudRemove(NetworkPacket* pkt);
344 void handleCommand_HudChange(NetworkPacket* pkt);
345 void handleCommand_HudSetFlags(NetworkPacket* pkt);
346 void handleCommand_HudSetParam(NetworkPacket* pkt);
347 void handleCommand_HudSetSky(NetworkPacket* pkt);
348 void handleCommand_CloudParams(NetworkPacket* pkt);
349 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
350 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
351 void handleCommand_EyeOffset(NetworkPacket* pkt);
352 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
353 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
355 void ProcessData(NetworkPacket *pkt);
357 void Send(NetworkPacket* pkt);
359 void interact(u8 action, const PointedThing& pointed);
361 void sendNodemetaFields(v3s16 p, const std::string &formname,
362 const StringMap &fields);
363 void sendInventoryFields(const std::string &formname,
364 const StringMap &fields);
365 void sendInventoryAction(InventoryAction *a);
366 void sendChatMessage(const std::wstring &message);
367 void clearOutChatQueue();
368 void sendChangePassword(const std::string &oldpassword,
369 const std::string &newpassword);
370 void sendDamage(u8 damage);
371 void sendBreath(u16 breath);
375 ClientEnvironment& getEnv() { return m_env; }
376 ITextureSource *tsrc() { return getTextureSource(); }
377 ISoundManager *sound() { return getSoundManager(); }
378 static const std::string &getBuiltinLuaPath();
379 static const std::string &getClientModsLuaPath();
381 virtual const std::vector<ModSpec> &getMods() const;
382 virtual const ModSpec* getModSpec(const std::string &modname) const;
384 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
385 void removeNode(v3s16 p);
386 MapNode getNode(v3s16 p, bool *is_valid_position);
387 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
389 void setPlayerControl(PlayerControl &control);
391 void selectPlayerItem(u16 item);
392 u16 getPlayerItem() const
393 { return m_playeritem; }
395 // Returns true if the inventory of the local player has been
396 // updated from the server. If it is true, it is set to false.
397 bool getLocalInventoryUpdated();
398 // Copies the inventory of the local player to parameter
399 void getLocalInventory(Inventory &dst);
401 /* InventoryManager interface */
402 Inventory* getInventory(const InventoryLocation &loc);
403 void inventoryAction(InventoryAction *a);
405 const std::list<std::string> &getConnectedPlayerNames()
407 return m_env.getPlayerNames();
410 float getAnimationTime();
414 void setCrack(int level, v3s16 pos);
418 bool checkPrivilege(const std::string &priv) const
419 { return (m_privileges.count(priv) != 0); }
421 const std::unordered_set<std::string> &getPrivilegeList() const
422 { return m_privileges; }
424 bool getChatMessage(std::wstring &message);
425 void typeChatMessage(const std::wstring& message);
427 u64 getMapSeed(){ return m_map_seed; }
429 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
430 // Including blocks at appropriate edges
431 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
432 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
434 void updateCameraOffset(v3s16 camera_offset)
435 { m_mesh_update_thread.m_camera_offset = camera_offset; }
437 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
438 // Get event from queue. If queue is empty, it triggers an assertion failure.
439 ClientEvent getClientEvent();
441 bool accessDenied() const { return m_access_denied; }
443 bool reconnectRequested() const { return m_access_denied_reconnect; }
445 void setFatalError(const std::string &reason)
447 m_access_denied = true;
448 m_access_denied_reason = reason;
451 // Renaming accessDeniedReason to better name could be good as it's used to
452 // disconnect client when CSM failed.
453 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
455 bool itemdefReceived()
456 { return m_itemdef_received; }
457 bool nodedefReceived()
458 { return m_nodedef_received; }
460 { return !m_media_downloader; }
463 { return m_proto_ver; }
465 bool connectedToServer()
466 { return m_con.Connected(); }
468 float mediaReceiveProgress();
470 void afterContentReceived(IrrlichtDevice *device);
475 Minimap* getMinimap() { return m_minimap; }
476 void setCamera(Camera* camera) { m_camera = camera; }
478 Camera* getCamera () { return m_camera; }
480 bool shouldShowMinimap() const;
482 // IGameDef interface
483 virtual IItemDefManager* getItemDefManager();
484 virtual INodeDefManager* getNodeDefManager();
485 virtual ICraftDefManager* getCraftDefManager();
486 ITextureSource* getTextureSource();
487 virtual IShaderSource* getShaderSource();
488 IShaderSource *shsrc() { return getShaderSource(); }
489 scene::ISceneManager* getSceneManager();
490 virtual u16 allocateUnknownNodeId(const std::string &name);
491 virtual ISoundManager* getSoundManager();
492 virtual MtEventManager* getEventManager();
493 virtual ParticleManager* getParticleManager();
494 bool checkLocalPrivilege(const std::string &priv)
495 { return checkPrivilege(priv); }
496 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
498 virtual std::string getModStoragePath() const;
499 virtual bool registerModStorage(ModMetadata *meta);
500 virtual void unregisterModStorage(const std::string &name);
502 // The following set of functions is used by ClientMediaDownloader
503 // Insert a media file appropriately into the appropriate manager
504 bool loadMedia(const std::string &data, const std::string &filename);
505 // Send a request for conventional media transfer
506 void request_media(const std::vector<std::string> &file_requests);
508 LocalClientState getState() { return m_state; }
510 void makeScreenshot(IrrlichtDevice *device);
512 inline void pushToChatQueue(const std::wstring &input)
514 m_chat_queue.push(input);
517 ClientScripting *getScript() { return m_script; }
518 const bool moddingEnabled() const { return m_modding_enabled; }
520 inline void pushToEventQueue(const ClientEvent &event)
522 m_client_event_queue.push(event);
525 void showGameChat(const bool show = true);
526 void showGameHud(const bool show = true);
527 void showMinimap(const bool show = true);
528 void showProfiler(const bool show = true);
529 void showGameFog(const bool show = true);
530 void showGameDebug(const bool show = true);
532 IrrlichtDevice *getDevice() const { return m_device; }
534 const Address getServerAddress()
536 return m_con.GetPeerAddress(PEER_ID_SERVER);
539 const std::string &getAddressName() const
541 return m_address_name;
546 // Virtual methods from con::PeerHandler
547 void peerAdded(con::Peer *peer);
548 void deletingPeer(con::Peer *peer, bool timeout);
550 void initLocalMapSaving(const Address &address,
551 const std::string &hostname,
552 bool is_local_server);
557 void sendPlayerPos();
558 // Send the item number 'item' as player item to the server
559 void sendPlayerItem(u16 item);
561 void deleteAuthData();
562 // helper method shared with clientpackethandler
563 static AuthMechanism choseAuthMech(const u32 mechs);
565 void sendLegacyInit(const char* playerName, const char* playerPassword);
566 void sendInit(const std::string &playerName);
567 void startAuth(AuthMechanism chosen_auth_mechanism);
568 void sendDeletedBlocks(std::vector<v3s16> &blocks);
569 void sendGotBlocks(v3s16 block);
570 void sendRemovedSounds(std::vector<s32> &soundList);
573 inline std::string getPlayerName()
574 { return m_env.getLocalPlayer()->getName(); }
576 bool canSendChatMessage() const;
578 float m_packetcounter_timer = 0.0f;
579 float m_connection_reinit_timer = 0.1f;
580 float m_avg_rtt_timer = 0.0f;
581 float m_playerpos_send_timer = 0.0f;
582 float m_ignore_damage_timer = 0.0f; // Used after server moves player
583 IntervalLimiter m_map_timer_and_unload_interval;
585 IWritableTextureSource *m_tsrc;
586 IWritableShaderSource *m_shsrc;
587 IWritableItemDefManager *m_itemdef;
588 IWritableNodeDefManager *m_nodedef;
589 ISoundManager *m_sound;
590 MtEventManager *m_event;
593 MeshUpdateThread m_mesh_update_thread;
594 ClientEnvironment m_env;
595 ParticleManager m_particle_manager;
596 con::Connection m_con;
597 std::string m_address_name;
598 IrrlichtDevice *m_device;
599 Camera *m_camera = nullptr;
600 Minimap *m_minimap = nullptr;
601 bool m_minimap_disabled_by_server = false;
602 // Server serialization version
605 // Used version of the protocol with server
606 // Values smaller than 25 only mean they are smaller than 25,
607 // and aren't accurate. We simply just don't know, because
608 // the server didn't send the version back then.
609 // If 0, server init hasn't been received yet.
612 u16 m_playeritem = 0;
613 bool m_inventory_updated = false;
614 Inventory *m_inventory_from_server = nullptr;
615 float m_inventory_from_server_age = 0.0f;
616 PacketCounter m_packetcounter;
617 // Block mesh animation parameters
618 float m_animation_time = 0.0f;
619 int m_crack_level = -1;
621 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
623 //u32 m_daynight_ratio;
624 std::queue<std::wstring> m_chat_queue;
625 std::queue<std::wstring> m_out_chat_queue;
626 u32 m_last_chat_message_sent;
627 float m_chat_message_allowance = 5.0f;
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;
681 LocalClientState m_state;
683 // Used for saving server map to disk client-side
684 MapDatabase *m_localdb = nullptr;
685 IntervalLimiter m_localdb_save_interval;
686 u16 m_cache_save_interval;
688 ClientScripting *m_script = nullptr;
689 bool m_modding_enabled;
690 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
691 float m_mod_storage_save_timer = 10.0f;
692 GameUIFlags *m_game_ui_flags;
694 bool m_shutdown = false;
697 #endif // !CLIENT_HEADER