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"
40 #include "gameparams.h"
42 #include "util/numeric.h"
44 #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
50 class RenderingEngine;
51 class IWritableTextureSource;
52 class IWritableShaderSource;
53 class IWritableItemDefManager;
56 //class IWritableCraftDefManager;
57 class ClientMediaDownloader;
58 class SingleMediaDownloader;
59 struct MapDrawControl;
65 struct MinimapMapblock;
72 enum LocalClientState {
85 PacketCounter() = default;
89 auto n = m_packets.find(command);
90 if (n == m_packets.end())
91 m_packets[command] = 1;
102 void print(std::ostream &o) const;
106 std::map<u16, u32> m_packets;
109 class ClientScripting;
112 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
116 NOTE: Nothing is thread-safe here.
120 const char *playername,
121 const std::string &password,
122 const std::string &address_name,
123 MapDrawControl &control,
124 IWritableTextureSource *tsrc,
125 IWritableShaderSource *shsrc,
126 IWritableItemDefManager *itemdef,
127 NodeDefManager *nodedef,
128 ISoundManager *sound,
129 MtEventManager *event,
130 RenderingEngine *rendering_engine,
133 ELoginRegister allow_login_or_register
137 DISABLE_CLASS_COPY(Client);
139 // Load local mods into memory
140 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
141 std::string mod_subpath);
142 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
144 scanModSubfolder(mod_name, mod_path, "");
148 request all threads managed by client to be stopped
156 The name of the local player should already be set when
157 calling this, as it is sent in the initialization.
159 void connect(Address address, bool is_local_server);
162 Stuff that references the environment is valid only as
163 long as this is not called. (eg. Players)
164 If this throws a PeerNotFoundException, the connection has
167 void step(float dtime);
173 void handleCommand(NetworkPacket* pkt);
175 void handleCommand_Null(NetworkPacket* pkt) {};
176 void handleCommand_Deprecated(NetworkPacket* pkt);
177 void handleCommand_Hello(NetworkPacket* pkt);
178 void handleCommand_AuthAccept(NetworkPacket* pkt);
179 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
180 void handleCommand_DenySudoMode(NetworkPacket* pkt);
181 void handleCommand_AccessDenied(NetworkPacket* pkt);
182 void handleCommand_RemoveNode(NetworkPacket* pkt);
183 void handleCommand_AddNode(NetworkPacket* pkt);
184 void handleCommand_NodemetaChanged(NetworkPacket *pkt);
185 void handleCommand_BlockData(NetworkPacket* pkt);
186 void handleCommand_Inventory(NetworkPacket* pkt);
187 void handleCommand_TimeOfDay(NetworkPacket* pkt);
188 void handleCommand_ChatMessage(NetworkPacket *pkt);
189 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
190 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
191 void handleCommand_Movement(NetworkPacket* pkt);
192 void handleCommand_Fov(NetworkPacket *pkt);
193 void handleCommand_HP(NetworkPacket* pkt);
194 void handleCommand_Breath(NetworkPacket* pkt);
195 void handleCommand_MovePlayer(NetworkPacket* pkt);
196 void handleCommand_DeathScreen(NetworkPacket* pkt);
197 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
198 void handleCommand_Media(NetworkPacket* pkt);
199 void handleCommand_NodeDef(NetworkPacket* pkt);
200 void handleCommand_ItemDef(NetworkPacket* pkt);
201 void handleCommand_PlaySound(NetworkPacket* pkt);
202 void handleCommand_StopSound(NetworkPacket* pkt);
203 void handleCommand_FadeSound(NetworkPacket *pkt);
204 void handleCommand_Privileges(NetworkPacket* pkt);
205 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
206 void handleCommand_DetachedInventory(NetworkPacket* pkt);
207 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
208 void handleCommand_SpawnParticle(NetworkPacket* pkt);
209 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
210 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
211 void handleCommand_HudAdd(NetworkPacket* pkt);
212 void handleCommand_HudRemove(NetworkPacket* pkt);
213 void handleCommand_HudChange(NetworkPacket* pkt);
214 void handleCommand_HudSetFlags(NetworkPacket* pkt);
215 void handleCommand_HudSetParam(NetworkPacket* pkt);
216 void handleCommand_HudSetSky(NetworkPacket* pkt);
217 void handleCommand_HudSetSun(NetworkPacket* pkt);
218 void handleCommand_HudSetMoon(NetworkPacket* pkt);
219 void handleCommand_HudSetStars(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);
231 void handleCommand_MediaPush(NetworkPacket *pkt);
232 void handleCommand_MinimapModes(NetworkPacket *pkt);
233 void handleCommand_SetLighting(NetworkPacket *pkt);
235 void ProcessData(NetworkPacket *pkt);
237 void Send(NetworkPacket* pkt);
239 void interact(InteractAction action, const PointedThing &pointed);
241 void sendNodemetaFields(v3s16 p, const std::string &formname,
242 const StringMap &fields);
243 void sendInventoryFields(const std::string &formname,
244 const StringMap &fields);
245 void sendInventoryAction(InventoryAction *a);
246 void sendChatMessage(const std::wstring &message);
247 void clearOutChatQueue();
248 void sendChangePassword(const std::string &oldpassword,
249 const std::string &newpassword);
250 void sendDamage(u16 damage);
253 void sendHaveMedia(const std::vector<u32> &tokens);
255 ClientEnvironment& getEnv() { return m_env; }
256 ITextureSource *tsrc() { return getTextureSource(); }
257 ISoundManager *sound() { return getSoundManager(); }
258 static const std::string &getBuiltinLuaPath();
259 static const std::string &getClientModsLuaPath();
261 const std::vector<ModSpec> &getMods() const override;
262 const ModSpec* getModSpec(const std::string &modname) const override;
264 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
265 void removeNode(v3s16 p);
267 // helpers to enforce CSM restrictions
268 MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
269 int CSMClampRadius(v3s16 pos, int radius);
270 v3s16 CSMClampPos(v3s16 pos);
272 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
274 void setPlayerControl(PlayerControl &control);
276 // Returns true if the inventory of the local player has been
277 // updated from the server. If it is true, it is set to false.
278 bool updateWieldedItem();
280 /* InventoryManager interface */
281 Inventory* getInventory(const InventoryLocation &loc) override;
282 void inventoryAction(InventoryAction *a) override;
284 // Send the item number 'item' as player item to the server
285 void setPlayerItem(u16 item);
287 const std::list<std::string> &getConnectedPlayerNames()
289 return m_env.getPlayerNames();
292 float getAnimationTime();
296 void setCrack(int level, v3s16 pos);
300 bool checkPrivilege(const std::string &priv) const
301 { return (m_privileges.count(priv) != 0); }
303 const std::unordered_set<std::string> &getPrivilegeList() const
304 { return m_privileges; }
306 bool getChatMessage(std::wstring &message);
307 void typeChatMessage(const std::wstring& message);
309 u64 getMapSeed(){ return m_map_seed; }
311 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
312 // Including blocks at appropriate edges
313 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
314 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
316 void updateCameraOffset(v3s16 camera_offset)
317 { m_mesh_update_manager.m_camera_offset = camera_offset; }
319 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
320 // Get event from queue. If queue is empty, it triggers an assertion failure.
321 ClientEvent * getClientEvent();
323 bool accessDenied() const { return m_access_denied; }
325 bool reconnectRequested() const { return m_access_denied_reconnect; }
327 void setFatalError(const std::string &reason)
329 m_access_denied = true;
330 m_access_denied_reason = reason;
332 inline void setFatalError(const LuaError &e)
334 setFatalError(std::string("Lua: ") + e.what());
337 // Renaming accessDeniedReason to better name could be good as it's used to
338 // disconnect client when CSM failed.
339 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
341 bool itemdefReceived() const
342 { return m_itemdef_received; }
343 bool nodedefReceived() const
344 { return m_nodedef_received; }
345 bool mediaReceived() const
346 { return !m_media_downloader; }
347 bool activeObjectsReceived() const
348 { return m_activeobjects_received; }
350 u16 getProtoVersion()
351 { return m_proto_ver; }
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 const NodeDefManager* getNodeDefManager() override;
374 ICraftDefManager* getCraftDefManager() override;
375 ITextureSource* getTextureSource();
376 virtual IWritableShaderSource* getShaderSource();
377 u16 allocateUnknownNodeId(const std::string &name) override;
378 virtual ISoundManager* getSoundManager();
379 MtEventManager* getEventManager();
380 virtual ParticleManager* getParticleManager();
381 bool checkLocalPrivilege(const std::string &priv)
382 { return checkPrivilege(priv); }
383 virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
384 const std::string* getModFile(std::string filename);
385 ModStorageDatabase *getModStorageDatabase() override { return m_mod_storage_database; }
387 // Migrates away old files-based mod storage if necessary
388 void migrateModStorage();
390 // The following set of functions is used by ClientMediaDownloader
391 // Insert a media file appropriately into the appropriate manager
392 bool loadMedia(const std::string &data, const std::string &filename,
393 bool from_media_push = false);
395 // Send a request for conventional media transfer
396 void request_media(const std::vector<std::string> &file_requests);
398 LocalClientState getState() { return m_state; }
400 void makeScreenshot();
402 inline void pushToChatQueue(ChatMessage *cec)
404 m_chat_queue.push(cec);
407 ClientScripting *getScript() { return m_script; }
408 bool modsLoaded() const { return m_mods_loaded; }
410 void pushToEventQueue(ClientEvent *event);
412 void showMinimap(bool show = true);
414 const Address getServerAddress();
416 const std::string &getAddressName() const
418 return m_address_name;
421 inline u64 getCSMRestrictionFlags() const
423 return m_csm_restriction_flags;
426 inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
428 return m_csm_restriction_flags & flag;
431 bool joinModChannel(const std::string &channel) override;
432 bool leaveModChannel(const std::string &channel) override;
433 bool sendModChannelMessage(const std::string &channel,
434 const std::string &message) override;
435 ModChannel *getModChannel(const std::string &channel) override;
437 const std::string &getFormspecPrepend() const
439 return m_env.getLocalPlayer()->formspec_prepend;
441 inline MeshGrid getMeshGrid()
449 // Virtual methods from con::PeerHandler
450 void peerAdded(con::Peer *peer) override;
451 void deletingPeer(con::Peer *peer, bool timeout) override;
453 void initLocalMapSaving(const Address &address,
454 const std::string &hostname,
455 bool is_local_server);
459 void sendPlayerPos();
461 void deleteAuthData();
462 // helper method shared with clientpackethandler
463 static AuthMechanism choseAuthMech(const u32 mechs);
465 void sendInit(const std::string &playerName);
466 void startAuth(AuthMechanism chosen_auth_mechanism);
467 void sendDeletedBlocks(std::vector<v3s16> &blocks);
468 void sendGotBlocks(const std::vector<v3s16> &blocks);
469 void sendRemovedSounds(std::vector<s32> &soundList);
472 inline std::string getPlayerName()
473 { return m_env.getLocalPlayer()->getName(); }
475 bool canSendChatMessage() const;
477 float m_packetcounter_timer = 0.0f;
478 float m_connection_reinit_timer = 0.1f;
479 float m_avg_rtt_timer = 0.0f;
480 float m_playerpos_send_timer = 0.0f;
481 IntervalLimiter m_map_timer_and_unload_interval;
483 IWritableTextureSource *m_tsrc;
484 IWritableShaderSource *m_shsrc;
485 IWritableItemDefManager *m_itemdef;
486 NodeDefManager *m_nodedef;
487 ISoundManager *m_sound;
488 MtEventManager *m_event;
489 RenderingEngine *m_rendering_engine;
492 MeshUpdateManager m_mesh_update_manager;
493 ClientEnvironment m_env;
494 ParticleManager m_particle_manager;
495 std::unique_ptr<con::Connection> m_con;
496 std::string m_address_name;
497 ELoginRegister m_allow_login_or_register = ELoginRegister::Any;
498 Camera *m_camera = nullptr;
499 Minimap *m_minimap = nullptr;
500 bool m_minimap_disabled_by_server = false;
502 // Server serialization version
505 // Used version of the protocol with server
506 // Values smaller than 25 only mean they are smaller than 25,
507 // and aren't accurate. We simply just don't know, because
508 // the server didn't send the version back then.
509 // If 0, server init hasn't been received yet.
512 bool m_update_wielded_item = false;
513 Inventory *m_inventory_from_server = nullptr;
514 float m_inventory_from_server_age = 0.0f;
515 PacketCounter m_packetcounter;
516 // Block mesh animation parameters
517 float m_animation_time = 0.0f;
518 int m_crack_level = -1;
520 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
522 //u32 m_daynight_ratio;
523 std::queue<std::wstring> m_out_chat_queue;
524 u32 m_last_chat_message_sent;
525 float m_chat_message_allowance = 5.0f;
526 std::queue<ChatMessage *> m_chat_queue;
528 // The authentication methods we can use to enter sudo mode (=change password)
529 u32 m_sudo_auth_methods;
531 // The seed returned by the server in TOCLIENT_INIT is stored here
535 std::string m_playername;
536 std::string m_password;
537 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
538 std::string m_new_password;
539 // Usable by auth mechanisms.
540 AuthMechanism m_chosen_auth_mech;
541 void *m_auth_data = nullptr;
543 bool m_access_denied = false;
544 bool m_access_denied_reconnect = false;
545 std::string m_access_denied_reason = "";
546 std::queue<ClientEvent *> m_client_event_queue;
547 bool m_itemdef_received = false;
548 bool m_nodedef_received = false;
549 bool m_activeobjects_received = false;
550 bool m_mods_loaded = false;
552 std::vector<std::string> m_remote_media_servers;
553 // Media downloader, only exists during init
554 ClientMediaDownloader *m_media_downloader;
555 // Pending downloads of dynamic media (key: token)
556 std::vector<std::pair<u32, std::shared_ptr<SingleMediaDownloader>>> m_pending_media_downloads;
558 // time_of_day speed approximation for old protocol
559 bool m_time_of_day_set = false;
560 float m_last_time_of_day_f = -1.0f;
561 float m_time_of_day_update_timer = 0.0f;
563 // An interval for generally sending object positions and stuff
564 float m_recommended_send_interval = 0.1f;
567 float m_removed_sounds_check_timer = 0.0f;
568 // Mapping from server sound ids to our sound ids
569 std::unordered_map<s32, int> m_sounds_server_to_client;
570 // And the other way!
571 std::unordered_map<int, s32> m_sounds_client_to_server;
572 // Relation of client id to object id
573 std::unordered_map<int, u16> m_sounds_to_objects;
576 std::unordered_set<std::string> m_privileges;
578 // Detached inventories
580 std::unordered_map<std::string, Inventory*> m_detached_inventories;
582 // Storage for mesh data for creating multiple instances of the same mesh
583 StringMap m_mesh_data;
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;
596 ClientScripting *m_script = nullptr;
597 ModStorageDatabase *m_mod_storage_database = nullptr;
598 float m_mod_storage_save_timer = 10.0f;
599 std::vector<ModSpec> m_mods;
602 bool m_shutdown = false;
604 // CSM restrictions byteflag
605 u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
606 u32 m_csm_restriction_noderange = 8;
608 std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
610 // The number of blocks the client will combine for mesh generation.
611 MeshGrid m_mesh_grid;