Вопрос How to make resolver better?

Начинающий
Статус
Оффлайн
Регистрация
11 Сен 2024
Сообщения
14
Реакции[?]
1
Поинты[?]
1K
resolver.cpp:
#include "Resolver.h"

#include <algorithm>
#include "../../SDK/Interfaces.h"
#include "../../SDK/Misc/CBasePlayer.h"
#include "LagCompensation.h"
#include "../../SDK/Globals.h"
#include "AnimationSystem.h"


#include "../../Utils/Console.h"


CResolver* Resolver = new CResolver;

float CResolver::GetTime() {
    if (!Cheat.LocalPlayer)
        return GlobalVars->curtime;

    return TICKS_TO_TIME(Cheat.LocalPlayer->m_nTickBase());
}

float FindAvgYaw(const std::deque<LagRecord>& records) {
    float sin_sum = 0.f;
    float cos_sum = 0.f;

    for (int i = records.size() - 2; i > records.size() - 6; i--) {
        const LagRecord* record = &records.at(i);
        float eyeYaw = record->m_angEyeAngles.yaw;

        sin_sum += std::sinf(DEG2RAD(eyeYaw));
        cos_sum += std::cosf(DEG2RAD(eyeYaw));
    }

    return RAD2DEG(std::atan2f(sin_sum, cos_sum));
}

void CResolver::Reset(CBasePlayer* pl) {
    if (pl) {
        resolver_data[pl->EntIndex()].reset();
        return;
    }

    for (int i = 0; i < 64; ++i) {
        resolver_data[i].reset();
    }
}

