From 56a71aba568758a1f6fc732945a5889136c7c7a6 Mon Sep 17 00:00:00 2001
From: PixieCore <41352111+PixieCore@users.noreply.github.com>
Date: Mon, 28 Mar 2022 18:47:11 +0200
Subject: [PATCH] A few RTech changes.

* Renamed pak_asyncload to pak_requestload
* Added new ConCommand to unload rpaks. It's called pak_requestunload.
* When CHostState requests an rpak unload, it will now print the name of it.
* Turned a few static addresses onto patternscans.
---
 r5dev/engine/host_state.cpp    |  10 ++-
 r5dev/public/include/memaddr.h |   2 +-
 r5dev/rtech/rtech_game.cpp     |   2 +-
 r5dev/rtech/rtech_game.h       |   4 +-
 r5dev/rtech/rtech_utils.cpp    |  22 +++++-
 r5dev/rtech/rtech_utils.h      |  12 ++--
 r5dev/tier0/cmd.cpp            |  26 +++++--
 r5dev/tier0/cmd.h              |   2 +
 r5dev/tier0/completion.cpp     | 125 ++++++++++++++++-----------------
 r5dev/tier0/completion.h       |   9 +--
 10 files changed, 130 insertions(+), 84 deletions(-)

diff --git a/r5dev/engine/host_state.cpp b/r5dev/engine/host_state.cpp
index c251c1ea..77c1117b 100644
--- a/r5dev/engine/host_state.cpp
+++ b/r5dev/engine/host_state.cpp
@@ -27,6 +27,7 @@
 #include "engine/baseserver.h"
 #endif // !CLIENT_DLL
 #include "rtech/rtech_game.h"
+#include "rtech/rtech_utils.h"
 #ifndef DEDICATED
 #include "vgui/vgui_baseui_interface.h"
 #endif // DEDICATED
@@ -284,8 +285,15 @@ FORCEINLINE void CHostState::UnloadPakFile(void)
 {
 	for (auto& it : g_nLoadedPakFileId)
 	{
-		if (it >= 0) // [ PIXIE ] TODO: Create RTech function to get RPakLoadedInfo by ID and print which rpak is getting unloaded.
+		if (it >= 0)
 		{
+#ifdef GAMEDLL_S3
+			RPakLoadedInfo_t pakInfo = g_pRTech->GetPakLoadedInfo(it);
+			if (pakInfo.m_pszFileName)
+			{
+				DevMsg(eDLL_T::RTECH, "Unloading PakFile '%s' now.", pakInfo.m_pszFileName);
+			}
+#endif // GAMEDLL_S3
 			RTech_UnloadPak(it);
 		}
 	}
diff --git a/r5dev/public/include/memaddr.h b/r5dev/public/include/memaddr.h
index 74dcd386..87d9f182 100644
--- a/r5dev/public/include/memaddr.h
+++ b/r5dev/public/include/memaddr.h
@@ -458,7 +458,7 @@ public:
 		return ADDRESS(latestOccurence);
 	}
 
