Fix FS a bit (#688)
This commit is contained in:
parent
86b402a5a0
commit
dcf701562f
@ -8,7 +8,7 @@ namespace Components
|
|||||||
|
|
||||||
void FileSystem::File::read(Game::FsThread thread)
|
void FileSystem::File::read(Game::FsThread thread)
|
||||||
{
|
{
|
||||||
std::lock_guard _(FileSystem::FSMutex);
|
std::lock_guard _(FSMutex);
|
||||||
|
|
||||||
assert(!filePath.empty());
|
assert(!filePath.empty());
|
||||||
|
|
||||||
@ -38,14 +38,14 @@ namespace Components
|
|||||||
{
|
{
|
||||||
this->buffer.clear();
|
this->buffer.clear();
|
||||||
|
|
||||||
Game::RawFile* rawfile = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_RAWFILE, this->filePath.data()).rawfile;
|
auto* rawfile = Game::DB_FindXAssetHeader(Game::XAssetType::ASSET_TYPE_RAWFILE, this->filePath.data()).rawfile;
|
||||||
if (!rawfile || Game::DB_IsXAssetDefault(Game::XAssetType::ASSET_TYPE_RAWFILE, this->filePath.data())) return;
|
if (!rawfile || Game::DB_IsXAssetDefault(Game::XAssetType::ASSET_TYPE_RAWFILE, this->filePath.data())) return;
|
||||||
|
|
||||||
this->buffer.resize(Game::DB_GetRawFileLen(rawfile));
|
this->buffer.resize(Game::DB_GetRawFileLen(rawfile));
|
||||||
Game::DB_GetRawBuffer(rawfile, this->buffer.data(), static_cast<int>(this->buffer.size()));
|
Game::DB_GetRawBuffer(rawfile, this->buffer.data(), static_cast<int>(this->buffer.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::FileReader::FileReader(const std::string& file) : handle(0), name(file)
|
FileSystem::FileReader::FileReader(std::string file) : handle(0), name(std::move(file))
|
||||||
{
|
{
|
||||||
this->size = Game::FS_FOpenFileReadCurrentThread(this->name.data(), &this->handle);
|
this->size = Game::FS_FOpenFileReadCurrentThread(this->name.data(), &this->handle);
|
||||||
}
|
}
|
||||||
@ -58,25 +58,25 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::FileReader::exists()
|
bool FileSystem::FileReader::exists() const noexcept
|
||||||
{
|
{
|
||||||
return (this->size >= 0 && this->handle);
|
return (this->size >= 0 && this->handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FileSystem::FileReader::getName()
|
std::string FileSystem::FileReader::getName() const
|
||||||
{
|
{
|
||||||
return this->name;
|
return this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSystem::FileReader::getSize()
|
int FileSystem::FileReader::getSize() const noexcept
|
||||||
{
|
{
|
||||||
return this->size;
|
return this->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FileSystem::FileReader::getBuffer()
|
std::string FileSystem::FileReader::getBuffer() const
|
||||||
{
|
{
|
||||||
Utils::Memory::Allocator allocator;
|
Utils::Memory::Allocator allocator;
|
||||||
if (!this->exists()) return std::string();
|
if (!this->exists()) return {};
|
||||||
|
|
||||||
const auto position = Game::FS_FTell(this->handle);
|
const auto position = Game::FS_FTell(this->handle);
|
||||||
this->seek(0, Game::FS_SEEK_SET);
|
this->seek(0, Game::FS_SEEK_SET);
|
||||||
@ -93,9 +93,9 @@ namespace Components
|
|||||||
return {buffer, static_cast<std::size_t>(this->size)};
|
return {buffer, static_cast<std::size_t>(this->size)};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileSystem::FileReader::read(void* buffer, size_t _size)
|
bool FileSystem::FileReader::read(void* buffer, std::size_t _size) const noexcept
|
||||||
{
|
{
|
||||||
if (!this->exists() || static_cast<size_t>(this->size) < _size || Game::FS_Read(buffer, _size, this->handle) != static_cast<int>(_size))
|
if (!this->exists() || static_cast<std::size_t>(this->size) < _size || Game::FS_Read(buffer, static_cast<int>(_size), this->handle) != static_cast<int>(_size))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -103,7 +103,7 @@ namespace Components
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::FileReader::seek(int offset, int origin)
|
void FileSystem::FileReader::seek(int offset, int origin) const
|
||||||
{
|
{
|
||||||
if (this->exists())
|
if (this->exists())
|
||||||
{
|
{
|
||||||
@ -111,11 +111,11 @@ namespace Components
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::FileWriter::write(const std::string& data)
|
void FileSystem::FileWriter::write(const std::string& data) const
|
||||||
{
|
{
|
||||||
if (this->handle)
|
if (this->handle)
|
||||||
{
|
{
|
||||||
Game::FS_Write(data.data(), data.size(), this->handle);
|
Game::FS_Write(data.data(), static_cast<int>(data.size()), this->handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +204,7 @@ namespace Components
|
|||||||
|
|
||||||
bool FileSystem::_DeleteFile(const std::string& folder, const std::string& file)
|
bool FileSystem::_DeleteFile(const std::string& folder, const std::string& file)
|
||||||
{
|
{
|
||||||
char path[MAX_PATH] = {0};
|
char path[MAX_PATH]{};
|
||||||
Game::FS_BuildPathToFile(Dvar::Var("fs_basepath").get<const char*>(), reinterpret_cast<char*>(0x63D0BB8), Utils::String::VA("%s/%s", folder.data(), file.data()), reinterpret_cast<char**>(&path));
|
Game::FS_BuildPathToFile(Dvar::Var("fs_basepath").get<const char*>(), reinterpret_cast<char*>(0x63D0BB8), Utils::String::VA("%s/%s", folder.data(), file.data()), reinterpret_cast<char**>(&path));
|
||||||
return Game::FS_Remove(path);
|
return Game::FS_Remove(path);
|
||||||
}
|
}
|
||||||
@ -212,19 +212,18 @@ namespace Components
|
|||||||
int FileSystem::ReadFile(const char* path, char** buffer)
|
int FileSystem::ReadFile(const char* path, char** buffer)
|
||||||
{
|
{
|
||||||
if (!buffer) return -1;
|
if (!buffer) return -1;
|
||||||
else *buffer = nullptr;
|
|
||||||
if (!path) return -1;
|
if (!path) return -1;
|
||||||
|
|
||||||
std::lock_guard _(FileSystem::Mutex);
|
std::lock_guard _(Mutex);
|
||||||
FileSystem::FileReader reader(path);
|
FileReader reader(path);
|
||||||
|
|
||||||
int size = reader.getSize();
|
int size = reader.getSize();
|
||||||
if (reader.exists() && size >= 0)
|
if (reader.exists() && size >= 0)
|
||||||
{
|
{
|
||||||
*buffer = FileSystem::AllocateFile(size + 1);
|
*buffer = AllocateFile(size + 1);
|
||||||
if (reader.read(*buffer, size)) return size;
|
if (reader.read(*buffer, size)) return size;
|
||||||
|
|
||||||
FileSystem::FreeFile(*buffer);
|
FreeFile(*buffer);
|
||||||
*buffer = nullptr;
|
*buffer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,12 +232,12 @@ namespace Components
|
|||||||
|
|
||||||
char* FileSystem::AllocateFile(int size)
|
char* FileSystem::AllocateFile(int size)
|
||||||
{
|
{
|
||||||
return FileSystem::MemAllocator.allocateArray<char>(size);
|
return MemAllocator.allocateArray<char>(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::FreeFile(void* buffer)
|
void FileSystem::FreeFile(void* buffer)
|
||||||
{
|
{
|
||||||
FileSystem::MemAllocator.free(buffer);
|
MemAllocator.free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::RegisterFolder(const char* folder)
|
void FileSystem::RegisterFolder(const char* folder)
|
||||||
@ -256,10 +255,10 @@ namespace Components
|
|||||||
{
|
{
|
||||||
if (ZoneBuilder::IsEnabled())
|
if (ZoneBuilder::IsEnabled())
|
||||||
{
|
{
|
||||||
FileSystem::RegisterFolder("zonedata");
|
RegisterFolder("zonedata");
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::RegisterFolder("userraw");
|
RegisterFolder("userraw");
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void FileSystem::StartupStub()
|
__declspec(naked) void FileSystem::StartupStub()
|
||||||
@ -286,34 +285,34 @@ namespace Components
|
|||||||
|
|
||||||
void FileSystem::FsStartupSync(const char* a1)
|
void FileSystem::FsStartupSync(const char* a1)
|
||||||
{
|
{
|
||||||
std::lock_guard _(FileSystem::FSMutex);
|
std::lock_guard _(FSMutex);
|
||||||
return Utils::Hook::Call<void(const char*)>(0x4823A0)(a1); // FS_Startup
|
return Utils::Hook::Call<void(const char*)>(0x4823A0)(a1); // FS_Startup
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::FsRestartSync(int a1, int a2)
|
void FileSystem::FsRestartSync(int localClientNum, int checksumFeed)
|
||||||
{
|
{
|
||||||
std::lock_guard _(FileSystem::FSMutex);
|
std::lock_guard _(FSMutex);
|
||||||
Maps::GetUserMap()->freeIwd();
|
Maps::GetUserMap()->freeIwd();
|
||||||
Utils::Hook::Call<void(int, int)>(0x461A50)(a1, a2); // FS_Restart
|
Utils::Hook::Call<void(int, int)>(0x461A50)(localClientNum, checksumFeed); // FS_Restart
|
||||||
Maps::GetUserMap()->reloadIwd();
|
Maps::GetUserMap()->reloadIwd();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::FsShutdownSync(int a1)
|
void FileSystem::FsShutdownSync(int closemfp)
|
||||||
{
|
{
|
||||||
std::lock_guard _(FileSystem::FSMutex);
|
std::lock_guard _(FSMutex);
|
||||||
Maps::GetUserMap()->freeIwd();
|
Maps::GetUserMap()->freeIwd();
|
||||||
Utils::Hook::Call<void(int)>(0x4A46C0)(a1); // FS_Shutdown
|
Utils::Hook::Call<void(int)>(0x4A46C0)(closemfp); // FS_Shutdown
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileSystem::DelayLoadImagesSync()
|
void FileSystem::DelayLoadImagesSync()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::recursive_mutex> _(FileSystem::FSMutex);
|
std::lock_guard _(FSMutex);
|
||||||
return Utils::Hook::Call<void()>(0x494060)(); // DB_LoadDelayedImages
|
return Utils::Hook::Call<void()>(0x494060)(); // DB_LoadDelayedImages
|
||||||
}
|
}
|
||||||
|
|
||||||
int FileSystem::LoadTextureSync(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image)
|
int FileSystem::LoadTextureSync(Game::GfxImageLoadDef** loadDef, Game::GfxImage* image)
|
||||||
{
|
{
|
||||||
std::lock_guard _(FileSystem::FSMutex);
|
std::lock_guard _(FSMutex);
|
||||||
return Game::Load_Texture(loadDef, image);
|
return Game::Load_Texture(loadDef, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,23 +330,20 @@ namespace Components
|
|||||||
|
|
||||||
FileSystem::FileSystem()
|
FileSystem::FileSystem()
|
||||||
{
|
{
|
||||||
FileSystem::MemAllocator.clear();
|
|
||||||
|
|
||||||
// Thread safe file system interaction
|
// Thread safe file system interaction
|
||||||
Utils::Hook(0x4F4BFF, FileSystem::AllocateFile, HOOK_CALL).install()->quick();
|
Utils::Hook(0x4F4BFF, AllocateFile, HOOK_CALL).install()->quick();
|
||||||
//Utils::Hook(Game::FS_ReadFile, FileSystem::ReadFile, HOOK_JUMP).install()->quick();
|
Utils::Hook(Game::FS_FreeFile, FreeFile, HOOK_JUMP).install()->quick();
|
||||||
Utils::Hook(Game::FS_FreeFile, FileSystem::FreeFile, HOOK_JUMP).install()->quick();
|
|
||||||
|
|
||||||
// Filesystem config checks
|
// Filesystem config checks
|
||||||
Utils::Hook(0x6098FD, FileSystem::ExecIsFSStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x6098FD, ExecIsFSStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Don't strip the folders from the config name (otherwise our ExecIsFSStub fails)
|
// Don't strip the folders from the config name (otherwise our ExecIsFSStub fails)
|
||||||
Utils::Hook::Nop(0x6098F2, 5);
|
Utils::Hook::Nop(0x6098F2, 5);
|
||||||
|
|
||||||
// Register additional folders
|
// Register additional folders
|
||||||
Utils::Hook(0x482647, FileSystem::StartupStub, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x482647, StartupStub, HOOK_JUMP).install()->quick();
|
||||||
|
|
||||||
// exec whitelist removal (YAYFINITY WARD)
|
// exec whitelist removal
|
||||||
Utils::Hook::Nop(0x609685, 5);
|
Utils::Hook::Nop(0x609685, 5);
|
||||||
Utils::Hook::Nop(0x60968C, 2);
|
Utils::Hook::Nop(0x60968C, 2);
|
||||||
|
|
||||||
@ -355,30 +351,30 @@ namespace Components
|
|||||||
Utils::Hook::Nop(0x642A4B, 5);
|
Utils::Hook::Nop(0x642A4B, 5);
|
||||||
|
|
||||||
// Ignore bad magic, when trying to free hunk when it's already cleared
|
// Ignore bad magic, when trying to free hunk when it's already cleared
|
||||||
Utils::Hook::Set<WORD>(0x49AACE, 0xC35E);
|
Utils::Hook::Set<std::uint16_t>(0x49AACE, 0xC35E);
|
||||||
|
|
||||||
// Synchronize filesystem starts
|
// Synchronize filesystem starts
|
||||||
Utils::Hook(0x4290C6, FileSystem::FsStartupSync, HOOK_CALL).install()->quick(); // FS_InitFilesystem
|
Utils::Hook(0x4290C6, FsStartupSync, HOOK_CALL).install()->quick(); // FS_InitFilesystem
|
||||||
Utils::Hook(0x461A88, FileSystem::FsStartupSync, HOOK_CALL).install()->quick(); // FS_Restart
|
Utils::Hook(0x461A88, FsStartupSync, HOOK_CALL).install()->quick(); // FS_Restart
|
||||||
|
|
||||||
// Synchronize filesystem restarts
|
// Synchronize filesystem restarts
|
||||||
Utils::Hook(0x4A745B, FileSystem::FsRestartSync, HOOK_CALL).install()->quick(); // SV_SpawnServer
|
Utils::Hook(0x4A745B, FsRestartSync, HOOK_CALL).install()->quick(); // SV_SpawnServer
|
||||||
Utils::Hook(0x4C8609, FileSystem::FsRestartSync, HOOK_CALL).install()->quick(); // FS_ConditionalRestart
|
Utils::Hook(0x4C8609, FsRestartSync, HOOK_CALL).install()->quick(); // FS_ConditionalRestart
|
||||||
Utils::Hook(0x5AC68E, FileSystem::FsRestartSync, HOOK_CALL).install()->quick(); // CL_ParseServerMessage
|
Utils::Hook(0x5AC68E, FsRestartSync, HOOK_CALL).install()->quick(); // CL_ParseServerMessage
|
||||||
|
|
||||||
// Synchronize filesystem stops
|
// Synchronize filesystem stops
|
||||||
Utils::Hook(0x461A55, FileSystem::FsShutdownSync, HOOK_CALL).install()->quick(); // FS_Restart
|
Utils::Hook(0x461A55, FsShutdownSync, HOOK_CALL).install()->quick(); // FS_Restart
|
||||||
Utils::Hook(0x4D40DB, FileSystem::FsShutdownSync, HOOK_CALL).install()->quick(); // Com_Quitf
|
Utils::Hook(0x4D40DB, FsShutdownSync, HOOK_CALL).install()->quick(); // Com_Quitf
|
||||||
|
|
||||||
// Synchronize db image loading
|
// Synchronize db image loading
|
||||||
Utils::Hook(0x415AB8, FileSystem::DelayLoadImagesSync, HOOK_CALL).install()->quick();
|
Utils::Hook(0x415AB8, DelayLoadImagesSync, HOOK_CALL).install()->quick();
|
||||||
Utils::Hook(0x4D32BC, FileSystem::LoadTextureSync, HOOK_CALL).install()->quick();
|
Utils::Hook(0x4D32BC, LoadTextureSync, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Handle IWD freeing
|
// Handle IWD freeing
|
||||||
Utils::Hook(0x642F60, FileSystem::IwdFreeStub, HOOK_CALL).install()->quick();
|
Utils::Hook(0x642F60, IwdFreeStub, HOOK_CALL).install()->quick();
|
||||||
|
|
||||||
// Set the working dir based on info from the Xlabs launcher
|
// Set the working dir based on info from the Xlabs launcher
|
||||||
Utils::Hook(0x4326E0, FileSystem::Sys_DefaultInstallPath_Hk, HOOK_JUMP).install()->quick();
|
Utils::Hook(0x4326E0, Sys_DefaultInstallPath_Hk, HOOK_JUMP).install()->quick();
|
||||||
}
|
}
|
||||||
|
|
||||||
FileSystem::~FileSystem()
|
FileSystem::~FileSystem()
|
||||||
|
@ -10,9 +10,9 @@ namespace Components
|
|||||||
public:
|
public:
|
||||||
virtual ~AbstractFile() = default;
|
virtual ~AbstractFile() = default;
|
||||||
|
|
||||||
virtual bool exists() = 0;
|
[[nodiscard]] virtual bool exists() const noexcept = 0;
|
||||||
virtual std::string getName() = 0;
|
[[nodiscard]] virtual std::string getName() const = 0;
|
||||||
virtual std::string& getBuffer() = 0;
|
[[nodiscard]] virtual std::string& getBuffer() = 0;
|
||||||
|
|
||||||
virtual explicit operator bool()
|
virtual explicit operator bool()
|
||||||
{
|
{
|
||||||
@ -27,9 +27,9 @@ namespace Components
|
|||||||
File(std::string file) : filePath{std::move(file)} { this->read(); }
|
File(std::string file) : filePath{std::move(file)} { this->read(); }
|
||||||
File(std::string file, Game::FsThread thread) : filePath{std::move(file)} { this->read(thread); }
|
File(std::string file, Game::FsThread thread) : filePath{std::move(file)} { this->read(thread); }
|
||||||
|
|
||||||
bool exists() override { return !this->buffer.empty(); }
|
[[nodiscard]] bool exists() const noexcept override { return !this->buffer.empty(); }
|
||||||
std::string getName() override { return this->filePath; }
|
[[nodiscard]] std::string getName() const override { return this->filePath; }
|
||||||
std::string& getBuffer() override { return this->buffer; }
|
[[nodiscard]] std::string& getBuffer() override { return this->buffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filePath;
|
std::string filePath;
|
||||||
@ -44,9 +44,9 @@ namespace Components
|
|||||||
RawFile() = default;
|
RawFile() = default;
|
||||||
RawFile(std::string file) : filePath(std::move(file)) { this->read(); }
|
RawFile(std::string file) : filePath(std::move(file)) { this->read(); }
|
||||||
|
|
||||||
bool exists() override { return !this->buffer.empty(); }
|
[[nodiscard]] bool exists() const noexcept override { return !this->buffer.empty(); }
|
||||||
std::string getName() override { return this->filePath; }
|
[[nodiscard]] std::string getName() const override { return this->filePath; }
|
||||||
std::string& getBuffer() override { return this->buffer; }
|
[[nodiscard]] std::string& getBuffer() override { return this->buffer; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filePath;
|
std::string filePath;
|
||||||
@ -58,16 +58,16 @@ namespace Components
|
|||||||
class FileReader
|
class FileReader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
FileReader() : handle(0), size(-1), name() {}
|
FileReader() : handle(0), size(-1) {}
|
||||||
FileReader(const std::string& file);
|
FileReader(std::string file);
|
||||||
~FileReader();
|
~FileReader();
|
||||||
|
|
||||||
bool exists();
|
[[nodiscard]] bool exists() const noexcept;
|
||||||
std::string getName();
|
[[nodiscard]] std::string getName() const;
|
||||||
std::string getBuffer();
|
[[nodiscard]] std::string getBuffer() const;
|
||||||
int getSize();
|
[[nodiscard]] int getSize() const noexcept;
|
||||||
bool read(void* buffer, size_t size);
|
bool read(void* buffer, std::size_t size) const noexcept;
|
||||||
void seek(int offset, int origin);
|
void seek(int offset, int origin) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int handle;
|
int handle;
|
||||||
@ -81,7 +81,7 @@ namespace Components
|
|||||||
FileWriter(std::string file, bool append = false) : handle(0), filePath(std::move(file)) { this->open(append); }
|
FileWriter(std::string file, bool append = false) : handle(0), filePath(std::move(file)) { this->open(append); }
|
||||||
~FileWriter() { this->close(); }
|
~FileWriter() { this->close(); }
|
||||||
|
|
||||||
void write(const std::string& data);
|
void write(const std::string& data) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int handle;
|
int handle;
|
||||||
@ -115,10 +115,10 @@ namespace Components
|
|||||||
static int ExecIsFSStub(const char* execFilename);
|
static int ExecIsFSStub(const char* execFilename);
|
||||||
|
|
||||||
static void FsStartupSync(const char* a1);
|
static void FsStartupSync(const char* a1);
|
||||||
static void FsRestartSync(int a1, int a2);
|
static void FsRestartSync(int localClientNum, int checksumFeed);
|
||||||
static void FsShutdownSync(int a1);
|
static void FsShutdownSync(int closemfp);
|
||||||
static void DelayLoadImagesSync();
|
static void DelayLoadImagesSync();
|
||||||
static int LoadTextureSync(Game::GfxImageLoadDef **loadDef, Game::GfxImage *image);
|
static int LoadTextureSync(Game::GfxImageLoadDef** loadDef, Game::GfxImage* image);
|
||||||
|
|
||||||
static void IwdFreeStub(Game::iwd_t* iwd);
|
static void IwdFreeStub(Game::iwd_t* iwd);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user