Merge branch 'Joelrau:main' into main
This commit is contained in:
commit
87f1ded80b
@ -112,6 +112,7 @@ namespace dedicated
|
||||
|
||||
// Disable frontend
|
||||
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
|
||||
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
|
||||
|
||||
// sound initialization
|
||||
utils::hook::nop(0xC93213_b, 5); // snd stream thread
|
||||
utils::hook::set<uint8_t>(0xC93206_b, 0); // snd_active
|
||||
// crashes in cp_disco
|
||||
//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::nop(0xC5007B_b, 6); // unknown check in SV_ExecuteClientMessage
|
||||
@ -216,6 +218,9 @@ namespace dedicated
|
||||
// image stream (pak)
|
||||
utils::hook::set<uint8_t>(0xA7DB10_b, 0xC3); // DB_CreateGfxImageStreamInternal
|
||||
|
||||
// recipe save threads
|
||||
utils::hook::set<uint8_t>(0xE7C970_b, 0xC3);
|
||||
|
||||
// set game mode
|
||||
scheduler::once([]()
|
||||
{
|
||||
|
@ -59,7 +59,7 @@ namespace fastfiles
|
||||
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);
|
||||
if (!result.data)
|
||||
if (!result.data && type != game::ASSET_TYPE_LOCALIZE_ENTRY)
|
||||
{
|
||||
console::error("Error: Could not find %s \"%s\"\n",
|
||||
game::g_assetNames[static_cast<unsigned int>(type)],
|
||||
|
@ -28,6 +28,8 @@ namespace party
|
||||
bool hostDefined{ false };
|
||||
} connect_state;
|
||||
|
||||
bool preloaded_map = false;
|
||||
|
||||
void perform_game_initialization()
|
||||
{
|
||||
command::execute("onlinegame 1", true);
|
||||
@ -45,7 +47,7 @@ namespace party
|
||||
return;
|
||||
}
|
||||
|
||||
if (game::Live_SyncOnlineDataFlags(0) != 0)
|
||||
if (game::Live_SyncOnlineDataFlags(0) != 0/* || !utils::hook::invoke<bool>(0xBB5E70_b)*/)
|
||||
{
|
||||
scheduler::once([=]()
|
||||
{
|
||||
@ -55,18 +57,37 @@ namespace party
|
||||
}
|
||||
|
||||
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(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();
|
||||
|
||||
// setup agent count
|
||||
utils::hook::invoke<void>(0xC19B00_b, gametype.data());
|
||||
|
||||
preloaded_map = false;
|
||||
|
||||
// connect
|
||||
char session_info[0x100] = {};
|
||||
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)
|
||||
{
|
||||
[[maybe_unused]]auto* mapname = game::Dvar_FindVar("ui_mapname");
|
||||
@ -75,11 +96,21 @@ namespace party
|
||||
auto* private_clients = game::Dvar_FindVar("ui_privateClients");
|
||||
auto* hardcore = game::Dvar_FindVar("ui_hardcore");
|
||||
|
||||
// Com_FrontEndScene_ShutdownAndDisable
|
||||
utils::hook::invoke<void>(0x5AEFB0_b);
|
||||
if (game::Com_FrontEnd_IsInFrontEnd())
|
||||
{
|
||||
// Com_FrontEndScene_ShutdownAndDisable
|
||||
utils::hook::invoke<void>(0x5AEFB0_b);
|
||||
}
|
||||
|
||||
utils::hook::set<uint8_t>(0x5EBED0_b, 0xC3); // ret
|
||||
utils::hook::set<uint8_t>(0xC69890_b, 0xC3); // ret
|
||||
if (game::CL_IsGameClientActive(0))
|
||||
{
|
||||
//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(
|
||||
map_name.data(),
|
||||
gametype->current.string,
|
||||
@ -88,8 +119,7 @@ namespace party
|
||||
hardcore->current.enabled,
|
||||
false,
|
||||
false);
|
||||
utils::hook::set<uint8_t>(0xC69890_b, 0x48); // restore
|
||||
utils::hook::set<uint8_t>(0x5EBED0_b, 0x40); // restore
|
||||
post_disaster();
|
||||
}
|
||||
|
||||
std::string get_dvar_string(const std::string& dvar)
|
||||
@ -124,6 +154,42 @@ namespace party
|
||||
|
||||
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)
|
||||
@ -190,17 +256,50 @@ namespace party
|
||||
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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)
|
||||
@ -225,7 +324,6 @@ namespace party
|
||||
game::Com_SetLocalizedErrorMessage(error.data(), "MENU_NOTICE");
|
||||
}
|
||||
|
||||
|
||||
class component final : public component_interface
|
||||
{
|
||||
public:
|
||||
@ -251,9 +349,15 @@ namespace party
|
||||
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>(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)
|
||||
{
|
||||
if (args.size() != 2)
|
||||
@ -286,7 +390,6 @@ namespace party
|
||||
start_map(args.get(1), true);
|
||||
});
|
||||
|
||||
// need to fix this, currently game will freeze in loadingnewmap command
|
||||
command::add("map_restart", []()
|
||||
{
|
||||
if (!game::SV_Loaded() || game::Com_FrontEnd_IsInFrontEnd())
|
||||
@ -300,7 +403,9 @@ namespace party
|
||||
return;
|
||||
}
|
||||
|
||||
pre_disaster();
|
||||
game::SV_CmdsMP_RequestMapRestart(1, 0);
|
||||
post_disaster();
|
||||
});
|
||||
|
||||
command::add("fast_restart", []()
|
||||
@ -316,7 +421,9 @@ namespace party
|
||||
return;
|
||||
}
|
||||
|
||||
pre_disaster();
|
||||
game::SV_CmdsMP_RequestMapRestart(0, 0);
|
||||
post_disaster();
|
||||
});
|
||||
|
||||
command::add("connect", [](const command::params& argument)
|
||||
|
62
src/client/component/thread_names.cpp
Normal file
62
src/client/component/thread_names.cpp
Normal 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)
|
@ -412,6 +412,31 @@ namespace game
|
||||
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
|
||||
{
|
||||
enum connstate_t : std::uint32_t
|
||||
|
@ -93,6 +93,8 @@ namespace game
|
||||
WEAK symbol<void(char* buffer)> FS_FreeFile{ 0xCDE1F0 };
|
||||
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<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<bool()> SV_Loaded{ 0xC114C0 };
|
||||
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(const char*)> SND_SetMusicState{ 0xC9E110 };
|
||||
@ -187,4 +190,6 @@ namespace game
|
||||
WEAK symbol<int> sv_migrate{ 0x6B2C9DC };
|
||||
|
||||
WEAK symbol<SOCKET> query_socket{ 0x779FDC8 };
|
||||
|
||||
WEAK symbol<DWORD> threadIds{ 0x602BAB0 };
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user