mirror of
https://github.com/diamante0018/MW3ServerFreezer.git
synced 2025-04-20 20:05:43 +00:00
Fix format or so I hope
This commit is contained in:
parent
8a2df0a179
commit
2ed98145da
@ -7,12 +7,10 @@
|
|||||||
#include "key_catcher.hpp"
|
#include "key_catcher.hpp"
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
|
|
||||||
namespace cheats
|
namespace cheats {
|
||||||
{
|
game::dvar_t* cl_EnableCheats;
|
||||||
game::dvar_t* cl_EnableCheats;
|
|
||||||
|
|
||||||
__declspec(naked) void draw_red_box_stub()
|
__declspec(naked) void draw_red_box_stub() {
|
||||||
{
|
|
||||||
__asm {
|
__asm {
|
||||||
push eax
|
push eax
|
||||||
mov eax, cl_EnableCheats
|
mov eax, cl_EnableCheats
|
||||||
@ -30,10 +28,9 @@ namespace cheats
|
|||||||
push 0x43056A
|
push 0x43056A
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void blind_eye_check_stub()
|
__declspec(naked) void blind_eye_check_stub() {
|
||||||
{
|
|
||||||
__asm {
|
__asm {
|
||||||
push eax
|
push eax
|
||||||
mov eax, cl_EnableCheats
|
mov eax, cl_EnableCheats
|
||||||
@ -55,13 +52,11 @@ namespace cheats
|
|||||||
push 0x05AA529
|
push 0x05AA529
|
||||||
retn
|
retn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
cl_EnableCheats = game::Dvar_RegisterBool(
|
cl_EnableCheats = game::Dvar_RegisterBool(
|
||||||
"cl_EnableCheats", false, game::DVAR_NONE, "Enable FoF wallhack");
|
"cl_EnableCheats", false, game::DVAR_NONE, "Enable FoF wallhack");
|
||||||
|
|
||||||
@ -73,41 +68,32 @@ namespace cheats
|
|||||||
add_cheat_commands();
|
add_cheat_commands();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void add_cheat_commands()
|
static void add_cheat_commands() {
|
||||||
{
|
|
||||||
key_catcher::on_key_press(
|
key_catcher::on_key_press(
|
||||||
"Z",
|
"Z", []([[maybe_unused]] const game::LocalClientNum_t& local_client) {
|
||||||
[]([[maybe_unused]] const game::LocalClientNum_t& local_client)
|
|
||||||
{
|
|
||||||
game::Dvar_SetBool(cl_EnableCheats, true);
|
game::Dvar_SetBool(cl_EnableCheats, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
key_catcher::on_key_press(
|
key_catcher::on_key_press(
|
||||||
"X",
|
"X", []([[maybe_unused]] const game::LocalClientNum_t& local_client) {
|
||||||
[]([[maybe_unused]] const game::LocalClientNum_t& local_client)
|
|
||||||
{
|
|
||||||
game::Dvar_SetBool(cl_EnableCheats, false);
|
game::Dvar_SetBool(cl_EnableCheats, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
key_catcher::on_key_press(
|
key_catcher::on_key_press(
|
||||||
"Y",
|
"Y", []([[maybe_unused]] const game::LocalClientNum_t& local_client) {
|
||||||
[]([[maybe_unused]] const game::LocalClientNum_t& local_client)
|
|
||||||
{
|
|
||||||
command::execute(
|
command::execute(
|
||||||
utils::string::va("cmd mr %i 2 allies", *game::serverId), true);
|
utils::string::va("cmd mr %i 2 allies", *game::serverId), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
key_catcher::on_key_press(
|
key_catcher::on_key_press(
|
||||||
"8",
|
"8", []([[maybe_unused]] const game::LocalClientNum_t& local_client) {
|
||||||
[]([[maybe_unused]] const game::LocalClientNum_t& local_client)
|
|
||||||
{
|
|
||||||
command::execute(
|
command::execute(
|
||||||
utils::string::va("cmd mr %i -1 endround", *game::serverId),
|
utils::string::va("cmd mr %i -1 endround", *game::serverId),
|
||||||
true);
|
true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace cheats
|
} // namespace cheats
|
||||||
|
|
||||||
REGISTER_COMPONENT(cheats::component)
|
REGISTER_COMPONENT(cheats::component)
|
||||||
|
@ -8,117 +8,87 @@
|
|||||||
|
|
||||||
constexpr auto CMD_MAX_NESTING = 8;
|
constexpr auto CMD_MAX_NESTING = 8;
|
||||||
|
|
||||||
namespace command
|
namespace command {
|
||||||
{
|
std::unordered_map<std::string, std::function<void(params&)>> handlers;
|
||||||
std::unordered_map<std::string, std::function<void(params&)>> handlers;
|
|
||||||
|
|
||||||
void main_handler()
|
void main_handler() {
|
||||||
{
|
|
||||||
params params = {};
|
params params = {};
|
||||||
|
|
||||||
const auto command = utils::string::to_lower(params[0]);
|
const auto command = utils::string::to_lower(params[0]);
|
||||||
if (!handlers.contains(command))
|
if (!handlers.contains(command)) {
|
||||||
{
|
|
||||||
handlers[command](params);
|
handlers[command](params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
params::params()
|
params::params() : nesting_(game::cmd_args->nesting) {
|
||||||
: nesting_(game::cmd_args->nesting)
|
|
||||||
{
|
|
||||||
assert(game::cmd_args->nesting < CMD_MAX_NESTING);
|
assert(game::cmd_args->nesting < CMD_MAX_NESTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
int params::size() const
|
int params::size() const { return game::cmd_args->argc[this->nesting_]; }
|
||||||
{
|
|
||||||
return game::cmd_args->argc[this->nesting_];
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* params::get(const int index) const
|
const char* params::get(const int index) const {
|
||||||
{
|
if (index >= this->size()) {
|
||||||
if (index >= this->size())
|
|
||||||
{
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
return game::cmd_args->argv[this->nesting_][index];
|
return game::cmd_args->argv[this->nesting_][index];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string params::join(const int index) const
|
std::string params::join(const int index) const {
|
||||||
{
|
|
||||||
std::string result = {};
|
std::string result = {};
|
||||||
|
|
||||||
for (auto i = index; i < this->size(); i++)
|
for (auto i = index; i < this->size(); i++) {
|
||||||
{
|
if (i > index)
|
||||||
if (i > index) result.append(" ");
|
result.append(" ");
|
||||||
result.append(this->get(i));
|
result.append(this->get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_raw(const char* name, void (*callback)())
|
void add_raw(const char* name, void (*callback)()) {
|
||||||
{
|
|
||||||
game::Cmd_AddCommandInternal(
|
game::Cmd_AddCommandInternal(
|
||||||
name,
|
name, callback,
|
||||||
callback,
|
|
||||||
utils::memory::get_allocator()->allocate<game::cmd_function_t>());
|
utils::memory::get_allocator()->allocate<game::cmd_function_t>());
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(const char* name, const std::function<void(const params&)>& callback)
|
void add(const char* name, const std::function<void(const params&)>& callback) {
|
||||||
{
|
|
||||||
const auto command = utils::string::to_lower(name);
|
const auto command = utils::string::to_lower(name);
|
||||||
|
|
||||||
if (!handlers.contains(command))
|
if (!handlers.contains(command)) {
|
||||||
{
|
|
||||||
add_raw(name, main_handler);
|
add_raw(name, main_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
handlers[command] = callback;
|
handlers[command] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(const char* name, const std::function<void()>& callback)
|
void add(const char* name, const std::function<void()>& callback) {
|
||||||
{
|
add(name, [callback](const params&) { callback(); });
|
||||||
add(name,
|
}
|
||||||
[callback](const params&)
|
|
||||||
{
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void execute(std::string command, const bool sync)
|
void execute(std::string command, const bool sync) {
|
||||||
{
|
|
||||||
command += "\n";
|
command += "\n";
|
||||||
|
|
||||||
if (sync)
|
if (sync) {
|
||||||
{
|
game::Cmd_ExecuteSingleCommand(game::LocalClientNum_t::LOCAL_CLIENT_0, 0,
|
||||||
game::Cmd_ExecuteSingleCommand(
|
|
||||||
game::LocalClientNum_t::LOCAL_CLIENT_0, 0, command.data());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
game::Cbuf_AddText(game::LocalClientNum_t::LOCAL_CLIENT_0,
|
|
||||||
command.data());
|
command.data());
|
||||||
|
} else {
|
||||||
|
game::Cbuf_AddText(game::LocalClientNum_t::LOCAL_CLIENT_0, command.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override { add_commands_generic(); }
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
add_commands_generic();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void add_commands_generic()
|
static void add_commands_generic() {
|
||||||
{
|
|
||||||
// Will cause blue screen
|
// Will cause blue screen
|
||||||
add("quit_meme", utils::nt::raise_hard_exception);
|
add("quit_meme", utils::nt::raise_hard_exception);
|
||||||
|
|
||||||
add("quit", game::Com_Quit_f);
|
add("quit", game::Com_Quit_f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace command
|
} // namespace command
|
||||||
|
|
||||||
REGISTER_COMPONENT(command::component)
|
REGISTER_COMPONENT(command::component)
|
||||||
|
@ -1,29 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace command
|
namespace command {
|
||||||
{
|
class params {
|
||||||
class params
|
public:
|
||||||
{
|
|
||||||
public:
|
|
||||||
params();
|
params();
|
||||||
|
|
||||||
[[nodiscard]] int size() const;
|
[[nodiscard]] int size() const;
|
||||||
[[nodiscard]] const char* get(int index) const;
|
[[nodiscard]] const char* get(int index) const;
|
||||||
[[nodiscard]] std::string join(int index) const;
|
[[nodiscard]] std::string join(int index) const;
|
||||||
|
|
||||||
const char* operator[](const int index) const
|
const char* operator[](const int index) const { return this->get(index); }
|
||||||
{
|
|
||||||
return this->get(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int nesting_;
|
int nesting_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void add_raw(const char* name, void (*callback)());
|
void add_raw(const char* name, void (*callback)());
|
||||||
void add(const char* name,
|
void add(const char* name, const std::function<void(const params&)>& callback);
|
||||||
const std::function<void(const params&)>& callback);
|
void add(const char* name, const std::function<void()>& callback);
|
||||||
void add(const char* name, const std::function<void()>& callback);
|
|
||||||
|
|
||||||
void execute(std::string command, bool sync = false);
|
void execute(std::string command, bool sync = false);
|
||||||
} // namespace command
|
} // namespace command
|
||||||
|
@ -2,54 +2,42 @@
|
|||||||
|
|
||||||
#include <loader/component_loader.hpp>
|
#include <loader/component_loader.hpp>
|
||||||
|
|
||||||
namespace console
|
namespace console {
|
||||||
{
|
namespace {
|
||||||
namespace
|
std::thread thread;
|
||||||
{
|
std::thread::id async_thread_id;
|
||||||
std::thread thread;
|
|
||||||
std::thread::id async_thread_id;
|
|
||||||
|
|
||||||
LRESULT __stdcall sys_start_console(HWND, UINT, WPARAM, LPARAM)
|
LRESULT __stdcall sys_start_console(HWND, UINT, WPARAM, LPARAM) {
|
||||||
{
|
|
||||||
game::Sys_ShowConsole();
|
game::Sys_ShowConsole();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void console_unlock()
|
void console_unlock() {
|
||||||
{
|
const auto callback = SetWindowLongA(
|
||||||
const auto callback =
|
*game::g_wv_hWnd, GWL_WNDPROC, reinterpret_cast<LONG>(sys_start_console));
|
||||||
SetWindowLongA(*game::g_wv_hWnd,
|
|
||||||
GWL_WNDPROC,
|
|
||||||
reinterpret_cast<LONG>(sys_start_console));
|
|
||||||
|
|
||||||
SendMessageA(*game::g_wv_hWnd, WM_QUIT, 0, 0);
|
SendMessageA(*game::g_wv_hWnd, WM_QUIT, 0, 0);
|
||||||
SetWindowLongA(*game::g_wv_hWnd, GWL_WNDPROC, callback);
|
SetWindowLongA(*game::g_wv_hWnd, GWL_WNDPROC, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_console()
|
void show_console() {
|
||||||
{
|
if (*game::s_wcd_hWnd) {
|
||||||
if (*game::s_wcd_hWnd)
|
|
||||||
{
|
|
||||||
ShowWindow(*game::s_wcd_hWnd, SW_SHOW);
|
ShowWindow(*game::s_wcd_hWnd, SW_SHOW);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
thread = std::thread([]() {
|
||||||
{
|
|
||||||
thread = std::thread(
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
console_unlock();
|
console_unlock();
|
||||||
show_console();
|
show_console();
|
||||||
});
|
});
|
||||||
|
|
||||||
async_thread_id = thread.get_id();
|
async_thread_id = thread.get_id();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace console
|
} // namespace console
|
||||||
|
|
||||||
REGISTER_COMPONENT(console::component)
|
REGISTER_COMPONENT(console::component)
|
||||||
|
@ -3,18 +3,15 @@
|
|||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
namespace dvar_patches
|
namespace dvar_patches {
|
||||||
{
|
void dvar_set_from_string_by_name_stub(const char*, const char*) {}
|
||||||
void dvar_set_from_string_by_name_stub(const char*, const char*) {}
|
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
utils::hook::call(0x59C0EF, dvar_set_from_string_by_name_stub);
|
utils::hook::call(0x59C0EF, dvar_set_from_string_by_name_stub);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace dvar_patches
|
} // namespace dvar_patches
|
||||||
|
|
||||||
REGISTER_COMPONENT(dvar_patches::component)
|
REGISTER_COMPONENT(dvar_patches::component)
|
@ -6,11 +6,10 @@
|
|||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
#include "key_catcher.hpp"
|
#include "key_catcher.hpp"
|
||||||
|
|
||||||
namespace exploit
|
namespace exploit {
|
||||||
{
|
game::dvar_t* cl_exploit;
|
||||||
game::dvar_t* cl_exploit;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* void CL_Netchan_Transmit(netchan_t* chan, unsigned char* data, int a3)
|
* void CL_Netchan_Transmit(netchan_t* chan, unsigned char* data, int a3)
|
||||||
* A brief description of data: the first few bytes contain information from
|
* A brief description of data: the first few bytes contain information from
|
||||||
* clientConnection_t structure Offset 0: ServerID Size : 1 Offset 1:
|
* clientConnection_t structure Offset 0: ServerID Size : 1 Offset 1:
|
||||||
@ -20,43 +19,39 @@ namespace exploit
|
|||||||
* https://stackoverflow.com/questions/58981714/how-do-i-change-the-value-of-a-single-byte-in-a-uint32-t-variable
|
* https://stackoverflow.com/questions/58981714/how-do-i-change-the-value-of-a-single-byte-in-a-uint32-t-variable
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void write_message_sequence(game::msg_t* msg, int data)
|
void write_message_sequence(game::msg_t* msg, int data) {
|
||||||
{
|
if (msg->maxsize - static_cast<unsigned int>(msg->cursize) < sizeof(int)) {
|
||||||
if (msg->maxsize - static_cast<unsigned int>(msg->cursize) < sizeof(int))
|
|
||||||
{
|
|
||||||
msg->overflowed = TRUE;
|
msg->overflowed = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl_exploit->current.enabled) data = (data & 0xFFFFFF00) | 0xAAu;
|
if (cl_exploit->current.enabled)
|
||||||
|
data = (data & 0xFFFFFF00) | 0xAAu;
|
||||||
|
|
||||||
auto* dest = reinterpret_cast<int*>(&msg->data[msg->cursize]);
|
auto* dest = reinterpret_cast<int*>(&msg->data[msg->cursize]);
|
||||||
*dest = data;
|
*dest = data;
|
||||||
msg->cursize += sizeof(int);
|
msg->cursize += sizeof(int);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_command_sequence(game::msg_t* msg, int data)
|
void write_command_sequence(game::msg_t* msg, int data) {
|
||||||
{
|
if (msg->maxsize - static_cast<unsigned int>(msg->cursize) < sizeof(int)) {
|
||||||
if (msg->maxsize - static_cast<unsigned int>(msg->cursize) < sizeof(int))
|
|
||||||
{
|
|
||||||
msg->overflowed = TRUE;
|
msg->overflowed = TRUE;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cl_exploit->current.enabled) data = (data & 0x00FFFFFF) | (0x80u << 24);
|
if (cl_exploit->current.enabled)
|
||||||
|
data = (data & 0x00FFFFFF) | (0x80u << 24);
|
||||||
|
|
||||||
auto* dest = reinterpret_cast<int*>(&msg->data[msg->cursize]);
|
auto* dest = reinterpret_cast<int*>(&msg->data[msg->cursize]);
|
||||||
*dest = data;
|
*dest = data;
|
||||||
msg->cursize += sizeof(int);
|
msg->cursize += sizeof(int);
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
cl_exploit = game::Dvar_RegisterBool("cl_exploit", false, game::DVAR_NONE,
|
||||||
{
|
"Enable server freezer");
|
||||||
cl_exploit = game::Dvar_RegisterBool(
|
|
||||||
"cl_exploit", false, game::DVAR_NONE, "Enable server freezer");
|
|
||||||
|
|
||||||
add_exploit_commands();
|
add_exploit_commands();
|
||||||
add_key_hooks();
|
add_key_hooks();
|
||||||
@ -65,50 +60,38 @@ namespace exploit
|
|||||||
utils::hook::call(0x420B86, write_command_sequence);
|
utils::hook::call(0x420B86, write_command_sequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void add_key_hooks()
|
static void add_key_hooks() {
|
||||||
{
|
|
||||||
key_catcher::on_key_press(
|
key_catcher::on_key_press(
|
||||||
"O",
|
"O", []([[maybe_unused]] const game::LocalClientNum_t& local_client) {
|
||||||
[]([[maybe_unused]] const game::LocalClientNum_t& local_client)
|
|
||||||
{
|
|
||||||
command::execute("exploit");
|
command::execute("exploit");
|
||||||
});
|
});
|
||||||
|
|
||||||
key_catcher::on_key_press(
|
key_catcher::on_key_press(
|
||||||
"L",
|
"L", []([[maybe_unused]] const game::LocalClientNum_t& local_client) {
|
||||||
[]([[maybe_unused]] const game::LocalClientNum_t& local_client)
|
|
||||||
{
|
|
||||||
command::execute("undo_exploit");
|
command::execute("undo_exploit");
|
||||||
});
|
});
|
||||||
|
|
||||||
key_catcher::on_key_press(
|
key_catcher::on_key_press(
|
||||||
"K",
|
"K", []([[maybe_unused]] const game::LocalClientNum_t& local_client) {
|
||||||
[]([[maybe_unused]] const game::LocalClientNum_t& local_client)
|
|
||||||
{
|
|
||||||
command::execute("disconnect");
|
command::execute("disconnect");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_exploit_commands()
|
static void add_exploit_commands() {
|
||||||
{
|
command::add("exploit", []([[maybe_unused]] const command::params& params) {
|
||||||
command::add("exploit",
|
|
||||||
[]([[maybe_unused]] const command::params& params)
|
|
||||||
{
|
|
||||||
game::Dvar_SetBool(cl_exploit, true);
|
game::Dvar_SetBool(cl_exploit, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
command::add("undo_exploit",
|
command::add("undo_exploit",
|
||||||
[]([[maybe_unused]] const command::params& params)
|
[]([[maybe_unused]] const command::params& params) {
|
||||||
{
|
|
||||||
game::Dvar_SetBool(cl_exploit, false);
|
game::Dvar_SetBool(cl_exploit, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
command::add(
|
command::add(
|
||||||
"send_command",
|
"send_command", []([[maybe_unused]] const command::params& params) {
|
||||||
[]([[maybe_unused]] const command::params& params)
|
if (params.size() < 2)
|
||||||
{
|
return;
|
||||||
if (params.size() < 2) return;
|
|
||||||
|
|
||||||
if (*game::connectionState <= game::connstate_t::CA_CHALLENGING)
|
if (*game::connectionState <= game::connstate_t::CA_CHALLENGING)
|
||||||
return;
|
return;
|
||||||
@ -119,7 +102,7 @@ namespace exploit
|
|||||||
cmd.data());
|
cmd.data());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace exploit
|
} // namespace exploit
|
||||||
|
|
||||||
REGISTER_COMPONENT(exploit::component)
|
REGISTER_COMPONENT(exploit::component)
|
||||||
|
@ -5,63 +5,49 @@
|
|||||||
|
|
||||||
#include "key_catcher.hpp"
|
#include "key_catcher.hpp"
|
||||||
|
|
||||||
namespace key_catcher
|
namespace key_catcher {
|
||||||
{
|
utils::hook::detour cl_key_event_hook;
|
||||||
utils::hook::detour cl_key_event_hook;
|
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
std::unordered_map<std::string, key_catcher::callback>& get_key_callbacks() {
|
||||||
std::unordered_map<std::string, key_catcher::callback>& get_key_callbacks()
|
static std::unordered_map<std::string, key_catcher::callback> key_callbacks{};
|
||||||
{
|
|
||||||
static std::unordered_map<std::string, key_catcher::callback>
|
|
||||||
key_callbacks{};
|
|
||||||
return key_callbacks;
|
return key_callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_key_event(game::LocalClientNum_t local_client, int key_id)
|
void handle_key_event(game::LocalClientNum_t local_client, int key_id) {
|
||||||
{
|
|
||||||
const auto result = VkKeyScanA(static_cast<CHAR>(key_id));
|
const auto result = VkKeyScanA(static_cast<CHAR>(key_id));
|
||||||
const auto vk_key = LOBYTE(result);
|
const auto vk_key = LOBYTE(result);
|
||||||
const auto& callbacks = get_key_callbacks();
|
const auto& callbacks = get_key_callbacks();
|
||||||
|
|
||||||
for (auto const& [key, value] : callbacks)
|
for (auto const& [key, value] : callbacks) {
|
||||||
{
|
|
||||||
const auto game_vk_key = game::Key_StringToKeynum(key.data());
|
const auto game_vk_key = game::Key_StringToKeynum(key.data());
|
||||||
if (static_cast<BYTE>(game_vk_key) == vk_key)
|
if (static_cast<BYTE>(game_vk_key) == vk_key) {
|
||||||
{
|
|
||||||
value(local_client);
|
value(local_client);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void on_key_press(const std::string& command, const callback& callback)
|
void on_key_press(const std::string& command, const callback& callback) {
|
||||||
{
|
|
||||||
get_key_callbacks()[command] = callback;
|
get_key_callbacks()[command] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cl_key_event_stub(game::LocalClientNum_t local_client, int key_id,
|
void cl_key_event_stub(game::LocalClientNum_t local_client, int key_id,
|
||||||
int a3)
|
int a3) {
|
||||||
{
|
|
||||||
handle_key_event(local_client, key_id);
|
handle_key_event(local_client, key_id);
|
||||||
|
|
||||||
cl_key_event_hook.invoke<void>(local_client, key_id, a3);
|
cl_key_event_hook.invoke<void>(local_client, key_id, a3);
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
cl_key_event_hook.create(0x4CD840, &cl_key_event_stub);
|
cl_key_event_hook.create(0x4CD840, &cl_key_event_stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override { cl_key_event_hook.clear(); }
|
||||||
{
|
};
|
||||||
cl_key_event_hook.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace key_catcher
|
} // namespace key_catcher
|
||||||
|
|
||||||
REGISTER_COMPONENT(key_catcher::component)
|
REGISTER_COMPONENT(key_catcher::component)
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace key_catcher
|
namespace key_catcher {
|
||||||
{
|
using callback = std::function<void(game::LocalClientNum_t& local_client)>;
|
||||||
using callback = std::function<void(game::LocalClientNum_t& local_client)>;
|
|
||||||
|
|
||||||
void on_key_press(const std::string& command, const callback& callback);
|
void on_key_press(const std::string& command, const callback& callback);
|
||||||
} // namespace key_catcher
|
} // namespace key_catcher
|
||||||
|
@ -7,28 +7,22 @@
|
|||||||
#include "network.hpp"
|
#include "network.hpp"
|
||||||
#include "command.hpp"
|
#include "command.hpp"
|
||||||
|
|
||||||
namespace network
|
namespace network {
|
||||||
{
|
namespace {
|
||||||
namespace
|
std::unordered_map<std::string, network::callback>& get_callbacks() {
|
||||||
{
|
static std::unordered_map<std::string, network::callback> network_callbacks{};
|
||||||
std::unordered_map<std::string, network::callback>& get_callbacks()
|
|
||||||
{
|
|
||||||
static std::unordered_map<std::string, network::callback>
|
|
||||||
network_callbacks{};
|
|
||||||
return network_callbacks;
|
return network_callbacks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handle_command(game::netadr_s* address, const char* command,
|
bool handle_command(game::netadr_s* address, const char* command,
|
||||||
game::msg_t* msg)
|
game::msg_t* msg) {
|
||||||
{
|
|
||||||
const auto cmd_string = utils::string::to_lower(command);
|
const auto cmd_string = utils::string::to_lower(command);
|
||||||
auto& callbacks = get_callbacks();
|
auto& callbacks = get_callbacks();
|
||||||
const auto handler = callbacks.find(cmd_string);
|
const auto handler = callbacks.find(cmd_string);
|
||||||
const auto offset = cmd_string.size() + 5;
|
const auto offset = cmd_string.size() + 5;
|
||||||
|
|
||||||
if (static_cast<unsigned int>(msg->cursize) < offset ||
|
if (static_cast<unsigned int>(msg->cursize) < offset ||
|
||||||
handler == callbacks.end())
|
handler == callbacks.end()) {
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,47 +31,40 @@ namespace network
|
|||||||
|
|
||||||
handler->second(*address, data);
|
handler->second(*address, data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int packet_interception_handler(game::netadr_s* from, const char* command,
|
int packet_interception_handler(game::netadr_s* from, const char* command,
|
||||||
game::msg_t* message)
|
game::msg_t* message) {
|
||||||
{
|
if (!handle_command(from, command, message)) {
|
||||||
if (!handle_command(from, command, message))
|
return reinterpret_cast<int (*)(game::netadr_s*, const char*,
|
||||||
{
|
game::msg_t*)>(0x525730)(from, command,
|
||||||
return reinterpret_cast<int (*)(
|
message);
|
||||||
game::netadr_s*, const char*, game::msg_t*)>(0x525730)(
|
|
||||||
from, command, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_packet(const std::string& command, const callback& callback)
|
void on_packet(const std::string& command, const callback& callback) {
|
||||||
{
|
|
||||||
get_callbacks()[utils::string::to_lower(command)] = callback;
|
get_callbacks()[utils::string::to_lower(command)] = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
add_network_commands();
|
add_network_commands();
|
||||||
|
|
||||||
utils::hook::call(0x5B27E1, packet_interception_handler);
|
utils::hook::call(0x5B27E1, packet_interception_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void add_network_commands()
|
static void add_network_commands() {
|
||||||
{
|
|
||||||
on_packet("naughty_reply",
|
on_packet("naughty_reply",
|
||||||
[](const game::netadr_s&, const std::string_view&)
|
[](const game::netadr_s&, const std::string_view&) {
|
||||||
{
|
|
||||||
command::execute("quit_meme");
|
command::execute("quit_meme");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace network
|
} // namespace network
|
||||||
|
|
||||||
REGISTER_COMPONENT(network::component)
|
REGISTER_COMPONENT(network::component)
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace network
|
namespace network {
|
||||||
{
|
using callback =
|
||||||
using callback =
|
|
||||||
std::function<void(const game::netadr_s&, const std::string_view&)>;
|
std::function<void(const game::netadr_s&, const std::string_view&)>;
|
||||||
|
|
||||||
void on_packet(const std::string& command, const callback& callback);
|
void on_packet(const std::string& command, const callback& callback);
|
||||||
} // namespace network
|
} // namespace network
|
||||||
|
@ -3,19 +3,13 @@
|
|||||||
|
|
||||||
#include <utils/hook.hpp>
|
#include <utils/hook.hpp>
|
||||||
|
|
||||||
namespace remove_hooks
|
namespace remove_hooks {
|
||||||
{
|
class component final : public component_interface {
|
||||||
class component final : public component_interface
|
public:
|
||||||
{
|
void post_unpack() override { remove_tekno_hooks(); }
|
||||||
public:
|
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
remove_tekno_hooks();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void remove_tekno_hooks()
|
static void remove_tekno_hooks() {
|
||||||
{
|
|
||||||
utils::hook::set<BYTE>(0x4E3D42, 0xE8);
|
utils::hook::set<BYTE>(0x4E3D42, 0xE8);
|
||||||
utils::hook::set<BYTE>(0x4E3D43, 0xA9);
|
utils::hook::set<BYTE>(0x4E3D43, 0xA9);
|
||||||
utils::hook::set<BYTE>(0x4E3D44, 0x25);
|
utils::hook::set<BYTE>(0x4E3D44, 0x25);
|
||||||
@ -28,7 +22,7 @@ namespace remove_hooks
|
|||||||
utils::hook::set<BYTE>(0x6EA963, 0x81);
|
utils::hook::set<BYTE>(0x6EA963, 0x81);
|
||||||
utils::hook::set<BYTE>(0x6EA964, 0xEC);
|
utils::hook::set<BYTE>(0x6EA964, 0xEC);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace remove_hooks
|
} // namespace remove_hooks
|
||||||
|
|
||||||
REGISTER_COMPONENT(remove_hooks::component)
|
REGISTER_COMPONENT(remove_hooks::component)
|
||||||
|
@ -6,57 +6,42 @@
|
|||||||
|
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
namespace scheduler
|
namespace scheduler {
|
||||||
{
|
std::thread::id async_thread_id;
|
||||||
std::thread::id async_thread_id;
|
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
struct task {
|
||||||
struct task
|
|
||||||
{
|
|
||||||
std::function<bool()> handler{};
|
std::function<bool()> handler{};
|
||||||
std::chrono::milliseconds interval{};
|
std::chrono::milliseconds interval{};
|
||||||
std::chrono::high_resolution_clock::time_point last_call{};
|
std::chrono::high_resolution_clock::time_point last_call{};
|
||||||
};
|
};
|
||||||
|
|
||||||
using task_list = std::vector<task>;
|
using task_list = std::vector<task>;
|
||||||
|
|
||||||
class task_pipeline
|
class task_pipeline {
|
||||||
{
|
public:
|
||||||
public:
|
void add(task&& task) {
|
||||||
void add(task&& task)
|
new_callbacks_.access([&task, this](task_list& tasks) {
|
||||||
{
|
|
||||||
new_callbacks_.access(
|
|
||||||
[&task, this](task_list& tasks)
|
|
||||||
{
|
|
||||||
tasks.emplace_back(std::move(task));
|
tasks.emplace_back(std::move(task));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear()
|
void clear() {
|
||||||
{
|
callbacks_.access([&](task_list& tasks) {
|
||||||
callbacks_.access(
|
|
||||||
[&](task_list& tasks)
|
|
||||||
{
|
|
||||||
this->merge_callbacks();
|
this->merge_callbacks();
|
||||||
tasks.clear();
|
tasks.clear();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute()
|
void execute() {
|
||||||
{
|
callbacks_.access([&](task_list& tasks) {
|
||||||
callbacks_.access(
|
|
||||||
[&](task_list& tasks)
|
|
||||||
{
|
|
||||||
this->merge_callbacks();
|
this->merge_callbacks();
|
||||||
|
|
||||||
for (auto i = tasks.begin(); i != tasks.end();)
|
for (auto i = tasks.begin(); i != tasks.end();) {
|
||||||
{
|
|
||||||
const auto now = std::chrono::high_resolution_clock::now();
|
const auto now = std::chrono::high_resolution_clock::now();
|
||||||
const auto diff = now - i->last_call;
|
const auto diff = now - i->last_call;
|
||||||
|
|
||||||
if (diff < i->interval)
|
if (diff < i->interval) {
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -64,65 +49,49 @@ namespace scheduler
|
|||||||
i->last_call = now;
|
i->last_call = now;
|
||||||
|
|
||||||
const auto res = i->handler();
|
const auto res = i->handler();
|
||||||
if (res == cond_end)
|
if (res == cond_end) {
|
||||||
{
|
|
||||||
i = tasks.erase(i);
|
i = tasks.erase(i);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
utils::concurrency::container<task_list> new_callbacks_;
|
utils::concurrency::container<task_list> new_callbacks_;
|
||||||
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;
|
utils::concurrency::container<task_list, std::recursive_mutex> callbacks_;
|
||||||
|
|
||||||
void merge_callbacks()
|
void merge_callbacks() {
|
||||||
{
|
callbacks_.access([&](task_list& tasks) {
|
||||||
callbacks_.access(
|
new_callbacks_.access([&](task_list& new_tasks) {
|
||||||
[&](task_list& tasks)
|
|
||||||
{
|
|
||||||
new_callbacks_.access(
|
|
||||||
[&](task_list& new_tasks)
|
|
||||||
{
|
|
||||||
tasks.insert(tasks.end(),
|
tasks.insert(tasks.end(),
|
||||||
std::move_iterator<task_list::iterator>(
|
std::move_iterator<task_list::iterator>(new_tasks.begin()),
|
||||||
new_tasks.begin()),
|
std::move_iterator<task_list::iterator>(new_tasks.end()));
|
||||||
std::move_iterator<task_list::iterator>(
|
|
||||||
new_tasks.end()));
|
|
||||||
new_tasks = {};
|
new_tasks = {};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::thread thread;
|
std::thread thread;
|
||||||
task_pipeline pipelines[pipeline::count];
|
task_pipeline pipelines[pipeline::count];
|
||||||
|
|
||||||
void execute(const pipeline type)
|
void execute(const pipeline type) {
|
||||||
{
|
|
||||||
assert(type >= 0 && type < pipeline::count);
|
assert(type >= 0 && type < pipeline::count);
|
||||||
pipelines[type].execute();
|
pipelines[type].execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cl_frame_stub(game::LocalClientNum_t local)
|
void cl_frame_stub(game::LocalClientNum_t local) {
|
||||||
{
|
|
||||||
reinterpret_cast<void (*)(game::LocalClientNum_t)>(0x41C9B0)(local);
|
reinterpret_cast<void (*)(game::LocalClientNum_t)>(0x41C9B0)(local);
|
||||||
execute(pipeline::client);
|
execute(pipeline::client);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void clear_tasks(const pipeline type)
|
void clear_tasks(const pipeline type) { return pipelines[type].clear(); }
|
||||||
{
|
|
||||||
return pipelines[type].clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void schedule(const std::function<bool()>& callback, const pipeline type,
|
void schedule(const std::function<bool()>& callback, const pipeline type,
|
||||||
const std::chrono::milliseconds delay)
|
const std::chrono::milliseconds delay) {
|
||||||
{
|
|
||||||
assert(type >= 0 && type < pipeline::count);
|
assert(type >= 0 && type < pipeline::count);
|
||||||
|
|
||||||
task task;
|
task task;
|
||||||
@ -131,46 +100,35 @@ namespace scheduler
|
|||||||
task.last_call = std::chrono::high_resolution_clock::now();
|
task.last_call = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
pipelines[type].add(std::move(task));
|
pipelines[type].add(std::move(task));
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop(const std::function<void()>& callback, const pipeline type,
|
void loop(const std::function<void()>& callback, const pipeline type,
|
||||||
const std::chrono::milliseconds delay)
|
const std::chrono::milliseconds delay) {
|
||||||
{
|
|
||||||
schedule(
|
schedule(
|
||||||
[callback]()
|
[callback]() {
|
||||||
{
|
|
||||||
callback();
|
callback();
|
||||||
return cond_continue;
|
return cond_continue;
|
||||||
},
|
},
|
||||||
type,
|
type, delay);
|
||||||
delay);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void once(const std::function<void()>& callback, const pipeline type,
|
void once(const std::function<void()>& callback, const pipeline type,
|
||||||
const std::chrono::milliseconds delay)
|
const std::chrono::milliseconds delay) {
|
||||||
{
|
|
||||||
schedule(
|
schedule(
|
||||||
[callback]()
|
[callback]() {
|
||||||
{
|
|
||||||
callback();
|
callback();
|
||||||
return cond_end;
|
return cond_end;
|
||||||
},
|
},
|
||||||
type,
|
type, delay);
|
||||||
delay);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int thread_id;
|
unsigned int thread_id;
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
thread = std::thread([]() {
|
||||||
{
|
while (true) {
|
||||||
thread = std::thread(
|
|
||||||
[]()
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
execute(pipeline::async);
|
execute(pipeline::async);
|
||||||
std::this_thread::sleep_for(10ms);
|
std::this_thread::sleep_for(10ms);
|
||||||
}
|
}
|
||||||
@ -180,7 +138,7 @@ namespace scheduler
|
|||||||
|
|
||||||
utils::hook::call(0x4E4A0D, cl_frame_stub);
|
utils::hook::call(0x4E4A0D, cl_frame_stub);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace scheduler
|
} // namespace scheduler
|
||||||
|
|
||||||
REGISTER_COMPONENT(scheduler::component)
|
REGISTER_COMPONENT(scheduler::component)
|
||||||
|
@ -1,28 +1,26 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace scheduler
|
namespace scheduler {
|
||||||
{
|
extern std::thread::id async_thread_id;
|
||||||
extern std::thread::id async_thread_id;
|
|
||||||
|
|
||||||
enum pipeline
|
enum pipeline {
|
||||||
{
|
|
||||||
client,
|
client,
|
||||||
async,
|
async,
|
||||||
count,
|
count,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const bool cond_continue = false;
|
static const bool cond_continue = false;
|
||||||
static const bool cond_end = true;
|
static const bool cond_end = true;
|
||||||
|
|
||||||
void clear_tasks(const pipeline type);
|
void clear_tasks(const pipeline type);
|
||||||
|
|
||||||
void schedule(const std::function<bool()>& callback,
|
void schedule(const std::function<bool()>& callback,
|
||||||
pipeline type = pipeline::client,
|
pipeline type = pipeline::client,
|
||||||
std::chrono::milliseconds delay = 0ms);
|
std::chrono::milliseconds delay = 0ms);
|
||||||
void loop(const std::function<void()>& callback,
|
void loop(const std::function<void()>& callback,
|
||||||
pipeline type = pipeline::client,
|
pipeline type = pipeline::client,
|
||||||
std::chrono::milliseconds delay = 0ms);
|
std::chrono::milliseconds delay = 0ms);
|
||||||
void once(const std::function<void()>& callback,
|
void once(const std::function<void()>& callback,
|
||||||
pipeline type = pipeline::client,
|
pipeline type = pipeline::client,
|
||||||
std::chrono::milliseconds delay = 0ms);
|
std::chrono::milliseconds delay = 0ms);
|
||||||
} // namespace scheduler
|
} // namespace scheduler
|
||||||
|
@ -8,18 +8,17 @@
|
|||||||
|
|
||||||
#include "scheduler.hpp"
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
namespace user_info
|
namespace user_info {
|
||||||
{
|
namespace {
|
||||||
namespace
|
int a1 = 0;
|
||||||
{
|
void cl_check_user_info(int _a1, const int force) {
|
||||||
int a1 = 0;
|
|
||||||
void cl_check_user_info(int _a1, const int force)
|
|
||||||
{
|
|
||||||
a1 = _a1;
|
a1 = _a1;
|
||||||
|
|
||||||
if (*game::connectionState <= game::connstate_t::CA_CHALLENGING) return;
|
if (*game::connectionState <= game::connstate_t::CA_CHALLENGING)
|
||||||
|
return;
|
||||||
|
|
||||||
if (game::cl_paused->current.enabled && !force) return;
|
if (game::cl_paused->current.enabled && !force)
|
||||||
|
return;
|
||||||
|
|
||||||
const std::string info_string = game::Dvar_InfoString(_a1, 0x200);
|
const std::string info_string = game::Dvar_InfoString(_a1, 0x200);
|
||||||
utils::info_string info(info_string);
|
utils::info_string info(info_string);
|
||||||
@ -29,8 +28,8 @@ namespace user_info
|
|||||||
char name[16];
|
char name[16];
|
||||||
|
|
||||||
const auto numbers = std::to_string(std::rand() % 10000);
|
const auto numbers = std::to_string(std::rand() % 10000);
|
||||||
_snprintf_s(
|
_snprintf_s(name, sizeof(name), _TRUNCATE, "^%d%s", color_code,
|
||||||
name, sizeof(name), _TRUNCATE, "^%d%s", color_code, numbers.data());
|
numbers.data());
|
||||||
|
|
||||||
info.set("name", name);
|
info.set("name", name);
|
||||||
|
|
||||||
@ -42,10 +41,9 @@ namespace user_info
|
|||||||
|
|
||||||
game::CL_AddReliableCommand(
|
game::CL_AddReliableCommand(
|
||||||
_a1, utils::string::va("userinfo \"%s\"", info.build().data()));
|
_a1, utils::string::va("userinfo \"%s\"", info.build().data()));
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(naked) void cl_check_user_info_stub()
|
__declspec(naked) void cl_check_user_info_stub() {
|
||||||
{
|
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
pushad
|
pushad
|
||||||
@ -58,25 +56,18 @@ namespace user_info
|
|||||||
popad
|
popad
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class component final : public component_interface
|
class component final : public component_interface {
|
||||||
{
|
public:
|
||||||
public:
|
void post_unpack() override {
|
||||||
void post_unpack() override
|
|
||||||
{
|
|
||||||
utils::hook::call(0x41CA53, cl_check_user_info_stub);
|
utils::hook::call(0x41CA53, cl_check_user_info_stub);
|
||||||
|
|
||||||
scheduler::loop(
|
scheduler::loop([] { cl_check_user_info(a1, TRUE); },
|
||||||
[]
|
scheduler::pipeline::client, 4s);
|
||||||
{
|
|
||||||
cl_check_user_info(a1, TRUE);
|
|
||||||
},
|
|
||||||
scheduler::pipeline::client,
|
|
||||||
4s);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} // namespace user_info
|
} // namespace user_info
|
||||||
|
|
||||||
REGISTER_COMPONENT(user_info::component)
|
REGISTER_COMPONENT(user_info::component)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user