1 // ServerQueue.C -*- C++ -*-
2 // Copyright (c) 1997, 1998 Etienne BERNARD
3 // Copyright (C) 2002,2005,2008 Clinton Ebadi
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
24 #include "ServerQueue.H"
29 #include "ServerQueueItem.H"
33 #include "BotInterp.H"
37 int ServerQueue::max_penalty = 20;
39 ServerQueue::ServerQueue(Socket * s, bool d)
40 : Queue(s,d), penalty(0)
47 ServerQueue::~ServerQueue()
49 penalty = std::numeric_limits<int>::min ();
54 ServerQueue::addItem(ServerQueueItem *sqi)
56 BotLock queue_lock (queue_mutex);
57 std::list<ServerQueueItem *>::iterator it, it2;
59 for (it = serverQueue.begin(); it != serverQueue.end(); ++it)
69 if (it2 != serverQueue.end() && *it2)
71 // All right, we try to merge this item to the previous
72 if ((*it2)->merge(sqi))
79 serverQueue.insert(it, sqi);
83 ServerQueue::addLine(String l, int pr, int pen, int t)
85 ServerQueueOtherItem * sqoi =
86 new ServerQueueOtherItem(l, pr, pen, t);
93 // Locking around the entire queue flush prevents another thread
94 // from spamming the queue and preventing lower priority messages
95 // from ever being sent
96 BotLock flush_lock (queue_mutex);
98 // Called every second, we decrement the penalty
104 while (!serverQueue.empty() && (penalty < max_penalty))
106 ServerQueueItem * sqi = serverQueue.front ();
107 penalty += sqi->penalty + sqi->getLine().length()/100;
109 bool res = sendLine(sqi->getLine());
111 serverQueue.pop_front ();
123 #define MNICK (Interp::bot->nickName + "!" + Interp::bot->userHost)
125 ServerQueue::sendCTCP(String to, String command,
128 sendPrivmsg(to, String("\001") + command + " " + message + "\001");
131 if (command == "ACTION")
133 Interp::bot->botInterp->RunHooks (Hook::SEND_ACTION,
145 Interp::bot->botInterp->RunHooks (Hook::SEND_CTCP,
146 MNICK + " " + to + " " +
147 command + " " + message,
164 ServerQueue::sendCTCPReply(String to, String command,
167 sendNotice(to, String("\001") + command + " " +
172 ServerQueue::sendChannelMode(String mode)
174 addLine(mode, CHANNELMODE_PRIORITY, CHANNELMODE_PENALTY,
175 ServerQueueItem::CHANNELMODE);
179 ServerQueue::sendChannelMode(String channel, String mode, String parameters)
181 ServerQueueChannelModeItem * sqcmi =
182 new ServerQueueChannelModeItem(channel, mode, parameters);
187 ServerQueue::sendInvite(String channel, String nick)
189 addLine(String("INVITE ") + nick + " " + channel,
190 INVITE_PRIORITY, INVITE_PENALTY, ServerQueueItem::INVITE);
194 ServerQueue::sendJoin(String channel, String key)
196 addLine(String("JOIN ") + channel + " " + key,
197 JOIN_PRIORITY, JOIN_PENALTY, ServerQueueItem::JOIN);
201 ServerQueue::sendKick(String channel, String nick, String reason)
203 ServerQueueKickItem * sqki =
204 new ServerQueueKickItem(channel, nick, reason);
209 ServerQueue::sendNick(String nick)
211 addLine(String("NICK ") + nick,
212 NICK_PRIORITY, NICK_PENALTY, ServerQueueItem::NICK);
216 ServerQueue::sendNotice(String to, String message)
218 ServerQueueNoticeItem *sqni =
219 new ServerQueueNoticeItem(to, message);
224 ServerQueue::sendPart(String channel)
226 addLine(String("PART ") + channel,
227 PART_PRIORITY, PART_PENALTY, ServerQueueItem::PART);
231 ServerQueue::sendPass(String pass)
233 addLine(String("PASS ") + pass,
234 NICK_PRIORITY, NICK_PENALTY, ServerQueueItem::PASS);
238 ServerQueue::sendPing(String server)
240 addLine(String("PING :") + server,
241 PING_PRIORITY, PING_PENALTY, ServerQueueItem::PING);
245 ServerQueue::sendPong(String crap)
247 addLine(String("PONG ") + crap,
248 PONG_PRIORITY, PONG_PENALTY, ServerQueueItem::PONG);
252 ServerQueue::sendPrivmsg(String dest, String message)
254 addLine(String("PRIVMSG ") + dest + " :" + message,
255 PRIVMSG_PRIORITY, PRIVMSG_PENALTY, ServerQueueItem::PRIVMSG);
258 if (message[0] != '\001')
259 if (Utils::channel_p (dest))
260 Interp::bot->botInterp->RunHooks (Hook::SEND_PUBLIC,
261 Interp::bot->nickName + " " + dest +
265 (Interp::bot->nickName),
266 Utils::str2scm (dest),
267 Utils::str2scm (message),
270 Interp::bot->botInterp->RunHooks
272 Interp::bot->nickName + " " + dest +
274 scm_list_n (Utils::str2scm (Interp::bot->nickName),
275 Utils::str2scm (dest),
277 (message), SCM_UNDEFINED));
282 ServerQueue::sendQuit(String reason)
284 addLine(String("QUIT :") + reason,
285 QUIT_PRIORITY, QUIT_PENALTY, ServerQueueItem::QUIT);
289 ServerQueue::sendTopic(String channel, String topic)
291 addLine(String("TOPIC ") + channel + " :" + topic,
292 TOPIC_PRIORITY, TOPIC_PENALTY, ServerQueueItem::TOPIC);
296 ServerQueue::sendUser(String username, String ircname)
298 addLine(String("USER ") + username + " 0 * :" + ircname,
299 NICK_PRIORITY, NICK_PENALTY, ServerQueueItem::USER);
303 ServerQueue::sendUserMode(String nick, String mode)
305 addLine(String("MODE ") + nick + " " + mode,
306 USERMODE_PRIORITY, USERMODE_PENALTY,
307 ServerQueueItem::USERMODE);
311 ServerQueue::sendUserhost(String nick)
313 addLine(String("USERHOST ") + nick,
314 USERHOST_PRIORITY, USERHOST_PENALTY, ServerQueueItem::USERHOST);
318 ServerQueue::sendWho(String who)
320 addLine(String("WHO ") + who,
321 WHO_PRIORITY, WHO_PENALTY, ServerQueueItem::WHO);
324 Interp::bot->botInterp->RunHooks (Hook::SEND_WHO,
333 ServerQueue::sendWhois(String nick)
335 addLine(String("WHOIS ") + nick,
336 NICK_PRIORITY, WHOIS_PENALTY, ServerQueueItem::WHOIS);
339 Interp::bot->botInterp->RunHooks (Hook::SEND_WHOIS,