Symphony Of Empires
network.hpp
Go to the documentation of this file.
1 // Eng3D - General purpouse game engine
2 // Copyright (C) 2021, Eng3D contributors
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with this program. If not, see <https://www.gnu.org/licenses/>.
16 //
17 // ----------------------------------------------------------------------------
18 // Name:
19 // network.hpp
20 //
21 // Abstract:
22 // Does some important stuff.
23 // ----------------------------------------------------------------------------
24 
25 #pragma once
26 
27 #include <exception>
28 #include <vector>
29 #include <string>
30 #include <cstring>
31 #include <atomic>
32 #include <thread>
33 #include <mutex>
34 #include <deque>
35 #include <stdexcept>
36 #include <functional>
37 #include <tbb/concurrent_queue.h>
38 
39 #ifdef E3D_TARGET_WINDOWS
40 // Allow us to use deprecated functions like inet_addr
41 # define _WINSOCK_DEPRECATED_NO_WARNINGS
42 // MingW heavily dislikes ws2def.h and causes spurious errors
43 //# ifndef __MINGW32__
44 //# include <ws2def.h>
45 //# endif
46 # ifndef WINSOCK2_IMPORTED
47 # define WINSOCK2_IMPORTED
48 # include <winsock2.h>
49 # endif
50 #elif defined E3D_TARGET_UNIX
51 # define _XOPEN_SOURCE_EXTENDED 1
52 # include <netdb.h>
53 # include <arpa/inet.h>
54 #endif
55 
56 // Visual Studio does not know about UNISTD.H, Mingw does through
57 #ifndef _MSC_VER
58 # include <unistd.h>
59 #endif
60 
61 #include "eng3d/utils.hpp"
62 
63 namespace Eng3D::Deser {
64  struct Archive;
65 }
66 
67 namespace Eng3D::Networking {
68  class SocketException : public std::exception {
69  std::string buffer;
70  public:
71  SocketException(const std::string& msg) {
72  buffer = msg;
73  }
74  virtual const char* what() const noexcept {
75  return buffer.c_str();
76  }
77  };
78 
79  class SocketStream {
80  bool is_server_stream = false;
81  public:
82  SocketStream() = default;
83  SocketStream(int _fd) : fd(_fd) {}
84  ~SocketStream() = default;
85  bool send(const void* data, size_t size, std::function<bool()> pred);
86  bool recv(void* data, size_t size, std::function<bool()> pred = 0);
87  void set_timeout(int seconds);
88  bool has_pending();
89  void set_blocking(bool value);
90 
91  int fd;
92  };
93 
94  enum class PacketCode {
95  OK,
97  };
98 
99  class Packet {
100  size_t n_data = 0;
101  PacketCode code = PacketCode::OK;
102  public:
103  Packet() = default;
104  Packet(int _fd) {
106  }
107  Packet(int _fd, const void* buf, size_t size) {
109  this->data(buf, size);
110  }
111  ~Packet() = default;
112 
113  inline void* data() {
114  return static_cast<void*>(&buffer[0]);
115  }
116 
117  template<typename T>
118  inline void data(const T* buf = nullptr, size_t size = sizeof(T)) {
119  n_data = size;
120  buffer.resize(n_data);
121  if(buf != nullptr)
122  std::memcpy(&buffer[0], buf, size);
123  }
124 
125  inline size_t size() const {
126  return n_data;
127  }
128 
129  inline bool is_ok() const {
130  return (code == PacketCode::OK);
131  }
132 
133  bool send();
134  bool recv();
135 
136  std::vector<uint8_t> buffer;
138  std::function<bool()> pred;
139  };
140 
141  class ServerClient {
142  int conn_fd = 0;
143  public:
144  ServerClient() = default;
145  ~ServerClient();
146 
147  int try_connect(int fd);
148  void flush_packets();
149  bool has_pending();
150 
151  std::atomic<bool> is_connected;
152  tbb::concurrent_bounded_queue<Eng3D::Networking::Packet> packets;
153  std::string username;
154  std::unique_ptr<std::thread> thread;
155  };
156 
157  class Server {
158  protected:
159  struct sockaddr_in addr;
160  int fd;
161  std::atomic<bool> run;
162  public:
163  class Exception : public std::exception {
164  std::string msg;
165  public:
166  Exception(const std::string& _msg)
167  : msg{ _msg }
168  {
169 
170  }
171  virtual const char* what() const noexcept {
172  return msg.c_str();
173  }
174  };
175 
176  Server(unsigned port, unsigned max_conn);
177  ~Server();
178  void broadcast(const Eng3D::Networking::Packet& packet);
179  void do_netloop(std::function<void(int i)> on_wake_thread, int id);
180 
181  virtual void on_connect(int conn_fd, int id) = 0;
182  virtual void on_disconnect() = 0;
183  virtual void handler(const Packet& packet, Eng3D::Deser::Archive& ar, int id) = 0;
184 
186  std::size_t n_clients;
187  std::size_t player_count = 0;
188  };
189 
190  class Client {
191  protected:
192  struct sockaddr_in addr;
193  int fd;
194  public:
195  class Exception : public std::exception {
196  std::string msg;
197  public:
198  Exception(const std::string& _msg)
199  : msg{ _msg }
200  {
201 
202  }
203  virtual const char* what() const noexcept {
204  return msg.c_str();
205  }
206  };
207 
208  Client(std::string host, const unsigned port);
209  ~Client();
210  void do_netloop(std::function<bool()> cond, std::function<void(const Packet& packet, Eng3D::Deser::Archive& ar)> handler);
211 
212  inline void send(const Eng3D::Networking::Packet& packet) {
213  packets.push(packet);
214  }
215 
216  inline int get_fd() const {
217  return fd;
218  }
219 
220  tbb::concurrent_bounded_queue<Eng3D::Networking::Packet> packets;
221  std::string username;
222  };
223 }
virtual const char * what() const noexcept
Definition: network.hpp:203
Exception(const std::string &_msg)
Definition: network.hpp:198
tbb::concurrent_bounded_queue< Eng3D::Networking::Packet > packets
Definition: network.hpp:220
Client(std::string host, const unsigned port)
Definition: network.cpp:380
struct sockaddr_in addr
Definition: network.hpp:192
void do_netloop(std::function< bool()> cond, std::function< void(const Packet &packet, Eng3D::Deser::Archive &ar)> handler)
Definition: network.cpp:424
void send(const Eng3D::Networking::Packet &packet)
Definition: network.hpp:212
std::vector< uint8_t > buffer
Definition: network.hpp:136
std::function< bool()> pred
Definition: network.hpp:138
Packet(int _fd, const void *buf, size_t size)
Definition: network.hpp:107
void data(const T *buf=nullptr, size_t size=sizeof(T))
Definition: network.hpp:118
size_t size() const
Definition: network.hpp:125
Exception(const std::string &_msg)
Definition: network.hpp:166
virtual const char * what() const noexcept
Definition: network.hpp:171
void flush_packets()
TODO: flush packets.
Definition: network.cpp:230
tbb::concurrent_bounded_queue< Eng3D::Networking::Packet > packets
Definition: network.hpp:152
std::unique_ptr< std::thread > thread
Definition: network.hpp:154
std::atomic< bool > is_connected
Definition: network.hpp:151
struct sockaddr_in addr
Definition: network.hpp:159
std::size_t player_count
Definition: network.hpp:187
virtual void handler(const Packet &packet, Eng3D::Deser::Archive &ar, int id)=0
void do_netloop(std::function< void(int i)> on_wake_thread, int id)
Definition: network.cpp:298
Server(unsigned port, unsigned max_conn)
Definition: network.cpp:241
ServerClient * clients
Definition: network.hpp:185
virtual void on_connect(int conn_fd, int id)=0
virtual void on_disconnect()=0
std::atomic< bool > run
Definition: network.hpp:161
void broadcast(const Eng3D::Networking::Packet &packet)
This will broadcast the given packet to all clients currently on the server.
Definition: network.cpp:292
virtual const char * what() const noexcept
Definition: network.hpp:74
SocketException(const std::string &msg)
Definition: network.hpp:71
bool recv(void *data, size_t size, std::function< bool()> pred=0)
Definition: network.cpp:94
void set_timeout(int seconds)
Definition: network.cpp:115
bool send(const void *data, size_t size, std::function< bool()> pred)
Definition: network.cpp:74
void set_blocking(bool value)
Definition: network.cpp:143
Base class that serves as archiver, stores (in memory) the data required for serialization/deserializ...
Definition: serializer.hpp:64