Add patches and fixes

This commit is contained in:
Joelrau 2021-01-17 09:53:43 +02:00
parent f81b01fa70
commit 0614305235
11 changed files with 124 additions and 68 deletions

View File

@ -99,11 +99,12 @@ namespace auth
return; return;
} }
utils::cryptography::ecc::key key; // THIS CRASHES WITH DEDICATED WHEN CONNECTING!
/*utils::cryptography::ecc::key key;
key.set(info.publickey()); key.set(info.publickey());
const auto xuid = strtoull(steam_id.data(), nullptr, 16); //const auto xuid = strtoull(steam_id.data(), nullptr, 16);
if (xuid != key.get_hash()) //if (xuid != key.get_hash())
{ {
// xuid is always 0 // xuid is always 0
//MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0); //MessageBoxA(nullptr, steam_id.data(), std::to_string(key.get_hash()).data(), 0);
@ -115,7 +116,7 @@ namespace auth
{ {
network::send(*from, "error", "Challenge signature was invalid!", '\n'); network::send(*from, "error", "Challenge signature was invalid!", '\n');
return; return;
} }*/
game::SV_DirectConnect(from); game::SV_DirectConnect(from);
} }

View File

@ -5,6 +5,7 @@
#include "game/game.hpp" #include "game/game.hpp"
#include "party.hpp" #include "party.hpp"
#include <utils/hook.hpp>
#include <utils/string.hpp> #include <utils/string.hpp>
namespace bots namespace bots
@ -27,19 +28,17 @@ namespace bots
return; return;
} }
auto* bot_ent = game::SV_AddTestClient(0); // SV_BotGetRandomName
if (&bot_ent) auto* bot_name = reinterpret_cast<const char* (*)()>(0x1404267E0)();
auto* bot_ent = game::SV_AddBot(bot_name);
if (bot_ent)
{ {
game::SV_SpawnTestClient(bot_ent); game::SV_SpawnTestClient(bot_ent);
} }
else if (can_spawn()) // workaround since first bot won't ever spawn
// SV_BotGetRandomName
/*auto* bot_name = reinterpret_cast<const char* (*)()>(0x1404267E0)();
auto* bot_ent = game::SV_AddBot(bot_name);
if (&bot_ent)
{ {
game::SV_SpawnTestClient(bot_ent); add_bot();
}*/ }
} }
} }
@ -63,7 +62,7 @@ namespace bots
num_bots = atoi(params.get(1)); num_bots = atoi(params.get(1));
} }
for (auto i = 0; i < num_bots; i++) for (auto i = 0; i < (num_bots > *game::mp::svs_numclients ? *game::mp::svs_numclients : num_bots); i++)
{ {
scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i); scheduler::once(add_bot, scheduler::pipeline::server, 100ms * i);
} }

View File

