Merge branch 'Joelrau:main' into main

This commit is contained in:
Liam 2023-02-11 07:01:43 +00:00 committed by GitHub
commit 87f1ded80b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 221 additions and 17 deletions

View File

@ -112,6 +112,7 @@ namespace dedicated
// Disable frontend // Disable frontend
dvars::override::register_bool("frontEndSceneEnabled", false, game::DVAR_FLAG_READ); dvars::override::register_bool("frontEndSceneEnabled", false, game::DVAR_FLAG_READ);
utils::hook::set<uint8_t>(0x5AC8F0_b, 0xC3); // Com_FastFile_Frame_FrontEnd
// Disable shader preload // Disable shader preload
dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_READ); dvars::override::register_bool("r_preloadShaders", false, game::DVAR_FLAG_READ);
@ -146,8 +147,9 @@ namespace dedicated
utils::hook::set<uint8_t>(0xD2EBB0_b, 0xC3); // recommended settings check utils::hook::set<uint8_t>(0xD2EBB0_b, 0xC3); // recommended settings check
// sound initialization // sound initialization
utils::hook::nop(0xC93213_b, 5); // snd stream thread // crashes in cp_disco
utils::hook::set<uint8_t>(0xC93206_b, 0); // snd_active //utils::hook::nop(0xC93213_b, 5); // snd stream thread
//utils::hook::set<uint8_t>(0xC93206_b, 0); // snd_active
utils::hook::set<uint8_t>(0xD597C0_b, 0xC3); // init voice system utils::hook::set<uint8_t>(0xD597C0_b, 0xC3); // init voice system
utils::hook::nop(0xC5007B_b, 6); // unknown check in SV_ExecuteClientMessage utils::hook::nop(0xC5007B_b, 6); // unknown check in SV_ExecuteClientMessage
@ -216,6 +218,9 @@ namespace dedicated
// image stream (pak) // image stream (pak)
utils::hook::set<uint8_t>(0xA7DB10_b, 0xC3); // DB_CreateGfxImageStreamInternal utils::hook::set<uint8_t>(0xA7DB10_b, 0xC3); // DB_CreateGfxImageStreamInternal
// recipe save threads
utils::hook::set<uint8_t>(0xE7C970_b, 0xC3);
// set game mode // set game mode
scheduler::once([]() scheduler::once([]()
{ {

View File

@ -59,7 +59,7 @@ namespace fastfiles
game::XAssetHeader db_find_xasset_header_stub(game::XAssetType type, const char* name, const int allow_create_default) game::XAssetHeader db_find_xasset_header_stub(game::XAssetType type, const char* name, const int allow_create_default)
{ {
auto result = db_find_xasset_header_hook.invoke<game::XAssetHeader>(type, name, allow_create_default); auto result = db_find_xasset_header_hook.invoke<game::XAssetHeader>(type, name, allow_create_default);
if (!result.data) if (!result.data && type != game::ASSET_TYPE_LOCALIZE_ENTRY)
{ {
console::error("Error: Could not find %s \"%s\"\n", console::error("Error: Could not find %s \"%s\"\n",
game::g_assetNames[static_cast<unsigned int>(type)], game::g_assetNames[static_cast<unsigned int>(type)],

View File

@ -28,6 +28,8 @@ namespace party
bool hostDefined{ false }; bool hostDefined{ false };
} connect_state; } connect_state;
bool preloaded_map = false;
void perform_game_initialization() void perform_game_initialization()
{ {
command::execute("onlinegame 1", true); command::execute("onlinegame 1", true);
@ -45,7 +47,7 @@ namespace party
return; return;
} }
if (game::Live_SyncOnlineDataFlags(0) != 0) if (game::Live_SyncOnlineDataFlags(0) != 0/* || !utils::hook::invoke<bool>(0xBB5E70_b)*/)
{ {
scheduler::once([=]() scheduler::once([=]()
{ {
@ -55,18 +57,37 @@ namespace party
} }
const auto ui_maxclients = game::Dvar_FindVar("ui_maxclients"); const auto ui_maxclients = game::Dvar_FindVar("ui_maxclients");
const auto party_maxplayers = game::Dvar_FindVar("party_maxplayers");
game::Dvar_SetInt(ui_maxclients, sv_maxclients); game::Dvar_SetInt(ui_maxclients, sv_maxclients);
game::Dvar_SetInt(party_maxplayers, sv_maxclients);
command::execute(utils::string::va("ui_mapname %s", mapname.data()), true);
command::execute(utils::string::va("ui_gametype %s", gametype.data()), true);
perform_game_initialization(); perform_game_initialization();
// setup agent count // setup agent count
utils::hook::invoke<void>(0xC19B00_b, gametype.data()); utils::hook::invoke<void>(0xC19B00_b, gametype.data());
preloaded_map = false;
// connect // connect
char session_info[0x100] = {}; char session_info[0x100] = {};
game::CL_MainMP_ConnectAndPreloadMap(0, reinterpret_cast<void*>(session_info), &target, mapname.data(), gametype.data()); game::CL_MainMP_ConnectAndPreloadMap(0, reinterpret_cast<void*>(session_info), &target, mapname.data(), gametype.data());
} }
void pre_disaster()
{
utils::hook::set<uint8_t>(0x5EBED0_b, 0xC3); // ret // client snapshot
utils::hook::set<uint8_t>(0xC69890_b, 0xC3); // ret // nav mesh
}
void post_disaster()
{
utils::hook::set<uint8_t>(0xC69890_b, 0x48); // restore // client snapshot
//utils::hook::set<uint8_t>(0x5EBED0_b, 0x40); // restore // nav mesh
}
void start_map_for_party(std::string map_name) void start_map_for_party(std::string map_name)
{ {
[[maybe_unused]]auto* mapname = game::Dvar_FindVar("ui_mapname"); [[maybe_unused]]auto* mapname = game::Dvar_FindVar("ui_mapname");
@ -75,11 +96,21 @@ namespace party
auto* private_clients = game::Dvar_FindVar("ui_privateClients"); auto* private_clients = game::Dvar_FindVar("ui_privateClients");
auto* hardcore = game::Dvar_FindVar("ui_hardcore"); auto* hardcore = game::Dvar_FindVar("ui_hardcore");
// Com_FrontEndScene_ShutdownAndDisable if (game::Com_FrontEnd_IsInFrontEnd())
utils::hook::invoke<void>(0x5AEFB0_b); {
// Com_FrontEndScene_ShutdownAndDisable
utils::hook::invoke<void>(0x5AEFB0_b);
}
utils::hook::set<uint8_t>(0x5EBED0_b, 0xC3); // ret if (game::CL_IsGameClientActive(0))
utils::hook::set<uint8_t>(0xC69890_b, 0xC3); // ret {
//utils::hook::invoke<void>(0xC58E20_b, game::Lobby_GetPartyData()); // SV_MainMP_MatchEnd
//utils::hook::invoke<void>(0xB200F0_b); // G_MainMP_ExitLevel
}
utils::hook::invoke<void>(0xC12850_b); // SV_GameMP_ShutdownGameProgs
pre_disaster();
game::SV_CmdsMP_StartMapForParty( game::SV_CmdsMP_StartMapForParty(
map_name.data(), map_name.data(),
gametype->current.string, gametype->current.string,
@ -88,8 +119,7 @@ namespace party
hardcore->current.enabled, hardcore->current.enabled,
false, false,
false); false);
utils::hook::set<uint8_t>(0xC69890_b, 0x48); // restore post_disaster();
utils::hook::set<uint8_t>(0x5EBED0_b, 0x40); // restore
} }
std::string get_dvar_string(const std::string& dvar) std::string get_dvar_string(const std::string& dvar)
@ -124,6 +154,42 @@ namespace party
return false; return false;
} }
void com_gamestart_beginclient_stub(const char* mapname, const char* gametype, char a3)
{
if (preloaded_map)
{
// Com_GameStart_BeginClient
utils::hook::invoke<void>(0x5B0130_b, mapname, gametype, 0);
}
else
{
// DB_LoadLevelXAssets
utils::hook::invoke<void>(0x3B9C90_b, mapname, 0);
}
}
void com_restart_for_frontend_stub()
{
if (preloaded_map)
{
// Com_RestartForFrontend
utils::hook::invoke<void>(0xBAF0B0_b);
}
else
{
// Com_Restart
utils::hook::invoke<void>(0xBAF0A0_b);
}
}
utils::hook::detour sv_start_map_for_party_hook;
void sv_start_map_for_party_stub(const char* map, const char* game_type, int client_count, int agent_count, bool hardcore,
bool map_is_preloaded, bool migrate)
{
preloaded_map = map_is_preloaded;
sv_start_map_for_party_hook.invoke<void>(map, game_type, client_count, agent_count, hardcore, map_is_preloaded, migrate);
}
} }
void start_map(const std::string& mapname, bool dev) void start_map(const std::string& mapname, bool dev)
@ -190,17 +256,50 @@ namespace party
int get_client_num_by_name(const std::string& name) int get_client_num_by_name(const std::string& name)
{ {
return 0; for (auto i = 0; !name.empty() && i < *game::svs_numclients; ++i)
{
if (game::g_entities[i].client)
{
char client_name[32] = { 0 };
strncpy_s(client_name, game::g_entities[i].client->name, sizeof(client_name));
game::I_CleanStr(client_name);
if (client_name == name)
{
return i;
}
}
}
return -1;
} }
int get_client_count() int get_client_count()
{ {
return 0; auto count = 0;
for (auto i = 0; i < *game::svs_numclients; ++i)
{
if (game::svs_clients[i].header.state >= 1)
{
++count;
}
}
return count;
} }
int get_bot_count() int get_bot_count()
{ {
return 0; auto count = 0;
for (auto i = 0; i < *game::svs_numclients; ++i)
{
if (game::svs_clients[i].header.state >= 1 &&
game::SV_BotIsBot(i))
{
++count;
}
}
return count;
} }
void connect(const game::netadr_s& target) void connect(const game::netadr_s& target)
@ -225,7 +324,6 @@ namespace party
game::Com_SetLocalizedErrorMessage(error.data(), "MENU_NOTICE"); game::Com_SetLocalizedErrorMessage(error.data(), "MENU_NOTICE");
} }
class component final : public component_interface class component final : public component_interface
{ {
public: public:
@ -251,9 +349,15 @@ namespace party
utils::hook::set(0x1BBA700_b + 56, a3); utils::hook::set(0x1BBA700_b + 56, a3);
utils::hook::set<uint8_t>(0xC562FD_b, 0xEB); // allow mapname to be changed while server is running utils::hook::set<uint8_t>(0xC562FD_b, 0xEB); // allow mapname to be changed while server is running
utils::hook::set<uint8_t>(0x9B37B0_b, 0xC3); // CL_MainMp_PreloadMap ( map restart issue )
// need to fix this, currently it will disconnect everyone from the server when a new map is rotated utils::hook::nop(0xA7A8DF_b, 5); // R_SyncRenderThread inside CL_MainMp_PreloadMap ( freezes )
utils::hook::call(0x9AFE84_b, com_gamestart_beginclient_stub); // blackscreen issue on connect
utils::hook::call(0x9B4077_b, com_gamestart_beginclient_stub); // crash on map rotate
utils::hook::call(0x9B404A_b, com_restart_for_frontend_stub); // crash on map rotate
// TODO: fix disaster shit, those patches are shite.
command::add("map", [](const command::params& args) command::add("map", [](const command::params& args)
{ {
if (args.size() != 2) if (args.size() != 2)
@ -286,7 +390,6 @@ namespace party
start_map(args.get(1), true); start_map(args.get(1), true);
}); });
// need to fix this, currently game will freeze in loadingnewmap command
command::add("map_restart", []() command::add("map_restart", []()
{ {
if (!game::SV_Loaded() || game::Com_FrontEnd_IsInFrontEnd()) if (!game::SV_Loaded() || game::Com_FrontEnd_IsInFrontEnd())
@ -300,7 +403,9 @@ namespace party
return; return;
} }
pre_disaster();
game::SV_CmdsMP_RequestMapRestart(1, 0); game::SV_CmdsMP_RequestMapRestart(1, 0);
post_disaster();
}); });
command::add("fast_restart", []() command::add("fast_restart", []()
@ -316,7 +421,9 @@ namespace party
return; return;
} }
pre_disaster();
game::SV_CmdsMP_RequestMapRestart(0, 0); game::SV_CmdsMP_RequestMapRestart(0, 0);
post_disaster();
}); });
command::add("connect", [](const command::params& argument) command::add("connect", [](const command::params& argument)

View File

@ -0,0 +1,62 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include "scheduler.hpp"
#include "game/game.hpp"
#include <utils/thread.hpp>
namespace thread_names
{
namespace
{
void set_thread_names()
{
static std::unordered_map<int, std::string> thread_names =
{
{game::THREAD_CONTEXT_MAIN, "Main"},
{game::THREAD_CONTEXT_BACKEND, "Backend"}, // Renderer
{game::THREAD_CONTEXT_WORKER0, "Worker0"},
{game::THREAD_CONTEXT_WORKER1, "Worker1"},
{game::THREAD_CONTEXT_WORKER2, "Worker2"},
{game::THREAD_CONTEXT_WORKER3, "Worker3"},
{game::THREAD_CONTEXT_WORKER4, "Worker4"},
{game::THREAD_CONTEXT_WORKER5, "Worker5"},
{game::THREAD_CONTEXT_WORKER6, "Worker6"},
{game::THREAD_CONTEXT_WORKER7, "Worker7"},
{game::THREAD_CONTEXT_SERVER, "Server"},
{game::THREAD_CONTEXT_CINEMATIC, "Cinematic"},
{game::THREAD_CONTEXT_WINDOW, "Window"},
{game::THREAD_CONTEXT_WINDOW, "Input"},
{game::THREAD_CONTEXT_DATABASE, "Database"},
{game::THREAD_CONTEXT_SOUND_STREAM, "Sound Stream"},
{game::THREAD_CONTEXT_SOUND, "Snd stream packet callback"},
{game::THREAD_CONTEXT_RECIPE, "Recipe"},
};
for (const auto& thread_name : thread_names)
{
const auto id = game::threadIds[thread_name.first];
if (id)
{
utils::thread::set_name(id, thread_name.second);
}
}
}
}
class component final : public component_interface
{
public:
void post_unpack() override
{
set_thread_names();
scheduler::once(set_thread_names, scheduler::pipeline::main);
scheduler::once(set_thread_names, scheduler::pipeline::renderer);
scheduler::once(set_thread_names, scheduler::pipeline::server);
}
};
}
REGISTER_COMPONENT(thread_names::component)

View File

@ -412,6 +412,31 @@ namespace game
CRITSECT_DEMONWARE = 39, CRITSECT_DEMONWARE = 39,
}; };
enum ThreadContext
{
THREAD_CONTEXT_MAIN = 0,
THREAD_CONTEXT_BACKEND = 1,
THREAD_CONTEXT_WORKER0 = 2,
THREAD_CONTEXT_WORKER1 = 3,
THREAD_CONTEXT_WORKER2 = 4,
THREAD_CONTEXT_WORKER3 = 5,
THREAD_CONTEXT_WORKER4 = 6,
THREAD_CONTEXT_WORKER5 = 7,
THREAD_CONTEXT_WORKER6 = 8,
THREAD_CONTEXT_WORKER7 = 9,
THREAD_CONTEXT_SERVER = 10,
THREAD_CONTEXT_CINEMATIC = 11,
THREAD_CONTEXT_WINDOW = 12,
THREAD_CONTEXT_INPUT = 13,
THREAD_CONTEXT_DATABASE = 14,
THREAD_CONTEXT_SOUND_STREAM = 15,
THREAD_CONTEXT_SOUND = 16,
THREAD_CONTEXT_UNKNOWN17 = 17,
THREAD_CONTEXT_UNKNOWN18 = 18,
THREAD_CONTEXT_UNKNOWN19 = 19,
THREAD_CONTEXT_RECIPE = 20,
};
namespace entity namespace entity
{ {
enum connstate_t : std::uint32_t enum connstate_t : std::uint32_t

View File

@ -93,6 +93,8 @@ namespace game
WEAK symbol<void(char* buffer)> FS_FreeFile{ 0xCDE1F0 }; WEAK symbol<void(char* buffer)> FS_FreeFile{ 0xCDE1F0 };
WEAK symbol<void(int h, const char* fmt, ...)> FS_Printf{ 0xCDD1C0 }; WEAK symbol<void(int h, const char* fmt, ...)> FS_Printf{ 0xCDD1C0 };
WEAK symbol<char* (char* string)> I_CleanStr{ 0xCFACC0 };
WEAK symbol<const char* (int, int, int)> Key_KeynumToString{ 0x9A95E0 }; WEAK symbol<const char* (int, int, int)> Key_KeynumToString{ 0x9A95E0 };
WEAK symbol<bool()> LUI_CoD_InFrontEnd{ 0x615080 }; WEAK symbol<bool()> LUI_CoD_InFrontEnd{ 0x615080 };
@ -154,6 +156,7 @@ namespace game
WEAK symbol<void(int clientNum, svscmd_type type, const char* text)> SV_GameSendServerCommand{ 0xC54780 }; WEAK symbol<void(int clientNum, svscmd_type type, const char* text)> SV_GameSendServerCommand{ 0xC54780 };
WEAK symbol<bool()> SV_Loaded{ 0xC114C0 }; WEAK symbol<bool()> SV_Loaded{ 0xC114C0 };
WEAK symbol<bool(const char* name)> SV_MapExists{ 0xCDB620 }; WEAK symbol<bool(const char* name)> SV_MapExists{ 0xCDB620 };
WEAK symbol<bool(int clientNum)> SV_BotIsBot{ 0xC3BC90 };
WEAK symbol<void(int)> SND_StopSounds{ 0xCA06E0 }; WEAK symbol<void(int)> SND_StopSounds{ 0xCA06E0 };
WEAK symbol<void(const char*)> SND_SetMusicState{ 0xC9E110 }; WEAK symbol<void(const char*)> SND_SetMusicState{ 0xC9E110 };
@ -187,4 +190,6 @@ namespace game
WEAK symbol<int> sv_migrate{ 0x6B2C9DC }; WEAK symbol<int> sv_migrate{ 0x6B2C9DC };
WEAK symbol<SOCKET> query_socket{ 0x779FDC8 }; WEAK symbol<SOCKET> query_socket{ 0x779FDC8 };
WEAK symbol<DWORD> threadIds{ 0x602BAB0 };
} }