Вопрос Get the entitiy class name

Начинающий
Статус
Оффлайн
Регистрация
11 Фев 2023
Сообщения
62
Реакции[?]
0
Поинты[?]
0
ihave all entities but i just wanna understand which one is hero and which one is tower which one is creeps etc ...

he my CBaseEntity.h , CDOTABaseNPC.h
cpp:
#pragma once
enum DOTA_GC_TEAM : int {
    DOTA_GC_TEAM_GOOD_GUYS = 0,
    DOTA_GC_TEAM_BAD_GUYS = 1,
    DOTA_GC_TEAM_BROADCASTER = 2,
    DOTA_GC_TEAM_SPECTATOR = 3,
    DOTA_GC_TEAM_PLAYER_POOL = 4,
    DOTA_GC_TEAM_NOTEAM = 5,
    DOTA_GC_TEAM_CUSTOM_1 = 6,
    DOTA_GC_TEAM_CUSTOM_2 = 7,
    DOTA_GC_TEAM_CUSTOM_3 = 8,
    DOTA_GC_TEAM_CUSTOM_4 = 9,
    DOTA_GC_TEAM_CUSTOM_5 = 10,
    DOTA_GC_TEAM_CUSTOM_6 = 11,
    DOTA_GC_TEAM_CUSTOM_7 = 12,
    DOTA_GC_TEAM_CUSTOM_8 = 13,
    DOTA_GC_TEAM_NEUTRALS = 14
};

#include "../base/VClass.h"
#include "../base/NormalClass.h"
#include "../base/Definitions.h"
#include "../base/Vector.h"
#include "../base/Color.h"


#include "CEntityIdentity.h"
#include "CHandle.h"
#include "../VMI.h"

class CDOTAPlayerController;

struct CEntSchemaClassBinding {
    const char
        * binaryName, // ex: C_DOTA_Unit_Hero_Nevermore
        * serverName; // ex: CDOTA_Unit_Hero_Nevermore

    void* parent;
    const char* fullName; // ex: client.dll!C_DOTA_Unit_Hero_Nevermore
    void* idk;

    int listIndex;
    PAD(4 + 8 * 2);
};

class CBaseEntity : public VClass {
public:
    struct CModelState : public NormalClass {
        FIELD(uint64_t, MeshGroupMask, 0x198);
        GETTER(const char*, GetModelName, 0xa8);
        NormalClass* GetModel() const {
            return [I]Member<NormalClass*[/I]>(0xa0);
        };
    };

    struct CSkeletonInstance : public VClass {
        // reversed from xref: "CBaseModelEntity::SetBodygroup(%d,%d) failed: CBaseModelEntity has no model!\n"
        // last two subs are get and set
        GETTER(CBaseEntity*, GetOwner, 0x30);
        IGETTER(CModelState, GetModelState, 0x170)
    };

    CEntSchemaClassBinding* SchemaBinding() const {
        return GetVFunc(VMI::CBaseEntity::GetSchemaBinding).Call<CEntSchemaClassBinding*>();
    };

    inline static void(__fastcall* OnColorChanged)(void*) = {};

    GETTER(CEntityIdentity*, GetIdentity, 0x10);
    GETTER(int, GetHealth, 0x34c);
    GETTER(int, GetMaxHealth, 0x348);
    GETTER(DOTA_GC_TEAM, GetTeam, 0x3eb);
    GETTER(int8_t, GetLifeState, 0x350);
    GETTER(CHandle<CDOTAPlayerController>, GetOwnerEntityHandle, 0x43c);
    GETTER(CSkeletonInstance*, GetGameSceneNode, 0x330);

    bool IsAlive() const {
        return GetLifeState() == 0;
    }

    bool IsDormant() const {
        return GetIdentity() && GetIdentity()->IsDormant();
    }

    const char* GetModelName() const {
        // og's explanation:
        // CModelState has 3 CStrongHandle pointers at 0xA0 and below
        // These strong handles have a model pointer and its name
        return GetGameSceneNode()->GetModelState()->GetModelName();
    }

    bool IsSameTeam(CBaseEntity* other) const {
        return GetTeam() == other->GetTeam();
    }

    uint32_t GetHandle() const {
        auto id = GetIdentity();
        if (!IsValidReadPtr(id))
            return INVALID_HANDLE;
        return id->entHandle;
    }

