X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fcontent_sao.cpp;h=9b4ae6100e0eec7d422de0f94f4e4558b7576468;hb=787b43b2183262a08726434e2597638ad85bfb72;hp=ae08b4260385fb9b4f253b7ff81fc2dd9482094f;hpb=7d9329ecfe84733cdefa34eab25ee3d124c94c59;p=dragonfireclient.git diff --git a/src/content_sao.cpp b/src/content_sao.cpp index ae08b4260..9b4ae6100 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -27,9 +27,10 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "tool.h" // For ToolCapabilities #include "gamedef.h" #include "player.h" -#include "scriptapi.h" +#include "scripting_game.h" #include "genericobject.h" #include "util/serialize.h" +#include "util/mathconstants.h" std::map ServerActiveObject::m_types; @@ -68,6 +69,10 @@ class DummyLoadSAO : public ServerActiveObject return false; } + bool collideWithObjects() { + return false; + } + private: }; @@ -140,6 +145,10 @@ class TestSAO : public ServerActiveObject return false; } + bool collideWithObjects() { + return false; + } + private: float m_timer1; float m_age; @@ -325,6 +334,9 @@ class ItemSAO : public ServerActiveObject return false; } + bool collideWithObjects() { + return false; + } private: std::string m_itemstring; @@ -387,8 +399,7 @@ LuaEntitySAO::LuaEntitySAO(ServerEnvironment *env, v3f pos, LuaEntitySAO::~LuaEntitySAO() { if(m_registered){ - lua_State *L = m_env->getLua(); - scriptapi_luaentity_rm(L, m_id); + m_env->getScriptIface()->luaentity_Remove(m_id); } } @@ -397,16 +408,18 @@ void LuaEntitySAO::addedToEnvironment(u32 dtime_s) ServerActiveObject::addedToEnvironment(dtime_s); // Create entity from name - lua_State *L = m_env->getLua(); - m_registered = scriptapi_luaentity_add(L, m_id, m_init_name.c_str()); + m_registered = m_env->getScriptIface()-> + luaentity_Add(m_id, m_init_name.c_str()); if(m_registered){ // Get properties - scriptapi_luaentity_get_properties(L, m_id, &m_prop); + m_env->getScriptIface()-> + luaentity_GetProperties(m_id, &m_prop); // Initialize HP from properties m_hp = m_prop.hp_max; // Activate entity, supplying serialized state - scriptapi_luaentity_activate(L, m_id, m_init_state.c_str(), dtime_s); + m_env->getScriptIface()-> + luaentity_Activate(m_id, m_init_state.c_str(), dtime_s); } } @@ -496,13 +509,14 @@ void LuaEntitySAO::step(float dtime, bool send_recommended) box.MaxEdge *= BS; collisionMoveResult moveresult; f32 pos_max_d = BS*0.25; // Distance per iteration - f32 stepheight = 0; // Maximum climbable step height v3f p_pos = m_base_position; v3f p_velocity = m_velocity; v3f p_acceleration = m_acceleration; moveresult = collisionMoveSimple(m_env,m_env->getGameDef(), - pos_max_d, box, stepheight, dtime, - p_pos, p_velocity, p_acceleration); + pos_max_d, box, m_prop.stepheight, dtime, + p_pos, p_velocity, p_acceleration, + this, m_prop.collideWithObjects); + // Apply results m_base_position = p_pos; m_velocity = p_velocity; @@ -512,11 +526,14 @@ void LuaEntitySAO::step(float dtime, bool send_recommended) * dtime * m_acceleration; m_velocity += dtime * m_acceleration; } + + if(m_prop.automatic_face_movement_dir){ + m_yaw = atan2(m_velocity.Z,m_velocity.X) * 180 / M_PI; + } } if(m_registered){ - lua_State *L = m_env->getLua(); - scriptapi_luaentity_step(L, m_id, dtime); + m_env->getScriptIface()->luaentity_Step(m_id, dtime); } if(send_recommended == false) @@ -626,8 +643,8 @@ std::string LuaEntitySAO::getStaticData() os<getLua(); - std::string state = scriptapi_luaentity_get_staticdata(L, m_id); + std::string state = m_env->getScriptIface()-> + luaentity_GetStaticdata(m_id); os<getDescription(); + actionstream<getDescription()<<", damage "<getLua(); - scriptapi_luaentity_punch(L, m_id, puncher, + m_env->getScriptIface()->luaentity_Punch(m_id, puncher, time_from_last_punch, toolcap, dir); return result.wear; @@ -702,8 +724,7 @@ void LuaEntitySAO::rightClick(ServerActiveObject *clicker) // It's best that attachments cannot be clicked if(isAttached()) return; - lua_State *L = m_env->getLua(); - scriptapi_luaentity_rightclick(L, m_id, clicker); + m_env->getScriptIface()->luaentity_Rightclick(m_id, clicker); } void LuaEntitySAO::setPos(v3f pos) @@ -905,6 +926,10 @@ bool LuaEntitySAO::getCollisionBox(aabb3f *toset) { return false; } +bool LuaEntitySAO::collideWithObjects(){ + return m_prop.collideWithObjects; +} + /* PlayerSAO */ @@ -917,8 +942,8 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_, m_player(player_), m_peer_id(peer_id_), m_inventory(NULL), + m_damage(0), m_last_good_position(0,0,0), - m_last_good_position_age(0), m_time_from_last_punch(0), m_nocheat_dig_pos(32767, 32767, 32767), m_nocheat_dig_time(0), @@ -928,14 +953,22 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_, m_properties_sent(true), m_privs(privs), m_is_singleplayer(is_singleplayer), + m_animation_speed(0), + m_animation_blend(0), m_animation_sent(false), m_bone_position_sent(false), + m_attachment_parent_id(0), m_attachment_sent(false), // public m_moved(false), m_inventory_not_sent(false), m_hp_not_sent(false), - m_wielded_item_not_sent(false) + m_breath_not_sent(false), + m_wielded_item_not_sent(false), + m_physics_override_speed(1), + m_physics_override_jump(1), + m_physics_override_gravity(1), + m_physics_override_sent(false) { assert(m_player); assert(m_peer_id != 0); @@ -981,7 +1014,6 @@ void PlayerSAO::addedToEnvironment(u32 dtime_s) m_player->setPlayerSAO(this); m_player->peer_id = m_peer_id; m_last_good_position = m_player->getPosition(); - m_last_good_position_age = 0.0; } // Called before removing from environment @@ -1019,7 +1051,7 @@ std::string PlayerSAO::getClientInitializationData(u16 protocol_version) writeF1000(os, m_player->getYaw()); writeS16(os, getHP()); - writeU8(os, 4 + m_bone_position.size()); // number of messages stuffed in here + writeU8(os, 5 + m_bone_position.size()); // number of messages stuffed in here os<getMaxLagEstimate() * 2.0; + if(lag_pool_max < LAG_POOL_MIN) + lag_pool_max = LAG_POOL_MIN; + m_dig_pool.setMax(lag_pool_max); + m_move_pool.setMax(lag_pool_max); + + // Increment cheat prevention timers + m_dig_pool.add(dtime); + m_move_pool.add(dtime); m_time_from_last_punch += dtime; m_nocheat_dig_time += dtime; @@ -1093,66 +1139,8 @@ void PlayerSAO::step(float dtime, bool send_recommended) { v3f pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition(); m_last_good_position = pos; - m_last_good_position_age = 0; m_player->setPosition(pos); } - else - { - if(m_is_singleplayer || g_settings->getBool("disable_anticheat")) - { - m_last_good_position = m_player->getPosition(); - m_last_good_position_age = 0; - } - else - { - /* - Check player movements - - NOTE: Actually the server should handle player physics like the - client does and compare player's position to what is calculated - on our side. This is required when eg. players fly due to an - explosion. Altough a node-based alternative might be possible - too, and much more lightweight. - */ - - float player_max_speed = 0; - float player_max_speed_up = 0; - if(m_privs.count("fast") != 0){ - // Fast speed - player_max_speed = BS * 20; - player_max_speed_up = BS * 20; - } else { - // Normal speed - player_max_speed = BS * 4.0; - player_max_speed_up = BS * 4.0; - } - // Tolerance - player_max_speed *= 2.5; - player_max_speed_up *= 2.5; - - m_last_good_position_age += dtime; - if(m_last_good_position_age >= 1.0){ - float age = m_last_good_position_age; - v3f diff = (m_player->getPosition() - m_last_good_position); - float d_vert = diff.Y; - diff.Y = 0; - float d_horiz = diff.getLength(); - /*infostream<getName()<<"'s horizontal speed is " - <<(d_horiz/age)<getPosition(); - } else { - actionstream<<"Player "<getName() - <<" moved too fast; resetting position" - <setPosition(m_last_good_position); - m_moved = true; - } - m_last_good_position_age = 0; - } - } - } if(send_recommended == false) return; @@ -1196,6 +1184,14 @@ void PlayerSAO::step(float dtime, bool send_recommended) m_messages_out.push_back(aom); } + if(m_physics_override_sent == false){ + 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); + // create message and add to list + ActiveObjectMessage aom(getId(), true, str); + m_messages_out.push_back(aom); + } + if(m_animation_sent == false){ m_animation_sent = true; std::string str = gob_cmd_update_animation(m_animation_range, m_animation_speed, m_animation_blend); @@ -1237,7 +1233,6 @@ void PlayerSAO::setPos(v3f pos) m_player->setPosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; - m_last_good_position_age = 0; // Force position change on client m_moved = true; } @@ -1249,7 +1244,6 @@ void PlayerSAO::moveTo(v3f pos, bool continuous) m_player->setPosition(pos); // Movement caused by this command is always valid m_last_good_position = pos; - m_last_good_position_age = 0; // Force position change on client m_moved = true; } @@ -1294,20 +1288,17 @@ int PlayerSAO::punch(v3f dir, HitParams hitparams = getHitParams(m_armor_groups, toolcap, time_from_last_punch); + std::string punchername = "nil"; + + if ( puncher != 0 ) + punchername = puncher->getDescription(); + actionstream<<"Player "<getName()<<" punched by " - <getDescription()<<", damage "<hp; } +s16 PlayerSAO::readDamage() +{ + s16 damage = m_damage; + m_damage = 0; + return damage; +} + void PlayerSAO::setHP(s16 hp) { s16 oldhp = m_player->hp; @@ -1337,19 +1335,25 @@ void PlayerSAO::setHP(s16 hp) m_player->hp = hp; - if(hp != oldhp) + if(hp != oldhp) { m_hp_not_sent = true; + if(oldhp > hp) + m_damage += oldhp - hp; + } - // On death or reincarnation send an active object message + // Update properties on death if((hp == 0) != (oldhp == 0)) - { - // Will send new is_visible value based on (getHP()!=0) m_properties_sent = false; - // Send new HP - std::string str = gob_cmd_punched(0, getHP()); - ActiveObjectMessage aom(getId(), true, str); - m_messages_out.push_back(aom); - } +} + +u16 PlayerSAO::getBreath() const +{ + return m_player->getBreath(); +} + +void PlayerSAO::setBreath(u16 breath) +{ + m_player->setBreath(breath); } void PlayerSAO::setArmorGroups(const ItemGroupList &armor_groups) @@ -1458,7 +1462,73 @@ std::string PlayerSAO::getPropertyPacket() return gob_cmd_set_properties(m_prop); } +bool PlayerSAO::checkMovementCheat() +{ + bool cheated = false; + if(isAttached() || m_is_singleplayer || + g_settings->getBool("disable_anticheat")) + { + m_last_good_position = m_player->getPosition(); + } + else + { + /* + Check player movements + + NOTE: Actually the server should handle player physics like the + client does and compare player's position to what is calculated + on our side. This is required when eg. players fly due to an + explosion. Altough a node-based alternative might be possible + too, and much more lightweight. + */ + + float player_max_speed = 0; + float player_max_speed_up = 0; + if(m_privs.count("fast") != 0){ + // Fast speed + player_max_speed = m_player->movement_speed_fast; + player_max_speed_up = m_player->movement_speed_fast; + } else { + // Normal speed + player_max_speed = m_player->movement_speed_walk; + player_max_speed_up = m_player->movement_speed_walk; + } + // Tolerance. With the lag pool we shouldn't need it. + //player_max_speed *= 2.5; + //player_max_speed_up *= 2.5; + + v3f diff = (m_player->getPosition() - m_last_good_position); + float d_vert = diff.Y; + diff.Y = 0; + float d_horiz = diff.getLength(); + float required_time = d_horiz/player_max_speed; + if(d_vert > 0 && d_vert/player_max_speed > required_time) + required_time = d_vert/player_max_speed; + if(m_move_pool.grab(required_time)){ + m_last_good_position = m_player->getPosition(); + } else { + actionstream<<"Player "<getName() + <<" moved too fast; resetting position" + <setPosition(m_last_good_position); + m_moved = true; + cheated = true; + } + } + return cheated; +} + bool PlayerSAO::getCollisionBox(aabb3f *toset) { - //player collision handling is already done clientside no need to do it twice - return false; + //update collision box + *toset = m_player->getCollisionbox(); + + toset->MinEdge += m_base_position; + toset->MaxEdge += m_base_position; + + return true; } + +bool PlayerSAO::collideWithObjects(){ + return true; +} +