Support converting our lua functions to lui functions

This commit is contained in:
Federico Cecchetto 2021-10-02 18:30:21 +02:00
parent b461a6ab3c
commit 82ab4453a0
7 changed files with 85 additions and 5 deletions

View File

@ -59,7 +59,7 @@ namespace notifies
const auto result = hook(self, sol::as_args(args)); const auto result = hook(self, sol::as_args(args));
scripting::lua::handle_error(result); scripting::lua::handle_error(result);
const auto value = scripting::lua::convert({ state, result }); const auto value = scripting::lua::convert({state, result});
const auto type = value.get_raw().type; const auto type = value.get_raw().type;
game::Scr_ClearOutParams(); game::Scr_ClearOutParams();

View File

@ -15,6 +15,7 @@
#include "ui_scripting.hpp" #include "ui_scripting.hpp"
#include "game/ui_scripting/lua/engine.hpp" #include "game/ui_scripting/lua/engine.hpp"
#include "game/ui_scripting/execution.hpp"
#include <utils/string.hpp> #include <utils/string.hpp>
#include <utils/hook.hpp> #include <utils/hook.hpp>
@ -26,6 +27,9 @@ namespace ui_scripting
namespace namespace
{ {
unsigned int function_id = 0;
std::unordered_map<game::hks::cclosure*, sol::protected_function> converted_functions;
utils::hook::detour hksi_open_lib_hook; utils::hook::detour hksi_open_lib_hook;
utils::hook::detour hksi_lual_error_hook; utils::hook::detour hksi_lual_error_hook;
utils::hook::detour hksi_lual_error_hook2; utils::hook::detour hksi_lual_error_hook2;
@ -106,6 +110,52 @@ namespace ui_scripting
} }
} }
int main_function_handler(game::hks::lua_State* state)
{
const auto value = state->m_apistack.base[-1];
if (value.t != game::hks::TCFUNCTION)
{
return 0;
}
const auto closure = value.v.cClosure;
if (converted_functions.find(closure) == converted_functions.end())
{
return 0;
}
const auto function = converted_functions[closure];
const auto count = static_cast<int>(state->m_apistack.top - state->m_apistack.base);
const auto arguments = get_return_values(count);
const auto s = function.lua_state();
std::vector<sol::lua_value> converted_args;
for (const auto& argument : arguments)
{
converted_args.push_back(lua::convert(s, argument));
}
const auto results = function(sol::as_args(converted_args));
for (const auto& result : results)
{
push_value(lua::convert({s, result}));
}
return results.return_count();
}
void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function)
{
converted_functions[closure] = function;
}
void clear_converted_functions()
{
converted_functions.clear();
}
void enable_error_hook() void enable_error_hook()
{ {
error_hook_enabled = true; error_hook_enabled = true;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "game/ui_scripting/lua/value_conversion.hpp"
#include "game/ui_scripting/menu.hpp" #include "game/ui_scripting/menu.hpp"
#include "game/ui_scripting/event.hpp" #include "game/ui_scripting/event.hpp"
@ -7,6 +8,10 @@ namespace ui_scripting
extern std::unordered_map<std::string, game::hks::lua_function> functions; extern std::unordered_map<std::string, game::hks::lua_function> functions;
extern std::unordered_map<std::string, game::hks::lua_function> methods; extern std::unordered_map<std::string, game::hks::lua_function> methods;
int main_function_handler(game::hks::lua_State* state);
void add_converted_function(game::hks::cclosure* closure, const sol::protected_function& function);
void clear_converted_functions();
void enable_error_hook(); void enable_error_hook();
void disable_error_hook(); void disable_error_hook();

View File

@ -160,5 +160,7 @@ namespace game
WEAK symbol<void(lua_State* s, int index)> hksi_lua_pushvalue{0x2DE040}; WEAK symbol<void(lua_State* s, int index)> hksi_lua_pushvalue{0x2DE040};
WEAK symbol<HashTable*(lua_State* s, unsigned int arraySize, unsigned int hashSize)> Hashtable_Create{0x2C8290}; WEAK symbol<HashTable*(lua_State* s, unsigned int arraySize, unsigned int hashSize)> Hashtable_Create{0x2C8290};
WEAK symbol<HksObject*(HashTable* t, HksObject* result, HksObject* key)> Hashtable_getNextHash{0x2D5150}; WEAK symbol<HksObject*(HashTable* t, HksObject* result, HksObject* key)> Hashtable_getNextHash{0x2D5150};
WEAK symbol<cclosure*(lua_State* s, lua_function function, int num_upvalues,
int internal_, int profilerTreatClosureAsFunc)> cclosure_Create{0x2C84B0};
} }
} }

