Гайд Продолжение. панорама - меню и кд абилок врагов

Shitcode lord 💩
Забаненный
Статус
Оффлайн
Регистрация
25 Ноя 2020
Сообщения
272
Реакции[?]
84
Поинты[?]
8K
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Пользователь
Статус
Оффлайн
Регистрация
8 Апр 2022
Сообщения
662
Реакции[?]
104
Поинты[?]
67K
фух заебался, давно панораму не трогал.
C++:
class CUIPanelRAII;
class CUIPanel : public VClass
{
public:
    static CUIPanelRAII Create(const std::string_view& id);
    void LoadLayout(const std::string_view& url, bool option)
    {
        CallVFunc<13>(url.data(), option);
    }
    std::string_view GetName() const noexcept
    {
        const auto result = Member<const char*>(0x10);
        if (result)
            return { result };
        return {};
    }
    void RemoveAndDeleteChildren()
    {
        CallVFunc<50>();
    }
};

class CUIPanelRAII
{
public:
    CUIPanel& panel;
    ~CUIPanelRAII() noexcept
    {
        try {
            panel.RemoveAndDeleteChildren();
        }
        catch (...) {}
    }
};

class CPanel2D : public VClass
{
public:
    auto& GetUI()
    {
        auto result = Member<CUIPanel*>(0x8);
        if(!result)
            throw std::runtime_error{ "CPanel2D::GetUI returned nullptr!" };
        return *result;
    }
};

class CTopLevelWindowSource2 : public VClass
{
public:
    std::string_view GetName() const noexcept
    {
        const auto result = Member<const char*>(0x160);
        if (result)
            return { result };
        return {};
    }
   
    CUIPanel& GetPanoramaView() const
    {
        if (const auto intermediate_result = Member<CUIPanel**>(0x88); intermediate_result)
            if (const auto result = *intermediate_result; result)
                return *result;
        throw std::runtime_error{ "CTopLevelWindowSource2::GetPanoramaView is nullptr!" };
    }
};

class CUIEngineSource2 : public VClass
{
public:
    auto& GetTopLevelWindows() const noexcept
    {
        return Member<CUtlVector<CTopLevelWindowSource2*>>(0x60);
    }
    auto& GetDotaHUD()
    {
        const auto& windows = GetTopLevelWindows();
        if (
            const auto match = std::ranges::find_if(windows, [](const auto& window)
                {
                    if(window)
                        return window->GetName() == "DotaHud";
                    return false;
                });
            match != windows.end() && match != nullptr
            )
            if(const auto ptr = *match; ptr)
                return *ptr;

        throw std::runtime_error{"DotaHud top level window not found!"};
    }

    auto MakeSymbol(const std::string_view& string) const
    {
        return CallVFunc<120, std::uint16_t>(string.data());
    }
protected:
    friend class CUIPanel;
    auto& CreatePanel(const std::string_view& symbol_str, const std::string_view& id, const CUIPanel& parent)
    {
        const auto symbol = MakeSymbol(symbol_str);
        auto result = CallVFunc<29, CPanel2D*>(&symbol, id.data(), &parent);
        if(!result)
            throw std::runtime_error{ "PanoramaUI::CreatePanel returned nullptr!" };
        return *result;
    }
};

class CPanoramaUIEngine : public VClass
{
public:
    static auto& Create()
    {
        static auto ptr = CreateInterface<CPanoramaUIEngine*>("panorama.dll", "PanoramaUIEngine");
        return *ptr;
    }
    CUIEngineSource2& GetPanoramaSource2()
    {
        auto result = Member<CUIEngineSource2*>(0x28);
        if (!result)
            throw std::runtime_error{"PanoramaUI::CUIEngineSource2 is nullptr!"};
        return *result;
    }
};

CUIPanelRAII CUIPanel::Create(const std::string_view& id)
{
    auto& panorama = CPanoramaUIEngine::Create().GetPanoramaSource2();
    return { panorama.CreatePanel("Panel", id, panorama.GetDotaHUD().GetPanoramaView()).GetUI() };
}
инит
C++:
Logger::Create();
            Logger::LogMessage("Injected at %s\n", FormatCurrentTime().data());

            BenchmarkTimePoint Init{};

            BenchmarkTimePoint patterns{};
            PatternDB::ScanPatterns();
            Logger::LogTiming("Pattern scan took %sms\n", patterns.GetElapsedMillisecondsAsString().data());

            auto& panorama = CPanoramaUIEngine::Create().GetPanoramaSource2();
            Logger::LogInfo("CPanoramaUIEngine: 0x%p\n", &CPanoramaUIEngine::Create());
            Logger::LogInfo("CUIEngineSource2: 0x%p\n", &panorama);
            CTopLevelWindowSource2& dotahud = panorama.GetDotaHUD();

            Logger::LogInfo("DotaHUD CTopLevelWindowSource2: 0x%p\n", &dotahud);
            Logger::LogInfo("DotaHUD CUIPanel: 0x%p\n", &dotahud.GetPanoramaView());

            auto my_panel_raii = CUIPanel::Create("MyTestPanel");
            Logger::LogInfo("MyTestPanel CUIPanel: 0x%p\n", &my_panel_raii.panel);
            my_panel_raii.panel.LoadLayout(R"xml(file://{resources}/mypanel.xml)xml", false);

            Logger::LogTiming("Initialization took %sms\n", Init.GetElapsedMillisecondsAsString().c_str());
       
            AwaitEjection();
            Logger::LogMessage("Ejected at %s\n", FormatCurrentTime().c_str());