    // Returns the index of this entity in the entity system
    uint32_t GetIndex() const {
        return H2IDX(GetHandle());
    }

    void SetColor(Color clr)
    {
        Field<Color>(0x5f0) = clr;
        OnColorChanged(this);
    }

    float& ModelScale() const {
        return Member<VClass*>(0x330)
            ->Field<float>(0xcc);
    }

    Vector GetPos() const {
        return Member<VClass*>(0x330)
            ->Member<Vector>(0xd0);
    }

    // In degrees from 180 to -180(on 0 it looks right)
    float GetRotation() const {
        return Member<VClass*>(0x330)
            ->Member<Vector>(0xc0).y;
    }

    // Gets the point in front of the entity at the specified distance
    Vector GetForwardVector(float dist) const {
        auto pos = GetPos();
        float rotation = GetRotation() * M_PI / 180;

        float sine = sinf(rotation), cosine = cosf(rotation);
        auto forwardVec = Vector(cosine * dist, sine * dist, 0);
        return pos + forwardVec;
    }
};


C++:
#pragma once
#include "CBaseEntity.h"
#include "CDOTAItem.h"
#include "CDOTAUnitInventory.h"
#include "CDOTAModifierManager.h"
#include "../Enums.h"

class CEconWearable;

class CDOTABaseNPC : public CBaseEntity {
public:
    inline static float(*GetAttackSpeed)(CDOTABaseNPC* npc) = nullptr;

    struct BarrierData {
        float
            maxPhys,
            maxMagic,
            maxAll,
            phys, // physical blocks damage
            magic, // blocks magical damage
            all; // blocks all forms of damage
    };

    GETTER(BarrierData, GetBarriers, 0x17E4);


    IGETTER(CDOTAModifierManager, GetModifierManager, 0xc80);

    bool HasModifier(std::string_view name) const {
        return GetModifier(name) != nullptr;
    }

    float GetPhysicalArmorValue() const {
        return GetVFunc(VMI::CDOTABaseNPC::GetPhysicalArmorValue).Call<float>(0ull);
    }

    float GetMagicalArmorValue() const {
        return GetVFunc(VMI::CDOTABaseNPC::GetMagicalArmorValue).Call<float>(0ull, 0ull);
    }

    VGETTER(float, GetIdealSpeed, VMI::CDOTABaseNPC::GetIdealSpeed);
    VGETTER(void, OnWearablesChanged, VMI::CDOTABaseNPC::OnWearablesChanged);

    bool IsTargetable() const {
        return !IsDormant() && IsAlive() && !IsWaitingToSpawn();
    }

    // JS func, uses another vtable at offset
    bool IsRoshan() const {
        return MemberInline<VClass>(0xA38)->GetVFunc(VMI::CDOTABaseNPC::IsRoshan).Call<bool>();
    }

    int GetAttackDamageMin() const { return Member<int>(0xc68) + Member<int>(0xc70); }

    float GetAttackRange() const {
        return GetVFunc(VMI::CDOTABaseNPC::GetAttackRange).Call<float>(0, 1);
    };

    GETTER(bool, IsWaitingToSpawn, 0x1510);
    GETTER(bool, IsAncient, 0xab0);
    GETTER(float, GetArmor, 0x1408);
    GETTER(float, GetBaseMagicalResistance, 0x140c);
    GETTER(const char*, GetUnitName, 0xbc8);
    GETTER(DOTAUnitAttackCapability_t, GetAttackCapabilities, 0x1184);
    GETTER(float, GetHealthRegen, 0xac0);
    GETTER(float, GetMana, 0xb00);
    GETTER(float, GetMaxMana, 0xb04);
    GETTER(float, GetManaRegen, 0xb08);
    GETTER(float, GetBaseAttackTime, 0xaf0);
    GETTER(float, GetHullRadius, 0xbb8);
    GETTER(int, GetMoveSpeed, 0xae8);
    GETTER(bool, IsMoving, 0x1528);

    FIELD(CUtlVector<CHandle<CEconWearable>>, Wearables, 0x9d0);
    FIELD(CUtlVector<CHandle<CEconWearable>>, OldWearables, 0x16e0);

    IGETTER(CDOTAUnitInventory, GetInventory, 0xfa0);

