summaryrefslogtreecommitdiffstats
path: root/chicken-wranglers/src/main/gamehost.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'chicken-wranglers/src/main/gamehost.cpp')
-rw-r--r--chicken-wranglers/src/main/gamehost.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/chicken-wranglers/src/main/gamehost.cpp b/chicken-wranglers/src/main/gamehost.cpp
new file mode 100644
index 0000000..6948d65
--- /dev/null
+++ b/chicken-wranglers/src/main/gamehost.cpp
@@ -0,0 +1,199 @@
+/****************************************************************************
+**
+** This file is a part of QtChickenWranglers.
+**
+** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).*
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions
+** are met:
+**
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+**
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in the
+** documentation and/or other materials provided with the distribution.
+**
+** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+** the names of its contributors may be used to endorse or promote
+** products derived from this software without specific prior written
+** permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+** FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+** COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+** BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+** LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+** ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+** POSSIBILITY OF SUCH DAMAGE."
+**
+****************************************************************************/
+
+
+#include <QtDeclarative>
+
+#include "global.h"
+#include "matchcontroller.h"
+#include "networkconnection.h"
+#include "playermodel.h"
+#include "settings.h"
+
+#include "gamehost.h"
+
+GameHost::GameHost(QDeclarativeContext *context, const QString &connectivity,
+ QObject *parent)
+ : QObject(parent), m_declarativeContext(context), m_networkServer(0),
+ m_playerListModel(new PlayerListModel(this)), m_matchController(0),
+ m_status(NoStatus), m_error(NoError)
+{
+ m_declarativeContext->setContextProperty("playerListModel", m_playerListModel);
+
+ qmlRegisterType<MatchController>("game.types", 1, 0, "Match");
+
+ m_networkServer = new NetworkServer(connectivity, Settings::lanUdpDiscoveryTimeout(),
+ Settings::lanUdpDiscoveryHostAttempts());
+ m_networkServer->setLanPorts(Settings::lanUdpPort(), Settings::lanTcpPort());
+
+ connect(m_networkServer, SIGNAL(error(NetworkServer::ServerError)),
+ this, SLOT(onServerError(NetworkServer::ServerError)));
+ connect(m_networkServer, SIGNAL(started()),
+ this, SLOT(onServerStarted()));
+ connect(m_networkServer, SIGNAL(peerConnected(NetworkConnection *)),
+ this, SLOT(onPeerConnected(NetworkConnection *)));
+ connect(m_networkServer, SIGNAL(peerDisconnected(NetworkConnection *)),
+ this, SLOT(onPeerDisconnected(NetworkConnection *)));
+}
+
+GameHost::GameHost(QObject *parent)
+ : QObject(parent)
+{
+}
+
+GameHost::~GameHost()
+{
+ delete m_networkServer;
+}
+
+void GameHost::setStatus(Status status)
+{
+ if (m_status == status)
+ return;
+
+ m_status = status;
+
+ if (m_status == Match)
+ newMatch();
+}
+
+void GameHost::newMatch()
+{
+ if (m_matchController) {
+ m_matchController->deleteLater();
+ m_matchController = 0;
+ }
+
+ m_matchController = new MatchController(m_playerListModel, Settings::matchChickenNumber(),
+ Settings::matchTime(), this);
+ m_declarativeContext->setContextProperty("matchController", m_matchController);
+
+ connect(m_matchController, SIGNAL(matchOver()),
+ this, SLOT(onMatchOver()));
+
+ m_playerListModel->notifyMatchReady();
+}
+
+void GameHost::startConnection()
+{
+ m_error = NoError;
+ m_status = NoStatus;
+
+ m_networkServer->start();
+}
+
+void GameHost::quit()
+{
+ m_error = NoError;
+ m_status = NoStatus;
+ m_networkServer->closeAll();
+
+ emit ended();
+}
+
+void GameHost::onPeerConnected(NetworkConnection *connection)
+{
+ qDebug("Peer connected: %d" , connection->id());
+
+ addPlayer(connection);
+}
+
+void GameHost::onPeerDisconnected(NetworkConnection *connection)
+{
+ qDebug("Peer disconnected: %d" , connection->id());
+
+ removePlayer(connection);
+}
+
+void GameHost::addPlayer(NetworkConnection *connection)
+{
+ if (m_playerListModel->rowCount() == Global::maximumPlayers) {
+ qWarning("Maximum number of players reached (%d)", Global::maximumPlayers);
+
+ // TODO: Notify client that host is full
+ return;
+ }
+
+ m_playerListModel->newPlayer(connection);
+}
+
+void GameHost::removePlayer(NetworkConnection *connection)
+{
+ m_playerListModel->removePlayer(connection);
+}
+
+void GameHost::onServerError(NetworkServer::ServerError error)
+{
+ if (error == NetworkServer::AnotherServerRunningError)
+ m_error = AnotherServerRunningError;
+ else
+ m_error = UnknownError;
+
+ if (m_status == Error)
+ return;
+
+ m_status = Error;
+ emit statusChanged();
+
+ quit();
+}
+
+void GameHost::onServerStarted()
+{
+ if (m_status == Start)
+ return;
+
+ m_status = Start;
+ emit statusChanged();
+}
+
+void GameHost::onMatchOver()
+{
+ m_status = WaitingRoom;
+
+ m_playerListModel->reset();
+ m_playerListModel->notifyMatchFinished();
+}
+
+void GameHost::setConnectivity(const QString &connectivity)
+{
+ m_networkServer->createConnectionHandler(connectivity);
+}