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,
146 CE_ADD_PARTICLESPAWNER,
147 CE_DELETE_PARTICLESPAWNER,
152 CE_OVERRIDE_DAY_NIGHT_RATIO,
157 ClientEventType type;
169 bool set_camera_point_target;
170 f32 camera_point_target_x;
171 f32 camera_point_target_y;
172 f32 camera_point_target_z;
175 std::string *formspec;
176 std::string *formname;
179 //} textures_updated;
186 bool collisiondetection;
187 bool collision_removal;
189 std::string *texture;
190 struct TileAnimationParams animation;
206 bool collisiondetection;
207 bool collision_removal;
210 std::string *texture;
212 struct TileAnimationParams animation;
214 } add_particlespawner;
217 } delete_particlespawner;
246 video::SColor *bgcolor;
248 std::vector<std::string> *params;
253 } override_day_night_ratio;
268 void add(u16 command)
270 std::map<u16, u16>::iterator n = m_packets.find(command);
271 if(n == m_packets.end())
273 m_packets[command] = 1;
283 for(std::map<u16, u16>::iterator
284 i = m_packets.begin();
285 i != m_packets.end(); ++i)
291 void print(std::ostream &o)
293 for(std::map<u16, u16>::iterator
294 i = m_packets.begin();
295 i != m_packets.end(); ++i)
298 <<" count "<<i->second
305 std::map<u16, u16> m_packets;
308 class ClientScripting;
310 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
314 NOTE: Nothing is thread-safe here.
318 IrrlichtDevice *device,
319 const char *playername,
320 std::string password,
321 MapDrawControl &control,
322 IWritableTextureSource *tsrc,
323 IWritableShaderSource *shsrc,
324 IWritableItemDefManager *itemdef,
325 IWritableNodeDefManager *nodedef,
326 ISoundManager *sound,
327 MtEventManager *event,
336 request all threads managed by client to be stopped
344 The name of the local player should already be set when
345 calling this, as it is sent in the initialization.
347 void connect(Address address,
348 const std::string &address_name,
349 bool is_local_server);
352 Stuff that references the environment is valid only as
353 long as this is not called. (eg. Players)
354 If this throws a PeerNotFoundException, the connection has
357 void step(float dtime);
363 void handleCommand(NetworkPacket* pkt);
365 void handleCommand_Null(NetworkPacket* pkt) {};
366 void handleCommand_Deprecated(NetworkPacket* pkt);
367 void handleCommand_Hello(NetworkPacket* pkt);
368 void handleCommand_AuthAccept(NetworkPacket* pkt);
369 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
370 void handleCommand_DenySudoMode(NetworkPacket* pkt);
371 void handleCommand_InitLegacy(NetworkPacket* pkt);
372 void handleCommand_AccessDenied(NetworkPacket* pkt);
373 void handleCommand_RemoveNode(NetworkPacket* pkt);
374 void handleCommand_AddNode(NetworkPacket* pkt);
375 void handleCommand_BlockData(NetworkPacket* pkt);
376 void handleCommand_Inventory(NetworkPacket* pkt);
377 void handleCommand_TimeOfDay(NetworkPacket* pkt);
378 void handleCommand_ChatMessage(NetworkPacket* pkt);
379 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
380 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
381 void handleCommand_Movement(NetworkPacket* pkt);
382 void handleCommand_HP(NetworkPacket* pkt);
383 void handleCommand_Breath(NetworkPacket* pkt);
384 void handleCommand_MovePlayer(NetworkPacket* pkt);
385 void handleCommand_PlayerItem(NetworkPacket* pkt);
386 void handleCommand_DeathScreen(NetworkPacket* pkt);
387 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
388 void handleCommand_Media(NetworkPacket* pkt);
389 void handleCommand_ToolDef(NetworkPacket* pkt);
390 void handleCommand_NodeDef(NetworkPacket* pkt);
391 void handleCommand_CraftItemDef(NetworkPacket* pkt);
392 void handleCommand_ItemDef(NetworkPacket* pkt);
393 void handleCommand_PlaySound(NetworkPacket* pkt);
394 void handleCommand_StopSound(NetworkPacket* pkt);
395 void handleCommand_Privileges(NetworkPacket* pkt);
396 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
397 void handleCommand_DetachedInventory(NetworkPacket* pkt);
398 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
399 void handleCommand_SpawnParticle(NetworkPacket* pkt);
400 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
401 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
402 void handleCommand_HudAdd(NetworkPacket* pkt);
403 void handleCommand_HudRemove(NetworkPacket* pkt);
404 void handleCommand_HudChange(NetworkPacket* pkt);
405 void handleCommand_HudSetFlags(NetworkPacket* pkt);
406 void handleCommand_HudSetParam(NetworkPacket* pkt);
407 void handleCommand_HudSetSky(NetworkPacket* pkt);
408 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
409 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
410 void handleCommand_EyeOffset(NetworkPacket* pkt);
411 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
413 void ProcessData(NetworkPacket *pkt);
415 void Send(NetworkPacket* pkt);
417 void interact(u8 action, const PointedThing& pointed);
419 void sendNodemetaFields(v3s16 p, const std::string &formname,
420 const StringMap &fields);
421 void sendInventoryFields(const std::string &formname,
422 const StringMap &fields);
423 void sendInventoryAction(InventoryAction *a);
424 void sendChatMessage(const std::wstring &message);
425 void sendChangePassword(const std::string &oldpassword,
426 const std::string &newpassword);
427 void sendDamage(u8 damage);
428 void sendBreath(u16 breath);
432 ClientEnvironment& getEnv() { return m_env; }
433 ITextureSource *tsrc() { return getTextureSource(); }
434 ISoundManager *sound() { return getSoundManager(); }
435 static const std::string getBuiltinLuaPath();
437 virtual const std::vector<ModSpec> &getMods() const;
438 virtual const ModSpec* getModSpec(const std::string &modname) const;
440 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
441 void removeNode(v3s16 p);
442 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
444 void setPlayerControl(PlayerControl &control);
446 void selectPlayerItem(u16 item);
447 u16 getPlayerItem() const
448 { return m_playeritem; }
450 // Returns true if the inventory of the local player has been
451 // updated from the server. If it is true, it is set to false.
452 bool getLocalInventoryUpdated();
453 // Copies the inventory of the local player to parameter
454 void getLocalInventory(Inventory &dst);
456 /* InventoryManager interface */
457 Inventory* getInventory(const InventoryLocation &loc);
458 void inventoryAction(InventoryAction *a);
460 const std::list<std::string> &getConnectedPlayerNames()
462 return m_env.getPlayerNames();
465 float getAnimationTime();
468 void setCrack(int level, v3s16 pos);
472 bool checkPrivilege(const std::string &priv) const
473 { return (m_privileges.count(priv) != 0); }
475 bool getChatMessage(std::wstring &message);
476 void typeChatMessage(const std::wstring& message);
478 u64 getMapSeed(){ return m_map_seed; }
480 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
481 // Including blocks at appropriate edges
482 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
483 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
485 void updateCameraOffset(v3s16 camera_offset)
486 { m_mesh_update_thread.m_camera_offset = camera_offset; }
488 // Get event from queue. CE_NONE is returned if queue is empty.
489 ClientEvent getClientEvent();
492 { return m_access_denied; }
494 bool reconnectRequested() { return m_access_denied_reconnect; }
496 std::string accessDeniedReason()
497 { return m_access_denied_reason; }
499 bool itemdefReceived()
500 { return m_itemdef_received; }
501 bool nodedefReceived()
502 { return m_nodedef_received; }
504 { return m_media_downloader == NULL; }
507 { return m_proto_ver; }
509 bool connectedToServer()
510 { return m_con.Connected(); }
512 float mediaReceiveProgress();
514 void afterContentReceived(IrrlichtDevice *device);
517 float getCurRate(void);
518 float getAvgRate(void);
523 void setCamera(Camera* camera)
524 { m_camera = camera; }
529 bool isMinimapDisabledByServer()
530 { return m_minimap_disabled_by_server; }
532 // IGameDef interface
533 virtual IItemDefManager* getItemDefManager();
534 virtual INodeDefManager* getNodeDefManager();
535 virtual ICraftDefManager* getCraftDefManager();
536 ITextureSource* getTextureSource();
537 virtual IShaderSource* getShaderSource();
538 IShaderSource *shsrc() { return getShaderSource(); }
539 scene::ISceneManager* getSceneManager();
540 virtual u16 allocateUnknownNodeId(const std::string &name);
541 virtual ISoundManager* getSoundManager();
542 virtual MtEventManager* getEventManager();
543 virtual ParticleManager* getParticleManager();
544 bool checkLocalPrivilege(const std::string &priv)
545 { return checkPrivilege(priv); }
546 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
548 // The following set of functions is used by ClientMediaDownloader
549 // Insert a media file appropriately into the appropriate manager
550 bool loadMedia(const std::string &data, const std::string &filename);
551 // Send a request for conventional media transfer
552 void request_media(const std::vector<std::string> &file_requests);
553 // Send a notification that no conventional media transfer is needed
554 void received_media();
556 LocalClientState getState() { return m_state; }
558 void makeScreenshot(IrrlichtDevice *device);
562 // Virtual methods from con::PeerHandler
563 void peerAdded(con::Peer *peer);
564 void deletingPeer(con::Peer *peer, bool timeout);
566 void initLocalMapSaving(const Address &address,
567 const std::string &hostname,
568 bool is_local_server);
573 void sendPlayerPos();
574 // Send the item number 'item' as player item to the server
575 void sendPlayerItem(u16 item);
577 void deleteAuthData();
578 // helper method shared with clientpackethandler
579 static AuthMechanism choseAuthMech(const u32 mechs);
581 void sendLegacyInit(const char* playerName, const char* playerPassword);
582 void sendInit(const std::string &playerName);
583 void startAuth(AuthMechanism chosen_auth_mechanism);
584 void sendDeletedBlocks(std::vector<v3s16> &blocks);
585 void sendGotBlocks(v3s16 block);
586 void sendRemovedSounds(std::vector<s32> &soundList);
589 inline std::string getPlayerName()
590 { return m_env.getLocalPlayer()->getName(); }
592 float m_packetcounter_timer;
593 float m_connection_reinit_timer;
594 float m_avg_rtt_timer;
595 float m_playerpos_send_timer;
596 float m_ignore_damage_timer; // Used after server moves player
597 IntervalLimiter m_map_timer_and_unload_interval;
599 IWritableTextureSource *m_tsrc;
600 IWritableShaderSource *m_shsrc;
601 IWritableItemDefManager *m_itemdef;
602 IWritableNodeDefManager *m_nodedef;
603 ISoundManager *m_sound;
604 MtEventManager *m_event;
607 MeshUpdateThread m_mesh_update_thread;
608 ClientEnvironment m_env;
609 ParticleManager m_particle_manager;
610 con::Connection m_con;
611 IrrlichtDevice *m_device;
614 bool m_minimap_disabled_by_server;
615 // Server serialization version
618 // Used version of the protocol with server
619 // Values smaller than 25 only mean they are smaller than 25,
620 // and aren't accurate. We simply just don't know, because
621 // the server didn't send the version back then.
622 // If 0, server init hasn't been received yet.
626 bool m_inventory_updated;
627 Inventory *m_inventory_from_server;
628 float m_inventory_from_server_age;
629 PacketCounter m_packetcounter;
630 // Block mesh animation parameters
631 float m_animation_time;
634 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
636 //u32 m_daynight_ratio;
637 std::queue<std::wstring> m_chat_queue;
639 // The authentication methods we can use to enter sudo mode (=change password)
640 u32 m_sudo_auth_methods;
642 // The seed returned by the server in TOCLIENT_INIT is stored here
646 std::string m_playername;
647 std::string m_password;
648 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
649 std::string m_new_password;
650 // Usable by auth mechanisms.
651 AuthMechanism m_chosen_auth_mech;
655 bool m_access_denied;
656 bool m_access_denied_reconnect;
657 std::string m_access_denied_reason;
658 std::queue<ClientEvent> m_client_event_queue;
659 bool m_itemdef_received;
660 bool m_nodedef_received;
661 ClientMediaDownloader *m_media_downloader;
663 // time_of_day speed approximation for old protocol
664 bool m_time_of_day_set;
665 float m_last_time_of_day_f;
666 float m_time_of_day_update_timer;
668 // An interval for generally sending object positions and stuff
669 float m_recommended_send_interval;
672 float m_removed_sounds_check_timer;
673 // Mapping from server sound ids to our sound ids
674 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
675 // And the other way!
676 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
677 // And relations to objects
678 UNORDERED_MAP<int, u16> m_sounds_to_objects;
681 UNORDERED_SET<std::string> m_privileges;
683 // Detached inventories
685 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
687 // Storage for mesh data for creating multiple instances of the same mesh
688 StringMap m_mesh_data;
691 LocalClientState m_state;
693 // Used for saving server map to disk client-side
695 IntervalLimiter m_localdb_save_interval;
696 u16 m_cache_save_interval;
698 // TODO: Add callback to update these when g_settings changes
699 bool m_cache_smooth_lighting;
700 bool m_cache_enable_shaders;
701 bool m_cache_use_tangent_vertices;
703 ClientScripting *m_script;
705 DISABLE_CLASS_COPY(Client);
708 #endif // !CLIENT_HEADER