diff --git a/src/component/gsc.cpp b/src/component/gsc.cpp index 26fd678..1f5a960 100644 --- a/src/component/gsc.cpp +++ b/src/component/gsc.cpp @@ -13,6 +13,8 @@ namespace gsc { + std::unordered_map replaced_functions; + function_args::function_args(std::vector values) : values_(values) { @@ -203,9 +205,9 @@ namespace gsc void get_replaced_pos(unsigned int pos) { - if (scripting::replaced_functions.find(pos) != scripting::replaced_functions.end()) + if (replaced_functions.find(pos) != replaced_functions.end()) { - replaced_pos = scripting::replaced_functions[pos]; + replaced_pos = replaced_functions[pos]; } } @@ -299,7 +301,7 @@ namespace gsc throw std::runtime_error("Invalid type"); } - scripting::replaced_functions[what.u.uintValue] = with.u.uintValue; + replaced_functions[what.u.uintValue] = with.u.uintValue; return {}; }); diff --git a/src/component/gsc.hpp b/src/component/gsc.hpp index 8dcc3c2..a357eb7 100644 --- a/src/component/gsc.hpp +++ b/src/component/gsc.hpp @@ -2,6 +2,8 @@ namespace gsc { + extern std::unordered_map replaced_functions; + class function_args { public: diff --git a/src/component/scheduler.hpp b/src/component/scheduler.hpp index 7014cd7..4a5e5aa 100644 --- a/src/component/scheduler.hpp +++ b/src/component/scheduler.hpp @@ -5,6 +5,4 @@ namespace scheduler void schedule(const std::function& callback, std::chrono::milliseconds delay = 0ms); void loop(const std::function& callback, std::chrono::milliseconds delay = 0ms); void once(const std::function& callback, std::chrono::milliseconds delay = 0ms); - - void init(); } diff --git a/src/component/scripting.cpp b/src/component/scripting.cpp index 7df58ff..00953e1 100644 --- a/src/component/scripting.cpp +++ b/src/component/scripting.cpp @@ -8,12 +8,12 @@ #include "game/scripting/execution.hpp" #include "game/scripting/functions.hpp" +#include "gsc.hpp" + namespace scripting { std::unordered_map> fields_table; - std::unordered_map> script_function_table; - - std::unordered_map replaced_functions; + std::unordered_map> script_function_table; namespace { @@ -23,8 +23,10 @@ namespace scripting utils::hook::detour scr_load_level_hook; utils::hook::detour g_shutdown_game_hook; - utils::hook::detour scr_emit_function_hook; - utils::hook::detour scr_end_load_scripts_hook; + utils::hook::detour scr_set_thread_position_hook; + utils::hook::detour process_script_hook; + + std::string current_file; void vm_notify_stub(const unsigned int notify_list_owner_id, const unsigned int string_value, game::VariableValue* top) @@ -71,57 +73,33 @@ namespace scripting void g_shutdown_game_stub(const int free_scripts) { command::clear_script_commands(); - replaced_functions.clear(); + gsc::replaced_functions.clear(); g_shutdown_game_hook.invoke(free_scripts); } - char* function_pos(unsigned int filename, unsigned int name) + void process_script_stub(const char* filename) { - const auto scripts_pos = *reinterpret_cast(0x1D6EB14); + current_file = filename; - const auto v2 = game::FindVariable(scripts_pos, filename); - - const auto v3 = game::FindObject(scripts_pos, v2); - const auto v4 = game::FindVariable(v3, name); - - if (!v2 || !v3 || !v4) + const auto file_id = atoi(filename); + if (file_id) { - return 0; + current_file = scripting::file_list[file_id]; } - return utils::hook::invoke(0x5659C0, v3, v4); + process_script_hook.invoke(filename); } - void scr_emit_function_stub(unsigned int filename, unsigned int threadName, char* codePos) + void scr_set_thread_position_stub(unsigned int threadName, const char* codePos) { - const auto* name = game::SL_ConvertToString(filename); - const auto filename_id = atoi(name); + const auto function_name = scripting::find_token(threadName); - for (const auto& entry : scripting::file_list) + if (!function_name.empty()) { - if (entry.first == filename_id) - { - if (script_function_table.find(entry.second) == script_function_table.end()) - { - script_function_table[entry.second] = {}; - } - - for (const auto& token : scripting::token_map) - { - if (token.second == threadName) - { - const auto pos = function_pos(filename, threadName); - - if (pos) - { - script_function_table[entry.second][token.first] = pos; - } - } - } - } + script_function_table[current_file][function_name] = codePos; } - scr_emit_function_hook.invoke(filename, threadName, codePos); + scr_set_thread_position_hook.invoke(threadName, codePos); } } @@ -134,6 +112,10 @@ namespace scripting g_shutdown_game_hook.create(0x50C100, g_shutdown_game_stub); scr_add_class_field_hook.create(0x567CD0, scr_add_class_field_stub); + vm_notify_hook.create(0x569720, vm_notify_stub); + + scr_set_thread_position_hook.create(0x5616D0, scr_set_thread_position_stub); + process_script_hook.create(0x56B130, process_script_stub); } }; } diff --git a/src/component/scripting.hpp b/src/component/scripting.hpp index b8fc942..1f16a66 100644 --- a/src/component/scripting.hpp +++ b/src/component/scripting.hpp @@ -2,8 +2,6 @@ namespace scripting { - extern std::unordered_map replaced_functions; - extern std::unordered_map> fields_table; - extern std::unordered_map> script_function_table; + extern std::unordered_map> script_function_table; } \ No newline at end of file diff --git a/src/game/scripting/execution.cpp b/src/game/scripting/execution.cpp index 9f1047a..8625390 100644 --- a/src/game/scripting/execution.cpp +++ b/src/game/scripting/execution.cpp @@ -155,8 +155,7 @@ namespace scripting return get_return_value(); } - script_value call_script_function(const entity& entity, const std::string& filename, - const std::string& function, const std::vector& arguments) + const char* get_function_pos(const std::string& filename, const std::string& function) { if (scripting::script_function_table.find(filename) == scripting::script_function_table.end()) { @@ -164,14 +163,18 @@ namespace scripting }; const auto functions = scripting::script_function_table[filename]; - if (functions.find(function) == functions.end()) { throw std::runtime_error("Function '" + function + "' in file '" + filename + "' not found"); } - const auto pos = functions.at(function); + return functions.at(function); + } + script_value call_script_function(const entity& entity, const std::string& filename, + const std::string& function, const std::vector& arguments) + { + const auto pos = get_function_pos(filename, function); return exec_ent_thread(entity, pos, arguments); } diff --git a/src/game/scripting/functions.cpp b/src/game/scripting/functions.cpp index 18b5195..b827de4 100644 --- a/src/game/scripting/functions.cpp +++ b/src/game/scripting/functions.cpp @@ -71,6 +71,19 @@ namespace scripting } } + std::string find_token(unsigned int id) + { + for (const auto& token : token_map) + { + if (token.second == id) + { + return token.first; + } + } + + return {}; + } + int find_token_id(const std::string& name) { const auto result = token_map.find(name); diff --git a/src/game/scripting/functions.hpp b/src/game/scripting/functions.hpp index 2f0cc11..2e62b9a 100644 --- a/src/game/scripting/functions.hpp +++ b/src/game/scripting/functions.hpp @@ -12,4 +12,5 @@ namespace scripting script_function find_function(const std::string& name, const bool prefer_global); int find_token_id(const std::string& name); + std::string find_token(unsigned int id); }