diff options
| author | Adam <Adam@anope.org> | 2010-11-20 21:45:30 -0500 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2010-12-12 19:35:27 -0500 |
| commit | 246f44b9888161aecefc81f0ff17ddd893287e3c (patch) | |
| tree | b89607a9ad9c91914f292fc54cc32213a8d9f5c4 /modules/core | |
| parent | a85112172d842aa74aa5531788d383328d153e74 (diff) | |
Added cs_mode, rewrote the old list mode code, and added CIDR support
Diffstat (limited to 'modules/core')
| -rw-r--r-- | modules/core/cs_clearusers.cpp | 14 | ||||
| -rw-r--r-- | modules/core/cs_forbid.cpp | 10 | ||||
| -rw-r--r-- | modules/core/cs_info.cpp | 3 | ||||
| -rw-r--r-- | modules/core/cs_mode.cpp | 306 | ||||
| -rw-r--r-- | modules/core/cs_set.cpp | 2 | ||||
| -rw-r--r-- | modules/core/cs_set_persist.cpp | 4 | ||||
| -rw-r--r-- | modules/core/db_plain.cpp | 75 | ||||
| -rw-r--r-- | modules/core/os_defcon.cpp | 2 |
8 files changed, 369 insertions, 47 deletions
diff --git a/modules/core/cs_clearusers.cpp b/modules/core/cs_clearusers.cpp index 55c6f684e..028c7e5d6 100644 --- a/modules/core/cs_clearusers.cpp +++ b/modules/core/cs_clearusers.cpp @@ -28,15 +28,9 @@ class CommandCSClearUsers : public Command ChannelInfo *ci = c ? c->ci : NULL; Anope::string modebuf; - ChannelMode *owner = ModeManager::FindChannelModeByName(CMODE_OWNER); - ChannelMode *admin = ModeManager::FindChannelModeByName(CMODE_PROTECT); - ChannelMode *op = ModeManager::FindChannelModeByName(CMODE_OP); - ChannelMode *halfop = ModeManager::FindChannelModeByName(CMODE_HALFOP); - ChannelMode *voice = ModeManager::FindChannelModeByName(CMODE_VOICE); - if (!c) u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, chan.c_str()); - else if (!check_access(u, ci, CA_CLEAR)) + else if (!check_access(u, ci, CA_FOUNDER)) u->SendMessage(ChanServ, ACCESS_DENIED); Anope::string buf = "CLEAR USERS command from " + u->nick + " (" + u->Account()->display + ")"; @@ -55,18 +49,18 @@ class CommandCSClearUsers : public Command bool OnHelp(User *u, const Anope::string &subcommand) { - u->SendMessage(ChanServ, CHAN_HELP_CLEAR); + u->SendMessage(ChanServ, CHAN_HELP_CLEARUSERS); return true; } void OnSyntaxError(User *u, const Anope::string &subcommand) { - SyntaxError(ChanServ, u, "CLEAR", CHAN_CLEAR_SYNTAX); + SyntaxError(ChanServ, u, "CLEAR", CHAN_CLEARUSERS_SYNTAX); } void OnServHelp(User *u) { - u->SendMessage(ChanServ, CHAN_HELP_CMD_CLEAR); + u->SendMessage(ChanServ, CHAN_HELP_CMD_CLEARUSERS); } }; diff --git a/modules/core/cs_forbid.cpp b/modules/core/cs_forbid.cpp index ef55439b2..25fd90868 100644 --- a/modules/core/cs_forbid.cpp +++ b/modules/core/cs_forbid.cpp @@ -63,12 +63,16 @@ class CommandCSForbid : public Command ci->forbidby = u->nick; ci->forbidreason = reason; - if ((c = findchan(ci->name))) + if ((c = ci->c)) { /* Before banning everyone, it might be prudent to clear +e and +I lists.. * to prevent ppl from rejoining.. ~ Viper */ - c->ClearExcepts(); - c->ClearInvites(); + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = c->GetModeList(CMODE_EXCEPT); + for (; modes.first != modes.second; ++modes.first) + c->RemoveMode(NULL, CMODE_EXCEPT, modes.first->second); + modes = c->GetModeList(CMODE_INVITEOVERRIDE); + for (; modes.first != modes.second; ++modes.first) + c->RemoveMode(NULL, CMODE_INVITEOVERRIDE, modes.first->second); for (CUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; ) { diff --git a/modules/core/cs_info.cpp b/modules/core/cs_info.cpp index d9c507505..0df02ff43 100644 --- a/modules/core/cs_info.cpp +++ b/modules/core/cs_info.cpp @@ -66,7 +66,8 @@ class CommandCSInfo : public Command u->SendMessage(ChanServ, CHAN_INFO_TIME_REGGED, do_strftime(ci->time_registered).c_str()); u->SendMessage(ChanServ, CHAN_INFO_LAST_USED, do_strftime(ci->last_used).c_str()); - if (!ci->last_topic.empty() && (show_all || (!ci->HasMLock(CMODE_SECRET, true) && (!ci->c || !ci->c->HasMode(CMODE_SECRET))))) + ModeLock *secret = ci->GetMLock(CMODE_SECRET); + if (!ci->last_topic.empty() && (show_all || ((!secret || secret->set == false) && (!ci->c || !ci->c->HasMode(CMODE_SECRET))))) { u->SendMessage(ChanServ, CHAN_INFO_LAST_TOPIC, ci->last_topic.c_str()); u->SendMessage(ChanServ, CHAN_INFO_TOPIC_SET_BY, ci->last_topic_setter.c_str()); diff --git a/modules/core/cs_mode.cpp b/modules/core/cs_mode.cpp new file mode 100644 index 000000000..e92a76988 --- /dev/null +++ b/modules/core/cs_mode.cpp @@ -0,0 +1,306 @@ +/* ChanServ core functions + * + * (C) 2003-2010 Anope Team + * Contact us at team@anope.org + * + * Please read COPYING and README for further details. + * + * Based on the original code of Epona by Lara. + * Based on the original code of Services by Andy Church. + */ + +/*************************************************************************/ + +#include "module.h" + +class CommandCSMode : public Command +{ + void DoLock(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + const Anope::string &subcommand = params[2]; + const Anope::string ¶m = params.size() > 3 ? params[3] : ""; + + if (subcommand.equals_ci("ADD") && !param.empty()) + { + spacesepstream sep(param); + Anope::string modes; + + sep.GetToken(modes); + + int adding = -1; + for (size_t i = 0; i < modes.length(); ++i) + { + switch (modes[i]) + { + case '+': + adding = 1; + break; + case '-': + adding = 0; + break; + default: + if (adding == -1) + break; + ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]); + if (!cm || !cm->CanSet(u)) + { + u->SendMessage(ChanServ, CHAN_MODE_LOCK_UNKNOWN, modes[i]); + break; + } + Anope::string mode_param; + if (((cm->Type == MODE_STATUS || cm->Type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->Type == MODE_PARAM && adding && !sep.GetToken(mode_param))) + u->SendMessage(ChanServ, CHAN_MODE_LOCK_MISSING_PARAM, cm->ModeChar); + else + { + ci->SetMLock(cm, adding, mode_param, u->nick); + if (!mode_param.empty()) + mode_param = " " + mode_param; + u->SendMessage(ChanServ, CHAN_MODE_LOCKED, adding ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str()); + } + } + } + + if (ci->c) + check_modes(ci->c); + } + else if (subcommand.equals_ci("DEL") && !param.empty()) + { + spacesepstream sep(param); + Anope::string modes; + + sep.GetToken(modes); + + int adding = -1; + for (size_t i = 0; i < modes.length(); ++i) + { + switch (modes[i]) + { + case '+': + adding = 1; + break; + case '-': + adding = 0; + break; + default: + if (adding == -1) + break; + ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]); + if (!cm || !cm->CanSet(u)) + { + u->SendMessage(ChanServ, CHAN_MODE_LOCK_UNKNOWN, modes[i]); + break; + } + Anope::string mode_param; + if (!cm->Type == MODE_REGULAR && !sep.GetToken(mode_param)) + u->SendMessage(ChanServ, CHAN_MODE_LOCK_MISSING_PARAM, cm->ModeChar); + else + { + if (ci->RemoveMLock(cm, mode_param)) + { + if (!mode_param.empty()) + mode_param = " " + mode_param; + u->SendMessage(ChanServ, CHAN_MODE_UNLOCKED, adding == 1 ? '+' : '-', cm->ModeChar, mode_param.c_str(), ci->name.c_str()); + } + else + u->SendMessage(ChanServ, CHAN_MODE_NOT_LOCKED, cm->ModeChar, ci->name.c_str()); + } + } + } + } + else if (subcommand.equals_ci("LIST")) + { + const std::multimap<ChannelModeName, ModeLock> &mlocks = ci->GetMLock(); + if (mlocks.empty()) + { + u->SendMessage(ChanServ, CHAN_MODE_LOCK_NONE, ci->name.c_str()); + } + else + { + u->SendMessage(ChanServ, CHAN_MODE_LOCK_HEADER, ci->name.c_str()); + for (std::multimap<ChannelModeName, ModeLock>::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it) + { + const ModeLock &ml = it->second; + ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name); + if (!cm) + continue; + + Anope::string modeparam = ml.param; + if (!modeparam.empty()) + modeparam = " " + modeparam; + Anope::string setter = ml.setter; + if (setter.empty()) + setter = ci->founder ? ci->founder->display : "Unknown"; + u->SendMessage(ChanServ, CHAN_MODE_LIST_FMT, ml.set ? '+' : '-', cm->ModeChar, modeparam.c_str(), setter.c_str(), do_strftime(ml.created).c_str()); + } + } + } + else + this->OnSyntaxError(u, subcommand); + } + + void DoSet(User *u, ChannelInfo *ci, const std::vector<Anope::string> ¶ms) + { + spacesepstream sep(params.size() > 3 ? params[3] : ""); + Anope::string modes = params[2], param; + + Log(LOG_COMMAND, u, this, ci) << "to set " << params[2]; + + int adding = -1; + for (size_t i = 0; i < modes.length(); ++i) + { + switch (modes[i]) + { + case '+': + adding = 1; + break; + case '-': + adding = 0; + break; + case '*': + if (adding == -1) + break; + for (std::map<Anope::string, Mode *>::const_iterator it = ModeManager::Modes.begin(), it_end = ModeManager::Modes.end(); it != it_end; ++it) + { + Mode *m = it->second; + if (m->Class == MC_CHANNEL) + { + ChannelMode *cm = debug_cast<ChannelMode *>(m); + if (cm->Type == MODE_REGULAR || (!adding && cm->Type == MODE_PARAM)) + { + if (!cm->CanSet(u)) + continue; + if (adding) + ci->c->SetMode(NULL, cm); + else + ci->c->RemoveMode(NULL, cm); + } + } + } + break; + default: + if (adding == -1) + break; + ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]); + if (!cm || !cm->CanSet(u)) + continue; + switch (cm->Type) + { + case MODE_REGULAR: + if (adding) + ci->c->SetMode(NULL, cm); + else + ci->c->RemoveMode(NULL, cm); + break; + case MODE_PARAM: + if (adding && !sep.GetToken(param)) + break; + if (adding) + ci->c->SetMode(NULL, cm, param); + else + ci->c->RemoveMode(NULL, cm); + break; + case MODE_STATUS: + if (!sep.GetToken(param)) + break; + if (str_is_wildcard(param)) + { + for (CUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end; ++it) + { + UserContainer *uc = *it; + + if (Anope::Match(u->GetMask(), param)) + { + if (adding) + ci->c->SetMode(NULL, cm, uc->user->nick); + else + ci->c->RemoveMode(NULL, cm, uc->user->nick); + } + } + } + else + { + if (adding) + ci->c->SetMode(NULL, cm, param); + else + ci->c->RemoveMode(NULL, cm, param); + } + break; + case MODE_LIST: + if (!sep.GetToken(param)) + break; + if (adding) + ci->c->SetMode(NULL, cm, param); + else + { + std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> its = ci->c->GetModeList(cm->Name); + for (; its.first != its.second;) + { + const Anope::string &mask = its.first->second; + ++its.first; + + if (Anope::Match(mask, param)) + ci->c->RemoveMode(NULL, cm, mask); + } + } + } + } + } + } + + public: + CommandCSMode() : Command("MODE", 3, 4) + { + } + + CommandReturn Execute(User *u, const std::vector<Anope::string> ¶ms) + { + const Anope::string &subcommand = params[1]; + + ChannelInfo *ci = cs_findchan(params[0]); + + if (!ci || !ci->c) + u->SendMessage(ChanServ, CHAN_X_NOT_IN_USE, ci->name.c_str()); + else if (!check_access(u, ci, CA_MODE) && !u->Account()->HasCommand("chanserv/mode")) + u->SendMessage(ChanServ, ACCESS_DENIED); + else if (subcommand.equals_ci("LOCK")) + this->DoLock(u, ci, params); + else if (subcommand.equals_ci("SET")) + this->DoSet(u, ci, params); + else + this->OnSyntaxError(u, ""); + + return MOD_CONT; + } + + bool OnHelp(User *u, const Anope::string &subcommand) + { + u->SendMessage(ChanServ, CHAN_HELP_MODE); + return true; + } + + void OnSyntaxError(User *u, const Anope::string &subcommand) + { + SyntaxError(ChanServ, u, "MODE", CHAN_MODE_SYNTAX); + } + + void OnServHelp(User *u) + { + u->SendMessage(ChanServ, CHAN_HELP_CMD_MODE); + } +}; + +class CSMode : public Module +{ + CommandCSMode commandcsmode; + + public: + CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator) + { + this->SetAuthor("Anope"); + this->SetType(CORE); + + this->AddCommand(ChanServ, &commandcsmode); + } +}; + +MODULE_INIT(CSMode) diff --git a/modules/core/cs_set.cpp b/modules/core/cs_set.cpp index 04721cab8..e9774ba42 100644 --- a/modules/core/cs_set.cpp +++ b/modules/core/cs_set.cpp @@ -44,7 +44,7 @@ class CommandCSSet : public Command // XXX Remove after 1.9.4 release if (params[1].equals_ci("MLOCK")) { - u->SendMessage(ChanServ, CHAN_SET_MLOCK_DEPRECATED); + u->SendMessage(ChanServ, CHAN_SET_MLOCK_DEPRECATED, Config->s_ChanServ.c_str()); return MOD_CONT; } diff --git a/modules/core/cs_set_persist.cpp b/modules/core/cs_set_persist.cpp index bee71f95e..1a567ef83 100644 --- a/modules/core/cs_set_persist.cpp +++ b/modules/core/cs_set_persist.cpp @@ -61,7 +61,7 @@ class CommandCSSetPersist : public Command if (ci->c && !ci->c->HasMode(CMODE_PERM)) ci->c->SetMode(NULL, cm); /* Add it to the channels mlock */ - ci->SetMLock(CMODE_PERM, true); + ci->SetMLock(cm, true); } } @@ -81,7 +81,7 @@ class CommandCSSetPersist : public Command if (ci->c && ci->c->HasMode(CMODE_PERM)) ci->c->RemoveMode(NULL, cm); /* Remove from mlock */ - ci->RemoveMLock(CMODE_PERM); + ci->RemoveMLock(cm); } /* No channel mode, no BotServ, but using ChanServ as the botserv bot diff --git a/modules/core/db_plain.cpp b/modules/core/db_plain.cpp index d6f7963d5..5db485fc8 100644 --- a/modules/core/db_plain.cpp +++ b/modules/core/db_plain.cpp @@ -258,7 +258,6 @@ ChannelLevel ChannelLevels[] = { {"AUTOVOICE", CA_AUTOVOICE}, {"OPDEOP", CA_OPDEOP}, {"ACCESS_LIST", CA_ACCESS_LIST}, - {"CLEAR", CA_CLEAR}, {"NOJOIN", CA_NOJOIN}, {"ACCESS_CHANGE", CA_ACCESS_CHANGE}, {"MEMO", CA_MEMO}, @@ -749,6 +748,16 @@ class DBPlain : public Module /* For now store mlocked modes in extensible, Anope hasn't yet connected to the IRCd and doesn't know what modes exist */ ci->Extend("db_mlp", new ExtensibleItemRegular<std::vector<std::pair<Anope::string, Anope::string> > >(mlp)); } + else if (key.equals_ci("MLP_OFF")) + { + std::vector<std::pair<Anope::string, Anope::string> > mlp; + ci->GetExtRegular("db_mlp_off", mlp); + + mlp.push_back(std::make_pair(params[0], params[1])); + + /* For now store mlocked modes in extensible, Anope hasn't yet connected to the IRCd and doesn't know what modes exist */ + ci->Extend("db_mlp_off", new ExtensibleItemRegular<std::vector<std::pair<Anope::string, Anope::string> > >(mlp)); + } else if (key.equals_ci("MI")) { Memo *m = new Memo; @@ -972,30 +981,29 @@ class DBPlain : public Module db << ci->GetAkick(k)->reason; db << endl; } - if (ci->GetMLockCount(true)) + db << "MD MLOCK_ON"; { - db << "MD MLOCK_ON"; - Anope::string oldmodes; if ((!Me || !Me->IsSynced()) && ci->GetExtRegular("db_mlock_modes_on", oldmodes)) - { db << " " << oldmodes; - } else { - for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) + for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) { - ChannelMode *cm = it->second; - if (ci->HasMLock(cm->Name, true)) + const ModeLock &ml = it->second; + if (ml.set) + { + ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name); + if (!cm || cm->Type != MODE_REGULAR) + continue; db << " " << cm->NameAsString; + } } } - db << endl; } - if (ci->GetMLockCount(false)) + db << endl; + db << "MD MLOCK_OFF"; { - db << "MD MLOCK_OFF"; - Anope::string oldmodes; if ((!Me || !Me->IsSynced()) && ci->GetExtRegular("db_mlock_modes_off", oldmodes)) { @@ -1003,32 +1011,41 @@ class DBPlain : public Module } else { - for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) + for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) { - ChannelMode *cm = it->second; - if (ci->HasMLock(cm->Name, false)) + const ModeLock &ml = it->second; + if (!ml.set) + { + ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name); + if (!cm || cm->Type != MODE_REGULAR) + continue; db << " " << cm->NameAsString; + } } } - db << endl; } - std::vector<std::pair<Anope::string, Anope::string> > oldparams;; - if ((!Me || !Me->IsSynced()) && ci->GetExtRegular("db_mlp", oldparams)) + db << endl; { - for (std::vector<std::pair<Anope::string, Anope::string> >::iterator it = oldparams.begin(), it_end = oldparams.end(); it != it_end; ++it) + std::vector<std::pair<Anope::string, Anope::string> > oldparams;; + if ((!Me || !Me->IsSynced()) && ci->GetExtRegular("db_mlp", oldparams)) { - db << "MD MLP " << it->first << " " << it->second << endl; + for (std::vector<std::pair<Anope::string, Anope::string> >::iterator it = oldparams.begin(), it_end = oldparams.end(); it != it_end; ++it) + { + db << "MD MLP " << it->first << " " << it->second << endl; + } } - } - else - { - for (std::map<char, ChannelMode *>::iterator it = ModeManager::ChannelModesByChar.begin(), it_end = ModeManager::ChannelModesByChar.end(); it != it_end; ++it) + else { - ChannelMode *cm = it->second; - Anope::string Param; + for (std::map<ChannelModeName, ModeLock>::const_iterator it = ci->GetMLock().begin(), it_end = ci->GetMLock().end(); it != it_end; ++it) + { + const ModeLock &ml = it->second; + ChannelMode *cm = ModeManager::FindChannelModeByName(ml.name); + if (!cm) + continue; - if (ci->GetParam(cm->Name, Param)) - db << "MD MLP " << cm->NameAsString << " " << Param << endl; + if (!ml.param.empty()) + db << "MD MLP" << (ml.set ? " " : "_OFF ") << cm->NameAsString << " " << ml.param << endl; + } } } MemoInfo *memos = &ci->memos; diff --git a/modules/core/os_defcon.cpp b/modules/core/os_defcon.cpp index e17a6d33a..cfc8ebe62 100644 --- a/modules/core/os_defcon.cpp +++ b/modules/core/os_defcon.cpp @@ -207,7 +207,7 @@ class OSDefcon : public Module EventReturn OnPreCommandRun(User *u, BotInfo *bi, Anope::string &command, Anope::string &message, bool fantasy) { - if (!is_oper(u) && CheckDefCon(DEFCON_OPER_ONLY) || CheckDefCon(DEFCON_SILENT_OPER_ONLY)) + if (!is_oper(u) && (CheckDefCon(DEFCON_OPER_ONLY) || CheckDefCon(DEFCON_SILENT_OPER_ONLY))) { if (!CheckDefCon(DEFCON_SILENT_OPER_ONLY)) u->SendMessage(bi, OPER_DEFCON_DENIED); |
