h2-mod/src/client/component/mods.cpp

114 lines
2.2 KiB
C++
Raw Normal View History

#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "game/game.hpp"
#include "command.hpp"
2022-06-17 14:22:12 -04:00
#include "console.hpp"
#include "scheduler.hpp"
2022-03-19 18:06:00 -04:00
#include "filesystem.hpp"
#include "materials.hpp"
#include "fonts.hpp"
2022-03-21 13:39:51 -04:00
#include "mods.hpp"
#include <utils/hook.hpp>
#include <utils/io.hpp>
namespace mods
{
2022-03-21 13:39:51 -04:00
std::string mod_path{};
2022-03-19 18:06:00 -04:00
namespace
{
utils::hook::detour db_release_xassets_hook;
2022-03-20 14:40:15 -04:00
bool release_assets = false;
2022-03-19 18:06:00 -04:00
void db_release_xassets_stub()
{
2022-03-20 14:40:15 -04:00
if (release_assets)
{
materials::clear();
fonts::clear();
}
2022-03-19 18:06:00 -04:00
db_release_xassets_hook.invoke<void>();
}
void restart()
{
scheduler::once([]()
{
2022-03-20 14:40:15 -04:00
release_assets = true;
2022-03-19 18:06:00 -04:00
game::Com_Shutdown("");
2022-03-20 14:40:15 -04:00
release_assets = false;
2022-03-19 18:06:00 -04:00
}, scheduler::pipeline::main);
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
if (!utils::io::directory_exists("mods"))
{
utils::io::create_directory("mods");
}
2022-03-19 18:06:00 -04:00
db_release_xassets_hook.create(0x140416A80, db_release_xassets_stub);
command::add("loadmod", [](const command::params& params)
{
if (params.size() < 2)
{
2022-06-17 14:22:12 -04:00
console::info("Usage: loadmod mods/<modname>");
return;
}
2022-03-19 18:06:00 -04:00
if (!game::Com_InFrontend())
{
2022-06-17 14:22:12 -04:00
console::error("Cannot load mod while in-game!\n");
game::CG_GameMessage(0, "^1Cannot unload mod while in-game!");
return;
}
const auto path = params.get(1);
if (!utils::io::directory_exists(path))
{
2022-06-17 14:22:12 -04:00
console::error("Mod %s not found!\n", path);
return;
}
2022-06-17 14:22:12 -04:00
console::info("Loading mod %s\n", path);
2022-03-21 13:39:51 -04:00
filesystem::get_search_paths().erase(mod_path);
2022-03-19 18:06:00 -04:00
filesystem::get_search_paths().insert(path);
2022-03-21 13:39:51 -04:00
mod_path = path;
2022-03-19 18:06:00 -04:00
restart();
});
command::add("unloadmod", [](const command::params& params)
{
2022-03-21 13:39:51 -04:00
if (mod_path.empty())
{
2022-06-17 14:22:12 -04:00
console::info("No mod loaded\n");
return;
}
2022-03-19 18:06:00 -04:00
if (!game::Com_InFrontend())
{
2022-06-17 14:22:12 -04:00
console::error("Cannot unload mod while in-game!\n");
game::CG_GameMessage(0, "^1Cannot unload mod while in-game!");
return;
}
2022-06-17 14:22:12 -04:00
console::info("Unloading mod %s\n", mod_path.data());
2022-03-21 13:39:51 -04:00
filesystem::get_search_paths().erase(mod_path);
mod_path.clear();
2022-03-19 18:06:00 -04:00
restart();
});
}
};
}
REGISTER_COMPONENT(mods::component)