Гайд Как стать самым богатым человеком в мире в несколько строчек кода в с++ или гайд на тему Skin/Inventory Changer в Dota 2

Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
286
Реакции[?]
24
Поинты[?]
12K
Если ты такой же бедный, как я, и хочешь экипнуть шмоточки на свою любимую без встречи с банкоматом(дяди Габена), то этот гайд будет полезным для тебя.

В конечном итоге у тебя должно быть что-то такое:

(MENU)

(IN GAME)




Мой гайд складывается с двух важных штук, а именно:

1- Инвентори Ченжер - добавление шмоток в инвентарь.
2- Скин Ченжер - экипировка шмоток на героев, показывание шмоток в игре.



1 Ищем функцию, которая позволит нам создать объект вещи ( объект класса CEconItem)

Помочь в этом деле может дайлибсы, ссылку на которые вы можете найти в соседних темах. Вам нужен libclient.dylib.

Смотрите где она вызывается и берёте оттуда хрефы и идёте в client.dll и ищите что-то похожее на то, что в либе.
Могут быть разные способы вызова функции, я лично просто делаю сигу(signature) по байтам и просто юзаю популярный метод FindPattern.

Путём вызова вышеупомянотой функции, вы создадите пустую шмотку. Теперь нам нужно её заполнить информацией.

Если посмотреть на сурсы (
Пожалуйста, авторизуйтесь для просмотра ссылки.
), то увидим такие поля, как : m_ItemID, m_AccountID, m_unInventory, m_ItemDefIndex(важно) и т.д. Нам понадобится на самом деле только те которые я упомянул + некоторые которые нам нужно отреверсить самим.

Заходим в IDA ->Class Informer-> ждём пока загрузит все вмтки(в случае,если ещё не пользовались этим плагином) -> вписываем CEconItem и ищём там где будет написано вот это(нам нужно то что имеет 9 функций)


Берём любую из фунок и ставим БП в чём угодно: Cheat Engine, x64dbg, etc.
Одеваем/Снимаем шмотку в инвентаре(Желательно та которая касается героя а не курьера т.д.)
Копируем значение из регистра RCX и идём в ReClass.Описываем наш класс.


Как видим размер структуры 0x50.(Айдишку аккаунта я заменил числами из вмт, поэтому не пытайтесь найти и не кидайте;-) )
Есть ещё полезная вмт на 6 индексе(0,1,2....6) которая сдампит вам поля. Благодаря этому можно правильно описать структуру тоже, но это ваш выбор. Я лично ручонками описовал а потом как-то решил проверить, правильно ли я отреверсил класс.

Думаю вам было достаточно 1-го часа , чтоб отреверсить нужное и понять где лежит поле [uint32_t m_ItemDefIndex].
Что нужно туда вписать? Как говорит само название переменной Item Definition Index ( индекс дефиниции айтема). Где нам взять этот индекс дефиниции? Well, если вы пробовали хоть раз делать скинченжер олдовским методом VPK, то думаю вы на память помните название файла items_game.txt.

Качаем и устанавливаем GCFScape.


Открываем и ищем(и открываем)
X:\SteamLibrary\steamapps\common\dota 2 beta\game\dota\pak01_dir.vpk

идём по пути \scripts\items\items_game.txt







Делаем магию экстракта и запускаем в формате текстового документа(рекомен. Notepad++)

Как называется ваша любимая шмотка в доте на английском языке? Моя аркана на секси фантомку, поэтому ищем CTRL+F -> Manifold Paradox

Мы видим на скрине дефиницию под индексом 7247,которая описывает нашу аркану(назваание,префаб,картинка,редкость, стили и т.д.)

Если покрутить выше-ниже то мы увидим что есть какая очерёдность, типа сверху будет 7246,а ниже 7248. В общем это и есть индекс дефиниции( в нашем случае ItemDefIndex арканы на фантомку будет 7247)


Следущее поле после дефиниции индекса которое нам понадобится это АккаунтАйди(а также SOID_t
C++:
struct SOID_t
{
    UINT64 SteamID;
    UINT32 Type;
};
структуру, которая нам понадобиться при добавлении шмотки в кэш). Его можна "вытащить" из разных мест, но лично я беру его из объекта CDOTAPlayerInventory (
Пожалуйста, авторизуйтесь для просмотра ссылки.
). Как нам получить CDOTAPlayerInventory? Просто, берёшь и получаешь либо вручную, либо через вмт(не помню индекса))
C++:
class CDOTAPlayerInventory;

class CDOTAInventoryManager
{
public:

CDOTAPlayerInventory*
{
return (CDOTAPlayerInventory*)((uintptr_t)this + OFFSET_ИЩЕМ_С_ПОМОЩЬЮ_РЕКЛАССА) // C Style но похуй, не умею я пользоватся reinterpret_cast-ом
}// не дереференсим иначе получим VMT-шку.
Ты возможно хочешь сказать, ладно я не тупой я понял, как получить инвентарь игрока, он лежит в менеджере, но как же получить менджер, так вот....сам открываешь либу (client.dll) и ищешь что-либо связанное с InventoryManager, смотришь хрефы(если вдруг не понял что такое хрефы,то это строки ) либо
- поможет хреф "welcome_equip_seasonal_terrain" в IDA (client.dll)


EconItemSystem или EconItemSchema получаешь через хреф "scripts/items/items_game.txt" , смотришь кто вызывает(ну логично что в параметр rcx будет this(EconItemSystem))


Нам нужно получить объект CDOTAItemDefinition, чтобы из него брать всякие штуки позже, если нужно будет.
Делаем так само как мы делали в CEconItem( берём любую функу из вмт и ставим БП, я бы порекомендовал взять ту которая голубым цветом подсвечивается). Не хотел заново загружать дбшку новую, поэтому халявщики ловите немножко отревершеную вмт(мб wrong )

А, забыл сказать,скачайте себе FunctionStringAssociate на IDA. Полезная хуйня для реверсинга! Это чтоб видеть какие хрефы внутри функции(как видите выше на скрине)

По сути нам ток надо поле uint32_t m_itemDefIndex (оно лежит где-то между 0x8 - 0x18 поищите, пореверсите)



Есть функа CDOTAItemSchema::GetItemDefinitionByIndex,которую найдёте по хрефу

(Если лень делать сигу на функу то можна и самому ребилднуть функцию)

C++:
class ItemDefList
{
public:
    uint32_t ItemDefIndex; //0x0000
    uint32_t unk; //0x0004
    CDOTAItemDefinition* ItemDefinition; //0x0008
    int unk0; //0x0010
    uint32_t unk1; //0x0014
}; //Size: 0x0018

class CEconItemSchema
{
public:
    void* VMT; //0x0000
    void* N00000344; //0x0008
    void* N00000345; //0x0010
    void* N00000346; //0x0018
    void* N00000347; //0x0020
    void* N00000348; //0x0028
    void* N00000349; //0x0030
    void* N0000034A; //0x0038
    void* N0000034B; //0x0040
    uint64_t ItemDefsa; //0x0048
    ItemDefList* ItemDefs; //0x0050
    uint64_t ItemDefsCapacity; //0x0058
    int unk;
    uint32_t ItemDefsCount;

    int GetItemsCount()
    {
        return ItemDefsa;
    }

