Вопрос Сохранение информации об игроке

Начинающий
Статус
Оффлайн
Регистрация
8 Апр 2021
Сообщения
9
Реакции[?]
1
Поинты[?]
0
Привет всем. Надеюсь получу ответ на свой вопрос.
Как сделать сохранение информации о том, что я заресольвил соперника и чтобы чит больше его не ресольвил, а стрелял как запомнил?

К примеру возьмём любой код рандом ресольвера с инета:
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"
float EyeAngles[64] = { 0 };

float GetBackwardYaw(player_t* player)
{
    return math::calculate_angle(g_ctx.local()->GetAbsOrigin(), player->GetAbsOrigin()).y;
}

int DetectStand(player_t* player)
{
    Vector src3D, dst3D, forward, right, up, src, dst;
    float back_two, right_two, left_two;
    trace_t tr;
    Ray_t ray, ray2, ray3, ray4, ray5;
    CTraceFilter filter;

    math::angle_vectors(Vector(0, GetBackwardYaw(player), 0), &forward, &right, &up);

    filter.pSkip = player;
    src3D = player->get_shoot_position();
    dst3D = src3D + (forward * 384); //Might want to experiment with other numbers, incase you don't know what the number does, its how far the trace will go. Lower = shorter.

    ray.Init(src3D, dst3D);
    m_trace()->TraceRay(ray, MASK_SHOT, &filter, &tr);
    back_two = (tr.endpos - tr.startpos).Length();

    ray2.Init(src3D + right * 30, dst3D + right * 30);
    m_trace()->TraceRay(ray2, MASK_SHOT, &filter, &tr);
    right_two = (tr.endpos - tr.startpos).Length();

    ray3.Init(src3D - right * 30, dst3D - right * 30);
    m_trace()->TraceRay(ray3, MASK_SHOT, &filter, &tr);
    left_two = (tr.endpos - tr.startpos).Length();

    if (left_two > right_two)
        return -1;
    else if (right_two > left_two)
        return 1;
    else
        return 0;
}

float GetForwardYaw(player_t* player)
{
    return math::normalize_yaw(GetBackwardYaw(player) - 180.f);
}

resolver_side resolver::FreeStand(player_t* e)
{

    float angle = math::normalize_yaw(e->m_angEyeAngles().y);

    bool forward = fabsf(math::normalize_yaw(angle - GetForwardYaw(e))) < 90.f;

    auto misses = g_ctx.globals.missed_shots[e->EntIndex()];

    int S = DetectStand(e);

    bool HIGHDELTA = misses >= 3;


    switch (misses % 2)
    {
    case 0:
        switch (last_side)
        {
        case RESOLVER_SECOND:
            return RESOLVER_FIRST;
            break;
        case RESOLVER_FIRST:
            return RESOLVER_SECOND;
            break;
        default:
            if (S == 1)
            {
                if (forward)
                    return RESOLVER_SECOND;
                else
                    return RESOLVER_FIRST;
            }
            else
            {
                if (forward)
                    return RESOLVER_FIRST;
                else
                    return RESOLVER_SECOND;
            }
            break;
        }
        break;
    case 1:
        switch (last_side)
        {
        case RESOLVER_SECOND:
            return RESOLVER_SECOND;
            break;
        case RESOLVER_FIRST:
            return RESOLVER_FIRST;
            break;
        default:
            if (S == 1)
            {
                if (forward)
                    return RESOLVER_FIRST;
                else
                    return RESOLVER_SECOND;
            }
            else
            {
                if (forward)
                    return RESOLVER_SECOND;
                else
                    return RESOLVER_FIRST;
            }
            break;
        }
        break;
    }

}

