RType
Server.cpp
Go to the documentation of this file.
1 /*
2 ** EPITECH PROJECT, 2023
3 ** R-type
4 ** File description:
5 ** R-type
6 */
7 
8 #include "Server.hpp"
9 
10 #include "SFML/Window/Keyboard.hpp"
11 #include <sys/time.h>
12 #include <utility>
13 
14 /**
15  * @brief Construct a new Server:: Server object
16  * @param port
17  */
18 Server::Server(int port)
19 {
20  _serverSocket = std::make_shared<ServerSocket>();
21  _gameLoader = std::make_unique<DLLoader>("../lib_r_type.so");
22  _serverSocket->init_server(port);
23  _game = std::unique_ptr<IGame>(_gameLoader->getInstance("create", _serverSocket));
24  _packetHeartBeat = std::make_unique<Packet>();
25 }
26 
27 /**
28  * @brief &operator<< overload the << operator for CODE enum
29  * @param os
30  * @param packetCode
31  */
32 std::ostream &operator<<(std::ostream &os, CODE const &packetCode)
33 {
34  switch (packetCode) {
35  case CODE::ELEMENT:
36  os << "ELEMENT";
37  break;
38  case CODE::EVENT:
39  os << "EVENT";
40  break;
41  case CODE::LOGIN:
42  os << "LOGIN";
43  break;
44  case CODE::LOGOUT:
45  os << "LOGOUT";
46  break;
47  case CODE::MESSAGE:
48  os << "MESSAGE";
49  break;
50  case CODE::UNDEFINED:
51  os << "UNDEFINED";
52  break;
53  }
54  return os;
55 }
56 
57 /**
58  * @brief &operator<< overload the << operator for Element struct
59  * @param os
60  * @param packetElement
61  */
62 std::ostream &operator<<(std::ostream &os, Element const &packetElement)
63 {
64  os << "Element: " << packetElement.id << " " << packetElement.x << " " << packetElement.y << " "
65  << packetElement.type;
66  return os;
67 }
68 
69 /**
70  * @brief &operator<< overload the << operator for Packet struct
71  * @param os
72  * @param packet
73  */
74 std::ostream &operator<<(std::ostream &os, std::unique_ptr<Packet> &packet)
75 {
76  os << "Packet: " << packet->code << " " << packet->data_size;
77  if (packet->code == CODE::ELEMENT) {
78  os << static_cast<Element *>(packet->data);
79  }
80  if (packet->code == CODE::MESSAGE) {
81  os << " "
82  << "Message: " + std::string(static_cast<char *>(packet->data));
83  }
84  return os;
85 }
86 
87 Packet packet{};
88 
89 /**
90  * @brief run the server
91  */
92 void Server::run()
93 {
94  bool send_broadcast = false;
95  while (true) {
96  _serverSocket->init_fd_set();
97  _packetClientId = _serverSocket->receive();
98  _packet = std::move(std::get<0>(_packetClientId));
99  std::shared_ptr<Event> event = std::make_shared<Event>();
100  event->id = std::get<1>(_packetClientId);
101  event->eventType = 0;
102  event->key = sf::Keyboard::Key::Unknown;
103 
104  if (_packet) {
105  if (_packet->code == HEARTBEAT) {
106  gettimeofday(&_currentTime, nullptr);
107  _receveidTime = *static_cast<timeval *>(_packet->data);
108  _packetHeartBeat->code = HEARTBEAT;
109  _packetHeartBeat->data_size = sizeof(timeval);
110  _packetHeartBeat->data = malloc(_packetHeartBeat->data_size);
111  timersub(&_currentTime, &_receveidTime, &_packetHeartBeatData);
112  // std::cout << "Ping: " << _packetHeartBeatData.tv_sec * 1000 + _packetHeartBeatData.tv_usec / 1000 <<
113  // "ms" << std::endl;
114  memcpy(_packetHeartBeat->data, &_currentTime, _packetHeartBeat->data_size);
115  _serverSocket->send(_packetHeartBeat.get(),
116  _serverSocket->getClientAddress(std::get<1>(_packetClientId)));
117  free(_packetHeartBeat->data);
118  }
119  if (_packet->code == MESSAGE) {
120  if (std::string(static_cast<char *>(_packet->data)) == "connection") {
121  // std::string message = "Message: " + std::string(static_cast<char *>(_packet->data));
122  // std::cout << "Message: " << static_cast<char *>(_packet->data) << std::endl;
123  auto *packetConnectionAccepted = new Packet();
124  packetConnectionAccepted->code = MESSAGE;
125  packetConnectionAccepted->data_size = 19;
126  packetConnectionAccepted->data = malloc(packetConnectionAccepted->data_size);
127  memcpy(packetConnectionAccepted->data, "connection accepted", packetConnectionAccepted->data_size);
128  _serverSocket->send(packetConnectionAccepted,
129  _serverSocket->getClientAddress(std::get<1>(_packetClientId)));
130  free(packetConnectionAccepted->data);
131  delete packetConnectionAccepted;
132  }
133  }
134  if (_packet->code == EVENT) {
135  Event event1{};
136  memset(&event1, 0, sizeof(Event));
137  memcpy(&event1, _packet->data, sizeof(Event));
138  event = std::make_shared<Event>(event1);
139  event->id = std::get<1>(_packetClientId);
140  }
141  }
142  _game->update(event, _packet);
143  if (_packet) {
144  free(_packet->data);
145  _packet.reset();
146  _packetClientId = std::tuple<std::unique_ptr<Packet>, int>(nullptr, 0);
147  }
148  // test (ça fonctionne ici mais pas ailleurs (reçois UNDEFINED packet sur le client depuis un send à un autre
149  // endroit qu'ici))
150  /*packet.code = LOGIN;
151  packet.data_size = 4;
152  packet.data = malloc(packet.data_size);
153  memcpy(packet.data, "test", packet.data_size);
154  if (!_serverSocket->getClients().empty())
155  _serverSocket->send(&packet, _serverSocket->getClientAddress(1));
156  */
157  }
158 }