@ -55,8 +55,8 @@ namespace command
static std::string comand_line_buffer = GetCommandLineA(); static std::string comand_line_buffer = GetCommandLineA();
auto* command_line = comand_line_buffer.data(); auto* command_line = comand_line_buffer.data();
auto& com_num_console_lines = *reinterpret_cast<int*>(0x141AE732C); auto& com_num_console_lines = *reinterpret_cast<int*>(0x147B76504);
auto* com_console_lines = reinterpret_cast<char**>(0x141AE7330); auto* com_console_lines = reinterpret_cast<char**>(0x147B76510);
auto inq = false; auto inq = false;
com_console_lines[0] = command_line; com_console_lines[0] = command_line;
@ -97,8 +97,8 @@ namespace command
// parse the commandline if it's not parsed // parse the commandline if it's not parsed
parse_command_line(); parse_command_line();
auto& com_num_console_lines = *reinterpret_cast<int*>(0x141AE732C); auto& com_num_console_lines = *reinterpret_cast<int*>(0x147B76504);
auto* com_console_lines = reinterpret_cast<char**>(0x141AE7330); auto* com_console_lines = reinterpret_cast<char**>(0x147B76510);
for (int i = 0; i < com_num_console_lines; i++) for (int i = 0; i < com_num_console_lines; i++)
{ {
@ -404,12 +404,12 @@ namespace command
{ {
if (!game::Dvar_FindVar("sv_cheats")->current.enabled) if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
return; return;
} }
game::mp::g_entities[client_num].flags ^= 1; game::mp::g_entities[client_num].flags ^= 1;
game::SV_GameSendServerCommand(client_num, 1, game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
utils::string::va("f \"godmode %s\"", utils::string::va("f \"godmode %s\"",
game::mp::g_entities[client_num].flags & 1 game::mp::g_entities[client_num].flags & 1
? "^2on" ? "^2on"
@ -420,14 +420,14 @@ namespace command
{ {
if (!game::Dvar_FindVar("sv_cheats")->current.enabled) if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
return; return;
} }
game::mp::g_entities[client_num].flags ^= 2; game::mp::g_entities[client_num].flags ^= 2;
game::SV_GameSendServerCommand(client_num, 2, game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
utils::string::va("f \"demigod mode %s\"", utils::string::va("f \"demigod mode %s\"",
game::mp::g_entities[client_num].flags & 1 game::mp::g_entities[client_num].flags & 2
? "^2on" ? "^2on"
: "^1off")); : "^1off"));
}); });
@ -436,12 +436,12 @@ namespace command
{ {
if (!game::Dvar_FindVar("sv_cheats")->current.enabled) if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
return; return;
} }
game::mp::g_entities[client_num].client->flags ^= 1; game::mp::g_entities[client_num].client->flags ^= 1;
game::SV_GameSendServerCommand(client_num, 1, game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
utils::string::va("f \"noclip %s\"", utils::string::va("f \"noclip %s\"",
game::mp::g_entities[client_num].client->flags & 1 game::mp::g_entities[client_num].client->flags & 1
? "^2on" ? "^2on"
@ -452,12 +452,12 @@ namespace command
{ {
if (!game::Dvar_FindVar("sv_cheats")->current.enabled) if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
return; return;
} }
game::mp::g_entities[client_num].client->flags ^= 2; game::mp::g_entities[client_num].client->flags ^= 2;
game::SV_GameSendServerCommand(client_num, 1, game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE,
utils::string::va("f \"ufo %s\"", utils::string::va("f \"ufo %s\"",
game::mp::g_entities[client_num].client->flags & 2 game::mp::g_entities[client_num].client->flags & 2
? "^2on" ? "^2on"
@ -468,13 +468,13 @@ namespace command
{ {
if (!game::Dvar_FindVar("sv_cheats")->current.enabled) if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
return; return;
} }
if (params.size() < 2) if (params.size() < 2)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"You did not specify a weapon name\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\"");
return; return;
} }
@ -494,13 +494,13 @@ namespace command
{ {
if (!game::Dvar_FindVar("sv_cheats")->current.enabled) if (!game::Dvar_FindVar("sv_cheats")->current.enabled)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"Cheats are not enabled on this server\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"Cheats are not enabled on this server\"");
return; return;
} }
if (params.size() < 2) if (params.size() < 2)
{ {
game::SV_GameSendServerCommand(client_num, 1, "f \"You did not specify a weapon name\""); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE, "f \"You did not specify a weapon name\"");
return; return;
} }

View File

@ -131,7 +131,7 @@ namespace dvar_cheats
const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack const auto* dvar = game::Scr_GetString(0); // grab the original dvar again since it's never stored on stack
const auto* command = utils::string::va("q %s \"%s\"", dvar, value); const auto* command = utils::string::va("q %s \"%s\"", dvar, value);
game::SV_GameSendServerCommand(entity_num, 1, command); game::SV_GameSendServerCommand(entity_num, game::SV_CMD_RELIABLE, command);
} }
const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a) const auto player_cmd_set_client_dvar = utils::hook::assemble([](utils::hook::assembler& a)

View File

@ -70,6 +70,17 @@ namespace fastfiles
}, 0, false); }, 0, false);
}); });
command::add("fontlist", [](const command::params& params)
{
game::DB_EnumXAssets_FastFile(game::ASSET_TYPE_FONT, [](const game::XAssetHeader header, void*)
{
if (header.font && header.font->fontName)
{
printf("%s\n", header.font->fontName);
}
}, 0, false);
});
command::add("g_poolSizes", []() command::add("g_poolSizes", []()
{ {
for (auto i = 0; i < game::ASSET_TYPE_COUNT; i++) for (auto i = 0; i < game::ASSET_TYPE_COUNT; i++)

View File

@ -80,7 +80,7 @@ namespace game_console
void print(const std::string& data) void print(const std::string& data)
{ {
//print_internal(data.data()); print_internal(data.data());
printf("%s\n", data.data()); printf("%s\n", data.data());
} }
@ -406,6 +406,24 @@ namespace game_console
} }
} }
void print_internal(const char* fmt, ...)
{
char va_buffer[0x200] = { 0 };
va_list ap;
va_start(ap, fmt);
vsprintf_s(va_buffer, fmt, ap);
va_end(ap);
const auto formatted = std::string(va_buffer);
const auto lines = utils::string::split(formatted, '\n');
for (auto& line : lines)
{
print_internal(line);
}
}
void print(const int type, const char* fmt, ...) void print(const int type, const char* fmt, ...)
{ {
char va_buffer[0x200] = {0}; char va_buffer[0x200] = {0};
@ -654,19 +672,6 @@ namespace game_console
return true; return true;
} }
int printf_stub(char const* format, ...)
{
int result;
char buffer[256];
va_list args;
va_start(args, format);
result = vsnprintf(buffer, 256, format, args);
va_end(args);
std::cout << buffer;
print_internal(buffer);
return result;
}
class component final : public component_interface class component final : public component_interface
{ {
public: public:
@ -687,8 +692,6 @@ namespace game_console
return; return;
} }
utils::hook::jump(printf, printf_stub);
// initialize our structs // initialize our structs
con.cursor = 0; con.cursor = 0;
con.visible_line_count = 0; con.visible_line_count = 0;
@ -725,7 +728,7 @@ namespace game_console
dvars::con_outputBarColor = game::Dvar_RegisterVec4("con_outputBarColor", 0.5f, 0.5f, 0.5f, 0.6f, 0.0f, dvars::con_outputBarColor = game::Dvar_RegisterVec4("con_outputBarColor", 0.5f, 0.5f, 0.5f, 0.6f, 0.0f,
1.0f, 1, 1.0f, 1,
"color of console output bar"); "color of console output bar");
dvars::con_outputSliderColor = game::Dvar_RegisterVec4("con_outputSliderColor", 0.0f, 0.7f, 1.0f, 1.00f, dvars::con_outputSliderColor = game::Dvar_RegisterVec4("con_outputSliderColor", 1.0f, 0.8f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1, "color of console output slider"); 1, "color of console output slider");
dvars::con_outputWindowColor = game::Dvar_RegisterVec4("con_outputWindowColor", 0.25f, 0.25f, 0.25f, 0.85f, dvars::con_outputWindowColor = game::Dvar_RegisterVec4("con_outputWindowColor", 0.25f, 0.25f, 0.25f, 0.85f,

View File

@ -10,6 +10,7 @@ namespace game_console
}; };
void print(int type, const char* fmt, ...); void print(int type, const char* fmt, ...);
void print_internal(const char* fmt, ...);
bool console_char_event(int local_client_num, int key); bool console_char_event(int local_client_num, int key);
bool console_key_event(int local_client_num, int key, int down); bool console_key_event(int local_client_num, int key, int down);

