20 #include <tqiodevice.h>
22 #include <tqptrlist.h>
23 #include <tqptrqueue.h>
25 #include <tqvaluelist.h>
29 #include "kmessageio.h"
30 #include "kmessageserver.h"
34 KMessageServerSocket::KMessageServerSocket (TQ_UINT16 port, TQObject *parent)
35 : TQServerSocket (port, 0, parent)
39 KMessageServerSocket::~KMessageServerSocket ()
43 void KMessageServerSocket::newConnection (
int socket)
53 MessageBuffer (TQ_UINT32 clientID,
const TQByteArray &messageData)
54 : id (clientID), data (messageData) { }
62 class 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), TQT_SIGNAL (timeout()),
97 kdDebug(11001) <<
"CREATE(KMessageServer="
106 KMessageServer::~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, TQT_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, TQT_SIGNAL (connectionBroken()),
187 this, TQT_SLOT (removeBrokenClient()));
188 connect (client, TQT_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();
253 void 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;
421 TQT_TQIODEVICE(&out_buffer)->writeBlock (in_buffer.readAll());
427 TQValueList <TQ_UINT32> clients;
428 in_stream >> clients;
429 out_stream << TQ_UINT32 (MSG_FORWARD) << clientID << clients;
431 TQT_TQIODEVICE(&out_buffer)->writeBlock (in_buffer.readAll());
437 out_stream << TQ_UINT32 (ANS_CLIENT_ID) << clientID;
442 out_stream << TQ_UINT32 (ANS_ADMIN_ID) << d->mAdminID;
446 case REQ_ADMIN_CHANGE:
447 if (clientID == d->mAdminID)
450 in_stream >> newAdmin;
455 case REQ_REMOVE_CLIENT:
456 if (clientID == d->mAdminID)
458 TQValueList <TQ_UINT32> client_list;
459 in_stream >> client_list;
460 for (TQValueListIterator <TQ_UINT32> iter = client_list.begin(); iter != client_list.end(); ++iter)
466 kdWarning (11001) << k_funcinfo <<
": removing non-existing clientID" << endl;
471 case REQ_MAX_NUM_CLIENTS:
472 if (clientID == d->mAdminID)
474 TQ_INT32 maximum_clients;
475 in_stream >> maximum_clients;
480 case REQ_CLIENT_LIST:
482 out_stream << TQ_UINT32 (ANS_CLIENT_LIST) <<
clientIDs();
492 if (!unknown && !in_buffer.atEnd())
493 kdWarning (11001) << k_funcinfo <<
": Extra data received for message ID " << messageID << endl;
498 kdWarning (11001) << k_funcinfo <<
": received unknown message ID " << messageID << endl;
501 d->mMessageQueue.remove();
502 if (d->mMessageQueue.isEmpty())
504 d->mIsRecursive =
false;
509 kdDebug(11001) <<
"------------------ KMESSAGESERVER -----------------------" << endl;
510 kdDebug(11001) <<
"MaxClients : " <<
maxClients() << endl;
511 kdDebug(11001) <<
"NoOfClients : " <<
clientCount() << endl;
512 kdDebug(11001) <<
"---------------------------------------------------" << endl;
515 #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.