Parse playlists file directly after loading it

No longer need a thread that loops and waits until its loaded into memory before parsing it.
This commit is contained in:
Kawe Mazidjatari 2022-05-28 17:07:30 +02:00
parent 79d602c274
commit e5e0d528f0
4 changed files with 47 additions and 41 deletions

View File

@ -194,7 +194,6 @@ FORCEINLINE void CHostState::Setup(void)
NET_GenerateKey();
}
ResetLevelName();
KeyValues::Setup();
}
//-----------------------------------------------------------------------------

View File

@ -310,10 +310,10 @@ void CBrowser::LaunchServer(void)
DevMsg(eDLL_T::ENGINE, "Starting server with name: \"%s\" map: \"%s\" playlist: \"%s\"\n", m_Server.svServerName.c_str(), m_Server.svMapName.c_str(), m_Server.svPlaylist.c_str());
/*
* Playlist gets parsed in two instances, first in LoadPlaylist all the neccessary values.
* Playlist gets parsed in two instances, first in KeyValues::ParsePlaylists with all the neccessary values.
* Then when you would normally call launchplaylist which calls StartPlaylist it would cmd call mp_gamemode which parses the gamemode specific part of the playlist..
*/
KeyValues_LoadPlaylist(m_Server.svPlaylist.c_str());
KeyValues_ParsePlaylists(m_Server.svPlaylist.c_str());
stringstream ssModeCommand;
ssModeCommand << "mp_gamemode " << m_Server.svPlaylist;
ProcessCommand(ssModeCommand.str().c_str());

View File

