Support loading fastfiles from appdata

This commit is contained in:
Federico Cecchetto 2022-09-10 22:59:55 +02:00
parent 9fcf994b35
commit cfe8713805

View File

@ -6,6 +6,7 @@
#include "fastfiles.hpp"
#include "command.hpp"
#include "console.hpp"
#include "filesystem.hpp"
#include <utils/hook.hpp>
#include <utils/concurrency.hpp>
@ -148,15 +149,11 @@ namespace fastfiles
if (localized)
{
const auto language = game::SEH_GetCurrentLanguageCode();
if (!try_load_zone(language + "_"s + name, false) && language != "eng"s)
{
try_load_zone("eng_" + name, false);
}
try_load_zone(language + "_"s + name, false);
}
if (!fastfiles::exists(name))
{
console::debug("fastfile %s doesn't exist\n", name.data());
return false;
}
@ -168,32 +165,73 @@ namespace fastfiles
return true;
}
HANDLE find_fastfile(const std::string& filename, bool check_loc_folder)
{
std::string path{};
std::string loc_folder{};
if (check_loc_folder && game::DB_IsLocalized(filename.data()))
{
const auto handle = find_fastfile(filename, false);
if (handle != reinterpret_cast<HANDLE>(-1))
{
return handle;
}
loc_folder = game::SEH_GetCurrentLanguageName() + "/"s;
}
if (!filesystem::find_file(loc_folder + filename, &path))
{
if (!filesystem::find_file("zone/"s + loc_folder + filename, &path))
{
return reinterpret_cast<HANDLE>(-1);
}
}
return CreateFileA(path.data(), 0x80000000, 1u, 0, 3u, 0x60000000u, 0);
}
utils::hook::detour sys_createfile_hook;
HANDLE sys_create_file_stub(game::Sys_Folder folder, const char* base_filename)
{
const auto* fs_basepath = game::Dvar_FindVar("fs_basepath");
const 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 : "";
const std::string dir = fs_basepath ? fs_basepath->current.string : "";
const std::string mod_dir = fs_game ? fs_game->current.string : "";
const std::string name = base_filename;
if (base_filename == "mod.ff"s)
if (name == "mod.ff")
{
if (!mod_dir.empty())
{
auto path = utils::string::va("%s\\%s\\%s", dir.data(), mod_dir.data(), base_filename);
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, 0x80000000, 1u, 0, 3u, 0x60000000u, 0);
}
}
return (HANDLE)-1;
return reinterpret_cast<HANDLE>(-1);
}
if (name.ends_with(".ff"))
{
const auto handle = find_fastfile(name, true);
if (handle != reinterpret_cast<HANDLE>(-1))
{
return handle;
}
}
return sys_createfile_hook.invoke<HANDLE>(folder, base_filename);
}
template <typename T> inline void merge(std::vector<T>* target, T* source, size_t length)
template <typename T>
inline void merge(std::vector<T>* target, T* source, size_t length)
{
if (source)
{
@ -204,7 +242,8 @@ namespace fastfiles
}
}
template <typename T> inline void merge(std::vector<T>* target, std::vector<T> source)
template <typename T>
inline void merge(std::vector<T>* target, std::vector<T> source)
{
for (auto& entry : source)
{
@ -252,8 +291,10 @@ namespace fastfiles
bool exists(const std::string& zone)
{
const auto is_localized = game::DB_IsLocalized(zone.data());
const auto handle = game::Sys_CreateFile((is_localized ? game::SF_ZONE_LOC : game::SF_ZONE), utils::string::va("%s.ff", zone.data()));
if (handle != (HANDLE)-1)
const auto handle = game::Sys_CreateFile((is_localized ? game::SF_ZONE_LOC : game::SF_ZONE),
utils::string::va("%s.ff", zone.data()));
if (handle != reinterpret_cast<HANDLE>(-1))
{
CloseHandle(handle);
return true;