Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Cs2 Prediction HELP

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
14 Ноя 2025
Сообщения
8
Реакции
0
Prediction:
Expand Collapse Copy
#include "../../Precompiled.h"

void ClientSidePredict(CNetworkGameClient* pNetworkGameClient, int nPredictionReason) {
    if (pNetworkGameClient->m_bShouldPredict && pNetworkGameClient->m_iDeltaTick > 0 && pNetworkGameClient->m_iServerTick > 0) {
    
        Interfaces::m_pClient->FrameStageNotify(FRAME_NET_UPDATE_PREPROCESS);

        const bool bInPredictionBackup = pNetworkGameClient->m_bInPrediction;
        //    pNetworkGameClient->m_bInPrediction = true;
        Interfaces::m_pPrediction->Update(nPredictionReason, pNetworkGameClient->m_iServerTick);
        //    pNetworkGameClient->m_bInPrediction = bInPredictionBackup;
    }
}

void CEnginePrediction::Begin(CUserCmd* pCmd)
{
    if (pCmd->m_nCommandNumber == this->m_nLastSequenceProcessed)
        return;

    CCSPlayer_MovementServices* pMovementServices = Globals::m_pLocalPlayerPawn->m_pMovementServices();
    if (!pMovementServices)
        return;

    CNetworkGameClient* pNetworkGameClient = Interfaces::m_pNetworkClientService->GetNetworkGameClient();
    if (!pNetworkGameClient)
        return;

    CUserCmdManager* pCmdManager = Globals::m_pLocalPlayerController->GetUserCmdManager();
    if (!pCmdManager)
        return;

    CCSPlayer_MovementServices* pMoveService = Globals::m_pLocalPlayerPawn->m_pMovementServices();
    if (!pMoveService)
        return;

    if (!Globals::m_pLocalPlayerController->m_bPawnIsAlive())
        return

        LocalPlayerData::m_pWeapon->UpdateAccuracyPenalty_Rebuilt();

    m_PredictionData.m_vAbsVelocityBackup = Globals::m_pLocalPlayerPawn->m_vecAbsVelocity();
    m_PredictionData.m_vVelocityBackup = Globals::m_pLocalPlayerPawn->m_vecVelocity();
    m_PredictionData.m_vPreAbsOrigin = Globals::m_pLocalPlayerPawn->m_pGameSceneNode()->m_vecAbsOrigin();

    m_PredictionData.m_flIntervalPerSubTick = Interfaces::m_pGlobalVariables->m_flIntervalPerSubTick;
    m_PredictionData.m_flCurrentTime = Interfaces::m_pGlobalVariables->m_flCurrentTime;
    m_PredictionData.m_flCurrentTime2 = Interfaces::m_pGlobalVariables->m_flCurrentTime2;
    m_PredictionData.m_nTickCount = Interfaces::m_pGlobalVariables->m_nTickCount;
    m_PredictionData.m_flFrameTime = Interfaces::m_pGlobalVariables->m_flFrameTime;
    m_PredictionData.m_flFrameTime2 = Interfaces::m_pGlobalVariables->m_flFrameTime2;
    m_PredictionData.m_nPrePredictionFlags = Globals::m_pLocalPlayerPawn->m_fFlags();

    m_PredictionData.m_nTickBase = LocalPlayerData::m_nTickBase;

    m_PredictionData.m_bInPrediction = Interfaces::m_pPrediction->m_bInPrediction;
    m_PredictionData.m_bFirstPrediction = Interfaces::m_pPrediction->m_bFirstPrediction;
    m_PredictionData.m_bHasBeenPredicted = pCmd->m_bHasBeenPredicted;
    m_PredictionData.m_bShouldPredict = pNetworkGameClient->m_bShouldPredict;

    //printf("%llx\n", Globals::m_pLocalPlayerPawn->m_pMovementServices());
    m_PredictionData.m_pMovementServicesBackup = Interfaces::m_pMemAlloc->Alloc(0x5e0);
    memcpy(m_PredictionData.m_pMovementServicesBackup, Globals::m_pLocalPlayerPawn->m_pMovementServices(), 0x5e0);

    pCmd->m_bHasBeenPredicted = false;
    pNetworkGameClient->m_bShouldPredict = true;
    Interfaces::m_pPrediction->m_bFirstPrediction = false;
    Interfaces::m_pPrediction->m_bInPrediction = true;

    //printf("calling SetPredictionCommand\n");

    pMovementServices->SetPredictionCommand(pCmd);

    //Globals::m_pLocalPlayerController->GetCurrentCommand( ) = pCmd;///broke

    //printf("calling RunCommand\n");

    pMoveService->RunCommand(pCmd);

    // Save post-prediction flags IMMEDIATELY after RunCommand
    // This captures the predicted state before any restoration operations
    // Store flags from pawn directly after prediction
    m_PredictionData.m_nPostPredictionFlags = Globals::m_pLocalPlayerPawn->m_fFlags();

    //printf("calling ClientSidePredict\n");

    //ClientSidePredict( pNetworkGameClient, PREDICTION_REASON_CREATEMOVE );

    Vector vNonInterpolatedShootPos = LocalPlayerData::m_vecEyePosition;
    //xref sv: ERROR: Player %s calculated shoot time [ #%d + %.3f ] does not match time from cmd [ #%d + %.3f ]\n
    using fnCalculateShootPosition = void(__fastcall*)(Vector*, C_CSPlayerPawn*, TimeStamp_t*, void*, void*);
    static fnCalculateShootPosition CalculateShootPosition = (fnCalculateShootPosition)(Memory::FindPattern(CLIENT_DLL, "48 89 5C 24 ? 48 89 6C 24 ? 56 57 41 56 48 81 EC ? ? ? ? 44 8B 92 ? ? ? ?"));
    TimeStamp_t objTimeStamp = { (int)Globals::m_pLocalPlayerController->m_nTickBase(), 0.f };
    //printf("calling CalculateShootPosition %llx\n", Globals::m_pLocalPlayerPawn);
    CalculateShootPosition(&vNonInterpolatedShootPos, Globals::m_pLocalPlayerPawn, &objTimeStamp, nullptr, nullptr);
    //printf("called CalculateShootPosition\n");
    NRagebot::m_vShootPos = LocalPlayerData::m_vecEyePosition;

    //printf("calling ResetPredictionCommand\n");

    pMovementServices->ResetPredictionCommand();

    memcpy(Globals::m_pLocalPlayerPawn->m_pMovementServices(), m_PredictionData.m_pMovementServicesBackup, 0x5e0);

    Interfaces::m_pMemAlloc->Free(m_PredictionData.m_pMovementServicesBackup);


    Globals::m_pLocalPlayerPawn->m_pGameSceneNode()->m_vecAbsOrigin() = m_PredictionData.m_vPreAbsOrigin;

    Globals::m_pLocalPlayerPawn->m_vecAbsVelocity() = m_PredictionData.m_vAbsVelocityBackup;
    Globals::m_pLocalPlayerPawn->m_vecVelocity() = m_PredictionData.m_vVelocityBackup;
}

