• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdegames API Reference
  • KDE Home
  • Contact Us
 

libkdegames/libkdegamesprivate/kgame

  • sources
  • kde-4.14
  • kdegames
  • libkdegames
  • libkdegamesprivate
  • kgame
kmessageclient.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the KDE 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 "kmessageclient.h"
21 
22 #include <kdebug.h>
23 #include <stdio.h>
24 
25 #include <qbuffer.h>
26 #include <QTimer>
27 #include <QList>
28 #include <QDataStream>
29 #include "kmessageio.h"
30 #include "kmessageserver.h"
31 
32 class KMessageClientPrivate
33 {
34 public:
35  KMessageClientPrivate ()
36  : adminID (0), connection (0)
37  {}
38 
39  ~KMessageClientPrivate ()
40  {
41  delete connection;
42  }
43 
44  quint32 adminID;
45  QList <quint32> clientList;
46  KMessageIO *connection;
47 
48  bool isLocked;
49  QList <QByteArray> delayedMessages;
50 };
51 
52 KMessageClient::KMessageClient (QObject *parent)
53  : QObject (parent),
54  d( new KMessageClientPrivate )
55 {
56  d->isLocked = false;
57 }
58 
59 KMessageClient::~KMessageClient ()
60 {
61  d->delayedMessages.clear();
62  delete d;
63 }
64 
65 // -- setServer stuff
66 
67 void KMessageClient::setServer (const QString &host, quint16 port)
68 {
69  setServer (new KMessageSocket (host, port));
70 }
71 
72 void KMessageClient::setServer (KMessageServer *server)
73 {
74  KMessageDirect *serverIO = new KMessageDirect ();
75  setServer (new KMessageDirect (serverIO));
76  server->addClient (serverIO);
77 }
78 
79 void KMessageClient::setServer (KMessageIO *connection)
80 {
81  if (d->connection)
82  {
83  delete d->connection;
84  kDebug (11001) << ": We are changing the server!";
85  }
86 
87  d->connection = connection;
88  if (connection )
89  {
90  connect (connection, SIGNAL (received(QByteArray)),
91  this, SLOT (processIncomingMessage(QByteArray)));
92  connect (connection, SIGNAL (connectionBroken()),
93  this, SLOT (removeBrokenConnection()));
94  }
95 }
96 
97 // -- id stuff
98 
99 quint32 KMessageClient::id () const
100 {
101  return (d->connection) ? d->connection->id () : 0;
102 }
103 
104 bool KMessageClient::isAdmin () const
105 {
106  return id() != 0 && id() == adminId();
107 }
108 
109 quint32 KMessageClient::adminId () const
110 {
111  return d->adminID;
112 }
113 
114 QList <quint32> KMessageClient::clientList() const
115 {
116  return d->clientList;
117 }
118 
119 bool KMessageClient::isConnected () const
120 {
121  return d->connection && d->connection->isConnected();
122 }
123 
124 bool KMessageClient::isNetwork () const
125 {
126  return isConnected() ? d->connection->isNetwork() : false;
127 }
128 
129 quint16 KMessageClient::peerPort () const
130 {
131  return d->connection ? d->connection->peerPort() : 0;
132 }
133 
134 QString KMessageClient::peerName () const
135 {
136  return d->connection ? d->connection->peerName() : QString::fromLatin1("localhost");
137 }
138 
139 // --------------------- Sending messages
140 
141 void KMessageClient::sendServerMessage (const QByteArray &msg)
142 {
143  if (!d->connection)
144  {
145  kWarning (11001) << ": We have no connection yet!";
146  return;
147  }
148  d->connection->send (msg);
149 }
150 
151 void KMessageClient::sendBroadcast (const QByteArray &msg)
152 {
153  QByteArray sendBuffer;
154  QBuffer buffer (&sendBuffer);
155  buffer.open (QIODevice::WriteOnly);
156  QDataStream stream (&buffer);
157 
158  stream << static_cast<quint32> ( KMessageServer::REQ_BROADCAST );
159  buffer.QIODevice::write (msg);
160  sendServerMessage (sendBuffer);
161 }
162 
163 void KMessageClient::sendForward (const QByteArray &msg, const QList <quint32> &clients)
164 {
165  QByteArray sendBuffer;
166  QBuffer buffer (&sendBuffer);
167  buffer.open (QIODevice::WriteOnly);
168  QDataStream stream (&buffer);
169 
170  stream << static_cast<quint32>( KMessageServer::REQ_FORWARD ) << clients;
171  buffer.QIODevice::write (msg);
172  sendServerMessage (sendBuffer);
173 }
174 
175 void KMessageClient::sendForward (const QByteArray &msg, quint32 client)
176 {
177  sendForward (msg, QList <quint32> () << client);
178 }
179 
180 
181 // --------------------- Receiving and processing messages
182 
183 void KMessageClient::processIncomingMessage (const QByteArray &msg)
184 {
185  if (d->isLocked)
186  {
187  d->delayedMessages.append(msg);
188  return;
189  }
190  if (d->delayedMessages.count() > 0)
191  {
192  d->delayedMessages.append (msg);
193  QByteArray first = d->delayedMessages.front();
194  d->delayedMessages.pop_front();
195  processMessage (first);
196  }
197  else
198  {
199  processMessage(msg);
200  }
201 }
202 
203 void KMessageClient::processMessage (const QByteArray &msg)
204 {
205  if (d->isLocked)
206  { // must NOT happen, since we check in processIncomingMessage as well as in processFirstMessage
207  d->delayedMessages.append(msg);
208  return;
209  }
210  QBuffer in_buffer;
211  in_buffer.setData(msg);
212  in_buffer.open (QIODevice::ReadOnly);
213  QDataStream in_stream (&in_buffer);
214 
215 
216  bool unknown = false;
217 
218  quint32 messageID;
219  in_stream >> messageID;
220  switch (messageID)
221  {
222  case KMessageServer::MSG_BROADCAST:
223  {
224  quint32 clientID;
225  in_stream >> clientID;
226  emit broadcastReceived (in_buffer.readAll(), clientID);
227  }
228  break;
229 
230  case KMessageServer::MSG_FORWARD:
231  {
232  quint32 clientID;
233  QList <quint32> receivers;
234  in_stream >> clientID >> receivers;
235  emit forwardReceived (in_buffer.readAll(), clientID, receivers);
236  }
237  break;
238 
239  case KMessageServer::ANS_CLIENT_ID:
240  {
241  bool old_admin = isAdmin();
242  quint32 clientID;
243  in_stream >> clientID;
244  d->connection->setId (clientID);
245  if (old_admin != isAdmin())
246  emit adminStatusChanged (isAdmin());
247  }
248  break;
249 
250  case KMessageServer::ANS_ADMIN_ID:
251  {
252  bool old_admin = isAdmin();
253  in_stream >> d->adminID;
254  if (old_admin != isAdmin())
255  emit adminStatusChanged (isAdmin());
256  }
257  break;
258 
259  case KMessageServer::ANS_CLIENT_LIST:
260  {
261  in_stream >> d->clientList;
262  }
263  break;
264 
265  case KMessageServer::EVNT_CLIENT_CONNECTED:
266  {
267  quint32 id;
268  in_stream >> id;
269 
270  if (d->clientList.contains (id))
271  kWarning (11001) << ": Adding a client that already existed!";
272  else
273  d->clientList.append (id);
274 
275  emit eventClientConnected (id);
276  }
277  break;
278 
279  case KMessageServer::EVNT_CLIENT_DISCONNECTED:
280  {
281  quint32 id;
282  qint8 broken;
283  in_stream >> id >> broken;
284 
285  if (!d->clientList.contains (id))
286  kWarning (11001) << ": Removing a client that doesn't exist!";
287  else
288  d->clientList.removeAll (id);
289 
290  emit eventClientDisconnected (id, bool (broken));
291  }
292  break;
293 
294  default:
295  unknown = true;
296  }
297 
298  if (!unknown && !in_buffer.atEnd())
299  kWarning (11001) << ": Extra data received for message ID" << messageID;
300 
301  emit serverMessageReceived (msg, unknown);
302 
303  if (unknown)
304  kWarning (11001) << ": received unknown message ID" << messageID;
305 }
306 
307 void KMessageClient::processFirstMessage()
308 {
309  if (d->isLocked)
310  {
311  return;
312  }
313  if (d->delayedMessages.count() == 0)
314  {
315  kDebug(11001) << ": no messages delayed";
316  return;
317  }
318  QByteArray first = d->delayedMessages.front();
319  d->delayedMessages.pop_front();
320  processMessage (first);
321 }
322 
323 void KMessageClient::removeBrokenConnection ()
324 {
325  kDebug (11001) << ": timer single shot for removeBrokenConnection"<<this;
326  // MH We cannot directly delete the socket. otherwise QSocket crashes
327  QTimer::singleShot( 0, this, SLOT(removeBrokenConnection2()) );
328  return;
329 }
330 
331 
332 void KMessageClient::removeBrokenConnection2 ()
333 {
334  kDebug (11001) << ": Broken:Deleting the connection object"<<this;
335 
336  emit aboutToDisconnect(id());
337  delete d->connection;
338  d->connection = 0;
339  d->adminID = 0;
340  emit connectionBroken();
341  kDebug (11001) << ": Broken:Deleting the connection object DONE";
342 }
343 
344 void KMessageClient::disconnect ()
345 {
346  kDebug (11001) << ": Disconnect:Deleting the connection object";
347 
348  emit aboutToDisconnect(id());
349  delete d->connection;
350  d->connection = 0;
351  d->adminID = 0;
352  emit connectionBroken();
353  kDebug (11001) << ": Disconnect:Deleting the connection object DONE";
354 }
355 
356 void KMessageClient::lock ()
357 {
358  d->isLocked = true;
359 }
360 
361 void KMessageClient::unlock ()
362 {
363  d->isLocked = false;
364  for (int i = 0; i < d->delayedMessages.count(); i++)
365  {
366  QTimer::singleShot(0, this, SLOT(processFirstMessage()));
367  }
368 }
369 
370 unsigned int KMessageClient::delayedMessageCount() const
371 {
372  return d->delayedMessages.count();
373 }
374 
375 #include "kmessageclient.moc"
KMessageClient::processIncomingMessage
virtual void processIncomingMessage(const QByteArray &msg)
This slot is called from the signal KMessageIO::received whenever a message from the KMessageServer a...
Definition: kmessageclient.cpp:183
KMessageServer::REQ_FORWARD
Definition: kmessageserver.h:185
KMessageClient::isAdmin
bool isAdmin() const
Definition: kmessageclient.cpp:104
KMessageClient::peerPort
quint16 peerPort() const
Definition: kmessageclient.cpp:129
KMessageServer::EVNT_CLIENT_DISCONNECTED
Definition: kmessageserver.h:204
KMessageClient::delayedMessageCount
unsigned int delayedMessageCount() const
Definition: kmessageclient.cpp:370
KMessageServer::ANS_ADMIN_ID
Definition: kmessageserver.h:201
KMessageSocket
This class implements the message communication using a TCP/IP socket.
Definition: kmessageio.h:170
QByteArray
KMessageServer::REQ_BROADCAST
Definition: kmessageserver.h:184
KMessageClient::sendForward
void sendForward(const QByteArray &msg, const QList< quint32 > &clients)
Sends a message to all the clients in a list.
Definition: kmessageclient.cpp:163
QDataStream
KMessageServer::EVNT_CLIENT_CONNECTED
Definition: kmessageserver.h:203
KMessageClient::sendServerMessage
void sendServerMessage(const QByteArray &msg)
Sends a message to the KMessageServer.
Definition: kmessageclient.cpp:141
KMessageClient::aboutToDisconnect
void aboutToDisconnect(quint32 id)
This signal is emitted right before the client disconnects.
QBuffer::setData
void setData(const QByteArray &data)
KMessageServer::ANS_CLIENT_ID
Definition: kmessageserver.h:200
KMessageClient::adminId
quint32 adminId() const
Definition: kmessageclient.cpp:109
KMessageClient::forwardReceived
void forwardReceived(const QByteArray &msg, quint32 senderID, const QList< quint32 > &receivers)
This signal is emitted when the client receives a forward message from the KMessageServer, sent by another client.
QBuffer
KMessageClient::isConnected
bool isConnected() const
Definition: kmessageclient.cpp:119
KMessageClient::clientList
QList< quint32 > clientList() const
Definition: kmessageclient.cpp:114
kmessageserver.h
KMessageClient::serverMessageReceived
void serverMessageReceived(const QByteArray &msg, bool &unknown)
This signal is emitted on every message that came from the server.
KMessageDirect
This class implements the message communication using function calls directly.
Definition: kmessageio.h:294
KMessageServer::addClient
void addClient(KMessageIO *)
Adds a new KMessageIO object to the communication server.
Definition: kmessageserver.cpp:180
KMessageClient::KMessageClient
KMessageClient(QObject *parent=0)
Constructor.
Definition: kmessageclient.cpp:52
QBuffer::atEnd
virtual bool atEnd() const
KMessageClient::removeBrokenConnection
virtual void removeBrokenConnection()
This slot is called from the signal KMessageIO::connectionBroken.
Definition: kmessageclient.cpp:323
KMessageServer::MSG_BROADCAST
Definition: kmessageserver.h:198
KMessageClient::processFirstMessage
void processFirstMessage()
Called from unlock() (using QTimer::singleShot) until all delayed messages are delivered.
Definition: kmessageclient.cpp:307
KMessageServer::MSG_FORWARD
Definition: kmessageserver.h:199
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:344
QObject
KMessageClient::removeBrokenConnection2
void removeBrokenConnection2()
Definition: kmessageclient.cpp:332
KMessageClient::sendBroadcast
void sendBroadcast(const QByteArray &msg)
Sends a message to all the clients connected to the server, including ourself.
Definition: kmessageclient.cpp:151
KMessageIO
This abstract base class represents one end of a message connections between two clients.
Definition: kmessageio.h:57
KMessageClient::isNetwork
bool isNetwork() const
Definition: kmessageclient.cpp:124
QIODevice::readAll
QByteArray readAll()
KMessageServer
A server for message sending and broadcasting, using TCP/IP connections.
Definition: kmessageserver.h:175
QBuffer::open
virtual bool open(QFlags< QIODevice::OpenModeFlag > flags)
QString
QList< quint32 >
KMessageClient::eventClientConnected
void eventClientConnected(quint32 clientID)
This signal is emitted when another client has connected to the server.
KMessageServer::ANS_CLIENT_LIST
Definition: kmessageserver.h:202
KMessageClient::broadcastReceived
void broadcastReceived(const QByteArray &msg, quint32 senderID)
This signal is emitted when the client receives a broadcast message from the KMessageServer, sent by another client.
KMessageClient::eventClientDisconnected
void eventClientDisconnected(quint32 clientID, bool broken)
This signal is emitted when the server has lost the connection to one of the clients (This could be b...
KMessageClient::lock
void lock()
Once this function is called no message will be received anymore.
Definition: kmessageclient.cpp:356
KMessageClient::id
quint32 id() const
Definition: kmessageclient.cpp:99
KMessageClient::processMessage
virtual void processMessage(const QByteArray &msg)
This slot is called from processIncomingMessage or processFirstMessage, depending on whether the clie...
Definition: kmessageclient.cpp:203
KMessageClient::connectionBroken
void connectionBroken()
This signal is emitted when the connection to the KMessageServer is broken.
KMessageClient::peerName
QString peerName() const
Definition: kmessageclient.cpp:134
KMessageClient::unlock
void unlock()
Deliver every message that was delayed by lock() and actually deliver all messages that get received ...
Definition: kmessageclient.cpp:361
QString::fromLatin1
QString fromLatin1(const char *str, int size)
kmessageio.h
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
KMessageClient::setServer
void setServer(const QString &host, quint16 port)
Connects the client to (another) server.
Definition: kmessageclient.cpp:67
KMessageClient::~KMessageClient
~KMessageClient()
Destructor.
Definition: kmessageclient.cpp:59
kmessageclient.h
QObject::receivers
int receivers(const char *signal) const
QTimer::singleShot
singleShot
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:18:54 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

libkdegames/libkdegamesprivate/kgame

Skip menu "libkdegames/libkdegamesprivate/kgame"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdegames API Reference

Skip menu "kdegames API Reference"
  • granatier
  • kapman
  • kblackbox
  • kgoldrunner
  • kigo
  • kmahjongg
  • KShisen
  • ksquares
  • libkdegames
  •   highscore
  •   libkdegamesprivate
  •     kgame
  • libkmahjongg
  • palapeli
  •   libpala

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal