parent
91a8b5bf94
commit
85794fd992
@ -81,6 +81,24 @@ namespace command
|
|||||||
assert(this->nesting_ < game::CMD_MAX_NESTING);
|
assert(this->nesting_ < game::CMD_MAX_NESTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
params::params(const std::string& text)
|
||||||
|
: needs_end_(true)
|
||||||
|
{
|
||||||
|
auto* cmd_args = get_cmd_args();
|
||||||
|
game::Cmd_TokenizeStringKernel(0, game::CONTROLLER_INDEX_FIRST, text.data(),
|
||||||
|
512 - cmd_args->totalUsedArgvPool, false, cmd_args);
|
||||||
|
|
||||||
|
this->nesting_ = cmd_args->nesting;
|
||||||
|
}
|
||||||
|
|
||||||
|
params::~params()
|
||||||
|
{
|
||||||
|
if (this->needs_end_)
|
||||||
|
{
|
||||||
|
game::Cmd_EndTokenizedString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int params::size() const
|
int params::size() const
|
||||||
{
|
{
|
||||||
return get_cmd_args()->argc[this->nesting_];
|
return get_cmd_args()->argc[this->nesting_];
|
||||||
@ -189,8 +207,10 @@ namespace command
|
|||||||
auto& allocator = *utils::memory::get_allocator();
|
auto& allocator = *utils::memory::get_allocator();
|
||||||
const auto* cmd_string = allocator.duplicate_string(command);
|
const auto* cmd_string = allocator.duplicate_string(command);
|
||||||
|
|
||||||
game::Cmd_AddCommandInternal(cmd_string, game::Cbuf_AddServerText_f, allocator.allocate<game::cmd_function_s>());
|
game::Cmd_AddCommandInternal(cmd_string, game::Cbuf_AddServerText_f,
|
||||||
game::Cmd_AddServerCommandInternal(cmd_string, execute_custom_sv_command, allocator.allocate<game::cmd_function_s>());
|
allocator.allocate<game::cmd_function_s>());
|
||||||
|
game::Cmd_AddServerCommandInternal(cmd_string, execute_custom_sv_command,
|
||||||
|
allocator.allocate<game::cmd_function_s>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,14 @@ namespace command
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
params();
|
params();
|
||||||
|
params(const std::string& text);
|
||||||
|
~params();
|
||||||
|
|
||||||
|
params(params&&) = delete;
|
||||||
|
params(const params&) = delete;
|
||||||
|
|
||||||
|
params& operator=(params&&) = delete;
|
||||||
|
params& operator=(const params&) = delete;
|
||||||
|
|
||||||
[[nodiscard]] int size() const;
|
[[nodiscard]] int size() const;
|
||||||
[[nodiscard]] const char* get(int index) const;
|
[[nodiscard]] const char* get(int index) const;
|
||||||
@ -17,6 +25,7 @@ namespace command
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool needs_end_{false};
|
||||||
int nesting_;
|
int nesting_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ namespace console
|
|||||||
utils::image::object logo;
|
utils::image::object logo;
|
||||||
std::atomic_bool started{false};
|
std::atomic_bool started{false};
|
||||||
std::atomic_bool terminate_runner{false};
|
std::atomic_bool terminate_runner{false};
|
||||||
|
utils::concurrency::container<std::function<void(const std::string& message)>> interceptor{};
|
||||||
utils::concurrency::container<std::queue<std::string>> message_queue{};
|
utils::concurrency::container<std::queue<std::string>> message_queue{};
|
||||||
|
|
||||||
void print_message(const char* message)
|
void print_message(const char* message)
|
||||||
@ -43,6 +44,14 @@ namespace console
|
|||||||
|
|
||||||
void queue_message(const char* message)
|
void queue_message(const char* message)
|
||||||
{
|
{
|
||||||
|
interceptor.access([message](const std::function<void(const std::string&)>& callback)
|
||||||
|
{
|
||||||
|
if (callback)
|
||||||
|
{
|
||||||
|
callback(message);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
message_queue.access([message](std::queue<std::string>& queue)
|
message_queue.access([message](std::queue<std::string>& queue)
|
||||||
{
|
{
|
||||||
queue.push(message);
|
queue.push(message);
|
||||||
@ -202,6 +211,19 @@ namespace console
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_interceptor(std::function<void(const std::string& message)> callback)
|
||||||
|
{
|
||||||
|
interceptor.access([&callback](std::function<void(const std::string&)>& c)
|
||||||
|
{
|
||||||
|
c = std::move(callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_interceptor()
|
||||||
|
{
|
||||||
|
set_interceptor({});
|
||||||
|
}
|
||||||
|
|
||||||
struct component final : generic_component
|
struct component final : generic_component
|
||||||
{
|
{
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
|
@ -3,4 +3,24 @@
|
|||||||
namespace console
|
namespace console
|
||||||
{
|
{
|
||||||
void set_title(const std::string& title);
|
void set_title(const std::string& title);
|
||||||
|
void set_interceptor(std::function<void(const std::string& message)> callback);
|
||||||
|
void remove_interceptor();
|
||||||
|
|
||||||
|
struct scoped_interceptor
|
||||||
|
{
|
||||||
|
scoped_interceptor(std::function<void(const std::string& message)> callback)
|
||||||
|
{
|
||||||
|
set_interceptor(std::move(callback));
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_interceptor()
|
||||||
|
{
|
||||||
|
remove_interceptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
scoped_interceptor(scoped_interceptor&&) = delete;
|
||||||
|
scoped_interceptor(const scoped_interceptor&) = delete;
|
||||||
|
scoped_interceptor& operator=(scoped_interceptor&&) = delete;
|
||||||
|
scoped_interceptor& operator=(const scoped_interceptor&) = delete;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <game/game.hpp>
|
||||||
|
|
||||||
namespace network
|
namespace network
|
||||||
{
|
{
|
||||||
using data_view = std::basic_string_view<uint8_t>;
|
using data_view = std::basic_string_view<uint8_t>;
|
||||||
|
74
src/client/component/rcon.cpp
Normal file
74
src/client/component/rcon.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include <std_include.hpp>
|
||||||
|
#include "loader/component_loader.hpp"
|
||||||
|
|
||||||
|
#include "network.hpp"
|
||||||
|
#include "console.hpp"
|
||||||
|
#include "command.hpp"
|
||||||
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
|
#include <utils/finally.hpp>
|
||||||
|
#include <utils/string.hpp>
|
||||||
|
|
||||||
|
#include <game/utils.hpp>
|
||||||
|
|
||||||
|
namespace rcon
|
||||||
|
{
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::optional<std::string> get_and_validate_rcon_command(const std::string& data)
|
||||||
|
{
|
||||||
|
const command::params params{reinterpret_cast<const char*>(data.data())};
|
||||||
|
|
||||||
|
if (params.size() <= 1)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params[0] != game::get_dvar_string("rcon_password"))
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
return params.join(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rcon_executer(const game::netadr_t& target, const std::string& data)
|
||||||
|
{
|
||||||
|
const auto command = get_and_validate_rcon_command(data);
|
||||||
|
if (!command)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string console_buffer{};
|
||||||
|
|
||||||
|
console::scoped_interceptor _([&console_buffer](const std::string& text)
|
||||||
|
{
|
||||||
|
console_buffer += text;
|
||||||
|
});
|
||||||
|
|
||||||
|
game::Cmd_ExecuteSingleCommand(0, game::CONTROLLER_INDEX_FIRST, command->data(), true);
|
||||||
|
|
||||||
|
network::send(target, "print", console_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void rcon_handler(const game::netadr_t& target, const network::data_view& data)
|
||||||
|
{
|
||||||
|
auto str_data = std::string(reinterpret_cast<const char*>(data.data()), data.size());
|
||||||
|
scheduler::once([target, s = std::move(str_data)]
|
||||||
|
{
|
||||||
|
rcon_executer(target, s);
|
||||||
|
}, scheduler::main);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct component final : server_component
|
||||||
|
{
|
||||||
|
void post_unpack() override
|
||||||
|
{
|
||||||
|
network::on("rcon", rcon_handler);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
REGISTER_COMPONENT(rcon::component)
|
@ -50,8 +50,11 @@ namespace game
|
|||||||
};
|
};
|
||||||
WEAK symbol<void(int localClientNum, ControllerIndex_t controllerIndex, const char* text,
|
WEAK symbol<void(int localClientNum, ControllerIndex_t controllerIndex, const char* text,
|
||||||
bool fromRemoteConsole)> Cmd_ExecuteSingleCommand{
|
bool fromRemoteConsole)> Cmd_ExecuteSingleCommand{
|
||||||
0x1420ED380
|
0x1420ED380, 0x1404F8890
|
||||||
};
|
};
|
||||||
|
WEAK symbol<void(int localClientNum, ControllerIndex_t localControllerIndex, const char* text_in, int max_tokens,
|
||||||
|
bool evalExpressions, CmdArgs* args)> Cmd_TokenizeStringKernel{0x1420EED60, 0x1404FA300};
|
||||||
|
WEAK symbol<void()> Cmd_EndTokenizedString{0x1420ECED0, 0x1404F8420};
|
||||||
WEAK symbol<void(char* text, int maxSize)> Con_GetTextCopy{0x14133A7D0, 0x140182C40};
|
WEAK symbol<void(char* text, int maxSize)> Con_GetTextCopy{0x14133A7D0, 0x140182C40};
|
||||||
|
|
||||||
// DB
|
// DB
|
||||||
|
Loading…
Reference in New Issue
Block a user