summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/cs_saset.cpp131
-rw-r--r--src/core/cs_saset_noexpire.cpp85
-rw-r--r--src/core/cs_set.cpp794
-rw-r--r--src/core/cs_set_bantype.cpp113
-rw-r--r--src/core/cs_set_description.cpp107
-rw-r--r--src/core/cs_set_email.cpp106
-rw-r--r--src/core/cs_set_entrymsg.cpp114
-rw-r--r--src/core/cs_set_founder.cpp142
-rw-r--r--src/core/cs_set_keeptopic.cpp112
-rw-r--r--src/core/cs_set_mlock.cpp197
-rw-r--r--src/core/cs_set_opnotice.cpp112
-rw-r--r--src/core/cs_set_peace.cpp114
-rw-r--r--src/core/cs_set_persist.cpp163
-rw-r--r--src/core/cs_set_private.cpp112
-rw-r--r--src/core/cs_set_restricted.cpp116
-rw-r--r--src/core/cs_set_secure.cpp112
-rw-r--r--src/core/cs_set_securefounder.cpp118
-rw-r--r--src/core/cs_set_secureops.cpp112
-rw-r--r--src/core/cs_set_signkick.cpp112
-rw-r--r--src/core/cs_set_successor.cpp145
-rw-r--r--src/core/cs_set_topiclock.cpp112
-rw-r--r--src/core/cs_set_url.cpp114
-rw-r--r--src/core/cs_set_xop.cpp144
23 files changed, 2741 insertions, 746 deletions
diff --git a/src/core/cs_saset.cpp b/src/core/cs_saset.cpp
new file mode 100644
index 000000000..29f7f7264
--- /dev/null
+++ b/src/core/cs_saset.cpp
@@ -0,0 +1,131 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSASet : public Command
+{
+ std::map<ci::string, Command *> subcommands;
+
+ public:
+ CommandCSSASet(const ci::string &cname) : Command(cname, 2, 3)
+ {
+ }
+
+ ~CommandCSSASet()
+ {
+ for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ {
+ delete it->second;
+ }
+ this->subcommands.clear();
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (readonly)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED);
+ return MOD_CONT;
+ }
+
+ Command *c = this->FindCommand(params[1]);
+
+ if (c)
+ {
+ ci::string cmdparams = cs_findchan(params[0])->name.c_str();
+ for (std::vector<ci::string>::const_iterator it = params.begin() + 2; it != params.end(); ++it)
+ cmdparams += " " + *it;
+ mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
+ }
+ else
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET");
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &subcommand)
+ {
+ if (subcommand.empty())
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SASET_HEAD);
+ for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ it->second->OnServHelp(u);
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TAIL);
+ return true;
+ }
+ else
+ {
+ Command *c = this->FindCommand(subcommand);
+
+ if (c)
+ {
+ return c->OnHelp(u, subcommand);
+ }
+ }
+
+ return false;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &subcommand)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SASET);
+ }
+
+ bool AddSubcommand(Command *c)
+ {
+ return this->subcommands.insert(std::make_pair(c->name, c)).second;
+ }
+
+ bool DelSubcommand(const ci::string &command)
+ {
+ return this->subcommands.erase(command);
+ }
+
+ Command *FindCommand(const ci::string &subcommand)
+ {
+ std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand);
+
+ if (it != this->subcommands.end())
+ {
+ return it->second;
+ }
+
+ return NULL;
+ }
+};
+
+class CSSASet : public Module
+{
+ public:
+ CSSASet(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ this->AddCommand(ChanServ, new CommandCSSASet("SASET"));
+ }
+};
+
+MODULE_INIT(CSSASet)
diff --git a/src/core/cs_saset_noexpire.cpp b/src/core/cs_saset_noexpire.cpp
new file mode 100644
index 000000000..8d9ce2e18
--- /dev/null
+++ b/src/core/cs_saset_noexpire.cpp
@@ -0,0 +1,85 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSASetNoexpire : public Command
+{
+ public:
+ CommandCSSASetNoexpire(const ci::string &cname) : Command(cname, 2, 2, "chanserv/saset/noexpire")
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[0] == "ON")
+ {
+ ci->SetFlag(CI_NO_EXPIRE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_ON, ci->name.c_str());
+ }
+ else if (params[0] == "OFF")
+ {
+ ci->UnsetFlag(CI_NO_EXPIRE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "NOEXPIRE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET_NOEXPIRE);
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET NOEXPIRE", CHAN_SET_NOEXPIRE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_NOEXPIRE);
+ }
+};
+
+class CSSetNoexpire : public Module
+{
+ public:
+ CSSetNoexpire(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetNoexpire("NOEXPIRE"));
+ }
+
+ ~CSSetNoexpire()
+ {
+ Command *c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("NOEXPIRE");
+ }
+};
+
+MODULE_INIT(CSSetNoexpire)
diff --git a/src/core/cs_set.cpp b/src/core/cs_set.cpp
index f169e2264..c11a1c102 100644
--- a/src/core/cs_set.cpp
+++ b/src/core/cs_set.cpp
@@ -13,809 +13,110 @@
/*************************************************************************/
#include "module.h"
-#include "hashcomp.h"
class CommandCSSet : public Command
{
- private:
- CommandReturn DoSetFounder(User * u, ChannelInfo * ci, const ci::string &param)
- {
- NickAlias *na = findnick(param);
- NickCore *nc, *nc0 = ci->founder;
-
- if (!na)
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, param.c_str());
- return MOD_CONT;
- }
- else if (na->HasFlag(NS_FORBIDDEN))
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, param.c_str());
- return MOD_CONT;
- }
-
- nc = na->nc;
- if (Config.CSMaxReg && nc->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_FOUNDER_TOO_MANY_CHANS, param.c_str());
- return MOD_CONT;
- }
-
- Alog() << Config.s_ChanServ << ": Changing founder of " << ci->name << " from " << ci->founder->display
- << " to " << nc->display << " by " << u->GetMask();
-
- /* Founder and successor must not be the same group */
- if (nc == ci->successor)
- ci->successor = NULL;
-
- nc0->channelcount--;
- ci->founder = nc;
- nc->channelcount++;
-
- notice_lang(Config.s_ChanServ, u, CHAN_FOUNDER_CHANGED, ci->name.c_str(), param.c_str());
- return MOD_CONT;
- }
-
- CommandReturn DoSetSuccessor(User * u, ChannelInfo * ci, const ci::string &param)
- {
- NickAlias *na;
- NickCore *nc;
-
- if (!param.empty())
- {
- na = findnick(param);
-
- if (!na)
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, param.c_str());
- return MOD_CONT;
- }
- if (na->HasFlag(NS_FORBIDDEN))
- {
- notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, param.c_str());
- return MOD_CONT;
- }
- if (na->nc == ci->founder)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_IS_FOUNDER, param.c_str(), ci->name.c_str());
- return MOD_CONT;
- }
- nc = na->nc;
-
- }
- else
- nc = NULL;
-
- Alog() << Config.s_ChanServ << ": Changing successor of " << ci->name << " from "
- << (ci->successor ? ci->successor->display : "none")
- << " to " << (nc ? nc->display : "none") << " by " << u->GetMask();
-
- ci->successor = nc;
-
- if (nc)
- notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_CHANGED, ci->name.c_str(), param.c_str());
- else
- notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_UNSET, ci->name.c_str());
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetDesc(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->desc)
- delete [] ci->desc;
- ci->desc = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_DESC_CHANGED, ci->name.c_str(), param.c_str());
- return MOD_CONT;
- }
-
- CommandReturn DoSetURL(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->url)
- delete [] ci->url;
- if (!param.empty())
- {
- ci->url = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_URL_CHANGED, ci->name.c_str(), param.c_str());
- }
- else
- {
- ci->url = NULL;
- notice_lang(Config.s_ChanServ, u, CHAN_URL_UNSET, ci->name.c_str());
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetEMail(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->email)
- delete [] ci->email;
- if (!param.empty())
- {
- ci->email = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_CHANGED, ci->name.c_str(), param.c_str());
- }
- else
- {
- ci->email = NULL;
- notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_UNSET, ci->name.c_str());
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetEntryMsg(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (ci->entry_message)
- delete [] ci->entry_message;
- if (!param.empty())
- {
- ci->entry_message = sstrdup(param.c_str());
- notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_CHANGED, ci->name.c_str(), param.c_str());
- }
- else
- {
- ci->entry_message = NULL;
- notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_UNSET, ci->name.c_str());
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetMLock(User * u, ChannelInfo * ci, const char *modes)
- {
- int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
- unsigned char mode;
- ChannelMode *cm;
- ChannelModeParam *cmp;
-
- ci->ClearMLock();
-
- if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
- ci->SetMLock(CMODE_REGISTERED, true);
-
- ci->ClearParams();
-
- std::string params(modes ? modes : ""), param;
- unsigned space = params.find(' ');
- if (space != std::string::npos)
- {
- param = params.substr(space + 1);
- params = params.substr(0, space);
- modes = params.c_str();
- }
- spacesepstream modeparams(param);
-
- while (modes && (mode = *modes++)) {
- switch (mode) {
- case '+':
- add = 1;
- continue;
- case '-':
- add = 0;
- continue;
- default:
- if (add < 0)
- continue;
- }
-
- if ((cm = ModeManager::FindChannelModeByChar(mode)))
- {
- if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(u))
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, mode);
- }
- else if (add)
- {
- ci->RemoveMLock(cm->Name);
-
- if (cm->Type == MODE_PARAM)
- {
- cmp = dynamic_cast<ChannelModeParam *>(cm);
-
- if (!modeparams.GetToken(param))
- continue;
-
- if (!cmp->IsValid(param))
- continue;
-
- ci->SetMLock(cmp->Name, true, param);
- }
- else
- {
- ci->SetMLock(cm->Name, true);
- }
- }
- else
- {
- ci->SetMLock(cm->Name, false);
- }
- }
- else
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode);
- } /* while (*modes) */
-
- if (ModeManager::FindChannelModeByName(CMODE_REDIRECT)) {
- /* We can't mlock +L if +l is not mlocked as well. */
- if (ci->HasMLock(CMODE_REDIRECT, true) && !ci->HasMLock(CMODE_LIMIT, true))
- {
- ci->RemoveMLock(CMODE_REDIRECT);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_L_REQUIRED);
- }
- }
-
- /* Some ircd we can't set NOKNOCK without INVITE */
- /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
- if (ModeManager::FindChannelModeByName(CMODE_NOKNOCK) && ircd->knock_needs_i) {
- if (ci->HasMLock(CMODE_NOKNOCK, true) && !ci->HasMLock(CMODE_INVITE, true))
- {
- ci->RemoveMLock(CMODE_NOKNOCK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_K_REQUIRED);
- }
- }
-
- /* Since we always enforce mode r there is no way to have no
- * mode lock at all.
- */
- if (get_mlock_modes(ci, 0)) {
- notice_lang(Config.s_ChanServ, u, CHAN_MLOCK_CHANGED, ci->name.c_str(),
- get_mlock_modes(ci, 0));
- }
-
- /* Implement the new lock. */
- if (ci->c)
- check_modes(ci->c);
- return MOD_CONT;
- }
-
- CommandReturn DoSetBanType(User * u, ChannelInfo * ci, const char *param)
- {
- char *endptr;
-
- int16 bantype = strtol(param, &endptr, 10);
-
- if (*endptr != 0 || bantype < 0 || bantype > 3) {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_INVALID, param);
- } else {
- ci->bantype = bantype;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(),
- ci->bantype);
- }
- return MOD_CONT;
- }
-
- CommandReturn DoSetKeepTopic(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_KEEPTOPIC);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_KEEPTOPIC);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "KEEPTOPIC");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetTopicLock(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_TOPICLOCK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_TOPICLOCK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "TOPICLOCK");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetPrivate(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_PRIVATE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_PRIVATE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "PRIVATE");
-
- return MOD_CONT;
- }
+ std::map<ci::string, Command *> subcommands;
- CommandReturn DoSetSecureOps(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_SECUREOPS);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_SECUREOPS);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "SECUREOPS");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetSecureFounder(User * u, ChannelInfo * ci, const ci::string &param)
+ public:
+ CommandCSSet(const ci::string &cname) : Command(cname, 2, 3)
{
- if (param == "ON")
- {
- ci->SetFlag(CI_SECUREFOUNDER);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_SECUREFOUNDER);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "SECUREFOUNDER");
-
- return MOD_CONT;
}
- CommandReturn DoSetRestricted(User * u, ChannelInfo * ci, const ci::string &param)
+ ~CommandCSSet()
{
- if (param == "ON")
+ for (std::map<ci::string, Command *>::const_iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
{
- ci->SetFlag(CI_RESTRICTED);
- if (ci->levels[CA_NOJOIN] < 0)
- ci->levels[CA_NOJOIN] = 0;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_ON, ci->name.c_str());
+ delete it->second;
}
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_RESTRICTED);
- if (ci->levels[CA_NOJOIN] >= 0)
- ci->levels[CA_NOJOIN] = -2;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "RESTRICTED");
-
- return MOD_CONT;
+ this->subcommands.clear();
}
- CommandReturn DoSetSecure(User * u, ChannelInfo * ci, const ci::string &param)
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
{
- if (param == "ON")
+ if (readonly)
{
- ci->SetFlag(CI_SECURE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_ON, ci->name.c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED);
+ return MOD_CONT;
}
- else if (param == "OFF")
+ if (!check_access(u, cs_findchan(params[0]), CA_SET))
{
- ci->UnsetFlag(CI_SECURE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_OFF, ci->name.c_str());
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
}
- else
- this->OnSyntaxError(u, "SECURE");
- return MOD_CONT;
- }
-
- CommandReturn DoSetSignKick(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_SIGNKICK);
- ci->UnsetFlag(CI_SIGNKICK_LEVEL);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_ON, ci->name.c_str());
- }
- else if (param == "LEVEL")
- {
- ci->SetFlag(CI_SIGNKICK_LEVEL);
- ci->UnsetFlag(CI_SIGNKICK);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_LEVEL, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_SIGNKICK);
- ci->UnsetFlag(CI_SIGNKICK_LEVEL);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "SIGNKICK");
- return MOD_CONT;
- }
+ Command *c = this->FindCommand(params[1]);
- CommandReturn DoSetOpNotice(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
- {
- ci->SetFlag(CI_OPNOTICE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
+ if (c)
{
- ci->UnsetFlag(CI_OPNOTICE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_OFF, ci->name.c_str());
+ ci::string cmdparams = cs_findchan(params[0])->name.c_str();
+ for (std::vector<ci::string>::const_iterator it = params.begin() + 2; it != params.end(); ++it)
+ cmdparams += " " + *it;
+ mod_run_cmd(ChanServ, u, c, params[1], cmdparams);
}
else
- this->OnSyntaxError(u, "OPNOTICE");
-
- return MOD_CONT;
- }
-
-#define CHECKLEV(lev) ((ci->levels[(lev)] != ACCESS_INVALID) && (access->level >= ci->levels[(lev)]))
-
- CommandReturn DoSetXOP(User * u, ChannelInfo * ci, const ci::string &param)
- {
- if (param == "ON")
{
- if (!(ci->HasFlag(CI_XOP)))
- {
- ChanAccess *access;
-
- for (unsigned i = ci->GetAccessCount() - 1; 0 <= i; --i)
- {
- access = ci->GetAccess(i);
-
- /* This will probably cause wrong levels to be set, but hey,
- * it's better than losing it altogether.
- */
- if (access->level == ACCESS_QOP)
- access->level = ACCESS_QOP;
- else if (CHECKLEV(CA_AKICK) || CHECKLEV(CA_SET))
- access->level = ACCESS_SOP;
- else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP) || CHECKLEV(CA_OPDEOPME))
- access->level = ACCESS_AOP;
- else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP) || CHECKLEV(CA_HALFOPME)))
- access->level = ACCESS_HOP;
- else if (CHECKLEV(CA_AUTOVOICE) || CHECKLEV(CA_VOICE) || CHECKLEV(CA_VOICEME))
- access->level = ACCESS_VOP;
- else
- {
- ci->EraseAccess(i);
- }
- }
-
- reset_levels(ci);
- ci->SetFlag(CI_XOP);
- }
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " enabled XOP for " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_XOP);
-
- Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled XOP for " << ci->name;
- notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name.c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET");
}
- else
- this->OnSyntaxError(u, "XOP");
return MOD_CONT;
}
-#undef CHECKLEV
-
- CommandReturn DoSetPeace(User * u, ChannelInfo * ci, const ci::string &param)
+ bool OnHelp(User *u, const ci::string &subcommand)
{
- if (param == "ON")
- {
- ci->SetFlag(CI_PEACE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
+ if (subcommand.empty())
{
- ci->UnsetFlag(CI_PEACE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_OFF, ci->name.c_str());
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_HEAD);
+ for (std::map<ci::string, Command *>::iterator it = this->subcommands.begin(); it != this->subcommands.end(); ++it)
+ it->second->OnServHelp(u);
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TAIL);
+ return true;
}
else
- this->OnSyntaxError(u, "PEACE");
-
- return MOD_CONT;
- }
-
- CommandReturn DoSetPersist(User *u, ChannelInfo *ci, const ci::string &param)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
-
- if (param == "ON")
{
- if (!ci->HasFlag(CI_PERSIST))
- {
- ci->SetFlag(CI_PERSIST);
-
- /* Channel doesn't exist, create it internally */
- if (!ci->c)
- {
- new Channel(ci->name);
- if (ci->bi)
- bot_join(ci);
- }
+ Command *c = this->FindCommand(subcommand);
- /* No botserv bot, no channel mode */
- if (!ci->bi && !cm)
- {
- /* Give them ChanServ
- * Yes, this works fine with no Config.s_BotServ
- */
- ChanServ->Assign(NULL, ci);
- }
-
- /* Set the perm mode */
- if (cm && ci->c && !ci->c->HasMode(CMODE_PERM))
- {
- ci->c->SetMode(NULL, cm);
- }
- }
-
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- if (ci->HasFlag(CI_PERSIST))
+ if (c)
{
- ci->UnsetFlag(CI_PERSIST);
-
- /* Unset perm mode */
- if (cm && ci->c && ci->c->HasMode(CMODE_PERM))
- ci->c->RemoveMode(NULL, cm);
- if (Config.s_BotServ && ci->bi && ci->c->users.size() == Config.BSMinUsers - 1)
- ircdproto->SendPart(ci->bi, ci->c, NULL);
-
- /* No channel mode, no BotServ, but using ChanServ as the botserv bot
- * which was assigned when persist was set on
- */
- if (!cm && !Config.s_BotServ && ci->bi)
- {
- /* Unassign bot */
- ChanServ->UnAssign(NULL, ci);
- }
-
- if (ci->c && ci->c->users.empty())
- delete ci->c;
+ return c->OnHelp(u, subcommand);
}
-
- notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_OFF, ci->name.c_str());
}
- else
- this->OnSyntaxError(u, "PERSIST");
- return MOD_CONT;
+ return false;
}
- CommandReturn DoSetNoExpire(User * u, ChannelInfo * ci, const ci::string &param)
+ void OnSyntaxError(User *u, const ci::string &subcommand)
{
- if (!u->Account()->HasCommand("chanserv/set/noexpire"))
- {
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- return MOD_CONT;
- }
- if (param == "ON")
- {
- ci->SetFlag(CI_NO_EXPIRE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_ON, ci->name.c_str());
- }
- else if (param == "OFF")
- {
- ci->UnsetFlag(CI_NO_EXPIRE);
- notice_lang(Config.s_ChanServ, u, CHAN_SET_NOEXPIRE_OFF, ci->name.c_str());
- }
- else
- this->OnSyntaxError(u, "NOEXPIRE");
-
- return MOD_CONT;
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
}
- public:
- CommandCSSet() : Command("SET", 2, 3)
+ void OnServHelp(User *u)
{
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET);
}
- CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ bool AddSubcommand(Command *c)
{
- const char *chan = params[0].c_str();
- ci::string cmd = params[1];
- ci::string param = params.size() > 2 ? params[2] : "";
- ChannelInfo *ci = cs_findchan(chan);
- bool is_servadmin = u->Account()->HasPriv("chanserv/set");
-
- if (readonly) {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_DISABLED);
- return MOD_CONT;
- }
-
- if (param.empty() && cmd != "SUCCESSOR" && cmd != "URL" && cmd != "EMAIL" && cmd != "ENTRYMSG" && cmd != "MLOCK")
- this->OnSyntaxError(u, cmd);
- else if (!is_servadmin && !check_access(u, ci, CA_SET))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else if (cmd == "FOUNDER")
- {
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else
- DoSetFounder(u, ci, param);
- }
- else if (cmd == "SUCCESSOR")
- {
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else
- DoSetSuccessor(u, ci, param);
- }
- else if (cmd == "DESC")
- DoSetDesc(u, ci, param);
- else if (cmd == "URL")
- DoSetURL(u, ci, param);
- else if (cmd == "EMAIL")
- DoSetEMail(u, ci, param);
- else if (cmd == "ENTRYMSG")
- DoSetEntryMsg(u, ci, param);
- else if (cmd == "TOPIC")
- notice_lang(Config.s_ChanServ, u, OBSOLETE_COMMAND, "TOPIC");
- else if (cmd == "BANTYPE")
- DoSetBanType(u, ci, param.c_str());
- else if (cmd == "MLOCK")
- DoSetMLock(u, ci, param.c_str());
- else if (cmd == "KEEPTOPIC")
- DoSetKeepTopic(u, ci, param);
- else if (cmd == "TOPICLOCK")
- DoSetTopicLock(u, ci, param);
- else if (cmd == "PRIVATE")
- DoSetPrivate(u, ci, param);
- else if (cmd == "SECUREOPS")
- DoSetSecureOps(u, ci, param);
- else if (cmd == "SECUREFOUNDER")
- {
- if (!is_servadmin && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
- notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
- else
- DoSetSecureFounder(u, ci, param);
- }
- else if (cmd == "RESTRICTED")
- DoSetRestricted(u, ci, param);
- else if (cmd == "SECURE")
- DoSetSecure(u, ci, param);
- else if (cmd == "SIGNKICK")
- DoSetSignKick(u, ci, param);
- else if (cmd == "OPNOTICE")
- DoSetOpNotice(u, ci, param);
- else if (cmd == "XOP")
- {
- if (!FindModule("cs_xop"))
- notice_lang(Config.s_ChanServ, u, CHAN_XOP_NOT_AVAILABLE, cmd.c_str());
- else
- DoSetXOP(u, ci, param);
- }
- else if (cmd == "PEACE")
- DoSetPeace(u, ci, param);
- else if (cmd == "PERSIST")
- DoSetPersist(u, ci, param);
- else if (cmd == "NOEXPIRE")
- DoSetNoExpire(u, ci, param);
- else
- {
- notice_lang(Config.s_ChanServ, u, CHAN_SET_UNKNOWN_OPTION, cmd.c_str());
- notice_lang(Config.s_ChanServ, u, MORE_INFO, Config.s_ChanServ, "SET");
- }
-
- return MOD_CONT;
+ return this->subcommands.insert(std::make_pair(c->name, c)).second;
}
- bool OnHelp(User *u, const ci::string &subcommand)
+ bool DelSubcommand(const ci::string &command)
{
- if (subcommand.empty())
- {
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET);
- if (u->Account() && u->Account()->IsServicesOper())
- notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET);
- }
- else if (subcommand == "FOUNDER")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER);
- else if (subcommand == "SUCCESSOR")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR);
- else if (subcommand == "DESC")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC);
- else if (subcommand == "URL")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL);
- else if (subcommand == "EMAIL")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL);
- else if (subcommand == "ENTRYMSG")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG);
- else if (subcommand == "BANTYPE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE);
- else if (subcommand == "PRIVATE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE);
- else if (subcommand == "KEEPTOPIC")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC);
- else if (subcommand == "TOPICLOCK")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK);
- else if (subcommand == "MLOCK")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK);
- else if (subcommand == "RESTRICTED")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED);
- else if (subcommand == "SECURE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, Config.s_NickServ);
- else if (subcommand == "SECUREOPS")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS);
- else if (subcommand == "SECUREFOUNDER")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER);
- else if (subcommand == "SIGNKICK")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK);
- else if (subcommand == "OPNOTICE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE);
- else if (subcommand == "XOP")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP);
- else if (subcommand == "PEACE")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE);
- else if (subcommand == "PERSIST")
- notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST);
- else if (subcommand == "NOEXPIRE")
- notice_help(Config.s_ChanServ, u, CHAN_SERVADMIN_HELP_SET_NOEXPIRE);
- else
- return false;
-
- return true;
+ return this->subcommands.erase(command);
}
- void OnSyntaxError(User *u, const ci::string &subcommand)
+ Command *FindCommand(const ci::string &subcommand)
{
- int reply = CHAN_SET_SYNTAX;
- ci::string command = "SET";
+ std::map<ci::string, Command *>::const_iterator it = this->subcommands.find(subcommand);
- if (!subcommand.empty())
+ if (it != this->subcommands.end())
{
- if (subcommand == "KEEPTOPIC")
- reply = CHAN_SET_KEEPTOPIC_SYNTAX;
- else if (subcommand == "TOPICLOCK")
- reply = CHAN_SET_TOPICLOCK_SYNTAX;
- else if (subcommand == "PRIVATE")
- reply = CHAN_SET_PRIVATE_SYNTAX;
- else if (subcommand == "SECUREOPS")
- reply = CHAN_SET_SECUREOPS_SYNTAX;
- else if (subcommand == "SECUREFOUNDER")
- reply = CHAN_SET_SECUREFOUNDER_SYNTAX;
- else if (subcommand == "RESTRICTED")
- reply = CHAN_SET_RESTRICTED_SYNTAX;
- else if (subcommand == "SECURE")
- reply = CHAN_SET_SECURE_SYNTAX;
- else if (subcommand == "SIGNKICK")
- reply = CHAN_SET_SIGNKICK_SYNTAX;
- else if (subcommand == "OPNOTICE")
- reply = CHAN_SET_OPNOTICE_SYNTAX;
- else if (subcommand == "XOP")
- reply = CHAN_SET_XOP_SYNTAX;
- else if (subcommand == "PEACE")
- reply = CHAN_SET_PEACE_SYNTAX;
- else if (subcommand == "PERSIST")
- reply = CHAN_SET_PERSIST_SYNTAX;
- else if (subcommand == "NOEXPIRE")
- reply = CHAN_SET_NOEXPIRE_SYNTAX;
-
- if (reply != CHAN_SET_SYNTAX)
- command += " " + subcommand;
+ return it->second;
}
- syntax_error(Config.s_ChanServ, u, command.c_str(), reply);
- }
-
- void OnServHelp(User *u)
- {
- notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET);
+ return NULL;
}
};
@@ -827,7 +128,8 @@ class CSSet : public Module
this->SetAuthor("Anope");
this->SetVersion(VERSION_STRING);
this->SetType(CORE);
- this->AddCommand(ChanServ, new CommandCSSet());
+
+ this->AddCommand(ChanServ, new CommandCSSet("SET"));
}
};
diff --git a/src/core/cs_set_bantype.cpp b/src/core/cs_set_bantype.cpp
new file mode 100644
index 000000000..985c6f1e6
--- /dev/null
+++ b/src/core/cs_set_bantype.cpp
@@ -0,0 +1,113 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetBanType : public Command
+{
+ public:
+ CommandCSSetBanType(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ char *endptr;
+
+ int16 bantype = strtol(params[1].c_str(), &endptr, 10);
+
+ if (*endptr != 0 || bantype < 0 || bantype > 3)
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_INVALID, params[1].c_str());
+ else
+ {
+ ci->bantype = bantype;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_BANTYPE_CHANGED, ci->name.c_str(), ci->bantype);
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_BANTYPE);
+ }
+};
+
+class CommandCSSASetBanType : public CommandCSSetBanType
+{
+ public:
+ CommandCSSASetBanType(const ci::string &cname) : CommandCSSetBanType(cname, "chanserv/saset/bantype")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_BANTYPE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetBanType : public Module
+{
+ public:
+ CSSetBanType(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetBanType("BANTYPE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetBanType("BANTYPE"));
+ }
+
+ ~CSSetBanType()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("BANTYPE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("BANTYPE");
+ }
+};
+
+MODULE_INIT(CSSetBanType)
diff --git a/src/core/cs_set_description.cpp b/src/core/cs_set_description.cpp
new file mode 100644
index 000000000..44e6090bf
--- /dev/null
+++ b/src/core/cs_set_description.cpp
@@ -0,0 +1,107 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetDescription : public Command
+{
+ public:
+ CommandCSSetDescription(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->desc)
+ delete [] ci->desc;
+ ci->desc = sstrdup(params[1].c_str());
+
+ notice_lang(Config.s_ChanServ, u, CHAN_DESC_CHANGED, ci->name.c_str(), ci->desc);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_DESC);
+ }
+};
+
+class CommandCSSASetDescription : public CommandCSSetDescription
+{
+ public:
+ CommandCSSASetDescription(const ci::string &cname) : CommandCSSetDescription(cname, "chanserv/saset/description")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_DESC, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetDescription : public Module
+{
+ public:
+ CSSetDescription(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetDescription("DESC"));
+
+ c = FindCommand(ChanServ, "SASEt");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetDescription("DESC"));
+ }
+
+ ~CSSetDescription()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("DESC");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("DESC");
+ }
+};
+
+MODULE_INIT(CSSetDescription)
diff --git a/src/core/cs_set_email.cpp b/src/core/cs_set_email.cpp
new file mode 100644
index 000000000..d226a3b06
--- /dev/null
+++ b/src/core/cs_set_email.cpp
@@ -0,0 +1,106 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetEMail : public Command
+{
+ public:
+ CommandCSSetEMail(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->email)
+ delete [] ci->email;
+ if (params.size() > 1)
+ {
+ ci->email = sstrdup(params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_CHANGED, ci->name.c_str(), ci->email);
+ }
+ else
+ {
+ ci->email = NULL;
+ notice_lang(Config.s_ChanServ, u, CHAN_EMAIL_UNSET, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_EMAIL);
+ }
+};
+
+class CommandCSSASetEMail : public CommandCSSetEMail
+{
+ public:
+ CommandCSSASetEMail(const ci::string &cname) : CommandCSSetEMail(cname, "chanserv/saset/email")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_EMAIL, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ /// XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetEMail : public Module
+{
+ public:
+ CSSetEMail(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetEMail("EMAIL"));
+ }
+
+ ~CSSetEMail()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("EMAIL");
+ }
+};
+
+MODULE_INIT(CSSetEMail)
diff --git a/src/core/cs_set_entrymsg.cpp b/src/core/cs_set_entrymsg.cpp
new file mode 100644
index 000000000..b7c223546
--- /dev/null
+++ b/src/core/cs_set_entrymsg.cpp
@@ -0,0 +1,114 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetEntryMsg : public Command
+{
+ public:
+ CommandCSSetEntryMsg(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->entry_message)
+ delete [] ci->entry_message;
+ if (params.size() > 1)
+ {
+ ci->entry_message = sstrdup(params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_CHANGED, ci->name.c_str(), ci->entry_message);
+ }
+ else
+ {
+ ci->entry_message = NULL;
+ notice_lang(Config.s_ChanServ, u, CHAN_ENTRY_MSG_UNSET, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG, "SEt");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_ENTRYMSG);
+ }
+};
+
+class CommandCSSASetEntryMsg : public CommandCSSetEntryMsg
+{
+ public:
+ CommandCSSASetEntryMsg(const ci::string &cname) : CommandCSSetEntryMsg(cname, "/chanserv/saset/entrymsg")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_ENTRYMSG, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetEntryMsg : public Module
+{
+ public:
+ CSSetEntryMsg(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetEntryMsg("ENTRYMSG"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetEntryMsg("ENTRYMSG"));
+ }
+
+ ~CSSetEntryMsg()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("ENTRYMSG");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("ENTRYMSG");
+ }
+};
+
+MODULE_INIT(CSSetEntryMsg)
diff --git a/src/core/cs_set_founder.cpp b/src/core/cs_set_founder.cpp
new file mode 100644
index 000000000..6a456a0f6
--- /dev/null
+++ b/src/core/cs_set_founder.cpp
@@ -0,0 +1,142 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetFounder : public Command
+{
+ public:
+ CommandCSSetFounder(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (this->permission.empty() && (ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER)))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+ NickAlias *na = findnick(params[1]);
+ NickCore *nc, *nc0 = ci->founder;
+
+
+ if (!na)
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, params[1].c_str());
+ return MOD_CONT;
+ }
+ else if (na->HasFlag(NS_FORBIDDEN))
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, na->nick);
+ return MOD_CONT;
+ }
+
+ nc = na->nc;
+ if (Config.CSMaxReg && nc->channelcount >= Config.CSMaxReg && !u->Account()->HasPriv("chanserv/no-register-limit"))
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_FOUNDER_TOO_MANY_CHANS, na->nick);
+ return MOD_CONT;
+ }
+
+ Alog() << Config.s_ChanServ << ": Changing founder of " << ci->name << " from " << ci->founder->display
+ << " to " << nc->display << " by " << u->GetMask();
+
+ /* Founder and successor must not be the same group */
+ if (nc == ci->successor)
+ ci->successor = NULL;
+
+ nc0->channelcount--;
+ ci->founder = nc;
+ nc->channelcount++;
+
+ notice_lang(Config.s_ChanServ, u, CHAN_FOUNDER_CHANGED, ci->name.c_str(), na->nick);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_FOUNDER);
+ }
+};
+
+class CommandCSSASetFounder : public CommandCSSetFounder
+{
+ public:
+ CommandCSSASetFounder(const ci::string &cname) : CommandCSSetFounder(cname, "chanserv/saset/founder")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_FOUNDER, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetFounder : public Module
+{
+ public:
+ CSSetFounder(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetFounder("FOUNDER"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetFounder("FOUNDER"));
+ }
+
+ ~CSSetFounder()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("FOUNDER");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("FOUNDER");
+ }
+};
+
+MODULE_INIT(CSSetFounder)
diff --git a/src/core/cs_set_keeptopic.cpp b/src/core/cs_set_keeptopic.cpp
new file mode 100644
index 000000000..87a4660cf
--- /dev/null
+++ b/src/core/cs_set_keeptopic.cpp
@@ -0,0 +1,112 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetKeepTopic : public Command
+{
+ public:
+ CommandCSSetKeepTopic(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_KEEPTOPIC);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_KEEPTOPIC);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_KEEPTOPIC_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "KEEPTOPIC");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET KEEPTOPIC", CHAN_SET_KEEPTOPIC_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_KEEPTOPIC);
+ }
+};
+
+class CommandCSSASetKeepTopic : public CommandCSSetKeepTopic
+{
+ public:
+ CommandCSSASetKeepTopic(const ci::string &cname) : CommandCSSetKeepTopic(cname, "chanserv/saset/keeptopic")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_KEEPTOPIC, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET KEEPTOPIC", CHAN_SASET_KEEPTOPIC_SYNTAX);
+ }
+};
+
+class CSSetKeepTopic : public Module
+{
+ public:
+ CSSetKeepTopic(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetKeepTopic("KEEPTOPIC"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetKeepTopic("KEEPTOPIC"));
+ }
+
+ ~CSSetKeepTopic()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("KEEPTOPIC");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("KEEPTOPIC");
+ }
+};
+
+MODULE_INIT(CSSetKeepTopic)
diff --git a/src/core/cs_set_mlock.cpp b/src/core/cs_set_mlock.cpp
new file mode 100644
index 000000000..d75363ac4
--- /dev/null
+++ b/src/core/cs_set_mlock.cpp
@@ -0,0 +1,197 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetMLock : public Command
+{
+ public:
+ CommandCSSetMLock(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 0, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ int add = -1; /* 1 if adding, 0 if deleting, -1 if neither */
+ unsigned char mode;
+ ChannelMode *cm;
+ unsigned paramcount = 2;
+
+ ci->ClearMLock();
+ ci->ClearParams();
+
+ if (ModeManager::FindChannelModeByName(CMODE_REGISTERED))
+ ci->SetMLock(CMODE_REGISTERED, true);
+
+ const char *modes = params[1].c_str();
+ while (modes && (mode = *modes++))
+ {
+ switch (mode) {
+ case '+':
+ add = 1;
+ continue;
+ case '-':
+ add = 0;
+ continue;
+ default:
+ if (add < 0)
+ continue;
+ }
+
+ if ((cm = ModeManager::FindChannelModeByChar(mode)))
+ {
+ if (cm->Type == MODE_STATUS || cm->Type == MODE_LIST || !cm->CanSet(u))
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_IMPOSSIBLE_CHAR, mode);
+ }
+ else if (add)
+ {
+ ci->RemoveMLock(cm->Name);
+
+ if (cm->Type == MODE_PARAM)
+ {
+ if (paramcount >= params.size())
+ continue;
+
+ std::string param = params[paramcount].c_str();
+
+ ChannelModeParam *cmp = dynamic_cast<ChannelModeParam *>(cm);
+
+ if (!cmp || !cmp->IsValid(param))
+ continue;
+
+ ci->SetMLock(cmp->Name, true, param);
+ }
+ else
+ {
+ ci->SetMLock(cm->Name, true);
+ }
+ }
+ else
+ {
+ ci->SetMLock(cm->Name, false);
+ }
+ }
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_UNKNOWN_CHAR, mode);
+ } /* while (*modes) */
+
+ if (ModeManager::FindChannelModeByName(CMODE_REDIRECT))
+ {
+ /* We can't mlock +L if +l is not mlocked as well. */
+ if (ci->HasMLock(CMODE_REDIRECT, true) && !ci->HasMLock(CMODE_LIMIT, true))
+ {
+ ci->RemoveMLock(CMODE_REDIRECT);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_L_REQUIRED);
+ }
+ }
+
+ /* Some ircd we can't set NOKNOCK without INVITE */
+ /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */
+ if (ModeManager::FindChannelModeByName(CMODE_NOKNOCK) && ircd->knock_needs_i)
+ {
+ if (ci->HasMLock(CMODE_NOKNOCK, true) && !ci->HasMLock(CMODE_INVITE, true))
+ {
+ ci->RemoveMLock(CMODE_NOKNOCK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_MLOCK_K_REQUIRED);
+ }
+ }
+
+ /* Since we always enforce mode r there is no way to have no
+ * mode lock at all.
+ */
+ if (get_mlock_modes(ci, 0)) {
+ notice_lang(Config.s_ChanServ, u, CHAN_MLOCK_CHANGED, ci->name.c_str(), get_mlock_modes(ci, 0));
+ }
+
+ /* Implement the new lock. */
+ if (ci->c)
+ check_modes(ci->c);
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_MLOCK);
+ }
+};
+
+class CommandCSSASetMLock : public CommandCSSetMLock
+{
+ public:
+ CommandCSSASetMLock(const ci::string &cname) : CommandCSSetMLock(cname, "chanserv/saset/mlock")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_MLOCK, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetMLock : public Module
+{
+ public:
+ CSSetMLock(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetMLock("MLOCK"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetMLock("MLOCK"));
+ }
+
+ ~CSSetMLock()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("MLOCK");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("MLOCK");
+ }
+};
+
+MODULE_INIT(CSSetMLock)
diff --git a/src/core/cs_set_opnotice.cpp b/src/core/cs_set_opnotice.cpp
new file mode 100644
index 000000000..b889869bd
--- /dev/null
+++ b/src/core/cs_set_opnotice.cpp
@@ -0,0 +1,112 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetOpNotice : public Command
+{
+ public:
+ CommandCSSetOpNotice(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_OPNOTICE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_OPNOTICE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_OPNOTICE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "OPNOTICE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET OPNOTICE", CHAN_SET_OPNOTICE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_OPNOTICE);
+ }
+};
+
+class CommandCSSASetOpNotice : public CommandCSSetOpNotice
+{
+ public:
+ CommandCSSASetOpNotice(const ci::string &cname) : CommandCSSetOpNotice(cname, "chanserv/saset/opnotice")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_OPNOTICE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET OPNOTICE", CHAN_SASET_OPNOTICE_SYNTAX);
+ }
+};
+
+class CSSetOpNotice : public Module
+{
+ public:
+ CSSetOpNotice(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetOpNotice("OPNOTICE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetOpNotice("OPNOTICE"));
+ }
+
+ ~CSSetOpNotice()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("OPNOTICE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("OPNOTICE");
+ }
+};
+
+MODULE_INIT(CSSetOpNotice)
diff --git a/src/core/cs_set_peace.cpp b/src/core/cs_set_peace.cpp
new file mode 100644
index 000000000..05cf5f863
--- /dev/null
+++ b/src/core/cs_set_peace.cpp
@@ -0,0 +1,114 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetPeace : public Command
+{
+ public:
+ CommandCSSetPeace(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_PEACE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_PEACE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PEACE_OFF, ci->name.c_str());
+ }
+ else
+ {
+ this->OnSyntaxError(u, "PEACE");
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET PEACE", CHAN_SET_PEACE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PEACE, "SET");
+ }
+};
+
+class CommandCSSASetPeace : public CommandCSSetPeace
+{
+ public:
+ CommandCSSASetPeace(const ci::string &cname) : CommandCSSetPeace(cname, "chanserv/saset/peace")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PEACE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET PEACE", CHAN_SASET_PEACE_SYNTAX);
+ }
+};
+
+class CSSetPeace : public Module
+{
+ public:
+ CSSetPeace(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetPeace("PEACE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetPeace("PEACE"));
+ }
+
+ ~CSSetPeace()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("PEACE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("PEACE");
+ }
+};
+
+MODULE_INIT(CSSetPeace)
diff --git a/src/core/cs_set_persist.cpp b/src/core/cs_set_persist.cpp
new file mode 100644
index 000000000..0e713c715
--- /dev/null
+++ b/src/core/cs_set_persist.cpp
@@ -0,0 +1,163 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetPersist : public Command
+{
+ public:
+ CommandCSSetPersist(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ ChannelMode *cm = ModeManager::FindChannelModeByName(CMODE_PERM);
+
+ if (params[0] == "ON")
+ {
+ if (!ci->HasFlag(CI_PERSIST))
+ {
+ ci->SetFlag(CI_PERSIST);
+
+ /* Channel doesn't exist, create it internally */
+ if (!ci->c)
+ {
+ new Channel(ci->name);
+ if (ci->bi)
+ bot_join(ci);
+ }
+
+ /* No botserv bot, no channel mode */
+ if (!ci->bi && !cm)
+ {
+ /* Give them ChanServ
+ * Yes, this works fine with no Config.s_BotServ
+ */
+ ChanServ->Assign(NULL, ci);
+ }
+
+ /* Set the perm mode */
+ if (cm && ci->c && !ci->c->HasMode(CMODE_PERM))
+ {
+ ci->c->SetMode(NULL, cm);
+ }
+ }
+
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_ON, ci->name.c_str());
+ }
+ else if (params[0] == "OFF")
+ {
+ if (ci->HasFlag(CI_PERSIST))
+ {
+ ci->UnsetFlag(CI_PERSIST);
+
+ /* Unset perm mode */
+ if (cm && ci->c && ci->c->HasMode(CMODE_PERM))
+ ci->c->RemoveMode(NULL, cm);
+ if (Config.s_BotServ && ci->bi && ci->c->users.size() == Config.BSMinUsers - 1)
+ ircdproto->SendPart(ci->bi, ci->c, NULL);
+
+ /* No channel mode, no BotServ, but using ChanServ as the botserv bot
+ * which was assigned when persist was set on
+ */
+ if (!cm && !Config.s_BotServ && ci->bi)
+ {
+ /* Unassign bot */
+ ChanServ->UnAssign(NULL, ci);
+ }
+
+ if (ci->c && ci->c->users.empty())
+ delete ci->c;
+ }
+
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PERSIST_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "PERSIST");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET PERSIST", CHAN_SET_PERSIST_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PERSIST);
+ }
+};
+
+class CommandCSSASetPersist : public CommandCSSetPersist
+{
+ public:
+ CommandCSSASetPersist(const ci::string &cname) : CommandCSSetPersist(cname, "chanserv/saset/persist")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PERSIST, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET PERSIST", CHAN_SASET_PERSIST_SYNTAX);
+ }
+};
+
+class CSSetPersist : public Module
+{
+ public:
+ CSSetPersist(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetPersist("PERSIST"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetPersist("PERSIST"));
+ }
+
+ ~CSSetPersist()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("PERSIST");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("PERSIST");
+ }
+};
+
+MODULE_INIT(CSSetPersist)
diff --git a/src/core/cs_set_private.cpp b/src/core/cs_set_private.cpp
new file mode 100644
index 000000000..9f96828df
--- /dev/null
+++ b/src/core/cs_set_private.cpp
@@ -0,0 +1,112 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetPrivate : public Command
+{
+ public:
+ CommandCSSetPrivate(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_PRIVATE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_PRIVATE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_PRIVATE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "PRIVATE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET PRIVATE", CHAN_SET_PRIVATE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_PRIVATE);
+ }
+};
+
+class CommandCSSASetPrivate : public CommandCSSetPrivate
+{
+ public:
+ CommandCSSASetPrivate(const ci::string &cname) : CommandCSSetPrivate(cname, "chanserv/saset/private")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_PRIVATE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET PRIVATE", CHAN_SASET_PRIVATE_SYNTAX);
+ }
+};
+
+class CSSetPrivate : public Module
+{
+ public:
+ CSSetPrivate(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetPrivate("PRIVATE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetPrivate("PRIVATE"));
+ }
+
+ ~CSSetPrivate()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("PRIVATE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("PRIVATE");
+ }
+};
+
+MODULE_INIT(CSSetPrivate)
diff --git a/src/core/cs_set_restricted.cpp b/src/core/cs_set_restricted.cpp
new file mode 100644
index 000000000..7e0cc42b3
--- /dev/null
+++ b/src/core/cs_set_restricted.cpp
@@ -0,0 +1,116 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetRestricted : public Command
+{
+ public:
+ CommandCSSetRestricted(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_RESTRICTED);
+ if (ci->levels[CA_NOJOIN] < 0)
+ ci->levels[CA_NOJOIN] = 0;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_RESTRICTED);
+ if (ci->levels[CA_NOJOIN] >= 0)
+ ci->levels[CA_NOJOIN] = -2;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_RESTRICTED_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "RESTRICTED");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET RESTRICTED", CHAN_SET_RESTRICTED_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_RESTRICTED);
+ }
+};
+
+class CommandCSSASetRestricted : public CommandCSSetRestricted
+{
+ public:
+ CommandCSSASetRestricted(const ci::string &cname) : CommandCSSetRestricted(cname, "chanserv/saset/restricted")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_RESTRICTED, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET RESTRICTED", CHAN_SASET_RESTRICTED_SYNTAX);
+ }
+};
+
+class CSSetRestricted : public Module
+{
+ public:
+ CSSetRestricted(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetRestricted("RESTRICTED"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetRestricted("RESTRICTED"));
+ }
+
+ ~CSSetRestricted()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("RESTRICTED");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("RESTRICTED");
+ }
+};
+
+MODULE_INIT(CSSetRestricted)
diff --git a/src/core/cs_set_secure.cpp b/src/core/cs_set_secure.cpp
new file mode 100644
index 000000000..bdcffdb21
--- /dev/null
+++ b/src/core/cs_set_secure.cpp
@@ -0,0 +1,112 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSecure : public Command
+{
+ public:
+ CommandCSSetSecure(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SECURE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SECURE);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECURE_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SECURE");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SECURE", CHAN_SET_SECURE_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECURE);
+ }
+};
+
+class CommandCSSASetSecure : public CommandCSSetSecure
+{
+ public:
+ CommandCSSASetSecure(const ci::string &cname) : CommandCSSetSecure(cname, "chanserv/saset/secure")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECURE, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SECURE", CHAN_SASET_SECURE_SYNTAX);
+ }
+};
+
+class CSSetSecure : public Module
+{
+ public:
+ CSSetSecure(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSecure("SECURE"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetSecure("SECURE"));
+ }
+
+ ~CSSetSecure()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SECURE");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SECURE");
+ }
+};
+
+MODULE_INIT(CSSetSecure)
diff --git a/src/core/cs_set_securefounder.cpp b/src/core/cs_set_securefounder.cpp
new file mode 100644
index 000000000..9d4a99d20
--- /dev/null
+++ b/src/core/cs_set_securefounder.cpp
@@ -0,0 +1,118 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSecureFounder : public Command
+{
+ public:
+ CommandCSSetSecureFounder(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SECUREFOUNDER);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SECUREFOUNDER);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREFOUNDER_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SECUREFOUNDER");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SECUREFOUNDER", CHAN_SET_SECUREFOUNDER_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECUREFOUNDER);
+ }
+};
+
+class CommandCSSASetSecureFounder : public CommandCSSetSecureFounder
+{
+ public:
+ CommandCSSASetSecureFounder(const ci::string &cname) : CommandCSSetSecureFounder(cname, "chanserv/saset/securefounder")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREFOUNDER, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SECUREFOUNDER", CHAN_SASET_SECUREFOUNDER_SYNTAX);
+ }
+};
+
+class CSSetSecureFounder : public Module
+{
+ public:
+ CSSetSecureFounder(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSecureFounder("SECUREFOUNDER"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetSecureFounder("SECUREFOUNDER"));
+ }
+
+ ~CSSetSecureFounder()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SECUREFOUNDER");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SECUREFOUNDER");
+ }
+};
+
+MODULE_INIT(CSSetSecureFounder)
diff --git a/src/core/cs_set_secureops.cpp b/src/core/cs_set_secureops.cpp
new file mode 100644
index 000000000..dc510f71a
--- /dev/null
+++ b/src/core/cs_set_secureops.cpp
@@ -0,0 +1,112 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSecureOps : public Command
+{
+ public:
+ CommandCSSetSecureOps(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SECUREOPS);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SECUREOPS);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SECUREOPS_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SECUREOPS");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SECUREOPS", CHAN_SET_SECUREOPS_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SECUREOPS);
+ }
+};
+
+class CommandCSSASetSecureOps : public CommandCSSetSecureOps
+{
+ public:
+ CommandCSSASetSecureOps(const ci::string &cname) : CommandCSSetSecureOps(cname, "chanserv/saset/secureops")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SECUREOPS, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SECUREOPS", CHAN_SASET_SECUREOPS_SYNTAX);
+ }
+};
+
+class CSSetSecureOps : public Module
+{
+ public:
+ CSSetSecureOps(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSecureOps("SECUREOPS"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetSecureOps("SECUREOPS"));
+ }
+
+ ~CSSetSecureOps()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SECUREOPS");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SECUREOPS");
+ }
+};
+
+MODULE_INIT(CSSetSecureOps)
diff --git a/src/core/cs_set_signkick.cpp b/src/core/cs_set_signkick.cpp
new file mode 100644
index 000000000..2e24f8d38
--- /dev/null
+++ b/src/core/cs_set_signkick.cpp
@@ -0,0 +1,112 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSignKick : public Command
+{
+ public:
+ CommandCSSetSignKick(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_SIGNKICK);
+ ci->UnsetFlag(CI_SIGNKICK_LEVEL);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_ON, ci->name.c_str());
+ }
+ else if (params[1] == "LEVEL")
+ {
+ ci->SetFlag(CI_SIGNKICK_LEVEL);
+ ci->UnsetFlag(CI_SIGNKICK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_LEVEL, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_SIGNKICK);
+ ci->UnsetFlag(CI_SIGNKICK_LEVEL);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_SIGNKICK_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "SIGNKICK");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET SIGNKICK", CHAN_SET_SIGNKICK_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SIGNKICK);
+ }
+};
+
+class CommandCSSASetSignKick : public CommandCSSetSignKick
+{
+ public:
+ CommandCSSASetSignKick(const ci::string &cname) : CommandCSSetSignKick(cname, "chanserv/saset/signkick")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SIGNKICK, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET SIGNKICK", CHAN_SASET_SIGNKICK_SYNTAX);
+ }
+};
+
+class CSSetSignKick : public Module
+{
+ public:
+ CSSetSignKick(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSignKick("SIGNKICK"));
+ }
+
+ ~CSSetSignKick()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SIGNKICK");
+ }
+};
+
+MODULE_INIT(CSSetSignKick)
diff --git a/src/core/cs_set_successor.cpp b/src/core/cs_set_successor.cpp
new file mode 100644
index 000000000..3de30631a
--- /dev/null
+++ b/src/core/cs_set_successor.cpp
@@ -0,0 +1,145 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetSuccessor : public Command
+{
+ public:
+ CommandCSSetSuccessor(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (this->permission.empty() && ci->HasFlag(CI_SECUREFOUNDER) ? !IsFounder(u, ci) : !check_access(u, ci, CA_FOUNDER))
+ {
+ notice_lang(Config.s_ChanServ, u, ACCESS_DENIED);
+ return MOD_CONT;
+ }
+
+ NickCore *nc;
+
+ if (params.size() > 1)
+ {
+ NickAlias *na = findnick(params[1]);
+
+ if (!na)
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_NOT_REGISTERED, params[1].c_str());
+ return MOD_CONT;
+ }
+ if (na->HasFlag(NS_FORBIDDEN))
+ {
+ notice_lang(Config.s_ChanServ, u, NICK_X_FORBIDDEN, na->nick);
+ return MOD_CONT;
+ }
+ if (na->nc == ci->founder)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_IS_FOUNDER, na->nick, ci->name.c_str());
+ return MOD_CONT;
+ }
+ nc = na->nc;
+
+ }
+ else
+ nc = NULL;
+
+ Alog() << Config.s_ChanServ << ": Changing successor of " << ci->name << " from "
+ << (ci->successor ? ci->successor->display : "none")
+ << " to " << (nc ? nc->display : "none") << " by " << u->GetMask();
+
+ ci->successor = nc;
+
+ if (nc)
+ notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_CHANGED, ci->name.c_str(), nc->display);
+ else
+ notice_lang(Config.s_ChanServ, u, CHAN_SUCCESSOR_UNSET, ci->name.c_str());
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_SUCCESSOR);
+ }
+};
+
+class CommandCSSASetSuccessor : public CommandCSSetSuccessor
+{
+ public:
+ CommandCSSASetSuccessor(const ci::string &cname) : CommandCSSetSuccessor(cname, "chanserv/saset/successor")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_SUCCESSOR, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASEt", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetSuccessor : public Module
+{
+ public:
+ CSSetSuccessor(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSuccessor("SUCCESSOR"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetSuccessor("SUCCESSOR"));
+ }
+
+ ~CSSetSuccessor()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("SUCCESSOR");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("SUCCESSOR");
+ }
+};
+
+MODULE_INIT(CSSetSuccessor)
diff --git a/src/core/cs_set_topiclock.cpp b/src/core/cs_set_topiclock.cpp
new file mode 100644
index 000000000..14934f551
--- /dev/null
+++ b/src/core/cs_set_topiclock.cpp
@@ -0,0 +1,112 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetTopicLock : public Command
+{
+ public:
+ CommandCSSetTopicLock(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ ci->SetFlag(CI_TOPICLOCK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_TOPICLOCK);
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_TOPICLOCK_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "TOPICLOCK");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_TOPICLOCK_SYNTAX);;
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_TOPICLOCK);
+ }
+};
+
+class CommandCSSASetTopicLock : public CommandCSSetTopicLock
+{
+ public:
+ CommandCSSASetTopicLock(const ci::string &cname) : CommandCSSetTopicLock(cname, "chanserv/saset/topiclock")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_TOPICLOCK, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET", CHAN_SASET_TOPICLOCK_SYNTAX);
+ }
+};
+
+class CSSetTopicLock : public Module
+{
+ public:
+ CSSetTopicLock(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetTopicLock("TOPICLOCK"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetTopicLock("TOPICLOCK"));
+ }
+
+ ~CSSetTopicLock()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("TOPICLOCK");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("TOPICLOCK");
+ }
+};
+
+MODULE_INIT(CSSetTopicLock)
diff --git a/src/core/cs_set_url.cpp b/src/core/cs_set_url.cpp
new file mode 100644
index 000000000..06c49da4f
--- /dev/null
+++ b/src/core/cs_set_url.cpp
@@ -0,0 +1,114 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+class CommandCSSetURL : public Command
+{
+ public:
+ CommandCSSetURL(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 1, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (ci->url)
+ delete [] ci->url;
+ if (params.size() > 1)
+ {
+ ci->url = sstrdup(params[1].c_str());
+ notice_lang(Config.s_ChanServ, u, CHAN_URL_CHANGED, ci->name.c_str(), ci->url);
+ }
+ else
+ {
+ ci->url = NULL;
+ notice_lang(Config.s_ChanServ, u, CHAN_URL_UNSET, ci->name.c_str());
+ }
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SET", CHAN_SET_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_URL);
+ }
+};
+
+class CommandCSSASetURL : public CommandCSSetURL
+{
+ public:
+ CommandCSSASetURL(const ci::string &cname) : CommandCSSetURL(cname, "chanserv/saset/url")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_URL, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ // XXX
+ syntax_error(Config.s_ChanServ, u, "SASET URL", CHAN_SASET_SYNTAX);
+ }
+};
+
+class CSSetURL : public Module
+{
+ public:
+ CSSetURL(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetURL("URL"));
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->AddSubcommand(new CommandCSSASetURL("URL"));
+ }
+
+ ~CSSetURL()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("URL");
+
+ c = FindCommand(ChanServ, "SASET");
+ if (c)
+ c->DelSubcommand("URL");
+ }
+};
+
+MODULE_INIT(CSSetURL)
diff --git a/src/core/cs_set_xop.cpp b/src/core/cs_set_xop.cpp
new file mode 100644
index 000000000..398cf4c1b
--- /dev/null
+++ b/src/core/cs_set_xop.cpp
@@ -0,0 +1,144 @@
+/* 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.
+ *
+ * $Id$
+ *
+ */
+/*************************************************************************/
+
+#include "module.h"
+
+#define CHECKLEV(lev) ((ci->levels[(lev)] != ACCESS_INVALID) && (access->level >= ci->levels[(lev)]))
+
+class CommandCSSetXOP : public Command
+{
+ public:
+ CommandCSSetXOP(const ci::string &cname, const std::string &cpermission = "") : Command(cname, 2, 2, cpermission)
+ {
+ }
+
+ CommandReturn Execute(User *u, const std::vector<ci::string> &params)
+ {
+ if (!FindModule("cs_xop"))
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_XOP_NOT_AVAILABLE, "XOP");
+ return MOD_CONT;
+ }
+
+ ChannelInfo *ci = cs_findchan(params[0]);
+ assert(ci);
+
+ if (params[1] == "ON")
+ {
+ if (!ci->HasFlag(CI_XOP))
+ {
+ ChanAccess *access;
+
+ for (unsigned i = ci->GetAccessCount() - 1; 0 <= i; --i)
+ {
+ access = ci->GetAccess(i);
+
+ /* This will probably cause wrong levels to be set, but hey,
+ * it's better than losing it altogether.
+ */
+ if (access->level == ACCESS_QOP)
+ access->level = ACCESS_QOP;
+ else if (CHECKLEV(CA_AKICK) || CHECKLEV(CA_SET))
+ access->level = ACCESS_SOP;
+ else if (CHECKLEV(CA_AUTOOP) || CHECKLEV(CA_OPDEOP) || CHECKLEV(CA_OPDEOPME))
+ access->level = ACCESS_AOP;
+ else if (ModeManager::FindChannelModeByName(CMODE_HALFOP) && (CHECKLEV(CA_AUTOHALFOP) || CHECKLEV(CA_HALFOP)
+|| CHECKLEV(CA_HALFOPME)))
+ access->level = ACCESS_HOP;
+ else if (CHECKLEV(CA_AUTOVOICE) || CHECKLEV(CA_VOICE) || CHECKLEV(CA_VOICEME))
+ access->level = ACCESS_VOP;
+ else
+ ci->EraseAccess(i);
+ }
+
+ reset_levels(ci);
+ ci->SetFlag(CI_XOP);
+ }
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " enabled XOP for " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_ON, ci->name.c_str());
+ }
+ else if (params[1] == "OFF")
+ {
+ ci->UnsetFlag(CI_XOP);
+
+ Alog() << Config.s_ChanServ << ": " << u->GetMask() << " disabled XOP for " << ci->name;
+ notice_lang(Config.s_ChanServ, u, CHAN_SET_XOP_OFF, ci->name.c_str());
+ }
+ else
+ this->OnSyntaxError(u, "XOP");
+
+ return MOD_CONT;
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP, "SET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SET XOP", CHAN_SET_XOP_SYNTAX);
+ }
+
+ void OnServHelp(User *u)
+ {
+ notice_lang(Config.s_ChanServ, u, CHAN_HELP_CMD_SET_XOP);
+ }
+};
+
+class CommandCSSASetXOP : public CommandCSSetXOP
+{
+ public:
+ CommandCSSASetXOP(const ci::string &cname) : CommandCSSetXOP(cname, "chanserv/saset/xop")
+ {
+ }
+
+ bool OnHelp(User *u, const ci::string &)
+ {
+ notice_help(Config.s_ChanServ, u, CHAN_HELP_SET_XOP, "SASET");
+ return true;
+ }
+
+ void OnSyntaxError(User *u, const ci::string &)
+ {
+ syntax_error(Config.s_ChanServ, u, "SASET XOP", CHAN_SASET_XOP_SYNTAX);
+ }
+};
+
+class CSSetXOP : public Module
+{
+ public:
+ CSSetXOP(const std::string &modname, const std::string &creator) : Module(modname, creator)
+ {
+ this->SetAuthor("Anope");
+ this->SetVersion("$Id$");
+ this->SetType(CORE);
+
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->AddSubcommand(new CommandCSSetXOP("XOP"));
+ }
+
+ ~CSSetXOP()
+ {
+ Command *c = FindCommand(ChanServ, "SET");
+ if (c)
+ c->DelSubcommand("XOP");
+ }
+};
+
+MODULE_INIT(CSSetXOP)