Вопрос All my abilities and items are invalid

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
11 Фев 2023
Сообщения
141
Реакции
3
sorry to bother with this long post but iam trying to keep it detailed as possible


here is how iam getting the abilities
C++:
Expand Collapse Copy
CDOTABaseNPC* hero = reinterpret_cast<CDOTABaseNPC*>(const_cast<CBaseEntity*>(entity));
                    if (hero && IsValidReadPtr(hero)) {
                        printf("DEBUG: Hero pointer is valid, processing abilities\n");
                        printf("DEBUG: Hero address: %p\n", hero);
                        printf("DEBUG: Hero abilities: %p\n", hero->GetAbilities());
                        for (auto ability : hero->GetAbilities()) {
                            // Check if the handle is valid first
                            if (!ability.IsValid())
                                continue;
                           
                            // Get the entity pointer safely
                            auto* abilityEntity = ability.Entity();
                            if (!abilityEntity || !IsValidReadPtr(abilityEntity))
                                printf("DEBUG: Ability entity is invalid\n");
                                continue;
                               
                            // Check if the identity is valid
                            auto* identity = abilityEntity->GetIdentity();
                            if (!identity || !identity->GetName())
                                printf("DEBUG: Ability identity is invalid\n");
                                continue;
                               
                            printf("DEBUG: Ability address: %p\n", abilityEntity);
                            printf("DEBUG: Ability name: %s\n", identity->GetName());
                            printf("DEBUG: Ability index: %d\n", abilityEntity->GetIndex());
                        }
                    } else {
                        printf("DEBUG: Hero pointer is invalid\n");
                    }

in the auto* abilityEntity = ability.Entity();
we are calling CGameEntitySystem.h

to get the entity like this:
C++:
Expand Collapse Copy
template<typename T>
inline T* CHandle<T>::Entity() const {
    return CGameEntitySystem::Get()->GetEntity<T>(Index());
}

then we are calling the GetEntity from the same class (CGameEntitySystem) to get the entity like so:
C++:
Expand Collapse Copy
 template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        auto identity = GetIdentity(index);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity))
            return (T*)identity->entity;
        return nullptr;
    }

here is the abilities output iam getting

Код:
Expand Collapse Copy
DEBUG: Hero pointer is valid, processing abilities
DEBUG: Hero address: 000001E4EB9C1000
DEBUG: Hero abilities: 00000047830EF9E0
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid


I wanna know why all my abilities entities are invalid ?

and once again iam really sorry for the long post
 
Последнее редактирование:
by the way i tried to debugg the CGameEntitySystem::Get() and found out that it is correct, but still cant figure out why all entities are invalid on my end
 
after some inspections i noticed that abilities and items are entities so i need to get this entity -> identity -> getname( )

after doing this it is still invalid too !

im going crazy here :D
 
sorry to bother with this long post but iam trying to keep it detailed as possible


here is how iam getting the abilities
C++:
Expand Collapse Copy
CDOTABaseNPC* hero = reinterpret_cast<CDOTABaseNPC*>(const_cast<CBaseEntity*>(entity));
                    if (hero && IsValidReadPtr(hero)) {
                        printf("DEBUG: Hero pointer is valid, processing abilities\n");
                        printf("DEBUG: Hero address: %p\n", hero);
                        printf("DEBUG: Hero abilities: %p\n", hero->GetAbilities());
                        for (auto ability : hero->GetAbilities()) {
                            // Check if the handle is valid first
                            if (!ability.IsValid())
                                continue;
                         
                            // Get the entity pointer safely
                            auto* abilityEntity = ability.Entity();
                            if (!abilityEntity || !IsValidReadPtr(abilityEntity))
                                printf("DEBUG: Ability entity is invalid\n");
                                continue;
                             
                            // Check if the identity is valid
                            auto* identity = abilityEntity->GetIdentity();
                            if (!identity || !identity->GetName())
                                printf("DEBUG: Ability identity is invalid\n");
                                continue;
                             
                            printf("DEBUG: Ability address: %p\n", abilityEntity);
                            printf("DEBUG: Ability name: %s\n", identity->GetName());
                            printf("DEBUG: Ability index: %d\n", abilityEntity->GetIndex());
                        }
                    } else {
                        printf("DEBUG: Hero pointer is invalid\n");
                    }

in the auto* abilityEntity = ability.Entity();
we are calling CGameEntitySystem.h

to get the entity like this:
C++:
Expand Collapse Copy
template<typename T>
inline T* CHandle<T>::Entity() const {
    return CGameEntitySystem::Get()->GetEntity<T>(Index());
}

then we are calling the GetEntity from the same class (CGameEntitySystem) to get the entity like so:
C++:
Expand Collapse Copy
 template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        auto identity = GetIdentity(index);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity))
            return (T*)identity->entity;
        return nullptr;
    }

here is the abilities output iam getting

Код:
Expand Collapse Copy
DEBUG: Hero pointer is valid, processing abilities
DEBUG: Hero address: 000001E4EB9C1000
DEBUG: Hero abilities: 00000047830EF9E0
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid
DEBUG: Ability entity is invalid


I wanna know why all my abilities entities are invalid ?

and once again iam really sorry for the long post
what's GetAbilities?
also what does this even mean
Код:
Expand Collapse Copy
                        printf("DEBUG: Hero abilities: %p\n", hero->GetAbilities());
why would you pass a range(something that has .begin() and .end() methods) to printf, and why are you formatting a non-pointer object as a pointer??????
why even bother with those IsValidReadPtr? forget it, just check for nullptr and if it's not nullptr then assume it's safe to use that pointer, unless you're using some heuristics(making some dirty, hack-ish, possibly inaccurate guesses and assumptions in an attempt to solve some problem)(you're not doing that)
if there are actually some non-nullptr pointers that are invalid - the game would crash anyway, it's not your problem. and if the game is working fine, yet only you get invalid pointers because you're just doing something wrong - then your cheat causing crashes is definitely good for you, because if you're doing something wrong that means you need to update/fix your code(and you shouldn't keep using it - it's simply broken!), and crashes alert you of that fact(and crashes are usually well-debuggable, especially if they're easy to reproduce). it's better to crash and be alerted that shit went wrong, instead of either having your cheat malfunction or not function at all. if you're doing everything right then there won't be any problems in the first place, and if you're doing something wrong then you need to fix it immediately.
try logging the handles themselves and manually extracting indices(&0x7FFF) and checking those entities in the console("cl_ent_find_index <index>")
then try obtaining the entities at those indices and logging those too
and checking their names etc. and seeing if you get the correct entities
 