R_PlayerState CResolver::DetectPlayerState(CBasePlayer* player, AnimationLayer* animlayers) {
    if (!(player->m_fFlags() & FL_ONGROUND))
        return R_PlayerState::AIR;

    CCSGOPlayerAnimationState* animstate = player->GetAnimstate();

    if (player->m_vecVelocity().Length2DSqr() > 256.f && animstate->flWalkToRunTransition > 0.8f && animlayers[ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate > 0.0001f)
        return R_PlayerState::MOVING;

    return R_PlayerState::STANDING;
}

R_AntiAimType CResolver::DetectAntiAim(CBasePlayer* player, const std::deque<LagRecord>& records) {
    if (records.size() < 12)
        return R_AntiAimType::NONE;

    int jitteredRecords = 0;
    int staticRecords = 0;
    float avgDelta = 0.f;
    float prevEyeYaw = player->m_angEyeAngles().yaw;

    for (int i = records.size() - 2; i > records.size() - 10; i--) {
        const LagRecord* record = &records.at(i);
        float eyeYaw = record->m_angEyeAngles.yaw;

        float delta = std::abs(Math::AngleDiff(eyeYaw, prevEyeYaw));

        avgDelta += delta;

        if (delta > 32.f)
            jitteredRecords++;
        else
            staticRecords++;

        prevEyeYaw = eyeYaw;
    }

    if (jitteredRecords > staticRecords)
        return R_AntiAimType::JITTER;

    if (avgDelta * 0.5f < 30.f)
        return R_AntiAimType::STATIC;

    return R_AntiAimType::UNKNOWN;
}

float ValveAngleDiff(float destAngle, float srcAngle)
{
    float delta;

    delta = fmodf(destAngle - srcAngle, 360.0f);
    if (destAngle > srcAngle)
    {
        if (delta >= 180)
            delta -= 360;
    }
    else
    {
        if (delta <= -180)
            delta += 360;
    }
    return delta;
}


void CResolver::SetupLayer(LagRecord* record, int idx, float delta) {
    CCSGOPlayerAnimationState* animstate = record->player->GetAnimstate();

    QAngle angles = record->player->m_angEyeAngles();

    animstate->flFootYaw = Math::AngleNormalize(angles.yaw + delta);

    Vector vel = record->player->m_vecVelocity();
    float flRawYawIdeal = atan2(-vel.y, -vel.x) * 180.f / M_PI;
    if (flRawYawIdeal < 0)
        flRawYawIdeal += 360;

    animstate->flMoveYaw = Math::AngleNormalize(ValveAngleDiff(flRawYawIdeal, animstate->flFootYaw));
    if (record->prev_record)
        memcpy(record->player->GetAnimlayers(), record->prev_record->animlayers, sizeof(AnimationLayer) * 13);

    animstate->ForceUpdate();
    animstate->Update(angles);

    auto& resolver_layer = record->resolver_data.layers[idx];
    resolver_layer.desync = delta;
    resolver_layer.delta = std::abs(record->animlayers[ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate - record->player->GetAnimlayers()[ANIMATION_LAYER_MOVEMENT_MOVE].m_flPlaybackRate) * 1000.f;

    *animstate = *AnimationSystem->GetUnupdatedAnimstate(record->player->EntIndex());
}

void CResolver::SetupResolverLayers(CBasePlayer* player, LagRecord* record) {
    SetupLayer(record, 0, 0.f);
    SetupLayer(record, 1, record->resolver_data.max_desync_delta);
    SetupLayer(record, 2, -record->resolver_data.max_desync_delta);
    SetupLayer(record, 3, record->resolver_data.max_desync_delta * 0.6f);
    SetupLayer(record, 4, -record->resolver_data.max_desync_delta * 0.6f);
}

void CResolver::DetectFreestand(CBasePlayer* player, LagRecord* record, const std::deque<LagRecord>& records) {
    if (records.size() < 16)
        return;

    Vector eyePos = player->m_vecOrigin() + Vector(0, 0, 64 - player->m_flDuckAmount() * 16.f);

    Vector forward = (Cheat.LocalPlayer->m_vecOrigin() - player->m_vecOrigin()).Q_Normalized();

    float notModifiedYaw = player->m_angEyeAngles().yaw;

    if (record->resolver_data.antiaim_type != R_AntiAimType::STATIC)
        notModifiedYaw = FindAvgYaw(records);

    Vector right = Math::AngleVectors(QAngle(5.f, notModifiedYaw + 90.f, 0));

    Vector negPos = eyePos - right * 23.f;
    Vector posPos = eyePos + right * 23.f;

    CTraceFilterWorldAndPropsOnly filter;
    Ray_t rayNeg(negPos, negPos + forward * 128.f);
    Ray_t rayPos(posPos, posPos + forward * 128.f);
    CGameTrace negTrace, posTrace;

    EngineTrace->TraceRay(rayNeg, MASK_SHOT_HULL | CONTENTS_GRATE, &filter, &negTrace);
    EngineTrace->TraceRay(rayPos, MASK_SHOT_HULL | CONTENTS_GRATE, &filter, &posTrace);

    if (negTrace.startsolid && posTrace.startsolid) {
        record->resolver_data.side = 0;
        record->resolver_data.resolver_type = ResolverType::NONE;
        return;
    }
    else if (negTrace.startsolid) {
        record->resolver_data.side = -1;
        record->resolver_data.resolver_type = ResolverType::FREESTAND;
        return;
    }
    else if (posTrace.startsolid) {
        record->resolver_data.side = 1;
        record->resolver_data.resolver_type = ResolverType::FREESTAND;
        return;
    }

    if (negTrace.fraction == 1.f && posTrace.fraction == 1.f) {
        record->resolver_data.side = 0;
        record->resolver_data.resolver_type = ResolverType::NONE;
        return;
    }
    record->resolver_data.side = negTrace.fraction < posTrace.fraction ? -1 : 1;
    record->resolver_data.resolver_type = ResolverType::FREESTAND;
}

void CResolver::Apply(LagRecord* record) {
    if (record->resolver_data.side != 0) {
        float body_yaw = record->resolver_data.max_desync_delta * record->resolver_data.side;
        auto state = record->player->GetAnimstate();

        state->flFootYaw = Math::AngleNormalize(state->flEyeYaw + body_yaw);
    }
}

void CResolver::Run(CBasePlayer* player, LagRecord* record, std::deque<LagRecord>& records) {
    if (GameRules()->IsFreezePeriod() || player->m_fFlags() & FL_FROZEN || !Cheat.LocalPlayer->IsAlive() || record->shooting)
        return;

    LagRecord* prevRecord = record->prev_record;

    record->resolver_data.max_desync_delta = player->GetMaxDesyncDelta();

    //#ifndef RESOLVER_DEBUG
    if (!record->m_nChokedTicks || player->m_bIsDefusing()) {
        record->resolver_data.side = 0;
        record->resolver_data.resolver_type = ResolverType::NONE;
        return;
    }
    //#endif

    record->resolver_data.player_state = DetectPlayerState(player, record->animlayers);
    record->resolver_data.antiaim_type = DetectAntiAim(player, records);

    SetupResolverLayers(player, record);

    record->resolver_data.resolver_type = ResolverType::NONE;

    float min_delta = 1000.f;
    for (auto& layer : record->resolver_data.layers) {
        if (layer.delta < min_delta) {
            min_delta = layer.delta;
            if (layer.desync != 0.f) {
                record->resolver_data.side = layer.desync < 0.f ? -1 : 1;
                record->resolver_data.resolver_type = ResolverType::ANIM;
            }
        }
    }

    if (min_delta > 10.f)
        record->resolver_data.resolver_type = ResolverType::NONE;

    float vel_sqr = player->m_vecVelocity().LengthSqr();

    if (vel_sqr < 256.f || record->animlayers[ANIMATION_LAYER_MOVEMENT_MOVE].m_flWeight <= 0.f || record->resolver_data.resolver_type == ResolverType::NONE || !(player->m_fFlags() & FL_ONGROUND)) {
        if (record->resolver_data.antiaim_type == R_AntiAimType::JITTER && records.size() > 16) {
            float eyeYaw = player->m_angEyeAngles().yaw;
            float prevEyeYaw = FindAvgYaw(records);
            float delta = Math::AngleDiff(eyeYaw, prevEyeYaw);

            if (delta < 0.f)
                record->resolver_data.side = 1;
            else
                record->resolver_data.side = -1;

            record->resolver_data.resolver_type = ResolverType::LOGIC;
        }
        else {
            DetectFreestand(player, record, records);
        }
    }

    auto res_data = &resolver_data[player->EntIndex()];
    float curtime = GetTime();

    if (record->resolver_data.resolver_type != ResolverType::NONE) {
        res_data->last_resolved = curtime;
        res_data->last_side = record->resolver_data.side;
        res_data->res_type_last = record->resolver_data.resolver_type;
    }
    else {
        record->resolver_data.resolver_type = ResolverType::MEMORY;
        record->resolver_data.side = res_data->last_side;
    }

    if (curtime - res_data->brute_time < 5.f && record->resolver_data.resolver_type != ResolverType::LOGIC) {
        record->resolver_data.side = res_data->brute_side;
        record->resolver_data.resolver_type = ResolverType::BRUTEFORCE;
    }

    if (record->resolver_data.side == 0) {
        record->resolver_data.side = -1;
        record->resolver_data.resolver_type = ResolverType::DEFAULT;
    }

    Apply(record);
}

void CResolver::OnMiss(CBasePlayer* player, LagRecord* record) {
    auto bf_data = &resolver_data[player->EntIndex()];

    if (bf_data->missed_shots % 3 || bf_data->missed_shots == 0)
        bf_data->brute_side = (record->resolver_data.side == 0) ? -1 : -record->resolver_data.side;
    bf_data->brute_time = GetTime();
    bf_data->missed_shots++;
}

void CResolver::OnHit(CBasePlayer* player, LagRecord* record) {
    auto bf_data = &resolver_data[player->EntIndex()];

    bf_data->brute_side = record->resolver_data.side;
    bf_data->brute_time = GetTime();
    bf_data->missed_shots = 0;
}
resolver.h:
#pragma once

#include <deque>

#include "../../SDK/Misc/CBasePlayer.h"

struct LagRecord;

enum class R_PlayerState {
    STANDING,
    MOVING,
    AIR
};

enum class R_AntiAimType {
    NONE,
    STATIC,
    JITTER,
    UNKNOWN,
};

enum class ResolverType {
    NONE,
    FREESTAND,
    LOGIC,
    ANIM,
    BRUTEFORCE,
    MEMORY,
    DEFAULT,
};

struct ResolverLayer_t {
    float desync = 0.f;
    float delta = 0.f;
};

//#define RESOLVER_DEBUG 1

struct ResolverData_t {
    R_PlayerState player_state = R_PlayerState::STANDING;
    R_AntiAimType antiaim_type = R_AntiAimType::UNKNOWN;
    ResolverType resolver_type = ResolverType::NONE;

    ResolverLayer_t layers[5];

    float max_desync_delta = 0.f;
    int side = 0;
};

struct ResolverDataStatic_t {
    int brute_side = 0;
    float brute_time = 0.f;
    float last_resolved = 0.f;
    ResolverType res_type_last = ResolverType::NONE;
    int last_side = 0;
    int missed_shots = 0;

    void reset() {
        last_resolved = 0.f;
        brute_side = 0;
        brute_time = 0.f;
    }
};

class CResolver {
    ResolverDataStatic_t resolver_data[64];

    float GetTime();
public:
    CResolver() {
        for (int i = 0; i < 64; ++i) {
            resolver_data[i].reset();
        }
    }  

    void            Reset(CBasePlayer* pl = nullptr);

    R_PlayerState    DetectPlayerState(CBasePlayer* player, AnimationLayer* animlayers);
    R_AntiAimType    DetectAntiAim(CBasePlayer* player, const std::deque<LagRecord>& records);

    void            SetupLayer(LagRecord* record, int idx, float delta);
    void            SetupResolverLayers(CBasePlayer* player, LagRecord* record);

    void            DetectFreestand(CBasePlayer* player, LagRecord* record, const std::deque<LagRecord>& records);

    void            Apply(LagRecord* record);
    void            Run(CBasePlayer* player, LagRecord* record, std::deque<LagRecord>& records);

    void            OnMiss(CBasePlayer* player, LagRecord* record);
    void            OnHit(CBasePlayer* player, LagRecord* record);
};

extern CResolver* Resolver;
i need help with missing to correction misses
 
Главный модератор
Главный Модератор
Статус
Оффлайн
Регистрация
1 Фев 2020
Сообщения
1,264
Реакции[?]
453
Поинты[?]
92K
C++:
void CResolver::Apply(LagRecord* record) {
    if (record->resolver_data.side != 0) {
        float body_yaw = record->resolver_data.max_desync_delta * record->resolver_data.side;
        auto state = record->player->GetAnimstate();
       
        if (record->resolver_data.antiaim_type == R_AntiAimType::STATIC) // uwukson: we shouldn't use the resolver on the jitter, because it's an animation bug (we'd have to rebuild the animation for that, but that's okay)
            state->flFootYaw = Math::AngleNormalize(state->flEyeYaw + body_yaw);

        state->flMoveYaw = state->flFootYaw; // uwukson: we get the values from flMoveYaw and set them in flFootYaw, and now we update the values in flMoveYaw
    }
}
 
Сверху Снизу