Add some functions + namespace support

This commit is contained in:
Federico Cecchetto 2022-06-11 23:21:47 +02:00
parent a1b8d80bf2
commit c466066530
5 changed files with 105 additions and 13 deletions

View File

@ -130,12 +130,12 @@ namespace command
{ {
scripting::on_shutdown(clear_script_commands); scripting::on_shutdown(clear_script_commands);
gsc::function::add("executecommand", [](const std::string& command) const auto execute_command = [](const std::string& command)
{ {
execute(command, false); execute(command, false);
}); };
gsc::function::add("addcommand", [](const std::string& name, const scripting::function& function) const auto add_command = [](const std::string& name, const scripting::function& function)
{ {
command::add_script_command(name, [function](const command::params& params) command::add_script_command(name, [function](const command::params& params)
{ {
@ -148,7 +148,28 @@ namespace command
function({array}); function({array});
}); });
};
gsc::function::add_multiple([](const std::string& command)
{
execute(command, false);
}, "executecommand", "command::execute");
gsc::function::add_multiple([](const std::string& name, const scripting::function& function)
{
command::add_script_command(name, [function](const command::params& params)
{
scripting::array array;
for (auto i = 0; i < params.size(); i++)
{
array.push(params[i]);
}
function({array});
}); });
}, "addcommand", "command::add");
} }
}; };
} }

View File

@ -171,6 +171,42 @@ namespace gsc
{ {
scr_settings_hook.invoke<void>(developer_script, developer_script, 0, inst); scr_settings_hook.invoke<void>(developer_script, developer_script, 0, inst);
} }
utils::hook::detour scr_get_builtin_hook;
unsigned int scr_get_builtin_stub(int inst, game::sval_u func_name)
{
const auto type = *reinterpret_cast<uint8_t*>(func_name.block);
if (type != 28)
{
return scr_get_builtin_hook.invoke<unsigned int>(inst, func_name);
}
const auto func_namea = *reinterpret_cast<void**>(reinterpret_cast<size_t>(func_name.block) + 4);
const auto typea = *reinterpret_cast<uint8_t*>(func_namea);
if (typea != 20)
{
return scr_get_builtin_hook.invoke<unsigned int>(inst, func_name);
}
const auto func_nameb = *reinterpret_cast<void**>(reinterpret_cast<size_t>(func_namea) + 4);
const auto typeb = *reinterpret_cast<uint8_t*>(func_nameb);
if (typeb == 23) // script::function type call
{
const auto namespace_ = game::SL_ConvertToString(
*reinterpret_cast<unsigned int*>(reinterpret_cast<size_t>(func_nameb) + 4), game::SCRIPTINSTANCE_SERVER);
const auto name = game::SL_ConvertToString(
*reinterpret_cast<unsigned int*>(reinterpret_cast<size_t>(func_nameb) + 8), game::SCRIPTINSTANCE_SERVER);
const auto full_name = utils::string::va("%s::%s", namespace_, name);
if (functions.find(full_name) != functions.end())
{
return game::SL_GetString(full_name, 0, game::SCRIPTINSTANCE_SERVER);
}
}
return scr_get_builtin_hook.invoke<unsigned int>(inst, func_name);
}
} }
namespace function namespace function
@ -209,6 +245,8 @@ namespace gsc
get_function_hook.create(utils::hook::extract<size_t>(SELECT_VALUE(0x8A02FB, 0x8DE11B) + 1), get_function_stub); get_function_hook.create(utils::hook::extract<size_t>(SELECT_VALUE(0x8A02FB, 0x8DE11B) + 1), get_function_stub);
get_method_hook.create(utils::hook::extract<size_t>(SELECT_VALUE(0x8A052E, 0x8DE34E) + 1), get_method_stub); get_method_hook.create(utils::hook::extract<size_t>(SELECT_VALUE(0x8A052E, 0x8DE34E) + 1), get_method_stub);
scr_get_builtin_hook.create(SELECT_VALUE(0x4ACAC0, 0x411490), scr_get_builtin_stub);
// \n******* script runtime error *******\n%s\n // \n******* script runtime error *******\n%s\n
utils::hook::set<char>(SELECT_VALUE(0x9FC5C0 + 40, 0xAABA68 + 40), '\n'); utils::hook::set<char>(SELECT_VALUE(0x9FC5C0 + 40, 0xAABA68 + 40), '\n');
utils::hook::set<char>(SELECT_VALUE(0x9FC5C0 + 41, 0xAABA68 + 41), '\0'); utils::hook::set<char>(SELECT_VALUE(0x9FC5C0 + 41, 0xAABA68 + 41), '\0');
@ -225,13 +263,10 @@ namespace gsc
return array; return array;
}); });
const auto typeof = [](const scripting::script_value& value) gsc::function::add_multiple([](const scripting::script_value& value)
{ {
return value.type_name(); return value.type_name();
}; }, "typeof", "type");
gsc::function::add("typeof", typeof);
gsc::function::add("type", typeof);
} }
}; };
} }

