diff options
Diffstat (limited to 'libkdegames/kgame/kgame.h')
-rw-r--r-- | libkdegames/kgame/kgame.h | 932 |
1 files changed, 932 insertions, 0 deletions
diff --git a/libkdegames/kgame/kgame.h b/libkdegames/kgame/kgame.h new file mode 100644 index 00000000..37d8d974 --- /dev/null +++ b/libkdegames/kgame/kgame.h @@ -0,0 +1,932 @@ +/* + This file is part of the KDE games library + Copyright (C) 2001 Martin Heni ([email protected]) + Copyright (C) 2001 Andreas Beckermann ([email protected]) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ +/* + $Id$ +*/ +#ifndef __KGAME_H_ +#define __KGAME_H_ + +#include <qstring.h> +#include <qptrlist.h> +#include <qvaluelist.h> + +#include "kgamenetwork.h" +#include <kdemacros.h> +class KRandomSequence; + +class KPlayer; +class KGamePropertyBase; +class KGamePropertyHandler; +class KGameSequence; + +class KGamePrivate; + +/** + * @short The main KDE game object + * + * The KGame class is the central game object. A game basically + * consists of following features: + * - Player handling (add, remove,...) + * - Game status (end,start,pause,...) + * - load/save + * - Move (and message) handling + * - nextPlayer and gameOver() + * - Network connection (for KGameNetwork) + * + * Example: + * \code + * KGame *game=new KGame; + * \endcode + * + * + * @author Martin Heni <[email protected]> + * + */ +class KDE_EXPORT KGame : public KGameNetwork +{ + Q_OBJECT + +public: + typedef QPtrList<KPlayer> KGamePlayerList; + + /** + * The policy of the property. This can be PolicyClean (setVale uses + * send), PolicyDirty (setValue uses changeValue) or + * PolicyLocal (setValue uses setLocal). + * + * A "clean" policy means that the property is always the same on every + * client. This is achieved by calling send which actually changes + * the value only when the message from the MessageServer is received. + * + * A "dirty" policy means that as soon as setValue is called the + * property is changed immediately. And additionally sent over network. + * This can sometimes lead to bugs as the other clients do not + * immediately have the same value. For more information see + * changeValue. + * + * PolicyLocal means that a KGameProperty behaves like ever + * "normal" variable. Whenever setValue is called (e.g. using "=") + * the value of the property is changes immediately without sending it + * over network. You might want to use this if you are sure that all + * clients set the property at the same time. + **/ + enum GamePolicy + { + PolicyUndefined = 0, + PolicyClean = 1, + PolicyDirty = 2, + PolicyLocal = 3 + }; + + /** + * Create a KGame object. The cookie is used to identify your + * game in load/save and network operations. Change this between + * games. + */ + KGame(int cookie=42,QObject* parent=0); + + /** + * Destructs the game + */ + virtual ~KGame(); + + /** + * Gives debug output of the game status + */ + virtual void Debug(); + + /** + * Game status - Use this to Control the game flow. + * The KGame e.g. sets the status to Pause when you have + * less player than the minimum amount + */ + enum GameStatus + { + Init = 0, + Run = 1, + Pause = 2, + End = 3, + Abort = 4, + SystemPause = 5, + Intro = 6, + UserStatus = 7 + }; + + // Properties + /** + * Returns a list of all active players + * + * @return the list of players + */ + KGamePlayerList *playerList(); + + /** + * The same as @ref playerList but returns a const pointer. + **/ + const KGamePlayerList *playerList() const; + + /** + * Returns a list of all inactive players + * @return the list of players + */ + KGamePlayerList *inactivePlayerList(); + + /** + * The same as @ref inactivePlayerList but returns a const pointer. + **/ + const KGamePlayerList *inactivePlayerList() const; + + /** + * Returns a pointer to the game's KRandomSequence. This sequence is + * identical for all network players! + * @return KRandomSequence pointer + */ + KRandomSequence *random() const; + + /** + * @return The KGameSequence object that is currently in use. + * @see setGameSequence + **/ + KGameSequence *gameSequence() const; + + /** + * Is the game running + * @return true/false + */ + bool isRunning() const; + + // Player handling + /** + * Returns the player object for a given player id + * @param id Player id + * @return player object + */ + KPlayer *findPlayer(Q_UINT32 id) const; + + /** + * Set a new @ref KGameSequence to control player management. By default + * KGame uses a normal @ref KGameSequence object. You might want to subclass + * that and provide your own object. + * + * The previous sequence will get deleted. + * @param sequence The new game sequence object. KGame takes ownership and + * will delete it on destruction! + **/ + void setGameSequence(KGameSequence* sequence); + + /** + * Note that KPlayer::save must be implemented properly, as well as + * KPlayer::rtti + * This will only send a message to all clients. The player is _not_ added + * directly! + * See also playerInput which will be called as soon as the + * player really has been added. + * + * Note that an added player will first get into a "queue" and won't be in + * the game. It will be added to the game as soon as systemAddPlayer is + * called what will happen as soon as IdAddPlayer is received. + * + * Note: you probably want to connect to signalPlayerJoinedGame for + * further initialization! + * @param newplayer The player you want to add. KGame will send a message to + * all clients and add the player using systemAddPlayer + **/ + void addPlayer(KPlayer* newplayer); + + /** + * Sends a message over the network, msgid=IdRemovePlayer. + * + * As soon as this message is received by networkTransmission + * systemRemovePlayer is called and the player is removed. + **/ + //AB: TODO: make sendMessage to return if the message will be able to be + //sent, eg if a socket is connected, etc. If sendMessage returns false + //remove the player directly using systemRemovePlayer + bool removePlayer(KPlayer * player) { return removePlayer(player, 0); } + + /** + * Called by the destructor of KPlayer to remove itself from the game + * + **/ + void playerDeleted(KPlayer * player); + + /** + * sends activate player: internal use only? + */ + bool activatePlayer(KPlayer *player); + + /** + * sends inactivate player: internal use only? + */ + bool inactivatePlayer(KPlayer *player); + + /** + * Set the maximal number of players. After this is + * reached no more players can be added. You must be ADMIN to call this (@see + * isAdmin). + * @param maxnumber maximal number of players + */ + void setMaxPlayers(uint maxnumber); + + /** + * What is the maximal number of players? + * @return maximal number of players + */ + int maxPlayers() const; + + /** + * Set the minimal number of players. A game can not be started + * with less player resp. is paused when already running. You must be ADMIN + * to call this (see @ref isAdmin)! + * @param minnumber minimal number of players + */ + void setMinPlayers(uint minnumber); + + /** + * What is the minimal number of players? + * @return minimal number of players + */ + uint minPlayers() const; + + /** + * Returns how many players are plugged into the game + * @return number of players + */ + uint playerCount() const; + + /** + * @deprecated + * Use @ref KGameSequence::nextPlayer instead + **/ + virtual KPlayer * nextPlayer(KPlayer *last,bool exclusive=true); + + // Input events + /** + * Called by KPlayer to send a player input to the + * KMessageServer. + **/ + virtual bool sendPlayerInput(QDataStream &msg,KPlayer *player,Q_UINT32 sender=0); + + /** + * Called when a player input arrives from KMessageServer. + * + * Calls prepareNext (using QTimer::singleShot) if gameOver() + * returns 0. This function should normally not be used outside KGame. + * It could be made non-virtual,protected in a later version. At the + * moment it is a virtual function to give you more control over KGame. + * + * For documentation see playerInput. + **/ + virtual bool systemPlayerInput(QDataStream &msg,KPlayer *player,Q_UINT32 sender=0); + + /** + * This virtual function is called if the KGame needs to create a new player. + * This happens only over a network and with load/save. Doing nothing + * will create a default KPlayer. If you want to have your own player + * you have to create one with the given rtti here. + * Note: If your game uses a player class derived from KPlayer you MUST + * override this function and create your player here. Otherwise the + * game will crash. + * Example: + * \code + * KPlayer *MyGame::createPlayer(int rtti,int io,bool isvirtual) + * { + * KPlayer *player=new MyPlayer; + * if (!isvirtual) // network player ? + * { + * // Define something like this to add the IO modules + * createIO(player,(KGameIO::IOMode)io); + * } + * return player; + * } + * \endcode + * + * @param rtti is the type of the player (0 means default KPlayer) + * @param io is the 'or'ed rtti of the KGameIO's + * @param isvirtual true if player is virtual + */ + virtual KPlayer *createPlayer(int rtti,int io,bool isvirtual); + + // load/save + /** + * Load a saved game, from file OR network. This function has + * to be overwritten or you need to connect to the load signal + * if you have game data other than KGameProperty. + * For file load you should reset() the game before any load attempt + * to make sure you load into an clear state. + * + * @param stream a data stream where you can stream the game from + * @param reset - shall the game be reset before loading + * + * @return true? + */ + virtual bool load(QDataStream &stream,bool reset=true); + + /** + * Same as above function but with different parameters + * + * @param filename - the filename of the file to be opened + * @param reset - shall the game be reset before loading + * + * @return true? + **/ + virtual bool load(QString filename,bool reset=true); + + /** + * Save a game to a file OR to network. Otherwise the same as + * the load function + * + * @param stream a data stream to load the game from + * @param saveplayers If true then all players wil be saved too + * + * @return true? + */ + virtual bool save(QDataStream &stream,bool saveplayers=true); + + /** + * Same as above function but with different parameters + * + * @param filename the filename of the file to be saved + * @param saveplayers If true then all players wil be saved too + * + * @return true? + **/ + virtual bool save(QString filename,bool saveplayers=true); + + /** + * Resets the game, i.e. puts it into a state where everything + * can be started from, e.g. a load game + * Right now it does only need to delete all players + * + * @return true on success + */ + virtual bool reset(); + + + // Game sequence + /** + * returns the game status, ie running,pause,ended,... + * + * @return game status + */ + int gameStatus() const; + + /** + * sets the game status + * + * @param status the new status + */ + void setGameStatus(int status); + + /** + * docu: see KPlayer + **/ + bool addProperty(KGamePropertyBase* data); + + /** + * This is called by KPlayer::sendProperty only! Internal function! + **/ + bool sendPlayerProperty(int msgid, QDataStream& s, Q_UINT32 playerId); + + /** + * This function allows to find the pointer to a player + * property when you know it's id + */ + KGamePropertyBase* findProperty(int id) const; + + /** + * Changes the consistency policy of a property. The + * GamePolicy is one of PolicyClean (default), PolicyDirty or PolicyLocal. + * + * It is up to you to decide how you want to work. + **/ + void setPolicy(GamePolicy p,bool recursive=true); + + /** + * @return The default policy of the property + **/ + GamePolicy policy() const; + + /** + * See KGameNetwork::sendMessage + * + * Send a network message msg with a given message ID msgid to all players of + * a given group (see KPlayer::group) + * @param msg the message which will be send. See messages.txt for contents + * @param msgid an id for this message + * @param sender the id of the sender + * @param group the group of the receivers + * @return true if worked + */ + bool sendGroupMessage(const QByteArray& msg, int msgid, Q_UINT32 sender, const QString& group); + bool sendGroupMessage(const QDataStream &msg, int msgid, Q_UINT32 sender, const QString& group); + bool sendGroupMessage(int msg, int msgid, Q_UINT32 sender, const QString& group); + bool sendGroupMessage(const QString& msg, int msgid, Q_UINT32 sender, const QString& group); + + /** + * This will either forward an incoming message to a specified player + * (see KPlayer::networkTransmission) or + * handle the message directly (e.g. if msgif==IdRemovePlayer it will remove + * the (in the stream) specified player). If both is not possible (i.e. the + * message is user specified data) the signal signalNetworkData is + * emitted. + * + * This emits signalMessageUpdate <em>before</em> doing anything with + * the message. You can use this signal when you want to be notified about + * an update/change. + * @param msgid Specifies the kind of the message. See messages.txt for + * further information + * @param stream The message that is being sent + * @param receiver The is of the player this message is for. 0 For broadcast. + * @param sender + * @param clientID the client from which we received the transmission - hardly used + **/ + virtual void networkTransmission(QDataStream &stream, int msgid, Q_UINT32 receiver, Q_UINT32 sender, Q_UINT32 clientID); + + /** + * Returns a pointer to the KGame property handler + **/ + KGamePropertyHandler* dataHandler() const; + +protected slots: + /** + * Called by KGamePropertyHandler only! Internal function! + **/ + void sendProperty(int msgid, QDataStream& stream, bool* sent); + + /** + * Called by KGamePropertyHandler only! Internal function! + **/ + void emitSignal(KGamePropertyBase *me); + + /** + * @deprecated + * Use KGameSequence::prepareNext() instead + **/ + virtual void prepareNext(); + + + /** + * Calls negotiateNetworkGame() + * See KGameNetwork::signalClientConnected + **/ + void slotClientConnected(Q_UINT32 clientId); + + /** + * This slot is called whenever the connection to a client is lost (ie the + * signal KGameNetwork::signalClientDisconnected is emitted) and will remove + * the players from that client. + * @param clientId The client the connection has been lost to + * @param broken (ignore this - not used) + **/ + void slotClientDisconnected(Q_UINT32 clientId,bool broken); + + /** + * This slot is called whenever the connection to the server is lost (ie the + * signal KGameNetwork::signalConnectionBroken is emitted) and will + * switch to local game mode + **/ + void slotServerDisconnected(); + +signals: + /** + * When a client disconnects from the game usually all players from that + * client are removed. But if you use completely the KGame structure you + * probably don't want this. You just want to replace the KGameIO of the + * (human) player by a computer KGameIO. So this player continues game but + * is from this point on controlled by the computer. + * + * You achieve this by connecting to this signal. It is emitted as soon as a + * client disconnects on <em>all</em> other clients. Make sure to add a new + * KGameIO only once! you might want to use @ref isAdmin for this. If you + * added a new KGameIO set *remove=false otherwise the player is completely + * removed. + * @param player The player that is about to be removed. Add your new + * KGameIO here - but only on <em>one</em> client! + * @param remove Set this to FALSE if you don't want this player to be + * removed completely. + **/ + void signalReplacePlayerIO(KPlayer* player, bool* remove); + + /** + * The game will be loaded from the given stream. Load from here + * the data which is NOT a game or player property. + * It is not necessary to use this signal for a full property game. + * + * This signal is emitted <em>before</em> the players are loaded by + * KGame. See also signalLoad + * + * You must load <em>exactly</em> the same data from the stream that you have saved + * in signalSavePrePlayers. Otherwise player loading will not work + * anymore. + * + * @param stream the load stream + */ + void signalLoadPrePlayers(QDataStream &stream); + + /** + * The game will be loaded from the given stream. Load from here + * the data which is NOT a game or player property. + * It is not necessary to use this signal for a full property game. + * + * @param stream the load stream + */ + void signalLoad(QDataStream &stream); + + /** + * The game will be saved to the given stream. Fill this with data + * which is NOT a game or player property. + * It is not necessary to use this signal for a full property game. + * + * This signal is emitted <em>before</em> the players are saved by + * KGame. See also signalSave + * + * If you can choose between signalSavePrePlayers and signalSave then + * better use signalSave + * + * @param stream the save stream + **/ + void signalSavePrePlayers(QDataStream &stream); + + /** + * The game will be saved to the given stream. Fill this with data + * which is NOT a game or player property. + * It is not necessary to use this signal for a full property game. + * + * @param stream the save stream + */ + void signalSave(QDataStream &stream); + + /** + * Is emmited if a game with a different version cookie is loaded. + * Normally this should result in an error. But maybe you do support + * loading of older game versions. Here would be a good place to do a + * conversion. + * + * @param stream - the load stream + * @param network - true if this is a network connect. False for load game + * @param cookie - the saved cookie. It differs from KGame::cookie() + * @param result - set this to true if you managed to load the game + */ + void signalLoadError(QDataStream &stream,bool network,int cookie, bool &result); + + /** + * We got an user defined update message. This is usually done + * by a sendData in a inherited KGame Object which defines its + * own methods and has to syncronise them over the network. + * Reaction to this is usually a call to a KGame function. + */ + void signalNetworkData(int msgid,const QByteArray& buffer, Q_UINT32 receiver, Q_UINT32 sender); + + /** + * We got an network message. this can be used to notify us that something + * changed. What changed can be seen in the message id. Whether this is + * the best possible method to do this is unclear... + */ + void signalMessageUpdate(int msgid,Q_UINT32 receiver,Q_UINT32 sender); + + /** + * a player left the game because of a broken connection or so! + * + * Note that when this signal is emitted the player is not part of @ref + * playerList anymore but the pointer is still valid. You should do some + * final cleanups here since the player is usually deleted after the signal + * is emitted. + * + * @param player the player who left the game + */ + void signalPlayerLeftGame(KPlayer *player); + + /** + * a player joined the game + * + * @param player the player who joined the game + */ + void signalPlayerJoinedGame(KPlayer *player); + + + /** + * This signal is emmited if a player property changes its value and + * the property is set to notify this change + */ + void signalPropertyChanged(KGamePropertyBase *property, KGame *me); + + /** + * Is emitted after a call to gameOver() returns a non zero + * return code. This code is forwarded to this signal as 'status'. + * + * @param status the return code of gameOver() + * @param current the player who did the last move + * @param me a pointer to the KGame object + */ + void signalGameOver(int status, KPlayer *current, KGame *me); + + /** + * Is emmited after a client is successfully connected to the game. + * The client id is the id of the new game client. An easy way to + * check whether that's us is + * \code + * if (clientid==gameid()) .. // we joined + * else ... // someone joined the game + * \endcode + * @param clientid - The id of the new client + * @param me - our game pointer + */ + void signalClientJoinedGame(Q_UINT32 clientid,KGame *me); + + /** + * This signal is emitted after a network partner left the + * game (either by a broken connection or voluntarily). + * All changes to the network players have already be done. + * If there are not enough players left, the game might have + * been paused. To check this you get the old gamestatus + * before the disconnection as argument here. The id of the + * client who left the game allows to distinguish who left the + * game. If it is 0, the server disconnected and you were a client + * which has been switched back to local play. + * You can use this signal to, e.g. set some menues back to local + * player when they were network before. + * + * @param clientID - 0:server left, otherwise the client who left + * @param oldgamestatus - the gamestatus before the loss + * @param me - our game pointer + **/ + void signalClientLeftGame(int clientID,int oldgamestatus,KGame *me); + + +protected: + /** + * A player input occurred. This is the most important function + * as the given message will contain the current move made by + * the given player. + * Note that you HAVE to overwrite this function. Otherwise your + * game makes no sense at all. + * Generally you have to return TRUE in this function. Only then + * the game sequence is proceeded by calling @ref playerInputFinished + * which in turn will check for game over or the next player + * However, if you have a delayed move, because you e.g. move a + * card or a piece you want to return FALSE to pause the game sequence + * and then manually call @ref playerInputFinished to resume it. + * Example: + * \code + * bool MyClass::playerInput(QDataStream &msg,KPlayer *player) + * { + * Q_INT32 move; + * msg >> move; + * kdDebug() << " Player " << player->id() << " moved to " << move << + * endl; + * return true; + * } + * \endcode + * + * @param msg the move message + * @param player the player who did the move + * @return true - input ready, false: input manual + */ + virtual bool playerInput(QDataStream &msg,KPlayer *player)=0; + + + /** + * Called after the player input is processed by the game. Here the + * checks for game over and nextPlayer (in the case of turn base games) + * are processed. + * Call this manually if you have a delayed move, i.e. your playerInput + * function returns FALSE. If it returns true you need not do anything + * here. + * + * @return the current player + * + **/ + KPlayer *playerInputFinished(KPlayer *player); + + + /** + * This virtual function can be overwritten for your own player management. + * It is called when a new game connects to an existing network game or + * to the network master. In case you do not want all players of both games + * to be present in the new network game, you can deactivate players here. + * This is of particular importance if you have a game with fixed number of + * player like e.g. chess. A network connect needs to disable one player of + * each game to make sense. + * + * Not overwriting this function will activate a default behaviour which + * will deactivate players until the @ref maxPlayers() numebr is reached + * according to the KPlayer::networkPriority() value. Players with a low + * value will be kicked out first. With equal priority players of the new + * client will leave first. This means, not setting this value and not + * overwriting this function will never allow a chess game to add client + * players!!! + * On the other hand setting one player of each game to a networkPriorty of + * say 10, already does most of the work for you. + * + * The parameters of this function are the playerlist of the network game, + * which is @ref playerList(). The second argument is the player list of + * the new client who wants to join and the third argument serves as return + * parameter. All <em>player ID's</em> which are written into this list + * will be <em>removed</em> from the created game. You do this by an + * \code + * inactivate.append(player->id()); + * \endcode + * + * @param oldplayer - the list of the network players + * @param newplayer - the list of the client players + * @param inactivate - the value list of ids to be deactivated + * + **/ + virtual void newPlayersJoin(KGamePlayerList *oldplayer, + KGamePlayerList *newplayer, + QValueList<int> &inactivate) { + Q_UNUSED( oldplayer ); + Q_UNUSED( newplayer ); + Q_UNUSED( inactivate ); + } + + /** + * Save the player list to a stream. Used for network game and load/save. + * Can be overwritten if you know what you are doing + * + * @param stream is the stream to save the player ot + * @param list the optional list is the player list to be saved, default is playerList() + * + **/ + void savePlayers(QDataStream &stream,KGamePlayerList *list=0); + + /** + * Prepare a player for being added. Put all data about a player into the + * stream so that it can be sent to the KGameCommunicationServer using + * addPlayer (e.g.) + * + * This function ensures that the code for adding a player is the same in + * addPlayer as well as in negotiateNetworkGame + * @param stream is the stream to add the player + * @param player The player to add + **/ + void savePlayer(QDataStream& stream,KPlayer* player); + + /** + * Load the player list from a stream. Used for network game and load/save. + * Can be overwritten if you know what you are doing + * + * @param stream is the stream to save the player to + * @param isvirtual will set the virtual flag true/false + * + **/ + KPlayer *loadPlayer(QDataStream& stream,bool isvirtual=false); + + + /** + * inactivates player. Use @ref inactivatePlayer instead! + */ + bool systemInactivatePlayer(KPlayer *player); + + /** + * activates player. Use @ref activatePlayer instead! + */ + bool systemActivatePlayer(KPlayer *player); + + /** + * Adds a player to the game + * + * Use @ref addPlayer to send @ref KGameMessage::IdAddPlayer. As soon as + * this Id is received this function is called, where the player (see @ref + * KPlayer::rtti) is added as well as its properties (see @ref KPlayer::save + * and @ref KPlayer::load) + * + * This method calls the overloaded @ref systemAddPlayer with the created + * player as argument. That method will really add the player. + * If you need to do some changes to your newly added player just connect to + * @ref signalPlayerJoinedGame + */ + + /** + * Finally adds a player to the game and therefore to the list. + **/ + void systemAddPlayer(KPlayer* newplayer); + + /** + * Removes a player from the game + * + * Use removePlayer to send KGameMessage::IdRemovePlayer. As soon + * as this Id is received systemRemovePlayer is called and the player is + * removed directly. + **/ + void systemRemovePlayer(KPlayer* player,bool deleteit); + + /** + * This member function will transmit e.g. all players to that client, as well as + * all properties of these players (at least if they have been added by + * @ref KPlayer::addProperty) so that the client will finally have the same + * status as the master. You want to overwrite this function if you expand + * KGame by any properties which have to be known by all clients. + * + * Only the ADMIN is allowed to call this. + * @param clientID The ID of the message client which has connected + **/ + virtual void negotiateNetworkGame(Q_UINT32 clientID); + + /** + * syncronise the random numbers with all network clients + * not used by KGame - if it should be kept then as public method + */ + void syncRandom(); + + void deletePlayers(); + void deleteInactivePlayers(); + + /** + * @deprecated + * Use @ref KGameSequence instead. + * + * @param player the player who made the last move + * @return anything else but 0 is considered as game over + */ + virtual int checkGameOver(KPlayer *player); + + /** + * Load a saved game, from file OR network. Internal. + * Warning: loadgame must not rely that all players all already + * activated. Actually the network will activate a player AFTER + * the loadgame only. This is not true anymore. But be careful + * anyway. + * + * @param stream a data stream where you can stream the game from + * @param network is it a network call -> make players virtual + * @param reset shall the game be reset before loading + * + * @return true? + */ + virtual bool loadgame(QDataStream &stream, bool network, bool reset); + + /** + * Save a game, to file OR network. Internal. + * + * @param stream a data stream where you can stream the game from + * @param network is it a call from the network or from a file (unused but informative) + * @param saveplayers shall the players be saved too (should be TRUE) + * + * @return true? + */ + virtual bool savegame(QDataStream &stream, bool network,bool saveplayers); + +private: + //AB: this is to hide the "receiver" parameter from the user. It shouldn't be + //used if possible (except for init). + /** + * This is an overloaded function. Id differs from the public one only in + * its parameters: + * + * @param receiver The Client that will receive the message. You will hardly + * ever need this. It it internally used to initialize a newly connected + * client. + **/ + //void addPlayer(KPlayer* newplayer, Q_UINT32 receiver); + + /** + * Just the same as the public one except receiver: + * @param receiver 0 for broadcast, otherwise the receiver. Should only be + * used in special circumstances and not outside KGame. + **/ + bool removePlayer(KPlayer * player, Q_UINT32 receiver); + + /** + * Helping function - game negotiation + **/ + void setupGame(Q_UINT32 sender); + + /** + * Helping function - game negotiation + **/ + void setupGameContinue(QDataStream& msg, Q_UINT32 sender); + + /** + * Removes a player from all lists, removes the @ref KGame pointer from the + * @ref KPlayer and deletes the player. Used by (e.g.) @ref + * systemRemovePlayer + * @return True if the player has been removed, false if the current is not + * found + **/ + bool systemRemove(KPlayer* player,bool deleteit); + + +private: + KGamePrivate* d; +}; + +#endif |