aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/clientiface.cpp2
-rw-r--r--src/content_sao.cpp6
-rw-r--r--src/content_sao.h5
-rw-r--r--src/environment.cpp2
-rw-r--r--src/environment.h2
-rw-r--r--src/localplayer.h1
-rw-r--r--src/player.cpp206
-rw-r--r--src/player.h149
-rw-r--r--src/remoteplayer.cpp230
-rw-r--r--src/remoteplayer.h175
-rw-r--r--src/script/lua_api/l_object.cpp2
-rw-r--r--src/script/lua_api/l_object.h2
-rw-r--r--src/server.cpp8
-rw-r--r--src/server.h2
15 files changed, 423 insertions, 370 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 753291cba..8e3ae95ab 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -445,6 +445,7 @@ set(common_SRCS
porting.cpp
profiler.cpp
quicktune.cpp
+ remoteplayer.cpp
rollback.cpp
rollback_interface.cpp
serialization.cpp
diff --git a/src/clientiface.cpp b/src/clientiface.cpp
index fbfc16770..d78cf1c53 100644
--- a/src/clientiface.cpp
+++ b/src/clientiface.cpp
@@ -22,7 +22,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "clientiface.h"
#include "util/numeric.h"
#include "util/mathconstants.h"
-#include "player.h"
+#include "remoteplayer.h"
#include "settings.h"
#include "mapblock.h"
#include "network/connection.h"
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 1664f5993..5d3ed38bc 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -26,7 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serialization.h" // For compressZlib
#include "tool.h" // For ToolCapabilities
#include "gamedef.h"
-#include "player.h"
+#include "remoteplayer.h"
#include "server.h"
#include "scripting_game.h"
#include "genericobject.h"
@@ -391,7 +391,7 @@ std::string LuaEntitySAO::getClientInitializationData(u16 protocol_version)
(*ii).second.X, (*ii).second.Y)); // m_bone_position.size
}
os<<serializeLongString(gob_cmd_update_attachment(m_attachment_parent_id, m_attachment_bone, m_attachment_position, m_attachment_rotation)); // 4
- for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin();
+ for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin();
(ii != m_attachment_child_ids.end()); ++ii) {
if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) {
os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), obj->getClientInitializationData(protocol_version)));
@@ -880,7 +880,7 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version)
m_physics_override_jump, m_physics_override_gravity, m_physics_override_sneak,
m_physics_override_sneak_glitch)); // 5
os << serializeLongString(gob_cmd_update_nametag_attributes(m_prop.nametag_color)); // 6 (GENERIC_CMD_UPDATE_NAMETAG_ATTRIBUTES) : Deprecated, for backwards compatibility only.
- for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin();
+ for (UNORDERED_SET<int>::const_iterator ii = m_attachment_child_ids.begin();
ii != m_attachment_child_ids.end(); ++ii) {
if (ServerActiveObject *obj = m_env->getActiveObject(*ii)) {
os << serializeLongString(gob_cmd_update_infant(*ii, obj->getSendType(), obj->getClientInitializationData(protocol_version)));
diff --git a/src/content_sao.h b/src/content_sao.h
index 341ebb5da..76a3a37da 100644
--- a/src/content_sao.h
+++ b/src/content_sao.h
@@ -22,7 +22,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "serverobject.h"
#include "itemgroup.h"
-#include "player.h"
#include "object_properties.h"
/*
@@ -157,6 +156,8 @@ public:
}
};
+class RemotePlayer;
+
class PlayerSAO : public ServerActiveObject
{
public:
@@ -231,7 +232,7 @@ public:
void disconnected();
- RemotePlayer* getPlayer() { return m_player; }
+ RemotePlayer *getPlayer() { return m_player; }
u16 getPeerID() const { return m_peer_id; }
// Cheat prevention
diff --git a/src/environment.cpp b/src/environment.cpp
index 514aa918a..ff43ac516 100644
--- a/src/environment.cpp
+++ b/src/environment.cpp
@@ -2705,7 +2705,7 @@ u16 ClientEnvironment::addActiveObject(ClientActiveObject *object)
}
object->setId(new_id);
}
- if(!isFreeClientActiveObjectId(object->getId(), m_active_objects)) {
+ if (!isFreeClientActiveObjectId(object->getId(), m_active_objects)) {
infostream<<"ClientEnvironment::addActiveObject(): "
<<"id is not free ("<<object->getId()<<")"<<std::endl;
delete object;
diff --git a/src/environment.h b/src/environment.h
index 7ed38ad5d..f19708ad7 100644
--- a/src/environment.h
+++ b/src/environment.h
@@ -377,7 +377,7 @@ public:
Find out what new objects have been removed from
inside a radius around a position
*/
- void getRemovedActiveObjects(RemotePlayer* player, s16 radius,
+ void getRemovedActiveObjects(RemotePlayer *player, s16 radius,
s16 player_radius,
std::set<u16> &current_objects,
std::queue<u16> &removed_objects);
diff --git a/src/localplayer.h b/src/localplayer.h
index 182b51d4d..9d43128aa 100644
--- a/src/localplayer.h
+++ b/src/localplayer.h
@@ -28,6 +28,7 @@ class Client;
class Environment;
class GenericCAO;
class ClientActiveObject;
+class IGameDef;
enum LocalPlayerAnimations {NO_ANIM, WALK_ANIM, DIG_ANIM, WD_ANIM}; // no local animation, walking, digging, both
diff --git a/src/player.cpp b/src/player.cpp
index c0d367134..fa82a79f4 100644
--- a/src/player.cpp
+++ b/src/player.cpp
@@ -19,15 +19,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "player.h"
-#include <fstream>
#include "threading/mutex_auto_lock.h"
#include "util/numeric.h"
#include "hud.h"
#include "constants.h"
#include "gamedef.h"
#include "settings.h"
-#include "content_sao.h"
-#include "filesys.h"
#include "log.h"
#include "porting.h" // strlcpy
@@ -143,206 +140,3 @@ void Player::clearHud()
hud.pop_back();
}
}
-
-/*
- RemotePlayer
-*/
-// static config cache for remoteplayer
-bool RemotePlayer::m_setting_cache_loaded = false;
-float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f;
-u16 RemotePlayer::m_setting_chat_message_limit_trigger_kick = 0;
-
-RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef):
- Player(name, idef),
- protocol_version(0),
- m_sao(NULL),
- m_dirty(false),
- m_last_chat_message_sent(time(NULL)),
- m_chat_message_allowance(5.0f),
- m_message_rate_overhead(0),
- hud_hotbar_image(""),
- hud_hotbar_selected_image("")
-{
- if (!RemotePlayer::m_setting_cache_loaded) {
- RemotePlayer::m_setting_chat_message_limit_per_10sec =
- g_settings->getFloat("chat_message_limit_per_10sec");
- RemotePlayer::m_setting_chat_message_limit_trigger_kick =
- g_settings->getU16("chat_message_limit_trigger_kick");
- RemotePlayer::m_setting_cache_loaded = true;
- }
- movement_acceleration_default = g_settings->getFloat("movement_acceleration_default") * BS;
- movement_acceleration_air = g_settings->getFloat("movement_acceleration_air") * BS;
- movement_acceleration_fast = g_settings->getFloat("movement_acceleration_fast") * BS;
- movement_speed_walk = g_settings->getFloat("movement_speed_walk") * BS;
- movement_speed_crouch = g_settings->getFloat("movement_speed_crouch") * BS;
- movement_speed_fast = g_settings->getFloat("movement_speed_fast") * BS;
- movement_speed_climb = g_settings->getFloat("movement_speed_climb") * BS;
- movement_speed_jump = g_settings->getFloat("movement_speed_jump") * BS;
- movement_liquid_fluidity = g_settings->getFloat("movement_liquid_fluidity") * BS;
- movement_liquid_fluidity_smooth = g_settings->getFloat("movement_liquid_fluidity_smooth") * BS;
- movement_liquid_sink = g_settings->getFloat("movement_liquid_sink") * BS;
- movement_gravity = g_settings->getFloat("movement_gravity") * BS;
-}
-
-void RemotePlayer::save(std::string savedir, IGameDef *gamedef)
-{
- /*
- * We have to open all possible player files in the players directory
- * and check their player names because some file systems are not
- * case-sensitive and player names are case-sensitive.
- */
-
- // A player to deserialize files into to check their names
- RemotePlayer testplayer("", gamedef->idef());
-
- savedir += DIR_DELIM;
- std::string path = savedir + m_name;
- for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) {
- if (!fs::PathExists(path)) {
- // Open file and serialize
- std::ostringstream ss(std::ios_base::binary);
- serialize(ss);
- if (!fs::safeWriteToFile(path, ss.str())) {
- infostream << "Failed to write " << path << std::endl;
- }
- setModified(false);
- return;
- }
- // Open file and deserialize
- std::ifstream is(path.c_str(), std::ios_base::binary);
- if (!is.good()) {
- infostream << "Failed to open " << path << std::endl;
- return;
- }
- testplayer.deSerialize(is, path);
- is.close();
- if (strcmp(testplayer.getName(), m_name) == 0) {
- // Open file and serialize
- std::ostringstream ss(std::ios_base::binary);
- serialize(ss);
- if (!fs::safeWriteToFile(path, ss.str())) {
- infostream << "Failed to write " << path << std::endl;
- }
- setModified(false);
- return;
- }
- path = savedir + m_name + itos(i);
- }
-
- infostream << "Didn't find free file for player " << m_name << std::endl;
- return;
-}
-
-void RemotePlayer::deSerialize(std::istream &is, const std::string &playername)
-{
- Settings args;
-
- if (!args.parseConfigLines(is, "PlayerArgsEnd")) {
- throw SerializationError("PlayerArgsEnd of player " +
- playername + " not found!");
- }
-
- m_dirty = true;
- //args.getS32("version"); // Version field value not used
- std::string name = args.get("name");
- strlcpy(m_name, name.c_str(), PLAYERNAME_SIZE);
- setPitch(args.getFloat("pitch"));
- setYaw(args.getFloat("yaw"));
- setPosition(args.getV3F("position"));
- try{
- hp = args.getS32("hp");
- }catch(SettingNotFoundException &e) {
- hp = PLAYER_MAX_HP;
- }
- try{
- m_breath = args.getS32("breath");
- }catch(SettingNotFoundException &e) {
- m_breath = PLAYER_MAX_BREATH;
- }
-
- inventory.deSerialize(is);
-
- if(inventory.getList("craftpreview") == NULL) {
- // Convert players without craftpreview
- inventory.addList("craftpreview", 1);
-
- bool craftresult_is_preview = true;
- if(args.exists("craftresult_is_preview"))
- craftresult_is_preview = args.getBool("craftresult_is_preview");
- if(craftresult_is_preview)
- {
- // Clear craftresult
- inventory.getList("craftresult")->changeItem(0, ItemStack());
- }
- }
-}
-
-void RemotePlayer::serialize(std::ostream &os)
-{
- // Utilize a Settings object for storing values
- Settings args;
- args.setS32("version", 1);
- args.set("name", m_name);
- //args.set("password", m_password);
- args.setFloat("pitch", m_pitch);
- args.setFloat("yaw", m_yaw);
- args.setV3F("position", m_position);
- args.setS32("hp", hp);
- args.setS32("breath", m_breath);
-
- args.writeLines(os);
-
- os<<"PlayerArgsEnd\n";
-
- inventory.serialize(os);
-}
-
-void RemotePlayer::setPosition(const v3f &position)
-{
- if (position != m_position)
- m_dirty = true;
-
- Player::setPosition(position);
- if(m_sao)
- m_sao->setBasePosition(position);
-}
-
-const RemotePlayerChatResult RemotePlayer::canSendChatMessage()
-{
- // Rate limit messages
- u32 now = time(NULL);
- float time_passed = now - m_last_chat_message_sent;
- m_last_chat_message_sent = now;
-
- // If this feature is disabled
- if (m_setting_chat_message_limit_per_10sec <= 0.0) {
- return RPLAYER_CHATRESULT_OK;
- }
-
- m_chat_message_allowance += time_passed * (m_setting_chat_message_limit_per_10sec / 8.0f);
- if (m_chat_message_allowance > m_setting_chat_message_limit_per_10sec) {
- m_chat_message_allowance = m_setting_chat_message_limit_per_10sec;
- }
-
- if (m_chat_message_allowance < 1.0f) {
- infostream << "Player " << m_name
- << " chat limited due to excessive message amount." << std::endl;
-
- // Kick player if flooding is too intensive
- m_message_rate_overhead++;
- if (m_message_rate_overhead > RemotePlayer::m_setting_chat_message_limit_trigger_kick) {
- return RPLAYER_CHATRESULT_KICK;
- }
-
- return RPLAYER_CHATRESULT_FLOODING;
- }
-
- // Reinit message overhead
- if (m_message_rate_overhead > 0) {
- m_message_rate_overhead = 0;
- }
-
- m_chat_message_allowance -= 1.0f;
- return RPLAYER_CHATRESULT_OK;
-}
-
diff --git a/src/player.h b/src/player.h
index 1980a86a3..3c945b100 100644
--- a/src/player.h
+++ b/src/player.h
@@ -99,9 +99,7 @@ struct PlayerControl
};
class Map;
-class IGameDef;
struct CollisionInfo;
-class PlayerSAO;
struct HudElement;
class Environment;
@@ -258,152 +256,5 @@ private:
Mutex m_mutex;
};
-enum RemotePlayerChatResult {
- RPLAYER_CHATRESULT_OK,
- RPLAYER_CHATRESULT_FLOODING,
- RPLAYER_CHATRESULT_KICK,
-};
-/*
- Player on the server
-*/
-class RemotePlayer : public Player
-{
-public:
- RemotePlayer(const char *name, IItemDefManager *idef);
- virtual ~RemotePlayer() {}
-
- void save(std::string savedir, IGameDef *gamedef);
- void deSerialize(std::istream &is, const std::string &playername);
-
- PlayerSAO *getPlayerSAO() { return m_sao; }
- void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; }
- void setPosition(const v3f &position);
-
- const RemotePlayerChatResult canSendChatMessage();
-
- void setHotbarItemcount(s32 hotbar_itemcount)
- {
- hud_hotbar_itemcount = hotbar_itemcount;
- }
-
- s32 getHotbarItemcount() const { return hud_hotbar_itemcount; }
-
- void overrideDayNightRatio(bool do_override, float ratio)
- {
- m_day_night_ratio_do_override = do_override;
- m_day_night_ratio = ratio;
- }
-
- void getDayNightRatio(bool *do_override, float *ratio)
- {
- *do_override = m_day_night_ratio_do_override;
- *ratio = m_day_night_ratio;
- }
-
- // Use a function, if isDead can be defined by other conditions
- bool isDead() const { return hp == 0; }
-
- void setHotbarImage(const std::string &name)
- {
- hud_hotbar_image = name;
- }
-
- std::string getHotbarImage() const
- {
- return hud_hotbar_image;
- }
-
- void setHotbarSelectedImage(const std::string &name)
- {
- hud_hotbar_selected_image = name;
- }
-
- const std::string &getHotbarSelectedImage() const
- {
- return hud_hotbar_selected_image;
- }
-
- // Deprecated
- f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
-
- // Deprecated
- f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; }
-
- void setSky(const video::SColor &bgcolor, const std::string &type,
- const std::vector<std::string> &params)
- {
- m_sky_bgcolor = bgcolor;
- m_sky_type = type;
- m_sky_params = params;
- }
-
- void getSky(video::SColor *bgcolor, std::string *type,
- std::vector<std::string> *params)
- {
- *bgcolor = m_sky_bgcolor;
- *type = m_sky_type;
- *params = m_sky_params;
- }
-
- bool checkModified() const { return m_dirty || inventory.checkModified(); }
-
- void setModified(const bool x)
- {
- m_dirty = x;
- if (!x)
- inventory.setModified(x);
- }
-
- virtual void setBreath(u16 breath)
- {
- if (breath != m_breath)
- m_dirty = true;
- Player::setBreath(breath);
- }
-
- virtual void setPitch(f32 pitch)
- {
- if (pitch != m_pitch)
- m_dirty = true;
- Player::setPitch(pitch);
- }
-
- virtual void setYaw(f32 yaw)
- {
- if (yaw != m_yaw)
- m_dirty = true;
- Player::setYaw(yaw);
- }
-
- u16 protocol_version;
-private:
- /*
- serialize() writes a bunch of text that can contain
- any characters except a '\0', and such an ending that
- deSerialize stops reading exactly at the right point.
- */
- void serialize(std::ostream &os);
-
- PlayerSAO *m_sao;
- bool m_dirty;
-
- static bool m_setting_cache_loaded;
- static float m_setting_chat_message_limit_per_10sec;
- static u16 m_setting_chat_message_limit_trigger_kick;
-
- u32 m_last_chat_message_sent;
- float m_chat_message_allowance;
- u16 m_message_rate_overhead;
-
- bool m_day_night_ratio_do_override;
- float m_day_night_ratio;
- std::string hud_hotbar_image;
- std::string hud_hotbar_selected_image;
-
- std::string m_sky_type;
- video::SColor m_sky_bgcolor;
- std::vector<std::string> m_sky_params;
-};
-
#endif
diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp
new file mode 100644
index 000000000..f64d1d690
--- /dev/null
+++ b/src/remoteplayer.cpp
@@ -0,0 +1,230 @@
+/*
+Minetest
+Copyright (C) 2010-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2014-2016 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include "remoteplayer.h"
+#include "content_sao.h"
+#include "filesys.h"
+#include "gamedef.h"
+#include "porting.h" // strlcpy
+#include "settings.h"
+
+
+/*
+ RemotePlayer
+*/
+// static config cache for remoteplayer
+bool RemotePlayer::m_setting_cache_loaded = false;
+float RemotePlayer::m_setting_chat_message_limit_per_10sec = 0.0f;
+u16 RemotePlayer::m_setting_chat_message_limit_trigger_kick = 0;
+
+RemotePlayer::RemotePlayer(const char *name, IItemDefManager *idef):
+ Player(name, idef),
+ protocol_version(0),
+ m_sao(NULL),
+ m_dirty(false),
+ m_last_chat_message_sent(time(NULL)),
+ m_chat_message_allowance(5.0f),
+ m_message_rate_overhead(0),
+ hud_hotbar_image(""),
+ hud_hotbar_selected_image("")
+{
+ if (!RemotePlayer::m_setting_cache_loaded) {
+ RemotePlayer::m_setting_chat_message_limit_per_10sec =
+ g_settings->getFloat("chat_message_limit_per_10sec");
+ RemotePlayer::m_setting_chat_message_limit_trigger_kick =
+ g_settings->getU16("chat_message_limit_trigger_kick");
+ RemotePlayer::m_setting_cache_loaded = true;
+ }
+ movement_acceleration_default = g_settings->getFloat("movement_acceleration_default") * BS;
+ movement_acceleration_air = g_settings->getFloat("movement_acceleration_air") * BS;
+ movement_acceleration_fast = g_settings->getFloat("movement_acceleration_fast") * BS;
+ movement_speed_walk = g_settings->getFloat("movement_speed_walk") * BS;
+ movement_speed_crouch = g_settings->getFloat("movement_speed_crouch") * BS;
+ movement_speed_fast = g_settings->getFloat("movement_speed_fast") * BS;
+ movement_speed_climb = g_settings->getFloat("movement_speed_climb") * BS;
+ movement_speed_jump = g_settings->getFloat("movement_speed_jump") * BS;
+ movement_liquid_fluidity = g_settings->getFloat("movement_liquid_fluidity") * BS;
+ movement_liquid_fluidity_smooth = g_settings->getFloat("movement_liquid_fluidity_smooth") * BS;
+ movement_liquid_sink = g_settings->getFloat("movement_liquid_sink") * BS;
+ movement_gravity = g_settings->getFloat("movement_gravity") * BS;
+}
+
+void RemotePlayer::save(std::string savedir, IGameDef *gamedef)
+{
+ /*
+ * We have to open all possible player files in the players directory
+ * and check their player names because some file systems are not
+ * case-sensitive and player names are case-sensitive.
+ */
+
+ // A player to deserialize files into to check their names
+ RemotePlayer testplayer("", gamedef->idef());
+
+ savedir += DIR_DELIM;
+ std::string path = savedir + m_name;
+ for (u32 i = 0; i < PLAYER_FILE_ALTERNATE_TRIES; i++) {
+ if (!fs::PathExists(path)) {
+ // Open file and serialize
+ std::ostringstream ss(std::ios_base::binary);
+ serialize(ss);
+ if (!fs::safeWriteToFile(path, ss.str())) {
+ infostream << "Failed to write " << path << std::endl;
+ }
+ setModified(false);
+ return;
+ }
+ // Open file and deserialize
+ std::ifstream is(path.c_str(), std::ios_base::binary);
+ if (!is.good()) {
+ infostream << "Failed to open " << path << std::endl;
+ return;
+ }
+ testplayer.deSerialize(is, path);
+ is.close();
+ if (strcmp(testplayer.getName(), m_name) == 0) {
+ // Open file and serialize
+ std::ostringstream ss(std::ios_base::binary);
+ serialize(ss);
+ if (!fs::safeWriteToFile(path, ss.str())) {
+ infostream << "Failed to write " << path << std::endl;
+ }
+ setModified(false);
+ return;
+ }
+ path = savedir + m_name + itos(i);
+ }
+
+ infostream << "Didn't find free file for player " << m_name << std::endl;
+ return;
+}
+
+void RemotePlayer::deSerialize(std::istream &is, const std::string &playername)
+{
+ Settings args;
+
+ if (!args.parseConfigLines(is, "PlayerArgsEnd")) {
+ throw SerializationError("PlayerArgsEnd of player " +
+ playername + " not found!");
+ }
+
+ m_dirty = true;
+ //args.getS32("version"); // Version field value not used
+ std::string name = args.get("name");
+ strlcpy(m_name, name.c_str(), PLAYERNAME_SIZE);
+ setPitch(args.getFloat("pitch"));
+ setYaw(args.getFloat("yaw"));
+ setPosition(args.getV3F("position"));
+ try {
+ hp = args.getS32("hp");
+ } catch(SettingNotFoundException &e) {
+ hp = PLAYER_MAX_HP;
+ }
+
+ try {
+ m_breath = args.getS32("breath");
+ } catch(SettingNotFoundException &e) {
+ m_breath = PLAYER_MAX_BREATH;
+ }
+
+ inventory.deSerialize(is);
+
+ if(inventory.getList("craftpreview") == NULL) {
+ // Convert players without craftpreview
+ inventory.addList("craftpreview", 1);
+
+ bool craftresult_is_preview = true;
+ if(args.exists("craftresult_is_preview"))
+ craftresult_is_preview = args.getBool("craftresult_is_preview");
+ if(craftresult_is_preview)
+ {
+ // Clear craftresult
+ inventory.getList("craftresult")->changeItem(0, ItemStack());
+ }
+ }
+}
+
+void RemotePlayer::serialize(std::ostream &os)
+{
+ // Utilize a Settings object for storing values
+ Settings args;
+ args.setS32("version", 1);
+ args.set("name", m_name);
+ //args.set("password", m_password);
+ args.setFloat("pitch", m_pitch);
+ args.setFloat("yaw", m_yaw);
+ args.setV3F("position", m_position);
+ args.setS32("hp", hp);
+ args.setS32("breath", m_breath);
+
+ args.writeLines(os);
+
+ os<<"PlayerArgsEnd\n";
+
+ inventory.serialize(os);
+}
+
+void RemotePlayer::setPosition(const v3f &position)
+{
+ if (position != m_position)
+ m_dirty = true;
+
+ Player::setPosition(position);
+ if(m_sao)
+ m_sao->setBasePosition(position);
+}
+
+const RemotePlayerChatResult RemotePlayer::canSendChatMessage()
+{
+ // Rate limit messages
+ u32 now = time(NULL);
+ float time_passed = now - m_last_chat_message_sent;
+ m_last_chat_message_sent = now;
+
+ // If this feature is disabled
+ if (m_setting_chat_message_limit_per_10sec <= 0.0) {
+ return RPLAYER_CHATRESULT_OK;
+ }
+
+ m_chat_message_allowance += time_passed * (m_setting_chat_message_limit_per_10sec / 8.0f);
+ if (m_chat_message_allowance > m_setting_chat_message_limit_per_10sec) {
+ m_chat_message_allowance = m_setting_chat_message_limit_per_10sec;
+ }
+
+ if (m_chat_message_allowance < 1.0f) {
+ infostream << "Player " << m_name
+ << " chat limited due to excessive message amount." << std::endl;
+
+ // Kick player if flooding is too intensive
+ m_message_rate_overhead++;
+ if (m_message_rate_overhead > RemotePlayer::m_setting_chat_message_limit_trigger_kick) {
+ return RPLAYER_CHATRESULT_KICK;
+ }
+
+ return RPLAYER_CHATRESULT_FLOODING;
+ }
+
+ // Reinit message overhead
+ if (m_message_rate_overhead > 0) {
+ m_message_rate_overhead = 0;
+ }
+
+ m_chat_message_allowance -= 1.0f;
+ return RPLAYER_CHATRESULT_OK;
+}
diff --git a/src/remoteplayer.h b/src/remoteplayer.h
new file mode 100644
index 000000000..f6c70b0e9
--- /dev/null
+++ b/src/remoteplayer.h
@@ -0,0 +1,175 @@
+/*
+Minetest
+Copyright (C) 2010-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2014-2016 nerzhul, Loic Blot <loic.blot@unix-experience.fr>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef REMOTEPLAYER_HEADER
+#define REMOTEPLAYER_HEADER
+
+#include "player.h"
+
+class PlayerSAO;
+
+enum RemotePlayerChatResult {
+ RPLAYER_CHATRESULT_OK,
+ RPLAYER_CHATRESULT_FLOODING,
+ RPLAYER_CHATRESULT_KICK,
+};
+/*
+ Player on the server
+*/
+class RemotePlayer : public Player
+{
+public:
+ RemotePlayer(const char *name, IItemDefManager *idef);
+ virtual ~RemotePlayer() {}
+
+ void save(std::string savedir, IGameDef *gamedef);
+ void deSerialize(std::istream &is, const std::string &playername);
+
+ PlayerSAO *getPlayerSAO() { return m_sao; }
+ void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; }
+ void setPosition(const v3f &position);
+
+ const RemotePlayerChatResult canSendChatMessage();
+
+ void setHotbarItemcount(s32 hotbar_itemcount)
+ {
+ hud_hotbar_itemcount = hotbar_itemcount;
+ }
+
+ s32 getHotbarItemcount() const { return hud_hotbar_itemcount; }
+
+ void overrideDayNightRatio(bool do_override, float ratio)
+ {
+ m_day_night_ratio_do_override = do_override;
+ m_day_night_ratio = ratio;
+ }
+
+ void getDayNightRatio(bool *do_override, float *ratio)
+ {
+ *do_override = m_day_night_ratio_do_override;
+ *ratio = m_day_night_ratio;
+ }
+
+ // Use a function, if isDead can be defined by other conditions
+ bool isDead() const { return hp == 0; }
+
+ void setHotbarImage(const std::string &name)
+ {
+ hud_hotbar_image = name;
+ }
+
+ std::string getHotbarImage() const
+ {
+ return hud_hotbar_image;
+ }
+
+ void setHotbarSelectedImage(const std::string &name)
+ {
+ hud_hotbar_selected_image = name;
+ }
+
+ const std::string &getHotbarSelectedImage() const
+ {
+ return hud_hotbar_selected_image;
+ }
+
+ // Deprecated
+ f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; }
+
+ // Deprecated
+ f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; }
+
+ void setSky(const video::SColor &bgcolor, const std::string &type,
+ const std::vector<std::string> &params)
+ {
+ m_sky_bgcolor = bgcolor;
+ m_sky_type = type;
+ m_sky_params = params;
+ }
+
+ void getSky(video::SColor *bgcolor, std::string *type,
+ std::vector<std::string> *params)
+ {
+ *bgcolor = m_sky_bgcolor;
+ *type = m_sky_type;
+ *params = m_sky_params;
+ }
+
+ bool checkModified() const { return m_dirty || inventory.checkModified(); }
+
+ void setModified(const bool x)
+ {
+ m_dirty = x;
+ if (!x)
+ inventory.setModified(x);
+ }
+
+ virtual void setBreath(u16 breath)
+ {
+ if (breath != m_breath)
+ m_dirty = true;
+ Player::setBreath(breath);
+ }
+
+ virtual void setPitch(f32 pitch)
+ {
+ if (pitch != m_pitch)
+ m_dirty = true;
+ Player::setPitch(pitch);
+ }
+
+ virtual void setYaw(f32 yaw)
+ {
+ if (yaw != m_yaw)
+ m_dirty = true;
+ Player::setYaw(yaw);
+ }
+
+ u16 protocol_version;
+private:
+ /*
+ serialize() writes a bunch of text that can contain
+ any characters except a '\0', and such an ending that
+ deSerialize stops reading exactly at the right point.
+ */
+ void serialize(std::ostream &os);
+
+ PlayerSAO *m_sao;
+ bool m_dirty;
+
+ static bool m_setting_cache_loaded;
+ static float m_setting_chat_message_limit_per_10sec;
+ static u16 m_setting_chat_message_limit_trigger_kick;
+
+ u32 m_last_chat_message_sent;
+ float m_chat_message_allowance;
+ u16 m_message_rate_overhead;
+
+ bool m_day_night_ratio_do_override;
+ float m_day_night_ratio;
+ std::string hud_hotbar_image;
+ std::string hud_hotbar_selected_image;
+
+ std::string m_sky_type;
+ video::SColor m_sky_bgcolor;
+ std::vector<std::string> m_sky_params;
+};
+
+#endif
diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp
index a1f83919c..bb352e429 100644
--- a/src/script/lua_api/l_object.cpp
+++ b/src/script/lua_api/l_object.cpp
@@ -107,7 +107,7 @@ PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
return (PlayerSAO*)obj;
}
-RemotePlayer* ObjectRef::getplayer(ObjectRef *ref)
+RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
{
PlayerSAO *playersao = getplayersao(ref);
if (playersao == NULL)
diff --git a/src/script/lua_api/l_object.h b/src/script/lua_api/l_object.h
index dfc1b49d2..09f10e417 100644
--- a/src/script/lua_api/l_object.h
+++ b/src/script/lua_api/l_object.h
@@ -47,7 +47,7 @@ private:
static PlayerSAO* getplayersao(ObjectRef *ref);
- static RemotePlayer* getplayer(ObjectRef *ref);
+ static RemotePlayer *getplayer(ObjectRef *ref);
// Exported functions
diff --git a/src/server.cpp b/src/server.cpp
index 71e71f43e..a93c143c7 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -2688,7 +2688,7 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason)
SendChatMessage(PEER_ID_INEXISTENT,message);
}
-void Server::UpdateCrafting(RemotePlayer* player)
+void Server::UpdateCrafting(RemotePlayer *player)
{
DSTACK(FUNCTION_NAME);
@@ -3141,7 +3141,7 @@ void Server::spawnParticle(const std::string &playername, v3f pos,
u16 peer_id = PEER_ID_INEXISTENT;
if (playername != "") {
- RemotePlayer* player = m_env->getPlayer(playername.c_str());
+ RemotePlayer *player = m_env->getPlayer(playername.c_str());
if (!player)
return;
peer_id = player->peer_id;
@@ -3165,7 +3165,7 @@ u32 Server::addParticleSpawner(u16 amount, float spawntime,
u16 peer_id = PEER_ID_INEXISTENT;
if (playername != "") {
- RemotePlayer* player = m_env->getPlayer(playername.c_str());
+ RemotePlayer *player = m_env->getPlayer(playername.c_str());
if (!player)
return -1;
peer_id = player->peer_id;
@@ -3188,7 +3188,7 @@ void Server::deleteParticleSpawner(const std::string &playername, u32 id)
u16 peer_id = PEER_ID_INEXISTENT;
if (playername != "") {
- RemotePlayer* player = m_env->getPlayer(playername.c_str());
+ RemotePlayer *player = m_env->getPlayer(playername.c_str());
if (!player)
return;
peer_id = player->peer_id;
diff --git a/src/server.h b/src/server.h
index fc4758c5f..6ee61a0eb 100644
--- a/src/server.h
+++ b/src/server.h
@@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "environment.h"
#include "chat_interface.h"
#include "clientiface.h"
-#include "player.h"
+#include "remoteplayer.h"
#include "network/networkpacket.h"
#include <string>
#include <list>