From 253d3dd3d889eb61131810b04137ee3f9445db64 Mon Sep 17 00:00:00 2001
From: B3n30 <benediktthomas@gmail.com>
Date: Sat, 15 Jul 2017 11:39:27 +0200
Subject: [PATCH] Network: Propagate Room closing to connected members

---
 src/network/room.cpp        | 21 +++++++++++++++++++++
 src/network/room_member.cpp |  7 +++++--
 src/network/room_member.h   |  3 ++-
 3 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/src/network/room.cpp b/src/network/room.cpp
index da16793120..3f72d7cbe6 100644
--- a/src/network/room.cpp
+++ b/src/network/room.cpp
@@ -84,6 +84,11 @@ public:
      */
     void SendJoinSuccess(ENetPeer* client, MacAddress mac_address);
 
+    /**
+     * Notifies the members that the room is closed,
+     */
+    void SendCloseMessage();
+
     /**
      * Sends the information about the room, along with the list of members
      * to every connected client in the room.
@@ -159,6 +164,8 @@ void Room::RoomImpl::ServerLoop() {
             }
         }
     }
+    // Close the connection to all members:
+    SendCloseMessage();
 }
 
 void Room::RoomImpl::StartLoop() {
@@ -266,6 +273,20 @@ void Room::RoomImpl::SendJoinSuccess(ENetPeer* client, MacAddress mac_address) {
     enet_host_flush(server);
 }
 
+void Room::RoomImpl::SendCloseMessage() {
+    Packet packet;
+    packet << static_cast<MessageID>(IdCloseRoom);
+    ENetPacket* enet_packet =
+        enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
+    for (auto& member : members) {
+        enet_peer_send(member.peer, 0, enet_packet);
+    }
+    enet_host_flush(server);
+    for (auto& member : members) {
+        enet_peer_disconnect(member.peer, 0);
+    }
+}
+
 void Room::RoomImpl::BroadcastRoomInformation() {
     Packet packet;
     packet << static_cast<MessageID>(IdRoomInformation);
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index f6f8b0475c..8fd226ba57 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -127,6 +127,9 @@ void RoomMember::RoomMemberImpl::MemberLoop() {
                 case IdVersionMismatch:
                     SetState(State::WrongVersion);
                     break;
+                case IdCloseRoom:
+                    SetState(State::LostConnection);
+                    break;
                 default:
                     break;
                 }
@@ -307,7 +310,7 @@ RoomInformation RoomMember::GetRoomInformation() const {
 }
 
 void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port,
-                      u16 client_port) {
+                      u16 client_port, const MacAddress& preferred_mac) {
     // If the member is connected, kill the connection first
     if (room_member_impl->loop_thread && room_member_impl->loop_thread->joinable()) {
         room_member_impl->SetState(State::Error);
@@ -336,7 +339,7 @@ void RoomMember::Join(const std::string& nick, const char* server_addr, u16 serv
         room_member_impl->nickname = nick;
         room_member_impl->SetState(State::Joining);
         room_member_impl->StartLoop();
-        room_member_impl->SendJoinRequest(nick);
+        room_member_impl->SendJoinRequest(nick, preferred_mac);
     } else {
         room_member_impl->SetState(State::CouldNotConnect);
     }
diff --git a/src/network/room_member.h b/src/network/room_member.h
index 6522f053cf..fce608c828 100644
--- a/src/network/room_member.h
+++ b/src/network/room_member.h
@@ -97,7 +97,8 @@ public:
      * This may fail if the username is already taken.
      */
     void Join(const std::string& nickname, const char* server_addr = "127.0.0.1",
-              const u16 serverPort = DefaultRoomPort, const u16 clientPort = 0);
+              const u16 serverPort = DefaultRoomPort, const u16 clientPort = 0,
+              const MacAddress& preferred_mac = NoPreferredMac);
 
     /**
      * Sends a WiFi packet to the room.