Посмотреть вложение 196601
через файлики решил грузиться. файлик(mypanel.vxml_c) положил в dota 2 beta\game\dota\panorama(это {resources}).
компилил так(не знаю есть ли способы легче не занимался особо этой хуйней, так для теста):
скачал воркшоп тулс в стиме(это длс для доты)
скачал
Пожалуйста, авторизуйтесь для просмотра ссылки.
шаблонную кастомку кр4(и закинул файлы куда надо из архива), потом зашел в dota 2 beta\content\dota_addons\barebones\panorama, закинул туда свой файлик(mypanel.xml)(<root><Panel><Label text="GayPanel"/></Panel></root>), потом зашел в dota 2 beta\content\dota_addons\barebones\panorama\layout\custom_game\custom_ui_manifest.xml там ближе к концу добавил строчку
<CustomUIElement type="Hud" layoutfile="file://{resources}/mypanel.xml" />
она подгружает мой хмл файлик в кастомку(нужно чтобы он скомпилился иначе его заингорит габен при сборке кастомки)
потом запускаю доту с тулсами(со стима) выбираю barebones, захожу в хаммер, file->open->dota 2 beta\content\dota_addons\barebones\maps\playground.vmap, дальше f9(или file->build map...) жду
дальше забираю свое говно из C:\Users\user\Desktop\Programs\Steam\steamapps\common\dota 2 beta\game\dota_addons\barebones\panorama
кидаю в dota 2 beta\game\dota\panorama
можешь свой cutlvector дать? если отсюда брать
Пожалуйста, авторизуйтесь для просмотра ссылки.
там куча ошибок и нету .end как у тебя
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
можешь свой cutlvector дать? если отсюда брать
Пожалуйста, авторизуйтесь для просмотра ссылки.
там куча ошибок и нету .end как у тебя
так сделай begin и end брат
юзай простейшие итераторы встроенные через указатели
C++:
template< class T>
class CUtlVector
{
    int m_nAllocationCount{ 0 };
    T* m_pMemory{ nullptr };
    int m_nAllocSize{ 0 };
public:
    auto size() const noexcept
    {
        return m_nAllocationCount;
    }

    T* begin() const
    {
        return m_pMemory;
    }

    T* end() const noexcept
    {
        return m_pMemory + m_nAllocationCount;
    }
};
 
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
У меня такой короткий вопрос, почему у габена инфа(описание функции) отличается от фактического действия(то что происходит)?

CreatePanel third param (id) must be string or undefined

тоесть по габеналогике Type, parent, ID

Я сижу как даун всё делаю как написано и получаю 0 и сижу в ахуе, пока не додумался поставить БП и посмотреть как Дота делает.

А делает она всё наоборот
Type,ID, Parent (Возможно так было в гайде, но я подумал что гайд устаревший и решил делать так, как написано в длл )
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K

Я так понимаю GetContextPanel это *CUIengineSource + 0x2F8 ( v1, CurrentContext ) ?
да она по факту не нужна на самом деле.
вместо этого создавай свою главную панельку(к которой ты всех своих детей будешь прикреплять) внутри DotaHud какого-нибудь и всё
 
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
C++:
DeleteAsync это
CPanel2D::DeleteAsyncPanel = GetAbsoluteAddress(Panel2D->VirtualMethod(42) + 0x735, 3, 7);
Не могу никак найти в libpanoram-е что-то такое как DeleteASyncPanel смотрел на индекс 40,41,42,43,44, чтобы понять, что там лежит.


Окей, я нашел. она была в клиенте. Только она почему то не принимает float, как libclient.dylib
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
C++:
DeleteAsync это
CPanel2D::DeleteAsyncPanel = GetAbsoluteAddress(Panel2D->VirtualMethod(42) + 0x735, 3, 7);
Не могу никак найти в libpanoram-е что-то такое как DeleteASyncPanel смотрел на индекс 40,41,42,43,44, чтобы понять, что там лежит.


