summaryrefslogtreecommitdiff
path: root/src/modes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modes.cpp')
-rw-r--r--src/modes.cpp178
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 &param)
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 &param)
{
bool is_param = mode->type == MODE_PARAM;
@@ -313,7 +304,7 @@ void StackerInfo::AddMode(Mode *mode, bool set, const Anope::string &param)
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;
}