31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 */ |
32 */ |
33 |
33 |
34 #include <QMessageBox> |
34 #include <QMessageBox> |
35 #include "netclient.h" |
35 #include "netclient.h" |
36 |
36 #include "game.h" |
37 HWNet::HWNet() |
37 |
|
38 #include <QtDebug> |
|
39 |
|
40 #define chkp qDebug() << "hw chkp in " << __FILE__ << ":" << __LINE__ |
|
41 |
|
42 HWNet::HWNet(int Resolution, bool Fullscreen) |
38 : QObject() |
43 : QObject() |
39 { |
44 { |
|
45 gameResolution = Resolution; |
|
46 gameFullscreen = Fullscreen; |
40 state = nsDisconnected; |
47 state = nsDisconnected; |
41 IRCmsg_cmd_param = new QRegExp("^[A-Z]+ :.+$"); |
48 IRCmsg_cmd_text = new QRegExp("^[A-Z]+ :.+$"); |
42 IRCmsg_number_param = new QRegExp("^:\\S+ [0-9]{3} .+$"); |
49 IRCmsg_number_param = new QRegExp("^:\\S+ [0-9]{3} .+$"); |
43 IRCmsg_who_cmd_param = new QRegExp("^:\\S+ [A-Z]+ \\S+"); |
50 IRCmsg_who_cmd_target = new QRegExp("^:\\S+ [A-Z]+ \\S+$"); // last \\S should mean 'the 1st char is not ":"' |
44 IRCmsg_who_cmd_param_text = new QRegExp("^:\\S+ [A-Z]+ \\S+ :.+$"); |
51 IRCmsg_who_cmd_text = new QRegExp("^:\\S+ [A-Z]+ :.+$"); |
|
52 IRCmsg_who_cmd_target_text = new QRegExp("^:\\S+ [A-Z]+ \\S+ :.+$"); |
45 isOp = false; |
53 isOp = false; |
|
54 teamsCount = 0; |
46 |
55 |
47 connect(&NetSocket, SIGNAL(readyRead()), this, SLOT(ClientRead())); |
56 connect(&NetSocket, SIGNAL(readyRead()), this, SLOT(ClientRead())); |
48 connect(&NetSocket, SIGNAL(connected()), this, SLOT(OnConnect())); |
57 connect(&NetSocket, SIGNAL(connected()), this, SLOT(OnConnect())); |
49 connect(&NetSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnect())); |
58 connect(&NetSocket, SIGNAL(disconnected()), this, SLOT(OnDisconnect())); |
50 connect(&NetSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, |
59 connect(&NetSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, |
122 break; |
136 break; |
123 } |
137 } |
124 default: |
138 default: |
125 { |
139 { |
126 state = nsQuitting; |
140 state = nsQuitting; |
127 SendNet(QString("QUIT :oops")); |
141 RawSendNet(QString("QUIT :oops")); |
128 } |
142 } |
129 } |
143 } |
130 } |
144 } |
131 |
145 |
132 void HWNet::SendNet(const QString & str) |
146 void HWNet::RawSendNet(const QString & str) |
133 { |
147 { |
134 SendNet(str.toLatin1()); |
148 RawSendNet(str.toLatin1()); |
135 } |
149 } |
136 |
150 |
137 void HWNet::SendNet(const QByteArray & buf) |
151 void HWNet::RawSendNet(const QByteArray & buf) |
138 { |
152 { |
139 if (buf.size() > 510) return; |
153 if (buf.size() > 510) return; |
140 NetSocket.write(buf); |
154 NetSocket.write(buf); |
141 NetSocket.write("\x0d\x0a", 2); |
155 NetSocket.write("\x0d\x0a", 2); |
142 } |
156 } |
143 |
157 |
|
158 void HWNet::SendNet(const QByteArray & buf) |
|
159 { |
|
160 if ((state == nsGaming) || (state == nsStarting)) |
|
161 { |
|
162 QString msg = QString(buf.toBase64()); |
|
163 if (msg == "AUM=") |
|
164 { |
|
165 ConfigAsked(); |
|
166 } else |
|
167 { |
|
168 RawSendNet(QString("PRIVMSG %1 :"MAGIC_CHAR MAGIC_CHAR"%2").arg(channel, msg)); |
|
169 } |
|
170 } |
|
171 } |
|
172 |
144 void HWNet::ParseLine(const QString & msg) |
173 void HWNet::ParseLine(const QString & msg) |
145 { |
174 { |
146 //QMessageBox::information(0, "", msg); |
175 //QMessageBox::information(0, "", msg); |
147 if (IRCmsg_cmd_param->exactMatch(msg)) |
176 if (IRCmsg_cmd_text->exactMatch(msg)) |
148 { |
177 { |
149 msgcmd_paramHandler(msg); |
178 msgcmd_textHandler(msg); |
150 } else |
179 } else |
151 if (IRCmsg_number_param->exactMatch(msg)) |
180 if (IRCmsg_number_param->exactMatch(msg)) |
152 { |
181 { |
153 msgnumber_paramHandler(msg); |
182 msgnumber_paramHandler(msg); |
154 } else |
183 } else |
155 if (IRCmsg_who_cmd_param->exactMatch(msg)) |
184 if (IRCmsg_who_cmd_text->exactMatch(msg)) |
156 { |
185 { |
157 msgwho_cmd_paramHandler(msg); |
186 msgwho_cmd_textHandler(msg); |
158 } else |
187 } else |
159 if (IRCmsg_who_cmd_param_text->exactMatch(msg)) |
188 if (IRCmsg_who_cmd_target->exactMatch(msg)) |
160 { |
189 { |
161 msgwho_cmd_param_textHandler(msg); |
190 msgwho_cmd_targetHandler(msg); |
162 } |
191 } else |
163 } |
192 if (IRCmsg_who_cmd_target_text->exactMatch(msg)) |
164 |
193 { |
165 void HWNet::msgcmd_paramHandler(const QString & msg) |
194 msgwho_cmd_target_textHandler(msg); |
|
195 } |
|
196 } |
|
197 |
|
198 void HWNet::msgcmd_textHandler(const QString & msg) |
166 { |
199 { |
167 QStringList list = msg.split(" :"); |
200 QStringList list = msg.split(" :"); |
168 if (list[0] == "PING") |
201 if (list[0] == "PING") |
169 { |
202 { |
170 SendNet(QString("PONG %1").arg(list[1])); |
203 RawSendNet(QString("PONG %1").arg(list[1])); |
171 } |
204 } |
172 } |
205 } |
173 |
206 |
174 void HWNet::msgnumber_paramHandler(const QString & msg) |
207 void HWNet::msgnumber_paramHandler(const QString & msg) |
175 { |
208 { |
232 if (opnick == who) |
264 if (opnick == who) |
233 opnick = list[2]; |
265 opnick = list[2]; |
234 } |
266 } |
235 } |
267 } |
236 |
268 |
237 void HWNet::msgwho_cmd_param_textHandler(const QString & msg) |
269 void HWNet::msgwho_cmd_textHandler(const QString & msg) |
|
270 { |
|
271 int pos = msg.indexOf(" :"); |
|
272 QString text = msg.mid(pos + 2); |
|
273 QStringList list = msg.mid(0, pos).split(" "); |
|
274 QString who = list[0].mid(1).split("!")[0]; |
|
275 if (list[1] == "JOIN") |
|
276 { |
|
277 if (who == mynick) |
|
278 { |
|
279 channel = text; |
|
280 state = nsJoined; |
|
281 emit EnteredGame(); |
|
282 RawSendNet(QString("PRIVMSG %1 :Hello!").arg(channel)); |
|
283 } |
|
284 } |
|
285 } |
|
286 void HWNet::msgwho_cmd_target_textHandler(const QString & msg) |
238 { |
287 { |
239 int pos = msg.indexOf(" :"); |
288 int pos = msg.indexOf(" :"); |
240 QString text = msg.mid(pos + 2); |
289 QString text = msg.mid(pos + 2); |
241 QStringList list = msg.mid(0, pos).split(" "); |
290 QStringList list = msg.mid(0, pos).split(" "); |
242 QString who = list[0].mid(1).split("!")[0]; |
291 QString who = list[0].mid(1).split("!")[0]; |
243 if (list[1] == "PRIVMSG") |
292 if (list[1] == "PRIVMSG") |
244 { |
293 { |
245 SendNet(QString("PRIVMSG #alex :%1 said \"%2\" to %3").arg(who, text, list[2])); |
294 if (list[2] == opnick) |
246 } |
295 { |
247 } |
296 hwp_opmsg(who, text); |
|
297 } else |
|
298 if (list[2] == channel) |
|
299 { |
|
300 hwp_chanmsg(who, text); |
|
301 } |
|
302 } |
|
303 } |
|
304 |
|
305 void HWNet::hwp_opmsg(const QString & who, const QString & msg) |
|
306 { |
|
307 if (state != nsJoined) |
|
308 return ; |
|
309 if (!msg.startsWith(MAGIC_CHAR)) |
|
310 return ; |
|
311 QStringList list = msg.split(MAGIC_CHAR, QString::SkipEmptyParts); |
|
312 if (list[0] == "A") |
|
313 { |
|
314 list.removeFirst(); |
|
315 if (list.size() != 9) |
|
316 return ; |
|
317 if (teamsCount < 5) |
|
318 { |
|
319 teams[teamsCount].nick = who; |
|
320 teams[teamsCount].hhs = list; |
|
321 teamsCount++; |
|
322 QString teamnames; |
|
323 for(int i = 0; i < teamsCount; i++) |
|
324 { |
|
325 teamnames += MAGIC_CHAR; |
|
326 teamnames += teams[i].hhs[0]; |
|
327 } |
|
328 RawSendNet(QString("PRIVMSG %1 :"MAGIC_CHAR"Teams%2").arg(channel, teamnames)); |
|
329 } |
|
330 } |
|
331 } |
|
332 |
|
333 void HWNet::ConfigAsked() |
|
334 { |
|
335 configasks++; |
|
336 if (configasks == playerscnt) |
|
337 { |
|
338 quint32 color = 65535; |
|
339 for (int i = 0; i < teamsCount; i++) |
|
340 { |
|
341 chkp; SENDCFGSTRNET("eaddteam"); |
|
342 QString msg; |
|
343 msg = MAGIC_CHAR "T" MAGIC_CHAR + teams[i].nick + MAGIC_CHAR + teams[i].hhs.join(MAGIC_CHAR); |
|
344 RawSendNet(QString("PRIVMSG %1 :%2").arg(channel, msg)); |
|
345 hwp_chanmsg(mynick, msg); |
|
346 SENDCFGSTRNET(QString("ecolor %1").arg(color)); |
|
347 SENDCFGSTRNET("eadd hh0 0"); |
|
348 SENDCFGSTRNET("eadd hh1 0"); |
|
349 SENDCFGSTRNET("eadd hh2 0"); |
|
350 color <<= 8; |
|
351 } |
|
352 chkp; SENDCFGSTRNET("!"); |
|
353 } |
|
354 } |
|
355 |
|
356 void HWNet::hwp_chanmsg(const QString & who, const QString & msg) |
|
357 { |
|
358 if ((state < nsJoined) || (state > nsGaming)) |
|
359 { |
|
360 return ; |
|
361 } |
|
362 if ((state == nsJoined) && (msg.startsWith(MAGIC_CHAR"Start!"MAGIC_CHAR)) && (who == opnick)) |
|
363 { |
|
364 state = nsStarting; |
|
365 RunGame(msg.mid(7)); |
|
366 return ; |
|
367 } |
|
368 if ((state == nsStarting) && (msg == MAGIC_CHAR MAGIC_CHAR "AUM=")) |
|
369 { |
|
370 if (mynick == opnick) ConfigAsked(); |
|
371 return ; |
|
372 } |
|
373 if ((state == nsStarting) && (msg.startsWith(MAGIC_CHAR"T"MAGIC_CHAR))) |
|
374 { |
|
375 NetTeamAdded(msg.mid(3)); |
|
376 } |
|
377 if (state != nsGaming) |
|
378 { |
|
379 return; |
|
380 } |
|
381 if (msg.startsWith(MAGIC_CHAR MAGIC_CHAR)) // HWP message |
|
382 { |
|
383 emit FromNet(QByteArray::fromBase64(msg.mid(2).toLocal8Bit())); |
|
384 } else // smth other |
|
385 { |
|
386 |
|
387 } |
|
388 } |
|
389 |
|
390 void HWNet::NetTeamAdded(const QString & msg) |
|
391 { |
|
392 QStringList list = msg.split(MAGIC_CHAR, QString::SkipEmptyParts); |
|
393 if (list.size() != 10) |
|
394 return ; |
|
395 if (list[0] == mynick) |
|
396 { |
|
397 chkp; emit LocalCFG(list[1]); |
|
398 } else |
|
399 { |
|
400 chkp; SENDCFGSTRLOC("erdriven"); |
|
401 SENDCFGSTRLOC(QString("ename team %1").arg(list[2])); |
|
402 for (int i = 0; i < 8; i++) |
|
403 { |
|
404 SENDCFGSTRLOC(QString("ename hh%1").arg(i) + list[i + 3]); |
|
405 } |
|
406 chkp; } |
|
407 } |
|
408 |
|
409 void HWNet::AddTeam(const HWTeam & team) |
|
410 { |
|
411 if (state != nsJoined) |
|
412 { |
|
413 return ; |
|
414 } |
|
415 RawSendNet(QString("PRIVMSG %1 :").arg(opnick) + MAGIC_CHAR "A" MAGIC_CHAR + |
|
416 team.TeamName + MAGIC_CHAR + team.HHName[0] + MAGIC_CHAR + team.HHName[1] + MAGIC_CHAR + |
|
417 team.HHName[2] + MAGIC_CHAR + team.HHName[3] + MAGIC_CHAR + team.HHName[4] + MAGIC_CHAR + |
|
418 team.HHName[5] + MAGIC_CHAR + team.HHName[6] + MAGIC_CHAR + team.HHName[7]); |
|
419 } |
|
420 |
|
421 void HWNet::StartGame() |
|
422 { |
|
423 if ((opnick != mynick) || (state != nsJoined)) |
|
424 { |
|
425 return ; |
|
426 } |
|
427 QStringList players; |
|
428 for (int i = 0; i < teamsCount; i++) |
|
429 { |
|
430 if (!players.contains(teams[i].nick)) |
|
431 { |
|
432 players.append(teams[i].nick); |
|
433 } |
|
434 } |
|
435 playerscnt = players.size(); |
|
436 configasks = 0; |
|
437 |
|
438 QString seed; |
|
439 seedgen.GenRNDStr(seed, 10); |
|
440 QString msg = QString(MAGIC_CHAR"Start!"MAGIC_CHAR"%1").arg(seed); |
|
441 RawSendNet(QString("PRIVMSG %1 :%2").arg(channel, msg)); |
|
442 hwp_chanmsg(mynick, msg); |
|
443 } |
|
444 |
|
445 void HWNet::RunGame(const QString & seed) |
|
446 { |
|
447 HWGame * game = new HWGame(gameResolution, gameFullscreen); |
|
448 connect(game, SIGNAL(SendNet(const QByteArray &)), this, SLOT(SendNet(const QByteArray &))); |
|
449 connect(this, SIGNAL(FromNet(const QByteArray &)), game, SLOT(FromNet(const QByteArray &))); |
|
450 connect(this, SIGNAL(LocalCFG(const QString &)), game, SLOT(LocalCFG(const QString &))); |
|
451 game->StartNet(seed); |
|
452 } |