summaryrefslogtreecommitdiffstats
path: root/src/network/room.h
blob: a6798483705b11d1be7a958303de4cf81594493c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <array>
#include <memory>
#include <string>
#include <vector>
#include "common/common_types.h"
#include "network/verify_user.h"

namespace Network {

constexpr u32 network_version = 4; ///< The version of this Room and RoomMember

constexpr u16 DefaultRoomPort = 24872;

constexpr u32 MaxMessageSize = 500;

/// Maximum number of concurrent connections allowed to this room.
static constexpr u32 MaxConcurrentConnections = 254;

constexpr std::size_t NumChannels = 1; // Number of channels used for the connection

struct RoomInformation {
    std::string name;           ///< Name of the server
    std::string description;    ///< Server description
    u32 member_slots;           ///< Maximum number of members in this room
    u16 port;                   ///< The port of this room
    std::string preferred_game; ///< Game to advertise that you want to play
    u64 preferred_game_id;      ///< Title ID for the advertised game
    std::string host_username;  ///< Forum username of the host
    bool enable_citra_mods;     ///< Allow Citra Moderators to moderate on this room
};

struct GameInfo {
    std::string name{""};
    u64 id{0};
};

using MacAddress = std::array<u8, 6>;
/// A special MAC address that tells the room we're joining to assign us a MAC address
/// automatically.
constexpr MacAddress NoPreferredMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// 802.11 broadcast MAC address
constexpr MacAddress BroadcastMac = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};

// The different types of messages that can be sent. The first byte of each packet defines the type
enum RoomMessageTypes : u8 {
    IdJoinRequest = 1,
    IdJoinSuccess,
    IdRoomInformation,
    IdSetGameInfo,
    IdWifiPacket,
    IdChatMessage,
    IdNameCollision,
    IdMacCollision,
    IdVersionMismatch,
    IdWrongPassword,
    IdCloseRoom,
    IdRoomIsFull,
    IdConsoleIdCollision,
    IdStatusMessage,
    IdHostKicked,
    IdHostBanned,
    /// Moderation requests
    IdModKick,
    IdModBan,
    IdModUnban,
    IdModGetBanList,
    // Moderation responses
    IdModBanListResponse,
    IdModPermissionDenied,
    IdModNoSuchUser,
    IdJoinSuccessAsMod,
};

/// Types of system status messages
enum StatusMessageTypes : u8 {
    IdMemberJoin = 1,  ///< Member joining
    IdMemberLeave,     ///< Member leaving
    IdMemberKicked,    ///< A member is kicked from the room
    IdMemberBanned,    ///< A member is banned from the room
    IdAddressUnbanned, ///< A username / ip address is unbanned from the room
};

/// This is what a server [person creating a server] would use.
class Room final {
public:
    enum class State : u8 {
        Open,   ///< The room is open and ready to accept connections.
        Closed, ///< The room is not opened and can not accept connections.
    };

    struct Member {
        std::string nickname;     ///< The nickname of the member.
        std::string username;     ///< The web services username of the member. Can be empty.
        std::string display_name; ///< The web services display name of the member. Can be empty.
        std::string avatar_url;   ///< Url to the member's avatar. Can be empty.
        GameInfo game_info;       ///< The current game of the member
        MacAddress mac_address;   ///< The assigned mac address of the member.
    };

    Room();
    ~Room();

    /**
     * Gets the current state of the room.
     */
    State GetState() const;

    /**
     * Gets the room information of the room.
     */
    const RoomInformation& GetRoomInformation() const;

    /**
     * Gets the verify UID of this room.
     */
    std::string GetVerifyUID() const;

    /**
     * Gets a list of the mbmers connected to the room.
     */
    std::vector<Member> GetRoomMemberList() const;

    /**
     * Checks if the room is password protected
     */
    bool HasPassword() const;

    using UsernameBanList = std::vector<std::string>;
    using IPBanList = std::vector<std::string>;

    using BanList = std::pair<UsernameBanList, IPBanList>;

    /**
     * Creates the socket for this room. Will bind to default address if
     * server is empty string.
     */
    bool Create(const std::string& name, const std::string& description = "",
                const std::string& server = "", u16 server_port = DefaultRoomPort,
                const std::string& password = "",
                const u32 max_connections = MaxConcurrentConnections,
                const std::string& host_username = "", const std::string& preferred_game = "",
                u64 preferred_game_id = 0,
                std::unique_ptr<VerifyUser::Backend> verify_backend = nullptr,
                const BanList& ban_list = {}, bool enable_citra_mods = false);

    /**
     * Sets the verification GUID of the room.
     */
    void SetVerifyUID(const std::string& uid);

    /**
     * Gets the ban list (including banned forum usernames and IPs) of the room.
     */
    BanList GetBanList() const;

    /**
     * Destroys the socket
     */
    void Destroy();

private:
    class RoomImpl;
    std::unique_ptr<RoomImpl> room_impl;
};

} // namespace Network