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

Вопрос CS2 ESP — Пропадают игроки в цикле Entity List

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
737
Реакции
19
Здарова, реверсеры. Столкнулся с плавающим багом в своем проекте под CS2. Суть такая: ESP то работает на ура во всю карту, то видит только пару человек, а порой вообще решает уйти в отпуск и не рисует никого.

Оффсеты перепроверял раза три — всё актуально, база обновлена. Грешу на саму логику прохода по энтити-листу или на то, как забираю павны. Юзаю стандартную схему через контроллер, но где-то явно происходит осечка.

Код:
Expand Collapse Copy
void EntitySystem::UpdateEntities()
{
    uintptr_t entityListOffset = offsets.getEntityList();
    if (!entityListOffset) return;

    uintptr_t localPawn = offsets.getLocalPawn();
    if (!localPawn) return;

    myTeamID = *reinterpret_cast<int*>(localPawn + C_BaseEntity::m_iTeamNum);
    {
        std::lock_guard<std::mutex> lock(entityMutex);
        Vec3 myOrigin = offsets.getOrigin();

        for (int playerIndex = 0; playerIndex < 64; ++playerIndex)
        { 
            Entity& entity = playerEntities[playerIndex];
            uintptr_t listEntry = *reinterpret_cast<uintptr_t*>(entityListOffset + (0x8 * (playerIndex & 0x7FFF) >> 9) + 16);
            if (!listEntry) { entity.isAlive = false; continue; }

            uintptr_t currentController = *reinterpret_cast<uintptr_t*>(listEntry + 0x70 * (playerIndex & 0x1FF));
            if (!currentController) { entity.isAlive = false; continue; }

            uint32_t pawnHandle = *reinterpret_cast<uint32_t*>(currentController + CCSPlayerController::m_hPlayerPawn);
            if (!pawnHandle || pawnHandle == 0xFFFFFFFF) { entity.isAlive = false; continue; }

            uintptr_t listEntry2 = *reinterpret_cast<uintptr_t*>(entityListOffset + 0x70 * ((pawnHandle & 0x7FFF) >> 9) + 16);
            if (!listEntry2) { entity.isAlive = false; continue; }

            uintptr_t currentPawn = *reinterpret_cast<uintptr_t*>(listEntry2 + 0x70 * (pawnHandle & 0x1FF));
            if (!currentPawn) { entity.isAlive = false; continue; }

            const bool isDormant = *reinterpret_cast<bool*>(currentPawn + CGameSceneNode::m_bDormant);
            if (isDormant) { entity.isAlive = false; continue; }

            const int health = *reinterpret_cast<int*>(currentPawn + C_BaseEntity::m_iHealth);
            if (health < 1) { entity.isAlive = false; continue; }

            entity.health = health;
            if (currentPawn == localPawn) { entity.isAlive = false; continue; }

            entity.isAlive = true;
            Vec3 origin = *reinterpret_cast<Vec3*>(currentPawn + C_BasePlayerPawn::m_vOldOrigin);
            entity.origin = origin;
            entity.headPosition = offsets.BonePos(currentPawn, BoneIndices::HEAD);
            // ... логика со скелетами
        }
    }
}

Что уже проверено:
  1. Оффсеты m_hPlayerPawn и m_iHealth точно те, что нужны.
  2. Проверка на Dormancy (CGameSceneNode::m_bDormant). Может, в CS2 она работает специфично и отсекает тех, кто за стеной слишком рано?
  3. Мьютексы и потокобезопасность — тут вроде чисто, локов нет.

Есть подозрение, что лимит в 64 игрока в цикле — это слишком олдскульно для Source 2 и стоит чекать более широкий диапазон индексов, либо я где-то косячу с маской при получении listEntry2.

Если кто-то ковырял эту структуру недавно, подскажите, не менялась ли логика связки Controller -> Pawn в последних патчах, а то ESP в Premier-режиме превращается в лотерею.
 
Здарова, реверсеры. Столкнулся с плавающим багом в своем проекте под CS2. Суть такая: ESP то работает на ура во всю карту, то видит только пару человек, а порой вообще решает уйти в отпуск и не рисует никого.

Оффсеты перепроверял раза три — всё актуально, база обновлена. Грешу на саму логику прохода по энтити-листу или на то, как забираю павны. Юзаю стандартную схему через контроллер, но где-то явно происходит осечка.

