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"
41 #include "clientdynamicinfo.h"
43 #include "util/numeric.h"
45 #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
51 class RenderingEngine;
52 class IWritableTextureSource;
53 class IWritableShaderSource;
54 class IWritableItemDefManager;
57 //class IWritableCraftDefManager;
58 class ClientMediaDownloader;
59 class SingleMediaDownloader;
60 struct MapDrawControl;
66 struct MinimapMapblock;
73 enum LocalClientState {
86 PacketCounter() = default;
90 auto n = m_packets.find(command);
91 if (n == m_packets.end())
92 m_packets[command] = 1;
103 void print(std::ostream &o) const;
107 std::map<u16, u32> m_packets;
110 class ClientScripting;
113 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
117 NOTE: Nothing is thread-safe here.
121 const char *playername,
122 const std::string &password,
123 const std::string &address_name,
124 MapDrawControl &control,
125 IWritableTextureSource *tsrc,
126 IWritableShaderSource *shsrc,
127 IWritableItemDefManager *itemdef,
128 NodeDefManager *nodedef,
129 ISoundManager *sound,
130 MtEventManager *event,
131 RenderingEngine *rendering_engine,
134 ELoginRegister allow_login_or_register
138 DISABLE_CLASS_COPY(Client);
140 // Load local mods into memory
141 void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
142 std::string mod_subpath);
143 inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
145 scanModSubfolder(mod_name, mod_path, "");
149 request all threads managed by client to be stopped
157 The name of the local player should already be set when
158 calling this, as it is sent in the initialization.
160 void connect(Address address, bool is_local_server);
163 Stuff that references the environment is valid only as
164 long as this is not called. (eg. Players)
165 If this throws a PeerNotFoundException, the connection has
168 void step(float dtime);
174 void handleCommand(NetworkPacket* pkt);
176 void handleCommand_Null(NetworkPacket* pkt) {};
177 void handleCommand_Deprecated(NetworkPacket* pkt);
178 void handleCommand_Hello(NetworkPacket* pkt);
179 void handleCommand_AuthAccept(NetworkPacket* pkt);
180 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
181 void handleCommand_DenySudoMode(NetworkPacket* pkt);
182 void handleCommand_AccessDenied(NetworkPacket* pkt);
183 void handleCommand_RemoveNode(NetworkPacket* pkt);
184 void handleCommand_AddNode(NetworkPacket* pkt);
185 void handleCommand_NodemetaChanged(NetworkPacket *pkt);
186 void handleCommand_BlockData(NetworkPacket* pkt);
187 void handleCommand_Inventory(NetworkPacket* pkt);
188 void handleCommand_TimeOfDay(NetworkPacket* pkt);
189 void handleCommand_ChatMessage(NetworkPacket *pkt);
190 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
191 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
192 void handleCommand_Movement(NetworkPacket* pkt);
193 void handleCommand_Fov(NetworkPacket *pkt);
194 void handleCommand_HP(NetworkPacket* pkt);
195 void handleCommand_Breath(NetworkPacket* pkt);
196 void handleCommand_MovePlayer(NetworkPacket* pkt);
197 void handleCommand_DeathScreen(NetworkPacket* pkt);
198 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
199 void handleCommand_Media(NetworkPacket* pkt);
200 void handleCommand_NodeDef(NetworkPacket* pkt);
201 void handleCommand_ItemDef(NetworkPacket* pkt);
202 void handleCommand_PlaySound(NetworkPacket* pkt);
203 void handleCommand_StopSound(NetworkPacket* pkt);
204 void handleCommand_FadeSound(NetworkPacket *pkt);
205 void handleCommand_Privileges(NetworkPacket* pkt);
206 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
207 void handleCommand_DetachedInventory(NetworkPacket* pkt);
208 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
209 void handleCommand_SpawnParticle(NetworkPacket* pkt);
210 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
211 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
212 void handleCommand_HudAdd(NetworkPacket* pkt);
213 void handleCommand_HudRemove(NetworkPacket* pkt);
214 void handleCommand_HudChange(NetworkPacket* pkt);
215 void handleCommand_HudSetFlags(NetworkPacket* pkt);
216 void handleCommand_HudSetParam(NetworkPacket* pkt);
217 void handleCommand_HudSetSky(NetworkPacket* pkt);
218 void handleCommand_HudSetSun(NetworkPacket* pkt);
219 void handleCommand_HudSetMoon(NetworkPacket* pkt);
220 void handleCommand_HudSetStars(NetworkPacket* pkt);
221 void handleCommand_CloudParams(NetworkPacket* pkt);
222 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
223 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
224 void handleCommand_EyeOffset(NetworkPacket* pkt);
225 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
226 void handleCommand_ModChannelMsg(NetworkPacket *pkt);
227 void handleCommand_ModChannelSignal(NetworkPacket *pkt);
228 void handleCommand_SrpBytesSandB(NetworkPacket *pkt);
229 void handleCommand_FormspecPrepend(NetworkPacket *pkt);
230 void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt);
231 void handleCommand_PlayerSpeed(NetworkPacket *pkt);
232 void handleCommand_MediaPush(NetworkPacket *pkt);
233 void handleCommand_MinimapModes(NetworkPacket *pkt);
234 void handleCommand_SetLighting(NetworkPacket *pkt);
236 void ProcessData(NetworkPacket *pkt);
238 void Send(NetworkPacket* pkt);
240 void interact(InteractAction action, const PointedThing &pointed);
242 void sendNodemetaFields(v3s16 p, const std::string &formname,
243 const StringMap &fields);
244 void sendInventoryFields(const std::string &formname,
245 const StringMap &fields);
246 void sendInventoryAction(InventoryAction *a);
247 void sendChatMessage(const std::wstring &message);
248 void clearOutChatQueue();
249 void sendChangePassword(const std::string &oldpassword,
250 const std::string &newpassword);
251 void sendDamage(u16 damage);
254 void sendHaveMedia(const std::vector<u32> &tokens);
255 void sendUpdateClientInfo(const ClientDynamicInfo &info);
257 ClientEnvironment& getEnv() { return m_env; }
258 ITextureSource *tsrc() { return getTextureSource(); }
259 ISoundManager *sound() { return getSoundManager(); }
260 static const std::string &getBuiltinLuaPath();
261 static const std::string &getClientModsLuaPath();
263 const std::vector<ModSpec> &getMods() const override;
264 const ModSpec* getModSpec(const std::string &modname) const override;
266 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
267 void removeNode(v3s16 p);
269 // helpers to enforce CSM restrictions
270 MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
271 int CSMClampRadius(v3s16 pos, int radius);
272 v3s16 CSMClampPos(v3s16 pos);
274 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
276 void setPlayerControl(PlayerControl &control);
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 updateWieldedItem();
282 /* InventoryManager interface */
283 Inventory* getInventory(const InventoryLocation &loc) override;
284 void inventoryAction(InventoryAction *a) override;
286 // Send the item number 'item' as player item to the server
287 void setPlayerItem(u16 item);
289 const std::list<std::string> &getConnectedPlayerNames()
291 return m_env.getPlayerNames();
294 float getAnimationTime();
298 void setCrack(int level, v3s16 pos);
302 bool checkPrivilege(const std::string &priv) const
303 { return (m_privileges.count(priv) != 0); }
305 const std::unordered_set<std::string> &getPrivilegeList() const
306 { return m_privileges; }
308 bool getChatMessage(std::wstring &message);
309 void typeChatMessage(const std::wstring& message);
311 u64 getMapSeed(){ return m_map_seed; }
313 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
314 // Including blocks at appropriate edges
315 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
316 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
318 void updateCameraOffset(v3s16 camera_offset)
319 { m_mesh_update_manager.m_camera_offset = camera_offset; }
321 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
322 // Get event from queue. If queue is empty, it triggers an assertion failure.
323 ClientEvent * getClientEvent();
325 bool accessDenied() const { return m_access_denied; }
327 bool reconnectRequested() const { return m_access_denied_reconnect; }
329 void setFatalError(const std::string &reason)
331 m_access_denied = true;
332 m_access_denied_reason = reason;
334 inline void setFatalError(const LuaError &e)
336 setFatalError(std::string("Lua: ") + e.what());
339 // Renaming accessDeniedReason to better name could be good as it's used to
340 // disconnect client when CSM failed.
341 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
343 bool itemdefReceived() const
344 { return m_itemdef_received; }
345 bool nodedefReceived() const
346 { return m_nodedef_received; }
347 bool mediaReceived() const
348 { return !m_media_downloader; }
349 bool activeObjectsReceived() const
350 { return m_activeobjects_received; }
352 u16 getProtoVersion()
353 { return m_proto_ver; }
355 bool m_simple_singleplayer_mode;
357 float mediaReceiveProgress();
359 void afterContentReceived();
360 void showUpdateProgressTexture(void *args, u32 progress, u32 max_progress);
365 Minimap* getMinimap() { return m_minimap; }
366 void setCamera(Camera* camera) { m_camera = camera; }
368 Camera* getCamera () { return m_camera; }
369 scene::ISceneManager *getSceneManager();
371 bool shouldShowMinimap() const;
373 // IGameDef interface
374 IItemDefManager* getItemDefManager() override;
375 const NodeDefManager* getNodeDefManager() 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)
384 { return checkPrivilege(priv); }
385 virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
386 const std::string* getModFile(std::string filename);
387 ModStorageDatabase *getModStorageDatabase() override { return m_mod_storage_database; }
389 // Migrates away old files-based mod storage if necessary
390 void migrateModStorage();
392 // The following set of functions is used by ClientMediaDownloader
393 // Insert a media file appropriately into the appropriate manager
394 bool loadMedia(const std::string &data, const std::string &filename,
395 bool from_media_push = false);
397 // Send a request for conventional media transfer
398 void request_media(const std::vector<std::string> &file_requests);
400 LocalClientState getState() { return m_state; }
402 void makeScreenshot();
404 inline void pushToChatQueue(ChatMessage *cec)
406 m_chat_queue.push(cec);
409 ClientScripting *getScript() { return m_script; }
410 bool modsLoaded() const { return m_mods_loaded; }
412 void pushToEventQueue(ClientEvent *event);
414 void showMinimap(bool show = true);
416 const Address getServerAddress();
418 const std::string &getAddressName() const
420 return m_address_name;
423 inline u64 getCSMRestrictionFlags() const
425 return m_csm_restriction_flags;
428 inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
430 return m_csm_restriction_flags & flag;
433 bool joinModChannel(const std::string &channel) override;
434 bool leaveModChannel(const std::string &channel) override;
435 bool sendModChannelMessage(const std::string &channel,
436 const std::string &message) override;
437 ModChannel *getModChannel(const std::string &channel) override;
439 const std::string &getFormspecPrepend() const
441 return m_env.getLocalPlayer()->formspec_prepend;
443 inline MeshGrid getMeshGrid()
451 // Virtual methods from con::PeerHandler
452 void peerAdded(con::Peer *peer) override;
453 void deletingPeer(con::Peer *peer, bool timeout) override;
455 void initLocalMapSaving(const Address &address,
456 const std::string &hostname,
457 bool is_local_server);
461 void sendPlayerPos();
463 void deleteAuthData();
464 // helper method shared with clientpackethandler
465 static AuthMechanism choseAuthMech(const u32 mechs);
467 void sendInit(const std::string &playerName);
468 void startAuth(AuthMechanism chosen_auth_mechanism);
469 void sendDeletedBlocks(std::vector<v3s16> &blocks);
470 void sendGotBlocks(const std::vector<v3s16> &blocks);
471 void sendRemovedSounds(std::vector<s32> &soundList);
474 inline std::string getPlayerName()
475 { return m_env.getLocalPlayer()->getName(); }
477 bool canSendChatMessage() const;
479 float m_packetcounter_timer = 0.0f;
480 float m_connection_reinit_timer = 0.1f;
481 float m_avg_rtt_timer = 0.0f;
482 float m_playerpos_send_timer = 0.0f;
483 IntervalLimiter m_map_timer_and_unload_interval;
485 IWritableTextureSource *m_tsrc;
486 IWritableShaderSource *m_shsrc;
487 IWritableItemDefManager *m_itemdef;
488 NodeDefManager *m_nodedef;
489 ISoundManager *m_sound;
490 MtEventManager *m_event;
491 RenderingEngine *m_rendering_engine;
494 MeshUpdateManager m_mesh_update_manager;
495 ClientEnvironment m_env;
496 ParticleManager m_particle_manager;
497 std::unique_ptr<con::Connection> m_con;
498 std::string m_address_name;
499 ELoginRegister m_allow_login_or_register = ELoginRegister::Any;
500 Camera *m_camera = nullptr;
501 Minimap *m_minimap = nullptr;
502 bool m_minimap_disabled_by_server = false;
504 // Server serialization version
507 // Used version of the protocol with server
508 // Values smaller than 25 only mean they are smaller than 25,
509 // and aren't accurate. We simply just don't know, because
510 // the server didn't send the version back then.
511 // If 0, server init hasn't been received yet.
514 bool m_update_wielded_item = false;
515 Inventory *m_inventory_from_server = nullptr;
516 float m_inventory_from_server_age = 0.0f;
517 PacketCounter m_packetcounter;
518 // Block mesh animation parameters
519 float m_animation_time = 0.0f;
520 int m_crack_level = -1;
522 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
524 //u32 m_daynight_ratio;
525 std::queue<std::wstring> m_out_chat_queue;
526 u32 m_last_chat_message_sent;
527 float m_chat_message_allowance = 5.0f;
528 std::queue<ChatMessage *> m_chat_queue;
530 // The authentication methods we can use to enter sudo mode (=change password)
531 u32 m_sudo_auth_methods;
533 // The seed returned by the server in TOCLIENT_INIT is stored here
537 std::string m_playername;
538 std::string m_password;
539 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
540 std::string m_new_password;
541 // Usable by auth mechanisms.
542 AuthMechanism m_chosen_auth_mech;
543 void *m_auth_data = nullptr;
545 bool m_access_denied = false;
546 bool m_access_denied_reconnect = false;
547 std::string m_access_denied_reason = "";
548 std::queue<ClientEvent *> m_client_event_queue;
549 bool m_itemdef_received = false;
550 bool m_nodedef_received = false;
551 bool m_activeobjects_received = false;
552 bool m_mods_loaded = false;
554 std::vector<std::string> m_remote_media_servers;
555 // Media downloader, only exists during init
556 ClientMediaDownloader *m_media_downloader;
557 // Pending downloads of dynamic media (key: token)
558 std::vector<std::pair<u32, std::shared_ptr<SingleMediaDownloader>>> m_pending_media_downloads;
560 // time_of_day speed approximation for old protocol
561 bool m_time_of_day_set = false;
562 float m_last_time_of_day_f = -1.0f;
563 float m_time_of_day_update_timer = 0.0f;
565 // An interval for generally sending object positions and stuff
566 float m_recommended_send_interval = 0.1f;
569 float m_removed_sounds_check_timer = 0.0f;
570 // Mapping from server sound ids to our sound ids
571 std::unordered_map<s32, int> m_sounds_server_to_client;
572 // And the other way!
573 std::unordered_map<int, s32> m_sounds_client_to_server;
574 // Relation of client id to object id
575 std::unordered_map<int, u16> m_sounds_to_objects;
578 std::unordered_set<std::string> m_privileges;
580 // Detached inventories
582 std::unordered_map<std::string, Inventory*> m_detached_inventories;
584 // Storage for mesh data for creating multiple instances of the same mesh
585 StringMap m_mesh_data;
588 LocalClientState m_state;
592 // Used for saving server map to disk client-side
593 MapDatabase *m_localdb = nullptr;
594 IntervalLimiter m_localdb_save_interval;
595 u16 m_cache_save_interval;
598 ClientScripting *m_script = nullptr;
599 ModStorageDatabase *m_mod_storage_database = nullptr;
600 float m_mod_storage_save_timer = 10.0f;
601 std::vector<ModSpec> m_mods;
604 bool m_shutdown = false;
606 // CSM restrictions byteflag
607 u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
608 u32 m_csm_restriction_noderange = 8;
610 std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
612 // The number of blocks the client will combine for mesh generation.
613 MeshGrid m_mesh_grid;