Add command handling
This commit is contained in:
parent
b9c7e0a08c
commit
0ef86e413b
@ -5,9 +5,15 @@ namespace game
|
|||||||
{
|
{
|
||||||
namespace native
|
namespace native
|
||||||
{
|
{
|
||||||
|
Cmd_AddCommand_t Cmd_AddCommand;
|
||||||
|
|
||||||
Conbuf_AppendText_t Conbuf_AppendText;
|
Conbuf_AppendText_t Conbuf_AppendText;
|
||||||
|
|
||||||
Sys_ShowConsole_t Sys_ShowConsole;
|
Sys_ShowConsole_t Sys_ShowConsole;
|
||||||
|
|
||||||
|
int* cmd_args;
|
||||||
|
int* cmd_argc;
|
||||||
|
const char*** cmd_argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -32,8 +38,14 @@ namespace game
|
|||||||
{
|
{
|
||||||
mode = _mode;
|
mode = _mode;
|
||||||
|
|
||||||
|
native::Cmd_AddCommand = native::Cmd_AddCommand_t(SELECT_VALUE(0x558820, 0x545DF0, 0));
|
||||||
|
|
||||||
native::Conbuf_AppendText = native::Conbuf_AppendText_t(SELECT_VALUE(0x4C84E0, 0x5CF610, 0x53C790));
|
native::Conbuf_AppendText = native::Conbuf_AppendText_t(SELECT_VALUE(0x4C84E0, 0x5CF610, 0x53C790));
|
||||||
|
|
||||||
native::Sys_ShowConsole = native::Sys_ShowConsole_t(SELECT_VALUE(0x470AF0, 0x5CF590, 0));
|
native::Sys_ShowConsole = native::Sys_ShowConsole_t(SELECT_VALUE(0x470AF0, 0x5CF590, 0));
|
||||||
|
|
||||||
|
native::cmd_args = reinterpret_cast<int*>(SELECT_VALUE(0x1750750, 0x1C978D0, 0x1B455F8));
|
||||||
|
native::cmd_argc = reinterpret_cast<int*>(SELECT_VALUE(0x1750794, 0x1C97914, 0x1B4563C));
|
||||||
|
native::cmd_argv = reinterpret_cast<const char***>(SELECT_VALUE(0x17507B4, 0x1C97934, 0x1B4565C));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,18 @@ namespace game
|
|||||||
{
|
{
|
||||||
namespace native
|
namespace native
|
||||||
{
|
{
|
||||||
|
typedef void (*Cmd_AddCommand_t)(const char* cmdName, void(*function)(), cmd_function_t* allocedCmd);
|
||||||
|
extern Cmd_AddCommand_t Cmd_AddCommand;
|
||||||
|
|
||||||
typedef void (*Conbuf_AppendText_t)(const char* message);
|
typedef void (*Conbuf_AppendText_t)(const char* message);
|
||||||
extern Conbuf_AppendText_t Conbuf_AppendText;
|
extern Conbuf_AppendText_t Conbuf_AppendText;
|
||||||
|
|
||||||
typedef void (*Sys_ShowConsole_t)();
|
typedef void (*Sys_ShowConsole_t)();
|
||||||
extern Sys_ShowConsole_t Sys_ShowConsole;
|
extern Sys_ShowConsole_t Sys_ShowConsole;
|
||||||
|
|
||||||
|
extern int* cmd_args;
|
||||||
|
extern int* cmd_argc;
|
||||||
|
extern const char*** cmd_argv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_mp();
|
bool is_mp();
|
||||||
|
@ -368,5 +368,15 @@ namespace game
|
|||||||
char m_hash[4];
|
char m_hash[4];
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
typedef struct cmd_function_s
|
||||||
|
{
|
||||||
|
cmd_function_s* next;
|
||||||
|
const char* name;
|
||||||
|
const char* autoCompleteDir;
|
||||||
|
const char* autoCompleteExt;
|
||||||
|
void (__cdecl *function)();
|
||||||
|
int flags;
|
||||||
|
} cmd_function_t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
47
src/module/command.cpp
Normal file
47
src/module/command.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include "command.hpp"
|
||||||
|
#include "utils/string.hpp"
|
||||||
|
#include "game/structs.hpp"
|
||||||
|
#include "game/game.hpp"
|
||||||
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
|
utils::memory::allocator command::allocator_;
|
||||||
|
std::mutex command::mutex_;
|
||||||
|
std::unordered_map<std::string, std::function<void(const std::vector<std::string>&)>> command::callbacks_;
|
||||||
|
|
||||||
|
void command::add(const std::string& name, const std::function<void(const std::vector<std::string>&)>& callback)
|
||||||
|
{
|
||||||
|
std::lock_guard _(mutex_);
|
||||||
|
callbacks_[utils::string::to_lower(name)] = callback;
|
||||||
|
|
||||||
|
const auto cmd_name = allocator_.duplicate_string(name);
|
||||||
|
const auto cmd_function = allocator_.allocate<game::native::cmd_function_t>();
|
||||||
|
|
||||||
|
game::native::Cmd_AddCommand(cmd_name, dispatcher, cmd_function);
|
||||||
|
}
|
||||||
|
|
||||||
|
void command::pre_destroy()
|
||||||
|
{
|
||||||
|
std::lock_guard _(mutex_);
|
||||||
|
callbacks_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void command::dispatcher()
|
||||||
|
{
|
||||||
|
if (game::native::cmd_argc[*game::native::cmd_args] < 1) return;
|
||||||
|
|
||||||
|
const auto command = utils::string::to_lower(game::native::cmd_argv[*game::native::cmd_args][0]);
|
||||||
|
const auto handler = callbacks_.find(command);
|
||||||
|
if (handler == callbacks_.end()) return;
|
||||||
|
|
||||||
|
std::vector<std::string> arguments;
|
||||||
|
|
||||||
|
for (auto i = 0; i < game::native::cmd_argc[*game::native::cmd_args]; ++i)
|
||||||
|
{
|
||||||
|
arguments.emplace_back(game::native::cmd_argv[*game::native::cmd_args][i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
handler->second(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_MODULE(command);
|
18
src/module/command.hpp
Normal file
18
src/module/command.hpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "loader/module_loader.hpp"
|
||||||
|
#include "utils/memory.hpp"
|
||||||
|
|
||||||
|
class command final : public module
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void add(const std::string& name, const std::function<void(const std::vector<std::string>&)>& callback);
|
||||||
|
|
||||||
|
void pre_destroy() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static utils::memory::allocator allocator_;
|
||||||
|
static std::mutex mutex_;
|
||||||
|
static std::unordered_map<std::string, std::function<void(const std::vector<std::string>&)>> callbacks_;
|
||||||
|
|
||||||
|
static void dispatcher();
|
||||||
|
};
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
std::mutex scheduler::mutex_;
|
std::mutex scheduler::mutex_;
|
||||||
std::vector<std::function<void()>> scheduler::callbacks_;
|
std::vector<std::function<void()>> scheduler::callbacks_;
|
||||||
|
std::vector<std::function<void()>> scheduler::single_callbacks_;
|
||||||
|
|
||||||
void scheduler::on_frame(const std::function<void()>& callback)
|
void scheduler::on_frame(const std::function<void()>& callback)
|
||||||
{
|
{
|
||||||
@ -10,25 +11,40 @@ void scheduler::on_frame(const std::function<void()>& callback)
|
|||||||
callbacks_.push_back(callback);
|
callbacks_.push_back(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void scheduler::once(const std::function<void()>& callback)
|
||||||
|
{
|
||||||
|
std::lock_guard _(mutex_);
|
||||||
|
single_callbacks_.push_back(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void scheduler::execute()
|
void scheduler::execute()
|
||||||
{
|
{
|
||||||
std::vector<std::function<void()>> callbacks_copy;
|
std::vector<std::function<void()>> callbacks_copy;
|
||||||
|
std::vector<std::function<void()>> single_callbacks_copy;
|
||||||
|
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
std::lock_guard _(mutex_);
|
||||||
callbacks_copy = callbacks_;
|
callbacks_copy = callbacks_;
|
||||||
|
single_callbacks_copy = single_callbacks_;
|
||||||
|
single_callbacks_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto& callback : callbacks_copy)
|
for (const auto& callback : callbacks_copy)
|
||||||
{
|
{
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& callback : single_callbacks_copy)
|
||||||
|
{
|
||||||
|
callback();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void scheduler::pre_destroy()
|
void scheduler::pre_destroy()
|
||||||
{
|
{
|
||||||
std::lock_guard _(mutex_);
|
std::lock_guard _(mutex_);
|
||||||
callbacks_.clear();
|
callbacks_.clear();
|
||||||
|
single_callbacks_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_MODULE(scheduler);
|
REGISTER_MODULE(scheduler);
|
||||||
|
@ -5,6 +5,7 @@ class scheduler final : public module
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static void on_frame(const std::function<void()>& callback);
|
static void on_frame(const std::function<void()>& callback);
|
||||||
|
static void once(const std::function<void()>& callback);
|
||||||
static void execute();
|
static void execute();
|
||||||
|
|
||||||
void pre_destroy() override;
|
void pre_destroy() override;
|
||||||
@ -12,4 +13,5 @@ public:
|
|||||||
private:
|
private:
|
||||||
static std::mutex mutex_;
|
static std::mutex mutex_;
|
||||||
static std::vector<std::function<void()>> callbacks_;
|
static std::vector<std::function<void()>> callbacks_;
|
||||||
|
static std::vector<std::function<void()>> single_callbacks_;
|
||||||
};
|
};
|
||||||
|
@ -18,6 +18,26 @@ namespace utils
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string to_lower(std::string text)
|
||||||
|
{
|
||||||
|
std::transform(text.begin(), text.end(), text.begin(), [](const char input)
|
||||||
|
{
|
||||||
|
return CHAR(tolower(input));
|
||||||
|
});
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_upper(std::string text)
|
||||||
|
{
|
||||||
|
std::transform(text.begin(), text.end(), text.begin(), [](const char input)
|
||||||
|
{
|
||||||
|
return CHAR(toupper(input));
|
||||||
|
});
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
std::string dump_hex(const std::string& data, const std::string& separator)
|
std::string dump_hex(const std::string& data, const std::string& separator)
|
||||||
{
|
{
|
||||||
std::string result;
|
std::string result;
|
||||||
|
@ -76,6 +76,9 @@ namespace utils
|
|||||||
|
|
||||||
const char* va(const char* fmt, ...);
|
const char* va(const char* fmt, ...);
|
||||||
|
|
||||||
|
std::string to_lower(std::string text);
|
||||||
|
std::string to_upper(std::string text);
|
||||||
|
|
||||||
std::string dump_hex(const std::string& data, const std::string& separator = " ");
|
std::string dump_hex(const std::string& data, const std::string& separator = " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user