diff options
Diffstat (limited to 'src/network')
| -rw-r--r-- | src/network/room.cpp | 170 | ||||
| -rw-r--r-- | src/network/room.h | 14 | ||||
| -rw-r--r-- | src/network/room_member.cpp | 123 | ||||
| -rw-r--r-- | src/network/room_member.h | 70 |
4 files changed, 168 insertions, 209 deletions
diff --git a/src/network/room.cpp b/src/network/room.cpp index 3fc3a0383..b06797bf1 100644 --- a/src/network/room.cpp +++ b/src/network/room.cpp | |||
| @@ -20,9 +20,7 @@ namespace Network { | |||
| 20 | 20 | ||
| 21 | class Room::RoomImpl { | 21 | class Room::RoomImpl { |
| 22 | public: | 22 | public: |
| 23 | // This MAC address is used to generate a 'Nintendo' like Mac address. | 23 | std::mt19937 random_gen; ///< Random number generator. Used for GenerateFakeIPAddress |
| 24 | const MacAddress NintendoOUI; | ||
| 25 | std::mt19937 random_gen; ///< Random number generator. Used for GenerateMacAddress | ||
| 26 | 24 | ||
| 27 | ENetHost* server = nullptr; ///< Network interface. | 25 | ENetHost* server = nullptr; ///< Network interface. |
| 28 | 26 | ||
| @@ -35,10 +33,9 @@ public: | |||
| 35 | std::string password; ///< The password required to connect to this room. | 33 | std::string password; ///< The password required to connect to this room. |
| 36 | 34 | ||
| 37 | struct Member { | 35 | struct Member { |
| 38 | std::string nickname; ///< The nickname of the member. | 36 | std::string nickname; ///< The nickname of the member. |
| 39 | std::string console_id_hash; ///< A hash of the console ID of the member. | 37 | GameInfo game_info; ///< The current game of the member |
| 40 | GameInfo game_info; ///< The current game of the member | 38 | IPv4Address fake_ip; ///< The assigned fake ip address of the member. |
| 41 | MacAddress mac_address; ///< The assigned mac address of the member. | ||
| 42 | /// Data of the user, often including authenticated forum username. | 39 | /// Data of the user, often including authenticated forum username. |
| 43 | VerifyUser::UserData user_data; | 40 | VerifyUser::UserData user_data; |
| 44 | ENetPeer* peer; ///< The remote peer. | 41 | ENetPeer* peer; ///< The remote peer. |
| @@ -51,8 +48,7 @@ public: | |||
| 51 | IPBanList ip_ban_list; ///< List of banned IP addresses | 48 | IPBanList ip_ban_list; ///< List of banned IP addresses |
| 52 | mutable std::mutex ban_list_mutex; ///< Mutex for the ban lists | 49 | mutable std::mutex ban_list_mutex; ///< Mutex for the ban lists |
| 53 | 50 | ||
| 54 | RoomImpl() | 51 | RoomImpl() : random_gen(std::random_device()()) {} |
| 55 | : NintendoOUI{0x00, 0x1F, 0x32, 0x00, 0x00, 0x00}, random_gen(std::random_device()()) {} | ||
| 56 | 52 | ||
| 57 | /// Thread that receives and dispatches network packets | 53 | /// Thread that receives and dispatches network packets |
| 58 | std::unique_ptr<std::thread> room_thread; | 54 | std::unique_ptr<std::thread> room_thread; |
| @@ -101,16 +97,10 @@ public: | |||
| 101 | bool IsValidNickname(const std::string& nickname) const; | 97 | bool IsValidNickname(const std::string& nickname) const; |
| 102 | 98 | ||
| 103 | /** | 99 | /** |
| 104 | * Returns whether the MAC address is valid, ie. isn't already taken by someone else in the | 100 | * Returns whether the fake ip address is valid, ie. isn't already taken by someone else in the |
| 105 | * room. | 101 | * room. |
| 106 | */ | 102 | */ |
| 107 | bool IsValidMacAddress(const MacAddress& address) const; | 103 | bool IsValidFakeIPAddress(const IPv4Address& address) const; |
| 108 | |||
| 109 | /** | ||
| 110 | * Returns whether the console ID (hash) is valid, ie. isn't already taken by someone else in | ||
| 111 | * the room. | ||
| 112 | */ | ||
| 113 | bool IsValidConsoleId(const std::string& console_id_hash) const; | ||
| 114 | 104 | ||
| 115 | /** | 105 | /** |
| 116 | * Returns whether a user has mod permissions. | 106 | * Returns whether a user has mod permissions. |
| @@ -128,15 +118,9 @@ public: | |||
| 128 | void SendNameCollision(ENetPeer* client); | 118 | void SendNameCollision(ENetPeer* client); |
| 129 | 119 | ||
| 130 | /** | 120 | /** |
| 131 | * Sends a ID_ROOM_MAC_COLLISION message telling the client that the MAC is invalid. | 121 | * Sends a ID_ROOM_IP_COLLISION message telling the client that the IP is invalid. |
| 132 | */ | 122 | */ |
| 133 | void SendMacCollision(ENetPeer* client); | 123 | void SendIPCollision(ENetPeer* client); |
| 134 | |||
| 135 | /** | ||
| 136 | * Sends a IdConsoleIdCollison message telling the client that another member with the same | ||
| 137 | * console ID exists. | ||
| 138 | */ | ||
| 139 | void SendConsoleIdCollision(ENetPeer* client); | ||
| 140 | 124 | ||
| 141 | /** | 125 | /** |
| 142 | * Sends a ID_ROOM_VERSION_MISMATCH message telling the client that the version is invalid. | 126 | * Sends a ID_ROOM_VERSION_MISMATCH message telling the client that the version is invalid. |
| @@ -152,13 +136,13 @@ public: | |||
| 152 | * Notifies the member that its connection attempt was successful, | 136 | * Notifies the member that its connection attempt was successful, |
| 153 | * and it is now part of the room. | 137 | * and it is now part of the room. |
| 154 | */ | 138 | */ |
| 155 | void SendJoinSuccess(ENetPeer* client, MacAddress mac_address); | 139 | void SendJoinSuccess(ENetPeer* client, IPv4Address fake_ip); |
| 156 | 140 | ||
| 157 | /** | 141 | /** |
| 158 | * Notifies the member that its connection attempt was successful, | 142 | * Notifies the member that its connection attempt was successful, |
| 159 | * and it is now part of the room, and it has been granted mod permissions. | 143 | * and it is now part of the room, and it has been granted mod permissions. |
| 160 | */ | 144 | */ |
| 161 | void SendJoinSuccessAsMod(ENetPeer* client, MacAddress mac_address); | 145 | void SendJoinSuccessAsMod(ENetPeer* client, IPv4Address fake_ip); |
| 162 | 146 | ||
| 163 | /** | 147 | /** |
| 164 | * Sends a IdHostKicked message telling the client that they have been kicked. | 148 | * Sends a IdHostKicked message telling the client that they have been kicked. |
| @@ -210,7 +194,7 @@ public: | |||
| 210 | * <u32> num_members: the number of currently joined clients | 194 | * <u32> num_members: the number of currently joined clients |
| 211 | * This is followed by the following three values for each member: | 195 | * This is followed by the following three values for each member: |
| 212 | * <String> nickname of that member | 196 | * <String> nickname of that member |
| 213 | * <MacAddress> mac_address of that member | 197 | * <IPv4Address> fake_ip of that member |
| 214 | * <String> game_name of that member | 198 | * <String> game_name of that member |
| 215 | */ | 199 | */ |
| 216 | void BroadcastRoomInformation(); | 200 | void BroadcastRoomInformation(); |
| @@ -219,13 +203,13 @@ public: | |||
| 219 | * Generates a free MAC address to assign to a new client. | 203 | * Generates a free MAC address to assign to a new client. |
| 220 | * The first 3 bytes are the NintendoOUI 0x00, 0x1F, 0x32 | 204 | * The first 3 bytes are the NintendoOUI 0x00, 0x1F, 0x32 |
| 221 | */ | 205 | */ |
| 222 | MacAddress GenerateMacAddress(); | 206 | IPv4Address GenerateFakeIPAddress(); |
| 223 | 207 | ||
| 224 | /** | 208 | /** |
| 225 | * Broadcasts this packet to all members except the sender. | 209 | * Broadcasts this packet to all members except the sender. |
| 226 | * @param event The ENet event containing the data | 210 | * @param event The ENet event containing the data |
| 227 | */ | 211 | */ |
| 228 | void HandleWifiPacket(const ENetEvent* event); | 212 | void HandleProxyPacket(const ENetEvent* event); |
| 229 | 213 | ||
| 230 | /** | 214 | /** |
| 231 | * Extracts a chat entry from a received ENet packet and adds it to the chat queue. | 215 | * Extracts a chat entry from a received ENet packet and adds it to the chat queue. |
| @@ -250,7 +234,7 @@ public: | |||
| 250 | void Room::RoomImpl::ServerLoop() { | 234 | void Room::RoomImpl::ServerLoop() { |
| 251 | while (state != State::Closed) { | 235 | while (state != State::Closed) { |
| 252 | ENetEvent event; | 236 | ENetEvent event; |
| 253 | if (enet_host_service(server, &event, 16) > 0) { | 237 | if (enet_host_service(server, &event, 50) > 0) { |
| 254 | switch (event.type) { | 238 | switch (event.type) { |
| 255 | case ENET_EVENT_TYPE_RECEIVE: | 239 | case ENET_EVENT_TYPE_RECEIVE: |
| 256 | switch (event.packet->data[0]) { | 240 | switch (event.packet->data[0]) { |
| @@ -260,8 +244,8 @@ void Room::RoomImpl::ServerLoop() { | |||
| 260 | case IdSetGameInfo: | 244 | case IdSetGameInfo: |
| 261 | HandleGameNamePacket(&event); | 245 | HandleGameNamePacket(&event); |
| 262 | break; | 246 | break; |
| 263 | case IdWifiPacket: | 247 | case IdProxyPacket: |
| 264 | HandleWifiPacket(&event); | 248 | HandleProxyPacket(&event); |
| 265 | break; | 249 | break; |
| 266 | case IdChatMessage: | 250 | case IdChatMessage: |
| 267 | HandleChatPacket(&event); | 251 | HandleChatPacket(&event); |
| @@ -313,11 +297,8 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { | |||
| 313 | std::string nickname; | 297 | std::string nickname; |
| 314 | packet.Read(nickname); | 298 | packet.Read(nickname); |
| 315 | 299 | ||
| 316 | std::string console_id_hash; | 300 | IPv4Address preferred_fake_ip; |
| 317 | packet.Read(console_id_hash); | 301 | packet.Read(preferred_fake_ip); |
| 318 | |||
| 319 | MacAddress preferred_mac; | ||
| 320 | packet.Read(preferred_mac); | ||
| 321 | 302 | ||
| 322 | u32 client_version; | 303 | u32 client_version; |
| 323 | packet.Read(client_version); | 304 | packet.Read(client_version); |
| @@ -338,20 +319,15 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { | |||
| 338 | return; | 319 | return; |
| 339 | } | 320 | } |
| 340 | 321 | ||
| 341 | if (preferred_mac != NoPreferredMac) { | 322 | if (preferred_fake_ip != NoPreferredIP) { |
| 342 | // Verify if the preferred mac is available | 323 | // Verify if the preferred fake ip is available |
| 343 | if (!IsValidMacAddress(preferred_mac)) { | 324 | if (!IsValidFakeIPAddress(preferred_fake_ip)) { |
| 344 | SendMacCollision(event->peer); | 325 | SendIPCollision(event->peer); |
| 345 | return; | 326 | return; |
| 346 | } | 327 | } |
| 347 | } else { | 328 | } else { |
| 348 | // Assign a MAC address of this client automatically | 329 | // Assign a fake ip address of this client automatically |
| 349 | preferred_mac = GenerateMacAddress(); | 330 | preferred_fake_ip = GenerateFakeIPAddress(); |
| 350 | } | ||
| 351 | |||
| 352 | if (!IsValidConsoleId(console_id_hash)) { | ||
| 353 | SendConsoleIdCollision(event->peer); | ||
| 354 | return; | ||
| 355 | } | 331 | } |
| 356 | 332 | ||
| 357 | if (client_version != network_version) { | 333 | if (client_version != network_version) { |
| @@ -361,8 +337,7 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { | |||
| 361 | 337 | ||
| 362 | // At this point the client is ready to be added to the room. | 338 | // At this point the client is ready to be added to the room. |
| 363 | Member member{}; | 339 | Member member{}; |
| 364 | member.mac_address = preferred_mac; | 340 | member.fake_ip = preferred_fake_ip; |
| 365 | member.console_id_hash = console_id_hash; | ||
| 366 | member.nickname = nickname; | 341 | member.nickname = nickname; |
| 367 | member.peer = event->peer; | 342 | member.peer = event->peer; |
| 368 | 343 | ||
| @@ -408,9 +383,9 @@ void Room::RoomImpl::HandleJoinRequest(const ENetEvent* event) { | |||
| 408 | // Notify everyone that the room information has changed. | 383 | // Notify everyone that the room information has changed. |
| 409 | BroadcastRoomInformation(); | 384 | BroadcastRoomInformation(); |
| 410 | if (HasModPermission(event->peer)) { | 385 | if (HasModPermission(event->peer)) { |
| 411 | SendJoinSuccessAsMod(event->peer, preferred_mac); | 386 | SendJoinSuccessAsMod(event->peer, preferred_fake_ip); |
| 412 | } else { | 387 | } else { |
| 413 | SendJoinSuccess(event->peer, preferred_mac); | 388 | SendJoinSuccess(event->peer, preferred_fake_ip); |
| 414 | } | 389 | } |
| 415 | } | 390 | } |
| 416 | 391 | ||
| @@ -575,19 +550,11 @@ bool Room::RoomImpl::IsValidNickname(const std::string& nickname) const { | |||
| 575 | [&nickname](const auto& member) { return member.nickname != nickname; }); | 550 | [&nickname](const auto& member) { return member.nickname != nickname; }); |
| 576 | } | 551 | } |
| 577 | 552 | ||
| 578 | bool Room::RoomImpl::IsValidMacAddress(const MacAddress& address) const { | 553 | bool Room::RoomImpl::IsValidFakeIPAddress(const IPv4Address& address) const { |
| 579 | // A MAC address is valid if it is not already taken by anybody else in the room. | 554 | // An IP address is valid if it is not already taken by anybody else in the room. |
| 580 | std::lock_guard lock(member_mutex); | 555 | std::lock_guard lock(member_mutex); |
| 581 | return std::all_of(members.begin(), members.end(), | 556 | return std::all_of(members.begin(), members.end(), |
| 582 | [&address](const auto& member) { return member.mac_address != address; }); | 557 | [&address](const auto& member) { return member.fake_ip != address; }); |
| 583 | } | ||
| 584 | |||
| 585 | bool Room::RoomImpl::IsValidConsoleId(const std::string& console_id_hash) const { | ||
| 586 | // A Console ID is valid if it is not already taken by anybody else in the room. | ||
| 587 | std::lock_guard lock(member_mutex); | ||
| 588 | return std::all_of(members.begin(), members.end(), [&console_id_hash](const auto& member) { | ||
| 589 | return member.console_id_hash != console_id_hash; | ||
| 590 | }); | ||
| 591 | } | 558 | } |
| 592 | 559 | ||
| 593 | bool Room::RoomImpl::HasModPermission(const ENetPeer* client) const { | 560 | bool Room::RoomImpl::HasModPermission(const ENetPeer* client) const { |
| @@ -621,19 +588,9 @@ void Room::RoomImpl::SendNameCollision(ENetPeer* client) { | |||
| 621 | enet_host_flush(server); | 588 | enet_host_flush(server); |
| 622 | } | 589 | } |
| 623 | 590 | ||
| 624 | void Room::RoomImpl::SendMacCollision(ENetPeer* client) { | 591 | void Room::RoomImpl::SendIPCollision(ENetPeer* client) { |
| 625 | Packet packet; | 592 | Packet packet; |
| 626 | packet.Write(static_cast<u8>(IdMacCollision)); | 593 | packet.Write(static_cast<u8>(IdIpCollision)); |
| 627 | |||
| 628 | ENetPacket* enet_packet = | ||
| 629 | enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); | ||
| 630 | enet_peer_send(client, 0, enet_packet); | ||
| 631 | enet_host_flush(server); | ||
| 632 | } | ||
| 633 | |||
| 634 | void Room::RoomImpl::SendConsoleIdCollision(ENetPeer* client) { | ||
| 635 | Packet packet; | ||
| 636 | packet.Write(static_cast<u8>(IdConsoleIdCollision)); | ||
| 637 | 594 | ||
| 638 | ENetPacket* enet_packet = | 595 | ENetPacket* enet_packet = |
| 639 | enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); | 596 | enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); |
| @@ -672,20 +629,20 @@ void Room::RoomImpl::SendVersionMismatch(ENetPeer* client) { | |||
| 672 | enet_host_flush(server); | 629 | enet_host_flush(server); |
| 673 | } | 630 | } |
| 674 | 631 | ||
| 675 | void Room::RoomImpl::SendJoinSuccess(ENetPeer* client, MacAddress mac_address) { | 632 | void Room::RoomImpl::SendJoinSuccess(ENetPeer* client, IPv4Address fake_ip) { |
| 676 | Packet packet; | 633 | Packet packet; |
| 677 | packet.Write(static_cast<u8>(IdJoinSuccess)); | 634 | packet.Write(static_cast<u8>(IdJoinSuccess)); |
| 678 | packet.Write(mac_address); | 635 | packet.Write(fake_ip); |
| 679 | ENetPacket* enet_packet = | 636 | ENetPacket* enet_packet = |
| 680 | enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); | 637 | enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); |
| 681 | enet_peer_send(client, 0, enet_packet); | 638 | enet_peer_send(client, 0, enet_packet); |
| 682 | enet_host_flush(server); | 639 | enet_host_flush(server); |
| 683 | } | 640 | } |
| 684 | 641 | ||
| 685 | void Room::RoomImpl::SendJoinSuccessAsMod(ENetPeer* client, MacAddress mac_address) { | 642 | void Room::RoomImpl::SendJoinSuccessAsMod(ENetPeer* client, IPv4Address fake_ip) { |
| 686 | Packet packet; | 643 | Packet packet; |
| 687 | packet.Write(static_cast<u8>(IdJoinSuccessAsMod)); | 644 | packet.Write(static_cast<u8>(IdJoinSuccessAsMod)); |
| 688 | packet.Write(mac_address); | 645 | packet.Write(fake_ip); |
| 689 | ENetPacket* enet_packet = | 646 | ENetPacket* enet_packet = |
| 690 | enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); | 647 | enet_packet_create(packet.GetData(), packet.GetDataSize(), ENET_PACKET_FLAG_RELIABLE); |
| 691 | enet_peer_send(client, 0, enet_packet); | 648 | enet_peer_send(client, 0, enet_packet); |
| @@ -818,7 +775,7 @@ void Room::RoomImpl::BroadcastRoomInformation() { | |||
| 818 | std::lock_guard lock(member_mutex); | 775 | std::lock_guard lock(member_mutex); |
| 819 | for (const auto& member : members) { | 776 | for (const auto& member : members) { |
| 820 | packet.Write(member.nickname); | 777 | packet.Write(member.nickname); |
| 821 | packet.Write(member.mac_address); | 778 | packet.Write(member.fake_ip); |
| 822 | packet.Write(member.game_info.name); | 779 | packet.Write(member.game_info.name); |
| 823 | packet.Write(member.game_info.id); | 780 | packet.Write(member.game_info.id); |
| 824 | packet.Write(member.user_data.username); | 781 | packet.Write(member.user_data.username); |
| @@ -833,34 +790,43 @@ void Room::RoomImpl::BroadcastRoomInformation() { | |||
| 833 | enet_host_flush(server); | 790 | enet_host_flush(server); |
| 834 | } | 791 | } |
| 835 | 792 | ||
| 836 | MacAddress Room::RoomImpl::GenerateMacAddress() { | 793 | IPv4Address Room::RoomImpl::GenerateFakeIPAddress() { |
| 837 | MacAddress result_mac = | 794 | IPv4Address result_ip{192, 168, 0, 0}; |
| 838 | NintendoOUI; // The first three bytes of each MAC address will be the NintendoOUI | 795 | std::uniform_int_distribution<> dis(0x01, 0xFE); // Random byte between 1 and 0xFE |
| 839 | std::uniform_int_distribution<> dis(0x00, 0xFF); // Random byte between 0 and 0xFF | ||
| 840 | do { | 796 | do { |
| 841 | for (std::size_t i = 3; i < result_mac.size(); ++i) { | 797 | for (std::size_t i = 2; i < result_ip.size(); ++i) { |
| 842 | result_mac[i] = dis(random_gen); | 798 | result_ip[i] = dis(random_gen); |
| 843 | } | 799 | } |
| 844 | } while (!IsValidMacAddress(result_mac)); | 800 | } while (!IsValidFakeIPAddress(result_ip)); |
| 845 | return result_mac; | 801 | |
| 802 | return result_ip; | ||
| 846 | } | 803 | } |
| 847 | 804 | ||
| 848 | void Room::RoomImpl::HandleWifiPacket(const ENetEvent* event) { | 805 | void Room::RoomImpl::HandleProxyPacket(const ENetEvent* event) { |
| 849 | Packet in_packet; | 806 | Packet in_packet; |
| 850 | in_packet.Append(event->packet->data, event->packet->dataLength); | 807 | in_packet.Append(event->packet->data, event->packet->dataLength); |
| 851 | in_packet.IgnoreBytes(sizeof(u8)); // Message type | 808 | in_packet.IgnoreBytes(sizeof(u8)); // Message type |
| 852 | in_packet.IgnoreBytes(sizeof(u8)); // WifiPacket Type | 809 | |
| 853 | in_packet.IgnoreBytes(sizeof(u8)); // WifiPacket Channel | 810 | in_packet.IgnoreBytes(sizeof(u8)); // Domain |
| 854 | in_packet.IgnoreBytes(sizeof(MacAddress)); // WifiPacket Transmitter Address | 811 | in_packet.IgnoreBytes(sizeof(IPv4Address)); // IP |
| 855 | MacAddress destination_address; | 812 | in_packet.IgnoreBytes(sizeof(u16)); // Port |
| 856 | in_packet.Read(destination_address); | 813 | |
| 814 | in_packet.IgnoreBytes(sizeof(u8)); // Domain | ||
| 815 | IPv4Address remote_ip; | ||
| 816 | in_packet.Read(remote_ip); // IP | ||
| 817 | in_packet.IgnoreBytes(sizeof(u16)); // Port | ||
| 818 | |||
| 819 | in_packet.IgnoreBytes(sizeof(u8)); // Protocol | ||
| 820 | bool broadcast; | ||
| 821 | in_packet.Read(broadcast); // Broadcast | ||
| 857 | 822 | ||
| 858 | Packet out_packet; | 823 | Packet out_packet; |
| 859 | out_packet.Append(event->packet->data, event->packet->dataLength); | 824 | out_packet.Append(event->packet->data, event->packet->dataLength); |
| 860 | ENetPacket* enet_packet = enet_packet_create(out_packet.GetData(), out_packet.GetDataSize(), | 825 | ENetPacket* enet_packet = enet_packet_create(out_packet.GetData(), out_packet.GetDataSize(), |
| 861 | ENET_PACKET_FLAG_RELIABLE); | 826 | ENET_PACKET_FLAG_RELIABLE); |
| 862 | 827 | ||
| 863 | if (destination_address == BroadcastMac) { // Send the data to everyone except the sender | 828 | const auto& destination_address = remote_ip; |
| 829 | if (broadcast) { // Send the data to everyone except the sender | ||
| 864 | std::lock_guard lock(member_mutex); | 830 | std::lock_guard lock(member_mutex); |
| 865 | bool sent_packet = false; | 831 | bool sent_packet = false; |
| 866 | for (const auto& member : members) { | 832 | for (const auto& member : members) { |
| @@ -877,16 +843,16 @@ void Room::RoomImpl::HandleWifiPacket(const ENetEvent* event) { | |||
| 877 | std::lock_guard lock(member_mutex); | 843 | std::lock_guard lock(member_mutex); |
| 878 | auto member = std::find_if(members.begin(), members.end(), | 844 | auto member = std::find_if(members.begin(), members.end(), |
| 879 | [destination_address](const Member& member_entry) -> bool { | 845 | [destination_address](const Member& member_entry) -> bool { |
| 880 | return member_entry.mac_address == destination_address; | 846 | return member_entry.fake_ip == destination_address; |
| 881 | }); | 847 | }); |
| 882 | if (member != members.end()) { | 848 | if (member != members.end()) { |
| 883 | enet_peer_send(member->peer, 0, enet_packet); | 849 | enet_peer_send(member->peer, 0, enet_packet); |
| 884 | } else { | 850 | } else { |
| 885 | LOG_ERROR(Network, | 851 | LOG_ERROR(Network, |
| 886 | "Attempting to send to unknown MAC address: " | 852 | "Attempting to send to unknown IP address: " |
| 887 | "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}", | 853 | "{}.{}.{}.{}", |
| 888 | destination_address[0], destination_address[1], destination_address[2], | 854 | destination_address[0], destination_address[1], destination_address[2], |
| 889 | destination_address[3], destination_address[4], destination_address[5]); | 855 | destination_address[3]); |
| 890 | enet_packet_destroy(enet_packet); | 856 | enet_packet_destroy(enet_packet); |
| 891 | } | 857 | } |
| 892 | } | 858 | } |
| @@ -1073,7 +1039,7 @@ std::vector<Member> Room::GetRoomMemberList() const { | |||
| 1073 | member.username = member_impl.user_data.username; | 1039 | member.username = member_impl.user_data.username; |
| 1074 | member.display_name = member_impl.user_data.display_name; | 1040 | member.display_name = member_impl.user_data.display_name; |
| 1075 | member.avatar_url = member_impl.user_data.avatar_url; | 1041 | member.avatar_url = member_impl.user_data.avatar_url; |
| 1076 | member.mac_address = member_impl.mac_address; | 1042 | member.fake_ip = member_impl.fake_ip; |
| 1077 | member.game = member_impl.game_info; | 1043 | member.game = member_impl.game_info; |
| 1078 | member_list.push_back(member); | 1044 | member_list.push_back(member); |
| 1079 | } | 1045 | } |
diff --git a/src/network/room.h b/src/network/room.h index 6f7e3b5b5..c2a4b1a70 100644 --- a/src/network/room.h +++ b/src/network/room.h | |||
| @@ -9,12 +9,12 @@ | |||
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/announce_multiplayer_room.h" | 10 | #include "common/announce_multiplayer_room.h" |
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "common/socket_types.h" | ||
| 12 | #include "network/verify_user.h" | 13 | #include "network/verify_user.h" |
| 13 | 14 | ||
| 14 | namespace Network { | 15 | namespace Network { |
| 15 | 16 | ||
| 16 | using AnnounceMultiplayerRoom::GameInfo; | 17 | using AnnounceMultiplayerRoom::GameInfo; |
| 17 | using AnnounceMultiplayerRoom::MacAddress; | ||
| 18 | using AnnounceMultiplayerRoom::Member; | 18 | using AnnounceMultiplayerRoom::Member; |
| 19 | using AnnounceMultiplayerRoom::RoomInformation; | 19 | using AnnounceMultiplayerRoom::RoomInformation; |
| 20 | 20 | ||
| @@ -29,12 +29,9 @@ static constexpr u32 MaxConcurrentConnections = 254; | |||
| 29 | 29 | ||
| 30 | constexpr std::size_t NumChannels = 1; // Number of channels used for the connection | 30 | constexpr std::size_t NumChannels = 1; // Number of channels used for the connection |
| 31 | 31 | ||
| 32 | /// A special MAC address that tells the room we're joining to assign us a MAC address | 32 | /// A special IP address that tells the room we're joining to assign us a IP address |
| 33 | /// automatically. | 33 | /// automatically. |
| 34 | constexpr MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 34 | constexpr IPv4Address NoPreferredIP = {0xFF, 0xFF, 0xFF, 0xFF}; |
| 35 | |||
| 36 | // 802.11 broadcast MAC address | ||
| 37 | constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | ||
| 38 | 35 | ||
| 39 | // The different types of messages that can be sent. The first byte of each packet defines the type | 36 | // The different types of messages that can be sent. The first byte of each packet defines the type |
| 40 | enum RoomMessageTypes : u8 { | 37 | enum RoomMessageTypes : u8 { |
| @@ -42,15 +39,14 @@ enum RoomMessageTypes : u8 { | |||
| 42 | IdJoinSuccess, | 39 | IdJoinSuccess, |
| 43 | IdRoomInformation, | 40 | IdRoomInformation, |
| 44 | IdSetGameInfo, | 41 | IdSetGameInfo, |
| 45 | IdWifiPacket, | 42 | IdProxyPacket, |
| 46 | IdChatMessage, | 43 | IdChatMessage, |
| 47 | IdNameCollision, | 44 | IdNameCollision, |
| 48 | IdMacCollision, | 45 | IdIpCollision, |
| 49 | IdVersionMismatch, | 46 | IdVersionMismatch, |
| 50 | IdWrongPassword, | 47 | IdWrongPassword, |
| 51 | IdCloseRoom, | 48 | IdCloseRoom, |
| 52 | IdRoomIsFull, | 49 | IdRoomIsFull, |
| 53 | IdConsoleIdCollision, | ||
| 54 | IdStatusMessage, | 50 | IdStatusMessage, |
| 55 | IdHostKicked, | 51 | IdHostKicked, |
| 56 | IdHostBanned, | 52 | IdHostBanned, |
diff --git a/src/network/room_member.cpp b/src/network/room_member.cpp index e4f823e98..9f08bf611 100644 --- a/src/network/room_member.cpp +++ b/src/network/room_member.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <set> | 7 | #include <set> |
| 8 | #include <thread> | 8 | #include <thread> |
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/socket_types.h" | ||
| 10 | #include "enet/enet.h" | 11 | #include "enet/enet.h" |
| 11 | #include "network/packet.h" | 12 | #include "network/packet.h" |
| 12 | #include "network/room_member.h" | 13 | #include "network/room_member.h" |
| @@ -38,7 +39,7 @@ public: | |||
| 38 | std::string username; ///< The username of this member. | 39 | std::string username; ///< The username of this member. |
| 39 | mutable std::mutex username_mutex; ///< Mutex for locking username. | 40 | mutable std::mutex username_mutex; ///< Mutex for locking username. |
| 40 | 41 | ||
| 41 | MacAddress mac_address; ///< The mac_address of this member. | 42 | IPv4Address fake_ip; ///< The fake ip of this member. |
| 42 | 43 | ||
| 43 | std::mutex network_mutex; ///< Mutex that controls access to the `client` variable. | 44 | std::mutex network_mutex; ///< Mutex that controls access to the `client` variable. |
| 44 | /// Thread that receives and dispatches network packets | 45 | /// Thread that receives and dispatches network packets |
| @@ -56,7 +57,7 @@ public: | |||
| 56 | CallbackSet<T>& Get(); | 57 | CallbackSet<T>& Get(); |
| 57 | 58 | ||
| 58 | private: | 59 | private: |
| 59 | CallbackSet<WifiPacket> callback_set_wifi_packet; | 60 | CallbackSet<ProxyPacket> callback_set_proxy_packet; |
| 60 | CallbackSet<ChatEntry> callback_set_chat_messages; | 61 | CallbackSet<ChatEntry> callback_set_chat_messages; |
| 61 | CallbackSet<StatusMessageEntry> callback_set_status_messages; | 62 | CallbackSet<StatusMessageEntry> callback_set_status_messages; |
| 62 | CallbackSet<RoomInformation> callback_set_room_information; | 63 | CallbackSet<RoomInformation> callback_set_room_information; |
| @@ -78,15 +79,15 @@ public: | |||
| 78 | 79 | ||
| 79 | /** | 80 | /** |
| 80 | * Sends a request to the server, asking for permission to join a room with the specified | 81 | * Sends a request to the server, asking for permission to join a room with the specified |
| 81 | * nickname and preferred mac. | 82 | * nickname and preferred fake ip. |
| 82 | * @params nickname The desired nickname. | 83 | * @params nickname The desired nickname. |
| 83 | * @params console_id_hash A hash of the Console ID. | 84 | * @params preferred_fake_ip The preferred IP address to use in the room, the NoPreferredIP |
| 84 | * @params preferred_mac The preferred MAC address to use in the room, the NoPreferredMac tells | 85 | * tells |
| 85 | * @params password The password for the room | 86 | * @params password The password for the room |
| 86 | * the server to assign one for us. | 87 | * the server to assign one for us. |
| 87 | */ | 88 | */ |
| 88 | void SendJoinRequest(const std::string& nickname_, const std::string& console_id_hash, | 89 | void SendJoinRequest(const std::string& nickname_, |
| 89 | const MacAddress& preferred_mac = NoPreferredMac, | 90 | const IPv4Address& preferred_fake_ip = NoPreferredIP, |
| 90 | const std::string& password = "", const std::string& token = ""); | 91 | const std::string& password = "", const std::string& token = ""); |
| 91 | 92 | ||
| 92 | /** | 93 | /** |
| @@ -101,10 +102,10 @@ public: | |||
| 101 | void HandleRoomInformationPacket(const ENetEvent* event); | 102 | void HandleRoomInformationPacket(const ENetEvent* event); |
| 102 | 103 | ||
| 103 | /** | 104 | /** |
| 104 | * Extracts a WifiPacket from a received ENet packet. | 105 | * Extracts a ProxyPacket from a received ENet packet. |
| 105 | * @param event The ENet event that was received. | 106 | * @param event The ENet event that was received. |
| 106 | */ | 107 | */ |
| 107 | void HandleWifiPackets(const ENetEvent* event); | 108 | void HandleProxyPackets(const ENetEvent* event); |
| 108 | 109 | ||
| 109 | /** | 110 | /** |
| 110 | * Extracts a chat entry from a received ENet packet and adds it to the chat queue. | 111 | * Extracts a chat entry from a received ENet packet and adds it to the chat queue. |
| @@ -158,12 +159,12 @@ void RoomMember::RoomMemberImpl::MemberLoop() { | |||
| 158 | while (IsConnected()) { | 159 | while (IsConnected()) { |
| 159 | std::lock_guard lock(network_mutex); | 160 | std::lock_guard lock(network_mutex); |
| 160 | ENetEvent event; | 161 | ENetEvent event; |
| 161 | if (enet_host_service(client, &event, 16) > 0) { | 162 | if (enet_host_service(client, &event, 100) > 0) { |
| 162 | switch (event.type) { | 163 | switch (event.type) { |
| 163 | case ENET_EVENT_TYPE_RECEIVE: | 164 | case ENET_EVENT_TYPE_RECEIVE: |
| 164 | switch (event.packet->data[0]) { | 165 | switch (event.packet->data[0]) { |
| 165 | case IdWifiPacket: | 166 | case IdProxyPacket: |
| 166 | HandleWifiPackets(&event); | 167 | HandleProxyPackets(&event); |
| 167 | break; | 168 | break; |
| 168 | case IdChatMessage: | 169 | case IdChatMessage: |
| 169 | HandleChatPacket(&event); | 170 | HandleChatPacket(&event); |
| @@ -198,13 +199,9 @@ void RoomMember::RoomMemberImpl::MemberLoop() { | |||
| 198 | SetState(State::Idle); | 199 | SetState(State::Idle); |
| 199 | SetError(Error::NameCollision); | 200 | SetError(Error::NameCollision); |
| 200 | break; | 201 | break; |
| 201 | case IdMacCollision: | 202 | case IdIpCollision: |
| 202 | SetState(State::Idle); | 203 | SetState(State::Idle); |
| 203 | SetError(Error::MacCollision); | 204 | SetError(Error::IpCollision); |
| 204 | break; | ||
| 205 | case IdConsoleIdCollision: | ||
| 206 | SetState(State::Idle); | ||
| 207 | SetError(Error::ConsoleIdCollision); | ||
| 208 | break; | 205 | break; |
| 209 | case IdVersionMismatch: | 206 | case IdVersionMismatch: |
| 210 | SetState(State::Idle); | 207 | SetState(State::Idle); |
| @@ -275,15 +272,13 @@ void RoomMember::RoomMemberImpl::Send(Packet&& packet) { | |||
| 275 | } | 272 | } |
| 276 | 273 | ||
| 277 | void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname_, | 274 | void RoomMember::RoomMemberImpl::SendJoinRequest(const std::string& nickname_, |
| 278 | const std::string& console_id_hash, | 275 | const IPv4Address& preferred_fake_ip, |
| 279 | const MacAddress& preferred_mac, | ||
| 280 | const std::string& password, | 276 | const std::string& password, |
| 281 | const std::string& token) { | 277 | const std::string& token) { |
| 282 | Packet packet; | 278 | Packet packet; |
| 283 | packet.Write(static_cast<u8>(IdJoinRequest)); | 279 | packet.Write(static_cast<u8>(IdJoinRequest)); |
| 284 | packet.Write(nickname_); | 280 | packet.Write(nickname_); |
| 285 | packet.Write(console_id_hash); | 281 | packet.Write(preferred_fake_ip); |
| 286 | packet.Write(preferred_mac); | ||
| 287 | packet.Write(network_version); | 282 | packet.Write(network_version); |
| 288 | packet.Write(password); | 283 | packet.Write(password); |
| 289 | packet.Write(token); | 284 | packet.Write(token); |
| @@ -317,7 +312,7 @@ void RoomMember::RoomMemberImpl::HandleRoomInformationPacket(const ENetEvent* ev | |||
| 317 | 312 | ||
| 318 | for (auto& member : member_information) { | 313 | for (auto& member : member_information) { |
| 319 | packet.Read(member.nickname); | 314 | packet.Read(member.nickname); |
| 320 | packet.Read(member.mac_address); | 315 | packet.Read(member.fake_ip); |
| 321 | packet.Read(member.game_info.name); | 316 | packet.Read(member.game_info.name); |
| 322 | packet.Read(member.game_info.id); | 317 | packet.Read(member.game_info.id); |
| 323 | packet.Read(member.username); | 318 | packet.Read(member.username); |
| @@ -342,29 +337,38 @@ void RoomMember::RoomMemberImpl::HandleJoinPacket(const ENetEvent* event) { | |||
| 342 | packet.IgnoreBytes(sizeof(u8)); // Ignore the message type | 337 | packet.IgnoreBytes(sizeof(u8)); // Ignore the message type |
| 343 | 338 | ||
| 344 | // Parse the MAC Address from the packet | 339 | // Parse the MAC Address from the packet |
| 345 | packet.Read(mac_address); | 340 | packet.Read(fake_ip); |
| 346 | } | 341 | } |
| 347 | 342 | ||
| 348 | void RoomMember::RoomMemberImpl::HandleWifiPackets(const ENetEvent* event) { | 343 | void RoomMember::RoomMemberImpl::HandleProxyPackets(const ENetEvent* event) { |
| 349 | WifiPacket wifi_packet{}; | 344 | ProxyPacket proxy_packet{}; |
| 350 | Packet packet; | 345 | Packet packet; |
| 351 | packet.Append(event->packet->data, event->packet->dataLength); | 346 | packet.Append(event->packet->data, event->packet->dataLength); |
| 352 | 347 | ||
| 353 | // Ignore the first byte, which is the message id. | 348 | // Ignore the first byte, which is the message id. |
| 354 | packet.IgnoreBytes(sizeof(u8)); // Ignore the message type | 349 | packet.IgnoreBytes(sizeof(u8)); // Ignore the message type |
| 355 | 350 | ||
| 356 | // Parse the WifiPacket from the packet | 351 | // Parse the ProxyPacket from the packet |
| 357 | u8 frame_type; | 352 | u8 local_family; |
| 358 | packet.Read(frame_type); | 353 | packet.Read(local_family); |
| 359 | WifiPacket::PacketType type = static_cast<WifiPacket::PacketType>(frame_type); | 354 | proxy_packet.local_endpoint.family = static_cast<Domain>(local_family); |
| 355 | packet.Read(proxy_packet.local_endpoint.ip); | ||
| 356 | packet.Read(proxy_packet.local_endpoint.portno); | ||
| 357 | |||
| 358 | u8 remote_family; | ||
| 359 | packet.Read(remote_family); | ||
| 360 | proxy_packet.remote_endpoint.family = static_cast<Domain>(remote_family); | ||
| 361 | packet.Read(proxy_packet.remote_endpoint.ip); | ||
| 362 | packet.Read(proxy_packet.remote_endpoint.portno); | ||
| 363 | |||
| 364 | u8 protocol_type; | ||
| 365 | packet.Read(protocol_type); | ||
| 366 | proxy_packet.protocol = static_cast<Protocol>(protocol_type); | ||
| 360 | 367 | ||
| 361 | wifi_packet.type = type; | 368 | packet.Read(proxy_packet.broadcast); |
| 362 | packet.Read(wifi_packet.channel); | 369 | packet.Read(proxy_packet.data); |
| 363 | packet.Read(wifi_packet.transmitter_address); | ||
| 364 | packet.Read(wifi_packet.destination_address); | ||
| 365 | packet.Read(wifi_packet.data); | ||
| 366 | 370 | ||
| 367 | Invoke<WifiPacket>(wifi_packet); | 371 | Invoke<ProxyPacket>(proxy_packet); |
| 368 | } | 372 | } |
| 369 | 373 | ||
| 370 | void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) { | 374 | void RoomMember::RoomMemberImpl::HandleChatPacket(const ENetEvent* event) { |
| @@ -440,8 +444,8 @@ void RoomMember::RoomMemberImpl::Disconnect() { | |||
| 440 | } | 444 | } |
| 441 | 445 | ||
| 442 | template <> | 446 | template <> |
| 443 | RoomMember::RoomMemberImpl::CallbackSet<WifiPacket>& RoomMember::RoomMemberImpl::Callbacks::Get() { | 447 | RoomMember::RoomMemberImpl::CallbackSet<ProxyPacket>& RoomMember::RoomMemberImpl::Callbacks::Get() { |
| 444 | return callback_set_wifi_packet; | 448 | return callback_set_proxy_packet; |
| 445 | } | 449 | } |
| 446 | 450 | ||
| 447 | template <> | 451 | template <> |
| @@ -525,19 +529,18 @@ const std::string& RoomMember::GetUsername() const { | |||
| 525 | return room_member_impl->username; | 529 | return room_member_impl->username; |
| 526 | } | 530 | } |
| 527 | 531 | ||
| 528 | const MacAddress& RoomMember::GetMacAddress() const { | 532 | const IPv4Address& RoomMember::GetFakeIpAddress() const { |
| 529 | ASSERT_MSG(IsConnected(), "Tried to get MAC address while not connected"); | 533 | ASSERT_MSG(IsConnected(), "Tried to get fake ip address while not connected"); |
| 530 | return room_member_impl->mac_address; | 534 | return room_member_impl->fake_ip; |
| 531 | } | 535 | } |
| 532 | 536 | ||
| 533 | RoomInformation RoomMember::GetRoomInformation() const { | 537 | RoomInformation RoomMember::GetRoomInformation() const { |
| 534 | return room_member_impl->room_information; | 538 | return room_member_impl->room_information; |
| 535 | } | 539 | } |
| 536 | 540 | ||
| 537 | void RoomMember::Join(const std::string& nick, const std::string& console_id_hash, | 541 | void RoomMember::Join(const std::string& nick, const char* server_addr, u16 server_port, |
| 538 | const char* server_addr, u16 server_port, u16 client_port, | 542 | u16 client_port, const IPv4Address& preferred_fake_ip, |
| 539 | const MacAddress& preferred_mac, const std::string& password, | 543 | const std::string& password, const std::string& token) { |
| 540 | const std::string& token) { | ||
| 541 | // If the member is connected, kill the connection first | 544 | // If the member is connected, kill the connection first |
| 542 | if (room_member_impl->loop_thread && room_member_impl->loop_thread->joinable()) { | 545 | if (room_member_impl->loop_thread && room_member_impl->loop_thread->joinable()) { |
| 543 | Leave(); | 546 | Leave(); |
| @@ -571,7 +574,7 @@ void RoomMember::Join(const std::string& nick, const std::string& console_id_has | |||
| 571 | if (net > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { | 574 | if (net > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { |
| 572 | room_member_impl->nickname = nick; | 575 | room_member_impl->nickname = nick; |
| 573 | room_member_impl->StartLoop(); | 576 | room_member_impl->StartLoop(); |
| 574 | room_member_impl->SendJoinRequest(nick, console_id_hash, preferred_mac, password, token); | 577 | room_member_impl->SendJoinRequest(nick, preferred_fake_ip, password, token); |
| 575 | SendGameInfo(room_member_impl->current_game_info); | 578 | SendGameInfo(room_member_impl->current_game_info); |
| 576 | } else { | 579 | } else { |
| 577 | enet_peer_disconnect(room_member_impl->server, 0); | 580 | enet_peer_disconnect(room_member_impl->server, 0); |
| @@ -584,14 +587,22 @@ bool RoomMember::IsConnected() const { | |||
| 584 | return room_member_impl->IsConnected(); | 587 | return room_member_impl->IsConnected(); |
| 585 | } | 588 | } |
| 586 | 589 | ||
| 587 | void RoomMember::SendWifiPacket(const WifiPacket& wifi_packet) { | 590 | void RoomMember::SendProxyPacket(const ProxyPacket& proxy_packet) { |
| 588 | Packet packet; | 591 | Packet packet; |
| 589 | packet.Write(static_cast<u8>(IdWifiPacket)); | 592 | packet.Write(static_cast<u8>(IdProxyPacket)); |
| 590 | packet.Write(static_cast<u8>(wifi_packet.type)); | 593 | |
| 591 | packet.Write(wifi_packet.channel); | 594 | packet.Write(static_cast<u8>(proxy_packet.local_endpoint.family)); |
| 592 | packet.Write(wifi_packet.transmitter_address); | 595 | packet.Write(proxy_packet.local_endpoint.ip); |
| 593 | packet.Write(wifi_packet.destination_address); | 596 | packet.Write(proxy_packet.local_endpoint.portno); |
| 594 | packet.Write(wifi_packet.data); | 597 | |
| 598 | packet.Write(static_cast<u8>(proxy_packet.remote_endpoint.family)); | ||
| 599 | packet.Write(proxy_packet.remote_endpoint.ip); | ||
| 600 | packet.Write(proxy_packet.remote_endpoint.portno); | ||
| 601 | |||
| 602 | packet.Write(static_cast<u8>(proxy_packet.protocol)); | ||
| 603 | packet.Write(proxy_packet.broadcast); | ||
| 604 | packet.Write(proxy_packet.data); | ||
| 605 | |||
| 595 | room_member_impl->Send(std::move(packet)); | 606 | room_member_impl->Send(std::move(packet)); |
| 596 | } | 607 | } |
| 597 | 608 | ||
| @@ -645,8 +656,8 @@ RoomMember::CallbackHandle<RoomMember::Error> RoomMember::BindOnError( | |||
| 645 | return room_member_impl->Bind(callback); | 656 | return room_member_impl->Bind(callback); |
| 646 | } | 657 | } |
| 647 | 658 | ||
| 648 | RoomMember::CallbackHandle<WifiPacket> RoomMember::BindOnWifiPacketReceived( | 659 | RoomMember::CallbackHandle<ProxyPacket> RoomMember::BindOnProxyPacketReceived( |
| 649 | std::function<void(const WifiPacket&)> callback) { | 660 | std::function<void(const ProxyPacket&)> callback) { |
| 650 | return room_member_impl->Bind(callback); | 661 | return room_member_impl->Bind(callback); |
| 651 | } | 662 | } |
| 652 | 663 | ||
| @@ -685,7 +696,7 @@ void RoomMember::Leave() { | |||
| 685 | room_member_impl->client = nullptr; | 696 | room_member_impl->client = nullptr; |
| 686 | } | 697 | } |
| 687 | 698 | ||
| 688 | template void RoomMember::Unbind(CallbackHandle<WifiPacket>); | 699 | template void RoomMember::Unbind(CallbackHandle<ProxyPacket>); |
| 689 | template void RoomMember::Unbind(CallbackHandle<RoomMember::State>); | 700 | template void RoomMember::Unbind(CallbackHandle<RoomMember::State>); |
| 690 | template void RoomMember::Unbind(CallbackHandle<RoomMember::Error>); | 701 | template void RoomMember::Unbind(CallbackHandle<RoomMember::Error>); |
| 691 | template void RoomMember::Unbind(CallbackHandle<RoomInformation>); | 702 | template void RoomMember::Unbind(CallbackHandle<RoomInformation>); |
diff --git a/src/network/room_member.h b/src/network/room_member.h index bbb7d13d4..4252b7146 100644 --- a/src/network/room_member.h +++ b/src/network/room_member.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | #include "common/announce_multiplayer_room.h" | 10 | #include "common/announce_multiplayer_room.h" |
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "common/socket_types.h" | ||
| 12 | #include "network/room.h" | 13 | #include "network/room.h" |
| 13 | 14 | ||
| 14 | namespace Network { | 15 | namespace Network { |
| @@ -17,22 +18,12 @@ using AnnounceMultiplayerRoom::GameInfo; | |||
| 17 | using AnnounceMultiplayerRoom::RoomInformation; | 18 | using AnnounceMultiplayerRoom::RoomInformation; |
| 18 | 19 | ||
| 19 | /// Information about the received WiFi packets. | 20 | /// Information about the received WiFi packets. |
| 20 | /// Acts as our own 802.11 header. | 21 | struct ProxyPacket { |
| 21 | struct WifiPacket { | 22 | SockAddrIn local_endpoint; |
| 22 | enum class PacketType : u8 { | 23 | SockAddrIn remote_endpoint; |
| 23 | Beacon, | 24 | Protocol protocol; |
| 24 | Data, | 25 | bool broadcast; |
| 25 | Authentication, | 26 | std::vector<u8> data; |
| 26 | AssociationResponse, | ||
| 27 | Deauthentication, | ||
| 28 | NodeMap | ||
| 29 | }; | ||
| 30 | PacketType type; ///< The type of 802.11 frame. | ||
| 31 | std::vector<u8> data; ///< Raw 802.11 frame data, starting at the management frame header | ||
| 32 | /// for management frames. | ||
| 33 | MacAddress transmitter_address; ///< Mac address of the transmitter. | ||
| 34 | MacAddress destination_address; ///< Mac address of the receiver. | ||
| 35 | u8 channel; ///< WiFi channel where this frame was transmitted. | ||
| 36 | }; | 27 | }; |
| 37 | 28 | ||
| 38 | /// Represents a chat message. | 29 | /// Represents a chat message. |
| @@ -72,15 +63,14 @@ public: | |||
| 72 | HostKicked, ///< Kicked by the host | 63 | HostKicked, ///< Kicked by the host |
| 73 | 64 | ||
| 74 | // Reasons why connection was rejected | 65 | // Reasons why connection was rejected |
| 75 | UnknownError, ///< Some error [permissions to network device missing or something] | 66 | UnknownError, ///< Some error [permissions to network device missing or something] |
| 76 | NameCollision, ///< Somebody is already using this name | 67 | NameCollision, ///< Somebody is already using this name |
| 77 | MacCollision, ///< Somebody is already using that mac-address | 68 | IpCollision, ///< Somebody is already using that fake-ip-address |
| 78 | ConsoleIdCollision, ///< Somebody in the room has the same Console ID | 69 | WrongVersion, ///< The room version is not the same as for this RoomMember |
| 79 | WrongVersion, ///< The room version is not the same as for this RoomMember | 70 | WrongPassword, ///< The password doesn't match the one from the Room |
| 80 | WrongPassword, ///< The password doesn't match the one from the Room | 71 | CouldNotConnect, ///< The room is not responding to a connection attempt |
| 81 | CouldNotConnect, ///< The room is not responding to a connection attempt | 72 | RoomIsFull, ///< Room is already at the maximum number of players |
| 82 | RoomIsFull, ///< Room is already at the maximum number of players | 73 | HostBanned, ///< The user is banned by the host |
| 83 | HostBanned, ///< The user is banned by the host | ||
| 84 | 74 | ||
| 85 | // Reasons why moderation request failed | 75 | // Reasons why moderation request failed |
| 86 | PermissionDenied, ///< The user does not have mod permissions | 76 | PermissionDenied, ///< The user does not have mod permissions |
| @@ -92,9 +82,9 @@ public: | |||
| 92 | std::string username; ///< The web services username of the member. Can be empty. | 82 | std::string username; ///< The web services username of the member. Can be empty. |
| 93 | std::string display_name; ///< The web services display name of the member. Can be empty. | 83 | std::string display_name; ///< The web services display name of the member. Can be empty. |
| 94 | std::string avatar_url; ///< Url to the member's avatar. Can be empty. | 84 | std::string avatar_url; ///< Url to the member's avatar. Can be empty. |
| 95 | GameInfo game_info; ///< Name of the game they're currently playing, or empty if they're | 85 | GameInfo game_info; ///< Name of the game they're currently playing, or empty if they're |
| 96 | /// not playing anything. | 86 | /// not playing anything. |
| 97 | MacAddress mac_address; ///< MAC address associated with this member. | 87 | IPv4Address fake_ip; ///< Fake Ip address associated with this member. |
| 98 | }; | 88 | }; |
| 99 | using MemberList = std::vector<MemberInformation>; | 89 | using MemberList = std::vector<MemberInformation>; |
| 100 | 90 | ||
| @@ -135,7 +125,7 @@ public: | |||
| 135 | /** | 125 | /** |
| 136 | * Returns the MAC address of the RoomMember. | 126 | * Returns the MAC address of the RoomMember. |
| 137 | */ | 127 | */ |
| 138 | const MacAddress& GetMacAddress() const; | 128 | const IPv4Address& GetFakeIpAddress() const; |
| 139 | 129 | ||
| 140 | /** | 130 | /** |
| 141 | * Returns information about the room we're currently connected to. | 131 | * Returns information about the room we're currently connected to. |
| @@ -149,19 +139,17 @@ public: | |||
| 149 | 139 | ||
| 150 | /** | 140 | /** |
| 151 | * Attempts to join a room at the specified address and port, using the specified nickname. | 141 | * Attempts to join a room at the specified address and port, using the specified nickname. |
| 152 | * A console ID hash is passed in to check console ID conflicts. | ||
| 153 | * This may fail if the username or console ID is already taken. | ||
| 154 | */ | 142 | */ |
| 155 | void Join(const std::string& nickname, const std::string& console_id_hash, | 143 | void Join(const std::string& nickname, const char* server_addr = "127.0.0.1", |
| 156 | const char* server_addr = "127.0.0.1", u16 server_port = DefaultRoomPort, | 144 | u16 server_port = DefaultRoomPort, u16 client_port = 0, |
| 157 | u16 client_port = 0, const MacAddress& preferred_mac = NoPreferredMac, | 145 | const IPv4Address& preferred_fake_ip = NoPreferredIP, |
| 158 | const std::string& password = "", const std::string& token = ""); | 146 | const std::string& password = "", const std::string& token = ""); |
| 159 | 147 | ||
| 160 | /** | 148 | /** |
| 161 | * Sends a WiFi packet to the room. | 149 | * Sends a WiFi packet to the room. |
| 162 | * @param packet The WiFi packet to send. | 150 | * @param packet The WiFi packet to send. |
| 163 | */ | 151 | */ |
| 164 | void SendWifiPacket(const WifiPacket& packet); | 152 | void SendProxyPacket(const ProxyPacket& packet); |
| 165 | 153 | ||
| 166 | /** | 154 | /** |
| 167 | * Sends a chat message to the room. | 155 | * Sends a chat message to the room. |
| @@ -207,14 +195,14 @@ public: | |||
| 207 | CallbackHandle<Error> BindOnError(std::function<void(const Error&)> callback); | 195 | CallbackHandle<Error> BindOnError(std::function<void(const Error&)> callback); |
| 208 | 196 | ||
| 209 | /** | 197 | /** |
| 210 | * Binds a function to an event that will be triggered every time a WifiPacket is received. | 198 | * Binds a function to an event that will be triggered every time a ProxyPacket is received. |
| 211 | * The function wil be called everytime the event is triggered. | 199 | * The function wil be called everytime the event is triggered. |
| 212 | * The callback function must not bind or unbind a function. Doing so will cause a deadlock | 200 | * The callback function must not bind or unbind a function. Doing so will cause a deadlock |
| 213 | * @param callback The function to call | 201 | * @param callback The function to call |
| 214 | * @return A handle used for removing the function from the registered list | 202 | * @return A handle used for removing the function from the registered list |
| 215 | */ | 203 | */ |
| 216 | CallbackHandle<WifiPacket> BindOnWifiPacketReceived( | 204 | CallbackHandle<ProxyPacket> BindOnProxyPacketReceived( |
| 217 | std::function<void(const WifiPacket&)> callback); | 205 | std::function<void(const ProxyPacket&)> callback); |
| 218 | 206 | ||
| 219 | /** | 207 | /** |
| 220 | * Binds a function to an event that will be triggered every time the RoomInformation changes. | 208 | * Binds a function to an event that will be triggered every time the RoomInformation changes. |
| @@ -292,10 +280,8 @@ inline const char* GetErrorStr(const RoomMember::Error& e) { | |||
| 292 | return "UnknownError"; | 280 | return "UnknownError"; |
| 293 | case RoomMember::Error::NameCollision: | 281 | case RoomMember::Error::NameCollision: |
| 294 | return "NameCollision"; | 282 | return "NameCollision"; |
| 295 | case RoomMember::Error::MacCollision: | 283 | case RoomMember::Error::IpCollision: |
| 296 | return "MaxCollision"; | 284 | return "IpCollision"; |
| 297 | case RoomMember::Error::ConsoleIdCollision: | ||
| 298 | return "ConsoleIdCollision"; | ||
| 299 | case RoomMember::Error::WrongVersion: | 285 | case RoomMember::Error::WrongVersion: |
| 300 | return "WrongVersion"; | 286 | return "WrongVersion"; |
| 301 | case RoomMember::Error::WrongPassword: | 287 | case RoomMember::Error::WrongPassword: |