ok i didnt know that GetAbilities() has .begin() and .end() but here is the second attempt
main.cpp:
Expand Collapse Copy
 try {
                    CDOTABaseNPC* hero = reinterpret_cast<CDOTABaseNPC*>(const_cast<CBaseEntity*>(entity));
                    if (hero) {
                        printf("DEBUG: Hero pointer is valid, processing abilities\n");
                        printf("DEBUG: Hero address: %p\n", hero);
                        for (CHandle<CDOTABaseAbility> ability : hero->GetAbilities()) {
                            // Check if the ability handle is valid
                            if (!ability.IsValid()) {
                                printf("DEBUG: Ability handle is invalid\n");
                                continue;
                            }
                     
                            // Get the entity pointer and validate it
                            auto* abilityEntity = ability.Entity();
                            if (abilityEntity == nullptr) {
                                printf("DEBUG: Ability entity is invalid\n");
                                continue;
                            }
                     
                            // Get ability identity
                            auto* identity = ability->GetIdentity();
                            if (!identity) {
                                printf("DEBUG: Ability identity is null\n");
                                continue;
                            }
                    
                         
                            } catch (...) {
                                printf("DEBUG: Exception while getting ability properties\n");
                            }
                     
                            printf("DEBUG: --- End Ability Details ---\n\n");
                        }
                    } else {
                        printf("DEBUG: Hero pointer is invalid\n");
                    }
                } catch (...) {
                    printf("DEBUG: Exception in hero processing ability\n");
                }

and here is the CDOTABaseNPC
CDOTABaseNPC.h:
Expand Collapse Copy
 CUtlVector<CHandle<CDOTABaseAbility>>& GetAbilities() const {
        return *MemberInline<CUtlVector<CHandle<CDOTABaseAbility>>>(Offsets.m_hAbilities);
    }

and here is the debugging info
1759021832825.png


then it is never passes the abilityEntity because the the ability entity is always 0x00000000000000000000
1 more question please is the type for the ability is correct (CHandle<CDOTABaseAbility>) ?
i really appreciate your time and effort @Liberalist
please forgive me i know that iam really stupid but this is my C++ play ground and this is really my first project in C++ and game hacking
 
Последнее редактирование:
ok i didnt know that GetAbilities() has .begin() and .end() but here is the second attempt
main.cpp:
Expand Collapse Copy
 try {
                    CDOTABaseNPC* hero = reinterpret_cast<CDOTABaseNPC*>(const_cast<CBaseEntity*>(entity));
                    if (hero) {
                        printf("DEBUG: Hero pointer is valid, processing abilities\n");
                        printf("DEBUG: Hero address: %p\n", hero);
                        for (CHandle<CDOTABaseAbility> ability : hero->GetAbilities()) {
                            // Check if the ability handle is valid
                            if (!ability.IsValid()) {
                                printf("DEBUG: Ability handle is invalid\n");
                                continue;
                            }
                    
                            // Get the entity pointer and validate it
                            auto* abilityEntity = ability.Entity();
                            if (abilityEntity == nullptr) {
                                printf("DEBUG: Ability entity is invalid\n");
                                continue;
                            }
                    
                            // Get ability identity
                            auto* identity = ability->GetIdentity();
                            if (!identity) {
                                printf("DEBUG: Ability identity is null\n");
                                continue;
                            }
                   
                        
                            } catch (...) {
                                printf("DEBUG: Exception while getting ability properties\n");
                            }
                    
                            printf("DEBUG: --- End Ability Details ---\n\n");
                        }
                    } else {
                        printf("DEBUG: Hero pointer is invalid\n");
                    }
                } catch (...) {
                    printf("DEBUG: Exception in hero processing ability\n");
                }

and here is the CDOTABaseNPC
CDOTABaseNPC.h:
Expand Collapse Copy
 CUtlVector<CHandle<CDOTABaseAbility>>& GetAbilities() const {
        return *MemberInline<CUtlVector<CHandle<CDOTABaseAbility>>>(Offsets.m_hAbilities);
    }

and here is the debugging info
Посмотреть вложение 316647

then it is never passes the abilityEntity because the the ability entity is always 0x00000000000000000000
1 more question please is the type for the ability is correct (CHandle<CDOTABaseAbility>) ?
i really appreciate your time and effort @Liberalist
please forgive me i know that iam really stupid but this is my C++ play ground and this is really my first project in C++ and game hacking
C++:
Expand Collapse Copy
                        for (auto ability : hero->GetAbilities()) {
this kind of construction(formally called "range-based for loop") requires begin() and end() - if you didn't know that then why use that construction? in general if you don't understand how something works then you should either not use it or learn how it works at least to some acceptable degree.
also it's not m_hAbilities, it's m_vecAbilities(doesn't matter much but still)
also begin and end return iterators, iterators' operator* methods usually return a reference
meaning that (assuming your CUtlVector is correctly implemented) instead of this
C++:
Expand Collapse Copy
                        for (CHandle<CDOTABaseAbility> ability : hero->GetAbilities()) {
you should do this
C++:
Expand Collapse Copy
                        for (const CHandle<CDOTABaseAbility>& ability : hero->GetAbilities()) {
this is also trivial and doesn't matter much in this case specifically but does matter in general - your code makes a copy of the chandle object(again this is trivial and cheap in this case), whereas if you use & or const&(again, assuming your CUtlVector is implemented correctly(for example, returns pointers(which return a reference when you use operator* on them - pointers are built-in iterators) for begin and end)), you will refer specifically to the memory location where that chandle resides(meaning you'll be reading directly from there instead of making a copy) rather than a temporary variable that contains a copy of that data. also keep in mind that `auto` doesn't deduce references(unlike `decltype(auto)`). avoid making useless copies, especially when working with complex, large objects(chandles are cheap primitive types so it's fine here but still). if you're working with a specific thing in memory then use pointers(and references) instead of reading the data from memory and copying it into your own object(it only makes sense when you want to gain actual, independent ownership of the underlying resource, i.e. to have your own independent copy - that's what copying is for). references and pointers REFER to a memory location, they don't store the underlying data itself - they only allow you to ACCESS the data that belongs to somebody else(which is exactly the thing you're doing here - accessing dota's objects), whereas a non-pointer/non-reference type actually stores data
anyway, 21659830 & 0x7FFF gives 182
try cl_ent_find_index 182 in the console
(I mean obviously since you're going to restart dota by the time you read this, you'll need to try this once again and you'll probably get a different handle etc. - so it's not literally 182 but rather your handle & 0x7FFF)
if you can find the entity in the console but you get nullptr in your code - then your entitysystem code is wrong.
to identify the problem, identify the subsystem responsible for it, then isolate its subsystems and see if the problem can be reproduced. if yes, fix that subsystem or recursively break it down further into subsystems and start again - if not, then most likely the problem is caused by the interaction/connection between subsystems rather than the subsystems themselves.
if you're playing a game with 10 mods enabled and the game is crashing, then you try to disable some of the mods to see if it's just one of the mods causing the problem, and if it's not any one individual mod then it means some of them are just incompatible with each other(or you're loading them in the wrong order, etc.) - they're all safe to use individually but can't be used together
if you're getting offsets from schema, then using the offsets to get ability entity handles, then using entity handles to get entities, then the problem may be in one of those three things. try them out individually and see if one of them is causing the problem. if the problem only appears when all three(or some of them) are joined together, then you're probably just connecting these things wrong
 
after checking the chandle index which is ( value & 0x7FFF ) i got indexes and after using it against cl_ent_find_index i found out that this is the correct abilities

