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
144 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
145 std::string mod_subpath);
146 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
148 scanModSubfolder(mod_name, mod_path, "");
152 request all threads managed by client to be stopped
160 The name of the local player should already be set when
161 calling this, as it is sent in the initialization.
163 void connect(Address address, bool is_local_server);
166 Stuff that references the environment is valid only as
167 long as this is not called. (eg. Players)
168 If this throws a PeerNotFoundException, the connection has
171 void step(float dtime);
177 void handleCommand(NetworkPacket* pkt);
179 void handleCommand_Null(NetworkPacket* pkt) {};
180 void handleCommand_Deprecated(NetworkPacket* pkt);
181 void handleCommand_Hello(NetworkPacket* pkt);
182 void handleCommand_AuthAccept(NetworkPacket* pkt);
183 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
184 void handleCommand_DenySudoMode(NetworkPacket* pkt);
185 void handleCommand_AccessDenied(NetworkPacket* pkt);
186 void handleCommand_RemoveNode(NetworkPacket* pkt);
187 void handleCommand_AddNode(NetworkPacket* pkt);
188 void handleCommand_NodemetaChanged(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_CSMRestrictionFlags(NetworkPacket *pkt);
230 void handleCommand_PlayerSpeed(NetworkPacket *pkt);
232 void ProcessData(NetworkPacket *pkt);
234 void Send(NetworkPacket* pkt);
236 void interact(InteractAction action, const PointedThing &pointed);
238 void sendNodemetaFields(v3s16 p, const std::string &formname,
239 const StringMap &fields);
240 void sendInventoryFields(const std::string &formname,
241 const StringMap &fields);
242 void sendInventoryAction(InventoryAction *a);
243 void sendChatMessage(const std::wstring &message);
244 void clearOutChatQueue();
245 void sendChangePassword(const std::string &oldpassword,
246 const std::string &newpassword);
247 void sendDamage(u16 damage);
251 ClientEnvironment& getEnv() { return m_env; }
252 ITextureSource *tsrc() { return getTextureSource(); }
253 ISoundManager *sound() { return getSoundManager(); }
254 static const std::string &getBuiltinLuaPath();
255 static const std::string &getClientModsLuaPath();
257 const std::vector<ModSpec> &getMods() const override;
258 const ModSpec* getModSpec(const std::string &modname) const override;
260 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
261 void removeNode(v3s16 p);
264 * Helper function for Client Side Modding
265 * CSM restrictions are applied there, this should not be used for core engine
267 * @param is_valid_position
270 MapNode getNode(v3s16 p, bool *is_valid_position);
271 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
273 void setPlayerControl(PlayerControl &control);
275 // Returns true if the inventory of the local player has been
276 // updated from the server. If it is true, it is set to false.
277 bool updateWieldedItem();
279 /* InventoryManager interface */
280 Inventory* getInventory(const InventoryLocation &loc) override;
281 void inventoryAction(InventoryAction *a) override;
283 // Send the item number 'item' as player item to the server
284 void setPlayerItem(u16 item);
286 const std::list<std::string> &getConnectedPlayerNames()
288 return m_env.getPlayerNames();
291 float getAnimationTime();
295 void setCrack(int level, v3s16 pos);
299 bool checkPrivilege(const std::string &priv) const
300 { return (m_privileges.count(priv) != 0); }
302 const std::unordered_set<std::string> &getPrivilegeList() const
303 { return m_privileges; }
305 bool getChatMessage(std::wstring &message);
306 void typeChatMessage(const std::wstring& message);
308 u64 getMapSeed(){ return m_map_seed; }
310 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
311 // Including blocks at appropriate edges
312 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
313 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
315 void updateCameraOffset(v3s16 camera_offset)
316 { m_mesh_update_thread.m_camera_offset = camera_offset; }
318 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
319 // Get event from queue. If queue is empty, it triggers an assertion failure.
320 ClientEvent * getClientEvent();
322 bool accessDenied() const { return m_access_denied; }
324 bool reconnectRequested() const { return m_access_denied_reconnect; }
326 void setFatalError(const std::string &reason)
328 m_access_denied = true;
329 m_access_denied_reason = reason;
332 // Renaming accessDeniedReason to better name could be good as it's used to
333 // disconnect client when CSM failed.
334 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
336 bool itemdefReceived()
337 { return m_itemdef_received; }
338 bool nodedefReceived()
339 { return m_nodedef_received; }
341 { return !m_media_downloader; }
343 u16 getProtoVersion()
344 { return m_proto_ver; }
346 bool connectedToServer();
347 void confirmRegistration();
348 bool m_is_registration_confirmation_state = false;
349 bool m_simple_singleplayer_mode;
351 float mediaReceiveProgress();
353 void afterContentReceived();
358 Minimap* getMinimap() { return m_minimap; }
359 void setCamera(Camera* camera) { m_camera = camera; }
361 Camera* getCamera () { return m_camera; }
363 bool shouldShowMinimap() const;
365 // IGameDef interface
366 IItemDefManager* getItemDefManager() override;
367 const NodeDefManager* getNodeDefManager() override;
368 ICraftDefManager* getCraftDefManager() override;
369 ITextureSource* getTextureSource();
370 virtual IShaderSource* getShaderSource();
371 u16 allocateUnknownNodeId(const std::string &name) override;
372 virtual ISoundManager* getSoundManager();
373 MtEventManager* getEventManager();
374 virtual ParticleManager* getParticleManager();
375 bool checkLocalPrivilege(const std::string &priv)
376 { return checkPrivilege(priv); }
377 virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
378 const std::string* getModFile(const std::string &filename);
380 std::string getModStoragePath() const override;
381 bool registerModStorage(ModMetadata *meta) override;
382 void unregisterModStorage(const std::string &name) override;
384 // The following set of functions is used by ClientMediaDownloader
385 // Insert a media file appropriately into the appropriate manager
386 bool loadMedia(const std::string &data, const std::string &filename);
387 // Send a request for conventional media transfer
388 void request_media(const std::vector<std::string> &file_requests);
390 LocalClientState getState() { return m_state; }
392 void makeScreenshot();
394 inline void pushToChatQueue(ChatMessage *cec)
396 m_chat_queue.push(cec);
399 ClientScripting *getScript() { return m_script; }
400 const bool modsLoaded() const { return m_mods_loaded; }
402 void pushToEventQueue(ClientEvent *event);
404 void showMinimap(bool show = true);
406 const Address getServerAddress();
408 const std::string &getAddressName() const
410 return m_address_name;
413 inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
415 return m_csm_restriction_flags & flag;
418 u32 getCSMNodeRangeLimit() const
420 return m_csm_restriction_noderange;
423 inline std::unordered_map<u32, u32> &getHUDTranslationMap()
425 return m_hud_server_to_client;
428 bool joinModChannel(const std::string &channel) override;
429 bool leaveModChannel(const std::string &channel) override;
430 bool sendModChannelMessage(const std::string &channel,
431 const std::string &message) override;
432 ModChannel *getModChannel(const std::string &channel) override;
434 const std::string &getFormspecPrepend() const
436 return m_env.getLocalPlayer()->formspec_prepend;
440 bool checkBuiltinIntegrity();
442 // Virtual methods from con::PeerHandler
443 void peerAdded(con::Peer *peer) override;
444 void deletingPeer(con::Peer *peer, bool timeout) override;
446 void initLocalMapSaving(const Address &address,
447 const std::string &hostname,
448 bool is_local_server);
453 void sendPlayerPos();
455 void deleteAuthData();
456 // helper method shared with clientpackethandler
457 static AuthMechanism choseAuthMech(const u32 mechs);
459 void sendInit(const std::string &playerName);
460 void promptConfirmRegistration(AuthMechanism chosen_auth_mechanism);
461 void startAuth(AuthMechanism chosen_auth_mechanism);
462 void sendDeletedBlocks(std::vector<v3s16> &blocks);
463 void sendGotBlocks(const std::vector<v3s16> &blocks);
464 void sendRemovedSounds(std::vector<s32> &soundList);
467 inline std::string getPlayerName()
468 { return m_env.getLocalPlayer()->getName(); }
470 bool canSendChatMessage() const;
472 float m_packetcounter_timer = 0.0f;
473 float m_connection_reinit_timer = 0.1f;
474 float m_avg_rtt_timer = 0.0f;
475 float m_playerpos_send_timer = 0.0f;
476 IntervalLimiter m_map_timer_and_unload_interval;
478 IWritableTextureSource *m_tsrc;
479 IWritableShaderSource *m_shsrc;
480 IWritableItemDefManager *m_itemdef;
481 NodeDefManager *m_nodedef;
482 ISoundManager *m_sound;
483 MtEventManager *m_event;
486 MeshUpdateThread m_mesh_update_thread;
487 ClientEnvironment m_env;
488 ParticleManager m_particle_manager;
489 std::unique_ptr<con::Connection> m_con;
490 std::string m_address_name;
491 Camera *m_camera = nullptr;
492 Minimap *m_minimap = nullptr;
493 bool m_minimap_disabled_by_server = false;
494 // Server serialization version
497 // Used version of the protocol with server
498 // Values smaller than 25 only mean they are smaller than 25,
499 // and aren't accurate. We simply just don't know, because
500 // the server didn't send the version back then.
501 // If 0, server init hasn't been received yet.
504 bool m_update_wielded_item = false;
505 Inventory *m_inventory_from_server = nullptr;
506 float m_inventory_from_server_age = 0.0f;
507 PacketCounter m_packetcounter;
508 // Block mesh animation parameters
509 float m_animation_time = 0.0f;
510 int m_crack_level = -1;
512 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
514 //u32 m_daynight_ratio;
515 std::queue<std::wstring> m_out_chat_queue;
516 u32 m_last_chat_message_sent;
517 float m_chat_message_allowance = 5.0f;
518 std::queue<ChatMessage *> m_chat_queue;
520 // The authentication methods we can use to enter sudo mode (=change password)
521 u32 m_sudo_auth_methods;
523 // The seed returned by the server in TOCLIENT_INIT is stored here
527 std::string m_playername;
528 std::string m_password;
529 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
530 std::string m_new_password;
531 // Usable by auth mechanisms.
532 AuthMechanism m_chosen_auth_mech;
533 void *m_auth_data = nullptr;
536 bool m_access_denied = false;
537 bool m_access_denied_reconnect = false;
538 std::string m_access_denied_reason = "";
539 std::queue<ClientEvent *> m_client_event_queue;
540 bool m_itemdef_received = false;
541 bool m_nodedef_received = false;
542 bool m_mods_loaded = false;
543 ClientMediaDownloader *m_media_downloader;
545 // time_of_day speed approximation for old protocol
546 bool m_time_of_day_set = false;
547 float m_last_time_of_day_f = -1.0f;
548 float m_time_of_day_update_timer = 0.0f;
550 // An interval for generally sending object positions and stuff
551 float m_recommended_send_interval = 0.1f;
554 float m_removed_sounds_check_timer = 0.0f;
555 // Mapping from server sound ids to our sound ids
556 std::unordered_map<s32, int> m_sounds_server_to_client;
557 // And the other way!
558 std::unordered_map<int, s32> m_sounds_client_to_server;
559 // And relations to objects
560 std::unordered_map<int, u16> m_sounds_to_objects;
562 // Map server hud ids to client hud ids
563 std::unordered_map<u32, u32> m_hud_server_to_client;
566 std::unordered_set<std::string> m_privileges;
568 // Detached inventories
570 std::unordered_map<std::string, Inventory*> m_detached_inventories;
572 // Storage for mesh data for creating multiple instances of the same mesh
573 StringMap m_mesh_data;
575 StringMap m_mod_files;
578 LocalClientState m_state;
582 // Used for saving server map to disk client-side
583 MapDatabase *m_localdb = nullptr;
584 IntervalLimiter m_localdb_save_interval;
585 u16 m_cache_save_interval;
587 ClientScripting *m_script = nullptr;
588 bool m_modding_enabled;
589 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
590 float m_mod_storage_save_timer = 10.0f;
591 std::vector<ModSpec> m_mods;
593 bool m_shutdown = false;
595 // CSM restrictions byteflag
596 u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
597 u32 m_csm_restriction_noderange = 8;
599 std::unique_ptr<ModChannelMgr> m_modchannel_mgr;