20#include <tqiodevice.h>
23#include <tqptrqueue.h>
25#include <tqvaluelist.h>
29#include "kmessageio.h"
30#include "kmessageserver.h"
34KMessageServerSocket::KMessageServerSocket (TQ_UINT16 port, TQObject *parent)
35 : TQServerSocket (port, 0, parent)
39KMessageServerSocket::~KMessageServerSocket ()
43void KMessageServerSocket::newConnection (
int socket)
53 MessageBuffer (TQ_UINT32 clientID,
const TQByteArray &messageData)
54 : id (clientID), data (messageData) { }
62class KMessageServerPrivate
65 KMessageServerPrivate()
66 : mMaxClients (-1), mGameId (1), mUniqueClientNumber (1), mAdminID (0), mServerSocket (0)
68 mClientList.setAutoDelete (
true);
69 mMessageQueue.setAutoDelete (
true);
75 TQ_UINT32 mUniqueClientNumber;
80 TQPtrList <KMessageIO> mClientList;
81 TQPtrQueue <MessageBuffer> mMessageQueue;
92 d =
new KMessageServerPrivate;
93 d->mIsRecursive=
false;
95 connect (&(d->mTimer), TQ_SIGNAL (timeout()),
97 kdDebug(11001) <<
"CREATE(KMessageServer="
106KMessageServer::~KMessageServer()
108 kdDebug(11001) << k_funcinfo <<
"this=" <<
this << endl;
113 kdDebug(11001) << k_funcinfo <<
" done" << endl;
120 kdDebug(11001) << k_funcinfo << endl;
122 if (d->mServerSocket)
124 kdDebug (11001) << k_funcinfo <<
": We were already offering connections!" << endl;
125 delete d->mServerSocket;
129 d->mIsRecursive =
false;
131 if (!d->mServerSocket || !d->mServerSocket->ok())
133 kdError(11001) << k_funcinfo <<
": Serversocket::ok() == false" << endl;
134 delete d->mServerSocket;
139 kdDebug (11001) << k_funcinfo <<
": Now listening to port "
140 << d->mServerSocket->port() << endl;
141 connect (d->mServerSocket, TQ_SIGNAL (newClientConnected (
KMessageIO*)),
148 if (d->mServerSocket)
149 return d->mServerSocket->port();
156 if (d->mServerSocket)
158 delete d->mServerSocket;
159 d->mServerSocket = 0;
165 return d->mServerSocket != 0;
175 if (d->mMaxClients >= 0 && d->mMaxClients <=
clientCount())
177 kdError (11001) << k_funcinfo <<
": Maximum number of clients reached!" << endl;
183 kdDebug (11001) << k_funcinfo <<
": " << client->
id() << endl;
186 connect (client, TQ_SIGNAL (connectionBroken()),
187 this, TQ_SLOT (removeBrokenClient()));
188 connect (client, TQ_SIGNAL (received (
const TQByteArray &)),
193 TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (EVNT_CLIENT_CONNECTED) << client->
id();
197 d->mClientList.append (client);
200 TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_CLIENT_ID) << client->
id();
204 TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_CLIENT_LIST) <<
clientIDs();
216 TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_ADMIN_ID) <<
adminID();
225 TQ_UINT32 clientID = client->
id();
226 if (!d->mClientList.removeRef (client))
228 kdError(11001) << k_funcinfo <<
": Deleting client that wasn't added before!" << endl;
234 TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (EVNT_CLIENT_DISCONNECTED) << client->
id() << (TQ_INT8)broken;
240 if (!d->mClientList.isEmpty())
241 setAdmin (d->mClientList.first()->id());
249 d->mClientList.clear();
253void KMessageServer::removeBrokenClient ()
255 if (!sender()->inherits (
"KMessageIO"))
257 kdError (11001) << k_funcinfo <<
": sender of the signal was not a KMessageIO object!" << endl;
275 return d->mMaxClients;
280 return d->mClientList.count();
285 TQValueList <TQ_UINT32> list;
286 for (TQPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter)
287 list.append ((*iter)->id());
296 TQPtrListIterator <KMessageIO> iter (d->mClientList);
299 if ((*iter)->id() == no)
319 kdWarning (11001) <<
"Trying to set a new admin that doesn't exist!" << endl;
326 TQDataStream (msg, IO_WriteOnly) << TQ_UINT32 (ANS_ADMIN_ID) <<
adminID;
337 return d->mUniqueClientNumber++;
344 for (TQPtrListIterator <KMessageIO> iter (d->mClientList); *iter; ++iter)
357 for (TQValueListConstIterator <TQ_UINT32> iter = ids.begin(); iter != ids.end(); ++iter)
363 if (!sender() || !sender()->inherits(
"KMessageIO"))
365 kdError (11001) << k_funcinfo <<
": slot was not called from KMessageIO!" << endl;
370 TQ_UINT32 clientID = client->
id();
377 d->mMessageQueue.enqueue (
new MessageBuffer (clientID, msg));
378 if (!d->mTimer.isActive())
385 if (d->mMessageQueue.isEmpty())
394 d->mIsRecursive =
true;
396 MessageBuffer *msg_buf = d->mMessageQueue.head();
398 TQ_UINT32 clientID = msg_buf->id;
399 TQBuffer in_buffer (msg_buf->data);
400 in_buffer.open (IO_ReadOnly);
401 TQDataStream in_stream (&in_buffer);
404 TQBuffer out_buffer (out_msg);
405 out_buffer.open (IO_WriteOnly);
406 TQDataStream out_stream (&out_buffer);
408 bool unknown =
false;
410 TQByteArray ttt=in_buffer.buffer();
412 in_stream >> messageID;
417 out_stream << TQ_UINT32 (MSG_BROADCAST) << clientID;
418 out_buffer.writeBlock (in_buffer.readAll());
424 TQValueList <TQ_UINT32> clients;
425 in_stream >> clients;
426 out_stream << TQ_UINT32 (MSG_FORWARD) << clientID << clients;
427 out_buffer.writeBlock (in_buffer.readAll());
433 out_stream << TQ_UINT32 (ANS_CLIENT_ID) << clientID;
438 out_stream << TQ_UINT32 (ANS_ADMIN_ID) << d->mAdminID;
442 case REQ_ADMIN_CHANGE:
443 if (clientID == d->mAdminID)
446 in_stream >> newAdmin;
451 case REQ_REMOVE_CLIENT:
452 if (clientID == d->mAdminID)
454 TQValueList <TQ_UINT32> client_list;
455 in_stream >> client_list;
456 for (TQValueListIterator <TQ_UINT32> iter = client_list.begin(); iter != client_list.end(); ++iter)
462 kdWarning (11001) << k_funcinfo <<
": removing non-existing clientID" << endl;
467 case REQ_MAX_NUM_CLIENTS:
468 if (clientID == d->mAdminID)
470 TQ_INT32 maximum_clients;
471 in_stream >> maximum_clients;
476 case REQ_CLIENT_LIST:
478 out_stream << TQ_UINT32 (ANS_CLIENT_LIST) <<
clientIDs();
488 if (!unknown && !in_buffer.atEnd())
489 kdWarning (11001) << k_funcinfo <<
": Extra data received for message ID " << messageID << endl;
494 kdWarning (11001) << k_funcinfo <<
": received unknown message ID " << messageID << endl;
497 d->mMessageQueue.remove();
498 if (d->mMessageQueue.isEmpty())
500 d->mIsRecursive =
false;
505 kdDebug(11001) <<
"------------------ KMESSAGESERVER -----------------------" << endl;
506 kdDebug(11001) <<
"MaxClients : " <<
maxClients() << endl;
507 kdDebug(11001) <<
"NoOfClients : " <<
clientCount() << endl;
508 kdDebug(11001) <<
"---------------------------------------------------" << endl;
511#include "kmessageserver.moc"
This abstract base class represents one end of a message connections between two clients.
virtual void send(const TQByteArray &msg)=0
This slot sends the data block in /e msg to the connected object, that will emit /e received().
TQ_UINT32 id()
Queries the ID of this object.
void setId(TQ_UINT32 id)
Sets the ID number of this object.
Internal class of KMessageServer.
void removeClient(KMessageIO *io, bool broken)
Removes the KMessageIO object from the client list and deletes it.
virtual void getReceivedMessage(const TQByteArray &msg)
This slot receives all the messages from the KMessageIO::received signals.
bool initNetwork(TQ_UINT16 port=0)
Starts the Communication server to listen for incoming TCP/IP connections.
void clientConnected(KMessageIO *client)
A new client connected to the game.
virtual void broadcastMessage(const TQByteArray &msg)
Sends a message to all connected clients.
void setMaxClients(int maxnumber)
sets the maximum number of clients which can connect.
virtual void Debug()
Gives debug output of the game status.
void addClient(KMessageIO *)
Adds a new KMessageIO object to the communication server.
KMessageServer(TQ_UINT16 cookie=42, TQObject *parent=0)
Create a KGameNetwork object.
int maxClients() const
returns the maximum number of clients
virtual void processOneMessage()
This slot is called whenever there are elements in the message queue.
TQ_UINT32 uniqueClientNumber() const
TQValueList< TQ_UINT32 > clientIDs() const
returns a list of the unique IDs of all clients.
TQ_UINT16 serverPort() const
Returns the TCP/IP port number we are listening to for incoming connections.
void connectionLost(KMessageIO *client)
A network connection got broken.
TQ_UINT32 adminID() const
Returns the clientID of the admin, if there is a admin, 0 otherwise.
void deleteClients()
Deletes all connections to the clients.
void stopNetwork()
Stops listening for connections.
void setAdmin(TQ_UINT32 adminID)
Sets the admin to a new client with the given ID.
virtual void sendMessage(TQ_UINT32 id, const TQByteArray &msg)
Sends a message to a single client with the given ID.
void messageReceived(const TQByteArray &data, TQ_UINT32 clientID, bool &unknown)
This signal is always emitted when a message from a client is received.
KMessageIO * findClient(TQ_UINT32 no) const
Find the KMessageIO object to the given client number.
bool isOfferingConnections() const
Are we still offer offering server connections?
int clientCount() const
returns the current number of connected clients.
This class implements the message communication using a TCP/IP socket.