|
|
|
/*
|
|
|
|
This file is part of the TDE 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 <tqstring.h>
|
|
|
|
#include <tqobject.h>
|
|
|
|
#include <kdemacros.h>
|
|
|
|
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 <martin@heni-online.de>
|
|
|
|
* @version $Id$
|
|
|
|
*/
|
|
|
|
class KDE_EXPORT KGameNetwork : public TQObject
|
|
|
|
{
|
|
|
|
TQ_OBJECT
|
|
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
/**
|
|
|
|
* Create a KGameNetwork object
|
|
|
|
*/
|
|
|
|
KGameNetwork(int cookie=42,TQObject* 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
|
|
|
|
**/
|
|
|
|
TQ_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 (TQ_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 _twin4._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 TQString& type, const TQString& name=TQString());
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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 TQString& host, TQ_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.
|
|
|
|
**/
|
|
|
|
TQ_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".
|
|
|
|
**/
|
|
|
|
TQString 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 TQByteArray& buffer, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @overload
|
|
|
|
**/
|
|
|
|
bool sendSystemMessage(int data, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @overload
|
|
|
|
**/
|
|
|
|
bool sendSystemMessage(const TQDataStream &msg, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @overload
|
|
|
|
**/
|
|
|
|
bool sendSystemMessage(const TQString& msg, int msgid, TQ_UINT32 receiver=0, TQ_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 TQByteArray& message, TQ_UINT32 receiver=0, TQ_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 TQByteArray& buffer, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is an overloaded member function, provided for convenience.
|
|
|
|
**/
|
|
|
|
bool sendMessage(const TQDataStream &msg, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is an overloaded member function, provided for convenience.
|
|
|
|
**/
|
|
|
|
bool sendMessage(const TQString& msg, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is an overloaded member function, provided for convenience.
|
|
|
|
**/
|
|
|
|
bool sendMessage(int data, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0);
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Called by ReceiveNetworkTransmission(). Will be overwritten by
|
|
|
|
* KGame and handle the incoming message.
|
|
|
|
**/
|
|
|
|
virtual void networkTransmission(TQDataStream&, int, TQ_UINT32, TQ_UINT32, TQ_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(TQ_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. tqApp->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, TQString 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(TQ_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(TQ_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 TQByteArray& a, TQ_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(TQ_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
|