diff options
Diffstat (limited to 'src/modes.cpp')
-rw-r--r-- | src/modes.cpp | 178 |
1 files changed, 104 insertions, 74 deletions
diff --git a/src/modes.cpp b/src/modes.cpp index b559e7026..274cb2713 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -1,9 +1,21 @@ -/* Mode support +/* + * Anope IRC Services * - * (C) 2008-2011 Adam <Adam@anope.org> - * (C) 2008-2017 Anope Team <team@anope.org> + * Copyright (C) 2008-2011 Adam <Adam@anope.org> + * Copyright (C) 2008-2017 Anope Team <team@anope.org> * - * Please read COPYING and README for further details. + * This file is part of Anope. Anope is free software; you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software + * Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ #include "services.h" @@ -13,6 +25,8 @@ #include "protocol.h" #include "channels.h" #include "uplink.h" +#include "event.h" +#include "modules/chanserv.h" struct StackerInfo; @@ -36,9 +50,6 @@ static std::map<Anope::string, UserMode *> UserModesByName; /* Sorted by status */ static std::vector<ChannelModeStatus *> ChannelModesByStatus; -/* Number of generic modes we support */ -unsigned ModeManager::GenericChannelModes = 0, ModeManager::GenericUserModes = 0; - struct StackerInfo { /* Modes to be added */ @@ -46,9 +57,7 @@ struct StackerInfo /* Modes to be deleted */ std::list<std::pair<Mode *, Anope::string> > DelModes; /* Bot this is sent from */ - BotInfo *bi; - - StackerInfo() : bi(NULL) { } + User *bi = nullptr; /** Add a mode to this object * @param mode The mode @@ -124,6 +133,12 @@ Mode::~Mode() bool Mode::CanSet(User *u) const { + if (!setable) + return false; + + if (oper_only) + return u && u->HasMode("OPER"); + return true; } @@ -142,8 +157,7 @@ ChannelMode::ChannelMode(const Anope::string &cm, char mch) : Mode(cm, MC_CHANNE bool ChannelMode::CanSet(User *u) const { - EventReturn MOD_RESULT; - FOREACH_RESULT(OnCanSet, MOD_RESULT, (u, this)); + EventReturn MOD_RESULT = EventManager::Get()->Dispatch(&Event::CanSet::OnCanSet, u, this); return MOD_RESULT != EVENT_STOP; } @@ -186,6 +200,11 @@ ChannelModeParam::ChannelModeParam(const Anope::string &cm, char mch, bool ma) : this->type = MODE_PARAM; } +bool ChannelModeParam::IsValid(Anope::string &value) const +{ + return std::regex_search(value.str(), param_validation); +} + ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char msymbol, short mlevel) : ChannelMode(mname, modeChar), symbol(msymbol), level(mlevel) { this->type = MODE_STATUS; @@ -231,34 +250,6 @@ ChannelMode *ChannelModeVirtual<T>::Wrap(Anope::string ¶m) template class ChannelModeVirtual<ChannelMode>; template class ChannelModeVirtual<ChannelModeList>; -bool UserModeOperOnly::CanSet(User *u) const -{ - return u && u->HasMode("OPER"); -} - -bool UserModeNoone::CanSet(User *u) const -{ - return false; -} - -bool ChannelModeKey::IsValid(Anope::string &value) const -{ - if (!value.empty() && value.find(':') == Anope::string::npos && value.find(',') == Anope::string::npos) - return true; - - return false; -} - -bool ChannelModeOperOnly::CanSet(User *u) const -{ - return u && u->HasMode("OPER"); -} - -bool ChannelModeNoone::CanSet(User *u) const -{ - return false; -} - void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string ¶m) { bool is_param = mode->type == MODE_PARAM; @@ -313,7 +304,7 @@ void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string ¶m) static class ModePipe : public Pipe { public: - void OnNotify() + void OnNotify() override { ModeManager::ProcessModes(); } @@ -395,15 +386,10 @@ bool ModeManager::AddUserMode(UserMode *um) { if (ModeManager::FindUserModeByChar(um->mchar) != NULL) return false; + if (ModeManager::FindUserModeByName(um->name) != NULL) return false; - if (um->name.empty()) - { - um->name = stringify(++GenericUserModes); - Log() << "ModeManager: Added generic support for user mode " << um->mchar; - } - unsigned want = um->mchar; if (want >= UserModesIdx.size()) UserModesIdx.resize(want + 1); @@ -413,7 +399,7 @@ bool ModeManager::AddUserMode(UserMode *um) UserModes.push_back(um); - FOREACH_MOD(OnUserModeAdd, (um)); + EventManager::Get()->Dispatch(&Event::UserModeAdd::OnUserModeAdd, um); return true; } @@ -425,12 +411,6 @@ bool ModeManager::AddChannelMode(ChannelMode *cm) if (ModeManager::FindChannelModeByName(cm->name) != NULL) return false; - if (cm->name.empty()) - { - cm->name = stringify(++GenericChannelModes); - Log() << "ModeManager: Added generic support for channel mode " << cm->mchar; - } - if (cm->mchar) { unsigned want = cm->mchar; @@ -454,7 +434,7 @@ bool ModeManager::AddChannelMode(ChannelMode *cm) ChannelModes.push_back(cm); - FOREACH_MOD(OnChannelModeAdd, (cm)); + EventManager::Get()->Dispatch(&Event::ChannelModeAdd::OnChannelModeAdd, cm); for (unsigned int i = 0; i < ChannelModes.size(); ++i) ChannelModes[i]->Check(); @@ -570,7 +550,7 @@ char ModeManager::GetStatusChar(char value) ChannelMode *cm = ChannelModesIdx[want]; if (cm == NULL || cm->type != MODE_STATUS || cm->mchar == value) return 0; - + return cm->mchar; } @@ -610,13 +590,13 @@ void ModeManager::RebuildStatusModes() std::sort(ChannelModesByStatus.begin(), ChannelModesByStatus.end(), statuscmp); } -void ModeManager::StackerAdd(BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param) +void ModeManager::StackerAdd(User *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param) { StackerInfo *s = GetInfo(ChannelStackerObjects, c); s->AddMode(cm, Set, Param); if (bi) s->bi = bi; - else + else if (c->ci) s->bi = c->ci->WhoSends(); if (!modePipe) @@ -624,7 +604,7 @@ void ModeManager::StackerAdd(BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, modePipe->Notify(); } -void ModeManager::StackerAdd(BotInfo *bi, User *u, UserMode *um, bool Set, const Anope::string &Param) +void ModeManager::StackerAdd(User *bi, User *u, UserMode *um, bool Set, const Anope::string &Param) { StackerInfo *s = GetInfo(UserStackerObjects, u); s->AddMode(um, Set, Param); @@ -647,7 +627,7 @@ void ModeManager::ProcessModes() std::list<Anope::string> ModeStrings = BuildModeStrings(s); for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit) - IRCD->SendMode(s->bi, u, lit->c_str()); + IRCD->SendMode(s->bi, u, *lit); delete it->second; } UserStackerObjects.clear(); @@ -662,7 +642,7 @@ void ModeManager::ProcessModes() std::list<Anope::string> ModeStrings = BuildModeStrings(s); for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit) - IRCD->SendMode(s->bi, c, lit->c_str()); + IRCD->SendMode(s->bi, c, *lit); delete it->second; } ChannelStackerObjects.clear(); @@ -678,7 +658,7 @@ static void StackerDel(std::map<T *, StackerInfo *> &map, T *obj) StackerInfo *si = it->second; std::list<Anope::string> ModeStrings = BuildModeStrings(si); for (std::list<Anope::string>::iterator lit = ModeStrings.begin(), lit_end = ModeStrings.end(); lit != lit_end; ++lit) - IRCD->SendMode(si->bi, obj, lit->c_str()); + IRCD->SendMode(si->bi, obj, *lit); delete si; map.erase(it); @@ -742,7 +722,59 @@ void ModeManager::StackerDel(Mode *m) } } -Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0), family(0) +void ModeManager::Apply(Configuration::Conf *old) +{ +#warning "remove old modes" + + for (Configuration::Channelmode &cm : Config->Channelmodes) + { + ChannelMode *mode; + + if (cm.list) + Anope::Logger.Log("Creating channelmode list {0} ({1})", cm.name, cm.character); + else if (cm.status) + Anope::Logger.Log("Creating channelmode status {0} ({1})", cm.name, cm.character); + else if (cm.param) + Anope::Logger.Log("Creating channelmode param {0} ({1})", cm.name, cm.character); + else + Anope::Logger.Log("Creating channelmode {0} ({1})", cm.name, cm.character); + + if (cm.list) + mode = new ChannelModeList(cm.name, cm.character); + else if (cm.status) + mode = new ChannelModeStatus(cm.name, cm.character, cm.status, cm.level); + else if (cm.param) + mode = new ChannelModeParam(cm.name, cm.character, !cm.param_unset); + else + mode = new ChannelMode(cm.name, cm.character); + + mode->SetSetable(cm.setable); + mode->SetOperOnly(cm.oper_only); + + if (!AddChannelMode(mode)) + delete mode; + } + + for (Configuration::Usermode &um : Config->Usermodes) + { + UserMode *mode; + + Anope::Logger.Log("Creating usermode {0} ({1})", um.name, um.character); + + if (um.param) + mode = new UserModeParam(um.name, um.character); + else + mode = new UserMode(um.name, um.character); + + mode->SetSetable(um.setable); + mode->SetOperOnly(um.oper_only); + + if (!AddUserMode(mode)) + delete mode; + } +} + +Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0) { Anope::string n, u, h; @@ -769,21 +801,21 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh else this->nick = fh; } - + at = this->host.find('#'); if (at != Anope::string::npos) { this->real = this->host.substr(at + 1); this->host = this->host.substr(0, at); } - + /* If the mask is all *'s it will match anything, so just clear it */ if (this->nick.find_first_not_of("*") == Anope::string::npos) this->nick.clear(); - + if (this->user.find_first_not_of("*") == Anope::string::npos) this->user.clear(); - + if (this->host.find_first_not_of("*") == Anope::string::npos) this->host.clear(); else @@ -803,12 +835,10 @@ Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh { this->cidr_len = convertTo<unsigned short>(cidr_range); - /* If we got here, cidr_len is a valid number. */ - this->host = cidr_ip; this->family = addr.family(); - Log(LOG_DEBUG) << "Ban " << mask << " has cidr " << this->cidr_len; + Anope::Logger.Log("Ban {0} has cidr {1}", mask, this->cidr_len); } } catch (const ConvertException &) { } @@ -831,6 +861,7 @@ const Anope::string Entry::GetNUHMask() const h = host.empty() ? "*" : host, r = real.empty() ? "" : "#" + real, c; + switch (family) { case AF_INET: @@ -842,8 +873,7 @@ const Anope::string Entry::GetNUHMask() const c = "/" + stringify(cidr_len); break; } - - return n + "!" + u + "@" + h + c + r; + return n + "!" + u + "@" + h + r + c; } bool Entry::Matches(User *u, bool full) const @@ -888,10 +918,10 @@ bool Entry::Matches(User *u, bool full) const else if (!this->host.empty() && !Anope::Match(u->GetDisplayedHost(), this->host) && !Anope::Match(u->GetCloakedHost(), this->host) && (!full || (!Anope::Match(u->host, this->host) && !Anope::Match(u->ip.addr(), this->host)))) ret = false; - + if (!this->real.empty() && !Anope::Match(u->realname, this->real)) ret = false; - + return ret; } |