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"