add gsc io funcs
This commit is contained in:
parent
81e91b939f
commit
c2b2ce8e4c
@ -8,6 +8,7 @@
|
||||
#include "command.hpp"
|
||||
#include "console.hpp"
|
||||
#include "game_console.hpp"
|
||||
#include "gsc.hpp"
|
||||
#include "fastfiles.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "scheduler.hpp"
|
||||
@ -607,6 +608,12 @@ namespace command
|
||||
utils::hook::jump(SELECT_VALUE(0x3A7C80_b, 0x4E9F40_b), dvar_command_stub, true);
|
||||
|
||||
add_commands_generic();
|
||||
|
||||
gsc::function::add("executecommand", []()
|
||||
{
|
||||
const auto cmd = gsc::get_argument(0).as<std::string>();
|
||||
command::execute(cmd, true);
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -3,12 +3,10 @@
|
||||
|
||||
#include "console.hpp"
|
||||
#include "fastfiles.hpp"
|
||||
#include "gsc.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "logfile.hpp"
|
||||
#include "gsc.hpp"
|
||||
#include "scripting.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/dvars.hpp"
|
||||
#include "game/scripting/functions.hpp"
|
||||
|
||||
@ -452,16 +450,6 @@ namespace gsc
|
||||
}
|
||||
}
|
||||
|
||||
scripting::script_value get_argument(int index)
|
||||
{
|
||||
if (index >= static_cast<int>(game::scr_VmPub->outparamcount))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return game::scr_VmPub->top[-index];
|
||||
}
|
||||
|
||||
void execute_custom_function(builtin_function function)
|
||||
{
|
||||
auto error = false;
|
||||
@ -551,18 +539,6 @@ namespace gsc
|
||||
current_filename = filename;
|
||||
scr_emit_function_hook.invoke<void>(filename, thread_name, code_pos);
|
||||
}
|
||||
|
||||
void replace(std::string& str, const std::string& from, const std::string& to)
|
||||
{
|
||||
const auto start_pos = str.find(from);
|
||||
|
||||
if (start_pos == std::string::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
str.replace(start_pos, from.length(), to);
|
||||
}
|
||||
}
|
||||
|
||||
game::ScriptFile* find_script(game::XAssetType /*type*/, const char* name, int /*allow_create_default*/)
|
||||
@ -606,6 +582,16 @@ namespace gsc
|
||||
}
|
||||
}
|
||||
|
||||
scripting::script_value get_argument(int index)
|
||||
{
|
||||
if (index >= static_cast<int>(game::scr_VmPub->outparamcount))
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
return game::scr_VmPub->top[-index];
|
||||
}
|
||||
|
||||
namespace function
|
||||
{
|
||||
void add(const std::string& name, builtin_function function)
|
||||
@ -715,94 +701,6 @@ namespace gsc
|
||||
utils::hook::nop(SELECT_VALUE(0x3CBA4E_b, 0x512AAE_b), 2);
|
||||
utils::hook::call(SELECT_VALUE(0x3CBA46_b, 0x512AA6_b), vm_call_builtin_method_stub);
|
||||
|
||||
function::add("print", []()
|
||||
{
|
||||
const auto num = game::Scr_GetNumParam();
|
||||
std::string buffer{};
|
||||
|
||||
for (auto i = 0; i < num; i++)
|
||||
{
|
||||
const auto str = game::Scr_GetString(i);
|
||||
buffer.append(str);
|
||||
buffer.append("\t");
|
||||
}
|
||||
|
||||
console::info("[SCRIPT] %s\n", buffer.data());
|
||||
});
|
||||
|
||||
function::add("assert", []()
|
||||
{
|
||||
const auto expr = get_argument(0).as<int>();
|
||||
if (!expr)
|
||||
{
|
||||
throw std::runtime_error("assert fail");
|
||||
}
|
||||
});
|
||||
|
||||
function::add("assertex", []()
|
||||
{
|
||||
const auto expr = get_argument(0).as<int>();
|
||||
if (!expr)
|
||||
{
|
||||
const auto error = get_argument(1).as<std::string>();
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
});
|
||||
|
||||
function::add("replacefunc", []()
|
||||
{
|
||||
const auto what = get_argument(0).get_raw();
|
||||
const auto with = get_argument(1).get_raw();
|
||||
|
||||
if (what.type != game::SCRIPT_FUNCTION)
|
||||
{
|
||||
throw std::runtime_error("replaceFunc: parameter 1 must be a function");
|
||||
return;
|
||||
}
|
||||
|
||||
if (with.type != game::SCRIPT_FUNCTION)
|
||||
{
|
||||
throw std::runtime_error("replaceFunc: parameter 2 must be a function");
|
||||
return;
|
||||
}
|
||||
|
||||
logfile::set_gsc_hook(what.u.codePosValue, with.u.codePosValue);
|
||||
});
|
||||
|
||||
function::add("toupper", []()
|
||||
{
|
||||
const auto string = get_argument(0).as<std::string>();
|
||||
game::Scr_AddString(utils::string::to_upper(string).data());
|
||||
});
|
||||
|
||||
function::add("logprint", []()
|
||||
{
|
||||
std::string buffer{};
|
||||
|
||||
const auto params = game::Scr_GetNumParam();
|
||||
for (auto i = 0; i < params; i++)
|
||||
{
|
||||
const auto string = game::Scr_GetString(i);
|
||||
buffer.append(string);
|
||||
}
|
||||
|
||||
game::G_LogPrintf("%s", buffer.data());
|
||||
});
|
||||
|
||||
function::add("va", []()
|
||||
{
|
||||
auto fmt = get_argument(0).as<std::string>();
|
||||
|
||||
const auto params = game::Scr_GetNumParam();
|
||||
for (auto i = 1; i < params; i++)
|
||||
{
|
||||
const auto arg = get_argument(i).to_string();
|
||||
replace(fmt, "%s", arg);
|
||||
}
|
||||
|
||||
game::Scr_AddString(fmt.data());
|
||||
});
|
||||
|
||||
scripting::on_shutdown([](int free_scripts)
|
||||
{
|
||||
if (free_scripts)
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/game.hpp"
|
||||
#include "game/scripting/script_value.hpp"
|
||||
|
||||
namespace gsc
|
||||
{
|
||||
@ -15,6 +15,8 @@ namespace gsc
|
||||
void load_main_handles();
|
||||
void load_init_handles();
|
||||
|
||||
scripting::script_value get_argument(int index);
|
||||
|
||||
namespace function
|
||||
{
|
||||
void add(const std::string& name, builtin_function function);
|
||||
|
220
src/client/component/io.cpp
Normal file
220
src/client/component/io.cpp
Normal file
@ -0,0 +1,220 @@
|
||||
#include <std_include.hpp>
|
||||
#include "loader/component_loader.hpp"
|
||||
|
||||
#include "game/game.hpp"
|
||||
|
||||
#include "console.hpp"
|
||||
#include "gsc.hpp"
|
||||
#include "logfile.hpp"
|
||||
#include "scheduler.hpp"
|
||||
|
||||
#include "gsc.hpp"
|
||||
|
||||
#include <utils/hook.hpp>
|
||||
#include <utils/http.hpp>
|
||||
#include <utils/io.hpp>
|
||||
|
||||
namespace io
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void replace(std::string& str, const std::string& from, const std::string& to)
|
||||
{
|
||||
const auto start_pos = str.find(from);
|
||||
|
||||
if (start_pos == std::string::npos)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
str.replace(start_pos, from.length(), to);
|
||||
}
|
||||
}
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
void post_unpack() override
|
||||
{
|
||||
gsc::function::add("print", []()
|
||||
{
|
||||
const auto num = game::Scr_GetNumParam();
|
||||
std::string buffer{};
|
||||
|
||||
for (auto i = 0; i < num; i++)
|
||||
{
|
||||
const auto str = game::Scr_GetString(i);
|
||||
buffer.append(str);
|
||||
buffer.append("\t");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
console::debug("[SCRIPT] %s\n", buffer.data());
|
||||
#else
|
||||
console::info("[SCRIPT] %s\n", buffer.data());
|
||||
#endif
|
||||
});
|
||||
|
||||
gsc::function::add("assert", []()
|
||||
{
|
||||
const auto expr = gsc::get_argument(0).as<int>();
|
||||
if (!expr)
|
||||
{
|
||||
throw std::runtime_error("assert fail");
|
||||
}
|
||||
});
|
||||
|
||||
gsc::function::add("assertex", []()
|
||||
{
|
||||
const auto expr = gsc::get_argument(0).as<int>();
|
||||
if (!expr)
|
||||
{
|
||||
const auto error = gsc::get_argument(1).as<std::string>();
|
||||
throw std::runtime_error(error);
|
||||
}
|
||||
});
|
||||
|
||||
gsc::function::add("replacefunc", []()
|
||||
{
|
||||
const auto what = gsc::get_argument(0).get_raw();
|
||||
const auto with = gsc::get_argument(1).get_raw();
|
||||
|
||||
if (what.type != game::SCRIPT_FUNCTION)
|
||||
{
|
||||
throw std::runtime_error("replaceFunc: parameter 1 must be a function");
|
||||
return;
|
||||
}
|
||||
|
||||
if (with.type != game::SCRIPT_FUNCTION)
|
||||
{
|
||||
throw std::runtime_error("replaceFunc: parameter 2 must be a function");
|
||||
return;
|
||||
}
|
||||
|
||||
logfile::set_gsc_hook(what.u.codePosValue, with.u.codePosValue);
|
||||
});
|
||||
|
||||
gsc::function::add("toupper", []()
|
||||
{
|
||||
const auto string = gsc::get_argument(0).as<std::string>();
|
||||
game::Scr_AddString(utils::string::to_upper(string).data());
|
||||
});
|
||||
|
||||
gsc::function::add("logprint", []()
|
||||
{
|
||||
std::string buffer{};
|
||||
|
||||
const auto params = game::Scr_GetNumParam();
|
||||
for (auto i = 0; i < params; i++)
|
||||
{
|
||||
const auto string = game::Scr_GetString(i);
|
||||
buffer.append(string);
|
||||
}
|
||||
|
||||
game::G_LogPrintf("%s", buffer.data());
|
||||
});
|
||||
|
||||
gsc::function::add("va", []()
|
||||
{
|
||||
auto fmt = gsc::get_argument(0).as<std::string>();
|
||||
|
||||
const auto params = game::Scr_GetNumParam();
|
||||
for (auto i = 1; i < params; i++)
|
||||
{
|
||||
const auto arg = gsc::get_argument(i).to_string();
|
||||
replace(fmt, "%s", arg);
|
||||
}
|
||||
|
||||
game::Scr_AddString(fmt.data());
|
||||
});
|
||||
|
||||
gsc::function::add("fileexists", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
|
||||
game::Scr_AddBool(utils::io::file_exists(path));
|
||||
});
|
||||
|
||||
gsc::function::add("writefile", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
const auto data = gsc::get_argument(1).as<std::string>();
|
||||
|
||||
const auto params = game::Scr_GetNumParam();
|
||||
|
||||
auto append = false;
|
||||
if (params > 2)
|
||||
{
|
||||
append = gsc::get_argument(2).as<bool>();
|
||||
}
|
||||
|
||||
game::Scr_AddBool(utils::io::write_file(path, data, append));
|
||||
});
|
||||
|
||||
gsc::function::add("readfile", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
game::Scr_AddString(utils::io::read_file(path).data());
|
||||
});
|
||||
|
||||
/*
|
||||
gsc::function::add("filesize", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
|
||||
// return type is size_t, so we probably need to find a way to do that :P maybe just make it a string? lmao
|
||||
game::Scr_AddInt(utils::io::file_size(path));
|
||||
});
|
||||
*/
|
||||
|
||||
gsc::function::add("createdirectory", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
game::Scr_AddBool(utils::io::create_directory(path));
|
||||
});
|
||||
|
||||
gsc::function::add("directoryexists", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
game::Scr_AddBool(utils::io::directory_exists(path));
|
||||
});
|
||||
|
||||
gsc::function::add("directoryisempty", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
game::Scr_AddBool(utils::io::directory_is_empty(path));
|
||||
});
|
||||
|
||||
/*
|
||||
gsc::function::add("listfiles", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
const auto files = utils::io::list_files(path);
|
||||
|
||||
scripting::array array{};
|
||||
for (const auto& file : files)
|
||||
{
|
||||
array.push(file);
|
||||
}
|
||||
|
||||
return array;
|
||||
});
|
||||
*/
|
||||
|
||||
gsc::function::add("copyfolder", []()
|
||||
{
|
||||
const auto source = gsc::get_argument(0).as<std::string>();
|
||||
const auto target = gsc::get_argument(1).as<std::string>();
|
||||
utils::io::copy_folder(source, target);
|
||||
});
|
||||
|
||||
gsc::function::add("removefile", []()
|
||||
{
|
||||
const auto path = gsc::get_argument(0).as<std::string>();
|
||||
game::Scr_AddBool(utils::io::remove_file(path));
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
REGISTER_COMPONENT(io::component)
|
@ -152,6 +152,8 @@ namespace game
|
||||
unsigned int paramcount)> VM_Execute{0x3C9E50, 0x510EB0};
|
||||
|
||||
WEAK symbol<void(const char* value)> Scr_AddString{0x3C7B20, 0x50EC50};
|
||||
WEAK symbol<void(int value)> Scr_AddInt{0x3C7A40, 0x50EB70};
|
||||
WEAK symbol<void(int value)> Scr_AddBool{0x3C77C0, 0x50E8F0};
|
||||
|
||||
WEAK symbol<void(unsigned int id, scr_string_t stringValue,
|
||||
unsigned int paramcount)> Scr_NotifyId{0x3C92E0, 0x510340};
|
||||
@ -191,10 +193,10 @@ namespace game
|
||||
WEAK symbol<void(XZoneInfo* zoneInfo, unsigned int zoneCount, DBSyncMode syncMode)> DB_LoadXAssets{0x1F31E0, 0x397500};
|
||||
WEAK symbol<bool(const char* zoneName)> DB_IsLocalized{0x1F23C0, 0x396790};
|
||||
|
||||
WEAK symbol<void(int clientNum, const char* menu,
|
||||
int a3, int a4, unsigned int a5)> LUI_OpenMenu{0x3F20A0, 0x1E1210};
|
||||
WEAK symbol<void(int clientNum, const char* menu, int a3,
|
||||
hks::lua_State* a4)> LUI_LeaveMenuByName{0xF6D00, 0x26BE80};
|
||||
WEAK symbol<void(int client_num, const char* menu,
|
||||
int is_popup, int client_num, unsigned int is_exclusive)> LUI_OpenMenu{0x3F20A0, 0x1E1210};
|
||||
WEAK symbol<void(int clientNum, const char* menu, int immediate,
|
||||
hks::lua_State* state)> LUI_LeaveMenuByName{0xF6D00, 0x26BE80};
|
||||
WEAK symbol<void()> LUI_EnterCriticalSection{0xF19A0, 0x2669B0};
|
||||
WEAK symbol<void()> LUI_LeaveCriticalSection{0xF6C40, 0x26BDC0};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user