1
0
mirror of https://github.com/Mauler125/r5sdk.git synced 2025-02-09 19:15:03 +01:00

Implementation for rpak swap. Read description.

* RTech::GetPakLoadedInfo returns a reference now instead of a copy. Make sure to check the pointer is valid from now on if dealing with the returned pak entry.
* RTech::GetPakLoadedInfo now has a overloaded function that takes string as argument for searching an pak entry.
* new ConCommand pak_swap which has Pak_Swap_f as callback.
* Pak_Swap_f performs pak unload and then load again.
* pak_requestunload can now be used with pak name
This commit is contained in:
PixieCore 2022-05-19 00:47:16 +02:00
parent 6bd1643dfb
commit 5655b8c759
6 changed files with 116 additions and 16 deletions

@ -69,14 +69,17 @@ RPakHandle_t CPakFile::AsyncLoad(const char* szPakFileName, uintptr_t pMalloc, i
//-----------------------------------------------------------------------------
void CPakFile::Unload(RPakHandle_t handle)
{
RPakLoadedInfo_t pakInfo = g_pRTech->GetPakLoadedInfo(handle);
RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(handle);
if (pakInfo.m_pszFileName)
if (pakInfo)
{
DevMsg(eDLL_T::RTECH, "Unloading pak file: '%s'\n", pakInfo.m_pszFileName);
if (pakInfo->m_pszFileName)
{
DevMsg(eDLL_T::RTECH, "Unloading pak file: '%s'\n", pakInfo->m_pszFileName);
if (strcmp(pakInfo.m_pszFileName, "mp_lobby.rpak") == 0)
s_bBasePaksInitialized = false;
if (strcmp(pakInfo->m_pszFileName, "mp_lobby.rpak") == 0)
s_bBasePaksInitialized = false;
}
}
CPakFile_Unload(handle);

@ -498,22 +498,48 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std::
}
//-----------------------------------------------------------------------------
// Purpose: gets information about loaded pak file
// Purpose: gets copied information about loaded pak file via pak ID
//-----------------------------------------------------------------------------
RPakLoadedInfo_t RTech::GetPakLoadedInfo(int nPakId)
RPakLoadedInfo_t* RTech::GetPakLoadedInfo(int nPakId)
{
for (int i = 0; i < *s_pLoadedPakCount; ++i)
{
RPakLoadedInfo_t info = g_pLoadedPakInfo[i];
RPakLoadedInfo_t* info = &g_pLoadedPakInfo[i];
if (!info)
continue;
if (info.m_nPakId != nPakId)
if (info->m_nPakId != nPakId)
continue;
return info;
}
Warning(eDLL_T::RTECH, "%s - Failed getting RPakLoadInfo_t for PakId '%d'\n", __FUNCTION__, nPakId);
return RPakLoadedInfo_t();
return nullptr;
}
//-----------------------------------------------------------------------------
// Purpose: gets copied information about loaded pak file via pak name
//-----------------------------------------------------------------------------
RPakLoadedInfo_t* RTech::GetPakLoadedInfo(const char* szPakName)
{
for (int i = 0; i < *s_pLoadedPakCount; ++i)
{
RPakLoadedInfo_t* info = &g_pLoadedPakInfo[i];
if (!info)
continue;
if (!info->m_pszFileName || !*info->m_pszFileName)
continue;
if (strcmp(szPakName, info->m_pszFileName) != 0)
continue;
return info;
}
Warning(eDLL_T::RTECH, "%s - Failed getting RPakLoadInfo_t for Pak '%s'\n", __FUNCTION__, szPakName);
return nullptr;
}
///////////////////////////////////////////////////////////////////////////////
RTech* g_pRTech = new RTech();

@ -172,7 +172,8 @@ public:
std::uint64_t __fastcall StringToGuid(const char* pData);
std::uint8_t __fastcall DecompressPakFile(RPakDecompState_t* state, std::uint64_t inLen, std::uint64_t outLen);
std::uint32_t __fastcall DecompressPakFileInit(RPakDecompState_t* state, std::uint8_t* fileBuffer, std::int64_t fileSize, std::int64_t offNoHeader, std::int64_t headerSize);
RPakLoadedInfo_t GetPakLoadedInfo(int nPakId);
RPakLoadedInfo_t* GetPakLoadedInfo(int nPakId);
RPakLoadedInfo_t* GetPakLoadedInfo(const char* szPakName);
};

