Fix format or so I hope

This commit is contained in:
6arelyFuture 2022-03-22 23:44:31 +00:00
parent 8a2df0a179
commit 2ed98145da
No known key found for this signature in database
GPG Key ID: E883E2BC9657D955
14 changed files with 541 additions and 711 deletions

View File

@ -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
@ -32,8 +30,7 @@ namespace cheats
} }
} }
__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
@ -57,11 +54,9 @@ namespace cheats
} }
} }
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");
@ -74,34 +69,25 @@ namespace cheats
} }
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);

View File

@ -8,111 +8,81 @@
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 void post_unpack() override { add_commands_generic(); }
{
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);

View File

@ -1,9 +1,7 @@
#pragma once #pragma once
namespace command namespace command {
{ class params {
class params
{
public: public:
params(); params();
@ -11,18 +9,14 @@ namespace command
[[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);

View File

@ -2,47 +2,35 @@
#include <loader/component_loader.hpp> #include <loader/component_loader.hpp>
namespace console namespace console {
{ namespace {
namespace
{
std::thread thread; std::thread thread;
std::thread::id async_thread_id; 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();
}); });

View File

@ -3,15 +3,12 @@
#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);
} }
}; };

View File

@ -6,8 +6,7 @@
#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;
/* /*
@ -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,
cl_exploit = game::Dvar_RegisterBool( "Enable server freezer");
"cl_exploit", false, game::DVAR_NONE, "Enable server freezer");
add_exploit_commands(); add_exploit_commands();
add_key_hooks(); add_key_hooks();
@ -66,49 +61,37 @@ namespace exploit
} }
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;

View File

@ -5,30 +5,23 @@
#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;
} }
@ -36,31 +29,24 @@ namespace key_catcher
} }
} // 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

View File

@ -1,7 +1,6 @@
#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);

View File

@ -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;
} }
@ -41,39 +35,32 @@ namespace network
} // 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");
}); });
} }

View File

@ -1,7 +1,6 @@
#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&)>;

View File

@ -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: public:
void post_unpack() override void post_unpack() override { remove_tekno_hooks(); }
{
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);

View File

@ -6,14 +6,11 @@
#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{};
@ -21,42 +18,30 @@ namespace scheduler
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,12 +49,9 @@ 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;
} }
} }
@ -80,19 +62,12 @@ namespace scheduler
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 = {};
}); });
}); });
@ -102,27 +77,21 @@ namespace scheduler
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;
@ -134,43 +103,32 @@ namespace scheduler
} }
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([]() {
thread = std::thread( while (true) {
[]()
{
while (true)
{
execute(pipeline::async); execute(pipeline::async);
std::this_thread::sleep_for(10ms); std::this_thread::sleep_for(10ms);
} }

View File

@ -1,11 +1,9 @@
#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,

View File

@ -8,18 +8,17 @@
#include "scheduler.hpp" #include "scheduler.hpp"
namespace user_info namespace user_info {
{ namespace {
namespace
{
int a1 = 0; int a1 = 0;
void cl_check_user_info(int _a1, const int force) 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);
@ -44,8 +43,7 @@ namespace user_info
_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
@ -61,20 +59,13 @@ namespace user_info
} }
} // 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