[Kde-games-devel] Re: Sending a message to one KGame client

Andreas Beckermann kde-games-devel@mail.kde.org
Sat, 1 Mar 2003 00:38:20 +0100


--Boundary-00=_sL/X+NXpEt2cMnS
Content-Type: text/plain;
  charset="utf-8"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

On Thursday 27 February 2003 03:26, Neil Stevens wrote:
> On Tuesday February 25, 2003 01:02, Martin Heni wrote:
> > However, I think this is not necessarily the function wanted in Neils
> > application. I suppose it would be better to just target the games with
> > the direct messaged sent. I would assume in this concept he has
> > only one (real) player per game anyway?
>
> Yes, I will only have one player per Megami instance.

Hm. So how will you  show e.g. the names of other players to your primary 
player? When there is only one KPlayer object per client...
Do you maintain an additional data set?

> > So I would just send a user message directly to game XYZ and then
> > analyse the incoming messages (signal exists) and perform some actions
> > depending on the ID's of the messages. In this respect all can be
> > drivern by direct addresses user messages. This should be quite easily
> > implemented.
>
> So the trick then becomes mapping KPlayers to KGames, no?

A KPlayer ID is created using KGameMessage::createPlayerId() and therefore 
already has the game ID inside :)
You could use KGameMessage::rawGameId() to retrieve the ID of the KGame object 
(and therefore also of the KMessageClient object).

I have finished my exams for now and therefore have a bit of time again. I 
have attached a patch that should forward all messages that have a KGame-only 
"receiver" part to that client only.
Note that this really *must* be a KGame::gameId(), a KPlayer::id() will still 
be broadcast (the message must go to the player object on all clients). You 
could use KGameMessage::rawGameId(myPlayer->id()) to retrieve the ID of the 
KGame object.

I have tested this patch with a slightly hacked KGameChat widget, so that it 
sends out private messages and it seems to work. Broadcast messages continue 
to work, so I think there should be no unwanted side-effects.

Is your game already so far that you can test this patch?

CU
Andi
	
--Boundary-00=_sL/X+NXpEt2cMnS
Content-Type: text/x-diff;
  charset="utf-8";
  name="kgamenetwork.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment; filename="kgamenetwork.diff"

Index: kgamenetwork.cpp
===================================================================
RCS file: /home/kde/kdegames/libkdegames/kgame/kgamenetwork.cpp,v
retrieving revision 1.39
diff -u -3 -p -r1.39 kgamenetwork.cpp
--- kgamenetwork.cpp	21 Feb 2003 14:24:17 -0000	1.39
+++ kgamenetwork.cpp	28 Feb 2003 23:31:43 -0000
@@ -130,6 +130,10 @@ void KGameNetwork::setMaster()
    connect (d->mMessageClient, SIGNAL(eventClientDisconnected(Q_UINT32, bool)),
             this, SIGNAL(signalClientDisconnected(Q_UINT32, bool)));
 
+   // broacast and direct messages are treated equally on receive.
+   connect (d->mMessageClient, SIGNAL(forwardReceived(const QByteArray&, Q_UINT32, const QValueList<Q_UINT32>&)),
+            d->mMessageClient, SIGNAL(broadcastReceived(const QByteArray&, Q_UINT32)));
+
  } else {
    // should be no problem but still has to be tested
    kdDebug(11001) << k_funcinfo << "Client already exists!" << endl;
@@ -347,6 +351,9 @@ bool KGameNetwork::sendSystemMessage(con
    sender = gameId();
  }
 
+ Q_UINT32 receiverClient = KGameMessage::rawGameId(receiver); // KGame::gameId()
+ int receiverPlayer = KGameMessage::rawPlayerId(receiver); // KPlayer::id()
+
  KGameMessage::createHeader(stream, sender, receiver, msgid);
  stream.writeRawBytes(data.data(), data.size());
 
@@ -364,7 +371,17 @@ bool KGameNetwork::sendSystemMessage(con
    return false;
  }
 
- d->mMessageClient->sendBroadcast(buffer);
+ if (receiverClient == 0 || receiverPlayer != 0)
+ {
+   // if receiverClient == 0 this is a broadcast message. if it is != 0 but
+   // receiverPlayer is also != 0 we have to send broadcast anyway, because the
+   // KPlayer object on all clients needs to receive the message.
+   d->mMessageClient->sendBroadcast(buffer);
+ }
+ else
+ {
+   d->mMessageClient->sendForward(buffer, receiverClient);
+ }
  return true;
 }
 

--Boundary-00=_sL/X+NXpEt2cMnS--