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));
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;
game::Scr_ClearOutParams();

View File

@ -15,6 +15,7 @@
#include "ui_scripting.hpp"
#include "game/ui_scripting/lua/engine.hpp"
#include "game/ui_scripting/execution.hpp"
#include <utils/string.hpp>
#include <utils/hook.hpp>
@ -26,6 +27,9 @@ namespace ui_scripting
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_lual_error_hook;
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()
{
error_hook_enabled = true;

View File

@ -1,4 +1,5 @@
#pragma once
#include "game/ui_scripting/lua/value_conversion.hpp"
#include "game/ui_scripting/menu.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> 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 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<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<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);
value get_return_value(int offset);
arguments get_return_values(int count);
arguments call_script_function(const function& function, const arguments& arguments);

View File

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

View File

@ -1,6 +1,8 @@
#include <std_include.hpp>
#include "value_conversion.hpp"
#include "../execution.hpp"
#include "../stack_isolation.hpp"
#include "../../../component/ui_scripting.hpp"
namespace ui_scripting::lua
{
@ -17,6 +19,18 @@ namespace ui_scripting::lua
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)
@ -76,6 +90,11 @@ namespace ui_scripting::lua
return {convert_table(value.as<sol::table>())};
}
if (value.is<sol::protected_function>())
{
return {convert_function(value.as<sol::protected_function>())};
}
return {};
}