    CDOTAItemDefinition* GetItemDefinitionByIndex(int Index)
    {
        ItemDefList* first = ItemDefs;
        ItemDefList* iter = first;
        for (int i = 0; i < ItemDefsCount; ++i)
        {

            if (!iter)
            {
                continue;
            }
            if (!iter->ItemDefinition)
            {
                continue;
            }
            if (!*(uintptr_t*)iter->ItemDefinition)
            {
                continue;
            }
            if (iter->ItemDefIndex == Index)
            {
                return iter->ItemDefinition;
            }
            iter = (ItemDefList*)((uintptr_t)first + i * 0x18);
        }
      
        return nullptr;
    }

}; // size 0x60
Не бейте палками за такую бюджетную итерацию.

Окей, здесь давайте остановимся и подсчитаем, чего мы достигли к этому моменту.

- Создавать класс CEconItem и его объект (CreateSharedObject).
- Заполнять CEconItem инфой( AccountID, DefIndex, m_NumInventory )
- Получить CDOTAInventoryManager + CDOTAPlayerInventory
- Получить объект класса CDOTAItemDefinition

Осталось 2 важных шага, чтобы всё сработало.

- Добавить нашу новосозданную и заполненою инфой шмотку в кэш (SharedObjectCache)
-Оповестить наш инвентарь о том что у нас есть шмотка.

Внутри CDOTAGCClientSystem лежит указатель на SharedObjectCache (посмотрите реклассом)
CDOTAGCClientSystem получаем через хреф "cache_%u_%u.soc", там есть функа которая ретёрнит указатель( подсказка, где-то перед концом v6 = )

Теперь добавляем в наш кэш нашу шмотку при помощи вмтшной функции(если что индекс в client.dll будет либо -1 либо +1, помните это!)


И finally оповещаем инвентарь о наших действиях при помощи

Не забываем что если видим две точки то обычно это означает что в регистре RCX лежит указатель this

CDOTAPlayerInventory->SOCReated(soid*,CEconItem*,ESOCacheEvent::Incremental);

C++:
enum ESOCacheEvent
{

    /// Dummy sentinel value
    eSOCacheEvent_None = 0,

    /// We received a our first update from the GC and are subscribed
    eSOCacheEvent_Subscribed = 1,

    /// We lost connection to GC or GC notified us that we are no longer subscribed.
    /// Objects stay in the cache, but we no longer receive updates
    eSOCacheEvent_Unsubscribed = 2,

    /// We received a full update from the GC on a cache for which we were already subscribed.
    /// This can happen if connectivity is lost, and then restored before we realized it was lost.
    eSOCacheEvent_Resubscribed = 3,

    /// We received an incremental update from the GC about specific object(s) being
    /// added, updated, or removed from the cache
    eSOCacheEvent_Incremental = 4,

    /// A lister was added to the cache
    /// @see CGCClientSharedObjectCache::AddListener
    eSOCacheEvent_ListenerAdded = 5,

    /// A lister was removed from the cache
    /// @see CGCClientSharedObjectCache::RemoveListener
    eSOCacheEvent_ListenerRemoved = 6,
};

Кстате, рекомендую вызывать все функи в основном трэде. В ваших хуках фрейма и т.д. и т.п..


Лично я вот так добавляю:
C++:
for (int i = 0; i < g_CDOTAItemSchema->GetItemsCount(); ++i)
            {
                auto itemdef = g_CDOTAItemSchema->GetItemDefinitionByIndex(i);
                if (!itemdef)
                {
                    continue;
                }
                auto Object = CreateSharedObjectEconItem();

                Object->m_ItemID = i + 100;
                Object->m_numInventory = i + 1;
                Object->m_DefIndex = itemdef->DefinitionIndex;
                Object->m_unStyle = 0;
                Object->m_AccountID = g_InventoryManager->GetPlayerInventory()->soid.SteamID;
                g_DOTAGCClientSystem->SOCache->AddObject(Object);

                g_InventoryManager->GetPlayerInventory()->SOCreated(&g_InventoryManager->GetPlayerInventory()->soid, Object, ESOCacheEvent::eSOCacheEvent_Incremental);
             

            }
Я знаю, что там возможно много лишнего наделал, но ничего страшного не случилось. Знаете как лучше сделать? Делайте, как знаете.Я всеголишь делюсь знаниями как Хермеус Мора ака Святой Деоген.




2. Мы добавили шмотки в инвентарь, но мы не можем их экипнуть(одеть, надеть, опробовать, и т.д.) Когда мы одеваем что-либо мы делаем запрос на сервер Валве с просьбой, чтоб можна одеть шмотку либо шмотки). Наша задача состоит в том, чтобы перехватить эту отправку запроса и ничего не высылать, а сделать ответ(give myself green light)



Делаем вмт хуки на

EGCResults ISteamGameCoordinator::SendMessage(uint32_t unMsgType, const void* pubData, uint32_t cubData) = 0;


bool ISteamGameCoordinator::IsMessageAvailable(uint32_t* pcubMsgSize) = 0;

EGCResults ISteamGameCoordinator::RetrieveMessage(uint32_t* punMsgType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize) = 0;



m_pSteamGameCoordinator можна получить из CGCClient, который может быть получен при помощи CreateInterface("DOTA_CLIENT_GCCLIENT");

Нам также нужно получить коллбек на OnGCMessageAvailable(); ( xref in client.dll "Recv msg %u (%s), %u bytes\n" )
чтоб заставить доту проверить наше сообщение(ответ).


