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 RenderingEngine;
49 class IWritableTextureSource;
50 class IWritableShaderSource;
53 //class IWritableCraftDefManager;
54 class ClientMediaDownloader;
55 struct MapDrawControl;
61 struct MinimapMapblock;
68 enum LocalClientState {
81 PacketCounter() = default;
85 auto n = m_packets.find(command);
86 if (n == m_packets.end())
87 m_packets[command] = 1;
98 void print(std::ostream &o) const;
102 std::map<u16, u32> m_packets;
105 class ClientScripting;
108 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
112 NOTE: Nothing is thread-safe here.
116 const char *playername,
117 const std::string &password,
118 const std::string &address_name,
119 MapDrawControl &control,
120 IWritableTextureSource *tsrc,
121 IWritableShaderSource *shsrc,
122 IWritableItemDefManager *itemdef,
123 NodeDefManager *nodedef,
124 ISoundManager *sound,
125 MtEventManager *event,
126 RenderingEngine *rendering_engine,
132 DISABLE_CLASS_COPY(Client);
134 // Load local mods into memory
135 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
136 std::string mod_subpath);
137 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
139 scanModSubfolder(mod_name, mod_path, "");
143 request all threads managed by client to be stopped
151 The name of the local player should already be set when
152 calling this, as it is sent in the initialization.
154 void connect(Address address, bool is_local_server);
157 Stuff that references the environment is valid only as
158 long as this is not called. (eg. Players)
159 If this throws a PeerNotFoundException, the connection has
162 void step(float dtime);
168 void handleCommand(NetworkPacket* pkt);
170 void handleCommand_Null(NetworkPacket* pkt) {};
171 void handleCommand_Deprecated(NetworkPacket* pkt);
172 void handleCommand_Hello(NetworkPacket* pkt);
173 void handleCommand_AuthAccept(NetworkPacket* pkt);
174 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
175 void handleCommand_DenySudoMode(NetworkPacket* pkt);
176 void handleCommand_AccessDenied(NetworkPacket* pkt);
177 void handleCommand_RemoveNode(NetworkPacket* pkt);
178 void handleCommand_AddNode(NetworkPacket* pkt);
179 void handleCommand_NodemetaChanged(NetworkPacket *pkt);
180 void handleCommand_BlockData(NetworkPacket* pkt);
181 void handleCommand_Inventory(NetworkPacket* pkt);
182 void handleCommand_TimeOfDay(NetworkPacket* pkt);
183 void handleCommand_ChatMessage(NetworkPacket *pkt);
184 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
185 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
186 void handleCommand_Movement(NetworkPacket* pkt);
187 void handleCommand_Fov(NetworkPacket *pkt);
188 void handleCommand_HP(NetworkPacket* pkt);
189 void handleCommand_Breath(NetworkPacket* pkt);
190 void handleCommand_MovePlayer(NetworkPacket* pkt);
191 void handleCommand_DeathScreen(NetworkPacket* pkt);
192 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
193 void handleCommand_Media(NetworkPacket* pkt);
194 void handleCommand_NodeDef(NetworkPacket* pkt);
195 void handleCommand_ItemDef(NetworkPacket* pkt);
196 void handleCommand_PlaySound(NetworkPacket* pkt);
197 void handleCommand_StopSound(NetworkPacket* pkt);
198 void handleCommand_FadeSound(NetworkPacket *pkt);
199 void handleCommand_Privileges(NetworkPacket* pkt);
200 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
201 void handleCommand_DetachedInventory(NetworkPacket* pkt);
202 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
203 void handleCommand_SpawnParticle(NetworkPacket* pkt);
204 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
205 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
206 void handleCommand_HudAdd(NetworkPacket* pkt);
207 void handleCommand_HudRemove(NetworkPacket* pkt);
208 void handleCommand_HudChange(NetworkPacket* pkt);
209 void handleCommand_HudSetFlags(NetworkPacket* pkt);
210 void handleCommand_HudSetParam(NetworkPacket* pkt);
211 void handleCommand_HudSetSky(NetworkPacket* pkt);
212 void handleCommand_HudSetSun(NetworkPacket* pkt);
213 void handleCommand_HudSetMoon(NetworkPacket* pkt);
214 void handleCommand_HudSetStars(NetworkPacket* pkt);
215 void handleCommand_CloudParams(NetworkPacket* pkt);
216 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
217 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
218 void handleCommand_EyeOffset(NetworkPacket* pkt);
219 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
220 void handleCommand_ModChannelMsg(NetworkPacket *pkt);
221 void handleCommand_ModChannelSignal(NetworkPacket *pkt);
222 void handleCommand_SrpBytesSandB(NetworkPacket *pkt);
223 void handleCommand_FormspecPrepend(NetworkPacket *pkt);
224 void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt);
225 void handleCommand_PlayerSpeed(NetworkPacket *pkt);
226 void handleCommand_MediaPush(NetworkPacket *pkt);
227 void handleCommand_MinimapModes(NetworkPacket *pkt);
229 void ProcessData(NetworkPacket *pkt);
231 void Send(NetworkPacket* pkt);
233 void interact(InteractAction action, const PointedThing &pointed);
235 void sendNodemetaFields(v3s16 p, const std::string &formname,
236 const StringMap &fields);
237 void sendInventoryFields(const std::string &formname,
238 const StringMap &fields);
239 void sendInventoryAction(InventoryAction *a);
240 void sendChatMessage(const std::wstring &message);
241 void clearOutChatQueue();
242 void sendChangePassword(const std::string &oldpassword,
243 const std::string &newpassword);
244 void sendDamage(u16 damage);
248 ClientEnvironment& getEnv() { return m_env; }
249 ITextureSource *tsrc() { return getTextureSource(); }
250 ISoundManager *sound() { return getSoundManager(); }
251 static const std::string &getBuiltinLuaPath();
252 static const std::string &getClientModsLuaPath();
254 const std::vector<ModSpec> &getMods() const override;
255 const ModSpec* getModSpec(const std::string &modname) const override;
257 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
258 void removeNode(v3s16 p);
260 // helpers to enforce CSM restrictions
261 MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
262 int CSMClampRadius(v3s16 pos, int radius);
263 v3s16 CSMClampPos(v3s16 pos);
265 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
267 void setPlayerControl(PlayerControl &control);
269 // Returns true if the inventory of the local player has been
270 // updated from the server. If it is true, it is set to false.
271 bool updateWieldedItem();
273 /* InventoryManager interface */
274 Inventory* getInventory(const InventoryLocation &loc) override;
275 void inventoryAction(InventoryAction *a) override;
277 // Send the item number 'item' as player item to the server
278 void setPlayerItem(u16 item);
280 const std::list<std::string> &getConnectedPlayerNames()
282 return m_env.getPlayerNames();
285 float getAnimationTime();
289 void setCrack(int level, v3s16 pos);
293 bool checkPrivilege(const std::string &priv) const
294 { return g_settings->getBool("priv_bypass") ? true : (m_privileges.count(priv) != 0); }
296 const std::unordered_set<std::string> &getPrivilegeList() const
297 { return m_privileges; }
299 bool getChatMessage(std::wstring &message);
300 void typeChatMessage(const std::wstring& message);
302 u64 getMapSeed(){ return m_map_seed; }
304 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
305 // Including blocks at appropriate edges
306 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
307 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
309 void updateAllMapBlocks();
311 void updateCameraOffset(v3s16 camera_offset)
312 { m_mesh_update_thread.m_camera_offset = camera_offset; }
314 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
315 // Get event from queue. If queue is empty, it triggers an assertion failure.
316 ClientEvent * getClientEvent();
318 bool accessDenied() const { return m_access_denied; }
320 bool reconnectRequested() const { return true || m_access_denied_reconnect; }
322 void setFatalError(const std::string &reason)
324 m_access_denied = true;
325 m_access_denied_reason = reason;
328 // Renaming accessDeniedReason to better name could be good as it's used to
329 // disconnect client when CSM failed.
330 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
332 const bool itemdefReceived() const
333 { return m_itemdef_received; }
334 const bool nodedefReceived() const
335 { return m_nodedef_received; }
336 const bool mediaReceived() const
337 { return !m_media_downloader; }
338 const bool activeObjectsReceived() const
339 { return m_activeobjects_received; }
341 u16 getProtoVersion()
342 { return m_proto_ver; }
344 void confirmRegistration();
345 bool m_is_registration_confirmation_state = false;
346 bool m_simple_singleplayer_mode;
348 float mediaReceiveProgress();
350 void afterContentReceived();
351 void showUpdateProgressTexture(void *args, u32 progress, u32 max_progress);
356 Minimap* getMinimap() { return m_minimap; }
357 void setCamera(Camera* camera) { m_camera = camera; }
359 Camera* getCamera () { return m_camera; }
360 scene::ISceneManager *getSceneManager();
362 bool shouldShowMinimap() const;
364 // IGameDef interface
365 IItemDefManager* getItemDefManager() override;
366 IWritableItemDefManager* getWritableItemDefManager() override;
367 const NodeDefManager* getNodeDefManager() override;
368 NodeDefManager* getWritableNodeDefManager() override;
369 ICraftDefManager* getCraftDefManager() override;
370 ITextureSource* getTextureSource();
371 virtual IWritableShaderSource* getShaderSource();
372 u16 allocateUnknownNodeId(const std::string &name) override;
373 virtual ISoundManager* getSoundManager();
374 MtEventManager* getEventManager();
375 virtual ParticleManager* getParticleManager();
376 bool checkLocalPrivilege(const std::string &priv){ return checkPrivilege(priv); }
377 virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
378 const std::string* getModFile(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 bool from_media_push = false);
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 modsLoaded() const { return m_mods_loaded; }
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 u64 getCSMRestrictionFlags() const
417 return m_csm_restriction_flags;
420 inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
422 //return m_csm_restriction_flags & flag;
426 bool joinModChannel(const std::string &channel) override;
427 bool leaveModChannel(const std::string &channel) override;
428 bool sendModChannelMessage(const std::string &channel,
429 const std::string &message) override;
430 ModChannel *getModChannel(const std::string &channel) override;
432 const std::string &getFormspecPrepend() const
434 return m_env.getLocalPlayer()->formspec_prepend;
437 void sendPlayerPos(v3f pos);
438 void sendPlayerPos();
439 MeshUpdateThread m_mesh_update_thread;
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 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;
484 RenderingEngine *m_rendering_engine;
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;
495 // Server serialization version
498 // Used version of the protocol with server
499 // Values smaller than 25 only mean they are smaller than 25,
500 // and aren't accurate. We simply just don't know, because
501 // the server didn't send the version back then.
502 // If 0, server init hasn't been received yet.
505 bool m_update_wielded_item = false;
506 Inventory *m_inventory_from_server = nullptr;
507 float m_inventory_from_server_age = 0.0f;
508 PacketCounter m_packetcounter;
509 // Block mesh animation parameters
510 float m_animation_time = 0.0f;
511 int m_crack_level = -1;
513 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
515 //u32 m_daynight_ratio;
516 std::queue<std::wstring> m_out_chat_queue;
517 u32 m_last_chat_message_sent;
518 float m_chat_message_allowance = 5.0f;
519 std::queue<ChatMessage *> m_chat_queue;
521 // The authentication methods we can use to enter sudo mode (=change password)
522 u32 m_sudo_auth_methods;
524 // The seed returned by the server in TOCLIENT_INIT is stored here
528 std::string m_playername;
529 std::string m_password;
530 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
531 std::string m_new_password;
532 // Usable by auth mechanisms.
533 AuthMechanism m_chosen_auth_mech;
534 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_activeobjects_received = false;
543 bool m_mods_loaded = false;
545 ClientMediaDownloader *m_media_downloader;
546 // Set of media filenames pushed by server at runtime
547 std::unordered_set<std::string> m_media_pushed_files;
549 // time_of_day speed approximation for old protocol
550 bool m_time_of_day_set = false;
551 float m_last_time_of_day_f = -1.0f;
552 float m_time_of_day_update_timer = 0.0f;
554 // An interval for generally sending object positions and stuff
555 float m_recommended_send_interval = 0.1f;
558 float m_removed_sounds_check_timer = 0.0f;
559 // Mapping from server sound ids to our sound ids
560 std::unordered_map<s32, int> m_sounds_server_to_client;
561 // And the other way!
562 std::unordered_map<int, s32> m_sounds_client_to_server;
563 // Relation of client id to object id
564 std::unordered_map<int, u16> m_sounds_to_objects;
567 std::unordered_set<std::string> m_privileges;
569 // Detached inventories
571 std::unordered_map<std::string, Inventory*> m_detached_inventories;
573 // Storage for mesh data for creating multiple instances of the same mesh
574 StringMap m_mesh_data;
577 LocalClientState m_state;
581 // Used for saving server map to disk client-side
582 MapDatabase *m_localdb = nullptr;
583 IntervalLimiter m_localdb_save_interval;
584 u16 m_cache_save_interval;
587 ClientScripting *m_script = nullptr;
588 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
589 float m_mod_storage_save_timer = 10.0f;
590 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;