• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • libtdegames
 

libtdegames

  • libtdegames
  • kgame
kmessageclient.cpp
1 /*
2  This file is part of the TDE games library
3  Copyright (C) 2001 Burkhard Lehner (Burkhard.Lehner@gmx.de)
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License version 2 as published by the Free Software Foundation.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Library General Public License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include <kdebug.h>
21 #include <stdio.h>
22 
23 #include <tqbuffer.h>
24 #include <tqtimer.h>
25 
26 #include "kmessageio.h"
27 #include "kmessageserver.h"
28 
29 #include "kmessageclient.h"
30 
31 class KMessageClientPrivate
32 {
33 public:
34  KMessageClientPrivate ()
35  : adminID (0), connection (0)
36  {}
37 
38  ~KMessageClientPrivate ()
39  {
40  delete connection;
41  }
42 
43  TQ_UINT32 adminID;
44  TQValueList <TQ_UINT32> clientList;
45  KMessageIO *connection;
46 
47  bool isLocked;
48  TQValueList <TQByteArray> delayedMessages;
49 };
50 
51 KMessageClient::KMessageClient (TQObject *parent, const char *name)
52  : TQObject (parent, name)
53 {
54  d = new KMessageClientPrivate ();
55  d->isLocked = false;
56 }
57 
58 KMessageClient::~KMessageClient ()
59 {
60  d->delayedMessages.clear();
61  delete d;
62 }
63 
64 // -- setServer stuff
65 
66 void KMessageClient::setServer (const TQString &host, TQ_UINT16 port)
67 {
68  setServer (new KMessageSocket (host, port));
69 }
70 
71 void KMessageClient::setServer (KMessageServer *server)
72 {
73  KMessageDirect *serverIO = new KMessageDirect ();
74  setServer (new KMessageDirect (serverIO));
75  server->addClient (serverIO);
76 }
77 
78 void KMessageClient::setServer (KMessageIO *connection)
79 {
80  if (d->connection)
81  {
82  delete d->connection;
83  kdDebug (11001) << k_funcinfo << ": We are changing the server!" << endl;
84  }
85 
86  d->connection = connection;
87  if (connection )
88  {
89  connect (connection, TQ_SIGNAL (received(const TQByteArray &)),
90  this, TQ_SLOT (processIncomingMessage(const TQByteArray &)));
91  connect (connection, TQ_SIGNAL (connectionBroken()),
92  this, TQ_SLOT (removeBrokenConnection ()));
93  }
94 }
95 
96 // -- id stuff
97 
98 TQ_UINT32 KMessageClient::id () const
99 {
100  return (d->connection) ? d->connection->id () : 0;
101 }
102 
103 bool KMessageClient::isAdmin () const
104 {
105  return id() != 0 && id() == adminId();
106 }
107 
108 TQ_UINT32 KMessageClient::adminId () const
109 {
110  return d->adminID;
111 }
112 
113 const TQValueList <TQ_UINT32> &KMessageClient::clientList() const
114 {
115  return d->clientList;
116 }
117 
118 bool KMessageClient::isConnected () const
119 {
120  return d->connection && d->connection->isConnected();
121 }
122 
123 bool KMessageClient::isNetwork () const
124 {
125  return isConnected() ? d->connection->isNetwork() : false;
126 }
127 
128 TQ_UINT16 KMessageClient::peerPort () const
129 {
130  return d->connection ? d->connection->peerPort() : 0;
131 }
132 
133 TQString KMessageClient::peerName () const
134 {
135  return d->connection ? d->connection->peerName() : TQString::fromLatin1("localhost");
136 }
137 
138 // --------------------- Sending messages
139 
140 void KMessageClient::sendServerMessage (const TQByteArray &msg)
141 {
142  if (!d->connection)
143  {
144  kdWarning (11001) << k_funcinfo << ": We have no connection yet!" << endl;
145  return;
146  }
147  d->connection->send (msg);
148 }
149 
150 void KMessageClient::sendBroadcast (const TQByteArray &msg)
151 {
152  TQByteArray sendBuffer;
153  TQBuffer buffer (sendBuffer);
154  buffer.open (IO_WriteOnly);
155  TQDataStream stream (&buffer);
156 
157  stream << static_cast<TQ_UINT32> ( KMessageServer::REQ_BROADCAST );
158  buffer.writeBlock (msg);
159  sendServerMessage (sendBuffer);
160 }
161 
162 void KMessageClient::sendForward (const TQByteArray &msg, const TQValueList <TQ_UINT32> &clients)
163 {
164  TQByteArray sendBuffer;
165  TQBuffer buffer (sendBuffer);
166  buffer.open (IO_WriteOnly);
167  TQDataStream stream (&buffer);
168 
169  stream << static_cast<TQ_UINT32>( KMessageServer::REQ_FORWARD ) << clients;
170  buffer.writeBlock (msg);
171  sendServerMessage (sendBuffer);
172 }
173 
174 void KMessageClient::sendForward (const TQByteArray &msg, TQ_UINT32 client)
175 {
176  sendForward (msg, TQValueList <TQ_UINT32> () << client);
177 }
178 
179 
180 // --------------------- Receiving and processing messages
181 
182 void KMessageClient::processIncomingMessage (const TQByteArray &msg)
183 {
184  if (d->isLocked)
185  {
186  d->delayedMessages.append(msg);
187  return;
188  }
189  if (d->delayedMessages.count() > 0)
190  {
191  d->delayedMessages.append (msg);
192  TQByteArray first = d->delayedMessages.front();
193  d->delayedMessages.pop_front();
194  processMessage (first);
195  }
196  else
197  {
198  processMessage(msg);
199  }
200 }
201 
202 void KMessageClient::processMessage (const TQByteArray &msg)
203 {
204  if (d->isLocked)
205  { // must NOT happen, since we check in processIncomingMessage as well as in processFirstMessage
206  d->delayedMessages.append(msg);
207  return;
208  }
209  TQBuffer in_buffer (msg);
210  in_buffer.open (IO_ReadOnly);
211  TQDataStream in_stream (&in_buffer);
212 
213 
214  bool unknown = false;
215 
216  TQ_UINT32 messageID;
217  in_stream >> messageID;
218  switch (messageID)
219  {
220  case KMessageServer::MSG_BROADCAST:
221  {
222  TQ_UINT32 clientID;
223  in_stream >> clientID;
224  emit broadcastReceived (in_buffer.readAll(), clientID);
225  }
226  break;
227 
228  case KMessageServer::MSG_FORWARD:
229  {
230  TQ_UINT32 clientID;
231  TQValueList <TQ_UINT32> receivers;
232  in_stream >> clientID >> receivers;
233  emit forwardReceived (in_buffer.readAll(), clientID, receivers);
234  }
235  break;
236 
237  case KMessageServer::ANS_CLIENT_ID:
238  {
239  bool old_admin = isAdmin();
240  TQ_UINT32 clientID;
241  in_stream >> clientID;
242  d->connection->setId (clientID);
243  if (old_admin != isAdmin())
244  emit adminStatusChanged (isAdmin());
245  }
246  break;
247 
248  case KMessageServer::ANS_ADMIN_ID:
249  {
250  bool old_admin = isAdmin();
251  in_stream >> d->adminID;
252  if (old_admin != isAdmin())
253  emit adminStatusChanged (isAdmin());
254  }
255  break;
256 
257  case KMessageServer::ANS_CLIENT_LIST:
258  {
259  in_stream >> d->clientList;
260  }
261  break;
262 
263  case KMessageServer::EVNT_CLIENT_CONNECTED:
264  {
265  TQ_UINT32 id;
266  in_stream >> id;
267 
268  if (d->clientList.contains (id))
269  kdWarning (11001) << k_funcinfo << ": Adding a client that already existed!" << endl;
270  else
271  d->clientList.append (id);
272 
273  emit eventClientConnected (id);
274  }
275  break;
276 
277  case KMessageServer::EVNT_CLIENT_DISCONNECTED:
278  {
279  TQ_UINT32 id;
280  TQ_INT8 broken;
281  in_stream >> id >> broken;
282 
283  if (!d->clientList.contains (id))
284  kdWarning (11001) << k_funcinfo << ": Removing a client that doesn't exist!" << endl;
285  else
286  d->clientList.remove (id);
287 
288  emit eventClientDisconnected (id, bool (broken));
289  }
290  break;
291 
292  default:
293  unknown = true;
294  }
295 
296  if (!unknown && !in_buffer.atEnd())
297  kdWarning (11001) << k_funcinfo << ": Extra data received for message ID " << messageID << endl;
298 
299  emit serverMessageReceived (msg, unknown);
300 
301  if (unknown)
302  kdWarning (11001) << k_funcinfo << ": received unknown message ID " << messageID << endl;
303 }
304 
305 void KMessageClient::processFirstMessage()
306 {
307  if (d->isLocked)
308  {
309  return;
310  }
311  if (d->delayedMessages.count() == 0)
312  {
313  kdDebug(11001) << k_funcinfo << ": no messages delayed" << endl;
314  return;
315  }
316  TQByteArray first = d->delayedMessages.front();
317  d->delayedMessages.pop_front();
318  processMessage (first);
319 }
320 
321 void KMessageClient::removeBrokenConnection ()
322 {
323  kdDebug (11001) << k_funcinfo << ": timer single shot for removeBrokenConnection"<<this << endl;
324  // MH We cannot directly delete the socket. otherwise TQSocket crashes
325  TQTimer::singleShot( 0, this, TQ_SLOT(removeBrokenConnection2()) );
326  return;
327 }
328 
329 
330 void KMessageClient::removeBrokenConnection2 ()
331 {
332  kdDebug (11001) << k_funcinfo << ": Broken:Deleting the connection object"<<this << endl;
333 
334  emit aboutToDisconnect(id());
335  delete d->connection;
336  d->connection = 0;
337  d->adminID = 0;
338  emit connectionBroken();
339  kdDebug (11001) << k_funcinfo << ": Broken:Deleting the connection object DONE" << endl;
340 }
341 
342 void KMessageClient::disconnect ()
343 {
344  kdDebug (11001) << k_funcinfo << ": Disconnect:Deleting the connection object" << endl;
345 
346  emit aboutToDisconnect(id());
347  delete d->connection;
348  d->connection = 0;
349  d->adminID = 0;
350  emit connectionBroken();
351  kdDebug (11001) << k_funcinfo << ": Disconnect:Deleting the connection object DONE" << endl;
352 }
353 
354 void KMessageClient::lock ()
355 {
356  d->isLocked = true;
357 }
358 
359 void KMessageClient::unlock ()
360 {
361  d->isLocked = false;
362  for (unsigned int i = 0; i < d->delayedMessages.count(); i++)
363  {
364  TQTimer::singleShot(0, this, TQ_SLOT(processFirstMessage()));
365  }
366 }
367 
368 unsigned int KMessageClient::delayedMessageCount() const
369 {
370  return d->delayedMessages.count();
371 }
372 
373 #include "kmessageclient.moc"
KMessageClient::eventClientDisconnected
void eventClientDisconnected(TQ_UINT32 clientID, bool broken)
This signal is emitted when the server has lost the connection to one of the clients (This could be b...
KMessageClient::sendBroadcast
void sendBroadcast(const TQByteArray &msg)
Sends a message to all the clients connected to the server, including ourself.
Definition: kmessageclient.cpp:150
KMessageClient::sendForward
void sendForward(const TQByteArray &msg, const TQValueList< TQ_UINT32 > &clients)
Sends a message to all the clients in a list.
Definition: kmessageclient.cpp:162
KMessageClient::delayedMessageCount
unsigned int delayedMessageCount() const
Definition: kmessageclient.cpp:368
KMessageSocket
This class implements the message communication using a TCP/IP socket.
Definition: kmessageio.h:170
KMessageClient::aboutToDisconnect
void aboutToDisconnect(TQ_UINT32 id)
This signal is emitted right before the client disconnects.
KMessageClient::id
TQ_UINT32 id() const
Definition: kmessageclient.cpp:98
KMessageClient::isAdmin
bool isAdmin() const
Definition: kmessageclient.cpp:103
KMessageClient::isNetwork
bool isNetwork() const
Definition: kmessageclient.cpp:123
KMessageDirect
This class implements the message communication using function calls directly.
Definition: kmessageio.h:297
KMessageServer::addClient
void addClient(KMessageIO *)
Adds a new KMessageIO object to the communication server.
Definition: kmessageserver.cpp:170
KMessageClient::removeBrokenConnection
virtual void removeBrokenConnection()
This slot is called from the signal KMessageIO::connectionBroken.
Definition: kmessageclient.cpp:321
KMessageClient::processFirstMessage
void processFirstMessage()
Called from unlock() (using TQTimer::singleShot) until all delayed messages are delivered.
Definition: kmessageclient.cpp:305
KMessageClient::adminStatusChanged
void adminStatusChanged(bool isAdmin)
This signal is emitted when this client becomes the admin client or when it loses the admin client st...
KMessageClient::disconnect
void disconnect()
Corresponds to setServer(0); but also emits the connectionBroken signal.
Definition: kmessageclient.cpp:342
KMessageIO
This abstract base class represents one end of a message connections between two clients.
Definition: kmessageio.h:56
KMessageClient::eventClientConnected
void eventClientConnected(TQ_UINT32 clientID)
This signal is emitted when another client has connected to the server.
KMessageServer
A server for message sending and broadcasting, using TCP/IP connections.
Definition: kmessageserver.h:175
KMessageClient::clientList
const TQValueList< TQ_UINT32 > & clientList() const
Definition: kmessageclient.cpp:113
KMessageClient::serverMessageReceived
void serverMessageReceived(const TQByteArray &msg, bool &unknown)
This signal is emitted on every message that came from the server.
KMessageClient::adminId
TQ_UINT32 adminId() const
Definition: kmessageclient.cpp:108
KMessageClient::peerPort
TQ_UINT16 peerPort() const
Definition: kmessageclient.cpp:128
KMessageClient::isConnected
bool isConnected() const
Definition: kmessageclient.cpp:118
KMessageClient::lock
void lock()
Once this function is called no message will be received anymore.
Definition: kmessageclient.cpp:354
KMessageClient::forwardReceived
void forwardReceived(const TQByteArray &msg, TQ_UINT32 senderID, const TQValueList< TQ_UINT32 > &receivers)
This signal is emitted when the client receives a forward message from the KMessageServer, sent by another client.
KMessageClient::broadcastReceived
void broadcastReceived(const TQByteArray &msg, TQ_UINT32 senderID)
This signal is emitted when the client receives a broadcast message from the KMessageServer, sent by another client.
KMessageClient::connectionBroken
void connectionBroken()
This signal is emitted when the connection to the KMessageServer is broken.
KMessageClient::sendServerMessage
void sendServerMessage(const TQByteArray &msg)
Sends a message to the KMessageServer.
Definition: kmessageclient.cpp:140
KMessageClient::KMessageClient
KMessageClient(TQObject *parent=0, const char *name=0)
Constructor.
Definition: kmessageclient.cpp:51
KMessageClient::unlock
void unlock()
Deliver every message that was delayed by lock() and actually deliver all messages that get received ...
Definition: kmessageclient.cpp:359
KMessageClient::processIncomingMessage
virtual void processIncomingMessage(const TQByteArray &msg)
This slot is called from the signal KMessageIO::received whenever a message from the KMessageServer a...
Definition: kmessageclient.cpp:182
KMessageClient::setServer
void setServer(const TQString &host, TQ_UINT16 port)
Connects the client to (another) server.
Definition: kmessageclient.cpp:66
KMessageClient::processMessage
virtual void processMessage(const TQByteArray &msg)
This slot is called from processIncomingMessage or processFirstMessage, depending on whether the clie...
Definition: kmessageclient.cpp:202
KMessageClient::~KMessageClient
~KMessageClient()
Destructor.
Definition: kmessageclient.cpp:58
KMessageClient::peerName
TQString peerName() const
Definition: kmessageclient.cpp:133

libtdegames

Skip menu "libtdegames"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

libtdegames

Skip menu "libtdegames"
  • libtdegames
Generated for libtdegames by doxygen 1.8.13
This website is maintained by Timothy Pearson.