but still always the auto* abilityEntity = ability.Entity(); is wrong

and i have set debugger and followed it

It took me to
CGameEntitySystem.h:
Expand Collapse Copy
template<typename T>
inline T* CHandle<T>::Entity() const {
    return CGameEntitySystem::Get()->GetEntity<T>(Index());
}

and i tried to follow the GetEntity

CGameEntitySystem.h:
Expand Collapse Copy
 template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        printf("GetEntity called with index: %d\n", index);
        auto identity = GetIdentity(index);
        printf("Retrieved identity: %p\n", identity);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity))
            return (T*)identity->entity;
        return nullptr;
    }

and the GetIdentity method is always 00000000000000000000

hre is the code for the GetIdentity


CGameEntitySystem.h:
Expand Collapse Copy
 CEntityIdentity* GetIdentity(int index)
    {
        if (index <= -1 || index >= (MAX_TOTAL_ENTITIES - 1))
            return nullptr;

        CEntityIdentities* chunkToUse = m_pEntityList[(index / MAX_ENTITIES_IN_LIST)]; // equal to ( index >> 9 )

        if (!chunkToUse)
            return nullptr;

        CEntityIdentity* identity = chunkToUse->m_pIdentities[index % MAX_ENTITIES_IN_LIST]; // equal to (index & 1FF)

        if (!identity)
            return nullptr;


        return identity;
    }



here is screenshot of the console

1759097787550.png
 
Последнее редактирование:
after checking the chandle index which is ( value & 0x7FFF ) i got indexes and after using it against cl_ent_find_index i found out that this is the correct abilities

but still always the auto* abilityEntity = ability.Entity(); is wrong

and i have set debugger and followed it

It took me to
CGameEntitySystem.h:
Expand Collapse Copy
template<typename T>
inline T* CHandle<T>::Entity() const {
    return CGameEntitySystem::Get()->GetEntity<T>(Index());
}

and i tried to follow the GetEntity

CGameEntitySystem.h:
Expand Collapse Copy
 template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        printf("GetEntity called with index: %d\n", index);
        auto identity = GetIdentity(index);
        printf("Retrieved identity: %p\n", identity);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity))
            return (T*)identity->entity;
        return nullptr;
    }

and the GetIdentity method is always 00000000000000000000

hre is the code for the GetIdentity


CGameEntitySystem.h:
Expand Collapse Copy
 CEntityIdentity* GetIdentity(int index)
    {
        if (index <= -1 || index >= (MAX_TOTAL_ENTITIES - 1))
            return nullptr;

        CEntityIdentities* chunkToUse = m_pEntityList[(index / MAX_ENTITIES_IN_LIST)]; // equal to ( index >> 9 )

        if (!chunkToUse)
            return nullptr;

        CEntityIdentity* identity = chunkToUse->m_pIdentities[index % MAX_ENTITIES_IN_LIST]; // equal to (index & 1FF)

        if (!identity)
            return nullptr;


        return identity;
    }



here is screenshot of the console

Посмотреть вложение 316728
you copy-pasted that shitcode wrong.
(this assumes your CEntityIdentity is a struct with sizeof = 0x78)
C++:
Expand Collapse Copy
CEntityIdentity* GetIdentity(int index)
{
    if (index <= -1 || index >= (MAX_TOTAL_ENTITIES - 1))
        return nullptr;
    CEntityIdentity* entity_list = m_pEntityList[(index / MAX_ENTITIES_IN_LIST)]; //m_pEntityList is an array of 64 CEntityIdentity*, located at offset 0x10
    if (!entity_list)
        return nullptr;

    return (entity_list + (index % MAX_ENTITIES_IN_LIST));
}
 
after changing my GetIdentity

and have this

cheat-console.png

ingame-console.png
cheat-engine-dissect.png

so that means that there is too much problems

here is my CGameEntitySystem.h
CGameEntitySystem.h:
Expand Collapse Copy
#pragma once
#include "../base/Definitions.h"
#include "./CEntityIdentity.h"
#include "../base/CUtlVector.h"
#include "./Chandle.h"
#include "../base/VClass.h"
#include "../base/NormalClass.h"
#include "../base/Library.h"

#define MAX_ENTITIES_IN_LIST 512
#define MAX_ENTITY_LISTS 64 // 0x3F
#define MAX_TOTAL_ENTITIES MAX_ENTITIES_IN_LIST * MAX_ENTITY_LISTS // 0x8000

class IEntityListener {
public:
    virtual void OnEntityCreated(CBaseEntity* ent) = 0;
    virtual void OnEntitySpawned(CBaseEntity* ent) {};
    virtual void OnEntityDeleted(CBaseEntity* ent) = 0;
    virtual void OnEntityParentChanged(CBaseEntity* ent, CBaseEntity* parent) {};
};

class CEntitySystem : public VClass {
public:
    virtual void BuildResourceManifest(void) = 0; // 01
    virtual void n_2() = 0;
    virtual void n_3() = 0;
    virtual void n_4() = 0;
    virtual void n_5() = 0;
    virtual void n_6() = 0;
    virtual void AddRefKeyValues(void const*) = 0; // 7
    virtual void ReleaseKeyValues(void const*) = 0; // 8
    virtual void n_9() = 0;
    virtual void n_10() = 0;
    virtual void ClearEntityDatabase(void) = 0; // 11
    virtual CBaseEntity* FindEntityProcedural(const char *...) = 0;
    virtual CBaseEntity* OnEntityParentChanged(CBaseEntity*, CBaseEntity*) = 0; //13
    virtual CBaseEntity* OnAddEntity(CBaseEntity*, ENT_HANDLE) = 0; // 14
    virtual CBaseEntity* OnRemoveEntity(CBaseEntity*, ENT_HANDLE) = 0; // 15
    virtual void n_16() = 0;
    virtual void SortEntities(int, void*, int*, int*) = 0; // 17
    virtual void n_18() = 0;
    virtual void n_19() = 0;
    virtual void n_20() = 0;
    virtual void n_21() = 0;
};

class CGameEntitySystem : public CGameEntitySystem
{
    void* unk;
    CEntityIdentity* m_pEntityList[MAX_ENTITY_LISTS];
public:
    CEntityIdentity* GetIdentity(int index)
    {
        if (index <= -1 || index >= (MAX_TOTAL_ENTITIES - 1))
            return nullptr;

        CEntityIdentity* entity_list = m_pEntityList[(index / MAX_ENTITIES_IN_LIST)];
        if (!entity_list)
            return nullptr;

        return (entity_list + (index % MAX_ENTITIES_IN_LIST));
    }

