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.
22 #include "clientenvironment.h"
23 #include "irrlichttypes_extrabloated.h"
28 #include <unordered_set>
29 #include "clientobject.h"
31 #include "inventorymanager.h"
32 #include "localplayer.h"
33 #include "client/hud.h"
34 #include "particles.h"
36 #include "tileanimation.h"
37 #include "mesh_generator_thread.h"
38 #include "network/address.h"
39 #include "network/peerhandler.h"
42 #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
48 class IWritableTextureSource;
49 class IWritableShaderSource;
50 class IWritableItemDefManager;
53 //class IWritableCraftDefManager;
54 class ClientMediaDownloader;
55 struct MapDrawControl;
61 struct MinimapMapblock;
68 enum LocalClientState {
81 PacketCounter() = default;
85 std::map<u16, u16>::iterator n = m_packets.find(command);
86 if(n == m_packets.end())
88 m_packets[command] = 1;
98 for (auto &m_packet : m_packets) {
103 void print(std::ostream &o)
105 for (const auto &m_packet : m_packets) {
106 o << "cmd "<< m_packet.first <<" count "<< m_packet.second << std::endl;
112 std::map<u16, u16> m_packets;
115 class ClientScripting;
118 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
122 NOTE: Nothing is thread-safe here.
126 const char *playername,
127 const std::string &password,
128 const std::string &address_name,
129 MapDrawControl &control,
130 IWritableTextureSource *tsrc,
131 IWritableShaderSource *shsrc,
132 IWritableItemDefManager *itemdef,
133 NodeDefManager *nodedef,
134 ISoundManager *sound,
135 MtEventManager *event,
141 DISABLE_CLASS_COPY(Client);
143 // Load local mods into memory
145 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
146 std::string mod_subpath);
147 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
149 scanModSubfolder(mod_name, mod_path, "");
153 request all threads managed by client to be stopped
161 The name of the local player should already be set when
162 calling this, as it is sent in the initialization.
164 void connect(Address address, bool is_local_server);
167 Stuff that references the environment is valid only as
168 long as this is not called. (eg. Players)
169 If this throws a PeerNotFoundException, the connection has
172 void step(float dtime);
178 void handleCommand(NetworkPacket* pkt);
180 void handleCommand_Null(NetworkPacket* pkt) {};
181 void handleCommand_Deprecated(NetworkPacket* pkt);
182 void handleCommand_Hello(NetworkPacket* pkt);
183 void handleCommand_AuthAccept(NetworkPacket* pkt);
184 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
185 void handleCommand_DenySudoMode(NetworkPacket* pkt);
186 void handleCommand_AccessDenied(NetworkPacket* pkt);
187 void handleCommand_RemoveNode(NetworkPacket* pkt);
188 void handleCommand_AddNode(NetworkPacket* pkt);
189 void handleCommand_BlockData(NetworkPacket* pkt);
190 void handleCommand_Inventory(NetworkPacket* pkt);
191 void handleCommand_TimeOfDay(NetworkPacket* pkt);
192 void handleCommand_ChatMessage(NetworkPacket *pkt);
193 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
194 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
195 void handleCommand_Movement(NetworkPacket* pkt);
196 void handleCommand_HP(NetworkPacket* pkt);
197 void handleCommand_Breath(NetworkPacket* pkt);
198 void handleCommand_MovePlayer(NetworkPacket* pkt);
199 void handleCommand_DeathScreen(NetworkPacket* pkt);
200 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
201 void handleCommand_Media(NetworkPacket* pkt);
202 void handleCommand_NodeDef(NetworkPacket* pkt);
203 void handleCommand_ItemDef(NetworkPacket* pkt);
204 void handleCommand_PlaySound(NetworkPacket* pkt);
205 void handleCommand_StopSound(NetworkPacket* pkt);
206 void handleCommand_FadeSound(NetworkPacket *pkt);
207 void handleCommand_Privileges(NetworkPacket* pkt);
208 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
209 void handleCommand_DetachedInventory(NetworkPacket* pkt);
210 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
211 void handleCommand_SpawnParticle(NetworkPacket* pkt);
212 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
213 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
214 void handleCommand_HudAdd(NetworkPacket* pkt);
215 void handleCommand_HudRemove(NetworkPacket* pkt);
216 void handleCommand_HudChange(NetworkPacket* pkt);
217 void handleCommand_HudSetFlags(NetworkPacket* pkt);
218 void handleCommand_HudSetParam(NetworkPacket* pkt);
219 void handleCommand_HudSetSky(NetworkPacket* pkt);
220 void handleCommand_CloudParams(NetworkPacket* pkt);
221 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
222 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
223 void handleCommand_EyeOffset(NetworkPacket* pkt);
224 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
225 void handleCommand_ModChannelMsg(NetworkPacket *pkt);
226 void handleCommand_ModChannelSignal(NetworkPacket *pkt);
227 void handleCommand_SrpBytesSandB(NetworkPacket *pkt);
228 void handleCommand_FormspecPrepend(NetworkPacket *pkt);
229 void handleCommand_CSMFlavourLimits(NetworkPacket *pkt);
231 void ProcessData(NetworkPacket *pkt);
233 void Send(NetworkPacket* pkt);
235 void interact(u8 action, const PointedThing& pointed);
237 void sendNodemetaFields(v3s16 p, const std::string &formname,
238 const StringMap &fields);
239 void sendInventoryFields(const std::string &formname,
240 const StringMap &fields);
241 void sendInventoryAction(InventoryAction *a);
242 void sendChatMessage(const std::wstring &message);
243 void clearOutChatQueue();
244 void sendChangePassword(const std::string &oldpassword,
245 const std::string &newpassword);
246 void sendDamage(u8 damage);
250 ClientEnvironment& getEnv() { return m_env; }
251 ITextureSource *tsrc() { return getTextureSource(); }
252 ISoundManager *sound() { return getSoundManager(); }
253 static const std::string &getBuiltinLuaPath();
254 static const std::string &getClientModsLuaPath();
256 const std::vector<ModSpec> &getMods() const override;
257 const ModSpec* getModSpec(const std::string &modname) const override;
259 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
260 void removeNode(v3s16 p);
263 * Helper function for Client Side Modding
264 * Flavour is applied there, this should not be used for core engine
266 * @param is_valid_position
269 MapNode getNode(v3s16 p, bool *is_valid_position);
270 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
272 void setPlayerControl(PlayerControl &control);
274 void selectPlayerItem(u16 item);
275 u16 getPlayerItem() const
276 { return m_playeritem; }
278 // Returns true if the inventory of the local player has been
279 // updated from the server. If it is true, it is set to false.
280 bool getLocalInventoryUpdated();
281 // Copies the inventory of the local player to parameter
282 void getLocalInventory(Inventory &dst);
284 /* InventoryManager interface */
285 Inventory* getInventory(const InventoryLocation &loc) override;
286 void inventoryAction(InventoryAction *a) override;
288 const std::list<std::string> &getConnectedPlayerNames()
290 return m_env.getPlayerNames();
293 float getAnimationTime();
297 void setCrack(int level, v3s16 pos);
301 bool checkPrivilege(const std::string &priv) const
302 { return (m_privileges.count(priv) != 0); }
304 const std::unordered_set<std::string> &getPrivilegeList() const
305 { return m_privileges; }
307 bool getChatMessage(std::wstring &message);
308 void typeChatMessage(const std::wstring& message);
310 u64 getMapSeed(){ return m_map_seed; }
312 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
313 // Including blocks at appropriate edges
314 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
315 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
317 void updateCameraOffset(v3s16 camera_offset)
318 { m_mesh_update_thread.m_camera_offset = camera_offset; }
320 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
321 // Get event from queue. If queue is empty, it triggers an assertion failure.
322 ClientEvent * getClientEvent();
324 bool accessDenied() const { return m_access_denied; }
326 bool reconnectRequested() const { return m_access_denied_reconnect; }
328 void setFatalError(const std::string &reason)
330 m_access_denied = true;
331 m_access_denied_reason = reason;
334 // Renaming accessDeniedReason to better name could be good as it's used to
335 // disconnect client when CSM failed.
336 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
338 bool itemdefReceived()
339 { return m_itemdef_received; }
340 bool nodedefReceived()
341 { return m_nodedef_received; }
343 { return !m_media_downloader; }
346 { return m_proto_ver; }
348 bool connectedToServer();
349 void confirmRegistration();
350 bool m_is_registration_confirmation_state = false;
351 bool m_simple_singleplayer_mode;
353 float mediaReceiveProgress();
355 void afterContentReceived();
360 Minimap* getMinimap() { return m_minimap; }
361 void setCamera(Camera* camera) { m_camera = camera; }
363 Camera* getCamera () { return m_camera; }
365 bool shouldShowMinimap() const;
367 // IGameDef interface
368 IItemDefManager* getItemDefManager() override;
369 const NodeDefManager* getNodeDefManager() override;
370 ICraftDefManager* getCraftDefManager() override;
371 ITextureSource* getTextureSource();
372 virtual IShaderSource* getShaderSource();
373 u16 allocateUnknownNodeId(const std::string &name) override;
374 virtual ISoundManager* getSoundManager();
375 MtEventManager* getEventManager();
376 virtual ParticleManager* getParticleManager();
377 bool checkLocalPrivilege(const std::string &priv)
378 { return checkPrivilege(priv); }
379 virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
380 const std::string* getModFile(const std::string &filename);
382 std::string getModStoragePath() const override;
383 bool registerModStorage(ModMetadata *meta) override;
384 void unregisterModStorage(const std::string &name) override;
386 // The following set of functions is used by ClientMediaDownloader
387 // Insert a media file appropriately into the appropriate manager
388 bool loadMedia(const std::string &data, const std::string &filename);
389 // Send a request for conventional media transfer
390 void request_media(const std::vector<std::string> &file_requests);
392 LocalClientState getState() { return m_state; }
394 void makeScreenshot();
396 inline void pushToChatQueue(ChatMessage *cec)
398 m_chat_queue.push(cec);
401 ClientScripting *getScript() { return m_script; }
402 const bool moddingEnabled() const { return m_modding_enabled; }
404 void pushToEventQueue(ClientEvent *event);
406 void showMinimap(bool show = true);
408 const Address getServerAddress();
410 const std::string &getAddressName() const
412 return m_address_name;
415 inline bool checkCSMFlavourLimit(CSMFlavourLimit flag) const
417 return m_csm_flavour_limits & flag;
420 u32 getCSMNodeRangeLimit() const
422 return m_csm_noderange_limit;
425 inline std::unordered_map<u32, u32> &getHUDTranslationMap()
427 return m_hud_server_to_client;
430 bool joinModChannel(const std::string &channel) override;
431 bool leaveModChannel(const std::string &channel) override;
432 bool sendModChannelMessage(const std::string &channel,
433 const std::string &message) override;
434 ModChannel *getModChannel(const std::string &channel) override;
436 const std::string &getFormspecPrepend() const
438 return m_env.getLocalPlayer()->formspec_prepend;
442 bool checkBuiltinIntegrity();
444 // Virtual methods from con::PeerHandler
445 void peerAdded(con::Peer *peer) override;
446 void deletingPeer(con::Peer *peer, bool timeout) override;
448 void initLocalMapSaving(const Address &address,
449 const std::string &hostname,
450 bool is_local_server);
455 void sendPlayerPos();
456 // Send the item number 'item' as player item to the server
457 void sendPlayerItem(u16 item);
459 void deleteAuthData();
460 // helper method shared with clientpackethandler
461 static AuthMechanism choseAuthMech(const u32 mechs);
463 void sendInit(const std::string &playerName);
464 void promptConfirmRegistration(AuthMechanism chosen_auth_mechanism);
465 void startAuth(AuthMechanism chosen_auth_mechanism);
466 void sendDeletedBlocks(std::vector<v3s16> &blocks);
467 void sendGotBlocks(v3s16 block);
468 void sendRemovedSounds(std::vector<s32> &soundList);
471 inline std::string getPlayerName()
472 { return m_env.getLocalPlayer()->getName(); }
474 bool canSendChatMessage() const;
476 float m_packetcounter_timer = 0.0f;
477 float m_connection_reinit_timer = 0.1f;
478 float m_avg_rtt_timer = 0.0f;
479 float m_playerpos_send_timer = 0.0f;
480 IntervalLimiter m_map_timer_and_unload_interval;
482 IWritableTextureSource *m_tsrc;
483 IWritableShaderSource *m_shsrc;
484 IWritableItemDefManager *m_itemdef;
485 NodeDefManager *m_nodedef;
486 ISoundManager *m_sound;
487 MtEventManager *m_event;
490 MeshUpdateThread m_mesh_update_thread;
491 ClientEnvironment m_env;
492 ParticleManager m_particle_manager;
493 std::unique_ptr<con::Connection> m_con;
494 std::string m_address_name;
495 Camera *m_camera = nullptr;
496 Minimap *m_minimap = nullptr;
497 bool m_minimap_disabled_by_server = false;
498 // Server serialization version
501 // Used version of the protocol with server
502 // Values smaller than 25 only mean they are smaller than 25,
503 // and aren't accurate. We simply just don't know, because
504 // the server didn't send the version back then.
505 // If 0, server init hasn't been received yet.
508 u16 m_playeritem = 0;
509 bool m_inventory_updated = false;
510 Inventory *m_inventory_from_server = nullptr;
511 float m_inventory_from_server_age = 0.0f;
512 PacketCounter m_packetcounter;
513 // Block mesh animation parameters
514 float m_animation_time = 0.0f;
515 int m_crack_level = -1;
517 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
519 //u32 m_daynight_ratio;
520 std::queue<std::wstring> m_out_chat_queue;
521 u32 m_last_chat_message_sent;
522 float m_chat_message_allowance = 5.0f;
523 std::queue<ChatMessage *> m_chat_queue;
525 // The authentication methods we can use to enter sudo mode (=change password)
526 u32 m_sudo_auth_methods;
528 // The seed returned by the server in TOCLIENT_INIT is stored here
532 std::string m_playername;
533 std::string m_password;
534 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
535 std::string m_new_password;
536 // Usable by auth mechanisms.
537 AuthMechanism m_chosen_auth_mech;
538 void *m_auth_data = nullptr;
541 bool m_access_denied = false;
542 bool m_access_denied_reconnect = false;
543 std::string m_access_denied_reason = "";
544 std::queue<ClientEvent *> m_client_event_queue;
545 bool m_itemdef_received = false;
546 bool m_nodedef_received = false;
547 bool m_mods_loaded = false;
548 ClientMediaDownloader *m_media_downloader;
550 // time_of_day speed approximation for old protocol
551 bool m_time_of_day_set = false;
552 float m_last_time_of_day_f = -1.0f;
553 float m_time_of_day_update_timer = 0.0f;
555 // An interval for generally sending object positions and stuff
556 float m_recommended_send_interval = 0.1f;
559 float m_removed_sounds_check_timer = 0.0f;
560 // Mapping from server sound ids to our sound ids
561 std::unordered_map<s32, int> m_sounds_server_to_client;
562 // And the other way!
563 std::unordered_map<int, s32> m_sounds_client_to_server;
564 // And relations to objects
565 std::unordered_map<int, u16> m_sounds_to_objects;
567 // CSM/client IDs to SSM/server IDs Mapping
568 // Map server particle spawner IDs to client IDs
569 std::unordered_map<u32, u32> m_particles_server_to_client;
570 // Map server hud ids to client hud ids
571 std::unordered_map<u32, u32> m_hud_server_to_client;
574 std::unordered_set<std::string> m_privileges;
576 // Detached inventories
578 std::unordered_map<std::string, Inventory*> m_detached_inventories;
580 // Storage for mesh data for creating multiple instances of the same mesh
581 StringMap m_mesh_data;
583 StringMap m_mod_files;
586 LocalClientState m_state;
590 // Used for saving server map to disk client-side
591 MapDatabase *m_localdb = nullptr;
592 IntervalLimiter m_localdb_save_interval;
593 u16 m_cache_save_interval;
595 ClientScripting *m_script = nullptr;
596 bool m_modding_enabled;
597 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
598 float m_mod_storage_save_timer = 10.0f;
599 std::vector<ModSpec> m_mods;
601 bool m_shutdown = false;
603 // CSM flavour limits byteflag
604 u64 m_csm_flavour_limits = CSMFlavourLimit::CSM_FL_NONE;
605 u32 m_csm_noderange_limit = 8;
607 std::unique_ptr<ModChannelMgr> m_modchannel_mgr;