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"
41 class IWritableTextureSource;
42 class IWritableShaderSource;
43 class IWritableItemDefManager;
44 class IWritableNodeDefManager;
45 //class IWritableCraftDefManager;
46 class ClientMediaDownloader;
47 struct MapDrawControl;
52 struct MinimapMapblock;
56 struct QueuedMeshUpdate
60 bool ack_block_to_server;
66 enum LocalClientState {
73 A thread-safe queue of mesh update tasks
83 peer_id=0 adds with nobody to send to
85 void addBlock(v3s16 p, MeshMakeData *data,
86 bool ack_block_to_server, bool urgent);
88 // Returned pointer must be deleted
89 // Returns NULL if queue is empty
90 QueuedMeshUpdate * pop();
94 MutexAutoLock lock(m_mutex);
95 return m_queue.size();
99 std::vector<QueuedMeshUpdate*> m_queue;
100 std::set<v3s16> m_urgents;
104 struct MeshUpdateResult
108 bool ack_block_to_server;
111 p(-1338,-1338,-1338),
113 ack_block_to_server(false)
118 class MeshUpdateThread : public UpdateThread
121 MeshUpdateQueue m_queue_in;
124 virtual void doUpdate();
128 MeshUpdateThread() : UpdateThread("Mesh") {}
130 void enqueueUpdate(v3s16 p, MeshMakeData *data,
131 bool ack_block_to_server, bool urgent);
132 MutexedQueue<MeshUpdateResult> m_queue_out;
134 v3s16 m_camera_offset;
141 CE_PLAYER_FORCE_MOVE,
145 CE_ADD_PARTICLESPAWNER,
146 CE_DELETE_PARTICLESPAWNER,
151 CE_OVERRIDE_DAY_NIGHT_RATIO,
156 ClientEventType type;
168 bool set_camera_point_target;
169 f32 camera_point_target_x;
170 f32 camera_point_target_y;
171 f32 camera_point_target_z;
174 std::string *formspec;
175 std::string *formname;
178 //} textures_updated;
185 bool collisiondetection;
186 bool collision_removal;
188 std::string *texture;
203 bool collisiondetection;
204 bool collision_removal;
207 std::string *texture;
209 } add_particlespawner;
212 } delete_particlespawner;
241 video::SColor *bgcolor;
243 std::vector<std::string> *params;
248 } override_day_night_ratio;
263 void add(u16 command)
265 std::map<u16, u16>::iterator n = m_packets.find(command);
266 if(n == m_packets.end())
268 m_packets[command] = 1;
278 for(std::map<u16, u16>::iterator
279 i = m_packets.begin();
280 i != m_packets.end(); ++i)
286 void print(std::ostream &o)
288 for(std::map<u16, u16>::iterator
289 i = m_packets.begin();
290 i != m_packets.end(); ++i)
293 <<" count "<<i->second
300 std::map<u16, u16> m_packets;
303 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
307 NOTE: Nothing is thread-safe here.
311 IrrlichtDevice *device,
312 const char *playername,
313 std::string password,
314 MapDrawControl &control,
315 IWritableTextureSource *tsrc,
316 IWritableShaderSource *shsrc,
317 IWritableItemDefManager *itemdef,
318 IWritableNodeDefManager *nodedef,
319 ISoundManager *sound,
320 MtEventManager *event,
327 request all threads managed by client to be stopped
335 The name of the local player should already be set when
336 calling this, as it is sent in the initialization.
338 void connect(Address address,
339 const std::string &address_name,
340 bool is_local_server);
343 Stuff that references the environment is valid only as
344 long as this is not called. (eg. Players)
345 If this throws a PeerNotFoundException, the connection has
348 void step(float dtime);
354 void handleCommand(NetworkPacket* pkt);
356 void handleCommand_Null(NetworkPacket* pkt) {};
357 void handleCommand_Deprecated(NetworkPacket* pkt);
358 void handleCommand_Hello(NetworkPacket* pkt);
359 void handleCommand_AuthAccept(NetworkPacket* pkt);
360 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
361 void handleCommand_DenySudoMode(NetworkPacket* pkt);
362 void handleCommand_InitLegacy(NetworkPacket* pkt);
363 void handleCommand_AccessDenied(NetworkPacket* pkt);
364 void handleCommand_RemoveNode(NetworkPacket* pkt);
365 void handleCommand_AddNode(NetworkPacket* pkt);
366 void handleCommand_BlockData(NetworkPacket* pkt);
367 void handleCommand_Inventory(NetworkPacket* pkt);
368 void handleCommand_TimeOfDay(NetworkPacket* pkt);
369 void handleCommand_ChatMessage(NetworkPacket* pkt);
370 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
371 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
372 void handleCommand_Movement(NetworkPacket* pkt);
373 void handleCommand_HP(NetworkPacket* pkt);
374 void handleCommand_Breath(NetworkPacket* pkt);
375 void handleCommand_MovePlayer(NetworkPacket* pkt);
376 void handleCommand_PlayerItem(NetworkPacket* pkt);
377 void handleCommand_DeathScreen(NetworkPacket* pkt);
378 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
379 void handleCommand_Media(NetworkPacket* pkt);
380 void handleCommand_ToolDef(NetworkPacket* pkt);
381 void handleCommand_NodeDef(NetworkPacket* pkt);
382 void handleCommand_CraftItemDef(NetworkPacket* pkt);
383 void handleCommand_ItemDef(NetworkPacket* pkt);
384 void handleCommand_PlaySound(NetworkPacket* pkt);
385 void handleCommand_StopSound(NetworkPacket* pkt);
386 void handleCommand_Privileges(NetworkPacket* pkt);
387 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
388 void handleCommand_DetachedInventory(NetworkPacket* pkt);
389 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
390 void handleCommand_SpawnParticle(NetworkPacket* pkt);
391 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
392 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
393 void handleCommand_HudAdd(NetworkPacket* pkt);
394 void handleCommand_HudRemove(NetworkPacket* pkt);
395 void handleCommand_HudChange(NetworkPacket* pkt);
396 void handleCommand_HudSetFlags(NetworkPacket* pkt);
397 void handleCommand_HudSetParam(NetworkPacket* pkt);
398 void handleCommand_HudSetSky(NetworkPacket* pkt);
399 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
400 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
401 void handleCommand_EyeOffset(NetworkPacket* pkt);
402 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
404 void ProcessData(NetworkPacket *pkt);
406 void Send(NetworkPacket* pkt);
408 void interact(u8 action, const PointedThing& pointed);
410 void sendNodemetaFields(v3s16 p, const std::string &formname,
411 const StringMap &fields);
412 void sendInventoryFields(const std::string &formname,
413 const StringMap &fields);
414 void sendInventoryAction(InventoryAction *a);
415 void sendChatMessage(const std::wstring &message);
416 void sendChangePassword(const std::string &oldpassword,
417 const std::string &newpassword);
418 void sendDamage(u8 damage);
419 void sendBreath(u16 breath);
423 ClientEnvironment& getEnv() { return m_env; }
424 ITextureSource *tsrc() { return getTextureSource(); }
425 ISoundManager *sound() { return getSoundManager(); }
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 const std::list<std::string> &getConnectedPlayerNames()
449 return m_env.getPlayerNames();
452 float getAnimationTime();
455 void setCrack(int level, v3s16 pos);
459 bool checkPrivilege(const std::string &priv) const
460 { return (m_privileges.count(priv) != 0); }
462 bool getChatMessage(std::wstring &message);
463 void typeChatMessage(const std::wstring& message);
465 u64 getMapSeed(){ return m_map_seed; }
467 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
468 // Including blocks at appropriate edges
469 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
470 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
472 void updateCameraOffset(v3s16 camera_offset)
473 { m_mesh_update_thread.m_camera_offset = camera_offset; }
475 // Get event from queue. CE_NONE is returned if queue is empty.
476 ClientEvent getClientEvent();
479 { return m_access_denied; }
481 bool reconnectRequested() { return m_access_denied_reconnect; }
483 std::string accessDeniedReason()
484 { return m_access_denied_reason; }
486 bool itemdefReceived()
487 { return m_itemdef_received; }
488 bool nodedefReceived()
489 { return m_nodedef_received; }
491 { return m_media_downloader == NULL; }
494 { return m_proto_ver; }
496 bool connectedToServer()
497 { return m_con.Connected(); }
499 float mediaReceiveProgress();
501 void afterContentReceived(IrrlichtDevice *device);
504 float getCurRate(void);
505 float getAvgRate(void);
510 void setCamera(Camera* camera)
511 { m_camera = camera; }
516 bool isMinimapDisabledByServer()
517 { return m_minimap_disabled_by_server; }
519 // IGameDef interface
520 virtual IItemDefManager* getItemDefManager();
521 virtual INodeDefManager* getNodeDefManager();
522 virtual ICraftDefManager* getCraftDefManager();
523 ITextureSource* getTextureSource();
524 virtual IShaderSource* getShaderSource();
525 IShaderSource *shsrc() { return getShaderSource(); }
526 scene::ISceneManager* getSceneManager();
527 virtual u16 allocateUnknownNodeId(const std::string &name);
528 virtual ISoundManager* getSoundManager();
529 virtual MtEventManager* getEventManager();
530 virtual ParticleManager* getParticleManager();
531 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