Окей, я нашел. она была в клиенте. Только она почему то не принимает float, как libclient.dylib
CPanel2D находится в клиенте. CUIPanel находится в панораме.
кстати(по крайней мере раньше так было) у CUIPanel есть виртуальный метод panorama::CUIPanel::RemoveAndDeleteChildren
 
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
CPanel2D находится в клиенте. CUIPanel находится в панораме.
кстати(по крайней мере раньше так было) у CUIPanel есть виртуальный метод panorama::CUIPanel::RemoveAndDeleteChildren
52-й индекс что-то лежит с хрефом RemoveAndDeleteChildren.


Но ведь если я правильно перешел по хрефам и т.д, то это и должна быть функция DeletePanel
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Я правильно получаю StyleOffset? (И панельтип оффсет?)

//old VVV
C++:
    auto CUIEngineSource2::MakeSymbol(const std::string_view& string) const
    {
        std::uint16_t result{};
        CallVFunc<120>(&result, string.data());
        return result;
    }
бля хахаха а что значит
if(result) return result;
return 0;
так если у тебя result == 0 то return result и так вернет 0
 
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
//old VVV
C++:
    auto CUIEngineSource2::MakeSymbol(const std::string_view& string) const
    {
        std::uint16_t result{};
        CallVFunc<120>(&result, string.data());
        return result;
    }
бля хахаха а что значит
if(result) return result;
return 0;
так если у тебя result == 0 то return result и так вернет 0
Это я для себя, для отладки больше говнеца вписал. Чтобы было проще бпшки ставить и дебажить, если вдруг что не так пойдёт.



На 120-м индексе лежит такая функция(которую и ты по сути вызываешь,но я как даун сейчас по сиге вызываю, потом сделаю через вмт)

1662923387762.png

Я вызываю саму GetPanelType, которая вовзращает свежое значение( хуй знает зачем тот 0 в начале, но я делаю как игра делает и мне заебись )



Так, ты и не ответил, это такие должны быть числа( ну более менее) ?


И теперь с этим вот индексом(ну тоесть Style оффсетом) я теперь должен вызвать:
C++:
CUIPanel::BSetProperty(&StyleOffset,"html dota code") ;
?
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Это я для себя, для отладки больше говнеца вписал. Чтобы было проще бпшки ставить и дебажить, если вдруг что не так пойдёт.



На 120-м индексе лежит такая функция(которую и ты по сути вызываешь,но я как даун сейчас по сиге вызываю, потом сделаю через вмт)

Посмотреть вложение 220658

Я вызываю саму GetPanelType, которая вовзращает свежое значение( хуй знает зачем тот 0 в начале, но я делаю как игра делает и мне заебись )



Так, ты и не ответил, это такие должны быть числа( ну более менее) ?


И теперь с этим вот индексом(ну тоесть Style оффсетом) я теперь должен вызвать:
C++:
CUIPanel::BSetProperty(&StyleOffset,"html dota code") ;
?
эти числа могут быть любыми(ну всмысле хуй знает какие они будут, это не захардкоженные константы). это индекс в таблице строк. габен строки в таблице хранит для экономии места
 
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
эти числа могут быть любыми(ну всмысле хуй знает какие они будут, это не захардкоженные константы). это индекс в таблице строк. габен строки в таблице хранит для экономии места
FrameUpdate ошибка
 
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
Спасибо Liberalist

Окей, я чето наделал и вроде теперь не выскакивает ошибка.

Вообще не видно почти


Хз, может ли быть что я изменил НА

ИЗ
 
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
Liberalist компилить файлики можно чуть проще, нужен только Workshop Tools DLC.
Скомпиленные будут в "C:\Program Files (x86)\Steam\steamapps\common\dota 2 beta\game\dota_addons\custom".

Bash:
@echo off
set Compiler="C:\Program Files (x86)\Steam\steamapps\common\dota 2 beta\game\bin\win64\resourcecompiler.exe"
set ModSrc="C:\Program Files (x86)\Steam\steamapps\common\dota 2 beta\content\dota_addons\custom\*.*"
%Compiler% -vpkincr -i %ModSrc% -f -r
Этот способ компиляции еще работает? Ты лично проверял? И если не секрет, сурсы кинешь?(Не свои,а откуда узнал о таком методе компиляции)
 
Пользователь
Статус
Оффлайн
Регистрация
8 Апр 2022
Сообщения
662
Реакции[?]
104
Поинты[?]
67K
так сделай begin и end брат
юзай простейшие итераторы встроенные через указатели
C++:
template< class T>
class CUtlVector
{
    int m_nAllocationCount{ 0 };
    T* m_pMemory{ nullptr };
    int m_nAllocSize{ 0 };
public:
    auto size() const noexcept
    {
        return m_nAllocationCount;
    }

    T* begin() const
    {
        return m_pMemory;
    }

