Skip to content

Commit d0f6511

Browse files
authored
Merge branch 'praydog:master' into master
2 parents 384e718 + 3f9086f commit d0f6511

9 files changed

Lines changed: 217 additions & 48 deletions

File tree

include/reframework/API.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#endif
88

99
#define REFRAMEWORK_PLUGIN_VERSION_MAJOR 1
10-
#define REFRAMEWORK_PLUGIN_VERSION_MINOR 13
10+
#define REFRAMEWORK_PLUGIN_VERSION_MINOR 14
1111
#define REFRAMEWORK_PLUGIN_VERSION_PATCH 0
1212

1313
#define REFRAMEWORK_RENDERER_D3D11 0
@@ -34,6 +34,7 @@ typedef void (*REFOnPreApplicationEntryCb)();
3434
typedef void (*REFOnPostApplicationEntryCb)();
3535
typedef void (*REFOnDeviceResetCb)();
3636
typedef bool (*REFOnMessageCb)(void*, unsigned int, unsigned long long, long long);
37+
typedef bool (*REFOnPreGuiDrawElementCb)(void*, void*);
3738

3839
typedef struct {
3940
void* context;
@@ -59,6 +60,7 @@ typedef bool (*REFOnMessageFn)(REFOnMessageCb);
5960

6061
typedef bool (*REFOnImGuiFrameFn)(REFOnImGuiFrameCb);
6162
typedef bool (*REFOnImGuiDrawUIFn)(REFOnImGuiDrawUICb);
63+
typedef bool (*REFOnPreGuiDrawElementFn)(REFOnPreGuiDrawElementCb);
6264

6365
typedef struct {
6466
int major;
@@ -88,6 +90,7 @@ typedef struct {
8890

8991
REFOnImGuiFrameFn on_imgui_frame;
9092
REFOnImGuiDrawUIFn on_imgui_draw_ui;
93+
REFOnPreGuiDrawElementFn on_pre_gui_draw_element;
9194
} REFrameworkPluginFunctions;
9295

9396
typedef struct {

src/mods/APIProxy.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ bool APIProxy::add_on_imgui_draw_ui(REFOnImGuiDrawUICb cb) {
9393
return true;
9494
}
9595

96+
bool APIProxy::add_on_pre_gui_draw_element(REFOnPreGuiDrawElementCb cb) {
97+
std::unique_lock _{m_api_cb_mtx};
98+
99+
m_on_pre_gui_draw_element_cbs.push_back(cb);
100+
return true;
101+
}
102+
96103
void APIProxy::on_lua_state_created(sol::state& state) {
97104
std::shared_lock _{m_api_cb_mtx};
98105

@@ -277,4 +284,23 @@ bool APIProxy::on_message(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
277284
}
278285

279286
return true;
287+
}
288+
289+
bool APIProxy::on_pre_gui_draw_element(REComponent* gui_element, void* primitive_context) {
290+
std::shared_lock _{m_api_cb_mtx};
291+
292+
bool any_false = false;
293+
294+
for (auto&& cb : m_on_pre_gui_draw_element_cbs) {
295+
try {
296+
if (!cb(gui_element, primitive_context)) {
297+
any_false = true;
298+
}
299+
} catch(...) {
300+
spdlog::error("[APIProxy] Exception occurred in on_pre_gui_draw_element callback; one of the plugins has an error.");
301+
continue;
302+
}
303+
}
304+
305+
return !any_false;
280306
}

src/mods/APIProxy.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ class APIProxy : public Mod {
2222
void on_pre_application_entry(void* entry, const char* name, size_t hash) override;
2323
void on_application_entry(void* entry, const char* name, size_t hash) override;
2424
void on_device_reset() override;
25+
bool on_pre_gui_draw_element(REComponent* gui_element, void* primitive_context) override;
2526
bool on_message(HWND wnd, UINT message, WPARAM w_param, LPARAM l_param) override;
2627

2728
public:
@@ -34,6 +35,7 @@ class APIProxy : public Mod {
3435
using REFOnMessageCb = std::function<std::remove_pointer<::REFOnMessageCb>::type>;
3536
using REFOnImGuiFrameCb = std::function<std::remove_pointer<::REFOnImGuiFrameCb>::type>;
3637
using REFOnImGuiDrawUICb = std::function<std::remove_pointer<::REFOnImGuiDrawUICb>::type>;
38+
using REFOnPreGuiDrawElementCb = std::function<std::remove_pointer<::REFOnPreGuiDrawElementCb>::type>;
3739

3840
bool add_on_lua_state_created(REFLuaStateCreatedCb cb);
3941
bool add_on_lua_state_destroyed(REFLuaStateDestroyedCb cb);
@@ -44,6 +46,7 @@ class APIProxy : public Mod {
4446
bool add_on_message(REFOnMessageCb cb);
4547
bool add_on_imgui_frame(REFOnImGuiFrameCb cb);
4648
bool add_on_imgui_draw_ui(REFOnImGuiDrawUICb cb);
49+
bool add_on_pre_gui_draw_element(REFOnPreGuiDrawElementCb cb);
4750

4851
private:
4952
// API Callbacks
@@ -55,6 +58,7 @@ class APIProxy : public Mod {
5558
std::vector<APIProxy::REFOnMessageCb> m_on_message_cbs{};
5659
std::vector<APIProxy::REFOnImGuiFrameCb> m_on_imgui_frame_cbs{};
5760
std::vector<APIProxy::REFOnImGuiDrawUICb> m_on_imgui_draw_ui_cbs{};
61+
std::vector<APIProxy::REFOnPreGuiDrawElementCb> m_on_pre_gui_draw_element_cbs{};
5862

5963
// Application Entry Callbacks
6064
std::unordered_map<size_t, std::vector<APIProxy::REFOnPreApplicationEntryCb>> m_on_pre_application_entry_cbs{};

src/mods/PluginLoader.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ REFrameworkPluginFunctions g_plugin_functions {
7272

7373
reframework_on_imgui_frame,
7474
reframework_on_imgui_draw_ui,
75+
reframework_on_pre_gui_draw_element,
7576
};
7677

7778
REFrameworkSDKFunctions g_sdk_functions {
@@ -932,4 +933,12 @@ bool reframework_on_imgui_draw_ui(REFOnImGuiFrameCb cb) {
932933
}
933934

934935
return APIProxy::get()->add_on_imgui_draw_ui(cb);
936+
}
937+
938+
bool reframework_on_pre_gui_draw_element(REFOnPreGuiDrawElementCb cb) {
939+
if (cb == nullptr) {
940+
return false;
941+
}
942+
943+
return APIProxy::get()->add_on_pre_gui_draw_element(cb);
935944
}

src/mods/PluginLoader.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ bool reframework_on_device_reset(REFOnDeviceResetCb cb);
1919
bool reframework_on_message(REFOnMessageCb cb);
2020
bool reframework_on_imgui_frame(REFOnImGuiFrameCb cb);
2121
bool reframework_on_imgui_draw_ui(REFOnImGuiDrawUICb cb);
22+
bool reframework_on_pre_gui_draw_element(REFOnPreGuiDrawElementCb cb);
2223

2324
lua_State* reframework_create_script_state();
2425
void reframework_destroy_script_state(lua_State*);

src/mods/ScriptRunner.cpp

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ ScriptState::ScriptState(const ScriptState::GarbageCollectionData& gc_data,bool
135135
os["setlocale"] = sol::nil;
136136
os["getenv"] = sol::nil;
137137

138+
auto debug = m_lua["debug"];
139+
debug["getregistry"] = sol::nil;
140+
138141
bindings::open_sdk(this);
139142
bindings::open_imgui(this);
140143
bindings::open_json(this);
@@ -374,6 +377,15 @@ ScriptState::ScriptState(const ScriptState::GarbageCollectionData& gc_data,bool
374377
);
375378

376379
m_lua["reframework"] = g_framework.get();
380+
m_lua.registry()["package_path"] = m_lua["package"]["path"];
381+
m_lua.registry()["package_cpath"] = m_lua["package"]["cpath"];
382+
m_lua.registry()["package_searchers"] = m_lua.create_table();
383+
384+
sol::table package_searchers = m_lua["package"]["searchers"];
385+
386+
for (auto&& [k, v] : package_searchers) {
387+
m_lua.registry()["package_searchers"][k] = v;
388+
}
377389

378390
// clang-format on
379391
//callback function removed from constructor and moved out into script runner
@@ -398,7 +410,12 @@ void ScriptState::run_script(const std::string& p) {
398410

399411
spdlog::info("[ScriptState] Running script {}...", p);
400412

401-
std::string old_path = m_lua["package"]["path"];
413+
m_lua["package"]["path"] = m_lua.registry()["package_path"];
414+
m_lua["package"]["cpath"] = m_lua.registry()["package_cpath"];
415+
416+
const std::string old_pristine_path = m_lua.registry()["package_path"];
417+
const std::string old_pristine_cpath = m_lua.registry()["package_cpath"];
418+
const std::string old_path = m_lua["package"]["path"];
402419

403420
try {
404421
auto path = std::filesystem::path(p);
@@ -411,6 +428,9 @@ void ScriptState::run_script(const std::string& p) {
411428
package_path = package_path + ";" + dir.string() + "/?.dll";
412429

413430
m_lua["package"]["path"] = package_path;
431+
m_lua.registry()["package_path"] = m_lua["package"]["path"];
432+
m_lua.registry()["package_cpath"] = m_lua["package"]["cpath"];
433+
414434
m_lua.safe_script_file(p);
415435
} catch (const std::exception& e) {
416436
ScriptRunner::get()->spew_error(e.what());
@@ -421,6 +441,8 @@ void ScriptState::run_script(const std::string& p) {
421441
}
422442

423443
m_lua["package"]["path"] = old_path;
444+
m_lua.registry()["package_path"] = old_pristine_path;
445+
m_lua.registry()["package_cpath"] = old_pristine_cpath;
424446
}
425447

426448
// i have to wonder why this isn't in sol when they have safe_script stuff
@@ -467,6 +489,22 @@ void ScriptState::on_draw_ui() {
467489
api::imnodes::cleanup();
468490
}
469491

492+
void ScriptState::on_update_transform(RETransform* transform) {
493+
try {
494+
if (m_on_update_transform_fns.empty()) {
495+
return;
496+
}
497+
if (m_on_update_transform_fns.find(transform) != m_on_update_transform_fns.end()) {
498+
std::scoped_lock _{m_execution_mutex};
499+
handle_protected_result(m_on_update_transform_fns[transform](transform));
500+
}
501+
} catch (const std::exception& e) {
502+
ScriptRunner::get()->spew_error(e.what());
503+
} catch (...) {
504+
ScriptRunner::get()->spew_error("Unknown exception in on_update_transform");
505+
}
506+
}
507+
470508
void ScriptState::on_pre_application_entry(size_t hash) {
471509
try {
472510
if (m_pre_application_entry_fns.empty()) {
@@ -613,6 +651,11 @@ void ScriptState::add_vtable(::REManagedObject* obj, sdk::REMethodDefinition* fn
613651
m_hooks_to_add.emplace_back(obj, fn, pre_cb, post_cb);
614652
}
615653

654+
void ScriptState::add_update_transform(RETransform* transform, sol::protected_function fn) {
655+
ScriptRunner::get()->on_add_update_transform();
656+
m_on_update_transform_fns[transform] = fn;
657+
}
658+
616659
void ScriptState::install_hooks() {
617660
for (; !m_hooks_to_add.empty(); m_hooks_to_add.pop_front()) {
618661
auto hookdef = m_hooks_to_add.front();
@@ -1150,6 +1193,26 @@ void ScriptRunner::on_draw_ui() {
11501193
}
11511194
}
11521195

1196+
void ScriptRunner::on_update_transform(RETransform* transform) {
1197+
if (!m_has_any_transform_updates) {
1198+
return;
1199+
}
1200+
1201+
std::scoped_lock _{m_access_mutex};
1202+
1203+
if (m_states.empty()) {
1204+
return;
1205+
}
1206+
1207+
if (m_last_online_match_state) {
1208+
return;
1209+
}
1210+
1211+
for (auto& state : m_states) {
1212+
state->on_update_transform(transform);
1213+
}
1214+
}
1215+
11531216
void ScriptRunner::on_pre_application_entry(void* entry, const char* name, size_t hash) {
11541217
std::scoped_lock _{ m_access_mutex };
11551218

@@ -1264,6 +1327,9 @@ void ScriptRunner::reset_scripts() {
12641327
// the FirstPerson mod would attempt to hook an already hooked function
12651328
m_main_state.reset();
12661329
m_states.clear();
1330+
1331+
m_has_any_transform_updates = false;
1332+
12671333
//creating the main lua state
12681334
m_main_state = std::make_shared<ScriptState>(make_gc_data(),true);
12691335
//inserting it into the states vector

src/mods/ScriptRunner.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ class ScriptState : public std::enable_shared_from_this<ScriptState> {
137137

138138
void on_frame();
139139
void on_draw_ui();
140+
void on_update_transform(RETransform* transform);
140141
void on_pre_application_entry(size_t hash);
141142
void on_application_entry(size_t hash);
142143
bool on_pre_gui_draw_element(REComponent* gui_element, void* primitive_context);
@@ -152,6 +153,7 @@ class ScriptState : public std::enable_shared_from_this<ScriptState> {
152153
// add_hook enqueues the hook definition to be installed the next time install_hooks is called.
153154
void add_hook(sdk::REMethodDefinition* fn, sol::protected_function pre_cb, sol::protected_function post_cb, sol::object ignore_jmp_obj);
154155
void add_vtable(::REManagedObject* obj, sdk::REMethodDefinition* fn, sol::protected_function pre_cb, sol::protected_function post_cb);
156+
void add_update_transform(RETransform* transform, sol::protected_function fn);
155157

156158
// install_hooks goes through the queue of added hooks and actually creates them. The queue is emptied as a result.
157159
void install_hooks();
@@ -279,6 +281,8 @@ class ScriptState : public std::enable_shared_from_this<ScriptState> {
279281
std::unordered_multimap<size_t, sol::protected_function> m_pre_application_entry_fns{};
280282
std::unordered_multimap<size_t, sol::protected_function> m_application_entry_fns{};
281283

284+
std::unordered_map<RETransform*, sol::protected_function> m_on_update_transform_fns{};
285+
282286
std::vector<sol::protected_function> m_pre_gui_draw_element_fns{};
283287
std::vector<sol::protected_function> m_gui_draw_element_fns{};
284288
std::vector<sol::protected_function> m_on_draw_ui_fns{};
@@ -338,6 +342,7 @@ class ScriptRunner : public Mod {
338342
}
339343
void on_frame() override;
340344
void on_draw_ui() override;
345+
void on_update_transform(RETransform* transform) override;
341346
void on_pre_application_entry(void* entry, const char* name, size_t hash) override;
342347
void on_application_entry(void* entry, const char* name, size_t hash) override;
343348
bool on_pre_gui_draw_element(REComponent* gui_element, void* primitive_context) override;
@@ -348,10 +353,6 @@ class ScriptRunner : public Mod {
348353
const auto& get_state() {
349354
return m_main_state;
350355
}
351-
//not sure how to approach this, should there be error checking here?
352-
const auto& get_state(int index) {
353-
return m_states[index];
354-
}
355356

356357
void lock() {
357358
m_access_mutex.lock();
@@ -389,6 +390,10 @@ class ScriptRunner : public Mod {
389390
m_states_to_delete.push_back(lua_state);
390391
}
391392

393+
void on_add_update_transform() {
394+
m_has_any_transform_updates = true;
395+
}
396+
392397
private:
393398
ScriptState::GarbageCollectionData make_gc_data() const {
394399
ScriptState::GarbageCollectionData data{};
@@ -420,6 +425,7 @@ class ScriptRunner : public Mod {
420425
std::chrono::system_clock::time_point m_scene_check_time{};
421426
bool m_checked_scene_once{false};
422427
bool m_scene_okay{false};
428+
bool m_has_any_transform_updates{false};
423429
bool m_console_spawned{false};
424430
bool m_needs_first_reset{true};
425431
bool m_last_online_match_state{false};

0 commit comments

Comments
 (0)