Refactoring + update some stuff

This commit is contained in:
Federico Cecchetto 2021-06-19 03:40:28 +02:00
parent 833271b7a1
commit 50eb58dfd9
8 changed files with 52 additions and 53 deletions

View File

@ -13,6 +13,8 @@
namespace gsc namespace gsc
{ {
std::unordered_map<unsigned, unsigned> replaced_functions;
function_args::function_args(std::vector<scripting::script_value> values) function_args::function_args(std::vector<scripting::script_value> values)
: values_(values) : values_(values)
{ {
@ -203,9 +205,9 @@ namespace gsc
void get_replaced_pos(unsigned int pos) 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"); throw std::runtime_error("Invalid type");
} }
scripting::replaced_functions[what.u.uintValue] = with.u.uintValue; replaced_functions[what.u.uintValue] = with.u.uintValue;
return {}; return {};
}); });

View File

@ -2,6 +2,8 @@
namespace gsc namespace gsc
{ {
extern std::unordered_map<unsigned, unsigned> replaced_functions;
class function_args class function_args
{ {
public: public:

View File

@ -5,6 +5,4 @@ namespace scheduler
void schedule(const std::function<bool()>& callback, std::chrono::milliseconds delay = 0ms); void schedule(const std::function<bool()>& callback, std::chrono::milliseconds delay = 0ms);
void loop(const std::function<void()>& callback, std::chrono::milliseconds delay = 0ms); void loop(const std::function<void()>& callback, std::chrono::milliseconds delay = 0ms);
void once(const std::function<void()>& callback, std::chrono::milliseconds delay = 0ms); void once(const std::function<void()>& callback, std::chrono::milliseconds delay = 0ms);
void init();
} }

View File

@ -8,12 +8,12 @@
#include "game/scripting/execution.hpp" #include "game/scripting/execution.hpp"
#include "game/scripting/functions.hpp" #include "game/scripting/functions.hpp"
#include "gsc.hpp"
namespace scripting namespace scripting
{ {
std::unordered_map<int, std::unordered_map<std::string, int>> fields_table; std::unordered_map<int, std::unordered_map<std::string, int>> fields_table;
std::unordered_map<std::string, std::unordered_map<std::string, char*>> script_function_table; std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
std::unordered_map<unsigned, unsigned> replaced_functions;
namespace namespace
{ {
@ -23,8 +23,10 @@ namespace scripting
utils::hook::detour scr_load_level_hook; utils::hook::detour scr_load_level_hook;
utils::hook::detour g_shutdown_game_hook; utils::hook::detour g_shutdown_game_hook;
utils::hook::detour scr_emit_function_hook; utils::hook::detour scr_set_thread_position_hook;
utils::hook::detour scr_end_load_scripts_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, void vm_notify_stub(const unsigned int notify_list_owner_id, const unsigned int string_value,
game::VariableValue* top) game::VariableValue* top)
@ -71,57 +73,33 @@ namespace scripting
void g_shutdown_game_stub(const int free_scripts) void g_shutdown_game_stub(const int free_scripts)
{ {
command::clear_script_commands(); command::clear_script_commands();
replaced_functions.clear(); gsc::replaced_functions.clear();
g_shutdown_game_hook.invoke<void>(free_scripts); g_shutdown_game_hook.invoke<void>(free_scripts);
} }
char* function_pos(unsigned int filename, unsigned int name) void process_script_stub(const char* filename)
{ {
const auto scripts_pos = *reinterpret_cast<int*>(0x1D6EB14); current_file = filename;
const auto v2 = game::FindVariable(scripts_pos, filename); const auto file_id = atoi(filename);
if (file_id)
const auto v3 = game::FindObject(scripts_pos, v2);
const auto v4 = game::FindVariable(v3, name);
if (!v2 || !v3 || !v4)
{ {
return 0; current_file = scripting::file_list[file_id];
} }
return utils::hook::invoke<char*>(0x5659C0, v3, v4); process_script_hook.invoke<void>(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 function_name = scripting::find_token(threadName);
const auto filename_id = atoi(name);
for (const auto& entry : scripting::file_list) if (!function_name.empty())
{ {
if (entry.first == filename_id) script_function_table[current_file][function_name] = codePos;
{
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;
}
}
}
}
} }
scr_emit_function_hook.invoke<void>(filename, threadName, codePos); scr_set_thread_position_hook.invoke<void>(threadName, codePos);
} }
} }
@ -134,6 +112,10 @@ namespace scripting
g_shutdown_game_hook.create(0x50C100, g_shutdown_game_stub); g_shutdown_game_hook.create(0x50C100, g_shutdown_game_stub);
scr_add_class_field_hook.create(0x567CD0, scr_add_class_field_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);
} }
}; };
} }

View File

@ -2,8 +2,6 @@
namespace scripting namespace scripting
{ {
extern std::unordered_map<unsigned, unsigned> replaced_functions;
extern std::unordered_map<int, std::unordered_map<std::string, int>> fields_table; extern std::unordered_map<int, std::unordered_map<std::string, int>> fields_table;
extern std::unordered_map<std::string, std::unordered_map<std::string, char*>> script_function_table; extern std::unordered_map<std::string, std::unordered_map<std::string, const char*>> script_function_table;
} }

View File

@ -155,8 +155,7 @@ namespace scripting
return get_return_value(); return get_return_value();
} }
script_value call_script_function(const entity& entity, const std::string& filename, const char* get_function_pos(const std::string& filename, const std::string& function)
const std::string& function, const std::vector<script_value>& arguments)
{ {
if (scripting::script_function_table.find(filename) == scripting::script_function_table.end()) 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]; const auto functions = scripting::script_function_table[filename];
if (functions.find(function) == functions.end()) if (functions.find(function) == functions.end())
{ {
throw std::runtime_error("Function '" + function + "' in file '" + filename + "' not found"); 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<script_value>& arguments)
{
const auto pos = get_function_pos(filename, function);
return exec_ent_thread(entity, pos, arguments); return exec_ent_thread(entity, pos, arguments);
} }

View File

@ -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) int find_token_id(const std::string& name)
{ {
const auto result = token_map.find(name); const auto result = token_map.find(name);

View File

@ -12,4 +12,5 @@ namespace scripting
script_function find_function(const std::string& name, const bool prefer_global); script_function find_function(const std::string& name, const bool prefer_global);
int find_token_id(const std::string& name); int find_token_id(const std::string& name);
std::string find_token(unsigned int id);
} }