Updated Glossario.tex
[GoMoku3D.git] / src / network / ClientSocket.cpp
blob77aebf460d2c8c30d79190881a90ad655960891a
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 <QVariant>
24 #include "ClientSocket.h"
26 #define HANDLER_SIGNATURE(token) \
27 void ClientSocket::parse_##token() { \
28 QString elementName = name().toString(); \
29 Q_ASSERT_X(elementName == #token, \
30 (QString("ClientSocket::parse_") + #token + "()").toUtf8().constData(), \
31 ("called while parsing " + elementName).toUtf8().constData()); \
32 SET_HANDLER(#token)
34 ClientSocket::ClientSocket(QTcpSocket *socket) : StreamSocket(socket)
36 connect(_socket, SIGNAL(hostFound()), this, SLOT(notifyHostFound()));
37 connect(_socket, SIGNAL(connected()), this, SLOT(openStream()));
40 void ClientSocket::joinGame(QString mode, QString name)
42 mode = mode.toLower();
44 Q_ASSERT_X(mode == "player" || mode == "spectator", "ClientSocket::joinGame()", "invalid mode value");
45 Q_ASSERT_X(!name.isEmpty(), "ClientSocket::joinGame()", "null or empty string passed as name");
47 if (state() != Idle) {
48 LOG("not sending <joinRequest> while state = " + stateString());
49 return;
52 writeStartElement("joinRequest");
53 writeAttribute("gameMode", mode);
54 writeCharacters(name);
55 writeEndElement();
57 _localPlayerName = name;
58 changeState(AwaitingJoinAnswer);
61 void ClientSocket::cancelJoin()
63 if (state() != AwaitingJoinAnswer && state() != AwaitingGameStart) {
64 LOG("no previous join request can be cancelled (state = " + stateString() + ")");
65 return;
68 writeTextElement("playerLeft", QString::number(-1));
70 _localPlayerName = "";
71 changeState(Idle);
74 void ClientSocket::notifyHostFound()
76 emit statusChanged(YELLOW_TEXT(tr("connecting...")));
79 BEGIN_TERMINAL_HANDLER(joinACK)
80 bool ok;
81 int id = readElementText().toInt(&ok);
82 if (!ok || id < -1 || id > 2) {
83 WARN(tr("invalid content in <joinACK> : %1").arg(readElementText()));
84 } else {
85 emit joinAccepted(id);
86 changeState(AwaitingGameStart);
88 RESTORE_HANDLER("")
89 END_TERMINAL_HANDLER
91 BEGIN_TERMINAL_HANDLER(joinNAK)
92 bool ok;
93 int errorCode = readElementText().toInt(&ok);
94 if (!ok) {
95 WARN(tr("invalid content in <joinNAK> : %1").arg(readElementText()));
96 errorCode = -1;
98 QString cause;
99 switch (errorCode) {
100 case 1:
101 cause = tr("You cannot join while a match\nis already in progress.");
102 break;
103 case 2:
104 cause = tr("The name you have chosen is already\nbeing used by someone else.");
105 break;
106 case 3:
107 cause = tr("The server you are connecting to\nis using an incompatible protocol version.");
108 break;
109 default:
110 cause = tr("An unknown error occurred.");
112 _localPlayerName = "";
113 emit joinRefused(cause);
114 changeState(Idle);
115 RESTORE_HANDLER("")
116 END_TERMINAL_HANDLER
118 BEGIN_NONTERMINAL_HANDLER(settings)
119 changeState(Idle);
120 QString playing = attributes().value("playing").toString().toLower();
121 emit receivedGameSettings(property("settings/d1").toInt(),
122 property("settings/d2").toInt(),
123 property("settings/numberOfPlayers").toInt(),
124 property("settings/timerDuration").toInt(),
125 playing == "true" ? true : false);
126 RESTORE_HANDLER("")
127 return;
128 END_NONTERMINAL_HANDLER(settings)
130 BEGIN_TERMINAL_HANDLER(difficultyOne)
131 bool ok;
132 int value = readElementText().toInt(&ok);
133 if (!ok) {
134 WARN(tr("invalid <difficultyOne> value in <settings> : %1").arg(readElementText()));
135 value = -1;
137 setProperty("settings/d1", QVariant(value));
138 RESTORE_HANDLER("settings")
139 END_TERMINAL_HANDLER
141 BEGIN_TERMINAL_HANDLER(difficultyTwo)
142 bool ok;
143 int value = readElementText().toInt(&ok);
144 if (!ok) {
145 WARN(tr("invalid <difficultyTwo> value in <settings> : %1").arg(readElementText()));
146 value = -1;
148 setProperty("settings/d2", QVariant(value));
149 RESTORE_HANDLER("settings")
150 END_TERMINAL_HANDLER
152 BEGIN_TERMINAL_HANDLER(numberOfPlayers)
153 bool ok;
154 int value = readElementText().toInt(&ok);
155 if (!ok) {
156 WARN(tr("invalid <numberOfPlayers> value in <settings> : %1").arg(readElementText()));
157 value = -1;
159 setProperty("settings/numberOfPlayers", QVariant(value));
160 RESTORE_HANDLER("settings")
161 END_TERMINAL_HANDLER
163 BEGIN_TERMINAL_HANDLER(timerDuration)
164 bool ok;
165 int value = readElementText().toInt(&ok);
166 if (!ok) {
167 WARN(tr("invalid <timerDuration> value in <settings> : %1").arg(readElementText()));
168 value = -1;
170 setProperty("settings/timerDuration", QVariant(value));
171 RESTORE_HANDLER("settings")
172 END_TERMINAL_HANDLER
174 HANDLER_SIGNATURE(history)
175 while (!atEnd()) {
176 readNext();
177 elementName = name().toString();
178 if (isStartElement()) {
179 parse("history_" + elementName);
180 } else if (isEndElement()) {
181 Q_ASSERT(elementName == "history");
182 QList<Move> moveList;
183 for (int i = 0; i < property("history/size").toInt(); i++) {
184 QVariant x = property(("history/move_" + QString::number(i)).toUtf8().constData());
185 moveList.append(x.value<Move>());
187 emit receivedHistory(moveList);
188 setProperty("history/size", QVariant(0));
189 RESTORE_HANDLER("")
190 return;
191 END_NONTERMINAL_HANDLER(history)
193 void ClientSocket::parse_history_move() {
194 QString elementName = name().toString();
195 qDebug() << "parsing" << "history_" + elementName;
196 Q_ASSERT_X(elementName == "move", "ClientSocket::parse_history_move()",
197 ("called while parsing " + elementName).toUtf8().constData());
198 SET_HANDLER("history_move")
199 while (!atEnd()) {
200 readNext();
201 elementName = name().toString();
202 if (isStartElement()) {
203 parse("history_" + elementName);
204 } else if (isEndElement()) {
205 Q_ASSERT(elementName == "move");
206 Move m(property("move/player").toInt(),
207 property("move/point").value<Point>());
208 int n = property("history/size").toInt();
209 setProperty(("history/move_" + QString::number(n)).toUtf8().constData(), QVariant::fromValue(m));
210 n++;
211 setProperty("history/size", QVariant(n));
212 RESTORE_HANDLER("history")
213 return;
214 } else {
215 LOG("unexpected data in <move> {" + tokenString() + "}");
218 RESTORE_HANDLER("")
221 void ClientSocket::parse_history_player() {
222 QString elementName = name().toString();
223 qDebug() << "parsing" << "history_" + elementName;
224 Q_ASSERT_X(elementName == "player", "ClientSocket::parse_history_player()",
225 ("called while parsing " + elementName).toUtf8().constData());
226 SET_HANDLER("history_player")
227 if (atEnd()) return;
228 bool ok;
229 int id = readElementText().toInt(&ok);
230 if (!ok) {
231 WARN(tr("invalid <player> value in <move> : %1").arg(readElementText()));
232 id = -1;
234 setProperty("move/player", QVariant(id));
235 RESTORE_HANDLER("history_move")
238 void ClientSocket::parse_history_point() {
239 QString elementName = name().toString();
240 qDebug() << "parsing" << "history_" + elementName;
241 Q_ASSERT_X(elementName == "point", "ClientSocket::parse_history_point()",
242 ("called while parsing " + elementName).toUtf8().constData());
243 SET_HANDLER("history_point")
244 while (!atEnd()) {
245 readNext();
246 elementName = name().toString();
247 if (isStartElement()) {
248 parse("history_" + elementName);
249 } else if (isEndElement()) {
250 Q_ASSERT(elementName == "point");
251 Point p(property("move/point/x").toInt(),
252 property("move/point/y").toInt(),
253 property("move/point/z").toInt());
254 setProperty("move/point", QVariant::fromValue(p));
255 RESTORE_HANDLER("history_move")
256 return;
257 } else {
258 LOG("unexpected data in <point> {" + tokenString() + "}");
261 RESTORE_HANDLER("")
264 void ClientSocket::parse_history_x() {
265 QString elementName = name().toString();
266 qDebug() << "parsing" << "history_" + elementName;
267 Q_ASSERT_X(elementName == "x", "ClientSocket::parse_history_x()",
268 ("called while parsing " + elementName).toUtf8().constData());
269 SET_HANDLER("history_x")
270 if (atEnd()) return;
271 bool ok;
272 int value = readElementText().toInt(&ok);
273 if (!ok) {
274 WARN(tr("invalid <x> value in <point> : %1").arg(readElementText()));
275 value = -1;
277 setProperty("move/point/x", QVariant(value));
278 RESTORE_HANDLER("history_point")
281 void ClientSocket::parse_history_y() {
282 QString elementName = name().toString();
283 qDebug() << "parsing" << "history_" + elementName;
284 Q_ASSERT_X(elementName == "y", "ClientSocket::parse_history_y()",
285 ("called while parsing " + elementName).toUtf8().constData());
286 SET_HANDLER("history_y")
287 if (atEnd()) return;
288 bool ok;
289 int value = readElementText().toInt(&ok);
290 if (!ok) {
291 WARN(tr("invalid <y> value in <point> : %1").arg(readElementText()));
292 value = -1;
294 setProperty("move/point/y", QVariant(value));
295 RESTORE_HANDLER("history_point")
298 void ClientSocket::parse_history_z() {
299 QString elementName = name().toString();
300 qDebug() << "parsing" << "history_" + elementName;
301 Q_ASSERT_X(elementName == "z", "ClientSocket::parse_history_z()",
302 ("called while parsing " + elementName).toUtf8().constData());
303 SET_HANDLER("history_z")
304 if (atEnd()) return;
305 bool ok;
306 int value = readElementText().toInt(&ok);
307 if (!ok) {
308 WARN(tr("invalid <z> value in <point> : %1").arg(readElementText()));
309 value = -1;
311 setProperty("move/point/z", QVariant(value));
312 RESTORE_HANDLER("history_point")