@@ -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+
470508void 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+
616659void 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+
11531216void 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
0 commit comments