    template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        printf("GetEntity called with index: %d\n", index);
        auto identity = GetIdentity(index);
        printf("Retrieved identity: %p\n", identity);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity)) {
            printf("Entity pointer is valid: %p\n", identity->entity);
            return (T*)identity->entity;
        }
        return nullptr;
    }

    decltype(auto) getFirstIdentity()
    {
       
        return Member<CEntityIdentity*>(0x210);
    }


    GETTER(int, GetHighestEntityIndex, 0x2100);
    FIELD(CUtlVector<IEntityListener*>, GetListeners, 0x1558);

    static CGameEntitySystem* Get() {
        if (lib.engine) {
            auto GRSC = lib.engine->LoadInterface<void>("GameResourceServiceClientV001");
            if (GRSC) {
                return static_cast<NormalClass*>(GRSC)->Member<CGameEntitySystem*>(0x58);
            }
        }
        return nullptr;
    }
};

template<typename T>
inline T* CHandle<T>::Entity() const {
    return CGameEntitySystem::Get()->GetEntity<T>(Index());
}

and here is the code iam using to get the abilities in the main.cpp

main.cpp:
Expand Collapse Copy
auto& abilities = hero->GetAbilities();
printf("DEBUG: Abilities container size: %zu\n", abilities.size());
for (const CHandle<CDOTABaseAbility>& ability : abilities) {
   
    if (!ability.IsValid()) {
        printf("DEBUG: Ability handle is invalid\n");
        continue;
    }
   
    // Get the entity pointer and validate it
    auto* abilityEntity = ability.Entity();
    if (abilityEntity == nullptr) {
        printf("DEBUG: Ability entity is null\n");
        continue;
    }
   
    // Validate the ability entity pointer
    if (!IsValidReadPtr(abilityEntity)) {
        printf("DEBUG: Ability entity pointer is invalid\n");
        continue;
    }

    auto* abilityIdentity = abilityEntity->GetIdentity();
    if (abilityIdentity == nullptr) {
        printf("DEBUG: abilityEntity->GetIdentity() returned null\n");
        continue;
    }

    // LOG THE ABILITY ENTITY / IDENTITY ADDRESSES
                printf("DEBUG: Ability entity address: %p\n", abilityEntity);
                printf("DEBUG: Ability identity address: %p\n", abilityIdentity);
   
    printf("DEBUG: --- End Ability Details ---\n\n");
 
   
}


and here is my CDOTABaseNPC.h GetAbilities() Method please make sure that iam using
CDOTABaseNPC.h:
Expand Collapse Copy
 CUtlVector<CHandle<CDOTABaseAbility>>& GetAbilities() const {
        return *MemberInline<CUtlVector<CHandle<CDOTABaseAbility>>>(Offsets.m_vecAbilities);
    }



and here is my Chandle.h File
CHandle.h:
Expand Collapse Copy
class CBaseEntity;

template<typename T = CBaseEntity>
struct CHandle {
    constexpr static uint32_t INVALID_HANDLE = 0XFFFFFFFF;

    uint32_t val;

    CHandle() : val(INVALID_HANDLE) {}
    CHandle(uint32_t val) : val(val) {}

    uint32_t Index() const {
        return val & 0x7fff;
    }

    explicit operator uint32_t() const {
        return val;
    }

    explicit operator bool() const {
        return IsValid();
    }

    T* Entity() const;

    operator T* () const {
        return Entity();
    }

    T* operator->() const {
        return Entity();
    }

    T* operator*() const {
        return Entity();
    }

    bool IsValid() const {
        return val != INVALID_HANDLE;
    }

    bool operator==(const CHandle<T> other) const {
        return other.val == val;  
    }
};

template<typename T>
std::ostream& operator<<(std::ostream& os, CHandle<T> h) {
    return os << "H[" << (*h) << "]";
}


and here is my CUTlVector.h file

CUtlVector.h:
Expand Collapse Copy
// Source engine's own analog to std::vector
template <class T>
class CUtlVector
{
public:
    uint32_t m_Size;
    T* m_pElements;
    uint32_t m_Capacity;

    T& operator[](int i) const {
        return m_pElements[i];
    }

    T& at(int i) const {
        return m_pElements[i];
    }

    T* begin() const {
        return m_pElements;
    }

    T* end() const {
        return m_pElements + m_Size;
    }

    T& first() const {
        assert(m_Size > 0 && "CUtlVector::first(): no elements");
        return m_pElements[0];
    }
    T& last() const {
        assert(m_Size > 0 && "CUtlVector::last(): no elements");
        return m_pElements[m_Size - 1];
    }

    bool empty() const {
        return m_Size == 0;
    }

    void pop_back() {
        m_Size--;
    }

    void remove_by_value(const T& elem) {
        int idx = 0;
        for (; idx < m_Size; idx++)
            if (m_pElements[idx] == elem)
                break;

        if (idx == m_Size)
            return;

        for (int i = idx + 1; i < m_Size; i++)
            m_pElements[i - 1] = m_pElements[i];

        m_Size--;
    }

    void remove_at(unsigned idx) {
        for (int i = idx + 1; i < m_Size; i++)
            m_pElements[i - 1] = m_pElements[i];

        m_Size--;
    }

    void push_back(const T& elem) {
        m_Size++;
        adjust_capacity();
        m_pElements[m_Size - 1] = elem;
    }

    void adjust_capacity() {
        if (m_Size <= m_Capacity)
            return;

        if (m_Capacity == 0)
            m_Capacity = 1;
        else
            m_Capacity *= 2;

        m_pElements = m_pElements
            ? CMemAlloc::Get()->ReAlloc(m_pElements, m_Capacity * sizeof(T))
            : CMemAlloc::Get()->Alloc<T>(m_Size * sizeof(T));

    }

    int size() const
    {
        return m_Size;
    }
};


im really sorry but iam really struggling and started to look in another places which is i know wrong


as u can see there is problem cuz in the game console 179 the entity is chaos_knight_chaos_bolt and in my dissect it is C_Dota_Ability_Special_bonus_Base
 
after changing my GetIdentity

and have this

Посмотреть вложение 316789
Посмотреть вложение 316790Посмотреть вложение 316791
so that means that there is too much problems

here is my CGameEntitySystem.h
CGameEntitySystem.h:
Expand Collapse Copy
#pragma once
#include "../base/Definitions.h"
#include "./CEntityIdentity.h"
#include "../base/CUtlVector.h"
#include "./Chandle.h"
#include "../base/VClass.h"
#include "../base/NormalClass.h"
#include "../base/Library.h"

#define MAX_ENTITIES_IN_LIST 512
#define MAX_ENTITY_LISTS 64 // 0x3F
#define MAX_TOTAL_ENTITIES MAX_ENTITIES_IN_LIST * MAX_ENTITY_LISTS // 0x8000

class IEntityListener {
public:
    virtual void OnEntityCreated(CBaseEntity* ent) = 0;
    virtual void OnEntitySpawned(CBaseEntity* ent) {};
    virtual void OnEntityDeleted(CBaseEntity* ent) = 0;
    virtual void OnEntityParentChanged(CBaseEntity* ent, CBaseEntity* parent) {};
};