View File

@ -26,8 +26,26 @@ namespace lui
return; return;
} }
game::LUI_OpenMenu(0, params[1], 0, 0, 0);
});
command::add("lui_open_popup", [](const command::params& params)
{
if (params.size() <= 1)
{
game_console::print(game_console::con_type_info, "usage: lui_open_popup <name>\n");
return;
}
game::LUI_OpenMenu(0, params[1], 1, 0, 0); game::LUI_OpenMenu(0, params[1], 1, 0, 0);
}); });
command::add("runMenuScript", [](const command::params& params)
{
const auto args_str = params.join(1);
const auto* args = args_str.data();
game::UI_RunMenuScript(0, &args);
});
} }
}; };
} }

View File

@ -166,7 +166,7 @@ namespace network
const char* description) const char* description)
{ {
auto dvar = game::Dvar_RegisterInt("net_port", 27016, 0, 0xFFFFu, game::DVAR_FLAG_LATCHED, "Network port"); auto dvar = game::Dvar_RegisterInt("net_port", 27016, 0, 0xFFFFu, game::DVAR_FLAG_LATCHED, "Network port");
// read net_port from command line // read net_port from command line
command::read_startup_variable("net_port"); command::read_startup_variable("net_port");
@ -246,9 +246,11 @@ namespace network
// don't try to reconnect client // don't try to reconnect client
utils::hook::call(0x140439D4D, reconnect_migratated_client); utils::hook::call(0x140439D4D, reconnect_migratated_client);
utils::hook::nop(0x140439D28, 4); // this crashes when reconnecting for some reason
// allow server owner to modify net_port before the socket bind // allow server owner to modify net_port before the socket bind
utils::hook::call(0x1404D7A7F, register_netport_stub); utils::hook::call(0x1404D7A3D, register_netport_stub);
utils::hook::call(0x1404D7E28, register_netport_stub);
// ignore built in "print" oob command and add in our own // ignore built in "print" oob command and add in our own
utils::hook::set<uint8_t>(0x14020A723, 0xEB); utils::hook::set<uint8_t>(0x14020A723, 0xEB);

View File

@ -16,6 +16,20 @@ namespace patches
{ {
namespace namespace
{ {
game::dvar_t* register_virtual_lobby_enabled_stub(const char* name, bool value,
const unsigned int /*flags*/,
const char* description)
{
return game::Dvar_RegisterBool(name, false, game::DVAR_FLAG_READ, description);
}
game::dvar_t* register_virtual_lobby_mode_stub(const char* name, int /*value*/, int /*min*/, int /*max*/,
const unsigned int /*flags*/,
const char* description)
{
return game::Dvar_RegisterInt(name, 0, 0, 0, game::DVAR_FLAG_READ, description);
}
utils::hook::detour live_get_local_client_name_hook; utils::hook::detour live_get_local_client_name_hook;
const char* live_get_local_client_name() const char* live_get_local_client_name()
@ -23,21 +37,9 @@ namespace patches
return game::Dvar_FindVar("name")->current.string; return game::Dvar_FindVar("name")->current.string;
} }
utils::hook::detour sv_kick_client_num_hook;
void sv_kick_client_num(const int clientNum, const char* reason)
{
// Don't kick bot to equalize team balance.
if (reason == "EXE_PLAYERKICKED_BOT_BALANCE"s)
{
return;
}
return sv_kick_client_num_hook.invoke<void>(clientNum, reason);
}
utils::hook::detour com_register_dvars_hook; utils::hook::detour com_register_dvars_hook;
void com_register_dvars() void com_register_dvars_stub()
{ {
if (game::environment::is_mp()) if (game::environment::is_mp())
{ {
@ -161,7 +163,7 @@ namespace patches
LoadLibraryA("PhysXUpdateLoader64.dll"); LoadLibraryA("PhysXUpdateLoader64.dll");
// Register dvars // Register dvars
com_register_dvars_hook.create(SELECT_VALUE(0x1402F86F0, 0x1403CF7F0), &com_register_dvars); com_register_dvars_hook.create(SELECT_VALUE(0x1402F86F0, 0x1403CF7F0), &com_register_dvars_stub);
// Unlock fps in main menu // Unlock fps in main menu
utils::hook::set<BYTE>(SELECT_VALUE(0x140144F5B, 0x140213C3B), 0xEB); utils::hook::set<BYTE>(SELECT_VALUE(0x140144F5B, 0x140213C3B), 0xEB);
@ -203,12 +205,12 @@ namespace patches
static void patch_mp() static void patch_mp()
{ {
// Disable virtualLobby
//utils::hook::call(0x1403CFDCC, register_virtual_lobby_enabled_stub);
// Use name dvar // Use name dvar
live_get_local_client_name_hook.create(0x1404D47F0, &live_get_local_client_name); live_get_local_client_name_hook.create(0x1404D47F0, &live_get_local_client_name);
// Patch SV_KickClientNum
sv_kick_client_num_hook.create(0x1404377A0, &sv_kick_client_num);
// block changing name in-game // block changing name in-game
utils::hook::set<uint8_t>(0x140438850, 0xC3); utils::hook::set<uint8_t>(0x140438850, 0xC3);

View File

@ -78,5 +78,24 @@ namespace game
return "Unknown (" + std::to_string(static_cast<int>(mode)) + ")"; return "Unknown (" + std::to_string(static_cast<int>(mode)) + ")";
} }
} }
std::string playmode_to_string(game::CodPlayMode playmode)
{
switch (playmode)
{
case CODPLAYMODE_CORE:
return "Core";
case CODPLAYMODE_ZOMBIES:
return "Zombies";
case CODPLAYMODE_SURVIVAL:
return "Survival";
case CODPLAYMODE_SP:
return "Singleplayer";
case CODPLAYMODE_NONE:
return "None";
default:
return "Unknown (" + std::to_string(static_cast<int>(playmode)) + ")";
}
}
} }
} }