View File

@ -7,6 +7,7 @@ namespace ui_scripting
{ {
void push_value(const value& value); void push_value(const value& value);
value get_return_value(int offset); value get_return_value(int offset);
arguments get_return_values(int count);
arguments call_script_function(const function& function, const arguments& arguments); arguments call_script_function(const function& function, const arguments& arguments);

View File

@ -3,6 +3,7 @@
#include "context.hpp" #include "context.hpp"
#include "../../../component/scheduler.hpp" #include "../../../component/scheduler.hpp"
#include "../../../component/ui_scripting.hpp"
#include <utils/io.hpp> #include <utils/io.hpp>
#include <utils/string.hpp> #include <utils/string.hpp>
@ -200,7 +201,7 @@ namespace ui_scripting::lua::engine
: "keyup"; : "keyup";
event.arguments = {key}; event.arguments = {key};
notify(event); engine::notify(event);
break; break;
} }
@ -346,7 +347,7 @@ namespace ui_scripting::lua::engine
event event; event event;
event.element = &menu.second; event.element = &menu.second;
event.name = "close"; event.name = "close";
notify(event); engine::notify(event);
menu.second.close(); menu.second.close();
} }
@ -377,7 +378,7 @@ namespace ui_scripting::lua::engine
event event; event event;
event.element = menu; event.element = menu;
event.name = "open"; event.name = "open";
notify(event); engine::notify(event);
menu->open(); menu->open();
} }
@ -394,13 +395,14 @@ namespace ui_scripting::lua::engine
event event; event event;
event.element = menu; event.element = menu;
event.name = "close"; event.name = "close";
notify(event); engine::notify(event);
menu->close(); menu->close();
} }
void start() void start()
{ {
clear_converted_functions();
close_all_menus(); close_all_menus();
get_scripts().clear(); get_scripts().clear();
clear_menus(); clear_menus();
@ -409,6 +411,7 @@ namespace ui_scripting::lua::engine
void stop() void stop()
{ {
clear_converted_functions();
close_all_menus(); close_all_menus();
get_scripts().clear(); get_scripts().clear();
clear_menus(); clear_menus();

View File

@ -1,6 +1,8 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "value_conversion.hpp" #include "value_conversion.hpp"
#include "../execution.hpp" #include "../execution.hpp"
#include "../stack_isolation.hpp"
#include "../../../component/ui_scripting.hpp"
namespace ui_scripting::lua namespace ui_scripting::lua
{ {
@ -17,6 +19,18 @@ namespace ui_scripting::lua
return res; return res;
} }
value convert_function(const sol::protected_function& function)
{
const auto closure = game::hks::cclosure_Create(*game::hks::lua_state, main_function_handler, 0, 0, 0);
add_converted_function(closure, function);
game::hks::HksObject value{};
value.t = game::hks::TCFUNCTION;
value.v.cClosure = closure;
return value;
}
} }
value convert(const sol::lua_value& value) value convert(const sol::lua_value& value)
@ -76,6 +90,11 @@ namespace ui_scripting::lua
return {convert_table(value.as<sol::table>())}; return {convert_table(value.as<sol::table>())};
} }
if (value.is<sol::protected_function>())
{
return {convert_function(value.as<sol::protected_function>())};
}
return {}; return {};
} }