summaryrefslogtreecommitdiff
path: root/src/network/room_member.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/room_member.h')
-rw-r--r--src/network/room_member.h304
1 files changed, 304 insertions, 0 deletions
diff --git a/src/network/room_member.h b/src/network/room_member.h
new file mode 100644
index 000000000..4252b7146
--- /dev/null
+++ b/src/network/room_member.h
@@ -0,0 +1,304 @@
1// SPDX-FileCopyrightText: Copyright 2017 Citra Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <functional>
7#include <memory>
8#include <string>
9#include <vector>
10#include "common/announce_multiplayer_room.h"
11#include "common/common_types.h"
12#include "common/socket_types.h"
13#include "network/room.h"
14
15namespace Network {
16
17using AnnounceMultiplayerRoom::GameInfo;
18using AnnounceMultiplayerRoom::RoomInformation;
19
20/// Information about the received WiFi packets.
21struct ProxyPacket {
22 SockAddrIn local_endpoint;
23 SockAddrIn remote_endpoint;
24 Protocol protocol;
25 bool broadcast;
26 std::vector<u8> data;
27};
28
29/// Represents a chat message.
30struct ChatEntry {
31 std::string nickname; ///< Nickname of the client who sent this message.
32 /// Web services username of the client who sent this message, can be empty.
33 std::string username;
34 std::string message; ///< Body of the message.
35};
36
37/// Represents a system status message.
38struct StatusMessageEntry {
39 StatusMessageTypes type; ///< Type of the message
40 /// Subject of the message. i.e. the user who is joining/leaving/being banned, etc.
41 std::string nickname;
42 std::string username;
43};
44
45/**
46 * This is what a client [person joining a server] would use.
47 * It also has to be used if you host a game yourself (You'd create both, a Room and a
48 * RoomMembership for yourself)
49 */
50class RoomMember final {
51public:
52 enum class State : u8 {
53 Uninitialized, ///< Not initialized
54 Idle, ///< Default state (i.e. not connected)
55 Joining, ///< The client is attempting to join a room.
56 Joined, ///< The client is connected to the room and is ready to send/receive packets.
57 Moderator, ///< The client is connnected to the room and is granted mod permissions.
58 };
59
60 enum class Error : u8 {
61 // Reasons why connection was closed
62 LostConnection, ///< Connection closed
63 HostKicked, ///< Kicked by the host
64
65 // Reasons why connection was rejected
66 UnknownError, ///< Some error [permissions to network device missing or something]
67 NameCollision, ///< Somebody is already using this name
68 IpCollision, ///< Somebody is already using that fake-ip-address
69 WrongVersion, ///< The room version is not the same as for this RoomMember
70 WrongPassword, ///< The password doesn't match the one from the Room
71 CouldNotConnect, ///< The room is not responding to a connection attempt
72 RoomIsFull, ///< Room is already at the maximum number of players
73 HostBanned, ///< The user is banned by the host
74
75 // Reasons why moderation request failed
76 PermissionDenied, ///< The user does not have mod permissions
77 NoSuchUser, ///< The nickname the user attempts to kick/ban does not exist
78 };
79
80 struct MemberInformation {
81 std::string nickname; ///< Nickname of the member.
82 std::string username; ///< The web services username of the member. Can be empty.
83 std::string display_name; ///< The web services display name of the member. Can be empty.
84 std::string avatar_url; ///< Url to the member's avatar. Can be empty.
85 GameInfo game_info; ///< Name of the game they're currently playing, or empty if they're
86 /// not playing anything.
87 IPv4Address fake_ip; ///< Fake Ip address associated with this member.
88 };
89 using MemberList = std::vector<MemberInformation>;
90
91 // The handle for the callback functions
92 template <typename T>
93 using CallbackHandle = std::shared_ptr<std::function<void(const T&)>>;
94
95 /**
96 * Unbinds a callback function from the events.
97 * @param handle The connection handle to disconnect
98 */
99 template <typename T>
100 void Unbind(CallbackHandle<T> handle);
101
102 RoomMember();
103 ~RoomMember();
104
105 /**
106 * Returns the status of our connection to the room.
107 */
108 State GetState() const;
109
110 /**
111 * Returns information about the members in the room we're currently connected to.
112 */
113 const MemberList& GetMemberInformation() const;
114
115 /**
116 * Returns the nickname of the RoomMember.
117 */
118 const std::string& GetNickname() const;
119
120 /**
121 * Returns the username of the RoomMember.
122 */
123 const std::string& GetUsername() const;
124
125 /**
126 * Returns the MAC address of the RoomMember.
127 */
128 const IPv4Address& GetFakeIpAddress() const;
129
130 /**
131 * Returns information about the room we're currently connected to.
132 */
133 RoomInformation GetRoomInformation() const;
134
135 /**
136 * Returns whether we're connected to a server or not.
137 */
138 bool IsConnected() const;
139
140 /**
141 * Attempts to join a room at the specified address and port, using the specified nickname.
142 */
143 void Join(const std::string& nickname, const char* server_addr = "127.0.0.1",
144 u16 server_port = DefaultRoomPort, u16 client_port = 0,
145 const IPv4Address& preferred_fake_ip = NoPreferredIP,
146 const std::string& password = "", const std::string& token = "");
147
148 /**
149 * Sends a WiFi packet to the room.
150 * @param packet The WiFi packet to send.
151 */
152 void SendProxyPacket(const ProxyPacket& packet);
153
154 /**
155 * Sends a chat message to the room.
156 * @param message The contents of the message.
157 */
158 void SendChatMessage(const std::string& message);
159
160 /**
161 * Sends the current game info to the room.
162 * @param game_info The game information.
163 */
164 void SendGameInfo(const GameInfo& game_info);
165
166 /**
167 * Sends a moderation request to the room.
168 * @param type Moderation request type.
169 * @param nickname The subject of the request. (i.e. the user you want to kick/ban)
170 */
171 void SendModerationRequest(RoomMessageTypes type, const std::string& nickname);
172
173 /**
174 * Attempts to retrieve ban list from the room.
175 * If success, the ban list callback would be called. Otherwise an error would be emitted.
176 */
177 void RequestBanList();
178
179 /**
180 * Binds a function to an event that will be triggered every time the State of the member
181 * changed. The function wil be called every time the event is triggered. The callback function
182 * must not bind or unbind a function. Doing so will cause a deadlock
183 * @param callback The function to call
184 * @return A handle used for removing the function from the registered list
185 */
186 CallbackHandle<State> BindOnStateChanged(std::function<void(const State&)> callback);
187
188 /**
189 * Binds a function to an event that will be triggered every time an error happened. The
190 * function wil be called every time the event is triggered. The callback function must not bind
191 * or unbind a function. Doing so will cause a deadlock
192 * @param callback The function to call
193 * @return A handle used for removing the function from the registered list
194 */
195 CallbackHandle<Error> BindOnError(std::function<void(const Error&)> callback);
196
197 /**
198 * Binds a function to an event that will be triggered every time a ProxyPacket is received.
199 * The function wil be called everytime the event is triggered.
200 * The callback function must not bind or unbind a function. Doing so will cause a deadlock
201 * @param callback The function to call
202 * @return A handle used for removing the function from the registered list
203 */
204 CallbackHandle<ProxyPacket> BindOnProxyPacketReceived(
205 std::function<void(const ProxyPacket&)> callback);
206
207 /**
208 * Binds a function to an event that will be triggered every time the RoomInformation changes.
209 * The function wil be called every time the event is triggered.
210 * The callback function must not bind or unbind a function. Doing so will cause a deadlock
211 * @param callback The function to call
212 * @return A handle used for removing the function from the registered list
213 */
214 CallbackHandle<RoomInformation> BindOnRoomInformationChanged(
215 std::function<void(const RoomInformation&)> callback);
216
217 /**
218 * Binds a function to an event that will be triggered every time a ChatMessage is received.
219 * The function wil be called every time the event is triggered.
220 * The callback function must not bind or unbind a function. Doing so will cause a deadlock
221 * @param callback The function to call
222 * @return A handle used for removing the function from the registered list
223 */
224 CallbackHandle<ChatEntry> BindOnChatMessageRecieved(
225 std::function<void(const ChatEntry&)> callback);
226
227 /**
228 * Binds a function to an event that will be triggered every time a StatusMessage is
229 * received. The function will be called every time the event is triggered. The callback
230 * function must not bind or unbind a function. Doing so will cause a deadlock
231 * @param callback The function to call
232 * @return A handle used for removing the function from the registered list
233 */
234 CallbackHandle<StatusMessageEntry> BindOnStatusMessageReceived(
235 std::function<void(const StatusMessageEntry&)> callback);
236
237 /**
238 * Binds a function to an event that will be triggered every time a requested ban list
239 * received. The function will be called every time the event is triggered. The callback
240 * function must not bind or unbind a function. Doing so will cause a deadlock
241 * @param callback The function to call
242 * @return A handle used for removing the function from the registered list
243 */
244 CallbackHandle<Room::BanList> BindOnBanListReceived(
245 std::function<void(const Room::BanList&)> callback);
246
247 /**
248 * Leaves the current room.
249 */
250 void Leave();
251
252private:
253 class RoomMemberImpl;
254 std::unique_ptr<RoomMemberImpl> room_member_impl;
255};
256
257inline const char* GetStateStr(const RoomMember::State& s) {
258 switch (s) {
259 case RoomMember::State::Uninitialized:
260 return "Uninitialized";
261 case RoomMember::State::Idle:
262 return "Idle";
263 case RoomMember::State::Joining:
264 return "Joining";
265 case RoomMember::State::Joined:
266 return "Joined";
267 case RoomMember::State::Moderator:
268 return "Moderator";
269 }
270 return "Unknown";
271}
272
273inline const char* GetErrorStr(const RoomMember::Error& e) {
274 switch (e) {
275 case RoomMember::Error::LostConnection:
276 return "LostConnection";
277 case RoomMember::Error::HostKicked:
278 return "HostKicked";
279 case RoomMember::Error::UnknownError:
280 return "UnknownError";
281 case RoomMember::Error::NameCollision:
282 return "NameCollision";
283 case RoomMember::Error::IpCollision:
284 return "IpCollision";
285 case RoomMember::Error::WrongVersion:
286 return "WrongVersion";
287 case RoomMember::Error::WrongPassword:
288 return "WrongPassword";
289 case RoomMember::Error::CouldNotConnect:
290 return "CouldNotConnect";
291 case RoomMember::Error::RoomIsFull:
292 return "RoomIsFull";
293 case RoomMember::Error::HostBanned:
294 return "HostBanned";
295 case RoomMember::Error::PermissionDenied:
296 return "PermissionDenied";
297 case RoomMember::Error::NoSuchUser:
298 return "NoSuchUser";
299 default:
300 return "Unknown";
301 }
302}
303
304} // namespace Network