Skip to content

Commit

Permalink
basic fs_game loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Joelrau committed Jul 13, 2024
1 parent b311c04 commit e90ef0f
Show file tree
Hide file tree
Showing 5 changed files with 235 additions and 88 deletions.
64 changes: 64 additions & 0 deletions src/client/component/fastfiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ namespace fastfiles
utils::hook::detour db_load_x_zone_hook;
utils::hook::detour db_find_xasset_header_hook;
utils::hook::detour db_add_xasset_hook;
utils::hook::detour sys_createfile_hook;

void db_try_load_x_file_internal_stub(const char* zone_name, const unsigned int zone_flags,
const bool is_base_map, const bool was_paused, const int failure_mode)
Expand Down Expand Up @@ -107,6 +108,63 @@ namespace fastfiles
auto result = db_add_xasset_hook.invoke<game::XAssetHeader>(type, header_ptr);
return result;
}

HANDLE sys_create_file_stub(game::Sys_Folder folder, const char* base_filename)
{
if (base_filename == "mod.ff"s)
{
auto* fs_basepath = game::Dvar_FindVar("fs_basepath");
auto* fs_game = game::Dvar_FindVar("fs_game");

std::string dir = fs_basepath ? fs_basepath->current.string : "";
std::string mod_dir = fs_game ? fs_game->current.string : "";

if (!mod_dir.empty())
{
const auto path = utils::string::va("%s\\%s\\%s", dir.data(), mod_dir.data(), base_filename);
if (utils::io::file_exists(path))
{
return CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING,
FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, nullptr);
}
}
return INVALID_HANDLE_VALUE;
}

return sys_createfile_hook.invoke<HANDLE>(folder, base_filename);
}

template <typename T> inline void merge(std::vector<T>* target, T* source, size_t length)
{
if (source)
{
for (size_t i = 0; i < length; ++i)
{
target->push_back(source[i]);
}
}
}

template <typename T> inline void merge(std::vector<T>* target, std::vector<T> source)
{
for (auto& entry : source)
{
target->push_back(entry);
}
}

void load_fastfiles1_stub(game::XZoneInfo* zoneInfo, unsigned int zoneCount, game::DBSyncMode syncMode)
{
std::vector<game::XZoneInfo> data;
merge(&data, zoneInfo, zoneCount);

if (fastfiles::exists("mod"))
{
data.push_back({ "mod", game::DB_ZONE_GAME | game::DB_ZONE_CUSTOM, 0 });
}

game::DB_LoadXAssets(data.data(), static_cast<std::uint32_t>(data.size()), syncMode);
}
}

namespace zone_loading
Expand Down Expand Up @@ -205,6 +263,12 @@ namespace fastfiles
// Skip signature validation
utils::hook::set(0x1409E6390, 0xC301B0);

// Add custom zone paths
sys_createfile_hook.create(game::Sys_CreateFile, sys_create_file_stub);

// Add custom zones in fastfiles load (level specific) (mod)
utils::hook::call(0x1403B9E9F, load_fastfiles1_stub);

