KDEGames

kgamenetwork.h
1 /*
2  This file is part of the KDE games library
3  SPDX-FileCopyrightText: 2001 Martin Heni <kde at heni-online.de>
4  SPDX-FileCopyrightText: 2001 Andreas Beckermann <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-only
7 */
8 
9 #ifndef __KGAMENETWORK_H_
10 #define __KGAMENETWORK_H_
11 
12 // own
13 #include "libkdegamesprivate_export.h"
14 // Qt
15 #include <QString>
16 #include <QObject>
17 // Std
18 #include <memory>
19 
20 class KGameIO;
21 class KMessageIO;
22 class KMessageClient;
23 class KMessageServer;
24 
25 class KGameNetworkPrivate;
26 
27 /**
28  * \class KGameNetwork kgamenetwork.h <KGame/KGameNetwork>
29  *
30  * The KGameNetwork class is the KGame class with network
31  * support. All other features are the same but they are
32  * now network transparent. It is not used directly but
33  * only via a KGame object. So you do not really have
34  * to bother with this object.
35  *
36  * @short The main KDE game object
37  */
38 class KDEGAMESPRIVATE_EXPORT KGameNetwork : public QObject
39 {
40  Q_OBJECT
41 
42 public:
43  /**
44  * Create a KGameNetwork object
45  */
46  explicit KGameNetwork(int cookie=42,QObject* parent=nullptr);
47  virtual ~KGameNetwork();
48 
49  /**
50  * Gives debug output of the game status
51  **/
52  virtual void Debug();
53 
54  /**
55  * @return TRUE if this is a network game - i.e. you are either MASTER or
56  * connected to a remote MASTER.
57  **/
58  bool isNetwork() const;
59 
60  /**
61  * Is this the game MASTER (i.e. has started theKMessageServer). A
62  * game has always exactly one MASTER. This is either a KGame object (i.e. a
63  * Client) or an own MessageServer-process. A KGame object that has the
64  * MASTER status is always admin.
65  *
66  * You probably don't want to use this. It is a mostly internal method which
67  * will probably become protected. Better use isAdmin
68  *
69  * @see isAdmin
70  * @return Whether this client has started the KMessageServer
71  **/
72  bool isMaster() const;
73 
74  /**
75  * The admin of a game is the one who initializes newly connected clients
76  * using negotiateNetworkGame and is allowed to configure the game.
77  * E.g. only the admin is allowed to use KGame::setMaxPlayers.
78  *
79  * If one KGame object in the game is MASTER then this client is the admin
80  * as well. isMaster and isAdmin differ only if the KMessageServer
81  * is running in an own process.
82  * @return Whether this client (KGame object) is the admin
83  **/
84  bool isAdmin() const;
85 
86  /**
87  * The unique ID of this game
88  *
89  * @return int id
90  **/
91  quint32 gameId() const;
92 
93  /**
94  * Inits a network game as network MASTER. Note that if the
95  * KMessageServer is not yet started it will be started here (see
96  * setMaster). Any existing connection will be disconnected.
97  *
98  * If you already offer connections the port is changed.
99  *
100  * @param port The port on which the service is offered
101  * @return true if it worked
102  **/
103  bool offerConnections (quint16 port);
104 
105  void setDiscoveryInfo(const QString& type, const QString& name=QString());
106 
107  /**
108  * Inits a network game as a network CLIENT
109  *
110  * @param host the host to which we want to connect
111  * @param port the port we want to connect to
112  *
113  * @return true if connected
114  **/
115  bool connectToServer(const QString& host, quint16 port);
116  bool connectToServer(KMessageIO *connection);
117 
118  /**
119  * @return The port we are listening to if offerConnections was called
120  * or the port we are connected to if connectToServer was called.
121  * Otherwise 0.
122  **/
123  quint16 port() const;
124 
125  /**
126  * @return The name of the host that we are currently connected to is
127  * isNetwork is TRUE and we are not the MASTER, i.e. if connectToServer
128  * was called. Otherwise this will return "localhost".
129  **/
130  QString hostName() const;
131 
132  /**
133  * Stops offering server connections - only for game MASTER
134  * @return true
135  **/
136  bool stopServerConnection();
137 
138  /**
139  * Changes the maximal connection number of the KMessageServer to max.
140  * -1 Means infinite connections are possible. Note that existing
141  * connections are not affected, so even if you set this to 0 in a running
142  * game no client is being disconnected. You can call this only if you are
143  * the ADMIN!
144  *
145  * @see KMessageServer::setMaxClients
146  * @param max The maximal number of connections possible.
147  **/
148  void setMaxClients(int max);
149 
150  //AB: is this now internal only? Can we make it protected (maybe with
151  //friends)? sendSystemMessage AND sendMessage is very confusing to the
152  //user.
153  /**
154  * Sends a network message msg with a given msg id msgid to all clients.
155  * Use this to communicate with KGame (e.g. to add a player ot to configure
156  * the game - usually not necessary).
157  *
158  * For your own messages use sendMessage instead! This is mostly
159  * internal!
160  *
161  * @param buffer the message which will be send. See messages.txt for contents
162  * @param msgid an id for this message. See
163  * KGameMessage::GameMessageIds
164  * @param receiver the KGame / KPlayer this message is for.
165  * @param sender The KGame / KPlayer this message is from (i.e.
166  * you). You
167  * probably want to leave this 0, then KGameNetwork will create the correct
168  * value for you. You might want to use this if you send a message from a
169  * specific player.
170  * @return true if worked
171  */
172  // AB: TODO: doc on how "receiver" and "sender" should be created!
173  bool sendSystemMessage(const QByteArray& buffer, int msgid, quint32 receiver=0, quint32 sender=0);
174 
175  /**
176  * @overload
177  **/
178  bool sendSystemMessage(int data, int msgid, quint32 receiver=0, quint32 sender=0);
179 
180  /**
181  * @overload
182  **/
183  bool sendSystemMessage(const QDataStream &msg, int msgid, quint32 receiver=0, quint32 sender=0);
184 
185  /**
186  * @overload
187  **/
188  bool sendSystemMessage(const QString& msg, int msgid, quint32 receiver=0, quint32 sender=0);
189 
190  /**
191  * Sends a network message
192  * @param error The error code
193  * @param message The error message - use KGameError
194  * @param receiver the KGame / KPlayer this message is for. 0 For
195  * all
196  * @param sender The KGame / KPlayer this message is from (i.e.
197  * you). You probably want to leave this 0, then KGameNetwork will create
198  * the correct value for you. You might want to use this if you send a
199  * message from a specific player.
200  **/
201  void sendError(int error, const QByteArray& message, quint32 receiver=0, quint32 sender=0);
202 
203  /**
204  * Are we still offer offering server connections - only for game MASTER
205  * @return true/false
206  **/
207  bool isOfferingConnections() const;
208 
209  /**
210  * Application cookie. this identifies the game application. It
211  * help to distinguish between e.g. KPoker and KWin4
212  * @return the application cookie
213  **/
214  int cookie() const;
215 
216  /**
217  * Send a network message msg with a given message ID msgid to all clients.
218  * You want to use this to send a message to the clients.
219  *
220  * Note that a message is always sent to ALL clients! This is necessary so
221  * that all clients always have the same data and can easily be changed from
222  * network to non-network without restarting the game. If you want a
223  * specific KGame / KPlayer to react to the message use the
224  * receiver and sender parameters. See KGameMessage::calsMessageId
225  *
226  * SendMessage differs from sendSystemMessage only by the msgid parameter.
227  * sendSystemMessage is thought as a KGame only method while
228  * sendMessage is for public use. The msgid parameter will be
229  * +=KGameMessage::IdUser and in KGame::signalNetworkData msgid will
230  * be -= KGameMessage::IdUser again, so that one can easily distinguish
231  * between system and user messages.
232  *
233  * Use sendSystemMessage to communicate with KGame (e.g. by adding a
234  * player) and sendMessage for your own user message.
235  *
236  * Note: a player should send messages through a KGameIO!
237  *
238  * @param buffer the message which will be send. See messages.txt for contents
239  * @param msgid an id for this message. See KGameMessage::GameMessageIds
240  * @param receiver the KGame / KPlayer this message is for.
241  * @param sender The KGame / KPlayer this message is from (i.e.
242  * you). You
243  * probably want to leave this 0, then KGameNetwork will create the correct
244  * value for you. You might want to use this if you send a message from a
245  * specific player.
246  * @return true if worked
247  **/
248  // AB: TODO: doc on how "receiver" and "sender" should be created!
249  bool sendMessage(const QByteArray& buffer, int msgid, quint32 receiver=0, quint32 sender=0);
250 
251  /**
252  * This is an overloaded member function, provided for convenience.
253  **/
254  bool sendMessage(const QDataStream &msg, int msgid, quint32 receiver=0, quint32 sender=0);
255 
256  /**
257  * This is an overloaded member function, provided for convenience.
258  **/
259  bool sendMessage(const QString& msg, int msgid, quint32 receiver=0, quint32 sender=0);
260 
261  /**
262  * This is an overloaded member function, provided for convenience.
263  **/
264  bool sendMessage(int data, int msgid, quint32 receiver=0, quint32 sender=0);
265 
266 
267  /**
268  * Called by ReceiveNetworkTransmission(). Will be overwritten by
269  * KGame and handle the incoming message.
270  **/
271  virtual void networkTransmission(QDataStream&, int, quint32, quint32, quint32 clientID) = 0;
272 
273 
274  /**
275  * Disconnect the current connection and establish a new local one.
276  **/
277  void disconnect();
278 
279 
280  /**
281  * If you are the ADMIN of the game you can give the ADMIN status away to
282  * another client. Use this e.g. if you want to quit the game or if you want
283  * another client to administrate the game (note that disconnect calls
284  * this automatically).
285  * @param clientID the ID of the new ADMIN (note: this is the _client_ID
286  * which has nothing to do with the player IDs. See KMessageServer)
287  **/
288  void electAdmin(quint32 clientID);
289 
290  /**
291  * Don't use this unless you really know what you're doing! You might
292  * experience some strange behaviour if you send your messages directly
293  * through the KMessageClient!
294  *
295  * @return a pointer to the KMessageClient used internally to send the
296  * messages. You should rather use one of the send functions!
297  **/
298  KMessageClient* messageClient() const;
299 
300  /**
301  * Don't use this unless you really know what you are doing! You might
302  * experience some strange behaviour if you use the message server directly!
303  *
304  * @return a pointer to the message server if this is the MASTER KGame
305  * object. Note that it might be possible that no KGame object contains
306  * the KMessageServer at all! It might even run stand alone!
307  **/
308  KMessageServer* messageServer() const;
309 
310  /**
311  * You should call this before doing thigs like, e.g. qApp->processEvents().
312  * Don't forget to call unlock once you are done!
313  *
314  * @see KMessageClient::lock
315  **/
316  virtual void lock();
317 
318  /**
319  * @see KMessageClient::unlock
320  **/
321  virtual void unlock();
322 
323 Q_SIGNALS:
324  /**
325  * A network error occurred
326  * @param error the error code
327  * @param text the error text
328  */
329  void signalNetworkErrorMessage(int error, const QString &text);
330 
331  /**
332  * Our connection to the KMessageServer has broken.
333  * See KMessageClient::connectionBroken
334  **/
335  void signalConnectionBroken();
336 
337  /**
338  * This signal is emitted whenever the KMessageServer sends us a message that a
339  * new client connected. KGame uses this to call KGame::negotiateNetworkGame
340  * for the newly connected client if we are admin (see isAdmin)
341  *
342  * @see KMessageClient::eventClientConnected
343  *
344  * @param clientID the ID of the newly connected client
345  **/
346  void signalClientConnected(quint32 clientID);
347 
348  /**
349  * This signal is emitted whenever the KMessageServer sends us a message
350  * that a connection to a client was detached. The second parameter can be used
351  * to distinguish between network errors or removing on purpose.
352  *
353  * @see KMessageClient::eventClientDisconnected
354  *
355  * @param clientID the client that has disconnected
356  * @param broken true if the connection was lost because of a network error, false
357  * if the connection was closed by the message server admin.
358  */
359  void signalClientDisconnected(quint32 clientID, bool broken);
360 
361  /**
362  * This client gets or loses the admin status.
363  * @see KMessageClient::adminStatusChanged
364  * @param isAdmin True if this client gets the ADMIN status otherwise FALSE
365  **/
366  void signalAdminStatusChanged(bool isAdmin);
367 
368 protected:
369  /**
370  * @internal
371  * Start a KMessageServer object and use it as the MASTER of the game.
372  * Note that you must not call this if there is already another master
373  * running!
374  **/
375  void setMaster();
376 
377 protected Q_SLOTS:
378  /**
379  * Called by KMessageClient::broadcastReceived() and will check if the
380  * message format is valid. If it is not, it will generate an error (see
381  * signalNetworkVersionError and signalNetworkErorrMessage).
382  * If it is valid, the pure virtual method networkTransmission() is called.
383  * (This one is overwritten in KGame.)
384  **/
385  void receiveNetworkTransmission(const QByteArray& a, quint32 clientID);
386 
387  /**
388  * This KGame object receives or loses the admin status.
389  * @param isAdmin Whether we are admin or not
390  **/
391  void slotAdminStatusChanged(bool isAdmin);
392 
393  /**
394  * Called when the network connection is about to terminate. Is used
395  * to store the network parameter like the game id
396  */
397  void aboutToLoseConnection(quint32 id);
398 
399  /**
400  * Called when the network connection is terminated. Used to clean
401  * up the disconnect parameter
402  */
403  void slotResetConnection();
404 
405 
406 private:
407  void tryPublish();
408  void tryStopPublishing();
409 
410 private:
411  std::unique_ptr<KGameNetworkPrivate> const d;
412 };
413 
414 #endif
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
A client to connect to a KMessageServer.
This abstract base class represents one end of a message connections between two clients.
Definition: kmessageio.h:51
A server for message sending and broadcasting, using TCP/IP connections.
The KGameNetwork class is the KGame class with network support.
Definition: kgamenetwork.h:38
Base class for IO devices for games.
Definition: kgameio.h:56
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Jun 24 2021 22:37:53 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.