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;
52 //class IWritableCraftDefManager;
53 class ClientMediaDownloader;
54 struct MapDrawControl;
60 struct MinimapMapblock;
67 enum LocalClientState {
80 PacketCounter() = default;
84 std::map<u16, u16>::iterator n = m_packets.find(command);
85 if(n == m_packets.end())
87 m_packets[command] = 1;
97 for (auto &m_packet : m_packets) {
102 void print(std::ostream &o)
104 for (const auto &m_packet : m_packets) {
105 o << "cmd "<< m_packet.first <<" count "<< m_packet.second << std::endl;
111 std::map<u16, u16> m_packets;
114 class ClientScripting;
117 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
121 NOTE: Nothing is thread-safe here.
125 const char *playername,
126 const std::string &password,
127 const std::string &address_name,
128 MapDrawControl &control,
129 IWritableTextureSource *tsrc,
130 IWritableShaderSource *shsrc,
131 IWritableItemDefManager *itemdef,
132 NodeDefManager *nodedef,
133 ISoundManager *sound,
134 MtEventManager *event,
140 DISABLE_CLASS_COPY(Client);
142 // 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_BlockData(NetworkPacket* pkt);
189 void handleCommand_Inventory(NetworkPacket* pkt);
190 void handleCommand_TimeOfDay(NetworkPacket* pkt);
191 void handleCommand_ChatMessage(NetworkPacket *pkt);
192 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
193 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
194 void handleCommand_Movement(NetworkPacket* pkt);
195 void handleCommand_HP(NetworkPacket* pkt);
196 void handleCommand_Breath(NetworkPacket* pkt);
197 void handleCommand_MovePlayer(NetworkPacket* pkt);
198 void handleCommand_DeathScreen(NetworkPacket* pkt);
199 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
200 void handleCommand_Media(NetworkPacket* pkt);
201 void handleCommand_NodeDef(NetworkPacket* pkt);
202 void handleCommand_ItemDef(NetworkPacket* pkt);
203 void handleCommand_PlaySound(NetworkPacket* pkt);
204 void handleCommand_StopSound(NetworkPacket* pkt);
205 void handleCommand_FadeSound(NetworkPacket *pkt);
206 void handleCommand_Privileges(NetworkPacket* pkt);
207 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
208 void handleCommand_DetachedInventory(NetworkPacket* pkt);
209 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
210 void handleCommand_SpawnParticle(NetworkPacket* pkt);
211 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
212 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
213 void handleCommand_HudAdd(NetworkPacket* pkt);
214 void handleCommand_HudRemove(NetworkPacket* pkt);
215 void handleCommand_HudChange(NetworkPacket* pkt);
216 void handleCommand_HudSetFlags(NetworkPacket* pkt);
217 void handleCommand_HudSetParam(NetworkPacket* pkt);
218 void handleCommand_HudSetSky(NetworkPacket* pkt);
219 void handleCommand_CloudParams(NetworkPacket* pkt);
220 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
221 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
222 void handleCommand_EyeOffset(NetworkPacket* pkt);
223 void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
224 void handleCommand_ModChannelMsg(NetworkPacket *pkt);
225 void handleCommand_ModChannelSignal(NetworkPacket *pkt);
226 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
227 void handleCommand_CSMFlavourLimits(NetworkPacket *pkt);
229 void ProcessData(NetworkPacket *pkt);
231 void Send(NetworkPacket* pkt);
233 void interact(u8 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(u8 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 virtual const std::vector<ModSpec> &getMods() const;
255 virtual const ModSpec* getModSpec(const std::string &modname) const;
257 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
258 void removeNode(v3s16 p);
261 * Helper function for Client Side Modding
262 * Flavour is applied there, this should not be used for core engine
264 * @param is_valid_position
267 MapNode getNode(v3s16 p, bool *is_valid_position);
268 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
270 void setPlayerControl(PlayerControl &control);
272 void selectPlayerItem(u16 item);
273 u16 getPlayerItem() const
274 { return m_playeritem; }
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 getLocalInventoryUpdated();
279 // Copies the inventory of the local player to parameter
280 void getLocalInventory(Inventory &dst);
282 /* InventoryManager interface */
283 Inventory* getInventory(const InventoryLocation &loc);
284 void inventoryAction(InventoryAction *a);
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; }
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 virtual IItemDefManager* getItemDefManager();
367 virtual const NodeDefManager* getNodeDefManager();
368 virtual ICraftDefManager* getCraftDefManager();
369 ITextureSource* getTextureSource();
370 virtual IShaderSource* getShaderSource();
371 IShaderSource *shsrc() { return getShaderSource(); }
372 virtual u16 allocateUnknownNodeId(const std::string &name);
373 virtual ISoundManager* getSoundManager();
374 virtual MtEventManager* getEventManager();
375 virtual ParticleManager* getParticleManager();
376 bool checkLocalPrivilege(const std::string &priv)
377 { return checkPrivilege(priv); }
378 virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
379 const std::string* getModFile(const std::string &filename);
381 virtual std::string getModStoragePath() const;
382 virtual bool registerModStorage(ModMetadata *meta);
383 virtual void unregisterModStorage(const std::string &name);
385 // The following set of functions is used by ClientMediaDownloader
386 // Insert a media file appropriately into the appropriate manager
387 bool loadMedia(const std::string &data, const std::string &filename);
388 // Send a request for conventional media transfer
389 void request_media(const std::vector<std::string> &file_requests);
391 LocalClientState getState() { return m_state; }
393 void makeScreenshot();
395 inline void pushToChatQueue(ChatMessage *cec)
397 m_chat_queue.push(cec);
400 ClientScripting *getScript() { return m_script; }
401 const bool moddingEnabled() const { return m_modding_enabled; }
403 void pushToEventQueue(ClientEvent *event);
405 void showMinimap(bool show = true);
407 const Address getServerAddress();
409 const std::string &getAddressName() const
411 return m_address_name;
414 inline bool checkCSMFlavourLimit(CSMFlavourLimit flag) const
416 return m_csm_flavour_limits & flag;
419 u32 getCSMNodeRangeLimit() const
421 return m_csm_noderange_limit;
424 inline std::unordered_map<u32, u32> &getHUDTranslationMap()
426 return m_hud_server_to_client;
429 bool joinModChannel(const std::string &channel);
430 bool leaveModChannel(const std::string &channel);
431 bool sendModChannelMessage(const std::string &channel, const std::string &message);
432 ModChannel *getModChannel(const std::string &channel);
436 bool checkBuiltinIntegrity();
438 // Virtual methods from con::PeerHandler
439 void peerAdded(con::Peer *peer);
440 void deletingPeer(con::Peer *peer, bool timeout);
442 void initLocalMapSaving(const Address &address,
443 const std::string &hostname,
444 bool is_local_server);
449 void sendPlayerPos();
450 // Send the item number 'item' as player item to the server
451 void sendPlayerItem(u16 item);
453 void deleteAuthData();
454 // helper method shared with clientpackethandler
455 static AuthMechanism choseAuthMech(const u32 mechs);
457 void sendInit(const std::string &playerName);
458 void promptConfirmRegistration(AuthMechanism chosen_auth_mechanism);
459 void startAuth(AuthMechanism chosen_auth_mechanism);
460 void sendDeletedBlocks(std::vector<v3s16> &blocks);
461 void sendGotBlocks(v3s16 block);
462 void sendRemovedSounds(std::vector<s32> &soundList);
465 inline std::string getPlayerName()
466 { return m_env.getLocalPlayer()->getName(); }
468 bool canSendChatMessage() const;
470 float m_packetcounter_timer = 0.0f;
471 float m_connection_reinit_timer = 0.1f;
472 float m_avg_rtt_timer = 0.0f;
473 float m_playerpos_send_timer = 0.0f;
474 IntervalLimiter m_map_timer_and_unload_interval;
476 IWritableTextureSource *m_tsrc;
477 IWritableShaderSource *m_shsrc;
478 IWritableItemDefManager *m_itemdef;
479 NodeDefManager *m_nodedef;
480 ISoundManager *m_sound;
481 MtEventManager *m_event;
484 MeshUpdateThread m_mesh_update_thread;
485 ClientEnvironment m_env;
486 ParticleManager m_particle_manager;
487 std::unique_ptr<con::Connection> m_con;
488 std::string m_address_name;
489 Camera *m_camera = nullptr;
490 Minimap *m_minimap = nullptr;
491 bool m_minimap_disabled_by_server = false;
492 // Server serialization version
495 // Used version of the protocol with server
496 // Values smaller than 25 only mean they are smaller than 25,
497 // and aren't accurate. We simply just don't know, because
498 // the server didn't send the version back then.
499 // If 0, server init hasn't been received yet.
502 u16 m_playeritem = 0;
503 bool m_inventory_updated = false;
504 Inventory *m_inventory_from_server = nullptr;
505 float m_inventory_from_server_age = 0.0f;
506 PacketCounter m_packetcounter;
507 // Block mesh animation parameters
508 float m_animation_time = 0.0f;
509 int m_crack_level = -1;
511 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
513 //u32 m_daynight_ratio;
514 std::queue<std::wstring> m_out_chat_queue;
515 u32 m_last_chat_message_sent;
516 float m_chat_message_allowance = 5.0f;
517 std::queue<ChatMessage *> m_chat_queue;
519 // The authentication methods we can use to enter sudo mode (=change password)
520 u32 m_sudo_auth_methods;
522 // The seed returned by the server in TOCLIENT_INIT is stored here
526 std::string m_playername;
527 std::string m_password;
528 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
529 std::string m_new_password;
530 // Usable by auth mechanisms.
531 AuthMechanism m_chosen_auth_mech;
532 void *m_auth_data = nullptr;
535 bool m_access_denied = false;
536 bool m_access_denied_reconnect = false;
537 std::string m_access_denied_reason = "";
538 std::queue<ClientEvent *> m_client_event_queue;
539 bool m_itemdef_received = false;
540 bool m_nodedef_received = false;
541 bool m_mods_loaded = false;
542 ClientMediaDownloader *m_media_downloader;
544 // time_of_day speed approximation for old protocol
545 bool m_time_of_day_set = false;
546 float m_last_time_of_day_f = -1.0f;
547 float m_time_of_day_update_timer = 0.0f;
549 // An interval for generally sending object positions and stuff
550 float m_recommended_send_interval = 0.1f;
553 float m_removed_sounds_check_timer = 0.0f;
554 // Mapping from server sound ids to our sound ids
555 std::unordered_map<s32, int> m_sounds_server_to_client;
556 // And the other way!
557 std::unordered_map<int, s32> m_sounds_client_to_server;
558 // And relations to objects
559 std::unordered_map<int, u16> m_sounds_to_objects;
561 // CSM/client IDs to SSM/server IDs Mapping
562 // Map server particle spawner IDs to client IDs
563 std::unordered_map<u32, u32> m_particles_server_to_client;
564 // Map server hud ids to client hud ids
565 std::unordered_map<u32, u32> m_hud_server_to_client;
568 std::unordered_set<std::string> m_privileges;
570 // Detached inventories
572 std::unordered_map<std::string, Inventory*> m_detached_inventories;
574 // Storage for mesh data for creating multiple instances of the same mesh
575 StringMap m_mesh_data;
577 StringMap m_mod_files;
580 LocalClientState m_state;
584 // Used for saving server map to disk client-side
585 MapDatabase *m_localdb = nullptr;
586 IntervalLimiter m_localdb_save_interval;
587 u16 m_cache_save_interval;
589 ClientScripting *m_script = nullptr;
590 bool m_modding_enabled;
591 std::unordered_map<std::string, ModMetadata *> m_mod_storages;
592 float m_mod_storage_save_timer = 10.0f;
593 std::vector<ModSpec> m_mods;
595 bool m_shutdown = false;
597 // CSM flavour limits byteflag
598 u64 m_csm_flavour_limits = CSMFlavourLimit::CSM_FL_NONE;
599 u32 m_csm_noderange_limit = 8;
601 std::unique_ptr<ModChannelMgr> m_modchannel_mgr;