mirror of
https://github.com/alicealys/t5-gsc-utils.git
synced 2025-06-06 03:17:41 +00:00
Add addCommand & executeCommand
This commit is contained in:
parent
f583846c2d
commit
cbdc2bfd7f
156
src/component/command.cpp
Normal file
156
src/component/command.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#include "stdinc.hpp"
|
||||||
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
|
#include "game/game.hpp"
|
||||||
|
|
||||||
|
#include "command.hpp"
|
||||||
|
#include "gsc.hpp"
|
||||||
|
#include "scripting.hpp"
|
||||||
|
|
||||||
|
#include <utils/string.hpp>
|
||||||
|
#include <utils/memory.hpp>
|
||||||
|
|
||||||
|
namespace command
|
||||||
|
{
|
||||||
|
std::unordered_map<std::string, std::function<void(params&)>> handlers;
|
||||||
|
|
||||||
|
std::vector<std::string> script_commands;
|
||||||
|
utils::memory::allocator allocator;
|
||||||
|
|
||||||
|
game::CmdArgs* get_cmd_args()
|
||||||
|
{
|
||||||
|
return reinterpret_cast<game::CmdArgs*>(game::Sys_GetValue(4));
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_handler()
|
||||||
|
{
|
||||||
|
params params = {};
|
||||||
|
|
||||||
|
const auto command = utils::string::to_lower(params[0]);
|
||||||
|
|
||||||
|
if (handlers.find(command) != handlers.end())
|
||||||
|
{
|
||||||
|
handlers[command](params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
params::params()
|
||||||
|
: nesting_(get_cmd_args()->nesting)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int params::size() const
|
||||||
|
{
|
||||||
|
const auto cmd_args = get_cmd_args();
|
||||||
|
return cmd_args->argc[cmd_args->nesting];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* params::get(int index) const
|
||||||
|
{
|
||||||
|
if (index >= this->size())
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto cmd_args = get_cmd_args();
|
||||||
|
return cmd_args->argv[this->nesting_][index];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string params::join(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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_raw(const char* name, void (*callback)())
|
||||||
|
{
|
||||||
|
game::Cmd_AddCommandInternal(name, callback, utils::memory::get_allocator()->allocate<game::cmd_function_t>());
|
||||||
|
}
|
||||||
|
|
||||||
|
void add(const char* name, std::function<void(params&)> callback)
|
||||||
|
{
|
||||||
|
const auto command = utils::string::to_lower(name);
|
||||||
|
|
||||||
|
if (handlers.find(command) == handlers.end())
|
||||||
|
{
|
||||||
|
add_raw(name, main_handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
handlers[command] = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_script_command(const std::string& name, const std::function<void(const params&)>& callback)
|
||||||
|
{
|
||||||
|
script_commands.push_back(name);
|
||||||
|
const auto name_ = allocator.duplicate_string(name);
|
||||||
|
add(name_, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_script_commands()
|
||||||
|
{
|
||||||
|
for (const auto& name : script_commands)
|
||||||
|
{
|
||||||
|
handlers.erase(name);
|
||||||
|
game::Cmd_RemoveCommand(name.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
allocator.clear();
|
||||||
|
script_commands.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void execute(std::string command, const bool sync)
|
||||||
|
{
|
||||||
|
command += "\n";
|
||||||
|
|
||||||
|
if (sync)
|
||||||
|
{
|
||||||
|
game::Cmd_ExecuteSingleCommand(0, 0, command.data());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
game::Cbuf_AddText(0, command.data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class component final : public component_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void post_unpack() override
|
||||||
|
{
|
||||||
|
scripting::on_shutdown(clear_script_commands);
|
||||||
|
|
||||||
|
gsc::function::add("executecommand", [](const std::string& command)
|
||||||
|
{
|
||||||
|
execute(command, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
gsc::function::add("addcommand", [](const std::string& name, const scripting::function& function)
|
||||||
|
{
|
||||||
|
command::add_script_command(name, [function](const command::params& params)
|
||||||
|
{
|
||||||
|
scripting::array array;
|
||||||
|
|
||||||
|
for (auto i = 0; i < params.size(); i++)
|
||||||
|
{
|
||||||
|
array.push(params[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function({array});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_COMPONENT(command::component)
|
30
src/component/command.hpp
Normal file
30
src/component/command.hpp
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace command
|
||||||
|
{
|
||||||
|
class params
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
params();
|
||||||
|
|
||||||
|
int size() const;
|
||||||
|
const char* get(int index) const;
|
||||||
|
std::string join(int index) const;
|
||||||
|
|
||||||
|
const char* operator[](const int index) const
|
||||||
|
{
|
||||||
|
return this->get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int nesting_;
|
||||||
|
};
|
||||||
|
|
||||||
|
void add_raw(const char* name, void (*callback)());
|
||||||
|
void add(const char* name, std::function<void(params&)> callback);
|
||||||
|
|
||||||
|
void add_script_command(const std::string& name, const std::function<void(const params&)>& callback);
|
||||||
|
void clear_script_commands();
|
||||||
|
|
||||||
|
void execute(std::string command, const bool sync = false);
|
||||||
|
}
|
@ -9,6 +9,7 @@ BOOL APIENTRY DllMain(HMODULE /*module_*/, DWORD ul_reason_for_call, LPVOID /*re
|
|||||||
{
|
{
|
||||||
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
if (ul_reason_for_call == DLL_PROCESS_ATTACH)
|
||||||
{
|
{
|
||||||
|
utils::hook::jump(reinterpret_cast<size_t>(&printf), game::Com_Printf);
|
||||||
component_loader::post_unpack();
|
component_loader::post_unpack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,8 +385,8 @@ namespace scripting
|
|||||||
}
|
}
|
||||||
|
|
||||||
function_argument::function_argument(const arguments& args, const script_value& value, const int index, const bool exists)
|
function_argument::function_argument(const arguments& args, const script_value& value, const int index, const bool exists)
|
||||||
: values_(args)
|
: script_value(value)
|
||||||
, value_(value)
|
, values_(args)
|
||||||
, index_(index)
|
, index_(index)
|
||||||
, exists_(exists)
|
, exists_(exists)
|
||||||
{
|
{
|
||||||
|
@ -232,7 +232,7 @@ public: \
|
|||||||
class function_argument;
|
class function_argument;
|
||||||
using variadic_args = std::vector<function_argument>;
|
using variadic_args = std::vector<function_argument>;
|
||||||
|
|
||||||
class function_argument
|
class function_argument : public script_value
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
function_argument(const arguments& args, const script_value& value, const int index, const bool exists);
|
function_argument(const arguments& args, const script_value& value, const int index, const bool exists);
|
||||||
@ -247,7 +247,7 @@ public: \
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return this->value_.as<T>();
|
return script_value::as<T>();
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
@ -267,21 +267,6 @@ public: \
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string() const
|
|
||||||
{
|
|
||||||
return this->value_.to_string();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string type_name() const
|
|
||||||
{
|
|
||||||
return this->value_.type_name();
|
|
||||||
}
|
|
||||||
|
|
||||||
script_value get_raw() const
|
|
||||||
{
|
|
||||||
return this->value_;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator variadic_args() const
|
operator variadic_args() const
|
||||||
{
|
{
|
||||||
variadic_args args{};
|
variadic_args args{};
|
||||||
@ -296,9 +281,9 @@ public: \
|
|||||||
operator C<T, std::allocator<T>>() const
|
operator C<T, std::allocator<T>>() const
|
||||||
{
|
{
|
||||||
const auto container_type = get_c_typename<C<T, std::allocator<T>>>();
|
const auto container_type = get_c_typename<C<T, std::allocator<T>>>();
|
||||||
if (!this->value_.is<array>())
|
if (!script_value::as<ArrayType>())
|
||||||
{
|
{
|
||||||
const auto type = get_typename(this->value_.get_raw());
|
const auto type = get_typename(this->get_raw());
|
||||||
|
|
||||||
throw std::runtime_error(utils::string::va("has type '%s' but should be '%s'",
|
throw std::runtime_error(utils::string::va("has type '%s' but should be '%s'",
|
||||||
type.data(),
|
type.data(),
|
||||||
@ -307,7 +292,7 @@ public: \
|
|||||||
}
|
}
|
||||||
|
|
||||||
C<T, std::allocator<T>> container{};
|
C<T, std::allocator<T>> container{};
|
||||||
const auto array = this->value_.as<ArrayType>();
|
const auto array = script_value::as<ArrayType>();
|
||||||
for (auto i = 0; i < array.size(); i++)
|
for (auto i = 0; i < array.size(); i++)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -332,7 +317,6 @@ public: \
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
arguments values_{};
|
arguments values_{};
|
||||||
script_value value_{};
|
|
||||||
int index_{};
|
int index_{};
|
||||||
bool exists_{};
|
bool exists_{};
|
||||||
};
|
};
|
||||||
|
@ -9,14 +9,16 @@ namespace game
|
|||||||
WEAK symbol<int(const char* str)> BG_StringHashValue{0x0, 0x0};
|
WEAK symbol<int(const char* str)> BG_StringHashValue{0x0, 0x0};
|
||||||
|
|
||||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_InsertText{0x0, 0x0};
|
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_InsertText{0x0, 0x0};
|
||||||
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x0, 0x0};
|
WEAK symbol<void(int localClientNum, const char* text)> Cbuf_AddText{0x49B930, 0x56EF70};
|
||||||
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{0x0, 0x0};
|
WEAK symbol<void(int localClientNum, int controllerIndex, const char* text)> Cmd_ExecuteSingleCommand{0x619D00, 0x50B470};
|
||||||
WEAK symbol<void(const char* cmdName, void(), cmd_function_t* allocedCmd)> Cmd_AddCommandInternal{0x0, 0x0};
|
WEAK symbol<void(const char* cmdName, void(), cmd_function_t* allocedCmd)> Cmd_AddCommandInternal{0x661400, 0x6AD580};
|
||||||
WEAK symbol<const char*(int index)> Cmd_Argv{0x0, 0x0};
|
WEAK symbol<const char*(int index)> Cmd_Argv{0x0, 0x0};
|
||||||
WEAK symbol<void(const char* cmdName)> Cmd_RemoveCommand{0x0, 0x0};
|
WEAK symbol<void(const char* cmdName)> Cmd_RemoveCommand{0x5F1A90, 0x527EA0};
|
||||||
|
|
||||||
WEAK symbol<void(int clientNum)> ClientUserInfoChanged{0x0, 0x0};
|
WEAK symbol<void(int clientNum)> ClientUserInfoChanged{0x0, 0x0};
|
||||||
|
|
||||||
|
WEAK symbol<int(const char* fmt, ...)> Com_Printf{0x566BC0, 0x64C260};
|
||||||
|
|
||||||
WEAK symbol<const dvar_t*(const char*)> Dvar_FindVar{0x0, 0x0};
|
WEAK symbol<const dvar_t*(const char*)> Dvar_FindVar{0x0, 0x0};
|
||||||
WEAK symbol<int(const dvar_t*)> Dvar_GetInt{0x0, 0x0};
|
WEAK symbol<int(const dvar_t*)> Dvar_GetInt{0x0, 0x0};
|
||||||
WEAK symbol<dvar_t*(const char* dvarName, int value, int min, int max,
|
WEAK symbol<dvar_t*(const char* dvarName, int value, int min, int max,
|
||||||
@ -40,8 +42,8 @@ namespace game
|
|||||||
WEAK symbol<void(scriptInstance_t inst)> Scr_ClearOutParams{0x654D10, 0x588680};
|
WEAK symbol<void(scriptInstance_t inst)> Scr_ClearOutParams{0x654D10, 0x588680};
|
||||||
|
|
||||||
WEAK symbol<unsigned int(scriptInstance_t inst)> AllocObject{0x0, 0x0};
|
WEAK symbol<unsigned int(scriptInstance_t inst)> AllocObject{0x0, 0x0};
|
||||||
WEAK symbol<unsigned int(scriptInstance_t inst, unsigned int id)> AllocThread{0x0, 0x0};
|
WEAK symbol<unsigned int(scriptInstance_t inst, unsigned int id)> AllocThread{0x69E140, 0x43CA60};
|
||||||
WEAK symbol<void(scriptInstance_t inst, unsigned int id)> RemoveRefToObject{0x0, 0x0};
|
WEAK symbol<void(scriptInstance_t inst, unsigned int id)> RemoveRefToObject{0x5517B0, 0x698FA0};
|
||||||
WEAK symbol<void(scriptInstance_t inst, const float* vectorValue)> RemoveRefToVector{0x0, 0x0};
|
WEAK symbol<void(scriptInstance_t inst, const float* vectorValue)> RemoveRefToVector{0x0, 0x0};
|
||||||
WEAK symbol<void(scriptInstance_t inst, const int type, VariableUnion value)> AddRefToValue_{0x53FD50, 0x6706B0};
|
WEAK symbol<void(scriptInstance_t inst, const int type, VariableUnion value)> AddRefToValue_{0x53FD50, 0x6706B0};
|
||||||
|
|
||||||
@ -95,13 +97,13 @@ namespace game
|
|||||||
|
|
||||||
WEAK symbol<gentity_s*(scr_entref_t entref)> GetPlayerEntity{0x0, 0x0};
|
WEAK symbol<gentity_s*(scr_entref_t entref)> GetPlayerEntity{0x0, 0x0};
|
||||||
|
|
||||||
WEAK symbol<unsigned int(scriptInstance_t inst, unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x0, 0x0};
|
WEAK symbol<unsigned int(scriptInstance_t inst, unsigned int localId, const char* pos, unsigned int paramcount)> VM_Execute{0x8ACE60, 0x8EADE0};
|
||||||
|
|
||||||
WEAK symbol<void(int clientNum, const char* reason)> SV_GameDropClient{0x0, 0x0};
|
WEAK symbol<void(int clientNum, const char* reason)> SV_GameDropClient{0x0, 0x0};
|
||||||
WEAK symbol<bool(int clientNum)> SV_IsTestClient{0x0, 0x0};
|
WEAK symbol<bool(int clientNum)> SV_IsTestClient{0x0, 0x0};
|
||||||
WEAK symbol<void(int clientNum, int type, const char* command)> SV_GameSendServerCommand{0x0, 0x0};
|
WEAK symbol<void(int clientNum, int type, const char* command)> SV_GameSendServerCommand{0x0, 0x0};
|
||||||
|
|
||||||
WEAK symbol<void*(int valueIndex)> Sys_GetValue{0x0, 0x0};
|
WEAK symbol<void*(int valueIndex)> Sys_GetValue{0x67D4F0, 0x529EB0};
|
||||||
WEAK symbol<int()> Sys_Milliseconds{0x0, 0x0};
|
WEAK symbol<int()> Sys_Milliseconds{0x0, 0x0};
|
||||||
|
|
||||||
WEAK symbol<void*(jmp_buf* Buf, int Value)> longjmp{0x96B980, 0x9D05C4};
|
WEAK symbol<void*(jmp_buf* Buf, int Value)> longjmp{0x96B980, 0x9D05C4};
|
||||||
@ -123,7 +125,7 @@ namespace game
|
|||||||
WEAK symbol<scr_classStruct_t*> g_classMap{0x0, 0x0};
|
WEAK symbol<scr_classStruct_t*> g_classMap{0x0, 0x0};
|
||||||
|
|
||||||
WEAK symbol<gentity_s> g_entities{0x0, 0x0};
|
WEAK symbol<gentity_s> g_entities{0x0, 0x0};
|
||||||
WEAK symbol<unsigned int> levelEntityId{0x0, 0x0};
|
WEAK symbol<unsigned int> levelEntityId{0x32C86A0, 0x3DCB2A0};
|
||||||
|
|
||||||
WEAK symbol<client_s> svs_clients{0x0, 0x0};
|
WEAK symbol<client_s> svs_clients{0x0, 0x0};
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user