bool resolver::IsFakewalking(player_t* entity)
{
    bool
        bFakewalking = false,
        stage1 = false,            // stages needed cause we are iterating all layers, eitherwise won't work :)
        stage2 = false,
        stage3 = false;

    for (int i = 0; i < entity->animlayer_count(); i++)
    {
        if (player_record->layers[i].m_nSequence == 26 && player_record->layers[i].m_flWeight < 0.4f)
            stage1 = true;
        if (player_record->layers[i].m_nSequence == 7 && player_record->layers[i].m_flWeight > 0.001f)
            stage2 = true;
        if (player_record->layers[i].m_nSequence == 2 && player_record->layers[i].m_flWeight == 0)
            stage3 = true;
    }

    if (stage1 && stage2)
        bFakewalking = (stage3 || (player->m_fFlags() & FL_DUCKING)); // since weight from stage3 can be 0 aswell when crouching, we need this kind of check, cause you can fakewalk while crouching, thats why it's nested under stage1 and stage2   
    else
        bFakewalking = false;

    return bFakewalking;
}

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;
}

bool CanSeeHitbox(player_t* entity, int HITBOX)
{
    return g_ctx.local()->CanSeePlayer(entity, entity->hitbox_position(HITBOX));
}

struct {
    float movinglby[65];
}records;

bool resolver::Saw(player_t* entity)
{
    if (!(CanSeeHitbox(entity, HITBOX_HEAD) && CanSeeHitbox(entity, HITBOX_LEFT_FOOT) && CanSeeHitbox(entity, HITBOX_RIGHT_FOOT))
        || (CanSeeHitbox(entity, HITBOX_HEAD) && CanSeeHitbox(entity, HITBOX_LEFT_FOOT) && CanSeeHitbox(entity, HITBOX_RIGHT_FOOT)))
        return false;

    return true;
}

resolver_side resolver::TraceSide(player_t* entity)
{
    auto first_visible = util::visible(g_ctx.globals.eye_pos, entity->hitbox_position_matrix(HITBOX_HEAD, player_record->matrixes_data.positive), player, g_ctx.local());
    auto second_visible = util::visible(g_ctx.globals.eye_pos, entity->hitbox_position_matrix(HITBOX_HEAD, player_record->matrixes_data.negative), player, g_ctx.local());
    auto main_visible = util::visible(g_ctx.globals.eye_pos, entity->hitbox_position_matrix(HITBOX_HEAD, player_record->matrixes_data.main), player, g_ctx.local());
    if (main_visible)
    {
        if (first_visible)
            return RESOLVER_SECOND;
        else if (second_visible)
            return  RESOLVER_FIRST;
    }
    else
    {
        if (first_visible)
            return  RESOLVER_FIRST;
        else if (second_visible)
            return  RESOLVER_SECOND;
    }

    return RESOLVER_ORIGINAL;
}

bool ValidPitch(player_t* entity)
{
    int pitch = entity->m_angEyeAngles().x;
    return pitch == 0 || pitch > 90 || pitch < -90;
}

void resolver::NoSpreadResolver()
{
    if (last_side != RESOLVER_ORIGINAL)
    {
        switch (last_side)
        {
        case RESOLVER_ORIGINAL:
            g_ctx.globals.missed_shots[player->EntIndex()] = 0;
            fake = true;
            break;
        case RESOLVER_ZERO:
            player_record->type = BRUTEFORCE;
            player_record->side = RESOLVER_LOW_FIRST;

            was_first_bruteforce = false;
            was_second_bruteforce = false;
            return;
        case RESOLVER_FIRST:
            player_record->type = BRUTEFORCE;
            player_record->side = was_second_bruteforce ? RESOLVER_ZERO : RESOLVER_SECOND;

            was_first_bruteforce = true;
            return;
        case RESOLVER_SECOND:
            player_record->type = BRUTEFORCE;
            player_record->side = was_first_bruteforce ? RESOLVER_ZERO : RESOLVER_FIRST;

            was_second_bruteforce = true;
            return;
        case RESOLVER_LOW_FIRST:
            player_record->type = BRUTEFORCE;
            player_record->side = RESOLVER_LOW_SECOND;
            return;
        case RESOLVER_LOW_SECOND:
            player_record->type = BRUTEFORCE;
            player_record->side = RESOLVER_FIRST;
            return;
        }
    }
    switch (g_ctx.globals.missed_shots[player->EntIndex()])
    {
    case 0:
        player_record->side = RESOLVER_SECOND;
        break;

    case 1:
        player_record->side = RESOLVER_FIRST;
        break;

    case 2:
        player_record->side = RESOLVER_LOW_FIRST;
        break;

    case 3:
        player_record->side = RESOLVER_LOW_SECOND;
        break;

    case 4:
        player_record->side = RESOLVER_FIRST;
        break;

    case 5:
        player_record->side = RESOLVER_SECOND;
        break;
    }
    if (g_ctx.globals.missed_shots[player->EntIndex()] == 5)
        g_ctx.globals.missed_shots[player->EntIndex()] = 0;
}



