Load STBSP file specified in prereq file

The game now loads a override STBSP file for the BSP if field 'stbsp' in level prereq settings is populated.
This commit is contained in:
Amos 2022-03-02 01:16:35 +01:00
parent fa8c9be8cc
commit 8e1953cc8d
15 changed files with 144 additions and 58 deletions

View File

@ -9,6 +9,7 @@
#include "engine/cmodel_bsp.h"
#include "engine/host_cmd.h"
#include "engine/gl_screen.h"
#include "engine/gl_matsysiface.h"
#include "engine/modelloader.h"
#include "engine/cl_main.h"
#include "engine/sv_main.h"

View File

@ -58,8 +58,9 @@
#include "engine/sys_engine.h"
#include "engine/sys_utils.h"
#include "engine/sys_getmodes.h"
#ifndef DEDICATED
#include "engine/gl_matsysiface.h"
#include "engine/gl_screen.h"
#ifndef DEDICATED
#include "engine/debugoverlay.h"
#endif // !DEDICATED
#include "game/server/ai_node.h"
@ -107,6 +108,10 @@ void Systems_Init()
CBaseClient_Attach();
CBaseFileSystem_Attach();
#ifndef DEDICATED
CMaterialSystem_Attach();
#endif // !DEDICATED
QHull_Attach();
//BspLib_Attach();
@ -192,6 +197,10 @@ void Systems_Shutdown()
CBaseClient_Detach();
CBaseFileSystem_Detach();
#ifndef DEDICATED
CMaterialSystem_Detach();
#endif // !DEDICATED
QHull_Detach();
//BspLib_Detach();

View File

