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;
125 virtual void doUpdate();
129 MeshUpdateThread() : UpdateThread("Mesh") {}
131 void enqueueUpdate(v3s16 p, MeshMakeData *data,
132 bool ack_block_to_server, bool urgent);
133 MutexedQueue<MeshUpdateResult> m_queue_out;
135 v3s16 m_camera_offset;
142 CE_PLAYER_FORCE_MOVE,
145 CE_SHOW_LOCAL_FORMSPEC,
147 CE_ADD_PARTICLESPAWNER,
148 CE_DELETE_PARTICLESPAWNER,
153 CE_OVERRIDE_DAY_NIGHT_RATIO,
158 ClientEventType type;
170 bool set_camera_point_target;
171 f32 camera_point_target_x;
172 f32 camera_point_target_y;
173 f32 camera_point_target_z;
176 std::string *formspec;
177 std::string *formname;
180 //} textures_updated;
187 bool collisiondetection;
188 bool collision_removal;
190 std::string *texture;
191 struct TileAnimationParams animation;
207 bool collisiondetection;
208 bool collision_removal;
211 std::string *texture;
213 struct TileAnimationParams animation;
215 } add_particlespawner;
218 } delete_particlespawner;
247 video::SColor *bgcolor;
249 std::vector<std::string> *params;
254 } override_day_night_ratio;
269 void add(u16 command)
271 std::map<u16, u16>::iterator n = m_packets.find(command);
272 if(n == m_packets.end())
274 m_packets[command] = 1;
284 for(std::map<u16, u16>::iterator
285 i = m_packets.begin();
286 i != m_packets.end(); ++i)
292 void print(std::ostream &o)
294 for(std::map<u16, u16>::iterator
295 i = m_packets.begin();
296 i != m_packets.end(); ++i)
299 <<" count "<<i->second
306 std::map<u16, u16> m_packets;
309 class ClientScripting;
312 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
316 NOTE: Nothing is thread-safe here.
320 IrrlichtDevice *device,
321 const char *playername,
322 std::string password,
323 MapDrawControl &control,
324 IWritableTextureSource *tsrc,
325 IWritableShaderSource *shsrc,
326 IWritableItemDefManager *itemdef,
327 IWritableNodeDefManager *nodedef,
328 ISoundManager *sound,
329 MtEventManager *event,
331 GameUIFlags *game_ui_flags
339 request all threads managed by client to be stopped
347 The name of the local player should already be set when
348 calling this, as it is sent in the initialization.
350 void connect(Address address,
351 const std::string &address_name,
352 bool is_local_server);
355 Stuff that references the environment is valid only as
356 long as this is not called. (eg. Players)
357 If this throws a PeerNotFoundException, the connection has
360 void step(float dtime);
366 void handleCommand(NetworkPacket* pkt);
368 void handleCommand_Null(NetworkPacket* pkt) {};
369 void handleCommand_Deprecated(NetworkPacket* pkt);
370 void handleCommand_Hello(NetworkPacket* pkt);
371 void handleCommand_AuthAccept(NetworkPacket* pkt);
372 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
373 void handleCommand_DenySudoMode(NetworkPacket* pkt);
374 void handleCommand_InitLegacy(NetworkPacket* pkt);
375 void handleCommand_AccessDenied(NetworkPacket* pkt);
376 void handleCommand_RemoveNode(NetworkPacket* pkt);
377 void handleCommand_AddNode(NetworkPacket* pkt);
378 void handleCommand_BlockData(NetworkPacket* pkt);
379 void handleCommand_Inventory(NetworkPacket* pkt);
380 void handleCommand_TimeOfDay(NetworkPacket* pkt);
381 void handleCommand_ChatMessage(NetworkPacket* pkt);
382 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
383 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
384 void handleCommand_Movement(NetworkPacket* pkt);
385 void handleCommand_HP(NetworkPacket* pkt);
386 void handleCommand_Breath(NetworkPacket* pkt);
387 void handleCommand_MovePlayer(NetworkPacket* pkt);
388 void handleCommand_PlayerItem(NetworkPacket* pkt);
389 void handleCommand_DeathScreen(NetworkPacket* pkt);
390 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
391 void handleCommand_Media(NetworkPacket* pkt);
392 void handleCommand_ToolDef(NetworkPacket* pkt);
393 void handleCommand_NodeDef(NetworkPacket* pkt);
394 void handleCommand_CraftItemDef(NetworkPacket* pkt);
395 void handleCommand_ItemDef(NetworkPacket* pkt);
396 void handleCommand_PlaySound(NetworkPacket* pkt);
397 void handleCommand_StopSound(NetworkPacket* pkt);
398 void handleCommand_Privileges(NetworkPacket* pkt);
399 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
400 void handleCommand_DetachedInventory(NetworkPacket* pkt);
401 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
402 void handleCommand_SpawnParticle(NetworkPacket* pkt);
403 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
404 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
405 void handleCommand_HudAdd(NetworkPacket* pkt);
406 void handleCommand_HudRemove(NetworkPacket* pkt);
407 void handleCommand_HudChange(NetworkPacket* pkt);
408 void handleCommand_HudSetFlags(NetworkPacket* pkt);
409 void handleCommand_HudSetParam(NetworkPacket* pkt);
410 void handleCommand_HudSetSky(NetworkPacket* pkt);
411 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
412 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
413 void handleCommand_EyeOffset(NetworkPacket* pkt);
414 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
416 void ProcessData(NetworkPacket *pkt);
418 void Send(NetworkPacket* pkt);
420 void interact(u8 action, const PointedThing& pointed);
422 void sendNodemetaFields(v3s16 p, const std::string &formname,
423 const StringMap &fields);
424 void sendInventoryFields(const std::string &formname,
425 const StringMap &fields);
426 void sendInventoryAction(InventoryAction *a);
427 void sendChatMessage(const std::wstring &message);
428 void sendChangePassword(const std::string &oldpassword,
429 const std::string &newpassword);
430 void sendDamage(u8 damage);
431 void sendBreath(u16 breath);
435 ClientEnvironment& getEnv() { return m_env; }
436 ITextureSource *tsrc() { return getTextureSource(); }
437 ISoundManager *sound() { return getSoundManager(); }
438 static const std::string &getBuiltinLuaPath();
439 static const std::string &getClientModsLuaPath();
441 virtual const std::vector<ModSpec> &getMods() const;
442 virtual const ModSpec* getModSpec(const std::string &modname) const;
444 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
445 void removeNode(v3s16 p);
446 MapNode getNode(v3s16 p, bool *is_valid_position);
447 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
449 void setPlayerControl(PlayerControl &control);
451 void selectPlayerItem(u16 item);
452 u16 getPlayerItem() const
453 { return m_playeritem; }
455 // Returns true if the inventory of the local player has been
456 // updated from the server. If it is true, it is set to false.
457 bool getLocalInventoryUpdated();
458 // Copies the inventory of the local player to parameter
459 void getLocalInventory(Inventory &dst);
461 /* InventoryManager interface */
462 Inventory* getInventory(const InventoryLocation &loc);
463 void inventoryAction(InventoryAction *a);
465 const std::list<std::string> &getConnectedPlayerNames()
467 return m_env.getPlayerNames();
470 float getAnimationTime();
473 void setCrack(int level, v3s16 pos);
477 bool checkPrivilege(const std::string &priv) const
478 { return (m_privileges.count(priv) != 0); }
480 bool getChatMessage(std::wstring &message);
481 void typeChatMessage(const std::wstring& message);
483 u64 getMapSeed(){ return m_map_seed; }
485 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
486 // Including blocks at appropriate edges
487 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
488 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
490 void updateCameraOffset(v3s16 camera_offset)
491 { m_mesh_update_thread.m_camera_offset = camera_offset; }
493 // Get event from queue. CE_NONE is returned if queue is empty.
494 ClientEvent getClientEvent();
496 bool accessDenied() const { return m_access_denied; }
498 bool reconnectRequested() const { return m_access_denied_reconnect; }
500 void setFatalError(const std::string &reason)
502 m_access_denied = true;
503 m_access_denied_reason = reason;
506 // Renaming accessDeniedReason to better name could be good as it's used to
507 // disconnect client when CSM failed.
508 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
510 bool itemdefReceived()
511 { return m_itemdef_received; }
512 bool nodedefReceived()
513 { return m_nodedef_received; }
515 { return m_media_downloader == NULL; }
518 { return m_proto_ver; }
520 bool connectedToServer()
521 { return m_con.Connected(); }
523 float mediaReceiveProgress();
525 void afterContentReceived(IrrlichtDevice *device);
530 Minimap* getMinimap() { return m_minimap; }
531 void setCamera(Camera* camera) { m_camera = camera; }
536 bool shouldShowMinimap() const;
538 // IGameDef interface
539 virtual IItemDefManager* getItemDefManager();
540 virtual INodeDefManager* getNodeDefManager();
541 virtual ICraftDefManager* getCraftDefManager();
542 ITextureSource* getTextureSource();
543 virtual IShaderSource* getShaderSource();
544 IShaderSource *shsrc() { return getShaderSource(); }
545 scene::ISceneManager* getSceneManager();
546 virtual u16 allocateUnknownNodeId(const std::string &name);
547 virtual ISoundManager* getSoundManager();
548 virtual MtEventManager* getEventManager();
549 virtual ParticleManager* getParticleManager();
550 bool checkLocalPrivilege(const std::string &priv)
551 { return checkPrivilege(priv); }
552 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
554 virtual std::string getModStoragePath() const;
555 virtual bool registerModStorage(ModMetadata *meta);
556 virtual void unregisterModStorage(const std::string &name);
558 // The following set of functions is used by ClientMediaDownloader
559 // Insert a media file appropriately into the appropriate manager
560 bool loadMedia(const std::string &data, const std::string &filename);
561 // Send a request for conventional media transfer
562 void request_media(const std::vector<std::string> &file_requests);
563 // Send a notification that no conventional media transfer is needed
564 void received_media();
566 LocalClientState getState() { return m_state; }
568 void makeScreenshot(IrrlichtDevice *device);
570 inline void pushToChatQueue(const std::wstring &input)
572 m_chat_queue.push(input);
575 ClientScripting *getScript() { return m_script; }
576 const bool moddingEnabled() const { return m_modding_enabled; }
578 inline void pushToEventQueue(const ClientEvent &event)
580 m_client_event_queue.push(event);
583 void showGameChat(const bool show = true);
584 void showGameHud(const bool show = true);
585 void showMinimap(const bool show = true);
586 void showProfiler(const bool show = true);
587 void showGameFog(const bool show = true);
588 void showGameDebug(const bool show = true);
592 // Virtual methods from con::PeerHandler
593 void peerAdded(con::Peer *peer);
594 void deletingPeer(con::Peer *peer, bool timeout);
596 void initLocalMapSaving(const Address &address,
597 const std::string &hostname,
598 bool is_local_server);
603 void sendPlayerPos();
604 // Send the item number 'item' as player item to the server
605 void sendPlayerItem(u16 item);
607 void deleteAuthData();
608 // helper method shared with clientpackethandler
609 static AuthMechanism choseAuthMech(const u32 mechs);
611 void sendLegacyInit(const char* playerName, const char* playerPassword);
612 void sendInit(const std::string &playerName);
613 void startAuth(AuthMechanism chosen_auth_mechanism);
614 void sendDeletedBlocks(std::vector<v3s16> &blocks);
615 void sendGotBlocks(v3s16 block);
616 void sendRemovedSounds(std::vector<s32> &soundList);
619 inline std::string getPlayerName()
620 { return m_env.getLocalPlayer()->getName(); }
622 float m_packetcounter_timer;
623 float m_connection_reinit_timer;
624 float m_avg_rtt_timer;
625 float m_playerpos_send_timer;
626 float m_ignore_damage_timer; // Used after server moves player
627 IntervalLimiter m_map_timer_and_unload_interval;
629 IWritableTextureSource *m_tsrc;
630 IWritableShaderSource *m_shsrc;
631 IWritableItemDefManager *m_itemdef;
632 IWritableNodeDefManager *m_nodedef;
633 ISoundManager *m_sound;
634 MtEventManager *m_event;
637 MeshUpdateThread m_mesh_update_thread;
638 ClientEnvironment m_env;
639 ParticleManager m_particle_manager;
640 con::Connection m_con;
641 IrrlichtDevice *m_device;
644 bool m_minimap_disabled_by_server;
645 // Server serialization version
648 // Used version of the protocol with server
649 // Values smaller than 25 only mean they are smaller than 25,
650 // and aren't accurate. We simply just don't know, because
651 // the server didn't send the version back then.
652 // If 0, server init hasn't been received yet.
656 bool m_inventory_updated;
657 Inventory *m_inventory_from_server;
658 float m_inventory_from_server_age;
659 PacketCounter m_packetcounter;
660 // Block mesh animation parameters
661 float m_animation_time;
664 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
666 //u32 m_daynight_ratio;
667 std::queue<std::wstring> m_chat_queue;
669 // The authentication methods we can use to enter sudo mode (=change password)
670 u32 m_sudo_auth_methods;
672 // The seed returned by the server in TOCLIENT_INIT is stored here
676 std::string m_playername;
677 std::string m_password;
678 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
679 std::string m_new_password;
680 // Usable by auth mechanisms.
681 AuthMechanism m_chosen_auth_mech;
685 bool m_access_denied;
686 bool m_access_denied_reconnect;
687 std::string m_access_denied_reason;
688 std::queue<ClientEvent> m_client_event_queue;
689 bool m_itemdef_received;
690 bool m_nodedef_received;
691 ClientMediaDownloader *m_media_downloader;
693 // time_of_day speed approximation for old protocol
694 bool m_time_of_day_set;
695 float m_last_time_of_day_f;
696 float m_time_of_day_update_timer;
698 // An interval for generally sending object positions and stuff
699 float m_recommended_send_interval;
702 float m_removed_sounds_check_timer;
703 // Mapping from server sound ids to our sound ids
704 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
705 // And the other way!
706 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
707 // And relations to objects
708 UNORDERED_MAP<int, u16> m_sounds_to_objects;
711 UNORDERED_SET<std::string> m_privileges;
713 // Detached inventories
715 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
717 // Storage for mesh data for creating multiple instances of the same mesh
718 StringMap m_mesh_data;
721 LocalClientState m_state;
723 // Used for saving server map to disk client-side
725 IntervalLimiter m_localdb_save_interval;
726 u16 m_cache_save_interval;
728 // TODO: Add callback to update these when g_settings changes
729 bool m_cache_smooth_lighting;
730 bool m_cache_enable_shaders;
731 bool m_cache_use_tangent_vertices;
733 ClientScripting *m_script;
734 bool m_modding_enabled;
735 UNORDERED_MAP<std::string, ModMetadata *> m_mod_storages;
736 float m_mod_storage_save_timer;
737 GameUIFlags *m_game_ui_flags;
739 DISABLE_CLASS_COPY(Client);
742 #endif // !CLIENT_HEADER