diff options
Diffstat (limited to 'libkdegames/kgame/kmessageserver.cpp')
-rw-r--r-- | libkdegames/kgame/kmessageserver.cpp | 515 |
1 files changed, 0 insertions, 515 deletions
diff --git a/libkdegames/kgame/kmessageserver.cpp b/libkdegames/kgame/kmessageserver.cpp deleted file mode 100644 index 80df9207..00000000 --- a/libkdegames/kgame/kmessageserver.cpp +++ /dev/null @@ -1,515 +0,0 @@ -/* - This file is part of the KDE games library - Copyright (C) 2001 Burkhard Lehner ([email protected]) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License version 2 as published by the Free Software Foundation. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include <tqiodevice.h> -#include <tqbuffer.h> -#include <tqptrlist.h> -#include <tqptrqueue.h> -#include <tqtimer.h> -#include <tqvaluelist.h> - -#include <kdebug.h> - -#include "kmessageio.h" -#include "kmessageserver.h" - -// --------------- internal class KMessageServerSocket - -KMessageServerSocket::KMessageServerSocket (TQ_UINT16 port, TQObject *parent) - : TQServerSocket (port, 0, parent) -{ -} - -KMessageServerSocket::~KMessageServerSocket () -{ -} - -void KMessageServerSocket::newConnection (int socket) -{ - emit newClientConnected (new KMessageSocket (socket)); -} - -// ---------------- class for storing an incoming message - -class MessageBuffer -{ - public: - MessageBuffer (TQ_UINT32 clientID, const TQByteArray &messageData) - : id (clientID), data (messageData) { } - ~MessageBuffer () {} - TQ_UINT32 id; - TQByteArray data; -}; - -// ---------------- KMessageServer's private class - -class KMessageServerPrivate -{ -public: - KMessageServerPrivate() - : mMaxClients (-1), mGameId (1), mUniqueClientNumber (1), mAdminID (0), mServerSocket (0) - { - mClientList.setAutoDelete (true); - mMessageQueue.setAutoDelete (true); - } - - int mMaxClients; - int mGameId; - TQ_UINT16 mCookie; - TQ_UINT32 mUniqueClientNumber; - TQ_UINT32 mAdminID; - - KMessageServerSocket* mServerSocket; - - TQPtrList <KMessageIO> mClientList; - TQPtrQueue <MessageBuffer> mMessageQueue; - TQTimer mTimer; - bool mIsRecursive; -}; - - -// ------------------ KMessageServer - -KMessageServer::KMessageServer (TQ_UINT16 cookie,TQObject* parent) - : TQObject(parent, 0) -{ - d = new KMessageServerPrivate; - d->mIsRecursive=false; - d->mCookie=cookie; - connect (&(d->mTimer), TQT_SIGNAL (timeout()), - this, TQT_SLOT (processOneMessage())); - kdDebug(11001) << "CREATE(KMessageServer=" - << this - << ") cookie=" - << d->mCookie - << " sizeof(this)=" - << sizeof(KMessageServer) - << endl; -} - -KMessageServer::~KMessageServer() -{ - kdDebug(11001) << k_funcinfo << "this=" << this << endl; - Debug(); - stopNetwork(); - deleteClients(); - delete d; - kdDebug(11001) << k_funcinfo << " done" << endl; -} - -//------------------------------------- TCP/IP server stuff - -bool KMessageServer::initNetwork (TQ_UINT16 port) -{ - kdDebug(11001) << k_funcinfo << endl; - - if (d->mServerSocket) - { - kdDebug (11001) << k_funcinfo << ": We were already offering connections!" << endl; - delete d->mServerSocket; - } - - d->mServerSocket = new KMessageServerSocket (port); - d->mIsRecursive = false; - - if (!d->mServerSocket || !d->mServerSocket->ok()) - { - kdError(11001) << k_funcinfo << ": Serversocket::ok() == false" << endl; - delete d->mServerSocket; - d->mServerSocket=0; - return false; - } - - kdDebug (11001) << k_funcinfo << ": Now listening to port " - << d->mServerSocket->port() << endl; - connect (d->mServerSocket, TQT_SIGNAL (newClientConnected (KMessageIO*)), - this, TQT_SLOT (addClient (KMessageIO*))); - return true; -} - -TQ_UINT16 KMessageServer::serverPort () const -{ - if (d->mServerSocket) - return d->mServerSocket->port(); - else - return 0; -} - -void KMessageServer::stopNetwork() -{ - if (d->mServerSocket) - { - delete d->mServerSocket; - d->mServerSocket = 0; - } -} - -bool KMessageServer::isOfferingConnections() const -{ - return d->mServerSocket != 0; -} - -//----------------------------------------------- adding / removing clients - -void KMessageServer::addClient (KMessageIO* client) -{ - TQByteArray msg; - - // maximum number of clients reached? - if (d->mMaxClients >= 0 && d->mMaxClients <= clientCount()) - { - kdError (11001) << k_funcinfo << ": Maximum number of clients reached!" << endl; - return; - } - - // give it a unique ID - client->setId (uniqueClientNumber()); - kdDebug (11001) << k_funcinfo << ": " << client->id() << endl; - - // connect its signals - connect (client, TQT_SIGNAL (connectionBroken()), - this, TQT_SLOT (removeBrokenClient())); - connect (client, TQT_SIGNAL (received (const TQByteArray &)), - this, TQT_SLOT (getReceivedMessage (const TQByteArray &))); - - // Tell everyone about the new guest - // Note: The new client doesn't get this message! - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (EVNT_CLIENT_CONNECTED) << client->id(); - broadcastMessage (msg); - - // add to our list - d->mClientList.append (client); - - // tell it its ID - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_CLIENT_ID) << client->id(); - client->send (msg); - - // Give it the complete list of client IDs - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_CLIENT_LIST) << clientIDs(); - client->send (msg); - - - if (clientCount() == 1) - { - // if it is the first client, it becomes the admin - setAdmin (client->id()); - } - else - { - // otherwise tell it who is the admin - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_ADMIN_ID) << adminID(); - client->send (msg); - } - - emit clientConnected (client); -} - -void KMessageServer::removeClient (KMessageIO* client, bool broken) -{ - TQ_UINT32 clientID = client->id(); - if (!d->mClientList.removeRef (client)) - { - kdError(11001) << k_funcinfo << ": Deleting client that wasn't added before!" << endl; - return; - } - - // tell everyone about the removed client - TQByteArray msg; - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (EVNT_CLIENT_DISCONNECTED) << client->id() << (TQ_INT8)broken; - broadcastMessage (msg); - - // If it was the admin, select a new admin. - if (clientID == adminID()) - { - if (!d->mClientList.isEmpty()) - setAdmin (d->mClientList.first()->id()); - else - setAdmin (0); - } -} - -void KMessageServer::deleteClients() -{ - d->mClientList.clear(); - d->mAdminID = 0; -} - -void KMessageServer::removeBrokenClient () -{ - if (!sender()->inherits ("KMessageIO")) - { - kdError (11001) << k_funcinfo << ": sender of the signal was not a KMessageIO object!" << endl; - return; - } - - KMessageIO *client = (KMessageIO *) sender(); - - emit connectionLost (client); - removeClient (client, true); -} - - -void KMessageServer::setMaxClients(int c) -{ - d->mMaxClients = c; -} - -int KMessageServer::maxClients() const -{ - return d->mMaxClients; -} - -int KMessageServer::clientCount() const -{ - return d->mClientList.count(); -} - -TQValueList <TQ_UINT32> KMessageServer::clientIDs () const -{ - TQValueList <TQ_UINT32> list; - for (TQPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter) - list.append ((*iter)->id()); - return list; -} - -KMessageIO* KMessageServer::findClient (TQ_UINT32 no) const -{ - if (no == 0) - no = d->mAdminID; - - TQPtrListIterator <KMessageIO> iter (d->mClientList); - while (*iter) - { - if ((*iter)->id() == no) - return (*iter); - ++iter; - } - return 0; -} - -TQ_UINT32 KMessageServer::adminID () const -{ - return d->mAdminID; -} - -void KMessageServer::setAdmin (TQ_UINT32 adminID) -{ - // Trying to set the the client that is already admin => nothing to do - if (adminID == d->mAdminID) - return; - - if (adminID > 0 && findClient (adminID) == 0) - { - kdWarning (11001) << "Trying to set a new admin that doesn't exist!" << endl; - return; - } - - d->mAdminID = adminID; - - TQByteArray msg; - TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_ADMIN_ID) << adminID; - - // Tell everyone about the new master - broadcastMessage (msg); -} - - -//------------------------------------------- ID stuff - -TQ_UINT32 KMessageServer::uniqueClientNumber() const -{ - return d->mUniqueClientNumber++; -} - -// --------------------- Messages --------------------------- - -void KMessageServer::broadcastMessage (const TQByteArray &msg) -{ - for (TQPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter) - (*iter)->send (msg); -} - -void KMessageServer::sendMessage (TQ_UINT32 id, const TQByteArray &msg) -{ - KMessageIO *client = findClient (id); - if (client) - client->send (msg); -} - -void KMessageServer::sendMessage (const TQValueList <TQ_UINT32> &ids, const TQByteArray &msg) -{ - for (TQValueListConstIterator <TQ_UINT32> iter = ids.begin(); iter != ids.end(); ++iter) - sendMessage (*iter, msg); -} - -void KMessageServer::getReceivedMessage (const TQByteArray &msg) -{ - if (!sender() || !sender()->inherits("KMessageIO")) - { - kdError (11001) << k_funcinfo << ": slot was not called from KMessageIO!" << endl; - return; - } - //kdDebug(11001) << k_funcinfo << ": size=" << msg.size() << endl; - KMessageIO *client = (KMessageIO *) sender(); - TQ_UINT32 clientID = client->id(); - - //TQByteArray *ta=new TQByteArray; - //ta->duplicate(msg); - //d->mMessageQueue.enqueue (new MessageBuffer (clientID, *ta)); - - - d->mMessageQueue.enqueue (new MessageBuffer (clientID, msg)); - if (!d->mTimer.isActive()) - d->mTimer.start(0); // AB: should be , TRUE i guess -} - -void KMessageServer::processOneMessage () -{ - // This shouldn't happen, since the timer should be stopped before. But only to be sure! - if (d->mMessageQueue.isEmpty()) - { - d->mTimer.stop(); - return; - } - if (d->mIsRecursive) - { - return; - } - d->mIsRecursive = true; - - MessageBuffer *msg_buf = d->mMessageQueue.head(); - - TQ_UINT32 clientID = msg_buf->id; - TQBuffer in_buffer (msg_buf->data); - in_buffer.open (IO_ReadOnly); - TQDataStream in_stream (&in_buffer); - - TQByteArray out_msg; - TQBuffer out_buffer (out_msg); - out_buffer.open (IO_WriteOnly); - TQDataStream out_stream (&out_buffer); - - bool unknown = false; - - TQByteArray ttt=in_buffer.buffer(); - TQ_UINT32 messageID; - in_stream >> messageID; - //kdDebug(11001) << k_funcinfo << ": got message with messageID=" << messageID << endl; - switch (messageID) - { - case RETQ_BROADCAST: - out_stream << TQ_UINT32 (MSG_BROADCAST) << clientID; - // FIXME, compiler bug? - // this should be okay, since TQBuffer is subclass of TQIODevice! : - // out_buffer.writeBlock (in_buffer.readAll()); - TQT_TQIODEVICE(&out_buffer)->writeBlock (in_buffer.readAll()); - broadcastMessage (out_msg); - break; - - case RETQ_FORWARD: - { - TQValueList <TQ_UINT32> clients; - in_stream >> clients; - out_stream << TQ_UINT32 (MSG_FORWARD) << clientID << clients; - // see above! - TQT_TQIODEVICE(&out_buffer)->writeBlock (in_buffer.readAll()); - sendMessage (clients, out_msg); - } - break; - - case RETQ_CLIENT_ID: - out_stream << TQ_UINT32 (ANS_CLIENT_ID) << clientID; - sendMessage (clientID, out_msg); - break; - - case RETQ_ADMIN_ID: - out_stream << TQ_UINT32 (ANS_ADMIN_ID) << d->mAdminID; - sendMessage (clientID, out_msg); - break; - - case RETQ_ADMIN_CHANGE: - if (clientID == d->mAdminID) - { - TQ_UINT32 newAdmin; - in_stream >> newAdmin; - setAdmin (newAdmin); - } - break; - - case RETQ_REMOVE_CLIENT: - if (clientID == d->mAdminID) - { - TQValueList <TQ_UINT32> client_list; - in_stream >> client_list; - for (TQValueListIterator <TQ_UINT32> iter = client_list.begin(); iter != client_list.end(); ++iter) - { - KMessageIO *client = findClient (*iter); - if (client) - removeClient (client, false); - else - kdWarning (11001) << k_funcinfo << ": removing non-existing clientID" << endl; - } - } - break; - - case RETQ_MAX_NUM_CLIENTS: - if (clientID == d->mAdminID) - { - TQ_INT32 maximum_clients; - in_stream >> maximum_clients; - setMaxClients (maximum_clients); - } - break; - - case RETQ_CLIENT_LIST: - { - out_stream << TQ_UINT32 (ANS_CLIENT_LIST) << clientIDs(); - sendMessage (clientID, out_msg); - } - break; - - default: - unknown = true; - } - - // check if all the data has been used - if (!unknown && !in_buffer.atEnd()) - kdWarning (11001) << k_funcinfo << ": Extra data received for message ID " << messageID << endl; - - emit messageReceived (msg_buf->data, clientID, unknown); - - if (unknown) - kdWarning (11001) << k_funcinfo << ": received unknown message ID " << messageID << endl; - - // remove the message, since we are ready with it - d->mMessageQueue.remove(); - if (d->mMessageQueue.isEmpty()) - d->mTimer.stop(); - d->mIsRecursive = false; -} - -void KMessageServer::Debug() -{ - kdDebug(11001) << "------------------ KMESSAGESERVER -----------------------" << endl; - kdDebug(11001) << "MaxClients : " << maxClients() << endl; - kdDebug(11001) << "NoOfClients : " << clientCount() << endl; - kdDebug(11001) << "---------------------------------------------------" << endl; -} - -#include "kmessageserver.moc" |