1 // Channel.C -*- C++ -*-
2 // Copyright (c) 1997, 1998 Etienne BERNARD
3 // Copyright (C) 2002,2005,2008,2009 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
33 #include "ServerConnection.H"
34 #include "ShitEntry.H"
36 #include "StringTokenizer.H"
44 Channel::Channel(ServerConnection *c,
45 std::string name, std::string wanted = "")
46 : channelName(Utils::to_lower(name)), channelTopic(""),
47 lockedTopic(false), channelMode(0), channelLimit(0),
48 channelKey(""), keepModes(DEFAULT_KEEPMODES), wantedModes(wanted),
49 channelUserlist (name),
50 joined(false), doMode(true), gotWho(false), cnx(c)
52 if (c->bot->wantedChannels[channelName])
54 if (c->bot->wantedChannels[channelName]->keep != "")
55 keepModes = c->bot->wantedChannels[channelName]->keep;
57 if (c->bot->wantedChannels[channelName]->mode != "")
58 wantedModes = c->bot->wantedChannels[channelName]->mode;
66 Channel::addNick(std::string n, std::string uh, int mode, UserList *ul,
69 channelUserlist.add (n, uh, mode, ul, names);
73 Channel::delNick(std::string n)
75 channelUserlist.del (n);
79 Channel::changeNick(std::string on, std::string nn)
81 channelUserlist.change_nickname (on, nn);
85 Channel::hasNick(const std::string &n) const
87 return channelUserlist.in_channel_p (n);
91 Channel::getUser(const std::string &n) const
93 return channelUserlist.get (n);
97 Channel::change_user_key (std::string name, std::string key)
99 channelUserlist.change_user_key (name, key);
103 Channel::user_count () const throw ()
105 return channelUserlist.user_count ();
109 Channel::operator_count () const throw ()
111 return channelUserlist.operator_count ();
115 Channel::addBan(const Mask & mask, std::time_t expiration)
117 if (channelBanlist.add (mask, expiration))
118 cnx->queue->sendChannelMode (channelName, "+b", mask.getMask ());
122 Channel::delBan(const Mask & mask)
124 BanList::MatchList matches = channelBanlist.find_matches (mask);
126 for (BanList::MatchList::const_iterator it = matches.begin ();
127 it != matches.end ();
130 if (channelBanlist.del (*it))
131 cnx->queue->sendChannelMode (channelName, "-b", mask.getMask ());
135 void Channel::purge_expired_bans ()
137 BanList::MatchList expired = channelBanlist.delete_expired_x ();
139 for (BanList::MatchList::const_iterator it = expired.begin ();
140 it != expired.end ();
142 cnx->queue->sendChannelMode (channelName, "-b", (*it).getMask ());
146 Channel::resynchModes()
148 cnx->queue->sendChannelMode(std::string("MODE ") + channelName +
149 " +" + cnx->bot->wantedChannels[channelName]->mode);
153 Channel::parseMode(Person *from, std::string mode)
156 StringTokenizer st(mode);
157 std::string m = st.next_token(), n;
158 bool doNotObey = true; // disobey mode if server or target is protected
162 doNotObey = getUser(from->getNick()).getProt () <= User::NO_PROT;
164 catch (ChannelUserList::user_not_found&)
170 for (int i = 0; i < m.length(); i++)
176 case 'p': sign =='+' ? channelMode |= PRIVATE :
177 channelMode &= ~PRIVATE;
178 if (keepModes.find('p') != -1 && doNotObey) {
179 if (sign == '-' && wantedModes.find('p') != -1)
180 cnx->queue->sendChannelMode(channelName, "+p", "");
182 cnx->queue->sendChannelMode(channelName, "-p", "");
185 case 's': sign =='+' ? channelMode |= SECRET :
186 channelMode &= ~SECRET;
187 if (keepModes.find('s') != -1 && doNotObey) {
188 if (sign == '-' && wantedModes.find('s') != -1)
189 cnx->queue->sendChannelMode(channelName, "+s", "");
191 cnx->queue->sendChannelMode(channelName, "-s", "");
194 case 'i': sign =='+' ? channelMode |= INVITE_ONLY :
195 channelMode &= ~INVITE_ONLY;
196 if (keepModes.find('i') != -1 && doNotObey) {
197 if (sign == '-' && wantedModes.find('i') != -1)
198 cnx->queue->sendChannelMode(channelName, "+i", "");
200 cnx->queue->sendChannelMode(channelName, "-i", "");
203 case 't': sign =='+' ? channelMode |= TOPIC_RESTRICTED :
204 channelMode &= ~TOPIC_RESTRICTED;
205 if (keepModes.find('t') != -1 && doNotObey) {
206 if (sign == '-' && wantedModes.find('t') != -1)
207 cnx->queue->sendChannelMode(channelName, "+t", "");
209 cnx->queue->sendChannelMode(channelName, "-t", "");
212 case 'n': sign =='+' ? channelMode |= EXTMSG_RESTRICTED :
213 channelMode &= ~EXTMSG_RESTRICTED;
214 if (keepModes.find('n') != -1 && doNotObey) {
215 if (sign == '-' && wantedModes.find('n') != -1)
216 cnx->queue->sendChannelMode(channelName, "+n", "");
218 cnx->queue->sendChannelMode(channelName, "-n", "");
221 case 'm': sign =='+' ? channelMode |= MODERATED :
222 channelMode &= ~MODERATED;
223 if (keepModes.find('m') != -1 && doNotObey) {
224 if (sign == '-' && wantedModes.find('m') != -1)
225 cnx->queue->sendChannelMode(channelName, "+m", "");
227 cnx->queue->sendChannelMode(channelName, "-m", "");
231 if (keepModes.find('l') != -1 && doNotObey) {
232 if (sign == '-' && wantedModes.find('l') != -1)
233 cnx->queue->sendChannelMode(channelName, "+l",
234 Utils::long2str(channelLimit));
236 cnx->queue->sendChannelMode(channelName, "-l", "");
238 channelLimit = (sign == '+' ? std::atoi(st.next_token().c_str()) :
242 channelKey = st.next_token();
243 if (keepModes.find('k') != -1 && doNotObey) {
244 if (sign == '-' && wantedModes.find('k') != -1)
245 cnx->queue->sendChannelMode(channelName, "+k", channelKey);
247 cnx->queue->sendChannelMode(channelName, "-k", channelKey);
249 cnx->bot->wantedChannels[channelName]->key = (sign == '+' ? channelKey :
258 // sign == '+' ? countOp++ : countOp--;
259 channelUserlist.change_user_mode (n, User::OP_MODE, sign != '+');
261 if (sign == '-' && u.getProt() >= User::NO_DEOP) {
262 std::string fromNick = from->getNick();
263 User v = getUser(fromNick);
268 if (v.getProt() < User::NO_DEOP)
269 cnx->queue->sendChannelMode(channelName, "-o", fromNick);
271 cnx->queue->sendChannelMode(channelName, "+o", n);
275 if (doNotObey && !from &&
276 u.getProt() < User::NO_DEOP && !u.getAop())
277 cnx->queue->sendChannelMode(channelName, "-o", n);
279 cnx->bot->shitList->getShit(n+"!"+cnx->bot->getUserhost(channelName, n),
281 if (se && se->isStillValid() &&
282 se->getShitLevel() >= ShitEntry::SHIT_NOOP)
283 cnx->queue->sendChannelMode(channelName, "-o", n);
284 if (Utils::to_lower (n) == cnx->bot->nickName.toLower() && doMode) {
291 catch (ChannelUserList::user_not_found &)
296 channelUserlist.change_user_mode (st.next_token (),
301 std::string m = st.next_token();
303 channelBanlist.add (Mask(m));
306 ShitEntry * se = cnx->bot->shitList->getShit(m, channelName);
308 if (se && se->isStillValid() &&
309 se->getShitLevel() >= ShitEntry::SHIT_NODEBAN)
310 cnx->queue->sendChannelMode(channelName, "+b", m);
312 channelBanlist.del (Mask(m));