Гайд Сущности в доте для чайников

Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
781
Реакции[?]
331
Поинты[?]
63K
А не пробовал как в Mcdota через Reinit predictables найти энтити лист ?
Пожалуйста, авторизуйтесь для просмотра ссылки.

найти по Reinit Predictables не получится, такая строка только на линуксе есть.

Вот по этой можно найти.
CL: reinitialized %i predictable entities\n


GetHighestEntityIndex там просто инлайнится как я понял, в отличии от линукс версии. Вот эти две строки вместо нее.
НУ или v4 в дизасемблере

Самый первый вызов функции это GetBaseEntity(индекс).
перед вызовом this (EntitySystem) кладется в rcx

text:0000000180810AA0 sub_180810AA0 proc near

.text:0000000180810AA0 push rsi
.text:0000000180810AA2 sub rsp, 30h
.text:0000000180810AA6 mov rax, cs:qword_182EAE0A8 ; Вот тут
.text:0000000180810AAD mov [rsp+38h+arg_0], rbx
.text:0000000180810AB2 mov [rsp+38h+arg_8], rbp
.text:0000000180810AB7 xor ebp, ebp
.text:0000000180810AB9 mov [rsp+38h+arg_10], rdi
.text:0000000180810ABE mov ebx, ebp
.text:0000000180810AC0 mov byte ptr [rcx+100h], 1
.text:0000000180810AC7 mov edi, [rax+2060h] ; И вот тут
.text:0000000180810ACD mov [rsp+38h+var_10], r14
.text:0000000180810AD2 mov r14, rcx
.text:0000000180810AD5 test edi, edi
.text:0000000180810AD7 js loc_180810B94
.text:0000000180810ADD
.text:0000000180810ADD loc_180810ADD:
.text:0000000180810ADD
.text:0000000180810ADD mov [rsp+38h+var_18], r15
.text:0000000180810AE2 lea r15, qword_182E98388
.text:0000000180810AE9 nop dword ptr [rax+00000000h]
.text:0000000180810AF0
.text:0000000180810AF0 loc_180810AF0:
.text:0000000180810AF0 cmp ebx, 0FFFFFFFFh
.text:0000000180810AF3 jl loc_180810B85
.text:0000000180810AF9 mov rcx, cs:qword_182EAE0A8 ; entitySystem указатель.
.text:0000000180810B00 mov edx, ebx
.text:0000000180810B02 add rcx, 10h
.text:0000000180810B06 call sub_180164B30 ; Вот эта функция - GetBaseEntity
.text:0000000180810B0B test rax, rax

Не проверял, но похоже, что все так и есть.

