Some fixes

This commit is contained in:
Federico Cecchetto 2021-09-28 22:39:27 +02:00
parent 96304dbdf5
commit be5d909847
9 changed files with 110 additions and 49 deletions

View File

@ -21,8 +21,6 @@
namespace ui_scripting
{
std::unordered_map<std::string, std::unordered_map<std::string, game::hks::lua_function>> libs;
namespace
{
utils::hook::detour hksi_open_lib_hook;
@ -33,15 +31,23 @@ namespace ui_scripting
bool error_hook_enabled = false;
std::unordered_map<std::string, game::hks::lua_function> functions;
std::unordered_map<std::string, game::hks::lua_function> methods;
void* hksi_open_lib_stub(game::hks::lua_State* s, const char* libname, game::hks::luaL_Reg* l)
{
if (libname)
for (auto i = l; i->name; ++i)
{
libs[libname] = {};
for (auto i = l; i->name; ++i)
if (i->name == "__gc"s)
{
libs[libname][i->name] = i->function;
continue;
}
const auto lower = utils::string::to_lower(i->name);
libname
? functions[lower] = i->function
: methods[lower] = i->function;
}
return hksi_open_lib_hook.invoke<void*>(s, libname, l);
@ -75,7 +81,8 @@ namespace ui_scripting
ui_scripting::lua::engine::start();
});
libs = {};
functions = {};
methods = {};
return hks_start_hook.invoke<void*>(a1);
}
@ -90,8 +97,8 @@ namespace ui_scripting
if (name != "( lua_CFunction )LUI_CoD_LuaCall_UIExpression"s)
{
std::string name_ = name;
const auto sub = name_.substr(13, name_.size() - 14);
libs["Global"][sub] = f;
const auto sub = utils::string::to_lower(name_.substr(13, name_.size() - 14));
functions[sub] = f;
}
hksi_add_function_hook.invoke<void>(s, f, a3, name, a5);
@ -111,20 +118,26 @@ namespace ui_scripting
game::hks::lua_function find_function(const std::string& name)
{
const auto lower = utils::string::to_lower(name);
for (const auto lib : libs)
if (functions.find(lower) == functions.end())
{
for (const auto func : lib.second)
{
const auto lower_ = utils::string::to_lower(func.first);
if (lower == lower_)
{
return func.second;
}
}
return 0;
}
return functions[lower];
}
return 0;
game::hks::lua_function find_method(const std::string& name)
{
const auto lower = utils::string::to_lower(name);
if (methods.find(lower) == methods.end())
{
return 0;
}
return methods[lower];
}
void notify(const event& e)
{
lua::engine::notify(e);
}
class component final : public component_interface

View File

@ -1,12 +1,14 @@
#pragma once
#include "game/ui_scripting/menu.hpp"
#include "game/ui_scripting/event.hpp"
namespace ui_scripting
{
extern std::unordered_map<std::string, std::unordered_map<std::string, game::hks::lua_function>> libs;
void enable_error_hook();
void disable_error_hook();
game::hks::lua_function find_function(const std::string& name);
game::hks::lua_function find_method(const std::string& name);
void notify(event e);
}

View File

@ -153,5 +153,7 @@ namespace game
WEAK symbol<lua_State*> lua_state{0x19D83E8};
WEAK symbol<void(lua_State* s, const char* str, unsigned int l)> hksi_lua_pushlstring{0x287410};
WEAK symbol<const char*(lua_State* s, const HksObject* obj, unsigned int* len)> hks_obj_tolstring{0x287410};
WEAK symbol<int(lua_State* s, const HksObject* obj, HksObject* ret)> hks_obj_getmetatable{0x2DA210};
WEAK symbol<HksObject*(HksObject* result, lua_State* s, const HksObject* table, const HksObject* key)> hks_obj_getfield{0x2D9E20};
}
}

View File