void resolver::resolve_yaw()
{

    player_info_t player_info;

    if (!m_engine()->GetPlayerInfo(player->EntIndex(), &player_info))
        return;

    if (player_info.fakeplayer || !g_ctx.local()->is_alive() || player->m_iTeamNum() == g_ctx.local()->m_iTeamNum()) //-V807
    {
        player_record->side = RESOLVER_ORIGINAL;
        return;
    }

    if (aim::get().last_target[player->EntIndex()].record.type != LBY)
    {
        switch (last_side)
        {
        case RESOLVER_ORIGINAL:
            g_ctx.globals.missed_shots[player->EntIndex()] = 0;
            fake = true;
            break;
        case RESOLVER_ZERO:
            player_record->type = BRUTEFORCE;
            player_record->side = RESOLVER_LOW_FIRST;

            was_first_bruteforce = false;
            was_second_bruteforce = false;
            return;
        case RESOLVER_FIRST:
            player_record->type = BRUTEFORCE;
            player_record->side = was_second_bruteforce ? RESOLVER_ZERO : RESOLVER_SECOND;

            was_first_bruteforce = true;
            return;
        case RESOLVER_SECOND:
            player_record->type = BRUTEFORCE;
            player_record->side = was_first_bruteforce ? RESOLVER_ZERO : RESOLVER_FIRST;

            was_second_bruteforce = true;
            return;
        case RESOLVER_LOW_FIRST:
            player_record->type = BRUTEFORCE;
            player_record->side = RESOLVER_LOW_SECOND;
            return;
        case RESOLVER_LOW_SECOND:
            player_record->type = BRUTEFORCE;
            player_record->side = RESOLVER_FIRST;
            return;
        }
    }

    auto animstate = player->get_animation_state();

    if (!animstate)
    {
        player_record->side = RESOLVER_ORIGINAL;
        return;
    }

    if (!ValidPitch(player))
    {
        if (g_ctx.globals.missed_shots[player->EntIndex()] == 0)
            player_record->side = RESOLVER_ORIGINAL;
        else
            player_record->side = FreeStand(player);
        return;
    }



    if (fabs(original_pitch) > 90.0f)
        fake = true;
    else if (!fake)
    {
        player_record->side = RESOLVER_ORIGINAL;
        return;
    }

    if (player->m_vecVelocity().Length2D() > 50)
        records.movinglby[player->EntIndex()] = animstate->m_flGoalFeetYaw;


    auto delta = math::normalize_yaw(player->m_angEyeAngles().y - original_goal_feet_yaw);
    auto valid_lby = true;

    if (animstate->m_velocity > 0.1f || fabs(animstate->flUpVelocity) > 100.f)
        valid_lby = animstate->m_flTimeSinceStartedMoving < 0.22f;

    auto spread = m_cvar()->FindVar("weapon_accuracy_nospread")->GetInt();
    if (spread == 1)
    {
        NoSpreadResolver();
        return;
    }

    if (player->m_vecVelocity().Length2D() > 235 || !player->m_fFlags() & FL_ONGROUND)
        player_record->side = RESOLVER_ORIGINAL;
    else if (g_ctx.globals.missed_shots[player->EntIndex()] == 0)
        player_record->side = RESOLVER_SECOND;
    else if (Saw(player))
    {
        if (TraceSide(player) != RESOLVER_ORIGINAL)
            player_record->side = TraceSide(player);
        player_record->type = TRACE;
    }
    else if (fabs(delta) > 30.0f && valid_lby)
    {
        if (g_ctx.globals.missed_shots[player->EntIndex()])
            delta = -delta;

        if (delta > 30.0f)
        {
            player_record->type = LBY;
            player_record->side = RESOLVER_FIRST;
        }
        else if (delta < -30.0f)
        {
            player_record->type = LBY;
            player_record->side = RESOLVER_SECOND;
        }
    }
    else
    {
        auto trace = false;
        if (m_globals()->m_curtime - lock_side > 2.0f)
        {
            auto first_visible = util::visible(g_ctx.globals.eye_pos, player->hitbox_position_matrix(HITBOX_HEAD, player_record->matrixes_data.positive), player, g_ctx.local());
            auto second_visible = util::visible(g_ctx.globals.eye_pos, player->hitbox_position_matrix(HITBOX_HEAD, player_record->matrixes_data.negative), player, g_ctx.local());

            if (first_visible != second_visible)
            {
                trace = true;
                side = second_visible;
                lock_side = m_globals()->m_curtime;
            }
            else
            {
                auto first_position = g_ctx.globals.eye_pos.DistTo(player->hitbox_position_matrix(HITBOX_HEAD, player_record->matrixes_data.positive));
                auto second_position = g_ctx.globals.eye_pos.DistTo(player->hitbox_position_matrix(HITBOX_HEAD, player_record->matrixes_data.negative));

                if (fabs(first_position - second_position) > 1.0f)
                    side = first_position > second_position;
            }
        }
        else
            trace = true;

        if (side)
        {
            player_record->type = trace ? TRACE : DIRECTIONAL;
            player_record->side = RESOLVER_FIRST;
        }
        else
        {
            player_record->type = trace ? TRACE : DIRECTIONAL;
            player_record->side = RESOLVER_SECOND;
        }
    }
}

