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