From c90c389a8a8d9d8661e9772ec4144c5cf2039f23 Mon Sep 17 00:00:00 2001 From: toma Date: Wed, 25 Nov 2009 17:56:58 +0000 Subject: Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features. BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdegames@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- libkdegames/kgame/kgamenetwork.h | 431 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 431 insertions(+) create mode 100644 libkdegames/kgame/kgamenetwork.h (limited to 'libkdegames/kgame/kgamenetwork.h') diff --git a/libkdegames/kgame/kgamenetwork.h b/libkdegames/kgame/kgamenetwork.h new file mode 100644 index 00000000..6ff5cf94 --- /dev/null +++ b/libkdegames/kgame/kgamenetwork.h @@ -0,0 +1,431 @@ +/* + This file is part of the KDE games library + Copyright (C) 2001 Martin Heni (martin@heni-online.de) + Copyright (C) 2001 Andreas Beckermann (b_mann@gmx.de) + + 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 __KGAMENETWORK_H_ +#define __KGAMENETWORK_H_ + +#include +#include +#include +class KGameIO; +class KMessageClient; +class KMessageServer; + +class KGameNetworkPrivate; + +/** + * The KGameNetwork class is the KGame class with network + * support. All other features are the same but they are + * now network transparent. It is not used directly but + * only via a KGame object. So you do not really have + * to bother with this object. + * + * @short The main KDE game object + * @author Martin Heni + * @version $Id$ + */ +class KDE_EXPORT KGameNetwork : public QObject +{ + Q_OBJECT + +public: + /** + * Create a KGameNetwork object + */ + KGameNetwork(int cookie=42,QObject* parent=0); + virtual ~KGameNetwork(); + + /** + * Gives debug output of the game status + **/ + virtual void Debug(); + + /** + * @return TRUE if this is a network game - i.e. you are either MASTER or + * connected to a remote MASTER. + **/ + bool isNetwork() const; + + /** + * Is this the game MASTER (i.e. has started theKMessageServer). A + * game has always exactly one MASTER. This is either a KGame object (i.e. a + * Client) or an own MessageServer-process. A KGame object that has the + * MASTER status is always admin. + * + * You probably don't want to use this. It is a mostly internal method which + * will probably become protected. Better use isAdmin + * + * @see isAdmin + * @return Whether this client has started the KMessageServer + **/ + bool isMaster() const; + + /** + * The admin of a game is the one who initializes newly connected clients + * using negotiateNetworkGame and is allowed to configure the game. + * E.g. only the admin is allowed to use KGame::setMaxPlayers. + * + * If one KGame object in the game is MASTER then this client is the admin + * as well. isMaster and isAdmin differ only if the KMessageServer + * is running in an own process. + * @return Whether this client (KGame object) is the admin + **/ + bool isAdmin() const; + + /** + * The unique ID of this game + * + * @return int id + **/ + Q_UINT32 gameId() const; + + /** + * Inits a network game as network MASTER. Note that if the + * KMessageServer is not yet started it will be started here (see + * setMaster). Any existing connection will be disconnected. + * + * If you already offer connections the port is changed. + * + * @param port The port on which the service is offered + * @return true if it worked + **/ + bool offerConnections (Q_UINT16 port); + + /** + * Announces game MASTER on network using DNS-SD. Clients then can discover it using + * DNSSD::ServiceBrowser (or KGameConnectWidget) instead of manually entering + * IP address. + * @param type service type (something like _kwin4._tcp). + * It should be unique for application. + * @param name game name that will be displayed by clients. If not + * set hostname will be used. In case of name conflict -2, -3 and so on will be added to name. + * @since 3.4 + **/ + void setDiscoveryInfo(const QString& type, const QString& name=QString::null); + + /** + * Inits a network game as a network CLIENT + * + * @param host the host to which we want to connect + * @param port the port we want to connect to + * + * @return true if connected + **/ + bool connectToServer(const QString& host, Q_UINT16 port); + + /** + * @since 3.2 + * @return The port we are listening to if offerConnections was called + * or the port we are connected to if connectToServer was called. + * Otherwise 0. + **/ + Q_UINT16 port() const; + + /** + * @since 3.2 + * @return The name of the host that we are currently connected to is + * isNetwork is TRUE and we are not the MASTER, i.e. if connectToServer + * was called. Otherwise this will return "localhost". + **/ + QString hostName() const; + + /** + * Stops offering server connections - only for game MASTER + * @return true + **/ + bool stopServerConnection(); + + /** + * Changes the maximal connection number of the KMessageServer to max. + * -1 Means infinite connections are possible. Note that existing + * connections are not affected, so even if you set this to 0 in a running + * game no client is being disconnected. You can call this only if you are + * the ADMIN! + * + * @see KMessageServer::setMaxClients + * @param max The maximal number of connections possible. + **/ + void setMaxClients(int max); + + //AB: is this now internal only? Can we make it protected (maybe with + //friends)? sendSystemMessage AND sendMessage is very confusing to the + //user. + /** + * Sends a network message msg with a given msg id msgid to all clients. + * Use this to communicate with KGame (e.g. to add a player ot to configure + * the game - usually not necessary). + * + * For your own messages use sendMessage instead! This is mostly + * internal! + * + * @param buffer the message which will be send. See messages.txt for contents + * @param msgid an id for this message. See + * KGameMessage::GameMessageIds + * @param receiver the KGame / KPlayer this message is for. + * @param sender The KGame / KPlayer this message is from (i.e. + * you). You + * probably want to leave this 0, then KGameNetwork will create the correct + * value for you. You might want to use this if you send a message from a + * specific player. + * @return true if worked + */ + // AB: TODO: doc on how "receiver" and "sender" should be created! + bool sendSystemMessage(const QByteArray& buffer, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * @overload + **/ + bool sendSystemMessage(int data, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * @overload + **/ + bool sendSystemMessage(const QDataStream &msg, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * @overload + **/ + bool sendSystemMessage(const QString& msg, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * Sends a network message + * @param error The error code + * @param message The error message - use KGameError + * @param receiver the KGame / KPlayer this message is for. 0 For + * all + * @param sender The KGame / KPlayer this message is from (i.e. + * you). You probably want to leave this 0, then KGameNetwork will create + * the correct value for you. You might want to use this if you send a + * message from a specific player. + **/ + void sendError(int error, const QByteArray& message, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * Are we still offer offering server connections - only for game MASTER + * @return true/false + **/ + bool isOfferingConnections() const; + + /** + * Application cookie. this idendifies the game application. It + * help to distinguish between e.g. KPoker and KWin4 + * @return the application cookie + **/ + int cookie() const; + + /** + * Send a network message msg with a given message ID msgid to all clients. + * You want to use this to send a message to the clients. + * + * Note that a message is always sent to ALL clients! This is necessary so + * that all clients always have the same data and can easily be changed from + * network to non-network without restarting the game. If you want a + * specific KGame / KPlayer to react to the message use the + * receiver and sender parameters. See KGameMessage::calsMessageId + * + * SendMessage differs from sendSystemMessage only by the msgid parameter. + * sendSystemMessage is thought as a KGame only mehtod while + * sendMessage is for public use. The msgid parameter will be + * +=KGameMessage::IdUser and in KGame::signalNetworkData msgid will + * be -= KGameMessage::IdUser again, so that one can easily distinguish + * between system and user messages. + * + * Use sendSystemMessage to comunicate with KGame (e.g. by adding a + * player) and sendMessage for your own user message. + * + * Note: a player should send messages through a KGameIO! + * + * @param buffer the message which will be send. See messages.txt for contents + * @param msgid an id for this message. See KGameMessage::GameMessageIds + * @param receiver the KGame / KPlayer this message is for. + * @param sender The KGame / KPlayer this message is from (i.e. + * you). You + * probably want to leave this 0, then KGameNetwork will create the correct + * value for you. You might want to use this if you send a message from a + * specific player. + * @return true if worked + **/ + // AB: TODO: doc on how "receiver" and "sender" should be created! + bool sendMessage(const QByteArray& buffer, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * This is an overloaded member function, provided for convenience. + **/ + bool sendMessage(const QDataStream &msg, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * This is an overloaded member function, provided for convenience. + **/ + bool sendMessage(const QString& msg, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + /** + * This is an overloaded member function, provided for convenience. + **/ + bool sendMessage(int data, int msgid, Q_UINT32 receiver=0, Q_UINT32 sender=0); + + + /** + * Called by ReceiveNetworkTransmission(). Will be overwritten by + * KGame and handle the incoming message. + **/ + virtual void networkTransmission(QDataStream&, int, Q_UINT32, Q_UINT32, Q_UINT32 clientID) = 0; + + + /** + * Disconnect the current connection and establish a new local one. + **/ + void disconnect(); + + + /** + * If you are the ADMIN of the game you can give the ADMIN status away to + * another client. Use this e.g. if you want to quit the game or if you want + * another client to administrate the game (note that disconnect calls + * this automatically). + * @param clientID the ID of the new ADMIN (note: this is the _client_ID + * which has nothing to do with the player IDs. See KMessageServer) + **/ + void electAdmin(Q_UINT32 clientID); + + /** + * Don't use this unless you really know what youre doing! You might + * experience some strange behaviour if you send your messages directly + * through the KMessageClient! + * + * @return a pointer to the KMessageClient used internally to send the + * messages. You should rather use one of the send functions! + **/ + KMessageClient* messageClient() const; + + /** + * Don't use this unless you really know what you are doing! You might + * experience some strange behaviour if you use the message server directly! + * + * @return a pointer to the message server if this is the MASTER KGame + * object. Note that it might be possible that no KGame object contains + * the KMessageServer at all! It might even run stand alone! + **/ + KMessageServer* messageServer() const; + + /** + * You should call this before doing thigs like, e.g. qApp->processEvents(). + * Don't forget to call unlock once you are done! + * + * @see KMessageClient::lock + **/ + virtual void lock(); + + /** + * @see KMessageClient::unlock + **/ + virtual void unlock(); + +signals: + /** + * A network error occurred + * @param error the error code + * @param text the error text + */ + void signalNetworkErrorMessage(int error, QString text); + + /** + * Our connection to the KMessageServer has broken. + * See KMessageClient::connectionBroken + **/ + void signalConnectionBroken(); + + /** + * This signal is emitted whenever the KMessageServer sends us a message that a + * new client connected. KGame uses this to call KGame::negotiateNetworkGame + * for the newly connected client if we are admin (see isAdmin) + * + * @see KMessageClient::eventClientConnected + * + * @param clientID the ID of the newly connected client + **/ + void signalClientConnected(Q_UINT32 clientID); + + /** + * This signal is emitted whenever the KMessageServer sends us a message + * that a connection to a client was detached. The second parameter can be used + * to distinguish between network errors or removing on purpose. + * + * @see KMessageClient::eventClientDisconnected + * + * @param clientID the client that has disconnected + * @param broken true if the connection was lost because of a network error, false + * if the connection was closed by the message server admin. + */ + void signalClientDisconnected(Q_UINT32 clientID, bool broken); + + /** + * This client gets or loses the admin status. + * @see KMessageClient::adminStatusChanged + * @param isAdmin True if this client gets the ADMIN status otherwise FALSE + **/ + void signalAdminStatusChanged(bool isAdmin); + +protected: + /** + * @internal + * Start a KMessageServer object and use it as the MASTER of the game. + * Note that you must not call this if there is already another master + * running! + **/ + void setMaster(); + +protected slots: + /** + * Called by KMessageClient::broadcastReceived() and will check if the + * message format is valid. If it is not, it will generate an error (see + * signalNetworkVersionError and signalNetworkErorrMessage). + * If it is valid, the pure virtual method networkTransmission() is called. + * (This one is overwritten in KGame.) + **/ + void receiveNetworkTransmission(const QByteArray& a, Q_UINT32 clientID); + + /** + * This KGame object receives or loses the admin status. + * @param isAdmin Whether we are admin or not + **/ + void slotAdminStatusChanged(bool isAdmin); + + /** + * Called when the network connection is about to terminate. Is used + * to store the network parameter like the game id + */ + void aboutToLoseConnection(Q_UINT32 id); + + /** + * Called when the network connection is terminated. Used to clean + * up the disconnect parameter + */ + void slotResetConnection(); + + +private: + void tryPublish(); + void tryStopPublishing(); + KGameNetworkPrivate* d; +}; + +#endif -- cgit v1.2.1