it != channelList->end(); ++it) {
channel = (*it).first;
c = channelList->getChannel(channel);
- if (c->countOp == 1 &&
- c->count > 1 && this->iAmOp(channel))
+ if (c->operator_count () == 1 &&
+ c->user_count () > 1 && this->iAmOp(channel))
return false;
}
return true;
if (c && c->hasNick(nick))
- return c->getUser(nick)->userhost;
+ return c->getUser(nick).userhost;
unsigned long num = sentUserhostID++;
bool
Bot::iAmOp(String channel)
{
- User * me = channelList->getChannel(channel)->getUser(nickName);
- return (me->mode & User::OP_MODE);
+ return channelList->getChannel(channel)->getUser(nickName).mode & User::OP_MODE;
}
void
void BotMutex::lock ()
{
- 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;
pthread_mutex_lock (&mutex);
}
void BotMutex::unlock ()
{
- 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;
pthread_mutex_unlock (&mutex);
}
BotLock::BotLock (BotMutex & m)
: mutex(m)
{
- 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;
mutex.lock ();
}
BotLock::~BotLock ()
{
- 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;
mutex.unlock ();
}
// Channel.C -*- C++ -*-
// Copyright (c) 1997, 1998 Etienne BERNARD
-// Copyright (C) 2002,2005,2008 Clinton Ebadi
+// 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
#endif
Channel::Channel(ServerConnection *c,
- String name, String wanted = "")
- : channelName(name.toLower()), channelTopic(""),
+ std::string name, std::string wanted = "")
+ : channelName(Utils::to_lower(name)), channelTopic(""),
lockedTopic(false), channelMode(0), channelLimit(0),
- 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)
{
-#ifdef HAVE_STL_CLEAR
- channelMemory.clear();
-#endif
if (c->bot->wantedChannels[channelName])
{
if (c->bot->wantedChannels[channelName]->keep != "")
}
Channel::~Channel()
-{
- User *u;
- std::map<String, User *, std::less<String> >::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;
- }
-}
+{ }
void
-Channel::addNick(String n, String uh, int mode, UserList *ul,
+Channel::addNick(std::string n, std::string uh, int mode, UserList *ul,
bool names)
{
- 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);
}
void
-Channel::delNick(String n)
+Channel::delNick(std::string n)
{
- 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);
}
void
-Channel::changeNick(String on, String nn)
+Channel::changeNick(std::string on, std::string nn)
{
- on = on.toLower();
- User *u = getUser(on);
- channelMemory.erase(on);
- channelMemory[nn.toLower()] = u;
+ channelUserlist.change_nickname (on, nn);
}
bool
-Channel::hasNick(String n)
+Channel::hasNick(const std::string &n) const
{
- return getUser(n.toLower()) != 0;
+ return channelUserlist.in_channel_p (n);
}
-User *
-Channel::getUser(String n)
+const User
+Channel::getUser(const std::string &n) const
{
- User *u;
+ return channelUserlist.get (n);
+}
- n = n.toLower();
+void
+Channel::change_user_key (std::string name, std::string key)
+{
+ channelUserlist.change_user_key (name, key);
+}
- if ((u = channelMemory[n]) == 0) {
- channelMemory.erase(n);
- return 0;
- }
+unsigned int
+Channel::user_count () const throw ()
+{
+ return channelUserlist.user_count ();
+}
- return u;
+unsigned int
+Channel::operator_count () const throw ()
+{
+ return channelUserlist.operator_count ();
}
void
void
Channel::resynchModes()
{
- cnx->queue->sendChannelMode(String("MODE ") + channelName +
+ cnx->queue->sendChannelMode(std::string("MODE ") + channelName +
" +" + cnx->bot->wantedChannels[channelName]->mode);
}
void
-Channel::parseMode(Person *from, String mode)
+Channel::parseMode(Person *from, std::string mode)
{
char sign = '-';
StringTokenizer st(mode);
- 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
if (from)
- 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&)
+ { }
+
if (!gotWho)
doNotObey = false;
if (keepModes.find('l') != -1 && doNotObey) {
if (sign == '-' && wantedModes.find('l') != -1)
cnx->queue->sendChannelMode(channelName, "+l",
- String((long)channelLimit));
+ Utils::long2str(channelLimit));
else
cnx->queue->sendChannelMode(channelName, "-l", "");
}
cnx->queue->sendChannelMode(channelName, "-k", channelKey);
}
cnx->bot->wantedChannels[channelName]->key = (sign == '+' ? channelKey :
- String(""));
+ std::string(""));
break;
case 'o':
- 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;
+ }
case 'v':
- 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 != '+');
break;
case 'b':
- String m = st.next_token();
+ std::string m = st.next_token();
if (sign == '+')
- channelBanlist.add (m);
+ channelBanlist.add (Mask(m));
if (sign == '-')
{
ShitEntry * se = cnx->bot->shitList->getShit(m, channelName);
se->getShitLevel() >= ShitEntry::SHIT_NODEBAN)
cnx->queue->sendChannelMode(channelName, "+b", m);
else
- channelBanlist.del (m);
+ channelBanlist.del (Mask(m));
}
}
// Channel.H -*- C++ -*-
// Copyright (c) 1997, 1998 Etienne BERNARD
-// Copyright (C) 2002,2008 Clinton Ebadi
+// Copyright (C) 2002,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
#include <algorithm>
#include <functional>
-#include <map>
+#include <list>
+#include <string>
#include <vector>
#include <ctime>
#include "BanList.H"
-#include "String.H"
+#include "ChannelUserList.H"
+#include "Utils.H"
class BanEntry;
class Bot;
// want to set/keep on these channels, and the
// channel keys
struct wantedChannel {
- String mode;
- String keep;
- String key;
+ std::string mode;
+ std::string keep;
+ std::string key;
- wantedChannel(String m, String kp, String ky)
+ wantedChannel(std::string m, std::string kp, std::string ky)
: mode(m), keep(kp), key(ky) { }
};
class Channel {
- String channelName;
- String channelTopic;
+ std::string channelName;
+ std::string channelTopic;
bool lockedTopic;
int channelMode;
int channelLimit;
- String channelKey;
- String keepModes;
- String wantedModes;
+ std::string channelKey;
+ std::string keepModes;
+ std::string wantedModes;
- int count;
- int countOp;
bool joined;
bool doMode;
bool gotWho;
- std::map<String, User *, std::less<String> > channelMemory;
+ ChannelUserList channelUserlist;
BanList channelBanlist;
ServerConnection * cnx;
IS_LIMITED = 128 // +l <limit>
};
- Channel(ServerConnection *, String, String);
+ Channel(ServerConnection *, std::string, std::string);
~Channel();
- 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<typename T> void for_each_channel_users (const T & fun)
+ { channelUserlist.foreach (fun); }
void addBan(const Mask&, std::time_t = -1);
void delBan(const Mask&);
template<typename T> void for_each_ban_entry (const T & fun)
{ channelBanlist.foreach (fun); }
- void parseMode(Person *, String);
+ void parseMode(Person *, std::string);
void resynchModes();
friend class Bot;
--- /dev/null
+// 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 <algorithm>
+#include <functional>
+
+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<User>::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<User>::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<User>::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<User>::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<User>::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<User>::const_iterator user = users.begin ();
+ user != users.end ();
+ ++user)
+ {
+ if (user->mode & User::OP_MODE)
+ count++;
+ }
+
+ return count;
+}
--- /dev/null
+// 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 <algorithm>
+#include <list>
+#include <string>
+
+#include "BotThreading.H"
+
+class User;
+class UserList;
+class UserListItem;
+
+class ChannelUserList
+{
+ std::list<User> users;
+ mutable BotMutex users_mutex;
+ std::string channel_name;
+
+ std::equal_to<User> user_equal_p;
+ std::less<User> user_less_p;
+
+ std::list<User>::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<typename T>
+ void foreach (const T & fun)
+ {
+ BotLock foreach_lock (users_mutex);
+ std::for_each (users.begin (), users.end (), fun);
+ }
+};
+
+#endif
#include "Commands.H"
+#include <functional>
+
#include "BanEntry.H"
#include "Bot.H"
#include "ChannelList.H"
return Ok;
}
+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);
+}
+
Message
Commands::Deop(Bot *bot, String channel, String who)
{
return NotChannelOp(channel);
if (!Utils::wildcard_p(who)) {
- 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);
+ }
} else {
- Mask m(who);
- for (std::map<String, User *, std::less<String> >::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);
}
-
return Ok;
}
// We don't trust the user...
if (!CHANNEL(channel)) {
if (bot->wantedChannels[channel])
- bot->wantedChannels[channel]->key = key;
+ bot->wantedChannels[channel]->key = static_cast<std::string> (key);
else {
bot->wantedChannels[channel] = new wantedChannel("", "", key);
}
return Ok;
}
+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);
+}
+
Message
Commands::Kick(Bot *bot, String channel, String who, String reason)
{
if (Utils::wildcard_p(who)) {
Mask m(who);
- for (std::map<String, User *, std::less<String> >::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);
} else {
- 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);
+ }
}
return Ok;
if (Utils::wildcard_p(who))
return MassOpNotAllowed;
+
+ try
+ {
+ User u = c->getUser(who);
- 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);
+ }
return Ok;
}
#include "String.H"
class Bot;
+class Channel;
+class Mask;
class Message;
+class User;
class Commands {
public:
static Message Unlock(Bot *, String);
static Message Who (Bot *, String);
static Message Whois (Bot *, String);
+
+private:
+ class deop_wildcard : std::unary_function<User &, void>
+ {
+ Bot *bot;
+ Mask &mask;
+ const String channel;
+ public:
+ deop_wildcard (Bot*, Mask&, String&);
+ void operator ()(const User &);
+ };
+
+ class kick_wildcard : std::unary_function<User &, void>
+ {
+ Bot *bot;
+ Mask &mask;
+ const String channel;
+ const String reason;
+ public:
+ kick_wildcard (Bot*, Mask&, String&, String&);
+ void operator ()(const User &);
+ };
};
#endif
BotThreading.C \
Channel.C \
ChannelList.C \
+ ChannelUserList.C \
Commands.C \
Connection.C \
DCCChatConnection.C \
BotThreading.H \
Channel.H \
ChannelList.H \
+ ChannelUserList.H \
Commands.H \
Connection.H \
DCCChatConnection.H \
return;
}
ch->addNick (n, uh, 0, cnx->bot->userList);
- 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))
{
// This is a part of the antispoof code
- ch->getUser(n)->userkey = Utils::get_key ();
+ ch->change_user_key (n, Utils::get_key ());
Commands::CTCP (cnx->bot, n, "PING",
- ch->getUser(n)->userkey + " " + c);
+ ch->getUser(n).userkey + " " + c);
}
}
{
if (!cnx->bot->channelList->getChannel (channel))
return;
- User *u = cnx->bot->channelList->getChannel (channel)->getUser (target);
- if (u && u->getProt () >= User::NO_KICK)
+ try
{
- 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)
{
- 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");
+ }
}
}
+ catch (const ChannelUserList::user_not_found &e)
+ {
+
+ }
cnx->bot->channelList->getChannel (channel)->delNick (target);
}
}
StringTokenizer st3 (rest);
rest = st3.next_token ();
String c = st3.rest ();
- 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);
+ }
}
}
if (!c)
return;
c->delNick (n);
- if (c->countOp == 0 && c->count == 1)
+ if (c->operator_count () == 0 && c->user_count () == 1)
{
cnx->queue->sendPart (channel);
cnx->queue->sendJoin (channel,
return;
}
level = Utils::get_level (cnx->bot, from->getAddress (), to);
- 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;
+ }
else
- identified = u->userListItem->passwd == ""
- || u->userListItem->identified > 0;
+ {
+ identified = true;
+ }
}
else
{
// User.C -*- C++ -*-
// Copyright (c) 1997, 1998 Etienne BERNARD
+// Copyright (C) 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
#include "UserListItem.H"
#include "Utils.H"
-User::User(String n, String uh, String channel, int mode, UserList *ul)
+User::User(String n, String uh, String channel, int mode, UserListItem *uli)
: mode(mode), floodNum(0),
- userListItem(ul->getUserListItem(n + "!" + uh, channel)),
+ userListItem(uli),
nick(n), userhost(uh),
userkey("")
{ }
{ }
int
-User::getLevel()
+User::getLevel() const
{
if (userListItem && userListItem->identified &&
(userListItem->expirationDate == -1 ||
}
int
-User::getProt()
+User::getProt() const
{
if (userListItem && userListItem->identified &&
(userListItem->expirationDate == -1 ||
}
bool
-User::getAop()
+User::getAop() const
{
if (userListItem && userListItem->identified &&
(userListItem->expirationDate == -1 ||
return userListItem->aop;
return false;
}
+
+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);
+}
// User.H -*- C++ -*-
// Copyright (c) 1997, 1998 Etienne BERNARD
+// Copyright (C) 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
NO_DEOP = 3
};
- User(String, String, String, int, UserList *);
+ User(String, String, String, int, UserListItem *);
User(String, int);
- 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;
friend class Bot;
friend class Parser;
- friend class Channel;
+ friend class ChannelUserList;
friend class Commands;
friend class UserCommands;
};
return;
}
- 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<String, Channel *, std::less<String> >::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<String, Channel *, std::less<String> >::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;
+ }
}
void
channel);
}
-// FIXME: Convert
void
UserCommands::Kick(ServerConnection *cnx, Person *from,
String channel, String rest)
{
- String nick = from->getNick();
-
Channel * c = cnx->bot->channelList->getChannel(channel);
if (rest.length() == 0) {
String who = st.next_token();
if (Utils::wildcard_p(who)) {
- 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;
- }
- }
-
- if (!cnx->bot->iAmOp(channel)) {
- from->sendNotice(String("\002I am not channel op on\002 ") +
- channel);
- return;
- }
+ try
+ {
+ User u = c->getUser(from->getNick ());
- if (Utils::wildcard_p(who)) {
- Mask m(who);
- for (std::map<String, User *, std::less<String> >::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;
+ }
}
+
+ Message ret = Commands::Kick (cnx->bot, channel, who, st.rest ());
+ if (ret.getCode () != 0)
+ from->sendNotice (ret.getMessage ());
}
// FIXME: Convert
from->sendNotice(m.getMessage());
}
+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;
+ }
+}
+
void
UserCommands::Names(ServerConnection *cnx, Person *from,
String channel, String rest)
{
String nick = from->getNick();
- String result = "";
- int length = 0;
Channel *c = cnx->bot->channelList->getChannel(channel);
- std::map<String, User *, std::less<String> >::iterator it;
+ std::string result;
from->sendNotice(String("\002Names on ") +
channel + ":\002");
- 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);
if (result != "")
from->sendNotice(result);
struct in_addr iaddr;
if (isdigit(target[0])) { // An IP ?
- iaddr.s_addr = inet_addr((const char *)target);
+ iaddr.s_addr = inet_addr(target.c_str ());
host = gethostbyaddr((char *)(&iaddr),
sizeof(struct in_addr),
AF_INET);
return;
}
} else {
- host = gethostbyname((const char *)target);
+ host = gethostbyname(target.c_str ());
if (host) {
std::memcpy((char *)&iaddr, (char *)host->h_addr,
host->h_length);
target);
}
-// FIXME: Convert
void
UserCommands::Op(ServerConnection *cnx, Person *from,
String channel, String rest)
{
- 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 ());
}
-// FIXME: Convert
void
UserCommands::Part(ServerConnection *cnx, Person *from,
String channel, String rest)
{
- 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 ());
}
void
UserCommands::Password(ServerConnection *cnx, Person *from,
String channel, String rest)
{
- Channel *c = cnx->bot->channelList->getChannel(channel);
-
if (rest.length() == 0) {
from->sendNotice("\002No password.\002");
return;
}
- 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;
+ }
}
void
}
if (Utils::wildcard_p(who) && from) {
- 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) {
if (from)
from->sendNotice("\002You need an higher level to use"
" wildcards.\002");
String channel, String rest)
{
String nick = from->getNick();
- User * u = cnx->bot->channelList->getChannel(channel)->getUser(nick);
UserListItem * uli;
-
- if (u)
- uli = u->userListItem;
+
+ if (cnx->bot->channelList->getChannel(channel)->hasNick(nick))
+ uli = cnx->bot->channelList->getChannel(channel)->getUser(nick).userListItem;
else
uli = cnx->bot->userList->getUserListItem(from->getAddress(),
- channel);
-
+ channel);
+
if (uli) {
from->sendNotice(String("\002You are\002 ") +
- uli->mask.getMask() + " \002on\002 " +
- uli->channelMask.getMask());
+ uli->mask.getMask() + " \002on\002 " +
+ uli->channelMask.getMask());
from->sendNotice(String("\002Lvl:\002 ") +
- 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" : ""));
} else
from->sendNotice(String("\002You are not in the userlist for\002 ") +
- channel);
+ channel);
}
void
StringTokenizer st(rest);
String otherNick = st.next_token();
- User * u = cnx->bot->channelList->getChannel(channel)->getUser(otherNick);
UserListItem * uli;
- if (u)
- uli = u->userListItem;
+ if (cnx->bot->channelList->getChannel(channel)->hasNick(otherNick))
+ uli = cnx->bot->channelList->getChannel(channel)->getUser(otherNick).userListItem;
else
uli = cnx->bot->userList->getUserListItem(otherNick + "!" +
cnx->bot->getUserhost(channel,
#include "String.H"
+#include <functional>
+
class Person;
class ServerConnection;
+class User;
class UserCommands {
public:
static void UserList(ServerConnection *, Person *, String, String);
static void Who(ServerConnection *, Person *, String, String);
static void Whois(ServerConnection *, Person *, String, String);
+
+private:
+ struct map_names : std::unary_function<User &, void>
+ {
+ Person *from;
+ std::string &result;
+ unsigned int length;
+
+ map_names (Person*, std::string&);
+ void operator() (const User &);
+ };
};
#endif
{ return expirationDate == -1 || std::time(NULL) <= expirationDate; }
friend class Parser;
- friend class Channel;
+ friend class ChannelUserList;
friend class User;
friend class UserList;
friend class Commands;
if (!channel_p (channel))
return get_level(b, nuh);
- 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
return -1;
- }
return b->userList->getLevel(nuh, channel);
}