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"
39 #include "mesh_generator_thread.h"
43 class IWritableTextureSource;
44 class IWritableShaderSource;
45 class IWritableItemDefManager;
46 class IWritableNodeDefManager;
47 //class IWritableCraftDefManager;
48 class ClientMediaDownloader;
49 struct MapDrawControl;
54 struct MinimapMapblock;
58 enum LocalClientState {
71 CE_SHOW_LOCAL_FORMSPEC,
73 CE_ADD_PARTICLESPAWNER,
74 CE_DELETE_PARTICLESPAWNER,
79 CE_OVERRIDE_DAY_NIGHT_RATIO,
97 bool set_camera_point_target;
98 f32 camera_point_target_x;
99 f32 camera_point_target_y;
100 f32 camera_point_target_z;
103 std::string *formspec;
104 std::string *formname;
107 //} textures_updated;
114 bool collisiondetection;
115 bool collision_removal;
117 std::string *texture;
118 struct TileAnimationParams animation;
134 bool collisiondetection;
135 bool collision_removal;
138 std::string *texture;
140 struct TileAnimationParams animation;
142 } add_particlespawner;
145 } delete_particlespawner;
174 video::SColor *bgcolor;
176 std::vector<std::string> *params;
182 } override_day_night_ratio;
206 void add(u16 command)
208 std::map<u16, u16>::iterator n = m_packets.find(command);
209 if(n == m_packets.end())
211 m_packets[command] = 1;
221 for(std::map<u16, u16>::iterator
222 i = m_packets.begin();
223 i != m_packets.end(); ++i)
229 void print(std::ostream &o)
231 for(std::map<u16, u16>::iterator
232 i = m_packets.begin();
233 i != m_packets.end(); ++i)
236 <<" count "<<i->second
243 std::map<u16, u16> m_packets;
246 class ClientScripting;
249 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
253 NOTE: Nothing is thread-safe here.
257 IrrlichtDevice *device,
258 const char *playername,
259 const std::string &password,
260 const std::string &address_name,
261 MapDrawControl &control,
262 IWritableTextureSource *tsrc,
263 IWritableShaderSource *shsrc,
264 IWritableItemDefManager *itemdef,
265 IWritableNodeDefManager *nodedef,
266 ISoundManager *sound,
267 MtEventManager *event,
269 GameUIFlags *game_ui_flags
277 request all threads managed by client to be stopped
285 The name of the local player should already be set when
286 calling this, as it is sent in the initialization.
288 void connect(Address address, bool is_local_server);
291 Stuff that references the environment is valid only as
292 long as this is not called. (eg. Players)
293 If this throws a PeerNotFoundException, the connection has
296 void step(float dtime);
302 void handleCommand(NetworkPacket* pkt);
304 void handleCommand_Null(NetworkPacket* pkt) {};
305 void handleCommand_Deprecated(NetworkPacket* pkt);
306 void handleCommand_Hello(NetworkPacket* pkt);
307 void handleCommand_AuthAccept(NetworkPacket* pkt);
308 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
309 void handleCommand_DenySudoMode(NetworkPacket* pkt);
310 void handleCommand_InitLegacy(NetworkPacket* pkt);
311 void handleCommand_AccessDenied(NetworkPacket* pkt);
312 void handleCommand_RemoveNode(NetworkPacket* pkt);
313 void handleCommand_AddNode(NetworkPacket* pkt);
314 void handleCommand_BlockData(NetworkPacket* pkt);
315 void handleCommand_Inventory(NetworkPacket* pkt);
316 void handleCommand_TimeOfDay(NetworkPacket* pkt);
317 void handleCommand_ChatMessage(NetworkPacket* pkt);
318 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
319 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
320 void handleCommand_Movement(NetworkPacket* pkt);
321 void handleCommand_HP(NetworkPacket* pkt);
322 void handleCommand_Breath(NetworkPacket* pkt);
323 void handleCommand_MovePlayer(NetworkPacket* pkt);
324 void handleCommand_DeathScreen(NetworkPacket* pkt);
325 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
326 void handleCommand_Media(NetworkPacket* pkt);
327 void handleCommand_NodeDef(NetworkPacket* pkt);
328 void handleCommand_ItemDef(NetworkPacket* pkt);
329 void handleCommand_PlaySound(NetworkPacket* pkt);
330 void handleCommand_StopSound(NetworkPacket* pkt);
331 void handleCommand_FadeSound(NetworkPacket *pkt);
332 void handleCommand_Privileges(NetworkPacket* pkt);
333 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
334 void handleCommand_DetachedInventory(NetworkPacket* pkt);
335 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
336 void handleCommand_SpawnParticle(NetworkPacket* pkt);
337 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
338 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
339 void handleCommand_HudAdd(NetworkPacket* pkt);
340 void handleCommand_HudRemove(NetworkPacket* pkt);
341 void handleCommand_HudChange(NetworkPacket* pkt);
342 void handleCommand_HudSetFlags(NetworkPacket* pkt);
343 void handleCommand_HudSetParam(NetworkPacket* pkt);
344 void handleCommand_HudSetSky(NetworkPacket* pkt);
345 void handleCommand_CloudParams(NetworkPacket* pkt);
346 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
347 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
348 void handleCommand_EyeOffset(NetworkPacket* pkt);
349 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
351 void ProcessData(NetworkPacket *pkt);
353 void Send(NetworkPacket* pkt);
355 void interact(u8 action, const PointedThing& pointed);
357 void sendNodemetaFields(v3s16 p, const std::string &formname,
358 const StringMap &fields);
359 void sendInventoryFields(const std::string &formname,
360 const StringMap &fields);
361 void sendInventoryAction(InventoryAction *a);
362 void sendChatMessage(const std::wstring &message);
363 void sendChangePassword(const std::string &oldpassword,
364 const std::string &newpassword);
365 void sendDamage(u8 damage);
366 void sendBreath(u16 breath);
370 ClientEnvironment& getEnv() { return m_env; }
371 ITextureSource *tsrc() { return getTextureSource(); }
372 ISoundManager *sound() { return getSoundManager(); }
373 static const std::string &getBuiltinLuaPath();
374 static const std::string &getClientModsLuaPath();
376 virtual const std::vector<ModSpec> &getMods() const;
377 virtual const ModSpec* getModSpec(const std::string &modname) const;
379 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
380 void removeNode(v3s16 p);
381 MapNode getNode(v3s16 p, bool *is_valid_position);
382 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
384 void setPlayerControl(PlayerControl &control);
386 void selectPlayerItem(u16 item);
387 u16 getPlayerItem() const
388 { return m_playeritem; }
390 // Returns true if the inventory of the local player has been
391 // updated from the server. If it is true, it is set to false.
392 bool getLocalInventoryUpdated();
393 // Copies the inventory of the local player to parameter
394 void getLocalInventory(Inventory &dst);
396 /* InventoryManager interface */
397 Inventory* getInventory(const InventoryLocation &loc);
398 void inventoryAction(InventoryAction *a);
400 const std::list<std::string> &getConnectedPlayerNames()
402 return m_env.getPlayerNames();
405 float getAnimationTime();
409 void setCrack(int level, v3s16 pos);
413 bool checkPrivilege(const std::string &priv) const
414 { return (m_privileges.count(priv) != 0); }
416 bool getChatMessage(std::wstring &message);
417 void typeChatMessage(const std::wstring& message);
419 u64 getMapSeed(){ return m_map_seed; }
421 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
422 // Including blocks at appropriate edges
423 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
424 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
426 void updateCameraOffset(v3s16 camera_offset)
427 { m_mesh_update_thread.m_camera_offset = camera_offset; }
429 bool hasClientEvents() const { return !m_client_event_queue.empty(); }
430 // Get event from queue. If queue is empty, it triggers an assertion failure.
431 ClientEvent getClientEvent();
433 bool accessDenied() const { return m_access_denied; }
435 bool reconnectRequested() const { return m_access_denied_reconnect; }
437 void setFatalError(const std::string &reason)
439 m_access_denied = true;
440 m_access_denied_reason = reason;
443 // Renaming accessDeniedReason to better name could be good as it's used to
444 // disconnect client when CSM failed.
445 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
447 bool itemdefReceived()
448 { return m_itemdef_received; }
449 bool nodedefReceived()
450 { return m_nodedef_received; }
452 { return m_media_downloader == NULL; }
455 { return m_proto_ver; }
457 bool connectedToServer()
458 { return m_con.Connected(); }
460 float mediaReceiveProgress();
462 void afterContentReceived(IrrlichtDevice *device);
467 Minimap* getMinimap() { return m_minimap; }
468 void setCamera(Camera* camera) { m_camera = camera; }
473 bool shouldShowMinimap() const;
475 // IGameDef interface
476 virtual IItemDefManager* getItemDefManager();
477 virtual INodeDefManager* getNodeDefManager();
478 virtual ICraftDefManager* getCraftDefManager();
479 ITextureSource* getTextureSource();
480 virtual IShaderSource* getShaderSource();
481 IShaderSource *shsrc() { return getShaderSource(); }
482 scene::ISceneManager* getSceneManager();
483 virtual u16 allocateUnknownNodeId(const std::string &name);
484 virtual ISoundManager* getSoundManager();
485 virtual MtEventManager* getEventManager();
486 virtual ParticleManager* getParticleManager();
487 bool checkLocalPrivilege(const std::string &priv)
488 { return checkPrivilege(priv); }
489 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
491 virtual std::string getModStoragePath() const;
492 virtual bool registerModStorage(ModMetadata *meta);
493 virtual void unregisterModStorage(const std::string &name);
495 // The following set of functions is used by ClientMediaDownloader
496 // Insert a media file appropriately into the appropriate manager
497 bool loadMedia(const std::string &data, const std::string &filename);
498 // Send a request for conventional media transfer
499 void request_media(const std::vector<std::string> &file_requests);
501 LocalClientState getState() { return m_state; }
503 void makeScreenshot(IrrlichtDevice *device);
505 inline void pushToChatQueue(const std::wstring &input)
507 m_chat_queue.push(input);
510 ClientScripting *getScript() { return m_script; }
511 const bool moddingEnabled() const { return m_modding_enabled; }
513 inline void pushToEventQueue(const ClientEvent &event)
515 m_client_event_queue.push(event);
518 void showGameChat(const bool show = true);
519 void showGameHud(const bool show = true);
520 void showMinimap(const bool show = true);
521 void showProfiler(const bool show = true);
522 void showGameFog(const bool show = true);
523 void showGameDebug(const bool show = true);
525 IrrlichtDevice *getDevice() const { return m_device; }
527 const Address getServerAddress()
529 return m_con.GetPeerAddress(PEER_ID_SERVER);
532 const std::string &getAddressName() const
534 return m_address_name;
539 // Virtual methods from con::PeerHandler
540 void peerAdded(con::Peer *peer);
541 void deletingPeer(con::Peer *peer, bool timeout);
543 void initLocalMapSaving(const Address &address,
544 const std::string &hostname,
545 bool is_local_server);
550 void sendPlayerPos();
551 // Send the item number 'item' as player item to the server
552 void sendPlayerItem(u16 item);
554 void deleteAuthData();
555 // helper method shared with clientpackethandler
556 static AuthMechanism choseAuthMech(const u32 mechs);
558 void sendLegacyInit(const char* playerName, const char* playerPassword);
559 void sendInit(const std::string &playerName);
560 void startAuth(AuthMechanism chosen_auth_mechanism);
561 void sendDeletedBlocks(std::vector<v3s16> &blocks);
562 void sendGotBlocks(v3s16 block);
563 void sendRemovedSounds(std::vector<s32> &soundList);
566 inline std::string getPlayerName()
567 { return m_env.getLocalPlayer()->getName(); }
569 float m_packetcounter_timer;
570 float m_connection_reinit_timer;
571 float m_avg_rtt_timer;
572 float m_playerpos_send_timer;
573 float m_ignore_damage_timer; // Used after server moves player
574 IntervalLimiter m_map_timer_and_unload_interval;
576 IWritableTextureSource *m_tsrc;
577 IWritableShaderSource *m_shsrc;
578 IWritableItemDefManager *m_itemdef;
579 IWritableNodeDefManager *m_nodedef;
580 ISoundManager *m_sound;
581 MtEventManager *m_event;
584 MeshUpdateThread m_mesh_update_thread;
585 ClientEnvironment m_env;
586 ParticleManager m_particle_manager;
587 con::Connection m_con;
588 std::string m_address_name;
589 IrrlichtDevice *m_device;
592 bool m_minimap_disabled_by_server;
593 // Server serialization version
596 // Used version of the protocol with server
597 // Values smaller than 25 only mean they are smaller than 25,
598 // and aren't accurate. We simply just don't know, because
599 // the server didn't send the version back then.
600 // If 0, server init hasn't been received yet.
604 bool m_inventory_updated;
605 Inventory *m_inventory_from_server;
606 float m_inventory_from_server_age;
607 PacketCounter m_packetcounter;
608 // Block mesh animation parameters
609 float m_animation_time;
612 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
614 //u32 m_daynight_ratio;
615 std::queue<std::wstring> m_chat_queue;
617 // The authentication methods we can use to enter sudo mode (=change password)
618 u32 m_sudo_auth_methods;
620 // The seed returned by the server in TOCLIENT_INIT is stored here
624 std::string m_playername;
625 std::string m_password;
626 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
627 std::string m_new_password;
628 // Usable by auth mechanisms.
629 AuthMechanism m_chosen_auth_mech;
633 bool m_access_denied;
634 bool m_access_denied_reconnect;
635 std::string m_access_denied_reason;
636 std::queue<ClientEvent> m_client_event_queue;
637 bool m_itemdef_received;
638 bool m_nodedef_received;
639 ClientMediaDownloader *m_media_downloader;
641 // time_of_day speed approximation for old protocol
642 bool m_time_of_day_set;
643 float m_last_time_of_day_f;
644 float m_time_of_day_update_timer;
646 // An interval for generally sending object positions and stuff
647 float m_recommended_send_interval;
650 float m_removed_sounds_check_timer;
651 // Mapping from server sound ids to our sound ids
652 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
653 // And the other way!
654 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
655 // And relations to objects
656 UNORDERED_MAP<int, u16> m_sounds_to_objects;
659 UNORDERED_SET<std::string> m_privileges;
661 // Detached inventories
663 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
665 // Storage for mesh data for creating multiple instances of the same mesh
666 StringMap m_mesh_data;
669 LocalClientState m_state;
671 // Used for saving server map to disk client-side
672 MapDatabase *m_localdb;
673 IntervalLimiter m_localdb_save_interval;
674 u16 m_cache_save_interval;
676 ClientScripting *m_script;
677 bool m_modding_enabled;
678 UNORDERED_MAP<std::string, ModMetadata *> m_mod_storages;
679 float m_mod_storage_save_timer;
680 GameUIFlags *m_game_ui_flags;
683 DISABLE_CLASS_COPY(Client);
686 #endif // !CLIENT_HEADER