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

KDE's Doxygen guidelines are available online.