command::add("loadzone", [](const command::params& params)
{
if (params.size() < 2)
Expand Down
106 changes: 52 additions & 54 deletions src/client/component/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,27 @@ namespace filesystem
utils::hook::detour fs_startup_hook;
utils::hook::detour fs_build_os_path_hook;

const char* sys_default_install_path_stub()
{
static auto current_path = std::filesystem::current_path().string();
return current_path.data();
}

void fs_build_os_path_stub(const char* base, const char* game, const char* qpath, char* ospath)
{
if (!_stricmp(game, "players2"))
{
const auto path = "iw7-mod/"s + game;
fs_build_os_path_hook.invoke<void>(base, path.data(), qpath, ospath);
return;
}

fs_build_os_path_hook.invoke<void>(base, game, qpath, ospath);
}
}

namespace
{
bool initialized = false;

std::deque<std::filesystem::path>& get_search_paths_internal()
Expand All @@ -32,15 +53,7 @@ namespace filesystem
console::info("Current language: %s\n", game::SEH_GetLanguageName(*reinterpret_cast<int*>(0x1474C6420)));
console::info("Current search paths:\n");

if (game::fs_searchpaths.get())
{
for (auto i = game::fs_searchpaths.get()->next; i; i = i->next)
{
console::info("%s/%s\n", i->dir->path, i->dir->gamedir);
}
}

for (auto path : filesystem::get_search_paths())
for (auto& path : filesystem::get_search_paths())
{
console::info("%s\n", path.data());
}
Expand All @@ -53,14 +66,7 @@ namespace filesystem
initialized = true;

filesystem::register_path(utils::properties::get_appdata_path() / "cdata"); // CLIENT_DATA_FOLDER
filesystem::register_path(L".");
filesystem::register_path(L"iw7-mod");
filesystem::register_path(L"devraw_shared");
filesystem::register_path(L"devraw");
filesystem::register_path(L"raw_shared");
filesystem::register_path(L"raw");
filesystem::register_path(L"main_shared");
filesystem::register_path(L"main");
filesystem::register_path(sys_default_install_path_stub() + "/"s + "iw7-mod"s);

fs_startup_hook.invoke<void>(name);

Expand All @@ -77,7 +83,7 @@ namespace filesystem

bool can_insert_path(const std::filesystem::path& path)
{
for (const auto& path_ : get_search_paths_internal())
for (const auto& path_ : get_search_paths())
{
if (path_ == path)
{
Expand All @@ -87,34 +93,16 @@ namespace filesystem

return true;
}

const char* sys_default_install_path_stub()
{
static auto current_path = std::filesystem::current_path().string();
return current_path.data();
}

void fs_build_os_path_stub(const char* base, const char* game, const char* qpath, char* ospath)
{
if (!_stricmp(game, "players2"))
{
const auto path = "iw7-mod/"s + game;
fs_build_os_path_hook.invoke<void>(base, path.data(), qpath, ospath);
return;
}

fs_build_os_path_hook.invoke<void>(base, game, qpath, ospath);
}
}

std::string read_file(const std::string& path)
{
for (const auto& search_path : get_search_paths_internal())
for (const auto& search_path : get_search_paths())
{
const auto path_ = search_path / path;
if (utils::io::file_exists(path_.generic_string()))
const auto path_ = search_path + "/" + path;
if (utils::io::file_exists(path_))
{
return utils::io::read_file(path_.generic_string());
return utils::io::read_file(path_);
}
}

Expand All @@ -123,14 +111,14 @@ namespace filesystem

bool read_file(const std::string& path, std::string* data, std::string* real_path)
{
for (const auto& search_path : get_search_paths_internal())
for (const auto& search_path : get_search_paths())
{
const auto path_ = search_path / path;
if (utils::io::read_file(path_.generic_string(), data))
const auto path_ = search_path + "/" + path;
if (utils::io::read_file(path_, data))
{
if (real_path != nullptr)
{
*real_path = path_.generic_string();
*real_path = path_;
}

return true;
Expand All @@ -142,12 +130,12 @@ namespace filesystem

bool find_file(const std::string& path, std::string* real_path)
{
for (const auto& search_path : get_search_paths_internal())
for (const auto& search_path : get_search_paths())
{
const auto path_ = search_path / path;
if (utils::io::file_exists(path_.generic_string()))
const auto path_ = search_path + "/" + path;
if (utils::io::file_exists(path_))
{
*real_path = path_.generic_string();
*real_path = path_;
return true;
}
}
Expand All @@ -157,10 +145,10 @@ namespace filesystem

bool exists(const std::string& path)
{
for (const auto& search_path : get_search_paths_internal())
for (const auto& search_path : get_search_paths())
{
const auto path_ = search_path / path;
if (utils::io::file_exists(path_.generic_string()))
const auto path_ = search_path + "/" + path;
if (utils::io::file_exists(path_))
{
return true;
}
Expand Down Expand Up @@ -222,17 +210,27 @@ namespace filesystem
paths.push_back(path.generic_string());
}

if (game::fs_searchpaths.get())
{
for (auto i = game::fs_searchpaths.get()->next; i; i = i->next)
{
paths.push_back(utils::string::va("%s/%s", i->dir->path, i->dir->gamedir));
}
}

std::sort(paths.begin(), paths.end());

return paths;
}

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)
auto paths_oridinal = get_search_paths();
for (auto i = paths_oridinal.rbegin(); i != paths_oridinal.rend(); ++i)
{
paths.push_back(i->generic_string());
paths.push_back(*i);
}

return paths;
Expand Down
3 changes: 1 addition & 2 deletions src/client/component/gsc/script_loading.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,8 +312,7 @@ namespace gsc
{
for (const auto& path : filesystem::get_search_paths())
{
load_scripts(path, "scripts/"); // meant to override stock GSC
load_scripts(path, "custom_scripts/"); // for no issues, use custom_scripts/
load_scripts(path, "custom_scripts/");
load_scripts(path, "custom_scripts/"s + game::Com_GameMode_GetActiveGameModeStr() + "/");

if (game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_CP || game::Com_GameMode_GetActiveGameMode() == game::GAME_MODE_MP)
Expand Down
Loading

0 comments on commit e90ef0f

Please sign in to comment.