r5sdk/r5dev/filesystem/basefilesystem.cpp
Kawe Mazidjatari edc52ad669 IDetour: remove extraneous pointer assignments
Originally, we store the search results in a CMemory instance which we then assign to the actual function pointer. CMemory is just a pointer class; we can assign the results directly to the actual function pointer. This commit reduces a lot of code verbosity, and also reduced roughly 2KiB worth of static pointers in the resulting executable. This commit also officially deprecates the support for any GameDLL's below S3 (Season 3), since it makes more sense to port the assets from earlier/later games back to the version this SDK supports.
2024-04-05 17:19:32 +02:00

214 lines
7.0 KiB
C++

#include "core/stdafx.h"
#include "tier1/cvar.h"
#include "filesystem/basefilesystem.h"
#include "filesystem/filesystem.h"
#include "bspfile.h"
#include "engine/modelloader.h"
//---------------------------------------------------------------------------------
// Purpose: prints the output of the filesystem based on the warning level
// Input : *this -
// level -
// *pFmt -
//---------------------------------------------------------------------------------
void CBaseFileSystem::Warning(CBaseFileSystem* pFileSystem, FileWarningLevel_t level, const char* pFmt, ...)
{
if (level >= FileWarningLevel_t::FILESYSTEM_WARNING_REPORTALLACCESSES)
{
// Logging reads are very verbose! Explicitly toggle..
if (!fs_showAllReads->GetBool())
{
return;
}
}
va_list args;
va_start(args, pFmt);
CoreMsgV(LogType_t::LOG_WARNING, static_cast<LogLevel_t>(fs_showWarnings->GetInt()), eDLL_T::FS, "filesystem", pFmt, args);
va_end(args);
}
//---------------------------------------------------------------------------------
// Purpose: attempts to load files from disk if exist before loading from VPK/cache
// Input : *pszFilePath -
// Output : handle to file on success, NULL on failure
//---------------------------------------------------------------------------------
bool CBaseFileSystem::VCheckDisk(const char* pszFilePath)
{
// Only load material files from the disk if the mode isn't zero,
// use -novpk to load valve materials from the disk.
if (FileSystem()->CheckVPKMode(0) && V_strstr(pszFilePath, ".vmt"))
{
return false;
}
if (V_IsAbsolutePath(pszFilePath))
{
// Skip absolute file paths.
return false;
}
CUtlString filePath;
filePath.Format("platform/%s", pszFilePath);
filePath.FixSlashes();
filePath = filePath.Replace("\\*\\", "");
if (::FileExists(filePath.Get()))
{
return true;
}
return false;
}
//---------------------------------------------------------------------------------
// Purpose: loads files from VPK
// Input : *this -
// *pResults -
// *pszFilePath -
// Output : handle to file on success, NULL on failure
//---------------------------------------------------------------------------------
FileHandle_t CBaseFileSystem::VReadFromVPK(CBaseFileSystem* pFileSystem, FileHandle_t pResults, const char* pszFilePath)
{
if (VCheckDisk(pszFilePath))
{
*reinterpret_cast<int64_t*>(pResults) = -1;
return pResults;
}
return CBaseFileSystem__LoadFromVPK(pFileSystem, pResults, pszFilePath);
}
//---------------------------------------------------------------------------------
// Purpose: loads files from cache
// Input : *this -
// *pszFilePath -
// *pCache -
// Output : true if file exists, false otherwise
//---------------------------------------------------------------------------------
bool CBaseFileSystem::VReadFromCache(CBaseFileSystem* pFileSystem, const char* pszFilePath, FileSystemCache* pCache)
{
if (VCheckDisk(pszFilePath))
{
return false;
}
bool result = CBaseFileSystem__LoadFromCache(pFileSystem, pszFilePath, pCache);
return result;
}
//---------------------------------------------------------------------------------
// Purpose: mounts a BSP packfile lump as search path
// Input : *this -
// *pPath -
// *pPathID -
// *addType -
//---------------------------------------------------------------------------------
void CBaseFileSystem::VAddMapPackFile(CBaseFileSystem* pFileSystem, const char* pPath, const char* pPathID, SearchPathAdd_t addType)
{
// Since the mounting of the packfile lump is performed before the BSP header
// is loaded and parsed, we have to do it here. The internal 'AddMapPackFile'
// function has been patched to load the fields in the global 's_MapHeader'
// field, instead of the one that is getting initialized (see r5apex.patch).
if (s_MapHeader->ident != IDBSPHEADER || s_MapHeader->version != BSPVERSION)
{
FileHandle_t hBspFile = FileSystem()->Open(pPath, "rb", pPathID);
if (hBspFile != FILESYSTEM_INVALID_HANDLE)
{
memset(s_MapHeader, '\0', sizeof(BSPHeader_t));
FileSystem()->Read(s_MapHeader, sizeof(BSPHeader_t), hBspFile);
}
}
// If a lump exists, replace the path pointer with that of the lump so that
// the internal function loads this instead.
char lumpPathBuf[MAX_PATH];
V_snprintf(lumpPathBuf, sizeof(lumpPathBuf), "%s.%.4X.bsp_lump", pPath, LUMP_PAKFILE);
if (FileSystem()->FileExists(lumpPathBuf, pPathID))
{
pPath = lumpPathBuf;
}
CBaseFileSystem__AddMapPackFile(pFileSystem, pPath, pPathID, addType);
}
//---------------------------------------------------------------------------------
// Purpose: attempts to mount VPK file for filesystem usage
// Input : *this -
// *pszVpkPath -
// Output : pointer to VPK on success, NULL on failure
//---------------------------------------------------------------------------------
VPKData_t* CBaseFileSystem::VMountVPKFile(CBaseFileSystem* pFileSystem, const char* pszVpkPath)
{
int nHandle = CBaseFileSystem__GetMountedVPKHandle(pFileSystem, pszVpkPath);
VPKData_t* pPakData = CBaseFileSystem__MountVPKFile(pFileSystem, pszVpkPath);
if (pPakData)
{
if (nHandle < 0) // Only log if VPK hasn't been mounted yet.
{
::Msg(eDLL_T::FS, "Mounted vpk file: '%s' with handle: '%i'\n", pszVpkPath, pPakData->m_nHandle);
}
}
else // VPK failed to load or does not exist...
{
::Warning(eDLL_T::FS, "Unable to mount vpk file: '%s'\n", pszVpkPath);
}
return pPakData;
}
//---------------------------------------------------------------------------------
// Purpose: unmount a VPK file
// Input : *this -
// *pszVpkPath -
// Output : pointer to formatted VPK path string
//---------------------------------------------------------------------------------
const char* CBaseFileSystem::VUnmountVPKFile(CBaseFileSystem* pFileSystem, const char* pszVpkPath)
{
int nHandle = CBaseFileSystem__GetMountedVPKHandle(pFileSystem, pszVpkPath);
const char* pRet = CBaseFileSystem__UnmountVPKFile(pFileSystem, pszVpkPath);
if (nHandle >= 0)
{
::Msg(eDLL_T::FS, "Unmounted vpk file: '%s' with handle: '%i'\n", pszVpkPath, nHandle);
}
return pRet;
}
//---------------------------------------------------------------------------------
// Purpose: reads a string until its null terminator
// Input : *pFile -
// Output : string
//---------------------------------------------------------------------------------
CUtlString CBaseFileSystem::ReadString(FileHandle_t pFile)
{
CUtlString result;
char c = '\0';
do
{
Read(&c, sizeof(char), pFile);
if (c)
result += c;
} while (c);
return result;
}
void VBaseFileSystem::Detour(const bool bAttach) const
{
DetourSetup(&CBaseFileSystem__Warning, &CBaseFileSystem::Warning, bAttach);
DetourSetup(&CBaseFileSystem__LoadFromVPK, &CBaseFileSystem::VReadFromVPK, bAttach);
DetourSetup(&CBaseFileSystem__LoadFromCache, &CBaseFileSystem::VReadFromCache, bAttach);
DetourSetup(&CBaseFileSystem__AddMapPackFile, &CBaseFileSystem::VAddMapPackFile, bAttach);
DetourSetup(&CBaseFileSystem__MountVPKFile, &CBaseFileSystem::VMountVPKFile, bAttach);
DetourSetup(&CBaseFileSystem__UnmountVPKFile, &CBaseFileSystem::VUnmountVPKFile, bAttach);
}
CBaseFileSystem* g_pFileSystem = nullptr;