@ -154,7 +154,8 @@ void ConCommand::Init(void)
// RTECH API |
new ConCommand("rtech_strtoguid", "Calculates the GUID from input data.", FCVAR_DEVELOPMENTONLY, RTech_StringToGUID_f, nullptr);
new ConCommand("pak_requestload", "Requests asynchronous load for specified RPAK file.", FCVAR_DEVELOPMENTONLY, Pak_RequestLoad_f, nullptr);
new ConCommand("pak_requestunload", "Requests unload for specified RPAK by ID.", FCVAR_DEVELOPMENTONLY, Pak_RequestUnload_f, nullptr);
new ConCommand("pak_requestunload", "Requests unload for specified RPAK file or ID.", FCVAR_DEVELOPMENTONLY, Pak_RequestUnload_f, nullptr);
new ConCommand("pak_swap", "Requests dwap for specified RPAK file or ID", FCVAR_DEVELOPMENTONLY, Pak_Swap_f, nullptr);
new ConCommand("pak_decompress", "Decompresses the specified RPAK file.", FCVAR_DEVELOPMENTONLY, RTech_Decompress_f, nullptr);
new ConCommand("pak_listpaks", "Display a list of the loaded Pak files.", FCVAR_DEVELOPMENTONLY, Pak_ListPaks_f, nullptr);
//-------------------------------------------------------------------------

@ -378,18 +378,31 @@ void Pak_RequestUnload_f(const CCommand& args)
if (args.HasOnlyDigits(1))
{
RPakHandle_t nPakId = std::stoi(args.Arg(1));
RPakLoadedInfo_t pakInfo = g_pRTech->GetPakLoadedInfo(nPakId);
pakInfo.m_pszFileName ? DevMsg(eDLL_T::RTECH, "Requested Pak Unload for '%s'\n", pakInfo.m_pszFileName) : DevMsg(eDLL_T::RTECH, "Requested Pak Unload for '%d'\n", nPakId);
RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(nPakId);
if (!pakInfo)
{
throw std::exception("Found no Pak entry for specified ID.");
}
string pakName = pakInfo->m_pszFileName;
!pakName.empty() ? DevMsg(eDLL_T::RTECH, "Requested Pak Unload for '%s'\n", pakName.c_str()) : DevMsg(eDLL_T::RTECH, "Requested Pak Unload for '%d'\n", nPakId);
g_pakLoadApi->Unload(nPakId);
}
else
{
throw std::exception("Please provide a number as an arg.");
RPakLoadedInfo_t* pakInfo = g_pRTech->GetPakLoadedInfo(args.Arg(1));
if (!pakInfo)
{
throw std::exception("Found no Pak entry for specified name.");
}
DevMsg(eDLL_T::RTECH, "Requested Pak Unload for '%s'\n", args.Arg(1));
g_pakLoadApi->Unload(pakInfo->m_nPakId);
}
}
catch (std::exception& e)
{
Error(eDLL_T::RTECH, "RequestUnload Error: %s", e.what());
Error(eDLL_T::RTECH, "%s - %s", __FUNCTION__, e.what());
return;
}
#endif // GAMEDLL_S3
@ -405,6 +418,61 @@ void Pak_RequestLoad_f(const CCommand& args)
g_pakLoadApi->AsyncLoad(args.Arg(1));
}
/*
=====================
Pak_Swap_f
=====================
*/
void Pak_Swap_f(const CCommand& args)
{
#ifdef GAMEDLL_S3
try
{
RPakHandle_t nPakId = 0;
RPakLoadedInfo_t* pakInfo = nullptr;
string pakName = std::string();
if (args.HasOnlyDigits(1))
{
nPakId = std::stoi(args.Arg(1));
pakInfo = g_pRTech->GetPakLoadedInfo(nPakId);
if (!pakInfo)
{
throw std::exception("Found no Pak entry for specified ID.");
}
pakName = pakInfo->m_pszFileName;
}
else
{
pakName = args.Arg(1);
pakInfo = g_pRTech->GetPakLoadedInfo(args.Arg(1));
if (!pakInfo)
{
throw std::exception("Found no Pak entry for specified name.");
}
nPakId = pakInfo->m_nPakId;
}
!pakName.empty() ? DevMsg(eDLL_T::RTECH, "Requested Pak Swap for '%s'\n", pakName.c_str()) : DevMsg(eDLL_T::RTECH, "Requested Pak Swap for '%d'\n", nPakId);
g_pakLoadApi->Unload(nPakId);
while (pakInfo->m_nStatus != RPakStatus_t::PAK_STATUS_FREED) // Wait till this slot gets free'd.
std::this_thread::sleep_for(std::chrono::seconds(1));
g_pakLoadApi->AsyncLoad(pakName.c_str());
}
catch (std::exception& e)
{
Error(eDLL_T::RTECH, "%s - %s", __FUNCTION__, e.what());
return;
}
#endif// GAMEDLL_S3
}
/*
=====================
RTech_StringToGUID_f

@ -26,6 +26,7 @@ void Host_ReloadBanList_f(const CCommand& args);
void Pak_ListPaks_f(const CCommand& args);
void Pak_RequestUnload_f(const CCommand& args);
void Pak_RequestLoad_f(const CCommand& args);
void Pak_Swap_f(const CCommand& args);
void RTech_StringToGUID_f(const CCommand& args);
void RTech_Decompress_f(const CCommand& args);
void VPK_Unpack_f(const CCommand& args);