    std::span<CHandle<CDOTAItem>, 19> GetItems() const {
        return GetInventory()->GetItems();
    }

    std::span<CHandle<CDOTABaseAbility>, 35> GetAbilities() const {
        auto hAbilities = MemberInline<CHandle<CDOTABaseAbility>>(0xb28);
        return std::span<CHandle<CDOTABaseAbility>, 35>(hAbilities, 35);
    }

    CDOTABaseAbility* GetAbility(int index) const
    {
        if (index < 0 || index >= 35)
            return nullptr;

        return MemberInline<CHandle<CDOTABaseAbility>>(0xb28)[index];
    }

    CDOTABaseAbility* GetAbility(std::string_view name) const
    {
        auto abilities = GetAbilities();
        auto ability = std::find_if(abilities.begin(), abilities.end(),
            [name](auto x) {
                return x.IsValid() && x->GetIdentity()->GetName() && x->GetIdentity()->GetName() == name;
            }
        );
        return ability != abilities.end() ? *ability : nullptr;
    }

    CDOTAModifier* GetModifier(std::string_view name) const {
        auto arr = GetModifierManager()->GetModifierList();
        auto res = std::find_if(arr.begin(), arr.end(),
            [name](auto x) {
                return x->GetName() == name;
            }
        );
        return res != arr.end() ? *res : nullptr;
    }

    CDOTAItem* FindItemBySubstring(const char* str) const {
        for (const auto& item : GetItems())
            if (
                item.IsValid()
                && item->GetIdentity()->GetName()
                && strstr(item->GetIdentity()->GetName(), str)
                )
                return item;

        return nullptr;
    }

    CDOTAItem* FindItem(std::string_view name) const {
        auto items = GetItems();
        auto item = std::find_if(items.begin(), items.end(),
            [name](auto item) {
                return item.IsValid() && item->GetIdentity()->GetName() && item->GetIdentity()->GetName() == name;
            }
        );
        return item != items.end() ? **item : nullptr;
    }

    bool HasState(ModifierState state) const {
        auto unitState = Member<uint64_t>(0x1080);
        return (unitState & (1Ui64 << (int)state));
    }

    bool IsDisabled() const {
        return HasState(MODIFIER_STATE_FEARED)
            || HasState(MODIFIER_STATE_HEXED)
            || HasState(MODIFIER_STATE_MUTED)
            || HasState(MODIFIER_STATE_NIGHTMARED)
            || HasState(MODIFIER_STATE_OUT_OF_GAME)
            || HasState(MODIFIER_STATE_SILENCED)
            || HasState(MODIFIER_STATE_STUNNED)
            || HasState(MODIFIER_STATE_TAUNTED);
    }

    bool CanUseAbility(CDOTABaseAbility* ability) const {
        for (auto& ab : GetAbilities()) {
            if (ab->Member<float>(0x5b8))
                return false;
        }
        return IsAlive() &&
            ability->GetLevel() > 0
            && !IsDisabled()
            && !ability->GetCooldown()
            && ability->GetManaCost() <= GetMana()
            && !ability->IsInAbilityPhase();
    }

    Vector GetHealthBarPos() const {
        auto pos = GetPos();
        pos.z += Member<int>(0xaf8);
        return pos;
    };

    const char* GetModifiedAssetString(const char* str) const {
        return MemberInline<VClass>(0xA38)->GetVFunc(67).Call<const char*>(str);
    }

