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 <b_mann@gmx.de>
5
6 SPDX-License-Identifier: LGPL-2.0-only
7*/
8
9#ifndef __KGAMENETWORK_H_
10#define __KGAMENETWORK_H_
11
12// own
13#include "kdegamesprivate_export.h"
14// Qt
15#include <QObject>
16#include <QString>
17// Std
18#include <memory>
19
20class KGameIO;
21class KMessageIO;
22class KMessageClient;
23class KMessageServer;
24
25class 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 */
38class KDEGAMESPRIVATE_EXPORT KGameNetwork : public QObject
39{
41
42public:
43 /**
44 * Create a KGameNetwork object
45 */
46 explicit KGameNetwork(int cookie = 42, QObject *parent = nullptr);
47 ~KGameNetwork() override;
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 */
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 * Called by ReceiveNetworkTransmission(). Will be overwritten by
268 * KGame and handle the incoming message.
269 */
270 virtual void networkTransmission(QDataStream &, int, quint32, quint32, quint32 clientID) = 0;
271
272 /**
273 * Disconnect the current connection and establish a new local one.
274 */
275 void disconnect();
276
277 /**
278 * If you are the ADMIN of the game you can give the ADMIN status away to
279 * another client. Use this e.g. if you want to quit the game or if you want
280 * another client to administrate the game (note that disconnect calls
281 * this automatically).
282 * @param clientID the ID of the new ADMIN (note: this is the _client_ID
283 * which has nothing to do with the player IDs. See KMessageServer)
284 */
285 void electAdmin(quint32 clientID);
286
287 /**
288 * Don't use this unless you really know what you're doing! You might
289 * experience some strange behaviour if you send your messages directly
290 * through the KMessageClient!
291 *
292 * @return a pointer to the KMessageClient used internally to send the
293 * messages. You should rather use one of the send functions!
294 */
296
297 /**
298 * Don't use this unless you really know what you are doing! You might
299 * experience some strange behaviour if you use the message server directly!
300 *
301 * @return a pointer to the message server if this is the MASTER KGame
302 * object. Note that it might be possible that no KGame object contains
303 * the KMessageServer at all! It might even run stand alone!
304 */
306
307 /**
308 * You should call this before doing thigs like, e.g. qApp->processEvents().
309 * Don't forget to call unlock once you are done!
310 *
311 * @see KMessageClient::lock
312 */
313 virtual void lock();
314
315 /**
316 * @see KMessageClient::unlock
317 */
318 virtual void unlock();
319
321 /**
322 * A network error occurred
323 * @param error the error code
324 * @param text the error text
325 */
326 void signalNetworkErrorMessage(int error, const QString &text);
327
328 /**
329 * Our connection to the KMessageServer has broken.
330 * See KMessageClient::connectionBroken
331 */
333
334 /**
335 * This signal is emitted whenever the KMessageServer sends us a message that a
336 * new client connected. KGame uses this to call KGame::negotiateNetworkGame
337 * for the newly connected client if we are admin (see isAdmin)
338 *
339 * @see KMessageClient::eventClientConnected
340 *
341 * @param clientID the ID of the newly connected client
342 */
343 void signalClientConnected(quint32 clientID);
344
345 /**
346 * This signal is emitted whenever the KMessageServer sends us a message
347 * that a connection to a client was detached. The second parameter can be used
348 * to distinguish between network errors or removing on purpose.
349 *
350 * @see KMessageClient::eventClientDisconnected
351 *
352 * @param clientID the client that has disconnected
353 * @param broken true if the connection was lost because of a network error, false
354 * if the connection was closed by the message server admin.
355 */
356 void signalClientDisconnected(quint32 clientID, bool broken);
357
358 /**
359 * This client gets or loses the admin status.
360 * @see KMessageClient::adminStatusChanged
361 * @param isAdmin True if this client gets the ADMIN status otherwise FALSE
362 */
364
365protected:
366 /**
367 * @internal
368 * Start a KMessageServer object and use it as the MASTER of the game.
369 * Note that you must not call this if there is already another master
370 * running!
371 */
372 void setMaster();
373
374protected Q_SLOTS:
375 /**
376 * Called by KMessageClient::broadcastReceived() and will check if the
377 * message format is valid. If it is not, it will generate an error (see
378 * signalNetworkVersionError and signalNetworkErorrMessage).
379 * If it is valid, the pure virtual method networkTransmission() is called.
380 * (This one is overwritten in KGame.)
381 */
382 void receiveNetworkTransmission(const QByteArray &a, quint32 clientID);
383
384 /**
385 * This KGame object receives or loses the admin status.
386 * @param isAdmin Whether we are admin or not
387 */
389
390 /**
391 * Called when the network connection is about to terminate. Is used
392 * to store the network parameter like the game id
393 */
394 void aboutToLoseConnection(quint32 id);
395
396 /**
397 * Called when the network connection is terminated. Used to clean
398 * up the disconnect parameter
399 */
400 void slotResetConnection();
401
402private:
403 void tryPublish();
404 void tryStopPublishing();
405
406private:
407 std::unique_ptr<KGameNetworkPrivate> const d;
408};
409
410#endif
Base class for IO devices for games.
Definition kgameio.h:57
KMessageServer * messageServer() const
Don't use this unless you really know what you are doing!
bool isMaster() const
Is this the game MASTER (i.e.
KMessageClient * messageClient() const
Don't use this unless you really know what you're doing!
bool isNetwork() const
bool isAdmin() const
The admin of a game is the one who initializes newly connected clients using negotiateNetworkGame and...
void signalClientConnected(quint32 clientID)
This signal is emitted whenever the KMessageServer sends us a message that a new client connected.
bool connectToServer(const QString &host, quint16 port)
Inits a network game as a network CLIENT.
QString hostName() const
virtual void lock()
You should call this before doing thigs like, e.g.
KGameNetwork(int cookie=42, QObject *parent=nullptr)
Create a KGameNetwork object.
virtual void networkTransmission(QDataStream &, int, quint32, quint32, quint32 clientID)=0
Called by ReceiveNetworkTransmission().
void electAdmin(quint32 clientID)
If you are the ADMIN of the game you can give the ADMIN status away to another client.
virtual void Debug()
Gives debug output of the game status.
void slotResetConnection()
Called when the network connection is terminated.
int cookie() const
Application cookie.
bool sendMessage(const QByteArray &buffer, int msgid, quint32 receiver=0, quint32 sender=0)
Send a network message msg with a given message ID msgid to all clients.
quint32 gameId() const
The unique ID of this game.
void aboutToLoseConnection(quint32 id)
Called when the network connection is about to terminate.
bool isOfferingConnections() const
Are we still offer offering server connections - only for game MASTER.
void setMaxClients(int max)
Changes the maximal connection number of the KMessageServer to max.
bool offerConnections(quint16 port)
Inits a network game as network MASTER.
void slotAdminStatusChanged(bool isAdmin)
This KGame object receives or loses the admin status.
void signalConnectionBroken()
Our connection to the KMessageServer has broken.
virtual void unlock()
void signalNetworkErrorMessage(int error, const QString &text)
A network error occurred.
void signalClientDisconnected(quint32 clientID, bool broken)
This signal is emitted whenever the KMessageServer sends us a message that a connection to a client w...
quint16 port() const
void receiveNetworkTransmission(const QByteArray &a, quint32 clientID)
Called by KMessageClient::broadcastReceived() and will check if the message format is valid.
bool stopServerConnection()
Stops offering server connections - only for game MASTER.
void sendError(int error, const QByteArray &message, quint32 receiver=0, quint32 sender=0)
Sends a network message.
void signalAdminStatusChanged(bool isAdmin)
This client gets or loses the admin status.
bool sendSystemMessage(const QByteArray &buffer, int msgid, quint32 receiver=0, quint32 sender=0)
Sends a network message msg with a given msg id msgid to all clients.
A client to connect to a KMessageServer.
This abstract base class represents one end of a message connections between two clients.
Definition kmessageio.h:44
A server for message sending and broadcasting, using TCP/IP connections.
QObject(QObject *parent)
Q_OBJECTQ_OBJECT
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
QObject * sender() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:50:36 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.