27 #include "game.h" |
27 #include "game.h" |
28 |
28 |
29 char delimeter='\n'; |
29 char delimeter='\n'; |
30 |
30 |
31 HWNewNet::HWNewNet() : |
31 HWNewNet::HWNewNet() : |
32 isChief(false), |
32 isChief(false), |
33 m_game_connected(false), |
33 m_game_connected(false), |
34 loginStep(0), |
34 loginStep(0), |
35 netClientState(Disconnected) |
35 netClientState(Disconnected) |
36 { |
36 { |
37 // socket stuff |
37 // socket stuff |
38 connect(&NetSocket, SIGNAL(readyRead()), this, SLOT(ClientRead())); |
38 connect(&NetSocket, SIGNAL(readyRead()), this, SLOT(ClientRead())); |
39 connect(&NetSocket, SIGNAL(connected()), this, SLOT(OnConnect())); |
39 connect(&NetSocket, SIGNAL(connected()), this, SLOT(OnConnect())); |
40 connect(&NetSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnect())); |
40 connect(&NetSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnect())); |
101 } |
101 } |
102 |
102 |
103 void HWNewNet::AddTeam(const HWTeam & team) |
103 void HWNewNet::AddTeam(const HWTeam & team) |
104 { |
104 { |
105 QString cmd = QString("ADD_TEAM") + delimeter + |
105 QString cmd = QString("ADD_TEAM") + delimeter + |
106 team.name() + delimeter + |
106 team.name() + delimeter + |
107 team.color().name() + delimeter + |
107 team.color().name() + delimeter + |
108 team.grave() + delimeter + |
108 team.grave() + delimeter + |
109 team.fort() + delimeter + |
109 team.fort() + delimeter + |
110 team.voicepack() + delimeter + |
110 team.voicepack() + delimeter + |
111 team.flag() + delimeter + |
111 team.flag() + delimeter + |
112 QString::number(team.difficulty()); |
112 QString::number(team.difficulty()); |
113 |
113 |
114 for(int i = 0; i < HEDGEHOGS_PER_TEAM; ++i) |
114 for(int i = 0; i < HEDGEHOGS_PER_TEAM; ++i) |
115 { |
115 { |
116 cmd.append(delimeter); |
116 cmd.append(delimeter); |
117 cmd.append(team.hedgehog(i).Name); |
117 cmd.append(team.hedgehog(i).Name); |
131 RawSendNet(QString("NICK%1%2").arg(delimeter).arg(nick)); |
131 RawSendNet(QString("NICK%1%2").arg(delimeter).arg(nick)); |
132 } |
132 } |
133 |
133 |
134 void HWNewNet::ToggleReady() |
134 void HWNewNet::ToggleReady() |
135 { |
135 { |
136 RawSendNet(QString("TOGGLE_READY")); |
136 RawSendNet(QString("TOGGLE_READY")); |
137 } |
137 } |
138 |
138 |
139 void HWNewNet::SendNet(const QByteArray & buf) |
139 void HWNewNet::SendNet(const QByteArray & buf) |
140 { |
140 { |
141 QString msg = QString(buf.toBase64()); |
141 QString msg = QString(buf.toBase64()); |
142 |
142 |
143 RawSendNet(QString("EM%1%2").arg(delimeter).arg(msg)); |
143 RawSendNet(QString("EM%1%2").arg(delimeter).arg(msg)); |
144 } |
144 } |
145 |
145 |
146 void HWNewNet::RawSendNet(const QString & str) |
146 void HWNewNet::RawSendNet(const QString & str) |
147 { |
147 { |
148 RawSendNet(str.toUtf8()); |
148 RawSendNet(str.toUtf8()); |
149 } |
149 } |
150 |
150 |
151 void HWNewNet::RawSendNet(const QByteArray & buf) |
151 void HWNewNet::RawSendNet(const QByteArray & buf) |
152 { |
152 { |
153 qDebug() << "Client: " << QString(buf).split("\n"); |
153 qDebug() << "Client: " << QString(buf).split("\n"); |
155 NetSocket.write("\n\n", 2); |
155 NetSocket.write("\n\n", 2); |
156 } |
156 } |
157 |
157 |
158 void HWNewNet::ClientRead() |
158 void HWNewNet::ClientRead() |
159 { |
159 { |
160 while (NetSocket.canReadLine()) { |
160 while (NetSocket.canReadLine()) |
|
161 { |
161 QString s = QString::fromUtf8(NetSocket.readLine()); |
162 QString s = QString::fromUtf8(NetSocket.readLine()); |
162 if (s.endsWith('\n')) s.chop(1); |
163 if (s.endsWith('\n')) s.chop(1); |
163 |
164 |
164 if (s.size() == 0) { |
165 if (s.size() == 0) |
|
166 { |
165 ParseCmd(cmdbuf); |
167 ParseCmd(cmdbuf); |
166 cmdbuf.clear(); |
168 cmdbuf.clear(); |
167 } else |
169 } |
|
170 else |
168 cmdbuf << s; |
171 cmdbuf << s; |
169 } |
172 } |
170 } |
173 } |
171 |
174 |
172 void HWNewNet::OnConnect() |
175 void HWNewNet::OnConnect() |
173 { |
176 { |
174 netClientState = Connected; |
177 netClientState = Connected; |
175 } |
178 } |
176 |
179 |
177 void HWNewNet::OnDisconnect() |
180 void HWNewNet::OnDisconnect() |
178 { |
181 { |
183 |
186 |
184 void HWNewNet::displayError(QAbstractSocket::SocketError socketError) |
187 void HWNewNet::displayError(QAbstractSocket::SocketError socketError) |
185 { |
188 { |
186 m_game_connected = false; |
189 m_game_connected = false; |
187 |
190 |
188 switch (socketError) { |
191 switch (socketError) |
|
192 { |
189 case QAbstractSocket::RemoteHostClosedError: |
193 case QAbstractSocket::RemoteHostClosedError: |
190 break; |
194 break; |
191 case QAbstractSocket::HostNotFoundError: |
195 case QAbstractSocket::HostNotFoundError: |
192 emit disconnected(tr("The host was not found. Please check the host name and port settings.")); |
196 emit disconnected(tr("The host was not found. Please check the host name and port settings.")); |
193 break; |
197 break; |
194 case QAbstractSocket::ConnectionRefusedError: |
198 case QAbstractSocket::ConnectionRefusedError: |
195 emit disconnected(tr("Connection refused")); |
199 emit disconnected(tr("Connection refused")); |
196 break; |
200 break; |
197 default: |
201 default: |
198 emit disconnected(NetSocket.errorString()); |
202 emit disconnected(NetSocket.errorString()); |
199 } |
203 } |
200 } |
204 } |
201 |
205 |
202 void HWNewNet::SendPasswordHash(const QString & hash) |
206 void HWNewNet::SendPasswordHash(const QString & hash) |
203 { |
207 { |
204 RawSendNet(QString("PASSWORD%1%2").arg(delimeter).arg(hash)); |
208 RawSendNet(QString("PASSWORD%1%2").arg(delimeter).arg(hash)); |
205 } |
209 } |
206 |
210 |
207 void HWNewNet::ParseCmd(const QStringList & lst) |
211 void HWNewNet::ParseCmd(const QStringList & lst) |
208 { |
212 { |
209 qDebug() << "Server: " << lst; |
213 qDebug() << "Server: " << lst; |
210 |
214 |
211 if(!lst.size()) |
215 if(!lst.size()) |
212 { |
216 { |
213 qWarning("Net client: Bad message"); |
217 qWarning("Net client: Bad message"); |
214 return; |
218 return; |
221 } |
225 } |
222 |
226 |
223 if (lst[0] == "PROTO") |
227 if (lst[0] == "PROTO") |
224 return ; |
228 return ; |
225 |
229 |
226 if (lst[0] == "ERROR") { |
230 if (lst[0] == "ERROR") |
|
231 { |
227 if (lst.size() == 2) |
232 if (lst.size() == 2) |
228 emit Error(lst[1]); |
233 emit Error(lst[1]); |
229 else |
234 else |
230 emit Error("Unknown error"); |
235 emit Error("Unknown error"); |
231 return; |
236 return; |
232 } |
237 } |
233 |
238 |
234 if (lst[0] == "WARNING") { |
239 if (lst[0] == "WARNING") |
|
240 { |
235 if (lst.size() == 2) |
241 if (lst.size() == 2) |
236 emit Warning(lst[1]); |
242 emit Warning(lst[1]); |
237 else |
243 else |
238 emit Warning("Unknown warning"); |
244 emit Warning("Unknown warning"); |
239 return; |
245 return; |
240 } |
246 } |
241 |
247 |
242 if (lst[0] == "CONNECTED") { |
248 if (lst[0] == "CONNECTED") |
|
249 { |
243 if(lst.size() < 3 || lst[2].toInt() < cMinServerVersion) |
250 if(lst.size() < 3 || lst[2].toInt() < cMinServerVersion) |
244 { |
251 { |
245 // TODO: Warn user, disconnect |
252 // TODO: Warn user, disconnect |
246 qWarning() << "Server too old"; |
253 qWarning() << "Server too old"; |
247 } |
254 } |
252 m_game_connected = true; |
259 m_game_connected = true; |
253 emit adminAccess(false); |
260 emit adminAccess(false); |
254 return; |
261 return; |
255 } |
262 } |
256 |
263 |
257 if (lst[0] == "PING") { |
264 if (lst[0] == "PING") |
|
265 { |
258 if (lst.size() > 1) |
266 if (lst.size() > 1) |
259 RawSendNet(QString("PONG%1%2").arg(delimeter).arg(lst[1])); |
267 RawSendNet(QString("PONG%1%2").arg(delimeter).arg(lst[1])); |
260 else |
268 else |
261 RawSendNet(QString("PONG")); |
269 RawSendNet(QString("PONG")); |
262 return; |
270 return; |
263 } |
271 } |
264 |
272 |
265 if (lst[0] == "ROOMS") { |
273 if (lst[0] == "ROOMS") |
|
274 { |
266 QStringList tmp = lst; |
275 QStringList tmp = lst; |
267 tmp.removeFirst(); |
276 tmp.removeFirst(); |
268 emit roomsList(tmp); |
277 emit roomsList(tmp); |
269 return; |
278 return; |
270 } |
279 } |
271 |
280 |
272 if (lst[0] == "SERVER_MESSAGE") { |
281 if (lst[0] == "SERVER_MESSAGE") |
|
282 { |
273 if(lst.size() < 2) |
283 if(lst.size() < 2) |
274 { |
284 { |
275 qWarning("Net: Empty SERVERMESSAGE message"); |
285 qWarning("Net: Empty SERVERMESSAGE message"); |
276 return; |
286 return; |
277 } |
287 } |
278 emit serverMessage(lst[1]); |
288 emit serverMessage(lst[1]); |
279 return; |
289 return; |
280 } |
290 } |
281 |
291 |
282 if (lst[0] == "CHAT") { |
292 if (lst[0] == "CHAT") |
|
293 { |
283 if(lst.size() < 3) |
294 if(lst.size() < 3) |
284 { |
295 { |
285 qWarning("Net: Empty CHAT message"); |
296 qWarning("Net: Empty CHAT message"); |
286 return; |
297 return; |
287 } |
298 } |
305 else |
317 else |
306 emit chatStringFromNet(tmp.join("\n").prepend('\x01')); |
318 emit chatStringFromNet(tmp.join("\n").prepend('\x01')); |
307 return; |
319 return; |
308 } |
320 } |
309 |
321 |
310 if (lst[0] == "SERVER_VARS") { |
322 if (lst[0] == "SERVER_VARS") |
|
323 { |
311 QStringList tmp = lst; |
324 QStringList tmp = lst; |
312 tmp.removeFirst(); |
325 tmp.removeFirst(); |
313 while (tmp.size() >= 2) |
326 while (tmp.size() >= 2) |
314 { |
327 { |
315 if(tmp[0] == "MOTD_NEW") emit serverMessageNew(tmp[1]); |
328 if(tmp[0] == "MOTD_NEW") emit serverMessageNew(tmp[1]); |
338 flags.remove(0, 1); |
351 flags.remove(0, 1); |
339 char c = flags[0].toAscii(); |
352 char c = flags[0].toAscii(); |
340 |
353 |
341 switch(c) |
354 switch(c) |
342 { |
355 { |
343 case 'r': |
356 case 'r': |
344 { |
357 { |
345 for(int i = 2; i < lst.size(); ++i) |
358 for(int i = 2; i < lst.size(); ++i) |
346 { |
359 { |
347 if (lst[i] == mynick) { |
360 if (lst[i] == mynick) |
|
361 { |
348 emit setMyReadyStatus(setFlag); |
362 emit setMyReadyStatus(setFlag); |
349 } |
363 } |
350 |
364 |
351 emit setReadyStatus(lst[i], setFlag); |
365 emit setReadyStatus(lst[i], setFlag); |
352 } |
366 } |
367 tmp.removeFirst(); |
382 tmp.removeFirst(); |
368 emit AddNetTeam(tmp); |
383 emit AddNetTeam(tmp); |
369 return; |
384 return; |
370 } |
385 } |
371 |
386 |
372 if (lst[0] == "REMOVE_TEAM") { |
387 if (lst[0] == "REMOVE_TEAM") |
|
388 { |
373 if(lst.size() != 2) |
389 if(lst.size() != 2) |
374 { |
390 { |
375 qWarning("Net: Bad REMOVETEAM message"); |
391 qWarning("Net: Bad REMOVETEAM message"); |
376 return; |
392 return; |
377 } |
393 } |
378 emit RemoveNetTeam(HWTeam(lst[1])); |
394 emit RemoveNetTeam(HWTeam(lst[1])); |
379 return; |
395 return; |
380 } |
396 } |
381 |
397 |
382 if(lst[0] == "ROOMABANDONED") { |
398 if(lst[0] == "ROOMABANDONED") |
|
399 { |
383 netClientState = InLobby; |
400 netClientState = InLobby; |
384 askRoomsList(); |
401 askRoomsList(); |
385 emit LeftRoom(tr("Room destroyed")); |
402 emit LeftRoom(tr("Room destroyed")); |
386 return; |
403 return; |
387 } |
404 } |
388 |
405 |
389 if(lst[0] == "KICKED") { |
406 if(lst[0] == "KICKED") |
|
407 { |
390 netClientState = InLobby; |
408 netClientState = InLobby; |
391 askRoomsList(); |
409 askRoomsList(); |
392 emit LeftRoom(tr("You got kicked")); |
410 emit LeftRoom(tr("You got kicked")); |
393 return; |
411 return; |
394 } |
412 } |
395 |
413 |
396 if(lst[0] == "JOINED") { |
414 if(lst[0] == "JOINED") |
|
415 { |
397 if(lst.size() < 2) |
416 if(lst.size() < 2) |
398 { |
417 { |
399 qWarning("Net: Bad JOINED message"); |
418 qWarning("Net: Bad JOINED message"); |
400 return; |
419 return; |
401 } |
420 } |
451 else |
472 else |
452 emit chatStringFromNet(tr("%1 *** %2 has left (%3)").arg('\x03').arg(lst[1], lst[2])); |
473 emit chatStringFromNet(tr("%1 *** %2 has left (%3)").arg('\x03').arg(lst[1], lst[2])); |
453 return; |
474 return; |
454 } |
475 } |
455 |
476 |
456 if(lst[0] == "ROOM") { |
477 if(lst[0] == "ROOM") |
|
478 { |
457 if(lst.size() < 2) |
479 if(lst.size() < 2) |
458 { |
480 { |
459 qWarning("Net: Bad ROOM message"); |
481 qWarning("Net: Bad ROOM message"); |
460 return; |
482 return; |
461 } |
483 } |
462 RawSendNet(QString("LIST")); |
484 RawSendNet(QString("LIST")); |
463 return; |
485 return; |
464 } |
486 } |
465 |
487 |
466 if(lst[0] == "LOBBY:LEFT") { |
488 if(lst[0] == "LOBBY:LEFT") |
|
489 { |
467 if(lst.size() < 2) |
490 if(lst.size() < 2) |
468 { |
491 { |
469 qWarning("Net: Bad LOBBY:LEFT message"); |
492 qWarning("Net: Bad LOBBY:LEFT message"); |
470 return; |
493 return; |
471 } |
494 } |
475 else |
498 else |
476 emit chatStringLobby(lst[1], tr("%1 *** %2 has left (%3)").arg('\x03').arg("|nick|", lst[2])); |
499 emit chatStringLobby(lst[1], tr("%1 *** %2 has left (%3)").arg('\x03').arg("|nick|", lst[2])); |
477 return; |
500 return; |
478 } |
501 } |
479 |
502 |
480 if (lst[0] == "RUN_GAME") { |
503 if (lst[0] == "RUN_GAME") |
|
504 { |
481 netClientState = InGame; |
505 netClientState = InGame; |
482 emit AskForRunGame(); |
506 emit AskForRunGame(); |
483 return; |
507 return; |
484 } |
508 } |
485 |
509 |
486 if (lst[0] == "ASKPASSWORD") { |
510 if (lst[0] == "ASKPASSWORD") |
|
511 { |
487 emit AskForPassword(mynick); |
512 emit AskForPassword(mynick); |
488 return; |
513 return; |
489 } |
514 } |
490 |
515 |
491 if (lst[0] == "NOTICE") { |
516 if (lst[0] == "NOTICE") |
|
517 { |
492 if(lst.size() < 2) |
518 if(lst.size() < 2) |
493 { |
519 { |
494 qWarning("Net: Bad NOTICE message"); |
520 qWarning("Net: Bad NOTICE message"); |
495 return; |
521 return; |
496 } |
522 } |
610 } |
644 } |
611 |
645 |
612 void HWNewNet::onHedgehogsNumChanged(const HWTeam& team) |
646 void HWNewNet::onHedgehogsNumChanged(const HWTeam& team) |
613 { |
647 { |
614 if (isChief) |
648 if (isChief) |
615 RawSendNet(QString("HH_NUM%1%2%1%3") |
649 RawSendNet(QString("HH_NUM%1%2%1%3") |
616 .arg(delimeter) |
650 .arg(delimeter) |
617 .arg(team.name()) |
651 .arg(team.name()) |
618 .arg(team.numHedgehogs())); |
652 .arg(team.numHedgehogs())); |
619 } |
653 } |
620 |
654 |
621 void HWNewNet::onTeamColorChanged(const HWTeam& team) |
655 void HWNewNet::onTeamColorChanged(const HWTeam& team) |
622 { |
656 { |
623 if (isChief) |
657 if (isChief) |
624 RawSendNet(QString("TEAM_COLOR%1%2%1%3") |
658 RawSendNet(QString("TEAM_COLOR%1%2%1%3") |
625 .arg(delimeter) |
659 .arg(delimeter) |
626 .arg(team.name()) |
660 .arg(team.name()) |
627 .arg(team.color().name())); |
661 .arg(team.color().name())); |
628 } |
662 } |
629 |
663 |
630 void HWNewNet::onParamChanged(const QString & param, const QStringList & value) |
664 void HWNewNet::onParamChanged(const QString & param, const QStringList & value) |
631 { |
665 { |
632 if (isChief) |
666 if (isChief) |
633 RawSendNet( |
667 RawSendNet( |
634 QString("CFG%1%2%1%3") |
668 QString("CFG%1%2%1%3") |
635 .arg(delimeter) |
669 .arg(delimeter) |
636 .arg(param) |
670 .arg(param) |
637 .arg(value.join(QString(delimeter))) |
671 .arg(value.join(QString(delimeter))) |
638 ); |
672 ); |
639 } |
673 } |
640 |
674 |
641 void HWNewNet::chatLineToNet(const QString& str) |
675 void HWNewNet::chatLineToNet(const QString& str) |
642 { |
676 { |
643 if(str != "") { |
677 if(str != "") |
|
678 { |
644 RawSendNet(QString("CHAT") + delimeter + str); |
679 RawSendNet(QString("CHAT") + delimeter + str); |
645 emit(chatStringFromMe(HWProto::formatChatMsg(mynick, str))); |
680 emit(chatStringFromMe(HWProto::formatChatMsg(mynick, str))); |
646 } |
681 } |
647 } |
682 } |
648 |
683 |
649 void HWNewNet::chatLineToLobby(const QString& str) |
684 void HWNewNet::chatLineToLobby(const QString& str) |
650 { |
685 { |
651 if(str != "") { |
686 if(str != "") |
|
687 { |
652 RawSendNet(QString("CHAT") + delimeter + str); |
688 RawSendNet(QString("CHAT") + delimeter + str); |
653 emit chatStringLobby(mynick, HWProto::formatChatMsgForFrontend(str)); |
689 emit chatStringLobby(mynick, HWProto::formatChatMsgForFrontend(str)); |
654 } |
690 } |
655 } |
691 } |
656 |
692 |