parent
91a8b5bf94
commit
85794fd992
@ -81,6 +81,24 @@ namespace command
|
||||
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
|
||||
{
|
||||
return get_cmd_args()->argc[this->nesting_];
|
||||
@ -189,8 +207,10 @@ namespace command
|
||||
auto& allocator = *utils::memory::get_allocator();
|
||||
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_AddServerCommandInternal(cmd_string, execute_custom_sv_command, allocator.allocate<game::cmd_function_s>());
|
||||
game::Cmd_AddCommandInternal(cmd_string, game::Cbuf_AddServerText_f,
|
||||
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:
|
||||
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]] const char* get(int index) const;
|
||||
@ -17,6 +25,7 @@ namespace command
|
||||
}
|
||||
|
||||
private:
|
||||
bool needs_end_{false};
|
||||
int nesting_;
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,7 @@ namespace console
|
||||
utils::image::object logo;
|
||||
std::atomic_bool started{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{};
|
||||
|
||||
void print_message(const char* message)
|
||||
@ -43,6 +44,14 @@ namespace console
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
{
|
||||
void post_unpack() override
|
||||
|
@ -3,4 +3,24 @@
|
||||
namespace console
|
||||
{
|
||||
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
|
||||
|
||||
#include <game/game.hpp>
|
||||
|
||||
namespace network
|
||||
{
|
||||
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,
|
||||
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};
|
||||
|
||||
// DB
|
||||
|
Loading…
Reference in New Issue
Block a user