Как понять, что энтити герой(Поиск TeamID)?

Начинающий
Статус
Оффлайн
Регистрация
22 Янв 2019
Сообщения
8
Реакции[?]
2
Поинты[?]
0
День добрый!
Решил ради интереса написать на Python External для Доты, разобрался с поиском по спискам энтити и всё довольно стабильно работает.

Через CE нашел следующие оффсеты:
m_iHealth = 0x32C
m_iMana = 0xC7C
dwEntityList = "client.dll"+0x3A757C0

Однако не могу додумать, как понять, что энтити - герой. Я пытался найти teamID через Data Dissect по аналогии с CS:GO, но похоже, что номера команды в Доте отличаются от КС и не представлены в виде порядка цифр по типу: 1 - Spectator | 2 - T | 3 - CT
Возможно идея поиска ID команды не имеет смысла, т.к я подразумеваю, что крипы тоже имеют teamID, но как тогда отличить крипа от сущности игрока ?

Или может быть возможно получить имя инстанции указателя, по аналогии, как это делает CE?

 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
C++:
bool helper_check_hierarchy_for_name(const CSchemaClassBinding& binding, const std::string_view& name) noexcept
{
    for (const auto& parent_node : binding.GetParents())
    {
        if (const auto* parent = parent_node.GetParent(); parent)
        {
            if (parent->GetName() == name || helper_check_hierarchy_for_name(*parent, name))
                return true;
        }
    }
    return false;
}
//C_BaseEntity vvv
    const CSchemaClassBinding& GetBinding() const
    {
        const auto* result = CallVFunc<0, CSchemaClassBinding*>();
        if (!result)
            throw std::runtime_error{ "C_BaseEntity::GetBinding returned nullptr!" };
        return *result;
    }
    bool IsInstanceOfClass(const std::string_view& cls) const
    {
        const auto& binding = GetBinding();
        if (binding.GetName() == cls)
            return true;
        else
            return helper_check_hierarchy_for_name(binding, cls);
        return false;
    }
if (entity.IsInstanceOfClass("C_DOTA_BaseNPC_Hero"))
альтернативно(олд говнокод)(вроде работает но не особо тестил)
C++:
//CEntityIdentity vvv
        const char* BaseClass() {
            if (
                !baseinfo//0x8
                ) return 0;
            return **(const char***)(
                baseinfo
                );
        }
        bool OfBaseClass(const char* bc) {
            return StringsMatch(BaseClass(), bc);
        }
        bool IsHero() {
            return OfBaseClass("C_DOTA_BaseNPC_Hero");
        }
ну и если захочешь можешь всегда RTTI просто попробовать получить.
Пожалуйста, авторизуйтесь для просмотра ссылки.
----12.08.2022
(пофиксил) баг который не учитывал множественное наследование(ретурн в цикле делал вместо того чтобы сделать ретурн только если результат успешен). сначала не заметил баг т.к. MH супер редкий, потом в другом месте похожую хуиту сделал хуйца соснул и сюда вернулся чтобы пофиксить. но суть в том что сам фикс я не тестил нормально к сожалению поэтому в общем смотрите сами и дважды думайте прежде чем что-то копировать.
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
22 Янв 2019
Сообщения
8
Реакции[?]
2
Поинты[?]
0
C++:
bool helper_check_hierarchy_for_name(const CSchemaClassBinding& binding, const std::string_view& name) noexcept
{
    for (const auto& parent_node : binding.GetParents())
    {
        if (const auto* parent = parent_node.GetParent(); parent)
        {
            if (parent->GetName() == name)
                return true;
            else
                return helper_check_hierarchy_for_name(*parent, name);
        }
    }
    return false;
}
//C_BaseEntity vvv
    const CSchemaClassBinding& GetBinding() const
    {
        const auto* result = CallVFunc<0, CSchemaClassBinding*>();
        if (!result)
            throw std::runtime_error{ "C_BaseEntity::GetBinding returned nullptr!" };
        return *result;
    }
    bool IsInstanceOfClass(const std::string_view& cls) const
    {
        const auto& binding = GetBinding();
        if (binding.GetName() == cls)
            return true;
        else
            return helper_check_hierarchy_for_name(binding, cls);
        return false;
    }
