]> git.lizzy.rs Git - minetest.git/blob - src/client.h
33d806f9f6ffb8eedcd13fd92f63c122d05bcb9c
[minetest.git] / src / client.h
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 #ifndef CLIENT_HEADER
21 #define CLIENT_HEADER
22
23 #include "connection.h"
24 #include "environment.h"
25 #include "irrlichttypes_extrabloated.h"
26 #include "jthread/jmutex.h"
27 #include <ostream>
28 #include <map>
29 #include <set>
30 #include <vector>
31 #include "clientobject.h"
32 #include "gamedef.h"
33 #include "inventorymanager.h"
34 #include "localplayer.h"
35 #include "hud.h"
36 #include "particles.h"
37
38 struct MeshMakeData;
39 class MapBlockMesh;
40 class IWritableTextureSource;
41 class IWritableShaderSource;
42 class IWritableItemDefManager;
43 class IWritableNodeDefManager;
44 //class IWritableCraftDefManager;
45 class ClientMediaDownloader;
46 struct MapDrawControl;
47 class MtEventManager;
48 struct PointedThing;
49
50 struct QueuedMeshUpdate
51 {
52         v3s16 p;
53         MeshMakeData *data;
54         bool ack_block_to_server;
55
56         QueuedMeshUpdate();
57         ~QueuedMeshUpdate();
58 };
59
60 /*
61         A thread-safe queue of mesh update tasks
62 */
63 class MeshUpdateQueue
64 {
65 public:
66         MeshUpdateQueue();
67
68         ~MeshUpdateQueue();
69         
70         /*
71                 peer_id=0 adds with nobody to send to
72         */
73         void addBlock(v3s16 p, MeshMakeData *data,
74                         bool ack_block_to_server, bool urgent);
75
76         // Returned pointer must be deleted
77         // Returns NULL if queue is empty
78         QueuedMeshUpdate * pop();
79
80         u32 size()
81         {
82                 JMutexAutoLock lock(m_mutex);
83                 return m_queue.size();
84         }
85         
86 private:
87         std::vector<QueuedMeshUpdate*> m_queue;
88         std::set<v3s16> m_urgents;
89         JMutex m_mutex;
90 };
91
92 struct MeshUpdateResult
93 {
94         v3s16 p;
95         MapBlockMesh *mesh;
96         bool ack_block_to_server;
97
98         MeshUpdateResult():
99                 p(-1338,-1338,-1338),
100                 mesh(NULL),
101                 ack_block_to_server(false)
102         {
103         }
104 };
105
106 class MeshUpdateThread : public JThread
107 {
108 public:
109
110         MeshUpdateThread(IGameDef *gamedef):
111                 m_gamedef(gamedef)
112         {
113         }
114
115         void * Thread();
116
117         MeshUpdateQueue m_queue_in;
118
119         MutexedQueue<MeshUpdateResult> m_queue_out;
120
121         IGameDef *m_gamedef;
122 };
123
124 enum ClientEventType
125 {
126         CE_NONE,
127         CE_PLAYER_DAMAGE,
128         CE_PLAYER_FORCE_MOVE,
129         CE_DEATHSCREEN,
130         CE_SHOW_FORMSPEC,
131         CE_SPAWN_PARTICLE,
132         CE_ADD_PARTICLESPAWNER,
133         CE_DELETE_PARTICLESPAWNER,
134         CE_HUDADD,
135         CE_HUDRM,
136         CE_HUDCHANGE,
137         CE_SET_SKY,
138 };
139
140 struct ClientEvent
141 {
142         ClientEventType type;
143         union{
144                 struct{
145                 } none;
146                 struct{
147                         u8 amount;
148                 } player_damage;
149                 struct{
150                         f32 pitch;
151                         f32 yaw;
152                 } player_force_move;
153                 struct{
154                         bool set_camera_point_target;
155                         f32 camera_point_target_x;
156                         f32 camera_point_target_y;
157                         f32 camera_point_target_z;
158                 } deathscreen;
159                 struct{
160                         std::string *formspec;
161                         std::string *formname;
162                 } show_formspec;
163                 struct{
164                 } textures_updated;
165                 struct{
166                         v3f *pos;
167                         v3f *vel;
168                         v3f *acc;
169                         f32 expirationtime;
170                         f32 size;
171                         bool collisiondetection;
172                         bool vertical;
173                         std::string *texture;
174                 } spawn_particle;
175                 struct{
176                         u16 amount;
177                         f32 spawntime;
178                         v3f *minpos;
179                         v3f *maxpos;
180                         v3f *minvel;
181                         v3f *maxvel;
182                         v3f *minacc;
183                         v3f *maxacc;
184                         f32 minexptime;
185                         f32 maxexptime;
186                         f32 minsize;
187                         f32 maxsize;
188                         bool collisiondetection;
189                         bool vertical;
190                         std::string *texture;
191                         u32 id;
192                 } add_particlespawner;
193                 struct{
194                         u32 id;
195                 } delete_particlespawner;
196                 struct{
197                         u32 id;
198                         u8 type;
199                         v2f *pos;
200                         std::string *name;
201                         v2f *scale;
202                         std::string *text;
203                         u32 number;
204                         u32 item;
205                         u32 dir;
206                         v2f *align;
207                         v2f *offset;
208                         v3f *world_pos;
209                 } hudadd;
210                 struct{
211                         u32 id;
212                 } hudrm;
213                 struct{
214                         u32 id;
215                         HudElementStat stat;
216                         v2f *v2fdata;
217                         std::string *sdata;
218                         u32 data;
219                         v3f *v3fdata;
220                 } hudchange;
221                 struct{
222                         video::SColor *bgcolor;
223                         std::string *type;
224                         std::vector<std::string> *params;
225                 } set_sky;
226         };
227 };
228
229 /*
230         Packet counter
231 */
232
233 class PacketCounter
234 {
235 public:
236         PacketCounter()
237         {
238         }
239
240         void add(u16 command)
241         {
242                 std::map<u16, u16>::iterator n = m_packets.find(command);
243                 if(n == m_packets.end())
244                 {
245                         m_packets[command] = 1;
246                 }
247                 else
248                 {
249                         n->second++;
250                 }
251         }
252
253         void clear()
254         {
255                 for(std::map<u16, u16>::iterator
256                                 i = m_packets.begin();
257                                 i != m_packets.end(); ++i)
258                 {
259                         i->second = 0;
260                 }
261         }
262
263         void print(std::ostream &o)
264         {
265                 for(std::map<u16, u16>::iterator
266                                 i = m_packets.begin();
267                                 i != m_packets.end(); ++i)
268                 {
269                         o<<"cmd "<<i->first
270                                         <<" count "<<i->second
271                                         <<std::endl;
272                 }
273         }
274
275 private:
276         // command, count
277         std::map<u16, u16> m_packets;
278 };
279
280 class Client : public con::PeerHandler, public InventoryManager, public IGameDef
281 {
282 public:
283         /*
284                 NOTE: Nothing is thread-safe here.
285         */
286
287         Client(
288                         IrrlichtDevice *device,
289                         const char *playername,
290                         std::string password,
291                         MapDrawControl &control,
292                         IWritableTextureSource *tsrc,
293                         IWritableShaderSource *shsrc,
294                         IWritableItemDefManager *itemdef,
295                         IWritableNodeDefManager *nodedef,
296                         ISoundManager *sound,
297                         MtEventManager *event,
298                         bool ipv6
299         );
300         
301         ~Client();
302
303         /*
304          request all threads managed by client to be stopped
305          */
306         void Stop();
307
308
309         bool isShutdown();
310         /*
311                 The name of the local player should already be set when
312                 calling this, as it is sent in the initialization.
313         */
314         void connect(Address address);
315         /*
316                 returns true when
317                         m_con.Connected() == true
318                         AND m_server_ser_ver != SER_FMT_VER_INVALID
319                 throws con::PeerNotFoundException if connection has been deleted,
320                 eg. timed out.
321         */
322         bool connectedAndInitialized();
323         /*
324                 Stuff that references the environment is valid only as
325                 long as this is not called. (eg. Players)
326                 If this throws a PeerNotFoundException, the connection has
327                 timed out.
328         */
329         void step(float dtime);
330
331         void ProcessData(u8 *data, u32 datasize, u16 sender_peer_id);
332         // Returns true if something was received
333         bool AsyncProcessPacket();
334         bool AsyncProcessData();
335         void Send(u16 channelnum, SharedBuffer<u8> data, bool reliable);
336
337         void interact(u8 action, const PointedThing& pointed);
338
339         void sendNodemetaFields(v3s16 p, const std::string &formname,
340                         const std::map<std::string, std::string> &fields);
341         void sendInventoryFields(const std::string &formname,
342                         const std::map<std::string, std::string> &fields);
343         void sendInventoryAction(InventoryAction *a);
344         void sendChatMessage(const std::wstring &message);
345         void sendChangePassword(const std::wstring oldpassword,
346                         const std::wstring newpassword);
347         void sendDamage(u8 damage);
348         void sendBreath(u16 breath);
349         void sendRespawn();
350
351         ClientEnvironment& getEnv()
352         { return m_env; }
353         
354         // Causes urgent mesh updates (unlike Map::add/removeNodeWithEvent)
355         void removeNode(v3s16 p);
356         void addNode(v3s16 p, MapNode n, bool remove_metadata = true);
357         
358         void setPlayerControl(PlayerControl &control);
359
360         void selectPlayerItem(u16 item);
361         u16 getPlayerItem() const
362         { return m_playeritem; }
363
364         // Returns true if the inventory of the local player has been
365         // updated from the server. If it is true, it is set to false.
366         bool getLocalInventoryUpdated();
367         // Copies the inventory of the local player to parameter
368         void getLocalInventory(Inventory &dst);
369         
370         /* InventoryManager interface */
371         Inventory* getInventory(const InventoryLocation &loc);
372         void inventoryAction(InventoryAction *a);
373
374         // Gets closest object pointed by the shootline
375         // Returns NULL if not found
376         ClientActiveObject * getSelectedActiveObject(
377                         f32 max_d,
378                         v3f from_pos_f_on_map,
379                         core::line3d<f32> shootline_on_map
380         );
381
382         // Prints a line or two of info
383         void printDebugInfo(std::ostream &os);
384
385         std::list<std::string> getConnectedPlayerNames();
386
387         float getAnimationTime();
388
389         int getCrackLevel();
390         void setCrack(int level, v3s16 pos);
391
392         u16 getHP();
393         u16 getBreath();
394
395         bool checkPrivilege(const std::string &priv)
396         { return (m_privileges.count(priv) != 0); }
397
398         bool getChatMessage(std::wstring &message);
399         void typeChatMessage(const std::wstring& message);
400
401         u64 getMapSeed(){ return m_map_seed; }
402
403         void addUpdateMeshTask(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
404         // Including blocks at appropriate edges
405         void addUpdateMeshTaskWithEdge(v3s16 blockpos, bool ack_to_server=false, bool urgent=false);
406         void addUpdateMeshTaskForNode(v3s16 nodepos, bool ack_to_server=false, bool urgent=false);
407
408         // Get event from queue. CE_NONE is returned if queue is empty.
409         ClientEvent getClientEvent();
410         
411         bool accessDenied()
412         { return m_access_denied; }
413
414         std::wstring accessDeniedReason()
415         { return m_access_denied_reason; }
416
417         bool itemdefReceived()
418         { return m_itemdef_received; }
419         bool nodedefReceived()
420         { return m_nodedef_received; }
421         bool mediaReceived()
422         { return m_media_downloader == NULL; }
423
424         float mediaReceiveProgress();
425
426         void afterContentReceived(IrrlichtDevice *device, gui::IGUIFont* font);
427
428         float getRTT(void);
429
430         // IGameDef interface
431         virtual IItemDefManager* getItemDefManager();
432         virtual INodeDefManager* getNodeDefManager();
433         virtual ICraftDefManager* getCraftDefManager();
434         virtual ITextureSource* getTextureSource();
435         virtual IShaderSource* getShaderSource();
436         virtual u16 allocateUnknownNodeId(const std::string &name);
437         virtual ISoundManager* getSoundManager();
438         virtual MtEventManager* getEventManager();
439         virtual bool checkLocalPrivilege(const std::string &priv)
440         { return checkPrivilege(priv); }
441         virtual scene::IAnimatedMesh* getMesh(const std::string &filename);
442
443         // The following set of functions is used by ClientMediaDownloader
444         // Insert a media file appropriately into the appropriate manager
445         bool loadMedia(const std::string &data, const std::string &filename);
446         // Send a request for conventional media transfer
447         void request_media(const std::list<std::string> &file_requests);
448         // Send a notification that no conventional media transfer is needed
449         void received_media();
450
451 private:
452
453         // Virtual methods from con::PeerHandler
454         void peerAdded(con::Peer *peer);
455         void deletingPeer(con::Peer *peer, bool timeout);
456         
457         void ReceiveAll();
458         void Receive();
459         
460         void sendPlayerPos();
461         // Send the item number 'item' as player item to the server
462         void sendPlayerItem(u16 item);
463         
464         float m_packetcounter_timer;
465         float m_connection_reinit_timer;
466         float m_avg_rtt_timer;
467         float m_playerpos_send_timer;
468         float m_ignore_damage_timer; // Used after server moves player
469         IntervalLimiter m_map_timer_and_unload_interval;
470
471         IWritableTextureSource *m_tsrc;
472         IWritableShaderSource *m_shsrc;
473         IWritableItemDefManager *m_itemdef;
474         IWritableNodeDefManager *m_nodedef;
475         ISoundManager *m_sound;
476         MtEventManager *m_event;
477
478         MeshUpdateThread m_mesh_update_thread;
479         ClientEnvironment m_env;
480         con::Connection m_con;
481         IrrlichtDevice *m_device;
482         // Server serialization version
483         u8 m_server_ser_ver;
484         u16 m_playeritem;
485         bool m_inventory_updated;
486         Inventory *m_inventory_from_server;
487         float m_inventory_from_server_age;
488         std::set<v3s16> m_active_blocks;
489         PacketCounter m_packetcounter;
490         // Block mesh animation parameters
491         float m_animation_time;
492         int m_crack_level;
493         v3s16 m_crack_pos;
494         // 0 <= m_daynight_i < DAYNIGHT_CACHE_COUNT
495         //s32 m_daynight_i;
496         //u32 m_daynight_ratio;
497         Queue<std::wstring> m_chat_queue;
498         // The seed returned by the server in TOCLIENT_INIT is stored here
499         u64 m_map_seed;
500         std::string m_password;
501         bool m_access_denied;
502         std::wstring m_access_denied_reason;
503         Queue<ClientEvent> m_client_event_queue;
504         bool m_itemdef_received;
505         bool m_nodedef_received;
506         ClientMediaDownloader *m_media_downloader;
507
508         // time_of_day speed approximation for old protocol
509         bool m_time_of_day_set;
510         float m_last_time_of_day_f;
511         float m_time_of_day_update_timer;
512
513         // An interval for generally sending object positions and stuff
514         float m_recommended_send_interval;
515
516         // Sounds
517         float m_removed_sounds_check_timer;
518         // Mapping from server sound ids to our sound ids
519         std::map<s32, int> m_sounds_server_to_client;
520         // And the other way!
521         std::map<int, s32> m_sounds_client_to_server;
522         // And relations to objects
523         std::map<int, u16> m_sounds_to_objects;
524
525         // Privileges
526         std::set<std::string> m_privileges;
527
528         // Detached inventories
529         // key = name
530         std::map<std::string, Inventory*> m_detached_inventories;
531
532         // Storage for mesh data for creating multiple instances of the same mesh
533         std::map<std::string, std::string> m_mesh_data;
534 };
535
536 #endif // !CLIENT_HEADER
537