00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qiodevice.h>
00021 #include <qbuffer.h>
00022 #include <qptrlist.h>
00023 #include <qptrqueue.h>
00024 #include <qtimer.h>
00025 #include <qvaluelist.h>
00026
00027 #include <kdebug.h>
00028
00029 #include "kmessageio.h"
00030 #include "kmessageserver.h"
00031
00032
00033
00034 KMessageServerSocket::KMessageServerSocket (Q_UINT16 port, QObject *parent)
00035 : QServerSocket (port, 0, parent)
00036 {
00037 }
00038
00039 KMessageServerSocket::~KMessageServerSocket ()
00040 {
00041 }
00042
00043 void KMessageServerSocket::newConnection (int socket)
00044 {
00045 emit newClientConnected (new KMessageSocket (socket));
00046 }
00047
00048
00049
00050 class MessageBuffer
00051 {
00052 public:
00053 MessageBuffer (Q_UINT32 clientID, const QByteArray &messageData)
00054 : id (clientID), data (messageData) { }
00055 ~MessageBuffer () {}
00056 Q_UINT32 id;
00057 QByteArray data;
00058 };
00059
00060
00061
00062 class KMessageServerPrivate
00063 {
00064 public:
00065 KMessageServerPrivate()
00066 : mMaxClients (-1), mGameId (1), mUniqueClientNumber (1), mAdminID (0), mServerSocket (0)
00067 {
00068 mClientList.setAutoDelete (true);
00069 mMessageQueue.setAutoDelete (true);
00070 }
00071
00072 int mMaxClients;
00073 int mGameId;
00074 Q_UINT16 mCookie;
00075 Q_UINT32 mUniqueClientNumber;
00076 Q_UINT32 mAdminID;
00077
00078 KMessageServerSocket* mServerSocket;
00079
00080 QPtrList <KMessageIO> mClientList;
00081 QPtrQueue <MessageBuffer> mMessageQueue;
00082 QTimer mTimer;
00083 bool mIsRecursive;
00084 };
00085
00086
00087
00088
00089 KMessageServer::KMessageServer (Q_UINT16 cookie,QObject* parent)
00090 : QObject(parent, 0)
00091 {
00092 d = new KMessageServerPrivate;
00093 d->mIsRecursive=false;
00094 d->mCookie=cookie;
00095 connect (&(d->mTimer), SIGNAL (timeout()),
00096 this, SLOT (processOneMessage()));
00097 kdDebug(11001) << "CREATE(KMessageServer="
00098 << this
00099 << ") cookie="
00100 << d->mCookie
00101 << " sizeof(this)="
00102 << sizeof(KMessageServer)
00103 << endl;
00104 }
00105
00106 KMessageServer::~KMessageServer()
00107 {
00108 kdDebug(11001) << k_funcinfo << "this=" << this << endl;
00109 Debug();
00110 stopNetwork();
00111 deleteClients();
00112 delete d;
00113 kdDebug(11001) << k_funcinfo << " done" << endl;
00114 }
00115
00116
00117
00118 bool KMessageServer::initNetwork (Q_UINT16 port)
00119 {
00120 kdDebug(11001) << k_funcinfo << endl;
00121
00122 if (d->mServerSocket)
00123 {
00124 kdDebug (11001) << k_funcinfo << ": We were already offering connections!" << endl;
00125 delete d->mServerSocket;
00126 }
00127
00128 d->mServerSocket = new KMessageServerSocket (port);
00129 d->mIsRecursive = false;
00130
00131 if (!d->mServerSocket || !d->mServerSocket->ok())
00132 {
00133 kdError(11001) << k_funcinfo << ": Serversocket::ok() == false" << endl;
00134 delete d->mServerSocket;
00135 d->mServerSocket=0;
00136 return false;
00137 }
00138
00139 kdDebug (11001) << k_funcinfo << ": Now listening to port "
00140 << d->mServerSocket->port() << endl;
00141 connect (d->mServerSocket, SIGNAL (newClientConnected (KMessageIO*)),
00142 this, SLOT (addClient (KMessageIO*)));
00143 return true;
00144 }
00145
00146 Q_UINT16 KMessageServer::serverPort () const
00147 {
00148 if (d->mServerSocket)
00149 return d->mServerSocket->port();
00150 else
00151 return 0;
00152 }
00153
00154 void KMessageServer::stopNetwork()
00155 {
00156 if (d->mServerSocket)
00157 {
00158 delete d->mServerSocket;
00159 d->mServerSocket = 0;
00160 }
00161 }
00162
00163 bool KMessageServer::isOfferingConnections() const
00164 {
00165 return d->mServerSocket != 0;
00166 }
00167
00168
00169
00170 void KMessageServer::addClient (KMessageIO* client)
00171 {
00172 QByteArray msg;
00173
00174
00175 if (d->mMaxClients >= 0 && d->mMaxClients <= clientCount())
00176 {
00177 kdError (11001) << k_funcinfo << ": Maximum number of clients reached!" << endl;
00178 return;
00179 }
00180
00181
00182 client->setId (uniqueClientNumber());
00183 kdDebug (11001) << k_funcinfo << ": " << client->id() << endl;
00184
00185
00186 connect (client, SIGNAL (connectionBroken()),
00187 this, SLOT (removeBrokenClient()));
00188 connect (client, SIGNAL (received (const QByteArray &)),
00189 this, SLOT (getReceivedMessage (const QByteArray &)));
00190
00191
00192
00193 QDataStream (msg, IO_WriteOnly) << Q_UINT32 (EVNT_CLIENT_CONNECTED) << client->id();
00194 broadcastMessage (msg);
00195
00196
00197 d->mClientList.append (client);
00198
00199
00200 QDataStream (msg, IO_WriteOnly) << Q_UINT32 (ANS_CLIENT_ID) << client->id();
00201 client->send (msg);
00202
00203
00204 QDataStream (msg, IO_WriteOnly) << Q_UINT32 (ANS_CLIENT_LIST) << clientIDs();
00205 client->send (msg);
00206
00207
00208 if (clientCount() == 1)
00209 {
00210
00211 setAdmin (client->id());
00212 }
00213 else
00214 {
00215
00216 QDataStream (msg, IO_WriteOnly) << Q_UINT32 (ANS_ADMIN_ID) << adminID();
00217 client->send (msg);
00218 }
00219
00220 emit clientConnected (client);
00221 }
00222
00223 void KMessageServer::removeClient (KMessageIO* client, bool broken)
00224 {
00225 Q_UINT32 clientID = client->id();
00226 if (!d->mClientList.removeRef (client))
00227 {
00228 kdError(11001) << k_funcinfo << ": Deleting client that wasn't added before!" << endl;
00229 return;
00230 }
00231
00232
00233 QByteArray msg;
00234 QDataStream (msg, IO_WriteOnly) << Q_UINT32 (EVNT_CLIENT_DISCONNECTED) << client->id() << (Q_INT8)broken;
00235 broadcastMessage (msg);
00236
00237
00238 if (clientID == adminID())
00239 {
00240 if (!d->mClientList.isEmpty())
00241 setAdmin (d->mClientList.first()->id());
00242 else
00243 setAdmin (0);
00244 }
00245 }
00246
00247 void KMessageServer::deleteClients()
00248 {
00249 d->mClientList.clear();
00250 d->mAdminID = 0;
00251 }
00252
00253 void KMessageServer::removeBrokenClient ()
00254 {
00255 if (!sender()->inherits ("KMessageIO"))
00256 {
00257 kdError (11001) << k_funcinfo << ": sender of the signal was not a KMessageIO object!" << endl;
00258 return;
00259 }
00260
00261 KMessageIO *client = (KMessageIO *) sender();
00262
00263 emit connectionLost (client);
00264 removeClient (client, true);
00265 }
00266
00267
00268 void KMessageServer::setMaxClients(int c)
00269 {
00270 d->mMaxClients = c;
00271 }
00272
00273 int KMessageServer::maxClients() const
00274 {
00275 return d->mMaxClients;
00276 }
00277
00278 int KMessageServer::clientCount() const
00279 {
00280 return d->mClientList.count();
00281 }
00282
00283 QValueList <Q_UINT32> KMessageServer::clientIDs () const
00284 {
00285 QValueList <Q_UINT32> list;
00286 for (QPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter)
00287 list.append ((*iter)->id());
00288 return list;
00289 }
00290
00291 KMessageIO* KMessageServer::findClient (Q_UINT32 no) const
00292 {
00293 if (no == 0)
00294 no = d->mAdminID;
00295
00296 QPtrListIterator <KMessageIO> iter (d->mClientList);
00297 while (*iter)
00298 {
00299 if ((*iter)->id() == no)
00300 return (*iter);
00301 ++iter;
00302 }
00303 return 0;
00304 }
00305
00306 Q_UINT32 KMessageServer::adminID () const
00307 {
00308 return d->mAdminID;
00309 }
00310
00311 void KMessageServer::setAdmin (Q_UINT32 adminID)
00312 {
00313
00314 if (adminID == d->mAdminID)
00315 return;
00316
00317 if (adminID > 0 && findClient (adminID) == 0)
00318 {
00319 kdWarning (11001) << "Trying to set a new admin that doesn't exist!" << endl;
00320 return;
00321 }
00322
00323 d->mAdminID = adminID;
00324
00325 QByteArray msg;
00326 QDataStream (msg, IO_WriteOnly) << Q_UINT32 (ANS_ADMIN_ID) << adminID;
00327
00328
00329 broadcastMessage (msg);
00330 }
00331
00332
00333
00334
00335 Q_UINT32 KMessageServer::uniqueClientNumber() const
00336 {
00337 return d->mUniqueClientNumber++;
00338 }
00339
00340
00341
00342 void KMessageServer::broadcastMessage (const QByteArray &msg)
00343 {
00344 for (QPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter)
00345 (*iter)->send (msg);
00346 }
00347
00348 void KMessageServer::sendMessage (Q_UINT32 id, const QByteArray &msg)
00349 {
00350 KMessageIO *client = findClient (id);
00351 if (client)
00352 client->send (msg);
00353 }
00354
00355 void KMessageServer::sendMessage (const QValueList <Q_UINT32> &ids, const QByteArray &msg)
00356 {
00357 for (QValueListConstIterator <Q_UINT32> iter = ids.begin(); iter != ids.end(); ++iter)
00358 sendMessage (*iter, msg);
00359 }
00360
00361 void KMessageServer::getReceivedMessage (const QByteArray &msg)
00362 {
00363 if (!sender() || !sender()->inherits("KMessageIO"))
00364 {
00365 kdError (11001) << k_funcinfo << ": slot was not called from KMessageIO!" << endl;
00366 return;
00367 }
00368
00369 KMessageIO *client = (KMessageIO *) sender();
00370 Q_UINT32 clientID = client->id();
00371
00372
00373
00374
00375
00376
00377 d->mMessageQueue.enqueue (new MessageBuffer (clientID, msg));
00378 if (!d->mTimer.isActive())
00379 d->mTimer.start(0);
00380 }
00381
00382 void KMessageServer::processOneMessage ()
00383 {
00384
00385 if (d->mMessageQueue.isEmpty())
00386 {
00387 d->mTimer.stop();
00388 return;
00389 }
00390 if (d->mIsRecursive)
00391 {
00392 return;
00393 }
00394 d->mIsRecursive = true;
00395
00396 MessageBuffer *msg_buf = d->mMessageQueue.head();
00397
00398 Q_UINT32 clientID = msg_buf->id;
00399 QBuffer in_buffer (msg_buf->data);
00400 in_buffer.open (IO_ReadOnly);
00401 QDataStream in_stream (&in_buffer);
00402
00403 QByteArray out_msg;
00404 QBuffer out_buffer (out_msg);
00405 out_buffer.open (IO_WriteOnly);
00406 QDataStream out_stream (&out_buffer);
00407
00408 bool unknown = false;
00409
00410 QByteArray ttt=in_buffer.buffer();
00411 Q_UINT32 messageID;
00412 in_stream >> messageID;
00413
00414 switch (messageID)
00415 {
00416 case REQ_BROADCAST:
00417 out_stream << Q_UINT32 (MSG_BROADCAST) << clientID;
00418
00419
00420
00421 out_buffer.QIODevice::writeBlock (in_buffer.readAll());
00422 broadcastMessage (out_msg);
00423 break;
00424
00425 case REQ_FORWARD:
00426 {
00427 QValueList <Q_UINT32> clients;
00428 in_stream >> clients;
00429 out_stream << Q_UINT32 (MSG_FORWARD) << clientID << clients;
00430
00431 out_buffer.QIODevice::writeBlock (in_buffer.readAll());
00432 sendMessage (clients, out_msg);
00433 }
00434 break;
00435
00436 case REQ_CLIENT_ID:
00437 out_stream << Q_UINT32 (ANS_CLIENT_ID) << clientID;
00438 sendMessage (clientID, out_msg);
00439 break;
00440
00441 case REQ_ADMIN_ID:
00442 out_stream << Q_UINT32 (ANS_ADMIN_ID) << d->mAdminID;
00443 sendMessage (clientID, out_msg);
00444 break;
00445
00446 case REQ_ADMIN_CHANGE:
00447 if (clientID == d->mAdminID)
00448 {
00449 Q_UINT32 newAdmin;
00450 in_stream >> newAdmin;
00451 setAdmin (newAdmin);
00452 }
00453 break;
00454
00455 case REQ_REMOVE_CLIENT:
00456 if (clientID == d->mAdminID)
00457 {
00458 QValueList <Q_UINT32> client_list;
00459 in_stream >> client_list;
00460 for (QValueListIterator <Q_UINT32> iter = client_list.begin(); iter != client_list.end(); ++iter)
00461 {
00462 KMessageIO *client = findClient (*iter);
00463 if (client)
00464 removeClient (client, false);
00465 else
00466 kdWarning (11001) << k_funcinfo << ": removing non-existing clientID" << endl;
00467 }
00468 }
00469 break;
00470
00471 case REQ_MAX_NUM_CLIENTS:
00472 if (clientID == d->mAdminID)
00473 {
00474 Q_INT32 maximum_clients;
00475 in_stream >> maximum_clients;
00476 setMaxClients (maximum_clients);
00477 }
00478 break;
00479
00480 case REQ_CLIENT_LIST:
00481 {
00482 out_stream << Q_UINT32 (ANS_CLIENT_LIST) << clientIDs();
00483 sendMessage (clientID, out_msg);
00484 }
00485 break;
00486
00487 default:
00488 unknown = true;
00489 }
00490
00491
00492 if (!unknown && !in_buffer.atEnd())
00493 kdWarning (11001) << k_funcinfo << ": Extra data received for message ID " << messageID << endl;
00494
00495 emit messageReceived (msg_buf->data, clientID, unknown);
00496
00497 if (unknown)
00498 kdWarning (11001) << k_funcinfo << ": received unknown message ID " << messageID << endl;
00499
00500
00501 d->mMessageQueue.remove();
00502 if (d->mMessageQueue.isEmpty())
00503 d->mTimer.stop();
00504 d->mIsRecursive = false;
00505 }
00506
00507 void KMessageServer::Debug()
00508 {
00509 kdDebug(11001) << "------------------ KMESSAGESERVER -----------------------" << endl;
00510 kdDebug(11001) << "MaxClients : " << maxClients() << endl;
00511 kdDebug(11001) << "NoOfClients : " << clientCount() << endl;
00512 kdDebug(11001) << "---------------------------------------------------" << endl;
00513 }
00514
00515 #include "kmessageserver.moc"