class CEntitySystem : public VClass {
public:
    virtual void BuildResourceManifest(void) = 0; // 01
    virtual void n_2() = 0;
    virtual void n_3() = 0;
    virtual void n_4() = 0;
    virtual void n_5() = 0;
    virtual void n_6() = 0;
    virtual void AddRefKeyValues(void const*) = 0; // 7
    virtual void ReleaseKeyValues(void const*) = 0; // 8
    virtual void n_9() = 0;
    virtual void n_10() = 0;
    virtual void ClearEntityDatabase(void) = 0; // 11
    virtual CBaseEntity* FindEntityProcedural(const char *...) = 0;
    virtual CBaseEntity* OnEntityParentChanged(CBaseEntity*, CBaseEntity*) = 0; //13
    virtual CBaseEntity* OnAddEntity(CBaseEntity*, ENT_HANDLE) = 0; // 14
    virtual CBaseEntity* OnRemoveEntity(CBaseEntity*, ENT_HANDLE) = 0; // 15
    virtual void n_16() = 0;
    virtual void SortEntities(int, void*, int*, int*) = 0; // 17
    virtual void n_18() = 0;
    virtual void n_19() = 0;
    virtual void n_20() = 0;
    virtual void n_21() = 0;
};

class CGameEntitySystem : public CGameEntitySystem
{
    void* unk;
    CEntityIdentity* m_pEntityList[MAX_ENTITY_LISTS];
public:
    CEntityIdentity* GetIdentity(int index)
    {
        if (index <= -1 || index >= (MAX_TOTAL_ENTITIES - 1))
            return nullptr;

        CEntityIdentity* entity_list = m_pEntityList[(index / MAX_ENTITIES_IN_LIST)];
        if (!entity_list)
            return nullptr;

        return (entity_list + (index % MAX_ENTITIES_IN_LIST));
    }

    template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        printf("GetEntity called with index: %d\n", index);
        auto identity = GetIdentity(index);
        printf("Retrieved identity: %p\n", identity);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity)) {
            printf("Entity pointer is valid: %p\n", identity->entity);
            return (T*)identity->entity;
        }
        return nullptr;
    }

    decltype(auto) getFirstIdentity()
    {
      
        return Member<CEntityIdentity*>(0x210);
    }


    GETTER(int, GetHighestEntityIndex, 0x2100);
    FIELD(CUtlVector<IEntityListener*>, GetListeners, 0x1558);

    static CGameEntitySystem* Get() {
        if (lib.engine) {
            auto GRSC = lib.engine->LoadInterface<void>("GameResourceServiceClientV001");
            if (GRSC) {
                return static_cast<NormalClass*>(GRSC)->Member<CGameEntitySystem*>(0x58);
            }
        }
        return nullptr;
    }
};

template<typename T>
inline T* CHandle<T>::Entity() const {
    return CGameEntitySystem::Get()->GetEntity<T>(Index());
}

and here is the code iam using to get the abilities in the main.cpp

main.cpp:
Expand Collapse Copy
auto& abilities = hero->GetAbilities();
printf("DEBUG: Abilities container size: %zu\n", abilities.size());
for (const CHandle<CDOTABaseAbility>& ability : abilities) {
  
    if (!ability.IsValid()) {
        printf("DEBUG: Ability handle is invalid\n");
        continue;
    }
  
    // Get the entity pointer and validate it
    auto* abilityEntity = ability.Entity();
    if (abilityEntity == nullptr) {
        printf("DEBUG: Ability entity is null\n");
        continue;
    }
  
    // Validate the ability entity pointer
    if (!IsValidReadPtr(abilityEntity)) {
        printf("DEBUG: Ability entity pointer is invalid\n");
        continue;
    }

    auto* abilityIdentity = abilityEntity->GetIdentity();
    if (abilityIdentity == nullptr) {
        printf("DEBUG: abilityEntity->GetIdentity() returned null\n");
        continue;
    }

    // LOG THE ABILITY ENTITY / IDENTITY ADDRESSES
                printf("DEBUG: Ability entity address: %p\n", abilityEntity);
                printf("DEBUG: Ability identity address: %p\n", abilityIdentity);
  
    printf("DEBUG: --- End Ability Details ---\n\n");
 
  
}


and here is my CDOTABaseNPC.h GetAbilities() Method please make sure that iam using
CDOTABaseNPC.h:
Expand Collapse Copy
 CUtlVector<CHandle<CDOTABaseAbility>>& GetAbilities() const {
        return *MemberInline<CUtlVector<CHandle<CDOTABaseAbility>>>(Offsets.m_vecAbilities);
    }



and here is my Chandle.h File
CHandle.h:
Expand Collapse Copy
class CBaseEntity;

template<typename T = CBaseEntity>
struct CHandle {
    constexpr static uint32_t INVALID_HANDLE = 0XFFFFFFFF;

    uint32_t val;

    CHandle() : val(INVALID_HANDLE) {}
    CHandle(uint32_t val) : val(val) {}

    uint32_t Index() const {
        return val & 0x7fff;
    }

    explicit operator uint32_t() const {
        return val;
    }

    explicit operator bool() const {
        return IsValid();
    }

    T* Entity() const;

    operator T* () const {
        return Entity();
    }

    T* operator->() const {
        return Entity();
    }

    T* operator*() const {
        return Entity();
    }

    bool IsValid() const {
        return val != INVALID_HANDLE;
    }

    bool operator==(const CHandle<T> other) const {
        return other.val == val; 
    }
};

template<typename T>
std::ostream& operator<<(std::ostream& os, CHandle<T> h) {
    return os << "H[" << (*h) << "]";
}


and here is my CUTlVector.h file

CUtlVector.h:
Expand Collapse Copy
// Source engine's own analog to std::vector
template <class T>
class CUtlVector
{
public:
    uint32_t m_Size;
    T* m_pElements;
    uint32_t m_Capacity;

    T& operator[](int i) const {
        return m_pElements[i];
    }

    T& at(int i) const {
        return m_pElements[i];
    }

    T* begin() const {
        return m_pElements;
    }

    T* end() const {
        return m_pElements + m_Size;
    }

    T& first() const {
        assert(m_Size > 0 && "CUtlVector::first(): no elements");
        return m_pElements[0];
    }
    T& last() const {
        assert(m_Size > 0 && "CUtlVector::last(): no elements");
        return m_pElements[m_Size - 1];
    }

    bool empty() const {
        return m_Size == 0;
    }

    void pop_back() {
        m_Size--;
    }

    void remove_by_value(const T& elem) {
        int idx = 0;
        for (; idx < m_Size; idx++)
            if (m_pElements[idx] == elem)
                break;

        if (idx == m_Size)
            return;

        for (int i = idx + 1; i < m_Size; i++)
            m_pElements[i - 1] = m_pElements[i];

        m_Size--;
    }

    void remove_at(unsigned idx) {
        for (int i = idx + 1; i < m_Size; i++)
            m_pElements[i - 1] = m_pElements[i];

        m_Size--;
    }

    void push_back(const T& elem) {
        m_Size++;
        adjust_capacity();
        m_pElements[m_Size - 1] = elem;
    }

    void adjust_capacity() {
        if (m_Size <= m_Capacity)
            return;

        if (m_Capacity == 0)
            m_Capacity = 1;
        else
            m_Capacity *= 2;

        m_pElements = m_pElements
            ? CMemAlloc::Get()->ReAlloc(m_pElements, m_Capacity * sizeof(T))
            : CMemAlloc::Get()->Alloc<T>(m_Size * sizeof(T));

    }

