/** * 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); } }
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()); } } } } }