Пример итераций энтити
Пожалуйста, авторизуйтесь для просмотра ссылки.
в общем попрофилировал и пришел к выводу что вроде такая итерация напрямую через массив быстрее на пару фпс(разница не больше 6 фпс иногда ее практически нет в доте фпс нестабильный).
плюсы итерации через Next как в этом туторе:
во-первых она красивая, обернутая(что собственно значит надежная, малоошибочная)
во-вторых можно получить инфу о том находится ли сущность в тумане основываясь на том что если в итерации через Next сущности не было то она в тумане.
минусы Next:
во-первых вроде куча мусорных сущностей(то есть итерируем лишний хлам и поэтому -фпс)
во-вторых сама по себе медленная так как это обертка(любая обертка медленнее прямого управления данными)
в-третьих нельзя получить сущность по индексу не убив немножко фпс.(основная проблема которая ваще заставила меня задуматься)
плюсы голой итерации через массив:
во-первых быстрая так как голая + нету мусорных сущностей как в Next
во-вторых сущностей можно легко получить по индексу так как они в массиве по индексам расположены друг за другом
минусы голой итерации через массив:
во-первых эстетически уродливая(ну на это думаю всем насрать)
во-вторых нельзя получить инфу о сущности в тумане чисто на основе итерации(так как в этом массиве сущность всегда будет пока не удалится, а в тумане она не удаляется она просто засыпает)
в итоге я выбрал +парочку фпс и итерирую через массив а проблему с инфой о сущности в тумане решил по-другому.
C++:
class CENTITYIDENTITY {
...
        char flags[4];//оффсет 0x30
        bool IsDormant() {//true когда в тумане
            return (flags[0] & 0x80);
        }
+ проапгрейдил определение героя среди сущностей:
C++:
Function GetClassInfoByName = 0;
u64 GCIBN = FindPattern("client.dll",
        "33 ff 48 39 3d ?? ?? ?? ?? 0f 84 ?? ?? ?? ?? 48 39 3d ?? ?? ?? ?? 0f 84 ?? ?? ?? ?? 4c 8d 44 24 ",
        "getclassinfobyname not found");//dylib CEntitySystem::FindClassByName
    GetClassInfoByName = GCIBN - 0x51;
    ...
    Pointer<u64> CDOTABASENPC_HERO_CLASS = 0;
u64 HeroBaseClass = 0;
    //runframe:
    ...
//GameState = GameRules->GameState()
    if(Engine->InGame() && GameState == Game_Rules::DOTA_GAMERULES_PREGAME ||
        GameState == Game_Rules::DOTA_GAMERULES_GAME_IN_PROGRESS)
    if (!CDOTABASENPC_HERO_CLASS|| !HeroBaseClass) {
                CDOTABASENPC_HERO_CLASS = GetClassInfoByName(EntitySystem, "C_DOTA_BaseNPC_Hero");
                if(CDOTABASENPC_HERO_CLASS)
                HeroBaseClass = *CDOTABASENPC_HERO_CLASS;
            }
            ...
            //centityidentity
u64 baseinfo;//offset 8
                    bool IsHero() {
            return *(u64*)baseinfo == HeroBaseClass;
        }
            ...
            //iteration:
            ...
            if(entity_identity->IsHero())
то есть в итоге я не вызываю strcmp("C_DOTA_BaseNPC_Hero") каждый кадр а теперь просто сравниваю с указателем который я получаю 1 раз при входе в матч и сбрасываю по выходу из матча, что собственно особо и не придаст нам фпса но все же)
и вот в итоге сама голая итерация:
C++:
void IterateARRAY() {//dylib CGameEntitySystem::GetBaseEntity(CEntityIndex)
//массив разделен на 64 листа по 512 сущностей
        short LocalPlayerIndex = 0;
        if (!LocalPlayer) LocalPlayerIndex = Engine->GetLocalPlayerIndex();
        auto LPstack = LocalPlayer;
        u64 EntSys = EntitySystem;
        u64 HeroBC = HeroBaseClass;
        int highestindex = EntitySystem->Member(0x2060);
        int highestlist = highestindex >> 9;//целая часть от деления на 512
        int maxent = highestindex & 0x1ff;//последние 9 бит, то есть остаток деления на 512 кароче
        int entc = 0;
        for (int list = 0; list <= highestlist; list++) {
            u64 EntityList = *(u64*)(EntSys + 0x10 + list * 8);
            if (!EntityList) return;
                for (int ent = 0; ent < 512; ent++) {
                    if (list == highestlist && ent >= maxent) break;//если последний лист до не до конца 512 итерировать а до maxent
                    auto entident = (CENTITYIDENTITY*)(EntityList + ent * 0x78);//sizeof(centityidentity) = 0x78
                    if (!entident||!entident->entity) continue;
                    if (!LPstack) {//беру из стека/регистра а не напрямую из оперативки каждый цикл, +наносекунды быстроты
                        if (entident->Index() == LocalPlayerIndex) {
                            LocalPlayer = entident->entity;
                            LocalTeam = LocalPlayer->Team();
                            continue;
                        }
                    }
                    if (entident->DerefBaseInfo() == HeroBC) {//HeroBC загружаю из регистра/стека а не напрямую из оперативы это дает мне пару наносекунд быстроты... мда
                        if (!entident->entity->IsIllusion()) {//m_hReplicatingOtherHeroModel равна -1 у настоящего
                            //делаю ченибудь
                        }
                    }
                }
        }

    }
//и плюс еще
    Entity* GetEntityByIndex(u64 CEntSysPlusTen,int index) {
        //if index > 0x7ffe return 0; //вырубил для скорости
        int sar = index >> 9;
        //if sar > 0x3e return 0; //вырубил для скорости, хотя пара наносекунд(10 в минус девятой) ничего не меняют на самом деле поэтому можете включать спокойно
        u64 list = *(u64*)(CEntSysPlusTen + sar*8);
        auto ent = (CENTITYIDENTITY*)(list + 0x78 * (index & 0x1ff));
        return ent->entity;
        return 0;
    }