Код:
Expand Collapse Copy
void EntitySystem::UpdateEntities()
{
    uintptr_t entityListOffset = offsets.getEntityList();
    if (!entityListOffset) return;

    uintptr_t localPawn = offsets.getLocalPawn();
    if (!localPawn) return;

    myTeamID = *reinterpret_cast<int*>(localPawn + C_BaseEntity::m_iTeamNum);
    {
        std::lock_guard<std::mutex> lock(entityMutex);
        Vec3 myOrigin = offsets.getOrigin();

        for (int playerIndex = 0; playerIndex < 64; ++playerIndex)
        {
            Entity& entity = playerEntities[playerIndex];
            uintptr_t listEntry = *reinterpret_cast<uintptr_t*>(entityListOffset + (0x8 * (playerIndex & 0x7FFF) >> 9) + 16);
            if (!listEntry) { entity.isAlive = false; continue; }

            uintptr_t currentController = *reinterpret_cast<uintptr_t*>(listEntry + 0x70 * (playerIndex & 0x1FF));
            if (!currentController) { entity.isAlive = false; continue; }

            uint32_t pawnHandle = *reinterpret_cast<uint32_t*>(currentController + CCSPlayerController::m_hPlayerPawn);
            if (!pawnHandle || pawnHandle == 0xFFFFFFFF) { entity.isAlive = false; continue; }

            uintptr_t listEntry2 = *reinterpret_cast<uintptr_t*>(entityListOffset + 0x70 * ((pawnHandle & 0x7FFF) >> 9) + 16);
            if (!listEntry2) { entity.isAlive = false; continue; }

            uintptr_t currentPawn = *reinterpret_cast<uintptr_t*>(listEntry2 + 0x70 * (pawnHandle & 0x1FF));
            if (!currentPawn) { entity.isAlive = false; continue; }

            const bool isDormant = *reinterpret_cast<bool*>(currentPawn + CGameSceneNode::m_bDormant);
            if (isDormant) { entity.isAlive = false; continue; }

            const int health = *reinterpret_cast<int*>(currentPawn + C_BaseEntity::m_iHealth);
            if (health < 1) { entity.isAlive = false; continue; }

            entity.health = health;
            if (currentPawn == localPawn) { entity.isAlive = false; continue; }

            entity.isAlive = true;
            Vec3 origin = *reinterpret_cast<Vec3*>(currentPawn + C_BasePlayerPawn::m_vOldOrigin);
            entity.origin = origin;
            entity.headPosition = offsets.BonePos(currentPawn, BoneIndices::HEAD);
            // ... логика со скелетами
        }
    }
}

Что уже проверено:
  1. Оффсеты m_hPlayerPawn и m_iHealth точно те, что нужны.
  2. Проверка на Dormancy (CGameSceneNode::m_bDormant). Может, в CS2 она работает специфично и отсекает тех, кто за стеной слишком рано?
  3. Мьютексы и потокобезопасность — тут вроде чисто, локов нет.

Есть подозрение, что лимит в 64 игрока в цикле — это слишком олдскульно для Source 2 и стоит чекать более широкий диапазон индексов, либо я где-то косячу с маской при получении listEntry2.

Если кто-то ковырял эту структуру недавно, подскажите, не менялась ли логика связки Controller -> Pawn в последних патчах, а то ESP в Premier-режиме превращается в лотерею.
Мьютексы и потокобезопасность - лучше исключить
m_bDormant - вообще вырезать, в кс2 нету системы дорманта
 
Мьютексы и потокобезопасность - лучше исключить
m_bDormant - вообще вырезать, в кс2 нету системы дорманта
Это ии ботинок, автоматом переводит посты с других форумов (даже обратно не отвечая на те форумы), даж не пытайся помогать ибо пользы 0
 
Это ии ботинок, автоматом переводит посты с других форумов (даже обратно не отвечая на те форумы), даж не пытайся помогать ибо пользы 0
я знаю, просто по приколу отвечаю ему всегда, не зря же он делает эти посты
 
Это ии ботинок, автоматом переводит посты с других форумов (даже обратно не отвечая на те форумы), даж не пытайся помогать ибо пользы 0
зато для других пользователей форума может быть полезно
 
Назад
Сверху Снизу