00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "kgamenetwork.h"
00025 #include "kgamenetwork.moc"
00026 #include "kgamemessage.h"
00027 #include "kgameerror.h"
00028
00029 #include "kmessageserver.h"
00030 #include "kmessageclient.h"
00031 #include "kmessageio.h"
00032
00033 #include <kdebug.h>
00034
00035 #include <qbuffer.h>
00036
00037
00038 class KGameNetworkPrivate
00039 {
00040 public:
00041 KGameNetworkPrivate()
00042 {
00043 mMessageClient = 0;
00044 mMessageServer = 0;
00045 mDisconnectId = 0;
00046 }
00047
00048 public:
00049 KMessageClient* mMessageClient;
00050 KMessageServer* mMessageServer;
00051 Q_UINT32 mDisconnectId;
00052
00053 int mCookie;
00054 };
00055
00056
00057 KGameNetwork::KGameNetwork(int c, QObject* parent) : QObject(parent, 0)
00058 {
00059 d = new KGameNetworkPrivate;
00060 d->mCookie = (Q_INT16)c;
00061
00062
00063
00064 setMaster();
00065
00066 kdDebug(11001) << k_funcinfo << "this=" << this <<", cookie=" << cookie() << " sizeof(this)="<<sizeof(KGameNetwork) << endl;
00067 }
00068
00069 KGameNetwork::~KGameNetwork()
00070 {
00071 kdDebug(11001) << k_funcinfo << "this=" << this << endl;
00072
00073 delete d;
00074 }
00075
00076
00077 bool KGameNetwork::isNetwork() const
00078 { return isOfferingConnections() || d->mMessageClient->isNetwork();}
00079
00080 Q_UINT32 KGameNetwork::gameId() const
00081 {
00082
00083
00084
00085 if (d->mMessageClient->id()!=0 ) {
00086 return d->mMessageClient->id() ;
00087 } else {
00088 return d->mDisconnectId;
00089 }
00090 }
00091
00092 int KGameNetwork::cookie() const
00093 { return d->mCookie; }
00094
00095 bool KGameNetwork::isMaster() const
00096 { return (d->mMessageServer != 0); }
00097
00098 bool KGameNetwork::isAdmin() const
00099 { return (d->mMessageClient->isAdmin()); }
00100
00101 KMessageClient* KGameNetwork::messageClient() const
00102 { return d->mMessageClient; }
00103
00104 KMessageServer* KGameNetwork::messageServer() const
00105 { return d->mMessageServer; }
00106
00107
00108 void KGameNetwork::setMaster()
00109 {
00110 if (!d->mMessageServer) {
00111 d->mMessageServer = new KMessageServer (cookie(), this);
00112 } else {
00113 kdWarning(11001) << k_funcinfo << "Server already running!!" << endl;
00114 }
00115 if (!d->mMessageClient) {
00116 d->mMessageClient = new KMessageClient (this);
00117 connect (d->mMessageClient, SIGNAL(broadcastReceived(const QByteArray&, Q_UINT32)),
00118 this, SLOT(receiveNetworkTransmission(const QByteArray&, Q_UINT32)));
00119 connect (d->mMessageClient, SIGNAL(connectionBroken()),
00120 this, SIGNAL(signalConnectionBroken()));
00121 connect (d->mMessageClient, SIGNAL(aboutToDisconnect(Q_UINT32)),
00122 this, SLOT(aboutToLoseConnection(Q_UINT32)));
00123 connect (d->mMessageClient, SIGNAL(connectionBroken()),
00124 this, SLOT(slotResetConnection()));
00125
00126 connect (d->mMessageClient, SIGNAL(adminStatusChanged(bool)),
00127 this, SLOT(slotAdminStatusChanged(bool)));
00128 connect (d->mMessageClient, SIGNAL(eventClientConnected(Q_UINT32)),
00129 this, SIGNAL(signalClientConnected(Q_UINT32)));
00130 connect (d->mMessageClient, SIGNAL(eventClientDisconnected(Q_UINT32, bool)),
00131 this, SIGNAL(signalClientDisconnected(Q_UINT32, bool)));
00132
00133
00134 connect (d->mMessageClient, SIGNAL(forwardReceived(const QByteArray&, Q_UINT32, const QValueList<Q_UINT32>&)),
00135 d->mMessageClient, SIGNAL(broadcastReceived(const QByteArray&, Q_UINT32)));
00136
00137 } else {
00138
00139 kdDebug(11001) << k_funcinfo << "Client already exists!" << endl;
00140 }
00141 d->mMessageClient->setServer(d->mMessageServer);
00142 }
00143
00144 bool KGameNetwork::offerConnections(Q_UINT16 port)
00145 {
00146 kdDebug (11001) << k_funcinfo << "on port " << port << endl;
00147 if (!isMaster()) {
00148 setMaster();
00149 }
00150
00151
00152 d->mDisconnectId = 0;
00153
00154
00155 if (d->mMessageServer && d->mMessageServer->isOfferingConnections()) {
00156 kdDebug (11001) << k_funcinfo << "Already running as server! Changing the port now!" << endl;
00157 }
00158
00159 kdDebug (11001) << k_funcinfo << "before Server->initNetwork" << endl;
00160 if (!d->mMessageServer->initNetwork (port)) {
00161 kdError (11001) << k_funcinfo << "Unable to bind to port " << port << "!" << endl;
00162
00163
00164
00165
00166 return false;
00167 }
00168 kdDebug (11001) << k_funcinfo << "after Server->initNetwork" << endl;
00169 return true;
00170 }
00171
00172 bool KGameNetwork::connectToServer (const QString& host, Q_UINT16 port)
00173 {
00174 if (host.isEmpty()) {
00175 kdError(11001) << k_funcinfo << "No hostname given" << endl;
00176 return false;
00177 }
00178
00179
00180 d->mDisconnectId = 0;
00181
00182
00183
00184
00186
00187 if (d->mMessageServer) {
00188
00189 kdWarning(11001) << "we are server but we are trying to connect to another server! "
00190 << "make sure that all clients connect to that server! "
00191 << "quitting the local server now..." << endl;
00192 stopServerConnection();
00193 d->mMessageClient->setServer((KMessageIO*)0);
00194 delete d->mMessageServer;
00195 d->mMessageServer = 0;
00196 }
00197
00198 kdDebug(11001) << " about to set server" << endl;
00199 d->mMessageClient->setServer(host, port);
00200 emit signalAdminStatusChanged(false);
00201
00202
00203
00204
00205
00206 kdDebug(11001) << "connected to " << host << ":" << port << endl;
00207 return true;
00208 }
00209
00210 Q_UINT16 KGameNetwork::port() const
00211 {
00212 if (isNetwork()) {
00213 if (isOfferingConnections()) {
00214 return d->mMessageServer->serverPort();
00215 } else {
00216 return d->mMessageClient->peerPort();
00217 }
00218 }
00219 return 0;
00220 }
00221
00222 QString KGameNetwork::hostName() const
00223 {
00224 return d->mMessageClient->peerName();
00225 }
00226
00227 bool KGameNetwork::stopServerConnection()
00228 {
00229
00230 if (d->mMessageServer) {
00231 d->mMessageServer->stopNetwork();
00232 return true;
00233 }
00234 return false;
00235 }
00236
00237 bool KGameNetwork::isOfferingConnections() const
00238 { return (d->mMessageServer && d->mMessageServer->isOfferingConnections()); }
00239
00240 void KGameNetwork::disconnect()
00241 {
00242
00243 kdDebug(11001) << k_funcinfo << endl;
00244 stopServerConnection();
00245 if (d->mMessageServer) {
00246 QValueList <Q_UINT32> list=d->mMessageServer->clientIDs();
00247 QValueList<Q_UINT32>::Iterator it;
00248 for( it = list.begin(); it != list.end(); ++it )
00249 {
00250 kdDebug(11001) << "Client id=" << (*it) << endl;
00251 KMessageIO *client=d->mMessageServer->findClient(*it);
00252 if (!client)
00253 {
00254 continue;
00255 }
00256 kdDebug(11001) << " rtti=" << client->rtti() << endl;
00257 if (client->rtti()==2)
00258 {
00259 kdDebug(11001) << "DIRECT IO " << endl;
00260 }
00261 else
00262 {
00263 d->mMessageServer->removeClient(client,false);
00264 }
00265 }
00266 }
00267 else
00268 {
00269 kdDebug(11001) << k_funcinfo << "before client->disconnect() id="<<gameId()<< endl;
00270
00271 kdDebug(11001) << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++"<<endl;
00272 d->mMessageClient->disconnect();
00273
00274 kdDebug(11001) << "++++++--------------------------------------------+++++"<<endl;
00275 }
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 kdDebug(11001) << k_funcinfo << "DONE" << endl;
00288 }
00289
00290 void KGameNetwork::aboutToLoseConnection(Q_UINT32 clientID)
00291 {
00292 kdDebug(11001) << "Storing client id of connection "<<clientID<<endl;
00293 d->mDisconnectId = clientID;
00294 }
00295
00296 void KGameNetwork::slotResetConnection()
00297 {
00298 kdDebug(11001) << "Resseting client disconnect id"<<endl;
00299 d->mDisconnectId = 0;
00300 }
00301
00302 void KGameNetwork::electAdmin(Q_UINT32 clientID)
00303 {
00304 if (!isAdmin()) {
00305 kdWarning(11001) << k_funcinfo << "only ADMIN is allowed to call this!" << endl;
00306 return;
00307 }
00308 QByteArray buffer;
00309 QDataStream stream(buffer,IO_WriteOnly);
00310 stream << static_cast<Q_UINT32>( KMessageServer::REQ_ADMIN_CHANGE );
00311 stream << clientID;
00312 d->mMessageClient->sendServerMessage(buffer);
00313 }
00314
00315 void KGameNetwork::setMaxClients(int max)
00316 {
00317 if (!isAdmin()) {
00318 kdWarning(11001) << k_funcinfo << "only ADMIN is allowed to call this!" << endl;
00319 return;
00320 }
00321 QByteArray buffer;
00322 QDataStream stream(buffer,IO_WriteOnly);
00323 stream << static_cast<Q_UINT32>( KMessageServer::REQ_MAX_NUM_CLIENTS );
00324 stream << (Q_INT32)max;
00325 d->mMessageClient->sendServerMessage(buffer);
00326 }
00327
00328 void KGameNetwork::lock()
00329 {
00330 if (messageClient()) {
00331 messageClient()->lock();
00332 }
00333 }
00334
00335 void KGameNetwork::unlock()
00336 {
00337 if (messageClient()) {
00338 messageClient()->unlock();
00339 }
00340 }
00341
00342
00343
00344 bool KGameNetwork::sendSystemMessage(int data, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00345 {
00346 QByteArray buffer;
00347 QDataStream stream(buffer,IO_WriteOnly);
00348 stream << data;
00349 return sendSystemMessage(buffer,msgid,receiver,sender);
00350 }
00351
00352 bool KGameNetwork::sendSystemMessage(const QString &msg, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00353 {
00354 QByteArray buffer;
00355 QDataStream stream(buffer, IO_WriteOnly);
00356 stream << msg;
00357 return sendSystemMessage(buffer, msgid, receiver, sender);
00358 }
00359
00360 bool KGameNetwork::sendSystemMessage(const QDataStream &msg, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00361 { return sendSystemMessage(((QBuffer*)msg.device())->buffer(), msgid, receiver, sender); }
00362
00363 bool KGameNetwork::sendSystemMessage(const QByteArray& data, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00364 {
00365 QByteArray buffer;
00366 QDataStream stream(buffer,IO_WriteOnly);
00367 if (!sender) {
00368 sender = gameId();
00369 }
00370
00371 Q_UINT32 receiverClient = KGameMessage::rawGameId(receiver);
00372 int receiverPlayer = KGameMessage::rawPlayerId(receiver);
00373
00374 KGameMessage::createHeader(stream, sender, receiver, msgid);
00375 stream.writeRawBytes(data.data(), data.size());
00376
00377
00378
00379
00380
00381
00382
00383 if (!d->mMessageClient) {
00384
00385
00386
00387 kdWarning (11001) << k_funcinfo << "We don't have a client! Should never happen!" << endl;
00388 return false;
00389 }
00390
00391 if (receiverClient == 0 || receiverPlayer != 0)
00392 {
00393
00394
00395
00396 d->mMessageClient->sendBroadcast(buffer);
00397 }
00398 else
00399 {
00400 d->mMessageClient->sendForward(buffer, receiverClient);
00401 }
00402 return true;
00403 }
00404
00405 bool KGameNetwork::sendMessage(int data, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00406 { return sendSystemMessage(data,msgid+KGameMessage::IdUser,receiver,sender); }
00407
00408 bool KGameNetwork::sendMessage(const QString &msg, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00409 { return sendSystemMessage(msg,msgid+KGameMessage::IdUser,receiver,sender); }
00410
00411 bool KGameNetwork::sendMessage(const QDataStream &msg, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00412 { return sendSystemMessage(msg, msgid+KGameMessage::IdUser, receiver, sender); }
00413
00414 bool KGameNetwork::sendMessage(const QByteArray &msg, int msgid, Q_UINT32 receiver, Q_UINT32 sender)
00415 { return sendSystemMessage(msg, msgid+KGameMessage::IdUser, receiver, sender); }
00416
00417 void KGameNetwork::sendError(int error,const QByteArray& message, Q_UINT32 receiver, Q_UINT32 sender)
00418 {
00419 QByteArray buffer;
00420 QDataStream stream(buffer,IO_WriteOnly);
00421 stream << (Q_INT32) error;
00422 stream.writeRawBytes(message.data(), message.size());
00423 sendSystemMessage(stream,KGameMessage::IdError,receiver,sender);
00424 }
00425
00426
00427
00428 void KGameNetwork::receiveNetworkTransmission(const QByteArray& receiveBuffer, Q_UINT32 clientID)
00429 {
00430 QDataStream stream(receiveBuffer, IO_ReadOnly);
00431 int msgid;
00432 Q_UINT32 sender;
00433 Q_UINT32 receiver;
00434 KGameMessage::extractHeader(stream, sender, receiver, msgid);
00435
00436
00437
00438
00439
00440 if (receiver && receiver!=gameId() && !KGameMessage::isPlayer(receiver) )
00441 {
00442
00443 kdDebug(11001) << k_funcinfo << "Message not meant for us "
00444 << gameId() << "!=" << receiver << " rawid="
00445 << KGameMessage::rawGameId(receiver) << endl;
00446 return;
00447 }
00448 else if (msgid==KGameMessage::IdError)
00449 {
00450 QString text;
00451 Q_INT32 error;
00452 stream >> error;
00453 kdDebug(11001) << k_funcinfo << "Got IdError " << error << endl;
00454 text = KGameError::errorText(error, stream);
00455 kdDebug(11001) << "Error text: " << text.latin1() << endl;
00456 emit signalNetworkErrorMessage((int)error,text);
00457 }
00458 else
00459 {
00460 networkTransmission(stream, msgid, receiver, sender, clientID);
00461 }
00462 }
00463
00464
00465 void KGameNetwork::slotAdminStatusChanged(bool isAdmin)
00466 {
00467 emit signalAdminStatusChanged(isAdmin);
00468
00469
00470 }
00471
00472 void KGameNetwork::Debug()
00473 {
00474 kdDebug(11001) << "------------------- KNETWORKGAME -------------------------" << endl;
00475 kdDebug(11001) << "gameId " << gameId() << endl;
00476 kdDebug(11001) << "gameMaster " << isMaster() << endl;
00477 kdDebug(11001) << "gameAdmin " << isAdmin() << endl;
00478 kdDebug(11001) << "---------------------------------------------------" << endl;
00479 }
00480
00481
00482
00483