1 /** @file serversystem.h  Subsystem for tending to clients.
2  *
3  * @authors Copyright (c) 2013-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
4  *
5  * @par License
6  * GPL: http://www.gnu.org/licenses/gpl.html
7  *
8  * <small>This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version. This program is distributed in the hope that it
12  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
14  * Public License for more details. You should have received a copy of the GNU
15  * General Public License along with this program; if not, see:
16  * http://www.gnu.org/licenses</small>
17  */
18 
19 #ifndef SERVERSYSTEM_H
20 #define SERVERSYSTEM_H
21 
22 #include <de/libcore.h>
23 #include <de/System>
24 #include <de/Id>
25 #include <de/Error>
26 #include "remoteuser.h"
27 #include "dd_types.h"
28 
29 #include <QObject>
30 
31 /**
32  * Subsystem for tending to clients.
33  * @ingroup server
34  *
35  * - Immediately after connecting to a server the socket is put into the
36  *   set of remote users (RemoteUser class). One RemoteUser instance is
37  *   responsible for each connected socket.
38  * - Remote users may request upgrade to a Shell user, in which case ownership
39  *   of the socket is given to a ShellUser instance.
40  * - Remote users may join the game, becoming players in the game.
41  * - Silent remote users that hang around too long will be automatically
42  *   terminated if haven't joined the game.
43  *
44  * @todo This is a work in progress, as all remnants of the old network code
45  * have not been removed/revised.
46  */
47 class ServerSystem : public QObject, public de::System
48 {
49     Q_OBJECT
50 
51 public:
52     /// An error related to identifiers (e.g., invalid ID specified). @ingroup errors
53     DENG2_ERROR(IdError);
54 
55 public:
56     ServerSystem();
57 
58     /**
59      * Start listening for incoming connections.
60      *
61      * @param port  TCP port to listen on.
62      */
63     void start(de::duint16 port);
64 
65     void stop();
66 
67     bool isListening() const;
68 
69     /**
70      * The client is removed from the game immediately. This is used when the
71      * server needs to terminate a client's connection abnormally.
72      */
73     void terminateNode(de::Id const &id);
74 
75     RemoteUser &user(de::Id const &id) const;
76 
77     /**
78      * A network node wishes to become a real client.
79      * @return @c true if we allow this.
80      */
81     bool isUserAllowedToJoin(RemoteUser &user) const;
82 
83     void convertToShellUser(RemoteUser *user);
84 
85     void convertToRemoteFeedUser(RemoteUser *user);
86 
87     /**
88      * Returns the total number of connected users (of all types).
89      */
90     int userCount() const;
91 
92     /**
93      * Prints the status of the server into the log.
94      */
95     void printStatus();
96 
97     void timeChanged(de::Clock const &);
98 
99 protected slots:
100     void handleIncomingConnection();
101     void userDestroyed();
102 
103 private:
104     DENG2_PRIVATE(d)
105 };
106 
107 ServerSystem &App_ServerSystem();
108 
109 void    Server_Register(); // old-fashioned cvars
110 dd_bool N_ServerOpen(void);
111 dd_bool N_ServerClose(void);
112 void    N_PrintNetworkStatus(void);
113 
114 extern char *nptIPAddress; // cvar
115 extern int   nptIPPort;    // cvar
116 
117 #endif // SERVERSYSTEM_H
118