Add lui key events + fixes
This commit is contained in:
parent
684028bc95
commit
0915c68fd1
@ -4,6 +4,7 @@
|
|||||||
#include "game/game.hpp"
|
#include "game/game.hpp"
|
||||||
|
|
||||||
#include "game_console.hpp"
|
#include "game_console.hpp"
|
||||||
|
#include "game/ui_scripting/execution.hpp"
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
@ -16,6 +17,12 @@ namespace input
|
|||||||
|
|
||||||
void cl_char_event_stub(const int local_client_num, const int key)
|
void cl_char_event_stub(const int local_client_num, const int key)
|
||||||
{
|
{
|
||||||
|
ui_scripting::notify("keypress",
|
||||||
|
{
|
||||||
|
{"keynum", key},
|
||||||
|
{"key", game::Key_KeynumToString(key, 0, 1)},
|
||||||
|
});
|
||||||
|
|
||||||
if (!game_console::console_char_event(local_client_num, key))
|
if (!game_console::console_char_event(local_client_num, key))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -26,6 +33,12 @@ namespace input
|
|||||||
|
|
||||||
void cl_key_event_stub(const int local_client_num, const int key, const int down)
|
void cl_key_event_stub(const int local_client_num, const int key, const int down)
|
||||||
{
|
{
|
||||||
|
ui_scripting::notify(down ? "keydown" : "keyup",
|
||||||
|
{
|
||||||
|
{"keynum", key},
|
||||||
|
{"key", game::Key_KeynumToString(key, 0, 1)},
|
||||||
|
});
|
||||||
|
|
||||||
if (!game_console::console_key_event(local_client_num, key, down))
|
if (!game_console::console_key_event(local_client_num, key, down))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -153,6 +153,8 @@ namespace game
|
|||||||
int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x14039D5F0, 0x1404CD210};
|
int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x14039D5F0, 0x1404CD210};
|
||||||
WEAK symbol<bool(int clientNum, const char* name, hks::lua_State* s)> LUI_BeginEvent{0x1400D27F0, 0x140161A00};
|
WEAK symbol<bool(int clientNum, const char* name, hks::lua_State* s)> LUI_BeginEvent{0x1400D27F0, 0x140161A00};
|
||||||
WEAK symbol<void(hks::lua_State* s)> LUI_EndEvent{0x1400D3A80, 0x140162CD0};
|
WEAK symbol<void(hks::lua_State* s)> LUI_EndEvent{0x1400D3A80, 0x140162CD0};
|
||||||
|
WEAK symbol<void()> LUI_EnterCriticalSection{0x1400D3B70, 0x140162DC0};
|
||||||
|
WEAK symbol<void()> LUI_LeaveCriticalSection{0x1400D8DB0, 0x140168150};
|
||||||
|
|
||||||
WEAK symbol<bool(int clientNum, const char* menu)> Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320};
|
WEAK symbol<bool(int clientNum, const char* menu)> Menu_IsMenuOpenAndVisible{0x1404709C0, 0x1404C7320};
|
||||||
|
|
||||||
@ -273,5 +275,6 @@ namespace game
|
|||||||
int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x14008B5D0, 0x14011B540};
|
int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x14008B5D0, 0x14011B540};
|
||||||
WEAK symbol<int(lua_State* s, int t)> hksi_luaL_ref{0x1400A64D0, 0x140136D30};
|
WEAK symbol<int(lua_State* s, int t)> hksi_luaL_ref{0x1400A64D0, 0x140136D30};
|
||||||
WEAK symbol<void(lua_State* s, int t, int ref)> hksi_luaL_unref{0x14009EF10, 0x14012F610};
|
WEAK symbol<void(lua_State* s, int t, int ref)> hksi_luaL_unref{0x14009EF10, 0x14012F610};
|
||||||
|
WEAK symbol<void(lua_State* s, HksObject* lfp)> closePendingUpvalues{0x14008EA00, 0x14011E970};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,53 +40,53 @@ namespace ui_scripting
|
|||||||
bool notify(const std::string& name, const event_arguments& arguments)
|
bool notify(const std::string& name, const event_arguments& arguments)
|
||||||
{
|
{
|
||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
if (!game::LUI_BeginEvent(0, name.data(), state))
|
if (!state)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto _1 = gsl::finally(&disable_error_hook);
|
|
||||||
enable_error_hook();
|
|
||||||
|
|
||||||
const auto top = state->m_apistack.top;
|
const auto _1 = gsl::finally(game::LUI_LeaveCriticalSection);
|
||||||
|
game::LUI_EnterCriticalSection();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const auto event = get_return_value(0).as<table>();
|
const auto globals = table((*::game::hks::lua_state)->globals.v.table);
|
||||||
|
const auto engine = globals.get("Engine").as<table>();
|
||||||
|
const auto root = engine.get("GetLuiRoot").as<function>().call({})[0].as<userdata>();
|
||||||
|
const auto process_event = root.get("processEvent").as<function>();
|
||||||
|
|
||||||
|
table event{};
|
||||||
|
event.set("name", name);
|
||||||
|
|
||||||
for (const auto& arg : arguments)
|
for (const auto& arg : arguments)
|
||||||
{
|
{
|
||||||
event.set(arg.first, arg.second);
|
event.set(arg.first, arg.second);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
state->m_apistack.top = top;
|
process_event.call({root, event});
|
||||||
|
return true;
|
||||||
try
|
|
||||||
{
|
|
||||||
game::LUI_EndEvent(state);
|
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Error while processing event: ") + e.what());
|
printf("Error processing event '%s' %s\n", name.data(), e.what());
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
arguments call_script_function(const function& function, const arguments& arguments)
|
arguments call_script_function(const function& function, const arguments& arguments)
|
||||||
{
|
{
|
||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
state->m_apistack.top = state->m_apistack.base;
|
|
||||||
|
|
||||||
|
stack stack;
|
||||||
push_value(function);
|
push_value(function);
|
||||||
for (auto i = arguments.begin(); i != arguments.end(); ++i)
|
for (auto i = arguments.begin(); i != arguments.end(); ++i)
|
||||||
{
|
{
|
||||||
push_value(*i);
|
push_value(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto num_args = static_cast<int>(arguments.size());
|
||||||
|
stack.save(num_args + 1);
|
||||||
|
|
||||||
const auto _1 = gsl::finally(&disable_error_hook);
|
const auto _1 = gsl::finally(&disable_error_hook);
|
||||||
enable_error_hook();
|
enable_error_hook();
|
||||||
|
|
||||||
@ -98,6 +98,7 @@ namespace ui_scripting
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
stack.fix();
|
||||||
throw std::runtime_error(std::string("Error executing script function: ") + e.what());
|
throw std::runtime_error(std::string("Error executing script function: ") + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,9 +106,10 @@ namespace ui_scripting
|
|||||||
script_value get_field(const userdata& self, const script_value& key)
|
script_value get_field(const userdata& self, const script_value& key)
|
||||||
{
|
{
|
||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
state->m_apistack.top = state->m_apistack.base;
|
|
||||||
|
|
||||||
|
stack stack;
|
||||||
push_value(key);
|
push_value(key);
|
||||||
|
stack.save(1);
|
||||||
|
|
||||||
const auto _1 = gsl::finally(&disable_error_hook);
|
const auto _1 = gsl::finally(&disable_error_hook);
|
||||||
enable_error_hook();
|
enable_error_hook();
|
||||||
@ -124,16 +126,18 @@ namespace ui_scripting
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Error getting userdata field: ") + e.what());
|
stack.fix();
|
||||||
|
throw std::runtime_error("Error getting userdata field: "s + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
script_value get_field(const table& self, const script_value& key)
|
script_value get_field(const table& self, const script_value& key)
|
||||||
{
|
{
|
||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
state->m_apistack.top = state->m_apistack.base;
|
|
||||||
|
|
||||||
|
stack stack;
|
||||||
push_value(key);
|
push_value(key);
|
||||||
|
stack.save(1);
|
||||||
|
|
||||||
const auto _1 = gsl::finally(&disable_error_hook);
|
const auto _1 = gsl::finally(&disable_error_hook);
|
||||||
enable_error_hook();
|
enable_error_hook();
|
||||||
@ -150,14 +154,17 @@ namespace ui_scripting
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Error getting table field: ") + e.what());
|
stack.fix();
|
||||||
|
throw std::runtime_error("Error getting table field: "s + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_field(const userdata& self, const script_value& key, const script_value& value)
|
void set_field(const userdata& self, const script_value& key, const script_value& value)
|
||||||
{
|
{
|
||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
state->m_apistack.top = state->m_apistack.base;
|
|
||||||
|
stack stack;
|
||||||
|
stack.save(0);
|
||||||
|
|
||||||
const auto _1 = gsl::finally(&disable_error_hook);
|
const auto _1 = gsl::finally(&disable_error_hook);
|
||||||
enable_error_hook();
|
enable_error_hook();
|
||||||
@ -172,14 +179,17 @@ namespace ui_scripting
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Error setting userdata field: ") + e.what());
|
stack.fix();
|
||||||
|
throw std::runtime_error("Error setting userdata field: "s + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_field(const table& self, const script_value& key, const script_value& value)
|
void set_field(const table& self, const script_value& key, const script_value& value)
|
||||||
{
|
{
|
||||||
const auto state = *game::hks::lua_state;
|
const auto state = *game::hks::lua_state;
|
||||||
state->m_apistack.top = state->m_apistack.base;
|
|
||||||
|
stack stack;
|
||||||
|
stack.save(0);
|
||||||
|
|
||||||
const auto _1 = gsl::finally(&disable_error_hook);
|
const auto _1 = gsl::finally(&disable_error_hook);
|
||||||
enable_error_hook();
|
enable_error_hook();
|
||||||
@ -194,7 +204,8 @@ namespace ui_scripting
|
|||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(std::string("Error setting table field: ") + e.what());
|
stack.fix();
|
||||||
|
throw std::runtime_error("Error setting table field: "s + e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,4 +273,38 @@ namespace ui_scripting
|
|||||||
{
|
{
|
||||||
return call_script_function(*this, arguments);
|
return call_script_function(*this, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***************************************************************
|
||||||
|
* Stack
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
|
stack::stack()
|
||||||
|
{
|
||||||
|
this->state = *game::hks::lua_state;
|
||||||
|
this->state->m_apistack.top = this->state->m_apistack.base;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stack::save(int num_args)
|
||||||
|
{
|
||||||
|
this->num_args_ = num_args;
|
||||||
|
this->num_calls_ = state->m_numberOfCCalls;
|
||||||
|
this->base_bottom_ = state->m_apistack.base - state->m_apistack.bottom;
|
||||||
|
this->top_bottom_ = state->m_apistack.top - state->m_apistack.bottom;
|
||||||
|
this->callstack_ = state->m_callStack.m_current - state->m_callStack.m_records;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stack::fix()
|
||||||
|
{
|
||||||
|
this->state->m_numberOfCCalls = this->num_calls_;
|
||||||
|
|
||||||
|
game::hks::closePendingUpvalues(this->state, &this->state->m_apistack.bottom[this->top_bottom_ - this->num_args_]);
|
||||||
|
this->state->m_callStack.m_current = &this->state->m_callStack.m_records[this->callstack_];
|
||||||
|
|
||||||
|
this->state->m_apistack.base = &this->state->m_apistack.bottom[this->base_bottom_];
|
||||||
|
this->state->m_apistack.top = &this->state->m_apistack.bottom[this->top_bottom_ - static_cast<uint64_t>(this->num_args_ + 1)];
|
||||||
|
|
||||||
|
this->state->m_apistack.bottom[this->top_bottom_].t = this->state->m_apistack.top[-1].t;
|
||||||
|
this->state->m_apistack.bottom[this->top_bottom_].v.ptr = this->state->m_apistack.top[-1].v.ptr;
|
||||||
|
this->state->m_apistack.top = &this->state->m_apistack.bottom[this->top_bottom_ + 1];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -86,4 +86,28 @@ namespace ui_scripting
|
|||||||
|
|
||||||
int ref{};
|
int ref{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class stack final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
stack();
|
||||||
|
|
||||||
|
void save(int num_args);
|
||||||
|
void fix();
|
||||||
|
|
||||||
|
stack(stack&&) = delete;
|
||||||
|
stack(const stack&) = delete;
|
||||||
|
stack& operator=(stack&&) = delete;
|
||||||
|
stack& operator=(const stack&) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
game::hks::lua_State* state;
|
||||||
|
|
||||||
|
int num_args_;
|
||||||
|
int num_calls_;
|
||||||
|
|
||||||
|
uint64_t base_bottom_;
|
||||||
|
uint64_t top_bottom_;
|
||||||
|
uint64_t callstack_;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user