    T* end() const noexcept
    {
        return m_pMemory + m_nAllocationCount;
    }
};
а из строки больше никак лайаут не загрузишь? больше нету вроде как LoadLayoutFromStringAsync, просто чтобы сделать обычную абилити панель получается понадобится делать .xml файл для каждой абилки что-ли?
прям очень нужно из строки грузить
А еще есть ли какой то парент, который и в меню и в игре есть? Дотахуд только в игре
кстати ещё не очень пойму зачем тут raii делать? типо если панель не создалась, то в любом случае либо крашет либо в игру перезаходить(само всё очистится)
 
Последнее редактирование:
Начинающий
Статус
Оффлайн
Регистрация
30 Мар 2020
Сообщения
324
Реакции[?]
24
Поинты[?]
12K
Удалось скомпилить способом Wolf49406.
Вот такой вот код:
C++:
<root><Panel style="background-color:#cf7c76;width:250px;height:250px;background-position:right top;text-align: center;font-size: 15;"><Label text="Sample Text" /></Panel></root>
Только проблема такая, что позиция панельки не меняется да и текст почемуто на верху а не внутри квадратика(ну вернее не в центре как указанно)


Где и как можно тестить свои коды html панорамы, чтобы смотреть типа как будет выглядеть вот так а не так?
 
Участник
Статус
Оффлайн
Регистрация
23 Май 2019
Сообщения
779
Реакции[?]
331
Поинты[?]
63K
Удалось скомпилить способом Wolf49406.
Вот такой вот код:
C++:
<root><Panel style="background-color:#cf7c76;width:250px;height:250px;background-position:right top;text-align: center;font-size: 15;"><Label text="Sample Text" /></Panel></root>
Только проблема такая, что позиция панельки не меняется да и текст почемуто на верху а не внутри квадратика(ну вернее не в центре как указанно)


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


Создавал первый раз в своей жизни что-либо на языке html( ну если что оно не двигается оно просто в одной позиции стоит )
Получается всё должно быть так: создается 1 большая панель, к которой крепятся другие маленькие панельки( допустим хп бар и и мана бар ) Я пытался найти команду progress как в html, но её видимо нету в панораме.

В нашем чите, там где цикл основной мы делаем проверку, если сущность герой то мы создаем ей панель и загружаем ей вот этот вот(ниже) лейаут
и делаем:
C++:
int xPositionScreen;
int yPositionScreen;
entity->GetMainCUIPanel->GetPanel2D->GetChild(0)---> /*0 это типа самая самая главная панель, как я понял, да?*/-->SetStyle("position:{%d} px {%d}px",xPositionScreen,yPositionScreen);
C++:
Я правильно понял?

///entity->GetMainCUIPanel->GetPanel2D->GetChild(0)--->GetChild(0) это Label hero name
///entity->GetMainCUIPanel->GetPanel2D->GetChild(0)--->GetChild(1) это Panel
///entity->GetMainCUIPanel->GetPanel2D->GetChild(0)--->GetChild(2) это Panel ->GetChild(0) это Label Cur Health
///entity->GetMainCUIPanel->GetPanel2D->GetChild(0)--->GetChild(3) это Panel
///entity->GetMainCUIPanel->GetPanel2D->GetChild(0)--->GetChild(4) это Panel -> GetChild(0) это Label Cur mana

Нам ведь нужно только раз создать панельки такие в игре, при входе в катку, тоесть в начале матча, а не каждый раз когда итерирует?
html panoram
C++:
<root>
    <Panel hittest="false" style="position: 800px 500px 0px;background-color: none;width:180px;height:80px;"> 
        <Label style="text-shadow: 4px 4px 16px 3.0 #333333b0;font-weight:bold;position:7% 0% 0%;" text="npc_dota_hero_pudge"/>
        <Panel style="position: 5% 30% 0%;border: 2px solid #111111FF;background-color:#cc352d;width:160px;height:19px;"> <!-- MAX HEALTH -->
        </Panel>
        
        <Panel style="position: 5% 30% 0%;border: 2px solid #111111FF;background-color: red;width:160px;height:20px;"><!-- CUR HEALTH -->
        <Label style="position: 0% 10% 0%;color:white;font-size: 16px;" text="267/267"/>
        </Panel>
        
        <Panel style="position: 5% 55% 0%;border: 2px solid #111111FF;background-color: #0565a6;width:160px;height:20px;"> <!-- MAX MANA -->
        </Panel>
        
        <Panel style="position: 5% 55% 0%;border: 2px solid #111111FF;background-color: blue;width:160px;height:20px;"> <!-- CUR MANA -->
        <Label style="position: 0% 10% 0%;color:white;font-size: 16px;" text="267/267"/>
        </Panel>
    </Panel> 
</root>
 
Сверху Снизу