iw5-mod/src/module/chat.cpp

66 lines
1.3 KiB
C++

#include <std_include.hpp>
#include <loader/module_loader.hpp>
#include "game/game.hpp"
#include "game_log.hpp"
#include <utils/hook.hpp>
static void notify_on_say(game::native::gentity_s* ent, int mode, const char* message)
{
const auto ent_num = ent->s.number;
game::native::Scr_AddString(message + 1); // First character has nothing to do with actual message
game::native::Scr_AddInt(mode);
game::native::Scr_AddEntityNum(ent_num, 0);
game::native::Scr_NotifyLevel(game::native::SL_GetString("say", 0), 3);
const auto* guid = game::native::mp::SV_GetGuid(ent_num);
const auto* name = game::native::mp::svs_clients[ent_num].name;
if (mode == 0)
{
game_log::g_log_printf("say;%s;%d;%s;%s\n", guid, ent_num, name, message + 1);
}
else
{
game_log::g_log_printf("sayteam;%s;%d;%s;%s\n", guid, ent_num, name, message + 1);
}
}
static __declspec(naked) void g_say_stub()
{
__asm
{
pushad
push [esp + 0x20 + 0x108] // message
push [esp + 0x20 + 0x108] // mode
push ebp // ent
call notify_on_say
add esp, 0xC
popad
push 0x5C2940 // I_strncpyz
retn
}
}
class chat final : public module
{
public:
static_assert(offsetof(game::native::mp::client_t, name) == 0x2142C);
void post_load() override
{
if (game::is_mp())
{
utils::hook(0x502BAF, &g_say_stub, HOOK_CALL).install()->quick(); // I_strncpyz
}
}
};
REGISTER_MODULE(chat)