float resolver::resolve_pitch()
{
    return original_pitch;
}
Есть ли тут код с запоминанием ресольва противника? Если есть, то где? И как это все работает?
 
sapphire dev
Пользователь
Статус
Оффлайн
Регистрация
15 Мар 2018
Сообщения
188
Реакции[?]
124
Поинты[?]
36K
1. Твой код изменяет сайд и тип, которые находятся в рекорде, так что ты уже сохраняешь данные по тому, как ты отресольвил чела.
2. Я хз как и где ты вызываешь этот код, но предполагаю, что в анимфиксе, после чего ты применяешь нужный сайд и сторишь кости. Я бы сделал ресольвер прямо в аиме на рекорд в который ты собираешься стрелять после чего проводил бы манипуляции с ротацией оригинального анимстейта, костей, позов и прочего. Я бы не стал вызывать заного сетап бонес или глупо обновлять анимстейт по нужному сайду. (Это подсказка, как не сломать анимки, а ещё как не убить ФПС, т.к. это будет вызываться каждый тик, ибо это креатмув). После чего уже бы позволял срабатывать аиму.
3. Не юзай этот код, если можешь сделать лучше, он дерьмоват...
чтобы чит больше его не ресольвил, а стрелял как запомнил?
Если у тебя с этим проблема, то советую убедиться, что ресольаер изменяет данные в рекорде до того, как ты начинаешь стрелять в чела.
 
