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 JThread
120 MeshUpdateThread(IGameDef *gamedef):
127 MeshUpdateQueue m_queue_in;
129 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;
186 std::string *texture;
201 bool collisiondetection;
203 std::string *texture;
205 } add_particlespawner;
208 } delete_particlespawner;
237 video::SColor *bgcolor;
239 std::vector<std::string> *params;
244 } override_day_night_ratio;
259 void add(u16 command)
261 std::map<u16, u16>::iterator n = m_packets.find(command);
262 if(n == m_packets.end())
264 m_packets[command] = 1;
274 for(std::map<u16, u16>::iterator
275 i = m_packets.begin();
276 i != m_packets.end(); ++i)
282 void print(std::ostream &o)
284 for(std::map<u16, u16>::iterator
285 i = m_packets.begin();
286 i != m_packets.end(); ++i)
289 <<" count "<<i->second
296 std::map<u16, u16> m_packets;
299 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
303 NOTE: Nothing is thread-safe here.
307 IrrlichtDevice *device,
308 const char *playername,
309 std::string password,
310 MapDrawControl &control,
311 IWritableTextureSource *tsrc,
312 IWritableShaderSource *shsrc,
313 IWritableItemDefManager *itemdef,
314 IWritableNodeDefManager *nodedef,
315 ISoundManager *sound,
316 MtEventManager *event,
323 request all threads managed by client to be stopped
331 The name of the local player should already be set when
332 calling this, as it is sent in the initialization.
334 void connect(Address address,
335 const std::string &address_name,
336 bool is_local_server);
339 Stuff that references the environment is valid only as
340 long as this is not called. (eg. Players)
341 If this throws a PeerNotFoundException, the connection has
344 void step(float dtime);
350 void handleCommand(NetworkPacket* pkt);
352 void handleCommand_Null(NetworkPacket* pkt) {};
353 void handleCommand_Deprecated(NetworkPacket* pkt);
354 void handleCommand_Hello(NetworkPacket* pkt);
355 void handleCommand_AuthAccept(NetworkPacket* pkt);
356 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
357 void handleCommand_DenySudoMode(NetworkPacket* pkt);
358 void handleCommand_InitLegacy(NetworkPacket* pkt);
359 void handleCommand_AccessDenied(NetworkPacket* pkt);
360 void handleCommand_RemoveNode(NetworkPacket* pkt);
361 void handleCommand_AddNode(NetworkPacket* pkt);
362 void handleCommand_BlockData(NetworkPacket* pkt);
363 void handleCommand_Inventory(NetworkPacket* pkt);
364 void handleCommand_TimeOfDay(NetworkPacket* pkt);
365 void handleCommand_ChatMessage(NetworkPacket* pkt);
366 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
367 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
368 void handleCommand_Movement(NetworkPacket* pkt);
369 void handleCommand_HP(NetworkPacket* pkt);
370 void handleCommand_Breath(NetworkPacket* pkt);
371 void handleCommand_MovePlayer(NetworkPacket* pkt);
372 void handleCommand_PlayerItem(NetworkPacket* pkt);
373 void handleCommand_DeathScreen(NetworkPacket* pkt);
374 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
375 void handleCommand_Media(NetworkPacket* pkt);
376 void handleCommand_ToolDef(NetworkPacket* pkt);
377 void handleCommand_NodeDef(NetworkPacket* pkt);
378 void handleCommand_CraftItemDef(NetworkPacket* pkt);
379 void handleCommand_ItemDef(NetworkPacket* pkt);
380 void handleCommand_PlaySound(NetworkPacket* pkt);
381 void handleCommand_StopSound(NetworkPacket* pkt);
382 void handleCommand_Privileges(NetworkPacket* pkt);
383 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
384 void handleCommand_DetachedInventory(NetworkPacket* pkt);
385 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
386 void handleCommand_SpawnParticle(NetworkPacket* pkt);
387 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
388 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
389 void handleCommand_HudAdd(NetworkPacket* pkt);
390 void handleCommand_HudRemove(NetworkPacket* pkt);
391 void handleCommand_HudChange(NetworkPacket* pkt);
392 void handleCommand_HudSetFlags(NetworkPacket* pkt);
393 void handleCommand_HudSetParam(NetworkPacket* pkt);
394 void handleCommand_HudSetSky(NetworkPacket* pkt);
395 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
396 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
397 void handleCommand_EyeOffset(NetworkPacket* pkt);
398 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
400 void ProcessData(NetworkPacket *pkt);
402 // Returns true if something was received
403 bool AsyncProcessPacket();
404 bool AsyncProcessData();
405 void Send(NetworkPacket* pkt);
407 void interact(u8 action, const PointedThing& pointed);
409 void sendNodemetaFields(v3s16 p, const std::string &formname,
410 const StringMap &fields);
411 void sendInventoryFields(const std::string &formname,
412 const StringMap &fields);
413 void sendInventoryAction(InventoryAction *a);
414 void sendChatMessage(const std::wstring &message);
415 void sendChangePassword(const std::string &oldpassword,
416 const std::string &newpassword);
417 void sendDamage(u8 damage);
418 void sendBreath(u16 breath);
422 ClientEnvironment& getEnv()
425 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
426 void removeNode(v3s16 p);
427 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
429 void setPlayerControl(PlayerControl &control);
431 void selectPlayerItem(u16 item);
432 u16 getPlayerItem() const
433 { return m_playeritem; }
435 // Returns true if the inventory of the local player has been
436 // updated from the server. If it is true, it is set to false.
437 bool getLocalInventoryUpdated();
438 // Copies the inventory of the local player to parameter
439 void getLocalInventory(Inventory &dst);
441 /* InventoryManager interface */
442 Inventory* getInventory(const InventoryLocation &loc);
443 void inventoryAction(InventoryAction *a);
445 // Gets closest object pointed by the shootline
446 // Returns NULL if not found
447 ClientActiveObject * getSelectedActiveObject(
449 v3f from_pos_f_on_map,
450 core::line3d<f32> shootline_on_map
453 std::list<std::string> getConnectedPlayerNames();
455 float getAnimationTime();
458 void setCrack(int level, v3s16 pos);
460 void setHighlighted(v3s16 pos, bool show_higlighted);
461 v3s16 getHighlighted(){ return m_highlighted_pos; }
466 bool checkPrivilege(const std::string &priv)
467 { return (m_privileges.count(priv) != 0); }
469 bool getChatMessage(std::wstring &message);
470 void typeChatMessage(const std::wstring& message);
472 u64 getMapSeed(){ return m_map_seed; }
474 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
475 // Including blocks at appropriate edges
476 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
477 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
479 void updateCameraOffset(v3s16 camera_offset)
480 { m_mesh_update_thread.m_camera_offset = camera_offset; }
482 // Get event from queue. CE_NONE is returned if queue is empty.
483 ClientEvent getClientEvent();
486 { return m_access_denied; }
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 float mediaReceiveProgress();
503 void afterContentReceived(IrrlichtDevice *device);
506 float getCurRate(void);
507 float getAvgRate(void);
512 // IGameDef interface
513 virtual IItemDefManager* getItemDefManager();
514 virtual INodeDefManager* getNodeDefManager();
515 virtual ICraftDefManager* getCraftDefManager();
516 virtual ITextureSource* getTextureSource();
517 virtual IShaderSource* getShaderSource();
518 virtual scene::ISceneManager* getSceneManager();
519 virtual u16 allocateUnknownNodeId(const std::string &name);
520 virtual ISoundManager* getSoundManager();
521 virtual MtEventManager* getEventManager();
522 virtual ParticleManager* getParticleManager();
523 virtual bool checkLocalPrivilege(const std::string &priv)
524 { return checkPrivilege(priv); }
525 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
527 // The following set of functions is used by ClientMediaDownloader
528 // Insert a media file appropriately into the appropriate manager
529 bool loadMedia(const std::string &data, const std::string &filename);
530 // Send a request for conventional media transfer
531 void request_media(const std::vector<std::string> &file_requests);
532 // Send a notification that no conventional media transfer is needed
533 void received_media();
535 LocalClientState getState() { return m_state; }
537 void makeScreenshot(IrrlichtDevice *device);
541 // Virtual methods from con::PeerHandler
542 void peerAdded(con::Peer *peer);
543 void deletingPeer(con::Peer *peer, bool timeout);
545 void initLocalMapSaving(const Address &address,
546 const std::string &hostname,
547 bool is_local_server);
552 void sendPlayerPos();
553 // Send the item number 'item' as player item to the server
554 void sendPlayerItem(u16 item);
556 void deleteAuthData();
557 // helper method shared with clientpackethandler
558 static AuthMechanism choseAuthMech(const u32 mechs);
560 void sendLegacyInit(const char* playerName, const char* playerPassword);
561 void sendInit(const std::string &playerName);
562 void startAuth(AuthMechanism chosen_auth_mechanism);
563 void sendDeletedBlocks(std::vector<v3s16> &blocks);
564 void sendGotBlocks(v3s16 block);
565 void sendRemovedSounds(std::vector<s32> &soundList);
568 inline std::string getPlayerName()
569 { return m_env.getLocalPlayer()->getName(); }
571 float m_packetcounter_timer;
572 float m_connection_reinit_timer;
573 float m_avg_rtt_timer;
574 float m_playerpos_send_timer;
575 float m_ignore_damage_timer; // Used after server moves player
576 IntervalLimiter m_map_timer_and_unload_interval;
578 IWritableTextureSource *m_tsrc;
579 IWritableShaderSource *m_shsrc;
580 IWritableItemDefManager *m_itemdef;
581 IWritableNodeDefManager *m_nodedef;
582 ISoundManager *m_sound;
583 MtEventManager *m_event;
586 MeshUpdateThread m_mesh_update_thread;
587 ClientEnvironment m_env;
588 ParticleManager m_particle_manager;
589 con::Connection m_con;
590 IrrlichtDevice *m_device;
592 // Server serialization version
594 // Used version of the protocol with server
597 bool m_inventory_updated;
598 Inventory *m_inventory_from_server;
599 float m_inventory_from_server_age;
600 PacketCounter m_packetcounter;
601 bool m_show_highlighted;
602 // Block mesh animation parameters
603 float m_animation_time;
606 v3s16 m_highlighted_pos;
607 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
609 //u32 m_daynight_ratio;
610 std::queue<std::wstring> m_chat_queue;
612 // The authentication methods we can use to enter sudo mode (=change password)
613 u32 m_sudo_auth_methods;
615 // The seed returned by the server in TOCLIENT_INIT is stored here
619 std::string m_playername;
620 std::string m_password;
621 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
622 std::string m_new_password;
623 // Usable by auth mechanisms.
624 AuthMechanism m_chosen_auth_mech;
628 bool m_access_denied;
629 std::string m_access_denied_reason;
630 std::queue<ClientEvent> m_client_event_queue;
631 bool m_itemdef_received;
632 bool m_nodedef_received;
633 ClientMediaDownloader *m_media_downloader;
635 // time_of_day speed approximation for old protocol
636 bool m_time_of_day_set;
637 float m_last_time_of_day_f;
638 float m_time_of_day_update_timer;
640 // An interval for generally sending object positions and stuff
641 float m_recommended_send_interval;
644 float m_removed_sounds_check_timer;
645 // Mapping from server sound ids to our sound ids
646 std::map<s32, int> m_sounds_server_to_client;
647 // And the other way!
648 std::map<int, s32> m_sounds_client_to_server;
649 // And relations to objects
650 std::map<int, u16> m_sounds_to_objects;
653 std::set<std::string> m_privileges;
655 // Detached inventories
657 std::map<std::string, Inventory*> m_detached_inventories;
659 // Storage for mesh data for creating multiple instances of the same mesh
660 StringMap m_mesh_data;
663 LocalClientState m_state;
665 // Used for saving server map to disk client-side
667 IntervalLimiter m_localdb_save_interval;
668 u16 m_cache_save_interval;
670 // TODO: Add callback to update these when g_settings changes
671 bool m_cache_smooth_lighting;
672 bool m_cache_enable_shaders;
675 #endif // !CLIENT_HEADER