summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
Diffstat (limited to 'src/network')
-rw-r--r--src/network/room_member.cpp109
-rw-r--r--src/network/room_member.h18
2 files changed, 125 insertions, 2 deletions
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp
index e1a0dfdab..09573ee43 100644
--- a/src/network/room_member.cpp
+++ b/src/network/room_member.cpp
@@ -7,6 +7,7 @@
7#include <thread> 7#include <thread>
8#include "common/assert.h" 8#include "common/assert.h"
9#include "enet/enet.h" 9#include "enet/enet.h"
10#include "network/packet.h"
10#include "network/room_member.h" 11#include "network/room_member.h"
11 12
12namespace Network { 13namespace Network {
@@ -18,17 +19,49 @@ public:
18 ENetHost* client = nullptr; ///< ENet network interface. 19 ENetHost* client = nullptr; ///< ENet network interface.
19 ENetPeer* server = nullptr; ///< The server peer the client is connected to 20 ENetPeer* server = nullptr; ///< The server peer the client is connected to
20 21
22 /// Information about the clients connected to the same room as us.
23 MemberList member_information;
24 /// Information about the room we're connected to.
25 RoomInformation room_information;
26
21 std::atomic<State> state{State::Idle}; ///< Current state of the RoomMember. 27 std::atomic<State> state{State::Idle}; ///< Current state of the RoomMember.
22 void SetState(const State new_state); 28 void SetState(const State new_state);
23 bool IsConnected() const; 29 bool IsConnected() const;
24 30
25 std::string nickname; ///< The nickname of this member. 31 std::string nickname; ///< The nickname of this member.
32 MacAddress mac_address; ///< The mac_address of this member.
26 33
27 std::mutex network_mutex; ///< Mutex that controls access to the `client` variable. 34 std::mutex network_mutex; ///< Mutex that controls access to the `client` variable.
28 /// Thread that receives and dispatches network packets 35 /// Thread that receives and dispatches network packets
29 std::unique_ptr<std::thread> receive_thread; 36 std::unique_ptr<std::thread> receive_thread;
30 void ReceiveLoop(); 37 void ReceiveLoop();
31 void StartLoop(); 38 void StartLoop();
39
40 /**
41 * Sends data to the room. It will be send on channel 0 with flag RELIABLE
42 * @param packet The data to send
43 */
44 void Send(Packet& packet);
45 /**
46 * Sends a request to the server, asking for permission to join a room with the specified
47 * nickname and preferred mac.
48 * @params nickname The desired nickname.
49 * @params preferred_mac The preferred MAC address to use in the room, the NoPreferredMac tells
50 * the server to assign one for us.
51 */
52 void SendJoinRequest(const std::string& nickname,
53 const MacAddress& preferred_mac = NoPreferredMac);
54
55 /**
56 * Extracts a MAC Address from a received ENet packet.
57 * @param event The ENet event that was received.
58 */
59 void HandleJoinPacket(const ENetEvent* event);
60 /**
61 * Extracts RoomInformation and MemberInformation from a received RakNet packet.
62 * @param event The ENet event that was received.
63 */
64 void HandleRoomInformationPacket(const ENetEvent* event);
32}; 65};
33 66
34// RoomMemberImpl 67// RoomMemberImpl
@@ -50,6 +83,17 @@ void RoomMember::RoomMemberImpl::ReceiveLoop() {
50 if (event.type == ENET_EVENT_TYPE_RECEIVE) { 83 if (event.type == ENET_EVENT_TYPE_RECEIVE) {
51 switch (event.packet->data[0]) { 84 switch (event.packet->data[0]) {
52 // TODO(B3N30): Handle the other message types 85 // TODO(B3N30): Handle the other message types
86 case IdRoomInformation:
87 HandleRoomInformationPacket(&event);
88 break;
89 case IdJoinSuccess:
90 // The join request was successful, we are now in the room.
91 // If we joined successfully, there must be at least one client in the room: us.
92 ASSERT_MSG(member_information.size() > 0,
93 "We have not yet received member information.");
94 HandleJoinPacket(&event); // Get the MAC Address for the client
95 SetState(State::Joined);
96 break;
53 case IdNameCollision: 97 case IdNameCollision:
54 SetState(State::NameCollision); 98 SetState(State::NameCollision);
55 enet_packet_destroy(event.packet); 99 enet_packet_destroy(event.packet);
@@ -77,6 +121,59 @@ void RoomMember::RoomMemberImpl::StartLoop() {
77 receive_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::ReceiveLoop, this); 121 receive_thread = std::make_unique<std::thread>(&RoomMember::RoomMemberImpl::ReceiveLoop, this);
78} 122}
79 123
124void RoomMember::RoomMemberImpl::Send(Packet& packet) {
125 ENetPacket* enetPacket =
126 enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE);
127 enet_peer_send(server, 0, enetPacket);
128 enet_host_flush(client);
129}
130
131void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname,
132 const MacAddress& preferred_mac) {
133 Packet packet;
134 packet << static_cast<MessageID>(IdJoinRequest);
135 packet << nickname;
136 packet << preferred_mac;
137 Send(packet);
138}
139
140void RoomMember::RoomMemberImpl::HandleRoomInformationPacket(const ENetEvent* event) {
141 Packet packet;
142 packet.Append(event->packet->data, event->packet->dataLength);
143
144 // Ignore the first byte, which is the message id.
145 packet.IgnoreBytes(sizeof(MessageID));
146
147 RoomInformation info{};
148 packet >> info.name;
149 packet >> info.member_slots;
150 room_information.name = info.name;
151 room_information.member_slots = info.member_slots;
152
153 uint32_t num_members;
154 packet >> num_members;
155 member_information.resize(num_members);
156
157 for (auto& member : member_information) {
158 packet >> member.nickname;
159 packet >> member.mac_address;
160 packet >> member.game_name;
161 }
162 // TODO(B3N30): Invoke callbacks
163}
164
165void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) {
166 Packet packet;
167 packet.Append(event->packet->data, event->packet->dataLength);
168
169 // Ignore the first byte, which is the message id.
170 packet.IgnoreBytes(sizeof(MessageID));
171
172 // Parse the MAC Address from the BitStream
173 packet >> mac_address;
174 // TODO(B3N30): Invoke callbacks
175}
176
80// RoomMember 177// RoomMember
81RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} { 178RoomMember::RoomMember() : room_member_impl{std::make_unique<RoomMemberImpl>()} {
82 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0); 179 room_member_impl->client = enet_host_create(nullptr, 1, NumChannels, 0, 0);
@@ -92,6 +189,14 @@ RoomMember::State RoomMember::GetState() const {
92 return room_member_impl->state; 189 return room_member_impl->state;
93} 190}
94 191
192const RoomMember::MemberList& RoomMember::GetMemberInformation() const {
193 return room_member_impl->member_information;
194}
195
196RoomInformation RoomMember::GetRoomInformation() const {
197 return room_member_impl->room_information;
198}
199
95void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port, 200void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port,
96 u16 client_port) { 201 u16 client_port) {
97 ENetAddress address{}; 202 ENetAddress address{};
@@ -112,7 +217,7 @@ void RoomMember::Join(const std::string& nick, const char* server_addr, u16 serv
112 room_member_impl->nickname = nick; 217 room_member_impl->nickname = nick;
113 room_member_impl->SetState(State::Joining); 218 room_member_impl->SetState(State::Joining);
114 room_member_impl->StartLoop(); 219 room_member_impl->StartLoop();
115 // TODO(B3N30): Send a join request with the nickname to the server 220 room_member_impl->SendJoinRequest(nick);
116 } else { 221 } else {
117 room_member_impl->SetState(State::CouldNotConnect); 222 room_member_impl->SetState(State::CouldNotConnect);
118 } 223 }
diff --git a/src/network/room_member.h b/src/network/room_member.h
index 89ec6ae5a..f8bdbaea8 100644
--- a/src/network/room_member.h
+++ b/src/network/room_member.h
@@ -6,6 +6,7 @@
6 6
7#include <memory> 7#include <memory>
8#include <string> 8#include <string>
9#include <vector>
9#include "common/common_types.h" 10#include "common/common_types.h"
10#include "network/room.h" 11#include "network/room.h"
11 12
@@ -31,6 +32,14 @@ public:
31 CouldNotConnect ///< The room is not responding to a connection attempt 32 CouldNotConnect ///< The room is not responding to a connection attempt
32 }; 33 };
33 34
35 struct MemberInformation {
36 std::string nickname; ///< Nickname of the member.
37 std::string game_name; ///< Name of the game they're currently playing, or empty if they're
38 /// not playing anything.
39 MacAddress mac_address; ///< MAC address associated with this member.
40 };
41 using MemberList = std::vector<MemberInformation>;
42
34 RoomMember(); 43 RoomMember();
35 ~RoomMember(); 44 ~RoomMember();
36 45
@@ -40,6 +49,15 @@ public:
40 State GetState() const; 49 State GetState() const;
41 50
42 /** 51 /**
52 * Returns information about the members in the room we're currently connected to.
53 */
54 const MemberList& GetMemberInformation() const;
55 /**
56 * Returns information about the room we're currently connected to.
57 */
58 RoomInformation GetRoomInformation() const;
59
60 /**
43 * Returns whether we're connected to a server or not. 61 * Returns whether we're connected to a server or not.
44 */ 62 */
45 bool IsConnected() const; 63 bool IsConnected() const;