]> git.lizzy.rs Git - minetest.git/blob - src/server/player_sao.h
Drop content_sao.{cpp,h}
[minetest.git] / src / server / player_sao.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2013-2020 Minetest core developers & community
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21 #pragma once
22
23 #include "constants.h"
24 #include "network/networkprotocol.h"
25 #include "unit_sao.h"
26 #include "util/numeric.h"
27
28 /*
29         PlayerSAO needs some internals exposed.
30 */
31
32 class LagPool
33 {
34         float m_pool = 15.0f;
35         float m_max = 15.0f;
36
37 public:
38         LagPool() = default;
39
40         void setMax(float new_max)
41         {
42                 m_max = new_max;
43                 if (m_pool > new_max)
44                         m_pool = new_max;
45         }
46
47         void add(float dtime)
48         {
49                 m_pool -= dtime;
50                 if (m_pool < 0)
51                         m_pool = 0;
52         }
53
54         void empty() { m_pool = m_max; }
55
56         bool grab(float dtime)
57         {
58                 if (dtime <= 0)
59                         return true;
60                 if (m_pool + dtime > m_max)
61                         return false;
62                 m_pool += dtime;
63                 return true;
64         }
65 };
66
67 class RemotePlayer;
68
69 class PlayerSAO : public UnitSAO
70 {
71 public:
72         PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, session_t peer_id_,
73                         bool is_singleplayer);
74
75         ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_PLAYER; }
76         ActiveObjectType getSendType() const { return ACTIVEOBJECT_TYPE_GENERIC; }
77         std::string getDescription();
78
79         /*
80                 Active object <-> environment interface
81         */
82
83         void addedToEnvironment(u32 dtime_s);
84         void removingFromEnvironment();
85         bool isStaticAllowed() const { return false; }
86         std::string getClientInitializationData(u16 protocol_version);
87         void getStaticData(std::string *result) const;
88         void step(float dtime, bool send_recommended);
89         void setBasePosition(const v3f &position);
90         void setPos(const v3f &pos);
91         void moveTo(v3f pos, bool continuous);
92         void setPlayerYaw(const float yaw);
93         // Data should not be sent at player initialization
94         void setPlayerYawAndSend(const float yaw);
95         void setLookPitch(const float pitch);
96         // Data should not be sent at player initialization
97         void setLookPitchAndSend(const float pitch);
98         f32 getLookPitch() const { return m_pitch; }
99         f32 getRadLookPitch() const { return m_pitch * core::DEGTORAD; }
100         // Deprecated
101         f32 getRadLookPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
102         void setFov(const float pitch);
103         f32 getFov() const { return m_fov; }
104         void setWantedRange(const s16 range);
105         s16 getWantedRange() const { return m_wanted_range; }
106
107         /*
108                 Interaction interface
109         */
110
111         u16 punch(v3f dir, const ToolCapabilities *toolcap, ServerActiveObject *puncher,
112                         float time_from_last_punch);
113         void rightClick(ServerActiveObject *clicker) {}
114         void setHP(s32 hp, const PlayerHPChangeReason &reason);
115         void setHPRaw(u16 hp) { m_hp = hp; }
116         s16 readDamage();
117         u16 getBreath() const { return m_breath; }
118         void setBreath(const u16 breath, bool send = true);
119
120         /*
121                 Inventory interface
122         */
123         Inventory *getInventory() const;
124         InventoryLocation getInventoryLocation() const;
125         void setInventoryModified() {}
126         std::string getWieldList() const { return "main"; }
127         u16 getWieldIndex() const;
128         ItemStack getWieldedItem(ItemStack *selected, ItemStack *hand = nullptr) const;
129         bool setWieldedItem(const ItemStack &item);
130
131         /*
132                 PlayerSAO-specific
133         */
134
135         void disconnected();
136
137         RemotePlayer *getPlayer() { return m_player; }
138         session_t getPeerID() const { return m_peer_id; }
139
140         // Cheat prevention
141
142         v3f getLastGoodPosition() const { return m_last_good_position; }
143         float resetTimeFromLastPunch()
144         {
145                 float r = m_time_from_last_punch;
146                 m_time_from_last_punch = 0.0;
147                 return r;
148         }
149         void noCheatDigStart(const v3s16 &p)
150         {
151                 m_nocheat_dig_pos = p;
152                 m_nocheat_dig_time = 0;
153         }
154         v3s16 getNoCheatDigPos() { return m_nocheat_dig_pos; }
155         float getNoCheatDigTime() { return m_nocheat_dig_time; }
156         void noCheatDigEnd() { m_nocheat_dig_pos = v3s16(32767, 32767, 32767); }
157         LagPool &getDigPool() { return m_dig_pool; }
158         void setMaxSpeedOverride(const v3f &vel);
159         // Returns true if cheated
160         bool checkMovementCheat();
161
162         // Other
163
164         void updatePrivileges(const std::set<std::string> &privs, bool is_singleplayer)
165         {
166                 m_privs = privs;
167                 m_is_singleplayer = is_singleplayer;
168         }
169
170         bool getCollisionBox(aabb3f *toset) const;
171         bool getSelectionBox(aabb3f *toset) const;
172         bool collideWithObjects() const { return true; }
173
174         void finalize(RemotePlayer *player, const std::set<std::string> &privs);
175
176         v3f getEyePosition() const { return m_base_position + getEyeOffset(); }
177         v3f getEyeOffset() const;
178         float getZoomFOV() const;
179
180         inline Metadata &getMeta() { return m_meta; }
181
182 private:
183         std::string getPropertyPacket();
184         void unlinkPlayerSessionAndSave();
185         std::string generateUpdatePhysicsOverrideCommand() const;
186
187         RemotePlayer *m_player = nullptr;
188         session_t m_peer_id = 0;
189
190         // Cheat prevention
191         LagPool m_dig_pool;
192         LagPool m_move_pool;
193         v3f m_last_good_position;
194         float m_time_from_last_teleport = 0.0f;
195         float m_time_from_last_punch = 0.0f;
196         v3s16 m_nocheat_dig_pos = v3s16(32767, 32767, 32767);
197         float m_nocheat_dig_time = 0.0f;
198         float m_max_speed_override_time = 0.0f;
199         v3f m_max_speed_override = v3f(0.0f, 0.0f, 0.0f);
200
201         // Timers
202         IntervalLimiter m_breathing_interval;
203         IntervalLimiter m_drowning_interval;
204         IntervalLimiter m_node_hurt_interval;
205
206         bool m_position_not_sent = false;
207
208         // Cached privileges for enforcement
209         std::set<std::string> m_privs;
210         bool m_is_singleplayer;
211
212         u16 m_breath = PLAYER_MAX_BREATH_DEFAULT;
213         f32 m_pitch = 0.0f;
214         f32 m_fov = 0.0f;
215         s16 m_wanted_range = 0.0f;
216
217         Metadata m_meta;
218
219 public:
220         float m_physics_override_speed = 1.0f;
221         float m_physics_override_jump = 1.0f;
222         float m_physics_override_gravity = 1.0f;
223         bool m_physics_override_sneak = true;
224         bool m_physics_override_sneak_glitch = false;
225         bool m_physics_override_new_move = true;
226         bool m_physics_override_sent = false;
227 };
228
229 struct PlayerHPChangeReason
230 {
231         enum Type : u8
232         {
233                 SET_HP,
234                 PLAYER_PUNCH,
235                 FALL,
236                 NODE_DAMAGE,
237                 DROWNING,
238                 RESPAWN
239         };
240
241         Type type = SET_HP;
242         bool from_mod = false;
243         int lua_reference = -1;
244
245         // For PLAYER_PUNCH
246         ServerActiveObject *object = nullptr;
247         // For NODE_DAMAGE
248         std::string node;
249
250         inline bool hasLuaReference() const { return lua_reference >= 0; }
251
252         bool setTypeFromString(const std::string &typestr)
253         {
254                 if (typestr == "set_hp")
255                         type = SET_HP;
256                 else if (typestr == "punch")
257                         type = PLAYER_PUNCH;
258                 else if (typestr == "fall")
259                         type = FALL;
260                 else if (typestr == "node_damage")
261                         type = NODE_DAMAGE;
262                 else if (typestr == "drown")
263                         type = DROWNING;
264                 else if (typestr == "respawn")
265                         type = RESPAWN;
266                 else
267                         return false;
268
269                 return true;
270         }
271
272         std::string getTypeAsString() const
273         {
274                 switch (type) {
275                 case PlayerHPChangeReason::SET_HP:
276                         return "set_hp";
277                 case PlayerHPChangeReason::PLAYER_PUNCH:
278                         return "punch";
279                 case PlayerHPChangeReason::FALL:
280                         return "fall";
281                 case PlayerHPChangeReason::NODE_DAMAGE:
282                         return "node_damage";
283                 case PlayerHPChangeReason::DROWNING:
284                         return "drown";
285                 case PlayerHPChangeReason::RESPAWN:
286                         return "respawn";
287                 default:
288                         return "?";
289                 }
290         }
291
292         PlayerHPChangeReason(Type type) : type(type) {}
293
294         PlayerHPChangeReason(Type type, ServerActiveObject *object) :
295                         type(type), object(object)
296         {
297         }
298
299         PlayerHPChangeReason(Type type, std::string node) : type(type), node(node) {}
300 };