Подключаем протобафы к нашему проекту( https://yougame.biz/threads/245652/ )

И обрабатываем наши хуки:

C++:
class ItemEquipped
{
public:

    uint16_t HeroClass;
    uint16_t HeroSlot;
    uint32_t ItemDefIndex;
};
std::vector<ItemEquipped*> vecItemEquipped;

EGCResults SendMessagehk(ISteamGameCoordinator* thisptr, uint32_t unMsgType, ProtoBufMsgHeader_t* pubData, uint32_t cubData)
{
    if (!g_GCClient || !g_GCClient->m_pSteamGameCoordinator)
    {
        return EGCResults::k_EGCResultNotLoggedOn;
    }
    int MessageType = unMsgType & 0x7FFFFFFF;
    if (MessageType == k_EMsgClientToGCEquipItems) //EGCItemMsg::k_EMsgClientToGCEquipItems
    {
       

        CMsgClientToGCEquipItems message;

        int Headersize = pubData->m_cubProtoBufExtHdr + sizeof(ProtoBufMsgHeader_t);

        if (message.ParsePartialFromArray((const void*)((uintptr_t)pubData + Headersize), cubData - Headersize))
        {

            auto _class = message.equips().at(0).new_class();
            auto _slot = message.equips().at(0).new_slot();
            auto item = (C_EconItem*)g_InventoryManager->GetPlayerInventory()->GetItem(message.equips().at(0).item_id());
            if (item)
            {
                int sizeofclass = sizeof(C_EconItem);

           
                item->Equip(_class, _slot);
                ItemEquipped* ie = (ItemEquipped*)g_pMemAlloc->Alloc(sizeof(ItemEquipped));//new ItemEquipped();
                ie->HeroClass = _class;
                ie->HeroSlot = _slot;
                ie->HeroSlot = g_InventoryManager->GetSlotForHero(_class,_slot);
               
                ie->ItemDefIndex = item->m_DefIndex;
                 auto slots = g_InventoryManager->GetItemSlotsForHero(ie->HeroClass);
                vecItemEquipped.push_back(ie);
                g_InventoryManager->GetPlayerInventory()->SOUpdated(&g_InventoryManager->GetPlayerInventory()->soid, (CSharedObject*)item, eSOCacheEvent_Incremental);



                CMsgClientToGCEquipItemsResponse newmessage;

                newmessage.set_so_cache_version_id(1);
                auto size = newmessage.ByteSizeLong();
                CMsgProtoBufHeader origheader; // original
                CMsgProtoBufHeader header; // fakeheader
                if (pubData->m_cubProtoBufExtHdr > 0)
                {
                    if (origheader.ParsePartialFromArray((const void*)((ui)pubData + sizeof(ProtoBufMsgHeader_t)), pubData->m_cubProtoBufExtHdr))
                    {
                        if (origheader.has_job_id_source())
                            header.set_job_id_target(origheader.job_id_source());
                    }
                    else
                    {
                        ConColorMsg(&ColorABGR.Red, "Error in Parsing Message\n");
                    }
                }
                else
                {
                    ConColorMsg(&ColorABGR.Red, "Error in SendMessage\n");
                }
                auto headerSize = header.ByteSizeLong(); // size of the  header

                ProtoBufMsgHeader_t meta_header{ k_EMsgClientToGCEquipItemsResponse | 0x80000000,(UINT32)headerSize };

                std::vector<BYTE>MessageBytes;

                MessageBytes.resize(sizeof(meta_header) + newmessage.ByteSizeLong() + headerSize);


                *(ProtoBufMsgHeader_t*)MessageBytes.data() = meta_header;
                header.SerializeToArray(MessageBytes.data() + sizeof(ProtoBufMsgHeader_t), header.ByteSizeLong());
                newmessage.SerializeToArray(MessageBytes.data() + sizeof(ProtoBufMsgHeader_t) + headerSize, newmessage.ByteSizeLong());

                Messages.push(MessageBytes);

               
                bHasToCheckMessages = true;
            }
           
            return EGCResults::k_EGCResultOK;
        }

    }
    else if (MessageType == k_EMsgClientToGCSetItemStyle)
    {
         /// Пока что не интересовался стилями, кто захочет тот сделает, думаю.
    }


    return oSendMessage(thisptr, unMsgType, pubData, cubData);
}

bool hkIsMessageAvailable(ISteamGameCoordinator* thisptr, uint32_t* pcubMsgSize)
{
    if (!Messages.empty())
    {
        *pcubMsgSize = Messages.front().size();
        return true;
    }
    return oIsMessageAvailable(thisptr, pcubMsgSize);
}


EGCResults RetrieveMessage(ISteamGameCoordinator* thisptr, uint32_t* punMsgType, void* pubDest, uint32_t cubDest, uint32_t* pcubMsgSize)
{
    //int MessageType = *punMsgType & 0x7FFFFFFF;
    if (!Messages.empty())
    {
        auto message = Messages.front();

        if (cubDest < message.size())
        {
            ConMsg("small\n");
            return EGCResults::k_EGCResultBufferTooSmall;
        }
        //auto MessageHeader = reinterpret_cast<const ProtoBufMsgHeader_t*>(Message.data());
        ProtoBufMsgHeader_t* header = (ProtoBufMsgHeader_t*)(Messages.front().data());
        //header->FlagMsg();
        *punMsgType = header->m_EMsgFlagged;
        std::memcpy((void*)pubDest, (const void*)header, Messages.front().size());
        Messages.pop();

        ConMsg("dota has eaten our message\n");
        return EGCResults::k_EGCResultOK;
    }
    return oReceiveMessage(thisptr, punMsgType, pubDest, cubDest, pcubMsgSize);
}


Ну и наконец осталось токо одно сделать, заставить доту проверить наше сообщение. Путём вызова Callback'a OnGCMessageAvailable(). Я его вызываю в хуке фрейма.

C++:
if (bHasToCheckMessages)
        {


            ConMsg("Message is available\n");
            bHasToCheckMessages = false;
            oOnMessageAvailable(g_GCClient);
        }


На данном этапе мы теперь можем экипнуть ЛЮБУЮ шмотку на героя.

Важная инфа. После выхода из игры, удаляйте файлики .soc из SteamLibrary\steamapps\common\dota 2 beta\game\dota.

Иначе шмотки будут дюпатся :D. Там есть проблема с стандартными вещами, типа если вы экипнете стандарт шмот который последний в списке то будет краш, экипайте стандарт шмот который первый, который будет сверху. Поймёте короч.

Но есть одна проблема с которой я столкнулся. В демке всё работает нормально, а в лобби(на вальвовском сервере) будет стандарт шмотка.


Пофиксить было не легко.


Некоторые челы рекомендовали ловить ивент в котором он заспавнится и делать все свои действия там, но я решил не ебать себе мозг и просто захерачить как работяга
C++:
GetAsyncKeyState(VK_F1) & 1
{
Действия
}
В наших действиях должно быть такое:

- Очищаем m_hOldWearables нашей сущности (фантомки в данном случае) // credits to ExistedDim4
не сам указатель обнуляем, а значения которые он в себе хранит. Я надеюсь вы смотрели в гайд по дампу нашей легенды https://yougame.biz/threads/139802/
)
[class C_DOTA_BaseNPC ->>>>CUtlVector< CHandle< C_EconWearable > >] [m_hOldWearables] Offset 0xREVERSITE_SAMI_HAHAHAHAHHAHA

- Получаем каждую сущность внутри m_hMyWearables
[class C_BaseCombatCharacter ->>>> C_NetworkUtlVectorBase< CHandle< C_EconWearable > >] [m_hMyWearables] Offset 0x0xREVERSITE_SAMI_HAHAHAHAHHAHA.
Далее получаем AttributeContainer данной сущности
[class C_EconEntity ->>>> CAttributeContainer] [m_AttributeManager] Offset 0x960

Дампим шемой CAttributeContainer и смотрим на каком оффсете лежит C_EconItemView, это класс который вы тоже ДОЛЖНЫ задампить