поэтому мой вердикт переходите на голую итерацию ради +пары фпс и новых ощущений
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
А что делать если бесконечный цикл? И дальше первой энтити не идет, вроде все правильно
unsigned long long Entity = EntityFinder.getEntity(ent_find_pattern);
unsigned long long CEntityIdentity = *(unsigned long long*)(Entity + 0x10);
unsigned long long EntityName1 = *(unsigned long long*)(CEntityIdentity + 0x18);
unsigned long long EntityName2 = *(unsigned long long*)(CEntityIdentity + 0x20);

while (Entity)
{
if (CEntityIdentity)
{
if (EntityName1)
{
ConsoleMessage.CMSG("EntityName1 : %s\n", EntityName1);
}
else if (EntityName2)
{
ConsoleMessage.CMSG("EntityName2 : %s\n", EntityName2);
}
}
*(unsigned long long*)(CEntityIdentity + 0x58) == 0 ? Entity = 0 : Entity = *(unsigned long long*)(*(unsigned long long*)(CEntityIdentity + 0x58));
}

upd. проблему решил добавив переменные в цикл
 
Последнее редактирование:
Легенда форума
Статус
Онлайн
Регистрация
10 Дек 2018
Сообщения
4,385
Реакции[?]
2,286
Поинты[?]
191K
Качественныйкачественныйкачественный контеент!!!!
Лайк.
<3
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
C++:
// Entities Arrays

    unsigned long long Allies[5];

    unsigned long long Enemies[5];



    //(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8)))



    // Entity Iteration

    while (true)

    {

        if (*(unsigned long long*)(Entity + m_iTeamNum) == 2)

        {

            if (!strcmp((const char*)(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8))), "C_DOTA_BaseNPC_Hero"))

            {

                for (int i = 0; i < 5; i++)

                {

                    Allies[i] = Entity;

                }

            }

        }

        else if(*(unsigned long long*)(Entity + m_iTeamNum) != 2)

        {

            if (!strcmp((const char*)(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8))), "C_DOTA_BaseNPC_Hero"))

            {

                for (int i = 0; i < 5; i++)

                {

                    Enemies[i] = Entity;

                }

            }

        }



        if (*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x58) == 0) { break; }

        else { Entity = *(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x58)); }

    }



    for (int i = 0; i < 5; i++)

    {

        ConsoleMessage.CMSG("Ally : %s\n", n2hex(Allies[i]));

    }

}
Почему такая итерация не работает? Выводит CCCCCCCCCCCCCCCC
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
781
Реакции[?]
331
Поинты[?]
63K
// Entities Arrays
unsigned long long Allies[5];
unsigned long long Enemies[5];

//(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8)))

// Entity Iteration
while (true)
{
if (*(unsigned long long*)(Entity + m_iTeamNum) == 2)
{
if (!strcmp((const char*)(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8))), "C_DOTA_BaseNPC_Hero"))
{
for (int i = 0; i < 5; i++)
{
Allies = Entity;
}
}
}
else if(*(unsigned long long*)(Entity + m_iTeamNum) != 2)
{
if (!strcmp((const char*)(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8))), "C_DOTA_BaseNPC_Hero"))
{
for (int i = 0; i < 5; i++)
{
Enemies = Entity;
}
}
}

if (*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x58) == 0) { break; }
else { Entity = *(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x58)); }
}

for (int i = 0; i < 5; i++)
{
ConsoleMessage.CMSG("Ally : %s\n", n2hex(Allies));
}
}

