• 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
31class KMessageClientPrivate
32{
33public:
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
51KMessageClient::KMessageClient (TQObject *parent, const char *name)
52 : TQObject (parent, name)
53{
54 d = new KMessageClientPrivate ();
55 d->isLocked = false;
56}
57
58KMessageClient::~KMessageClient ()
59{
60 d->delayedMessages.clear();
61 delete d;
62}
63
64// -- setServer stuff
65
66void KMessageClient::setServer (const TQString &host, TQ_UINT16 port)
67{
68 setServer (new KMessageSocket (host, port));
69}
70
71void KMessageClient::setServer (KMessageServer *server)
72{
73 KMessageDirect *serverIO = new KMessageDirect ();
74 setServer (new KMessageDirect (serverIO));
75 server->addClient (serverIO);
76}
77
78void 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
98TQ_UINT32 KMessageClient::id () const
99{
100 return (d->connection) ? d->connection->id () : 0;
101}
102
103bool KMessageClient::isAdmin () const
104{
105 return id() != 0 && id() == adminId();
106}
107
108TQ_UINT32 KMessageClient::adminId () const
109{
110 return d->adminID;
111}
112
113const TQValueList <TQ_UINT32> &KMessageClient::clientList() const
114{
115 return d->clientList;
116}
117
118bool KMessageClient::isConnected () const
119{
120 return d->connection && d->connection->isConnected();
121}
122
123bool KMessageClient::isNetwork () const
124{
125 return isConnected() ? d->connection->isNetwork() : false;
126}
127
128TQ_UINT16 KMessageClient::peerPort () const
129{
130 return d->connection ? d->connection->peerPort() : 0;
131}
132
133TQString KMessageClient::peerName () const
134{
135 return d->connection ? d->connection->peerName() : TQString::fromLatin1("localhost");
136}
137
138// --------------------- Sending messages
139
140void 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
150void 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
162void 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
174void 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
182void 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
202void 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
305void 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
321void 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
330void 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
342void 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
354void KMessageClient::lock ()
355{
356 d->isLocked = true;
357}
358
359void 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
368unsigned int KMessageClient::delayedMessageCount() const
369{
370 return d->delayedMessages.count();
371}
372
373#include "kmessageclient.moc"
KMessageClient::processFirstMessage
void processFirstMessage()
Called from unlock() (using TQTimer::singleShot) until all delayed messages are delivered.
Definition: kmessageclient.cpp:305
KMessageClient::isConnected
bool isConnected() const
Definition: kmessageclient.cpp:118
KMessageClient::peerPort
TQ_UINT16 peerPort() const
Definition: kmessageclient.cpp:128
KMessageClient::isNetwork
bool isNetwork() const
Definition: kmessageclient.cpp:123
KMessageClient::clientList
const TQValueList< TQ_UINT32 > & clientList() const
Definition: kmessageclient.cpp:113
KMessageClient::setServer
void setServer(const TQString &host, TQ_UINT16 port)
Connects the client to (another) server.
Definition: kmessageclient.cpp:66
KMessageClient::lock
void lock()
Once this function is called no message will be received anymore.
Definition: kmessageclient.cpp:354
KMessageClient::adminId
TQ_UINT32 adminId() const
Definition: kmessageclient.cpp:108
KMessageClient::~KMessageClient
~KMessageClient()
Destructor.
Definition: kmessageclient.cpp:58
KMessageClient::peerName
TQString peerName() const
Definition: kmessageclient.cpp:133
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,...
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::aboutToDisconnect
void aboutToDisconnect(TQ_UINT32 id)
This signal is emitted right before the client disconnects.
KMessageClient::broadcastReceived
void broadcastReceived(const TQByteArray &msg, TQ_UINT32 senderID)
This signal is emitted when the client receives a broadcast message from the KMessageServer,...
KMessageClient::disconnect
void disconnect()
Corresponds to setServer(0); but also emits the connectionBroken signal.
Definition: kmessageclient.cpp:342
KMessageClient::KMessageClient
KMessageClient(TQObject *parent=0, const char *name=0)
Constructor.
Definition: kmessageclient.cpp:51
KMessageClient::connectionBroken
void connectionBroken()
This signal is emitted when the connection to the KMessageServer is broken.
KMessageClient::id
TQ_UINT32 id() const
Definition: kmessageclient.cpp:98
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::isAdmin
bool isAdmin() const
Definition: kmessageclient.cpp:103
KMessageClient::delayedMessageCount
unsigned int delayedMessageCount() const
Definition: kmessageclient.cpp:368
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::unlock
void unlock()
Deliver every message that was delayed by lock() and actually deliver all messages that get received ...
Definition: kmessageclient.cpp:359
KMessageClient::serverMessageReceived
void serverMessageReceived(const TQByteArray &msg, bool &unknown)
This signal is emitted on every message that came from the server.
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::removeBrokenConnection
virtual void removeBrokenConnection()
This slot is called from the signal KMessageIO::connectionBroken.
Definition: kmessageclient.cpp:321
KMessageClient::eventClientConnected
void eventClientConnected(TQ_UINT32 clientID)
This signal is emitted when another client has connected to the server.
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::sendServerMessage
void sendServerMessage(const TQByteArray &msg)
Sends a message to the KMessageServer.
Definition: kmessageclient.cpp:140
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
KMessageDirect
This class implements the message communication using function calls directly.
Definition: kmessageio.h:298
KMessageIO
This abstract base class represents one end of a message connections between two clients.
Definition: kmessageio.h:57
KMessageServer
A server for message sending and broadcasting, using TCP/IP connections.
Definition: kmessageserver.h:176
KMessageServer::addClient
void addClient(KMessageIO *)
Adds a new KMessageIO object to the communication server.
Definition: kmessageserver.cpp:170
KMessageSocket
This class implements the message communication using a TCP/IP socket.
Definition: kmessageio.h:171

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.9.4
This website is maintained by Timothy Pearson.