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 "jthread/jmutex.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;
54 struct QueuedMeshUpdate
58 bool ack_block_to_server;
64 enum LocalClientState {
71 A thread-safe queue of mesh update tasks
81 peer_id=0 adds with nobody to send to
83 void addBlock(v3s16 p, MeshMakeData *data,
84 bool ack_block_to_server, bool urgent);
86 // Returned pointer must be deleted
87 // Returns NULL if queue is empty
88 QueuedMeshUpdate * pop();
92 JMutexAutoLock lock(m_mutex);
93 return m_queue.size();
97 std::vector<QueuedMeshUpdate*> m_queue;
98 std::set<v3s16> m_urgents;
102 struct MeshUpdateResult
106 bool ack_block_to_server;
109 p(-1338,-1338,-1338),
111 ack_block_to_server(false)
116 class MeshUpdateThread : public UpdateThread
119 MeshUpdateQueue m_queue_in;
122 const char *getName()
123 { return "MeshUpdateThread"; }
124 virtual void doUpdate();
132 void enqueueUpdate(v3s16 p, MeshMakeData *data,
133 bool ack_block_to_server, bool urgent);
135 MutexedQueue<MeshUpdateResult> m_queue_out;
137 v3s16 m_camera_offset;
144 CE_PLAYER_FORCE_MOVE,
148 CE_ADD_PARTICLESPAWNER,
149 CE_DELETE_PARTICLESPAWNER,
154 CE_OVERRIDE_DAY_NIGHT_RATIO,
159 ClientEventType type;
171 bool set_camera_point_target;
172 f32 camera_point_target_x;
173 f32 camera_point_target_y;
174 f32 camera_point_target_z;
177 std::string *formspec;
178 std::string *formname;
181 //} textures_updated;
188 bool collisiondetection;
190 std::string *texture;
205 bool collisiondetection;
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 // Returns true if something was received
407 bool AsyncProcessPacket();
408 bool AsyncProcessData();
409 void Send(NetworkPacket* pkt);
411 void interact(u8 action, const PointedThing& pointed);
413 void sendNodemetaFields(v3s16 p, const std::string &formname,
414 const StringMap &fields);
415 void sendInventoryFields(const std::string &formname,
416 const StringMap &fields);
417 void sendInventoryAction(InventoryAction *a);
418 void sendChatMessage(const std::wstring &message);
419 void sendChangePassword(const std::string &oldpassword,
420 const std::string &newpassword);
421 void sendDamage(u8 damage);
422 void sendBreath(u16 breath);
426 ClientEnvironment& getEnv()
429 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
430 void removeNode(v3s16 p);
431 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
433 void setPlayerControl(PlayerControl &control);
435 void selectPlayerItem(u16 item);
436 u16 getPlayerItem() const
437 { return m_playeritem; }
439 // Returns true if the inventory of the local player has been
440 // updated from the server. If it is true, it is set to false.
441 bool getLocalInventoryUpdated();
442 // Copies the inventory of the local player to parameter
443 void getLocalInventory(Inventory &dst);
445 /* InventoryManager interface */
446 Inventory* getInventory(const InventoryLocation &loc);
447 void inventoryAction(InventoryAction *a);
449 // Gets closest object pointed by the shootline
450 // Returns NULL if not found
451 ClientActiveObject * getSelectedActiveObject(
453 v3f from_pos_f_on_map,
454 core::line3d<f32> shootline_on_map
457 std::list<std::string> getConnectedPlayerNames();
459 float getAnimationTime();
462 void setCrack(int level, v3s16 pos);
464 void setHighlighted(v3s16 pos, bool show_higlighted);
465 v3s16 getHighlighted(){ return m_highlighted_pos; }
470 bool checkPrivilege(const std::string &priv)
471 { return (m_privileges.count(priv) != 0); }
473 bool getChatMessage(std::wstring &message);
474 void typeChatMessage(const std::wstring& message);
476 u64 getMapSeed(){ return m_map_seed; }
478 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
479 // Including blocks at appropriate edges
480 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
481 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
483 void updateCameraOffset(v3s16 camera_offset)
484 { m_mesh_update_thread.m_camera_offset = camera_offset; }
486 // Get event from queue. CE_NONE is returned if queue is empty.
487 ClientEvent getClientEvent();
490 { return m_access_denied; }
492 std::string accessDeniedReason()
493 { return m_access_denied_reason; }
495 bool itemdefReceived()
496 { return m_itemdef_received; }
497 bool nodedefReceived()
498 { return m_nodedef_received; }
500 { return m_media_downloader == NULL; }
503 { return m_proto_ver; }
505 float mediaReceiveProgress();
507 void afterContentReceived(IrrlichtDevice *device);
510 float getCurRate(void);
511 float getAvgRate(void);
516 // IGameDef interface
517 virtual IItemDefManager* getItemDefManager();
518 virtual INodeDefManager* getNodeDefManager();
519 virtual ICraftDefManager* getCraftDefManager();
520 virtual ITextureSource* getTextureSource();
521 virtual IShaderSource* getShaderSource();
522 virtual scene::ISceneManager* getSceneManager();
523 virtual u16 allocateUnknownNodeId(const std::string &name);
524 virtual ISoundManager* getSoundManager();
525 virtual MtEventManager* getEventManager();
526 virtual ParticleManager* getParticleManager();
527 virtual bool checkLocalPrivilege(const std::string &priv)
528 { return checkPrivilege(priv); }
529 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
531 // The following set of functions is used by ClientMediaDownloader
532 // Insert a media file appropriately into the appropriate manager
533 bool loadMedia(const std::string &data, const std::string &filename);
534 // Send a request for conventional media transfer
535 void request_media(const std::vector<std::string> &file_requests);
536 // Send a notification that no conventional media transfer is needed
537 void received_media();
539 LocalClientState getState() { return m_state; }
541 void makeScreenshot(IrrlichtDevice *device);
545 // Virtual methods from con::PeerHandler
546 void peerAdded(con::Peer *peer);
547 void deletingPeer(con::Peer *peer, bool timeout);
549 void initLocalMapSaving(const Address &address,
550 const std::string &hostname,
551 bool is_local_server);
556 void sendPlayerPos();
557 // Send the item number 'item' as player item to the server
558 void sendPlayerItem(u16 item);
560 void deleteAuthData();
561 // helper method shared with clientpackethandler
562 static AuthMechanism choseAuthMech(const u32 mechs);
564 void sendLegacyInit(const char* playerName, const char* playerPassword);
565 void sendInit(const std::string &playerName);
566 void startAuth(AuthMechanism chosen_auth_mechanism);
567 void sendDeletedBlocks(std::vector<v3s16> &blocks);
568 void sendGotBlocks(v3s16 block);
569 void sendRemovedSounds(std::vector<s32> &soundList);
572 inline std::string getPlayerName()
573 { return m_env.getLocalPlayer()->getName(); }
575 float m_packetcounter_timer;
576 float m_connection_reinit_timer;
577 float m_avg_rtt_timer;
578 float m_playerpos_send_timer;
579 float m_ignore_damage_timer; // Used after server moves player
580 IntervalLimiter m_map_timer_and_unload_interval;
582 IWritableTextureSource *m_tsrc;
583 IWritableShaderSource *m_shsrc;
584 IWritableItemDefManager *m_itemdef;
585 IWritableNodeDefManager *m_nodedef;
586 ISoundManager *m_sound;
587 MtEventManager *m_event;
590 MeshUpdateThread m_mesh_update_thread;
591 ClientEnvironment m_env;
592 ParticleManager m_particle_manager;
593 con::Connection m_con;
594 IrrlichtDevice *m_device;
596 // Server serialization version
598 // Used version of the protocol with server
601 bool m_inventory_updated;
602 Inventory *m_inventory_from_server;
603 float m_inventory_from_server_age;
604 PacketCounter m_packetcounter;
605 bool m_show_highlighted;
606 // Block mesh animation parameters
607 float m_animation_time;
610 v3s16 m_highlighted_pos;
611 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
613 //u32 m_daynight_ratio;
614 std::queue<std::wstring> m_chat_queue;
616 // The authentication methods we can use to enter sudo mode (=change password)
617 u32 m_sudo_auth_methods;
619 // The seed returned by the server in TOCLIENT_INIT is stored here
623 std::string m_playername;
624 std::string m_password;
625 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
626 std::string m_new_password;
627 // Usable by auth mechanisms.
628 AuthMechanism m_chosen_auth_mech;
632 bool m_access_denied;
633 std::string m_access_denied_reason;
634 std::queue<ClientEvent> m_client_event_queue;
635 bool m_itemdef_received;
636 bool m_nodedef_received;
637 ClientMediaDownloader *m_media_downloader;
639 // time_of_day speed approximation for old protocol
640 bool m_time_of_day_set;
641 float m_last_time_of_day_f;
642 float m_time_of_day_update_timer;
644 // An interval for generally sending object positions and stuff
645 float m_recommended_send_interval;
648 float m_removed_sounds_check_timer;
649 // Mapping from server sound ids to our sound ids
650 std::map<s32, int> m_sounds_server_to_client;
651 // And the other way!
652 std::map<int, s32> m_sounds_client_to_server;
653 // And relations to objects
654 std::map<int, u16> m_sounds_to_objects;
657 std::set<std::string> m_privileges;
659 // Detached inventories
661 std::map<std::string, Inventory*> m_detached_inventories;
663 // Storage for mesh data for creating multiple instances of the same mesh
664 StringMap m_mesh_data;
667 LocalClientState m_state;
669 // Used for saving server map to disk client-side
671 IntervalLimiter m_localdb_save_interval;
672 u16 m_cache_save_interval;
674 // TODO: Add callback to update these when g_settings changes
675 bool m_cache_smooth_lighting;
676 bool m_cache_enable_shaders;
679 #endif // !CLIENT_HEADER