if (entity.IsInstanceOfClass("C_DOTA_BaseNPC_Hero"))
альтернативно(олд говнокод)(вроде работает но не особо тестил)
C++:
//CEntityIdentity vvv
        const char* BaseClass() {
            if (
                !baseinfo//0x8
                ) return 0;
            return **(const char***)(
                baseinfo
                );
        }
        bool OfBaseClass(const char* bc) {
            return StringsMatch(BaseClass(), bc);
        }
        bool IsHero() {
            return OfBaseClass("C_DOTA_BaseNPC_Hero");
        }
ну и если захочешь можешь всегда RTTI просто попробовать получить.
Пожалуйста, авторизуйтесь для просмотра ссылки.
Благодарю, спасибо большое !

Однако для себя я нашел решение попроще. Оставлю тут, если кому - то будет интересно.

Если посмотреть структурное дерево в CE, почти в любом энтити можно найти указатель на HeroesList, оффсет на который в данный момент - 0xD30. Он не значится, как инстанция, поэтому найти его очень просто. В этом древе на локальном оффсете - 0x0 - в виде 50 байтовой строки лежит имя энтити, к примеру - "npc_dota_hero_sven". Можно прочитать его и просто сделать в моем случае на Python срез строки [0:13], таким образом от этой строки у нас остается "npc_dota_hero", через условия смотрим строку и получаем проверку на то, герой ли энтити или нет, заодно можно и вытащить оттуда имя героя, если выполнить срез [14:], единственный минус в том, что имя героя будет системное, т.е - Shadow fiend будет Nevermore и т.д. Вот код, который я написал:

Python:
for i in range(1, 64):
    try:
        entity_list = mem.pm.read_longlong(mem.client_base + 0x3A757C0 + i * 0x8)
        for j in range(1, 512):
            try:
                entity = mem.pm.read_longlong(entity_list + j * 0x8)
                skeleton = mem.pm.read_longlong(entity + 0x310)
                nameslist = mem.pm.read_longlong(entity + 0xD30)
                name = mem.pm.read_string(nameslist + 0x0)
                if name[0:13] == "npc_dota_hero":
                    x_pos = mem.pm.read_float(skeleton + 0x10)
                    y_pos = mem.pm.read_float(skeleton + 0x14)
                    z_pos = mem.pm.read_float(skeleton + 0x88)
                    health = mem.pm.read_int(entity + 0x32C)
                    max_health = mem.pm.read_int(entity + 0x328)
                    mana = mem.pm.read_float(entity + 0xC7C)
                    max_mana = mem.pm.read_float(entity + 0xC80)
                    if health and mana:
                        cap = name[14:].capitalize()
                        print(cap)
                        print('Список: ', i, ' Энтити: ', j)
                        print("ХП: ", health, ' Мана: ', round(mana))
                        print('X: ', x_pos, ' Y: ', y_pos, ' Z: ', z_pos)
            except:
                None
    except:
        None
Остался только вопрос, как найти принадлежность героя к команде, потому что перерыв всю структуру энтити листа в CE, я так ничего и не нашел. Но думаю, если посидеть покумекать, сам додумаюсь.
 