    int size() const
    {
        return m_Size;
    }
};


im really sorry but iam really struggling and started to look in another places which is i know wrong


as u can see there is problem cuz in the game console 179 the entity is chaos_knight_chaos_bolt and in my dissect it is C_Dota_Ability_Special_bonus_Base
is your CEntityIdentity structure 120(0x78) bytes in size?
you need to get better at debugging. and yes, problems usually come in pairs - you solve one, you get another, this is normal
create a new temporary project(or branch if using git), but without any unnecessary garbage(like CUtlVector, chandle, etc.). just leave the code necessary for getting the entity by index(you can use cl_ent_find chaos_bolt to get the index of the chaos bolt, then hardcode that index in your code), and debug that code step by step, and also check the memory in cheat engine/reclass/x64dbg, find the entity manually and compare it to what your code does
1759206860508.png

entitysystem starting from 0x10 has pointers to entitylists
I'm looking for index 333 for example
Searching for entities with class/target name containing substrings: "chaos_bolt"
'chaos_knight_chaos_bolt' : 'chaos_knight_chaos_bolt' (entindex 333)
that's in the first list(333/512 = 0), at position 333(333 % 512 = 333)
so I multiply 333(decimal) by 0x78(that's the size of CEntityIdentity) and I get 0x9C18(written in hexadecimal, because that's what x64dbg uses mostly)
I add 0x9C18 to 0x26D3BB09448 (the first list) and I get 26D3BB13060(the identity of chaos bolt)
1759206944160.png

the entity is at 26E45BA2400
1759206994434.png

again, ISOLATE the problem. it's not CUtlVector - not abilities - not anything else - it's specifically your GetEntityByIndex stuff, so temporarily remove all that unnecessary code and work only with what's relevant
 
thanks a lot i will try and will let u know , thanks again mate
 
Скрытое содержимое
I don't use any of those;
also VClass is incompatible with virtual functions(they're mutually exclusive - VClass is for modeling virtual functions without declaring them)
remove VClass from CEntitySystem
check the layout of your CGameEntitySystem(newer VS versions have a "Memory layout" option when you hover over class name)
this is the expected layout(first member is the vtable - if you use `virtual` it's {vfptr} member, or you can explicitly specify void* vftable as the first member, or if you use VClass then it will be inherited from VClass - ALL OF THOSE ARE MUTUALLY EXCLUSIVE, USE ONLY ONE)
m_pEntityList is supposed to start at 0x10
1759243120486.png

C++:
Expand Collapse Copy
#include <Windows.h>

#include <cstdint>
#include <cstddef>
#include <format>

struct CEntityIdentity
{
    std::uint8_t pad[0x78];
};

struct CGameEntitySystem
{
    void* vftable; //VClass already has this member as the first member; `virtual` keyword creates this member as a hidden first member;
    void* unk;
    CEntityIdentity* m_pEntityList[64];
    CEntityIdentity* GetIdentity(int index)
    {
        if (index <= -1 || index >= (32768 - 1))
            return nullptr;
        CEntityIdentity* entity_list = m_pEntityList[(index / 512)];
        if (!entity_list)
            return nullptr;

        return (entity_list + (index % 512));
    }
};

BOOL APIENTRY DllMain(HMODULE, DWORD ul_reason_for_call, LPVOID)
{
    if (ul_reason_for_call == DLL_PROCESS_ATTACH)
    {
        auto const engine2 = GetModuleHandleA("engine2.dll");
        if (engine2)
        {
            auto const create_interface_fn = GetProcAddress(engine2, "CreateInterface");
            int status = 0;
            auto const GRSC = (reinterpret_cast<void* (*)(const char*, int*)>(create_interface_fn))
                ("GameResourceServiceClientV001", &status);
            if (status == 0 && GRSC)
            {
                const auto entity_system = *reinterpret_cast<CGameEntitySystem**>((char*)GRSC + 0x58);
                if (entity_system)
                {
                    OutputDebugStringA(std::format("identity @ 161: {}",
                        (void*)entity_system->GetIdentity(161)).data());
                }
            }
            else
            {
                OutputDebugStringA(std::format("CreateInterface GameResourceServiceClientV001 failure: {}",
                    reinterpret_cast<void*>(status)).data());
            }
        }
        else
        {
            OutputDebugStringA("no engine2.dll");
        }
    }
    return TRUE;
}
1759242964122.png

1759242927100.png

1759242952773.png
 
here is my CGameEntitySystem memory layout
1759385320527.png


and here is the full CGameEntitySystem.h file after the updates

CGameEntitySystem.h:
Expand Collapse Copy
#pragma once
#include "../base/Definitions.h"
#include "./CEntityIdentity.h"
#include "../base/CUtlVector.h"
#include "./Chandle.h"
#include "../base/VClass.h"
#include "../base/NormalClass.h"
#include "../base/Library.h"

#define MAX_ENTITIES_IN_LIST 512
#define MAX_ENTITY_LISTS 64 // 0x3F
#define MAX_TOTAL_ENTITIES MAX_ENTITIES_IN_LIST * MAX_ENTITY_LISTS // 0x8000
class CEntityIdentities
{
public:
    CEntityIdentity* m_pIdentities[MAX_ENTITIES_IN_LIST];
};

// The entity system utilizes listeners for the events mentioned below
// I almost feel like a Valve employee doing these things the intended way
class IEntityListener {
public:
    virtual void OnEntityCreated(CBaseEntity* ent) = 0;
    virtual void OnEntitySpawned(CBaseEntity* ent) {};
    virtual void OnEntityDeleted(CBaseEntity* ent) = 0;
    virtual void OnEntityParentChanged(CBaseEntity* ent, CBaseEntity* parent) {};
};

class CEntitySystem {
public:
    virtual void BuildResourceManifest(void) = 0; // 01
    virtual void n_2() = 0;
    virtual void n_3() = 0;
    virtual void n_4() = 0;
    virtual void n_5() = 0;
    virtual void n_6() = 0;
    virtual void AddRefKeyValues(void const*) = 0; // 7
    virtual void ReleaseKeyValues(void const*) = 0; // 8
    virtual void n_9() = 0;
    virtual void n_10() = 0;
    virtual void ClearEntityDatabase(void) = 0; // 11
    virtual CBaseEntity* FindEntityProcedural(const char *...) = 0;
    virtual CBaseEntity* OnEntityParentChanged(CBaseEntity*, CBaseEntity*) = 0; //13
    virtual CBaseEntity* OnAddEntity(CBaseEntity*, ENT_HANDLE) = 0; // 14
    virtual CBaseEntity* OnRemoveEntity(CBaseEntity*, ENT_HANDLE) = 0; // 15
    virtual void n_16() = 0;
    virtual void SortEntities(int, void*, int*, int*) = 0; // 17
    virtual void n_18() = 0;
    virtual void n_19() = 0;
    virtual void n_20() = 0;
    virtual void n_21() = 0;
};

class CGameEntitySystem
{
    void* vftable; // Explicit vftable member
    void* unk;
    CEntityIdentity* m_pEntityList[64];
public:
    CEntityIdentity* GetIdentity(int index)
    {
        if (index <= -1 || index >= (32768 - 1))
            return nullptr;
        CEntityIdentity* entity_list = m_pEntityList[(index / 512)];
        if (!entity_list)
            return nullptr;

        return (entity_list + (index % 512));
    }

    template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        printf("GetEntity called with index: %d\n", index);
        CEntityIdentity* identity = GetIdentity(index);
        printf("Retrieved identity: %p\n", identity);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity)) {
            printf("Entity pointer is valid: %p\n", identity->entity);
            return (T*)identity->entity;
        }
        return nullptr;
    }

    CEntityIdentity* getFirstIdentity() const {
        // Access the first entity in the linked list at offset 0x210
        return *reinterpret_cast<CEntityIdentity**>(reinterpret_cast<uintptr_t>(this) + 0x210);
    }

    // Method called by Main.cpp
    CBaseEntity* OnAddEntity(CBaseEntity* entity, uint32_t handle) {
        // For now, just return the entity (this might need proper implementation later)
        return entity;
    }

    // Note: These methods would need to be implemented with proper member access
    // GETTER(int, GetHighestEntityIndex, 0x2100);
    // FIELD(CUtlVector<IEntityListener*>, GetListeners, 0x1558);

    static CGameEntitySystem* Get() {
        if (lib.engine) {
            auto GRSC = lib.engine->LoadInterface<void>("GameResourceServiceClientV001");
            if (GRSC) {
                return static_cast<NormalClass*>(GRSC)->Member<CGameEntitySystem*>(0x58);
            }
        }
        return nullptr;
    }
};

