diff options
Diffstat (limited to 'src/network/room_member.cpp')
| -rw-r--r-- | src/network/room_member.cpp | 97 |
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 | ||
| 135 | void RoomMember::RoomMemberImpl::StartLoop() { | 137 | void RoomMember::RoomMemberImpl::StartLoop() { |
| @@ -137,6 +139,7 @@ void RoomMember::RoomMemberImpl::StartLoop() { | |||
| 137 | } | 139 | } |
| 138 | 140 | ||
| 139 | void RoomMember::RoomMemberImpl::Send(Packet& packet) { | 141 | void 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 | ||
| 236 | void 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 |
| 234 | RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} { | 264 | RoomMember::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 | ||
| 282 | const std::string& RoomMember::GetNickname() const { | ||
| 283 | return room_member_impl->nickname; | ||
| 284 | } | ||
| 285 | |||
| 286 | const MacAddress& RoomMember::GetMacAddress() const { | ||
| 287 | if (GetState() == State::Joined) | ||
| 288 | return room_member_impl->mac_address; | ||
| 289 | return MacAddress{}; | ||
| 290 | } | ||
| 291 | |||
| 252 | RoomInformation RoomMember::GetRoomInformation() const { | 292 | RoomInformation RoomMember::GetRoomInformation() const { |
| 253 | return room_member_impl->room_information; | 293 | return room_member_impl->room_information; |
| 254 | } | 294 | } |
| 255 | 295 | ||
| 256 | void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port, | 296 | void 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 { | |||
| 286 | void RoomMember::SendWifiPacket(const WifiPacket& wifi_packet) { | 336 | void 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 | ||
| 355 | void 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 | |||
| 305 | void RoomMember::Leave() { | 362 | void 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 |