Последнее редактирование:
🤡
Пользователь
Статус
Оффлайн
Регистрация
28 Апр 2014
Сообщения
127
Реакции[?]
163
Поинты[?]
21K
C++:
bool helper_check_hierarchy_for_name(const CSchemaClassBinding& binding, const std::string_view& name) noexcept
{
    for (const auto& parent_node : binding.GetParents())
    {
        if (const auto* parent = parent_node.GetParent(); parent)
        {
            if (parent->GetName() == name)
                return true;
            else
                return helper_check_hierarchy_for_name(*parent, name);
        }
    }
    return false;
}
//C_BaseEntity vvv
    const CSchemaClassBinding& GetBinding() const
    {
        const auto* result = CallVFunc<0, CSchemaClassBinding*>();
        if (!result)
            throw std::runtime_error{ "C_BaseEntity::GetBinding returned nullptr!" };
        return *result;
    }
    bool IsInstanceOfClass(const std::string_view& cls) const
    {
        const auto& binding = GetBinding();
        if (binding.GetName() == cls)
            return true;
        else
            return helper_check_hierarchy_for_name(binding, cls);
        return false;
    }
if (entity.IsInstanceOfClass("C_DOTA_BaseNPC_Hero"))
альтернативно(олд говнокод)(вроде работает но не особо тестил)
C++:
//CEntityIdentity vvv
        const char* BaseClass() {
            if (
                !baseinfo//0x8
                ) return 0;
            return **(const char***)(
                baseinfo
                );
        }
        bool OfBaseClass(const char* bc) {
            return StringsMatch(BaseClass(), bc);
        }
        bool IsHero() {
            return OfBaseClass("C_DOTA_BaseNPC_Hero");
        }
ну и если захочешь можешь всегда RTTI просто попробовать получить.
Пожалуйста, авторизуйтесь для просмотра ссылки.
Такой вариант подойдет, если делать проверку в хуке OnAddEntity, т.к. в тот момент ентити не имеет информации.
ОП же делает экстерн, для него лучший вариант client.dll/C_DOTA_BaseNPC/m_iUnitType, этот нетвар из схемы выдаст тип юнита (Герой, крип и т.п.)

Код:
client.dll\C_DOTA_BaseNPC\m_iUnitType int: 3076;  hex: c04;  oct: 6004; bin: 110000000100;
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Такой вариант подойдет, если делать проверку в хуке OnAddEntity, т.к. в тот момент ентити не имеет информации.
ОП же делает экстерн, для него лучший вариант client.dll/C_DOTA_BaseNPC/m_iUnitType, этот нетвар из схемы выдаст тип юнита (Герой, крип и т.п.)

Код:
client.dll\C_DOTA_BaseNPC\m_iUnitType int: 3076;  hex: c04;  oct: 6004; bin: 110000000100;
проблема лишь в том что не все сущности нпс. читать этот нетвар у не-нпс(например абилити) не совсем правильно.
 
🤡
Пользователь
Статус
Оффлайн
Регистрация
28 Апр 2014
Сообщения
127
Реакции[?]
163
Поинты[?]
21K
проблема лишь в том что не все сущности нпс. читать этот нетвар у не-нпс(например абилити) не совсем правильно.
Тоже верно, я по экстерналу не сильно подскажу, тут можно призвать oask. Он делал хороший экстернал, мб он подскажет куда лучше.
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Благодарю, спасибо большое !

Однако для себя я нашел решение попроще. Оставлю тут, если кому - то будет интересно.

Если посмотреть структурное дерево в CE, почти в любом энтити можно найти указатель на HeroesList, оффсет на который в данный момент - 0xD30. Он не значится, как инстанция, поэтому найти его очень просто. В этом древе на локальном оффсете - 0x0 - в виде 50 байтовой строки лежит имя энтити, к примеру - "npc_dota_hero_sven". Можно прочитать его и просто сделать в моем случае на Python срез строки [0:13], таким образом от этой строки у нас остается "npc_dota_hero", через условия смотрим строку и получаем проверку на то, герой ли энтити или нет, заодно можно и вытащить оттуда имя героя, если выполнить срез [14:], единственный минус в том, что имя героя будет системное, т.е - Shadow fiend будет Nevermore и т.д. Вот код, который я написал:

