From 569b89b36fff058390cb90458da4285552a9c97e Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sat, 8 Oct 2016 19:08:23 +0200 Subject: Move RemotePlayer code to its own cpp/header --- src/remoteplayer.cpp | 230 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 230 insertions(+) create mode 100644 src/remoteplayer.cpp (limited to 'src/remoteplayer.cpp') 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 +Copyright (C) 2014-2016 nerzhul, Loic Blot + +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; +} -- cgit v1.2.3 From 9d25242c5c1411d692254cf910345d51c9a24fa3 Mon Sep 17 00:00:00 2001 From: Ner'zhul Date: Sun, 30 Oct 2016 14:53:26 +0100 Subject: PlayerSAO/LocalPlayer refactor: (#4612) * Create UnitSAO, a common part between PlayerSAO & LuaEntitySAO * Move breath to PlayerSAO & LocalPlayer * Migrate m_yaw from (Remote)Player & LuaEntitySAO to UnitSAO * Migrate m_yaw from Player to LocalPlayer for client * Move some functions outside of player class to PlayerSAO/RemotePlayer or LocalPlayer depending on which class needs it * Move pitch to LocalPlayer & PlayerSAO * Move m_position from Player to LocalPlayer * Move camera_barely_in_ceiling to LocalPlayer as it's used only there * use PlayerSAO::m_base_position for Server side positions * remove a unused variable * ServerActiveObject::setPos now uses const ref * use ServerEnv::loadPlayer unconditionnaly as it creates RemotePlayer only if it's not already loaded * Move hp from Player to LocalPlayer * Move m_hp from LuaEntitySAO to UnitSAO * Use m_hp from PlayerSAO/UnitSAO instead of RemotePlayer --- src/clientiface.cpp | 14 ++-- src/collision.cpp | 2 +- src/content_sao.cpp | 155 +++++++++++++++++++----------------- src/content_sao.h | 62 +++++++++++---- src/environment.cpp | 35 ++++---- src/environment.h | 7 +- src/localplayer.cpp | 7 ++ src/localplayer.h | 41 ++++++++++ src/network/clientpackethandler.cpp | 1 - src/network/serverpackethandler.cpp | 55 +++++++------ src/player.cpp | 14 +--- src/player.h | 50 ------------ src/remoteplayer.cpp | 66 +++++++-------- src/remoteplayer.h | 35 +------- src/script/lua_api/l_object.cpp | 32 ++++---- src/server.cpp | 71 +++++++++-------- src/serverobject.h | 2 +- src/unittest/test_player.cpp | 39 +++++---- 18 files changed, 353 insertions(+), 335 deletions(-) (limited to 'src/remoteplayer.cpp') diff --git a/src/clientiface.cpp b/src/clientiface.cpp index d78cf1c53..d2e3a6da0 100644 --- a/src/clientiface.cpp +++ b/src/clientiface.cpp @@ -29,7 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "environment.h" #include "map.h" #include "emerge.h" -#include "serverobject.h" // TODO this is used for cleanup of only +#include "content_sao.h" // TODO this is used for cleanup of only #include "log.h" #include "util/srp.h" @@ -82,6 +82,10 @@ void RemoteClient::GetNextBlocks ( if (player == NULL) return; + PlayerSAO *sao = player->getPlayerSAO(); + if (sao == NULL) + return; + // Won't send anything if already sending if(m_blocks_sending.size() >= g_settings->getU16 ("max_simultaneous_block_sends_per_client")) @@ -90,7 +94,7 @@ void RemoteClient::GetNextBlocks ( return; } - v3f playerpos = player->getPosition(); + v3f playerpos = sao->getBasePosition(); v3f playerspeed = player->getSpeed(); v3f playerspeeddir(0,0,0); if(playerspeed.getLength() > 1.0*BS) @@ -103,10 +107,10 @@ void RemoteClient::GetNextBlocks ( v3s16 center = getNodeBlockPos(center_nodepos); // Camera position and direction - v3f camera_pos = player->getEyePosition(); + v3f camera_pos = sao->getEyePosition(); v3f camera_dir = v3f(0,0,1); - camera_dir.rotateYZBy(player->getPitch()); - camera_dir.rotateXZBy(player->getYaw()); + camera_dir.rotateYZBy(sao->getPitch()); + camera_dir.rotateXZBy(sao->getYaw()); /*infostream<<"camera_dir=("<(env); - if (s_env != 0) { + if (s_env != NULL) { f32 distance = speed_f->getLength(); std::vector s_objects; s_env->getObjectsInsideRadius(s_objects, *pos_f, distance * 1.5); diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 375a43c90..23a064085 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -118,14 +118,12 @@ LuaEntitySAO proto_LuaEntitySAO(NULL, v3f(0,0,0), "_prototype", ""); LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, const std::string &name, const std::string &state): - ServerActiveObject(env, pos), + UnitSAO(env, pos), m_init_name(name), m_init_state(state), m_registered(false), - m_hp(-1), m_velocity(0,0,0), m_acceleration(0,0,0), - m_yaw(0), m_properties_sent(true), m_last_sent_yaw(0), m_last_sent_position(0,0,0), @@ -664,16 +662,6 @@ v3f LuaEntitySAO::getAcceleration() return m_acceleration; } -void LuaEntitySAO::setYaw(float yaw) -{ - m_yaw = yaw; -} - -float LuaEntitySAO::getYaw() -{ - return m_yaw; -} - void LuaEntitySAO::setTextureMod(const std::string &mod) { std::string str = gob_cmd_set_texture_mod(mod); @@ -762,10 +750,9 @@ bool LuaEntitySAO::collideWithObjects(){ // No prototype, PlayerSAO does not need to be deserialized -PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, - const std::set &privs, bool is_singleplayer): - ServerActiveObject(env_, v3f(0,0,0)), - m_player(player_), +PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer): + UnitSAO(env_, v3f(0,0,0)), + m_player(NULL), m_peer_id(peer_id_), m_inventory(NULL), m_damage(0), @@ -777,7 +764,6 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_position_not_sent(false), m_armor_groups_sent(false), m_properties_sent(true), - m_privs(privs), m_is_singleplayer(is_singleplayer), m_animation_speed(0), m_animation_blend(0), @@ -786,6 +772,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_bone_position_sent(false), m_attachment_parent_id(0), m_attachment_sent(false), + m_breath(PLAYER_MAX_BREATH), + m_pitch(0), // public m_physics_override_speed(1), m_physics_override_jump(1), @@ -794,10 +782,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id m_physics_override_sneak_glitch(true), m_physics_override_sent(false) { - assert(m_player); // pre-condition assert(m_peer_id != 0); // pre-condition - setBasePosition(m_player->getPosition()); - m_inventory = &m_player->inventory; m_armor_groups["fleshy"] = 100; m_prop.hp_max = PLAYER_MAX_HP; @@ -816,6 +801,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id // end of default appearance m_prop.is_visible = true; m_prop.makes_footstep_sound = true; + m_hp = PLAYER_MAX_HP; } PlayerSAO::~PlayerSAO() @@ -824,6 +810,14 @@ PlayerSAO::~PlayerSAO() delete m_inventory; } +void PlayerSAO::initialize(RemotePlayer *player, const std::set &privs) +{ + assert(player); + m_player = player; + m_privs = privs; + m_inventory = &m_player->inventory; +} + std::string PlayerSAO::getDescription() { return std::string("player ") + m_player->getName(); @@ -833,10 +827,10 @@ std::string PlayerSAO::getDescription() void PlayerSAO::addedToEnvironment(u32 dtime_s) { ServerActiveObject::addedToEnvironment(dtime_s); - ServerActiveObject::setBasePosition(m_player->getPosition()); + ServerActiveObject::setBasePosition(m_base_position); m_player->setPlayerSAO(this); m_player->peer_id = m_peer_id; - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; } // Called before removing from environment @@ -844,9 +838,9 @@ void PlayerSAO::removingFromEnvironment() { ServerActiveObject::removingFromEnvironment(); if (m_player->getPlayerSAO() == this) { - m_player->setPlayerSAO(NULL); m_player->peer_id = 0; m_env->savePlayer(m_player); + m_player->setPlayerSAO(NULL); m_env->removePlayer(m_player); for (UNORDERED_SET::iterator it = m_attached_particle_spawners.begin(); it != m_attached_particle_spawners.end(); ++it) { @@ -870,8 +864,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) os<getName()); // name writeU8(os, 1); // is_player writeS16(os, getId()); //id - writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0)); - writeF1000(os, m_player->getYaw()); + writeV3F1000(os, m_base_position + v3f(0,BS*1,0)); + writeF1000(os, m_yaw); writeS16(os, getHP()); writeU8(os, 6 + m_bone_position.size() + m_attachment_child_ids.size()); // number of messages stuffed in here @@ -900,8 +894,8 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) writeU8(os, 0); // version os<getName()); // name writeU8(os, 1); // is_player - writeV3F1000(os, m_player->getPosition() + v3f(0,BS*1,0)); - writeF1000(os, m_player->getYaw()); + writeV3F1000(os, m_base_position + v3f(0,BS*1,0)); + writeF1000(os, m_yaw); writeS16(os, getHP()); writeU8(os, 2); // number of messages stuffed in here os<setPosition(m_last_good_position); + setBasePosition(m_last_good_position); ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } @@ -969,14 +963,13 @@ void PlayerSAO::step(float dtime, bool send_recommended) // Each frame, parent position is copied if the object is attached, otherwise it's calculated normally // If the object gets detached this comes into effect automatically from the last known origin - if(isAttached()) - { + if (isAttached()) { v3f pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition(); m_last_good_position = pos; - m_player->setPosition(pos); + setBasePosition(pos); } - if(send_recommended == false) + if (!send_recommended) return; // If the object is attached client-side, don't waste bandwidth sending its position to clients @@ -988,12 +981,12 @@ void PlayerSAO::step(float dtime, bool send_recommended) if(isAttached()) // Just in case we ever do send attachment position too pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition(); else - pos = m_player->getPosition() + v3f(0,BS*1,0); + pos = m_base_position + v3f(0,BS*1,0); std::string str = gob_cmd_update_position( pos, v3f(0,0,0), v3f(0,0,0), - m_player->getYaw(), + m_yaw, true, false, update_interval @@ -1003,7 +996,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_armor_groups_sent == false) { + if (!m_armor_groups_sent) { m_armor_groups_sent = true; std::string str = gob_cmd_update_armor_groups( m_armor_groups); @@ -1012,7 +1005,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_physics_override_sent == false){ + if (!m_physics_override_sent) { m_physics_override_sent = true; std::string str = gob_cmd_update_physics_override(m_physics_override_speed, m_physics_override_jump, m_physics_override_gravity, @@ -1022,7 +1015,7 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push(aom); } - if(m_animation_sent == false){ + if (!m_animation_sent) { m_animation_sent = true; std::string str = gob_cmd_update_animation( m_animation_range, m_animation_speed, m_animation_blend, m_animation_loop); @@ -1055,16 +1048,20 @@ void PlayerSAO::step(float dtime, bool send_recommended) void PlayerSAO::setBasePosition(const v3f &position) { + if (m_player && position != m_base_position) + m_player->setDirty(true); + // This needs to be ran for attachments too ServerActiveObject::setBasePosition(position); m_position_not_sent = true; } -void PlayerSAO::setPos(v3f pos) +void PlayerSAO::setPos(const v3f &pos) { if(isAttached()) return; - m_player->setPosition(pos); + + setBasePosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); @@ -1074,22 +1071,34 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) { if(isAttached()) return; - m_player->setPosition(pos); + + setBasePosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setYaw(float yaw) +void PlayerSAO::setYaw(const float yaw, bool send_data) { - m_player->setYaw(yaw); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + if (m_player && yaw != m_yaw) + m_player->setDirty(true); + + UnitSAO::setYaw(yaw); + + // Datas should not be sent at player initialization + if (send_data) + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setPitch(float pitch) +void PlayerSAO::setPitch(const float pitch, bool send_data) { - m_player->setPitch(pitch); - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); + if (m_player && pitch != m_pitch) + m_player->setDirty(true); + + m_pitch = pitch; + + if (send_data) + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } int PlayerSAO::punch(v3f dir, @@ -1153,13 +1162,8 @@ int PlayerSAO::punch(v3f dir, return hitparams.wear; } -void PlayerSAO::rightClick(ServerActiveObject *clicker) -{ -} - -s16 PlayerSAO::getHP() const +void PlayerSAO::rightClick(ServerActiveObject *) { - return m_player->hp; } s16 PlayerSAO::readDamage() @@ -1169,12 +1173,16 @@ s16 PlayerSAO::readDamage() return damage; } -void PlayerSAO::setHP(s16 hp) +void PlayerSAO::setHP(s16 hp, bool direct) { - s16 oldhp = m_player->hp; + if (direct) { + m_hp = hp; + return; + } + + s16 oldhp = m_hp; - s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, - hp - oldhp); + s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - oldhp); if (hp_change == 0) return; hp = oldhp + hp_change; @@ -1184,11 +1192,11 @@ void PlayerSAO::setHP(s16 hp) else if (hp > PLAYER_MAX_HP) hp = PLAYER_MAX_HP; - if(hp < oldhp && g_settings->getBool("enable_damage") == false) { + if (hp < oldhp && !g_settings->getBool("enable_damage")) { return; } - m_player->hp = hp; + m_hp = hp; if (oldhp > hp) m_damage += (oldhp - hp); @@ -1198,14 +1206,12 @@ void PlayerSAO::setHP(s16 hp) m_properties_sent = false; } -u16 PlayerSAO::getBreath() const +void PlayerSAO::setBreath(const u16 breath) { - return m_player->getBreath(); -} + if (m_player && breath != m_breath) + m_player->setDirty(true); -void PlayerSAO::setBreath(u16 breath) -{ - m_player->setBreath(breath); + m_breath = breath; } void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups) @@ -1355,7 +1361,7 @@ bool PlayerSAO::checkMovementCheat() { if (isAttached() || m_is_singleplayer || g_settings->getBool("disable_anticheat")) { - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; return false; } @@ -1382,7 +1388,7 @@ bool PlayerSAO::checkMovementCheat() // Tolerance. The lag pool does this a bit. //player_max_speed *= 2.5; - v3f diff = (m_player->getPosition() - m_last_good_position); + v3f diff = (m_base_position - m_last_good_position); float d_vert = diff.Y; diff.Y = 0; float d_horiz = diff.getLength(); @@ -1392,27 +1398,26 @@ bool PlayerSAO::checkMovementCheat() required_time = d_vert / player_max_speed; // Moving upwards if (m_move_pool.grab(required_time)) { - m_last_good_position = m_player->getPosition(); + m_last_good_position = m_base_position; } else { actionstream << "Player " << m_player->getName() << " moved too fast; resetting position" << std::endl; - m_player->setPosition(m_last_good_position); + setBasePosition(m_last_good_position); cheated = true; } return cheated; } -bool PlayerSAO::getCollisionBox(aabb3f *toset) { - //update collision box - *toset = m_player->getCollisionbox(); - +bool PlayerSAO::getCollisionBox(aabb3f *toset) +{ + *toset = aabb3f(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30); toset->MinEdge += m_base_position; toset->MaxEdge += m_base_position; - return true; } -bool PlayerSAO::collideWithObjects(){ +bool PlayerSAO::collideWithObjects() +{ return true; } diff --git a/src/content_sao.h b/src/content_sao.h index 76a3a37da..4ea6277ff 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -23,12 +23,35 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "serverobject.h" #include "itemgroup.h" #include "object_properties.h" +#include "constants.h" + +class UnitSAO: public ServerActiveObject +{ +public: + UnitSAO(ServerEnvironment *env, v3f pos): + ServerActiveObject(env, pos), + m_hp(-1), m_yaw(0) {} + virtual ~UnitSAO() {} + + virtual void setYaw(const float yaw) { m_yaw = yaw; } + float getYaw() const { return m_yaw; }; + f32 getRadYaw() const { return m_yaw * core::DEGTORAD; } + // Deprecated + f32 getRadYawDep() const { return (m_yaw + 90.) * core::DEGTORAD; } + + s16 getHP() const { return m_hp; } + // Use a function, if isDead can be defined by other conditions + bool isDead() const { return m_hp == 0; } +protected: + s16 m_hp; + float m_yaw; +}; /* LuaEntitySAO needs some internals exposed. */ -class LuaEntitySAO : public ServerActiveObject +class LuaEntitySAO : public UnitSAO { public: LuaEntitySAO(ServerEnvironment *env, v3f pos, @@ -74,8 +97,7 @@ public: v3f getVelocity(); void setAcceleration(v3f acceleration); v3f getAcceleration(); - void setYaw(float yaw); - float getYaw(); + void setTextureMod(const std::string &mod); void setSprite(v2s16 p, int num_frames, float framelength, bool select_horiz_by_yawpitch); @@ -91,10 +113,9 @@ private: bool m_registered; struct ObjectProperties m_prop; - s16 m_hp; v3f m_velocity; v3f m_acceleration; - float m_yaw; + ItemGroupList m_armor_groups; bool m_properties_sent; @@ -158,11 +179,10 @@ public: class RemotePlayer; -class PlayerSAO : public ServerActiveObject +class PlayerSAO : public UnitSAO { public: - PlayerSAO(ServerEnvironment *env_, RemotePlayer *player_, u16 peer_id_, - const std::set &privs, bool is_singleplayer); + PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer); ~PlayerSAO(); ActiveObjectType getType() const { return ACTIVEOBJECT_TYPE_PLAYER; } @@ -182,10 +202,14 @@ public: bool isAttached(); void step(float dtime, bool send_recommended); void setBasePosition(const v3f &position); - void setPos(v3f pos); + void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); - void setYaw(float); - void setPitch(float); + void setYaw(const float yaw, bool send_data = true); + void setPitch(const float pitch, bool send_data = true); + f32 getPitch() const { return m_pitch; } + f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } + // Deprecated + f32 getRadPitchDep() const { return -1.0 * m_pitch * core::DEGTORAD; } /* Interaction interface @@ -196,11 +220,10 @@ public: ServerActiveObject *puncher, float time_from_last_punch); void rightClick(ServerActiveObject *clicker); - s16 getHP() const; - void setHP(s16 hp); + void setHP(s16 hp, bool direct = false); s16 readDamage(); - u16 getBreath() const; - void setBreath(u16 breath); + u16 getBreath() const { return m_breath; } + void setBreath(const u16 breath); void setArmorGroups(const ItemGroupList &armor_groups); ItemGroupList getArmorGroups(); void setAnimation(v2f frame_range, float frame_speed, float frame_blend, bool frame_loop); @@ -283,6 +306,11 @@ public: bool getCollisionBox(aabb3f *toset); bool collideWithObjects(); + void initialize(RemotePlayer *player, const std::set &privs); + + v3f getEyePosition() const { return m_base_position + getEyeOffset(); } + v3f getEyeOffset() const { return v3f(0, BS * 1.625f, 0); } + private: std::string getPropertyPacket(); @@ -326,8 +354,8 @@ private: v3f m_attachment_position; v3f m_attachment_rotation; bool m_attachment_sent; - - + u16 m_breath; + f32 m_pitch; public: float m_physics_override_speed; float m_physics_override_jump; diff --git a/src/environment.cpp b/src/environment.cpp index ecda1b6a4..13c64b37c 100644 --- a/src/environment.cpp +++ b/src/environment.cpp @@ -608,9 +608,8 @@ void ServerEnvironment::saveLoadedPlayers() for (std::vector::iterator it = m_players.begin(); it != m_players.end(); ++it) { - RemotePlayer *player = static_cast(*it); - if (player->checkModified()) { - player->save(players_path, m_gamedef); + if ((*it)->checkModified()) { + (*it)->save(players_path, m_gamedef); } } } @@ -623,7 +622,7 @@ void ServerEnvironment::savePlayer(RemotePlayer *player) player->save(players_path, m_gamedef); } -RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) +RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername, PlayerSAO *sao) { bool newplayer = false; bool found = false; @@ -641,7 +640,8 @@ RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) std::ifstream is(path.c_str(), std::ios_base::binary); if (!is.good()) continue; - player->deSerialize(is, path); + + player->deSerialize(is, path, sao); is.close(); if (player->getName() == playername) { @@ -657,11 +657,13 @@ RemotePlayer *ServerEnvironment::loadPlayer(const std::string &playername) << " not found" << std::endl; if (newplayer) delete player; + return NULL; } - if (newplayer) + if (newplayer) { addPlayer(player); + } player->setModified(false); return player; } @@ -1271,12 +1273,16 @@ void ServerEnvironment::step(float dtime) i != m_players.end(); ++i) { RemotePlayer *player = dynamic_cast(*i); assert(player); + // Ignore disconnected players if (player->peer_id == 0) continue; + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + v3s16 blockpos = getNodeBlockPos( - floatToInt(player->getPosition(), BS)); + floatToInt(playersao->getBasePosition(), BS)); players_blockpos.push_back(blockpos); } @@ -1584,7 +1590,7 @@ u16 ServerEnvironment::addActiveObject(ServerActiveObject *object) Finds out what new objects have been added to inside a radius around a position */ -void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, +void ServerEnvironment::getAddedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects) @@ -1594,7 +1600,6 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, if (player_radius_f < 0) player_radius_f = 0; - /* Go through the object list, - discard m_removed objects, @@ -1602,20 +1607,21 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, - discard objects that are found in current_objects. - add remaining objects to added_objects */ - for(ActiveObjectMap::iterator i = m_active_objects.begin(); + for (ActiveObjectMap::iterator i = m_active_objects.begin(); i != m_active_objects.end(); ++i) { u16 id = i->first; // Get object ServerActiveObject *object = i->second; - if(object == NULL) + if (object == NULL) continue; // Discard if removed or deactivating if(object->m_removed || object->m_pending_deactivation) continue; - f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + f32 distance_f = object->getBasePosition(). + getDistanceFrom(playersao->getBasePosition()); if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { // Discard if too far if (distance_f > player_radius_f && player_radius_f != 0) @@ -1637,7 +1643,7 @@ void ServerEnvironment::getAddedActiveObjects(RemotePlayer *player, s16 radius, Finds out what objects have been removed from inside a radius around a position */ -void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius, +void ServerEnvironment::getRemovedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects) @@ -1647,7 +1653,6 @@ void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius if (player_radius_f < 0) player_radius_f = 0; - /* Go through current_objects; object is removed if: - object is not found in m_active_objects (this is actually an @@ -1675,7 +1680,7 @@ void ServerEnvironment::getRemovedActiveObjects(RemotePlayer *player, s16 radius continue; } - f32 distance_f = object->getBasePosition().getDistanceFrom(player->getPosition()); + f32 distance_f = object->getBasePosition().getDistanceFrom(playersao->getBasePosition()); if (object->getType() == ACTIVEOBJECT_TYPE_PLAYER) { if (distance_f <= player_radius_f || player_radius_f == 0) continue; diff --git a/src/environment.h b/src/environment.h index 3f3c1cf2c..4bee40e57 100644 --- a/src/environment.h +++ b/src/environment.h @@ -54,6 +54,7 @@ class ClientMap; class GameScripting; class Player; class RemotePlayer; +class PlayerSAO; class Environment { @@ -315,7 +316,7 @@ public: // Save players void saveLoadedPlayers(); void savePlayer(RemotePlayer *player); - RemotePlayer *loadPlayer(const std::string &playername); + RemotePlayer *loadPlayer(const std::string &playername, PlayerSAO *sao); void addPlayer(RemotePlayer *player); void removePlayer(RemotePlayer *player); @@ -362,7 +363,7 @@ public: Find out what new objects have been added to inside a radius around a position */ - void getAddedActiveObjects(RemotePlayer *player, s16 radius, + void getAddedActiveObjects(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &added_objects); @@ -371,7 +372,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(PlayerSAO *playersao, s16 radius, s16 player_radius, std::set ¤t_objects, std::queue &removed_objects); diff --git a/src/localplayer.cpp b/src/localplayer.cpp index bc242a59d..71efb2343 100644 --- a/src/localplayer.cpp +++ b/src/localplayer.cpp @@ -35,6 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc., LocalPlayer::LocalPlayer(Client *gamedef, const char *name): Player(name, gamedef->idef()), parent(0), + hp(PLAYER_MAX_HP), got_teleported(false), isAttached(false), touching_ground(false), @@ -62,6 +63,7 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): light_color(255,255,255,255), hurt_tilt_timer(0.0f), hurt_tilt_strength(0.0f), + m_position(0,0,0), m_sneak_node(32767,32767,32767), m_sneak_node_exists(false), m_need_to_get_new_sneak_node(true), @@ -69,6 +71,11 @@ LocalPlayer::LocalPlayer(Client *gamedef, const char *name): m_old_node_below(32767,32767,32767), m_old_node_below_type("air"), m_can_jump(false), + m_breath(PLAYER_MAX_BREATH), + m_yaw(0), + m_pitch(0), + camera_barely_in_ceiling(false), + m_collisionbox(-BS * 0.30, 0.0, -BS * 0.30, BS * 0.30, BS * 1.75, BS * 0.30), m_cao(NULL), m_gamedef(gamedef) { diff --git a/src/localplayer.h b/src/localplayer.h index eb727d7e3..749f8f8ce 100644 --- a/src/localplayer.h +++ b/src/localplayer.h @@ -40,6 +40,7 @@ public: ClientActiveObject *parent; + u16 hp; bool got_teleported; bool isAttached; bool touching_ground; @@ -99,10 +100,45 @@ public: u32 maxHudId() const { return hud.size(); } + u16 getBreath() const { return m_breath; } + void setBreath(u16 breath) { m_breath = breath; } + + v3s16 getLightPosition() const + { + return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); + } + + void setYaw(f32 yaw) + { + m_yaw = yaw; + } + + f32 getYaw() const { return m_yaw; } + + void setPitch(f32 pitch) + { + m_pitch = pitch; + } + + f32 getPitch() const { return m_pitch; } + + void setPosition(const v3f &position) + { + m_position = position; + } + + v3f getPosition() const { return m_position; } + v3f getEyePosition() const { return m_position + getEyeOffset(); } + v3f getEyeOffset() const + { + float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f; + return v3f(0, BS * eye_height, 0); + } private: void accelerateHorizontal(const v3f &target_speed, const f32 max_increase); void accelerateVertical(const v3f &target_speed, const f32 max_increase); + v3f m_position; // This is used for determining the sneaking range v3s16 m_sneak_node; // Whether the player is allowed to sneak @@ -117,6 +153,11 @@ private: v3s16 m_old_node_below; std::string m_old_node_below_type; bool m_can_jump; + u16 m_breath; + f32 m_yaw; + f32 m_pitch; + bool camera_barely_in_ceiling; + aabb3f m_collisionbox; GenericCAO* m_cao; Client *m_gamedef; diff --git a/src/network/clientpackethandler.cpp b/src/network/clientpackethandler.cpp index 090741f9f..411982f69 100644 --- a/src/network/clientpackethandler.cpp +++ b/src/network/clientpackethandler.cpp @@ -634,7 +634,6 @@ void Client::handleCommand_AnnounceMedia(NetworkPacket* pkt) m_media_downloader->addFile(name, sha1_raw); } - std::vector remote_media; try { std::string str; diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 554025747..5e70b4c6c 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -809,13 +809,6 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) return; } - // If player is dead we don't care of this packet - if (player->isDead()) { - verbosestream << "TOSERVER_PLAYERPOS: " << player->getName() - << " is dead. Ignoring packet"; - return; - } - PlayerSAO *playersao = player->getPlayerSAO(); if (playersao == NULL) { errorstream << "Server::ProcessData(): Canceling: " @@ -825,10 +818,17 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) return; } - player->setPosition(position); + // If player is dead we don't care of this packet + if (playersao->isDead()) { + verbosestream << "TOSERVER_PLAYERPOS: " << player->getName() + << " is dead. Ignoring packet"; + return; + } + + playersao->setBasePosition(position); player->setSpeed(speed); - player->setPitch(pitch); - player->setYaw(yaw); + playersao->setPitch(pitch, false); + playersao->setYaw(yaw, false); player->keyPressed = keyPressed; player->control.up = (keyPressed & 1); player->control.down = (keyPressed & 2); @@ -1100,7 +1100,7 @@ void Server::handleCommand_Damage(NetworkPacket* pkt) if (g_settings->getBool("enable_damage")) { actionstream << player->getName() << " damaged by " - << (int)damage << " hp at " << PP(player->getPosition() / BS) + << (int)damage << " hp at " << PP(playersao->getBasePosition() / BS) << std::endl; playersao->setHP(playersao->getHP() - damage); @@ -1124,16 +1124,6 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) return; } - /* - * If player is dead, we don't need to update the breath - * He is dead ! - */ - if (player->isDead()) { - verbosestream << "TOSERVER_BREATH: " << player->getName() - << " is dead. Ignoring packet"; - return; - } - PlayerSAO *playersao = player->getPlayerSAO(); if (playersao == NULL) { @@ -1144,6 +1134,16 @@ void Server::handleCommand_Breath(NetworkPacket* pkt) return; } + /* + * If player is dead, we don't need to update the breath + * He is dead ! + */ + if (playersao->isDead()) { + verbosestream << "TOSERVER_BREATH: " << player->getName() + << " is dead. Ignoring packet"; + return; + } + playersao->setBreath(breath); SendPlayerBreath(pkt->getPeerId()); } @@ -1264,13 +1264,16 @@ void Server::handleCommand_Respawn(NetworkPacket* pkt) return; } - if (!player->isDead()) + PlayerSAO *playersao = player->getPlayerSAO(); + assert(playersao); + + if (!playersao->isDead()) return; RespawnPlayer(pkt->getPeerId()); actionstream << player->getName() << " respawns at " - << PP(player->getPosition()/BS) << std::endl; + << PP(playersao->getBasePosition() / BS) << std::endl; // ActiveObject is added to environment in AsyncRunStep after // the previous addition has been successfully removed @@ -1322,9 +1325,9 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) return; } - if (player->isDead()) { + if (playersao->isDead()) { verbosestream << "TOSERVER_INTERACT: " << player->getName() - << " is dead. Ignoring packet"; + << " is dead. Ignoring packet"; return; } @@ -1455,7 +1458,7 @@ void Server::handleCommand_Interact(NetworkPacket* pkt) ToolCapabilities toolcap = punchitem.getToolCapabilities(m_itemdef); v3f dir = (pointed_object->getBasePosition() - - (player->getPosition() + player->getEyeOffset()) + (playersao->getBasePosition() + playersao->getEyeOffset()) ).normalize(); float time_from_last_punch = playersao->resetTimeFromLastPunch(); diff --git a/src/player.cpp b/src/player.cpp index fa82a79f4..9c321d571 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -30,18 +30,11 @@ with this program; if not, write to the Free Software Foundation, Inc., Player::Player(const char *name, IItemDefManager *idef): - camera_barely_in_ceiling(false), inventory(idef), - hp(PLAYER_MAX_HP), peer_id(PEER_ID_INEXISTENT), keyPressed(0), // protected - m_breath(PLAYER_MAX_BREATH), - m_pitch(0), - m_yaw(0), - m_speed(0,0,0), - m_position(0,0,0), - m_collisionbox(-BS*0.30,0.0,-BS*0.30,BS*0.30,BS*1.75,BS*0.30) + m_speed(0,0,0) { strlcpy(m_name, name, PLAYERNAME_SIZE); @@ -90,11 +83,6 @@ Player::~Player() clearHud(); } -v3s16 Player::getLightPosition() const -{ - return floatToInt(m_position + v3f(0,BS+BS/2,0), BS); -} - u32 Player::addHud(HudElement *toadd) { MutexAutoLock lock(m_mutex); diff --git a/src/player.h b/src/player.h index 6ac5dfe65..5f9bb7ec9 100644 --- a/src/player.h +++ b/src/player.h @@ -129,49 +129,7 @@ public: m_speed = speed; } - v3f getPosition() - { - return m_position; - } - - v3s16 getLightPosition() const; - - v3f getEyeOffset() - { - float eye_height = camera_barely_in_ceiling ? 1.5f : 1.625f; - return v3f(0, BS * eye_height, 0); - } - - v3f getEyePosition() - { - return m_position + getEyeOffset(); - } - - virtual void setPosition(const v3f &position) - { - m_position = position; - } - - virtual void setPitch(f32 pitch) - { - m_pitch = pitch; - } - - virtual void setYaw(f32 yaw) - { - m_yaw = yaw; - } - - f32 getPitch() const { return m_pitch; } - f32 getYaw() const { return m_yaw; } - u16 getBreath() const { return m_breath; } - - virtual void setBreath(u16 breath) { m_breath = breath; } - - f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } - f32 getRadYaw() const { return m_yaw * core::DEGTORAD; } const char *getName() const { return m_name; } - aabb3f getCollisionbox() const { return m_collisionbox; } u32 getFreeHudID() { @@ -183,7 +141,6 @@ public: return size; } - bool camera_barely_in_ceiling; v3f eye_offset_first; v3f eye_offset_third; @@ -205,8 +162,6 @@ public: v2s32 local_animations[4]; float local_animation_speed; - u16 hp; - u16 peer_id; std::string inventory_formspec; @@ -225,12 +180,7 @@ public: s32 hud_hotbar_itemcount; protected: char m_name[PLAYERNAME_SIZE]; - u16 m_breath; - f32 m_pitch; - f32 m_yaw; v3f m_speed; - v3f m_position; - aabb3f m_collisionbox; std::vector hud; private: diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index f64d1d690..605346928 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -96,7 +96,7 @@ void RemotePlayer::save(std::string savedir, IGameDef *gamedef) infostream << "Failed to open " << path << std::endl; return; } - testplayer.deSerialize(is, path); + testplayer.deSerialize(is, path, NULL); is.close(); if (strcmp(testplayer.getName(), m_name) == 0) { // Open file and serialize @@ -115,37 +115,46 @@ void RemotePlayer::save(std::string savedir, IGameDef *gamedef) return; } -void RemotePlayer::deSerialize(std::istream &is, const std::string &playername) +void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, + PlayerSAO *sao) { Settings args; if (!args.parseConfigLines(is, "PlayerArgsEnd")) { - throw SerializationError("PlayerArgsEnd of player " + - playername + " not found!"); + 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; + if (sao) { + try { + sao->setHP(args.getS32("hp"), true); + } catch(SettingNotFoundException &e) { + sao->setHP(PLAYER_MAX_HP, true); + } + + try { + sao->setBasePosition(args.getV3F("position")); + } catch (SettingNotFoundException &e) {} + + try { + sao->setPitch(args.getFloat("pitch"), false); + } catch (SettingNotFoundException &e) {} + try { + sao->setYaw(args.getFloat("yaw"), false); + } catch (SettingNotFoundException &e) {} + + try { + sao->setBreath(args.getS32("breath")); + } catch (SettingNotFoundException &e) {} } inventory.deSerialize(is); - if(inventory.getList("craftpreview") == NULL) { + if (inventory.getList("craftpreview") == NULL) { // Convert players without craftpreview inventory.addList("craftpreview", 1); @@ -167,11 +176,14 @@ void RemotePlayer::serialize(std::ostream &os) 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); + + if (m_sao) { + args.setS32("hp", m_sao->getHP()); + args.setV3F("position", m_sao->getBasePosition()); + args.setFloat("pitch", m_sao->getPitch()); + args.setFloat("yaw", m_sao->getYaw()); + args.setS32("breath", m_sao->getBreath()); + } args.writeLines(os); @@ -180,16 +192,6 @@ void RemotePlayer::serialize(std::ostream &os) 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 diff --git a/src/remoteplayer.h b/src/remoteplayer.h index 1b1a90de3..61b5a23de 100644 --- a/src/remoteplayer.h +++ b/src/remoteplayer.h @@ -40,11 +40,10 @@ public: virtual ~RemotePlayer() {} void save(std::string savedir, IGameDef *gamedef); - void deSerialize(std::istream &is, const std::string &playername); + void deSerialize(std::istream &is, const std::string &playername, PlayerSAO *sao); PlayerSAO *getPlayerSAO() { return m_sao; } void setPlayerSAO(PlayerSAO *sao) { m_sao = sao; } - void setPosition(const v3f &position); const RemotePlayerChatResult canSendChatMessage(); @@ -67,9 +66,6 @@ public: *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; @@ -90,12 +86,6 @@ public: 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 ¶ms) { @@ -121,27 +111,6 @@ public: 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); - } - void setLocalAnimations(v2s32 frames[4], float frame_speed) { for (int i = 0; i < 4; i++) @@ -156,6 +125,8 @@ public: *frame_speed = local_animation_speed; } + void setDirty(bool dirty) { m_dirty = true; } + u16 protocol_version; private: /* diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index 23994181c..cf124f17c 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1013,11 +1013,11 @@ int ObjectRef::l_get_look_dir(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - float pitch = player->getRadPitchDep(); - float yaw = player->getRadYawDep(); + float pitch = co->getRadPitchDep(); + float yaw = co->getRadYawDep(); v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw)); push_v3f(L, v); return 1; @@ -1033,10 +1033,10 @@ int ObjectRef::l_get_look_pitch(lua_State *L) "Deprecated call to get_look_pitch, use get_look_vertical instead"); ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadPitchDep()); + lua_pushnumber(L, co->getRadPitchDep()); return 1; } @@ -1050,10 +1050,10 @@ int ObjectRef::l_get_look_yaw(lua_State *L) "Deprecated call to get_look_yaw, use get_look_horizontal instead"); ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadYawDep()); + lua_pushnumber(L, co->getRadYawDep()); return 1; } @@ -1062,10 +1062,10 @@ int ObjectRef::l_get_look_vertical(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadPitch()); + lua_pushnumber(L, co->getRadPitch()); return 1; } @@ -1074,10 +1074,10 @@ int ObjectRef::l_get_look_horizontal(lua_State *L) { NO_MAP_LOCK_REQUIRED; ObjectRef *ref = checkobject(L, 1); - RemotePlayer *player = getplayer(ref); - if (player == NULL) return 0; + PlayerSAO* co = getplayersao(ref); + if (co == NULL) return 0; // Do it - lua_pushnumber(L, player->getRadYaw()); + lua_pushnumber(L, co->getRadYaw()); return 1; } diff --git a/src/server.cpp b/src/server.cpp index e67f37d56..cd526ad77 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -701,11 +701,15 @@ void Server::AsyncRunStep(bool initial_step) continue; } + PlayerSAO *playersao = player->getPlayerSAO(); + if (playersao == NULL) + continue; + std::queue removed_objects; std::queue added_objects; - m_env->getRemovedActiveObjects(player, radius, player_radius, + m_env->getRemovedActiveObjects(playersao, radius, player_radius, client->m_known_objects, removed_objects); - m_env->getAddedActiveObjects(player, radius, player_radius, + m_env->getAddedActiveObjects(playersao, radius, player_radius, client->m_known_objects, added_objects); // Ignore if nothing happened @@ -1108,7 +1112,7 @@ PlayerSAO* Server::StageTwoClientInit(u16 peer_id) SendPlayerBreath(peer_id); // Show death screen if necessary - if (player->isDead()) + if (playersao->isDead()) SendDeathscreen(peer_id, false, v3f(0,0,0)); // Note things in chat if not in simple singleplayer mode @@ -1860,18 +1864,18 @@ void Server::SendMovePlayer(u16 peer_id) DSTACK(FUNCTION_NAME); RemotePlayer *player = m_env->getPlayer(peer_id); assert(player); + PlayerSAO *sao = player->getPlayerSAO(); + assert(sao); NetworkPacket pkt(TOCLIENT_MOVE_PLAYER, sizeof(v3f) + sizeof(f32) * 2, peer_id); - pkt << player->getPosition() << player->getPitch() << player->getYaw(); + pkt << sao->getBasePosition() << sao->getPitch() << sao->getYaw(); { - v3f pos = player->getPosition(); - f32 pitch = player->getPitch(); - f32 yaw = player->getYaw(); + v3f pos = sao->getBasePosition(); verbosestream << "Server: Sending TOCLIENT_MOVE_PLAYER" << " pos=(" << pos.X << "," << pos.Y << "," << pos.Z << ")" - << " pitch=" << pitch - << " yaw=" << yaw + << " pitch=" << sao->getPitch() + << " yaw=" << sao->getYaw() << std::endl; } @@ -1984,8 +1988,12 @@ s32 Server::playSound(const SimpleSoundSpec &spec, if (!player) continue; + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + if (pos_exists) { - if(player->getPosition().getDistanceFrom(pos) > + if(sao->getBasePosition().getDistanceFrom(pos) > params.max_hear_distance) continue; } @@ -2044,14 +2052,17 @@ void Server::sendRemoveNode(v3s16 p, u16 ignore_id, pkt << p; std::vector clients = m_clients.getClientIDs(); - for(std::vector::iterator i = clients.begin(); - i != clients.end(); ++i) { + for (std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { if (far_players) { // Get player if (RemotePlayer *player = m_env->getPlayer(*i)) { + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + // If player is far away, only set modified blocks not sent - v3f player_pos = player->getPosition(); - if(player_pos.getDistanceFrom(p_f) > maxd) { + v3f player_pos = sao->getBasePosition(); + if (player_pos.getDistanceFrom(p_f) > maxd) { far_players->push_back(*i); continue; } @@ -2071,14 +2082,16 @@ void Server::sendAddNode(v3s16 p, MapNode n, u16 ignore_id, v3f p_f = intToFloat(p, BS); std::vector clients = m_clients.getClientIDs(); - for(std::vector::iterator i = clients.begin(); - i != clients.end(); ++i) { - - if(far_players) { + for(std::vector::iterator i = clients.begin(); i != clients.end(); ++i) { + if (far_players) { // Get player if (RemotePlayer *player = m_env->getPlayer(*i)) { + PlayerSAO *sao = player->getPlayerSAO(); + if (!sao) + continue; + // If player is far away, only set modified blocks not sent - v3f player_pos = player->getPosition(); + v3f player_pos = sao->getBasePosition(); if(player_pos.getDistanceFrom(p_f) > maxd) { far_players->push_back(*i); continue; @@ -3426,10 +3439,9 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version return NULL; } - // Load player if it isn't already loaded - if (!player) { - player = m_env->loadPlayer(name); - } + // Create a new player active object + PlayerSAO *playersao = new PlayerSAO(m_env, peer_id, isSingleplayer()); + player = m_env->loadPlayer(name, playersao); // Create player if it doesn't exist if (!player) { @@ -3438,8 +3450,7 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version // Set player position infostream<<"Server: Finding spawn place for player \"" <setPosition(pos); + playersao->setBasePosition(findSpawnPos()); // Make sure the player is saved player->setModified(true); @@ -3450,18 +3461,14 @@ PlayerSAO* Server::emergePlayer(const char *name, u16 peer_id, u16 proto_version // If the player exists, ensure that they respawn inside legal bounds // This fixes an assert crash when the player can't be added // to the environment - if (objectpos_over_limit(player->getPosition())) { + if (objectpos_over_limit(playersao->getBasePosition())) { actionstream << "Respawn position for player \"" << name << "\" outside limits, resetting" << std::endl; - v3f pos = findSpawnPos(); - player->setPosition(pos); + playersao->setBasePosition(findSpawnPos()); } } - // Create a new player active object - PlayerSAO *playersao = new PlayerSAO(m_env, player, peer_id, - getPlayerEffectivePrivs(player->getName()), - isSingleplayer()); + playersao->initialize(player, getPlayerEffectivePrivs(player->getName())); player->protocol_version = proto_version; diff --git a/src/serverobject.h b/src/serverobject.h index 63650e3be..9884eb0a1 100644 --- a/src/serverobject.h +++ b/src/serverobject.h @@ -85,7 +85,7 @@ public: Some more dynamic interface */ - virtual void setPos(v3f pos) + virtual void setPos(const v3f &pos) { setBasePosition(pos); } // continuous: if true, object does not stop immediately at pos virtual void moveTo(v3f pos, bool continuous) diff --git a/src/unittest/test_player.cpp b/src/unittest/test_player.cpp index 5de9eaaf2..fba422475 100644 --- a/src/unittest/test_player.cpp +++ b/src/unittest/test_player.cpp @@ -46,11 +46,14 @@ void TestPlayer::runTests(IGameDef *gamedef) void TestPlayer::testSave(IGameDef *gamedef) { RemotePlayer rplayer("testplayer_save", gamedef->idef()); - rplayer.setBreath(10); - rplayer.hp = 8; - rplayer.setYaw(0.1f); - rplayer.setPitch(0.6f); - rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f)); + PlayerSAO sao(NULL, 1, false); + sao.initialize(&rplayer, std::set()); + rplayer.setPlayerSAO(&sao); + sao.setBreath(10); + sao.setHP(8, true); + sao.setYaw(0.1f, false); + sao.setPitch(0.6f, false); + sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_save")); } @@ -58,24 +61,28 @@ void TestPlayer::testSave(IGameDef *gamedef) void TestPlayer::testLoad(IGameDef *gamedef) { RemotePlayer rplayer("testplayer_load", gamedef->idef()); - rplayer.setBreath(10); - rplayer.hp = 8; - rplayer.setYaw(0.1f); - rplayer.setPitch(0.6f); - rplayer.setPosition(v3f(450.2f, -15.7f, 68.1f)); + PlayerSAO sao(NULL, 1, false); + sao.initialize(&rplayer, std::set()); + rplayer.setPlayerSAO(&sao); + sao.setBreath(10); + sao.setHP(8, true); + sao.setYaw(0.1f, false); + sao.setPitch(0.6f, false); + sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_load")); RemotePlayer rplayer_load("testplayer_load", gamedef->idef()); + PlayerSAO sao_load(NULL, 2, false); std::ifstream is("testplayer_load", std::ios_base::binary); UASSERT(is.good()); - rplayer_load.deSerialize(is, "testplayer_load"); + rplayer_load.deSerialize(is, "testplayer_load", &sao_load); is.close(); UASSERT(strcmp(rplayer_load.getName(), "testplayer_load") == 0); - UASSERT(rplayer.getBreath() == 10); - UASSERT(rplayer.hp == 8); - UASSERT(rplayer.getYaw() == 0.1f); - UASSERT(rplayer.getPitch() == 0.6f); - UASSERT(rplayer.getPosition() == v3f(450.2f, -15.7f, 68.1f)); + UASSERT(sao_load.getBreath() == 10); + UASSERT(sao_load.getHP() == 8); + UASSERT(sao_load.getYaw() == 0.1f); + UASSERT(sao_load.getPitch() == 0.6f); + UASSERT(sao_load.getBasePosition() == v3f(450.2f, -15.7f, 68.1f)); } -- cgit v1.2.3 From 595932a8602292f28333ce14e20cee4b6d8820c1 Mon Sep 17 00:00:00 2001 From: Loic Blot Date: Sun, 30 Oct 2016 16:12:09 +0100 Subject: Fix overloading problems mentioned by clang --- src/content_sao.cpp | 28 ++++++++++++++-------------- src/content_sao.h | 13 +++++++++---- src/network/serverpackethandler.cpp | 4 ++-- src/remoteplayer.cpp | 8 ++++---- src/script/lua_api/l_object.cpp | 8 ++++---- src/unittest/test_player.cpp | 12 ++++++------ 6 files changed, 39 insertions(+), 34 deletions(-) (limited to 'src/remoteplayer.cpp') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 23a064085..5fb8f936e 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -507,7 +507,7 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker) m_env->getScriptIface()->luaentity_Rightclick(m_id, clicker); } -void LuaEntitySAO::setPos(v3f pos) +void LuaEntitySAO::setPos(const v3f &pos) { if(isAttached()) return; @@ -1078,27 +1078,32 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setYaw(const float yaw, bool send_data) +void PlayerSAO::setYaw(const float yaw) { if (m_player && yaw != m_yaw) m_player->setDirty(true); UnitSAO::setYaw(yaw); +} - // Datas should not be sent at player initialization - if (send_data) - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); +void PlayerSAO::setYawAndSend(const float yaw) +{ + setYaw(yaw); + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } -void PlayerSAO::setPitch(const float pitch, bool send_data) +void PlayerSAO::setPitch(const float pitch) { if (m_player && pitch != m_pitch) m_player->setDirty(true); m_pitch = pitch; +} - if (send_data) - ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); +void PlayerSAO::setPitchAndSend(const float pitch) +{ + setPitch(pitch); + ((Server*)m_env->getGameDef())->SendMovePlayer(m_peer_id); } int PlayerSAO::punch(v3f dir, @@ -1173,13 +1178,8 @@ s16 PlayerSAO::readDamage() return damage; } -void PlayerSAO::setHP(s16 hp, bool direct) +void PlayerSAO::setHP(s16 hp) { - if (direct) { - m_hp = hp; - return; - } - s16 oldhp = m_hp; s16 hp_change = m_env->getScriptIface()->on_player_hpchange(this, hp - oldhp); diff --git a/src/content_sao.h b/src/content_sao.h index 4ea6277ff..5d837a466 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -73,7 +73,7 @@ public: ServerActiveObject *puncher=NULL, float time_from_last_punch=1000000); void rightClick(ServerActiveObject *clicker); - void setPos(v3f pos); + void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); float getMinimumSavedMovement(); std::string getDescription(); @@ -204,8 +204,12 @@ public: void setBasePosition(const v3f &position); void setPos(const v3f &pos); void moveTo(v3f pos, bool continuous); - void setYaw(const float yaw, bool send_data = true); - void setPitch(const float pitch, bool send_data = true); + void setYaw(const float yaw); + // Data should not be sent at player initialization + void setYawAndSend(const float yaw); + void setPitch(const float pitch); + // Data should not be sent at player initialization + void setPitchAndSend(const float pitch); f32 getPitch() const { return m_pitch; } f32 getRadPitch() const { return m_pitch * core::DEGTORAD; } // Deprecated @@ -220,7 +224,8 @@ public: ServerActiveObject *puncher, float time_from_last_punch); void rightClick(ServerActiveObject *clicker); - void setHP(s16 hp, bool direct = false); + void setHP(s16 hp); + void setHPRaw(s16 hp) { m_hp = hp; } s16 readDamage(); u16 getBreath() const { return m_breath; } void setBreath(const u16 breath); diff --git a/src/network/serverpackethandler.cpp b/src/network/serverpackethandler.cpp index 5e70b4c6c..80eec140d 100644 --- a/src/network/serverpackethandler.cpp +++ b/src/network/serverpackethandler.cpp @@ -827,8 +827,8 @@ void Server::handleCommand_PlayerPos(NetworkPacket* pkt) playersao->setBasePosition(position); player->setSpeed(speed); - playersao->setPitch(pitch, false); - playersao->setYaw(yaw, false); + playersao->setPitch(pitch); + playersao->setYaw(yaw); player->keyPressed = keyPressed; player->control.up = (keyPressed & 1); player->control.down = (keyPressed & 2); diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index 605346928..f4a79dd08 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -131,9 +131,9 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, if (sao) { try { - sao->setHP(args.getS32("hp"), true); + sao->setHPRaw(args.getS32("hp")); } catch(SettingNotFoundException &e) { - sao->setHP(PLAYER_MAX_HP, true); + sao->setHPRaw(PLAYER_MAX_HP); } try { @@ -141,10 +141,10 @@ void RemotePlayer::deSerialize(std::istream &is, const std::string &playername, } catch (SettingNotFoundException &e) {} try { - sao->setPitch(args.getFloat("pitch"), false); + sao->setPitch(args.getFloat("pitch")); } catch (SettingNotFoundException &e) {} try { - sao->setYaw(args.getFloat("yaw"), false); + sao->setYaw(args.getFloat("yaw")); } catch (SettingNotFoundException &e) {} try { diff --git a/src/script/lua_api/l_object.cpp b/src/script/lua_api/l_object.cpp index cf124f17c..42395717f 100644 --- a/src/script/lua_api/l_object.cpp +++ b/src/script/lua_api/l_object.cpp @@ -1090,7 +1090,7 @@ int ObjectRef::l_set_look_vertical(lua_State *L) if (co == NULL) return 0; float pitch = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setPitch(pitch); + co->setPitchAndSend(pitch); return 1; } @@ -1103,7 +1103,7 @@ int ObjectRef::l_set_look_horizontal(lua_State *L) if (co == NULL) return 0; float yaw = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setYaw(yaw); + co->setYawAndSend(yaw); return 1; } @@ -1121,7 +1121,7 @@ int ObjectRef::l_set_look_pitch(lua_State *L) if (co == NULL) return 0; float pitch = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setPitch(pitch); + co->setPitchAndSend(pitch); return 1; } @@ -1139,7 +1139,7 @@ int ObjectRef::l_set_look_yaw(lua_State *L) if (co == NULL) return 0; float yaw = luaL_checknumber(L, 2) * core::RADTODEG; // Do it - co->setYaw(yaw); + co->setYawAndSend(yaw); return 1; } diff --git a/src/unittest/test_player.cpp b/src/unittest/test_player.cpp index fba422475..85fbc8b2d 100644 --- a/src/unittest/test_player.cpp +++ b/src/unittest/test_player.cpp @@ -50,9 +50,9 @@ void TestPlayer::testSave(IGameDef *gamedef) sao.initialize(&rplayer, std::set()); rplayer.setPlayerSAO(&sao); sao.setBreath(10); - sao.setHP(8, true); - sao.setYaw(0.1f, false); - sao.setPitch(0.6f, false); + sao.setHPRaw(8); + sao.setYaw(0.1f); + sao.setPitch(0.6f); sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_save")); @@ -65,9 +65,9 @@ void TestPlayer::testLoad(IGameDef *gamedef) sao.initialize(&rplayer, std::set()); rplayer.setPlayerSAO(&sao); sao.setBreath(10); - sao.setHP(8, true); - sao.setYaw(0.1f, false); - sao.setPitch(0.6f, false); + sao.setHPRaw(8); + sao.setYaw(0.1f); + sao.setPitch(0.6f); sao.setBasePosition(v3f(450.2f, -15.7f, 68.1f)); rplayer.save(".", gamedef); UASSERT(fs::PathExists("testplayer_load")); -- cgit v1.2.3 From 66bb2954362748c4722d366d0df490ad51a591a2 Mon Sep 17 00:00:00 2001 From: Ner'zhul Date: Sat, 5 Nov 2016 10:25:30 +0100 Subject: PlayerSAO saving fix (#4734) PlayerSAO::disconnected() function was historical and remove the link between SAO and RemotePlayer session. With previous attributes linked to RemotePlayer saving was working. But now attributes are read from SAO not RemotePlayer and the current serialize function verify SAO exists to save the player attributes. Because PlayerSAO::disconnected marks playersao for removal, only mark playerSAO for removal and let PlayerSAO::removingFromEnvironment do the correct saving behaviour and all the disconnection process instead of doing a partial removal and let the server loop doing the RemotePlayer cleanup and remove some saved attributes... --- src/content_sao.cpp | 20 +++++++++++--------- src/content_sao.h | 1 + src/remoteplayer.cpp | 14 +++++++------- src/server.cpp | 2 +- 4 files changed, 20 insertions(+), 17 deletions(-) (limited to 'src/remoteplayer.cpp') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 5fb8f936e..dff222f42 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -838,10 +838,7 @@ void PlayerSAO::removingFromEnvironment() { ServerActiveObject::removingFromEnvironment(); if (m_player->getPlayerSAO() == this) { - m_player->peer_id = 0; - m_env->savePlayer(m_player); - m_player->setPlayerSAO(NULL); - m_env->removePlayer(m_player); + unlinkPlayerSessionAndSave(); for (UNORDERED_SET::iterator it = m_attached_particle_spawners.begin(); it != m_attached_particle_spawners.end(); ++it) { m_env->deleteParticleSpawner(*it, false); @@ -1340,15 +1337,20 @@ void PlayerSAO::setWieldIndex(int i) } } +// Erase the peer id and make the object for removal void PlayerSAO::disconnected() { m_peer_id = 0; m_removed = true; - if(m_player->getPlayerSAO() == this) - { - m_player->setPlayerSAO(NULL); - m_player->peer_id = 0; - } +} + +void PlayerSAO::unlinkPlayerSessionAndSave() +{ + assert(m_player->getPlayerSAO() == this); + m_player->peer_id = 0; + m_env->savePlayer(m_player); + m_player->setPlayerSAO(NULL); + m_env->removePlayer(m_player); } std::string PlayerSAO::getPropertyPacket() diff --git a/src/content_sao.h b/src/content_sao.h index 5d837a466..f58c7dadb 100644 --- a/src/content_sao.h +++ b/src/content_sao.h @@ -318,6 +318,7 @@ public: private: std::string getPropertyPacket(); + void unlinkPlayerSessionAndSave(); RemotePlayer *m_player; u16 m_peer_id; diff --git a/src/remoteplayer.cpp b/src/remoteplayer.cpp index f4a79dd08..67ab89113 100644 --- a/src/remoteplayer.cpp +++ b/src/remoteplayer.cpp @@ -177,13 +177,13 @@ void RemotePlayer::serialize(std::ostream &os) args.set("name", m_name); //args.set("password", m_password); - if (m_sao) { - args.setS32("hp", m_sao->getHP()); - args.setV3F("position", m_sao->getBasePosition()); - args.setFloat("pitch", m_sao->getPitch()); - args.setFloat("yaw", m_sao->getYaw()); - args.setS32("breath", m_sao->getBreath()); - } + // This should not happen + assert(m_sao); + args.setS32("hp", m_sao->getHP()); + args.setV3F("position", m_sao->getBasePosition()); + args.setFloat("pitch", m_sao->getPitch()); + args.setFloat("yaw", m_sao->getYaw()); + args.setS32("breath", m_sao->getBreath()); args.writeLines(os); diff --git a/src/server.cpp b/src/server.cpp index cd526ad77..48331e4f8 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -2654,7 +2654,7 @@ void Server::DeleteClient(u16 peer_id, ClientDeletionReason reason) RemotePlayer *player = m_env->getPlayer(peer_id); /* Run scripts and remove from environment */ - if(player != NULL) { + if (player != NULL) { PlayerSAO *playersao = player->getPlayerSAO(); assert(playersao); -- cgit v1.2.3