diff --git a/r5dev/public/include/utility.h b/r5dev/public/include/utility.h index 1d114d6d..9a4cea26 100644 --- a/r5dev/public/include/utility.h +++ b/r5dev/public/include/utility.h @@ -16,6 +16,7 @@ std::string Base64Encode(const std::string& in); std::string Base64Decode(const std::string& in); bool StringReplace(std::string& str, const std::string& from, const std::string& to); std::string CreateDirectories(std::string svFilePath); +std::string ConvertToWinPath(const std::string& input); std::string StringEscape(const std::string& input); std::string StringUnescape(const std::string& input); diff --git a/r5dev/public/utility.cpp b/r5dev/public/utility.cpp index 431fa831..46468b54 100644 --- a/r5dev/public/utility.cpp +++ b/r5dev/public/utility.cpp @@ -296,6 +296,25 @@ std::string CreateDirectories(std::string svFilePath) return results; } +/////////////////////////////////////////////////////////////////////////////// +// For converting filepaths to windows filepaths. +std::string ConvertToWinPath(const std::string& input) +{ + char szFilePath[MAX_PATH] = { 0 }; + std::string results; + sprintf_s(szFilePath, MAX_PATH, "%s", input.c_str()); + + // Flip forward slashes in filepath to windows-style backslash + for (int i = 0; i < strlen(szFilePath); i++) + { + if (szFilePath[i] == '/') + { + szFilePath[i] = '\\'; + } + } + return results = szFilePath; +} + /////////////////////////////////////////////////////////////////////////////// // For escaping special characters in a string. std::string StringEscape(const std::string& input) diff --git a/r5dev/squirrel/sqvm.cpp b/r5dev/squirrel/sqvm.cpp index 3e819146..7d8341ec 100644 --- a/r5dev/squirrel/sqvm.cpp +++ b/r5dev/squirrel/sqvm.cpp @@ -143,82 +143,30 @@ void* HSQVM_WarningFunc(void* sqvm, int a2, int a3, int* nStringSize, void** ppS } //--------------------------------------------------------------------------------- -// Purpose: loads the include file from the mods directory +// Purpose: prints the global include file the compiler loads for loading scripts //--------------------------------------------------------------------------------- void* HSQVM_LoadRson(const char* szRsonName) { - char szFilePath[MAX_PATH] = { 0 }; - sprintf_s(szFilePath, MAX_PATH, "platform\\%s", szRsonName); - - // Flip forward slashes in filepath to windows-style backslash - for (int i = 0; i < strlen(szFilePath); i++) + if (sq_showrsonloading->GetBool()) { - if (szFilePath[i] == '/') - { - szFilePath[i] = '\\'; - } - } - - // Returns the new path if the rson exists on the disk - if (FileExists(szFilePath) && SQVM_LoadRson(szRsonName)) - { - if (sq_showrsonloading->GetBool()) - { - DevMsg(eDLL_T::ENGINE, "\n"); - DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n"); - DevMsg(eDLL_T::ENGINE, "] RSON_DISK --------------------------------------------------\n"); - DevMsg(eDLL_T::ENGINE, "] PATH: '%s'\n", szFilePath); - DevMsg(eDLL_T::ENGINE, "--------------------------------------------------------------\n"); - DevMsg(eDLL_T::ENGINE, "\n"); - } - return SQVM_LoadRson(szFilePath); - } - else - { - if (sq_showrsonloading->GetBool()) - { - DevMsg(eDLL_T::ENGINE, "\n"); - DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n"); - DevMsg(eDLL_T::ENGINE, "] RSON_VPK ---------------------------------------------------\n"); - DevMsg(eDLL_T::ENGINE, "] PATH: '%s'\n", szRsonName); - DevMsg(eDLL_T::ENGINE, "--------------------------------------------------------------\n"); - DevMsg(eDLL_T::ENGINE, "\n"); - } + DevMsg(eDLL_T::ENGINE, "\n"); + DevMsg(eDLL_T::ENGINE, "______________________________________________________________\n"); + DevMsg(eDLL_T::ENGINE, "] RSON_SQVM --------------------------------------------------\n"); + DevMsg(eDLL_T::ENGINE, "] PATH: '%s'\n", szRsonName); + DevMsg(eDLL_T::ENGINE, "--------------------------------------------------------------\n"); + DevMsg(eDLL_T::ENGINE, "\n"); } return SQVM_LoadRson(szRsonName); } //--------------------------------------------------------------------------------- -// Purpose: loads the script file from the mods directory +// Purpose: prints the scripts the compiler loads from global include to be compiled //--------------------------------------------------------------------------------- bool HSQVM_LoadScript(void* sqvm, const char* szScriptPath, const char* szScriptName, int nFlag) { - char filepath[MAX_PATH] = { 0 }; - sprintf_s(filepath, MAX_PATH, "platform\\%s", szScriptPath); - - // Flip forward slashes in filepath to windows-style backslash - for (int i = 0; i < strlen(filepath); i++) - { - if (filepath[i] == '/') - { - filepath[i] = '\\'; - } - } - if (sq_showscriptloading->GetBool()) { - DevMsg(eDLL_T::ENGINE, "Loading SQVM Script '%s'\n", filepath); - } - - // Returns true if the script exists on the disk - if (FileExists(filepath) && SQVM_LoadScript(sqvm, filepath, szScriptName, nFlag)) - { - return true; - } - - if (sq_showscriptloading->GetBool()) - { - DevMsg(eDLL_T::ENGINE, "FAILED. Try SP / VPK for '%s'\n", filepath); + DevMsg(eDLL_T::ENGINE, "Loading SQVM Script '%s'\n", szScriptName); } /////////////////////////////////////////////////////////////////////////////// @@ -247,7 +195,7 @@ void HSQVM_RegisterFunction(void* sqvm, const char* szName, const char* szHelpSt //--------------------------------------------------------------------------------- void RegisterServerScriptFunctions(void* sqvm) { - HSQVM_RegisterFunction(sqvm, "ServerNativeTest", "Native SERVER test function", "void", "", &VSquirrel::SHARED::Script_NativeTest); + HSQVM_RegisterFunction(sqvm, "SDKNativeTest", "Native SERVER test function", "void", "", &VSquirrel::SHARED::Script_NativeTest); } #ifndef DEDICATED @@ -256,7 +204,7 @@ void RegisterServerScriptFunctions(void* sqvm) //--------------------------------------------------------------------------------- void RegisterClientScriptFunctions(void* sqvm) { - HSQVM_RegisterFunction(sqvm, "ClientNativeTest", "Native CLIENT test function", "void", "", &VSquirrel::SHARED::Script_NativeTest); + HSQVM_RegisterFunction(sqvm, "SDKNativeTest", "Native CLIENT test function", "void", "", &VSquirrel::SHARED::Script_NativeTest); } //--------------------------------------------------------------------------------- @@ -264,7 +212,7 @@ void RegisterClientScriptFunctions(void* sqvm) //--------------------------------------------------------------------------------- void RegisterUIScriptFunctions(void* sqvm) { - HSQVM_RegisterFunction(sqvm, "UINativeTest", "Native UI test function", "void", "", &VSquirrel::SHARED::Script_NativeTest); + HSQVM_RegisterFunction(sqvm, "SDKNativeTest", "Native UI test function", "void", "", &VSquirrel::SHARED::Script_NativeTest); // functions for retrieving server browser data HSQVM_RegisterFunction(sqvm, "GetServerName", "Gets the name of the server at the specified index of the server list", "string", "int", &VSquirrel::UI::GetServerName); diff --git a/r5dev/vpc/basefilesystem.cpp b/r5dev/vpc/basefilesystem.cpp index b28d9a72..68b29f14 100644 --- a/r5dev/vpc/basefilesystem.cpp +++ b/r5dev/vpc/basefilesystem.cpp @@ -48,12 +48,63 @@ void HCBaseFileSystem_Warning(void* thisptr, FileWarningLevel_t level, const cha } } +//--------------------------------------------------------------------------------- +// Purpose: attempts to load files from disk if exist before loading from VPK +//--------------------------------------------------------------------------------- +FileHandle_t HCBaseFileSystem_ReadFromVPK(void* pVpk, std::int64_t* pResults, char* pszFilePath) +{ + std::string svFilePath = ConvertToWinPath(pszFilePath); + + if (strstr(svFilePath.c_str(), "\\\*\\")) + { + // Erase '//*/'. + svFilePath.erase(0, 4); + } + + // TODO: obtain 'mod' SearchPath's instead. + svFilePath.insert(0, "platform\\"); + + if (FileExists(svFilePath.c_str()) || FileExists(pszFilePath)) + { + *pResults = -1; + return (void*)pResults; + } + return CBaseFileSystem_LoadFromVPK(pVpk, pResults, pszFilePath); +} + +//--------------------------------------------------------------------------------- +// Purpose: attempts to load files from disk if exist before loading from cache +//--------------------------------------------------------------------------------- +bool HCBaseFileSystem_ReadFromCache(void* pFileSystem, char* pszFilePath, void* pResults) +{ + std::string svFilePath = ConvertToWinPath(pszFilePath); + + if (strstr(svFilePath.c_str(), "\\\*\\")) + { + // Erase '//*/'. + svFilePath.erase(0, 4); + } + + // TODO: obtain 'mod' SearchPath's instead. + svFilePath.insert(0, "platform\\"); + + if (FileExists(svFilePath.c_str()) || FileExists(pszFilePath)) + { + return false; + } + return CBaseFileSystem_LoadFromCache(pFileSystem, pszFilePath, pResults); +} + void CBaseFileSystem_Attach() { DetourAttach((LPVOID*)&CBaseFileSystem_Warning, &HCBaseFileSystem_Warning); + DetourAttach((LPVOID*)&CBaseFileSystem_LoadFromVPK, &HCBaseFileSystem_ReadFromVPK); + DetourAttach((LPVOID*)&CBaseFileSystem_LoadFromCache, &HCBaseFileSystem_ReadFromCache); } void CBaseFileSystem_Detach() { DetourDetach((LPVOID*)&CBaseFileSystem_Warning, &HCBaseFileSystem_Warning); + DetourDetach((LPVOID*)&CBaseFileSystem_LoadFromVPK, &HCBaseFileSystem_ReadFromVPK); + DetourDetach((LPVOID*)&CBaseFileSystem_LoadFromCache, &HCBaseFileSystem_ReadFromCache); } diff --git a/r5dev/vpc/basefilesystem.h b/r5dev/vpc/basefilesystem.h index cc16fc15..5c04523c 100644 --- a/r5dev/vpc/basefilesystem.h +++ b/r5dev/vpc/basefilesystem.h @@ -1,5 +1,7 @@ #pragma once +typedef void* FileHandle_t; + enum class FileWarningLevel_t : int { FILESYSTEM_WARNING = -1, // A problem! @@ -17,6 +19,12 @@ namespace /* ==== CBASEFILESYSTEM ================================================================================================================================================= */ ADDRESS p_CBaseFileSystem_Warning = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x4C\x89\x4C\x24\x20\xC3\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x48", "xxxxxx??????????x"); void (*CBaseFileSystem_Warning)(void* thisptr, FileWarningLevel_t level, const char* fmt, ...) = (void (*)(void*, FileWarningLevel_t, const char*, ...))p_CBaseFileSystem_Warning.GetPtr(); /*4C 89 4C 24 20 C3 ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? 48*/ + + ADDRESS p_CBaseFileSystem_LoadFromVPK = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x57\x48\x81\xEC\x00\x00\x00\x00\x49\x8B\xC0\x4C\x8D\x8C\x24\x00\x00\x00\x00", "xxxx?xxxx????xxxxxxx????"); + FileHandle_t(*CBaseFileSystem_LoadFromVPK)(void* pVpk, std::int64_t* pResults, char* pszAssetName) = (FileHandle_t(*)(void*, std::int64_t*, char*))p_CBaseFileSystem_LoadFromVPK.GetPtr(); /*48 89 5C 24 ? 57 48 81 EC ? ? ? ? 49 8B C0 4C 8D 8C 24 ? ? ? ?*/ + + ADDRESS p_CBaseFileSystem_LoadFromCache = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x40\x53\x48\x81\xEC\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x49\x8B\xD8", "xxxxx????xx?????xxx"); + bool(*CBaseFileSystem_LoadFromCache)(void* pFileSystem, char* pszAssetName, void* pResults) = (bool(*)(void*, char*, void*))p_CBaseFileSystem_LoadFromCache.GetPtr(); /*40 53 48 81 EC ? ? ? ? 80 3D ? ? ? ? ? 49 8B D8*/ } /////////////////////////////////////////////////////////////////////////////// @@ -28,7 +36,9 @@ class HBaseFileSystem : public IDetour { virtual void debugp() { - std::cout << "| FUN: CBaseFileSystem::Warning : 0x" << std::hex << std::uppercase << p_CBaseFileSystem_Warning.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CBaseFileSystem::Warning : 0x" << std::hex << std::uppercase << p_CBaseFileSystem_Warning.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CBaseFileSystem::LoadFromVPK : 0x" << std::hex << std::uppercase << p_CBaseFileSystem_LoadFromVPK.GetPtr() << std::setw(npad) << " |" << std::endl; + std::cout << "| FUN: CBaseFileSystem::LoadFromCache : 0x" << std::hex << std::uppercase << p_CBaseFileSystem_LoadFromCache.GetPtr() << std::setw(npad) << " |" << std::endl; std::cout << "+----------------------------------------------------------------+" << std::endl; } };