Python:
for i in range(1, 64):
    try:
        entity_list = mem.pm.read_longlong(mem.client_base + 0x3A757C0 + i * 0x8)
        for j in range(1, 512):
            try:
                entity = mem.pm.read_longlong(entity_list + j * 0x8)
                skeleton = mem.pm.read_longlong(entity + 0x310)
                nameslist = mem.pm.read_longlong(entity + 0xD30)
                name = mem.pm.read_string(nameslist + 0x0)
                if name[0:13] == "npc_dota_hero":
                    x_pos = mem.pm.read_float(skeleton + 0x10)
                    y_pos = mem.pm.read_float(skeleton + 0x14)
                    z_pos = mem.pm.read_float(skeleton + 0x88)
                    health = mem.pm.read_int(entity + 0x32C)
                    max_health = mem.pm.read_int(entity + 0x328)
                    mana = mem.pm.read_float(entity + 0xC7C)
                    max_mana = mem.pm.read_float(entity + 0xC80)
                    if health and mana:
                        cap = name[14:].capitalize()
                        print(cap)
                        print('Список: ', i, ' Энтити: ', j)
                        print("ХП: ", health, ' Мана: ', round(mana))
                        print('X: ', x_pos, ' Y: ', y_pos, ' Z: ', z_pos)
            except:
                None
    except:
        None
Остался только вопрос, как найти принадлежность героя к команде, потому что перерыв всю структуру энтити листа в CE, я так ничего и не нашел. Но думаю, если посидеть покумекать, сам додумаюсь.
это не хирослист)) это имя юнита.
и это нетвар который есть ТОЛЬКО у бейзнпс. то есть у абилок его нет. то есть читать его у ЛЮБОЙ сущности - просто небезопасно и последствия непредсказуемы. самое страшное будет если на 0xD30 у сущности(которая не нпс) будет лежать какой-нибудь мусор и этот мусор будет указателем на реальную строку которая начинается с npc_dota_hero - тогда твой чек будет УСПЕШЕН не смотря на то что сущность по факту нихуя не нпс и тем более не герой. еще страшнее будет если ты этот свой костыльный чек оставишь и потом будешь делать интернал и скопипастишь его туда, потому что тогда одним прекрасным днём ты обнаружишь какой-то рандомный непонятный краш.
C++:
//client.dll/C_DOTA_BaseNPC vvv
CUtlSymbolLarge m_iszUnitName(offset 0xd30)
тима это
C++:
//client.dll/C_BaseEntity vvv
uint8 m_iTeamNum(offset 0x3bf)
C++:
enum DOTATeam_t:
    DOTA_TEAM_FIRST = 2,
    DOTA_TEAM_GOODGUYS = 2,
    DOTA_TEAM_BADGUYS = 3,
    DOTA_TEAM_NEUTRALS = 4,
    DOTA_TEAM_NOTEAM = 5,
    DOTA_TEAM_CUSTOM_1 = 6,
    DOTA_TEAM_CUSTOM_2 = 7,
    DOTA_TEAM_CUSTOM_3 = 8,
    DOTA_TEAM_CUSTOM_4 = 9,
    DOTA_TEAM_CUSTOM_5 = 10,
    DOTA_TEAM_CUSTOM_6 = 11,
    DOTA_TEAM_CUSTOM_7 = 12,
    DOTA_TEAM_CUSTOM_8 = 13,
    DOTA_TEAM_COUNT = 14,
    DOTA_TEAM_CUSTOM_MIN = 6,
    DOTA_TEAM_CUSTOM_MAX = 13,
    DOTA_TEAM_CUSTOM_COUNT = 8,
дампы шемы есть тут в конце поста
 
