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 "environment.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"
37 #include "network/networkpacket.h"
41 class IWritableTextureSource;
42 class IWritableShaderSource;
43 class IWritableItemDefManager;
44 class IWritableNodeDefManager;
45 //class IWritableCraftDefManager;
46 class ClientMediaDownloader;
47 struct MapDrawControl;
52 struct MinimapMapblock;
55 struct QueuedMeshUpdate
59 bool ack_block_to_server;
65 enum LocalClientState {
72 A thread-safe queue of mesh update tasks
82 peer_id=0 adds with nobody to send to
84 void addBlock(v3s16 p, MeshMakeData *data,
85 bool ack_block_to_server, bool urgent);
87 // Returned pointer must be deleted
88 // Returns NULL if queue is empty
89 QueuedMeshUpdate * pop();
93 MutexAutoLock lock(m_mutex);
94 return m_queue.size();
98 std::vector<QueuedMeshUpdate*> m_queue;
99 std::set<v3s16> m_urgents;
103 struct MeshUpdateResult
107 bool ack_block_to_server;
110 p(-1338,-1338,-1338),
112 ack_block_to_server(false)
117 class MeshUpdateThread : public UpdateThread
120 MeshUpdateQueue m_queue_in;
123 virtual void doUpdate();
127 MeshUpdateThread() : UpdateThread("Mesh") {}
129 void enqueueUpdate(v3s16 p, MeshMakeData *data,
130 bool ack_block_to_server, bool urgent);
131 MutexedQueue<MeshUpdateResult> m_queue_out;
133 v3s16 m_camera_offset;
140 CE_PLAYER_FORCE_MOVE,
144 CE_ADD_PARTICLESPAWNER,
145 CE_DELETE_PARTICLESPAWNER,
150 CE_OVERRIDE_DAY_NIGHT_RATIO,
155 ClientEventType type;
167 bool set_camera_point_target;
168 f32 camera_point_target_x;
169 f32 camera_point_target_y;
170 f32 camera_point_target_z;
173 std::string *formspec;
174 std::string *formname;
177 //} textures_updated;
184 bool collisiondetection;
185 bool collision_removal;
187 std::string *texture;
202 bool collisiondetection;
203 bool collision_removal;
206 std::string *texture;
208 } add_particlespawner;
211 } delete_particlespawner;
240 video::SColor *bgcolor;
242 std::vector<std::string> *params;
247 } override_day_night_ratio;
262 void add(u16 command)
264 std::map<u16, u16>::iterator n = m_packets.find(command);
265 if(n == m_packets.end())
267 m_packets[command] = 1;
277 for(std::map<u16, u16>::iterator
278 i = m_packets.begin();
279 i != m_packets.end(); ++i)
285 void print(std::ostream &o)
287 for(std::map<u16, u16>::iterator
288 i = m_packets.begin();
289 i != m_packets.end(); ++i)
292 <<" count "<<i->second
299 std::map<u16, u16> m_packets;
302 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
306 NOTE: Nothing is thread-safe here.
310 IrrlichtDevice *device,
311 const char *playername,
312 std::string password,
313 MapDrawControl &control,
314 IWritableTextureSource *tsrc,
315 IWritableShaderSource *shsrc,
316 IWritableItemDefManager *itemdef,
317 IWritableNodeDefManager *nodedef,
318 ISoundManager *sound,
319 MtEventManager *event,
326 request all threads managed by client to be stopped
334 The name of the local player should already be set when
335 calling this, as it is sent in the initialization.
337 void connect(Address address,
338 const std::string &address_name,
339 bool is_local_server);
342 Stuff that references the environment is valid only as
343 long as this is not called. (eg. Players)
344 If this throws a PeerNotFoundException, the connection has
347 void step(float dtime);
353 void handleCommand(NetworkPacket* pkt);
355 void handleCommand_Null(NetworkPacket* pkt) {};
356 void handleCommand_Deprecated(NetworkPacket* pkt);
357 void handleCommand_Hello(NetworkPacket* pkt);
358 void handleCommand_AuthAccept(NetworkPacket* pkt);
359 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
360 void handleCommand_DenySudoMode(NetworkPacket* pkt);
361 void handleCommand_InitLegacy(NetworkPacket* pkt);
362 void handleCommand_AccessDenied(NetworkPacket* pkt);
363 void handleCommand_RemoveNode(NetworkPacket* pkt);
364 void handleCommand_AddNode(NetworkPacket* pkt);
365 void handleCommand_BlockData(NetworkPacket* pkt);
366 void handleCommand_Inventory(NetworkPacket* pkt);
367 void handleCommand_TimeOfDay(NetworkPacket* pkt);
368 void handleCommand_ChatMessage(NetworkPacket* pkt);
369 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
370 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
371 void handleCommand_Movement(NetworkPacket* pkt);
372 void handleCommand_HP(NetworkPacket* pkt);
373 void handleCommand_Breath(NetworkPacket* pkt);
374 void handleCommand_MovePlayer(NetworkPacket* pkt);
375 void handleCommand_PlayerItem(NetworkPacket* pkt);
376 void handleCommand_DeathScreen(NetworkPacket* pkt);
377 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
378 void handleCommand_Media(NetworkPacket* pkt);
379 void handleCommand_ToolDef(NetworkPacket* pkt);
380 void handleCommand_NodeDef(NetworkPacket* pkt);
381 void handleCommand_CraftItemDef(NetworkPacket* pkt);
382 void handleCommand_ItemDef(NetworkPacket* pkt);
383 void handleCommand_PlaySound(NetworkPacket* pkt);
384 void handleCommand_StopSound(NetworkPacket* pkt);
385 void handleCommand_Privileges(NetworkPacket* pkt);
386 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
387 void handleCommand_DetachedInventory(NetworkPacket* pkt);
388 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
389 void handleCommand_SpawnParticle(NetworkPacket* pkt);
390 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
391 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
392 void handleCommand_HudAdd(NetworkPacket* pkt);
393 void handleCommand_HudRemove(NetworkPacket* pkt);
394 void handleCommand_HudChange(NetworkPacket* pkt);
395 void handleCommand_HudSetFlags(NetworkPacket* pkt);
396 void handleCommand_HudSetParam(NetworkPacket* pkt);
397 void handleCommand_HudSetSky(NetworkPacket* pkt);
398 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
399 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
400 void handleCommand_EyeOffset(NetworkPacket* pkt);
401 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
403 void ProcessData(NetworkPacket *pkt);
405 // Returns true if something was received
406 bool AsyncProcessPacket();
407 bool AsyncProcessData();
408 void Send(NetworkPacket* pkt);
410 void interact(u8 action, const PointedThing& pointed);
412 void sendNodemetaFields(v3s16 p, const std::string &formname,
413 const StringMap &fields);
414 void sendInventoryFields(const std::string &formname,
415 const StringMap &fields);
416 void sendInventoryAction(InventoryAction *a);
417 void sendChatMessage(const std::wstring &message);
418 void sendChangePassword(const std::string &oldpassword,
419 const std::string &newpassword);
420 void sendDamage(u8 damage);
421 void sendBreath(u16 breath);
425 ClientEnvironment& getEnv()
428 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
429 void removeNode(v3s16 p);
430 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
432 void setPlayerControl(PlayerControl &control);
434 void selectPlayerItem(u16 item);
435 u16 getPlayerItem() const
436 { return m_playeritem; }
438 // Returns true if the inventory of the local player has been
439 // updated from the server. If it is true, it is set to false.
440 bool getLocalInventoryUpdated();
441 // Copies the inventory of the local player to parameter
442 void getLocalInventory(Inventory &dst);
444 /* InventoryManager interface */
445 Inventory* getInventory(const InventoryLocation &loc);
446 void inventoryAction(InventoryAction *a);
448 const std::list<std::string> &getConnectedPlayerNames()
450 return m_env.getPlayerNames();
453 float getAnimationTime();
456 void setCrack(int level, v3s16 pos);
460 bool checkPrivilege(const std::string &priv) const
461 { return (m_privileges.count(priv) != 0); }
463 bool getChatMessage(std::wstring &message);
464 void typeChatMessage(const std::wstring& message);
466 u64 getMapSeed(){ return m_map_seed; }
468 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
469 // Including blocks at appropriate edges
470 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
471 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
473 void updateCameraOffset(v3s16 camera_offset)
474 { m_mesh_update_thread.m_camera_offset = camera_offset; }
476 // Get event from queue. CE_NONE is returned if queue is empty.
477 ClientEvent getClientEvent();
480 { return m_access_denied; }
482 bool reconnectRequested() { return m_access_denied_reconnect; }
484 std::string accessDeniedReason()
485 { return m_access_denied_reason; }
487 bool itemdefReceived()
488 { return m_itemdef_received; }
489 bool nodedefReceived()
490 { return m_nodedef_received; }
492 { return m_media_downloader == NULL; }
495 { return m_proto_ver; }
497 bool connectedToServer()
498 { return m_con.Connected(); }
500 float mediaReceiveProgress();
502 void afterContentReceived(IrrlichtDevice *device);
505 float getCurRate(void);
506 float getAvgRate(void);
511 void setCamera(Camera* camera)
512 { m_camera = camera; }
517 bool isMinimapDisabledByServer()
518 { return m_minimap_disabled_by_server; }
520 // IGameDef interface
521 virtual IItemDefManager* getItemDefManager();
522 virtual INodeDefManager* getNodeDefManager();
523 virtual ICraftDefManager* getCraftDefManager();
524 virtual ITextureSource* getTextureSource();
525 virtual IShaderSource* getShaderSource();
526 virtual scene::ISceneManager* getSceneManager();
527 virtual u16 allocateUnknownNodeId(const std::string &name);
528 virtual ISoundManager* getSoundManager();
529 virtual MtEventManager* getEventManager();
530 virtual ParticleManager* getParticleManager();
531 virtual bool checkLocalPrivilege(const std::string &priv)
532 { return checkPrivilege(priv); }
533 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
535 // The following set of functions is used by ClientMediaDownloader
536 // Insert a media file appropriately into the appropriate manager
537 bool loadMedia(const std::string &data, const std::string &filename);
538 // Send a request for conventional media transfer
539 void request_media(const std::vector<std::string> &file_requests);
540 // Send a notification that no conventional media transfer is needed
541 void received_media();
543 LocalClientState getState() { return m_state; }
545 void makeScreenshot(IrrlichtDevice *device);
549 // Virtual methods from con::PeerHandler
550 void peerAdded(con::Peer *peer);
551 void deletingPeer(con::Peer *peer, bool timeout);
553 void initLocalMapSaving(const Address &address,
554 const std::string &hostname,
555 bool is_local_server);
560 void sendPlayerPos();
561 // Send the item number 'item' as player item to the server
562 void sendPlayerItem(u16 item);
564 void deleteAuthData();
565 // helper method shared with clientpackethandler
566 static AuthMechanism choseAuthMech(const u32 mechs);
568 void sendLegacyInit(const char* playerName, const char* playerPassword);
569 void sendInit(const std::string &playerName);
570 void startAuth(AuthMechanism chosen_auth_mechanism);
571 void sendDeletedBlocks(std::vector<v3s16> &blocks);
572 void sendGotBlocks(v3s16 block);
573 void sendRemovedSounds(std::vector<s32> &soundList);
576 inline std::string getPlayerName()
577 { return m_env.getLocalPlayer()->getName(); }
579 float m_packetcounter_timer;
580 float m_connection_reinit_timer;
581 float m_avg_rtt_timer;
582 float m_playerpos_send_timer;
583 float m_ignore_damage_timer; // Used after server moves player
584 IntervalLimiter m_map_timer_and_unload_interval;
586 IWritableTextureSource *m_tsrc;
587 IWritableShaderSource *m_shsrc;
588 IWritableItemDefManager *m_itemdef;
589 IWritableNodeDefManager *m_nodedef;
590 ISoundManager *m_sound;
591 MtEventManager *m_event;
594 MeshUpdateThread m_mesh_update_thread;
595 ClientEnvironment m_env;
596 ParticleManager m_particle_manager;
597 con::Connection m_con;
598 IrrlichtDevice *m_device;
601 bool m_minimap_disabled_by_server;
602 // Server serialization version
605 // Used version of the protocol with server
606 // Values smaller than 25 only mean they are smaller than 25,
607 // and aren't accurate. We simply just don't know, because
608 // the server didn't send the version back then.
609 // If 0, server init hasn't been received yet.
613 bool m_inventory_updated;
614 Inventory *m_inventory_from_server;
615 float m_inventory_from_server_age;
616 PacketCounter m_packetcounter;
617 // Block mesh animation parameters
618 float m_animation_time;
621 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
623 //u32 m_daynight_ratio;
624 std::queue<std::wstring> m_chat_queue;
626 // The authentication methods we can use to enter sudo mode (=change password)
627 u32 m_sudo_auth_methods;
629 // The seed returned by the server in TOCLIENT_INIT is stored here
633 std::string m_playername;
634 std::string m_password;
635 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
636 std::string m_new_password;
637 // Usable by auth mechanisms.
638 AuthMechanism m_chosen_auth_mech;
642 bool m_access_denied;
643 bool m_access_denied_reconnect;
644 std::string m_access_denied_reason;
645 std::queue<ClientEvent> m_client_event_queue;
646 bool m_itemdef_received;
647 bool m_nodedef_received;
648 ClientMediaDownloader *m_media_downloader;
650 // time_of_day speed approximation for old protocol
651 bool m_time_of_day_set;
652 float m_last_time_of_day_f;
653 float m_time_of_day_update_timer;
655 // An interval for generally sending object positions and stuff
656 float m_recommended_send_interval;
659 float m_removed_sounds_check_timer;
660 // Mapping from server sound ids to our sound ids
661 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
662 // And the other way!
663 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
664 // And relations to objects
665 UNORDERED_MAP<int, u16> m_sounds_to_objects;
668 UNORDERED_SET<std::string> m_privileges;
670 // Detached inventories
672 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
674 // Storage for mesh data for creating multiple instances of the same mesh
675 StringMap m_mesh_data;
678 LocalClientState m_state;
680 // Used for saving server map to disk client-side
682 IntervalLimiter m_localdb_save_interval;
683 u16 m_cache_save_interval;
685 // TODO: Add callback to update these when g_settings changes
686 bool m_cache_smooth_lighting;
687 bool m_cache_enable_shaders;
688 bool m_cache_use_tangent_vertices;
690 DISABLE_CLASS_COPY(Client);
693 #endif // !CLIENT_HEADER