iw4x-client/src/Components/Modules/UIScript.cpp

138 lines
2.7 KiB
C++
Raw Normal View History

2022-02-27 07:53:44 -05:00
#include <STDInclude.hpp>
2017-01-19 16:23:59 -05:00
namespace Components
{
2022-08-24 17:46:07 -04:00
std::unordered_map<std::string, UIScript::UIScriptHandler> UIScript::UIScripts;
std::unordered_map<int, std::function<void()>> UIScript::UIOwnerDraws;
2017-01-19 16:23:59 -05:00
2022-08-24 10:38:14 -04:00
template<> int UIScript::Token::get() const
2017-01-19 16:23:59 -05:00
{
if (this->isValid())
{
2022-08-24 10:38:14 -04:00
return std::atoi(this->token);
2017-01-19 16:23:59 -05:00
}
return 0;
}
2022-08-24 10:38:14 -04:00
template<> const char* UIScript::Token::get() const
2017-01-19 16:23:59 -05:00
{
if (this->isValid())
{
return this->token;
}
return "";
2017-01-19 16:23:59 -05:00
}
2022-08-24 10:38:14 -04:00
template<> std::string UIScript::Token::get() const
2017-01-19 16:23:59 -05:00
{
2022-08-24 10:38:14 -04:00
return {this->get<const char*>()};
2017-01-19 16:23:59 -05:00
}
2022-08-24 10:38:14 -04:00
bool UIScript::Token::isValid() const
2017-01-19 16:23:59 -05:00
{
return (this->token && this->token[0]);
}
void UIScript::Token::parse(const char** args)
{
if (args)
{
this->token = Game::Com_Parse(args);
}
}
2022-08-24 10:38:14 -04:00
Game::uiInfo_s* UIScript::UI_GetClientInfo(int localClientNum)
{
AssertIn(localClientNum, Game::STATIC_MAX_LOCAL_CLIENTS);
return &Game::uiInfoArray[localClientNum];
}
2022-08-24 17:46:07 -04:00
void UIScript::Add(const std::string& name, const UIScript::UIScriptHandler& callback)
2017-01-19 16:23:59 -05:00
{
UIScript::UIScripts[name] = callback;
}
2022-08-24 17:46:07 -04:00
void UIScript::AddOwnerDraw(int ownerdraw, const std::function<void()>& callback)
2017-01-19 16:23:59 -05:00
{
UIScript::UIOwnerDraws[ownerdraw] = callback;
}
bool UIScript::RunMenuScript(const char* name, const char** args)
{
2022-08-24 17:46:07 -04:00
if (const auto got = UIScript::UIScripts.find(name); got != UIScript::UIScripts.end())
2017-01-19 16:23:59 -05:00
{
2022-08-24 10:38:14 -04:00
const auto* info = UIScript::UI_GetClientInfo(0);
2022-08-24 17:46:07 -04:00
got->second(UIScript::Token(args), info);
2017-01-19 16:23:59 -05:00
return true;
}
return false;
}
void UIScript::OwnerDrawHandleKeyStub(int ownerDraw, int flags, float *special, int key)
{
2022-08-24 17:46:07 -04:00
if (key == 200 || key == 201) // mouse buttons
2017-01-19 16:23:59 -05:00
{
for (auto i = UIScript::UIOwnerDraws.begin(); i != UIScript::UIOwnerDraws.end(); ++i)
{
if (i->first == ownerDraw)
{
i->second();
}
}
}
Utils::Hook::Call<void(int, int, float*, int)>(0x4F58A0)(ownerDraw, flags, special, key);
}
__declspec(naked) void UIScript::RunMenuScriptStub()
{
__asm
{
mov eax, esp
add eax, 8h
mov edx, eax // UIScript name
mov eax, [esp + 0C10h] // UIScript args
push eax
push edx
call UIScript::RunMenuScript
add esp, 8h
test al, al
jz continue
// if returned
pop edi
pop esi
add esp, 0C00h
retn
continue:
mov eax, 45ED00h
jmp eax
}
}
UIScript::UIScript()
{
2022-08-24 10:38:14 -04:00
AssertSize(Game::uiInfo_s, 0x22FC);
if (Dedicated::IsEnabled()) return;
2017-01-19 16:23:59 -05:00
// Install handler
Utils::Hook::RedirectJump(0x45EC59, UIScript::RunMenuScriptStub);
// Install ownerdraw handler
Utils::Hook(0x63D233, UIScript::OwnerDrawHandleKeyStub, HOOK_CALL).install()->quick();
}
UIScript::~UIScript()
{
UIScript::UIScripts.clear();
UIScript::UIOwnerDraws.clear();
}
}