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/kbattleship/kbattleship/konnectionhandling.cpp

247 lines
8.9 KiB

/**************************************MM*************************************
konnectionhandling.cpp
-------------------
Developers: (c) 2000-2001 Nikolas Zimmermann <wildfox@kde.org>
(c) 2000-2001 Daniel Molkentin <molkentin@kde.org>
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "konnectionhandling.moc"
extern const char *protocolVersion;
KonnectionHandling::KonnectionHandling(TQWidget *parent, KBattleshipServer *server) : TQObject(parent)
{
m_kbserver = server;
m_kbclient = 0;
m_type = KonnectionHandling::SERVER;
connect(server, TQT_SIGNAL(sigServerFailure()), this, TQT_SIGNAL(sigAbortNetworkGame()));
connect(server, TQT_SIGNAL(sigNewConnect()), this, TQT_SLOT(slotNewClient()));
connect(server, TQT_SIGNAL(sigEndConnect()), this, TQT_SLOT(slotLostClient()));
connect(server, TQT_SIGNAL(sigNewMessage(KMessage *)), this, TQT_SLOT(slotNewMessage(KMessage *)));
connect(server, TQT_SIGNAL(sigMessageSent(KMessage *)), this, TQT_SLOT(slotMessageSent(KMessage *)));
}
KonnectionHandling::KonnectionHandling(TQWidget *parent, KBattleshipClient *client) : TQObject(parent)
{
m_kbclient = client;
m_kbserver = 0;
m_type = KonnectionHandling::CLIENT;
connect(client, TQT_SIGNAL(sigEndConnect()), this, TQT_SLOT(slotLostServer()));
connect(client, TQT_SIGNAL(sigSocketFailure(int)), this, TQT_SLOT(slotSocketError(int)));
connect(client, TQT_SIGNAL(sigNewMessage(KMessage *)), this, TQT_SLOT(slotNewMessage(KMessage *)));
connect(client, TQT_SIGNAL(sigMessageSent(KMessage *)), this, TQT_SLOT(slotMessageSent(KMessage *)));
}
void KonnectionHandling::updateInternal(KBattleshipServer *server)
{
m_kbserver = server;
m_kbclient = 0;
m_type = KonnectionHandling::SERVER;
connect(server, TQT_SIGNAL(sigServerFailure()), this, TQT_SIGNAL(sigAbortNetworkGame()));
connect(server, TQT_SIGNAL(sigNewConnect()), this, TQT_SLOT(slotNewClient()));
connect(server, TQT_SIGNAL(sigEndConnect()), this, TQT_SLOT(slotLostClient()));
connect(server, TQT_SIGNAL(sigNewMessage(KMessage *)), this, TQT_SLOT(slotNewMessage(KMessage *)));
connect(server, TQT_SIGNAL(sigMessageSent(KMessage *)), this, TQT_SLOT(slotMessageSent(KMessage *)));
}
void KonnectionHandling::updateInternal(KBattleshipClient *client)
{
m_kbclient = client;
m_kbserver = 0;
m_type = KonnectionHandling::CLIENT;
connect(client, TQT_SIGNAL(sigEndConnect()), this, TQT_SLOT(slotLostServer()));
connect(client, TQT_SIGNAL(sigSocketFailure(int)), this, TQT_SLOT(slotSocketError(int)));
connect(client, TQT_SIGNAL(sigNewMessage(KMessage *)), this, TQT_SLOT(slotNewMessage(KMessage *)));
connect(client, TQT_SIGNAL(sigMessageSent(KMessage *)), this, TQT_SLOT(slotMessageSent(KMessage *)));
}
void KonnectionHandling::slotNewClient()
{
}
void KonnectionHandling::slotLostClient()
{
KMessageBox::error(0L, i18n("Connection to client lost. Aborting the game."));
emit sigClientLost();
}
void KonnectionHandling::slotMessageSent(KMessage *msg)
{
if(msg->type() == KMessage::SHOOT)
emit sigShootable(false);
delete msg;
}
void KonnectionHandling::slotNewMessage(KMessage *msg)
{
KMessage *copy;
if(type() == KonnectionHandling::CLIENT)
{
switch(msg->type())
{
// First possible message
case KMessage::DISCARD:
if(msg->field("kmversion") == TQString("true"))
{
KMessageBox::error(0L, i18n("Connection dropped by enemy. The client's protocol implementation (%1) is not compatible with our (%2) version.").arg(msg->field("reason")).arg(protocolVersion));
emit sigAbortNetworkGame();
}
else
KMessageBox::error(0L, i18n(msg->field("reason").latin1()));
break;
// Got some informations
case KMessage::GETVERSION:
emit sigClientInformation(msg->field("clientName"), msg->field("clientVersion"), msg->field("clientDescription"), msg->field("protocolVersion"));
break;
// Got the enemy's nickname
case KMessage::GREET:
emit sigEnemyNickname(msg->field("nickname"));
emit sigStatusBar(i18n("Waiting for other player to place their ships..."));
break;
// The server wants ous to place the ships
case KMessage::SHIPSREADY:
emit sigPlaceShips(true);
emit sigStatusBar(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
break;
// The server shot and wants the field state
case KMessage::SHOOT:
emit sigSendFieldState(msg->field("fieldx").toInt(), msg->field("fieldy").toInt());
emit sigStatusBar(i18n("Enemy has shot. Shoot now."));
emit sigShootable(true);
break;
// The server gave us the field data of our last shot
case KMessage::ANSWER_SHOOT:
emit sigShootable(false);
emit sigEnemyFieldData(msg->field("fieldx").toInt(), msg->field("fieldy").toInt(), msg->field("fieldstate").toInt(), msg->field("xstart").toInt(), msg->field("xstop").toInt(), msg->field("ystart").toInt(), msg->field("ystop").toInt(), (msg->field("death") == TQString("true")));
break;
// The server starts a new game
case KMessage::REPLAY:
emit sigStatusBar(i18n("Waiting for other player to place their ships..."));
emit sigReplay();
break;
// We lost the game
case KMessage::WON:
emit sigStatusBar(i18n("You lost the game :("));
copy = new KMessage(msg);
emit sigLost(copy);
break;
// We got a chat message
case KMessage::CHAT:
emit sigChatMessage(msg->field("nickname"), msg->field("chat"), true);
break;
}
}
else
{
switch(msg->type())
{
// First message....got client information
case KMessage::GETVERSION:
if(msg->field("protocolVersion") != TQString::fromLatin1(protocolVersion))
{
m_kbserver->slotDiscardClient(protocolVersion, true, false);
KMessageBox::error(0L, i18n("Connection to client dropped. The client's protocol implementation (%1) is not compatible with our (%2) version.").arg(msg->field("protocolVersion")).arg(protocolVersion));
}
else
emit sigClientInformation(msg->field("clientName"), msg->field("clientVersion"), msg->field("clientDescription"), msg->field("protocolVersion"));
break;
// Got the enemy's nickname
case KMessage::GREET:
KMessageBox::information(0L, i18n("We have a player. Let's start..."));
emit sigStatusBar(i18n("Please place your ships. Use the \"Shift\" key to place the ships vertically."));
emit sigEnemyNickname(msg->field("nickname"));
emit sigSendNickname();
emit sigPlaceShips(true);
break;
// The client placed his ships...we can shoot now
case KMessage::SHIPSREADY:
emit sigShootable(true);
emit sigStatusBar(i18n("You can shoot now."));
break;
// The client gave us the field data of our last shot
case KMessage::ANSWER_SHOOT:
emit sigShootable(false);
emit sigEnemyFieldData(msg->field("fieldx").toInt(), msg->field("fieldy").toInt(), msg->field("fieldstate").toInt(), msg->field("xstart").toInt(), msg->field("xstop").toInt(), msg->field("ystart").toInt(), msg->field("ystop").toInt(), (msg->field("death") == TQString("true")));
break;
// The client shot and wants the field state
case KMessage::SHOOT:
emit sigSendFieldState(msg->field("fieldx").toInt(), msg->field("fieldy").toInt());
emit sigStatusBar(i18n("Enemy has shot. Shoot now."));
emit sigShootable(true);
break;
// The client asks for a replay
case KMessage::REPLAY:
emit sigReplay();
break;
// We lost the game
case KMessage::WON:
emit sigStatusBar(i18n("You lost the game :("));
copy = new KMessage(msg);
emit sigLost(copy);
break;
// We got a chat message
case KMessage::CHAT:
emit sigChatMessage(msg->field("nickname"), msg->field("chat"), true);
break;
}
}
delete msg;
}
void KonnectionHandling::slotSocketError(int error)
{
switch(error)
{
case IO_ConnectError:
KMessageBox::error(0L, i18n("Connection refused by other host."));
break;
case IO_LookupError:
KMessageBox::error(0L, i18n("Couldn't lookup host."));
break;
case IO_ReadError:
KMessageBox::error(0L, i18n("Couldn't connect to server."));
break;
default:
KMessageBox::error(0L, i18n("Unknown error; No: %1").arg(error));
break;
}
emit sigAbortNetworkGame();
}
void KonnectionHandling::slotLostServer()
{
KMessageBox::error(0L, i18n("Connection to server lost. Aborting the game."));
emit sigServerLost();
}