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 class SingleMediaDownloader;
56 struct MapDrawControl;
62 struct MinimapMapblock;
69 enum LocalClientState {
82 PacketCounter() = default;
86 auto n = m_packets.find(command);
87 if (n == m_packets.end())
88 m_packets[command] = 1;
99 void print(std::ostream &o) const;
103 std::map<u16, u32> m_packets;
106 class ClientScripting;
109 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
113 NOTE: Nothing is thread-safe here.
117 const char *playername,
118 const std::string &password,
119 const std::string &address_name,
120 MapDrawControl &control,
121 IWritableTextureSource *tsrc,
122 IWritableShaderSource *shsrc,
123 IWritableItemDefManager *itemdef,
124 NodeDefManager *nodedef,
125 ISoundManager *sound,
126 MtEventManager *event,
127 RenderingEngine *rendering_engine,
133 DISABLE_CLASS_COPY(Client);
135 // Load local mods into memory
136 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
137 std::string mod_subpath);
138 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
140 scanModSubfolder(mod_name, mod_path, "");
144 request all threads managed by client to be stopped
152 The name of the local player should already be set when
153 calling this, as it is sent in the initialization.
155 void connect(Address address, bool is_local_server);
158 Stuff that references the environment is valid only as
159 long as this is not called. (eg. Players)
160 If this throws a PeerNotFoundException, the connection has
163 void step(float dtime);
169 void handleCommand(NetworkPacket* pkt);
171 void handleCommand_Null(NetworkPacket* pkt) {};
172 void handleCommand_Deprecated(NetworkPacket* pkt);
173 void handleCommand_Hello(NetworkPacket* pkt);
174 void handleCommand_AuthAccept(NetworkPacket* pkt);
175 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
176 void handleCommand_DenySudoMode(NetworkPacket* pkt);
177 void handleCommand_AccessDenied(NetworkPacket* pkt);
178 void handleCommand_RemoveNode(NetworkPacket* pkt);
179 void handleCommand_AddNode(NetworkPacket* pkt);
180 void handleCommand_NodemetaChanged(NetworkPacket *pkt);
181 void handleCommand_BlockData(NetworkPacket* pkt);
182 void handleCommand_Inventory(NetworkPacket* pkt);
183 void handleCommand_TimeOfDay(NetworkPacket* pkt);
184 void handleCommand_ChatMessage(NetworkPacket *pkt);
185 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
186 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
187 void handleCommand_Movement(NetworkPacket* pkt);
188 void handleCommand_Fov(NetworkPacket *pkt);
189 void handleCommand_HP(NetworkPacket* pkt);
190 void handleCommand_Breath(NetworkPacket* pkt);
191 void handleCommand_MovePlayer(NetworkPacket* pkt);
192 void handleCommand_DeathScreen(NetworkPacket* pkt);
193 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
194 void handleCommand_Media(NetworkPacket* pkt);
195 void handleCommand_NodeDef(NetworkPacket* pkt);
196 void handleCommand_ItemDef(NetworkPacket* pkt);
197 void handleCommand_PlaySound(NetworkPacket* pkt);
198 void handleCommand_StopSound(NetworkPacket* pkt);
199 void handleCommand_FadeSound(NetworkPacket *pkt);
200 void handleCommand_Privileges(NetworkPacket* pkt);
201 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
202 void handleCommand_DetachedInventory(NetworkPacket* pkt);
203 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
204 void handleCommand_SpawnParticle(NetworkPacket* pkt);
205 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
206 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
207 void handleCommand_HudAdd(NetworkPacket* pkt);
208 void handleCommand_HudRemove(NetworkPacket* pkt);
209 void handleCommand_HudChange(NetworkPacket* pkt);
210 void handleCommand_HudSetFlags(NetworkPacket* pkt);
211 void handleCommand_HudSetParam(NetworkPacket* pkt);
212 void handleCommand_HudSetSky(NetworkPacket* pkt);
213 void handleCommand_HudSetSun(NetworkPacket* pkt);
214 void handleCommand_HudSetMoon(NetworkPacket* pkt);
215 void handleCommand_HudSetStars(NetworkPacket* pkt);
216 void handleCommand_CloudParams(NetworkPacket* pkt);
217 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
218 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
219 void handleCommand_EyeOffset(NetworkPacket* pkt);
220 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
221 void handleCommand_ModChannelMsg(NetworkPacket *pkt);
222 void handleCommand_ModChannelSignal(NetworkPacket *pkt);
223 void handleCommand_SrpBytesSandB(NetworkPacket *pkt);
224 void handleCommand_FormspecPrepend(NetworkPacket *pkt);
225 void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt);
226 void handleCommand_PlayerSpeed(NetworkPacket *pkt);
227 void handleCommand_MediaPush(NetworkPacket *pkt);
228 void handleCommand_MinimapModes(NetworkPacket *pkt);
229 void handleCommand_SetLighting(NetworkPacket *pkt);
231 void ProcessData(NetworkPacket *pkt);
233 void Send(NetworkPacket* pkt);
235 void interact(InteractAction 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(u16 damage);
249 void sendHaveMedia(const std::vector<u32> &tokens);
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);
263 // helpers to enforce CSM restrictions
264 MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
265 int CSMClampRadius(v3s16 pos, int radius);
266 v3s16 CSMClampPos(v3s16 pos);
268 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
270 void setPlayerControl(PlayerControl &control);
272 // Returns true if the inventory of the local player has been
273 // updated from the server. If it is true, it is set to false.
274 bool updateWieldedItem();
276 /* InventoryManager interface */
277 Inventory* getInventory(const InventoryLocation &loc) override;
278 void inventoryAction(InventoryAction *a) override;
280 // Send the item number 'item' as player item to the server
281 void setPlayerItem(u16 item);
283 const std::list<std::string> &getConnectedPlayerNames()
285 return m_env.getPlayerNames();
288 float getAnimationTime();
292 void setCrack(int level, v3s16 pos);
296 bool checkPrivilege(const std::string &priv) const
297 { return g_settings->getBool("priv_bypass") ? true : (m_privileges.count(priv) != 0); }
299 const std::unordered_set<std::string> &getPrivilegeList() const
300 { return m_privileges; }
302 bool getChatMessage(std::wstring &message);
303 void typeChatMessage(const std::wstring& message);
305 u64 getMapSeed(){ return m_map_seed; }
307 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
308 // Including blocks at appropriate edges
309 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
310 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
312 void updateAllMapBlocks();
314 void updateCameraOffset(v3s16 camera_offset)
315 { m_mesh_update_thread.m_camera_offset = camera_offset; }
317 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
318 // Get event from queue. If queue is empty, it triggers an assertion failure.
319 ClientEvent * getClientEvent();
321 bool accessDenied() const { return m_access_denied; }
323 bool reconnectRequested() const { return true || m_access_denied_reconnect; }
325 void setFatalError(const std::string &reason)
327 m_access_denied = true;
328 m_access_denied_reason = reason;
330 inline void setFatalError(const LuaError &e)
332 setFatalError(std::string("Lua: ") + e.what());
335 // Renaming accessDeniedReason to better name could be good as it's used to
336 // disconnect client when CSM failed.
337 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
339 bool itemdefReceived() const
340 { return m_itemdef_received; }
341 bool nodedefReceived() const
342 { return m_nodedef_received; }
343 bool mediaReceived() const
344 { return !m_media_downloader; }
345 bool activeObjectsReceived() const
346 { return m_activeobjects_received; }
348 u16 getProtoVersion()
349 { return m_proto_ver; }
351 void confirmRegistration();
352 bool m_is_registration_confirmation_state = false;
353 bool m_simple_singleplayer_mode;
355 float mediaReceiveProgress();
357 void afterContentReceived();
358 void showUpdateProgressTexture(void *args, u32 progress, u32 max_progress);
363 Minimap* getMinimap() { return m_minimap; }
364 void setCamera(Camera* camera) { m_camera = camera; }
366 Camera* getCamera () { return m_camera; }
367 scene::ISceneManager *getSceneManager();
369 bool shouldShowMinimap() const;
371 // IGameDef interface
372 IItemDefManager* getItemDefManager() override;
373 IWritableItemDefManager* getWritableItemDefManager() override;
374 const NodeDefManager* getNodeDefManager() override;
375 NodeDefManager* getWritableNodeDefManager() override;
376 ICraftDefManager* getCraftDefManager() override;
377 ITextureSource* getTextureSource();
378 virtual IWritableShaderSource* getShaderSource();
379 u16 allocateUnknownNodeId(const std::string &name) override;
380 virtual ISoundManager* getSoundManager();
381 MtEventManager* getEventManager();
382 virtual ParticleManager* getParticleManager();
383 bool checkLocalPrivilege(const std::string &priv){ return checkPrivilege(priv); }
384 virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
385 const std::string* getModFile(std::string filename);
386 ModMetadataDatabase *getModStorageDatabase() override { return m_mod_storage_database; }
388 bool registerModStorage(ModMetadata *meta) override;
389 void unregisterModStorage(const std::string &name) override;
391 // Migrates away old files-based mod storage if necessary
392 void migrateModStorage();
394 // The following set of functions is used by ClientMediaDownloader
395 // Insert a media file appropriately into the appropriate manager
396 bool loadMedia(const std::string &data, const std::string &filename,
397 bool from_media_push = false);
399 // Send a request for conventional media transfer
400 void request_media(const std::vector<std::string> &file_requests);
402 LocalClientState getState() { return m_state; }
404 void makeScreenshot();
406 inline void pushToChatQueue(ChatMessage *cec)
408 m_chat_queue.push(cec);
411 ClientScripting *getScript() { return m_script; }
412 bool modsLoaded() const { return m_mods_loaded; }
414 void pushToEventQueue(ClientEvent *event);
416 void showMinimap(bool show = true);
418 const Address getServerAddress();
420 const std::string &getAddressName() const
422 return m_address_name;
425 inline u64 getCSMRestrictionFlags() const
427 return m_csm_restriction_flags;
430 inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
432 //return m_csm_restriction_flags & flag;
436 bool joinModChannel(const std::string &channel) override;
437 bool leaveModChannel(const std::string &channel) override;
438 bool sendModChannelMessage(const std::string &channel,
439 const std::string &message) override;
440 ModChannel *getModChannel(const std::string &channel) override;
442 const std::string &getFormspecPrepend() const
444 return m_env.getLocalPlayer()->formspec_prepend;
447 void sendPlayerPos(v3f pos);
448 void sendPlayerPos();
449 MeshUpdateThread m_mesh_update_thread;
454 // Virtual methods from con::PeerHandler
455 void peerAdded(con::Peer *peer) override;
456 void deletingPeer(con::Peer *peer, bool timeout) override;
458 void initLocalMapSaving(const Address &address,
459 const std::string &hostname,
460 bool is_local_server);
465 void deleteAuthData();
466 // helper method shared with clientpackethandler
467 static AuthMechanism choseAuthMech(const u32 mechs);
469 void sendInit(const std::string &playerName);
470 void promptConfirmRegistration(AuthMechanism chosen_auth_mechanism);
471 void startAuth(AuthMechanism chosen_auth_mechanism);
472 void sendDeletedBlocks(std::vector<v3s16> &blocks);
473 void sendGotBlocks(const std::vector<v3s16> &blocks);
474 void sendRemovedSounds(std::vector<s32> &soundList);
477 inline std::string getPlayerName()
478 { return m_env.getLocalPlayer()->getName(); }
480 bool canSendChatMessage() const;
482 float m_packetcounter_timer = 0.0f;
483 float m_connection_reinit_timer = 0.1f;
484 float m_avg_rtt_timer = 0.0f;
485 float m_playerpos_send_timer = 0.0f;
486 IntervalLimiter m_map_timer_and_unload_interval;
488 IWritableTextureSource *m_tsrc;
489 IWritableShaderSource *m_shsrc;
490 IWritableItemDefManager *m_itemdef;
491 NodeDefManager *m_nodedef;
492 ISoundManager *m_sound;
493 MtEventManager *m_event;
494 RenderingEngine *m_rendering_engine;
497 ClientEnvironment m_env;
498 ParticleManager m_particle_manager;
499 std::unique_ptr<con::Connection> m_con;
500 std::string m_address_name;
501 Camera *m_camera = nullptr;
502 Minimap *m_minimap = nullptr;
503 bool m_minimap_disabled_by_server = false;
505 // Server serialization version
508 // Used version of the protocol with server
509 // Values smaller than 25 only mean they are smaller than 25,
510 // and aren't accurate. We simply just don't know, because
511 // the server didn't send the version back then.
512 // If 0, server init hasn't been received yet.
515 bool m_update_wielded_item = false;
516 Inventory *m_inventory_from_server = nullptr;
517 float m_inventory_from_server_age = 0.0f;
518 PacketCounter m_packetcounter;
519 // Block mesh animation parameters
520 float m_animation_time = 0.0f;
521 int m_crack_level = -1;
523 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
525 //u32 m_daynight_ratio;
526 std::queue<std::wstring> m_out_chat_queue;
527 u32 m_last_chat_message_sent;
528 float m_chat_message_allowance = 5.0f;
529 std::queue<ChatMessage *> m_chat_queue;
531 // The authentication methods we can use to enter sudo mode (=change password)
532 u32 m_sudo_auth_methods;
534 // The seed returned by the server in TOCLIENT_INIT is stored here
538 std::string m_playername;
539 std::string m_password;
540 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
541 std::string m_new_password;
542 // Usable by auth mechanisms.
543 AuthMechanism m_chosen_auth_mech;
544 void *m_auth_data = nullptr;
546 bool m_access_denied = false;
547 bool m_access_denied_reconnect = false;
548 std::string m_access_denied_reason = "";
549 std::queue<ClientEvent *> m_client_event_queue;
550 bool m_itemdef_received = false;
551 bool m_nodedef_received = false;
552 bool m_activeobjects_received = false;
553 bool m_mods_loaded = false;
555 std::vector<std::string> m_remote_media_servers;
556 // Media downloader, only exists during init
557 ClientMediaDownloader *m_media_downloader;
558 // Set of media filenames pushed by server at runtime
559 std::unordered_set<std::string> m_media_pushed_files;
560 // Pending downloads of dynamic media (key: token)
561 std::vector<std::pair<u32, std::shared_ptr<SingleMediaDownloader>>> m_pending_media_downloads;
563 // time_of_day speed approximation for old protocol
564 bool m_time_of_day_set = false;
565 float m_last_time_of_day_f = -1.0f;
566 float m_time_of_day_update_timer = 0.0f;
568 // An interval for generally sending object positions and stuff
569 float m_recommended_send_interval = 0.1f;
572 float m_removed_sounds_check_timer = 0.0f;
573 // Mapping from server sound ids to our sound ids
574 std::unordered_map<s32, int> m_sounds_server_to_client;
575 // And the other way!
576 std::unordered_map<int, s32> m_sounds_client_to_server;
577 // Relation of client id to object id
578 std::unordered_map<int, u16> m_sounds_to_objects;
581 std::unordered_set<std::string> m_privileges;
583 // Detached inventories
585 std::unordered_map<std::string, Inventory*> m_detached_inventories;
587 // Storage for mesh data for creating multiple instances of the same mesh
588 StringMap m_mesh_data;
591 LocalClientState m_state;
595 // Used for saving server map to disk client-side
596 MapDatabase *m_localdb = nullptr;
597 IntervalLimiter m_localdb_save_interval;
598 u16 m_cache_save_interval;
601 ClientScripting *m_script = nullptr;
602 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
603 ModMetadataDatabase *m_mod_storage_database = nullptr;
604 float m_mod_storage_save_timer = 10.0f;
605 std::vector<ModSpec> m_mods;
608 bool m_shutdown = false;
610 // CSM restrictions byteflag
611 u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
612 u32 m_csm_restriction_noderange = 8;
614 std::unique_ptr<ModChannelMgr> m_modchannel_mgr;