room_member.h 11 KB

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