-	ADDRESS FindPatternSIMD(uint8_t* szPattern, const char* szMask)
+	ADDRESS FindPatternSIMD(std::uint8_t* szPattern, const char* szMask)
 	{
 		ModuleSections mInfo = GetSectionByName(".text"); // Get the .text section.
 		if (!mInfo.IsSectionValid())
diff --git a/r5dev/rtech/rtech_game.cpp b/r5dev/rtech/rtech_game.cpp
index 346f577c..c580aba0 100644
--- a/r5dev/rtech/rtech_game.cpp
+++ b/r5dev/rtech/rtech_game.cpp
@@ -35,7 +35,7 @@ void HRTech_UnloadAsset(std::int64_t a1, std::int64_t a2) // This ain't related
 //-----------------------------------------------------------------------------
 // Purpose: load user-requested pak files on-demand
 //-----------------------------------------------------------------------------
-void HRtech_AsyncLoad(std::string svPakFileName)
+void HRTech_AsyncLoad(std::string svPakFileName)
 {
 	std::string svPakFilePathMod = "paks\\Win32\\" + svPakFileName;
 	std::string svPakFilePathBase = "paks\\Win64\\" + svPakFileName;
diff --git a/r5dev/rtech/rtech_game.h b/r5dev/rtech/rtech_game.h
index 6fd2d87e..2422d706 100644
--- a/r5dev/rtech/rtech_game.h
+++ b/r5dev/rtech/rtech_game.h
@@ -33,7 +33,7 @@ namespace
 	ADDRESS p_RTech_UnloadAsset = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x83\xEC\x28\x48\x85\xD2\x74\x40\x48\x8B\x05\x00\x00\x00\x00", "xxxxxxxxxxxx????");
 	void (*RTech_UnloadAsset)(std::int64_t a1, std::int64_t a2) = (void (*)(std::int64_t, std::int64_t))p_RTech_UnloadAsset.GetPtr(); /*48 83 EC 28 48 85 D2 74 40 48 8B 05 ? ? ? ?*/
 
-		ADDRESS p_RTech_LoadPak = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x4C\x24\x00\x56\x41\x55", "xxxx?xxx"); /*48 89 4C 24 ? 56 41 55*/
+	ADDRESS p_RTech_LoadPak = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x4C\x24\x00\x56\x41\x55", "xxxx?xxx"); /*48 89 4C 24 ? 56 41 55*/
 	unsigned int (*RTech_LoadPak)(void* thisptr, void* a2, std::uint64_t a3) = (unsigned int (*)(void*, void*, std::uint64_t))p_RTech_LoadPak.GetPtr();
 
 	ADDRESS p_RTech_LoadMapPak = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x81\xEC\x00\x00\x00\x00\x0F\xB6\x05\x00\x00\x00\x00\x4C\x8D\x05\x00\x00\x00\x00\x84\xC0", "xxx????xxx????xxx????xx");
@@ -53,7 +53,7 @@ namespace
 	void* (*RTech_UnloadPak)(int nPakId) = (void* (*)(int nPakId))p_RTech_UnloadPak.GetPtr();/*48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 8B C1*/
 }
 void HRTech_UnloadAsset(std::int64_t a1, std::int64_t a2);
-void HRtech_AsyncLoad(std::string svPakFileName);
+void HRTech_AsyncLoad(std::string svPakFileName);
 
 void RTech_Game_Attach();
 void RTech_Game_Detach();
diff --git a/r5dev/rtech/rtech_utils.cpp b/r5dev/rtech/rtech_utils.cpp
index d56b3ffd..fcc0c675 100644
--- a/r5dev/rtech/rtech_utils.cpp
+++ b/r5dev/rtech/rtech_utils.cpp
@@ -14,6 +14,7 @@ History:
 - 10:09:2021 | 18:22 : Implement 'StringToGuid' method
 - 12:11:2021 | 14:41 : Add decompression method to ConCommand callback
 - 25:12:2021 | 23:20 : Made everything more readable thanks to bezdna5-rs
+- 28:03:2021 | 18:00 : Added getting pak info by PakID.
 
 ******************************************************************************/
 
@@ -495,5 +496,24 @@ std::uint8_t __fastcall RTech::DecompressPakFile(RPakDecompState_t* state, std::
 
 	return result;
 }
+
+RPakLoadedInfo_t RTech::GetPakLoadedInfo(int nPakId)
+{
+#ifdef GAMEDLL_S3
+	for (int i = 0; i < *s_pLoadedPakCount; ++i)
+	{
+		RPakLoadedInfo_t info = g_pLoadedPakInfo[i];
+
+		if (info.m_nPakId != nPakId)
+			continue;
+
+		return info;
+	}
+
+	Warning(eDLL_T::RTECH, "Failed getting RPakLoadInfo_t for PakId '%d'", nPakId);
+#endif // GAMEDLL_S3
+
+	return RPakLoadedInfo_t();
+}
 ///////////////////////////////////////////////////////////////////////////////
-RTech* g_pRtech = new RTech();
+RTech* g_pRTech = new RTech();
diff --git a/r5dev/rtech/rtech_utils.h b/r5dev/rtech/rtech_utils.h
index 9bf1b083..4ab8c297 100644
--- a/r5dev/rtech/rtech_utils.h
+++ b/r5dev/rtech/rtech_utils.h
@@ -165,11 +165,12 @@ public:
 namespace
 {
 	/* ==== RTECH =========================================================================================================================================================== */
-	//DWORD64 p_RTech_Decompress = FindPatternV2("r5apex.exe", (const unsigned char*)"\x4C\x89\x44\x24\x18\x48\x89\x54\x24\x10\x53\x48\x83\xEC\x50\x48", "xxxxxxxxxxxxxxxx");
-	//char (*RTech_Decompress)(int64_t* parameter, std::uint64_t input, std::uint64_t output) = (char (*)(std::int64_t*, std::uint64_t, std::uint64_t))p_RTech_Decompress; /*4C 89 44 24 18 48 89 54 24 10 53 48 83 EC 50 48*/
+#ifdef GAMEDLL_S3
+	ADDRESS UnloadRoutine = g_mGameDll.FindPatternSIMD((std::uint8_t*)"\x48\x89\x5C\x24\x00\x48\x89\x74\x24\x00\x57\x48\x83\xEC\x30\x8B\xC1", "xxxx?xxxx?xxxxxxx"); /*48 89 5C 24 ? 48 89 74 24 ? 57 48 83 EC 30 8B C1*/
 
-	//DWORD64 p_RTech_DecompressedSize = FindPatternV2("r5apex.exe", (const unsigned char*)"\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x18\x48\x89\x74\x24\x20\x48\x89\x54\x24\x10\x57\x41\x54\x41\x55\x41\x56\x41\x57\x4C\x8B\x74", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
-	//std::int64_t (*RTech_DecompressedSize)(std::int64_t parameter, std::uint8_t* input, std::int64_t magic, std::int64_t a4, std::int64_t a5) = (std::int64_t (*)(std::int64_t, std::uint8_t*, std::int64_t, std::int64_t, std::int64_t))p_RTech_DecompressedSize; /*48 89 5C 24 08 48 89 6C 24 18 48 89 74 24 20 48 89 54 24 10 57 41 54 41 55 41 56 41 57 4C 8B 74*/
+	RPakLoadedInfo_t* g_pLoadedPakInfo = UnloadRoutine.FindPatternSelf("48 8D 05", ADDRESS::Direction::DOWN).ResolveRelativeAddressSelf(0x3, 0x7).RCast<RPakLoadedInfo_t*>();
+	std::int16_t* s_pLoadedPakCount = UnloadRoutine.FindPatternSelf("66 89", ADDRESS::Direction::DOWN, 450).ResolveRelativeAddressSelf(0x3, 0x7).RCast<std::int16_t*>();
+#endif // GAMEDLL_S3
 }
 
 class RTech
@@ -178,7 +179,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);
 };
 
 ///////////////////////////////////////////////////////////////////////////////
