24#include "kgamenetwork.h"
25#include "kgamenetwork.moc"
26#include "kgamemessage.h"
27#include "kgameerror.h"
29#include "kmessageserver.h"
30#include "kmessageclient.h"
31#include "kmessageio.h"
32#include <dnssd/publicservice.h>
39class KGameNetworkPrivate
51 KMessageClient* mMessageClient;
52 KMessageServer* mMessageServer;
53 TQ_UINT32 mDisconnectId;
54 DNSSD::PublicService* mService;
64 d =
new KGameNetworkPrivate;
65 d->mCookie = (TQ_INT16)c;
71 kdDebug(11001) << k_funcinfo <<
"this=" <<
this <<
", cookie=" <<
cookie() <<
" sizeof(this)="<<
sizeof(
KGameNetwork) << endl;
74KGameNetwork::~KGameNetwork()
76 kdDebug(11001) << k_funcinfo <<
"this=" <<
this << endl;
91 if (d->mMessageClient->id()!=0 ) {
92 return d->mMessageClient->id() ;
94 return d->mDisconnectId;
102{
return (d->mMessageServer != 0); }
105{
return (d->mMessageClient->isAdmin()); }
108{
return d->mMessageClient; }
111{
return d->mMessageServer; }
114void KGameNetwork::setMaster()
116 if (!d->mMessageServer) {
119 kdWarning(11001) << k_funcinfo <<
"Server already running!!" << endl;
121 if (!d->mMessageClient) {
122 d->mMessageClient =
new KMessageClient (
this);
123 connect (d->mMessageClient, TQ_SIGNAL(broadcastReceived(
const TQByteArray&, TQ_UINT32)),
125 connect (d->mMessageClient, TQ_SIGNAL(connectionBroken()),
127 connect (d->mMessageClient, TQ_SIGNAL(aboutToDisconnect(TQ_UINT32)),
129 connect (d->mMessageClient, TQ_SIGNAL(connectionBroken()),
132 connect (d->mMessageClient, TQ_SIGNAL(adminStatusChanged(
bool)),
134 connect (d->mMessageClient, TQ_SIGNAL(eventClientConnected(TQ_UINT32)),
136 connect (d->mMessageClient, TQ_SIGNAL(eventClientDisconnected(TQ_UINT32,
bool)),
140 connect (d->mMessageClient, TQ_SIGNAL(forwardReceived(
const TQByteArray&, TQ_UINT32,
const TQValueList<TQ_UINT32>&)),
141 d->mMessageClient, TQ_SIGNAL(broadcastReceived(
const TQByteArray&, TQ_UINT32)));
145 kdDebug(11001) << k_funcinfo <<
"Client already exists!" << endl;
147 d->mMessageClient->setServer(d->mMessageServer);
152 kdDebug() << k_funcinfo << type <<
":" << name << endl;
158void KGameNetwork::tryPublish()
161 if (!d->mService) d->mService =
new DNSSD::PublicService(d->mName,d->mType,
port());
163 if (d->mType!=d->mService->type()) d->mService->setType(d->mType);
164 if (d->mName!=d->mService->serviceName()) d->mService->setServiceName(d->mName);
166 if (!d->mService->isPublished()) d->mService->publishAsync();
169void KGameNetwork::tryStopPublishing()
171 if (d->mService) d->mService->stop();
176 kdDebug (11001) << k_funcinfo <<
"on port " <<
port << endl;
182 d->mDisconnectId = 0;
185 if (d->mMessageServer && d->mMessageServer->isOfferingConnections()) {
186 kdDebug (11001) << k_funcinfo <<
"Already running as server! Changing the port now!" << endl;
190 kdDebug (11001) << k_funcinfo <<
"before Server->initNetwork" << endl;
191 if (!d->mMessageServer->initNetwork (
port)) {
192 kdError (11001) << k_funcinfo <<
"Unable to bind to port " <<
port <<
"!" << endl;
199 kdDebug (11001) << k_funcinfo <<
"after Server->initNetwork" << endl;
206 if (host.isEmpty()) {
207 kdError(11001) << k_funcinfo <<
"No hostname given" << endl;
212 d->mDisconnectId = 0;
219 if (d->mMessageServer) {
221 kdWarning(11001) <<
"we are server but we are trying to connect to another server! "
222 <<
"make sure that all clients connect to that server! "
223 <<
"quitting the local server now..." << endl;
226 delete d->mMessageServer;
227 d->mMessageServer = 0;
230 kdDebug(11001) <<
" about to set server" << endl;
231 d->mMessageClient->setServer(host,
port);
238 kdDebug(11001) <<
"connected to " << host <<
":" <<
port << endl;
246 return d->mMessageServer->serverPort();
248 return d->mMessageClient->peerPort();
256 return d->mMessageClient->peerName();
263 if (d->mMessageServer) {
264 d->mMessageServer->stopNetwork();
271{
return (d->mMessageServer && d->mMessageServer->isOfferingConnections()); }
276 kdDebug(11001) << k_funcinfo << endl;
278 if (d->mMessageServer) {
279 TQValueList <TQ_UINT32> list=d->mMessageServer->clientIDs();
280 TQValueList<TQ_UINT32>::Iterator it;
281 for( it = list.begin(); it != list.end(); ++it )
283 kdDebug(11001) <<
"Client id=" << (*it) << endl;
284 KMessageIO *client=d->mMessageServer->findClient(*it);
289 kdDebug(11001) <<
" rtti=" << client->
rtti() << endl;
290 if (client->
rtti()==2)
292 kdDebug(11001) <<
"DIRECT IO " << endl;
296 d->mMessageServer->removeClient(client,
false);
302 kdDebug(11001) << k_funcinfo <<
"before client->disconnect() id="<<
gameId()<< endl;
304 kdDebug(11001) <<
"+++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
305 d->mMessageClient->disconnect();
307 kdDebug(11001) <<
"++++++--------------------------------------------+++++"<<endl;
320 kdDebug(11001) << k_funcinfo <<
"DONE" << endl;
325 kdDebug(11001) <<
"Storing client id of connection "<<clientID<<endl;
326 d->mDisconnectId = clientID;
331 kdDebug(11001) <<
"Resseting client disconnect id"<<endl;
332 d->mDisconnectId = 0;
338 kdWarning(11001) << k_funcinfo <<
"only ADMIN is allowed to call this!" << endl;
342 TQDataStream stream(buffer,IO_WriteOnly);
343 stream << static_cast<TQ_UINT32>( KMessageServer::REQ_ADMIN_CHANGE );
345 d->mMessageClient->sendServerMessage(buffer);
351 kdWarning(11001) << k_funcinfo <<
"only ADMIN is allowed to call this!" << endl;
355 TQDataStream stream(buffer,IO_WriteOnly);
356 stream << static_cast<TQ_UINT32>( KMessageServer::REQ_MAX_NUM_CLIENTS );
357 stream << (TQ_INT32)max;
358 d->mMessageClient->sendServerMessage(buffer);
380 TQDataStream stream(buffer,IO_WriteOnly);
388 TQDataStream stream(buffer, IO_WriteOnly);
394{
return sendSystemMessage(((TQBuffer*)msg.device())->buffer(), msgid, receiver, sender); }
399 TQDataStream stream(buffer,IO_WriteOnly);
404 TQ_UINT32 receiverClient = KGameMessage::rawGameId(receiver);
405 int receiverPlayer = KGameMessage::rawPlayerId(receiver);
407 KGameMessage::createHeader(stream, sender, receiver, msgid);
408 stream.writeRawBytes(data.data(), data.size());
416 if (!d->mMessageClient) {
420 kdWarning (11001) << k_funcinfo <<
"We don't have a client! Should never happen!" << endl;
424 if (receiverClient == 0 || receiverPlayer != 0)
429 d->mMessageClient->sendBroadcast(buffer);
433 d->mMessageClient->sendForward(buffer, receiverClient);
453 TQDataStream stream(buffer,IO_WriteOnly);
454 stream << (TQ_INT32) error;
455 stream.writeRawBytes(message.data(), message.size());
463 TQDataStream stream(receiveBuffer, IO_ReadOnly);
467 KGameMessage::extractHeader(stream, sender, receiver, msgid);
473 if (receiver && receiver!=
gameId() && !KGameMessage::isPlayer(receiver) )
476 kdDebug(11001) << k_funcinfo <<
"Message not meant for us "
477 <<
gameId() <<
"!=" << receiver <<
" rawid="
478 << KGameMessage::rawGameId(receiver) << endl;
481 else if (msgid==KGameMessage::IdError)
486 kdDebug(11001) << k_funcinfo <<
"Got IdError " << error << endl;
487 text = KGameError::errorText(error, stream);
488 kdDebug(11001) <<
"Error text: " << text.latin1() << endl;
507 kdDebug(11001) <<
"------------------- KNETWORKGAME -------------------------" << endl;
508 kdDebug(11001) <<
"gameId " <<
gameId() << endl;
509 kdDebug(11001) <<
"gameMaster " <<
isMaster() << endl;
510 kdDebug(11001) <<
"gameAdmin " <<
isAdmin() << endl;
511 kdDebug(11001) <<
"---------------------------------------------------" << endl;
KMessageServer * messageServer() const
Don't use this unless you really know what you are doing!
bool isMaster() const
Is this the game MASTER (i.e.
KMessageClient * messageClient() const
Don't use this unless you really know what youre doing!
bool offerConnections(TQ_UINT16 port)
Inits a network game as network MASTER.
bool isAdmin() const
The admin of a game is the one who initializes newly connected clients using negotiateNetworkGame and...
void aboutToLoseConnection(TQ_UINT32 id)
Called when the network connection is about to terminate.
void receiveNetworkTransmission(const TQByteArray &a, TQ_UINT32 clientID)
Called by KMessageClient::broadcastReceived() and will check if the message format is valid.
virtual void lock()
You should call this before doing thigs like, e.g.
void signalClientDisconnected(TQ_UINT32 clientID, bool broken)
This signal is emitted whenever the KMessageServer sends us a message that a connection to a client w...
virtual void Debug()
Gives debug output of the game status.
void slotResetConnection()
Called when the network connection is terminated.
void disconnect()
Disconnect the current connection and establish a new local one.
TQString hostName() const
void signalClientConnected(TQ_UINT32 clientID)
This signal is emitted whenever the KMessageServer sends us a message that a new client connected.
TQ_UINT32 gameId() const
The unique ID of this game.
int cookie() const
Application cookie.
bool sendSystemMessage(const TQByteArray &buffer, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0)
Sends a network message msg with a given msg id msgid to all clients.
bool sendMessage(const TQByteArray &buffer, int msgid, TQ_UINT32 receiver=0, TQ_UINT32 sender=0)
Send a network message msg with a given message ID msgid to all clients.
bool isOfferingConnections() const
Are we still offer offering server connections - only for game MASTER.
void setMaxClients(int max)
Changes the maximal connection number of the KMessageServer to max.
void slotAdminStatusChanged(bool isAdmin)
This KGame object receives or loses the admin status.
void electAdmin(TQ_UINT32 clientID)
If you are the ADMIN of the game you can give the ADMIN status away to another client.
void signalConnectionBroken()
Our connection to the KMessageServer has broken.
void setDiscoveryInfo(const TQString &type, const TQString &name=TQString())
Announces game MASTER on network using DNS-SD.
void sendError(int error, const TQByteArray &message, TQ_UINT32 receiver=0, TQ_UINT32 sender=0)
Sends a network message.
KGameNetwork(int cookie=42, TQObject *parent=0)
Create a KGameNetwork object.
void signalNetworkErrorMessage(int error, TQString text)
A network error occurred.
bool connectToServer(const TQString &host, TQ_UINT16 port)
Inits a network game as a network CLIENT.
bool stopServerConnection()
Stops offering server connections - only for game MASTER.
virtual void networkTransmission(TQDataStream &, int, TQ_UINT32, TQ_UINT32, TQ_UINT32 clientID)=0
Called by ReceiveNetworkTransmission().
void signalAdminStatusChanged(bool isAdmin)
This client gets or loses the admin status.
A client to connect to a KMessageServer.
void lock()
Once this function is called no message will be received anymore.
void unlock()
Deliver every message that was delayed by lock() and actually deliver all messages that get received ...
This abstract base class represents one end of a message connections between two clients.
virtual int rtti() const
The runtime idendifcation.
A server for message sending and broadcasting, using TCP/IP connections.