7 #include <netinet/in.h>
8 #include <sys/socket.h>
14 #include <gpsp/client.h>
15 #include <gpcm/client.h>
16 #include <webserver/client.h>
17 #include <browsing/client.h>
18 #include <gamestats/client.h>
19 #include <qr/client.h>
20 #include <websocket/client.h>
26 std::shared_lock<std::shared_mutex> guard(g_settings_mutex);
29 int socket_type = SOCK_STREAM;
39 case Server::Type::QR:
40 port = g_settings[
"qr"][
"port"].asInt();
41 socket_type = SOCK_DGRAM;
43 case Server::Type::GPSP:
44 port = g_settings[
"gpsp"][
"port"].asInt();
46 case Server::Type::GPCM:
47 port = g_settings[
"gpcm"][
"port"].asInt();
49 case Server::Type::Webserver:
50 port = g_settings[
"webserver"][
"port"].asInt();
52 case Server::Type::Browsing:
53 port = g_settings[
"browsing"][
"port"].asInt();
55 case Server::Type::GameStats:
56 port = g_settings[
"gamestats"][
"port"].asInt();
58 case Server::Type::Websocket:
59 port = g_settings[
"websocket"][
"port"].asInt();
63 if ((this->
_socket = socket(AF_INET, socket_type, 0)) < 0)
65 Logger::error(
"Server::Server() at socket", this->
_type);
69 if (setsockopt(this->
_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt_reuse,
sizeof(opt_reuse)))
71 Logger::error(
"Server::Server() at setsockopt with opt_reuse", this->
_type);
76 this->
_address.sin_addr.s_addr = INADDR_ANY;
77 this->
_address.sin_port = htons(port);
79 if (bind(this->
_socket, (
struct sockaddr*)&this->
_address,
sizeof(this->_address)) < 0)
81 Logger::error(
"Server::Server() at bind", this->
_type);
88 std::lock_guard<std::mutex> guard(this->
_mutex);
96 struct sockaddr_in client_address;
97 socklen_t client_address_len =
sizeof(client_address);
99 if (listen(this->
_socket, 3) < 0)
101 Logger::error(
"Server::Listen() on listen", this->
_type);
109 if ((client_socket = accept(this->
_socket, (
struct sockaddr*)&client_address, &client_address_len)) < 0)
111 Logger::error(
"Server::Listen() on accept", this->
_type);
117 case Server::Type::GPSP:
119 std::lock_guard<std::mutex> guard(this->
_mutex);
121 this->
_clients.push_back(std::make_shared<GPSP::Client>(client_socket, client_address));
123 std::shared_ptr<Net::Socket> client = this->
_clients.back();
127 std::thread t([client]() {
133 case Server::Type::GPCM:
135 std::lock_guard<std::mutex> guard(this->
_mutex);
137 this->
_clients.push_back(std::make_shared<GPCM::Client>(client_socket, client_address));
139 std::shared_ptr<Net::Socket> client = this->
_clients.back();
143 std::thread t([client]() {
149 case Server::Type::Browsing:
151 std::lock_guard<std::mutex> guard(this->
_mutex);
153 this->
_clients.push_back(std::make_shared<Browsing::Client>(client_socket, client_address));
155 std::shared_ptr<Net::Socket> client = this->
_clients.back();
159 std::thread t([client]() {
165 case Server::Type::Webserver:
167 std::lock_guard<std::mutex> guard(this->
_mutex);
169 this->
_clients.push_back(std::make_shared<Webserver::Client>(client_socket, client_address));
171 std::shared_ptr<Net::Socket> client = this->
_clients.back();
175 std::thread t([client]() {
181 case Server::Type::GameStats:
183 std::lock_guard<std::mutex> guard(this->
_mutex);
185 this->
_clients.push_back(std::make_shared<GameStats::Client>(client_socket, client_address));
187 std::shared_ptr<Net::Socket> client = this->
_clients.back();
191 std::thread t([client]() {
197 case Server::Type::Websocket:
199 std::lock_guard<std::mutex> guard(this->
_mutex);
201 this->
_clients.push_back(std::make_shared<Websocket::Client>(client_socket, client_address));
203 std::shared_ptr<Net::Socket> client = this->
_clients.back();
207 std::thread t([client]() {
226 struct sockaddr_in client_address;
227 socklen_t client_address_len =
sizeof(client_address);
233 std::vector<unsigned char> buffer(2048, 0);
236 ssize_t recv_size = recvfrom(
240 (
struct sockaddr*)&client_address, &client_address_len
245 buffer.resize(recv_size);
249 case Server::Type::QR:
262 Logger::error(
"Server::UDPListen() on recvfrom with state \"" + std::to_string(recv_size) +
"\"", this->
_type);
270 for(std::shared_ptr<Net::Socket> client : this->
_clients)
274 case Server::Type::GPSP:
275 dynamic_cast<GPSP::Client*
>(client.get())->Disconnect();
277 case Server::Type::GPCM:
278 dynamic_cast<GPCM::Client*
>(client.get())->Disconnect();
280 case Server::Type::Browsing:
283 case Server::Type::Webserver:
286 case Server::Type::GameStats:
295 shutdown(this->
_socket, SHUT_RDWR);
311 Logger::info(
"Server shutdown", this->
_type);
316 std::shared_lock<std::shared_mutex> guard2(g_settings_mutex);
318 if ((g_logger_mode & Logger::Mode::Development) != 0)
320 Logger::info(
"Client " + client.
GetAddress() +
" connected",
321 this->_type, g_settings[
"show_client_connect"].asBool());
327 std::shared_lock<std::shared_mutex> guard2(g_settings_mutex);
329 if ((g_logger_mode & Logger::Mode::Development) != 0)
331 Logger::info(
"Client " + client->GetAddress() +
" connected",
332 this->_type, g_settings[
"show_client_connect"].asBool());
338 std::shared_lock<std::shared_mutex> guard2(g_settings_mutex);
342 std::lock_guard<std::mutex> guard(this->
_mutex);
345 auto it = std::find_if(this->
_clients.begin(), this->_clients.end(),
346 [rawPtrToSearch =
const_cast<Net::Socket*
>(&client)](
const std::shared_ptr<Net::Socket>& ptr)
348 return ptr.get() == rawPtrToSearch;
355 if ((g_logger_mode & Logger::Mode::Development) != 0)
357 Logger::info(
"Client " + client.
GetAddress() +
" disconnected",
358 this->_type, g_settings[
"show_client_disconnect"].asBool());
366 if ((g_logger_mode & Logger::Mode::Development) != 0)
368 Logger::info(
"Client " + client.
GetAddress() +
" disconnected",
369 this->_type, g_settings[
"show_client_disconnect"].asBool());
Client class for handling browsing requests.
void Listen()
Listens for incoming requests from the client.
Represents a GPCM client.
void Listen()
Listens for incoming messages from the GPCM client.
Client class for GPSP protocol.
void Listen()
Listen for incoming messages.
Represents a client for game statistics.
void Listen()
Start listening for client requests.
A base class representing a network socket.
struct sockaddr_in _address
std::string GetSocketType() const
Gets the socket type.
std::string GetAddress() const
Gets the full address (IP:Port) associated with the socket.
Represents a client for QR protocol.
void onRequest(const std::vector< unsigned char > &request)
Event handler for incoming requests.
std::vector< std::shared_ptr< Net::Socket > > GetClients()
Get the vector of client sockets connected to this server.
void Close()
Close the server and stop listening for incoming connections.
void onClientConnect(const Net::Socket &client) const
Called when a client connects to the server.
std::vector< std::shared_ptr< Net::Socket > > _clients
Server(Server::Type type)
Constructor for the Server class.
void UDPListen()
Start listening for incoming UDP packets on the server.
Type
Enum defining the types of servers.
void onClientDisconnect(const Net::Socket &client)
Called when a client disconnects from the server.
void DisconnectAllClients()
Disconnect all connected clients from the server.
void onServerListen() const
Called when the server starts listening for incoming connections.
void onServerShutdown() const
Called when the server is shutting down.
void Listen()
Start listening for incoming connections on the server.
void Listen()
Start listening for incoming requests.