@ -1,7 +1,7 @@
#include <std_include.hpp>
#include "value.hpp"
#include "execution.hpp"
#include "stack_isolation.hpp"
#include "component/ui_scripting.hpp"
#include <utils/string.hpp>
@ -59,7 +59,6 @@ namespace ui_scripting
case 5:
{
const auto data = std::get<lightuserdata>(value_);
state->top->t = game::hks::HksObjectType::TLIGHTUSERDATA;
state->top->v.ptr = data.ptr;
state->top++;
@ -125,16 +124,15 @@ namespace ui_scripting
throw std::runtime_error("Invalid lua state");
}
const auto state = *game::hks::lua_state;
state->top = state->base;
const auto function = ui_scripting::find_function(name);
if (!function)
{
throw std::runtime_error("Function " + name + " not found");
}
const auto _ = gsl::finally([]()
stack_isolation _;
const auto __ = gsl::finally([]()
{
disable_error_hook();
});
@ -156,6 +154,11 @@ namespace ui_scripting
values.push_back(get_return_value(i));
}
if (values.size() == 0)
{
values.push_back({});
}
return values;
}
catch (const std::exception& e)

View File

@ -515,7 +515,7 @@ namespace ui_scripting::lua
}
}
lua::engine::notify(event);
notify(event);
};
element_type["hidden"] = sol::property(
@ -589,7 +589,7 @@ namespace ui_scripting::lua
}
}
lua::engine::notify(event);
notify(event);
};
menu_type["addchild"] = [](const sol::this_state s, menu& menu, element& element)
@ -640,7 +640,7 @@ namespace ui_scripting::lua
event event;
event.element = &menu;
event.name = "close";
handler.dispatch(event);
notify(event);
menu.open();
};
@ -650,7 +650,7 @@ namespace ui_scripting::lua
event event;
event.element = &menu;
event.name = "close";
handler.dispatch(event);
notify(event);
menu.close();
};
@ -809,7 +809,7 @@ namespace ui_scripting::lua
event event;
event.element = menu;
event.name = "open";
handler.dispatch(event);
notify(event);
menu->open();
};
@ -826,7 +826,7 @@ namespace ui_scripting::lua
event event;
event.element = menu;
event.name = "close";
handler.dispatch(event);
notify(event);
menu->close();
};
@ -953,11 +953,6 @@ namespace ui_scripting::lua
::game::Dvar_SetCommand(hash, "", string_value.data());
};
game_type["playsound"] = [](const game&, const std::string& sound)
{
::game::UI_PlayLocalSoundAlias(0, sound.data());
};
game_type["getwindowsize"] = [](const game&, const sol::this_state s)
{
const auto size = ::game::ScrPlace_GetViewPlacement()->realViewportSize;
@ -1001,14 +996,7 @@ namespace ui_scripting::lua
}
const auto values = call(name, arguments);
if (values.size() == 0)
{
return sol::lua_value{s, sol::lua_nil};
}
else
{
return sol::lua_value{s, sol::as_returns(values)};
}
return sol::as_returns(values);
};
struct player

View File

@ -10,7 +10,6 @@
#define SOL_PRINT_ERRORS 0
#include <sol/sol.hpp>
#include "engine.hpp"
#include "scheduler.hpp"
#include "event_handler.hpp"

View File

@ -0,0 +1,30 @@
#include <std_include.hpp>
#include "stack_isolation.hpp"
namespace ui_scripting
{
stack_isolation::stack_isolation()
{
const auto state = *game::hks::lua_state;
this->top_ = state->top;
this->base_ = state->base;
this->alloc_top_ = state->alloc_top;
this->bottom_ = state->bottom;
state->top = this->stack_;
state->base = state->top;
state->alloc_top = &this->stack_[ARRAYSIZE(this->stack_) - 1];
state->bottom = state->top;
}
stack_isolation::~stack_isolation()
{
const auto state = *game::hks::lua_state;
state->top = this->top_;
state->base = this->base_;
state->alloc_top = this->alloc_top_;
state->bottom = this->bottom_;
}
}

View File

@ -0,0 +1,25 @@
#pragma once
#include "game/game.hpp"
namespace ui_scripting
{
class stack_isolation final
{
public:
stack_isolation();
~stack_isolation();
stack_isolation(stack_isolation&&) = delete;
stack_isolation(const stack_isolation&) = delete;
stack_isolation& operator=(stack_isolation&&) = delete;
stack_isolation& operator=(const stack_isolation&) = delete;
private:
game::hks::HksObject stack_[512]{};
game::hks::HksObject* top_;
game::hks::HksObject* base_;
game::hks::HksObject* alloc_top_;
game::hks::HksObject* bottom_;
};
}

View File

@ -6,7 +6,6 @@ namespace ui_scripting
struct lightuserdata
{
void* ptr;
bool operator==(const lightuserdata other) const noexcept
{
return this->ptr == other.ptr;