[Split user list from Channel into ChannelUserList clinton@unknownlamer.org**20090223234748 Ignore-this: 557cbde4df29ff2f16d1d29ce81f36b2 This patch is *huge* and potentially introduces a few bug, but it *seems* ok so far. The ChannelUserList ought to be threadsafe; it was necessary to do this as soon I will be added a bot:channel-users function to the Scheme interface. Doing this, naturally, exposed a number of horrid design issues that I, as always, chose to ignore for now and instead merely cleaned up one aspect as best as it could be given the surrounding muck. (ok, Bobot++ isn't *terrible* but everything touches the internals of everything so now they all have the Clap because one class caught it). ] { hunk ./source/Bot.C 510 - if (c->countOp == 1 && - c->count > 1 && this->iAmOp(channel)) + if (c->operator_count () == 1 && + c->user_count () > 1 && this->iAmOp(channel)) hunk ./source/Bot.C 628 - return c->getUser(nick)->userhost; + return c->getUser(nick).userhost; hunk ./source/Bot.C 650 - User * me = channelList->getChannel(channel)->getUser(nickName); - return (me->mode & User::OP_MODE); + return channelList->getChannel(channel)->getUser(nickName).mode & User::OP_MODE; hunk ./source/BotThreading.C 55 - pthread_t self = pthread_self (); - std::cerr << "< Mutex Lock..." - << " Mutex: " << &mutex - << " Thread: " << &self - << std::endl; +// pthread_t self = pthread_self (); +// std::cerr << "< Mutex Lock..." +// << " Mutex: " << &mutex +// << " Thread: " << &self +// << std::endl; hunk ./source/BotThreading.C 65 - pthread_t self = pthread_self (); - std::cerr << "> Mutex Unlock..." - << " Mutex: " << &mutex - << " Thread: " << &self - << std::endl; +// pthread_t self = pthread_self (); +// std::cerr << "> Mutex Unlock..." +// << " Mutex: " << &mutex +// << " Thread: " << &self +// << std::endl; hunk ./source/BotThreading.C 92 - pthread_t self = pthread_self (); - std::cerr << "Lock Init..." - << " Lock: " << this - << " Mutex: " << &mutex - << " Thread: " << &self - << std::endl; +// pthread_t self = pthread_self (); +// std::cerr << "Lock Init..." +// << " Lock: " << this +// << " Mutex: " << &mutex +// << " Thread: " << &self +// << std::endl; hunk ./source/BotThreading.C 103 - pthread_t self = pthread_self (); - std::cerr << "Lock Destroy..." - << " Lock: " << this - << " Mutex: " << &mutex - << " Thread: " << &self - << std::endl; +// pthread_t self = pthread_self (); +// std::cerr << "Lock Destroy..." +// << " Lock: " << this +// << " Mutex: " << &mutex +// << " Thread: " << &self +// << std::endl; hunk ./source/Channel.C 3 -// Copyright (C) 2002,2005,2008 Clinton Ebadi +// Copyright (C) 2002,2005,2008,2009 Clinton Ebadi hunk ./source/Channel.C 45 - String name, String wanted = "") - : channelName(name.toLower()), channelTopic(""), + std::string name, std::string wanted = "") + : channelName(Utils::to_lower(name)), channelTopic(""), hunk ./source/Channel.C 48 - channelKey(""), keepModes(DEFAULT_KEEPMODES), wantedModes(wanted), count(0), - countOp(0), joined(false), doMode(true), gotWho(false), cnx(c) + channelKey(""), keepModes(DEFAULT_KEEPMODES), wantedModes(wanted), + channelUserlist (name), + joined(false), doMode(true), gotWho(false), cnx(c) hunk ./source/Channel.C 52 -#ifdef HAVE_STL_CLEAR - channelMemory.clear(); -#endif hunk ./source/Channel.C 63 -{ - User *u; - std::map >::iterator it; - - while (channelMemory.size() != 0) { - it = channelMemory.begin(); - u = (*it).second; - if (u && u->userListItem && u->userListItem->identified > 0) - u->userListItem->identified--; - channelMemory.erase(it); - delete u; - } -} +{ } hunk ./source/Channel.C 66 -Channel::addNick(String n, String uh, int mode, UserList *ul, +Channel::addNick(std::string n, std::string uh, int mode, UserList *ul, hunk ./source/Channel.C 69 - if (User * u = getUser(n.toLower())) { - count--; - if (u->mode & User::OP_MODE) - countOp--; - channelMemory.erase(n.toLower()); - delete u; - } - - User *u; - - if (names) - u = new User(n, mode); - else - u = new User(n, uh, channelName, mode, ul); - - channelMemory[n.toLower()] = u; - - if (u->userListItem) { - if (u->userListItem->identified) - u->userListItem->identified++; - else { - if (u->userListItem->passwd == "") - u->userListItem->identified = 1; - } - } - - count++; - if (u->mode & User::OP_MODE) - countOp++; + channelUserlist.add (n, uh, mode, ul, names); hunk ./source/Channel.C 73 -Channel::delNick(String n) +Channel::delNick(std::string n) hunk ./source/Channel.C 75 - n = n.toLower(); - User *u = getUser(n); - - if (!u) - return; - - if (channelMemory[n]!=0) { - channelMemory.erase(n); - } - - count--; - if (u->mode & User::OP_MODE) - countOp--; - if (u->userListItem && u->userListItem->identified > 0) - u->userListItem->identified--; - delete u; + channelUserlist.del (n); hunk ./source/Channel.C 79 -Channel::changeNick(String on, String nn) +Channel::changeNick(std::string on, std::string nn) hunk ./source/Channel.C 81 - on = on.toLower(); - User *u = getUser(on); - channelMemory.erase(on); - channelMemory[nn.toLower()] = u; + channelUserlist.change_nickname (on, nn); hunk ./source/Channel.C 85 -Channel::hasNick(String n) +Channel::hasNick(const std::string &n) const hunk ./source/Channel.C 87 - return getUser(n.toLower()) != 0; + return channelUserlist.in_channel_p (n); hunk ./source/Channel.C 90 -User * -Channel::getUser(String n) +const User +Channel::getUser(const std::string &n) const hunk ./source/Channel.C 93 - User *u; + return channelUserlist.get (n); +} hunk ./source/Channel.C 96 - n = n.toLower(); +void +Channel::change_user_key (std::string name, std::string key) +{ + channelUserlist.change_user_key (name, key); +} hunk ./source/Channel.C 102 - if ((u = channelMemory[n]) == 0) { - channelMemory.erase(n); - return 0; - } +unsigned int +Channel::user_count () const throw () +{ + return channelUserlist.user_count (); +} hunk ./source/Channel.C 108 - return u; +unsigned int +Channel::operator_count () const throw () +{ + return channelUserlist.operator_count (); hunk ./source/Channel.C 148 - cnx->queue->sendChannelMode(String("MODE ") + channelName + + cnx->queue->sendChannelMode(std::string("MODE ") + channelName + hunk ./source/Channel.C 153 -Channel::parseMode(Person *from, String mode) +Channel::parseMode(Person *from, std::string mode) hunk ./source/Channel.C 157 - String m = st.next_token(), n; - User *u = 0; + std::string m = st.next_token(), n; + bool doNotObey = true; // disobey mode if server or target is protected hunk ./source/Channel.C 160 - u = getUser(from->getNick()); - // u == 0 if it's a server mode - bool doNotObey = !u || (u->getProt() <= User::NO_PROT); + try + { + doNotObey = getUser(from->getNick()).getProt () <= User::NO_PROT; + } + catch (ChannelUserList::user_not_found&) + { } + hunk ./source/Channel.C 234 - String((long)channelLimit)); + Utils::long2str(channelLimit)); hunk ./source/Channel.C 250 - String("")); + std::string("")); hunk ./source/Channel.C 253 - n = st.next_token(); - u = getUser(n); - if (joined) - sign == '+' ? countOp++ : countOp--; - if (!u) - break; - sign == '+' ? (u->mode |= User::OP_MODE) : - (u->mode &= ~User::OP_MODE); - if (sign == '-' && u->getProt() >= User::NO_DEOP) { - String fromNick = from->getNick(); - User * v = getUser(fromNick); - if (u == v) - return; - if (v->getProt() < User::NO_DEOP) - cnx->queue->sendChannelMode(channelName, "-o", fromNick); - cnx->queue->sendChannelMode(channelName, "+o", n); - } - if (sign == '+') { - if (doNotObey && !from && - u->getProt() < User::NO_DEOP && !u->getAop()) - cnx->queue->sendChannelMode(channelName, "-o", n); - ShitEntry * se = - cnx->bot->shitList->getShit(n+"!"+cnx->bot->getUserhost(channelName, n), - channelName); - if (se && se->isStillValid() && - se->getShitLevel() >= ShitEntry::SHIT_NOOP) - cnx->queue->sendChannelMode(channelName, "-o", n); - if (n.toLower() == cnx->bot->nickName.toLower() && doMode) { - doMode = false; - resynchModes(); - } - } - break; + try + { + n = st.next_token(); + User u = getUser(n); + // if (joined) + // sign == '+' ? countOp++ : countOp--; + channelUserlist.change_user_mode (n, User::OP_MODE, sign != '+'); + + if (sign == '-' && u.getProt() >= User::NO_DEOP) { + std::string fromNick = from->getNick(); + User v = getUser(fromNick); + + if (n == fromNick) + return; + + if (v.getProt() < User::NO_DEOP) + cnx->queue->sendChannelMode(channelName, "-o", fromNick); + + cnx->queue->sendChannelMode(channelName, "+o", n); + } + + if (sign == '+') { + if (doNotObey && !from && + u.getProt() < User::NO_DEOP && !u.getAop()) + cnx->queue->sendChannelMode(channelName, "-o", n); + ShitEntry * se = + cnx->bot->shitList->getShit(n+"!"+cnx->bot->getUserhost(channelName, n), + channelName); + if (se && se->isStillValid() && + se->getShitLevel() >= ShitEntry::SHIT_NOOP) + cnx->queue->sendChannelMode(channelName, "-o", n); + if (Utils::to_lower (n) == cnx->bot->nickName.toLower() && doMode) { + doMode = false; + resynchModes(); + } + } + break; + } + catch (ChannelUserList::user_not_found &) + { + break; + } hunk ./source/Channel.C 296 - u = getUser(st.next_token()); - u->mode = (sign == '+' ? u->mode |= User::VOICE_MODE : - u->mode &= ~User::VOICE_MODE); + channelUserlist.change_user_mode (st.next_token (), + User::VOICE_MODE, + sign != '+'); hunk ./source/Channel.C 301 - String m = st.next_token(); + std::string m = st.next_token(); hunk ./source/Channel.C 303 - channelBanlist.add (m); + channelBanlist.add (Mask(m)); hunk ./source/Channel.C 312 - channelBanlist.del (m); + channelBanlist.del (Mask(m)); hunk ./source/Channel.H 3 -// Copyright (C) 2002,2008 Clinton Ebadi +// Copyright (C) 2002,2008,2009 Clinton Ebadi hunk ./source/Channel.H 25 -#include +#include +#include hunk ./source/Channel.H 32 -#include "String.H" +#include "ChannelUserList.H" +#include "Utils.H" hunk ./source/Channel.H 54 - String mode; - String keep; - String key; + std::string mode; + std::string keep; + std::string key; hunk ./source/Channel.H 58 - wantedChannel(String m, String kp, String ky) + wantedChannel(std::string m, std::string kp, std::string ky) hunk ./source/Channel.H 63 - String channelName; - String channelTopic; + std::string channelName; + std::string channelTopic; hunk ./source/Channel.H 68 - String channelKey; - String keepModes; - String wantedModes; + std::string channelKey; + std::string keepModes; + std::string wantedModes; hunk ./source/Channel.H 72 - int count; - int countOp; hunk ./source/Channel.H 75 - std::map > channelMemory; + ChannelUserList channelUserlist; hunk ./source/Channel.H 92 - Channel(ServerConnection *, String, String); + Channel(ServerConnection *, std::string, std::string); hunk ./source/Channel.H 95 - void addNick(String, String, int, UserList *, bool = false); - void delNick(String); - void changeNick(String, String); - bool hasNick(String); - User * getUser(String); + void addNick(std::string, std::string, int, UserList *, bool = false); + void delNick(std::string); + void changeNick(std::string, std::string); + void change_user_key (std::string, std::string); + bool hasNick(const std::string &) const; + const User getUser(const std::string &) const; + unsigned int user_count () const throw (); + unsigned int operator_count () const throw (); + template void for_each_channel_users (const T & fun) + { channelUserlist.foreach (fun); } hunk ./source/Channel.H 112 - void parseMode(Person *, String); + void parseMode(Person *, std::string); addfile ./source/ChannelUserList.C hunk ./source/ChannelUserList.C 1 +// ChannelUserList.C -*- C++ -*- +// Copyright (c) 1997, 1998 Etienne BERNARD +// Copyright (C) 2002,2005,2008,2009 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. + +#include "ChannelUserList.H" +#include "User.H" +#include "UserList.H" +#include "UserListItem.H" +#include "Utils.H" + +#include +#include + +ChannelUserList::ChannelUserList (const std::string & cn) throw () + : users_mutex (true), channel_name (cn) +{ } + +ChannelUserList::~ChannelUserList () throw () +{ + BotLock destructor_lock (users_mutex); + + while (users.begin () != users.end ()) + { + del (users.begin()->nick); + } +} + +std::list::iterator +ChannelUserList::get_user_i_ (const std::string &name) +{ + BotLock get_lock (users_mutex); + + return std::find_if (users.begin (), users.end (), + std::bind1st (user_equal_p, User(name, 0))); +} + +void +ChannelUserList::add_ (std::string name, std::string host, int mode, + UserListItem* user_list_item, bool names) throw () +{ + BotLock add_lock (users_mutex); + + del (name); + + if (user_list_item) + { + if (user_list_item->identified) + { + user_list_item->identified++; + } + else if (user_list_item->passwd == "") + { + user_list_item->identified = 1; + } + } + + Utils::push_sorted (users, + names ? User (name, mode) + : User (name, host, channel_name, mode, user_list_item), + user_less_p); +} + +void +ChannelUserList::add (std::string name, std::string host, int mode, + UserList* user_list, bool names) throw () +{ + BotLock add_lock (users_mutex); + name = Utils::to_lower (name); + + UserListItem *uli = names ? 0 : user_list->getUserListItem (name + "!" + host, + channel_name); + + add_ (name, host, mode, uli, names); +} + +void +ChannelUserList::del (const std::string &name) throw () +{ + BotLock del_lock (users_mutex); + + std::list::iterator found = get_user_i_ (name); + + if (found != users.end ()) + { + if (found->userListItem && found->userListItem->identified > 0) + found->userListItem->identified--; + + users.erase (found); + } +} + +User +ChannelUserList::get (const std::string & name) const throw (user_not_found) +{ + BotLock get_lock (users_mutex); + + std::list::const_iterator pos = + std::find_if (users.begin (), users.end (), + std::bind1st (user_equal_p, User(name, 0))); + + if (pos != users.end ()) + return *pos; + else + throw user_not_found (name); +} + +void +ChannelUserList::change_nickname (const std::string & old_name, + std::string new_name) + throw (user_not_found) +{ + BotLock change_lock (users_mutex); + + User user = get (old_name); + del (old_name); + add_ (new_name, user.userhost, user.mode, user.userListItem, false); +} + +void +ChannelUserList::change_user_mode (const std::string &name, int flag, bool remove) + throw () +{ + BotLock change_lock (users_mutex); + + std::list::iterator user = get_user_i_ (name); + + if (user != users.end ()) + { + remove ? user->mode &= ~flag : user->mode |= flag; + } +} + +bool +ChannelUserList::in_channel_p (const std::string &name) const throw () +{ + try + { + get (name); + } + catch (user_not_found &) + { + return false; + } + + return true; +} + +void +ChannelUserList::change_user_key (const std::string &name, const std::string &key) + throw () +{ + std::list::iterator user = get_user_i_ (name); + + if (user != users.end ()) + user->userkey = key; +} + +unsigned int +ChannelUserList::user_count () const throw () +{ + return users.size (); +} + +unsigned int +ChannelUserList::operator_count () const throw () +{ + unsigned int count = 0; + + for (std::list::const_iterator user = users.begin (); + user != users.end (); + ++user) + { + if (user->mode & User::OP_MODE) + count++; + } + + return count; +} addfile ./source/ChannelUserList.H hunk ./source/ChannelUserList.H 1 +// ChannelUserList.H -*- C++ -*- +// Copyright (c) 1997, 1998 Etienne BERNARD +// Copyright (C) 2002,2005,2008,2009 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. + +#ifndef CHANNEL_USER_LIST_H +#define CHANNEL_USER_LIST_H + +#include +#include +#include + +#include "BotThreading.H" + +class User; +class UserList; +class UserListItem; + +class ChannelUserList +{ + std::list users; + mutable BotMutex users_mutex; + std::string channel_name; + + std::equal_to user_equal_p; + std::less user_less_p; + + std::list::iterator get_user_i_ (const std::string &); + void add_ (std::string, std::string, int, UserListItem*, bool) throw (); + +public: + struct user_not_found + { + std::string name; + user_not_found (const std::string &n) + : name (n) + { } + }; + + enum + { + MODE_ADD = 0, + MODE_REMOVE = 1 + }; + + ChannelUserList (const std::string &) throw (); + ~ChannelUserList () throw (); + + void add (std::string, std::string, int, UserList*, bool = false) throw (); + void del (const std::string &) throw (); + User get (const std::string &) const throw (user_not_found); + void change_nickname (const std::string &, std::string) throw (user_not_found); + void change_user_mode (const std::string &, int, bool) throw (); + void change_user_key (const std::string &, const std::string &) throw (); + bool in_channel_p (const std::string &) const throw (); + unsigned int user_count () const throw (); + unsigned int operator_count () const throw (); + + template + void foreach (const T & fun) + { + BotLock foreach_lock (users_mutex); + std::for_each (users.begin (), users.end (), fun); + } +}; + +#endif hunk ./source/Commands.C 22 +#include + hunk ./source/Commands.C 378 +Commands::deop_wildcard::deop_wildcard +(Bot *b, Mask &m, String &c) + : bot (b), mask (m), channel (c) +{ } + +void +Commands::deop_wildcard::operator() (const User &user) +{ + if (mask.matches(user.nick + "!" + user.userhost) + && user.getProt() < User::NO_DEOP + && (user.mode & User::OP_MODE)) + QUEUE->sendChannelMode(channel, "-o", user.nick); +} + hunk ./source/Commands.C 406 - User *u = c->getUser(who); - if (!u) - return UserNotFound(who, channel); - if (!(u->mode & User::OP_MODE)) - return UserNotOp(who, channel); - if (u->getProt() >= User::NO_DEOP) - return UserProtected(who, channel); - QUEUE->sendChannelMode(channel, "-o", who); + try + { + User u = c->getUser(who); + + if (!(u.mode & User::OP_MODE)) + return UserNotOp(who, channel); + if (u.getProt() >= User::NO_DEOP) + return UserProtected(who, channel); + QUEUE->sendChannelMode(channel, "-o", who); + } + catch (const ChannelUserList::user_not_found &e) + { + return UserNotFound(e.name, channel); + } hunk ./source/Commands.C 421 - Mask m(who); - for (std::map >::iterator - it = c->channelMemory.begin(); - it != c->channelMemory.end(); ++it) { - if (m.matches((*it).second->nick + "!" + - (*it).second->userhost) && - (*it).second->getProt() < User::NO_DEOP && - ((*it).second->mode & User::OP_MODE)) - QUEUE->sendChannelMode(channel, "-o", (*it).second->nick); - } + Mask m (who); + deop_wildcard f (bot, m, channel); + c->for_each_channel_users (f); hunk ./source/Commands.C 425 - hunk ./source/Commands.C 473 - bot->wantedChannels[channel]->key = key; + bot->wantedChannels[channel]->key = static_cast (key); hunk ./source/Commands.C 498 +Commands::kick_wildcard::kick_wildcard +(Bot *b, Mask &m, String &c, String &r) + : bot (b), mask (m), channel (c), reason (r) +{ } + +void +Commands::kick_wildcard::operator() (const User &user) +{ + if (mask.matches(user.nick + "!" + user.userhost) && + user.getProt() < User::NO_KICK) + QUEUE->sendKick(channel, user.nick, reason); +} + hunk ./source/Commands.C 526 - for (std::map >::iterator it = - c->channelMemory.begin(); - it != c->channelMemory.end(); - ++it) - if (m.matches((*it).second->nick + "!" + - (*it).second->userhost) && - (*it).second->getProt() < User::NO_KICK) - QUEUE->sendKick(channel, (*it).second->nick, reason); + kick_wildcard f (bot, m, channel, reason); + c->for_each_channel_users (f); hunk ./source/Commands.C 529 - User * u = c->getUser(who); - if (!u) - return UserNotFound(who, channel); - if (u->getProt() < User::NO_KICK) - QUEUE->sendKick(channel, who, reason); - else - return UserProtected(who, channel); + try + { + User u = c->getUser(who); + + if (u.getProt() < User::NO_KICK) + QUEUE->sendKick(channel, who, reason); + else + return UserProtected(who, channel); + } + catch (const ChannelUserList::user_not_found &e) + { + return UserNotFound(e.name, channel); + } hunk ./source/Commands.C 706 + + try + { + User u = c->getUser(who); hunk ./source/Commands.C 711 - User *u = c->getUser(who); - if (!u) - return UserNotFound(who, channel); - - ShitEntry *se = bot->shitList->getShit(who, channel); - if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) - return UserOnShitList(who); - - QUEUE->sendChannelMode(channel, "+o", who); + ShitEntry *se = bot->shitList->getShit(who, channel); + if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) + return UserOnShitList(who); + + QUEUE->sendChannelMode(channel, "+o", who); + } + catch (const ChannelUserList::user_not_found &e) + { + return UserNotFound(e.name, channel); + } hunk ./source/Commands.H 28 +class Channel; +class Mask; hunk ./source/Commands.H 31 +class User; hunk ./source/Commands.H 77 + +private: + class deop_wildcard : std::unary_function + { + Bot *bot; + Mask &mask; + const String channel; + public: + deop_wildcard (Bot*, Mask&, String&); + void operator ()(const User &); + }; + + class kick_wildcard : std::unary_function + { + Bot *bot; + Mask &mask; + const String channel; + const String reason; + public: + kick_wildcard (Bot*, Mask&, String&, String&); + void operator ()(const User &); + }; hunk ./source/Makefile.am 11 + ChannelUserList.C \ hunk ./source/Makefile.am 49 + ChannelUserList.H \ hunk ./source/Parser.C 447 - if (ch->getUser (n)->getAop () - && !(ch->getUser (n)->mode & User::OP_MODE) && cnx->bot->iAmOp (c)) + if (ch->getUser (n).getAop () + && !(ch->getUser (n).mode & User::OP_MODE) && cnx->bot->iAmOp (c)) hunk ./source/Parser.C 451 - ch->getUser(n)->userkey = Utils::get_key (); + ch->change_user_key (n, Utils::get_key ()); hunk ./source/Parser.C 453 - ch->getUser(n)->userkey + " " + c); + ch->getUser(n).userkey + " " + c); hunk ./source/Parser.C 501 - User *u = cnx->bot->channelList->getChannel (channel)->getUser (target); - if (u && u->getProt () >= User::NO_KICK) + try hunk ./source/Parser.C 503 - String fromNick = from->getNick (); - User *v = - cnx->bot->channelList->getChannel (channel)->getUser (fromNick); - if (v->getProt () < User::NO_KICK) + User u = cnx->bot->channelList->getChannel (channel)->getUser (target); + if (u.getProt () >= User::NO_KICK) hunk ./source/Parser.C 506 - cnx->bot->logLine (from->getAddress () + " kicked " + target + - " (protected) out of channel " + channel + - " (" + reason + ")."); - cnx->queue->sendKick (channel, fromNick, - target + " \002is protected !\002"); + String fromNick = from->getNick (); + User v = + cnx->bot->channelList->getChannel (channel)->getUser (fromNick); + if (v.getProt () < User::NO_KICK) + { + cnx->bot->logLine (from->getAddress () + " kicked " + target + + " (protected) out of channel " + channel + + " (" + reason + ")."); + cnx->queue->sendKick (channel, fromNick, + target + " \002is protected !\002"); + } hunk ./source/Parser.C 518 + } + catch (const ChannelUserList::user_not_found &e) + { + hunk ./source/Parser.C 657 - if (cnx->bot->channelList->getChannel (c) && - cnx->bot->channelList->getChannel (c)->getUser (nick) && - cnx->bot->channelList->getChannel (c)->getUser (nick)-> - getAop () - && !(cnx->bot->channelList->getChannel (c)-> - getUser (nick)->mode & User::OP_MODE) - && cnx->bot->channelList->getChannel (c)->getUser (nick)-> - userkey == rest) - cnx->queue->sendChannelMode (c, "+o", nick); + Channel *channel = cnx->bot->channelList->getChannel (c); + + if (channel && channel->hasNick (nick)) + { + User u = cnx->bot->channelList->getChannel(c)->getUser(nick); + if (u.getAop () && !(u.mode & User::OP_MODE) && u.userkey == rest) + cnx->queue->sendChannelMode (c, "+o", nick); + } hunk ./source/Parser.C 760 - if (c->countOp == 0 && c->count == 1) + if (c->operator_count () == 0 && c->user_count () == 1) hunk ./source/Parser.C 997 - User *u = 0; - if (Channel * c = cnx->bot->channelList->getChannel (to)) - u = c->getUser (from->getNick ()); - if (!u || !u->userListItem) - identified = true; + + Channel * c = cnx->bot->channelList->getChannel (to); + if (c && c->hasNick (from->getNick ())) + { + User u = c->getUser (from->getNick ()); + if (!u.userListItem) + identified = true; + else + identified = u.userListItem->passwd == "" + || u.userListItem->identified > 0; + } hunk ./source/Parser.C 1009 - identified = u->userListItem->passwd == "" - || u->userListItem->identified > 0; + { + identified = true; + } hunk ./source/User.C 3 +// Copyright (C) 2009 Clinton Ebadi hunk ./source/User.C 25 -User::User(String n, String uh, String channel, int mode, UserList *ul) +User::User(String n, String uh, String channel, int mode, UserListItem *uli) hunk ./source/User.C 27 - userListItem(ul->getUserListItem(n + "!" + uh, channel)), + userListItem(uli), hunk ./source/User.C 38 -User::getLevel() +User::getLevel() const hunk ./source/User.C 48 -User::getProt() +User::getProt() const hunk ./source/User.C 58 -User::getAop() +User::getAop() const hunk ./source/User.C 66 + +bool +User::operator< (const User &rh) const +{ + return Utils::to_lower (nick) < Utils::to_lower (rh.nick); +} + +bool +User::operator== (const User &rh) const +{ + return Utils::to_lower (nick) == Utils::to_lower (rh.nick); +} hunk ./source/User.H 3 +// Copyright (C) 2009 Clinton Ebadi hunk ./source/User.H 63 - User(String, String, String, int, UserList *); + User(String, String, String, int, UserListItem *); hunk ./source/User.H 66 - int getLevel(); - int getProt(); - bool getAop(); + int getLevel() const; + int getProt() const; + bool getAop() const; + + bool operator< (const User &) const; + bool operator== (const User &) const; hunk ./source/User.H 75 - friend class Channel; + friend class ChannelUserList; hunk ./source/UserCommands.C 684 - User * u = c->getUser(from->getNick()); - if (!u) { - from->sendNotice(String("\002You can identify yourself on" - " channel\002 ") + channel + - " \002only if you are on the channel.\002"); - return; - } - - if (u->userListItem && u->userListItem->identified) { - from->sendNotice(String("\002You are already identified on" - " channel\002 ") + channel); - return; - } - - if (!u->userListItem) { - from->sendNotice("\002You are not in my userlist.\002"); - return; - } - - if (u->userListItem->passwd == - crypt((const char *)rest, (const char *)u->userListItem->passwd)) { - // For each channel, we increment identification counter - for (std::map >::iterator it = - cnx->bot->channelList->begin(); - it != cnx->bot->channelList->end(); ++it) - u->userListItem->identified++; - - from->sendNotice("\002You are now identified.\002"); - } else - from->sendNotice("\002This is a wrong password.\002"); + try + { + User u = c->getUser(from->getNick()); + + if (u.userListItem && u.userListItem->identified) { + from->sendNotice(String("\002You are already identified on" + " channel\002 ") + channel); + return; + } + + if (!u.userListItem) { + from->sendNotice("\002You are not in my userlist.\002"); + return; + } + + if (u.userListItem->passwd == + crypt(rest.c_str (), u.userListItem->passwd.c_str ())) { + // For each channel, we increment identification counter + // fixme: is this logic correct? + for (std::map >::iterator it = + cnx->bot->channelList->begin(); + it != cnx->bot->channelList->end(); ++it) + u.userListItem->identified++; + + from->sendNotice("\002You are now identified.\002"); + } else + from->sendNotice("\002This is a wrong password.\002"); + } + catch (ChannelUserList::user_not_found &e) + { + from->sendNotice(String("\002You can identify yourself on" + " channel\002 ") + channel + + " \002only if you are on the channel.\002"); + return; + } hunk ./source/UserCommands.C 775 -// FIXME: Convert hunk ./source/UserCommands.C 779 - String nick = from->getNick(); - hunk ./source/UserCommands.C 790 - User * u = c->getUser(nick); - if (!u) - return; - if (u->getLevel() < User::TRUSTED_USER) { - from->sendNotice("\002You need an higher level to " - "use wildcards.\002"); - return; - } - } + try + { + User u = c->getUser(from->getNick ()); hunk ./source/UserCommands.C 794 - if (!cnx->bot->iAmOp(channel)) { - from->sendNotice(String("\002I am not channel op on\002 ") + - channel); - return; - } - - if (Utils::wildcard_p(who)) { - Mask m(who); - for (std::map >::iterator it = - c->channelMemory.begin(); - it != c->channelMemory.end(); - ++it) - if (m.matches((*it).second->nick + "!" + - (*it).second->userhost) && - (*it).second->getProt() < User::NO_KICK) - cnx->queue->sendKick(channel, (*it).second->nick, st.rest()); - } else { - User * u = c->getUser(who); - if (!u) { - from->sendNotice(String("\002I can not find\002 ") + - who + " \002on\002 " + channel); - return; - } - if (u->getProt() < User::NO_KICK) - cnx->queue->sendKick(channel, who, st.rest()); - else - from->sendNotice(String("\002I can not kick\002 ") + - who + " \002on\002 " + channel + - " \002(protected).\002"); + if (u.getLevel() < User::TRUSTED_USER) { + from->sendNotice("\002You need an higher level to " + "use wildcards.\002"); + return; + } + } + catch (const ChannelUserList::user_not_found &) + { + return; + } hunk ./source/UserCommands.C 805 + + Message ret = Commands::Kick (cnx->bot, channel, who, st.rest ()); + if (ret.getCode () != 0) + from->sendNotice (ret.getMessage ()); hunk ./source/UserCommands.C 887 +UserCommands::map_names::map_names (Person *f, std::string &r) + : from (f), result (r), length (0) +{ } + +void +UserCommands::map_names::operator() (const User &user) +{ + result += (user.mode & User::OP_MODE ? "@" : + (user.mode & User::VOICE_MODE ? "+" : "")) + user.nick + " "; + length += user.nick.length() + 1; + + if (length >= 256) { + from->sendNotice(result); + result = ""; length = 0; + } +} + hunk ./source/UserCommands.C 909 - String result = ""; - int length = 0; hunk ./source/UserCommands.C 910 - std::map >::iterator it; + std::string result; hunk ./source/UserCommands.C 915 - for (it = c->channelMemory.begin(); - it != c->channelMemory.end(); ++it) { - result = result + - ((*it).second->mode & User::OP_MODE ? "@" : - ((*it).second->mode & User::VOICE_MODE ? "+" : "")) + - (*it).second->nick + " "; - length += (*it).first.length() + 1; - if (length >= 256) { - from->sendNotice(result); - result = ""; length = 0; - } - } + map_names f (from, result); + c->for_each_channel_users (f); hunk ./source/UserCommands.C 1001 - iaddr.s_addr = inet_addr((const char *)target); + iaddr.s_addr = inet_addr(target.c_str ()); hunk ./source/UserCommands.C 1012 - host = gethostbyname((const char *)target); + host = gethostbyname(target.c_str ()); hunk ./source/UserCommands.C 1026 -// FIXME: Convert hunk ./source/UserCommands.C 1030 - String nick = from->getNick(); - - if (!cnx->bot->iAmOp(channel)) { - from->sendNotice(String("\002I am not channel op on\002 ") + - channel); - return; - } - - if (Utils::wildcard_p(rest)) { - from->sendNotice("\002Mass op is not allowed.\002"); - return; - } - - String target; - - if (rest.length() == 0) - target = nick; - else - target = rest; - - User *u = cnx->bot->channelList->getChannel(channel)->getUser(target); - if (!u) { - from->sendNotice(String("\002I cannot find\002 ") + target + " \002on channel\002 " + channel); - return; - } - - ShitEntry *se = cnx->bot->shitList->getShit(target, channel); - if (se && se->isStillValid() && se->getShitLevel() >= ShitEntry::SHIT_NOOP) { - from->sendNotice(String("\002I can not op\002 ")+target+" \002on channel\002 "+channel+" \002(shitlist).\002"); - return; - } - - if (!(u->mode & User::OP_MODE)) - cnx->queue->sendChannelMode(channel, "+o", target); - else { - if (target == nick) - from->sendNotice(String("\002You are already channel " - "operator on\002 ") + channel); - else - from->sendNotice(target + " \002is already channel " - "operator on\002 " + channel); - } + Message ret = Commands::Op (cnx->bot, channel, + rest.length () == 0 ? from->getNick () : rest); + + if (ret.getCode () != 0) + from->sendNotice (ret.getMessage ()); hunk ./source/UserCommands.C 1037 -// FIXME: Convert hunk ./source/UserCommands.C 1041 - wantedChannel *w = cnx->bot->wantedChannels[channel]; - cnx->bot->wantedChannels.erase(channel); - delete w; - cnx->queue->sendPart(channel); + Message ret = Commands::Part (cnx->bot, channel); + + if (ret.getCode () != 0) + from->sendNotice (ret.getMessage ()); hunk ./source/UserCommands.C 1051 - Channel *c = cnx->bot->channelList->getChannel(channel); - hunk ./source/UserCommands.C 1056 - User * u = c->getUser(from->getNick()); - if (!u) { - from->sendNotice(String("\002To change your password for\002") + - channel + "\002, you need to be on the " - "channel.\002"); - return; - } - - if (!u->userListItem) { - from->sendNotice("\002You are not in my userlist.\002"); - return; - } - - if (rest.toLower() == "none") { - u->userListItem->passwd = ""; - from->sendNotice("\002Password cleared.\002"); - return; - } - - static char saltChars[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; - char salt[3]; - srand(time(0)); - salt[0] = saltChars[rand() % 64]; - salt[1] = saltChars[rand() % 64]; - salt[2] = '\0'; - - u->userListItem->passwd = crypt((const char *)rest, salt); - from->sendNotice("\002Password changed.\002"); + try + { + Channel *c = cnx->bot->channelList->getChannel(channel); + User u = c->getUser(from->getNick()); + + if (!u.userListItem) { + from->sendNotice("\002You are not in my userlist.\002"); + return; + } + + if (rest.toLower() == "none") { + u.userListItem->passwd = ""; + from->sendNotice("\002Password cleared.\002"); + return; + } + + static char saltChars[] = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./"; + char salt[3]; + srand(time(0)); + salt[0] = saltChars[rand() % 64]; + salt[1] = saltChars[rand() % 64]; + salt[2] = '\0'; + + u.userListItem->passwd = crypt(rest.c_str (), salt); + from->sendNotice("\002Password changed.\002"); + } + catch (const ChannelUserList::user_not_found &e) + { + from->sendNotice(String("\002To change your password for\002") + + channel + "\002, you need to be on the " + "channel.\002"); + return; + } hunk ./source/UserCommands.C 1306 - User * u = c->getUser(from->getNick()); - if (u && u->getLevel() < User::TRUSTED_USER) { + if (c->hasNick (from->getNick ()) + && c->getUser(from->getNick()).getLevel() < User::TRUSTED_USER) { hunk ./source/UserCommands.C 1387 - User * u = cnx->bot->channelList->getChannel(channel)->getUser(nick); hunk ./source/UserCommands.C 1388 - - if (u) - uli = u->userListItem; + + if (cnx->bot->channelList->getChannel(channel)->hasNick(nick)) + uli = cnx->bot->channelList->getChannel(channel)->getUser(nick).userListItem; hunk ./source/UserCommands.C 1393 - channel); - + channel); + hunk ./source/UserCommands.C 1397 - uli->mask.getMask() + " \002on\002 " + - uli->channelMask.getMask()); + uli->mask.getMask() + " \002on\002 " + + uli->channelMask.getMask()); hunk ./source/UserCommands.C 1400 - Utils::level2str(uli->level) + - " \002Prot:\002 " + - Utils::prot2str(uli->prot) + - " \002Aop:\002 " + - Utils::bool2str(uli->aop) + - " \002Expired:\002 " + - Utils::bool2str(!uli->isStillValid()) + - " \002Ident:\002 " + - (uli && !uli->identified ? "\026" : "") + - Utils::bool2str(uli && uli->identified) + - (uli && !uli->identified ? "\026" : "")); + Utils::level2str(uli->level) + + " \002Prot:\002 " + + Utils::prot2str(uli->prot) + + " \002Aop:\002 " + + Utils::bool2str(uli->aop) + + " \002Expired:\002 " + + Utils::bool2str(!uli->isStillValid()) + + " \002Ident:\002 " + + (uli && !uli->identified ? "\026" : "") + + Utils::bool2str(uli && uli->identified) + + (uli && !uli->identified ? "\026" : "")); hunk ./source/UserCommands.C 1413 - channel); + channel); hunk ./source/UserCommands.C 1430 - User * u = cnx->bot->channelList->getChannel(channel)->getUser(otherNick); hunk ./source/UserCommands.C 1432 - if (u) - uli = u->userListItem; + if (cnx->bot->channelList->getChannel(channel)->hasNick(otherNick)) + uli = cnx->bot->channelList->getChannel(channel)->getUser(otherNick).userListItem; hunk ./source/UserCommands.H 24 +#include + hunk ./source/UserCommands.H 28 +class User; hunk ./source/UserCommands.H 93 + +private: + struct map_names : std::unary_function + { + Person *from; + std::string &result; + unsigned int length; + + map_names (Person*, std::string&); + void operator() (const User &); + }; hunk ./source/UserListItem.H 74 - friend class Channel; + friend class ChannelUserList; hunk ./source/Utils.C 156 - if (Channel * c = b->channelList->getChannel(channel)) - { - User * u = c->getUser(get_nick (nuh)); - if (u) - return u->getLevel(); - } - else { + Channel * c = b->channelList->getChannel(channel); + if (c && c->hasNick (get_nick (nuh))) + return c->getUser(get_nick (nuh)).getLevel (); + else hunk ./source/Utils.C 161 - } }