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.
23 #include "network/connection.h"
24 #include "clientenvironment.h"
25 #include "irrlichttypes_extrabloated.h"
26 #include "threading/mutex.h"
31 #include "clientobject.h"
33 #include "inventorymanager.h"
34 #include "localplayer.h"
36 #include "particles.h"
38 #include "tileanimation.h"
42 class IWritableTextureSource;
43 class IWritableShaderSource;
44 class IWritableItemDefManager;
45 class IWritableNodeDefManager;
46 //class IWritableCraftDefManager;
47 class ClientMediaDownloader;
48 struct MapDrawControl;
53 struct MinimapMapblock;
57 struct QueuedMeshUpdate
61 bool ack_block_to_server;
67 enum LocalClientState {
74 A thread-safe queue of mesh update tasks
84 peer_id=0 adds with nobody to send to
86 void addBlock(v3s16 p, MeshMakeData *data,
87 bool ack_block_to_server, bool urgent);
89 // Returned pointer must be deleted
90 // Returns NULL if queue is empty
91 QueuedMeshUpdate * pop();
95 MutexAutoLock lock(m_mutex);
96 return m_queue.size();
100 std::vector<QueuedMeshUpdate*> m_queue;
101 std::set<v3s16> m_urgents;
105 struct MeshUpdateResult
109 bool ack_block_to_server;
112 p(-1338,-1338,-1338),
114 ack_block_to_server(false)
119 class MeshUpdateThread : public UpdateThread
122 MeshUpdateQueue m_queue_in;
123 int m_generation_interval;
126 virtual void doUpdate();
132 void enqueueUpdate(v3s16 p, MeshMakeData *data,
133 bool ack_block_to_server, bool urgent);
134 MutexedQueue<MeshUpdateResult> m_queue_out;
136 v3s16 m_camera_offset;
143 CE_PLAYER_FORCE_MOVE,
146 CE_SHOW_LOCAL_FORMSPEC,
148 CE_ADD_PARTICLESPAWNER,
149 CE_DELETE_PARTICLESPAWNER,
154 CE_OVERRIDE_DAY_NIGHT_RATIO,
159 ClientEventType type;
171 bool set_camera_point_target;
172 f32 camera_point_target_x;
173 f32 camera_point_target_y;
174 f32 camera_point_target_z;
177 std::string *formspec;
178 std::string *formname;
181 //} textures_updated;
188 bool collisiondetection;
189 bool collision_removal;
191 std::string *texture;
192 struct TileAnimationParams animation;
208 bool collisiondetection;
209 bool collision_removal;
212 std::string *texture;
214 struct TileAnimationParams animation;
216 } add_particlespawner;
219 } delete_particlespawner;
248 video::SColor *bgcolor;
250 std::vector<std::string> *params;
255 } override_day_night_ratio;
270 void add(u16 command)
272 std::map<u16, u16>::iterator n = m_packets.find(command);
273 if(n == m_packets.end())
275 m_packets[command] = 1;
285 for(std::map<u16, u16>::iterator
286 i = m_packets.begin();
287 i != m_packets.end(); ++i)
293 void print(std::ostream &o)
295 for(std::map<u16, u16>::iterator
296 i = m_packets.begin();
297 i != m_packets.end(); ++i)
300 <<" count "<<i->second
307 std::map<u16, u16> m_packets;
310 class ClientScripting;
313 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
317 NOTE: Nothing is thread-safe here.
321 IrrlichtDevice *device,
322 const char *playername,
323 std::string password,
324 MapDrawControl &control,
325 IWritableTextureSource *tsrc,
326 IWritableShaderSource *shsrc,
327 IWritableItemDefManager *itemdef,
328 IWritableNodeDefManager *nodedef,
329 ISoundManager *sound,
330 MtEventManager *event,
332 GameUIFlags *game_ui_flags
340 request all threads managed by client to be stopped
348 The name of the local player should already be set when
349 calling this, as it is sent in the initialization.
351 void connect(Address address,
352 const std::string &address_name,
353 bool is_local_server);
356 Stuff that references the environment is valid only as
357 long as this is not called. (eg. Players)
358 If this throws a PeerNotFoundException, the connection has
361 void step(float dtime);
367 void handleCommand(NetworkPacket* pkt);
369 void handleCommand_Null(NetworkPacket* pkt) {};
370 void handleCommand_Deprecated(NetworkPacket* pkt);
371 void handleCommand_Hello(NetworkPacket* pkt);
372 void handleCommand_AuthAccept(NetworkPacket* pkt);
373 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
374 void handleCommand_DenySudoMode(NetworkPacket* pkt);
375 void handleCommand_InitLegacy(NetworkPacket* pkt);
376 void handleCommand_AccessDenied(NetworkPacket* pkt);
377 void handleCommand_RemoveNode(NetworkPacket* pkt);
378 void handleCommand_AddNode(NetworkPacket* pkt);
379 void handleCommand_BlockData(NetworkPacket* pkt);
380 void handleCommand_Inventory(NetworkPacket* pkt);
381 void handleCommand_TimeOfDay(NetworkPacket* pkt);
382 void handleCommand_ChatMessage(NetworkPacket* pkt);
383 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
384 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
385 void handleCommand_Movement(NetworkPacket* pkt);
386 void handleCommand_HP(NetworkPacket* pkt);
387 void handleCommand_Breath(NetworkPacket* pkt);
388 void handleCommand_MovePlayer(NetworkPacket* pkt);
389 void handleCommand_PlayerItem(NetworkPacket* pkt);
390 void handleCommand_DeathScreen(NetworkPacket* pkt);
391 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
392 void handleCommand_Media(NetworkPacket* pkt);
393 void handleCommand_ToolDef(NetworkPacket* pkt);
394 void handleCommand_NodeDef(NetworkPacket* pkt);
395 void handleCommand_CraftItemDef(NetworkPacket* pkt);
396 void handleCommand_ItemDef(NetworkPacket* pkt);
397 void handleCommand_PlaySound(NetworkPacket* pkt);
398 void handleCommand_StopSound(NetworkPacket* pkt);
399 void handleCommand_Privileges(NetworkPacket* pkt);
400 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
401 void handleCommand_DetachedInventory(NetworkPacket* pkt);
402 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
403 void handleCommand_SpawnParticle(NetworkPacket* pkt);
404 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
405 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
406 void handleCommand_HudAdd(NetworkPacket* pkt);
407 void handleCommand_HudRemove(NetworkPacket* pkt);
408 void handleCommand_HudChange(NetworkPacket* pkt);
409 void handleCommand_HudSetFlags(NetworkPacket* pkt);
410 void handleCommand_HudSetParam(NetworkPacket* pkt);
411 void handleCommand_HudSetSky(NetworkPacket* pkt);
412 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
413 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
414 void handleCommand_EyeOffset(NetworkPacket* pkt);
415 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
417 void ProcessData(NetworkPacket *pkt);
419 void Send(NetworkPacket* pkt);
421 void interact(u8 action, const PointedThing& pointed);
423 void sendNodemetaFields(v3s16 p, const std::string &formname,
424 const StringMap &fields);
425 void sendInventoryFields(const std::string &formname,
426 const StringMap &fields);
427 void sendInventoryAction(InventoryAction *a);
428 void sendChatMessage(const std::wstring &message);
429 void sendChangePassword(const std::string &oldpassword,
430 const std::string &newpassword);
431 void sendDamage(u8 damage);
432 void sendBreath(u16 breath);
436 ClientEnvironment& getEnv() { return m_env; }
437 ITextureSource *tsrc() { return getTextureSource(); }
438 ISoundManager *sound() { return getSoundManager(); }
439 static const std::string &getBuiltinLuaPath();
440 static const std::string &getClientModsLuaPath();
442 virtual const std::vector<ModSpec> &getMods() const;
443 virtual const ModSpec* getModSpec(const std::string &modname) const;
445 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
446 void removeNode(v3s16 p);
447 MapNode getNode(v3s16 p, bool *is_valid_position);
448 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
450 void setPlayerControl(PlayerControl &control);
452 void selectPlayerItem(u16 item);
453 u16 getPlayerItem() const
454 { return m_playeritem; }
456 // Returns true if the inventory of the local player has been
457 // updated from the server. If it is true, it is set to false.
458 bool getLocalInventoryUpdated();
459 // Copies the inventory of the local player to parameter
460 void getLocalInventory(Inventory &dst);
462 /* InventoryManager interface */
463 Inventory* getInventory(const InventoryLocation &loc);
464 void inventoryAction(InventoryAction *a);
466 const std::list<std::string> &getConnectedPlayerNames()
468 return m_env.getPlayerNames();
471 float getAnimationTime();
474 void setCrack(int level, v3s16 pos);
478 bool checkPrivilege(const std::string &priv) const
479 { return (m_privileges.count(priv) != 0); }
481 bool getChatMessage(std::wstring &message);
482 void typeChatMessage(const std::wstring& message);
484 u64 getMapSeed(){ return m_map_seed; }
486 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
487 // Including blocks at appropriate edges
488 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
489 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
491 void updateCameraOffset(v3s16 camera_offset)
492 { m_mesh_update_thread.m_camera_offset = camera_offset; }
494 // Get event from queue. CE_NONE is returned if queue is empty.
495 ClientEvent getClientEvent();
497 bool accessDenied() const { return m_access_denied; }
499 bool reconnectRequested() const { return m_access_denied_reconnect; }
501 void setFatalError(const std::string &reason)
503 m_access_denied = true;
504 m_access_denied_reason = reason;
507 // Renaming accessDeniedReason to better name could be good as it's used to
508 // disconnect client when CSM failed.
509 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
511 bool itemdefReceived()
512 { return m_itemdef_received; }
513 bool nodedefReceived()
514 { return m_nodedef_received; }
516 { return m_media_downloader == NULL; }
519 { return m_proto_ver; }
521 bool connectedToServer()
522 { return m_con.Connected(); }
524 float mediaReceiveProgress();
526 void afterContentReceived(IrrlichtDevice *device);
531 Minimap* getMinimap() { return m_minimap; }
532 void setCamera(Camera* camera) { m_camera = camera; }
537 bool shouldShowMinimap() const;
539 // IGameDef interface
540 virtual IItemDefManager* getItemDefManager();
541 virtual INodeDefManager* getNodeDefManager();
542 virtual ICraftDefManager* getCraftDefManager();
543 ITextureSource* getTextureSource();
544 virtual IShaderSource* getShaderSource();
545 IShaderSource *shsrc() { return getShaderSource(); }
546 scene::ISceneManager* getSceneManager();
547 virtual u16 allocateUnknownNodeId(const std::string &name);
548 virtual ISoundManager* getSoundManager();
549 virtual MtEventManager* getEventManager();
550 virtual ParticleManager* getParticleManager();
551 bool checkLocalPrivilege(const std::string &priv)
552 { return checkPrivilege(priv); }
553 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
555 virtual std::string getModStoragePath() const;
556 virtual bool registerModStorage(ModMetadata *meta);
557 virtual void unregisterModStorage(const std::string &name);
559 // The following set of functions is used by ClientMediaDownloader
560 // Insert a media file appropriately into the appropriate manager
561 bool loadMedia(const std::string &data, const std::string &filename);
562 // Send a request for conventional media transfer
563 void request_media(const std::vector<std::string> &file_requests);
564 // Send a notification that no conventional media transfer is needed
565 void received_media();
567 LocalClientState getState() { return m_state; }
569 void makeScreenshot(IrrlichtDevice *device);
571 inline void pushToChatQueue(const std::wstring &input)
573 m_chat_queue.push(input);
576 ClientScripting *getScript() { return m_script; }
577 const bool moddingEnabled() const { return m_modding_enabled; }
579 inline void pushToEventQueue(const ClientEvent &event)
581 m_client_event_queue.push(event);
584 void showGameChat(const bool show = true);
585 void showGameHud(const bool show = true);
586 void showMinimap(const bool show = true);
587 void showProfiler(const bool show = true);
588 void showGameFog(const bool show = true);
589 void showGameDebug(const bool show = true);
593 // Virtual methods from con::PeerHandler
594 void peerAdded(con::Peer *peer);
595 void deletingPeer(con::Peer *peer, bool timeout);
597 void initLocalMapSaving(const Address &address,
598 const std::string &hostname,
599 bool is_local_server);
604 void sendPlayerPos();
605 // Send the item number 'item' as player item to the server
606 void sendPlayerItem(u16 item);
608 void deleteAuthData();
609 // helper method shared with clientpackethandler
610 static AuthMechanism choseAuthMech(const u32 mechs);
612 void sendLegacyInit(const char* playerName, const char* playerPassword);
613 void sendInit(const std::string &playerName);
614 void startAuth(AuthMechanism chosen_auth_mechanism);
615 void sendDeletedBlocks(std::vector<v3s16> &blocks);
616 void sendGotBlocks(v3s16 block);
617 void sendRemovedSounds(std::vector<s32> &soundList);
620 inline std::string getPlayerName()
621 { return m_env.getLocalPlayer()->getName(); }
623 float m_packetcounter_timer;
624 float m_connection_reinit_timer;
625 float m_avg_rtt_timer;
626 float m_playerpos_send_timer;
627 float m_ignore_damage_timer; // Used after server moves player
628 IntervalLimiter m_map_timer_and_unload_interval;
630 IWritableTextureSource *m_tsrc;
631 IWritableShaderSource *m_shsrc;
632 IWritableItemDefManager *m_itemdef;
633 IWritableNodeDefManager *m_nodedef;
634 ISoundManager *m_sound;
635 MtEventManager *m_event;
638 MeshUpdateThread m_mesh_update_thread;
639 ClientEnvironment m_env;
640 ParticleManager m_particle_manager;
641 con::Connection m_con;
642 IrrlichtDevice *m_device;
645 bool m_minimap_disabled_by_server;
646 // Server serialization version
649 // Used version of the protocol with server
650 // Values smaller than 25 only mean they are smaller than 25,
651 // and aren't accurate. We simply just don't know, because
652 // the server didn't send the version back then.
653 // If 0, server init hasn't been received yet.
657 bool m_inventory_updated;
658 Inventory *m_inventory_from_server;
659 float m_inventory_from_server_age;
660 PacketCounter m_packetcounter;
661 // Block mesh animation parameters
662 float m_animation_time;
665 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
667 //u32 m_daynight_ratio;
668 std::queue<std::wstring> m_chat_queue;
670 // The authentication methods we can use to enter sudo mode (=change password)
671 u32 m_sudo_auth_methods;
673 // The seed returned by the server in TOCLIENT_INIT is stored here
677 std::string m_playername;
678 std::string m_password;
679 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
680 std::string m_new_password;
681 // Usable by auth mechanisms.
682 AuthMechanism m_chosen_auth_mech;
686 bool m_access_denied;
687 bool m_access_denied_reconnect;
688 std::string m_access_denied_reason;
689 std::queue<ClientEvent> m_client_event_queue;
690 bool m_itemdef_received;
691 bool m_nodedef_received;
692 ClientMediaDownloader *m_media_downloader;
694 // time_of_day speed approximation for old protocol
695 bool m_time_of_day_set;
696 float m_last_time_of_day_f;
697 float m_time_of_day_update_timer;
699 // An interval for generally sending object positions and stuff
700 float m_recommended_send_interval;
703 float m_removed_sounds_check_timer;
704 // Mapping from server sound ids to our sound ids
705 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
706 // And the other way!
707 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
708 // And relations to objects
709 UNORDERED_MAP<int, u16> m_sounds_to_objects;
712 UNORDERED_SET<std::string> m_privileges;
714 // Detached inventories
716 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
718 // Storage for mesh data for creating multiple instances of the same mesh
719 StringMap m_mesh_data;
722 LocalClientState m_state;
724 // Used for saving server map to disk client-side
726 IntervalLimiter m_localdb_save_interval;
727 u16 m_cache_save_interval;
729 // TODO: Add callback to update these when g_settings changes
730 bool m_cache_smooth_lighting;
731 bool m_cache_enable_shaders;
732 bool m_cache_use_tangent_vertices;
734 ClientScripting *m_script;
735 bool m_modding_enabled;
736 UNORDERED_MAP<std::string, ModMetadata *> m_mod_storages;
737 float m_mod_storage_save_timer;
738 GameUIFlags *m_game_ui_flags;
741 DISABLE_CLASS_COPY(Client);
744 #endif // !CLIENT_HEADER