Move RemotePlayer code to its own cpp/header
authorLoic Blot <loic.blot@unix-experience.fr>
Sat, 8 Oct 2016 17:08:23 +0000 (19:08 +0200)
committerNer'zhul <nerzhul@users.noreply.github.com>
Sat, 8 Oct 2016 20:27:44 +0000 (22:27 +0200)
15 files changed:
src/CMakeLists.txt
src/clientiface.cpp
src/content_sao.cpp
src/content_sao.h
src/environment.cpp
src/environment.h
src/localplayer.h
src/player.cpp
src/player.h
src/remoteplayer.cpp [new file with mode: 0644]
src/remoteplayer.h [new file with mode: 0644]
src/script/lua_api/l_object.cpp
src/script/lua_api/l_object.h
src/server.cpp
src/server.h

index 753291cba44412a774d842ecd16c6f321d44d962..8e3ae95abf4b2768a767d2d152e625269eb7dbc5 100644 (file)
@@ -445,6 +445,7 @@ set(common_SRCS
        porting.cpp
        profiler.cpp
        quicktune.cpp
+       remoteplayer.cpp
        rollback.cpp
        rollback_interface.cpp
        serialization.cpp
index fbfc16770118c0fe452add5232b3078b23d6afb4..d78cf1c53bf63724632795d7f785f370d59ff623 100644 (file)
@@ -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"
index 1664f59931068b794d4d3068c4c84526708ef6ec..5d3ed38bc28f5b690ac30e116af3f65d62cb0bdf 100644 (file)
@@ -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)));
index 341ebb5da51489b0364508c892988c924739c697..76a3a37da03cb96bcd2cad142db17f7cda5e7386 100644 (file)
@@ -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();
 
-       RemotePlayergetPlayer() { return m_player; }
+       RemotePlayer *getPlayer() { return m_player; }
        u16 getPeerID() const { return m_peer_id; }
 
        // Cheat prevention
index 514aa918a0aaafc5fc0f556a42541eabe3471997..ff43ac516242f35125e94e37dbaf1e96bfbf2457 100644 (file)
@@ -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;
index 7ed38ad5dae2dbcb22f819cbb3cd918a95ee69f6..f19708ad7e22346fa3e378729e6642b366ba3dc9 100644 (file)
@@ -377,7 +377,7 @@ public:
                Find out what new objects have been removed from
                inside a radius around a position
        */
-       void getRemovedActiveObjects(RemotePlayerplayer, s16 radius,
+       void getRemovedActiveObjects(RemotePlayer *player, s16 radius,
                        s16 player_radius,
                        std::set<u16> &current_objects,
                        std::queue<u16> &removed_objects);
index 182b51d4d5b2c0144a3c069875c187ced576af34..9d43128aab8ca57b4aa2e288d24d06b360fc4f83 100644 (file)
@@ -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
 
index c0d36713431b5e04fef6821423a77a02da1e6e49..fa82a79f43b70cc60cde80eac33bb27a78c2ee53 100644 (file)
@@ -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;
-}
-
index 1980a86a3b9f6bda0510c7ebc49672caaede1fd8..3c945b100eb56033ba04a23ac68eb85fa5bd24fb 100644 (file)
@@ -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 (file)
index 0000000..f64d1d6
--- /dev/null
@@ -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 (file)
index 0000000..f6c70b0
--- /dev/null
@@ -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
index a1f83919ce0c99661d0c6254e40c69b0ce986a06..bb352e429cd853530b2aa9a06169ef86042546ba 100644 (file)
@@ -107,7 +107,7 @@ PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
        return (PlayerSAO*)obj;
 }
 
-RemotePlayerObjectRef::getplayer(ObjectRef *ref)
+RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
 {
        PlayerSAO *playersao = getplayersao(ref);
        if (playersao == NULL)
index dfc1b49d20b913262cf8da00f5160a318c3c8076..09f10e417e9ec40cfae02c7de57e6b0aadb76ea0 100644 (file)
@@ -47,7 +47,7 @@ private:
 
        static PlayerSAO* getplayersao(ObjectRef *ref);
 
-       static RemotePlayergetplayer(ObjectRef *ref);
+       static RemotePlayer *getplayer(ObjectRef *ref);
 
        // Exported functions
 
index 71e71f43e5ad3b47f141e76bd5cc5f9c2d4e0864..a93c143c7d01f5d10e6fcbd23caa407394798f16 100644 (file)
@@ -2688,7 +2688,7 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason)
                SendChatMessage(PEER_ID_INEXISTENT,message);
 }
 
-void Server::UpdateCrafting(RemotePlayerplayer)
+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 != "") {
-               RemotePlayerplayer = 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 != "") {
-               RemotePlayerplayer = 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 != "") {
-               RemotePlayerplayer = m_env->getPlayer(playername.c_str());
+               RemotePlayer *player = m_env->getPlayer(playername.c_str());
                if (!player)
                        return;
                peer_id = player->peer_id;
index fc4758c5f763093f51f22458f80b813408921427..6ee61a0eb6e9dab829751beac578f01b1ae631e2 100644 (file)
@@ -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>