// ServerQueue.C -*- C++ -*- // Copyright (c) 1997, 1998 Etienne BERNARD // Copyright (C) 2002,2005,2008 Clinton Ebadi // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301, USA. #ifdef HAVE_CONFIG_H #include "config.h" #endif //#include #include "ServerQueue.H" #include "Utils.H" ServerQueue::ServerQueue(Socket * s, bool d) : Queue(s,d), penalty(0) { #ifdef HAVE_STL_CLEAR serverQueue.clear(); #endif } ServerQueue::~ServerQueue() { penalty = INT_MIN; flush(); } void ServerQueue::addItem(ServerQueueItem *sqi) { std::list::iterator it, it2; for (it = serverQueue.begin(); it != serverQueue.end(); ++it) { if ((*it)->priority > sqi->priority) { break; } } it2 = it; --it2; if (it2 != serverQueue.end() && *it2) { // All right, we try to merge this item to the previous if ((*it2)->merge(sqi)) { delete sqi; return; } } serverQueue.insert(it, sqi); } void ServerQueue::addLine(String l, int pr, int pen, int t) { ServerQueueOtherItem * sqoi = new ServerQueueOtherItem(l, pr, pen, t); addItem(sqoi); } bool ServerQueue::flush() { // Called every second, we decrement the penalty if (penalty > 0) { penalty--; } while (!serverQueue.empty() && (penalty < 5)) { ServerQueueItem * sqi = (*serverQueue.begin()); penalty += sqi->penalty + sqi->getLine().length()/100 + 1; bool res = sendLine(sqi->getLine()); serverQueue.erase(serverQueue.begin()); delete sqi; if (!res) { return false; } } return true; } #define MNICK (Interp::bot->nickName + "!" + Interp::bot->userHost) void ServerQueue::sendCTCP(String to, String command, String message) { sendPrivmsg(to, String("\001") + command + " " + message + "\001"); #ifdef USESCRIPTS if (command == "ACTION") { Interp::bot->botInterp->RunHooks (Hook::SEND_ACTION, MNICK + " " + to + " " + message, scm_list_n (Utils:: str2scm (MNICK), Utils:: str2scm (to), Utils:: str2scm (message), SCM_UNDEFINED)); } else Interp::bot->botInterp->RunHooks (Hook::SEND_CTCP, MNICK + " " + to + " " + command + " " + message, scm_list_n (Utils:: str2scm (MNICK), Utils:: str2scm (to), Utils:: str2scm (command), Utils:: str2scm (message), SCM_UNDEFINED)); #endif } #undef MNICK void ServerQueue::sendCTCPReply(String to, String command, String message) { sendNotice(to, String("\001") + command + " " + message + "\001"); } void ServerQueue::sendChannelMode(String mode) { addLine(mode, CHANNELMODE_PRIORITY, CHANNELMODE_PENALTY, ServerQueueItem::CHANNELMODE); } void ServerQueue::sendChannelMode(String channel, String mode, String parameters) { ServerQueueChannelModeItem * sqcmi = new ServerQueueChannelModeItem(channel, mode, parameters); addItem(sqcmi); } void ServerQueue::sendInvite(String channel, String nick) { addLine(String("INVITE ") + nick + " " + channel, INVITE_PRIORITY, INVITE_PENALTY, ServerQueueItem::INVITE); } void ServerQueue::sendJoin(String channel, String key) { addLine(String("JOIN ") + channel + " " + key, JOIN_PRIORITY, JOIN_PENALTY, ServerQueueItem::JOIN); } void ServerQueue::sendKick(String channel, String nick, String reason) { ServerQueueKickItem * sqki = new ServerQueueKickItem(channel, nick, reason); addItem(sqki); } void ServerQueue::sendNick(String nick) { addLine(String("NICK ") + nick, NICK_PRIORITY, NICK_PENALTY, ServerQueueItem::NICK); } void ServerQueue::sendNotice(String to, String message) { ServerQueueNoticeItem *sqni = new ServerQueueNoticeItem(to, message); addItem(sqni); } void ServerQueue::sendPart(String channel) { addLine(String("PART ") + channel, PART_PRIORITY, PART_PENALTY, ServerQueueItem::PART); } void ServerQueue::sendPass(String pass) { addLine(String("PASS ") + pass, NICK_PRIORITY, NICK_PENALTY, ServerQueueItem::PASS); } void ServerQueue::sendPing(String server) { addLine(String("PING :") + server, PING_PRIORITY, PING_PENALTY, ServerQueueItem::PING); } void ServerQueue::sendPong(String crap) { addLine(String("PONG ") + crap, PONG_PRIORITY, PONG_PENALTY, ServerQueueItem::PONG); } void ServerQueue::sendPrivmsg(String dest, String message) { addLine(String("PRIVMSG ") + dest + " :" + message, PRIVMSG_PRIORITY, PRIVMSG_PENALTY, ServerQueueItem::PRIVMSG); // hook stuff #ifdef USESCRIPTS if (message[0] != '\001') if (Utils::channel_p (dest)) Interp::bot->botInterp->RunHooks (Hook::SEND_PUBLIC, Interp::bot->nickName + " " + dest + " " + message, scm_list_n (Utils::str2scm (Interp::bot->nickName), Utils::str2scm (dest), Utils::str2scm (message), SCM_UNDEFINED)); else Interp::bot->botInterp->RunHooks (Hook::SEND_MESSAGE, Interp::bot->nickName + " " + dest + message, scm_list_n (Utils::str2scm (Interp::bot->nickName), Utils::str2scm (dest), Utils::str2scm (message), SCM_UNDEFINED)); #endif } void ServerQueue::sendQuit(String reason) { addLine(String("QUIT :") + reason, QUIT_PRIORITY, QUIT_PENALTY, ServerQueueItem::QUIT); } void ServerQueue::sendTopic(String channel, String topic) { addLine(String("TOPIC ") + channel + " :" + topic, TOPIC_PRIORITY, TOPIC_PENALTY, ServerQueueItem::TOPIC); } void ServerQueue::sendUser(String username, String ircname) { addLine(String("USER ") + username + " 0 * :" + ircname, NICK_PRIORITY, NICK_PENALTY, ServerQueueItem::USER); } void ServerQueue::sendUserMode(String nick, String mode) { addLine(String("MODE ") + nick + " " + mode, USERMODE_PRIORITY, USERMODE_PENALTY, ServerQueueItem::USERMODE); } void ServerQueue::sendUserhost(String nick) { addLine(String("USERHOST ") + nick, USERHOST_PRIORITY, USERHOST_PENALTY, ServerQueueItem::USERHOST); } void ServerQueue::sendWho(String who) { addLine(String("WHO ") + who, WHO_PRIORITY, WHO_PENALTY, ServerQueueItem::WHO); #ifdef USESCRIPTS Interp::bot->botInterp->RunHooks (Hook::SEND_WHO, who, scm_list_n (Utils:: str2scm (who), SCM_UNDEFINED)); #endif } void ServerQueue::sendWhois(String nick) { addLine(String("WHOIS ") + nick, NICK_PRIORITY, WHOIS_PENALTY, ServerQueueItem::WHOIS); #ifdef USESCRIPTS Interp::bot->botInterp->RunHooks (Hook::SEND_WHOIS, nick, scm_list_n (Utils:: str2scm (nick), SCM_UNDEFINED)); #endif }