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"
38 #include "tileanimation.h"
39 #include "mesh_generator_thread.h"
43 class IWritableTextureSource;
44 class IWritableShaderSource;
45 class IWritableItemDefManager;
46 class IWritableNodeDefManager;
47 //class IWritableCraftDefManager;
48 class ClientMediaDownloader;
49 struct MapDrawControl;
54 struct MinimapMapblock;
58 enum LocalClientState {
71 CE_SHOW_LOCAL_FORMSPEC,
73 CE_ADD_PARTICLESPAWNER,
74 CE_DELETE_PARTICLESPAWNER,
79 CE_OVERRIDE_DAY_NIGHT_RATIO,
96 bool set_camera_point_target;
97 f32 camera_point_target_x;
98 f32 camera_point_target_y;
99 f32 camera_point_target_z;
102 std::string *formspec;
103 std::string *formname;
106 //} textures_updated;
113 bool collisiondetection;
114 bool collision_removal;
116 std::string *texture;
117 struct TileAnimationParams animation;
133 bool collisiondetection;
134 bool collision_removal;
137 std::string *texture;
139 struct TileAnimationParams animation;
141 } add_particlespawner;
144 } delete_particlespawner;
173 video::SColor *bgcolor;
175 std::vector<std::string> *params;
180 } override_day_night_ratio;
195 void add(u16 command)
197 std::map<u16, u16>::iterator n = m_packets.find(command);
198 if(n == m_packets.end())
200 m_packets[command] = 1;
210 for(std::map<u16, u16>::iterator
211 i = m_packets.begin();
212 i != m_packets.end(); ++i)
218 void print(std::ostream &o)
220 for(std::map<u16, u16>::iterator
221 i = m_packets.begin();
222 i != m_packets.end(); ++i)
225 <<" count "<<i->second
232 std::map<u16, u16> m_packets;
235 class ClientScripting;
238 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
242 NOTE: Nothing is thread-safe here.
246 IrrlichtDevice *device,
247 const char *playername,
248 std::string password,
249 MapDrawControl &control,
250 IWritableTextureSource *tsrc,
251 IWritableShaderSource *shsrc,
252 IWritableItemDefManager *itemdef,
253 IWritableNodeDefManager *nodedef,
254 ISoundManager *sound,
255 MtEventManager *event,
257 GameUIFlags *game_ui_flags
265 request all threads managed by client to be stopped
273 The name of the local player should already be set when
274 calling this, as it is sent in the initialization.
276 void connect(Address address,
277 const std::string &address_name,
278 bool is_local_server);
281 Stuff that references the environment is valid only as
282 long as this is not called. (eg. Players)
283 If this throws a PeerNotFoundException, the connection has
286 void step(float dtime);
292 void handleCommand(NetworkPacket* pkt);
294 void handleCommand_Null(NetworkPacket* pkt) {};
295 void handleCommand_Deprecated(NetworkPacket* pkt);
296 void handleCommand_Hello(NetworkPacket* pkt);
297 void handleCommand_AuthAccept(NetworkPacket* pkt);
298 void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
299 void handleCommand_DenySudoMode(NetworkPacket* pkt);
300 void handleCommand_InitLegacy(NetworkPacket* pkt);
301 void handleCommand_AccessDenied(NetworkPacket* pkt);
302 void handleCommand_RemoveNode(NetworkPacket* pkt);
303 void handleCommand_AddNode(NetworkPacket* pkt);
304 void handleCommand_BlockData(NetworkPacket* pkt);
305 void handleCommand_Inventory(NetworkPacket* pkt);
306 void handleCommand_TimeOfDay(NetworkPacket* pkt);
307 void handleCommand_ChatMessage(NetworkPacket* pkt);
308 void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
309 void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
310 void handleCommand_Movement(NetworkPacket* pkt);
311 void handleCommand_HP(NetworkPacket* pkt);
312 void handleCommand_Breath(NetworkPacket* pkt);
313 void handleCommand_MovePlayer(NetworkPacket* pkt);
314 void handleCommand_PlayerItem(NetworkPacket* pkt);
315 void handleCommand_DeathScreen(NetworkPacket* pkt);
316 void handleCommand_AnnounceMedia(NetworkPacket* pkt);
317 void handleCommand_Media(NetworkPacket* pkt);
318 void handleCommand_ToolDef(NetworkPacket* pkt);
319 void handleCommand_NodeDef(NetworkPacket* pkt);
320 void handleCommand_CraftItemDef(NetworkPacket* pkt);
321 void handleCommand_ItemDef(NetworkPacket* pkt);
322 void handleCommand_PlaySound(NetworkPacket* pkt);
323 void handleCommand_StopSound(NetworkPacket* pkt);
324 void handleCommand_Privileges(NetworkPacket* pkt);
325 void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
326 void handleCommand_DetachedInventory(NetworkPacket* pkt);
327 void handleCommand_ShowFormSpec(NetworkPacket* pkt);
328 void handleCommand_SpawnParticle(NetworkPacket* pkt);
329 void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
330 void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
331 void handleCommand_HudAdd(NetworkPacket* pkt);
332 void handleCommand_HudRemove(NetworkPacket* pkt);
333 void handleCommand_HudChange(NetworkPacket* pkt);
334 void handleCommand_HudSetFlags(NetworkPacket* pkt);
335 void handleCommand_HudSetParam(NetworkPacket* pkt);
336 void handleCommand_HudSetSky(NetworkPacket* pkt);
337 void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
338 void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
339 void handleCommand_EyeOffset(NetworkPacket* pkt);
340 void handleCommand_SrpBytesSandB(NetworkPacket* pkt);
342 void ProcessData(NetworkPacket *pkt);
344 void Send(NetworkPacket* pkt);
346 void interact(u8 action, const PointedThing& pointed);
348 void sendNodemetaFields(v3s16 p, const std::string &formname,
349 const StringMap &fields);
350 void sendInventoryFields(const std::string &formname,
351 const StringMap &fields);
352 void sendInventoryAction(InventoryAction *a);
353 void sendChatMessage(const std::wstring &message);
354 void sendChangePassword(const std::string &oldpassword,
355 const std::string &newpassword);
356 void sendDamage(u8 damage);
357 void sendBreath(u16 breath);
361 ClientEnvironment& getEnv() { return m_env; }
362 ITextureSource *tsrc() { return getTextureSource(); }
363 ISoundManager *sound() { return getSoundManager(); }
364 static const std::string &getBuiltinLuaPath();
365 static const std::string &getClientModsLuaPath();
367 virtual const std::vector<ModSpec> &getMods() const;
368 virtual const ModSpec* getModSpec(const std::string &modname) const;
370 // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
371 void removeNode(v3s16 p);
372 MapNode getNode(v3s16 p, bool *is_valid_position);
373 void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
375 void setPlayerControl(PlayerControl &control);
377 void selectPlayerItem(u16 item);
378 u16 getPlayerItem() const
379 { return m_playeritem; }
381 // Returns true if the inventory of the local player has been
382 // updated from the server. If it is true, it is set to false.
383 bool getLocalInventoryUpdated();
384 // Copies the inventory of the local player to parameter
385 void getLocalInventory(Inventory &dst);
387 /* InventoryManager interface */
388 Inventory* getInventory(const InventoryLocation &loc);
389 void inventoryAction(InventoryAction *a);
391 const std::list<std::string> &getConnectedPlayerNames()
393 return m_env.getPlayerNames();
396 float getAnimationTime();
400 void setCrack(int level, v3s16 pos);
404 bool checkPrivilege(const std::string &priv) const
405 { return (m_privileges.count(priv) != 0); }
407 bool getChatMessage(std::wstring &message);
408 void typeChatMessage(const std::wstring& message);
410 u64 getMapSeed(){ return m_map_seed; }
412 void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
413 // Including blocks at appropriate edges
414 void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
415 void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
417 void updateCameraOffset(v3s16 camera_offset)
418 { m_mesh_update_thread.m_camera_offset = camera_offset; }
420 // Get event from queue. CE_NONE is returned if queue is empty.
421 ClientEvent getClientEvent();
423 bool accessDenied() const { return m_access_denied; }
425 bool reconnectRequested() const { return m_access_denied_reconnect; }
427 void setFatalError(const std::string &reason)
429 m_access_denied = true;
430 m_access_denied_reason = reason;
433 // Renaming accessDeniedReason to better name could be good as it's used to
434 // disconnect client when CSM failed.
435 const std::string &accessDeniedReason() const { return m_access_denied_reason; }
437 bool itemdefReceived()
438 { return m_itemdef_received; }
439 bool nodedefReceived()
440 { return m_nodedef_received; }
442 { return m_media_downloader == NULL; }
445 { return m_proto_ver; }
447 bool connectedToServer()
448 { return m_con.Connected(); }
450 float mediaReceiveProgress();
452 void afterContentReceived(IrrlichtDevice *device);
457 Minimap* getMinimap() { return m_minimap; }
458 void setCamera(Camera* camera) { m_camera = camera; }
463 bool shouldShowMinimap() const;
465 // IGameDef interface
466 virtual IItemDefManager* getItemDefManager();
467 virtual INodeDefManager* getNodeDefManager();
468 virtual ICraftDefManager* getCraftDefManager();
469 ITextureSource* getTextureSource();
470 virtual IShaderSource* getShaderSource();
471 IShaderSource *shsrc() { return getShaderSource(); }
472 scene::ISceneManager* getSceneManager();
473 virtual u16 allocateUnknownNodeId(const std::string &name);
474 virtual ISoundManager* getSoundManager();
475 virtual MtEventManager* getEventManager();
476 virtual ParticleManager* getParticleManager();
477 bool checkLocalPrivilege(const std::string &priv)
478 { return checkPrivilege(priv); }
479 virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
481 virtual std::string getModStoragePath() const;
482 virtual bool registerModStorage(ModMetadata *meta);
483 virtual void unregisterModStorage(const std::string &name);
485 // The following set of functions is used by ClientMediaDownloader
486 // Insert a media file appropriately into the appropriate manager
487 bool loadMedia(const std::string &data, const std::string &filename);
488 // Send a request for conventional media transfer
489 void request_media(const std::vector<std::string> &file_requests);
490 // Send a notification that no conventional media transfer is needed
491 void received_media();
493 LocalClientState getState() { return m_state; }
495 void makeScreenshot(IrrlichtDevice *device);
497 inline void pushToChatQueue(const std::wstring &input)
499 m_chat_queue.push(input);
502 ClientScripting *getScript() { return m_script; }
503 const bool moddingEnabled() const { return m_modding_enabled; }
505 inline void pushToEventQueue(const ClientEvent &event)
507 m_client_event_queue.push(event);
510 void showGameChat(const bool show = true);
511 void showGameHud(const bool show = true);
512 void showMinimap(const bool show = true);
513 void showProfiler(const bool show = true);
514 void showGameFog(const bool show = true);
515 void showGameDebug(const bool show = true);
519 // Virtual methods from con::PeerHandler
520 void peerAdded(con::Peer *peer);
521 void deletingPeer(con::Peer *peer, bool timeout);
523 void initLocalMapSaving(const Address &address,
524 const std::string &hostname,
525 bool is_local_server);
530 void sendPlayerPos();
531 // Send the item number 'item' as player item to the server
532 void sendPlayerItem(u16 item);
534 void deleteAuthData();
535 // helper method shared with clientpackethandler
536 static AuthMechanism choseAuthMech(const u32 mechs);
538 void sendLegacyInit(const char* playerName, const char* playerPassword);
539 void sendInit(const std::string &playerName);
540 void startAuth(AuthMechanism chosen_auth_mechanism);
541 void sendDeletedBlocks(std::vector<v3s16> &blocks);
542 void sendGotBlocks(v3s16 block);
543 void sendRemovedSounds(std::vector<s32> &soundList);
546 inline std::string getPlayerName()
547 { return m_env.getLocalPlayer()->getName(); }
549 float m_packetcounter_timer;
550 float m_connection_reinit_timer;
551 float m_avg_rtt_timer;
552 float m_playerpos_send_timer;
553 float m_ignore_damage_timer; // Used after server moves player
554 IntervalLimiter m_map_timer_and_unload_interval;
556 IWritableTextureSource *m_tsrc;
557 IWritableShaderSource *m_shsrc;
558 IWritableItemDefManager *m_itemdef;
559 IWritableNodeDefManager *m_nodedef;
560 ISoundManager *m_sound;
561 MtEventManager *m_event;
564 MeshUpdateThread m_mesh_update_thread;
565 ClientEnvironment m_env;
566 ParticleManager m_particle_manager;
567 con::Connection m_con;
568 IrrlichtDevice *m_device;
571 bool m_minimap_disabled_by_server;
572 // Server serialization version
575 // Used version of the protocol with server
576 // Values smaller than 25 only mean they are smaller than 25,
577 // and aren't accurate. We simply just don't know, because
578 // the server didn't send the version back then.
579 // If 0, server init hasn't been received yet.
583 bool m_inventory_updated;
584 Inventory *m_inventory_from_server;
585 float m_inventory_from_server_age;
586 PacketCounter m_packetcounter;
587 // Block mesh animation parameters
588 float m_animation_time;
591 // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
593 //u32 m_daynight_ratio;
594 std::queue<std::wstring> m_chat_queue;
596 // The authentication methods we can use to enter sudo mode (=change password)
597 u32 m_sudo_auth_methods;
599 // The seed returned by the server in TOCLIENT_INIT is stored here
603 std::string m_playername;
604 std::string m_password;
605 // If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
606 std::string m_new_password;
607 // Usable by auth mechanisms.
608 AuthMechanism m_chosen_auth_mech;
612 bool m_access_denied;
613 bool m_access_denied_reconnect;
614 std::string m_access_denied_reason;
615 std::queue<ClientEvent> m_client_event_queue;
616 bool m_itemdef_received;
617 bool m_nodedef_received;
618 ClientMediaDownloader *m_media_downloader;
620 // time_of_day speed approximation for old protocol
621 bool m_time_of_day_set;
622 float m_last_time_of_day_f;
623 float m_time_of_day_update_timer;
625 // An interval for generally sending object positions and stuff
626 float m_recommended_send_interval;
629 float m_removed_sounds_check_timer;
630 // Mapping from server sound ids to our sound ids
631 UNORDERED_MAP<s32, int> m_sounds_server_to_client;
632 // And the other way!
633 UNORDERED_MAP<int, s32> m_sounds_client_to_server;
634 // And relations to objects
635 UNORDERED_MAP<int, u16> m_sounds_to_objects;
638 UNORDERED_SET<std::string> m_privileges;
640 // Detached inventories
642 UNORDERED_MAP<std::string, Inventory*> m_detached_inventories;
644 // Storage for mesh data for creating multiple instances of the same mesh
645 StringMap m_mesh_data;
648 LocalClientState m_state;
650 // Used for saving server map to disk client-side
652 IntervalLimiter m_localdb_save_interval;
653 u16 m_cache_save_interval;
655 ClientScripting *m_script;
656 bool m_modding_enabled;
657 UNORDERED_MAP<std::string, ModMetadata *> m_mod_storages;
658 float m_mod_storage_save_timer;
659 GameUIFlags *m_game_ui_flags;
662 DISABLE_CLASS_COPY(Client);
665 #endif // !CLIENT_HEADER