KDEGames

kgame.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 __KGAME_H_
10#define __KGAME_H_
11
12// own
13#include "kdegamesprivate_export.h"
14#include "kgamenetwork.h"
15// Qt
16#include <QDataStream>
17#include <QList>
18#include <QString>
19
20class KPlayer;
23class KGameSequence;
24
25class KGamePrivate;
26
27/**
28 * \class KGame kgame.h <KGame/KGame>
29 *
30 * @short The main KDE game object
31 *
32 * The KGame class is the central game object. A game basically
33 * consists of following features:
34 * - Player handling (add, remove,...)
35 * - Game status (end,start,pause,...)
36 * - load/save
37 * - Move (and message) handling
38 * - nextPlayer and gameOver()
39 * - Network connection (for KGameNetwork)
40 *
41 * Example:
42 * \code
43 * KGame *game=new KGame;
44 * \endcode
45 */
46class KDEGAMESPRIVATE_EXPORT KGame : public KGameNetwork
47{
48 Q_OBJECT
49
50public:
52
53 /**
54 * The policy of the property. This can be PolicyClean (setVale uses
55 * send), PolicyDirty (setValue uses changeValue) or
56 * PolicyLocal (setValue uses setLocal).
57 *
58 * A "clean" policy means that the property is always the same on every
59 * client. This is achieved by calling send which actually changes
60 * the value only when the message from the MessageServer is received.
61 *
62 * A "dirty" policy means that as soon as setValue is called the
63 * property is changed immediately. And additionally sent over network.
64 * This can sometimes lead to bugs as the other clients do not
65 * immediately have the same value. For more information see
66 * changeValue.
67 *
68 * PolicyLocal means that a KGameProperty behaves like ever
69 * "normal" variable. Whenever setValue is called (e.g. using "=")
70 * the value of the property is changes immediately without sending it
71 * over network. You might want to use this if you are sure that all
72 * clients set the property at the same time.
73 */
74 enum GamePolicy { PolicyUndefined = 0, PolicyClean = 1, PolicyDirty = 2, PolicyLocal = 3 };
75
76 /**
77 * Create a KGame object. The cookie is used to identify your
78 * game in load/save and network operations. Change this between
79 * games.
80 */
81 explicit KGame(int cookie = 42, QObject *parent = nullptr);
82
83 /**
84 * Destructs the game
85 */
86 ~KGame() override;
87
88 /**
89 * Gives debug output of the game status
90 */
91 void Debug() override;
92
93 /**
94 * Game status - Use this to Control the game flow.
95 * The KGame e.g. sets the status to Pause when you have
96 * less player than the minimum amount
97 */
98 enum GameStatus { Init = 0, Run = 1, Pause = 2, End = 3, Abort = 4, SystemPause = 5, Intro = 6, UserStatus = 7 };
99
100 // Properties
101 /**
102 * Returns a list of all active players
103 *
104 * @return the list of players
105 */
106 KGamePlayerList *playerList();
107
108 /**
109 * The same as @ref playerList but returns a const pointer.
110 */
111 const KGamePlayerList *playerList() const;
112
113 /**
114 * Returns a list of all inactive players
115 * @return the list of players
116 */
117 KGamePlayerList *inactivePlayerList();
118
119 /**
120 * The same as @ref inactivePlayerList but returns a const pointer.
121 */
122 const KGamePlayerList *inactivePlayerList() const;
123
124 /**
125 * @return The KGameSequence object that is currently in use.
126 * @see setGameSequence
127 */
128 KGameSequence *gameSequence() const;
129
130 /**
131 * Is the game running
132 * @return true/false
133 */
134 bool isRunning() const;
135
136 // Player handling
137 /**
138 * Returns the player object for a given player id
139 * @param id Player id
140 * @return player object
141 */
142 KPlayer *findPlayer(quint32 id) const;
143
144 /**
145 * Set a new @ref KGameSequence to control player management. By default
146 * KGame uses a normal @ref KGameSequence object. You might want to subclass
147 * that and provide your own object.
148 *
149 * The previous sequence will get deleted.
150 * @param sequence The new game sequence object. KGame takes ownership and
151 * will delete it on destruction!
152 */
153 void setGameSequence(KGameSequence *sequence);
154
155 /**
156 * Note that KPlayer::save must be implemented properly, as well as
157 * KPlayer::rtti
158 * This will only send a message to all clients. The player is _not_ added
159 * directly!
160 * See also playerInput which will be called as soon as the
161 * player really has been added.
162 *
163 * Note that an added player will first get into a "queue" and won't be in
164 * the game. It will be added to the game as soon as systemAddPlayer is
165 * called what will happen as soon as IdAddPlayer is received.
166 *
167 * Note: you probably want to connect to signalPlayerJoinedGame for
168 * further initialization!
169 * @param newplayer The player you want to add. KGame will send a message to
170 * all clients and add the player using systemAddPlayer
171 */
172 bool addPlayer(KPlayer *newplayer);
173
174 /**
175 * Sends a message over the network, msgid=IdRemovePlayer.
176 *
177 * As soon as this message is received by networkTransmission
178 * systemRemovePlayer is called and the player is removed.
179 */
180 // AB: TODO: make sendMessage to return if the message will be able to be
181 // sent, eg if a socket is connected, etc. If sendMessage returns false
182 // remove the player directly using systemRemovePlayer
183 bool removePlayer(KPlayer *player)
184 {
185 return removePlayer(player, 0);
186 }
187
188 /**
189 * Called by the destructor of KPlayer to remove itself from the game
190 *
191 */
192 void playerDeleted(KPlayer *player);
193
194 /**
195 * sends activate player: internal use only?
196 */
197 bool activatePlayer(KPlayer *player);
198
199 /**
200 * sends inactivate player: internal use only?
201 */
202 bool inactivatePlayer(KPlayer *player);
203
204 /**
205 * Set the maximal number of players. After this is
206 * reached no more players can be added. You must be ADMIN to call this (@see
207 * isAdmin).
208 * @param maxnumber maximal number of players
209 */
210 void setMaxPlayers(uint maxnumber);
211
212 /**
213 * What is the maximal number of players?
214 * @return maximal number of players
215 */
216 int maxPlayers() const;
217
218 /**
219 * Set the minimal number of players. A game can not be started
220 * with less player resp. is paused when already running. You must be ADMIN
221 * to call this (see @ref isAdmin)!
222 * @param minnumber minimal number of players
223 */
224 void setMinPlayers(uint minnumber);
225
226 /**
227 * What is the minimal number of players?
228 * @return minimal number of players
229 */
230 uint minPlayers() const;
231
232 /**
233 * Returns how many players are plugged into the game
234 * @return number of players
235 */
236 uint playerCount() const;
237
238 // Input events
239 /**
240 * Called by KPlayer to send a player input to the
241 * KMessageServer.
242 */
243 virtual bool sendPlayerInput(QDataStream &msg, KPlayer *player, quint32 sender = 0);
244
245 /**
246 * Called when a player input arrives from KMessageServer.
247 *
248 * Calls prepareNext (using QTimer::singleShot) if gameOver()
249 * returns 0. This function should normally not be used outside KGame.
250 * It could be made non-virtual,protected in a later version. At the
251 * moment it is a virtual function to give you more control over KGame.
252 *
253 * For documentation see playerInput.
254 */
255 virtual bool systemPlayerInput(QDataStream &msg, KPlayer *player, quint32 sender = 0);
256
257 /**
258 * This virtual function is called if the KGame needs to create a new player.
259 * This happens only over a network and with load/save. Doing nothing
260 * will create a default KPlayer. If you want to have your own player
261 * you have to create one with the given rtti here.
262 * Note: If your game uses a player class derived from KPlayer you MUST
263 * override this function and create your player here. Otherwise the
264 * game will crash.
265 * Example:
266 * \code
267 * KPlayer *MyGame::createPlayer(int rtti,int io,bool isvirtual)
268 * {
269 * KPlayer *player=new MyPlayer;
270 * if (!isvirtual) // network player ?
271 * {
272 * // Define something like this to add the IO modules
273 * createIO(player,(KGameIO::IOMode)io);
274 * }
275 * return player;
276 * }
277 * \endcode
278 *
279 * @param rtti is the type of the player (0 means default KPlayer)
280 * @param io is the 'or'ed rtti of the KGameIO's
281 * @param isvirtual true if player is virtual
282 */
283 virtual KPlayer *createPlayer(int rtti, int io, bool isvirtual);
284
285 // load/save
286 /**
287 * Load a saved game, from file OR network. This function has
288 * to be overwritten or you need to connect to the load signal
289 * if you have game data other than KGameProperty.
290 * For file load you should reset() the game before any load attempt
291 * to make sure you load into an clear state.
292 *
293 * @param stream a data stream where you can stream the game from
294 * @param reset - shall the game be reset before loading
295 *
296 * @return true?
297 */
298 virtual bool load(QDataStream &stream, bool reset = true);
299
300 /**
301 * Same as above function but with different parameters
302 *
303 * @param filename - the filename of the file to be opened
304 * @param reset - shall the game be reset before loading
305 *
306 * @return true?
307 */
308 virtual bool load(const QString &filename, bool reset = true);
309
310 /**
311 * Save a game to a file OR to network. Otherwise the same as
312 * the load function
313 *
314 * @param stream a data stream to load the game from
315 * @param saveplayers If true then all players wil be saved too
316 *
317 * @return true?
318 */
319 virtual bool save(QDataStream &stream, bool saveplayers = true);
320
321 /**
322 * Same as above function but with different parameters
323 *
324 * @param filename the filename of the file to be saved
325 * @param saveplayers If true then all players wil be saved too
326 *
327 * @return true?
328 */
329 virtual bool save(const QString &filename, bool saveplayers = true);
330
331 /**
332 * Resets the game, i.e. puts it into a state where everything
333 * can be started from, e.g. a load game
334 * Right now it does only need to delete all players
335 *
336 * @return true on success
337 */
338 virtual bool reset();
339
340 // Game sequence
341 /**
342 * returns the game status, ie running,pause,ended,...
343 *
344 * @return game status
345 */
346 int gameStatus() const;
347
348 /**
349 * sets the game status
350 *
351 * @param status the new status
352 */
353 void setGameStatus(int status);
354
355 /**
356 * docu: see KPlayer
357 */
358 bool addProperty(KGamePropertyBase *data);
359
360 /**
361 * This is called by KPlayer::sendProperty only! Internal function!
362 */
363 bool sendPlayerProperty(int msgid, QDataStream &s, quint32 playerId);
364
365 /**
366 * This function allows to find the pointer to a player
367 * property when you know its id
368 */
369 KGamePropertyBase *findProperty(int id) const;
370
371 /**
372 * Changes the consistency policy of a property. The
373 * GamePolicy is one of PolicyClean (default), PolicyDirty or PolicyLocal.
374 *
375 * It is up to you to decide how you want to work.
376 */
377 void setPolicy(GamePolicy p, bool recursive = true);
378
379 /**
380 * @return The default policy of the property
381 */
382 GamePolicy policy() const;
383
384 /**
385 * See KGameNetwork::sendMessage
386 *
387 * Send a network message msg with a given message ID msgid to all players of
388 * a given group (see KPlayer::group)
389 * @param msg the message which will be send. See messages.txt for contents
390 * @param msgid an id for this message
391 * @param sender the id of the sender
392 * @param group the group of the receivers
393 * @return true if worked
394 */
395 bool sendGroupMessage(const QByteArray &msg, int msgid, quint32 sender, const QString &group);
396 bool sendGroupMessage(const QDataStream &msg, int msgid, quint32 sender, const QString &group);
397 bool sendGroupMessage(int msg, int msgid, quint32 sender, const QString &group);
398 bool sendGroupMessage(const QString &msg, int msgid, quint32 sender, const QString &group);
399
400 /**
401 * This will either forward an incoming message to a specified player
402 * (see KPlayer::networkTransmission) or
403 * handle the message directly (e.g. if msgif==IdRemovePlayer it will remove
404 * the (in the stream) specified player). If both is not possible (i.e. the
405 * message is user specified data) the signal signalNetworkData is
406 * emitted.
407 *
408 * This emits signalMessageUpdate <em>before</em> doing anything with
409 * the message. You can use this signal when you want to be notified about
410 * an update/change.
411 * @param msgid Specifies the kind of the message. See messages.txt for
412 * further information
413 * @param stream The message that is being sent
414 * @param receiver The is of the player this message is for. 0 For broadcast.
415 * @param sender
416 * @param clientID the client from which we received the transmission - hardly used
417 */
418 void networkTransmission(QDataStream &stream, int msgid, quint32 receiver, quint32 sender, quint32 clientID) override;
419
420 /**
421 * Returns a pointer to the KGame property handler
422 */
423 KGamePropertyHandler *dataHandler() const;
424
425protected Q_SLOTS:
426 /**
427 * Called by KGamePropertyHandler only! Internal function!
428 */
429 void sendProperty(int msgid, QDataStream &stream, bool *sent);
430
431 /**
432 * Called by KGamePropertyHandler only! Internal function!
433 */
434 void emitSignal(KGamePropertyBase *me);
435
436 /**
437 * Calls negotiateNetworkGame()
438 * See KGameNetwork::signalClientConnected
439 */
440 void slotClientConnected(quint32 clientId);
441
442 /**
443 * This slot is called whenever the connection to a client is lost (ie the
444 * signal KGameNetwork::signalClientDisconnected is emitted) and will remove
445 * the players from that client.
446 * @param clientId The client the connection has been lost to
447 * @param broken (ignore this - not used)
448 */
449 void slotClientDisconnected(quint32 clientId, bool broken);
450
451 /**
452 * This slot is called whenever the connection to the server is lost (ie the
453 * signal KGameNetwork::signalConnectionBroken is emitted) and will
454 * switch to local game mode
455 */
456 void slotServerDisconnected();
457
459 /**
460 * When a client disconnects from the game usually all players from that
461 * client are removed. But if you use completely the KGame structure you
462 * probably don't want this. You just want to replace the KGameIO of the
463 * (human) player by a computer KGameIO. So this player continues game but
464 * is from this point on controlled by the computer.
465 *
466 * You achieve this by connecting to this signal. It is emitted as soon as a
467 * client disconnects on <em>all</em> other clients. Make sure to add a new
468 * KGameIO only once! you might want to use @ref isAdmin for this. If you
469 * added a new KGameIO set *remove=false otherwise the player is completely
470 * removed.
471 * @param player The player that is about to be removed. Add your new
472 * KGameIO here - but only on <em>one</em> client!
473 * @param remove Set this to FALSE if you don't want this player to be
474 * removed completely.
475 */
476 void signalReplacePlayerIO(KPlayer *player, bool *remove);
477
478 /**
479 * The game will be loaded from the given stream. Load from here
480 * the data which is NOT a game or player property.
481 * It is not necessary to use this signal for a full property game.
482 *
483 * This signal is emitted <em>before</em> the players are loaded by
484 * KGame. See also signalLoad
485 *
486 * You must load <em>exactly</em> the same data from the stream that you have saved
487 * in signalSavePrePlayers. Otherwise player loading will not work
488 * anymore.
489 *
490 * @param stream the load stream
491 */
493
494 /**
495 * The game will be loaded from the given stream. Load from here
496 * the data which is NOT a game or player property.
497 * It is not necessary to use this signal for a full property game.
498 *
499 * @param stream the load stream
500 */
501 void signalLoad(QDataStream &stream);
502
503 /**
504 * The game will be saved to the given stream. Fill this with data
505 * which is NOT a game or player property.
506 * It is not necessary to use this signal for a full property game.
507 *
508 * This signal is emitted <em>before</em> the players are saved by
509 * KGame. See also signalSave
510 *
511 * If you can choose between signalSavePrePlayers and signalSave then
512 * better use signalSave
513 *
514 * @param stream the save stream
515 */
517
518 /**
519 * The game will be saved to the given stream. Fill this with data
520 * which is NOT a game or player property.
521 * It is not necessary to use this signal for a full property game.
522 *
523 * @param stream the save stream
524 */
525 void signalSave(QDataStream &stream);
526
527 /**
528 * Is emitted if a game with a different version cookie is loaded.
529 * Normally this should result in an error. But maybe you do support
530 * loading of older game versions. Here would be a good place to do a
531 * conversion.
532 *
533 * @param stream - the load stream
534 * @param network - true if this is a network connect. False for load game
535 * @param cookie - the saved cookie. It differs from KGame::cookie()
536 * @param result - set this to true if you managed to load the game
537 */
538 void signalLoadError(QDataStream &stream, bool network, int cookie, bool &result);
539
540 /**
541 * We got an user defined update message. This is usually done
542 * by a sendData in a inherited KGame Object which defines its
543 * own methods and has to synchronize them over the network.
544 * Reaction to this is usually a call to a KGame function.
545 */
546 void signalNetworkData(int msgid, const QByteArray &buffer, quint32 receiver, quint32 sender);
547
548 /**
549 * We got an network message. this can be used to notify us that something
550 * changed. What changed can be seen in the message id. Whether this is
551 * the best possible method to do this is unclear...
552 */
553 void signalMessageUpdate(int msgid, quint32 receiver, quint32 sender);
554
555 /**
556 * a player left the game because of a broken connection or so!
557 *
558 * Note that when this signal is emitted the player is not part of @ref
559 * playerList anymore but the pointer is still valid. You should do some
560 * final cleanups here since the player is usually deleted after the signal
561 * is emitted.
562 *
563 * @param player the player who left the game
564 */
566
567 /**
568 * a player joined the game
569 *
570 * @param player the player who joined the game
571 */
573
574 /**
575 * This signal is emitted if a player property changes its value and
576 * the property is set to notify this change
577 */
579
580 /**
581 * Is emitted after a call to gameOver() returns a non zero
582 * return code. This code is forwarded to this signal as 'status'.
583 *
584 * @param status the return code of gameOver()
585 * @param current the player who did the last move
586 * @param me a pointer to the KGame object
587 */
588 void signalGameOver(int status, KPlayer *current, KGame *me);
589
590 /**
591 * Is emitted after a client is successfully connected to the game.
592 * The client id is the id of the new game client. An easy way to
593 * check whether that's us is
594 * \code
595 * if (clientid==gameid()) .. // we joined
596 * else ... // someone joined the game
597 * \endcode
598 * @param clientid - The id of the new client
599 * @param me - our game pointer
600 */
601 void signalClientJoinedGame(quint32 clientid, KGame *me);
602
603 /**
604 * This signal is emitted after a network partner left the
605 * game (either by a broken connection or voluntarily).
606 * All changes to the network players have already be done.
607 * If there are not enough players left, the game might have
608 * been paused. To check this you get the old gamestatus
609 * before the disconnection as argument here. The id of the
610 * client who left the game allows to distinguish who left the
611 * game. If it is 0, the server disconnected and you were a client
612 * which has been switched back to local play.
613 * You can use this signal to, e.g. set some menus back to local
614 * player when they were network before.
615 *
616 * @param clientID - 0:server left, otherwise the client who left
617 * @param oldgamestatus - the gamestatus before the loss
618 * @param me - our game pointer
619 */
620 void signalClientLeftGame(int clientID, int oldgamestatus, KGame *me);
621
622protected:
623 /**
624 * A player input occurred. This is the most important function
625 * as the given message will contain the current move made by
626 * the given player.
627 * Note that you HAVE to overwrite this function. Otherwise your
628 * game makes no sense at all.
629 * Generally you have to return TRUE in this function. Only then
630 * the game sequence is proceeded by calling @ref playerInputFinished
631 * which in turn will check for game over or the next player
632 * However, if you have a delayed move, because you e.g. move a
633 * card or a piece you want to return FALSE to pause the game sequence
634 * and then manually call @ref playerInputFinished to resume it.
635 * Example:
636 * \code
637 * bool MyClass::playerInput(QDataStream &msg,KPlayer *player)
638 * {
639 * qint32 move;
640 * msg >> move;
641 * qDebug() << " Player" << player->id() << "moved to" << move;
642 * return true;
643 * }
644 * \endcode
645 *
646 * @param msg the move message
647 * @param player the player who did the move
648 * @return true - input ready, false: input manual
649 */
650 virtual bool playerInput(QDataStream &msg, KPlayer *player) = 0;
651
652 /**
653 * Called after the player input is processed by the game. Here the
654 * checks for game over and nextPlayer (in the case of turn base games)
655 * are processed.
656 * Call this manually if you have a delayed move, i.e. your playerInput
657 * function returns FALSE. If it returns true you need not do anything
658 * here.
659 *
660 * @return the current player
661 *
662 */
663 KPlayer *playerInputFinished(KPlayer *player);
664
665 /**
666 * This virtual function can be overwritten for your own player management.
667 * It is called when a new game connects to an existing network game or
668 * to the network master. In case you do not want all players of both games
669 * to be present in the new network game, you can deactivate players here.
670 * This is of particular importance if you have a game with fixed number of
671 * player like e.g. chess. A network connect needs to disable one player of
672 * each game to make sense.
673 *
674 * Not overwriting this function will activate a default behaviour which
675 * will deactivate players until the @ref maxPlayers() number is reached
676 * according to the KPlayer::networkPriority() value. Players with a low
677 * value will be kicked out first. With equal priority players of the new
678 * client will leave first. This means, not setting this value and not
679 * overwriting this function will never allow a chess game to add client
680 * players!!!
681 * On the other hand setting one player of each game to a networkPriorty of
682 * say 10, already does most of the work for you.
683 *
684 * The parameters of this function are the playerlist of the network game,
685 * which is @ref playerList(). The second argument is the player list of
686 * the new client who wants to join and the third argument serves as return
687 * parameter. All <em>player ID's</em> which are written into this list
688 * will be <em>removed</em> from the created game. You do this by an
689 * \code
690 * inactivate.append(player->id());
691 * \endcode
692 *
693 * @param oldplayer - the list of the network players
694 * @param newplayer - the list of the client players
695 * @param inactivate - the value list of ids to be deactivated
696 *
697 */
698 virtual void newPlayersJoin(KGamePlayerList *oldplayer, KGamePlayerList *newplayer, QList<int> &inactivate)
699 {
700 Q_UNUSED(oldplayer);
701 Q_UNUSED(newplayer);
702 Q_UNUSED(inactivate);
703 }
704
705 /**
706 * Save the player list to a stream. Used for network game and load/save.
707 * Can be overwritten if you know what you are doing
708 *
709 * @param stream is the stream to save the player ot
710 * @param list the optional list is the player list to be saved, default is playerList()
711 *
712 */
713 void savePlayers(QDataStream &stream, KGamePlayerList *list = nullptr);
714
715 /**
716 * Prepare a player for being added. Put all data about a player into the
717 * stream so that it can be sent to the KGameCommunicationServer using
718 * addPlayer (e.g.)
719 *
720 * This function ensures that the code for adding a player is the same in
721 * addPlayer as well as in negotiateNetworkGame
722 * @param stream is the stream to add the player
723 * @param player The player to add
724 */
725 void savePlayer(QDataStream &stream, KPlayer *player);
726
727 /**
728 * Load the player list from a stream. Used for network game and load/save.
729 * Can be overwritten if you know what you are doing
730 *
731 * @param stream is the stream to save the player to
732 * @param isvirtual will set the virtual flag true/false
733 *
734 */
735 KPlayer *loadPlayer(QDataStream &stream, bool isvirtual = false);
736
737 /**
738 * inactivates player. Use @ref inactivatePlayer instead!
739 */
740 bool systemInactivatePlayer(KPlayer *player);
741
742 /**
743 * activates player. Use @ref activatePlayer instead!
744 */
745 bool systemActivatePlayer(KPlayer *player);
746
747 /**
748 * Adds a player to the game
749 *
750 * Use @ref addPlayer to send @ref KGameMessage::IdAddPlayer. As soon as
751 * this Id is received this function is called, where the player (see @ref
752 * KPlayer::rtti) is added as well as its properties (see @ref KPlayer::save
753 * and @ref KPlayer::load)
754 *
755 * This method calls the overloaded @ref systemAddPlayer with the created
756 * player as argument. That method will really add the player.
757 * If you need to do some changes to your newly added player just connect to
758 * @ref signalPlayerJoinedGame
759 */
760
761 /**
762 * Finally adds a player to the game and therefore to the list.
763 */
764 bool systemAddPlayer(KPlayer *newplayer);
765
766 /**
767 * Removes a player from the game
768 *
769 * Use removePlayer to send KGameMessage::IdRemovePlayer. As soon
770 * as this Id is received systemRemovePlayer is called and the player is
771 * removed directly.
772 */
773 void systemRemovePlayer(KPlayer *player, bool deleteit);
774
775 /**
776 * This member function will transmit e.g. all players to that client, as well as
777 * all properties of these players (at least if they have been added by
778 * @ref KPlayer::addProperty) so that the client will finally have the same
779 * status as the master. You want to overwrite this function if you expand
780 * KGame by any properties which have to be known by all clients.
781 *
782 * Only the ADMIN is allowed to call this.
783 * @param clientID The ID of the message client which has connected
784 */
785 virtual void negotiateNetworkGame(quint32 clientID);
786
787 void deletePlayers();
788 void deleteInactivePlayers();
789
790 /**
791 * Load a saved game, from file OR network. Internal.
792 * Warning: loadgame must not rely that all players all already
793 * activated. Actually the network will activate a player AFTER
794 * the loadgame only. This is not true anymore. But be careful
795 * anyway.
796 *
797 * @param stream a data stream where you can stream the game from
798 * @param network is it a network call -> make players virtual
799 * @param reset shall the game be reset before loading
800 *
801 * @return true?
802 */
803 virtual bool loadgame(QDataStream &stream, bool network, bool reset);
804
805 /**
806 * Save a game, to file OR network. Internal.
807 *
808 * @param stream a data stream where you can stream the game from
809 * @param network is it a call from the network or from a file (unused but informative)
810 * @param saveplayers shall the players be saved too (should be TRUE)
811 *
812 * @return true?
813 */
814 virtual bool savegame(QDataStream &stream, bool network, bool saveplayers);
815
816private:
817 // AB: this is to hide the "receiver" parameter from the user. It shouldn't be
818 // used if possible (except for init).
819 /**
820 * This is an overloaded function. Id differs from the public one only in
821 * its parameters:
822 *
823 * @param receiver The Client that will receive the message. You will hardly
824 * ever need this. It it internally used to initialize a newly connected
825 * client.
826 */
827 // void addPlayer(KPlayer* newplayer, quint32 receiver);
828
829 /**
830 * Just the same as the public one except receiver:
831 * @param receiver 0 for broadcast, otherwise the receiver. Should only be
832 * used in special circumstances and not outside KGame.
833 */
834 bool removePlayer(KPlayer *player, quint32 receiver);
835
836 /**
837 * Helping function - game negotiation
838 */
839 void setupGame(quint32 sender);
840
841 /**
842 * Helping function - game negotiation
843 */
844 void setupGameContinue(QDataStream &msg, quint32 sender);
845
846 /**
847 * Removes a player from all lists, removes the @ref KGame pointer from the
848 * @ref KPlayer and deletes the player. Used by (e.g.) @ref
849 * systemRemovePlayer
850 * @return True if the player has been removed, false if the current is not
851 * found
852 */
853 bool systemRemove(KPlayer *player, bool deleteit);
854
855private:
856 KGamePrivate *const d;
857};
858
859#endif
The KGameNetwork class is the KGame class with network support.
virtual void networkTransmission(QDataStream &, int, quint32, quint32, quint32 clientID)=0
Called by ReceiveNetworkTransmission().
virtual void Debug()
Gives debug output of the game status.
Base class of KGameProperty.
A collection class for KGameProperty objects.
This class takes care of round or move management as well of the gameover condition.
The main KDE game object.
Definition kgame.h:47
void signalSavePrePlayers(QDataStream &stream)
The game will be saved to the given stream.
virtual void newPlayersJoin(KGamePlayerList *oldplayer, KGamePlayerList *newplayer, QList< int > &inactivate)
This virtual function can be overwritten for your own player management.
Definition kgame.h:698
void signalMessageUpdate(int msgid, quint32 receiver, quint32 sender)
We got an network message.
bool removePlayer(KPlayer *player)
Sends a message over the network, msgid=IdRemovePlayer.
Definition kgame.h:183
void signalSave(QDataStream &stream)
The game will be saved to the given stream.
void signalPropertyChanged(KGamePropertyBase *property, KGame *me)
This signal is emitted if a player property changes its value and the property is set to notify this ...
void signalReplacePlayerIO(KPlayer *player, bool *remove)
When a client disconnects from the game usually all players from that client are removed.
void signalNetworkData(int msgid, const QByteArray &buffer, quint32 receiver, quint32 sender)
We got an user defined update message.
void signalGameOver(int status, KPlayer *current, KGame *me)
Is emitted after a call to gameOver() returns a non zero return code.
void signalPlayerJoinedGame(KPlayer *player)
a player joined the game
void signalLoadError(QDataStream &stream, bool network, int cookie, bool &result)
Is emitted if a game with a different version cookie is loaded.
GameStatus
Game status - Use this to Control the game flow.
Definition kgame.h:98
GamePolicy
The policy of the property.
Definition kgame.h:74
void signalPlayerLeftGame(KPlayer *player)
a player left the game because of a broken connection or so!
void signalClientLeftGame(int clientID, int oldgamestatus, KGame *me)
This signal is emitted after a network partner left the game (either by a broken connection or volunt...
void signalLoadPrePlayers(QDataStream &stream)
The game will be loaded from the given stream.
void signalLoad(QDataStream &stream)
The game will be loaded from the given stream.
void signalClientJoinedGame(quint32 clientid, KGame *me)
Is emitted after a client is successfully connected to the game.
virtual bool playerInput(QDataStream &msg, KPlayer *player)=0
A player input occurred.
Base class for a game player.
Definition kplayer.h:60
Q_SCRIPTABLE CaptureState status()
Q_SIGNALSQ_SIGNALS
Q_SLOTSQ_SLOTS
T qobject_cast(QObject *object)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sun Feb 25 2024 18:43:15 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.