properly do vstr

This commit is contained in:
6arelyFuture 2023-04-30 12:42:09 +01:00
parent 3189442299
commit dcb675c3e3
No known key found for this signature in database
GPG Key ID: 22F9079C86CFAB31
5 changed files with 112 additions and 6 deletions

View File

@ -8,10 +8,15 @@
constexpr auto CMD_MAX_NESTING = 8;
namespace command {
std::unordered_map<std::string, std::function<void(const params_sv&)>> handlers;
std::unordered_map<std::string, sv_command_param_function> handlers;
game::CmdArgs* get_cmd_args() {
return static_cast<game::CmdArgs*>(
game::Sys_GetValue(game::THREAD_VALUE_CMD));
}
void main_handler() {
params_sv params = {};
params_sv params;
const auto command = utils::string::to_lower(params[0]);
@ -20,6 +25,31 @@ void main_handler() {
}
}
params::params() : nesting_(get_cmd_args()->nesting) {
assert(this->nesting_ < game::CMD_MAX_NESTING);
}
int params::size() const { return get_cmd_args()->argc[this->nesting_]; }
const char* params::get(const int index) const {
if (index >= this->size()) {
return "";
}
return get_cmd_args()->argv[this->nesting_][index];
}
std::string params::join(const int index) const {
std::string result;
for (auto i = index; i < this->size(); i++) {
if (i > index)
result.append(" ");
result.append(this->get(i));
}
return result;
}
params_sv::params_sv() : nesting_(game::sv_cmd_args->nesting) {
assert(game::sv_cmd_args->nesting < CMD_MAX_NESTING);
}
@ -54,8 +84,7 @@ void add_raw(const char* name, void (*callback)()) {
utils::memory::get_allocator()->allocate<game::cmd_function_s>());
}
void add_sv(const char* name,
const std::function<void(const params_sv&)>& callback) {
void add_sv(const char* name, const sv_command_param_function& callback) {
const auto command = utils::string::to_lower(name);
if (!handlers.contains(command)) {

View File

@ -2,6 +2,20 @@
namespace command {
class params {
public:
params();
[[nodiscard]] int size() const;
[[nodiscard]] const char* get(int index) const;
[[nodiscard]] std::string join(int index) const;
const char* operator[](const int index) const { return this->get(index); }
private:
int nesting_;
};
class params_sv {
public:
params_sv();
@ -16,9 +30,11 @@ private:
int nesting_;
};
using command_param_function = std::function<void(const params&)>;
using sv_command_param_function = std::function<void(const params_sv&)>;
void add_raw(const char* name, void (*callback)());
void add_sv(const char* name,
const std::function<void(const params_sv&)>& callback);
void add_sv(const char* name, const sv_command_param_function& callback);
void execute(std::string command, bool sync = false);
} // namespace command

View File

@ -0,0 +1,50 @@
#include <std_include.hpp>
#include "loader/component_loader.hpp"
#include <utils/hook.hpp>
#include "command.hpp"
namespace command_additions {
namespace {
void cmd_vstr_f() {
const command::params params;
if (params.size() < 2) {
game::Com_Printf(game::CON_CHANNEL_DONT_FILTER,
"vstr <variablename> : execute a variable command\n");
return;
}
const auto* dvar_name = params.get(1);
const auto* dvar = game::Dvar_FindVar(dvar_name);
if (!dvar) {
game::Com_Printf(game::CON_CHANNEL_DONT_FILTER, "%s doesn't exist\n",
dvar_name);
return;
}
if (dvar->type == game::DVAR_TYPE_STRING ||
dvar->type == game::DVAR_TYPE_ENUM) {
// Adds \n automatically
command::execute(dvar->current.string);
} else {
game::Com_Printf(game::CON_CHANNEL_DONT_FILTER,
"%s is not a string-based dvar\n", dvar->name);
}
}
} // namespace
class component final : public component_interface {
public:
void post_unpack() override {
// Because this plugin is loaded late we must override the structure
auto* cmd_vstr_f_var = reinterpret_cast<game::cmd_function_s*>(
game::select(0x355E69C, 0x243FB1C));
cmd_vstr_f_var->function = cmd_vstr_f;
}
};
} // namespace command_additions
REGISTER_COMPONENT(command_additions::component)

View File

@ -158,6 +158,15 @@ struct CmdArgs {
static_assert(sizeof(CmdArgs) == 10476);
enum {
THREAD_VALUE_PROF_STACK = 0x0,
THREAD_VALUE_VA = 0x1,
THREAD_VALUE_COM_ERROR = 0x2,
THREAD_VALUE_TRACE = 0x3,
THREAD_VALUE_CMD = 0x4,
THREAD_VALUE_COUNT = 0x5,
};
typedef enum {
NA_BOT = 0x0,
NA_BAD = 0x1,

View File

@ -18,6 +18,8 @@ WEAK symbol<void(LocalClientNum_t, const char* text)> Cbuf_InsertText{0x695E10,
WEAK symbol<void(LocalClientNum_t, int controllerIndex, const char* text)>
Cmd_ExecuteSingleCommand{0x50B470, 0x829AD0};
WEAK symbol<void*(int valueIndex)> Sys_GetValue{0x529EB0, 0x67D4F0};
WEAK symbol<void(client_s*, svscmd_type, const char*, ...)>
SV_SendServerCommand{0x588B10, 0x6106E0};
WEAK symbol<void(int, svscmd_type, const char*)> SV_GameSendServerCommand{