Почему такая итерация не работает? Выводит CCCCCCCCCCCCCCCC
во-первых код в следующий раз лучше засунь в [CODE ] мне кажется так красивее выглядит,
во-вторых сделай себе просто вывод в консоль для начала чтобы удостовериться что ты правильно сформулировал свое условие и оно выполняется. ну просто чтобы ты знал что ты не чушь написал. заметь что m_iTeamNum это int, у тебя там unsigned long long. это неправильно. тебе нужно с ячейки Entity+m_iTeamNum считать 4 байта(int), а не 8(unsigned long long).
C++:
 if (*(int*)(Entity + m_iTeamNum) == 2)
{
            if (!strcmp((const char*)(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8))), "C_DOTA_BaseNPC_Hero"))
            {
                CMSG("condition satisfied");
            }
}
ну и else if(*(unsigned long long*)(Entity + m_iTeamNum) != 2) можешь просто заменить на else, потому что
*(unsigned long long*)(Entity + m_iTeamNum) == 2 разделяется на два исхода:
*(unsigned long long*)(Entity + m_iTeamNum) равен 2
*(unsigned long long*)(Entity + m_iTeamNum) не равен 2
в итоге чекая первый исход(==2), второй исход который будет != 2 и никакой иначе можно чекать без его указания а просто написав слово else
else if нужен только если ты чекаешь несколько условий
if(team == 2)
else if(team == 3)
else if(team == 4)
else//автоматически срабатывает если team !=2 && team != 3 &&team != 4
и
for (int i = 0; i < 5; i++)
{
Allies = Entity;
}

зачем ты заполняешь весь массив одной сущностью? сделай глобал переменную int ally_count, ставь в 0 при самом начале итерации, увеличивай ее каждый раз когда находишь союзника и записывай Allies[ally_count++] = Entity;//объединил два действия, сначала записываю по индексу ally_count потом его увеличиваю.
плюс
unsigned long long Allies[5] = {12345678};
unsigned long long Enemies[5] = {123456789};
инициализируй в какое-нибудь говно(123456789), чтобы ты когда выводишь в консоль если видишь там свое 123456789 то сразу понимаешь что в твой массив никто ничего не записывал, значит твои условия не выполняются и ты их неправильно составил
ну и указатель на указатель на указатель на жопу не надо так делать, лучше так сделай - тройной дереференс четверного указателя
***(const char****) (*(unsigned long long*)(EnT + 0x10) + 0x8)
а еще лучше структурами просто все сделай
EnT->identity(+0x10)->baseinfo(+0x8)->namestruct(+0x0)->name(+0x0)
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
во-первых код в следующий раз лучше засунь в [CODE ] мне кажется так красивее выглядит,
во-вторых сделай себе просто вывод в консоль для начала чтобы удостовериться что ты правильно сформулировал свое условие и оно выполняется. ну просто чтобы ты знал что ты не чушь написал. заметь что m_iTeamNum это int, у тебя там unsigned long long. это неправильно. тебе нужно с ячейки Entity+m_iTeamNum считать 4 байта(int), а не 8(unsigned long long).
C++:
 if (*(int*)(Entity + m_iTeamNum) == 2)
{
            if (!strcmp((const char*)(*(unsigned long long*)(*(unsigned long long*)(*(unsigned long long*)(Entity + 0x10) + 0x8))), "C_DOTA_BaseNPC_Hero"))
            {
                CMSG("condition satisfied");
            }
}
ну и else if(*(unsigned long long*)(Entity + m_iTeamNum) != 2) можешь просто заменить на else, потому что
*(unsigned long long*)(Entity + m_iTeamNum) == 2 разделяется на два исхода:
*(unsigned long long*)(Entity + m_iTeamNum) равен 2
*(unsigned long long*)(Entity + m_iTeamNum) не равен 2
в итоге чекая первый исход(==2), второй исход который будет != 2 и никакой иначе можно чекать без его указания а просто написав слово else
else if нужен только если ты чекаешь несколько условий
if(team == 2)
else if(team == 3)
else if(team == 4)
else//автоматически срабатывает если team !=2 && team != 3 &&team != 4
и
for (int i = 0; i < 5; i++)
{
Allies = Entity;
}

