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{
40 Q_OBJECT
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 */
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 * 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 */
295 KMessageClient *messageClient() const;
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 */
305 KMessageServer *messageServer() const;
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 */
363 void signalAdminStatusChanged(bool isAdmin);
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 */
388 void slotAdminStatusChanged(bool isAdmin);
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
The KGameNetwork class is the KGame class with network support.
void signalClientConnected(quint32 clientID)
This signal is emitted whenever the KMessageServer sends us a message that a new client connected.
virtual void networkTransmission(QDataStream &, int, quint32, quint32, quint32 clientID)=0
Called by ReceiveNetworkTransmission().
void signalConnectionBroken()
Our connection to the KMessageServer has broken.
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...
void signalAdminStatusChanged(bool isAdmin)
This client gets or loses the admin status.
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.
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
bool disconnect(const QMetaObject::Connection &connection)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:13:43 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.