void CEnginePrediction::End(CUserCmd* pCmd)
{
    if (pCmd->m_nCommandNumber == this->m_nLastSequenceProcessed)
        return;

    CCSPlayer_MovementServices* pMovementServices = Globals::m_pLocalPlayerPawn->m_pMovementServices();
    if (!pMovementServices)
        return;

    CNetworkGameClient* pNetworkGameClient = Interfaces::m_pNetworkClientService->GetNetworkGameClient();
    if (!pNetworkGameClient)
        return;

    Interfaces::m_pGlobalVariables->m_flIntervalPerSubTick = m_PredictionData.m_flIntervalPerSubTick;
    Interfaces::m_pGlobalVariables->m_flCurrentTime = m_PredictionData.m_flCurrentTime;
    Interfaces::m_pGlobalVariables->m_flCurrentTime2 = m_PredictionData.m_flCurrentTime2;
    Interfaces::m_pGlobalVariables->m_nTickCount = m_PredictionData.m_nTickCount;
    Interfaces::m_pGlobalVariables->m_flFrameTime = m_PredictionData.m_flFrameTime;
    Interfaces::m_pGlobalVariables->m_flFrameTime2 = m_PredictionData.m_flFrameTime2;

    Globals::m_pLocalPlayerController->m_nTickBase() = m_PredictionData.m_nTickBase;

    Interfaces::m_pPrediction->m_bFirstPrediction = m_PredictionData.m_bFirstPrediction;
    Interfaces::m_pPrediction->m_bInPrediction = m_PredictionData.m_bInPrediction;
    pCmd->m_bHasBeenPredicted = m_PredictionData.m_bHasBeenPredicted;
    pNetworkGameClient->m_bShouldPredict = m_PredictionData.m_bShouldPredict;


    if (m_PredictionData.m_nPostPredictionFlags == 0)
        m_PredictionData.m_nPostPredictionFlags = Globals::m_pLocalPlayerPawn->m_fFlags();


    this->m_nLastSequenceProcessed = pCmd->m_nCommandNumber;
}