зачем ты заполняешь весь массив одной сущностью? сделай глобал переменную int ally_count, ставь в 0 при самом начале итерации, увеличивай ее каждый раз когда находишь союзника и записывай Allies[ally_count++] = Entity;//объединил два действия, сначала записываю по индексу ally_count потом его увеличиваю.
плюс
unsigned long long Allies[5];
unsigned long long Enemies[5];
инициализируй в какое-нибудь говно(123456789), чтобы ты когда выводишь в консоль если видишь там свое 123456789 то сразу понимаешь что в твой массив никто ничего не записывал, значит твои условия не выполняются и ты их неправильно составил
ну и указатель на указатель на указатель на жопу не надо так делать, лучше так сделай - тройной дереференс четверного указателя
***(const char****) (*(unsigned long long*)(EnT + 0x10) + 0x8)
В код добавил, а про Allies[] хз, когда код вставлял убрались вскобки, спасибо
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
781
Реакции[?]
331
Поинты[?]
63K
В код добавил, а про Allies[] хз, когда код вставлял убрались вскобки, спасибо
да тут [ i ] когда пишешь включается italic стиль текста. я не про это а про то что ты во все пять позиций массива записываешь одни и те же данные, тебе нужно в каждую позицию разных сущностей записать, поэтому тебе и нужна переменная которая отсчитывает сколько ты всего врагов насчитал
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
да тут [ i ] когда пишешь включается italic стиль текста. я не про это а про то что ты во все пять позиций массива записываешь одни и те же данные, тебе нужно в каждую позицию разных сущностей записать, поэтому тебе и нужна переменная которая отсчитывает сколько ты всего врагов насчитал
Спасибо!
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
А что кстати можно сделать если ConMsg медленно выводит сообщение? Ща записал всю функу в отдельный хедр, получил адрес в мэйне (который GetProcAddr), инжекчу и выводит он сообщение через несколько секунд
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
781
Реакции[?]
331
Поинты[?]
63K
А что кстати можно сделать если ConMsg медленно выводит сообщение? Ща записал всю функу в отдельный хедр, получил адрес в мэйне (который GetProcAddr), инжекчу и выводит он сообщение через несколько секунд
от способа инжекта зависит. со стандартным без скрамбла/пост-инжект опций инжектит за долю секунды и моментально все выводит. а с мануал мапом скрамблом и пост-инжект опциями через пару секунд выводит.
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
от способа инжекта зависит. со стандартным без скрамбла/пост-инжект опций инжектит за долю секунды и моментально все выводит. а с мануал мапом скрамблом и пост-инжект опциями через пару секунд выводит.
Да, у меня мануалмап
 
Пользователь
Статус
Оффлайн
Регистрация
30 Апр 2019
Сообщения
130
Реакции[?]
30
Поинты[?]
0
блин я подумал тут про героев доты и о всяких их штучках рассказывается а тут опять эти кодеры сравнивают чей удав длиннее :rage:
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
У меня кстати когда я энтити в массив записываю и пытаюсь вывести ее у меня крашит, тоесть к примеру u64 name = *u64*(*(u64*)(Entity + 0x10) + 0x18),
CMSG("Ent name %s\n", n2hex(name));
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
781
Реакции[?]
331
Поинты[?]
63K
У меня кстати когда я энтити в массив записываю и пытаюсь вывести ее у меня крашит, тоесть к примеру u64 name = *u64*(*(u64*)(Entity + 0x10) + 0x18),
CMSG("Ent name %s\n", n2hex(name));
Ну во-первых сделай лог самой ентити, дабы убедиться что она у тебя не 12345678(то есть ты все условия правильно сформулировал и все норм записывает)
Во-вторых, если ты хочешь вывести имя, то тебе нужно
CMSG("Ent name %s\n", name);
n2hex это сделать из указателя строку которая содержит числовое значение указателя в 16ричной системе
u64 name = 4096;//по адресу 4096 в десятиричной системе хранится строка "npc_dota_hero_my_name"
CMSG(n2hex(name));//выдаст 0x1000, то есть строку которая содрежит 16ричное число указателя
CMSG(name);//выдаст "npc_dota_hero_my_name"
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
Да там даже смотри, если n2hex(Entity) работает, то n2hex(Allies[0]) не работает
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
781
Реакции[?]
331
Поинты[?]
63K
Да там даже смотри, если n2hex(Entity) работает, то n2hex(Allies[0]) не работает
в Allies[0] значит ничего не пишешь, либо потом когда-то обратно в мусор перезаписываешь.
там где у тебя Allies[ i ] = Entity; сделай CMSG("condition satisfied %d\n",i) чтобы убедиться что это происходит
скинь код кр4
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
Вот крч, ща теперь постоянно крашит :)) Пытаюсь через структуру сделать чтобы не писать постоянно смещения
C++:
    // Энтити
    C_BaseEntity* Entity = (C_BaseEntity*)getEntity();

    int allies_counter = 0;
    int enemies_counter = 0;

    unsigned long long Allies[] = { 0 };
    unsigned long long Enemies[] = { 0 };

    while (Entity)
    {
        if (*(int*)(Entity + m_iTeamNum) == 2)
        {
            if (!strcmp((const char*)(*(unsigned long long*)(Entity->CEntityIdentity->baseInfo)), "C_DOTA_BaseNPC_Hero"))
            {
                SDK.CMSG("Ally Entity : %s\n", n2hex((unsigned long long)Entity));
            }
        }
        else
        {
            if (!strcmp((const char*)(*(unsigned long long*)(Entity->CEntityIdentity->baseInfo)), "C_DOTA_BaseNPC_Hero"))
            {
                SDK.CMSG("Enemy Entity : %s\n", n2hex((unsigned long long)Entity));
            }
        }
        Entity->CEntityIdentity->m_pNext == 0 ? Entity = 0 : Entity = (C_BaseEntity*)(*(unsigned long long*)Entity->CEntityIdentity->m_pNext);
    }
