Big network update.
[GoMoku3D.git] / src / network / GameClient.cpp
blobfebcd8f685b7cbaa28874be8d119926db8251717
1 /********************************************************************
3 * Copyright (C) 2008 Davide Pesavento
5 * This file is part of GoMoku3D.
7 * GoMoku3D is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * GoMoku3D is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with GoMoku3D. If not, see <http://www.gnu.org/licenses/>.
20 *******************************************************************/
22 #include <QMutexLocker>
23 #include <QTcpSocket>
25 #include "GameClient.h"
26 #include "GameLoop.h"
27 #include "ChatWidget.h"
28 #include "SyncSharedCondition.h"
30 #define GREEN_TEXT(txt) \
31 QString("<html><head><meta name=\"qrichtext\" content=\"1\"/></head><body><p><span style=\"font-size:11pt; color:#008b00;\">") \
32 + txt + "</span></p></body></html>"
33 #define YELLOW_TEXT(txt) \
34 QString("<html><head><meta name=\"qrichtext\" content=\"1\"/></head><body><p><span style=\"font-size:11pt; color:#ebab00;\">") \
35 + txt + "</span></p></body></html>"
36 #define RED_TEXT(txt) \
37 QString("<html><head><meta name=\"qrichtext\" content=\"1\"/></head><body><p><span style=\"font-size:11pt; color:#8b0000;\">") \
38 + txt + "</span></p></body></html>"
40 GameClient::GameClient(QWidget *gui, QString serverAddress, quint16 serverPort) : Network(gui)
42 Q_ASSERT_X(gui != 0, "GameClient::GameClient()", "gui must not be null");
44 _localPlayer = -1;
45 QTcpSocket *s = new QTcpSocket();
46 _server = new ClientSocket(s);
48 connect(s, SIGNAL(hostFound()), this, SLOT(notifyStatusChange()));
49 connect(s, SIGNAL(connected()), this, SLOT(notifyStatusChange()));
50 connect(this, SIGNAL(statusChanged(QString)), gui, SLOT(setStatus(QString)));
51 connect(_server, SIGNAL(receivedGameSettings(int, int, int, int, bool)), gui, SLOT(displaySettings(int, int, int, int, bool)));
52 connect(_server, SIGNAL(joinAccepted(int)), this, SLOT(setLocalPlayer(int)));
53 connect(_server, SIGNAL(joinAccepted(int)), gui, SLOT(acceptedJoinRequest(int)));
54 connect(_server, SIGNAL(joinRefused(QString)), gui, SLOT(refusedJoinRequest(QString)));
55 connect(_server, SIGNAL(playerJoined(int, QString, QString)), gui, SLOT(addPlayer(int, QString, QString)));
56 connect(_server, SIGNAL(playerLeft(int)), gui, SLOT(removePlayer(int)));
57 //connect(_server, SIGNAL(receivedHistory(QList<Move>)), TODO);
58 connect(_server, SIGNAL(startGame()), gui, SLOT(gameStarted()));
59 connect(gui, SIGNAL(sendJoin(QString, QString)), _server, SLOT(joinGame(QString, QString)));
60 connect(_server, SIGNAL(receivedMove(Move)), this, SLOT(broadcastMove(Move)));
62 _server->changeState(StreamSocket::Connecting);
63 notifyStatusChange();
64 s->connectToHost(serverAddress, serverPort);
67 GameClient::~GameClient()
69 if (_server) {
70 delete _server;
74 void GameClient::broadcastMove(Move m)
76 // GameLoop sent the move
77 GameLoop *gl = qobject_cast<GameLoop*>(sender());
78 if (gl && (m.playerId() == _localPlayer)) {
79 _server->sendMove(m);
82 // the server sent the move
83 ClientSocket *socket = qobject_cast<ClientSocket*>(sender());
84 if (socket) {
85 QMutexLocker lock(SyncSharedCondition::instance());
86 SyncSharedCondition::instance()->notifyMove(m.point());
90 Point GameClient::requestMove()
92 Point p = _server->takeFirstMove().point();
93 if (p.isNull()) {
94 _server->changeState(StreamSocket::AwaitingMove);
96 return p;
99 void GameClient::setupChat(ChatWidget *widget)
101 if (widget) {
102 connect(_server, SIGNAL(receivedChatMessage(QString)), widget, SLOT(displayText(QString)));
103 connect(widget, SIGNAL(textEntered(QString)), _server, SLOT(sendChatMessage(QString)));
107 void GameClient::setupGameLoop(GameLoop *gameLoop)
109 connect(gameLoop, SIGNAL(moved(Move)), this, SLOT(broadcastMove(Move)));
112 void GameClient::setLocalPlayer(int id)
114 Q_ASSERT_X(id >= -1 && id <= 2, "GameClient::setLocalPlayer()", "invalid id");
115 Q_ASSERT_X(_server->state() == StreamSocket::AwaitingJoinAnswer,
116 "GameClient::setLocalPlayer()", "called outside 'AwaitingJoinAnswer' state");
118 _localPlayer = id;
121 void GameClient::notifyStatusChange()
123 switch (_server->state()) {
124 case StreamSocket::Unconnected:
125 emit statusChanged(RED_TEXT(tr("not connected")));
126 break;
127 case StreamSocket::Connecting:
128 case StreamSocket::OpeningStream:
129 emit statusChanged(YELLOW_TEXT(tr("connecting...")));
130 break;
131 case StreamSocket::FullyOpened:
132 emit statusChanged(GREEN_TEXT(tr("connected")));
133 break;
134 default:
135 break;