Помогите с предиктом, при выходе на противника начинает очень сильно телепортировать по карте либо просто тепнет на противника хоть стоял за стеной.

Не знаю точно из-за чего может быть такая проблема
 
у тя предикт который хотя бы как то работал до апдейта animgraph2.
во первых
удостоверься, что твои функи (RunCommand, SetPredictionCommand, ResetPredictionCommand) апдейтнуты. оно может не крашить.
во вторых в предикте игры есть такие приколы под названием сплиты. их было бы не плохо тоже сейвить и ресать. щас в предикте многое зависит от сплитов (если ошибаюсь, поправьте)
1768163370362.png

так же, то что ты вызываешь RunCommand, ну представь что это затычка просто чтоб работало. потому что в игре есть (по крайней мере была, точно знаю) функция, которая вызывает сразу ранкомманд, процессмувмент и другие фичи для предикта.
кароче, полазай по игре и посмотри что же ты делаешь не так, даже если на это уйдет месяц. оно того стоит, если ты хочешь продвигаться дальше в кс2 кодинге.
 
у тя предикт который хотя бы как то работал до апдейта animgraph2.
во первых
удостоверься, что твои функи (RunCommand, SetPredictionCommand, ResetPredictionCommand) апдейтнуты. оно может не крашить.
во вторых в предикте игры есть такие приколы под названием сплиты. их было бы не плохо тоже сейвить и ресать. щас в предикте многое зависит от сплитов (если ошибаюсь, поправьте)
Посмотреть вложение 324607
так же, то что ты вызываешь RunCommand, ну представь что это затычка просто чтоб работало. потому что в игре есть (по крайней мере была, точно знаю) функция, которая вызывает сразу ранкомманд, процессмувмент и другие фичи для предикта.
кароче, полазай по игре и посмотри что же ты делаешь не так, даже если на это уйдет месяц. оно того стоит, если ты хочешь продвигаться дальше в кс2 кодинге.
видимо никого не ебет что RunCommand уже вызывает всякие ваши процесс мувменты и прочую хуйню
сплиты тебе нужны для других вещей как пример чтобы получить доступ например к тем же m_nCommandsPredicted (сэйвить их нет никакого смысла)

по секрету скажу вам в целом ничего не нужно вызывать из pMovementServices пример ResetPredictionCommand, SetPredictionCommand, RunCommand и тд

Все что вам нужно это засторить все необходимые данные
Присвоить им необходимые значения
Hint: 40 55 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 01 @client.dll

И вызвать после этого всего ClientSidePrediction

И ресторнуть все необходимые данные

Ну и не забываем конечно же про главный чек:
C++:
Expand Collapse Copy
// pUserCmd + 8 = iSequenceNumber
// pUserCmd + 148 = iPredictionFlags
// Но как по мне чек на iPredictionFlags не нужен
// Достаточно лишь pUserCmd->m_iSequenceNumber == iSequenceNumber
if ( pUserCmd && *(pUserCmd + 8) == iSequenceNumber && *(pUserCmd + 148) == 2 )
    --iSequenceNumber; // вот тут должен быть return.

UPD: и то это не все что вам нужно для hittin p EnginePrediction
 
у тя предикт который хотя бы как то работал до апдейта animgraph2.
во первых
удостоверься, что твои функи (RunCommand, SetPredictionCommand, ResetPredictionCommand) апдейтнуты. оно может не крашить.
во вторых в предикте игры есть такие приколы под названием сплиты. их было бы не плохо тоже сейвить и ресать. щас в предикте многое зависит от сплитов (если ошибаюсь, поправьте)
Посмотреть вложение 324607
так же, то что ты вызываешь RunCommand, ну представь что это затычка просто чтоб работало. потому что в игре есть (по крайней мере была, точно знаю) функция, которая вызывает сразу ранкомманд, процессмувмент и другие фичи для предикта.
кароче, полазай по игре и посмотри что же ты делаешь не так, даже если на это уйдет месяц. оно того стоит, если ты хочешь продвигаться дальше в кс2 кодинге.
На клиенте сплит только 1(локал плеер), остальные доступы только серверу
видимо никого не ебет что RunCommand уже вызывает всякие ваши процесс мувменты и прочую хуйню
сплиты тебе нужны для других вещей как пример чтобы получить доступ например к тем же m_nCommandsPredicted (сэйвить их нет никакого смысла)

