1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 
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.
9 
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.
14 
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.
18 */
19 
20 #pragma once
21 
22 #include "clientenvironment.h"
23 #include "irrlichttypes_extrabloated.h"
24 #include <ostream>
25 #include <map>
26 #include <set>
27 #include <vector>
28 #include <unordered_set>
29 #include "clientobject.h"
30 #include "gamedef.h"
31 #include "inventorymanager.h"
32 #include "localplayer.h"
33 #include "client/hud.h"
34 #include "particles.h"
35 #include "mapnode.h"
36 #include "tileanimation.h"
37 #include "mesh_generator_thread.h"
38 #include "network/address.h"
39 #include "network/peerhandler.h"
40 #include <fstream>
41 
42 #define CLIENT_CHAT_MESSAGE_LIMIT_PER_10S 10.0f
43 
44 struct ClientEvent;
45 struct MeshMakeData;
46 struct ChatMessage;
47 class MapBlockMesh;
48 class IWritableTextureSource;
49 class IWritableShaderSource;
50 class IWritableItemDefManager;
51 class ISoundManager;
52 class NodeDefManager;
53 //class IWritableCraftDefManager;
54 class ClientMediaDownloader;
55 struct MapDrawControl;
56 class ModChannelMgr;
57 class MtEventManager;
58 struct PointedThing;
59 class MapDatabase;
60 class Minimap;
61 struct MinimapMapblock;
62 class Camera;
63 class NetworkPacket;
64 namespace con {
65 class Connection;
66 }
67 
68 enum LocalClientState {
69 	LC_Created,
70 	LC_Init,
71 	LC_Ready
72 };
73 
74 /*
75 	Packet counter
76 */
77 
78 class PacketCounter
79 {
80 public:
81 	PacketCounter() = default;
82 
add(u16 command)83 	void add(u16 command)
84 	{
85 		auto n = m_packets.find(command);
86 		if (n == m_packets.end())
87 			m_packets[command] = 1;
88 		else
89 			n->second++;
90 	}
91 
clear()92 	void clear()
93 	{
94 		m_packets.clear();
95 	}
96 
97 	u32 sum() const;
98 	void print(std::ostream &o) const;
99 
100 private:
101 	// command, count
102 	std::map<u16, u32> m_packets;
103 };
104 
105 class ClientScripting;
106 class GameUI;
107 
108 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
109 {
110 public:
111 	/*
112 		NOTE: Nothing is thread-safe here.
113 	*/
114 
115 	Client(
116 			const char *playername,
117 			const std::string &password,
118 			const std::string &address_name,
119 			MapDrawControl &control,
120 			IWritableTextureSource *tsrc,
121 			IWritableShaderSource *shsrc,
122 			IWritableItemDefManager *itemdef,
123 			NodeDefManager *nodedef,
124 			ISoundManager *sound,
125 			MtEventManager *event,
126 			bool ipv6,
127 			GameUI *game_ui
128 	);
129 
130 	~Client();
131 	DISABLE_CLASS_COPY(Client);
132 
133 	// Load local mods into memory
134 	void scanModSubfolder(const std::string &mod_name, const std::string &mod_path,
135 				std::string mod_subpath);
scanModIntoMemory(const std::string & mod_name,const std::string & mod_path)136 	inline void scanModIntoMemory(const std::string &mod_name, const std::string &mod_path)
137 	{
138 		scanModSubfolder(mod_name, mod_path, "");
139 	}
140 
141 	/*
142 	 request all threads managed by client to be stopped
143 	 */
144 	void Stop();
145 
146 
147 	bool isShutdown();
148 
149 	/*
150 		The name of the local player should already be set when
151 		calling this, as it is sent in the initialization.
152 	*/
153 	void connect(Address address, bool is_local_server);
154 
155 	/*
156 		Stuff that references the environment is valid only as
157 		long as this is not called. (eg. Players)
158 		If this throws a PeerNotFoundException, the connection has
159 		timed out.
160 	*/
161 	void step(float dtime);
162 
163 	/*
164 	 * Command Handlers
165 	 */
166 
167 	void handleCommand(NetworkPacket* pkt);
168 
handleCommand_Null(NetworkPacket * pkt)169 	void handleCommand_Null(NetworkPacket* pkt) {};
170 	void handleCommand_Deprecated(NetworkPacket* pkt);
171 	void handleCommand_Hello(NetworkPacket* pkt);
172 	void handleCommand_AuthAccept(NetworkPacket* pkt);
173 	void handleCommand_AcceptSudoMode(NetworkPacket* pkt);
174 	void handleCommand_DenySudoMode(NetworkPacket* pkt);
175 	void handleCommand_AccessDenied(NetworkPacket* pkt);
176 	void handleCommand_RemoveNode(NetworkPacket* pkt);
177 	void handleCommand_AddNode(NetworkPacket* pkt);
178 	void handleCommand_NodemetaChanged(NetworkPacket *pkt);
179 	void handleCommand_BlockData(NetworkPacket* pkt);
180 	void handleCommand_Inventory(NetworkPacket* pkt);
181 	void handleCommand_TimeOfDay(NetworkPacket* pkt);
182 	void handleCommand_ChatMessage(NetworkPacket *pkt);
183 	void handleCommand_ActiveObjectRemoveAdd(NetworkPacket* pkt);
184 	void handleCommand_ActiveObjectMessages(NetworkPacket* pkt);
185 	void handleCommand_Movement(NetworkPacket* pkt);
186 	void handleCommand_Fov(NetworkPacket *pkt);
187 	void handleCommand_HP(NetworkPacket* pkt);
188 	void handleCommand_Breath(NetworkPacket* pkt);
189 	void handleCommand_MovePlayer(NetworkPacket* pkt);
190 	void handleCommand_DeathScreen(NetworkPacket* pkt);
191 	void handleCommand_AnnounceMedia(NetworkPacket* pkt);
192 	void handleCommand_Media(NetworkPacket* pkt);
193 	void handleCommand_NodeDef(NetworkPacket* pkt);
194 	void handleCommand_ItemDef(NetworkPacket* pkt);
195 	void handleCommand_PlaySound(NetworkPacket* pkt);
196 	void handleCommand_StopSound(NetworkPacket* pkt);
197 	void handleCommand_FadeSound(NetworkPacket *pkt);
198 	void handleCommand_Privileges(NetworkPacket* pkt);
199 	void handleCommand_InventoryFormSpec(NetworkPacket* pkt);
200 	void handleCommand_DetachedInventory(NetworkPacket* pkt);
201 	void handleCommand_ShowFormSpec(NetworkPacket* pkt);
202 	void handleCommand_SpawnParticle(NetworkPacket* pkt);
203 	void handleCommand_AddParticleSpawner(NetworkPacket* pkt);
204 	void handleCommand_DeleteParticleSpawner(NetworkPacket* pkt);
205 	void handleCommand_HudAdd(NetworkPacket* pkt);
206 	void handleCommand_HudRemove(NetworkPacket* pkt);
207 	void handleCommand_HudChange(NetworkPacket* pkt);
208 	void handleCommand_HudSetFlags(NetworkPacket* pkt);
209 	void handleCommand_HudSetParam(NetworkPacket* pkt);
210 	void handleCommand_HudSetSky(NetworkPacket* pkt);
211 	void handleCommand_HudSetSun(NetworkPacket* pkt);
212 	void handleCommand_HudSetMoon(NetworkPacket* pkt);
213 	void handleCommand_HudSetStars(NetworkPacket* pkt);
214 	void handleCommand_CloudParams(NetworkPacket* pkt);
215 	void handleCommand_OverrideDayNightRatio(NetworkPacket* pkt);
216 	void handleCommand_LocalPlayerAnimations(NetworkPacket* pkt);
217 	void handleCommand_EyeOffset(NetworkPacket* pkt);
218 	void handleCommand_UpdatePlayerList(NetworkPacket* pkt);
219 	void handleCommand_ModChannelMsg(NetworkPacket *pkt);
220 	void handleCommand_ModChannelSignal(NetworkPacket *pkt);
221 	void handleCommand_SrpBytesSandB(NetworkPacket *pkt);
222 	void handleCommand_FormspecPrepend(NetworkPacket *pkt);
223 	void handleCommand_CSMRestrictionFlags(NetworkPacket *pkt);
224 	void handleCommand_PlayerSpeed(NetworkPacket *pkt);
225 	void handleCommand_MediaPush(NetworkPacket *pkt);
226 	void handleCommand_MinimapModes(NetworkPacket *pkt);
227 
228 	void ProcessData(NetworkPacket *pkt);
229 
230 	void Send(NetworkPacket* pkt);
231 
232 	void interact(InteractAction action, const PointedThing &pointed);
233 
234 	void sendNodemetaFields(v3s16 p, const std::string &formname,
235 		const StringMap &fields);
236 	void sendInventoryFields(const std::string &formname,
237 		const StringMap &fields);
238 	void sendInventoryAction(InventoryAction *a);
239 	void sendChatMessage(const std::wstring &message);
240 	void clearOutChatQueue();
241 	void sendChangePassword(const std::string &oldpassword,
242 		const std::string &newpassword);
243 	void sendDamage(u16 damage);
244 	void sendRespawn();
245 	void sendReady();
246 
getEnv()247 	ClientEnvironment& getEnv() { return m_env; }
tsrc()248 	ITextureSource *tsrc() { return getTextureSource(); }
sound()249 	ISoundManager *sound() { return getSoundManager(); }
250 	static const std::string &getBuiltinLuaPath();
251 	static const std::string &getClientModsLuaPath();
252 
253 	const std::vector<ModSpec> &getMods() const override;
254 	const ModSpec* getModSpec(const std::string &modname) const override;
255 
256 	// Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
257 	void removeNode(v3s16 p);
258 
259 	// helpers to enforce CSM restrictions
260 	MapNode CSMGetNode(v3s16 p, bool *is_valid_position);
261 	int CSMClampRadius(v3s16 pos, int radius);
262 	v3s16 CSMClampPos(v3s16 pos);
263 
264 	void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
265 
266 	void setPlayerControl(PlayerControl &control);
267 
268 	// Returns true if the inventory of the local player has been
269 	// updated from the server. If it is true, it is set to false.
270 	bool updateWieldedItem();
271 
272 	/* InventoryManager interface */
273 	Inventory* getInventory(const InventoryLocation &loc) override;
274 	void inventoryAction(InventoryAction *a) override;
275 
276 	// Send the item number 'item' as player item to the server
277 	void setPlayerItem(u16 item);
278 
getConnectedPlayerNames()279 	const std::list<std::string> &getConnectedPlayerNames()
280 	{
281 		return m_env.getPlayerNames();
282 	}
283 
284 	float getAnimationTime();
285 
286 	int getCrackLevel();
287 	v3s16 getCrackPos();
288 	void setCrack(int level, v3s16 pos);
289 
290 	u16 getHP();
291 
checkPrivilege(const std::string & priv)292 	bool checkPrivilege(const std::string &priv) const
293 	{ return (m_privileges.count(priv) != 0); }
294 
getPrivilegeList()295 	const std::unordered_set<std::string> &getPrivilegeList() const
296 	{ return m_privileges; }
297 
298 	bool getChatMessage(std::wstring &message);
299 	void typeChatMessage(const std::wstring& message);
300 
getMapSeed()301 	u64 getMapSeed(){ return m_map_seed; }
302 
303 	void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
304 	// Including blocks at appropriate edges
305 	void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
306 	void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
307 
updateCameraOffset(v3s16 camera_offset)308 	void updateCameraOffset(v3s16 camera_offset)
309 	{ m_mesh_update_thread.m_camera_offset = camera_offset; }
310 
hasClientEvents()311 	bool hasClientEvents() const { return !m_client_event_queue.empty(); }
312 	// Get event from queue. If queue is empty, it triggers an assertion failure.
313 	ClientEvent * getClientEvent();
314 
accessDenied()315 	bool accessDenied() const { return m_access_denied; }
316 
reconnectRequested()317 	bool reconnectRequested() const { return m_access_denied_reconnect; }
318 
setFatalError(const std::string & reason)319 	void setFatalError(const std::string &reason)
320 	{
321 		m_access_denied = true;
322 		m_access_denied_reason = reason;
323 	}
324 
325 	// Renaming accessDeniedReason to better name could be good as it's used to
326 	// disconnect client when CSM failed.
accessDeniedReason()327 	const std::string &accessDeniedReason() const { return m_access_denied_reason; }
328 
itemdefReceived()329 	const bool itemdefReceived() const
330 	{ return m_itemdef_received; }
nodedefReceived()331 	const bool nodedefReceived() const
332 	{ return m_nodedef_received; }
mediaReceived()333 	const bool mediaReceived() const
334 	{ return !m_media_downloader; }
activeObjectsReceived()335 	const bool activeObjectsReceived() const
336 	{ return m_activeobjects_received; }
337 
getProtoVersion()338 	u16 getProtoVersion()
339 	{ return m_proto_ver; }
340 
341 	void confirmRegistration();
342 	bool m_is_registration_confirmation_state = false;
343 	bool m_simple_singleplayer_mode;
344 
345 	float mediaReceiveProgress();
346 
347 	void afterContentReceived();
348 
349 	float getRTT();
350 	float getCurRate();
351 
getMinimap()352 	Minimap* getMinimap() { return m_minimap; }
setCamera(Camera * camera)353 	void setCamera(Camera* camera) { m_camera = camera; }
354 
getCamera()355 	Camera* getCamera () { return m_camera; }
356 
357 	bool shouldShowMinimap() const;
358 
359 	// IGameDef interface
360 	IItemDefManager* getItemDefManager() override;
361 	const NodeDefManager* getNodeDefManager() override;
362 	ICraftDefManager* getCraftDefManager() override;
363 	ITextureSource* getTextureSource();
364 	virtual IWritableShaderSource* getShaderSource();
365 	u16 allocateUnknownNodeId(const std::string &name) override;
366 	virtual ISoundManager* getSoundManager();
367 	MtEventManager* getEventManager();
368 	virtual ParticleManager* getParticleManager();
checkLocalPrivilege(const std::string & priv)369 	bool checkLocalPrivilege(const std::string &priv)
370 	{ return checkPrivilege(priv); }
371 	virtual scene::IAnimatedMesh* getMesh(const std::string &filename, bool cache = false);
372 	const std::string* getModFile(std::string filename);
373 
374 	std::string getModStoragePath() const override;
375 	bool registerModStorage(ModMetadata *meta) override;
376 	void unregisterModStorage(const std::string &name) override;
377 
378 	// The following set of functions is used by ClientMediaDownloader
379 	// Insert a media file appropriately into the appropriate manager
380 	bool loadMedia(const std::string &data, const std::string &filename,
381 		bool from_media_push = false);
382 	// Send a request for conventional media transfer
383 	void request_media(const std::vector<std::string> &file_requests);
384 
getState()385 	LocalClientState getState() { return m_state; }
386 
387 	void makeScreenshot();
388 
pushToChatQueue(ChatMessage * cec)389 	inline void pushToChatQueue(ChatMessage *cec)
390 	{
391 		m_chat_queue.push(cec);
392 	}
393 
getScript()394 	ClientScripting *getScript() { return m_script; }
modsLoaded()395 	const bool modsLoaded() const { return m_mods_loaded; }
396 
397 	void pushToEventQueue(ClientEvent *event);
398 
399 	void showMinimap(bool show = true);
400 
401 	const Address getServerAddress();
402 
getAddressName()403 	const std::string &getAddressName() const
404 	{
405 		return m_address_name;
406 	}
407 
getCSMRestrictionFlags()408 	inline u64 getCSMRestrictionFlags() const
409 	{
410 		return m_csm_restriction_flags;
411 	}
412 
checkCSMRestrictionFlag(CSMRestrictionFlags flag)413 	inline bool checkCSMRestrictionFlag(CSMRestrictionFlags flag) const
414 	{
415 		return m_csm_restriction_flags & flag;
416 	}
417 
418 	bool joinModChannel(const std::string &channel) override;
419 	bool leaveModChannel(const std::string &channel) override;
420 	bool sendModChannelMessage(const std::string &channel,
421 			const std::string &message) override;
422 	ModChannel *getModChannel(const std::string &channel) override;
423 
getFormspecPrepend()424 	const std::string &getFormspecPrepend() const
425 	{
426 		return m_env.getLocalPlayer()->formspec_prepend;
427 	}
428 private:
429 	void loadMods();
430 
431 	// Virtual methods from con::PeerHandler
432 	void peerAdded(con::Peer *peer) override;
433 	void deletingPeer(con::Peer *peer, bool timeout) override;
434 
435 	void initLocalMapSaving(const Address &address,
436 			const std::string &hostname,
437 			bool is_local_server);
438 
439 	void ReceiveAll();
440 
441 	void sendPlayerPos();
442 
443 	void deleteAuthData();
444 	// helper method shared with clientpackethandler
445 	static AuthMechanism choseAuthMech(const u32 mechs);
446 
447 	void sendInit(const std::string &playerName);
448 	void promptConfirmRegistration(AuthMechanism chosen_auth_mechanism);
449 	void startAuth(AuthMechanism chosen_auth_mechanism);
450 	void sendDeletedBlocks(std::vector<v3s16> &blocks);
451 	void sendGotBlocks(const std::vector<v3s16> &blocks);
452 	void sendRemovedSounds(std::vector<s32> &soundList);
453 
454 	// Helper function
getPlayerName()455 	inline std::string getPlayerName()
456 	{ return m_env.getLocalPlayer()->getName(); }
457 
458 	bool canSendChatMessage() const;
459 
460 	float m_packetcounter_timer = 0.0f;
461 	float m_connection_reinit_timer = 0.1f;
462 	float m_avg_rtt_timer = 0.0f;
463 	float m_playerpos_send_timer = 0.0f;
464 	IntervalLimiter m_map_timer_and_unload_interval;
465 
466 	IWritableTextureSource *m_tsrc;
467 	IWritableShaderSource *m_shsrc;
468 	IWritableItemDefManager *m_itemdef;
469 	NodeDefManager *m_nodedef;
470 	ISoundManager *m_sound;
471 	MtEventManager *m_event;
472 
473 
474 	MeshUpdateThread m_mesh_update_thread;
475 	ClientEnvironment m_env;
476 	ParticleManager m_particle_manager;
477 	std::unique_ptr<con::Connection> m_con;
478 	std::string m_address_name;
479 	Camera *m_camera = nullptr;
480 	Minimap *m_minimap = nullptr;
481 	bool m_minimap_disabled_by_server = false;
482 
483 	// Server serialization version
484 	u8 m_server_ser_ver;
485 
486 	// Used version of the protocol with server
487 	// Values smaller than 25 only mean they are smaller than 25,
488 	// and aren't accurate. We simply just don't know, because
489 	// the server didn't send the version back then.
490 	// If 0, server init hasn't been received yet.
491 	u16 m_proto_ver = 0;
492 
493 	bool m_update_wielded_item = false;
494 	Inventory *m_inventory_from_server = nullptr;
495 	float m_inventory_from_server_age = 0.0f;
496 	PacketCounter m_packetcounter;
497 	// Block mesh animation parameters
498 	float m_animation_time = 0.0f;
499 	int m_crack_level = -1;
500 	v3s16 m_crack_pos;
501 	// 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
502 	//s32 m_daynight_i;
503 	//u32 m_daynight_ratio;
504 	std::queue<std::wstring> m_out_chat_queue;
505 	u32 m_last_chat_message_sent;
506 	float m_chat_message_allowance = 5.0f;
507 	std::queue<ChatMessage *> m_chat_queue;
508 
509 	// The authentication methods we can use to enter sudo mode (=change password)
510 	u32 m_sudo_auth_methods;
511 
512 	// The seed returned by the server in TOCLIENT_INIT is stored here
513 	u64 m_map_seed = 0;
514 
515 	// Auth data
516 	std::string m_playername;
517 	std::string m_password;
518 	// If set, this will be sent (and cleared) upon a TOCLIENT_ACCEPT_SUDO_MODE
519 	std::string m_new_password;
520 	// Usable by auth mechanisms.
521 	AuthMechanism m_chosen_auth_mech;
522 	void *m_auth_data = nullptr;
523 
524 	bool m_access_denied = false;
525 	bool m_access_denied_reconnect = false;
526 	std::string m_access_denied_reason = "";
527 	std::queue<ClientEvent *> m_client_event_queue;
528 	bool m_itemdef_received = false;
529 	bool m_nodedef_received = false;
530 	bool m_activeobjects_received = false;
531 	bool m_mods_loaded = false;
532 
533 	ClientMediaDownloader *m_media_downloader;
534 	// Set of media filenames pushed by server at runtime
535 	std::unordered_set<std::string> m_media_pushed_files;
536 
537 	// time_of_day speed approximation for old protocol
538 	bool m_time_of_day_set = false;
539 	float m_last_time_of_day_f = -1.0f;
540 	float m_time_of_day_update_timer = 0.0f;
541 
542 	// An interval for generally sending object positions and stuff
543 	float m_recommended_send_interval = 0.1f;
544 
545 	// Sounds
546 	float m_removed_sounds_check_timer = 0.0f;
547 	// Mapping from server sound ids to our sound ids
548 	std::unordered_map<s32, int> m_sounds_server_to_client;
549 	// And the other way!
550 	std::unordered_map<int, s32> m_sounds_client_to_server;
551 	// Relation of client id to object id
552 	std::unordered_map<int, u16> m_sounds_to_objects;
553 
554 	// Privileges
555 	std::unordered_set<std::string> m_privileges;
556 
557 	// Detached inventories
558 	// key = name
559 	std::unordered_map<std::string, Inventory*> m_detached_inventories;
560 
561 	// Storage for mesh data for creating multiple instances of the same mesh
562 	StringMap m_mesh_data;
563 
564 	// own state
565 	LocalClientState m_state;
566 
567 	GameUI *m_game_ui;
568 
569 	// Used for saving server map to disk client-side
570 	MapDatabase *m_localdb = nullptr;
571 	IntervalLimiter m_localdb_save_interval;
572 	u16 m_cache_save_interval;
573 
574 	// Client modding
575 	ClientScripting *m_script = nullptr;
576 	std::unordered_map<std::string, ModMetadata *> m_mod_storages;
577 	float m_mod_storage_save_timer = 10.0f;
578 	std::vector<ModSpec> m_mods;
579 	StringMap m_mod_vfs;
580 
581 	bool m_shutdown = false;
582 
583 	// CSM restrictions byteflag
584 	u64 m_csm_restriction_flags = CSMRestrictionFlags::CSM_RF_NONE;
585 	u32 m_csm_restriction_noderange = 8;
586 
587 	std::unique_ptr<ModChannelMgr> m_modchannel_mgr;
588 };
589