@ -1214,37 +1214,22 @@ KeyValues* KeyValues::MakeCopy(void) const
return pNewKeyValue;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void KeyValues::Setup(void)
{
std::thread t1(KeyValues::InitPlaylists); // Start thread to grab playlists.
t1.detach(); // Detach thread from current one.
}
//-----------------------------------------------------------------------------
// Purpose: Initializes the playlist
//-----------------------------------------------------------------------------
void KeyValues::InitPlaylists(void)
{
while (true)
if (*g_pPlaylistKeyValues)
{
if (*g_pPlaylistKeyValues)
KeyValues* pPlaylists = (*g_pPlaylistKeyValues)->FindKey("Playlists", false);
if (pPlaylists)
{
KeyValues* pPlaylists = (*g_pPlaylistKeyValues)->FindKey("Playlists", false);
if (pPlaylists)
g_vAllPlaylists.clear();
for (KeyValues* pSubKey = pPlaylists->GetFirstTrueSubKey(); pSubKey != nullptr; pSubKey = pSubKey->GetNextTrueSubKey())
{
g_vAllPlaylists.clear();
for (KeyValues* pSubKey = pPlaylists->GetFirstTrueSubKey(); pSubKey != nullptr; pSubKey = pSubKey->GetNextTrueSubKey())
{
g_vAllPlaylists.push_back(pSubKey->GetName()); // Get all playlists.
}
break; // Break if playlist got filled.
g_vAllPlaylists.push_back(pSubKey->GetName()); // Get all playlists.
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
}
@ -1277,10 +1262,24 @@ void KeyValues::InitFileSystem(void)
}
//-----------------------------------------------------------------------------
// Purpose: loads the playlist
// Purpose: loads the playlists
// Input : *szPlaylist -
// Output : true on success, false on failure
//-----------------------------------------------------------------------------
bool KeyValues::LoadPlaylist(const char* szPlaylist)
bool KeyValues::LoadPlaylists(const char* pszPlaylist)
{
bool bResults = KeyValues_LoadPlaylists(pszPlaylist);
KeyValues::InitPlaylists();
return bResults;
}
//-----------------------------------------------------------------------------
// Purpose: parses the playlists
// Input : *szPlaylist -
// Output : true on success, false on failure
//-----------------------------------------------------------------------------
bool KeyValues::ParsePlaylists(const char* pszPlaylist)
{
memset(g_pMapVPKCache, '\0', 0x40); // Clear VPK cache to prevent crash while loading playlist.
@ -1294,7 +1293,7 @@ bool KeyValues::LoadPlaylist(const char* szPlaylist)
if (FileExists(sPlaylistPath))
{
std::uint8_t verifyPlaylistIntegrity[] = // Very hacky way for alternative inline assembly for x64..
uint8_t verifyPlaylistIntegrity[] = // Very hacky way for alternative inline assembly for x64..
{
0x48, 0x8B, 0x45, 0x58, // mov rcx, playlist
0xC7, 0x00, 0x00, 0x00, 0x00, // test playlist, playlist
@ -1302,11 +1301,11 @@ bool KeyValues::LoadPlaylist(const char* szPlaylist)
};
void* verifyPlaylistIntegrityFn = nullptr;
VirtualAlloc(verifyPlaylistIntegrity, 10, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
memcpy(&verifyPlaylistIntegrityFn, (const void*)verifyPlaylistIntegrity, 9);
memcpy(&verifyPlaylistIntegrityFn, reinterpret_cast<const void*>(verifyPlaylistIntegrity), 9);
reinterpret_cast<void(*)()>(verifyPlaylistIntegrityFn)();
}
return KeyValues_LoadPlaylist(szPlaylist); // Parse playlist.
return KeyValues_ParsePlaylists(pszPlaylist); // Parse playlist.
}
//-----------------------------------------------------------------------------
@ -1317,10 +1316,10 @@ bool KeyValues::LoadPlaylist(const char* szPlaylist)
//-----------------------------------------------------------------------------
KeyValues* KeyValues::ReadKeyValuesFile(CFileSystem_Stdio* pFileSystem, const char* pFileName)
{
static bool bInit{};
if (!bInit)
static bool bInitFileSystem{};
if (!bInitFileSystem)
{
bInit = true;
bInitFileSystem = true;
KeyValues::InitFileSystem();
}
return KeyValues_ReadKeyValuesFile(pFileSystem, pFileName);
@ -1329,13 +1328,15 @@ KeyValues* KeyValues::ReadKeyValuesFile(CFileSystem_Stdio* pFileSystem, const ch
///////////////////////////////////////////////////////////////////////////////
void CKeyValueSystem_Attach()
{
DetourAttach((LPVOID*)&KeyValues_LoadPlaylist, &KeyValues::LoadPlaylist);
DetourAttach((LPVOID*)&KeyValues_LoadPlaylists, &KeyValues::LoadPlaylists);
DetourAttach((LPVOID*)&KeyValues_ParsePlaylists, &KeyValues::ParsePlaylists);
DetourAttach((LPVOID*)&KeyValues_ReadKeyValuesFile, &KeyValues::ReadKeyValuesFile);
}
void CKeyValueSystem_Detach()
{
DetourDetach((LPVOID*)&KeyValues_LoadPlaylist, &KeyValues::LoadPlaylist);
DetourDetach((LPVOID*)&KeyValues_LoadPlaylists, &KeyValues::LoadPlaylists);
DetourDetach((LPVOID*)&KeyValues_ParsePlaylists, &KeyValues::ParsePlaylists);
DetourDetach((LPVOID*)&KeyValues_ReadKeyValuesFile, &KeyValues::ReadKeyValuesFile);
}

View File

@ -20,8 +20,11 @@ inline auto KeyValues_Init = p_KeyValues_Init.RCast<void* (*)(KeyValues* thisptr
inline CMemory p_KeyValues_FindKey;
inline auto KeyValues_FindKey = p_KeyValues_FindKey.RCast<void* (*)(KeyValues* thisptr, const char* pkeyName, bool bCreate)>();
inline CMemory p_KeyValues_LoadPlaylist;
inline auto KeyValues_LoadPlaylist = p_KeyValues_LoadPlaylist.RCast<bool (*)(const char* pszPlaylist)>();
inline CMemory p_KeyValues_LoadPlaylists;
inline auto KeyValues_LoadPlaylists = p_KeyValues_LoadPlaylists.RCast<bool (*)(const char* pszPlaylist)>();
inline CMemory p_KeyValues_ParsePlaylists;
inline auto KeyValues_ParsePlaylists = p_KeyValues_ParsePlaylists.RCast<bool (*)(const char* pszPlaylist)>();
inline CMemory p_KeyValues_GetCurrentPlaylist;
inline auto KeyValues_GetCurrentPlaylist = p_KeyValues_GetCurrentPlaylist.RCast<const char* (*)(void)>();
@ -137,10 +140,10 @@ public:
KeyValues* MakeCopy(void) const;
// Initialization
static void Setup(void);
static void InitPlaylists(void);
static void InitFileSystem(void);
static bool LoadPlaylist(const char* szPlaylist);
static bool LoadPlaylists(const char* szPlaylist);
static bool ParsePlaylists(const char* szPlaylist);
static KeyValues* ReadKeyValuesFile(CFileSystem_Stdio* pFileSystem, const char* pFileName);
public:
@ -178,7 +181,8 @@ class VKeyValues : public IDetour
{
spdlog::debug("| FUN: KeyValues::Init : {:#18x} |\n", p_KeyValues_Init.GetPtr());
spdlog::debug("| FUN: KeyValues::FindKey : {:#18x} |\n", p_KeyValues_FindKey.GetPtr());
spdlog::debug("| FUN: KeyValues::LoadPlaylist : {:#18x} |\n", p_KeyValues_LoadPlaylist.GetPtr());
spdlog::debug("| FUN: KeyValues::LoadPlaylists : {:#18x} |\n", p_KeyValues_LoadPlaylists.GetPtr());
spdlog::debug("| FUN: KeyValues::ParsePlaylists : {:#18x} |\n", p_KeyValues_ParsePlaylists.GetPtr());
spdlog::debug("| FUN: KeyValues::GetCurrentPlaylist : {:#18x} |\n", p_KeyValues_GetCurrentPlaylist.GetPtr());
spdlog::debug("| FUN: KeyValues::ReadKeyValuesFile : {:#18x} |\n", p_KeyValues_ReadKeyValuesFile.GetPtr());
spdlog::debug("| VAR: g_pPlaylistKeyValues : {:#18x} |\n", reinterpret_cast<uintptr_t>(g_pPlaylistKeyValues));
@ -197,11 +201,13 @@ class VKeyValues : public IDetour
p_KeyValues_GetCurrentPlaylist = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x48\x8B\x05\x00\x00\x00\x00\x48\x85\xC0\x75\x08\x48\x8D\x05\x00\x00\x00\x00\xC3\x0F\xB7\x50\x2A"), "xxx????xxxxxxxx????xxxxx");
p_KeyValues_ReadKeyValuesFile = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x48\x8B\xC4\x55\x53\x57\x41\x54\x48\x8D\x68\xA1"), "xxxxxxxxxxxx");
#endif
p_KeyValues_LoadPlaylist = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\xE8\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x74\x0C"), "x????xx?????xx").FollowNearCallSelf().GetPtr();
p_KeyValues_LoadPlaylists = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\x48\x89\x5C\x24\x00\x48\x89\x6C\x24\x00\x56\x57\x41\x56\x48\x83\xEC\x40\x48\x8B\xF1"), "xxxx?xxxx?xxxxxxxxxxx");
p_KeyValues_ParsePlaylists = g_mGameDll.FindPatternSIMD(reinterpret_cast<rsig_t>("\xE8\x00\x00\x00\x00\x80\x3D\x00\x00\x00\x00\x00\x74\x0C"), "x????xx?????xx").FollowNearCallSelf();
KeyValues_Init = p_KeyValues_Init.RCast<void* (*)(KeyValues*, const char*, int64_t, bool)>(); /*40 53 48 83 EC 20 48 8B 05 ?? ?? ?? 01 48 8B D9 4C 8B C2*/
KeyValues_FindKey = p_KeyValues_FindKey.RCast<void* (*)(KeyValues*, const char*, bool)>(); /*40 56 57 41 57 48 81 EC 30 01 00 00 45 0F B6 F8*/
KeyValues_LoadPlaylist = p_KeyValues_LoadPlaylist.RCast<bool (*)(const char*)>(); /*E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 0C*/
KeyValues_LoadPlaylists = p_KeyValues_ParsePlaylists.RCast<bool (*)(const char*)>(); /*48 89 5C 24 ?? 48 89 6C 24 ?? 56 57 41 56 48 83 EC 40 48 8B F1*/
KeyValues_ParsePlaylists = p_KeyValues_ParsePlaylists.RCast<bool (*)(const char*)>(); /*E8 ?? ?? ?? ?? 80 3D ?? ?? ?? ?? ?? 74 0C*/
KeyValues_GetCurrentPlaylist = p_KeyValues_GetCurrentPlaylist.RCast<const char* (*)(void)>(); /*48 8B 05 ?? ?? ?? ?? 48 85 C0 75 08 48 8D 05 ?? ?? ?? ?? C3 0F B7 50 2A*/
KeyValues_ReadKeyValuesFile = p_KeyValues_ReadKeyValuesFile.RCast<KeyValues* (*)(CFileSystem_Stdio*, const char*)>(); /*48 8B C4 55 53 57 41 54 48 8D 68 A1*/
}