smoking on that #pragma pack
Пользователь
Статус
Оффлайн
Регистрация
10 Янв 2018
Сообщения
324
Реакции[?]
96
Поинты[?]
1K
<...> таким образом от этой строки у нас остается "npc_dota_hero", через условия смотрим строку и получаем проверку на то, герой ли энтити или нет, заодно можно и вытащить оттуда имя героя, если выполнить срез [14:], единственный минус в том, что имя героя будет системное, т.е - Shadow fiend будет Nevermore и т.д.
изначально я делал также, но всё-таки лучше смотреть по нетвару "m_iUnitType" (если значение 1, то текущая энтити - герой, как ты и хотел)

Остался только вопрос, как найти принадлежность героя к команде, потому что перерыв всю структуру энтити листа в CE, я так ничего и не нашел. Но думаю, если посидеть покумекать, сам додумаюсь.
нетвар "m_iTeamNum", значение 2 - DOTA_TEAM_RADIANT, значение 3 - DOTA_TEAM_DIRE

ну а вообще, рекомендую заребилдить CGameEntitySystem::GetBaseEntity и получать энтитей точно также, как и игра, ибо в будущем, для полноценного чита, тебе нужно будет работать с хендлами и полученным из них индексом, где и пригодится CGameEntitySystem::GetBaseEntity.
 
Начинающий
Статус
Оффлайн
Регистрация
22 Янв 2019
Сообщения
8
Реакции[?]
2
Поинты[?]
0
это не хирослист)) это имя юнита.
и это нетвар который есть ТОЛЬКО у бейзнпс. то есть у абилок его нет. то есть читать его у ЛЮБОЙ сущности - просто небезопасно и последствия непредсказуемы. самое страшное будет если на 0xD30 у сущности(которая не нпс) будет лежать какой-нибудь мусор и этот мусор будет указателем на реальную строку которая начинается с npc_dota_hero - тогда твой чек будет УСПЕШЕН не смотря на то что сущность по факту нихуя не нпс и тем более не герой. еще страшнее будет если ты этот свой костыльный чек оставишь и потом будешь делать интернал и скопипастишь его туда, потому что тогда одним прекрасным днём ты обнаружишь какой-то рандомный непонятный краш.
C++:
//client.dll/C_DOTA_BaseNPC vvv
CUtlSymbolLarge m_iszUnitName(offset 0xd30)
тима это
C++:
//client.dll/C_BaseEntity vvv
uint8 m_iTeamNum(offset 0x3bf)
C++:
enum DOTATeam_t:
    DOTA_TEAM_FIRST = 2,
    DOTA_TEAM_GOODGUYS = 2,
    DOTA_TEAM_BADGUYS = 3,
    DOTA_TEAM_NEUTRALS = 4,
    DOTA_TEAM_NOTEAM = 5,
    DOTA_TEAM_CUSTOM_1 = 6,
    DOTA_TEAM_CUSTOM_2 = 7,
    DOTA_TEAM_CUSTOM_3 = 8,
    DOTA_TEAM_CUSTOM_4 = 9,
    DOTA_TEAM_CUSTOM_5 = 10,
    DOTA_TEAM_CUSTOM_6 = 11,
    DOTA_TEAM_CUSTOM_7 = 12,
    DOTA_TEAM_CUSTOM_8 = 13,
    DOTA_TEAM_COUNT = 14,
    DOTA_TEAM_CUSTOM_MIN = 6,
    DOTA_TEAM_CUSTOM_MAX = 13,
    DOTA_TEAM_CUSTOM_COUNT = 8,
дампы шемы есть тут в конце поста
Благодарю! Вообще я не собирался делать интернал, но тем не менее, спасибо. Теперь заодно разобрался, почему не мог найти m_iTeamNum, структура дерева в CE максимально показывает только оффсеты до C, т.е 0x3BC и т.д. Однако тем не менее на офсете 0x3BC лежит hex число, которое в зависимости от команды равно - 02000000 или 03000000, по сути можно было сделать сдвиг на пару байт и получить просто число, но я до этого не додумался и был уверен, что это никак не связанные друг с другом строки, что же, в следующий раз буду умнее.

