#pragma once #include #include #include #include #include #include "Client.hh" #include "ServerState.hh" class Server { public: Server() = delete; Server(const Server&) = delete; Server(Server&&) = delete; Server(std::shared_ptr base, std::shared_ptr state); virtual ~Server() = default; void listen(const std::string& addr_str, const std::string& socket_path, GameVersion version, ServerBehavior initial_state); void listen(const std::string& addr_str, const std::string& addr, int port, GameVersion version, ServerBehavior initial_state); void listen(const std::string& addr_str, int port, GameVersion version, ServerBehavior initial_state); void add_socket(const std::string& addr_str, int fd, GameVersion version, ServerBehavior initial_state); void connect_client(struct bufferevent* bev, uint32_t address, uint16_t client_port, uint16_t server_port, GameVersion version, ServerBehavior initial_state); std::shared_ptr get_client() const; private: std::shared_ptr base; struct ListeningSocket { std::string addr_str; int fd; GameVersion version; ServerBehavior behavior; std::unique_ptr listener; ListeningSocket( Server* s, const std::string& name, int fd, GameVersion version, ServerBehavior behavior); }; std::unordered_map listening_sockets; std::unordered_map> channel_to_client; std::shared_ptr state; static void dispatch_on_listen_accept(struct evconnlistener* listener, evutil_socket_t fd, struct sockaddr *address, int socklen, void* ctx); static void dispatch_on_listen_error(struct evconnlistener* listener, void* ctx); void disconnect_client(std::shared_ptr c); void on_listen_accept(struct evconnlistener* listener, evutil_socket_t fd, struct sockaddr *address, int socklen); void on_listen_error(struct evconnlistener* listener); static void on_client_input(Channel& ch, uint16_t command, uint32_t flag, std::string& data); static void on_client_error(Channel& ch, short events); };