View File

@ -56,6 +56,13 @@ namespace gsc
{ {
add_internal(name, wrap_function(f)); add_internal(name, wrap_function(f));
} }
template <typename ...Args, typename F>
void add_multiple(F f, Args&& ...names)
{
const auto wrap = wrap_function(f);
(add_internal(names, wrap), ...);
}
} }
namespace method namespace method
@ -67,5 +74,12 @@ namespace gsc
{ {
add_internal(name, wrap_function(f)); add_internal(name, wrap_function(f));
} }
template <typename ...Args, typename F>
void add_multiple(F f, Args&& ...names)
{
const auto wrap = wrap_function(f);
(add_internal(names, wrap), ...);
}
} }
} }

View File

@ -24,7 +24,7 @@ namespace string
// lua/lstrlib.c // lua/lstrlib.c
const char* getformat(const char* strfrmt, char* form) const char* getformat(const char* strfrmt, char* form)
{ {
const auto len = strspn(strfrmt, L_FMTFLAGSF "123456789.") + 1; const auto len = std::strspn(strfrmt, L_FMTFLAGSF "123456789.") + 1;
if (len >= MAX_FORMAT - 10) if (len >= MAX_FORMAT - 10)
{ {
throw std::runtime_error("invalid format (too long)"); throw std::runtime_error("invalid format (too long)");
@ -162,9 +162,8 @@ namespace string
public: public:
void post_unpack() override void post_unpack() override
{ {
gsc::function::add("va", format_string); gsc::function::add_multiple(format_string, "va", "string::va",
gsc::function::add("formatstring", format_string); "formatstring", "string::format", "sprintf");
gsc::function::add("sprintf", format_string);
gsc::function::add("printf", [](const std::string& fmt, const scripting::variadic_args& va) gsc::function::add("printf", [](const std::string& fmt, const scripting::variadic_args& va)
{ {
@ -179,6 +178,14 @@ namespace string
} }
printf("\n"); printf("\n");
}); });
gsc::function::add_multiple(utils::string::to_upper, "toupper", "string::toupper");
gsc::function::add_multiple(utils::string::to_lower, "tolower", "string::tolower");
gsc::function::add("string::isnumeric", utils::string::is_numeric);
gsc::function::add("string::startswith", utils::string::starts_with);
gsc::function::add("string::endswith", utils::string::ends_with);
gsc::function::add("string::replace", utils::string::replace);
} }
}; };
} }

View File

@ -767,4 +767,19 @@ namespace game
{ {
ScriptParseTree* scriptParseTree; ScriptParseTree* scriptParseTree;
}; };
union sval_u
{
unsigned __int8 type;
unsigned int stringValue;
unsigned int idValue;
float floatValue;
int intValue;
sval_u* node;
unsigned int sourcePosValue;
const char* codePosValue;
const char* debugString;
void* block;
};
} }