Последнее редактирование:
like amiri in my mind
Пользователь
Статус
Оффлайн
Регистрация
4 Дек 2022
Сообщения
308
Реакции[?]
54
Поинты[?]
1K
просто гфи на след сим тике восстанавливай, который был успешно зарезольвен, сохранить можешь вообще по разному, можешь в рекорд ее сохранить с пометкой resolved допустим и на след вызове сделать
if(prev_record->resolved)
record->gfy = prev_record->gfy
и вообще не юзай с инета код, либо юзай, но разберись как работает и где сохранить, тут много говна всякого навалено
да и также лв вроде сбрасывает missed_shots если противник умер и у тебя если ресольвер от этого зависит то он обнулится
 
sapphire dev
Пользователь
Статус
Оффлайн
Регистрация
15 Мар 2018
Сообщения
188
Реакции[?]
124
Поинты[?]
36K
просто гфи на след сим тике восстанавливай, который был успешно зарезольвен, сохранить можешь вообще по разному, можешь в рекорд ее сохранить с пометкой resolved допустим и на след вызове сделать
if(prev_record->resolved)
record->gfy = prev_record->gfy
Не делай так, не изменяй на прямую гфя, и уж точно не ресторь его с предыдущего рекорда... Тебе нужно каждый новый апдейт ресольвить, к тому же гфя будет иметь разное начальное значение на каждом рекорде, вернув с предыдущего ты не то что ломаешь анимки, ты ломаешь мне сердце...
Делай как я написал выше.
 
Начинающий
Статус
Оффлайн
Регистрация
8 Апр 2021
Сообщения
9
Реакции[?]
1
Поинты[?]
0
просто гфи на след сим тике восстанавливай, который был успешно зарезольвен, сохранить можешь вообще по разному, можешь в рекорд ее сохранить с пометкой resolved допустим и на след вызове сделать
if(prev_record->resolved)
record->gfy = prev_record->gfy
и вообще не юзай с инета код, либо юзай, но разберись как работает и где сохранить, тут много говна всякого навалено
да и также лв вроде сбрасывает missed_shots если противник умер и у тебя если ресольвер от этого зависит то он обнулится
ничего не понял
я же задаю банальные как бы вопросы, я не шарю в этой теме ничего. Хочу понять как работает это поэтапно.
 
like amiri in my mind
Пользователь
Статус
Оффлайн
Регистрация
4 Дек 2022
Сообщения
308
Реакции[?]
54
Поинты[?]
1K
Не делай так, не изменяй на прямую гфя, и уж точно не ресторь его с предыдущего рекорда... Тебе нужно каждый новый апдейт ресольвить, к тому же гфя будет иметь разное начальное значение на каждом рекорде, вернув с предыдущего ты не то что ломаешь анимки, ты ломаешь мне сердце...
Делай как я написал выше.
а бля ой аххаха, я имел ввиду дельту, ну строить с прев рекорда не очень да, согласен, хрень написал вобщем я, можно в ресольвере ласт голфитяв то сторить, тоесть его дельту
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
23 Сен 2019
Сообщения
51
Реакции[?]
23
Поинты[?]
1K
ничего не понял
я же задаю банальные как бы вопросы, я не шарю в этой теме ничего. Хочу понять как работает это поэтапно.
ну с компиленой весрией прев рекорд в нью рекорд нет ворк занеси во втором файле у тебя по счету в проекте net->work там оффсет сигнатуры по которой эта все тема эмулируется
пронеси:
Файл для скачки:
    float closest_distance = 100.0f;

    float radius = Settings::AntiAim::HeadEdge::distance + 0.1f;
    float step = M_PI * 2.0 / 8;

    for (float a = 0; a < (M_PI * 2.0); a += step)
    {
        Vector location(radius * cos(a) + position.x, radius * sin(a) + position.y, position.z);

        Ray_t ray;
        trace_t tr;
        ray.Init(position, location);
        CTraceFilter traceFilter;
        traceFilter.pSkip = localplayer;
        trace->TraceRay(ray, 0x4600400B, &traceFilter, &tr);

        float distance = Distance(position, tr.endpos);

        if (distance < closest_distance)
        {
            closest_distance = distance;
            angle.y = RAD2DEG(a);
        }
    }
