summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/chatManager.cpp6
-rw-r--r--src/chatManager.hpp2
-rw-r--r--src/commandHandler.cpp32
-rw-r--r--src/commandHandler.hpp2
-rw-r--r--src/inputManager.cpp26
-rw-r--r--src/session.cpp22
-rw-r--r--src/session.hpp5
-rw-r--r--src/sessionManager.cpp11
-rw-r--r--src/sessionManager.hpp4
9 files changed, 69 insertions, 41 deletions
diff --git a/src/chatManager.cpp b/src/chatManager.cpp
index 2f6a556..4392e00 100644
--- a/src/chatManager.cpp
+++ b/src/chatManager.cpp
@@ -13,7 +13,7 @@ CChatManager::~CChatManager() {
void CChatManager::newMessage(const SMessage &msg) {
log(LOG, "{}: {}", msg.username, msg.msg);
- broadcastMessage(msg);
+ g_pSessionManager->broadcastChat(msg);
m_vMessages.push_back(msg);
}
@@ -21,10 +21,6 @@ std::string CChatManager::fmtBroadcastMessage(const SMessage &msg) {
return NFormatter::fmt(NONE, "{}: {}", msg.username, msg.msg);
}
-void CChatManager::broadcastMessage(const SMessage &msg) {
- g_pSessionManager->broadcastChat(fmtBroadcastMessage(msg), msg.username);
-}
-
const std::vector<CChatManager::SMessage> &CChatManager::getChat() const {
return m_vMessages;
}
diff --git a/src/chatManager.hpp b/src/chatManager.hpp
index 0560657..084c002 100644
--- a/src/chatManager.hpp
+++ b/src/chatManager.hpp
@@ -11,9 +11,9 @@ class CChatManager {
struct SMessage {
std::string msg;
std::string username;
+ bool admin = false;
};
void newMessage(const SMessage &msg);
- void broadcastMessage(const SMessage &msg);
std::string fmtBroadcastMessage(const SMessage &msg);
const std::vector<SMessage> &getChat() const;
diff --git a/src/commandHandler.cpp b/src/commandHandler.cpp
index 12b51dc..712bbe2 100644
--- a/src/commandHandler.cpp
+++ b/src/commandHandler.cpp
@@ -1,5 +1,6 @@
#include "commandHandler.hpp"
#include "log.hpp"
+#include "sessionManager.hpp"
#include <algorithm>
CCommandHandler::CCommandHandler() {
@@ -56,3 +57,34 @@ CCommandHandler::SResult CCommandHandler::newCommand(const std::string &command,
return exeCommand(*getCommand(command), args);
}
+
+void CCommandHandler::handleCommand(std::string input, const char ip[INET_ADDRSTRLEN]) const {
+ input = input.substr(1);
+
+ std::string command;
+ std::string args;
+
+ size_t spacePos = input.find(' ');
+ if (spacePos == std::string::npos) {
+ command = input;
+ args = "";
+ } else {
+ command = input.substr(0, spacePos);
+ // skip extra spaces
+ size_t startPos = input.find_first_not_of(' ', spacePos);
+ if (startPos != std::string::npos)
+ args = input.substr(startPos);
+ }
+
+ args.empty() ? log(LOG, "Spawning Command: {}", command) : log(LOG, "Spawning Command: {}, Args: {}", command, args);
+ const auto exe = newCommand(command, args);
+
+ std::function<void(eFormatType, const std::string &)> outputter = [](eFormatType type, const std::string &msg) { log(type, "{}", msg); };
+
+ if (ip != nullptr)
+ if (auto session = g_pSessionManager->getByIp(ip))
+ outputter = [session](eFormatType, const std::string &msg) { session->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 78ab2e5..8d97fd5 100644
--- a/src/commandHandler.hpp
+++ b/src/commandHandler.hpp
@@ -3,6 +3,7 @@
#include <any>
#include <functional>
#include <memory>
+#include <netinet/in.h>
#include <string>
#include <vector>
@@ -32,6 +33,7 @@ class CCommandHandler {
// 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 char ip[INET_ADDRSTRLEN] = {}) const;
template <typename T>
struct SMakeCommandArgs {
diff --git a/src/inputManager.cpp b/src/inputManager.cpp
index 57b7b06..8de26bd 100644
--- a/src/inputManager.cpp
+++ b/src/inputManager.cpp
@@ -16,30 +16,6 @@ void CInputManager::run() {
inputLoop();
}
-static void handleCommand(std::string &input) {
- input = input.substr(1);
-
- std::string command;
- std::string args;
-
- size_t spacePos = input.find(' ');
- if (spacePos == std::string::npos) {
- command = input;
- args = "";
- } else {
- command = input.substr(0, spacePos);
- // skip extra spaces
- size_t startPos = input.find_first_not_of(' ', spacePos);
- if (startPos != std::string::npos)
- args = input.substr(startPos);
- }
-
- args.empty() ? log(TRACE, "Spawning Command: {}", command) : log(TRACE, "Spawning Command: {}, Args: {}", command, args);
- const auto exe = g_pCommandHandler->newCommand(command, args);
- exe.good ? exe.result.empty() ? log(LOG, "Command {} succeeded", command) : log(LOG, "Command {} succeeded: {}", command, exe.result) : exe.result.empty() ? log(ERR, "Command {} failed", command)
- : log(ERR, "Command {} failed: {}", command, exe.result);
-};
-
void CInputManager::inputLoop() {
while (true) {
std::string input;
@@ -49,6 +25,6 @@ void CInputManager::inputLoop() {
if (input.empty())
continue;
- g_pCommandHandler->isCommand(input) ? handleCommand(input) : g_pChatManager->broadcastMessage({.msg = input, .username = "Server"});
+ g_pCommandHandler->isCommand(input) ? g_pCommandHandler->handleCommand(input) : g_pChatManager->newMessage({.msg = input, .username = "Server"});
}
}
diff --git a/src/session.cpp b/src/session.cpp
index 9668cd8..26dc3f8 100644
--- a/src/session.cpp
+++ b/src/session.cpp
@@ -1,5 +1,6 @@
#include "session.hpp"
#include "chatManager.hpp"
+#include "commandHandler.hpp"
#include "log.hpp"
#include "server.hpp"
#include "sessionManager.hpp"
@@ -17,7 +18,8 @@ CSession::CSession()
throw std::runtime_error("session: Failed to create socket");
inet_ntop(AF_INET, &m_addr.sin_addr, m_ip, INET_ADDRSTRLEN);
- m_port = ntohs(m_addr.sin_port);
+ m_port = ntohs(m_addr.sin_port);
+ m_isAdmin = std::ranges::any_of(m_adminIps, [this](const char *ip) { return strcmp(ip, m_ip) == 0; });
log(LOG, "Client {} connected on port {}", m_ip, m_port);
log(TRACE, "session: initialized");
@@ -70,7 +72,12 @@ void CSession::recvLoop() {
if (!recvData->good)
break;
- g_pChatManager->newMessage({.msg = recvData->data, .username = m_name});
+ recvData->sanitize();
+ const auto isCommand = g_pCommandHandler->isCommand(recvData->data);
+ if (m_isAdmin && isCommand)
+ g_pCommandHandler->handleCommand(recvData->data, m_ip);
+
+ g_pChatManager->newMessage({.msg = recvData->data, .username = m_name, .admin = isCommand});
}
}
@@ -124,7 +131,7 @@ void CSession::run() {
#endif
if (registerSession()) {
for (const auto &chat : g_pChatManager->getChat())
- write(g_pChatManager->fmtBroadcastMessage(chat));
+ writeChat(chat);
recvLoop();
} else
log(LOG, "Client {} exited without even registering", m_ip);
@@ -200,6 +207,15 @@ bool CSession::write(const std::string &msg) {
return write("{}", msg);
}
+void CSession::writeChat(const CChatManager::SMessage &msg) {
+ if (m_name != msg.username) {
+ if (msg.admin && !m_isAdmin)
+ return;
+
+ write(g_pChatManager->fmtBroadcastMessage(msg));
+ }
+}
+
const std::string &CSession::getName() const {
return m_name;
}
diff --git a/src/session.hpp b/src/session.hpp
index 18c587d..1b7b8db 100644
--- a/src/session.hpp
+++ b/src/session.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "FileDescriptor.hpp"
+#include "chatManager.hpp"
#include "format.hpp"
#include <memory>
#include <netinet/in.h>
@@ -32,12 +33,15 @@ class CSession {
bool write(std::format_string<Args...> fmt, Args &&...args);
template <typename... Args>
bool write(eFormatType type, std::format_string<Args...> fmt, Args &&...args);
+ void writeChat(const CChatManager::SMessage &msg);
void run();
bool isValid();
private:
+ constexpr static char m_adminIps[1][INET_ADDRSTRLEN] = {"127.0.0.1"};
+
enum eEventType : std::uint8_t {
READ,
WRITE
@@ -50,6 +54,7 @@ class CSession {
std::string m_name;
char m_ip[INET_ADDRSTRLEN];
int m_port;
+ bool m_isAdmin = false;
bool m_isReading = false;
diff --git a/src/sessionManager.cpp b/src/sessionManager.cpp
index 51bede4..0e27367 100644
--- a/src/sessionManager.cpp
+++ b/src/sessionManager.cpp
@@ -45,13 +45,12 @@ void CSessionManager::broadcast(const std::string &msg) const {
session->write(msg);
}
-void CSessionManager::broadcastChat(const std::string &msg, const std::string &username) const {
+void CSessionManager::broadcastChat(const CChatManager::SMessage &msg) const {
for (const auto &[thread, session] : m_vSessions) {
if (!session)
continue;
- auto name = session->getName();
- if (name != username)
- session->write(msg);
+
+ session->writeChat(msg);
}
}
@@ -83,8 +82,8 @@ void CSessionManager::kick(std::pair<std::jthread, std::shared_ptr<CSession>> *s
auto it = std::ranges::find_if(m_vSessions, [session](const auto &s) { return s.second.get() == session->second.get(); });
if (it != m_vSessions.end()) {
- if (!reason.empty())
- it->second->write(reason);
+ if (!reason.empty())
+ it->second->write(reason);
const auto native_handle = it->first.native_handle();
if (it->first.joinable())
it->first.detach(); // .detach the thread since it's removing itself
diff --git a/src/sessionManager.hpp b/src/sessionManager.hpp
index a0f4389..4ca3311 100644
--- a/src/sessionManager.hpp
+++ b/src/sessionManager.hpp
@@ -1,5 +1,6 @@
#pragma once
+#include "chatManager.hpp"
#include "format.hpp"
#include "session.hpp"
#include <memory>
@@ -27,9 +28,10 @@ class CSessionManager {
std::vector<std::shared_ptr<CSession>> getSessions() const;
private:
- void broadcastChat(const std::string &msg, const std::string &username) const;
+ void broadcastChat(const CChatManager::SMessage &msg) const;
std::vector<std::pair<std::jthread, std::shared_ptr<CSession>>> m_vSessions;
+
friend class CChatManager;
};
inline std::shared_ptr<CSessionManager> g_pSessionManager;