summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorB3n30 <benediktthomas@gmail.com>2017-07-14 09:20:39 +0200
committerB3n30 <benediktthomas@gmail.com>2017-07-16 21:30:04 +0200
commita0626221a52056669c0b6d19b37d4189c1671fb7 (patch)
tree13b05ebe3fe162c1d90f79dc38c9e7129958bc2e
parentNetwork: Send the game title (diff)
downloadyuzu-a0626221a52056669c0b6d19b37d4189c1671fb7.tar
yuzu-a0626221a52056669c0b6d19b37d4189c1671fb7.tar.gz
yuzu-a0626221a52056669c0b6d19b37d4189c1671fb7.tar.bz2
yuzu-a0626221a52056669c0b6d19b37d4189c1671fb7.tar.lz
yuzu-a0626221a52056669c0b6d19b37d4189c1671fb7.tar.xz
yuzu-a0626221a52056669c0b6d19b37d4189c1671fb7.tar.zst
yuzu-a0626221a52056669c0b6d19b37d4189c1671fb7.zip
-rw-r--r--src/network/room.cpp35
-rw-r--r--src/network/room.h6
-rw-r--r--src/network/room_member.cpp53
-rw-r--r--src/network/room_member.h1
4 files changed, 70 insertions, 25 deletions
diff --git a/src/network/room.cpp b/src/network/room.cpp
index 9af5b4ea0..da1679312 100644
--- a/src/network/room.cpp
+++ b/src/network/room.cpp
@@ -74,6 +74,11 @@ public:
void SendMacCollision(ENetPeer* client);
/**
+ * Sends a ID_ROOM_VERSION_MISMATCH message telling the client that the MAC is invalid.
+ */
+ void SendVersionMismatch(ENetPeer* client);
+
+ /**
* Notifies the member that its connection attempt was successful,
* and it is now part of the room.
*/
@@ -170,6 +175,9 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) {
MacAddress preferred_mac;
packet >> preferred_mac;
+ u32 client_version;
+ packet >> client_version;
+
if (!IsValidNickname(nickname)) {
SendNameCollision(event->peer);
return;
@@ -186,6 +194,11 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) {
preferred_mac = GenerateMacAddress();
}
+ if (client_version != network_version) {
+ SendVersionMismatch(event->peer);
+ return;
+ }
+
// At this point the client is ready to be added to the room.
Member member{};
member.mac_address = preferred_mac;
@@ -232,6 +245,17 @@ void Room::RoomImpl::SendMacCollision(ENetPeer* client) {
enet_host_flush(server);
}
+void Room::RoomImpl::SendVersionMismatch(ENetPeer* client) {
+ Packet packet;
+ packet << static_cast<MessageID>(IdVersionMismatch);
+ packet << network_version;
+
+ ENetPacket* enet_packet =
+ enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
+ enet_peer_send(client, 0, enet_packet);
+ enet_host_flush(server);
+}
+
void Room::RoomImpl::SendJoinSuccess(ENetPeer* client, MacAddress mac_address) {
Packet packet;
packet << static_cast<MessageID>(IdJoinSuccess);
@@ -291,7 +315,7 @@ void Room::RoomImpl::HandleWifiPacket(const ENetEvent* event) {
if (destination_address == BroadcastMac) { // Send the data to everyone except the sender
for (const auto& member : members) {
if (member.peer != event->peer)
- enet_peer_send(member.peer, 0, event->packet);
+ enet_peer_send(member.peer, 0, enet_packet);
}
} else { // Send the data only to the destination client
auto member = std::find_if(members.begin(), members.end(),
@@ -327,9 +351,9 @@ void Room::RoomImpl::HandleChatPacket(const ENetEvent* event) {
ENetPacket* enet_packet = enet_packet_create(out_packet.GetData(), out_packet.GetDataSize(),
ENET_PACKET_FLAG_RELIABLE);
- for (auto it = members.begin(); it != members.end(); ++it) {
- if (it->peer != event->peer)
- enet_peer_send(it->peer, 0, enet_packet);
+ for (const auto& member : members) {
+ if (member.peer != event->peer)
+ enet_peer_send(member.peer, 0, enet_packet);
}
enet_host_flush(server);
}
@@ -369,6 +393,9 @@ Room::~Room() = default;
void Room::Create(const std::string& name, const std::string& server_address, u16 server_port) {
ENetAddress address;
address.host = ENET_HOST_ANY;
+ if (!server_address.empty()) {
+ enet_address_set_host(&address, server_address.c_str());
+ }
address.port = server_port;
room_impl->server = enet_host_create(&address, MaxConcurrentConnections, NumChannels, 0, 0);
diff --git a/src/network/room.h b/src/network/room.h
index 82e3dc62c..ffa17599d 100644
--- a/src/network/room.h
+++ b/src/network/room.h
@@ -11,6 +11,8 @@
namespace Network {
+constexpr u32 network_version = 1; ///< The version of this Room and RoomMember
+
constexpr u16 DefaultRoomPort = 1234;
constexpr size_t NumChannels = 1; // Number of channels used for the connection
@@ -37,7 +39,9 @@ enum RoomMessageTypes {
IdWifiPacket,
IdChatMessage,
IdNameCollision,
- IdMacCollision
+ IdMacCollision,
+ IdVersionMismatch,
+ IdCloseRoom
};
/// This is what a server [person creating a server] would use.
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
diff --git a/src/network/room_member.h b/src/network/room_member.h
index d874cc5e4..6522f053c 100644
--- a/src/network/room_member.h
+++ b/src/network/room_member.h
@@ -47,6 +47,7 @@ public:
// Reasons why connection was rejected
NameCollision, ///< Somebody is already using this name
MacCollision, ///< Somebody is already using that mac-address
+ WrongVersion, ///< The room version is not the same as for this RoomMember
CouldNotConnect ///< The room is not responding to a connection attempt
};