вот смотри теперь попробуй имплементировать координаты потому что так сохранять можно по ним тоже если много информации передавать то может перегрузится система и далее пробуешь установить это в стейтмент "HEAP" / "stack" (не путать с RBKBCX_1938x01);

Гип-гип!
 
like amiri in my mind
Пользователь
Статус
Оффлайн
Регистрация
4 Дек 2022
Сообщения
308
Реакции[?]
54
Поинты[?]
1K
ничего не понял
я же задаю банальные как бы вопросы, я не шарю в этой теме ничего. Хочу понять как работает это поэтапно.
вот посмотри ты наверное у ся после апдейта анимок в конце меняешь голфитяв, чтобы получить серверный без десинка и заресольвить типа, дальше в зависимости от условий и детекта определенных возвращается значение(его возвращает ресольвер), обновляется анимация(в файле анимаций), собираются кости(в файле анимаций) тд тп и запись бектрека готова, тебе остается посмотреть что делается в resolve_yaw и как меняется то самое значение, думаю просто прочитать код и определить как работает это ты сможешь, главное понимать что резик возвращает только дельту голфитява, ну или сам голфитяв, смотря с чем едят и анимации применяют то значение визуально на клиент чтобы ты попал
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
23 Сен 2019
Сообщения
51
Реакции[?]
23
Поинты[?]
1K
вот посмотри ты наверное у ся после апдейта анимок в конце меняешь голфитяв, чтобы получить серверный без десинка и заресольвить типа, дальше в зависимости от условий и детекта определенных возвращается значение(его возвращает ресольвер), обновляется анимация(в файле анимаций), собираются кости(в файле анимаций) тд тп и запись бектрека готова, тебе остается посмотреть что делается в resolve_yaw и как меняется то самое значение, думаю просто прочитать код и определить как работает это ты сможешь, главное понимать что резик возвращает только дельту голфитява и анимации применяют то значение визуально на клиент чтобы ты попал
не пон, че ты написал ес все можно сделать проще

кот:
    AntiAimType_Y aa_type = bFlip ? Settings::AntiAim::Yaw::typeFake : Settings::AntiAim::Yaw::type;

    static bool yFlip;
    float temp;
    double factor;
    static float trigger;
    QAngle temp_qangle;
    int random;
    int maxJitter;

    yFlip = bFlip != yFlip;

    switch (aa_type)
    {
        case AntiAimType_Y::SPIN_FAST:
            factor =  360.0 / M_PHI;
            factor *= 25;
            angle.y = fmodf(globalVars->curtime * factor, 360.0);
            break;
        case AntiAimType_Y::SPIN_SLOW:
            factor =  360.0 / M_PHI;
            angle.y = fmodf(globalVars->curtime * factor, 360.0);
            break;
        case AntiAimType_Y::JITTER:
            yFlip ? angle.y -= 90.0f : angle.y -= 270.0f;
            break;
        case AntiAimType_Y::BACKJITTER:
            angle.y -= 180;
            random = rand() % 100;
            maxJitter = rand() % (85 - 70 + 1) + 70;
            temp = maxJitter - (rand() % maxJitter);
            if (random < 35 + (rand() % 15))
                angle.y -= temp;
            else if (random < 85 + (rand() % 15 ))
                angle.y += temp;
            break;
        case AntiAimType_Y::SIDE:
            yFlip ? angle.y += 90.f : angle.y -= 90.0f;
            break;
        case AntiAimType_Y::BACKWARDS:
            angle.y -= 180.0f;
            break;
        case AntiAimType_Y::FORWARDS:
 
Сверху Снизу