Далее получаем DOTAItemDefinition по индексу внутри EconItemView(который как я сказал лежит в AttributeContainer)
, сравниваем слот и класс с тем что лежит в объектах лежащих в нашем контейнере vecItemEquipped.
C++:
for (const auto& obj : vecItemEquipped)
                {
                    if (obj->HeroSlot == definition->GetItemHeroSlot()) листайте выше, я на скрине вам раскрыл карты в вмтшке DOTAItemDefinition
                    {
                        if (obj->HeroClass == definition->GetItemHeroClass()) /// листайте выше, я на скрине вам раскрыл карты  в вмтшке DOTAItemDefinition
                        {
Если Conditions are met,то мы инитим эту же EconItemView из нашего фейкового CEconItem* который лежит в кеше, КОТОРЫЙ мы должны получить при помощи GetSharedObjectByID. Есть тысячи способ это сделать ну такш быть я пальну вам немного.

C++:
C_EconItem* CDOTAGCClientSystem::GetObjectByItemIndex(UINT32 Index)
{
    for (int i = 0; i < SOCache->CGCClientSharedObjectTypeCaches->Items->Count; i++)
    {
        auto obj = *(uintptr_t*)((uintptr_t)SOCache->CGCClientSharedObjectTypeCaches->Items->Message + i * 0x8);
        if (obj)
        {
            C_EconItem* ptr = (C_EconItem*)obj;
            if (ptr->m_DefIndex == Index)
            {
                return ptr;
            }
        }
    }
    return nullptr;
}
Я уверен, что даже существует скорее всего какая-то вмтшка, но я просто решил замутить по своему. А что, нельзя?

И так, инитим нашу C_EconItemView путём eponymous функции C_EconItemView::Init/ //// credits to ExistedDim4


C++:
InitEconItemView(ptr, fakeitem, 0); // EconItemView*,EconItem*,0
Last but not least, надо починить пару нетваров

C++:
WearableItem->SetVarBool(m_bHiddenByEquipmentSlot,false)/// Если кто вдруг уже забыл, WearableItem это сущность из LocalEntity-> m_hMyWearables[ ] в котором лежат хендлы наших шмоток, чтоб получить сущность юзайте McDota's EntitySystem
WearableItem->SetVarBool(m_bOwnerModelChanged,false)
WearableItem->SetVarBool(m_bIsGeneratingEconItem,false)
WearableItem->SetVarBool(m_bHiddenByCombiner,false)
WearableItem->SetVarBool(m_bIsItemVisibleOnGeneratedEntity,true)
а также PreDataUpdateнуть
C++:
enum DataUpdateType_t
{
    DATA_UPDATE_CREATED = 0,    // indicates it was created +and+ entered the pvs
//    DATA_UPDATE_ENTERED_PVS,
DATA_UPDATE_DATATABLE_CHANGED,
//    DATA_UPDATE_LEFT_PVS,
//    DATA_UPDATE_DESTROYED,        // FIXME: Could enable this, but it's a little worrying
                                // since it changes a bunch of existing code
};
C++:
LocalEntity->PreDataUpdate(DataUpdateType_t::DATA_UPDATE_CREATED); /// после фикса нетваров

C++:
Если работает, то индексы правильные скорее всего.
class C_BaseEntity
{
public:

    virtual void func0();//0x0
    virtual void func1();//0x8
    virtual void func2();//0x10
    virtual void func3();//0x18
    virtual void func4();//0x20
    virtual void func5();//0x28
    virtual void func6();//0x30
    virtual bool Spawn(void* ptr);//0x38
    virtual void PostDataUpdate(DataUpdateType_t);//0x40
    virtual void func9();//0x48
    virtual void func10();//0x50
    virtual void func11();//0x58
    virtual void func12();//0x60
    virtual void func13();//0x68
    virtual void PreDataUpdate(DataUpdateType_t);//0x70
}
и ещё нужно вызвать SetModel(WearableItem) которая пофиксит некоторые баги и с партиклями и с моделью. Она лежит внутри C_EconWearable::Spawn
хреф "CEntitySpawner<class CAdditionalWearable>::Spawn"
строка 163(после HexRay Decompilerинга ) , на ней функа C_EconWearable::Spawn внутри которой вам нужно взять какую-то из тех функций и вызвать.



И самый последний шаг это PostUpdate

C++:
LocalEntity->PostDataUpdate(DataUpdateType_t::DATA_UPDATE_DATATABLE_CHANGED);

На этом всё дамы и господа. Поздравляю вас. Теперь вы первый человек (мб второй хз) в мире, который имеет все шмотки в своём инвентаре,и который может понтоватся перед своими однокласниками гыгыгыгыгы. Будет норм если найдется здесь хоть 1 samaritan который реверснит стильки. Я делал когда-то но уже забыл, и впадлу. но дам подсказку что это нужно иметь дело с протобафами, в том же хуке SendMessage + RetrieveMessage :-)


Credits go to:
McDota
Legendary Liberalist
og
ExistedDim4
Morphling

Гарантирую, что простой копипастинг не спасёт человечество от Апокалипсиса aka VAC. Делаете всё на свой страх и риск.

Вродебы пересмотрел и ничего не забыл, но если что-то упустил, реверсите ёпта. А если ничего не выходит, ну тогда уж и быть оставьте сообщение ниже. Если у вас проблема с компиляцией протобафов, пж не пишите здесь а создайте отдельную тему. Я хочу чтобы в данном теме были сообщение только по отношению к ченжера.
 
Последнее редактирование:
Ревёрсер среднего звена
Пользователь
Статус
Оффлайн
Регистрация
24 Ноя 2022
Сообщения
303
Реакции[?]
106
Поинты[?]
55K
Важная инфа. После выхода из игры, удаляйте файлики .soc из SteamLibrary\steamapps\common\dota 2 beta\game\dota.
Хук на предотвращение сохранения
Пожалуйста, авторизуйтесь для просмотра ссылки.
(чуть ебано написано, удаляйте просто этот файл через путь и будет вам счастье)
 
Начинающий
Статус
Оффлайн
Регистрация
4 Апр 2024
Сообщения
23
Реакции[?]
1
Поинты[?]
1K
Далее получаем DOTAItemDefinition по индексу внутри EconItemView(который как я сказал лежит в AttributeContainer)
, сравниваем слот и класс с тем что лежит в объектах лежащих в нашем контейнере vecItemEquipped.
Все работает, но вот тут чет проблемка. Я так понимаю, slot - это индекс шмотки в инвентаре, т.е. сверху в низ от 0 до n.
Это например дефинишины СФа, при чем их вообще 7, но в 2 из 7 другой класс(т.е. не для сфа). И все >4(т.е. рабочих индексов слотов)
1720202575058.png
У Пуджа подходит больше индексов слотов и больше шмоток можно одеть, но при этом, волосы например, надеваются поверх стандартных. Оружие на левой руке даже стандартное не прорисовалось.
1720203450629.png1720203504076.png
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
286
Реакции[?]
24
Поинты[?]
12K
Все работает, но вот тут чет проблемка. Я так понимаю, slot - это индекс шмотки в инвентаре, т.е. сверху в низ от 0 до n.
Это например дефинишины СФа, при чем их вообще 7, но в 2 из 7 другой класс(т.е. не для сфа). И все >4(т.е. рабочих индексов слотов)
Посмотреть вложение 280550
У Марса вообще ни у одного дефинишина не подходит класс к его классу шмоток.
У Пуджа подходит больше индексов слотов и больше шмоток можно одеть, но при этом, волосы например, надеваются поверх стандартных. Оружие на левой руке даже стандартное не прорисовалось.
Посмотреть вложение 280556Посмотреть вложение 280557
Дружище, извини. Я гайд год назад делал я о скинченжере забыл совсем и без него играю. Очень прикольн, что ты юзаешь этот гайд значит всё еще в чем-то актуальный. Я рекомендую где-то поставить бпшку на какой-то функе и смотреть как слоты получаются. Я именно так и делал, я не ебу где это было но точно там можно где-то узнать как получить слоты. Я не уверен, что у тебя правильные слоты. Отвечаю, не уверен. чекни кстати в дайлибах, функи которые связанные сло слотами типа GetItemInSlot или GetSlotForHero что то в этом роде, там наверняка чето есть свзяанное слотами я так и искал.

апдейт. собственно я чекнул сурс в темке и вот чето надыбал

C++:
ie->HeroSlot = g_InventoryManager->GetSlotForHero(_class,_slot);
               
                ie->ItemDefIndex = item->m_DefIndex;
                 auto slots = g_InventoryManager->GetItemSlotsForHero(ie->HeroClass);
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
712
Реакции[?]
324
Поинты[?]
56K
слоты в scripts\npc\npc_heroes.txt есть если проблема чисто в слотах. ItemSlots ключ
класс итема если мы про шмот на героя говорим то он соответствует айди героя(в том же файле, HeroID)
Код:
"npc_dota_hero_nevermore"
    {
        "Model"        "models/heroes/shadow_fiend/shadow_fiend.vmdl"
        "IdleExpression"        "scenes/nevermore/nevermore_exp_idle_01.vcd"
        "SoundSet"        "Hero_Nevermore"
        "IdleSoundLoop"        "Hero_Nevermore.IdleLoop"
        "PickSound"        "nevermore_nev_spawn_11"
        "BanSound"        "nevermore_nev_anger_03"
        "Enabled"        "1"
        "BotImplemented"        "1"
        "HeroUnlockOrder"        "1"
        "Role"            "Carry,Nuker"
        "Rolelevels"    "2,3"
        "Complexity"    "2"
        "Team"        "Bad"
        "HeroID"        "11"
        "HeroOrderID"    "39"
        "ModelScale"        "0.980000"
        "VersusScale"        "0.980000"
        "LoadoutScale"        "0.98"
        "SpectatorLoadoutScale" "0.8"
        "HeroGlowColor"        "240 34 18"
        "CMEnabled"        "1"
        "NameAliases"        "sf,nevermore"
        "workshop_guide_name"        "Shadow Fiend"
        "LastHitChallengeRival"        "npc_dota_hero_lion"
        "HeroSelectSoundEffect"        "Hero_Nevermore.Pick"
        "GibType"        "ethereal"
        "GibTintColor"    "78 27 27 255"
        "new_player_enable"        "1"
        "SimilarHeroes"    "25,21,46"
        "Adjectives"
        {
            "Legs"            "0"
            "Nose"            "0"
            "Demon"            "1"
            "Flying"        "1"
            "Red"            "1"
        }
        "Ability1"        "nevermore_shadowraze1"
        "Ability2"        "nevermore_shadowraze2"
        "Ability3"        "nevermore_shadowraze3"
        "Ability4"        "nevermore_frenzy"
        "Ability5"        "nevermore_dark_lord"
        "Ability6"        "nevermore_requiem"
        "Ability7"        "nevermore_necromastery"
        "Ability10"        "special_bonus_unique_nevermore_7"
        "Ability11"        "special_bonus_unique_nevermore_4"
        "Ability12"        "special_bonus_unique_nevermore_3"
        "Ability13"        "special_bonus_unique_nevermore_2"
        "Ability14"        "special_bonus_unique_nevermore_1"
        "Ability15"        "special_bonus_unique_nevermore_6"
        "Ability16"        "special_bonus_unique_nevermore_frenzy_castspeed"
        "Ability17"        "special_bonus_unique_nevermore_raze_procsattacks"
        "Facets"
        {
            "nevermore_lasting_presence"     
            {
                "Icon"                "armor_broken"
                "Color"                "Gray"
                "GradientID"        "0"
            }           
            "nevermore_shadowmire"         
            {
                "Icon"                "slow"
                "Color"                "Red"
                "GradientID"        "0"
            }

        }
        "AbilityDraftAbilities"
        {
            "Ability1"        "nevermore_shadowraze2"
            "Ability2"        "nevermore_dark_lord"
            "Ability3"        "nevermore_necromastery"
            "Ability6"        "nevermore_requiem"
        }       
        "ArmorPhysical"        "1"
        "AttackCapabilities"        "DOTA_UNIT_CAP_RANGED_ATTACK"
        "AttackDamageMin"        "16"
        "AttackDamageMax"        "22"
        "AttackRate"        "1.6"
        "AttackAnimationPoint"        "0.500000"
        "AttackSpeedActivityModifiers"
        {
            "fast"        "175"
            "faster"    "275"
            "fastest"    "360"
        }
        "AttackAcquisitionRange"        "800"
        "AttackRange"        "525"       
        "ProjectileModel"        "particles/units/heroes/hero_nevermore/nevermore_base_attack.vpcf"
        "ProjectileSpeed"        "1200"
        "AttributePrimary"        "DOTA_ATTRIBUTE_AGILITY"
        "AttributeBaseStrength"        "19"
        "AttributeStrengthGain"        "2.700000"
        "AttributeBaseIntelligence"        "18"
        "AttributeIntelligenceGain"        "2.200000"
        "AttributeBaseAgility"        "25"
        "AttributeAgilityGain"        "3.500000"
        "StatusHealthRegen"        "0.25"
        "StatusManaRegen"    "0.3"
        "MovementSpeed"        "305"
        "MovementTurnRate"        "0.900000"
        "MovementSpeedActivityModifiers"
        {
            "fast_run"        "385"
        }
        "BoundsHullName"        "DOTA_HULL_SIZE_HERO"
        "particle_folder"        "particles/units/heroes/hero_nevermore"
        "GameSoundsFile"        "soundevents/game_sounds_heroes/game_sounds_nevermore.vsndevts"
        "VoiceFile"        "soundevents/voscripts/game_sounds_vo_nevermore.vsndevts"
        "RenderablePortrait"
        {
            "Particles"
            {
                "particles/units/heroes/hero_nevermore/nevermore_loadout.vpcf"        "loadout"
            }
        }
        "ItemSlots"
        {
            "0"
            {
                "SlotIndex"        "0"
                "SlotName"        "weapon"
                "SlotText"        "#LoadoutSlot_Weapon"
                "DisplayInLoadout" "0"
            }
            "1"
            {
                "SlotIndex"        "1"
                "SlotName"        "shoulder"
                "SlotText"        "#LoadoutSlot_Shoulder"
                "TextureWidth"        "512"
                "TextureHeight"        "512"
                "MaxPolygonsLOD0"        "4000"
                "MaxPolygonsLOD1"        "1600"
            }
            "2"
            {
                "SlotIndex"        "2"
                "SlotName"        "arms"
                "TextureWidth"        "512"
                "TextureHeight"        "512"
                "MaxPolygonsLOD0"        "4000"
                "MaxPolygonsLOD1"        "1600"
                "SlotText"        "#LoadoutSlot_Arms"
            }
            "3"
            {
                "SlotIndex"        "3"
                "SlotName"        "head"
                "SlotText"        "#LoadoutSlot_Head"
                "TextureWidth"        "512"
                "TextureHeight"        "512"
                "MaxPolygonsLOD0"        "3000"
                "MaxPolygonsLOD1"        "1200"
            }
            "4"
            {
                "SlotIndex"        "4"
                "SlotName"        "misc"
                "SlotText"        "#LoadoutSlot_Misc"
                "TextureWidth"        "256"
                "TextureHeight"        "256"
                "MaxPolygonsLOD0"        "0"
                "MaxPolygonsLOD1"        "0"
                "DisplayInLoadout" "0"
            }
            "5"
            {
                "SlotIndex"        "5"
                "SlotName"        "taunt"
                "SlotText"        "#LoadoutSlot_Taunt"
            }
            "6"
            {
                "SlotIndex"        "6"
                "SlotName"        "ambient_effects"
                "SlotText"        "#LoadoutSlot_Ambient_Effects"
                "DisplayInLoadout"        "0"
            }
        }
        "Bot"
        {
            "Loadout"
            {
                "item_tango"        "ITEM_CONSUMABLE | ITEM_SELLABLE"
                "item_flask"        "ITEM_CONSUMABLE | ITEM_SELLABLE"
                "item_branches"        "ITEM_CORE"
                "item_branches"        "ITEM_CORE"
                "item_bottle"        "ITEM_CORE | ITEM_SELLABLE"
                "item_boots"        "ITEM_CORE"
                "item_magic_stick"        "ITEM_CORE"
                "item_recipe_magic_wand"        "ITEM_CORE"
                "item_magic_wand"        "ITEM_DERIVED | ITEM_SELLABLE"
                "item_gloves"            "ITEM_CORE"
                "item_boots_of_elves"    "ITEM_CORE"
                "item_power_treads"        "ITEM_DERIVED"
                "item_blade_of_alacrity"        "ITEM_EXTENSION"
                "item_boots_of_elves"        "ITEM_EXTENSION"
                "item_recipe_yasha"        "ITEM_EXTENSION"
                "item_yasha"        "ITEM_DERIVED"
                "item_ogre_axe"        "ITEM_EXTENSION"
                "item_mithril_hammer"        "ITEM_EXTENSION"
                "item_recipe_black_king_bar"        "ITEM_EXTENSION"
                "item_black_king_bar"        "ITEM_DERIVED"
                "item_blight_stone"        "ITEM_EXTENSION"
                "item_mithril_hammer"        "ITEM_EXTENSION"
                "item_mithril_hammer"        "ITEM_EXTENSION"
                "item_desolator"        "ITEM_DERIVED"
                "item_claymore"            "ITEM_EXTENSION"
                "item_blades_of_attack"        "ITEM_EXTENSION"
                "item_recipe_lesser_crit"        "ITEM_EXTENSION"
                "item_lesser_crit"        "ITEM_DERIVED"
                "item_demon_edge"        "ITEM_LUXURY"
                "item_recipe_greater_crit"        "ITEM_LUXURY"
                "item_greater_crit"        "ITEM_DERIVED"
                "item_diadem"            "ITEM_EXTENSION"
                "item_recipe_manta"            "ITEM_EXTENSION"
                "item_manta"                "ITEM_LUXURY | ITEM_DERIVED"
                "item_talisman_of_evasion"        "ITEM_LUXURY"
                "item_claymore"        "ITEM_EXTENSION"
                "item_eagle"        "ITEM_LUXURY"
                "item_butterfly"        "ITEM_DERIVED"
            }
            "Build"
            {
                "1"        "nevermore_necromastery"
                "2"        "nevermore_shadowraze1"
                "3"        "nevermore_shadowraze1"
                "4"        "nevermore_necromastery"
                "5"        "nevermore_shadowraze1"
                "6"        "nevermore_necromastery"
                "7"        "nevermore_shadowraze1"
                "8"        "nevermore_necromastery"
                "9"        "nevermore_requiem"
                "10"        "special_bonus_attack_speed_25"
                "11"        "nevermore_dark_lord"
                "12"        "nevermore_requiem"
                "13"        "nevermore_dark_lord"
                "14"        "nevermore_dark_lord"
                "15"        "special_bonus_unique_nevermore_3"
                "16"        "nevermore_dark_lord"
                "17"        ""
                "18"        "nevermore_requiem"
                "19"        ""
                "20"        "special_bonus_unique_nevermore_2"
                "21"        ""
                "22"        ""
                "23"        ""
                "24"        ""
                "25"        "special_bonus_unique_nevermore_shadowraze_cooldown"
            }
            "HeroType"        "DOTA_BOT_HARD_CARRY"
            "LaningInfo"
            {
                "SoloDesire"        "2"
                "RequiresBabysit"        "1"
                "ProvidesBabysit"        "1"
                "SurvivalRating"        "1"
                "RequiresFarm"        "2"
                "ProvidesSetup"        "0"
                "RequiresSetup"        "1"
            }
        }
        "precache"
        {
            "particle"            "particles/econ/events/anniversary_10th/anniversary_10th_hat_ambient_npc_dota_hero_nevermore.vpcf"
        }
        "party_hat_effect"            "particles/econ/events/anniversary_10th/anniversary_10th_hat_ambient_npc_dota_hero_nevermore.vpcf"
        "showcase_attachments"
        {
            "attach_attack1"    "1"
            "attach_attack2"    "2"
            "attach_head"        "3"
        }
    }
 
Начинающий
Статус
Оффлайн
Регистрация
4 Апр 2024
Сообщения
23
Реакции[?]
1
Поинты[?]
1K
слоты в scripts\npc\npc_heroes.txt есть если проблема чисто в слотах. ItemSlots ключ
класс итема если мы про шмот на героя говорим то он соответствует айди героя(в том же файле, HeroID)
Код:
"npc_dota_hero_nevermore"
    {
        "Model"        "models/heroes/shadow_fiend/shadow_fiend.vmdl"
        "IdleExpression"        "scenes/nevermore/nevermore_exp_idle_01.vcd"
        "SoundSet"        "Hero_Nevermore"
        "IdleSoundLoop"        "Hero_Nevermore.IdleLoop"
        "PickSound"        "nevermore_nev_spawn_11"
        "BanSound"        "nevermore_nev_anger_03"
        "Enabled"        "1"
        "BotImplemented"        "1"
        "HeroUnlockOrder"        "1"
        "Role"            "Carry,Nuker"
        "Rolelevels"    "2,3"
        "Complexity"    "2"
        "Team"        "Bad"
        "HeroID"        "11"
        "HeroOrderID"    "39"
        "ModelScale"        "0.980000"
        "VersusScale"        "0.980000"
        "LoadoutScale"        "0.98"
        "SpectatorLoadoutScale" "0.8"
        "HeroGlowColor"        "240 34 18"
        "CMEnabled"        "1"
        "NameAliases"        "sf,nevermore"
        "workshop_guide_name"        "Shadow Fiend"
        "LastHitChallengeRival"        "npc_dota_hero_lion"
        "HeroSelectSoundEffect"        "Hero_Nevermore.Pick"
        "GibType"        "ethereal"
        "GibTintColor"    "78 27 27 255"
        "new_player_enable"        "1"
        "SimilarHeroes"    "25,21,46"
        "Adjectives"
        {
            "Legs"            "0"
            "Nose"            "0"
            "Demon"            "1"
            "Flying"        "1"
            "Red"            "1"
        }
        "Ability1"        "nevermore_shadowraze1"
        "Ability2"        "nevermore_shadowraze2"
        "Ability3"        "nevermore_shadowraze3"
        "Ability4"        "nevermore_frenzy"
        "Ability5"        "nevermore_dark_lord"
        "Ability6"        "nevermore_requiem"
        "Ability7"        "nevermore_necromastery"
        "Ability10"        "special_bonus_unique_nevermore_7"
        "Ability11"        "special_bonus_unique_nevermore_4"
        "Ability12"        "special_bonus_unique_nevermore_3"
        "Ability13"        "special_bonus_unique_nevermore_2"
        "Ability14"        "special_bonus_unique_nevermore_1"
        "Ability15"        "special_bonus_unique_nevermore_6"
        "Ability16"        "special_bonus_unique_nevermore_frenzy_castspeed"
        "Ability17"        "special_bonus_unique_nevermore_raze_procsattacks"
        "Facets"
        {
            "nevermore_lasting_presence"  
            {
                "Icon"                "armor_broken"
                "Color"                "Gray"
                "GradientID"        "0"
            }        
            "nevermore_shadowmire"      
            {
                "Icon"                "slow"
                "Color"                "Red"
                "GradientID"        "0"
            }

        }
        "AbilityDraftAbilities"
        {
            "Ability1"        "nevermore_shadowraze2"
            "Ability2"        "nevermore_dark_lord"
            "Ability3"        "nevermore_necromastery"
            "Ability6"        "nevermore_requiem"
        }    
        "ArmorPhysical"        "1"
        "AttackCapabilities"        "DOTA_UNIT_CAP_RANGED_ATTACK"
        "AttackDamageMin"        "16"
        "AttackDamageMax"        "22"
        "AttackRate"        "1.6"
        "AttackAnimationPoint"        "0.500000"
        "AttackSpeedActivityModifiers"
        {
            "fast"        "175"
            "faster"    "275"
            "fastest"    "360"
        }
        "AttackAcquisitionRange"        "800"
        "AttackRange"        "525"    
        "ProjectileModel"        "particles/units/heroes/hero_nevermore/nevermore_base_attack.vpcf"
        "ProjectileSpeed"        "1200"
        "AttributePrimary"        "DOTA_ATTRIBUTE_AGILITY"
        "AttributeBaseStrength"        "19"
        "AttributeStrengthGain"        "2.700000"
        "AttributeBaseIntelligence"        "18"
        "AttributeIntelligenceGain"        "2.200000"
        "AttributeBaseAgility"        "25"
        "AttributeAgilityGain"        "3.500000"
        "StatusHealthRegen"        "0.25"
        "StatusManaRegen"    "0.3"
        "MovementSpeed"        "305"
        "MovementTurnRate"        "0.900000"
        "MovementSpeedActivityModifiers"
        {
            "fast_run"        "385"
        }
        "BoundsHullName"        "DOTA_HULL_SIZE_HERO"
        "particle_folder"        "particles/units/heroes/hero_nevermore"
        "GameSoundsFile"        "soundevents/game_sounds_heroes/game_sounds_nevermore.vsndevts"
        "VoiceFile"        "soundevents/voscripts/game_sounds_vo_nevermore.vsndevts"
        "RenderablePortrait"
        {
            "Particles"
            {
                "particles/units/heroes/hero_nevermore/nevermore_loadout.vpcf"        "loadout"
            }
        }
        "ItemSlots"
        {
            "0"
            {
                "SlotIndex"        "0"
                "SlotName"        "weapon"
                "SlotText"        "#LoadoutSlot_Weapon"
                "DisplayInLoadout" "0"
            }
            "1"
            {
                "SlotIndex"        "1"
                "SlotName"        "shoulder"
                "SlotText"        "#LoadoutSlot_Shoulder"
                "TextureWidth"        "512"
                "TextureHeight"        "512"
                "MaxPolygonsLOD0"        "4000"
                "MaxPolygonsLOD1"        "1600"
            }
            "2"
            {
                "SlotIndex"        "2"
                "SlotName"        "arms"
                "TextureWidth"        "512"
                "TextureHeight"        "512"
                "MaxPolygonsLOD0"        "4000"
                "MaxPolygonsLOD1"        "1600"
                "SlotText"        "#LoadoutSlot_Arms"
            }
            "3"
            {
                "SlotIndex"        "3"
                "SlotName"        "head"
                "SlotText"        "#LoadoutSlot_Head"
                "TextureWidth"        "512"
                "TextureHeight"        "512"
                "MaxPolygonsLOD0"        "3000"
                "MaxPolygonsLOD1"        "1200"
            }
            "4"
            {
                "SlotIndex"        "4"
                "SlotName"        "misc"
                "SlotText"        "#LoadoutSlot_Misc"
                "TextureWidth"        "256"
                "TextureHeight"        "256"
                "MaxPolygonsLOD0"        "0"
                "MaxPolygonsLOD1"        "0"
                "DisplayInLoadout" "0"
            }
            "5"
            {
                "SlotIndex"        "5"
                "SlotName"        "taunt"
                "SlotText"        "#LoadoutSlot_Taunt"
            }
            "6"
            {
                "SlotIndex"        "6"
                "SlotName"        "ambient_effects"
                "SlotText"        "#LoadoutSlot_Ambient_Effects"
                "DisplayInLoadout"        "0"
            }
        }
        "Bot"
        {
            "Loadout"
            {
                "item_tango"        "ITEM_CONSUMABLE | ITEM_SELLABLE"
                "item_flask"        "ITEM_CONSUMABLE | ITEM_SELLABLE"
                "item_branches"        "ITEM_CORE"
                "item_branches"        "ITEM_CORE"
                "item_bottle"        "ITEM_CORE | ITEM_SELLABLE"
                "item_boots"        "ITEM_CORE"
                "item_magic_stick"        "ITEM_CORE"
                "item_recipe_magic_wand"        "ITEM_CORE"
                "item_magic_wand"        "ITEM_DERIVED | ITEM_SELLABLE"
                "item_gloves"            "ITEM_CORE"
                "item_boots_of_elves"    "ITEM_CORE"
                "item_power_treads"        "ITEM_DERIVED"
                "item_blade_of_alacrity"        "ITEM_EXTENSION"
                "item_boots_of_elves"        "ITEM_EXTENSION"
                "item_recipe_yasha"        "ITEM_EXTENSION"
                "item_yasha"        "ITEM_DERIVED"
                "item_ogre_axe"        "ITEM_EXTENSION"
                "item_mithril_hammer"        "ITEM_EXTENSION"
                "item_recipe_black_king_bar"        "ITEM_EXTENSION"
                "item_black_king_bar"        "ITEM_DERIVED"
                "item_blight_stone"        "ITEM_EXTENSION"
                "item_mithril_hammer"        "ITEM_EXTENSION"
                "item_mithril_hammer"        "ITEM_EXTENSION"
                "item_desolator"        "ITEM_DERIVED"
                "item_claymore"            "ITEM_EXTENSION"
                "item_blades_of_attack"        "ITEM_EXTENSION"
                "item_recipe_lesser_crit"        "ITEM_EXTENSION"
                "item_lesser_crit"        "ITEM_DERIVED"
                "item_demon_edge"        "ITEM_LUXURY"
                "item_recipe_greater_crit"        "ITEM_LUXURY"
                "item_greater_crit"        "ITEM_DERIVED"
                "item_diadem"            "ITEM_EXTENSION"
                "item_recipe_manta"            "ITEM_EXTENSION"
                "item_manta"                "ITEM_LUXURY | ITEM_DERIVED"
                "item_talisman_of_evasion"        "ITEM_LUXURY"
                "item_claymore"        "ITEM_EXTENSION"
                "item_eagle"        "ITEM_LUXURY"
                "item_butterfly"        "ITEM_DERIVED"
            }
            "Build"
            {
                "1"        "nevermore_necromastery"
                "2"        "nevermore_shadowraze1"
                "3"        "nevermore_shadowraze1"
                "4"        "nevermore_necromastery"
                "5"        "nevermore_shadowraze1"
                "6"        "nevermore_necromastery"
                "7"        "nevermore_shadowraze1"
                "8"        "nevermore_necromastery"
                "9"        "nevermore_requiem"
                "10"        "special_bonus_attack_speed_25"
                "11"        "nevermore_dark_lord"
                "12"        "nevermore_requiem"
                "13"        "nevermore_dark_lord"
                "14"        "nevermore_dark_lord"
                "15"        "special_bonus_unique_nevermore_3"
                "16"        "nevermore_dark_lord"
                "17"        ""
                "18"        "nevermore_requiem"
                "19"        ""
                "20"        "special_bonus_unique_nevermore_2"
                "21"        ""
                "22"        ""
                "23"        ""
                "24"        ""
                "25"        "special_bonus_unique_nevermore_shadowraze_cooldown"
            }
            "HeroType"        "DOTA_BOT_HARD_CARRY"
            "LaningInfo"
            {
                "SoloDesire"        "2"
                "RequiresBabysit"        "1"
                "ProvidesBabysit"        "1"
                "SurvivalRating"        "1"
                "RequiresFarm"        "2"
                "ProvidesSetup"        "0"
                "RequiresSetup"        "1"
            }
        }
        "precache"
        {
            "particle"            "particles/econ/events/anniversary_10th/anniversary_10th_hat_ambient_npc_dota_hero_nevermore.vpcf"
        }
        "party_hat_effect"            "particles/econ/events/anniversary_10th/anniversary_10th_hat_ambient_npc_dota_hero_nevermore.vpcf"
        "showcase_attachments"
        {
            "attach_attack1"    "1"
            "attach_attack2"    "2"
            "attach_head"        "3"
        }
    }
А где хранятся анимации моделей? Арканы или допустим косы фантомки от сета Алаянсов?
Я все это смог одеть, но анимации стандартные, а на некоторых арканах, типо ЦМ, там вообще анимация "лоу хп мувмента"
Вроде есть EntityModel,но не очень понятно как на нее выйти.
 
Последнее редактирование:
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
712
Реакции[?]
324
Поинты[?]
56K
А где хранятся анимации моделей? Арканы или допустим косы фантомки от сета Алаянсов?
Я все это смог одеть, но анимации стандартные, а на некоторых арканах, типо ЦМ, там вообще анимация "лоу хп мувмента"
Вроде есть EntityModel,но не очень понятно как на нее выйти.
в итемдефе в ассетмодифаерах. некоторые вещи с сервера присылаются, типа моделек
Код:
"5658"
        {
            "name"        "Gleaming Seal"
            "prefab"        "wearable"
            "branding"
            {
                "team_id"        "111474"
            }
            "creation_date"        "2013-11-06"
            "image_inventory"        "econ/items/phantom_assassin/lodas_pa_set__weapon/lodas_pa_set__weapon"
            "item_description"        "#DOTA_Item_Desc_The_Gleaming_Seal"
            "item_name"        "#DOTA_Item_Gleaming_Seal"
            "item_rarity"        "legendary"
            "item_type_name"        "#DOTA_WearableType_Honored_Scythe"
            "model_player"        "models/items/phantom_assassin/lodas_pa_set__weapon/lodas_pa_set__weapon.vmdl"
            "particle_folder"        "particles/econ/items/phantom_assassin/phantom_assassin_weapon_generic"
            "portraits"
            {
                "icon"
                {
                    "PortraitLightPosition"        "192.459381 163.687195 108.476494"
                    "PortraitLightAngles"        "34.727783 234.948120 0.000000"
                    "PortraitLightFOV"        "55"
                    "PortraitLightDistance"        "429"
                    "PortraitLightColor"        "254 254 254"
                    "PortraitShadowColor"        "97 97 97"
                    "PortraitShadowScale"        "5"
                    "PortraitGroundShadowScale"        "1.500000"
                    "PortraitAmbientColor"        "148 148 148"
                    "PortraitAmbientScale"        "5"
                    "PortraitSpecularColor"        "251 74 84"
                    "PortraitSpecularDirection"        "0.000000 0.000000 -1.000000"
                    "PortraitSpecularPower"        "16"
                    "PortraitBackgroundColor1"        "1.000000 1.000000 0.500000"
                    "PortraitBackgroundColor2"        "1.000000 1.000000 0.500000"
                    "PortraitBackgroundColor3"        "0.000000 0.000000 0.000000"
                    "PortraitBackgroundColor4"        "1.000000 0.200000 0.110000"
                    "PortraitBackgroundTexture"        "materials/vgui/econ/item_icon_bg.vmat"
                    "PortraitAnimationActivity"        "ACT_DOTA_RUN"
                    "PortraitAnimationCycle"        "0.240000"
                    "PortraitAnimationRate"        "0"
                    "PortraitHideHero"        "1"
                    "PortraitLightScale"        "1.750000"
                    "PortraitAmbientDirection"        "-63.256 82.956 -99.525"
                    "cameras"
                    {
                        "default"
                        {
                            "PortraitPosition"        "125.306160 -110.289192 182.854767"
                            "PortraitAngles"        "42.994995 138.768311 35.700073"
                            "PortraitFOV"        "90"
                            "PortraitFar"        "1000"
                        }
                    }
                }
            }
            "price_info"
            {
                "bucket"        "Normal"
                "class"        "NoPrice"
                "category_tags"        "Equipment"
                "date"        "1/13/2014"
                "price"        "0"
            }
            "used_by_heroes"
            {
                "npc_dota_hero_phantom_assassin"        "1"
            }
            "visuals"
            {
                "asset_modifier1"
                {
                    "type"        "particle"
                    "asset"        "particles/units/heroes/hero_phantom_assassin/phantom_assassin_ambient_blade.vpcf"
                    "modifier"        "particles/econ/items/phantom_assassin/phantom_assassin_weapon_generic/phantom_assassin_ambient_blade_generic.vpcf"
                }
                "asset_modifier0"
                {
                    "type"        "particle_snapshot"
                    "asset"        "particles/econ/items/phantom_assassin/phantom_assassin_weapon_generic.vsnap"
                    "modifier"        "particles/models/items/phantom_assassin/lodas_pa_set__weapon/lodas_pa_set__weapon.vsnap"
                }
                "asset_modifier2"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_IDLE"
                    "modifier"        "loda"
                }
                "asset_modifier3"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_RUN"
                    "modifier"        "loda"
                }
                "asset_modifier4"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_ATTACK"
                    "modifier"        "loda"
                }
                "asset_modifier5"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_LOADOUT"
                    "modifier"        "loda"
                }
                "asset_modifier"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_CAST_ABILITY_3"
                    "modifier"        "loda"
                }
                "asset_modifier"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_SPAWN"
                    "modifier"        "loda"
                    "style"        "0"
                }
            }
        }
 
