summaryrefslogtreecommitdiff
path: root/src/network/room_member.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/network/room_member.cpp97
1 files changed, 74 insertions, 23 deletions
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index d68bb551d..ec67aa5be 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -74,6 +74,11 @@ public:
74 * @param event The ENet event that was received. 74 * @param event The ENet event that was received.
75 */ 75 */
76 void HandleChatPacket(const ENetEvent* event); 76 void HandleChatPacket(const ENetEvent* event);
77
78 /**
79 * Disconnects the RoomMember from the Room
80 */
81 void Disconnect();
77}; 82};
78 83
79// RoomMemberImpl 84// RoomMemberImpl
@@ -92,7 +97,8 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() {
92 std::lock_guard<std::mutex> lock(network_mutex); 97 std::lock_guard<std::mutex> lock(network_mutex);
93 ENetEvent event; 98 ENetEvent event;
94 if (enet_host_service(client, &event, 1000) > 0) { 99 if (enet_host_service(client, &event, 1000) > 0) {
95 if (event.type == ENET_EVENT_TYPE_RECEIVE) { 100 switch (event.type) {
101 case ENET_EVENT_TYPE_RECEIVE:
96 switch (event.packet->data[0]) { 102 switch (event.packet->data[0]) {
97 // TODO(B3N30): Handle the other message types 103 // TODO(B3N30): Handle the other message types
98 case IdChatMessage: 104 case IdChatMessage:
@@ -111,25 +117,21 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() {
111 break; 117 break;
112 case IdNameCollision: 118 case IdNameCollision:
113 SetState(State::NameCollision); 119 SetState(State::NameCollision);
114 enet_packet_destroy(event.packet);
115 enet_peer_disconnect(server, 0);
116 enet_peer_reset(server);
117 return;
118 break; 120 break;
119 case IdMacCollision: 121 case IdMacCollision:
120 SetState(State::MacCollision); 122 SetState(State::MacCollision);
121 enet_packet_destroy(event.packet);
122 enet_peer_disconnect(server, 0);
123 enet_peer_reset(server);
124 return;
125 break; 123 break;
126 default: 124 default:
127 break; 125 break;
128 } 126 }
129 enet_packet_destroy(event.packet); 127 enet_packet_destroy(event.packet);
128 break;
129 case ENET_EVENT_TYPE_DISCONNECT:
130 SetState(State::LostConnection);
130 } 131 }
131 } 132 }
132 } 133 }
134 Disconnect();
133}; 135};
134 136
135void RoomMember::RoomMemberImpl::StartLoop() { 137void RoomMember::RoomMemberImpl::StartLoop() {
@@ -137,6 +139,7 @@ void RoomMember::RoomMemberImpl::StartLoop() {
137} 139}
138 140
139void RoomMember::RoomMemberImpl::Send(Packet& packet) { 141void RoomMember::RoomMemberImpl::Send(Packet& packet) {
142 std::lock_guard<std::mutex> lock(network_mutex);
140 ENetPacket* enetPacket = 143 ENetPacket* enetPacket =
141 enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); 144 enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
142 enet_peer_send(server, 0, enetPacket); 145 enet_peer_send(server, 0, enetPacket);
@@ -165,7 +168,7 @@ void RoomMember::RoomMemberImpl::HandleRoomInformationPacket(const ENetEvent* ev
165 room_information.name = info.name; 168 room_information.name = info.name;
166 room_information.member_slots = info.member_slots; 169 room_information.member_slots = info.member_slots;
167 170
168 uint32_t num_members; 171 u32 num_members;
169 packet >> num_members; 172 packet >> num_members;
170 member_information.resize(num_members); 173 member_information.resize(num_members);
171 174
@@ -198,7 +201,7 @@ void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) {
198 packet.IgnoreBytes(sizeof(MessageID)); 201 packet.IgnoreBytes(sizeof(MessageID));
199 202
200 // Parse the WifiPacket from the BitStream 203 // Parse the WifiPacket from the BitStream
201 uint8_t frame_type; 204 u8 frame_type;
202 packet >> frame_type; 205 packet >> frame_type;
203 WifiPacket::PacketType type = static_cast<WifiPacket::PacketType>(frame_type); 206 WifiPacket::PacketType type = static_cast<WifiPacket::PacketType>(frame_type);
204 207
@@ -207,10 +210,10 @@ void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) {
207 packet >> wifi_packet.transmitter_address; 210 packet >> wifi_packet.transmitter_address;
208 packet >> wifi_packet.destination_address; 211 packet >> wifi_packet.destination_address;
209 212
210 uint32_t data_length; 213 u32 data_length;
211 packet >> data_length; 214 packet >> data_length;
212 215
213 std::vector<uint8_t> data(data_length); 216 std::vector<u8> data(data_length);
214 packet >> data; 217 packet >> data;
215 218
216 wifi_packet.data = std::move(data); 219 wifi_packet.data = std::move(data);
@@ -230,6 +233,33 @@ void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) {
230 // TODO(B3N30): Invoke callbacks 233 // TODO(B3N30): Invoke callbacks
231} 234}
232 235
236void RoomMember::RoomMemberImpl::Disconnect() {
237 member_information.clear();
238 room_information.member_slots = 0;
239 room_information.name.clear();
240
241 if (server) {
242 enet_peer_disconnect(server, 0);
243 } else {
244 return;
245 }
246
247 ENetEvent event;
248 while (enet_host_service(client, &event, ConnectionTimeoutMs) > 0) {
249 switch (event.type) {
250 case ENET_EVENT_TYPE_RECEIVE:
251 enet_packet_destroy(event.packet); // Ignore all incoming data
252 break;
253 case ENET_EVENT_TYPE_DISCONNECT:
254 server = nullptr;
255 return;
256 }
257 }
258 // didn't disconnect gracefully force disconnect
259 enet_peer_reset(server);
260 server = nullptr;
261}
262
233// RoomMember 263// RoomMember
234RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} { 264RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} {
235 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0); 265 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0);
@@ -249,16 +279,36 @@ const RoomMember::MemberList& RoomMember::GetMemberInformation() const {
249 return room_member_impl->member_information; 279 return room_member_impl->member_information;
250} 280}
251 281
282const std::string& RoomMember::GetNickname() const {
283 return room_member_impl->nickname;
284}
285
286const MacAddress& RoomMember::GetMacAddress() const {
287 if (GetState() == State::Joined)
288 return room_member_impl->mac_address;
289 return MacAddress{};
290}
291
252RoomInformation RoomMember::GetRoomInformation() const { 292RoomInformation RoomMember::GetRoomInformation() const {
253 return room_member_impl->room_information; 293 return room_member_impl->room_information;
254} 294}
255 295
256void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port, 296void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port,
257 u16 client_port) { 297 u16 client_port) {
298 // If the member is connected, kill the connection first
299 if (room_member_impl->receive_thread && room_member_impl->receive_thread->joinable()) {
300 room_member_impl->SetState(State::Error);
301 room_member_impl->receive_thread->join();
302 room_member_impl->receive_thread.reset();
303 }
304 // If the thread isn't running but the ptr still exists, reset it
305 else if (room_member_impl->receive_thread) {
306 room_member_impl->receive_thread.reset();
307 }
308
258 ENetAddress address{}; 309 ENetAddress address{};
259 enet_address_set_host(&address, server_addr); 310 enet_address_set_host(&address, server_addr);
260 address.port = server_port; 311 address.port = server_port;
261
262 room_member_impl->server = 312 room_member_impl->server =
263 enet_host_connect(room_member_impl->client, &address, NumChannels, 0); 313 enet_host_connect(room_member_impl->client, &address, NumChannels, 0);
264 314
@@ -286,11 +336,11 @@ bool RoomMember::IsConnected() const {
286void RoomMember::SendWifiPacket(const WifiPacket& wifi_packet) { 336void RoomMember::SendWifiPacket(const WifiPacket& wifi_packet) {
287 Packet packet; 337 Packet packet;
288 packet << static_cast<MessageID>(IdWifiPacket); 338 packet << static_cast<MessageID>(IdWifiPacket);
289 packet << static_cast<uint8_t>(wifi_packet.type); 339 packet << static_cast<u8>(wifi_packet.type);
290 packet << wifi_packet.channel; 340 packet << wifi_packet.channel;
291 packet << wifi_packet.transmitter_address; 341 packet << wifi_packet.transmitter_address;
292 packet << wifi_packet.destination_address; 342 packet << wifi_packet.destination_address;
293 packet << static_cast<uint32_t>(wifi_packet.data.size()); 343 packet << static_cast<u32>(wifi_packet.data.size());
294 packet << wifi_packet.data; 344 packet << wifi_packet.data;
295 room_member_impl->Send(packet); 345 room_member_impl->Send(packet);
296} 346}
@@ -302,16 +352,17 @@ void RoomMember::SendChatMessage(const std::string& message) {
302 room_member_impl->Send(packet); 352 room_member_impl->Send(packet);
303} 353}
304 354
355void RoomMember::SendGameName(const std::string& game_name) {
356 Packet packet;
357 packet << static_cast<MessageID>(IdSetGameName);
358 packet << game_name;
359 room_member_impl->Send(packet);
360}
361
305void RoomMember::Leave() { 362void RoomMember::Leave() {
306 ASSERT_MSG(room_member_impl->receive_thread != nullptr, "Must be in a room to leave it."); 363 room_member_impl->SetState(State::Idle);
307 {
308 std::lock_guard<std::mutex> lock(room_member_impl->network_mutex);
309 enet_peer_disconnect(room_member_impl->server, 0);
310 room_member_impl->SetState(State::Idle);
311 }
312 room_member_impl->receive_thread->join(); 364 room_member_impl->receive_thread->join();
313 room_member_impl->receive_thread.reset(); 365 room_member_impl->receive_thread.reset();
314 enet_peer_reset(room_member_impl->server);
315} 366}
316 367
317} // namespace Network 368} // namespace Network