template<typename T>
inline T* CHandle<T>::Entity() const {
    auto* entitySystem = CGameEntitySystem::Get();
    printf("DEBUG: CHandle::Entity() - EntitySystem pointer: %p\n", entitySystem);
    return entitySystem ? entitySystem->GetEntity<T>(Index()) : nullptr;
}

and here is my CGameEntitySystem in the cheatengine dissect

1759386380770.png

GetEntity called with index: 192
Retrieved identity: 000001DD12191E48
Entity pointer is valid: 000001DD12191E60
DEBUG: Ability entity address: 000001DD12191E60
DEBUG: Ability identity address: FFFFFFFF01A980CD
DEBUG: ---End Ability Details ---

and here is the dissect for the 000001DD12191E60 ( which is the ability entity )
1759386635093.png


here is the cl_ent_find_index 192
1759386717746.png
 
here is my CGameEntitySystem memory layout
Посмотреть вложение 316976

and here is the full CGameEntitySystem.h file after the updates

CGameEntitySystem.h:
Expand Collapse Copy
#pragma once
#include "../base/Definitions.h"
#include "./CEntityIdentity.h"
#include "../base/CUtlVector.h"
#include "./Chandle.h"
#include "../base/VClass.h"
#include "../base/NormalClass.h"
#include "../base/Library.h"

#define MAX_ENTITIES_IN_LIST 512
#define MAX_ENTITY_LISTS 64 // 0x3F
#define MAX_TOTAL_ENTITIES MAX_ENTITIES_IN_LIST * MAX_ENTITY_LISTS // 0x8000
class CEntityIdentities
{
public:
    CEntityIdentity* m_pIdentities[MAX_ENTITIES_IN_LIST];
};

// The entity system utilizes listeners for the events mentioned below
// I almost feel like a Valve employee doing these things the intended way
class IEntityListener {
public:
    virtual void OnEntityCreated(CBaseEntity* ent) = 0;
    virtual void OnEntitySpawned(CBaseEntity* ent) {};
    virtual void OnEntityDeleted(CBaseEntity* ent) = 0;
    virtual void OnEntityParentChanged(CBaseEntity* ent, CBaseEntity* parent) {};
};

class CEntitySystem {
public:
    virtual void BuildResourceManifest(void) = 0; // 01
    virtual void n_2() = 0;
    virtual void n_3() = 0;
    virtual void n_4() = 0;
    virtual void n_5() = 0;
    virtual void n_6() = 0;
    virtual void AddRefKeyValues(void const*) = 0; // 7
    virtual void ReleaseKeyValues(void const*) = 0; // 8
    virtual void n_9() = 0;
    virtual void n_10() = 0;
    virtual void ClearEntityDatabase(void) = 0; // 11
    virtual CBaseEntity* FindEntityProcedural(const char *...) = 0;
    virtual CBaseEntity* OnEntityParentChanged(CBaseEntity*, CBaseEntity*) = 0; //13
    virtual CBaseEntity* OnAddEntity(CBaseEntity*, ENT_HANDLE) = 0; // 14
    virtual CBaseEntity* OnRemoveEntity(CBaseEntity*, ENT_HANDLE) = 0; // 15
    virtual void n_16() = 0;
    virtual void SortEntities(int, void*, int*, int*) = 0; // 17
    virtual void n_18() = 0;
    virtual void n_19() = 0;
    virtual void n_20() = 0;
    virtual void n_21() = 0;
};

class CGameEntitySystem
{
    void* vftable; // Explicit vftable member
    void* unk;
    CEntityIdentity* m_pEntityList[64];
public:
    CEntityIdentity* GetIdentity(int index)
    {
        if (index <= -1 || index >= (32768 - 1))
            return nullptr;
        CEntityIdentity* entity_list = m_pEntityList[(index / 512)];
        if (!entity_list)
            return nullptr;

        return (entity_list + (index % 512));
    }

    template<typename T = CBaseEntity>
    T* GetEntity(int index)
    {
        printf("GetEntity called with index: %d\n", index);
        CEntityIdentity* identity = GetIdentity(index);
        printf("Retrieved identity: %p\n", identity);
        if (identity && IsValidReadPtr(identity) && identity->entity && IsValidReadPtr(identity->entity)) {
            printf("Entity pointer is valid: %p\n", identity->entity);
            return (T*)identity->entity;
        }
        return nullptr;
    }

    CEntityIdentity* getFirstIdentity() const {
        // Access the first entity in the linked list at offset 0x210
        return *reinterpret_cast<CEntityIdentity**>(reinterpret_cast<uintptr_t>(this) + 0x210);
    }

    // Method called by Main.cpp
    CBaseEntity* OnAddEntity(CBaseEntity* entity, uint32_t handle) {
        // For now, just return the entity (this might need proper implementation later)
        return entity;
    }

    // Note: These methods would need to be implemented with proper member access
    // GETTER(int, GetHighestEntityIndex, 0x2100);
    // FIELD(CUtlVector<IEntityListener*>, GetListeners, 0x1558);

    static CGameEntitySystem* Get() {
        if (lib.engine) {
            auto GRSC = lib.engine->LoadInterface<void>("GameResourceServiceClientV001");
            if (GRSC) {
                return static_cast<NormalClass*>(GRSC)->Member<CGameEntitySystem*>(0x58);
            }
        }
        return nullptr;
    }
};