-extern RTech* g_pRtech;
+extern RTech* g_pRTech;
diff --git a/r5dev/tier0/cmd.cpp b/r5dev/tier0/cmd.cpp
index 66503408..1355e2bf 100644
--- a/r5dev/tier0/cmd.cpp
+++ b/r5dev/tier0/cmd.cpp
@@ -69,6 +69,23 @@ const char* CCommand::operator[](int nIndex) const
 	return Arg(nIndex);
 }
 
+//-----------------------------------------------------------------------------
+// Purpose: return boolean depending on if the string only has digits in it
+// Input  : svString - 
+//-----------------------------------------------------------------------------
+bool CCommand::HasOnlyDigits(int nIndex) const
+{
+	std::string svString = Arg(nIndex);
+	for (const char& character : svString)
+	{
+		if (std::isdigit(character) == 0)
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
 //-----------------------------------------------------------------------------
 // Purpose: construct/allocate
 //-----------------------------------------------------------------------------
@@ -122,10 +139,11 @@ void ConCommand::Init(void)
 	ConCommand* fs_decompress_pak = new ConCommand("fs_decompress_pak", "Decompresses user specified 'vpk_dir' file.", FCVAR_DEVELOPMENTONLY, _VPK_Decompress_f_CompletionFunc, nullptr);
 	//-------------------------------------------------------------------------
 	// RTECH API                                                              |
-	ConCommand* rtech_strtoguid  = new ConCommand("rtech_strtoguid", "Calculates the GUID from input data.", FCVAR_DEVELOPMENTONLY, _RTech_StringToGUID_f_CompletionFunc, nullptr);
-	ConCommand* pak_asyncload    = new ConCommand("pak_asyncload", "Loads the specified RPAK file asynchronously.", FCVAR_DEVELOPMENTONLY, _RTech_AsyncLoad_f_CompletionFunc, nullptr);
-	ConCommand* pak_decompress   = new ConCommand("pak_decompress", "Decompresses the specified RPAK file.", FCVAR_DEVELOPMENTONLY, _RTech_Decompress_f_CompletionFunc, nullptr);
-	ConCommand* pak_listpaks     = new ConCommand("pak_listpaks", "Display a list of the loaded Pak files.", FCVAR_DEVELOPMENTONLY, _Pak_ListPaks_f_CompletionFunc, nullptr);
+	ConCommand* rtech_strtoguid   = new ConCommand("rtech_strtoguid", "Calculates the GUID from input data.", FCVAR_DEVELOPMENTONLY, _RTech_StringToGUID_f_CompletionFunc, nullptr);
+	ConCommand* pak_requestload   = new ConCommand("pak_requestload", "Requests asynchronous load for specified RPAK FILE.", FCVAR_DEVELOPMENTONLY, _Pak_RequestLoad_f_CompletionFunc, nullptr);
+	ConCommand* pak_requestunload = new ConCommand("pak_requestunload", "Requests unload for specified RPAK ID.", FCVAR_DEVELOPMENTONLY, _Pak_RequestUnload_f_CompletionFunc, nullptr);
+	ConCommand* pak_decompress    = new ConCommand("pak_decompress", "Decompresses the specified RPAK file.", FCVAR_DEVELOPMENTONLY, _RTech_Decompress_f_CompletionFunc, nullptr);
+	ConCommand* pak_listpaks      = new ConCommand("pak_listpaks", "Display a list of the loaded Pak files.", FCVAR_DEVELOPMENTONLY, _Pak_ListPaks_f_CompletionFunc, nullptr);
 	//-------------------------------------------------------------------------
 	// NETCHANNEL                                                             |
 	ConCommand* net_toggletrace = new ConCommand("net_toggletrace", "Logs the sending and receiving datagram to a file on the disk.", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY, _NET_TraceNetChan_f_CompletionFunc, nullptr);
diff --git a/r5dev/tier0/cmd.h b/r5dev/tier0/cmd.h
index 6cbaa441..c00fb4eb 100644
--- a/r5dev/tier0/cmd.h
+++ b/r5dev/tier0/cmd.h
@@ -66,6 +66,8 @@ public:
 	const char* Arg(int nIndex) const;
 	const char* operator[](int nIndex) const;
 
+	bool HasOnlyDigits(int nIndex) const;
+
 private:
 	int          m_nQueuedVal;
 	int          m_nArgc;
diff --git a/r5dev/tier0/completion.cpp b/r5dev/tier0/completion.cpp
index 7c70998d..cc77b537 100644
--- a/r5dev/tier0/completion.cpp
+++ b/r5dev/tier0/completion.cpp
@@ -45,7 +45,7 @@ void _CGameConsole_f_CompletionFunc(const CCommand& args)
 _CCompanion_f_CompletionFunc
 =====================
 */
-void _CCompanion_f_CompletionFunc(const CCommand& cmd)
+void _CCompanion_f_CompletionFunc(const CCommand& args)
 {
 	g_pIBrowser->m_bActivate = !g_pIBrowser->m_bActivate;
 }
@@ -100,18 +100,6 @@ _KickID_f_CompletionFunc
 */
 void _KickID_f_CompletionFunc(const CCommand& args)
 {
-	static auto HasOnlyDigits = [](const std::string& string)
-	{
-		for (const char& character : string)
-		{
-			if (std::isdigit(character) == 0)
-			{
-				return false;
-			}
-		}
-		return true;
-	};
-
 	if (args.ArgC() < 2) // Do we atleast have 2 arguments?
 	{
 		return;
@@ -119,7 +107,7 @@ void _KickID_f_CompletionFunc(const CCommand& args)
 
 	try
 	{
-		bool onlyDigits = HasOnlyDigits(args.Arg(1));
+		bool onlyDigits = args.HasOnlyDigits(1);
 		for (int i = 0; i < MAX_PLAYERS; i++)
 		{
 			CBaseClient* client = g_pClient->GetClient(i);
@@ -250,18 +238,6 @@ _BanID_f_CompletionFunc
 */
 void _BanID_f_CompletionFunc(const CCommand& args)
 {
-	static auto HasOnlyDigits = [](const std::string& string)
-	{
-		for (const char& character : string)
-		{
-			if (std::isdigit(character) == 0)
-			{
-				return false;
-			}
-		}
-		return true;
-	};
-
 	if (args.ArgC() < 2)
 	{
 		return;
@@ -269,7 +245,7 @@ void _BanID_f_CompletionFunc(const CCommand& args)
 
 	try
 	{
-		bool onlyDigits = HasOnlyDigits(args.Arg(1));
+		bool onlyDigits = args.HasOnlyDigits(1);
 		for (int i = 0; i < MAX_PLAYERS; i++)
 		{
 			CBaseClient* client = g_pClient->GetClient(i);
@@ -347,18 +323,6 @@ _Unban_f_CompletionFunc
 */
 void _Unban_f_CompletionFunc(const CCommand& args)
 {
-	static auto HasOnlyDigits = [](const std::string& string)
-	{
-		for (const char& character : string)
-		{
-			if (std::isdigit(character) == 0)
-			{
-				return false;
-			}
-		}
-		return true;
-	};
-
 	if (args.ArgC() < 2)
 	{
 		return;
@@ -366,7 +330,7 @@ void _Unban_f_CompletionFunc(const CCommand& args)
 
 	try
 	{
-		if (HasOnlyDigits(args.Arg(1))) // Check if we have an ip address or origin ID.
+		if (args.HasOnlyDigits(1)) // Check if we have an ip address or origin ID.
 		{
 			g_pBanSystem->DeleteEntry("noIP", std::stoll(args.Arg(1))); // Delete ban entry.
 			g_pBanSystem->Save(); // Save modified vector to file.
@@ -399,15 +363,11 @@ void _ReloadBanList_f_CompletionFunc(const CCommand& args)
  _Pak_ListPaks_f_CompletionFunc
 =====================
 */
-void _Pak_ListPaks_f_CompletionFunc(const CCommand& cmd)
+void _Pak_ListPaks_f_CompletionFunc(const CCommand& args)
 {
 #ifdef GAMEDLL_S3
-	// [ PIXIE ]: TODO pattern scan these.
-	static std::int16_t* s_pLoadedPakCount = ADDRESS(0x167ED7C6C).RCast<std::int16_t*>();
-	static RPakLoadedInfo_t* g_pLoadedPakInfo = ADDRESS(0x167D40B70).RCast<RPakLoadedInfo_t*>();
-
-	DevMsg(eDLL_T::RTECH, "| id | name                             | status                               | asset count |\n");
-	DevMsg(eDLL_T::RTECH, "|----|----------------------------------|--------------------------------------|-------------|\n");
+	DevMsg(eDLL_T::RTECH, "| id | name                                               | status                               | asset count |\n");
+	DevMsg(eDLL_T::RTECH, "|----|----------------------------------------------------|--------------------------------------|-------------|\n");
 
 	std::uint32_t nActuallyLoaded = 0;
 
@@ -425,13 +385,58 @@ void _Pak_ListPaks_f_CompletionFunc(const CCommand& cmd)
 			rpakStatus = it->second;
 
 		// todo: make status into a string from an array/vector
-		DevMsg(eDLL_T::RTECH, "| %02i | %-32s | %-36s | %11i |\n", info.m_nPakId, info.m_pszFileName, rpakStatus.c_str(), info.m_nAssetCount);
+		DevMsg(eDLL_T::RTECH, "| %02i | %-50s | %-36s | %11i |\n", info.m_nPakId, info.m_pszFileName, rpakStatus.c_str(), info.m_nAssetCount);
 		nActuallyLoaded++;
 	}
-	DevMsg(eDLL_T::RTECH, "|----|----------------------------------|--------------------------------------|-------------|\n");
-	DevMsg(eDLL_T::RTECH, "| %16i loaded paks.                                                              |\n", nActuallyLoaded);
-	DevMsg(eDLL_T::RTECH, "|----|----------------------------------|--------------------------------------|-------------|\n");
-#endif
+	DevMsg(eDLL_T::RTECH, "|----|----------------------------------------------------|--------------------------------------|-------------|\n");
+	DevMsg(eDLL_T::RTECH, "| %16i loaded paks.                                                                                |\n", nActuallyLoaded);
+	DevMsg(eDLL_T::RTECH, "|----|----------------------------------------------------|--------------------------------------|-------------|\n");
+#endif // GAMEDLL_S3
+}
+
+/*
+=====================
+ _Pak_RequestUnload_f_CompletionFunc
+=====================
+*/
+void _Pak_RequestUnload_f_CompletionFunc(const CCommand& args)
+{
+#ifdef GAMEDLL_S3
+	if (args.ArgC() < 2)
+	{
+		return;
+	}
+
+	try
+	{
+		if (args.HasOnlyDigits(1))
+		{
+			int 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);
+			RTech_UnloadPak(nPakId);
+		}
+		else
+		{
+			throw std::exception("Please provide a number as an arg.");
+		}
+	}
+	catch (std::exception& e)
+	{
+		Error(eDLL_T::RTECH, "RequestUnload Error: %s", e.what());
+		return;
+	}
+#endif // GAMEDLL_S3
+}
+
+/*
+=====================
+_Pak_RequestLoad_f_CompletionFunc
+=====================
+*/
+void _Pak_RequestLoad_f_CompletionFunc(const CCommand& args)
+{
+	HRTech_AsyncLoad(args.Arg(1));
 }
 
 /*
@@ -446,23 +451,13 @@ void _RTech_StringToGUID_f_CompletionFunc(const CCommand& args)
 		return;
 	}
 
-	unsigned long long guid = g_pRtech->StringToGuid(args.Arg(1));
+	unsigned long long guid = g_pRTech->StringToGuid(args.Arg(1));
 
 	DevMsg(eDLL_T::RTECH, "______________________________________________________________\n");
 	DevMsg(eDLL_T::RTECH, "] RTECH_HASH -------------------------------------------------\n");
 	DevMsg(eDLL_T::RTECH, "] GUID: '0x%llX'\n", guid);
 }
 
-/*
-=====================
-_RTech_AsyncLoad_f_CompletionFunc
-=====================
-*/
-void _RTech_AsyncLoad_f_CompletionFunc(const CCommand& args)
-{
-	HRtech_AsyncLoad(args.Arg(1));
-}
-
 /*
 =====================
 _RTech_Decompress_f_CompletionFunc
@@ -538,7 +533,7 @@ void _RTech_Decompress_f_CompletionFunc(const CCommand& args)
 	}
 
 	RPakDecompState_t state;
-	std::uint32_t decompSize = g_pRtech->DecompressPakFileInit(&state, upak.data(), upak.size(), 0, PAK_HEADER_SIZE);
+	std::uint32_t decompSize = g_pRTech->DecompressPakFileInit(&state, upak.data(), upak.size(), 0, PAK_HEADER_SIZE);
 
 	if (decompSize == rheader->m_nSizeDisk)
 	{
@@ -555,7 +550,7 @@ void _RTech_Decompress_f_CompletionFunc(const CCommand& args)
 	state.m_nOutMask = UINT64_MAX;
 	state.m_nOut = uint64_t(pakBuf.data());
 
-	std::uint8_t decompResult = g_pRtech->DecompressPakFile(&state, upak.size(), pakBuf.size());
+	std::uint8_t decompResult = g_pRTech->DecompressPakFile(&state, upak.size(), pakBuf.size());
 	if (decompResult != 1)
 	{
 		Error(eDLL_T::RTECH, "Error: decompression failed for '%s' return value: '%u'!\n", pakNameIn.c_str(), +decompResult);
diff --git a/r5dev/tier0/completion.h b/r5dev/tier0/completion.h
index ddc494f6..9e004736 100644
--- a/r5dev/tier0/completion.h
+++ b/r5dev/tier0/completion.h
@@ -17,8 +17,8 @@ namespace
 
 ///////////////////////////////////////////////////////////////////////////////
 #ifndef DEDICATED
-void _CGameConsole_f_CompletionFunc(const CCommand& cmd);
-void _CCompanion_f_CompletionFunc(const CCommand& cmd);
+void _CGameConsole_f_CompletionFunc(const CCommand& args);
+void _CCompanion_f_CompletionFunc(const CCommand& args);
 #endif // !DEDICATED
 void _Kick_f_CompletionFunc(const CCommand& args);
 void _KickID_f_CompletionFunc(const CCommand& args);
@@ -26,9 +26,10 @@ void _Ban_f_CompletionFunc(const CCommand& args);
 void _BanID_f_CompletionFunc(const CCommand& args);
 void _Unban_f_CompletionFunc(const CCommand& args);
 void _ReloadBanList_f_CompletionFunc(const CCommand& args);
-void _Pak_ListPaks_f_CompletionFunc(const CCommand& cmd);
+void _Pak_ListPaks_f_CompletionFunc(const CCommand& args);
+void _Pak_RequestUnload_f_CompletionFunc(const CCommand& args);
+void _Pak_RequestLoad_f_CompletionFunc(const CCommand& args);
 void _RTech_StringToGUID_f_CompletionFunc(const CCommand& args);
-void _RTech_AsyncLoad_f_CompletionFunc(const CCommand& args);
 void _RTech_Decompress_f_CompletionFunc(const CCommand& args);
 void _VPK_Decompress_f_CompletionFunc(const CCommand& args);
 void _NET_TraceNetChan_f_CompletionFunc(const CCommand& args);