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;
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 MutexAutoLock 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 virtual void doUpdate();
126 MeshUpdateThread() : UpdateThread("Mesh") {}
128 void enqueueUpdate(v3s16 p, MeshMakeData *data,
129 bool ack_block_to_server, bool urgent);
130 MutexedQueue<MeshUpdateResult> m_queue_out;
132 v3s16 m_camera_offset;
139 CE_PLAYER_FORCE_MOVE,
143 CE_ADD_PARTICLESPAWNER,
144 CE_DELETE_PARTICLESPAWNER,
149 CE_OVERRIDE_DAY_NIGHT_RATIO,
154 ClientEventType type;
166 bool set_camera_point_target;
167 f32 camera_point_target_x;
168 f32 camera_point_target_y;
169 f32 camera_point_target_z;
172 std::string *formspec;
173 std::string *formname;
176 //} textures_updated;
183 bool collisiondetection;
185 std::string *texture;
200 bool collisiondetection;
202 std::string *texture;
204 } add_particlespawner;
207 } delete_particlespawner;
236 video::SColor *bgcolor;
238 std::vector<std::string> *params;
243 } override_day_night_ratio;
258 void add(u16 command)
260 std::map<u16, u16>::iterator n = m_packets.find(command);
261 if(n == m_packets.end())
263 m_packets[command] = 1;
273 for(std::map<u16, u16>::iterator
274 i = m_packets.begin();
275 i != m_packets.end(); ++i)
281 void print(std::ostream &o)
283 for(std::map<u16, u16>::iterator
284 i = m_packets.begin();
285 i != m_packets.end(); ++i)
288 <<" count "<<i->second
295 std::map<u16, u16> m_packets;
298 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
302 NOTE: Nothing is thread-safe here.
306 IrrlichtDevice *device,
307 const char *playername,
308 std::string password,
309 MapDrawControl &control,
310 IWritableTextureSource *tsrc,
311 IWritableShaderSource *shsrc,
312 IWritableItemDefManager *itemdef,
313 IWritableNodeDefManager *nodedef,
314 ISoundManager *sound,
315 MtEventManager *event,
322 request all threads managed by client to be stopped
330 The name of the local player should already be set when
331 calling this, as it is sent in the initialization.
333 void connect(Address address,
334 const std::string &address_name,
335 bool is_local_server);
338 Stuff that references the environment is valid only as
339 long as this is not called. (eg. Players)
340 If this throws a PeerNotFoundException, the connection has
343 void step(float dtime);
349 void handleCommand(NetworkPacket* pkt);
351 void handleCommand_Null(NetworkPacket* pkt) {};
352 void handleCommand_Deprecated(NetworkPacket* pkt);
353 void handleCommand_Hello(NetworkPacket* pkt);
354 void handleCommand_AuthAccept(NetworkPacket* pkt);
355 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
356 void handleCommand_DenySudoMode(NetworkPacket* pkt);
357 void handleCommand_InitLegacy(NetworkPacket* pkt);
358 void handleCommand_AccessDenied(NetworkPacket* pkt);
359 void handleCommand_RemoveNode(NetworkPacket* pkt);
360 void handleCommand_AddNode(NetworkPacket* pkt);
361 void handleCommand_BlockData(NetworkPacket* pkt);
362 void handleCommand_Inventory(NetworkPacket* pkt);
363 void handleCommand_TimeOfDay(NetworkPacket* pkt);
364 void handleCommand_ChatMessage(NetworkPacket* pkt);
365 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
366 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
367 void handleCommand_Movement(NetworkPacket* pkt);
368 void handleCommand_HP(NetworkPacket* pkt);
369 void handleCommand_Breath(NetworkPacket* pkt);
370 void handleCommand_MovePlayer(NetworkPacket* pkt);
371 void handleCommand_PlayerItem(NetworkPacket* pkt);
372 void handleCommand_DeathScreen(NetworkPacket* pkt);
373 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
374 void handleCommand_Media(NetworkPacket* pkt);
375 void handleCommand_ToolDef(NetworkPacket* pkt);
376 void handleCommand_NodeDef(NetworkPacket* pkt);
377 void handleCommand_CraftItemDef(NetworkPacket* pkt);
378 void handleCommand_ItemDef(NetworkPacket* pkt);
379 void handleCommand_PlaySound(NetworkPacket* pkt);
380 void handleCommand_StopSound(NetworkPacket* pkt);
381 void handleCommand_Privileges(NetworkPacket* pkt);
382 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
383 void handleCommand_DetachedInventory(NetworkPacket* pkt);
384 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
385 void handleCommand_SpawnParticle(NetworkPacket* pkt);
386 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
387 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
388 void handleCommand_HudAdd(NetworkPacket* pkt);
389 void handleCommand_HudRemove(NetworkPacket* pkt);
390 void handleCommand_HudChange(NetworkPacket* pkt);
391 void handleCommand_HudSetFlags(NetworkPacket* pkt);
392 void handleCommand_HudSetParam(NetworkPacket* pkt);
393 void handleCommand_HudSetSky(NetworkPacket* pkt);
394 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
395 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
396 void handleCommand_EyeOffset(NetworkPacket* pkt);
397 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
399 void ProcessData(NetworkPacket *pkt);
401 // Returns true if something was received
402 bool AsyncProcessPacket();
403 bool AsyncProcessData();
404 void Send(NetworkPacket* pkt);
406 void interact(u8 action, const PointedThing& pointed);
408 void sendNodemetaFields(v3s16 p, const std::string &formname,
409 const StringMap &fields);
410 void sendInventoryFields(const std::string &formname,
411 const StringMap &fields);
412 void sendInventoryAction(InventoryAction *a);
413 void sendChatMessage(const std::wstring &message);
414 void sendChangePassword(const std::string &oldpassword,
415 const std::string &newpassword);
416 void sendDamage(u8 damage);
417 void sendBreath(u16 breath);
421 ClientEnvironment& getEnv()
424 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
425 void removeNode(v3s16 p);
426 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
428 void setPlayerControl(PlayerControl &control);
430 void selectPlayerItem(u16 item);
431 u16 getPlayerItem() const
432 { return m_playeritem; }
434 // Returns true if the inventory of the local player has been
435 // updated from the server. If it is true, it is set to false.
436 bool getLocalInventoryUpdated();
437 // Copies the inventory of the local player to parameter
438 void getLocalInventory(Inventory &dst);
440 /* InventoryManager interface */
441 Inventory* getInventory(const InventoryLocation &loc);
442 void inventoryAction(InventoryAction *a);
444 // Gets closest object pointed by the shootline
445 // Returns NULL if not found
446 ClientActiveObject * getSelectedActiveObject(
448 v3f from_pos_f_on_map,
449 core::line3d<f32> shootline_on_map
452 std::list<std::string> getConnectedPlayerNames();
454 float getAnimationTime();
457 void setCrack(int level, v3s16 pos);
462 bool checkPrivilege(const std::string &priv)
463 { return (m_privileges.count(priv) != 0); }
465 bool getChatMessage(std::wstring &message);
466 void typeChatMessage(const std::wstring& message);
468 u64 getMapSeed(){ return m_map_seed; }
470 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
471 // Including blocks at appropriate edges
472 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
473 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
475 void updateCameraOffset(v3s16 camera_offset)
476 { m_mesh_update_thread.m_camera_offset = camera_offset; }
478 // Get event from queue. CE_NONE is returned if queue is empty.
479 ClientEvent getClientEvent();
482 { return m_access_denied; }
484 bool reconnectRequested() { return m_access_denied_reconnect; }
486 std::string accessDeniedReason()
487 { return m_access_denied_reason; }
489 bool itemdefReceived()
490 { return m_itemdef_received; }
491 bool nodedefReceived()
492 { return m_nodedef_received; }
494 { return m_media_downloader == NULL; }
497 { return m_proto_ver; }
499 float mediaReceiveProgress();
501 void afterContentReceived(IrrlichtDevice *device);
504 float getCurRate(void);
505 float getAvgRate(void);
510 bool isMinimapDisabledByServer()
511 { return m_minimap_disabled_by_server; }
513 // IGameDef interface
514 virtual IItemDefManager* getItemDefManager();
515 virtual INodeDefManager* getNodeDefManager();
516 virtual ICraftDefManager* getCraftDefManager();
517 virtual ITextureSource* getTextureSource();
518 virtual IShaderSource* getShaderSource();
519 virtual scene::ISceneManager* getSceneManager();
520 virtual u16 allocateUnknownNodeId(const std::string &name);
521 virtual ISoundManager* getSoundManager();
522 virtual MtEventManager* getEventManager();
523 virtual ParticleManager* getParticleManager();
524 virtual bool checkLocalPrivilege(const std::string &priv)
525 { return checkPrivilege(priv); }
526 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
528 // The following set of functions is used by ClientMediaDownloader
529 // Insert a media file appropriately into the appropriate manager
530 bool loadMedia(const std::string &data, const std::string &filename);
531 // Send a request for conventional media transfer
532 void request_media(const std::vector<std::string> &file_requests);
533 // Send a notification that no conventional media transfer is needed
534 void received_media();
536 LocalClientState getState() { return m_state; }
538 void makeScreenshot(IrrlichtDevice *device);
542 // Virtual methods from con::PeerHandler
543 void peerAdded(con::Peer *peer);
544 void deletingPeer(con::Peer *peer, bool timeout);
546 void initLocalMapSaving(const Address &address,
547 const std::string &hostname,
548 bool is_local_server);
553 void sendPlayerPos();
554 // Send the item number 'item' as player item to the server
555 void sendPlayerItem(u16 item);
557 void deleteAuthData();
558 // helper method shared with clientpackethandler
559 static AuthMechanism choseAuthMech(const u32 mechs);
561 void sendLegacyInit(const char* playerName, const char* playerPassword);
562 void sendInit(const std::string &playerName);
563 void startAuth(AuthMechanism chosen_auth_mechanism);
564 void sendDeletedBlocks(std::vector<v3s16> &blocks);
565 void sendGotBlocks(v3s16 block);
566 void sendRemovedSounds(std::vector<s32> &soundList);
569 inline std::string getPlayerName()
570 { return m_env.getLocalPlayer()->getName(); }
572 float m_packetcounter_timer;
573 float m_connection_reinit_timer;
574 float m_avg_rtt_timer;
575 float m_playerpos_send_timer;
576 float m_ignore_damage_timer; // Used after server moves player
577 IntervalLimiter m_map_timer_and_unload_interval;
579 IWritableTextureSource *m_tsrc;
580 IWritableShaderSource *m_shsrc;
581 IWritableItemDefManager *m_itemdef;
582 IWritableNodeDefManager *m_nodedef;
583 ISoundManager *m_sound;
584 MtEventManager *m_event;
587 MeshUpdateThread m_mesh_update_thread;
588 ClientEnvironment m_env;
589 ParticleManager m_particle_manager;
590 con::Connection m_con;
591 IrrlichtDevice *m_device;
593 bool m_minimap_disabled_by_server;
594 // Server serialization version
597 // Used version of the protocol with server
598 // Values smaller than 25 only mean they are smaller than 25,
599 // and aren't accurate. We simply just don't know, because
600 // the server didn't send the version back then.
601 // If 0, server init hasn't been received yet.
605 bool m_inventory_updated;
606 Inventory *m_inventory_from_server;
607 float m_inventory_from_server_age;
608 PacketCounter m_packetcounter;
609 // Block mesh animation parameters
610 float m_animation_time;
613 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
615 //u32 m_daynight_ratio;
616 std::queue<std::wstring> m_chat_queue;
618 // The authentication methods we can use to enter sudo mode (=change password)
619 u32 m_sudo_auth_methods;
621 // The seed returned by the server in TOCLIENT_INIT is stored here
625 std::string m_playername;
626 std::string m_password;
627 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
628 std::string m_new_password;
629 // Usable by auth mechanisms.
630 AuthMechanism m_chosen_auth_mech;
634 bool m_access_denied;
635 bool m_access_denied_reconnect;
636 std::string m_access_denied_reason;
637 std::queue<ClientEvent> m_client_event_queue;
638 bool m_itemdef_received;
639 bool m_nodedef_received;
640 ClientMediaDownloader *m_media_downloader;
642 // time_of_day speed approximation for old protocol
643 bool m_time_of_day_set;
644 float m_last_time_of_day_f;
645 float m_time_of_day_update_timer;
647 // An interval for generally sending object positions and stuff
648 float m_recommended_send_interval;
651 float m_removed_sounds_check_timer;
652 // Mapping from server sound ids to our sound ids
653 std::map<s32, int> m_sounds_server_to_client;
654 // And the other way!
655 std::map<int, s32> m_sounds_client_to_server;
656 // And relations to objects
657 std::map<int, u16> m_sounds_to_objects;
660 std::set<std::string> m_privileges;
662 // Detached inventories
664 std::map<std::string, Inventory*> m_detached_inventories;
666 // Storage for mesh data for creating multiple instances of the same mesh
667 StringMap m_mesh_data;
670 LocalClientState m_state;
672 // Used for saving server map to disk client-side
674 IntervalLimiter m_localdb_save_interval;
675 u16 m_cache_save_interval;
677 // TODO: Add callback to update these when g_settings changes
678 bool m_cache_smooth_lighting;
679 bool m_cache_enable_shaders;
680 bool m_cache_use_tangent_vertices;
682 DISABLE_CLASS_COPY(Client);
685 #endif // !CLIENT_HEADER