изначально я делал также, но всё-таки лучше смотреть по нетвару "m_iUnitType" (если значение 1, то текущая энтити - герой, как ты и хотел)


нетвар "m_iTeamNum", значение 2 - DOTA_TEAM_RADIANT, значение 3 - DOTA_TEAM_DIRE

ну а вообще, рекомендую заребилдить CGameEntitySystem::GetBaseEntity и получать энтитей точно также, как и игра, ибо в будущем, для полноценного чита, тебе нужно будет работать с хендлами и полученным из них индексом, где и пригодится CGameEntitySystem::GetBaseEntity.
Спасибо большое! Теперь окончательно разобрался с тем, что вводило меня в ступор, конкретно значения нетваров, вообще не имел представления, какие они могут быть, но теперь понял, ещё раз спасибо. Совет насчет ребилда функции интересный, но пока не хочу над этим париться, т.к хочу заняться отрисовкой мана баров и т.д на экране поверх игры. Думаю можно просто взять функцию WorldToScreen из моего проекта по КС и просто подставить матрицу Доты. Конечно не уверен, что оно будет работать так, как я думаю, но попробовать стоит.
 
https://qweme.dev
Пользователь
Статус
Оффлайн
Регистрация
25 Май 2022
Сообщения
165
Реакции[?]
87
Поинты[?]
21K
Благодарю! Вообще я не собирался делать интернал, но тем не менее, спасибо. Теперь заодно разобрался, почему не мог найти m_iTeamNum, структура дерева в CE максимально показывает только оффсеты до C, т.е 0x3BC и т.д. Однако тем не менее на офсете 0x3BC лежит hex число, которое в зависимости от команды равно - 02000000 или 03000000, по сути можно было сделать сдвиг на пару байт и получить просто число, но я до этого не додумался и был уверен, что это никак не связанные друг с другом строки, что же, в следующий раз буду умнее.



Спасибо большое! Теперь окончательно разобрался с тем, что вводило меня в ступор, конкретно значения нетваров, вообще не имел представления, какие они могут быть, но теперь понял, ещё раз спасибо. Совет насчет ребилда функции интересный, но пока не хочу над этим париться, т.к хочу заняться отрисовкой мана баров и т.д на экране поверх игры. Думаю можно просто взять функцию WorldToScreen из моего проекта по КС и просто подставить матрицу Доты. Конечно не уверен, что оно будет работать так, как я думаю, но попробовать стоит.
на питоне не получится сделать нормальный гуй, потому что питон ОЧЕЕЕНЬ медленный, когда в доте у тебя будет 180фпс, питон будет рендерить 20-30 от силы, твои глаза просто умрут

даже в екстрнал читах на плюсах есть с этим проблемы, а питон, ну это просто язык не для этого

и все эти адреса, лол, они умрут завтра утром

не понимаю я эти ваши экстерналы :/
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Благодарю! Вообще я не собирался делать интернал, но тем не менее, спасибо. Теперь заодно разобрался, почему не мог найти m_iTeamNum, структура дерева в CE максимально показывает только оффсеты до C, т.е 0x3BC и т.д. Однако тем не менее на офсете 0x3BC лежит hex число, которое в зависимости от команды равно - 02000000 или 03000000, по сути можно было сделать сдвиг на пару байт и получить просто число, но я до этого не додумался и был уверен, что это никак не связанные друг с другом строки, что же, в следующий раз буду умнее.



