From 554a0a88b805dbee8361908538e072302c3ebfa8 Mon Sep 17 00:00:00 2001 From: littleblack111 Date: Wed, 21 May 2025 19:32:26 +0800 Subject: feat: non-admin commands --- src/commandHandler.cpp | 19 ++++++++++++------- src/commandHandler.hpp | 6 ++++-- src/commands.cpp | 2 +- src/session.cpp | 8 ++++++-- src/session.hpp | 1 + 5 files changed, 24 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/commandHandler.cpp b/src/commandHandler.cpp index 7c04f68..7ca559d 100644 --- a/src/commandHandler.cpp +++ b/src/commandHandler.cpp @@ -1,5 +1,6 @@ #include "commandHandler.hpp" #include "log.hpp" +#include "session.hpp" #include "sessionManager.hpp" #include @@ -29,6 +30,7 @@ bool CCommandHandler::registerCommand(const SCommand &command) { m_vCommands.push_back(command); log(TRACE, "CommandHandler: registered command: {}", command.name); + return true; } @@ -54,14 +56,18 @@ CCommandHandler::SResult CCommandHandler::exeCommand(const SCommand &command, co return command.exe(parsed); } -CCommandHandler::SResult CCommandHandler::newCommand(const std::string &command, const std::string &args) const { +CCommandHandler::SResult CCommandHandler::newCommand(const std::string &command, const std::string &args, CSession* const user) const { if (!validCommand(command)) return {.result = "Invalid command", .good = false}; - return exeCommand(*getCommand(command), args); + const auto cmd = getCommand(command); + if (cmd->requireAdmin && !user->isAdmin()) + return {.result = "Permission denied", .good = false}; + + return exeCommand(*cmd, args); } -void CCommandHandler::handleCommand(std::string input, const std::string &ip) const { +void CCommandHandler::handleCommand(std::string input, CSession* const user) const { input = input.substr(1); std::string command; @@ -80,13 +86,12 @@ void CCommandHandler::handleCommand(std::string input, const std::string &ip) co } args.empty() ? log(LOG, "Spawning Command: {}", command) : log(LOG, "Spawning Command: {}, Args: {}", command, args); - const auto exe = newCommand(command, args); + const auto exe = newCommand(command, args, user); std::function outputter = [](eFormatType type, const std::string &msg) { log(type, "{}", msg); }; - if (!ip.empty()) - if (auto session = g_pSessionManager->getByIp(ip)) - outputter = [session](eFormatType, const std::string &msg) { session->write(msg); }; + if (!user->getIp().empty()) + outputter = [user](eFormatType, const std::string &msg) { user->write(msg); }; exe.good ? exe.result.empty() ? outputter(LOG, "Command succeeded") : outputter(LOG, exe.result) : exe.result.empty() ? outputter(ERR, "Command failed") : outputter(ERR, exe.result); diff --git a/src/commandHandler.hpp b/src/commandHandler.hpp index a69011e..f446574 100644 --- a/src/commandHandler.hpp +++ b/src/commandHandler.hpp @@ -1,5 +1,6 @@ #pragma once +#include "session.hpp" #include #include #include @@ -23,6 +24,7 @@ class CCommandHandler { }; struct SCommand { + bool requireAdmin = true; std::string name; std::function parser; std::function exe; @@ -32,8 +34,8 @@ class CCommandHandler { bool validCommand(const std::string &command) const; // return false if command struct is invalid bool registerCommand(const SCommand &command); - SResult newCommand(const std::string &command, const std::string &args) const; - void handleCommand(std::string input, const std::string &ip = {}) const; + SResult newCommand(const std::string &command, const std::string &args, CSession* const user) const; + void handleCommand(std::string input, CSession* const user = nullptr) const; template struct SMakeCommandArgs { diff --git a/src/commands.cpp b/src/commands.cpp index b20279d..544468d 100644 --- a/src/commands.cpp +++ b/src/commands.cpp @@ -43,7 +43,7 @@ void registerCommands() { g_pSessionManager->kick(session, true, data.reason); return {.result = "Kicked '" + data.target + "': " + data.reason, .good = true}; }})); - g_pCommandHandler->registerCommand({.name = "list", .parser = [](const std::string &args) -> CCommandHandler::SParseResult { + g_pCommandHandler->registerCommand({.requireAdmin = false, .name = "list", .parser = [](const std::string &args) -> CCommandHandler::SParseResult { (void)args; return {.data = std::any(), .good = true}; }, .exe = [](const std::any &parsed) -> CCommandHandler::SResult { (void)parsed; diff --git a/src/session.cpp b/src/session.cpp index d88af2f..e8597e3 100644 --- a/src/session.cpp +++ b/src/session.cpp @@ -86,8 +86,8 @@ void CSession::recvLoop() { } const auto isCommand = g_pCommandHandler->isCommand(recvData->data); - if (m_isAdmin && isCommand) - g_pCommandHandler->handleCommand(recvData->data, m_ip); + if (isCommand) + g_pCommandHandler->handleCommand(recvData->data, this); g_pChatManager->newMessage({.msg = recvData->data, .username = m_name, .admin = isCommand}); } @@ -270,6 +270,10 @@ const std::string &CSession::getIp() const { return m_ip; } +bool CSession::isAdmin() const { + return m_isAdmin; +} + void CSession::setSelf(std::pair> *self) { this->self = self; } diff --git a/src/session.hpp b/src/session.hpp index 1669964..e33635d 100644 --- a/src/session.hpp +++ b/src/session.hpp @@ -24,6 +24,7 @@ class CSession { const std::string &getName() const; const std::string &getIp() const; + bool isAdmin() const; void setSelf(std::pair> *self); std::unique_ptr read(); -- cgit v1.2.3