summaryrefslogtreecommitdiffstats
path: root/src/network/room_member.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/room_member.cpp')
-rw-r--r--src/network/room_member.cpp53
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