-
Автор темы
- #1
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Hello everyone. I wanted to release the resolver I've been working on for the past 4 days. I release it because I really don't care much about it. It includes lkfakof bruteforce and some random meme resolver. If you want to improve it feel free. I put no reactions on this because I think it makes 0 sense to do so.
Resolver.cpp:
Animation.cpp:
Animation.h:
Resolver.cpp:
C++:
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
#include "animation_system.h"
#include "..\ragebot\aim.h"
void resolver::initialize(player_t* e, adjust_data* record, const float& goal_feet_yaw, const float& pitch)
{
player = e;
player_record = record;
original_goal_feet_yaw = math::normalize_yaw(goal_feet_yaw);
original_pitch = math::normalize_pitch(pitch);
}
void resolver::reset()
{
player = nullptr;
player_record = nullptr;
side = false;
fake = false;
was_first_bruteforce = false;
was_second_bruteforce = false;
original_goal_feet_yaw = 0.0f;
original_pitch = 0.0f;
}
float flAngleMod(float flAngle)
{
return((360.0f / 65536.0f) * ((int32_t)(flAngle * (65536.0f / 360.0f)) & 65535));
}
float ApproachAngle(float flTarget, float flValue, float flSpeed)
{
flTarget = flAngleMod(flTarget);
flValue = flAngleMod(flValue);
float delta = flTarget - flValue;
if (flSpeed < 0)
flSpeed = -flSpeed;
if (delta < -180)
delta += 360;
else if (delta > 180)
delta -= 360;
if (delta > flSpeed)
flValue += flSpeed;
else if (delta < -flSpeed)
flValue -= flSpeed;
else
flValue = flTarget;
return flValue;
}
static auto GetSmoothedVelocity = [](float min_delta, Vector a, Vector b) {
Vector delta = a - b;
float delta_length = delta.Length();
if (delta_length <= min_delta) {
Vector result;
if (-min_delta <= delta_length) {
return a;
}
else {
float iradius = 1.0f / (delta_length + FLT_EPSILON);
return b - ((delta * iradius) * min_delta);
}
}
else {
float iradius = 1.0f / (delta_length + FLT_EPSILON);
return b + ((delta * iradius) * min_delta);
}
};
void resolver::resolve(player_t* player)
{
if (!player || !player->get_animation_state())
return;
auto animState = player->get_animation_state();
if (!animState)
return;
Vector velocity = player->m_vecVelocity();
float spd = velocity.LengthSqr();
if (spd > std::powf(1.2f * 260.0f, 2.f)) {
Vector velocity_normalized = velocity.Normalized();
velocity = velocity_normalized * (1.2f * 260.0f);
}
float Resolveyaw = animState->m_flGoalFeetYaw;
auto delta_time
= fmaxf(m_globals()->m_curtime - animState->m_flLastClientSideAnimationUpdateTime, 0.f);
float deltatime = fabs(delta_time);
float stop_to_full_running_fraction = 0.f;
bool is_standing = true;
float v25 = std::clamp(player->m_flDuckAmount() + animState->m_fLandingDuckAdditiveSomething, 0.0f, 1.0f);
float v26 = animState->m_fDuckAmount;
float v27 = deltatime * 6.0f;
float v28;
// clamp
if ((v25 - v26) <= v27) {
if (-v27 <= (v25 - v26))
v28 = v25;
else
v28 = v26 - v27;
}
else {
v28 = v26 + v27;
}
float flDuckAmount = std::clamp(v28, 0.0f, 1.0f);
Vector animationVelocity = velocity;
float speed = std::fminf(animationVelocity.Length(), 260.0f);
auto weapon = player->m_hActiveWeapon().Get();
if (!weapon)
return;
auto wpndata = weapon->get_csweapon_info();
if (!wpndata)
return;
float flMaxMovementSpeed = 260.0f;
if (weapon) {
flMaxMovementSpeed = std::fmaxf(wpndata->flMaxPlayerSpeed, 0.001f);
}
float flRunningSpeed = speed / (flMaxMovementSpeed * 0.520f);
float flDuckingSpeed_2 = speed / (flMaxMovementSpeed * 0.340f);
flRunningSpeed = std::clamp(flRunningSpeed, 0.0f, 1.0f);
float flYawModifier = (((stop_to_full_running_fraction * -0.3f) - 0.2f) * flRunningSpeed) + 1.0f;
if (flDuckAmount > 0.0f) {
float flDuckingSpeed = std::clamp(flDuckingSpeed_2, 0.0f, 1.0f);
flYawModifier += (flDuckAmount * flDuckingSpeed) * (0.5f - flYawModifier);
}
float flMaxBodyYaw = *reinterpret_cast<float*>(&animState->pad10[512]);
float flMinBodyYaw = *reinterpret_cast<float*>(&animState->pad10[516]);
float flEyeYaw = player->m_angEyeAngles().y;
float flEyeDiff = std::remainderf(flEyeYaw - Resolveyaw, 360.f);
if (flEyeDiff <= flMaxBodyYaw) {
if (flMinBodyYaw > flEyeDiff)
Resolveyaw = fabs(flMinBodyYaw) + flEyeYaw;
}
else {
Resolveyaw = flEyeYaw - fabs(flMaxBodyYaw);
}
if (speed > 0.1f || fabs(velocity.z) > 100.0f) {
Resolveyaw = ApproachAngle(
flEyeYaw,
Resolveyaw,
((stop_to_full_running_fraction * 20.0f) + 30.0f)
* deltatime);
}
else {
Resolveyaw = ApproachAngle(
player->m_flLowerBodyYawTarget(),
Resolveyaw,
deltatime * 100.0f);
}
if (stop_to_full_running_fraction > 0.0 && stop_to_full_running_fraction < 1.0)
{
const auto interval = m_globals()->m_intervalpertick * 2.f;
if (is_standing)
stop_to_full_running_fraction = stop_to_full_running_fraction - interval;
else
stop_to_full_running_fraction = interval + stop_to_full_running_fraction;
stop_to_full_running_fraction = std::clamp(stop_to_full_running_fraction, 0.f, 1.f);
}
if (speed > 135.2f && is_standing)
{
stop_to_full_running_fraction = fmaxf(stop_to_full_running_fraction, .0099999998f);
is_standing = false;
}
if (speed < 135.2f && !is_standing)
{
stop_to_full_running_fraction = fminf(stop_to_full_running_fraction, .99000001f);
is_standing = true;
}
float Left = flEyeYaw + flMinBodyYaw;
float Right = flEyeYaw + flMaxBodyYaw;
float brute_yaw = Resolveyaw;
brute_yaw = std::remainderf(brute_yaw, 360.f);
switch (g_ctx.globals.missed_shots[player->EntIndex()] % 3)
{
case 0:
player->get_animation_state()->m_flGoalFeetYaw = Left;
break;
case 1:
player->get_animation_state()->m_flGoalFeetYaw = brute_yaw;
break;
case 2:
player->get_animation_state()->m_flGoalFeetYaw = Right;
break;
default:
break;
}
}
float resolver::resolve_pitch()
{
return original_pitch;
}
C++:
// This is an independent project of an individual developer. Dear PVS-Studio, please check it.
// PVS-Studio Static Code Analyzer for C, C++, C#, and Java: http://www.viva64.com
#include "animation_system.h"
#include "..\misc\misc.h"
#include "..\misc\logs.h"
std::deque <adjust_data> player_records[65];
void lagcompensation::fsn(ClientFrameStage_t stage)
{
if (stage != FRAME_NET_UPDATE_END)
return;
if (!g_cfg.ragebot.enable && !g_cfg.legitbot.enabled)
return;
for (auto i = 1; i < m_globals()->m_maxclients; i++) //-V807
{
auto e = static_cast<player_t*>(m_entitylist()->GetClientEntity(i));
if (e == g_ctx.local())
continue;
if (!valid(i, e))
continue;
auto time_delta = abs(TIME_TO_TICKS(e->m_flSimulationTime()) - m_globals()->m_tickcount);
if (time_delta > 1.0f / m_globals()->m_intervalpertick)
continue;
auto update = player_records[i].empty() || e->m_flSimulationTime() != e->m_flOldSimulationTime(); //-V550
if (update && !player_records[i].empty())
{
auto server_tick = m_clientstate()->m_iServerTick - i % m_globals()->m_timestamprandomizewindow;
auto current_tick = server_tick - server_tick % m_globals()->m_timestampnetworkingbase;
if (TIME_TO_TICKS(e->m_flOldSimulationTime()) < current_tick && TIME_TO_TICKS(e->m_flSimulationTime()) == current_tick)
{
auto layer = &e->get_animlayers()[11];
auto previous_layer = &player_records[i].front().layers[11];
if (layer->m_flCycle == previous_layer->m_flCycle) //-V550
{
e->m_flSimulationTime() = e->m_flOldSimulationTime();
update = false;
}
}
}
if (update) //-V550
{
if (!player_records[i].empty() && (e->m_vecOrigin() - player_records[i].front().origin).LengthSqr() > 4096.0f)
for (auto& record : player_records[i])
record.invalid = true;
player_records[i].emplace_front(adjust_data());
update_player_animations(e);
while (player_records[i].size() > 32)
player_records[i].pop_back();
}
}
}
bool lagcompensation::valid(int i, player_t* e)
{
if (!g_cfg.ragebot.enable && !g_cfg.legitbot.enabled || !e->valid(false))
{
if (!e->is_alive())
{
is_dormant[i] = false;
player_resolver[i].reset();
g_ctx.globals.fired_shots[i] = 0;
g_ctx.globals.missed_shots[i] = 0;
}
else if (e->IsDormant())
is_dormant[i] = true;
player_records[i].clear();
return false;
}
return true;
}
void lagcompensation::update_player_animations(player_t* e)
{
auto animstate = e->get_animation_state();
if (!animstate)
return;
player_info_t player_info;
if (!m_engine()->GetPlayerInfo(e->EntIndex(), &player_info))
return;
auto records = &player_records[e->EntIndex()]; //-V826
if (records->empty())
return;
adjust_data* previous_record = nullptr;
if (records->size() >= 2)
previous_record = &records->at(1);
auto record = &records->front();
AnimationLayer animlayers[15];
memcpy(animlayers, e->get_animlayers(), e->animlayer_count() * sizeof(AnimationLayer));
memcpy(record->layers, animlayers, e->animlayer_count() * sizeof(AnimationLayer));
auto backup_lower_body_yaw_target = e->m_flLowerBodyYawTarget();
auto backup_duck_amount = e->m_flDuckAmount();
auto backup_flags = e->m_fFlags();
auto backup_eflags = e->m_iEFlags();
auto backup_curtime = m_globals()->m_curtime; //-V807
auto backup_frametime = m_globals()->m_frametime;
auto backup_realtime = m_globals()->m_realtime;
auto backup_framecount = m_globals()->m_framecount;
auto backup_tickcount = m_globals()->m_tickcount;
auto backup_interpolation_amount = m_globals()->m_interpolation_amount;
m_globals()->m_curtime = e->m_flSimulationTime();
m_globals()->m_frametime = m_globals()->m_intervalpertick;
if (previous_record)
{
auto velocity = e->m_vecVelocity();
auto was_in_air = e->m_fFlags() & FL_ONGROUND && previous_record->flags & FL_ONGROUND;
auto time_difference = max(m_globals()->m_intervalpertick, e->m_flSimulationTime() - previous_record->simulation_time);
auto origin_delta = e->m_vecOrigin() - previous_record->origin;
auto animation_speed = 0.0f;
if (!origin_delta.IsZero() && TIME_TO_TICKS(time_difference) > 0)
{
e->m_vecVelocity() = origin_delta * (1.0f / time_difference);
if (e->m_fFlags() & FL_ONGROUND && animlayers[11].m_flWeight > 0.0f && animlayers[11].m_flWeight < 1.0f && animlayers[11].m_flCycle > previous_record->layers[11].m_flCycle)
{
auto weapon = e->m_hActiveWeapon().Get();
if (weapon)
{
auto max_speed = 260.0f;
auto weapon_info = e->m_hActiveWeapon().Get()->get_csweapon_info();
if (weapon_info)
max_speed = e->m_bIsScoped() ? weapon_info->flMaxPlayerSpeedAlt : weapon_info->flMaxPlayerSpeed;
auto modifier = 0.35f * (1.0f - animlayers[11].m_flWeight);
if (modifier > 0.0f && modifier < 1.0f)
animation_speed = max_speed * (modifier + 0.55f);
}
}
if (animation_speed > 0.0f)
{
animation_speed /= e->m_vecVelocity().Length2D();
e->m_vecVelocity().x *= animation_speed;
e->m_vecVelocity().y *= animation_speed;
}
if (records->size() >= 3 && time_difference > m_globals()->m_intervalpertick)
{
auto previous_velocity = (previous_record->origin - records->at(2).origin) * (1.0f / time_difference);
if (!previous_velocity.IsZero() && !was_in_air)
{
auto current_direction = math::normalize_yaw(RAD2DEG(atan2(e->m_vecVelocity().y, e->m_vecVelocity().x)));
auto previous_direction = math::normalize_yaw(RAD2DEG(atan2(previous_velocity.y, previous_velocity.x)));
auto average_direction = current_direction - previous_direction;
average_direction = DEG2RAD(math::normalize_yaw(current_direction + average_direction * 0.5f));
auto direction_cos = cos(average_direction);
auto dirrection_sin = sin(average_direction);
auto velocity_speed = e->m_vecVelocity().Length2D();
e->m_vecVelocity().x = direction_cos * velocity_speed;
e->m_vecVelocity().y = dirrection_sin * velocity_speed;
}
}
if (!(e->m_fFlags() & FL_ONGROUND))
{
static auto sv_gravity = m_cvar()->FindVar(crypt_str("sv_gravity"));
auto fixed_timing = math::clamp(time_difference, m_globals()->m_intervalpertick, 1.0f);
e->m_vecVelocity().z -= sv_gravity->GetFloat() * fixed_timing * 0.5f;
}
else
e->m_vecVelocity().z = 0.0f;
}
}
e->m_iEFlags() &= ~0x1800;
if (e->m_fFlags() & FL_ONGROUND && e->m_vecVelocity().Length() > 0.0f && animlayers[6].m_flWeight <= 0.0f)
e->m_vecVelocity().Zero();
e->m_vecAbsVelocity() = e->m_vecVelocity();
e->m_bClientSideAnimation() = true;
if (is_dormant[e->EntIndex()])
{
is_dormant[e->EntIndex()] = false;
if (e->m_fFlags() & FL_ONGROUND)
{
animstate->m_bOnGround = true;
animstate->m_bInHitGroundAnimation = false;
}
animstate->time_since_in_air() = 0.0f;
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y);
}
auto updated_animations = false;
c_baseplayeranimationstate state;
memcpy(&state, animstate, sizeof(c_baseplayeranimationstate));
if (previous_record)
{
memcpy(e->get_animlayers(), previous_record->layers, e->animlayer_count() * sizeof(AnimationLayer));
auto ticks_chocked = 1;
auto simulation_ticks = TIME_TO_TICKS(e->m_flSimulationTime() - previous_record->simulation_time);
if (simulation_ticks > 0 && simulation_ticks < 31)
ticks_chocked = simulation_ticks;
if (ticks_chocked > 1)
{
auto land_time = 0.0f;
auto land_in_cycle = false;
auto is_landed = false;
auto on_ground = false;
if (animlayers[4].m_flCycle < 0.5f && (!(e->m_fFlags() & FL_ONGROUND) || !(previous_record->flags & FL_ONGROUND)))
{
land_time = e->m_flSimulationTime() - animlayers[4].m_flPlaybackRate * animlayers[4].m_flCycle;
land_in_cycle = land_time >= previous_record->simulation_time;
}
auto duck_amount_per_tick = (e->m_flDuckAmount() - previous_record->duck_amount) / ticks_chocked;
for (auto i = 0; i < ticks_chocked; ++i)
{
auto lby_delta = fabs(math::normalize_yaw(e->m_flLowerBodyYawTarget() - previous_record->lby));
if (lby_delta > 0.0f && e->m_vecVelocity().Length() < 5.0f)
{
auto delta = ticks_chocked - i;
auto use_new_lby = true;
if (lby_delta < 1.0f)
use_new_lby = !delta; //-V547
else
use_new_lby = delta < 2;
e->m_flLowerBodyYawTarget() = use_new_lby ? backup_lower_body_yaw_target : previous_record->lby;
}
auto simulated_time = previous_record->simulation_time + TICKS_TO_TIME(i);
if (duck_amount_per_tick) //-V550
e->m_flDuckAmount() = previous_record->duck_amount + duck_amount_per_tick * (float)i;
on_ground = e->m_fFlags() & FL_ONGROUND;
if (land_in_cycle && !is_landed)
{
if (land_time <= simulated_time)
{
is_landed = true;
on_ground = true;
}
else
on_ground = previous_record->flags & FL_ONGROUND;
}
if (on_ground)
e->m_fFlags() |= FL_ONGROUND;
else
e->m_fFlags() &= ~FL_ONGROUND;
auto simulated_ticks = TIME_TO_TICKS(simulated_time);
m_globals()->m_realtime = simulated_time;
m_globals()->m_curtime = simulated_time;
m_globals()->m_framecount = simulated_ticks;
m_globals()->m_tickcount = simulated_ticks;
m_globals()->m_interpolation_amount = 0.0f;
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
m_globals()->m_realtime = backup_realtime;
m_globals()->m_curtime = backup_curtime;
m_globals()->m_framecount = backup_framecount;
m_globals()->m_tickcount = backup_tickcount;
m_globals()->m_interpolation_amount = backup_interpolation_amount;
updated_animations = true;
}
}
}
if (!updated_animations)
{
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
}
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
auto setup_matrix = [&](player_t* e, AnimationLayer* layers, const int& matrix) -> void
{
e->invalidate_physics_recursive(8);
AnimationLayer backup_layers[15];
memcpy(backup_layers, e->get_animlayers(), e->animlayer_count() * sizeof(AnimationLayer));
memcpy(e->get_animlayers(), layers, e->animlayer_count() * sizeof(AnimationLayer));
switch (matrix)
{
case MAIN:
e->setup_bones_fixed(record->matrixes_data.main, BONE_USED_BY_ANYTHING);
break;
case NONE:
e->setup_bones_fixed(record->matrixes_data.zero, BONE_USED_BY_HITBOX);
break;
case FIRST:
e->setup_bones_fixed(record->matrixes_data.first, BONE_USED_BY_HITBOX);
break;
case SECOND:
e->setup_bones_fixed(record->matrixes_data.second, BONE_USED_BY_HITBOX);
break;
}
memcpy(e->get_animlayers(), backup_layers, e->animlayer_count() * sizeof(AnimationLayer));
};
#if RELEASE
if (!player_info.fakeplayer && g_ctx.local()->is_alive() && e->m_iTeamNum() != g_ctx.local()->m_iTeamNum() && !g_cfg.legitbot.enabled) //-V807
#else
if (g_ctx.local()->is_alive() && e->m_iTeamNum() != g_ctx.local()->m_iTeamNum() && !g_cfg.legitbot.enabled)
#endif
{
animstate->m_flGoalFeetYaw = previous_goal_feet_yaw[e->EntIndex()]; //-V807
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
previous_goal_feet_yaw[e->EntIndex()] = animstate->m_flGoalFeetYaw;
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y); //-V807
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, NONE);
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y + 60.0f);
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, FIRST);
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y - 60.0f);
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, SECOND);
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
player_resolver[e->EntIndex()].initialize(e, record, previous_goal_feet_yaw[e->EntIndex()], e->m_angEyeAngles().x);
if (g_cfg.player_list.low_delta[e->EntIndex()])
{
switch (record->side)
{
case RESOLVER_FIRST:
record->side = RESOLVER_LOW_FIRST;
break;
case RESOLVER_SECOND:
record->side = RESOLVER_LOW_SECOND;
break;
case RESOLVER_LOW_FIRST:
record->side = RESOLVER_FIRST;
break;
case RESOLVER_LOW_SECOND:
record->side = RESOLVER_SECOND;
break;
}
}
switch (record->side)
{
case RESOLVER_ORIGINAL:
animstate->m_flGoalFeetYaw = previous_goal_feet_yaw[e->EntIndex()];
break;
case RESOLVER_ZERO:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y);
break;
case RESOLVER_FIRST:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y + 60.0f);
break;
case RESOLVER_SECOND:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y - 60.0f);
break;
case RESOLVER_LOW_FIRST:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y + 30.0f);
break;
case RESOLVER_LOW_SECOND:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y - 30.0f);
break;
}
e->m_angEyeAngles().x = player_resolver[e->EntIndex()].resolve_pitch();
}
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, MAIN);
memcpy(e->m_CachedBoneData().Base(), record->matrixes_data.main, e->m_CachedBoneData().Count() * sizeof(matrix3x4_t));
m_globals()->m_curtime = backup_curtime;
m_globals()->m_frametime = backup_frametime;
e->m_flLowerBodyYawTarget() = backup_lower_body_yaw_target;
e->m_flDuckAmount() = backup_duck_amount;
e->m_fFlags() = backup_flags;
e->m_iEFlags() = backup_eflags;
memcpy(e->get_animlayers(), animlayers, e->animlayer_count() * sizeof(AnimationLayer));
record->store_data(e, false);
if (e->m_flSimulationTime() < e->m_flOldSimulationTime())
record->invalid = true;
}
C++:
#pragma once
#include "..\..\includes.hpp"
#include "..\..\sdk\structs.hpp"
enum
{
MAIN,
NONE,
FIRST,
SECOND
};
enum resolver_type
{
ORIGINAL,
BRUTEFORCE,
LBY,
TRACE,
DIRECTIONAL
};
enum resolver_side
{
RESOLVER_ORIGINAL,
RESOLVER_ZERO,
RESOLVER_FIRST,
RESOLVER_SECOND,
RESOLVER_LOW_FIRST,
RESOLVER_LOW_SECOND
};
struct matrixes
{
matrix3x4_t main[MAXSTUDIOBONES];
matrix3x4_t zero[MAXSTUDIOBONES];
matrix3x4_t first[MAXSTUDIOBONES];
matrix3x4_t second[MAXSTUDIOBONES];
};
class adjust_data;
class resolver
{
player_t* player = nullptr;
adjust_data* player_record = nullptr;
bool side = false;
bool fake = false;
bool was_first_bruteforce = false;
bool was_second_bruteforce = false;
float lock_side = 0.0f;
float original_goal_feet_yaw = 0.0f;
float original_pitch = 0.0f;
float resolve_way = 0.0f;
int FreestandSide[64];
public:
void initialize(player_t* e, adjust_data* record, const float& goal_feet_yaw, const float& pitch);
float GetAngle(player_t* e);
void reset();
void resolve(player_t* player);
float resolve_pitch();
void resolve_yaw();
void Resolver_meme(player_t* entity);
resolver_side last_side = RESOLVER_ORIGINAL;
};
class adjust_data //-V730
{
public:
player_t* player;
int i;
AnimationLayer layers[15];
matrixes matrixes_data;
resolver_type type;
resolver_side side;
bool invalid;
bool immune;
bool dormant;
bool bot;
int flags;
int bone_count;
float simulation_time;
float duck_amount;
float lby;
Vector angles;
Vector abs_angles;
Vector velocity;
Vector origin;
Vector mins;
Vector maxs;
adjust_data() //-V730
{
reset();
}
void reset()
{
player = nullptr;
i = -1;
type = ORIGINAL;
side = RESOLVER_ORIGINAL;
invalid = false;
immune = false;
dormant = false;
bot = false;
flags = 0;
bone_count = 0;
simulation_time = 0.0f;
duck_amount = 0.0f;
lby = 0.0f;
angles.Zero();
abs_angles.Zero();
velocity.Zero();
origin.Zero();
mins.Zero();
maxs.Zero();
}
adjust_data(player_t* e, bool store = true)
{
type = ORIGINAL;
side = RESOLVER_ORIGINAL;
invalid = false;
store_data(e, store);
}
void store_data(player_t* e, bool store = true)
{
if (!e->is_alive())
return;
player = e;
i = player->EntIndex();
if (store)
{
memcpy(layers, e->get_animlayers(), e->animlayer_count() * sizeof(AnimationLayer));
memcpy(matrixes_data.main, player->m_CachedBoneData().Base(), player->m_CachedBoneData().Count() * sizeof(matrix3x4_t));
}
immune = player->m_bGunGameImmunity() || player->m_fFlags() & FL_FROZEN;
dormant = player->IsDormant();
#if RELEASE
player_info_t player_info;
m_engine()->GetPlayerInfo(i, &player_info);
bot = player_info.fakeplayer;
#else
bot = false;
#endif
flags = player->m_fFlags();
bone_count = player->m_CachedBoneData().Count();
simulation_time = player->m_flSimulationTime();
duck_amount = player->m_flDuckAmount();
lby = player->m_flLowerBodyYawTarget();
angles = player->m_angEyeAngles();
abs_angles = player->GetAbsAngles();
velocity = player->m_vecVelocity();
origin = player->m_vecOrigin();
mins = player->GetCollideable()->OBBMins();
maxs = player->GetCollideable()->OBBMaxs();
}
void adjust_player()
{
if (!valid(false))
return;
memcpy(player->get_animlayers(), layers, player->animlayer_count() * sizeof(AnimationLayer));
memcpy(player->m_CachedBoneData().Base(), matrixes_data.main, player->m_CachedBoneData().Count() * sizeof(matrix3x4_t)); //-V807
player->m_fFlags() = flags;
player->m_CachedBoneData().m_Size = bone_count;
player->m_flSimulationTime() = simulation_time;
player->m_flDuckAmount() = duck_amount;
player->m_flLowerBodyYawTarget() = lby;
player->m_angEyeAngles() = angles;
player->set_abs_angles(abs_angles);
player->m_vecVelocity() = velocity;
player->m_vecOrigin() = origin;
player->set_abs_origin(origin);
player->GetCollideable()->OBBMins() = mins;
player->GetCollideable()->OBBMaxs() = maxs;
}
bool valid(bool extra_checks = true)
{
if (!this) //-V704
return false;
if (i > 0)
player = (player_t*)m_entitylist()->GetClientEntity(i);
if (!player)
return false;
if (player->m_lifeState() != LIFE_ALIVE)
return false;
if (immune)
return false;
if (dormant)
return false;
if (!extra_checks)
return true;
if (invalid)
return false;
auto net_channel_info = m_engine()->GetNetChannelInfo();
if (!net_channel_info)
return false;
static auto sv_maxunlag = m_cvar()->FindVar(crypt_str("sv_maxunlag"));
auto outgoing = net_channel_info->GetLatency(FLOW_OUTGOING);
auto incoming = net_channel_info->GetLatency(FLOW_INCOMING);
auto correct = math::clamp(outgoing + incoming + util::get_interpolation(), 0.0f, sv_maxunlag->GetFloat());
auto curtime = g_ctx.local()->is_alive() ? TICKS_TO_TIME(g_ctx.globals.fixed_tickbase) : m_globals()->m_curtime; //-V807
auto delta_time = correct - (curtime - simulation_time);
if (fabs(delta_time) > 0.2f)
return false;
auto extra_choke = 0;
if (g_ctx.globals.fakeducking)
extra_choke = 14 - m_clientstate()->iChokedCommands;
auto server_tickcount = extra_choke + m_globals()->m_tickcount + TIME_TO_TICKS(outgoing + incoming);
auto dead_time = (int)(TICKS_TO_TIME(server_tickcount) - sv_maxunlag->GetFloat());
if (simulation_time < (float)dead_time)
return false;
return true;
}
};
class optimized_adjust_data
{
public:
int i;
player_t* player;
float simulation_time;
float duck_amount;
Vector angles;
Vector origin;
optimized_adjust_data() //-V730
{
reset();
}
void reset()
{
i = 0;
player = nullptr;
simulation_time = 0.0f;
duck_amount = 0.0f;
angles.Zero();
origin.Zero();
}
};
extern std::deque <adjust_data> player_records[65];
class lagcompensation : public singleton <lagcompensation>
{
public:
void fsn(ClientFrameStage_t stage);
bool valid(int i, player_t* e);
void update_player_animations(player_t* e);
resolver player_resolver[65];
bool is_dormant[65];
float previous_goal_feet_yaw[65];
};