KDEGames

kgamechat.cpp
1 /*
2  This file is part of the KDE games library
3  SPDX-FileCopyrightText: 2001-2002 Andreas Beckermann <[email protected]>
4  SPDX-FileCopyrightText: 2001 Martin Heni <kde at heni-online.de>
5 
6  SPDX-License-Identifier: LGPL-2.0-only
7 */
8 
9 #include "kgamechat.h"
10 
11 // own
12 #include "../kchatbase_p.h"
13 #include "kgame.h"
14 #include "kplayer.h"
15 #include "kgameproperty.h"
16 #include "kgamemessage.h"
17 // KF
18 #include <KLocalizedString>
19 // Qt
20 #include <QMap>
21 
22 //FIXME:
23 #define FIRST_ID 2 // first id, that is free of use, aka not defined above
24 
25 class KGameChatPrivate : public KChatBasePrivate
26 {
27 public:
28  KGameChatPrivate(KChatBaseModel* model, KChatBaseItemDelegate* delegate, QWidget* parent)
29  : KChatBasePrivate(model, delegate, parent)
30  {
31  mFromPlayer = nullptr;
32  mGame = nullptr;
33 
34  mToMyGroup = -1;
35  }
36 
37  KGame* mGame;
38  KPlayer* mFromPlayer;
39  int mMessageId;
40 
41 
42  QMap<int, int> mSendId2PlayerId;
43  int mToMyGroup; // just as the above - but for the group, not for players
44 };
45 
46 KGameChat::KGameChat(KGame* g, int msgid, QWidget* parent, KChatBaseModel* model, KChatBaseItemDelegate* delegate)
47  : KChatBase(*new KGameChatPrivate(model, delegate, parent), parent, false)
48 {
49  init(g, msgid);
50 }
51 
52 KGameChat::KGameChat(KGame* g, int msgid, KPlayer* fromPlayer, QWidget* parent, KChatBaseModel* model, KChatBaseItemDelegate* delegate)
53  : KChatBase(*new KGameChatPrivate(model, delegate, parent), parent, false)
54 {
55  init(g, msgid);
56  setFromPlayer(fromPlayer);
57 }
58 
60  : KChatBase(*new KGameChatPrivate(nullptr, nullptr, parent), parent, false)
61 {
62  init(nullptr, -1);
63 }
64 
65 KGameChat::~KGameChat()
66 {
67  qCDebug(GAMES_PRIVATE_KGAME) ;
68 }
69 
70 void KGameChat::init(KGame* g, int msgId)
71 {
72  qCDebug(GAMES_PRIVATE_KGAME) ;
73  setMessageId(msgId);
74 
75  setKGame(g);
76 }
77 
78 void KGameChat::addMessage(int fromId, const QString& text)
79 {
80  Q_D(KGameChat);
81 
82  if (!d->mGame) {
83  qCWarning(GAMES_PRIVATE_KGAME) << "no KGame object has been set";
84  addMessage(i18n("Player %1", fromId), text);
85  } else {
86  KPlayer* p = d->mGame->findPlayer(fromId);
87  if (p) {
88  qCDebug(GAMES_PRIVATE_KGAME) << "adding message of player" << p->name() << "id=" << fromId;
89  addMessage(p->name(), text);
90  } else {
91  qCWarning(GAMES_PRIVATE_KGAME) << "Could not find player id" << fromId;
92  addMessage(i18nc("Unknown player", "Unknown"), text);
93  }
94  }
95 }
96 
98 {
99  Q_D(KGameChat);
100 
101  if (!d->mFromPlayer) {
102  qCWarning(GAMES_PRIVATE_KGAME) << ": You must set a player first!";
103  return;
104  }
105  if (!d->mGame) {
106  qCWarning(GAMES_PRIVATE_KGAME) << ": You must set a game first!";
107  return;
108  }
109 
110  qCDebug(GAMES_PRIVATE_KGAME) << "from:" << d->mFromPlayer->id() << "==" << d->mFromPlayer->name();
111 
112  int id = sendingEntry();
113 
114  if (isToGroupMessage(id)) {
115  // note: there is currently no support for other groups than the players
116  // group! It might be useful to send to other groups, too
117  QString group = d->mFromPlayer->group();
118  qCDebug(GAMES_PRIVATE_KGAME) << "send to group" << group;
119  int sender = d->mFromPlayer->id();
120  d->mGame->sendGroupMessage(text, messageId(), sender, group);
121 
122  //TODO
123  //AB: this message is never received!! we need to connect to
124  //KPlayer::networkData!!!
125  //TODO
126 
127  } else {
128  int toPlayer = 0;
129  if (!isSendToAllMessage(id) && isToPlayerMessage(id)) {
130  toPlayer = playerId(id);
131  if (toPlayer == -1) {
132  qCCritical(GAMES_PRIVATE_KGAME) << ": don't know that player "
133  << "- internal ERROR";
134  }
135  }
136  int receiver = toPlayer;
137  int sender = d->mFromPlayer->id();
138  d->mGame->sendMessage(text, messageId(), receiver, sender);
139  }
140 }
141 
142 void KGameChat::setMessageId(int msgid)
143 {
144  Q_D(KGameChat);
145 
146  d->mMessageId = msgid;
147 }
148 
150 {
151  Q_D(const KGameChat);
152 
153  return d->mMessageId;
154 }
155 
157 {
158  return (id == KChatBase::SendToAll);
159 }
160 
161 bool KGameChat::isToGroupMessage(int id) const
162 {
163  Q_D(const KGameChat);
164 
165  return (id == d->mToMyGroup);
166 }
167 
169 {
170  Q_D(const KGameChat);
171 
172  return d->mSendId2PlayerId.contains(id);
173 }
174 
176 {
177  return i18n("Send to %1", name);
178 }
179 
180 int KGameChat::playerId(int id) const
181 {
182  Q_D(const KGameChat);
183 
184  if (!isToPlayerMessage(id)) {
185  return -1;
186  }
187 
188  return d->mSendId2PlayerId[id];
189 }
190 
192 {
193  Q_D(const KGameChat);
194 
196  for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
197  if (it.value() == playerId) {
198  return it.key();
199  }
200  }
201  return -1;
202 }
203 
205 {
206  Q_D(const KGameChat);
207 
208  return d->mFromPlayer ? d->mFromPlayer->name() : QString();
209 }
210 
211 bool KGameChat::hasPlayer(int id) const
212 {
213  return (sendingId(id) != -1);
214 }
215 
217 {
218  Q_D(KGameChat);
219 
220  if (!p) {
221  qCCritical(GAMES_PRIVATE_KGAME) << ": NULL player";
222  removeSendingEntry(d->mToMyGroup);
223  d->mFromPlayer = nullptr;
224  return;
225  }
226  if (d->mFromPlayer) {
227  changeSendingEntry(p->group(), d->mToMyGroup);
228  } else {
229  if (d->mToMyGroup != -1) {
230  qCWarning(GAMES_PRIVATE_KGAME) << "send to my group exists already - removing";
231  removeSendingEntry(d->mToMyGroup);
232  }
233  d->mToMyGroup = nextId();
234  addSendingEntry(i18n("Send to My Group (\"%1\")", p->group()), d->mToMyGroup);
235  }
236  d->mFromPlayer = p;
237  qCDebug(GAMES_PRIVATE_KGAME) << "player=" << p;
238 }
239 
240 
242 {
243  Q_D(KGameChat);
244 
245  if (d->mGame) {
246  slotUnsetKGame();
247  }
248  qCDebug(GAMES_PRIVATE_KGAME) << "game=" << g;
249  d->mGame = g;
250 
251  if (d->mGame) {
252  connect(d->mGame, &KGame::signalPlayerJoinedGame, this, &KGameChat::slotAddPlayer);
253  connect(d->mGame, &KGame::signalPlayerLeftGame, this, &KGameChat::slotRemovePlayer);
254  connect(d->mGame, &KGame::signalNetworkData, this, &KGameChat::slotReceiveMessage);
256 
257  QList<KPlayer*> playerList = *d->mGame->playerList();
258  for (int i = 0; i < playerList.count(); i++) {
259  slotAddPlayer(playerList.at(i));
260  }
261  }
262 }
263 
264 KGame* KGameChat::game() const
265 {
266  Q_D(const KGameChat);
267 
268  return d->mGame;
269 }
270 
271 KPlayer* KGameChat::fromPlayer() const
272 {
273  Q_D(const KGameChat);
274 
275  return d->mFromPlayer;
276 }
277 
279 {
280 //TODO: test this method!
281  Q_D(KGameChat);
282 
283  if (!d->mGame) {
284  return;
285  }
286  disconnect(d->mGame, nullptr, this, nullptr);
287  removeSendingEntry(d->mToMyGroup);
289  for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
291  }
292 }
293 
294 void KGameChat::slotAddPlayer(KPlayer* p)
295 {
296  Q_D(KGameChat);
297 
298  if (!p) {
299  qCCritical(GAMES_PRIVATE_KGAME) << ": cannot add NULL player";
300  return;
301  }
302  if (hasPlayer(p->id())) {
303  qCCritical(GAMES_PRIVATE_KGAME) << ": player was added before";
304  return;
305  }
306 
307  int sendingId = nextId();
308  addSendingEntry(comboBoxItem(p->name()), sendingId);
309  d->mSendId2PlayerId.insert(sendingId, p->id());
310  connect(p, &KPlayer::signalPropertyChanged, this, &KGameChat::slotPropertyChanged);
312 }
313 
314 void KGameChat::slotRemovePlayer(KPlayer* p)
315 {
316  Q_D(KGameChat);
317 
318  if (!p) {
319  qCCritical(GAMES_PRIVATE_KGAME) << ": NULL player";
320  return;
321  }
322  if (!hasPlayer(p->id())) {
323  qCCritical(GAMES_PRIVATE_KGAME) << ": cannot remove non-existent player";
324  return;
325  }
326 
327  int id = sendingId(p->id());
328  removeSendingEntry(id);
329  p->disconnect(this);
330  d->mSendId2PlayerId.remove(id);
331 }
332 
333 void KGameChat::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* player)
334 {
335  if (prop->id() == KGamePropertyBase::IdName) {
336 // qCDebug(GAMES_PRIVATE_KGAME) << "new Name";
337  changeSendingEntry(player->name(), sendingId(player->id()));
338 /*
339  mCombo->changeItem(comboBoxItem(player->name()), index);
340  */
341  } else if (prop->id() == KGamePropertyBase::IdGroup) {
342  //TODO
343  }
344 }
345 
346 void KGameChat::slotReceivePrivateMessage(int msgid, const QByteArray& buffer, quint32 sender, KPlayer* me)
347 {
348  if (!me || me != fromPlayer()) {
349  qCDebug(GAMES_PRIVATE_KGAME) << "nope - not for us!";
350  return;
351  }
352  slotReceiveMessage(msgid, buffer, me->id(), sender);
353 }
354 
355 void KGameChat::slotReceiveMessage(int msgid, const QByteArray& buffer, quint32 , quint32 sender)
356 {
357  QDataStream msg(buffer);
358  if (msgid != messageId()) {
359  return;
360  }
361 
362  QString text;
363  msg >> text;
364 
365  addMessage(sender, text);
366 }
367 
virtual QString sendToPlayerEntry(const QString &name) const
Definition: kgamechat.cpp:175
KGameChat(KGame *game, int msgid, KPlayer *fromPlayer, QWidget *parent, KChatBaseModel *model=nullptr, KChatBaseItemDelegate *delegate=nullptr)
Construct a KGame chat widget on game that used msgid for the chat message.
Definition: kgamechat.cpp:52
void signalNetworkData(int msgid, const QByteArray &buffer, quint32 sender, KPlayer *me)
The player object got a message which was targeted at it but has no default method to process it...
quint32 id() const
Returns the id of the player.
Definition: kplayer.cpp:235
void changeSendingEntry(const QString &text, int id)
This changes a combo box entry.
Definition: kchatbase.cpp:205
void setKGame(KGame *g)
Set the KGame object for this chat widget.
Definition: kgamechat.cpp:241
bool isToGroupMessage(int id) const
Used to indicate whether a message shall be sent to a group of players.
Definition: kgamechat.cpp:161
int messageId() const
Definition: kgamechat.cpp:149
bool addSendingEntry(const QString &text, int id)
Adds a new entry in the combo box.
Definition: kchatbase.cpp:141
QObject * sender() const const
void removeSendingEntry(int id)
Removes the entry with the ID id from the combo box.
Definition: kchatbase.cpp:191
bool isToPlayerMessage(int id) const
Used to indicate whether the message shall be sent to a single player only.
Definition: kgamechat.cpp:168
const T & at(int i) const const
The base class for chat widgets.
Definition: kchatbase.h:68
void slotUnsetKGame()
Unsets a KGame object that has been set using setKGame before.
Definition: kgamechat.cpp:278
A delegate (see the Qt Model/View module for details) to paint the lines of the KChatBase list model ...
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QString fromName() const override
reimplemented from KChatBase
Definition: kgamechat.cpp:204
void signalPropertyChanged(KGamePropertyBase *property, KPlayer *me)
This signal is emitted if a player property changes its value and the property is set to notify this ...
void setFromPlayer(KPlayer *player)
This sets the fromPlayer to player.
Definition: kgamechat.cpp:216
int sendingId(int playerId) const
Definition: kgamechat.cpp:191
void returnPressed(const QString &text) override
This is called whenever the user pushed return ie wants to send a message.
Definition: kgamechat.cpp:97
int count(const T &value) const const
virtual const QString & name() const
Definition: kplayer.cpp:232
QString i18nc(const char *context, const char *text, const TYPE &arg...)
virtual const QString & group() const
Query the group the player belongs to.
Definition: kplayer.cpp:226
void signalPlayerJoinedGame(KPlayer *player)
a player joined the game
QMap::iterator end()
int nextId() const
Definition: kchatbase.cpp:235
QMap::iterator begin()
Base class for a game player.
Definition: kplayer.h:60
void slotReceivePrivateMessage(int msgid, const QByteArray &buffer, quint32 sender, KPlayer *me)
Called when KPlayer::signalNetworkData is emitted.
Definition: kgamechat.cpp:346
Base class of KGameProperty.
Definition: kgameproperty.h:35
void signalNetworkData(int msgid, const QByteArray &buffer, quint32 receiver, quint32 sender)
We got an user defined update message.
void signalPlayerLeftGame(KPlayer *player)
a player left the game because of a broken connection or so!
const Key key(const T &value, const Key &defaultKey) const const
QString i18n(const char *text, const TYPE &arg...)
bool hasPlayer(int id) const
Definition: kgamechat.cpp:211
void setMessageId(int msgid)
Change the message id of the chat widget.
Definition: kgamechat.cpp:142
int playerId(int id) const
Definition: kgamechat.cpp:180
The main KDE game object.
Definition: kgame.h:57
A Chat widget for KGame-based games.
Definition: kgamechat.h:35
int sendingEntry() const
Definition: kchatbase.cpp:175
bool isSendToAllMessage(int id) const
Definition: kgamechat.cpp:156
virtual QString comboBoxItem(const QString &name) const
Replace to customize the combo box.
Definition: kchatbase.cpp:261
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
void destroyed(QObject *obj)
int id() const
The model used to store messages displayed in the chat dialog messages list.
const T value(const Key &key, const T &defaultValue) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Tue Dec 7 2021 22:34:14 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.