#include #include "loader/component_loader.hpp" #include "game/game.hpp" #include "gsc.hpp" #include "io.hpp" #include "scheduler.hpp" #include "scripting.hpp" #include #include #include #include #include namespace io { namespace { struct watched_file { std::unique_ptr watcher; scripting::object handle; }; std::vector watched_files; void poll_files() { for (auto& file : watched_files) { std::string data; if (file.watcher->run(1ms, &data, true)) { scripting::notify(file.handle.get_entity_id(), "data", {data}); } } } } class component final : public component_interface { public: void on_after_dvar_init([[maybe_unused]] plugin::plugin* plugin) override { const auto fs_homepath = game::Dvar_FindVar("fs_homepath"); if (fs_homepath == nullptr) { return; } std::filesystem::current_path(fs_homepath->current.string); printf("working directory: %s", fs_homepath->current.string); } void on_startup([[maybe_unused]] plugin::plugin* plugin) override { gsc::function::add("hashstring", [](const char* str) { return game::BG_StringHashValue(str); }); gsc::function::add_multiple([](const std::string& file, const std::string& data, const scripting::variadic_args& va) { auto append = false; if (va.size() > 0) { append = va[0]; } return utils::io::write_file(file, data, append); }, "writefile", "io::write_file"); gsc::function::add_multiple([](const std::string& file, const std::string& data) { return utils::io::write_file(file, data, true); }, "appendfile", "io::append_file"); gsc::function::add_multiple(utils::io::file_exists, "fileexists", "io::file_exists"); gsc::function::add_multiple(utils::io::move_file, "movefile", "io::move_file"); gsc::function::add_multiple(utils::io::file_size, "filesize", "io::file_size"); gsc::function::add_multiple(utils::io::create_directory, "createdirectory", "io::create_directory"); gsc::function::add_multiple(utils::io::directory_exists, "directoryexists", "io::directory_exists"); gsc::function::add_multiple(utils::io::directory_is_empty, "directoryisempty", "io::directory_is_empty"); gsc::function::add_multiple(utils::io::list_files, "listfiles", "io::list_files"); gsc::function::add_multiple(utils::io::remove_file, "removefile", "io::remove_file"); gsc::function::add_multiple([](const std::string& directory, const scripting::variadic_args& va) { auto recursive = false; if (va.size() > 0) { recursive = va[0]; } utils::io::remove_directory(directory, recursive); }, "removedirectory", "io::remove_directory"); gsc::function::add_multiple(utils::io::copy_folder, "copyfolder", "io::copy_folder"); gsc::function::add_multiple(utils::io::copy_folder, "copydirectory", "io::copy_directory"); gsc::function::add_multiple(static_cast(utils::io::read_file), "readfile", "io::read_file"); if (utils::flags::has_flag("experimental-utils")) { scheduler::loop(poll_files, scheduler::server_packet_loop); scripting::on_shutdown([]() { watched_files.clear(); }); gsc::function::add("io::watch_file", [](const std::string& file) { scripting::object handle; auto watcher = std::make_unique(file); watcher->init(); watched_file watched_file{}; watched_file.watcher = std::move(watcher); watched_file.handle = handle; watched_files.emplace_back(std::move(watched_file)); return handle; }); } } }; } REGISTER_COMPONENT(io::component)