Add current language to search paths

This commit is contained in:
Federico Cecchetto 2022-07-15 02:02:50 +02:00
parent e0219775d2
commit 3e04061489
4 changed files with 137 additions and 18 deletions

View File

@ -2,25 +2,84 @@
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "filesystem.hpp" #include "filesystem.hpp"
#include "console.hpp"
#include "game/game.hpp"
#include <utils/io.hpp> #include <utils/io.hpp>
#include <utils/hook.hpp>
namespace filesystem namespace filesystem
{ {
std::unordered_set<std::string>& get_search_paths() namespace
{ {
static std::unordered_set<std::string> search_paths{}; bool initialized = false;
std::vector<std::filesystem::path>& get_search_paths_internal()
{
static std::vector<std::filesystem::path> search_paths{};
return search_paths; 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;
filesystem::register_path(L".");
filesystem::register_path(L"h2-mod");
filesystem::register_path(L"data");
utils::hook::invoke<void>(0x14060BF50, name);
}
std::vector<std::filesystem::path> get_paths(const std::filesystem::path& path)
{
std::vector<std::filesystem::path> paths{};
const auto code = game::SEH_GetCurrentLanguageCode();
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;
}
}
std::string read_file(const std::string& path) std::string read_file(const std::string& path)
{ {
for (const auto& search_path : get_search_paths()) for (const auto& search_path : get_search_paths_internal())
{ {
const auto path_ = search_path + "/" + path; const auto path_ = search_path / path;
if (utils::io::file_exists(path_)) if (utils::io::file_exists(path_.generic_string()))
{ {
return utils::io::read_file(path_); return utils::io::read_file(path_.generic_string());
} }
} }
@ -29,14 +88,14 @@ namespace filesystem
bool read_file(const std::string& path, std::string* data, std::string* real_path) bool read_file(const std::string& path, std::string* data, std::string* real_path)
{ {
for (const auto& search_path : get_search_paths()) for (const auto& search_path : get_search_paths_internal())
{ {
const auto path_ = search_path + "/" + path; const auto path_ = search_path / path;
if (utils::io::read_file(path_, data)) if (utils::io::read_file(path_.generic_string(), data))
{ {
if (real_path != nullptr) if (real_path != nullptr)
{ {
*real_path = path_; *real_path = path_.generic_string();
} }
return true; return true;
@ -46,14 +105,68 @@ namespace filesystem
return false; return false;
} }
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());
get_search_paths_internal().push_back(path_);
}
}
}
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;
}
class component final : public component_interface class component final : public component_interface
{ {
public: public:
void post_unpack() override void post_unpack() override
{ {
get_search_paths().insert("."); utils::hook::call(0x14060B052, fs_startup_stub);
get_search_paths().insert("h2-mod");
get_search_paths().insert("data");
} }
}; };
} }

View File

@ -2,7 +2,11 @@
namespace filesystem namespace filesystem
{ {
std::unordered_set<std::string>& get_search_paths();
std::string read_file(const std::string& path); std::string read_file(const std::string& path);
bool read_file(const std::string& path, std::string* data, std::string* real_path = nullptr); bool read_file(const std::string& path, std::string* data, std::string* real_path = nullptr);
void register_path(const std::filesystem::path& path);
void unregister_path(const std::filesystem::path& path);
std::vector<std::string> get_search_paths();
} }

View File

@ -88,8 +88,8 @@ namespace mods
} }
console::info("Loading mod %s\n", path); console::info("Loading mod %s\n", path);
filesystem::get_search_paths().erase(mod_path); filesystem::unregister_path(mod_path);
filesystem::get_search_paths().insert(path); filesystem::register_path(path);
mod_path = path; mod_path = path;
restart(); restart();
}); });
@ -110,7 +110,7 @@ namespace mods
} }
console::info("Unloading mod %s\n", mod_path.data()); console::info("Unloading mod %s\n", mod_path.data());
filesystem::get_search_paths().erase(mod_path); filesystem::unregister_path(mod_path);
mod_path.clear(); mod_path.clear();
restart(); restart();
}); });

View File

@ -155,6 +155,8 @@ namespace game
WEAK symbol<void(int critSec)> Sys_EnterCriticalSection{0x140624240}; WEAK symbol<void(int critSec)> Sys_EnterCriticalSection{0x140624240};
WEAK symbol<void(int critSec)> Sys_LeaveCriticalSection{0x1406242C0}; WEAK symbol<void(int critSec)> Sys_LeaveCriticalSection{0x1406242C0};
WEAK symbol<const char*()> SEH_GetCurrentLanguageCode{0x1405E5180};
WEAK symbol<const char*(const char* string)> UI_SafeTranslateString{0x1405A2930}; WEAK symbol<const char*(const char* string)> UI_SafeTranslateString{0x1405A2930};
WEAK symbol<int(int localClientNum, const char* sound)> UI_PlayLocalSoundAlias{0x140606080}; WEAK symbol<int(int localClientNum, const char* sound)> UI_PlayLocalSoundAlias{0x140606080};