QTfrontend/netclient.cpp
changeset 31 99888245a4e8
parent 29 9311259d5242
child 32 78bff13b11c0
equal deleted inserted replaced
30:794e98e11b66 31:99888245a4e8
    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,
    90 
    99 
    91 
   100 
    92 void HWNet::OnConnect()
   101 void HWNet::OnConnect()
    93 {
   102 {
    94 	state = nsConnected;
   103 	state = nsConnected;
    95 	SendNet(QString("USER hwgame 1 2 Hedgewars game"));
   104 	RawSendNet(QString("USER hwgame 1 2 Hedgewars game"));
    96 	SendNet(QString("NICK %1").arg(mynick));
   105 	RawSendNet(QString("NICK %1").arg(mynick));
    97 }
   106 }
    98 
   107 
    99 void HWNet::OnDisconnect()
   108 void HWNet::OnDisconnect()
   100 {
   109 {
   101 	state = nsDisconnected;
   110 	state = nsDisconnected;
   102 }
   111 }
   103 
   112 
   104 void HWNet::Perform()
   113 void HWNet::Perform()
   105 {
   114 {
   106 //	SendNet(QString("LIST"));
   115 
   107 	SendNet(QString("JOIN #alex"));
   116 }
       
   117 
       
   118 void HWNet::JoinGame(const QString & game)
       
   119 {
       
   120 	state = nsJoining;
       
   121 	RawSendNet(QString("JOIN %1").arg(game));
   108 }
   122 }
   109 
   123 
   110 void HWNet::Disconnect()
   124 void HWNet::Disconnect()
   111 {
   125 {
   112 	switch (state)
   126 	switch (state)
   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 {
   207 		{
   240 		{
   208 			if (opCount != 1)
   241 			if (opCount != 1)
   209 			{
   242 			{
   210 				opnick = "";
   243 				opnick = "";
   211 			}
   244 			}
   212 			SendNet(QString("PRIVMSG #alex :%1 ops here").arg(opCount));
       
   213 			opCount = 0;
   245 			opCount = 0;
   214 			break;
   246 			break;
   215 		}
   247 		}
   216 		case 432 : // ERR_ERRONEUSNICKNAME
   248 		case 432 : // ERR_ERRONEUSNICKNAME
   217 		case 433 : // ERR_NICKNAMEINUSE
   249 		case 433 : // ERR_NICKNAMEINUSE
   219 			// ask for another nick
   251 			// ask for another nick
   220 		}
   252 		}
   221 	}
   253 	}
   222 }
   254 }
   223 
   255 
   224 void HWNet::msgwho_cmd_paramHandler(const QString & msg)
   256 void HWNet::msgwho_cmd_targetHandler(const QString & msg)
   225 {
   257 {
   226 	QStringList list = msg.split(" ");
   258 	QStringList list = msg.split(" ");
   227 	QString who = list[0].mid(1).split("!")[0];
   259 	QString who = list[0].mid(1).split("!")[0];
   228 	if (list[1] == "NICK")
   260 	if (list[1] == "NICK")
   229 	{
   261 	{
   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 }