2022-10-04 22:09:22 -04:00
|
|
|
#include <std_include.hpp>
|
|
|
|
#include "loader/component_loader.hpp"
|
|
|
|
|
2022-10-21 18:05:18 -04:00
|
|
|
#include "component/console.hpp"
|
|
|
|
#include "component/logfile.hpp"
|
|
|
|
#include "component/scheduler.hpp"
|
|
|
|
#include "component/gsc/script_extension.hpp"
|
2022-10-04 22:09:22 -04:00
|
|
|
|
|
|
|
#include "game/dvars.hpp"
|
|
|
|
#include "game/game.hpp"
|
|
|
|
|
|
|
|
#include "game/scripting/execution.hpp"
|
|
|
|
|
|
|
|
#include <utils/hook.hpp>
|
|
|
|
#include <utils/http.hpp>
|
2022-10-14 15:02:18 -04:00
|
|
|
#include <utils/flags.hpp>
|
2022-10-04 22:09:22 -04:00
|
|
|
#include <utils/io.hpp>
|
|
|
|
|
|
|
|
namespace io
|
|
|
|
{
|
|
|
|
namespace
|
|
|
|
{
|
2022-10-26 23:22:45 -04:00
|
|
|
bool allow_root_io = false;
|
2022-10-14 15:02:18 -04:00
|
|
|
|
2022-10-04 22:09:22 -04:00
|
|
|
void check_path(const std::filesystem::path& path)
|
|
|
|
{
|
|
|
|
if (path.generic_string().find("..") != std::string::npos)
|
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
throw std::runtime_error("directory traversal is not allowed");
|
2022-10-04 22:09:22 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string convert_path(const std::filesystem::path& path)
|
|
|
|
{
|
|
|
|
check_path(path);
|
|
|
|
|
2022-10-26 23:22:45 -04:00
|
|
|
if (allow_root_io)
|
2022-10-14 15:02:18 -04:00
|
|
|
{
|
|
|
|
static const auto fs_base_game = game::Dvar_FindVar("fs_basepath");
|
|
|
|
const std::filesystem::path fs_base_game_path(fs_base_game->current.string);
|
|
|
|
return (fs_base_game_path / path).generic_string();
|
|
|
|
}
|
|
|
|
|
|
|
|
static const auto fs_game = game::Dvar_FindVar("fs_game");
|
2022-10-04 22:09:22 -04:00
|
|
|
if (fs_game->current.string && fs_game->current.string != ""s)
|
|
|
|
{
|
|
|
|
const std::filesystem::path fs_game_path(fs_game->current.string);
|
|
|
|
return (fs_game_path / path).generic_string();
|
|
|
|
}
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
throw std::runtime_error("fs_game is not properly defined");
|
2022-10-04 22:09:22 -04:00
|
|
|
}
|
2022-10-18 06:38:06 -04:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2022-10-04 22:09:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
class component final : public component_interface
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
void post_unpack() override
|
|
|
|
{
|
2022-10-26 23:22:45 -04:00
|
|
|
allow_root_io = utils::flags::has_flag("allow_root_io");
|
|
|
|
if (allow_root_io)
|
2022-10-14 15:02:18 -04:00
|
|
|
{
|
2022-10-26 23:22:45 -04:00
|
|
|
console::warn("GSC has access to your game folder. Remove the '-allow_root_io' launch parameter to disable this feature.");
|
2022-10-14 15:02:18 -04:00
|
|
|
}
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("fileexists", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
return utils::io::file_exists(path);
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("writefile", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
const auto data = args[1].as<std::string>();
|
2022-10-04 22:09:22 -04:00
|
|
|
|
|
|
|
auto append = false;
|
2022-10-14 12:39:27 -04:00
|
|
|
if (args.size() > 2u)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
append = args[2].as<bool>();
|
2022-10-04 22:09:22 -04:00
|
|
|
}
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
return utils::io::write_file(path, data, append);
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("readfile", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
return utils::io::read_file(path);
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("filesize", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
return static_cast<uint32_t>(utils::io::file_size(path));
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("createdirectory", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
return utils::io::create_directory(path);
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("directoryexists", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
return utils::io::directory_exists(path);
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("directoryisempty", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
return utils::io::directory_is_empty(path);
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("listfiles", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
2022-10-04 22:09:22 -04:00
|
|
|
const auto files = utils::io::list_files(path);
|
|
|
|
|
|
|
|
scripting::array array{};
|
|
|
|
for (const auto& file : files)
|
|
|
|
{
|
|
|
|
array.push(file);
|
|
|
|
}
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
return array;
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("copyfolder", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto source = convert_path(args[0].as<std::string>());
|
|
|
|
const auto target = convert_path(args[1].as<std::string>());
|
2022-10-04 22:09:22 -04:00
|
|
|
utils::io::copy_folder(source, target);
|
2022-10-14 12:39:27 -04:00
|
|
|
|
|
|
|
return scripting::script_value{};
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
|
|
|
|
2022-10-14 12:39:27 -04:00
|
|
|
gsc::function::add("removefile", [](const gsc::function_args& args)
|
2022-10-04 22:09:22 -04:00
|
|
|
{
|
2022-10-14 12:39:27 -04:00
|
|
|
const auto path = convert_path(args[0].as<std::string>());
|
|
|
|
return utils::io::remove_file(path);
|
2022-10-04 22:09:22 -04:00
|
|
|
});
|
2022-10-18 06:38:06 -04:00
|
|
|
|
|
|
|
gsc::function::add("va", [](const gsc::function_args& args)
|
|
|
|
{
|
|
|
|
auto fmt = args[0].as<std::string>();
|
|
|
|
|
|
|
|
for (auto i = 1u; i < args.size(); i++)
|
|
|
|
{
|
|
|
|
const auto arg = args[i].to_string();
|
|
|
|
replace(fmt, "%s", arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt;
|
|
|
|
});
|
2022-10-04 22:09:22 -04:00
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
REGISTER_COMPONENT(io::component)
|