template<typename T>
inline T* CHandle<T>::Entity() const {
    auto* entitySystem = CGameEntitySystem::Get();
    printf("DEBUG: CHandle::Entity() - EntitySystem pointer: %p\n", entitySystem);
    return entitySystem ? entitySystem->GetEntity<T>(Index()) : nullptr;
}

and here is my CGameEntitySystem in the cheatengine dissect

Посмотреть вложение 316978
GetEntity called with index: 192
Retrieved identity: 000001DD12191E48
Entity pointer is valid: 000001DD12191E60
DEBUG: Ability entity address: 000001DD12191E60
DEBUG: Ability identity address: FFFFFFFF01A980CD
DEBUG: ---End Ability Details ---

and here is the dissect for the 000001DD12191E60 ( which is the ability entity )
Посмотреть вложение 316979

here is the cl_ent_find_index 192
Посмотреть вложение 316980
for the gajillionth time, IS YOUR CENTITYIDENTITY 0x78 BYTES OR NOT
because pointer arithmetic adds sizeof's and not bytes
something tells me your sizeof(CEntityIdentity) is 0x80 instead of 0x78
 
for the gajillionth time, IS YOUR CENTITYIDENTITY 0x78 BYTES OR NOT
because pointer arithmetic adds sizeof's and not bytes
something tells me your sizeof(CEntityIdentity) is 0x80 instead of 0x78
it is 0x78 which is 120 bytes yes


CEntityIdentity.h:
Expand Collapse Copy
class CBaseEntity;

class CEntityIdentity : public VClass {
public:
    CBaseEntity* entity;
    void* dunno;
    int entHandle; // LOWORD(handle) & 0x7FFF = entID
    int unk2; // always seems to be -1
    const char* internalName; // these two strings are optional!
    const char* entityName; // ex: item_tpscroll
private:
    void* unkptr3;
public:
    union {
        char m_bFlags[4];
        DWORD m_nFlags;
    };
private:
    PAD(4);
    PAD(4 * 8);
public:
    CEntityIdentity* m_pPrev;
    CEntityIdentity* m_pNext;
    CEntityIdentity* m_pPrevByClass;
    CEntityIdentity* m_pNextByClass;
public:
    const char* GetName() const {
        return internalName ? internalName : entityName;
    }

    bool IsDormant() const {
        return (m_bFlags[0] & 0x80);
    }

    bool IsHero() const {
        const char* name = GetNameSymbol();
        return name && strstr(name, "npc_dota_hero_");
    }
    bool IsController() const {
        const char* name = GetDesignerNameSymbol();
        return name && strstr(name, "dota_player_controller");
    }
    bool IsCreep() const {
        const char* name = GetNameSymbol();
        return name && strstr(name, "npc_dota_creep_lane");
    }

    // --- Member accessors compatible with C++20 ---
    CBaseEntity* GetEntityPtr() const {
        // undocumented
        return Member<CBaseEntity*>(0x0);
    }
    CHandle<CBaseEntity> GetEntityHandle() const {
        // undocumented
        return Member<CHandle<CBaseEntity>>(0x10);
    }
    CEntityIdentity* GetNextIdentity() const {
        // CEntityIdentity* m_pNext(offset 0x60, size 0x8, align 0x8)
        return Member<CEntityIdentity*>(0x60);
    }
    const char* GetNameSymbol() const {
        // CUtlSymbolLarge m_name(offset 0x18, size 0x8, align 0x8)
        return Member<const char*>(0x18);
    }
    const char* GetDesignerNameSymbol() const {
        // CUtlSymbolLarge m_designerName(offset 0x20, size 0x8, align 0x8)
        return Member<const char*>(0x20);
    }
};[/CODE ]

should i remove the VClass usage from there right ?
yes dude thanks a lot the abilities worked now thanks a lot i really appreciate the time and effort
the problem was in my freaking CEntityIdentity thanks a lot and iam really sorry cuz of my questions
 
Последнее редактирование:
it is 0x78 which is 120 bytes yes


CEntityIdentity.h:
Expand Collapse Copy
class CBaseEntity;

class CEntityIdentity : public VClass {
public:
    CBaseEntity* entity;
    void* dunno;
    int entHandle; // LOWORD(handle) & 0x7FFF = entID
    int unk2; // always seems to be -1
    const char* internalName; // these two strings are optional!
    const char* entityName; // ex: item_tpscroll
private:
    void* unkptr3;
public:
    union {
        char m_bFlags[4];
        DWORD m_nFlags;
    };
private:
    PAD(4);
    PAD(4 * 8);
public:
    CEntityIdentity* m_pPrev;
    CEntityIdentity* m_pNext;
    CEntityIdentity* m_pPrevByClass;
    CEntityIdentity* m_pNextByClass;
public:
    const char* GetName() const {
        return internalName ? internalName : entityName;
    }

    bool IsDormant() const {
        return (m_bFlags[0] & 0x80);
    }

    bool IsHero() const {
        const char* name = GetNameSymbol();
        return name && strstr(name, "npc_dota_hero_");
    }
    bool IsController() const {
        const char* name = GetDesignerNameSymbol();
        return name && strstr(name, "dota_player_controller");
    }
    bool IsCreep() const {
        const char* name = GetNameSymbol();
        return name && strstr(name, "npc_dota_creep_lane");
    }

    // --- Member accessors compatible with C++20 ---
    CBaseEntity* GetEntityPtr() const {
        // undocumented
        return Member<CBaseEntity*>(0x0);
    }
    CHandle<CBaseEntity> GetEntityHandle() const {
        // undocumented
        return Member<CHandle<CBaseEntity>>(0x10);
    }
    CEntityIdentity* GetNextIdentity() const {
        // CEntityIdentity* m_pNext(offset 0x60, size 0x8, align 0x8)
        return Member<CEntityIdentity*>(0x60);
    }
    const char* GetNameSymbol() const {
        // CUtlSymbolLarge m_name(offset 0x18, size 0x8, align 0x8)
        return Member<const char*>(0x18);
    }
    const char* GetDesignerNameSymbol() const {
        // CUtlSymbolLarge m_designerName(offset 0x20, size 0x8, align 0x8)
        return Member<const char*>(0x20);
    }
};[/CODE ]

should i remove the VClass usage from there right ?
yes dude thanks a lot the abilities worked now thanks a lot i really appreciate the time and effort
the problem was in my freaking CEntityIdentity thanks a lot and iam really sorry cuz of my questions
yes it's not virtual at all - there is no vtable
VClass is NormalClass + vftable modelling(using virtual functions without writing all of them out sequentially)
NormalClass is member modelling(getting members by offsets without writing all of them out sequentially)
 
yes it's not virtual at all - there is no vtable
VClass is NormalClass + vftable modeling(using virtual functions without writing all of them out sequentially)
NormalClass is member modeling(getting members by offsets without writing all of them out sequentially)
i will search on it to understand it more, but thanks a lot man u are life saver!
 
Назад
Сверху Снизу