Начинающий
Статус
Оффлайн
Регистрация
4 Апр 2024
Сообщения
23
Реакции[?]
1
Поинты[?]
1K
в итемдефе в ассетмодифаерах. некоторые вещи с сервера присылаются, типа моделек
Код:
"5658"
        {
            "name"        "Gleaming Seal"
            "prefab"        "wearable"
            "branding"
            {
                "team_id"        "111474"
            }
            "creation_date"        "2013-11-06"
            "image_inventory"        "econ/items/phantom_assassin/lodas_pa_set__weapon/lodas_pa_set__weapon"
            "item_description"        "#DOTA_Item_Desc_The_Gleaming_Seal"
            "item_name"        "#DOTA_Item_Gleaming_Seal"
            "item_rarity"        "legendary"
            "item_type_name"        "#DOTA_WearableType_Honored_Scythe"
            "model_player"        "models/items/phantom_assassin/lodas_pa_set__weapon/lodas_pa_set__weapon.vmdl"
            "particle_folder"        "particles/econ/items/phantom_assassin/phantom_assassin_weapon_generic"
            "portraits"
            {
                "icon"
                {
                    "PortraitLightPosition"        "192.459381 163.687195 108.476494"
                    "PortraitLightAngles"        "34.727783 234.948120 0.000000"
                    "PortraitLightFOV"        "55"
                    "PortraitLightDistance"        "429"
                    "PortraitLightColor"        "254 254 254"
                    "PortraitShadowColor"        "97 97 97"
                    "PortraitShadowScale"        "5"
                    "PortraitGroundShadowScale"        "1.500000"
                    "PortraitAmbientColor"        "148 148 148"
                    "PortraitAmbientScale"        "5"
                    "PortraitSpecularColor"        "251 74 84"
                    "PortraitSpecularDirection"        "0.000000 0.000000 -1.000000"
                    "PortraitSpecularPower"        "16"
                    "PortraitBackgroundColor1"        "1.000000 1.000000 0.500000"
                    "PortraitBackgroundColor2"        "1.000000 1.000000 0.500000"
                    "PortraitBackgroundColor3"        "0.000000 0.000000 0.000000"
                    "PortraitBackgroundColor4"        "1.000000 0.200000 0.110000"
                    "PortraitBackgroundTexture"        "materials/vgui/econ/item_icon_bg.vmat"
                    "PortraitAnimationActivity"        "ACT_DOTA_RUN"
                    "PortraitAnimationCycle"        "0.240000"
                    "PortraitAnimationRate"        "0"
                    "PortraitHideHero"        "1"
                    "PortraitLightScale"        "1.750000"
                    "PortraitAmbientDirection"        "-63.256 82.956 -99.525"
                    "cameras"
                    {
                        "default"
                        {
                            "PortraitPosition"        "125.306160 -110.289192 182.854767"
                            "PortraitAngles"        "42.994995 138.768311 35.700073"
                            "PortraitFOV"        "90"
                            "PortraitFar"        "1000"
                        }
                    }
                }
            }
            "price_info"
            {
                "bucket"        "Normal"
                "class"        "NoPrice"
                "category_tags"        "Equipment"
                "date"        "1/13/2014"
                "price"        "0"
            }
            "used_by_heroes"
            {
                "npc_dota_hero_phantom_assassin"        "1"
            }
            "visuals"
            {
                "asset_modifier1"
                {
                    "type"        "particle"
                    "asset"        "particles/units/heroes/hero_phantom_assassin/phantom_assassin_ambient_blade.vpcf"
                    "modifier"        "particles/econ/items/phantom_assassin/phantom_assassin_weapon_generic/phantom_assassin_ambient_blade_generic.vpcf"
                }
                "asset_modifier0"
                {
                    "type"        "particle_snapshot"
                    "asset"        "particles/econ/items/phantom_assassin/phantom_assassin_weapon_generic.vsnap"
                    "modifier"        "particles/models/items/phantom_assassin/lodas_pa_set__weapon/lodas_pa_set__weapon.vsnap"
                }
                "asset_modifier2"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_IDLE"
                    "modifier"        "loda"
                }
                "asset_modifier3"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_RUN"
                    "modifier"        "loda"
                }
                "asset_modifier4"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_ATTACK"
                    "modifier"        "loda"
                }
                "asset_modifier5"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_LOADOUT"
                    "modifier"        "loda"
                }
                "asset_modifier"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_CAST_ABILITY_3"
                    "modifier"        "loda"
                }
                "asset_modifier"
                {
                    "type"        "activity"
                    "asset"        "ACT_DOTA_SPAWN"
                    "modifier"        "loda"
                    "style"        "0"
                }
            }
        }