@ -12,21 +12,15 @@
#include "engine/cmodel_bsp.h"
#include "rtech/rtech_game.h"
int g_nLoadedPakFileId[256]{};
//-----------------------------------------------------------------------------
// Purpose: loads required assets for specified level
// Todo : STBSP and VPK loading
// Todo : Unload all assets loaded by this functions using 'nPakId'
// Purpose: loads required pakfile assets for specified BSP
//-----------------------------------------------------------------------------
void MOD_LoadDependencies(eBspRes_t resourceType)
void MOD_PreloadPak(void)
{
std::ostringstream ostream;
ostream << "platform\\scripts\\levels\\" << g_pHostState->m_levelName << ".json";
ostream << "platform\\scripts\\levels\\settings\\" << g_pHostState->m_levelName << ".json";
std::filesystem::path fsPath = std::filesystem::current_path() /= ostream.str();
DevMsg(eDLL_T::ENGINE, "Loading level prerequisites file: '%s'\n", fsPath.string().c_str());
if (FileExists(fsPath.string().c_str()))
{
nlohmann::json jsIn;
@ -36,47 +30,36 @@ void MOD_LoadDependencies(eBspRes_t resourceType)
iPakLoadDefFile >> jsIn;
iPakLoadDefFile.close();
switch (resourceType)
if (!jsIn.is_null())
{
case eBspRes_t::RES_RPAK:
{
if (!jsIn.is_null())
if (!jsIn["rpak"].is_null())
{
if (!jsIn["rpak"].is_null())
int iPakIdx{};
for (auto it = jsIn["rpak"].begin(); it != jsIn["rpak"].end(); ++it)
{
int iPakIdx{};
for (auto it = jsIn["rpak"].begin(); it != jsIn["rpak"].end(); ++it)
if (it.value().is_string())
{
if (it.value().is_string())
{
std::string svToLoad = it.value().get<std::string>() + ".rpak";
unsigned int nPakId = 0;
nPakId = RTech_AsyncLoad((void*)svToLoad.c_str(), g_pMallocPool.GetPtr(), 4, 0);
std::string svToLoad = it.value().get<std::string>() + ".rpak";
unsigned int nPakId = 0;
nPakId = RTech_AsyncLoad((void*)svToLoad.c_str(), g_pMallocPool.GetPtr(), 4, 0);
if (nPakId == -1)
{
DevMsg(eDLL_T::RTECH, "RTech AsyncLoad failed read '%s' results '%u'\n", fsPath.string().c_str(), nPakId);
}
else
{
g_nLoadedPakFileId[iPakIdx] = nPakId;
iPakIdx++;
}
if (nPakId == -1)
{
DevMsg(eDLL_T::RTECH, "RTech_AsyncLoad: failed read '%s' results '%u'\n", fsPath.string().c_str(), nPakId);
}
else
{
g_nLoadedPakFileId[iPakIdx] = nPakId;
iPakIdx++;
}
}
}
}
break;
}
default:
{
break;
}
}
}
catch (const std::exception& ex)
{
DevMsg(eDLL_T::ENGINE, "Error parsing level prerequisites file: '%s'\n", fsPath.string().c_str(), ex.what());
DevMsg(eDLL_T::RTECH, "Exception while parsing RPak load list: '%s'\n", ex.what());
return;
}
}

View File

@ -7,16 +7,7 @@ namespace
// 0x140256480 // 48 89 5C 24 ? 48 89 6C 24 ? 57 48 81 EC ? ? ? ? 48 8B F9 33 ED //
}
enum class eBspRes_t
{
RES_RPAK = 0,
RES_VPK,
RES_STBSP
};
extern int g_nLoadedPakFileId[256];
void MOD_LoadDependencies(eBspRes_t resourceType);
void MOD_PreloadPak(void);
///////////////////////////////////////////////////////////////////////////////
class HModel_BSP : public IDetour
{

View File

@ -0,0 +1,20 @@
namespace
{
/* ==== MATSYSIFACE ===================================================================================================================================================== */
ADDRESS InitMaterialSystem = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00", "xxxxxxx????xxx????xxxxx????xxx????xxx????xxxxx????"); //
// 0x14024B390 // 48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? //
}
///////////////////////////////////////////////////////////////////////////////
class HGL_MatSysIFace : public IDetour
{
virtual void debugp()
{
std::cout << "| FUN: InitMaterialSystem : 0x" << std::hex << std::uppercase << InitMaterialSystem.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;
}
};
///////////////////////////////////////////////////////////////////////////////
REGISTER(HGL_MatSysIFace);

View File

@ -47,7 +47,7 @@ class HHostCmd : public IDetour
virtual void debugp()
{
std::cout << "| FUN: Host_Init : 0x" << std::hex << std::uppercase << p_Host_Init.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: Host_NewGame : 0x" << std::hex << std::uppercase << p_Host_NewGame.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: Host_NewGame : 0x" << std::hex << std::uppercase << p_Host_NewGame.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: malloc_internal : 0x" << std::hex << std::uppercase << p_malloc_internal.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| VAR: g_pEngineParms : 0x" << std::hex << std::uppercase << g_pEngineParmsBuffer.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| VAR: g_pMallocPool : 0x" << std::hex << std::uppercase << g_pMallocPool.GetPtr() << std::setw(npad) << " |" << std::endl;

View File

@ -193,7 +193,7 @@ void* HSys_LoadAssetHelper(const CHAR* lpFileName, std::int64_t a2, LARGE_INTEGE
bBasePaksLoaded || !strcmp(std::string(lpFileName).erase(0, 11).c_str(), "mp_lobby.rpak"))
{
// Attempt to load level dependencies if they exist.
MOD_LoadDependencies(eBspRes_t::RES_RPAK);
MOD_PreloadPak();
// By the time mp_lobby.rpak is loaded, all the base paks are loaded as well and we can load anything else.
bBasePaksLoaded = true;

View File

@ -0,0 +1,59 @@
//===========================================================================//
//
// Purpose:
//
//===========================================================================//
#include "core/stdafx.h"
#include "tier0/cvar.h"
#include "engine/sys_utils.h"
#include "materialsystem/materialsystem.h"
//---------------------------------------------------------------------------------
// Purpose: loads and processes STBSP files
// (overrides level name if stbsp field has value in prerequisites file)
// Input : *pszStreamDBFile -
//---------------------------------------------------------------------------------
void HStreamDB_Init(const char* pszStreamDBFile)
{
std::ostringstream ostream;
ostream << "platform\\scripts\\levels\\settings\\" << pszStreamDBFile << ".json";
std::filesystem::path fsPath = std::filesystem::current_path() /= ostream.str();
if (FileExists(fsPath.string().c_str()))
{
nlohmann::json jsIn;
try
{
std::ifstream iPakLoadDefFile(fsPath, std::ios::binary); // Parse prerequisites file.
iPakLoadDefFile >> jsIn;
iPakLoadDefFile.close();
if (!jsIn.is_null())
{
if (!jsIn["stbsp"].is_null())
{
std::string svStreamDBFile = jsIn["stbsp"].get<std::string>();
DevMsg(eDLL_T::MS, "StreamDB_Init: Loading override STBSP file '%s.stbsp'\n", svStreamDBFile.c_str(), pszStreamDBFile);
StreamDB_Init(svStreamDBFile.c_str());
return;
}
}
}
catch (const std::exception& ex)
{
DevMsg(eDLL_T::MS, "StreamDB_Init: Exception while parsing STBSP override: '%s'\n", ex.what());
}
}
StreamDB_Init(pszStreamDBFile);
}
///////////////////////////////////////////////////////////////////////////////
void CMaterialSystem_Attach()
{
DetourAttach((LPVOID*)&StreamDB_Init, &HStreamDB_Init);
}
void CMaterialSystem_Detach()
{
DetourDetach((LPVOID*)&StreamDB_Init, &HStreamDB_Init);
}

View File

@ -1,5 +1,4 @@
#pragma once
#include "engine/debugoverlay.h"
namespace
{
@ -7,12 +6,14 @@ namespace
ADDRESS CMaterialSystem__Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x83\xEC\x70\x48\x83\x3D\x00\x00\x00\x00\x00", "xxxx?xxxxxxxxxxxxxxxxxx?????");
// 0x1403BBFD0 // 48 89 5C 24 ? 55 56 57 41 54 41 55 41 56 41 57 48 83 EC 70 48 83 3D ? ? ? ? ? //
ADDRESS InitMaterialSystem = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00\x48\x8B\x0D\x00\x00\x00\x00\x48\x8D\x15\x00\x00\x00\x00\x48\x8B\x01\xFF\x90\x00\x00\x00\x00", "xxxxxxx????xxx????xxxxx????xxx????xxx????xxxxx????"); //
// 0x14024B390 // 48 83 EC 28 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? 48 8B 0D ? ? ? ? 48 8D 15 ? ? ? ? 48 8B 01 FF 90 ? ? ? ? //
ADDRESS p_DrawStreamOverlay = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x41\x56\xB8\x00\x00\x00\x00\xE8\x00\x00\x00\x00\x48\x2B\xE0\xC6\x02\x00", "xxx????x????xxxxxx"); // 41 56 B8 ? ? ? ? E8 ? ? ? ? 48 2B E0 C6 02 00 //
const char* (*DrawStreamOverlay)(void* thisptr, std::uint8_t* a2, void* unused, void* a4) = (const char* (*)(void*, std::uint8_t*, void*, void*))p_DrawStreamOverlay.GetPtr();
#ifndef DEDICATED
ADDRESS p_StreamDB_Init = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x48\x89\x74\x24\x00\x48\x89\x7C\x24\x00\x41\x54\x41\x56\x41\x57\x48\x83\xEC\x40\x48\x8B\xE9", "xxxx?xxxx?xxxx?xxxx?xxxxxxxxxxxxx");
void (*StreamDB_Init)(const char* pszStreamDbFile) = (void (*)(const char* pszStreamDbFile))p_StreamDB_Init.GetPtr(); /*48 89 5C 24 ? 48 89 6C 24 ? 48 89 74 24 ? 48 89 7C 24 ? 41 54 41 56 41 57 48 83 EC 40 48 8B E9*/
#endif // !DEDICATED
void* g_pMaterialSystem = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x8B\x0D\x00\x00\x00\x00\x48\x85\xC9\x74\x11\x48\x8B\x01\x48\x8D\x15\x00\x00\x00\x00", "xxx????xxxxxxxxxxx????").ResolveRelativeAddressSelf(0x3, 0x7).RCast<void*>();
int* total_streaming_tex_memory = p_DrawStreamOverlay.Offset(0x0).FindPatternSelf("48 8B 05", ADDRESS::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<int*>();
@ -21,19 +22,22 @@ namespace
}
void CMaterialSystem_Attach();
void CMaterialSystem_Detach();
///////////////////////////////////////////////////////////////////////////////
class HMaterialSystem : public IDetour
{
virtual void debugp()
{
std::cout << "| FUN: CMaterialSystem::Init : 0x" << std::hex << std::uppercase << CMaterialSystem__Init.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: InitMaterialSystem : 0x" << std::hex << std::uppercase << InitMaterialSystem.GetPtr() << std::setw(npad) << " |" << std::endl;
std::cout << "| FUN: DrawStreamOverlay : 0x" << std::hex << std::uppercase << p_DrawStreamOverlay.GetPtr() << std::setw(npad) << " |" << std::endl;
#ifndef DEDICATED
std::cout << "| FUN: StreamDB_Init : 0x" << std::hex << std::uppercase << p_StreamDB_Init.GetPtr() << std::setw(npad) << " |" << std::endl;
#endif // !DEDICATED
std::cout << "| VAR: g_pMaterialSystem : 0x" << std::hex << std::uppercase << g_pMaterialSystem << std::setw(0) << " |" << std::endl;
std::cout << "+----------------------------------------------------------------+" << std::endl;
}
};
///////////////////////////////////////////////////////////////////////////////
void DebugOverlays_Attach();
REGISTER(HMaterialSystem);

View File

@ -1,7 +1,13 @@
//=============================================================================//
//
// Purpose: RTech game utilities
//
//=============================================================================//
#include "core/stdafx.h"
#include "engine/host_cmd.h"
#include "engine/sys_utils.h"
#include "rtech/rtech_game.h"
int g_nLoadedPakFileId[256]{};
//-----------------------------------------------------------------------------
// Purpose: unloads asset files from the memory pool
@ -39,12 +45,12 @@ void HRtech_AsyncLoad(std::string svPakFileName)
if (nPakId == 0xFFFFFFFF)
{
DevMsg(eDLL_T::RTECH, "RTech AsyncLoad failed read '%s' results '%u'\n", svPakFileName.c_str(), nPakId);
DevMsg(eDLL_T::RTECH, "RTech_AsyncLoad: Failed read '%s' results '%u'\n", svPakFileName.c_str(), nPakId);
}
}
else
{
DevMsg(eDLL_T::RTECH, "RTech AsyncLoad failed. File '%s' doesn't exist\n", svPakFileName.c_str());
DevMsg(eDLL_T::RTECH, "RTech_AsyncLoad: Failed. File '%s' doesn't exist\n", svPakFileName.c_str());
}
}

View File

@ -56,6 +56,7 @@ void HRtech_AsyncLoad(std::string svPakFileName);
void RTech_Game_Attach();
void RTech_Game_Detach();
extern int g_nLoadedPakFileId[256];
///////////////////////////////////////////////////////////////////////////////
class HRTechGame : public IDetour
{

View File

@ -203,6 +203,7 @@
<ClInclude Include="..\engine\cl_main.h" />
<ClInclude Include="..\engine\cmodel_bsp.h" />
<ClInclude Include="..\engine\common.h" />
<ClInclude Include="..\engine\gl_matsysiface.h" />
<ClInclude Include="..\engine\host_cmd.h" />
<ClInclude Include="..\engine\host_state.h" />
<ClInclude Include="..\engine\modelloader.h" />

View File

@ -783,6 +783,9 @@
<ClInclude Include="..\public\include\globalvars_base.h">
<Filter>sdk\public\include</Filter>
</ClInclude>
<ClInclude Include="..\engine\gl_matsysiface.h">
<Filter>sdk\engine</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\client\IVEngineClient.cpp">

View File

@ -56,6 +56,7 @@
<ClCompile Include="..\game\server\gameinterface.cpp" />
<ClCompile Include="..\inputsystem\inputsystem.cpp" />
<ClCompile Include="..\launcher\IApplication.cpp" />
<ClCompile Include="..\materialsystem\materialsystem.cpp" />
<ClCompile Include="..\mathlib\adler32.cpp" />
<ClCompile Include="..\mathlib\bits.cpp" />
<ClCompile Include="..\mathlib\crc32.cpp" />
@ -131,6 +132,7 @@
<ClInclude Include="..\engine\cmodel_bsp.h" />
<ClInclude Include="..\engine\common.h" />
<ClInclude Include="..\engine\debugoverlay.h" />
<ClInclude Include="..\engine\gl_matsysiface.h" />
<ClInclude Include="..\engine\gl_screen.h" />
<ClInclude Include="..\engine\host_cmd.h" />
<ClInclude Include="..\engine\host_state.h" />

View File

@ -390,6 +390,9 @@
<ClCompile Include="..\engine\modelloader.cpp">
<Filter>sdk\engine</Filter>
</ClCompile>
<ClCompile Include="..\materialsystem\materialsystem.cpp">
<Filter>sdk\materialsystem</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\client\cdll_engine_int.h">
@ -1124,6 +1127,9 @@
<ClInclude Include="..\public\include\globalvars_base.h">
<Filter>sdk\public\include</Filter>
</ClInclude>
<ClInclude Include="..\engine\gl_matsysiface.h">
<Filter>sdk\engine</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="..\shared\resource\lockedserver.png">