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), TQ_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, 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();
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)
314 if (adminID == d->mAdminID)
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" TQ_UINT32 uniqueClientNumber() const
KMessageIO * findClient(TQ_UINT32 no) const
Find the KMessageIO object to the given client number.
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_UINT16 serverPort() const
Returns the TCP/IP port number we are listening to for incoming connections.
int clientCount() const
returns the current number of connected clients.
This class implements the message communication using a TCP/IP socket.
virtual void Debug()
Gives debug output of the game status.
void removeClient(KMessageIO *io, bool broken)
Removes the KMessageIO object from the client list and deletes it.
Internal class of KMessageServer.
void addClient(KMessageIO *)
Adds a new KMessageIO object to the communication server.
void clientConnected(KMessageIO *client)
A new client connected to the game.
void deleteClients()
Deletes all connections to the clients.
TQ_UINT32 adminID() const
Returns the clientID of the admin, if there is a admin, 0 otherwise.
KMessageServer(TQ_UINT16 cookie=42, TQObject *parent=0)
Create a KGameNetwork object.
void messageReceived(const TQByteArray &data, TQ_UINT32 clientID, bool &unknown)
This signal is always emitted when a message from a client is received.
This abstract base class represents one end of a message connections between two clients.
bool initNetwork(TQ_UINT16 port=0)
Starts the Communication server to listen for incoming TCP/IP connections.
void setId(TQ_UINT32 id)
Sets the ID number of this object.
void setAdmin(TQ_UINT32 adminID)
Sets the admin to a new client with the given ID.
virtual void getReceivedMessage(const TQByteArray &msg)
This slot receives all the messages from the KMessageIO::received signals.
virtual void processOneMessage()
This slot is called whenever there are elements in the message queue.
virtual void sendMessage(TQ_UINT32 id, const TQByteArray &msg)
Sends a message to a single client with the given ID.
TQValueList< TQ_UINT32 > clientIDs() const
returns a list of the unique IDs of all clients.
virtual void broadcastMessage(const TQByteArray &msg)
Sends a message to all connected clients.
bool isOfferingConnections() const
Are we still offer offering server connections?
int maxClients() const
returns the maximum number of clients
TQ_UINT32 id()
Queries the ID of this object.
void connectionLost(KMessageIO *client)
A network connection got broken.
void setMaxClients(int maxnumber)
sets the maximum number of clients which can connect.
void stopNetwork()
Stops listening for connections.