summaryrefslogtreecommitdiff
path: root/modules/commands/cs_mode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/commands/cs_mode.cpp')
-rw-r--r--modules/commands/cs_mode.cpp1059
1 files changed, 0 insertions, 1059 deletions
diff --git a/modules/commands/cs_mode.cpp b/modules/commands/cs_mode.cpp
deleted file mode 100644
index 4f177a771..000000000
--- a/modules/commands/cs_mode.cpp
+++ /dev/null
@@ -1,1059 +0,0 @@
-/* ChanServ core functions
- *
- * (C) 2003-2017 Anope Team
- * Contact us at team@anope.org
- *
- * Please read COPYING and README for further details.
- *
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
- */
-
-#include "module.h"
-#include "modules/cs_mode.h"
-
-struct ModeLockImpl : ModeLock, Serializable
-{
- ModeLockImpl() : Serializable("ModeLock")
- {
- }
-
- ~ModeLockImpl()
- {
- ChannelInfo *chan = ChannelInfo::Find(ci);
- if (chan)
- {
- ModeLocks *ml = chan->GetExt<ModeLocks>("modelocks");
- if (ml)
- ml->RemoveMLock(this);
- }
- }
-
- void Serialize(Serialize::Data &data) const anope_override;
- static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
-};
-
-struct ModeLocksImpl : ModeLocks
-{
- Serialize::Reference<ChannelInfo> ci;
- Serialize::Checker<ModeList> mlocks;
-
- ModeLocksImpl(Extensible *obj) : ci(anope_dynamic_static_cast<ChannelInfo *>(obj)), mlocks("ModeLock")
- {
- }
-
- ~ModeLocksImpl()
- {
- ModeList modelist;
- mlocks->swap(modelist);
- for (ModeList::iterator it = modelist.begin(); it != modelist.end(); ++it)
- {
- ModeLock *ml = *it;
- delete ml;
- }
- }
-
- bool HasMLock(ChannelMode *mode, const Anope::string &param, bool status) const anope_override
- {
- if (!mode)
- return false;
-
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- const ModeLock *ml = *it;
-
- if (ml->name == mode->name && ml->set == status && ml->param == param)
- return true;
- }
-
- return false;
- }
-
- bool SetMLock(ChannelMode *mode, bool status, const Anope::string &param, Anope::string setter, time_t created = Anope::CurTime) anope_override
- {
- if (!mode)
- return false;
-
- RemoveMLock(mode, status, param);
-
- if (setter.empty())
- setter = ci->GetFounder() ? ci->GetFounder()->display : "Unknown";
-
- ModeLock *ml = new ModeLockImpl();
- ml->ci = ci->name;
- ml->set = status;
- ml->name = mode->name;
- ml->param = param;
- ml->setter = setter;
- ml->created = created;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnMLock, MOD_RESULT, (this->ci, ml));
- if (MOD_RESULT == EVENT_STOP)
- {
- delete ml;
- return false;
- }
-
- this->mlocks->push_back(ml);
- return true;
- }
-
- bool RemoveMLock(ChannelMode *mode, bool status, const Anope::string &param = "") anope_override
- {
- if (!mode)
- return false;
-
- for (ModeList::iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
-
- if (m->name == mode->name)
- {
- // For list or status modes, we must check the parameter
- if (mode->type == MODE_LIST || mode->type == MODE_STATUS)
- if (m->param != param)
- continue;
-
- EventReturn MOD_RESULT;
- FOREACH_RESULT(OnUnMLock, MOD_RESULT, (this->ci, m));
- if (MOD_RESULT == EVENT_STOP)
- break;
-
- delete m;
- return true;
- }
- }
-
- return false;
- }
-
- void RemoveMLock(ModeLock *mlock) anope_override
- {
- ModeList::iterator it = std::find(this->mlocks->begin(), this->mlocks->end(), mlock);
- if (it != this->mlocks->end())
- this->mlocks->erase(it);
- }
-
- void ClearMLock() anope_override
- {
- ModeList ml;
- this->mlocks->swap(ml);
- for (unsigned i = 0; i < ml.size(); ++i)
- delete ml[i];
- }
-
- const ModeList &GetMLock() const anope_override
- {
- return this->mlocks;
- }
-
- std::list<ModeLock *> GetModeLockList(const Anope::string &name) anope_override
- {
- std::list<ModeLock *> mlist;
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
- if (m->name == name)
- mlist.push_back(m);
- }
- return mlist;
- }
-
- const ModeLock *GetMLock(const Anope::string &mname, const Anope::string &param = "") anope_override
- {
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- ModeLock *m = *it;
-
- if (m->name == mname && m->param == param)
- return m;
- }
-
- return NULL;
- }
-
- Anope::string GetMLockAsString(bool complete) const anope_override
- {
- Anope::string pos = "+", neg = "-", params;
-
- for (ModeList::const_iterator it = this->mlocks->begin(); it != this->mlocks->end(); ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
-
- if (!cm || cm->type == MODE_LIST || cm->type == MODE_STATUS)
- continue;
-
- if (ml->set)
- pos += cm->mchar;
- else
- neg += cm->mchar;
-
- if (complete && ml->set && !ml->param.empty() && cm->type == MODE_PARAM)
- params += " " + ml->param;
- }
-
- if (pos.length() == 1)
- pos.clear();
- if (neg.length() == 1)
- neg.clear();
-
- return pos + neg + params;
- }
-
- void Check() anope_override
- {
- if (this->mlocks->empty())
- ci->Shrink<ModeLocks>("modelocks");
- }
-};
-
-void ModeLockImpl::Serialize(Serialize::Data &data) const
-{
- data["ci"] << this->ci;
- data["set"] << this->set;
- data["name"] << this->name;
- data["param"] << this->param;
- data["setter"] << this->setter;
- data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created;
-}
-
-Serializable* ModeLockImpl::Unserialize(Serializable *obj, Serialize::Data &data)
-{
- Anope::string sci;
-
- data["ci"] >> sci;
-
- ChannelInfo *ci = ChannelInfo::Find(sci);
- if (!ci)
- return NULL;
-
- ModeLockImpl *ml;
- if (obj)
- ml = anope_dynamic_static_cast<ModeLockImpl *>(obj);
- else
- {
- ml = new ModeLockImpl();
- ml->ci = ci->name;
- }
-
- data["set"] >> ml->set;
- data["created"] >> ml->created;
- data["setter"] >> ml->setter;
- data["name"] >> ml->name;
- data["param"] >> ml->param;
-
- if (!obj)
- ci->Require<ModeLocksImpl>("modelocks")->mlocks->push_back(ml);
-
- return ml;
-}
-
-class CommandCSMode : public Command
-{
- bool CanSet(CommandSource &source, ChannelInfo *ci, ChannelMode *cm, bool self)
- {
- if (!ci || !cm || cm->type != MODE_STATUS)
- return false;
-
- return source.AccessFor(ci).HasPriv(cm->name + (self ? "ME" : ""));
- }
-
- void DoLock(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- User *u = source.GetUser();
- const Anope::string &subcommand = params[2];
- const Anope::string &param = params.size() > 3 ? params[3] : "";
-
- bool override = !source.AccessFor(ci).HasPriv("MODE");
- ModeLocks *modelocks = ci->Require<ModeLocks>("modelocks");
-
- if (Anope::ReadOnly && !subcommand.equals_ci("LIST"))
- {
- source.Reply(READ_ONLY_MODE);
- return;
- }
-
- if ((subcommand.equals_ci("ADD") || subcommand.equals_ci("SET")) && !param.empty())
- {
- /* If setting, remove the existing locks */
- if (subcommand.equals_ci("SET"))
- {
- const ModeLocks::ModeList mlocks = modelocks->GetMLock();
- for (ModeLocks::ModeList::const_iterator it = mlocks.begin(); it != mlocks.end(); ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (cm && cm->CanSet(source.GetUser()))
- modelocks->RemoveMLock(cm, ml->set, ml->param);
- }
- }
-
- spacesepstream sep(param);
- Anope::string modes;
-
- sep.GetToken(modes);
-
- Anope::string pos = "+", neg = "-", pos_params, neg_params;
-
- int adding = 1;
- bool needreply = true;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- default:
- needreply = false;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm)
- {
- source.Reply(_("Unknown mode character %c ignored."), modes[i]);
- break;
- }
- else if (u && !cm->CanSet(u))
- {
- source.Reply(_("You may not (un)lock mode %c."), modes[i]);
- break;
- }
-
- Anope::string mode_param;
- if (((cm->type == MODE_STATUS || cm->type == MODE_LIST) && !sep.GetToken(mode_param)) || (cm->type == MODE_PARAM && adding && !sep.GetToken(mode_param)))
- {
- source.Reply(_("Missing parameter for mode %c."), cm->mchar);
- continue;
- }
-
- if (cm->type == MODE_STATUS && !CanSet(source, ci, cm, false))
- {
- source.Reply(ACCESS_DENIED);
- continue;
- }
-
- if (cm->type == MODE_LIST && ci->c && IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) >= IRCD->GetMaxListFor(ci->c))
- {
- source.Reply(_("List for mode %c is full."), cm->mchar);
- continue;
- }
-
- if (modelocks->GetMLock().size() >= Config->GetModule(this->owner)->Get<unsigned>("max", "32"))
- {
- source.Reply(_("The mode lock list of \002%s\002 is full."), ci->name.c_str());
- continue;
- }
-
- modelocks->SetMLock(cm, adding, mode_param, source.GetNick());
-
- if (adding)
- {
- pos += cm->mchar;
- if (!mode_param.empty())
- pos_params += " " + mode_param;
- }
- else
- {
- neg += cm->mchar;
- if (!mode_param.empty())
- neg_params += " " + mode_param;
- }
- }
- }
-
- if (pos == "+")
- pos.clear();
- if (neg == "-")
- neg.clear();
- Anope::string reply = pos + neg + pos_params + neg_params;
-
- if (!reply.empty())
- {
- source.Reply(_("%s locked on %s."), reply.c_str(), ci->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to lock " << reply;
- }
- else if (needreply)
- source.Reply(_("Nothing to do."));
-
- if (ci->c)
- ci->c->CheckModes();
- }
- else if (subcommand.equals_ci("DEL") && !param.empty())
- {
- spacesepstream sep(param);
- Anope::string modes;
-
- sep.GetToken(modes);
-
- int adding = 1;
- bool needreply = true;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- default:
- needreply = false;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm)
- {
- source.Reply(_("Unknown mode character %c ignored."), modes[i]);
- break;
- }
- else if (u && !cm->CanSet(u))
- {
- source.Reply(_("You may not (un)lock mode %c."), modes[i]);
- break;
- }
-
- Anope::string mode_param;
- if (cm->type != MODE_REGULAR && !sep.GetToken(mode_param))
- source.Reply(_("Missing parameter for mode %c."), cm->mchar);
- else
- {
- if (modelocks->RemoveMLock(cm, adding, mode_param))
- {
- if (!mode_param.empty())
- mode_param = " " + mode_param;
- source.Reply(_("%c%c%s has been unlocked from %s."), adding == 1 ? '+' : '-', cm->mchar, mode_param.c_str(), ci->name.c_str());
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to unlock " << (adding ? '+' : '-') << cm->mchar << mode_param;
- }
- else
- source.Reply(_("%c%c is not locked on %s."), adding == 1 ? '+' : '-', cm->mchar, ci->name.c_str());
- }
- }
- }
-
- if (needreply)
- source.Reply(_("Nothing to do."));
- }
- else if (subcommand.equals_ci("LIST"))
- {
- const ModeLocks::ModeList mlocks = modelocks->GetMLock();
- if (mlocks.empty())
- {
- source.Reply(_("Channel %s has no mode locks."), ci->name.c_str());
- }
- else
- {
- ListFormatter list(source.GetAccount());
- list.AddColumn(_("Mode")).AddColumn(_("Param")).AddColumn(_("Creator")).AddColumn(_("Created"));
-
- for (ModeLocks::ModeList::const_iterator it = mlocks.begin(), it_end = mlocks.end(); it != it_end; ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (!cm)
- continue;
-
- ListFormatter::ListEntry entry;
- entry["Mode"] = Anope::printf("%c%c", ml->set ? '+' : '-', cm->mchar);
- entry["Param"] = ml->param;
- entry["Creator"] = ml->setter;
- entry["Created"] = Anope::strftime(ml->created, NULL, true);
- list.AddEntry(entry);
- }
-
- source.Reply(_("Mode locks for %s:"), ci->name.c_str());
-
- std::vector<Anope::string> replies;
- list.Process(replies);
-
- for (unsigned i = 0; i < replies.size(); ++i)
- source.Reply(replies[i]);
- }
- }
- else
- this->OnSyntaxError(source, subcommand);
- }
-
- void DoSet(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- User *u = source.GetUser();
-
- bool has_access = source.AccessFor(ci).HasPriv("MODE") || source.HasPriv("chanserv/administration");
- bool can_override = source.HasPriv("chanserv/administration");
-
- spacesepstream sep(params.size() > 3 ? params[3] : "");
- Anope::string modes = params[2], param;
-
- bool override = !source.AccessFor(ci).HasPriv("MODE") && source.HasPriv("chanserv/administration");
-
- int adding = -1;
- for (size_t i = 0; i < modes.length(); ++i)
- {
- switch (modes[i])
- {
- case '+':
- adding = 1;
- break;
- case '-':
- adding = 0;
- break;
- case '*':
- if (adding == -1 || !has_access)
- break;
- for (unsigned j = 0; j < ModeManager::GetChannelModes().size() && ci->c; ++j)
- {
- ChannelMode *cm = ModeManager::GetChannelModes()[j];
-
- if (!u || cm->CanSet(u) || can_override)
- {
- if (cm->type == MODE_REGULAR || (!adding && cm->type == MODE_PARAM))
- {
- if (adding)
- ci->c->SetMode(NULL, cm);
- else
- ci->c->RemoveMode(NULL, cm);
- }
- }
- }
- break;
- default:
- if (adding == -1)
- break;
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
- if (!cm || (u && !cm->CanSet(u) && !can_override))
- continue;
- switch (cm->type)
- {
- case MODE_REGULAR:
- if (!has_access)
- break;
- if (adding)
- ci->c->SetMode(NULL, cm);
- else
- ci->c->RemoveMode(NULL, cm);
- break;
- case MODE_PARAM:
- if (!has_access)
- break;
- if (adding && !sep.GetToken(param))
- break;
- if (adding)
- ci->c->SetMode(NULL, cm, param);
- else
- ci->c->RemoveMode(NULL, cm);
- break;
- case MODE_STATUS:
- {
- if (!sep.GetToken(param))
- param = source.GetNick();
-
- AccessGroup u_access = source.AccessFor(ci);
-
- if (param.find_first_of("*?") != Anope::string::npos)
- {
- if (!this->CanSet(source, ci, cm, false))
- {
- if (can_override)
- {
- override = true;
- }
- else
- {
- source.Reply(_("You do not have access to set mode %c."), cm->mchar);
- break;
- }
- }
-
- for (Channel::ChanUserList::const_iterator it = ci->c->users.begin(), it_end = ci->c->users.end(); it != it_end;)
- {
- ChanUserContainer *uc = it->second;
- ++it;
-
- AccessGroup targ_access = ci->AccessFor(uc->user);
-
- if (uc->user->IsProtected())
- {
- source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
- continue;
- }
-
- if (ci->HasExt("PEACE") && targ_access >= u_access)
- {
- if (can_override)
- {
- override = true;
- }
- else
- {
- source.Reply(_("You do not have the access to change %s's modes."), uc->user->nick.c_str());
- continue;
- }
- }
-
- if (Anope::Match(uc->user->GetMask(), param))
- {
- if (adding)
- ci->c->SetMode(NULL, cm, uc->user->GetUID());
- else
- ci->c->RemoveMode(NULL, cm, uc->user->GetUID());
- }
- }
- }
- else
- {
- User *target = User::Find(param, true);
- if (target == NULL)
- {
- source.Reply(NICK_X_NOT_IN_USE, param.c_str());
- break;
- }
-
- if (!this->CanSet(source, ci, cm, source.GetUser() == target))
- {
- if (can_override)
- {
- override = true;
- }
- else
- {
- source.Reply(_("You do not have access to set mode %c."), cm->mchar);
- break;
- }
- }
-
- if (source.GetUser() != target)
- {
- AccessGroup targ_access = ci->AccessFor(target);
- if (ci->HasExt("PEACE") && targ_access >= u_access)
- {
- source.Reply(_("You do not have the access to change %s's modes."), target->nick.c_str());
- break;
- }
- else if (can_override)
- {
- override = true;
- }
- else if (target->IsProtected())
- {
- source.Reply(ACCESS_DENIED);
- break;
- }
- }
-
- if (adding)
- ci->c->SetMode(NULL, cm, target->GetUID());
- else
- ci->c->RemoveMode(NULL, cm, target->GetUID());
- }
- break;
- }
- case MODE_LIST:
- if (!has_access)
- break;
- if (!sep.GetToken(param))
- break;
- if (adding)
- {
- if (IRCD->GetMaxListFor(ci->c) && ci->c->HasMode(cm->name) < IRCD->GetMaxListFor(ci->c))
- ci->c->SetMode(NULL, cm, param);
- }
- else
- {
- std::vector<Anope::string> v = ci->c->GetModeList(cm->name);
- for (unsigned j = 0; j < v.size(); ++j)
- if (Anope::Match(v[j], param))
- ci->c->RemoveMode(NULL, cm, v[j]);
- }
- }
- }
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to set " << params[2] << (params.size() > 3 ? " " + params[3] : "");
- }
- }
-
- void DoClear(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
- {
- const Anope::string &param = params.size() > 2 ? params[2] : "";
-
- if (param.empty())
- {
- std::vector<Anope::string> new_params;
- new_params.push_back(params[0]);
- new_params.push_back("SET");
- new_params.push_back("-*");
- this->DoSet(source, ci, new_params);
- return;
- }
-
- ChannelMode *cm;
- if (param.length() == 1)
- cm = ModeManager::FindChannelModeByChar(param[0]);
- else
- {
- cm = ModeManager::FindChannelModeByName(param.upper());
- if (!cm)
- cm = ModeManager::FindChannelModeByName(param.substr(0, param.length() - 1).upper());
- }
-
- if (!cm)
- {
- source.Reply(_("There is no such mode %s."), param.c_str());
- return;
- }
-
- if (cm->type != MODE_STATUS && cm->type != MODE_LIST)
- {
- source.Reply(_("Mode %s is not a status or list mode."), param.c_str());
- return;
- }
-
- std::vector<Anope::string> new_params;
- new_params.push_back(params[0]);
- new_params.push_back("SET");
- new_params.push_back("-" + stringify(cm->mchar));
- new_params.push_back("*");
- this->DoSet(source, ci, new_params);
- }
-
- public:
- CommandCSMode(Module *creator) : Command(creator, "chanserv/mode", 2, 4)
- {
- this->SetDesc(_("Control modes and mode locks on a channel"));
- this->SetSyntax(_("\037channel\037 LOCK {ADD|DEL|SET|LIST} [\037what\037]"));
- this->SetSyntax(_("\037channel\037 SET \037modes\037"));
- this->SetSyntax(_("\037channel\037 CLEAR [\037what\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- const Anope::string &subcommand = params[1];
-
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (!ci)
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- else if (subcommand.equals_ci("LOCK") && params.size() > 2)
- {
- if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- this->DoLock(source, ci, params);
- }
- else if (!ci->c)
- source.Reply(CHAN_X_NOT_IN_USE, params[0].c_str());
- else if (subcommand.equals_ci("SET") && params.size() > 2)
- this->DoSet(source, ci, params);
- else if (subcommand.equals_ci("CLEAR"))
- {
- if (!source.AccessFor(ci).HasPriv("MODE") && !source.HasPriv("chanserv/administration"))
- source.Reply(ACCESS_DENIED);
- else
- this->DoClear(source, ci, params);
- }
- else
- this->OnSyntaxError(source, "");
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- this->SendSyntax(source);
- source.Reply(" ");
- source.Reply(_("Mainly controls mode locks and mode access (which is different from channel access)\n"
- "on a channel.\n"
- " \n"
- "The \002%s LOCK\002 command allows you to add, delete, and view mode locks on a channel.\n"
- "If a mode is locked on or off, services will not allow that mode to be changed. The \002SET\002\n"
- "command will clear all existing mode locks and set the new one given, while \002ADD\002 and \002DEL\002\n"
- "modify the existing mode lock.\n"
- "Example:\n"
- " \002MODE #channel LOCK ADD +bmnt *!*@*aol*\002\n"
- " \n"
- "The \002%s SET\002 command allows you to set modes through services. Wildcards * and ? may\n"
- "be given as parameters for list and status modes.\n"
- "Example:\n"
- " \002MODE #channel SET +v *\002\n"
- " Sets voice status to all users in the channel.\n"
- " \n"
- " \002MODE #channel SET -b ~c:*\n"
- " Clears all extended bans that start with ~c:\n"
- " \n"
- "The \002%s CLEAR\002 command is an easy way to clear modes on a channel. \037what\037 may be\n"
- "any mode name. Examples include bans, excepts, inviteoverrides, ops, halfops, and voices. If \037what\037\n"
- "is not given then all basic modes are removed."),
- source.command.upper().c_str(), source.command.upper().c_str(), source.command.upper().c_str());
- return true;
- }
-};
-
-static Anope::map<std::pair<bool, Anope::string> > modes;
-
-class CommandCSModes : public Command
-{
- public:
- CommandCSModes(Module *creator) : Command(creator, "chanserv/modes", 1, 2)
- {
- this->SetSyntax(_("\037channel\037 [\037user\037]"));
- }
-
- void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
- {
- User *u = source.GetUser(),
- *targ = params.size() > 1 ? User::Find(params[1], true) : u;
- ChannelInfo *ci = ChannelInfo::Find(params[0]);
-
- if (!targ)
- {
- if (params.size() > 1)
- source.Reply(NICK_X_NOT_IN_USE, params[1].c_str());
- return;
- }
-
- if (!ci)
- {
- source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
- return;
- }
- else if (!ci->c)
- {
- source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
- return;
- }
-
- AccessGroup u_access = source.AccessFor(ci), targ_access = ci->AccessFor(targ);
- const std::pair<bool, Anope::string> &m = modes[source.command];
-
- bool can_override = source.HasPriv("chanserv/administration");
- bool override = false;
-
- if (m.second.empty())
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
-
- if (u == targ ? !u_access.HasPriv(m.second + "ME") : !u_access.HasPriv(m.second))
- {
- if (!can_override)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (!override && !m.first && u != targ && (targ->IsProtected() || (ci->HasExt("PEACE") && targ_access >= u_access)))
- {
- if (!can_override)
- {
- source.Reply(ACCESS_DENIED);
- return;
- }
- else
- override = true;
- }
-
- if (!ci->c->FindUser(targ))
- {
- source.Reply(NICK_X_NOT_ON_CHAN, targ->nick.c_str(), ci->name.c_str());
- return;
- }
-
- if (m.first)
- ci->c->SetMode(NULL, m.second, targ->GetUID());
- else
- ci->c->RemoveMode(NULL, m.second, targ->GetUID());
-
- Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "on " << targ->nick;
- }
-
- const Anope::string GetDesc(CommandSource &source) const anope_override
- {
- const std::pair<bool, Anope::string> &m = modes[source.command];
- if (!m.second.empty())
- {
- if (m.first)
- return Anope::printf(Language::Translate(source.GetAccount(), _("Gives you or the specified nick %s status on a channel")), m.second.c_str());
- else
- return Anope::printf(Language::Translate(source.GetAccount(), _("Removes %s status from you or the specified nick on a channel")), m.second.c_str());
- }
- else
- return "";
- }
-
- bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
- {
- const std::pair<bool, Anope::string> &m = modes[source.command];
- if (m.second.empty())
- return false;
-
- this->SendSyntax(source);
- source.Reply(" ");
- if (m.first)
- source.Reply(_("Gives %s status to the selected nick on a channel. If \037nick\037 is\n"
- "not given, it will %s you."),
- m.second.upper().c_str(), m.second.lower().c_str());
- else
- source.Reply(_("Removes %s status from the selected nick on a channel. If \037nick\037 is\n"
- "not given, it will de%s you."),
- m.second.upper().c_str(), m.second.lower().c_str());
- source.Reply(" ");
- source.Reply(_("You must have the %s(ME) privilege on the channel to use this command."), m.second.upper().c_str());
-
- return true;
- }
-};
-
-class CSMode : public Module
-{
- CommandCSMode commandcsmode;
- CommandCSModes commandcsmodes;
- ExtensibleItem<ModeLocksImpl> modelocks;
- Serialize::Type modelocks_type;
-
- public:
- CSMode(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
- commandcsmode(this), commandcsmodes(this),
- modelocks(this, "modelocks"),
- modelocks_type("ModeLock", ModeLockImpl::Unserialize)
- {
-
- }
-
- void OnReload(Configuration::Conf *conf) anope_override
- {
- modes.clear();
-
- for (int i = 0; i < conf->CountBlock("command"); ++i)
- {
- Configuration::Block *block = conf->GetBlock("command", i);
-
- const Anope::string &cname = block->Get<const Anope::string>("name"),
- &cmd = block->Get<const Anope::string>("command");
-
- if (cname.empty() || cmd != "chanserv/modes")
- continue;
-
- const Anope::string &set = block->Get<const Anope::string>("set"),
- &unset = block->Get<const Anope::string>("unset");
-
- if (set.empty() && unset.empty())
- continue;
-
- modes[cname] = std::make_pair(!set.empty(), !set.empty() ? set : unset);
- }
- }
-
- void OnCheckModes(Reference<Channel> &c) anope_override
- {
- if (!c || !c->ci)
- return;
-
- ModeLocks *locks = modelocks.Get(c->ci);
- if (locks)
- for (ModeLocks::ModeList::const_iterator it = locks->GetMLock().begin(), it_end = locks->GetMLock().end(); it != it_end; ++it)
- {
- const ModeLock *ml = *it;
- ChannelMode *cm = ModeManager::FindChannelModeByName(ml->name);
- if (!cm)
- continue;
-
- if (cm->type == MODE_REGULAR)
- {
- if (!c->HasMode(cm->name) && ml->set)
- c->SetMode(NULL, cm, "", false);
- else if (c->HasMode(cm->name) && !ml->set)
- c->RemoveMode(NULL, cm, "", false);
- }
- else if (cm->type == MODE_PARAM)
- {
- /* If the channel doesn't have the mode, or it does and it isn't set correctly */
- if (ml->set)
- {
- Anope::string param;
- c->GetParam(cm->name, param);
-
- if (!c->HasMode(cm->name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param)))
- c->SetMode(NULL, cm, ml->param, false);
- }
- else
- {
- if (c->HasMode(cm->name))
- c->RemoveMode(NULL, cm, "", false);
- }
-
- }
- else if (cm->type == MODE_LIST || cm->type == MODE_STATUS)
- {
- if (ml->set)
- c->SetMode(NULL, cm, ml->param, false);
- else
- c->RemoveMode(NULL, cm, ml->param, false);
- }
- }
- }
-
- void OnChanRegistered(ChannelInfo *ci) anope_override
- {
- ModeLocks *ml = modelocks.Require(ci);
- Anope::string mlock;
- spacesepstream sep(Config->GetModule(this)->Get<const Anope::string>("mlock", "+nt"));
- if (sep.GetToken(mlock))
- {
- bool add = true;
- for (unsigned i = 0; i < mlock.length(); ++i)
- {
- if (mlock[i] == '+')
- {
- add = true;
- continue;
- }
-
- if (mlock[i] == '-')
- {
- add = false;
- continue;
- }
-
- ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock[i]);
- if (!cm)
- continue;
-
- Anope::string param;
- if (cm->type == MODE_PARAM)
- {
- ChannelModeParam *cmp = anope_dynamic_static_cast<ChannelModeParam *>(cm);
- if (add || !cmp->minus_no_arg)
- {
- sep.GetToken(param);
- if (param.empty() || !cmp->IsValid(param))
- continue;
- }
- }
- else if (cm->type != MODE_REGULAR)
- {
- sep.GetToken(param);
- if (param.empty())
- continue;
- }
-
- ml->SetMLock(cm, add, param);
- }
- }
- ml->Check();
- }
-
- void OnChanInfo(CommandSource &source, ChannelInfo *ci, InfoFormatter &info, bool show_hidden) anope_override
- {
- if (!show_hidden)
- return;
-
- ModeLocks *ml = modelocks.Get(ci);
- if (ml)
- info[_("Mode lock")] = ml->GetMLockAsString(true);
- }
-};
-
-MODULE_INIT(CSMode)