summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/libsock/server/client.hpp105
-rw-r--r--include/libsock/server/server.hpp25
2 files changed, 130 insertions, 0 deletions
diff --git a/include/libsock/server/client.hpp b/include/libsock/server/client.hpp
new file mode 100644
index 0000000..b86b440
--- /dev/null
+++ b/include/libsock/server/client.hpp
@@ -0,0 +1,105 @@
+#pragma once
+
+#include "misc/FileDescriptor.hpp"
+#include "misc/memory.hpp"
+#include <format>
+#include <functional>
+#include <netinet/in.h>
+#include <optional>
+#include <string>
+#include <sys/socket.h>
+#include <thread>
+#include <vector>
+
+namespace LibSock {
+namespace Client {
+
+struct SRecvData {
+ std::string data;
+ const size_t size = 1024;
+ bool good = false;
+
+ bool isEmpty() const;
+ void sanitize();
+
+ static constexpr char asciiEscape = 0x1B; // 
+};
+
+enum eEventType : std::uint8_t {
+ READ,
+ WRITE
+};
+
+class Client {
+ public:
+ Client(bool track = false, bool oneShot = true);
+ ~Client();
+
+ const std::string &getName() const;
+ const std::string &getIp() const;
+ bool isAdmin() const;
+
+ UP<SRecvData> read(std::optional<std::function<void(const SRecvData &)>> cb = std::nullopt);
+ UP<SRecvData> read(const std::string &msg, std::optional<std::function<void(const SRecvData &)>> cb = std::nullopt);
+ bool write(const std::string &msg, std::optional<std::function<void(const SRecvData &)>> cb = std::nullopt);
+ template <typename... Args>
+ bool write(std::format_string<Args...> fmt, Args &&...args);
+
+ void run();
+
+ bool isValid();
+
+ private:
+ WP<Client> self;
+ SP<CFileDescriptor> m_sockfd;
+ sockaddr_in m_addr;
+ socklen_t m_addrLen = sizeof(m_addr);
+ std::string m_name;
+ std::string m_ip;
+ int m_port;
+ bool m_track;
+ bool m_oneShot;
+
+ std::optional<std::string> m_szReading = std::nullopt;
+
+ void recvLoop();
+
+ friend class Clients;
+};
+
+struct SData {
+ std::string msg;
+ std::optional<WP<Client>> sender = std::nullopt;
+ bool admin = false;
+};
+
+class Clients {
+ public:
+ Clients();
+ ~Clients();
+
+ void newClient(std::optional<std::function<void()>> cb = std::nullopt);
+
+ void run(std::optional<std::function<void()>> cb = std::nullopt);
+ void broadcast(const std::string &msg, std::optional<WP<Client>> self = std::nullopt); // second param only specified when we want to exclude the sender
+ void kick(WP<Client> client, const bool kill = false, const std::string &reason = "");
+ void addClient(const Client &client);
+
+ bool nameExists(const std::string &name);
+ void shutdownClients();
+
+ SP<Client> getByName(const std::string &name) const;
+ SP<Client> getByIp(const std::string &ip) const;
+ std::vector<SP<Client>> getClients() const;
+ std::vector<SData> getDatas() const;
+
+ private:
+ void broadcast(const SData &msg);
+
+ std::vector<std::pair<std::jthread, SP<Client>>> m_vClients;
+ std::vector<SData> m_vDatas;
+};
+inline SP<Clients> pClients;
+
+} // namespace Client
+} // namespace LibSock
diff --git a/include/libsock/server/server.hpp b/include/libsock/server/server.hpp
new file mode 100644
index 0000000..c97c945
--- /dev/null
+++ b/include/libsock/server/server.hpp
@@ -0,0 +1,25 @@
+#pragma once
+#include "misc/FileDescriptor.hpp"
+#include "misc/memory.hpp"
+#include <mutex>
+#include <netinet/in.h>
+
+namespace LibSock {
+namespace Server {
+
+class Server {
+ public:
+ Server(uint16_t port, bool reuseaddr = true, bool keepalive = false);
+ ~Server();
+ SP<CFileDescriptor> getSocket() const;
+
+ private:
+ SP<CFileDescriptor> m_sockfd;
+ sockaddr_in m_addr;
+ uint16_t m_port;
+
+ mutable std::mutex m_mutex;
+};
+inline UP<Server> pServer;
+} // namespace Server
+} // namespace LibSock