Спасибо большое! Теперь окончательно разобрался с тем, что вводило меня в ступор, конкретно значения нетваров, вообще не имел представления, какие они могут быть, но теперь понял, ещё раз спасибо. Совет насчет ребилда функции интересный, но пока не хочу над этим париться, т.к хочу заняться отрисовкой мана баров и т.д на экране поверх игры. Думаю можно просто взять функцию WorldToScreen из моего проекта по КС и просто подставить матрицу Доты. Конечно не уверен, что оно будет работать так, как я думаю, но попробовать стоит.
он не до C показывает. он просто инты показывает по дефолту(они идут +0, +4, +8, +C). тима это не инт, это чар(8 бит). оффсет - 3bf. на 0x3bc, 0x3be, 0x3bd лежит мусор который тебе не нужен(ну точнее там m_EntClientFlags и m_bClientSideRagdoll). просто считывай один байт сразу с 0x3bf и не надо ничего сдвигать.
и советую попробовать рекласс для реверса структур вместо чит енджина юзать.
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Забаненный
Статус
Оффлайн
Регистрация
29 Май 2022
Сообщения
324
Реакции[?]
280
Поинты[?]
20K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
С этим оффсетом одни замарочки были и потом опять GitHUB
Что там делать если не хочется замарачивать руки от ковбоя
По байтнику даже стыдно зависнуть на теме.
Но не весеть же обще на нитках
 
Начинающий
Статус
Оффлайн
Регистрация
22 Янв 2019
Сообщения
8
Реакции[?]
2
Поинты[?]
0
на питоне не получится сделать нормальный гуй, потому что питон ОЧЕЕЕНЬ медленный, когда в доте у тебя будет 180фпс, питон будет рендерить 20-30 от силы, твои глаза просто умрут

даже в екстрнал читах на плюсах есть с этим проблемы, а питон, ну это просто язык не для этого

и все эти адреса, лол, они умрут завтра утром

не понимаю я эти ваши экстерналы :/
Ну, я уже писал, что экстернал просто ради интереса для себя делаю. А вот насчет гуи - это все враки. Если нормально оптимизировать математику и взять в качестве интерфейса какой - нибудь ткинтер, то FPS как по мне, вполне хороший. Сканирование списка энтити занимает ~ 0,007 сек, отрисовка десятка элементов на канвасе в Ткинтере ~ 0,009 сек, знаю, т.к замерял сам, однако значения все равно довольно примерные. Когда я делал экстернал для КС, на гуи выходило где - то 60 ± 5 FPS, при том, что игра сама идет у меня в 144 FPS, отставаний рендера сильно не замечал.
 
Начинающий
Статус
Оффлайн
Регистрация
22 Янв 2019
Сообщения
8
Реакции[?]
2
Поинты[?]
0
он не до C показывает. он просто инты показывает по дефолту(они идут +0, +4, +8, +C). тима это не инт, это чар(8 бит). оффсет - 3bf. на 0x3bc, 0x3be, 0x3bd лежит мусор который тебе не нужен(ну точнее там m_EntClientFlags и m_bClientSideRagdoll). просто считывай один байт сразу с 0x3bf и не надо ничего сдвигать.
и советую попробовать рекласс для реверса структур вместо чит енджина юзать.
Пожалуйста, авторизуйтесь для просмотра ссылки.
Понял, принял, спасибо. Пожалуй последую совету и попробую рекласс, потому что реверс структур на CE оставляет желать лучшего.
 
https://qweme.dev
Пользователь
Статус
Оффлайн
Регистрация
25 Май 2022
Сообщения
165
Реакции[?]
87
Поинты[?]
21K
Ну, я уже писал, что экстернал просто ради интереса для себя делаю. А вот насчет гуи - это все враки. Если нормально оптимизировать математику и взять в качестве интерфейса какой - нибудь ткинтер, то FPS как по мне, вполне хороший. Сканирование списка энтити занимает ~ 0,007 сек, отрисовка десятка элементов на канвасе в Ткинтере ~ 0,009 сек, знаю, т.к замерял сам, однако значения все равно довольно примерные. Когда я делал экстернал для КС, на гуи выходило где - то 60 ± 5 FPS, при том, что игра сама идет у меня в 144 FPS, отставаний рендера сильно не замечал.
странно что у тебя глаз не замечает отставание в 2 раза, ну тогда юзай 2 потока для гуая и самой логики, чтобы не срать презент вычислениями
 
Сверху Снизу