From 93548ce1b525993a3d7ea2fa82bb1fe896e4e4f3 Mon Sep 17 00:00:00 2001 From: praydog Date: Sat, 13 Jul 2024 19:34:41 -0700 Subject: [PATCH] Lua: Pass locals onto hooks, fix error handling --- lua-api/lib/include/datatypes/FFrame.hpp | 20 ++++++++++++++ lua-api/lib/src/ScriptContext.cpp | 33 +++++++++++++++++------- 2 files changed, 44 insertions(+), 9 deletions(-) create mode 100644 lua-api/lib/include/datatypes/FFrame.hpp diff --git a/lua-api/lib/include/datatypes/FFrame.hpp b/lua-api/lib/include/datatypes/FFrame.hpp new file mode 100644 index 00000000..361ca808 --- /dev/null +++ b/lua-api/lib/include/datatypes/FFrame.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include +#include + +namespace lua::datatypes { + struct FFrame { + void* vtable; + + bool bool1; + bool bool2; + + void* node; + void* object; + void* code; + void* locals; + }; + + void bind_fframe(sol::state_view& lua); +} \ No newline at end of file diff --git a/lua-api/lib/src/ScriptContext.cpp b/lua-api/lib/src/ScriptContext.cpp index 1b5dd466..fa664a19 100644 --- a/lua-api/lib/src/ScriptContext.cpp +++ b/lua-api/lib/src/ScriptContext.cpp @@ -8,6 +8,7 @@ #include "datatypes/Vector.hpp" #include "datatypes/StructObject.hpp" +#include "datatypes/FFrame.hpp" #include "ScriptUtility.hpp" #include "ScriptContext.hpp" @@ -476,6 +477,8 @@ int ScriptContext::setup_bindings() { std::unique_lock _{ m_ufunction_hooks_mtx }; + fn->hook_ptr(global_ufunction_pre_handler, global_ufunction_post_handler); + if (auto it = m_ufunction_hooks.find(fn); it != m_ufunction_hooks.end()) { if (pre != sol::nil) { it->second->pre_hooks.push_back(pre); @@ -491,8 +494,6 @@ int ScriptContext::setup_bindings() { auto& hook = m_ufunction_hooks[fn]; hook = std::make_unique(); - fn->hook_ptr(global_ufunction_pre_handler, global_ufunction_post_handler); - if (pre != sol::nil) { hook->pre_hooks.push_back(pre); } @@ -662,7 +663,7 @@ int ScriptContext::setup_bindings() { return out.push(m_lua.lua_state()); } -bool ScriptContext::global_ufunction_pre_handler(uevr::API::UFunction* fn, uevr::API::UObject* obj, void* params, void* out_result) { +bool ScriptContext::global_ufunction_pre_handler(uevr::API::UFunction* fn, uevr::API::UObject* obj, void* frame, void* out_result) { bool any_false = false; g_contexts.for_each([=, &any_false](auto ctx) { @@ -672,12 +673,18 @@ bool ScriptContext::global_ufunction_pre_handler(uevr::API::UFunction* fn, uevr: auto it = ctx->m_ufunction_hooks.find(fn); if (it != ctx->m_ufunction_hooks.end()) { - for (auto& cb : it->second->pre_hooks) { - bool result = cb(fn, obj, params, out_result); + auto fframe = (lua::datatypes::FFrame*)frame; + auto locals = lua::datatypes::StructObject{fframe->locals, fn}; + auto locals_obj = sol::make_object(ctx->m_lua.lua_state(), &locals); - if (!result) { + for (auto& cb : it->second->pre_hooks) try { + if (sol::object result = ctx->handle_protected_result(cb(fn, obj, locals_obj, out_result)); !result.is() && result.is() && result.as() == false) { any_false = true; } + } catch (const std::exception& e) { + ScriptContext::log("Exception in global_ufunction_pre_handler: " + std::string(e.what())); + } catch (...) { + ScriptContext::log("Unknown exception in global_ufunction_pre_handler"); } } }); @@ -685,7 +692,7 @@ bool ScriptContext::global_ufunction_pre_handler(uevr::API::UFunction* fn, uevr: return !any_false; } -void ScriptContext::global_ufunction_post_handler(uevr::API::UFunction* fn, uevr::API::UObject* obj, void* params, void* result) { +void ScriptContext::global_ufunction_post_handler(uevr::API::UFunction* fn, uevr::API::UObject* obj, void* frame, void* result) { g_contexts.for_each([=](auto ctx) { std::scoped_lock _{ ctx->m_mtx }; std::scoped_lock __{ ctx->m_ufunction_hooks_mtx }; @@ -693,8 +700,16 @@ void ScriptContext::global_ufunction_post_handler(uevr::API::UFunction* fn, uevr auto it = ctx->m_ufunction_hooks.find(fn); if (it != ctx->m_ufunction_hooks.end()) { - for (auto& cb : it->second->post_hooks) { - cb(fn, obj, params, result); + auto fframe = (lua::datatypes::FFrame*)frame; + auto locals = lua::datatypes::StructObject{fframe->locals, fn}; + auto locals_obj = sol::make_object(ctx->m_lua.lua_state(), &locals); + + for (auto& cb : it->second->post_hooks) try { + ctx->handle_protected_result(cb(fn, obj, locals_obj, result)); + } catch (const std::exception& e) { + ScriptContext::log("Exception in global_ufunction_post_handler: " + std::string(e.what())); + } catch (...) { + ScriptContext::log("Unknown exception in global_ufunction_post_handler"); } } });