Там еще в цикле крч еще у меня Allies[allies_counter++] = Entity; и так же для врагов только Enemies[enemies_counter++]
C++:
// Вот классы
class C_EntityIdentity;

class C_BaseEntity
{
public:
    char pad_0000[16]; //0x0000
    C_EntityIdentity* CEntityIdentity; //0x0010
    char pad_0018[40]; //0x0018
}; //Size: 0x0040

class C_EntityIdentity
{
public:
    C_BaseEntity* m_pEnt; //0x0000
    unsigned long long baseInfo; //0x0008
    char pad_0010[8]; //0x0010
    unsigned long long entityName1; //0x0018
    unsigned long long entityName2; //0x0020
    char pad_0028[40]; //0x0028
    unsigned long long m_pPrev; //0x0050
    unsigned long long m_pNext; //0x0058
    char pad_0060[12]; //0x0060
}; //Size: 0x006C
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
781
Реакции[?]
331
Поинты[?]
63K
Вот крч, ща теперь постоянно крашит :)) Пытаюсь через структуру сделать чтобы не писать постоянно смещения
C++:
    // Энтити
    C_BaseEntity* Entity = (C_BaseEntity*)getEntity();

    int allies_counter = 0;
    int enemies_counter = 0;

    unsigned long long Allies[] = { 0 };
    unsigned long long Enemies[] = { 0 };

    while (Entity)
    {
        if (*(int*)(Entity + m_iTeamNum) == 2)
        {
            if (!strcmp((const char*)(*(unsigned long long*)(Entity->CEntityIdentity->baseInfo)), "C_DOTA_BaseNPC_Hero"))
            {
                SDK.CMSG("Ally Entity : %s\n", n2hex((unsigned long long)Entity));
            }
        }
        else
        {
            if (!strcmp((const char*)(*(unsigned long long*)(Entity->CEntityIdentity->baseInfo)), "C_DOTA_BaseNPC_Hero"))
            {
                SDK.CMSG("Enemy Entity : %s\n", n2hex((unsigned long long)Entity));
            }
        }
        Entity->CEntityIdentity->m_pNext == 0 ? Entity = 0 : Entity = (C_BaseEntity*)(*(unsigned long long*)Entity->CEntityIdentity->m_pNext);
    }
Там еще в цикле крч еще у меня Allies[allies_counter++] = Entity; и так же для врагов только Enemies[enemies_counter++]
C++:
// Вот классы
class C_EntityIdentity;

class C_BaseEntity
{
public:
    char pad_0000[16]; //0x0000
    C_EntityIdentity* CEntityIdentity; //0x0010
    char pad_0018[40]; //0x0018
}; //Size: 0x0040

