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