feat(chat): g_deadChat functionality
This commit is contained in:
parent
c3304fc1b9
commit
007b7e033b
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user