по секрету скажу вам в целом ничего не нужно вызывать из pMovementServices пример ResetPredictionCommand, SetPredictionCommand, RunCommand и тд

Все что вам нужно это засторить все необходимые данные
Присвоить им необходимые значения
Hint: 40 55 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 01 @client.dll

И вызвать после этого всего ClientSidePrediction

И ресторнуть все необходимые данные

Ну и не забываем конечно же про главный чек:
C++:
Expand Collapse Copy
// pUserCmd + 8 = iSequenceNumber
// pUserCmd + 148 = iPredictionFlags
// Но как по мне чек на iPredictionFlags не нужен
// Достаточно лишь pUserCmd->m_iSequenceNumber == iSequenceNumber
if ( pUserCmd && *(pUserCmd + 8) == iSequenceNumber && *(pUserCmd + 148) == 2 )
    --iSequenceNumber; // вот тут должен быть return.

UPD: и то это не все что вам нужно для hittin p EnginePrediction
Ненадо отнимать секвен намбер ведь апдейт уже это делает
Нужно лишь установить необходимые флаги(в курент флага установить 0 что бы был репредикт)
 
На клиенте сплит только 1(локал плеер), остальные доступы только серверу

Ненадо отнимать секвен намбер ведь апдейт уже это делает
Нужно лишь установить необходимые флаги(в курент флага установить 0 что бы был репредикт)
как я уже написал в комментарии тут нужен ретурн вместо отнимания
 
PS: оффсет 144 - прошлый флаг, 148 - текущий и вот енум
enum EPredictionState : int {
STATE_UNPROCESSED = 0,
STATE_PREDICTED = 1,
STATE_SKIPPED = 2,
STATE_REPREDICTED = 3
};
видимо никого не ебет что RunCommand уже вызывает всякие ваши процесс мувменты и прочую хуйню
сплиты тебе нужны для других вещей как пример чтобы получить доступ например к тем же m_nCommandsPredicted (сэйвить их нет никакого смысла)

по секрету скажу вам в целом ничего не нужно вызывать из pMovementServices пример ResetPredictionCommand, SetPredictionCommand, RunCommand и тд

Все что вам нужно это засторить все необходимые данные
Присвоить им необходимые значения
Hint: 40 55 56 41 57 48 8D 6C 24 ? 48 81 EC ? ? ? ? 48 8B 01 @client.dll

И вызвать после этого всего ClientSidePrediction

И ресторнуть все необходимые данные

Ну и не забываем конечно же про главный чек:
C++:
Expand Collapse Copy
// pUserCmd + 8 = iSequenceNumber
// pUserCmd + 148 = iPredictionFlags
// Но как по мне чек на iPredictionFlags не нужен
// Достаточно лишь pUserCmd->m_iSequenceNumber == iSequenceNumber
if ( pUserCmd && *(pUserCmd + 8) == iSequenceNumber && *(pUserCmd + 148) == 2 )
    --iSequenceNumber; // вот тут должен быть return.

UPD: и то это не все что вам нужно для hittin p EnginePrediction
Если ты сделаешь ретурн то ты не запредиктишь команду же
 
Последнее редактирование:
PS: оффсет 144 - прошлый флаг, 148 - текущий и вот енум
enum EPredictionState : int {
STATE_UNPROCESSED = 0,
STATE_PREDICTED = 1,
STATE_SKIPPED = 2,
STATE_REPREDICTED = 3
};

Если ты сделаешь ретурн то ты не запредиктишь команду же
запредиктишь
тебе нужно чекать на изменение iSequenceNumber'a на изменение перед своим EnginePrediction
e.g
C++:
Expand Collapse Copy
void CEnginePrediction::Begin( ... )
{
    if ( pUserCmd->m_iSequenceNumber == m_iLastSequenceNumber )
        return;
    
    // Ur prediction code related here...
}

void CEnginePrediction::End( ... )
{
    // After all prediction data...
    
    m_iLastSequenceNumber = pUserCmd->m_iSequenceNumber;
}
 
Назад
Сверху Снизу