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;
205 std::string *texture;
207 } add_particlespawner;
210 } delete_particlespawner;
239 video::SColor *bgcolor;
241 std::vector<std::string> *params;
246 } override_day_night_ratio;
261 void add(u16 command)
263 std::map<u16, u16>::iterator n = m_packets.find(command);
264 if(n == m_packets.end())
266 m_packets[command] = 1;
276 for(std::map<u16, u16>::iterator
277 i = m_packets.begin();
278 i != m_packets.end(); ++i)
284 void print(std::ostream &o)
286 for(std::map<u16, u16>::iterator
287 i = m_packets.begin();
288 i != m_packets.end(); ++i)
291 <<" count "<<i->second
298 std::map<u16, u16> m_packets;
301 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
305 NOTE: Nothing is thread-safe here.
309 IrrlichtDevice *device,
310 const char *playername,
311 std::string password,
312 MapDrawControl &control,
313 IWritableTextureSource *tsrc,
314 IWritableShaderSource *shsrc,
315 IWritableItemDefManager *itemdef,
316 IWritableNodeDefManager *nodedef,
317 ISoundManager *sound,
318 MtEventManager *event,
325 request all threads managed by client to be stopped
333 The name of the local player should already be set when
334 calling this, as it is sent in the initialization.
336 void connect(Address address,
337 const std::string &address_name,
338 bool is_local_server);
341 Stuff that references the environment is valid only as
342 long as this is not called. (eg. Players)
343 If this throws a PeerNotFoundException, the connection has
346 void step(float dtime);
352 void handleCommand(NetworkPacket* pkt);
354 void handleCommand_Null(NetworkPacket* pkt) {};
355 void handleCommand_Deprecated(NetworkPacket* pkt);
356 void handleCommand_Hello(NetworkPacket* pkt);
357 void handleCommand_AuthAccept(NetworkPacket* pkt);
358 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
359 void handleCommand_DenySudoMode(NetworkPacket* pkt);
360 void handleCommand_InitLegacy(NetworkPacket* pkt);
361 void handleCommand_AccessDenied(NetworkPacket* pkt);
362 void handleCommand_RemoveNode(NetworkPacket* pkt);
363 void handleCommand_AddNode(NetworkPacket* pkt);
364 void handleCommand_BlockData(NetworkPacket* pkt);
365 void handleCommand_Inventory(NetworkPacket* pkt);
366 void handleCommand_TimeOfDay(NetworkPacket* pkt);
367 void handleCommand_ChatMessage(NetworkPacket* pkt);
368 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
369 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
370 void handleCommand_Movement(NetworkPacket* pkt);
371 void handleCommand_HP(NetworkPacket* pkt);
372 void handleCommand_Breath(NetworkPacket* pkt);
373 void handleCommand_MovePlayer(NetworkPacket* pkt);
374 void handleCommand_PlayerItem(NetworkPacket* pkt);
375 void handleCommand_DeathScreen(NetworkPacket* pkt);
376 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
377 void handleCommand_Media(NetworkPacket* pkt);
378 void handleCommand_ToolDef(NetworkPacket* pkt);
379 void handleCommand_NodeDef(NetworkPacket* pkt);
380 void handleCommand_CraftItemDef(NetworkPacket* pkt);
381 void handleCommand_ItemDef(NetworkPacket* pkt);
382 void handleCommand_PlaySound(NetworkPacket* pkt);
383 void handleCommand_StopSound(NetworkPacket* pkt);
384 void handleCommand_Privileges(NetworkPacket* pkt);
385 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
386 void handleCommand_DetachedInventory(NetworkPacket* pkt);
387 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
388 void handleCommand_SpawnParticle(NetworkPacket* pkt);
389 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
390 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
391 void handleCommand_HudAdd(NetworkPacket* pkt);
392 void handleCommand_HudRemove(NetworkPacket* pkt);
393 void handleCommand_HudChange(NetworkPacket* pkt);
394 void handleCommand_HudSetFlags(NetworkPacket* pkt);
395 void handleCommand_HudSetParam(NetworkPacket* pkt);
396 void handleCommand_HudSetSky(NetworkPacket* pkt);
397 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
398 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
399 void handleCommand_EyeOffset(NetworkPacket* pkt);
400 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
402 void ProcessData(NetworkPacket *pkt);
404 // Returns true if something was received
405 bool AsyncProcessPacket();
406 bool AsyncProcessData();
407 void Send(NetworkPacket* pkt);
409 void interact(u8 action, const PointedThing& pointed);
411 void sendNodemetaFields(v3s16 p, const std::string &formname,
412 const StringMap &fields);
413 void sendInventoryFields(const std::string &formname,
414 const StringMap &fields);
415 void sendInventoryAction(InventoryAction *a);
416 void sendChatMessage(const std::wstring &message);
417 void sendChangePassword(const std::string &oldpassword,
418 const std::string &newpassword);
419 void sendDamage(u8 damage);
420 void sendBreath(u16 breath);
424 ClientEnvironment& getEnv()
427 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
428 void removeNode(v3s16 p);
429 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
431 void setPlayerControl(PlayerControl &control);
433 void selectPlayerItem(u16 item);
434 u16 getPlayerItem() const
435 { return m_playeritem; }
437 // Returns true if the inventory of the local player has been
438 // updated from the server. If it is true, it is set to false.
439 bool getLocalInventoryUpdated();
440 // Copies the inventory of the local player to parameter
441 void getLocalInventory(Inventory &dst);
443 /* InventoryManager interface */
444 Inventory* getInventory(const InventoryLocation &loc);
445 void inventoryAction(InventoryAction *a);
447 // Gets closest object pointed by the shootline
448 // Returns NULL if not found
449 ClientActiveObject * getSelectedActiveObject(
451 v3f from_pos_f_on_map,
452 core::line3d<f32> shootline_on_map
455 std::list<std::string> getConnectedPlayerNames();
457 float getAnimationTime();
460 void setCrack(int level, v3s16 pos);
464 bool checkPrivilege(const std::string &priv) const
465 { return (m_privileges.count(priv) != 0); }
467 bool getChatMessage(std::wstring &message);
468 void typeChatMessage(const std::wstring& message);
470 u64 getMapSeed(){ return m_map_seed; }
472 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
473 // Including blocks at appropriate edges
474 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
475 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
477 void updateCameraOffset(v3s16 camera_offset)
478 { m_mesh_update_thread.m_camera_offset = camera_offset; }
480 // Get event from queue. CE_NONE is returned if queue is empty.
481 ClientEvent getClientEvent();
484 { return m_access_denied; }
486 bool reconnectRequested() { return m_access_denied_reconnect; }
488 std::string accessDeniedReason()
489 { return m_access_denied_reason; }
491 bool itemdefReceived()
492 { return m_itemdef_received; }
493 bool nodedefReceived()
494 { return m_nodedef_received; }
496 { return m_media_downloader == NULL; }
499 { return m_proto_ver; }
501 bool connectedToServer()
502 { return m_con.Connected(); }
504 float mediaReceiveProgress();
506 void afterContentReceived(IrrlichtDevice *device);
509 float getCurRate(void);
510 float getAvgRate(void);
515 void setCamera(Camera* camera)
516 { m_camera = camera; }
521 bool isMinimapDisabledByServer()
522 { return m_minimap_disabled_by_server; }
524 // IGameDef interface
525 virtual IItemDefManager* getItemDefManager();
526 virtual INodeDefManager* getNodeDefManager();
527 virtual ICraftDefManager* getCraftDefManager();
528 virtual ITextureSource* getTextureSource();
529 virtual IShaderSource* getShaderSource();
530 virtual scene::ISceneManager* getSceneManager();
531 virtual u16 allocateUnknownNodeId(const std::string &name);
532 virtual ISoundManager* getSoundManager();
533 virtual MtEventManager* getEventManager();
534 virtual ParticleManager* getParticleManager();
535 virtual bool checkLocalPrivilege(const std::string &priv)
536 { return checkPrivilege(priv); }
537 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
539 // The following set of functions is used by ClientMediaDownloader
540 // Insert a media file appropriately into the appropriate manager
541 bool loadMedia(const std::string &data, const std::string &filename);
542 // Send a request for conventional media transfer
543 void request_media(const std::vector<std::string> &file_requests);
544 // Send a notification that no conventional media transfer is needed
545 void received_media();
547 LocalClientState getState() { return m_state; }
549 void makeScreenshot(IrrlichtDevice *device);
553 // Virtual methods from con::PeerHandler
554 void peerAdded(con::Peer *peer);
555 void deletingPeer(con::Peer *peer, bool timeout);
557 void initLocalMapSaving(const Address &address,
558 const std::string &hostname,
559 bool is_local_server);
564 void sendPlayerPos();
565 // Send the item number 'item' as player item to the server
566 void sendPlayerItem(u16 item);
568 void deleteAuthData();
569 // helper method shared with clientpackethandler
570 static AuthMechanism choseAuthMech(const u32 mechs);
572 void sendLegacyInit(const char* playerName, const char* playerPassword);
573 void sendInit(const std::string &playerName);
574 void startAuth(AuthMechanism chosen_auth_mechanism);
575 void sendDeletedBlocks(std::vector<v3s16> &blocks);
576 void sendGotBlocks(v3s16 block);
577 void sendRemovedSounds(std::vector<s32> &soundList);
580 inline std::string getPlayerName()
581 { return m_env.getLocalPlayer()->getName(); }
583 float m_packetcounter_timer;
584 float m_connection_reinit_timer;
585 float m_avg_rtt_timer;
586 float m_playerpos_send_timer;
587 float m_ignore_damage_timer; // Used after server moves player
588 IntervalLimiter m_map_timer_and_unload_interval;
590 IWritableTextureSource *m_tsrc;
591 IWritableShaderSource *m_shsrc;
592 IWritableItemDefManager *m_itemdef;
593 IWritableNodeDefManager *m_nodedef;
594 ISoundManager *m_sound;
595 MtEventManager *m_event;
598 MeshUpdateThread m_mesh_update_thread;
599 ClientEnvironment m_env;
600 ParticleManager m_particle_manager;
601 con::Connection m_con;
602 IrrlichtDevice *m_device;
605 bool m_minimap_disabled_by_server;
606 // Server serialization version
609 // Used version of the protocol with server
610 // Values smaller than 25 only mean they are smaller than 25,
611 // and aren't accurate. We simply just don't know, because
612 // the server didn't send the version back then.
613 // If 0, server init hasn't been received yet.
617 bool m_inventory_updated;
618 Inventory *m_inventory_from_server;
619 float m_inventory_from_server_age;
620 PacketCounter m_packetcounter;
621 // Block mesh animation parameters
622 float m_animation_time;
625 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
627 //u32 m_daynight_ratio;
628 std::queue<std::wstring> m_chat_queue;
630 // The authentication methods we can use to enter sudo mode (=change password)
631 u32 m_sudo_auth_methods;
633 // The seed returned by the server in TOCLIENT_INIT is stored here
637 std::string m_playername;
638 std::string m_password;
639 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
640 std::string m_new_password;
641 // Usable by auth mechanisms.
642 AuthMechanism m_chosen_auth_mech;
646 bool m_access_denied;
647 bool m_access_denied_reconnect;
648 std::string m_access_denied_reason;
649 std::queue<ClientEvent> m_client_event_queue;
650 bool m_itemdef_received;
651 bool m_nodedef_received;
652 ClientMediaDownloader *m_media_downloader;
654 // time_of_day speed approximation for old protocol
655 bool m_time_of_day_set;
656 float m_last_time_of_day_f;
657 float m_time_of_day_update_timer;
659 // An interval for generally sending object positions and stuff
660 float m_recommended_send_interval;
663 float m_removed_sounds_check_timer;
664 // Mapping from server sound ids to our sound ids
665 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
666 // And the other way!
667 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
668 // And relations to objects
669 UNORDERED_MAP<int, u16> m_sounds_to_objects;
672 UNORDERED_SET<std::string> m_privileges;
674 // Detached inventories
676 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
678 // Storage for mesh data for creating multiple instances of the same mesh
679 StringMap m_mesh_data;
682 LocalClientState m_state;
684 // Used for saving server map to disk client-side
686 IntervalLimiter m_localdb_save_interval;
687 u16 m_cache_save_interval;
689 // TODO: Add callback to update these when g_settings changes
690 bool m_cache_smooth_lighting;
691 bool m_cache_enable_shaders;
692 bool m_cache_use_tangent_vertices;
694 DISABLE_CLASS_COPY(Client);
697 #endif // !CLIENT_HEADER