Support loading fastfiles from appdata
This commit is contained in:
parent
9fcf994b35
commit
cfe8713805
@ -6,6 +6,7 @@
|
|||||||
#include "fastfiles.hpp"
|
#include "fastfiles.hpp"
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
|
#include "filesystem.hpp"
|
||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
#include <utils/concurrency.hpp>
|
#include <utils/concurrency.hpp>
|
||||||
@ -148,15 +149,11 @@ namespace fastfiles
|
|||||||
if (localized)
|
if (localized)
|
||||||
{
|
{
|
||||||
const auto language = game::SEH_GetCurrentLanguageCode();
|
const auto language = game::SEH_GetCurrentLanguageCode();
|
||||||
if (!try_load_zone(language + "_"s + name, false) && language != "eng"s)
|
try_load_zone(language + "_"s + name, false);
|
||||||
{
|
|
||||||
try_load_zone("eng_" + name, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fastfiles::exists(name))
|
if (!fastfiles::exists(name))
|
||||||
{
|
{
|
||||||
console::debug("fastfile %s doesn't exist\n", name.data());
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,32 +165,73 @@ namespace fastfiles
|
|||||||
return true;
|
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;
|
utils::hook::detour sys_createfile_hook;
|
||||||
HANDLE sys_create_file_stub(game::Sys_Folder folder, const char* base_filename)
|
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_basepath = game::Dvar_FindVar("fs_basepath");
|
||||||
const auto* fs_game = game::Dvar_FindVar("fs_game");
|
const auto* fs_game = game::Dvar_FindVar("fs_game");
|
||||||
|
|
||||||
std::string dir = fs_basepath ? fs_basepath->current.string : "";
|
const std::string dir = fs_basepath ? fs_basepath->current.string : "";
|
||||||
std::string mod_dir = fs_game ? fs_game->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())
|
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))
|
if (utils::io::file_exists(path))
|
||||||
{
|
{
|
||||||
return CreateFileA(path, 0x80000000, 1u, 0, 3u, 0x60000000u, 0);
|
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);
|
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)
|
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)
|
for (auto& entry : source)
|
||||||
{
|
{
|
||||||
@ -252,8 +291,10 @@ namespace fastfiles
|
|||||||
bool exists(const std::string& zone)
|
bool exists(const std::string& zone)
|
||||||
{
|
{
|
||||||
const auto is_localized = game::DB_IsLocalized(zone.data());
|
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()));
|
const auto handle = game::Sys_CreateFile((is_localized ? game::SF_ZONE_LOC : game::SF_ZONE),
|
||||||
if (handle != (HANDLE)-1)
|
utils::string::va("%s.ff", zone.data()));
|
||||||
|
|
||||||
|
if (handle != reinterpret_cast<HANDLE>(-1))
|
||||||
{
|
{
|
||||||
CloseHandle(handle);
|
CloseHandle(handle);
|
||||||
return true;
|
return true;
|
||||||
|
Loading…
Reference in New Issue
Block a user