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

213 lines
4.2 KiB
C++
Raw Normal View History

2022-03-19 18:06:00 -04:00
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "filesystem.hpp"
2022-07-14 20:02:50 -04:00
#include "console.hpp"
2022-07-15 18:29:44 -04:00
#include "localized_strings.hpp"
2022-07-14 20:02:50 -04:00
#include "game/game.hpp"
2022-03-19 18:06:00 -04:00
#include <utils/io.hpp>
2022-07-14 20:02:50 -04:00
#include <utils/hook.hpp>
2022-03-19 18:06:00 -04:00
namespace filesystem
{
2022-07-14 20:02:50 -04:00
namespace
2022-03-19 18:06:00 -04:00
{
2022-07-14 20:02:50 -04:00
bool initialized = false;
2022-07-19 13:42:59 -04:00
std::deque<std::filesystem::path>& get_search_paths_internal()
2022-07-14 20:02:50 -04:00
{
2022-07-19 13:42:59 -04:00
static std::deque<std::filesystem::path> search_paths{};
2022-07-14 20:02:50 -04:00
return search_paths;
}
bool is_polrus_lang()
{
static auto* loc_language = game::Dvar_FindVar("loc_language");
const auto id = loc_language->current.integer;
return id == 5 || id == 6 || id == 17;
}
void fs_startup_stub(const char* name)
{
console::info("[FS] Startup\n");
initialized = true;
2022-07-19 13:42:59 -04:00
filesystem::register_path(L"" CLIENT_DATA_FOLDER);
2022-07-14 20:02:50 -04:00
filesystem::register_path(L".");
filesystem::register_path(L"h2-mod");
2022-07-15 18:29:44 -04:00
localized_strings::clear();
2022-07-14 20:02:50 -04:00
utils::hook::invoke<void>(0x14060BF50, name);
}
std::vector<std::filesystem::path> get_paths(const std::filesystem::path& path)
{
std::vector<std::filesystem::path> paths{};
2022-07-31 17:59:01 -04:00
const auto code = game::SEH_GetCurrentLanguageName();
2022-07-14 20:02:50 -04:00
paths.push_back(path);
paths.push_back(path / code);
if (is_polrus_lang())
{
paths.push_back(path / "polrus");
}
return paths;
}
bool can_insert_path(const std::filesystem::path& path)
{
for (const auto& path_ : get_search_paths_internal())
{
if (path_ == path)
{
return false;
}
}
return true;
}
const char* sys_default_install_path_stub()
{
static auto current_path = std::filesystem::current_path().string();
return current_path.data();
}
2022-03-19 18:06:00 -04:00
}
std::string read_file(const std::string& path)
{
2022-07-14 20:02:50 -04:00
for (const auto& search_path : get_search_paths_internal())
2022-03-19 18:06:00 -04:00
{
2022-07-14 20:02:50 -04:00
const auto path_ = search_path / path;
if (utils::io::file_exists(path_.generic_string()))
2022-03-19 18:06:00 -04:00
{
2022-07-14 20:02:50 -04:00
return utils::io::read_file(path_.generic_string());
2022-03-19 18:06:00 -04:00
}
}
return {};
}
2022-04-28 16:41:29 -04:00
bool read_file(const std::string& path, std::string* data, std::string* real_path)
2022-03-19 18:06:00 -04:00
{
2022-07-14 20:02:50 -04:00
for (const auto& search_path : get_search_paths_internal())
2022-03-19 18:06:00 -04:00
{
2022-07-14 20:02:50 -04:00
const auto path_ = search_path / path;
if (utils::io::read_file(path_.generic_string(), data))
2022-03-19 18:06:00 -04:00
{
2022-04-28 16:41:29 -04:00
if (real_path != nullptr)
{
2022-07-14 20:02:50 -04:00
*real_path = path_.generic_string();
2022-04-28 16:41:29 -04:00
}
2022-03-19 18:06:00 -04:00
return true;
}
}
return false;
}
bool find_file(const std::string& path, std::string* real_path)
{
for (const auto& search_path : get_search_paths_internal())
{
const auto path_ = search_path / path;
if (utils::io::file_exists(path_.generic_string()))
{
*real_path = path_.generic_string();
return true;
}
}
return false;
}
2022-07-14 20:02:50 -04:00
void register_path(const std::filesystem::path& path)
{
if (!initialized)
{
return;
}
const auto paths = get_paths(path);
for (const auto& path_ : paths)
{
if (can_insert_path(path_))
{
console::info("[FS] Registering path '%s'\n", path_.generic_string().data());
2022-07-19 13:42:59 -04:00
get_search_paths_internal().push_front(path_);
2022-07-14 20:02:50 -04:00
}
}
}
void unregister_path(const std::filesystem::path& path)
{
if (!initialized)
{
return;
}
const auto paths = get_paths(path);
for (const auto& path_ : paths)
{
auto& search_paths = get_search_paths_internal();
for (auto i = search_paths.begin(); i != search_paths.end();)
{
if (*i == path_)
{
console::info("[FS] Unregistering path '%s'\n", path_.generic_string().data());
i = search_paths.erase(i);
}
else
{
++i;
}
}
}
}
std::vector<std::string> get_search_paths()
{
std::vector<std::string> paths{};
for (const auto& path : get_search_paths_internal())
{
paths.push_back(path.generic_string());
}
return paths;
}
2022-07-19 13:42:59 -04:00
std::vector<std::string> get_search_paths_rev()
{
std::vector<std::string> paths{};
const auto& search_paths = get_search_paths_internal();
for (auto i = search_paths.rbegin(); i != search_paths.rend(); ++i)
{
paths.push_back(i->generic_string());
}
return paths;
}
2022-03-19 18:06:00 -04:00
class component final : public component_interface
{
public:
void post_unpack() override
{
2022-07-14 20:02:50 -04:00
utils::hook::call(0x14060B052, fs_startup_stub);
utils::hook::jump(0x140624050, sys_default_install_path_stub);
2022-03-19 18:06:00 -04:00
}
};
}
REGISTER_COMPONENT(filesystem::component)