You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdegames/libkdegames/kgame/kgamechat.cpp

342 lines
8.5 KiB

/*
This file is part of the KDE games library
Copyright (C) 2001-2002 Andreas Beckermann (b_mann@gmx.de)
Copyright (C) 2001 Martin Heni (martin@heni-online.de)
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License version 2 as published by the Free Software Foundation.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "kgamechat.h"
#include "kgamechat.moc"
#include "kgame.h"
#include "kplayer.h"
#include "kgameproperty.h"
#include "kgamemessage.h"
#include <klocale.h>
#include <kdebug.h>
#include <tqmap.h>
#include <tqintdict.h>
//FIXME:
#define FIRST_ID 2 // first id, that is free of use, aka not defined above
class KGameChatPrivate
{
public:
KGameChatPrivate()
{
mFromPlayer = 0;
mGame = 0;
mToMyGroup = -1;
}
KGame* mGame;
KPlayer* mFromPlayer;
int mMessageId;
TQIntDict<KPlayer> mIndex2Player;
TQMap<int, int> mSendId2PlayerId;
int mToMyGroup; // just as the above - but for the group, not for players
};
KGameChat::KGameChat(KGame* g, int msgid, TQWidget* parent) : KChatBase(parent)
{
init(g, msgid);
}
KGameChat::KGameChat(KGame* g, int msgid, KPlayer* fromPlayer, TQWidget* parent) : KChatBase(parent)
{
init(g, msgid);
setFromPlayer(fromPlayer);
}
KGameChat::KGameChat(TQWidget* parent) : KChatBase(parent)
{
init(0, -1);
}
KGameChat::~KGameChat()
{
kdDebug(11001) << k_funcinfo << endl;
delete d;
}
void KGameChat::init(KGame* g, int msgId)
{
kdDebug(11001) << k_funcinfo << endl;
d = new KGameChatPrivate;
setMessageId(msgId);
setKGame(g);
}
void KGameChat::addMessage(int fromId, const TQString& text)
{
if (!d->mGame) {
kdWarning(11001) << "no KGame object has been set" << endl;
addMessage(i18n("Player %1").arg(fromId), text);
} else {
KPlayer* p = d->mGame->findPlayer(fromId);
if (p) {
kdDebug(11001) << "adding message of player " << p->name() << "id=" << fromId << endl;
addMessage(p->name(), text);
} else {
kdWarning(11001) << "Could not find player id " << fromId << endl;
addMessage(i18n("Unknown"), text);
}
}
}
void KGameChat::returnPressed(const TQString& text)
{
if (!d->mFromPlayer) {
kdWarning(11001) << k_funcinfo << ": You must set a player first!" << endl;
return;
}
if (!d->mGame) {
kdWarning(11001) << k_funcinfo << ": You must set a game first!" << endl;
return;
}
kdDebug(11001) << "from: " << d->mFromPlayer->id() << "==" << d->mFromPlayer->name() << endl;
int id = sendingEntry();
if (isToGroupMessage(id)) {
// note: there is currently no support for other groups than the players
// group! It might be useful to send to other groups, too
TQString group = d->mFromPlayer->group();
kdDebug(11001) << "send to group " << group << endl;
int sender = d->mFromPlayer->id();
d->mGame->sendGroupMessage(text, messageId(), sender, group);
//TODO
//AB: this message is never received!! we need to connect to
//KPlayer::networkData!!!
//TODO
} else {
int toPlayer = 0;
if (!isSendToAllMessage(id) && isToPlayerMessage(id)) {
toPlayer = playerId(id);
if (toPlayer == -1) {
kdError(11001) << k_funcinfo << ": don't know that player "
<< "- internal ERROR" << endl;
}
}
int receiver = toPlayer;
int sender = d->mFromPlayer->id();
d->mGame->sendMessage(text, messageId(), receiver, sender);
}
}
void KGameChat::setMessageId(int msgid)
{ d->mMessageId = msgid; }
int KGameChat::messageId() const
{ return d->mMessageId; }
bool KGameChat::isSendToAllMessage(int id) const
{ return (id == KChatBase::SendToAll); }
bool KGameChat::isToGroupMessage(int id) const
{ return (id == d->mToMyGroup); }
bool KGameChat::isToPlayerMessage(int id) const
{
return d->mSendId2PlayerId.contains(id); }
TQString KGameChat::sendToPlayerEntry(const TQString& name) const
{ return i18n("Send to %1").arg(name); }
int KGameChat::playerId(int id) const
{
if (!isToPlayerMessage(id)) {
return -1;
}
return d->mSendId2PlayerId[id];
}
int KGameChat::sendingId(int playerId) const
{
TQMap<int, int>::Iterator it;
for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
if (it.data() == playerId) {
return it.key();
}
}
return -1;
}
const TQString& KGameChat::fromName() const
{ return d->mFromPlayer ? d->mFromPlayer->name() : TQString::null; }
bool KGameChat::hasPlayer(int id) const
{
return (sendingId(id) != -1);
}
void KGameChat::setFromPlayer(KPlayer* p)
{
if (!p) {
kdError(11001) << k_funcinfo << ": NULL player" << endl;
removeSendingEntry(d->mToMyGroup);
d->mFromPlayer = 0;
return;
}
if (d->mFromPlayer) {
changeSendingEntry(p->group(), d->mToMyGroup);
} else {
if (d->mToMyGroup != -1) {
kdWarning(11001) << "send to my group exists already - removing" << endl;
removeSendingEntry(d->mToMyGroup);
}
d->mToMyGroup = nextId();
addSendingEntry(i18n("Send to My Group (\"%1\")").arg(p->group()), d->mToMyGroup);
}
d->mFromPlayer = p;
kdDebug(11001) << k_funcinfo << " player=" << p << endl;
}
void KGameChat::setKGame(KGame* g)
{
if (d->mGame) {
slotUnsetKGame();
}
kdDebug(11001) << k_funcinfo << " game=" << g << endl;
d->mGame = g;
if (d->mGame) {
connect(d->mGame, TQT_SIGNAL(signalPlayerJoinedGame(KPlayer*)),
this, TQT_SLOT(slotAddPlayer(KPlayer*)));
connect(d->mGame, TQT_SIGNAL(signalPlayerLeftGame(KPlayer*)),
this, TQT_SLOT(slotRemovePlayer(KPlayer*)));
connect(d->mGame, TQT_SIGNAL(signalNetworkData(int, const TQByteArray&, Q_UINT32, Q_UINT32)),
this, TQT_SLOT(slotReceiveMessage(int, const TQByteArray&, Q_UINT32, Q_UINT32)));
connect(d->mGame, TQT_SIGNAL(destroyed()), this, TQT_SLOT(slotUnsetKGame()));
TQPtrList<KPlayer> playerList = *d->mGame->playerList();
for (int unsigned i = 0; i < playerList.count(); i++) {
slotAddPlayer(playerList.at(i));
}
}
}
KGame* KGameChat::game() const
{
return d->mGame;
}
KPlayer* KGameChat::fromPlayer() const
{
return d->mFromPlayer;
}
void KGameChat::slotUnsetKGame()
{
//TODO: test this method!
if (!d->mGame) {
return;
}
disconnect(d->mGame, 0, this, 0);
removeSendingEntry(d->mToMyGroup);
TQMap<int, int>::Iterator it;
for (it = d->mSendId2PlayerId.begin(); it != d->mSendId2PlayerId.end(); ++it) {
removeSendingEntry(it.data());
}
}
void KGameChat::slotAddPlayer(KPlayer* p)
{
if (!p) {
kdError(11001) << k_funcinfo << ": cannot add NULL player" << endl;
return;
}
if (hasPlayer(p->id())) {
kdError(11001) << k_funcinfo << ": player was added before" << endl;
return;
}
int sendingId = nextId();
addSendingEntry(comboBoxItem(p->name()), sendingId);
d->mSendId2PlayerId.insert(sendingId, p->id());
connect(p, TQT_SIGNAL(signalPropertyChanged(KGamePropertyBase*, KPlayer*)),
this, TQT_SLOT(slotPropertyChanged(KGamePropertyBase*, KPlayer*)));
connect(p, TQT_SIGNAL(signalNetworkData(int, const TQByteArray&, Q_UINT32, KPlayer*)),
this, TQT_SLOT(slotReceivePrivateMessage(int, const TQByteArray&, Q_UINT32, KPlayer*)));
}
void KGameChat::slotRemovePlayer(KPlayer* p)
{
if (!p) {
kdError(11001) << k_funcinfo << ": NULL player" << endl;
return;
}
if (!hasPlayer(p->id())) {
kdError(11001) << k_funcinfo << ": cannot remove non-existent player" << endl;
return;
}
int id = sendingId(p->id());
removeSendingEntry(id);
p->disconnect(this);
d->mSendId2PlayerId.remove(id);
}
void KGameChat::slotPropertyChanged(KGamePropertyBase* prop, KPlayer* player)
{
if (prop->id() == KGamePropertyBase::IdName) {
// kdDebug(11001) << "new Name" << endl;
changeSendingEntry(player->name(), sendingId(player->id()));
/*
mCombo->changeItem(comboBoxItem(player->name()), index);
*/
} else if (prop->id() == KGamePropertyBase::IdGroup) {
//TODO
}
}
void KGameChat::slotReceivePrivateMessage(int msgid, const TQByteArray& buffer, Q_UINT32 sender, KPlayer* me)
{
if (!me || me != fromPlayer()) {
kdDebug() << k_funcinfo << "nope - not for us!" << endl;
return;
}
slotReceiveMessage(msgid, buffer, me->id(), sender);
}
void KGameChat::slotReceiveMessage(int msgid, const TQByteArray& buffer, Q_UINT32 , Q_UINT32 sender)
{
TQDataStream msg(buffer, IO_ReadOnly);
if (msgid != messageId()) {
return;
}
TQString text;
msg >> text;
addMessage(sender, text);
}