diff --git a/r5dev/include/gameclasses.h b/r5dev/include/gameclasses.h index 59d962ce..1197cee3 100644 --- a/r5dev/include/gameclasses.h +++ b/r5dev/include/gameclasses.h @@ -34,6 +34,8 @@ public: typedef int HKeySymbol; +#define MAKE_3_BYTES_FROM_1_AND_2( x1, x2 ) (( (( std::uint16_t )x2) << 8 ) | (std::uint8_t)(x1)) + class CKeyValuesSystem // VTABLE @ 0x1413AA1E8 in R5pc_r5launch_N1094_CL456479_2019_10_30_05_20_PM { public: @@ -140,11 +142,12 @@ public: KeyValues* FindKey(const char* keyName, bool bCreate) { - // static auto func = reinterpret_cast(p_KeyValues_FindKey); - // return func(this, keyName, bCreate); - return nullptr; + static auto func = reinterpret_cast(addr_KeyValues_FindKey); + return func(this, keyName, bCreate); } + const char* GetName(); + int GetInt(const char* keyName, int defaultValue) { KeyValues* dat = FindKey(keyName, false); @@ -368,8 +371,13 @@ namespace GameGlobals extern CHostState* HostState; extern CInputSystem* InputSystem; extern CCVar* Cvar; + extern KeyValues** PlaylistKeyValues; + extern CKeyValuesSystem* KeyValuesSystem; + extern std::vector allPlaylists; ConVar* CreateCustomConVar(const char* name, const char* defaultValue, int flags, const char* helpString, bool bMin, float fMin, bool bMax, float fMax, void* callback, void* unk); void InitGameGlobals(); + void InitConVars(); + void InitPlaylist(); extern bool IsInitialized; } \ No newline at end of file diff --git a/r5dev/include/hooks.h b/r5dev/include/hooks.h index b880254f..bad42cf2 100644 --- a/r5dev/include/hooks.h +++ b/r5dev/include/hooks.h @@ -103,9 +103,13 @@ namespace Hooks #pragma region Other int MSG_EngineError(char* fmt, va_list args); + bool LoadPlaylist(const char* playlist); using MSG_EngineErrorFn = int(*)(char*, va_list); extern MSG_EngineErrorFn originalMSG_EngineError; + + using LoadPlaylistFn = bool(*)(const char*); + extern LoadPlaylistFn originalLoadPlaylist; #pragma endregion void InstallHooks(); diff --git a/r5dev/include/patterns.h b/r5dev/include/patterns.h index 301ed6e4..4ca2776e 100644 --- a/r5dev/include/patterns.h +++ b/r5dev/include/patterns.h @@ -16,7 +16,7 @@ namespace FUNC_AT_ADDRESS(addr_ConCommand_IsFlagSet, bool(*)(int*, int), r5_patterns.PatternSearch("85 51 38 0F 95 C0 C3").GetPtr()); /*0x140279CE0*/ - FUNC_AT_ADDRESS(addr_downloadPlaylists_Callback, void*, r5_patterns.PatternSearch("33 C9 C6 05 ? ? ? ? ? E9 ? ? ? ?").GetPtr()); + FUNC_AT_ADDRESS(addr_downloadPlaylists_Callback, void(*)(), r5_patterns.PatternSearch("33 C9 C6 05 ? ? ? ? ? E9 ? ? ? ?").GetPtr()); #pragma endregion #pragma region Squirrel @@ -74,9 +74,23 @@ namespace /*0x1401B31C0*/ FUNC_AT_ADDRESS(addr_MemAlloc_Wrapper, void*(*)(__int64), r5_patterns.StringSearch("ConversionModeMenu").FindPatternSelf("E8 ? ? ? ? 48", MemoryAddress::Direction::UP).FollowNearCallSelf().GetPtr()); + + /*0x14B37DE80 has current loaded playlist name*/ + /*0x1402790C0*/ + FUNC_AT_ADDRESS(addr_LoadPlaylist, bool(*)(const char*), r5_patterns.PatternSearch("E8 ? ? ? ? 80 3D ? ? ? ? ? 74 0C").FollowNearCallSelf().GetPtr()); + + /*0x1671060C0*/ + FUNC_AT_ADDRESS(addr_MapVPKCache, void*, r5_patterns.StringSearch("PrecacheMTVF").FindPatternSelf("48 8D 1D ? ? ? ? 4C", MemoryAddress::Direction::UP, 900).OffsetSelf(0x3).ResolveRelativeAddress().GetPtr()); + + /*0x140278C50*/ + FUNC_AT_ADDRESS(addr_mp_gamemode_Callback, bool(*)(const char*), r5_patterns.StringSearch("Failed to load playlist data\n").FindPatternSelf("E8 ? ? ? ? B0 01", MemoryAddress::Direction::DOWN, 200).FollowNearCallSelf().GetPtr()); #pragma endregion - // Un-used atm. - // DWORD64 p_KeyValues_FindKey = /*1404744E0*/ reinterpret_cast(PatternScan("r5apex.exe", "40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45")); + +#pragma region KeyValues + /*0x1404744E0*/ + FUNC_AT_ADDRESS(addr_KeyValues_FindKey, void*(*)(void*, const char*, bool), r5_patterns.PatternSearch("40 56 57 41 57 48 81 EC ?? ?? ?? ?? 45").GetPtr()); +#pragma endregion + void PrintHAddress() // Test the sigscan results { @@ -85,6 +99,7 @@ namespace PRINT_ADDRESS("ConVar_IsFlagSet", addr_ConVar_IsFlagSet); PRINT_ADDRESS("ConCommand_IsFlagSet", addr_ConCommand_IsFlagSet); PRINT_ADDRESS("Downloadplaylists_Callback", addr_downloadPlaylists_Callback); + PRINT_ADDRESS("MP_gamemode_Callback", addr_mp_gamemode_Callback); PRINT_ADDRESS("SQVM_Print", addr_SQVM_Print); PRINT_ADDRESS("SQVM_LoadScript", addr_SQVM_LoadScript); PRINT_ADDRESS("SQVM_LoadRson", addr_SQVM_LoadRson); @@ -98,6 +113,8 @@ namespace PRINT_ADDRESS("CVEngineServer::IsPersistenceDataAvailable", addr_CVEngineServer_IsPersistenceDataAvailable); PRINT_ADDRESS("CBaseFileSystem::FileSystemWarning", addr_CBaseFileSystem_FileSystemWarning); PRINT_ADDRESS("MSG_EngineError", addr_MSG_EngineError); + PRINT_ADDRESS("LoadPlaylist", addr_LoadPlaylist); + PRINT_ADDRESS("MapVPKCache", addr_MapVPKCache); PRINT_ADDRESS("MemAlloc_Wrapper", addr_MemAlloc_Wrapper); std::cout << "+--------------------------------------------------------+" << std::endl; // TODO implement error handling when sigscan fails or result is 0 diff --git a/r5dev/r5dev.vcxproj b/r5dev/r5dev.vcxproj index f41f62bf..bc2148f4 100644 --- a/r5dev/r5dev.vcxproj +++ b/r5dev/r5dev.vcxproj @@ -382,6 +382,7 @@ if not EXIST $(SolutionDir)r5net\lib\$(Configuration)\r5net.lib ( + diff --git a/r5dev/r5dev.vcxproj.filters b/r5dev/r5dev.vcxproj.filters index 83ee6880..fe05a640 100644 --- a/r5dev/r5dev.vcxproj.filters +++ b/r5dev/r5dev.vcxproj.filters @@ -192,6 +192,9 @@ hooks\src\netchannel + + hooks\src\other + diff --git a/r5dev/src/CCompanion.cpp b/r5dev/src/CCompanion.cpp index b020ba40..82476a2e 100644 --- a/r5dev/src/CCompanion.cpp +++ b/r5dev/src/CCompanion.cpp @@ -191,7 +191,7 @@ void CCompanion::ServerBrowserSection() ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch, 20); ImGui::TableSetupColumn("Map", ImGuiTableColumnFlags_WidthStretch, 25); ImGui::TableSetupColumn("Port", ImGuiTableColumnFlags_WidthStretch, 5); - ImGui::TableSetupColumn("Gamemode", ImGuiTableColumnFlags_WidthStretch, 5); + ImGui::TableSetupColumn("Playlist", ImGuiTableColumnFlags_WidthStretch, 5); ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthStretch, 5); ImGui::TableHeadersRow(); @@ -200,7 +200,7 @@ void CCompanion::ServerBrowserSection() const char* name = server.name.c_str(); const char* map = server.map.c_str(); const char* port = server.port.c_str(); - const char* gamemode = server.gamemode.c_str(); + const char* playlist = server.playlist.c_str(); if (ServerBrowserFilter.PassFilter(name) || ServerBrowserFilter.PassFilter(map) @@ -216,7 +216,7 @@ void CCompanion::ServerBrowserSection() ImGui::Text(port); ImGui::TableNextColumn(); - ImGui::Text(gamemode); + ImGui::Text(playlist); ImGui::TableNextColumn(); std::string selectButtonText = "Connect##"; @@ -309,9 +309,9 @@ void CCompanion::ServerBrowserSection() 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; // ^^^^ // this definitely wont reach the final commit lmao @@ -328,7 +328,7 @@ void CCompanion::ServerBrowserSection() } ImGui::EndChild(); ImGui::PopStyleColor(); // Pop the override for the child bg. - + ImGui::SameLine(); ImGui::Text("Enter the following details to continue"); @@ -398,6 +398,17 @@ void CCompanion::HostServerSection() } ImGui::EndCombo(); } + if (ImGui::BeginCombo("Playlist##ServerHost_PlaylistBox", MyServer.playlist.c_str())) + { + for (auto& item : GameGlobals::allPlaylists) + { + if (ImGui::Selectable(item.c_str(), item == MyServer.playlist)) + { + MyServer.playlist = item; + } + } + ImGui::EndCombo(); + } ImGui::Spacing(); ImGui::Checkbox("Start as Dedicated Server (HACK)##ServerHost_DediCheckbox", &StartAsDedi); @@ -408,24 +419,36 @@ void CCompanion::HostServerSection() ImGui::Separator(); - if (ImGui::Button("Start Server##ServerHost_StartServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) + if (!GameGlobals::HostState->m_bActiveGame) { - if (!MyServer.name.empty()) + if (ImGui::Button("Start Server##ServerHost_StartServerButton", ImVec2(ImGui::GetWindowSize().x, 32))) { - ServerNameErr = std::string(); - UpdateHostingStatus(); - std::stringstream cmd; - cmd << "map " << ServerMap; - ProcessCommand(cmd.str().c_str()); - - if (StartAsDedi) + if (!MyServer.name.empty() && !MyServer.playlist.empty()) { - Hooks::ToggleDevCommands(); + ServerNameErr = std::string(); + UpdateHostingStatus(); + + /* + * Playlist gets parsed in two instances, first in LoadPlaylist 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.. + */ + addr_LoadPlaylist(MyServer.playlist.c_str()); + addr_mp_gamemode_Callback(MyServer.playlist.c_str()); + GameGlobals::Cvar->FindVar("mp_gamemode")->m_pzsCurrentValue = MyServer.playlist.c_str(); // Since we call the callback of the cmd, set the playlist name manually here. + + std::stringstream cmd; + cmd << "map " << ServerMap; + ProcessCommand(cmd.str().c_str()); + + if (StartAsDedi) + { + Hooks::ToggleDevCommands(); + } + } + else + { + ServerNameErr = "No Server Name assigned. Or playlist assigned."; } - } - else - { - ServerNameErr = "No Server Name assigned."; } } @@ -462,6 +485,14 @@ void CCompanion::HostServerSection() GameGlobals::HostState->m_iNextState = HostStates_t::HS_GAME_SHUTDOWN; // Force CHostState::FrameUpdate to shutdown the server for dedicated. } } + else + { + if (ImGui::Button("Reload Playlist from Disk##ServerHost_ReloadPlaylist", ImVec2(ImGui::GetWindowSize().x, 32))) + { + addr_downloadPlaylists_Callback(); + GameGlobals::InitPlaylist(); // Re-Init playlist. + } + } } void CCompanion::SettingsSection() diff --git a/r5dev/src/gameclasses.cpp b/r5dev/src/gameclasses.cpp index 72d1edf9..c62c0c29 100644 --- a/r5dev/src/gameclasses.cpp +++ b/r5dev/src/gameclasses.cpp @@ -2,8 +2,26 @@ #include "gameclasses.h" #include "id3dx.h" +// Need this for a re-factor later. +// Interface* interfaces = *reinterpret_cast(0x167F4FA48); + +// for (Interface* current = interfaces; current; current = reinterpret_cast(current->NextInterfacePtr)) +// { +// printf("%s: %p\n", current->InterfaceName, current->InterfacePtr); +// } + namespace GameGlobals { + bool IsInitialized = false; + CHostState* HostState = nullptr; + CInputSystem* InputSystem = nullptr; + CCVar* Cvar = nullptr; + + CKeyValuesSystem* KeyValuesSystem = nullptr; + KeyValues** PlaylistKeyValues = nullptr; + + std::vector allPlaylists = { "none" }; + namespace CustomConVar { void CGameConsole_Callback(void* cmd) @@ -55,12 +73,7 @@ namespace GameGlobals } } - bool IsInitialized = false; - CHostState* HostState = nullptr; - CInputSystem* InputSystem = nullptr; - CCVar* Cvar = nullptr; - - void EmptyHostNames() + void NullHostNames() { const char* hostnameArray[] = { @@ -95,17 +108,45 @@ namespace GameGlobals HostState = reinterpret_cast(0x141736120); // Get CHostState from memory. InputSystem = *reinterpret_cast(0x14D40B380); // Get IInputSystem from memory. Cvar = *reinterpret_cast(0x14D40B348); // Get CCVar from memory. - // Interface* interfaces = *reinterpret_cast(0x167F4FA48); + KeyValuesSystem = reinterpret_cast(0x141F105C0); // Get CKeyValuesSystem from memory. + PlaylistKeyValues = reinterpret_cast(0x16705B980); // Get the KeyValue for the playlist file. - // for (Interface* current = interfaces; current; current = reinterpret_cast(current->NextInterfacePtr)) - // { - // printf("%s: %p\n", current->InterfaceName, current->InterfacePtr); - // } + NullHostNames(); // Null all hostnames. + InitConVars(); // Initialize our custom ConVars. + std::thread t1(InitPlaylist); // Start thread to grab playlists. + t1.detach(); // Detach thread from current one. + + IsInitialized = true; + } + + void InitPlaylist() + { + while (true) + { + if ((*PlaylistKeyValues)) + { + KeyValues* playlists = (*PlaylistKeyValues)->FindKey("Playlists", false); // Find playlists key. + if (playlists) + { + allPlaylists.clear(); + for (KeyValues* dat = playlists->m_pSub; dat != nullptr; dat = dat->m_pPeer) // Parse through all sub keys. + { + allPlaylists.push_back(dat->GetName()); // Get all playlist names. + } + + break; // Break if playlist got filled. + } + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + } + + void InitConVars() + { ConVar* CGameConsoleConVar = CreateCustomConVar("cgameconsole", "0", 0, "Opens the R5 Reloaded Console", false, 0.f, false, 0.f, CustomConVar::CGameConsole_Callback, nullptr); ConVar* CCompanionConVar = CreateCustomConVar("ccompanion", "0", 0, "Opens the R5 Reloaded Server Browser", false, 0.f, false, 0.f, CustomConVar::CCompanion_Callback, nullptr); - EmptyHostNames(); - IsInitialized = true; } ConVar* CreateCustomConVar(const char* name, const char* defaultValue, int flags, const char* helpString, bool bMin, float fMin, bool bMax, float fMax, void* callback, void* unk) @@ -126,4 +167,13 @@ namespace GameGlobals return allocatedConvar; // Return allocated ConVar. } -} \ No newline at end of file +} + +#pragma region KeyValues + +const char* KeyValues::GetName() +{ + return GameGlobals::KeyValuesSystem->GetStringForSymbol(MAKE_3_BYTES_FROM_1_AND_2(m_iKeyNameCaseSensitive, m_iKeyNameCaseSensitive2)); +} + +#pragma endregion \ No newline at end of file diff --git a/r5dev/src/hooks/chlclient.cpp b/r5dev/src/hooks/chlclient.cpp index 4ae9839b..32b67fb9 100644 --- a/r5dev/src/hooks/chlclient.cpp +++ b/r5dev/src/hooks/chlclient.cpp @@ -20,6 +20,5 @@ void __fastcall Hooks::FrameStageNotify(CHLClient* rcx, ClientFrameStage_t curSt default: break; } - originalFrameStageNotify(rcx, curStage); } \ No newline at end of file diff --git a/r5dev/src/hooks/hooks.cpp b/r5dev/src/hooks/hooks.cpp index 08dbee96..aa0c2102 100644 --- a/r5dev/src/hooks/hooks.cpp +++ b/r5dev/src/hooks/hooks.cpp @@ -46,6 +46,7 @@ void Hooks::InstallHooks() /////////////////////////////////////////////////////////////////////////////// // Hook Utility functions MH_CreateHook(addr_MSG_EngineError, &Hooks::MSG_EngineError, reinterpret_cast(&originalMSG_EngineError)); + MH_CreateHook(addr_LoadPlaylist, &Hooks::LoadPlaylist, reinterpret_cast(&originalLoadPlaylist)); /////////////////////////////////////////////////////////////////////////////// // Hook WinAPI @@ -98,6 +99,7 @@ void Hooks::InstallHooks() /////////////////////////////////////////////////////////////////////////////// // Enabled Utility hooks MH_EnableHook(addr_MSG_EngineError); + MH_EnableHook(addr_LoadPlaylist); } void Hooks::RemoveHooks() @@ -143,6 +145,7 @@ void Hooks::RemoveHooks() /////////////////////////////////////////////////////////////////////////////// // Unhook Utility functions MH_RemoveHook(addr_MSG_EngineError); + MH_RemoveHook(addr_LoadPlaylist); /////////////////////////////////////////////////////////////////////////////// // Unhook CBaseFileSystem functions. diff --git a/r5dev/src/hooks/loadplaylist.cpp b/r5dev/src/hooks/loadplaylist.cpp new file mode 100644 index 00000000..dcf937aa --- /dev/null +++ b/r5dev/src/hooks/loadplaylist.cpp @@ -0,0 +1,13 @@ +#include "pch.h" +#include "hooks.h" + +namespace Hooks +{ + LoadPlaylistFn originalLoadPlaylist = nullptr; +} + +bool Hooks::LoadPlaylist(const char* playlist) +{ + memset(addr_MapVPKCache, 0, 0x40); // Bye bye vpk cache, you only make us crash >:(. + return originalLoadPlaylist(playlist); // Parse playlist like normally.. +} \ No newline at end of file diff --git a/r5dev/src/hooks/netchannel.cpp b/r5dev/src/hooks/netchannel.cpp index 2dc45d40..3b09e286 100644 --- a/r5dev/src/hooks/netchannel.cpp +++ b/r5dev/src/hooks/netchannel.cpp @@ -8,6 +8,6 @@ namespace Hooks void Hooks::NetChanShutdown(void* rcx, const char* reason, unsigned __int8 unk1, char unk2) { - reinterpret_cast(addr_downloadPlaylists_Callback)(); // Re-Load playlist from disk after getting dropped or disconnecting off a server. + addr_downloadPlaylists_Callback(); // Re-Load playlist from disk after getting dropped or disconnecting off a server. originalNetChanShutDown(rcx, reason, unk1, unk2); } \ No newline at end of file diff --git a/r5net/include/r5/serverlisting.h b/r5net/include/r5/serverlisting.h index 8db411c3..0b317eb6 100644 --- a/r5net/include/r5/serverlisting.h +++ b/r5net/include/r5/serverlisting.h @@ -6,7 +6,7 @@ struct ServerListing std::string map; std::string ip; std::string port; - std::string gamemode; + std::string playlist; std::string password; std::string checksum; std::string version; diff --git a/r5net/src/r5net.cpp b/r5net/src/r5net.cpp index 6afa0130..1ef0e78e 100644 --- a/r5net/src/r5net.cpp +++ b/r5net/src/r5net.cpp @@ -84,7 +84,7 @@ bool R5Net::Client::PostServerHost(std::string& outMessage, std::string& outToke reqBody["password"] = serverListing.password; reqBody["remote_checksum"] = serverListing.checksum; reqBody["version"] = GetVersionString(); - reqBody["gamemode"] = serverListing.gamemode; + reqBody["gamemode"] = serverListing.playlist; std::string reqBodyStr = reqBody.dump();