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 QueuedMeshUpdate
56 bool ack_block_to_server;
62 enum LocalClientState {
69 A thread-safe queue of mesh update tasks
79 peer_id=0 adds with nobody to send to
81 void addBlock(v3s16 p, MeshMakeData *data,
82 bool ack_block_to_server, bool urgent);
84 // Returned pointer must be deleted
85 // Returns NULL if queue is empty
86 QueuedMeshUpdate * pop();
90 JMutexAutoLock lock(m_mutex);
91 return m_queue.size();
95 std::vector<QueuedMeshUpdate*> m_queue;
96 std::set<v3s16> m_urgents;
100 struct MeshUpdateResult
104 bool ack_block_to_server;
107 p(-1338,-1338,-1338),
109 ack_block_to_server(false)
114 class MeshUpdateThread : public JThread
118 MeshUpdateThread(IGameDef *gamedef):
125 MeshUpdateQueue m_queue_in;
127 MutexedQueue<MeshUpdateResult> m_queue_out;
131 v3s16 m_camera_offset;
138 CE_PLAYER_FORCE_MOVE,
142 CE_ADD_PARTICLESPAWNER,
143 CE_DELETE_PARTICLESPAWNER,
148 CE_OVERRIDE_DAY_NIGHT_RATIO,
153 ClientEventType type;
165 bool set_camera_point_target;
166 f32 camera_point_target_x;
167 f32 camera_point_target_y;
168 f32 camera_point_target_z;
171 std::string *formspec;
172 std::string *formname;
175 //} textures_updated;
182 bool collisiondetection;
184 std::string *texture;
199 bool collisiondetection;
201 std::string *texture;
203 } add_particlespawner;
206 } delete_particlespawner;
235 video::SColor *bgcolor;
237 std::vector<std::string> *params;
242 } override_day_night_ratio;
257 void add(u16 command)
259 std::map<u16, u16>::iterator n = m_packets.find(command);
260 if(n == m_packets.end())
262 m_packets[command] = 1;
272 for(std::map<u16, u16>::iterator
273 i = m_packets.begin();
274 i != m_packets.end(); ++i)
280 void print(std::ostream &o)
282 for(std::map<u16, u16>::iterator
283 i = m_packets.begin();
284 i != m_packets.end(); ++i)
287 <<" count "<<i->second
294 std::map<u16, u16> m_packets;
297 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
301 NOTE: Nothing is thread-safe here.
305 IrrlichtDevice *device,
306 const char *playername,
307 std::string password,
308 MapDrawControl &control,
309 IWritableTextureSource *tsrc,
310 IWritableShaderSource *shsrc,
311 IWritableItemDefManager *itemdef,
312 IWritableNodeDefManager *nodedef,
313 ISoundManager *sound,
314 MtEventManager *event,
321 request all threads managed by client to be stopped
329 The name of the local player should already be set when
330 calling this, as it is sent in the initialization.
332 void connect(Address address,
333 const std::string &address_name,
334 bool is_local_server);
337 Stuff that references the environment is valid only as
338 long as this is not called. (eg. Players)
339 If this throws a PeerNotFoundException, the connection has
342 void step(float dtime);
348 void handleCommand(NetworkPacket* pkt);
350 void handleCommand_Null(NetworkPacket* pkt) {};
351 void handleCommand_Deprecated(NetworkPacket* pkt);
352 void handleCommand_Hello(NetworkPacket* pkt);
353 void handleCommand_AuthAccept(NetworkPacket* pkt);
354 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
355 void handleCommand_DenySudoMode(NetworkPacket* pkt);
356 void handleCommand_InitLegacy(NetworkPacket* pkt);
357 void handleCommand_AccessDenied(NetworkPacket* pkt);
358 void handleCommand_RemoveNode(NetworkPacket* pkt);
359 void handleCommand_AddNode(NetworkPacket* pkt);
360 void handleCommand_BlockData(NetworkPacket* pkt);
361 void handleCommand_Inventory(NetworkPacket* pkt);
362 void handleCommand_TimeOfDay(NetworkPacket* pkt);
363 void handleCommand_ChatMessage(NetworkPacket* pkt);
364 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
365 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
366 void handleCommand_Movement(NetworkPacket* pkt);
367 void handleCommand_HP(NetworkPacket* pkt);
368 void handleCommand_Breath(NetworkPacket* pkt);
369 void handleCommand_MovePlayer(NetworkPacket* pkt);
370 void handleCommand_PlayerItem(NetworkPacket* pkt);
371 void handleCommand_DeathScreen(NetworkPacket* pkt);
372 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
373 void handleCommand_Media(NetworkPacket* pkt);
374 void handleCommand_ToolDef(NetworkPacket* pkt);
375 void handleCommand_NodeDef(NetworkPacket* pkt);
376 void handleCommand_CraftItemDef(NetworkPacket* pkt);
377 void handleCommand_ItemDef(NetworkPacket* pkt);
378 void handleCommand_PlaySound(NetworkPacket* pkt);
379 void handleCommand_StopSound(NetworkPacket* pkt);
380 void handleCommand_Privileges(NetworkPacket* pkt);
381 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
382 void handleCommand_DetachedInventory(NetworkPacket* pkt);
383 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
384 void handleCommand_SpawnParticle(NetworkPacket* pkt);
385 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
386 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
387 void handleCommand_HudAdd(NetworkPacket* pkt);
388 void handleCommand_HudRemove(NetworkPacket* pkt);
389 void handleCommand_HudChange(NetworkPacket* pkt);
390 void handleCommand_HudSetFlags(NetworkPacket* pkt);
391 void handleCommand_HudSetParam(NetworkPacket* pkt);
392 void handleCommand_HudSetSky(NetworkPacket* pkt);
393 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
394 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
395 void handleCommand_EyeOffset(NetworkPacket* pkt);
396 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
398 void ProcessData(NetworkPacket *pkt);
400 // Returns true if something was received
401 bool AsyncProcessPacket();
402 bool AsyncProcessData();
403 void Send(NetworkPacket* pkt);
405 void interact(u8 action, const PointedThing& pointed);
407 void sendNodemetaFields(v3s16 p, const std::string &formname,
408 const StringMap &fields);
409 void sendInventoryFields(const std::string &formname,
410 const StringMap &fields);
411 void sendInventoryAction(InventoryAction *a);
412 void sendChatMessage(const std::wstring &message);
413 void sendChangePassword(const std::string &oldpassword,
414 const std::string &newpassword);
415 void sendDamage(u8 damage);
416 void sendBreath(u16 breath);
420 ClientEnvironment& getEnv()
423 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
424 void removeNode(v3s16 p);
425 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
427 void setPlayerControl(PlayerControl &control);
429 void selectPlayerItem(u16 item);
430 u16 getPlayerItem() const
431 { return m_playeritem; }
433 // Returns true if the inventory of the local player has been
434 // updated from the server. If it is true, it is set to false.
435 bool getLocalInventoryUpdated();
436 // Copies the inventory of the local player to parameter
437 void getLocalInventory(Inventory &dst);
439 /* InventoryManager interface */
440 Inventory* getInventory(const InventoryLocation &loc);
441 void inventoryAction(InventoryAction *a);
443 // Gets closest object pointed by the shootline
444 // Returns NULL if not found
445 ClientActiveObject * getSelectedActiveObject(
447 v3f from_pos_f_on_map,
448 core::line3d<f32> shootline_on_map
451 std::list<std::string> getConnectedPlayerNames();
453 float getAnimationTime();
456 void setCrack(int level, v3s16 pos);
458 void setHighlighted(v3s16 pos, bool show_higlighted);
459 v3s16 getHighlighted(){ return m_highlighted_pos; }
464 bool checkPrivilege(const std::string &priv)
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 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);
507 // IGameDef interface
508 virtual IItemDefManager* getItemDefManager();
509 virtual INodeDefManager* getNodeDefManager();
510 virtual ICraftDefManager* getCraftDefManager();
511 virtual ITextureSource* getTextureSource();
512 virtual IShaderSource* getShaderSource();
513 virtual scene::ISceneManager* getSceneManager();
514 virtual u16 allocateUnknownNodeId(const std::string &name);
515 virtual ISoundManager* getSoundManager();
516 virtual MtEventManager* getEventManager();
517 virtual ParticleManager* getParticleManager();
518 virtual bool checkLocalPrivilege(const std::string &priv)
519 { return checkPrivilege(priv); }
520 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
522 // The following set of functions is used by ClientMediaDownloader
523 // Insert a media file appropriately into the appropriate manager
524 bool loadMedia(const std::string &data, const std::string &filename);
525 // Send a request for conventional media transfer
526 void request_media(const std::vector<std::string> &file_requests);
527 // Send a notification that no conventional media transfer is needed
528 void received_media();
530 LocalClientState getState() { return m_state; }
532 void makeScreenshot(IrrlichtDevice *device);
536 // Virtual methods from con::PeerHandler
537 void peerAdded(con::Peer *peer);
538 void deletingPeer(con::Peer *peer, bool timeout);
540 void initLocalMapSaving(const Address &address,
541 const std::string &hostname,
542 bool is_local_server);
547 void sendPlayerPos();
548 // Send the item number 'item' as player item to the server
549 void sendPlayerItem(u16 item);
551 void deleteAuthData();
552 // helper method shared with clientpackethandler
553 static AuthMechanism choseAuthMech(const u32 mechs);
555 void sendLegacyInit(const char* playerName, const char* playerPassword);
556 void sendInit(const std::string &playerName);
557 void startAuth(AuthMechanism chosen_auth_mechanism);
558 void sendDeletedBlocks(std::vector<v3s16> &blocks);
559 void sendGotBlocks(v3s16 block);
560 void sendRemovedSounds(std::vector<s32> &soundList);
563 inline std::string getPlayerName()
564 { return m_env.getLocalPlayer()->getName(); }
566 float m_packetcounter_timer;
567 float m_connection_reinit_timer;
568 float m_avg_rtt_timer;
569 float m_playerpos_send_timer;
570 float m_ignore_damage_timer; // Used after server moves player
571 IntervalLimiter m_map_timer_and_unload_interval;
573 IWritableTextureSource *m_tsrc;
574 IWritableShaderSource *m_shsrc;
575 IWritableItemDefManager *m_itemdef;
576 IWritableNodeDefManager *m_nodedef;
577 ISoundManager *m_sound;
578 MtEventManager *m_event;
581 MeshUpdateThread m_mesh_update_thread;
582 ClientEnvironment m_env;
583 ParticleManager m_particle_manager;
584 con::Connection m_con;
585 IrrlichtDevice *m_device;
586 // Server serialization version
588 // Used version of the protocol with server
591 bool m_inventory_updated;
592 Inventory *m_inventory_from_server;
593 float m_inventory_from_server_age;
594 PacketCounter m_packetcounter;
595 bool m_show_highlighted;
596 // Block mesh animation parameters
597 float m_animation_time;
600 v3s16 m_highlighted_pos;
601 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
603 //u32 m_daynight_ratio;
604 std::queue<std::wstring> m_chat_queue;
606 // The authentication methods we can use to enter sudo mode (=change password)
607 u32 m_sudo_auth_methods;
609 // The seed returned by the server in TOCLIENT_INIT is stored here
613 std::string m_playername;
614 std::string m_password;
615 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
616 std::string m_new_password;
617 // Usable by auth mechanisms.
618 AuthMechanism m_chosen_auth_mech;
622 bool m_access_denied;
623 std::string m_access_denied_reason;
624 std::queue<ClientEvent> m_client_event_queue;
625 bool m_itemdef_received;
626 bool m_nodedef_received;
627 ClientMediaDownloader *m_media_downloader;
629 // time_of_day speed approximation for old protocol
630 bool m_time_of_day_set;
631 float m_last_time_of_day_f;
632 float m_time_of_day_update_timer;
634 // An interval for generally sending object positions and stuff
635 float m_recommended_send_interval;
638 float m_removed_sounds_check_timer;
639 // Mapping from server sound ids to our sound ids
640 std::map<s32, int> m_sounds_server_to_client;
641 // And the other way!
642 std::map<int, s32> m_sounds_client_to_server;
643 // And relations to objects
644 std::map<int, u16> m_sounds_to_objects;
647 std::set<std::string> m_privileges;
649 // Detached inventories
651 std::map<std::string, Inventory*> m_detached_inventories;
653 // Storage for mesh data for creating multiple instances of the same mesh
654 StringMap m_mesh_data;
657 LocalClientState m_state;
659 // Used for saving server map to disk client-side
661 IntervalLimiter m_localdb_save_interval;
662 u16 m_cache_save_interval;
664 // TODO: Add callback to update these when g_settings changes
665 bool m_cache_smooth_lighting;
666 bool m_cache_enable_shaders;
669 #endif // !CLIENT_HEADER