Так получается, что все эти активити вшиты в сам предмет т.е. анимации должны затягиваться как и эффекты? Но когда я надеваю шмотку в слот, тянется только внешка и эффекты, а анимация стандартной модели или лоу хп мувмента или анимация боя(у арканы фантомки)
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
712
Реакции[?]
324
Поинты[?]
56K
Так получается, что все эти активити вшиты в сам предмет т.е. анимации должны затягиваться как и эффекты? Но когда я надеваю шмотку в слот, тянется только внешка и эффекты, а анимация стандартной модели или лоу хп мувмента или анимация боя(у арканы фантомки)
анимации с сервера прилетают.
обычная атака
Код:
DebugString: "CDOTAUserMsg_TE_UnitAnimation [521]"
DebugString: "{"
DebugString: "entity: 2867357"
DebugString: "sequence_variant: 1"
DebugString: "playbackrate: 1.31000018"
DebugString: "castpoint: 0.229007602"
DebugString: "type: 0"
DebugString: "activity: 1503"
DebugString: "}"
атака с косой
Код:
DebugString: "CDOTAUserMsg_TE_UnitAnimation [521]"
DebugString: "{"
DebugString: "entity: 2867357"
DebugString: "sequence_variant: 3"
DebugString: "playbackrate: 1.31000018"
DebugString: "castpoint: 0.229007602"
DebugString: "type: 0"
DebugString: "activity: 1503"
DebugString: "}"
 
Сверху Снизу