Исходник Updated OnBodyUpdate // supremacy c+p ready

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
15 Окт 2019
Сообщения
44
Реакции
6
resolver.cpp:
Expand Collapse Copy
void Resolver::OnBodyUpdate(Player* player, float body) {
    // validate player entity.
    if (!player || !player->alive() || player->IsDormant())
        return;

    // ignore local player and teammates.
    if (player == g_cl.m_local || player->IsTeammate(g_cl.m_local))
        return;

    // get lag compensation data for this player.
    AimPlayer* lag_data = g_lagcomp.GetLagData(player->m_entIndex);
    if (!lag_data || lag_data->m_records.empty())
        return;

    // get the most recent record.
    LagRecord* current_record = &lag_data->m_records.front();
    if (!current_record)
        return;

    // get resolver data for this player.
    auto& resolver_data = m_resolver_data[player->m_entIndex];

    // reset dormancy flag since we're receiving updates.
    resolver_data.m_is_dormant = false;

    // store previous body yaw for delta calculations.
    const float previous_body = current_record->m_body;

    // update the body yaw in the record.
    current_record->m_body = body;
    current_record->m_old_body = previous_body;

    // normalize the body yaw.
    body = math::NormalizedAngle(body);

    // calculate body yaw delta from previous update.
    const float body_delta = std::fabs(math::AngleDiff(body, previous_body));

    // detect significant body yaw changes lby updates.
    const bool is_lby_update = body_delta > 25.0f;

    // constants
    constexpr float LBY_UPDATE_PERIOD = 1.1f;    // time between forced lby updates.
    constexpr float FIRST_UNLOCK_DELAY = 0.22f;  // delay after stopping movement.

    // handle lby update detection and timing.
    if (is_lby_update) {
        // mark this as an lby update.
        resolver_data.m_detect_body_update = 1;
        resolver_data.m_last_lby_update_time = current_record->m_anim_time;

        // schedule next expected lby update.
        resolver_data.m_lower_body_realign_timer = current_record->m_anim_time + LBY_UPDATE_PERIOD;

        // reset missed shots for lby prediction since we got a valid update.
        resolver_data.m_missed_shots_lby = std::max(0, resolver_data.m_missed_shots_lby - 1);

        // update lby prediction state.
        resolver_data.m_in_prediction_state = true;
    }
    else {
        // small body changes might indicate micro-adjustments.
        if (body_delta > 1.0f && body_delta < 25.0f) {
            resolver_data.m_micro_movement_detected = true;
        }
    }

    // handle first-time body update after movement stops.
    if (resolver_data.m_last_move_anim_time > 0.0f) {
        const float time_since_stop = current_record->m_anim_time - resolver_data.m_last_move_anim_time;

        // if this is the first body update after stopping, schedule unlock window.
        if (time_since_stop >= FIRST_UNLOCK_DELAY && time_since_stop <= 0.5f) {
            if (resolver_data.m_lower_body_realign_timer > current_record->m_anim_time + LBY_UPDATE_PERIOD) {
                resolver_data.m_lower_body_realign_timer = current_record->m_anim_time + FIRST_UNLOCK_DELAY;
                resolver_data.m_detect_body_update = 2; // mark as stop-based update.
            }
        }
    }

    // update body yaw history for pattern analysis.
    resolver_data.m_body_history.push_front(body);

    // limit history size to prevent memory bloat.
    while (resolver_data.m_body_history.size() > 8) {
        resolver_data.m_body_history.pop_back();
    }

    // analyze body yaw patterns for exploit detection.
    AnalyzeBodyPatterns(player, resolver_data);

    // store this body update for future reference.
    resolver_data.m_previous_lower_body_yaw = body;
    resolver_data.m_last_body_update_time = current_record->m_anim_time;

    // increment body update counter for statistical analysis.
    resolver_data.m_body_update_count++;

    // validate body yaw consistency across choked packets.
    ValidateBodyConsistency(player, current_record, resolver_data);
}

