diff options
Diffstat (limited to 'src/network/room_member.cpp')
-rw-r--r-- | src/network/room_member.cpp | 53 |
1 files changed, 33 insertions, 20 deletions
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp index ec67aa5be..f6f8b0475 100644 --- a/src/network/room_member.cpp +++ b/src/network/room_member.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include <atomic> +#include <list> #include <mutex> #include <thread> #include "common/assert.h" @@ -33,8 +34,10 @@ public: std::mutex network_mutex; ///< Mutex that controls access to the `client` variable. /// Thread that receives and dispatches network packets - std::unique_ptr<std::thread> receive_thread; - void ReceiveLoop(); + std::unique_ptr<std::thread> loop_thread; + std::mutex send_list_mutex; ///< Mutex that controls access to the `send_list` variable. + std::list<Packet> send_list; ///< A list that stores all packets to send the async + void MemberLoop(); void StartLoop(); /** @@ -91,7 +94,7 @@ bool RoomMember::RoomMemberImpl::IsConnected() const { return state == State::Joining || state == State::Joined; } -void RoomMember::RoomMemberImpl::ReceiveLoop() { +void RoomMember::RoomMemberImpl::MemberLoop() { // Receive packets while the connection is open while (IsConnected()) { std::lock_guard<std::mutex> lock(network_mutex); @@ -121,6 +124,9 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() { case IdMacCollision: SetState(State::MacCollision); break; + case IdVersionMismatch: + SetState(State::WrongVersion); + break; default: break; } @@ -128,22 +134,30 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() { break; case ENET_EVENT_TYPE_DISCONNECT: SetState(State::LostConnection); + break; + } + } + { + std::lock_guard<std::mutex> lock(send_list_mutex); + for (const auto& packet : send_list) { + ENetPacket* enetPacket = enet_packet_create(packet.GetData(), packet.GetDataSize(), + ENET_PACKET_FLAG_RELIABLE); + enet_peer_send(server, 0, enetPacket); } + enet_host_flush(client); + send_list.clear(); } } Disconnect(); }; void RoomMember::RoomMemberImpl::StartLoop() { - receive_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::ReceiveLoop, this); + loop_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::MemberLoop, this); } void RoomMember::RoomMemberImpl::Send(Packet& packet) { - std::lock_guard<std::mutex> lock(network_mutex); - ENetPacket* enetPacket = - enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); - enet_peer_send(server, 0, enetPacket); - enet_host_flush(client); + std::lock_guard<std::mutex> lock(send_list_mutex); + send_list.push_back(std::move(packet)); } void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname, @@ -152,6 +166,7 @@ void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname, packet << static_cast<MessageID>(IdJoinRequest); packet << nickname; packet << preferred_mac; + packet << network_version; Send(packet); } @@ -238,11 +253,9 @@ void RoomMember::RoomMemberImpl::Disconnect() { room_information.member_slots = 0; room_information.name.clear(); - if (server) { - enet_peer_disconnect(server, 0); - } else { + if (!server) return; - } + enet_peer_disconnect(server, 0); ENetEvent event; while (enet_host_service(client, &event, ConnectionTimeoutMs) > 0) { @@ -296,14 +309,14 @@ RoomInformation RoomMember::GetRoomInformation() const { void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port, u16 client_port) { // If the member is connected, kill the connection first - if (room_member_impl->receive_thread && room_member_impl->receive_thread->joinable()) { + if (room_member_impl->loop_thread && room_member_impl->loop_thread->joinable()) { room_member_impl->SetState(State::Error); - room_member_impl->receive_thread->join(); - room_member_impl->receive_thread.reset(); + room_member_impl->loop_thread->join(); + room_member_impl->loop_thread.reset(); } // If the thread isn't running but the ptr still exists, reset it - else if (room_member_impl->receive_thread) { - room_member_impl->receive_thread.reset(); + else if (room_member_impl->loop_thread) { + room_member_impl->loop_thread.reset(); } ENetAddress address{}; @@ -361,8 +374,8 @@ void RoomMember::SendGameName(const std::string& game_name) { void RoomMember::Leave() { room_member_impl->SetState(State::Idle); - room_member_impl->receive_thread->join(); - room_member_impl->receive_thread.reset(); + room_member_impl->loop_thread->join(); + room_member_impl->loop_thread.reset(); } } // namespace Network |