1 #ifndef SERVER_H
2 #define SERVER_H
3 
4 #include "pb/commands.pb.h"
5 #include "pb/serverinfo_ban.pb.h"
6 #include "pb/serverinfo_chat_message.pb.h"
7 #include "pb/serverinfo_user.pb.h"
8 #include "pb/serverinfo_warning.pb.h"
9 #include "server_player_reference.h"
10 
11 #include <QMap>
12 #include <QMultiMap>
13 #include <QMutex>
14 #include <QObject>
15 #include <QReadWriteLock>
16 #include <QStringList>
17 
18 class Server_DatabaseInterface;
19 class Server_Game;
20 class Server_Room;
21 class Server_ProtocolHandler;
22 class Server_AbstractUserInterface;
23 class GameReplay;
24 class IslMessage;
25 class SessionEvent;
26 class RoomEvent;
27 class DeckList;
28 class ServerInfo_Game;
29 class ServerInfo_Room;
30 class Response;
31 class GameEventContainer;
32 class CommandContainer;
33 class Command_JoinGame;
34 
35 enum AuthenticationResult
36 {
37     NotLoggedIn,
38     PasswordRight,
39     UnknownUser,
40     WouldOverwriteOldSession,
41     UserIsBanned,
42     UsernameInvalid,
43     RegistrationRequired,
44     UserIsInactive,
45     ClientIdRequired
46 };
47 
48 class Server : public QObject
49 {
50     Q_OBJECT
51 signals:
52     void pingClockTimeout();
53     void sigSendIslMessage(const IslMessage &message, int serverId);
54     void endSession(qint64 sessionId);
55 private slots:
56     void broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl = false);
57 
58 public:
59     mutable QReadWriteLock clientsLock, roomsLock; // locking order: roomsLock before clientsLock
60     Server(QObject *parent = nullptr);
61     ~Server() = default;
62     AuthenticationResult loginUser(Server_ProtocolHandler *session,
63                                    QString &name,
64                                    const QString &password,
65                                    QString &reason,
66                                    int &secondsLeft,
67                                    QString &clientid,
68                                    QString &clientVersion,
69                                    QString &connectionType);
70 
getRooms()71     const QMap<int, Server_Room *> &getRooms()
72     {
73         return rooms;
74     }
75 
76     Server_AbstractUserInterface *findUser(const QString &userName) const;
getUsers()77     const QMap<QString, Server_ProtocolHandler *> &getUsers() const
78     {
79         return users;
80     }
getUsersBySessionId()81     const QMap<qint64, Server_ProtocolHandler *> &getUsersBySessionId() const
82     {
83         return usersBySessionId;
84     }
getServerRequiredFeatureList()85     virtual QMap<QString, bool> getServerRequiredFeatureList() const
86     {
87         return QMap<QString, bool>();
88     }
89     void addClient(Server_ProtocolHandler *player);
90     void removeClient(Server_ProtocolHandler *player);
91     QList<QString> getOnlineModeratorList() const;
getLoginMessage()92     virtual QString getLoginMessage() const
93     {
94         return QString();
95     }
getRequiredFeatures()96     virtual QString getRequiredFeatures() const
97     {
98         return QString();
99     }
permitUnregisteredUsers()100     virtual bool permitUnregisteredUsers() const
101     {
102         return true;
103     }
getGameShouldPing()104     virtual bool getGameShouldPing() const
105     {
106         return false;
107     }
getClientIDRequiredEnabled()108     virtual bool getClientIDRequiredEnabled() const
109     {
110         return false;
111     }
getRegOnlyServerEnabled()112     virtual bool getRegOnlyServerEnabled() const
113     {
114         return false;
115     }
getMaxUserLimitEnabled()116     virtual bool getMaxUserLimitEnabled() const
117     {
118         return false;
119     }
getEnableLogQuery()120     virtual bool getEnableLogQuery() const
121     {
122         return false;
123     }
getStoreReplaysEnabled()124     virtual bool getStoreReplaysEnabled() const
125     {
126         return true;
127     }
getIdleClientTimeout()128     virtual int getIdleClientTimeout() const
129     {
130         return 0;
131     }
getClientKeepAlive()132     virtual int getClientKeepAlive() const
133     {
134         return 0;
135     }
getMaxGameInactivityTime()136     virtual int getMaxGameInactivityTime() const
137     {
138         return 9999999;
139     }
getMaxPlayerInactivityTime()140     virtual int getMaxPlayerInactivityTime() const
141     {
142         return 9999999;
143     }
getMessageCountingInterval()144     virtual int getMessageCountingInterval() const
145     {
146         return 0;
147     }
getMaxMessageCountPerInterval()148     virtual int getMaxMessageCountPerInterval() const
149     {
150         return 0;
151     }
getMaxMessageSizePerInterval()152     virtual int getMaxMessageSizePerInterval() const
153     {
154         return 0;
155     }
getMaxGamesPerUser()156     virtual int getMaxGamesPerUser() const
157     {
158         return 0;
159     }
getCommandCountingInterval()160     virtual int getCommandCountingInterval() const
161     {
162         return 0;
163     }
getMaxCommandCountPerInterval()164     virtual int getMaxCommandCountPerInterval() const
165     {
166         return 0;
167     }
getMaxUserTotal()168     virtual int getMaxUserTotal() const
169     {
170         return 9999999;
171     }
getServerID()172     virtual int getServerID() const
173     {
174         return 0;
175     }
permitCreateGameAsJudge()176     virtual bool permitCreateGameAsJudge() const
177     {
178         return false;
179     }
180 
181     Server_DatabaseInterface *getDatabaseInterface() const;
getNextLocalGameId()182     int getNextLocalGameId()
183     {
184         QMutexLocker locker(&nextLocalGameIdMutex);
185         return ++nextLocalGameId;
186     }
187 
188     void sendIsl_Response(const Response &item, int serverId = -1, qint64 sessionId = -1);
189     void sendIsl_SessionEvent(const SessionEvent &item, int serverId = -1, qint64 sessionId = -1);
190     void sendIsl_GameEventContainer(const GameEventContainer &item, int serverId = -1, qint64 sessionId = -1);
191     void sendIsl_RoomEvent(const RoomEvent &item, int serverId = -1, qint64 sessionId = -1);
192     void sendIsl_GameCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId, int playerId);
193     void sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId);
194 
getExternalUsers()195     const QMap<QString, Server_AbstractUserInterface *> &getExternalUsers() const
196     {
197         return externalUsers;
198     }
199 
200     void addPersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
201     void removePersistentPlayer(const QString &userName, int roomId, int gameId, int playerId);
202     QList<PlayerReference> getPersistentPlayerReferences(const QString &userName) const;
203     int getUsersCount() const;
204     int getGamesCount() const;
getTCPUserCount()205     int getTCPUserCount() const
206     {
207         return tcpUserCount;
208     }
getWebSocketUserCount()209     int getWebSocketUserCount() const
210     {
211         return webSocketUserCount;
212     }
213 
214 private:
215     QMultiMap<QString, PlayerReference> persistentPlayers;
216     mutable QReadWriteLock persistentPlayersLock;
217     int nextLocalGameId, tcpUserCount, webSocketUserCount;
218     QMutex nextLocalGameIdMutex;
219 
220 protected slots:
221     void externalUserJoined(const ServerInfo_User &userInfo);
222     void externalUserLeft(const QString &userName);
223     void externalRoomUserJoined(int roomId, const ServerInfo_User &userInfo);
224     void externalRoomUserLeft(int roomId, const QString &userName);
225     void externalRoomSay(int roomId, const QString &userName, const QString &message);
226     void externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo);
227     void
228     externalJoinGameCommandReceived(const Command_JoinGame &cmd, int cmdId, int roomId, int serverId, qint64 sessionId);
229     void
230     externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId);
231     void externalGameEventContainerReceived(const GameEventContainer &cont, qint64 sessionId);
232     void externalResponseReceived(const Response &resp, qint64 sessionId);
233 
doSendIslMessage(const IslMessage &,int)234     virtual void doSendIslMessage(const IslMessage & /* msg */, int /* serverId */)
235     {
236     }
237 
238 protected:
239     void prepareDestroy();
240     void setDatabaseInterface(Server_DatabaseInterface *_databaseInterface);
241     QList<Server_ProtocolHandler *> clients;
242     QMap<qint64, Server_ProtocolHandler *> usersBySessionId;
243     QMap<QString, Server_ProtocolHandler *> users;
244     QMap<qint64, Server_AbstractUserInterface *> externalUsersBySessionId;
245     QMap<QString, Server_AbstractUserInterface *> externalUsers;
246     QMap<int, Server_Room *> rooms;
247     QMap<QThread *, Server_DatabaseInterface *> databaseInterfaces;
248     void addRoom(Server_Room *newRoom);
249 };
250 
251 #endif
252