void Resolver::ValidateBodyConsistency(Player* player, LagRecord* record, resolver_data_t& data) {
    // skip validation if not enough data.
    if (!record || data.m_body_history.size() < 2)
        return;

    // get lag compensation data.
    AimPlayer* lag_data = g_lagcomp.GetLagData(player->m_entIndex);
    if (!lag_data || lag_data->m_records.size() < 2)
        return;

    // check consistency across recent records.
    const auto& recent_record = lag_data->m_records.at(1);
    const float time_delta = record->m_anim_time - recent_record.m_anim_time;

    // if time delta suggests choked packets, validate body consistency.
    if (time_delta > m_global_vars->m_interval * 1.5f) {
        const float body_delta = std::fabs(math::AngleDiff(record->m_body, recent_record.m_body));

        // large body changes over choked packets might indicate breaking.
        if (body_delta > 120.0f) {
            data.m_breaking_lc_detected = true;
            data.m_last_lc_break_time = record->m_anim_time;
        }
    }

    // validate against animation layers for additional consistency checks.
    if (player->m_PlayerAnimState()) {
        const auto& move_layer = player->m_AnimOverlay()[ANIMATION_LAYER_MOVEMENT_MOVE];

        // if player is moving, body should be more stable.
        if (move_layer.m_weight > 0.1f) {
            const float expected_stability = 1.0f - (move_layer.m_weight * 0.8f);
            const float actual_delta = data.m_body_history.size() > 1 ?
                std::fabs(math::AngleDiff(data.m_body_history[0], data.m_body_history[1])) : 0.0f;

            // if body is changing too much while moving, mark as suspicious.
            if (actual_delta > (180.0f * expected_stability)) {
                data.m_body_while_moving_detected = true;
            }
        }
    }
}

void Resolver::AnalyzeBodyPatterns(Player* player, resolver_data_t& data) {
    // need at least 3 samples for pattern analysis.
    if (data.m_body_history.size() < 3)
        return;

    // check for jitter patterns.
    bool is_jittering = true;
    float total_delta = 0.0f;

    for (size_t i = 1; i < data.m_body_history.size(); ++i) {
        const float delta = std::fabs(math::AngleDiff(data.m_body_history[i], data.m_body_history[i - 1]));
        total_delta += delta;

        // if any delta is too small, it's probably not jittering.
        if (delta < 5.0f) {
            is_jittering = false;
            break;
        }
    }

    // detect body yaw jitter exploit.
    if (is_jittering && total_delta > 180.0f) {
        data.m_body_jitter_detected = true;
        data.m_jitter_intensity = total_delta / (data.m_body_history.size() - 1);
    }
    else {
        data.m_body_jitter_detected = false;
        data.m_jitter_intensity = 0.0f;
    }

    // detect fake body patterns (rapidly switching between two values).
    if (data.m_body_history.size() >= 4) {
        const float first = data.m_body_history[0];
        const float third = data.m_body_history[2];
        const float delta_13 = std::fabs(math::AngleDiff(first, third));

        // if alternating between similar angles, mark as fake body.
        if (delta_13 < 5.0f) {
            const float second = data.m_body_history[1];
            const float delta_12 = std::fabs(math::AngleDiff(first, second));

            if (delta_12 > 35.0f) {
                data.m_fake_body_detected = true;
            }
        }
    }

    // reset fake body detection if pattern breaks.
    if (data.m_body_history.size() >= 6) {
        bool consistent_pattern = true;
        for (size_t i = 2; i < std::min<size_t>(6, data.m_body_history.size()); i += 2) {
            const float delta = std::fabs(math::AngleDiff(data.m_body_history[0], data.m_body_history[i]));
            if (delta > 15.0f) {
                consistent_pattern = false;
                break;
            }
        }

        if (!consistent_pattern) {
            data.m_fake_body_detected = false;
        }
    }
}
 
Назад
Сверху Снизу