summaryrefslogtreecommitdiffstats
path: root/kbattleship/kbattleship/konnectionhandling.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kbattleship/kbattleship/konnectionhandling.cpp')
-rw-r--r--kbattleship/kbattleship/konnectionhandling.cpp246
1 files changed, 246 insertions, 0 deletions
diff --git a/kbattleship/kbattleship/konnectionhandling.cpp b/kbattleship/kbattleship/konnectionhandling.cpp
new file mode 100644
index 00000000..bcfefe04
--- /dev/null
+++ b/kbattleship/kbattleship/konnectionhandling.cpp
@@ -0,0 +1,246 @@
+/**************************************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(QWidget *parent, KBattleshipServer *server) : QObject(parent)
+{
+ m_kbserver = server;
+ m_kbclient = 0;
+ m_type = KonnectionHandling::SERVER;
+ connect(server, SIGNAL(sigServerFailure()), this, SIGNAL(sigAbortNetworkGame()));
+ connect(server, SIGNAL(sigNewConnect()), this, SLOT(slotNewClient()));
+ connect(server, SIGNAL(sigEndConnect()), this, SLOT(slotLostClient()));
+ connect(server, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(server, SIGNAL(sigMessageSent(KMessage *)), this, SLOT(slotMessageSent(KMessage *)));
+}
+
+KonnectionHandling::KonnectionHandling(QWidget *parent, KBattleshipClient *client) : QObject(parent)
+{
+ m_kbclient = client;
+ m_kbserver = 0;
+ m_type = KonnectionHandling::CLIENT;
+ connect(client, SIGNAL(sigEndConnect()), this, SLOT(slotLostServer()));
+ connect(client, SIGNAL(sigSocketFailure(int)), this, SLOT(slotSocketError(int)));
+ connect(client, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(client, SIGNAL(sigMessageSent(KMessage *)), this, SLOT(slotMessageSent(KMessage *)));
+}
+
+void KonnectionHandling::updateInternal(KBattleshipServer *server)
+{
+ m_kbserver = server;
+ m_kbclient = 0;
+ m_type = KonnectionHandling::SERVER;
+ connect(server, SIGNAL(sigServerFailure()), this, SIGNAL(sigAbortNetworkGame()));
+ connect(server, SIGNAL(sigNewConnect()), this, SLOT(slotNewClient()));
+ connect(server, SIGNAL(sigEndConnect()), this, SLOT(slotLostClient()));
+ connect(server, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(server, SIGNAL(sigMessageSent(KMessage *)), this, SLOT(slotMessageSent(KMessage *)));
+}
+
+void KonnectionHandling::updateInternal(KBattleshipClient *client)
+{
+ m_kbclient = client;
+ m_kbserver = 0;
+ m_type = KonnectionHandling::CLIENT;
+ connect(client, SIGNAL(sigEndConnect()), this, SLOT(slotLostServer()));
+ connect(client, SIGNAL(sigSocketFailure(int)), this, SLOT(slotSocketError(int)));
+ connect(client, SIGNAL(sigNewMessage(KMessage *)), this, SLOT(slotNewMessage(KMessage *)));
+ connect(client, SIGNAL(sigMessageSent(KMessage *)), this, 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") == QString("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") == QString("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") != QString::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") == QString("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();
+}