예제 #1
0
/**
 * Checks for a new newline terminated line in the buffer and parses it
 *
 * @param client			the IRC proxy client to check for buffer lines
 */
static void checkForBufferLine(IrcProxyClient *client)
{
	char *message = client->ibuffer->str;

	if(strstr(message, "\n") != NULL) { // message has at least one newline
		g_string_free(client->ibuffer, false);
		stripDuplicateNewlines(message); // remove duplicate newlines, since server could send \r\n
		char **parts = g_strsplit(message, "\n", 0);
		int count = 0;
		for(char **iter = parts; *iter != NULL; iter++) {
			count++;
		}

		for(int i = 0; i < count - 1; i++) { // Don't trigger the last part, it's not yet complete
			char *part = parts[i];
			if(strlen(part) > 0) {
				IrcMessage *ircMessage = parseIrcMessage(part);

				if(ircMessage != NULL) {
					triggerEvent(client, "line", ircMessage);
					freeIrcMessage(ircMessage);
				}
			}
		}

		client->ibuffer = g_string_new(parts[count-1]); // reinitialize buffer

		g_strfreev(parts);
		free(message);
	}
}
예제 #2
0
void IrcClient::onIrcLine(const std::string& line) {
	std::string prefix;
	std::string command;
	std::string parameters;
	std::string trailing;

	log(LL_Trace, "IRC line received: %s\n", line.c_str());

	parseIrcMessage(line, prefix, command, parameters, trailing);

	if(command == "001") {
		char login[128];
		sprintf(login, "JOIN %s\r\n", channelName.c_str());
		write(login, strlen(login));
		joined = true;
		log(LL_Info,
		    "Joined IRC channel %s at %s:%d as user %s\n",
		    channelName.c_str(),
		    ip.c_str(),
		    port,
		    nickname.c_str());
	} else if(command == "PING") {
		std::string pong = "PONG :" + trailing + "\r\n";
		write(pong.c_str(), pong.size());
	} else if(command == "PRIVMSG") {
		std::string sender;

		if(trailing.size() == 0)
			return;

		// ignore special commands
		if(trailing[0] < ' ')
			return;

		sender.assign(prefix, 0, prefix.find_first_of('!'));

		switch(trailing[0]) {
			case '\"': {
				std::string target, msg;
				size_t separator = trailing.find_first_of(' ');

				target.assign(trailing, 1, separator - 1);

				if(separator == std::string::npos || separator == trailing.size() - 1) {
					sendMessage(sender.c_str(),
					            "Utilisation des messages priv\xE9s comme en jeu: \"Player message \xE0 envoyer");
					break;
				}

				msg.assign(trailing, separator + 1, std::string::npos);
				mpGsToIrc[target] = sender;
				gameSession->sendMsgToGS(CHAT_WHISPER, sender.c_str(), target.c_str(), msg.c_str());
				break;
			}

			case '$':
				gameSession->sendMsgToGS(CHAT_ADV, sender.c_str(), "", trailing.c_str() + 1);
				break;

			case '!':
				gameSession->sendMsgToGS(CHAT_GLOBAL, sender.c_str(), "", trailing.c_str() + 1);
				break;

			case '#':
				gameSession->sendMsgToGS(CHAT_PARTY, sender.c_str(), "", trailing.c_str() + 1);
				break;

			case '%':
				gameSession->sendMsgToGS(CHAT_GUILD, sender.c_str(), "", trailing.c_str() + 1);
				break;

			default: {
				if(parameters == nickname) {
					std::string target;
					auto it = mpIrcToGs.find(std::string(sender));

					if(it == mpIrcToGs.end()) {
						sendMessage(sender.c_str(),
						            "Utilisation des messages priv\xE9s comme en jeu: \"Player message \xE0 envoyer");
					} else {
						target = it->second;
					}

					if(!target.empty())
						gameSession->sendMsgToGS(CHAT_WHISPER, sender.c_str(), target.c_str(), trailing.c_str());
				} else {
					gameSession->sendMsgToGS(CHAT_NORMAL, sender.c_str(), "", trailing.c_str());
				}
			}
		}
	}
}