    const char* GetSmallIcon() const {
        return GetModifiedAssetString(GetIdentity()->GetName());
    }
};
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
851
Реакции[?]
335
Поинты[?]
67K
just use "your" "SchemaBinding" method(it's actually more like "GetCEntityClassNetworkInstance")?
keep in mind that both virtual indices and struct offsets may be outdated and you may have to update them.
alternatively, use netvar "client.dll/C_DOTA_BaseNPC/m_iUnitType" however that netvar only exists in C_DOTA_BaseNPC so you'd still have to initially test whether an entity is at least an C_DOTA_BaseNPC(so you'd still need to use rtti/schema/CEntityClass/vfuncs)(reading it in non-C_DOTA_BaseNPC entities will just give you unpredictable shit for results).
(it's a flag-enum, test for individual bits)
C++:
    enum class EUnitType : std::uint32_t /* not really tested much but should prob work */
    {
        kHero = 1,
        kCreepHero = 2,
        kTower = 4,
        kUnk = 8,
        kBuilding = 16,
        kAncient = 32,
        kBarracks = 64,
        kCreep = 128,
        kCourier = 256,
        kShop = 512,
        kLaneCreep = 1024,
        kBoss = 2048,
        kHallOfFame = 4096,
        kWard = 131072,
        kRoshan = 524288,
        kMiscBuilding = 1048576,
    };
 
Начинающий
Статус
Оффлайн
Регистрация
11 Фев 2023
Сообщения
62
Реакции[?]
0
Поинты[?]
0
ihave tried the Entity->SchemaBinding()->binaryName and it is giving me C_DOTAPlayerController which is not the thing i want i need
C_DOTA_Unit_Hero_Nevermore please take in mind that the entity is CBaseEntity type
and when loggin EntityHero->SchemaBinding()->binaryName please take in mind that EntityHero is of type
CDOTABaseNPC iam still getting C_DOTA_BaseNPC_Hero which is wrong too
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
851
Реакции[?]
335
Поинты[?]
67K
ihave tried the Entity->SchemaBinding()->binaryName and it is giving me C_DOTAPlayerController which is not the thing i want i need
C_DOTA_Unit_Hero_Nevermore please take in mind that the entity is CBaseEntity type
and when loggin EntityHero->SchemaBinding()->binaryName please take in mind that EntityHero is of type
CDOTABaseNPC iam still getting C_DOTA_BaseNPC_Hero which is wrong too
"your" names are simply wrong. C* are server names(mostly), C_* are client names. it's relatively "rare" for names to overlap(but it happens for some names - especially for modifiers(buffs)). the general rule is that the client employs C_* names.
your entity IS NOT CBaseEntity. it's simply named wrong. it should be C_BaseEntity. so is the name CDOTABaseNPC wrong, it should be C_DOTA_BaseNPC
ihave tried the Entity->SchemaBinding()->binaryName and it is giving me C_DOTAPlayerController which is not the thing i want i need
C_DOTA_Unit_Hero_Nevermore please take in mind that the entity is CBaseEntity type
and when loggin EntityHero->SchemaBinding()->binaryName please take in mind that EntityHero is of type
CDOTABaseNPC iam still getting C_DOTA_BaseNPC_Hero which is wrong too
also, obviously, don't confuse the player and his assigned hero - a player is somebody who controls hero(es), summons(dominated/summoned creeps), courier, etc.; his assigned(main, chosen at pick phase) hero is in netvar "client.dll/C_DOTAPlayerController/m_hAssignedHero"
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
851
Реакции[?]
335
Поинты[?]
67K
iam sorry but i didnt really understand what should i do
your message carries no information. when you go to the doctor's, do you also say "I feel shitty overall" or do you say "I'm hurting in my ..., because of ..., since ..., tried ..."?
provide context. you didn't understand: what, at which stage, why, etc.
"iam sorry but i didnt really understand what should i do" is NOT a question
 
Начинающий
Статус
Оффлайн
Регистрация
11 Фев 2023
Сообщения
62
Реакции[?]
0
Поинты[?]
0
ithought that if i use binaryName i will be getting something like this C_DOTA_Unit_Hero_Nevermore or C_DOTA_Unit_Hero_Nevermore but iam getting C_DOTAPlayerController
also i tried to get the m_iUnitType which is 0xa94 but there is nothing on this offset
so iam still at the same issue which is i wanna get the entities like C_DOTA_Unit_Hero_ArcWarden and C_DOTA_Unit_Creep or jungle creeps etc ....
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
851
Реакции[?]
335
Поинты[?]
67K
ithought that if i use binaryName i will be getting something like this C_DOTA_Unit_Hero_Nevermore or C_DOTA_Unit_Hero_Nevermore but iam getting C_DOTAPlayerController
also i tried to get the m_iUnitType which is 0xa94 but there is nothing on this offset
so iam still at the same issue which is i wanna get the entities like C_DOTA_Unit_Hero_ArcWarden and C_DOTA_Unit_Creep or jungle creeps etc ....
that's because you're trying it on a player.
also, obviously, don't confuse the player and his assigned hero - a player is somebody who controls hero(es), summons(dominated/summoned creeps), courier, etc.; his assigned(main, chosen at pick phase) hero is in netvar "client.dll/C_DOTAPlayerController/m_hAssignedHero"
m_iUnitType is C_DOTA_BaseNPC-specific, you have no right to touch it unless you made sure that the entity is C_DOTA_BaseNPC or inherits from it
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
851
Реакции[?]
335
Поинты[?]
67K
ithought that if i use binaryName i will be getting something like this C_DOTA_Unit_Hero_Nevermore or C_DOTA_Unit_Hero_Nevermore but iam getting C_DOTAPlayerController
also i tried to get the m_iUnitType which is 0xa94 but there is nothing on this offset
so iam still at the same issue which is i wanna get the entities like C_DOTA_Unit_Hero_ArcWarden and C_DOTA_Unit_Creep or jungle creeps etc ....
also, CScriptBindingPR_Entities::IsHero from 2016 has the code:
Код:
00007FFF24198410 | 48:83EC 28                 | sub rsp,28                                                             |
00007FFF24198414 | 8BCA                       | mov ecx,edx                                                            |
00007FFF24198416 | E8 15CAD1FF                | call client.7FFF23EB4E30                                               |
00007FFF2419841B | 48:85C0                    | test rax,rax                                                           |
00007FFF2419841E | 74 17                      | je client.7FFF24198437                                                 |
00007FFF24198420 | 80B8 98030000 00           | cmp byte ptr ds:[rax+398],0                                            |
00007FFF24198427 | 74 0E                      | je client.7FFF24198437                                                 |
00007FFF24198429 | 8B80 54090000              | mov eax,dword ptr ds:[rax+954]                                         |
00007FFF2419842F | 83E0 01                    | and eax,1                                                              |
00007FFF24198432 | 48:83C4 28                 | add rsp,28                                                             |
00007FFF24198436 | C3                         | ret                                                                    |
00007FFF24198437 | 32C0                       | xor al,al                                                              |
00007FFF24198439 | 48:83C4 28                 | add rsp,28                                                             |
00007FFF2419843D | C3                         | ret                                                                    |
or
C++:
entity = C_BaseEntity::Instance(argument);
if(entity->m_bIsDOTANPC) {
    return entity->m_iUnitType & EUnitTypes::kHero;
}
return false;
while current code for CScriptBindingPR_Entities::IsHero goes like this:
Код:
00007FFF2BBE7AB0 | 48:83EC 28                 | sub rsp,28                                                             |
...
00007FFF2BBE7AF4 | 8BCA                       | mov ecx,edx                                                            |
00007FFF2BBE7AF6 | E8 F520B4FF                | call client.7FFF2B729BF0                                               |
00007FFF2BBE7AFB | 48:85C0                    | test rax,rax                                                           |
00007FFF2BBE7AFE | 74 1E                      | je client.7FFF2BBE7B1E                                                 |
00007FFF2BBE7B00 | 80B8 44050000 03           | cmp byte ptr ds:[rax+544],3                                            |
00007FFF2BBE7B07 | 75 15                      | jne client.7FFF2BBE7B1E                                                |
00007FFF2BBE7B09 | 48:8D88 800A0000           | lea rcx,qword ptr ds:[rax+A80]                                         |
00007FFF2BBE7B10 | 48:8B01                    | mov rax,qword ptr ds:[rcx]                                             |
00007FFF2BBE7B13 | 48:83C4 28                 | add rsp,28                                                             |
00007FFF2BBE7B17 | 48:FFA0 18010000           | jmp qword ptr ds:[rax+118]                                             |
00007FFF2BBE7B1E | 32C0                       | xor al,al                                                              |
00007FFF2BBE7B20 | 48:83C4 28                 | add rsp,28                                                             |
00007FFF2BBE7B24 | C3                         | ret                                                                    |
or
C++:
entity = C_BaseEntity::Instance(argument);
if(byte:[entity + 0x544] == 3) {
    return static_cast<IHealthBarTarget*>(entity)->IsHero();//= entity->m_iUnitType & EUnitTypes::kHero
}
return false;
basically, C_BaseEntity still has m_bIsDOTANPC, it's just not a boolean anymore(3 = npc, everything else - not npc), and not openly described in schema anymore, and can be found @ 0x544 (right before client.dll/C_BaseEntity/m_bAnimTimeChanged).
 
Сверху Снизу