feat(chat): g_deadChat functionality

This commit is contained in:
Diavolo 2023-04-01 14:00:09 +02:00
parent c3304fc1b9
commit 007b7e033b
3 changed files with 54 additions and 8 deletions

View File

@ -1,12 +1,13 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "loader/component_loader.hpp" #include "loader/component_loader.hpp"
#include "chat.hpp"
#include "game/game.hpp" #include "game/game.hpp"
#include "game/utils.hpp" #include "game/utils.hpp"
#include <utils/hook.hpp> #include <utils/hook.hpp>
#include <utils/string.hpp> #include <utils/string.hpp>
#include "chat.hpp"
#include "command.hpp" #include "command.hpp"
#include "client_command.hpp" #include "client_command.hpp"
@ -14,6 +15,8 @@ namespace chat
{ {
namespace namespace
{ {
const game::dvar_t* g_deadChat;
void cmd_say_f(game::gentity_s* ent, const command::params_sv& params) void cmd_say_f(game::gentity_s* ent, const command::params_sv& params)
{ {
if (params.size() < 2) if (params.size() < 2)
@ -57,6 +60,31 @@ namespace chat
{ {
game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE_0, utils::string::va("v \"%Iu %d %d %s\"", -1, 0, 0, text.data())); game::SV_GameSendServerCommand(client_num, game::SV_CMD_RELIABLE_0, utils::string::va("v \"%Iu %d %d %s\"", -1, 0, 0, text.data()));
} }
// This function has probably a different name
void g_say_to_stub(utils::hook::assembler& a)
{
const auto no_dead_chat = a.newLabel();
// game's code
a.mov(rax, qword_ptr(rbx));
a.push(rax);
a.mov(rax, qword_ptr(reinterpret_cast<std::uintptr_t>(&g_deadChat)));
a.mov(al, byte_ptr(rax, 0x28)); // dvar_t.current.value.enabled
a.test(al, al);
a.pop(rax);
a.je(no_dead_chat);
a.jmp(0x140299061_g);
a.bind(no_dead_chat);
a.cmp(dword_ptr(rax, 0x16AE0), 0x0); // game's code
a.jmp(0x14029905B_g);
}
} }
const char* get_client_name(const uint64_t xuid) const char* get_client_name(const uint64_t xuid)
@ -76,6 +104,7 @@ namespace chat
return "Unknown Soldier"; return "Unknown Soldier";
} }
class component final : public generic_component class component final : public generic_component
{ {
public: public:
@ -130,6 +159,9 @@ namespace chat
// Kill say fallback // Kill say fallback
utils::hook::set<uint8_t>(0x1402FF987_g, 0xEB); utils::hook::set<uint8_t>(0x1402FF987_g, 0xEB);
g_deadChat = game::register_dvar_bool("g_deadChat", false, game::DVAR_NONE, "Allow dead players to chat with living players");
utils::hook::jump(0x140299051_g, utils::hook::assemble(g_say_to_stub));
} }
else else
{ {

View File

@ -676,7 +676,8 @@ namespace game
struct DvarValue struct DvarValue
{ {
union { union
{
bool enabled; bool enabled;
int integer; int integer;
uint32_t unsignedInt; uint32_t unsignedInt;
@ -693,27 +694,33 @@ namespace game
union DvarLimits union DvarLimits
{ {
struct { struct
{
int stringCount; int stringCount;
const char** strings; const char** strings;
} enumeration; } enumeration;
struct { struct
{
int min; int min;
int max; int max;
} integer; } integer;
struct { struct
{
int64_t min; int64_t min;
int64_t max; int64_t max;
} integer64; } integer64;
struct { struct
{
uint64_t min; uint64_t min;
uint64_t max; uint64_t max;
} unsignedInt64; } unsignedInt64;
struct { struct
{
float min; float min;
float max; float max;
} value; } value;
struct { struct
{
vec_t min; vec_t min;
vec_t max; vec_t max;
} vector; } vector;

View File

@ -5,6 +5,13 @@
namespace game namespace game
{ {
static_assert(offsetof(dvar_t, debugName) == 8);
static_assert(offsetof(dvar_t, description) == 16);
static_assert(offsetof(dvar_t, flags) == 24);
static_assert(offsetof(dvar_t, type) == 28);
static_assert(offsetof(dvar_t, modified) == 32);
static_assert(offsetof(dvar_t, current) == 40);
std::string get_dvar_string(const char* dvar_name) std::string get_dvar_string(const char* dvar_name)
{ {
const auto* dvar = Dvar_FindVar(dvar_name); const auto* dvar = Dvar_FindVar(dvar_name);