class C_EntityIdentity
{
public:
    C_BaseEntity* m_pEnt; //0x0000
    unsigned long long baseInfo; //0x0008
    char pad_0010[8]; //0x0010
    unsigned long long entityName1; //0x0018
    unsigned long long entityName2; //0x0020
    char pad_0028[40]; //0x0028
    unsigned long long m_pPrev; //0x0050
    unsigned long long m_pNext; //0x0058
    char pad_0060[12]; //0x0060
}; //Size: 0x006C
кароче вместо того чтобы копаться в твоем коде который не фулл сделал свой
C++:
    Entity* Allies[5] = { 0 };
    Entity* Enemies[5] = { 0 };
    int a_count = 0;
    int e_count = 0;
    
    for (auto e = EntitySystem->GetFirstEntity(); e;e=e->identity->GetNext()) {
        if (!strcmp(e->identity->baseinfo->ClassName(), "C_DOTA_BaseNPC_Hero")) {
            if (e->Team() == 2) {
                Allies[a_count++] = e;

            }
            else if (e->Team() == 3) {
                Enemies[e_count++] = e;
            }
        }
    }
    for (int i = 0; i < 5; i++) {
        if (Allies[i]) {
            CMSG("radiant ent ptr %s\n", n2hex(Allies[i]));
            CMSG("name is %s\n", Allies[i]->identity->designer_name);
        }
        if (Enemies[i]) {
            CMSG("dire ent ptr %s\n", n2hex(Enemies[i]));
            CMSG("name is %s\n", Enemies[i]->identity->designer_name);
        }
    }
вот классы
C++:
class Binfo {
    const char** classname;
public:
    auto ClassName() {
        return *classname;
    }
};
class Identity {
public:
    Entity* entity;//0
    Binfo* baseinfo;//8
    int handle;//10
private:
    int unk;//14
public:
    cc name;//18
    cc designer_name;
    char pad[0x30];
    Identity* m_pNext;
    Entity* GetNext() {
        if (m_pNext) return m_pNext->entity;
        return 0;
    }
};
class Entity {
public:
    u64 vmt;
    u64 unk;
    Identity* identity;
    int Team() {
        return *(int*)((u64)this + m_iTeamNum);
    }
};
теперь сравни код. когда я говорил "дай код" я имел ввиду чтобы ты фулл код скинул чтобы я у себя запустил и подебажил ну да ладно.
 
Начинающий
Статус
Оффлайн
Регистрация
15 Дек 2018
Сообщения
146
Реакции[?]
9
Поинты[?]
0
кароче вместо того чтобы копаться в твоем коде который не фулл сделал свой
C++:
    Entity* Allies[5] = { 0 };
    Entity* Enemies[5] = { 0 };
    int a_count = 0;
    int e_count = 0;
   
    for (auto e = EntitySystem->GetFirstEntity(); e;e=e->identity->GetNext()) {
        if (!strcmp(e->identity->baseinfo->ClassName(), "C_DOTA_BaseNPC_Hero")) {
            if (e->Team() == 2) {
                Allies[a_count++] = e;

            }
            else if (e->Team() == 3) {
                Enemies[e_count++] = e;
            }
        }
    }
    for (int i = 0; i < 5; i++) {
        if (Allies[i]) {
            CMSG("radiant ent ptr %s\n", n2hex(Allies[i]));
            CMSG("name is %s\n", Allies[i]->identity->designer_name);
        }
        if (Enemies[i]) {
            CMSG("dire ent ptr %s\n", n2hex(Enemies[i]));
            CMSG("name is %s\n", Enemies[i]->identity->designer_name);
        }
    }
вот классы
C++:
class Binfo {
    const char** classname;
public:
    auto ClassName() {
        return *classname;
    }
};
class Identity {
public:
    Entity* entity;//0
    Binfo* baseinfo;//8
    int handle;//10
private:
    int unk;//14
public:
    cc name;//18
    cc designer_name;
    char pad[0x30];
    Identity* m_pNext;
    Entity* GetNext() {
        if (m_pNext) return m_pNext->entity;
        return 0;
    }
};
class Entity {
public:
    u64 vmt;
    u64 unk;
    Identity* identity;
    int Team() {
        return *(int*)((u64)this + m_iTeamNum);
    }
};
теперь сравни код. когда я говорил "дай код" я имел ввиду чтобы ты фулл код скинул чтобы я у себя запустил и подебажил ну да ладно.
Спасибо!
 
Сверху Снизу