summaryrefslogtreecommitdiff
path: root/src/modes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modes.cpp')
-rw-r--r--src/modes.cpp322
1 files changed, 168 insertions, 154 deletions
diff --git a/src/modes.cpp b/src/modes.cpp
index 0eee41682..9481f570e 100644
--- a/src/modes.cpp
+++ b/src/modes.cpp
@@ -22,43 +22,65 @@ std::map<Channel *, StackerInfo *> ModeManager::ChannelStackerObjects;
std::vector<ChannelMode *> ModeManager::ChannelModes;
std::vector<UserMode *> ModeManager::UserModes;
+static std::map<Anope::string, ChannelMode *> ChannelModesByName;
+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;
-/* Default channel mode lock */
-std::list<std::pair<Anope::string, Anope::string> > ModeManager::ModeLockOn;
-std::list<Anope::string> ModeManager::ModeLockOff;
+ChannelStatus::ChannelStatus()
+{
+}
-/* Default modes bots have on channels */
-ChannelStatus ModeManager::DefaultBotModes;
+ChannelStatus::ChannelStatus(const Anope::string &m) : modes(m)
+{
+}
-Anope::string ChannelStatus::BuildCharPrefixList() const
+void ChannelStatus::AddMode(char c)
{
- Anope::string ret;
+ if (modes.find(c) == Anope::string::npos)
+ modes.append(c);
+}
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
+void ChannelStatus::DelMode(char c)
+{
+ modes = modes.replace_all_cs(c, "");
+}
- if (this->modes.count(cm->name))
- ret += cm->mchar;
- }
+bool ChannelStatus::HasMode(char c) const
+{
+ return modes.find(c) != Anope::string::npos;
+}
- return ret;
+bool ChannelStatus::Empty() const
+{
+ return modes.empty();
+}
+
+void ChannelStatus::Clear()
+{
+ modes.clear();
+}
+
+const Anope::string &ChannelStatus::Modes() const
+{
+ return modes;
}
Anope::string ChannelStatus::BuildModePrefixList() const
{
Anope::string ret;
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
+ for (size_t i = 0; i < modes.length(); ++i)
{
- ChannelMode *cm = ModeManager::ChannelModes[i];
-
- if (this->modes.count(cm->name))
+ ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
+ if (cm != NULL && cm->type == MODE_STATUS)
{
ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
- ret += cms->Symbol;
+ ret += cms->symbol;
}
}
@@ -96,9 +118,9 @@ ChannelMode::~ChannelMode()
bool ChannelMode::CanSet(User *u) const
{
- if (Config->NoMLock.find(this->mchar) != Anope::string::npos || Config->CSRequire.find(this->mchar) != Anope::string::npos)
- return false;
- return true;
+ EventReturn MOD_RESULT;
+ FOREACH_RESULT(I_OnCanSet, OnCanSet(u, this));
+ return MOD_RESULT == EVENT_ALLOW;
}
ChannelModeList::ChannelModeList(const Anope::string &cm, char mch) : ChannelMode(cm, mch)
@@ -119,7 +141,7 @@ ChannelModeParam::~ChannelModeParam()
{
}
-ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char mSymbol, short mlevel) : ChannelMode(mname, modeChar), Symbol(mSymbol), level(mlevel)
+ChannelModeStatus::ChannelModeStatus(const Anope::string &mname, char modeChar, char msymbol, short mlevel) : ChannelMode(mname, modeChar), symbol(msymbol), level(mlevel)
{
this->type = MODE_STATUS;
}
@@ -296,7 +318,12 @@ bool ModeManager::AddUserMode(UserMode *um)
Log() << "ModeManager: Added generic support for user mode " << um->mchar;
}
- ModeManager::UserModes.push_back(um);
+ unsigned want = um->mchar;
+ if (want >= ModeManager::UserModes.size())
+ ModeManager::UserModes.resize(want + 1);
+ ModeManager::UserModes[want] = um;
+
+ UserModesByName[um->name] = um;
FOREACH_MOD(I_OnUserModeAdd, OnUserModeAdd(um));
@@ -314,10 +341,23 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
Log() << "ModeManager: Added generic support for channel mode " << cm->mchar;
}
- ModeManager::ChannelModes.push_back(cm);
+ unsigned want = cm->mchar;
+ if (want >= ModeManager::ChannelModes.size())
+ ModeManager::ChannelModes.resize(want + 1);
+ ModeManager::ChannelModes[want] = cm;
- /* Apply this mode to the new default mlock if its used */
- UpdateDefaultMLock(Config);
+ if (cm->type == MODE_STATUS)
+ {
+ ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
+ want = cms->symbol;
+ if (want >= ModeManager::ChannelModes.size())
+ ModeManager::ChannelModes.resize(want + 1);
+ ModeManager::ChannelModes[want] = cms;
+
+ RebuildStatusModes();
+ }
+
+ ChannelModesByName[cm->name] = cm;
FOREACH_MOD(I_OnChannelModeAdd, OnChannelModeAdd(cm));
@@ -326,97 +366,139 @@ bool ModeManager::AddChannelMode(ChannelMode *cm)
void ModeManager::RemoveUserMode(UserMode *um)
{
- for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
- {
- UserMode *mode = ModeManager::UserModes[i];
- if (um == mode)
- {
- ModeManager::UserModes.erase(ModeManager::UserModes.begin() + i);
- break;
- }
- }
+ if (!um)
+ return;
+
+ unsigned want = um->mchar;
+ if (want >= ModeManager::UserModes.size())
+ return;
+
+ if (ModeManager::UserModes[want] != um)
+ return;
+
+ ModeManager::UserModes[want] = NULL;
+
+ UserModesByName.erase(um->name);
StackerDel(um);
}
void ModeManager::RemoveChannelMode(ChannelMode *cm)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
+ if (!cm)
+ return;
+
+ unsigned want = cm->mchar;
+ if (want >= ModeManager::ChannelModes.size())
+ return;
+
+ if (ModeManager::ChannelModes[want] != cm)
+ return;
+
+ ModeManager::ChannelModes[want] = NULL;
+
+ if (cm->type == MODE_STATUS)
{
- ChannelMode *mode = ModeManager::ChannelModes[i];
- if (cm == mode)
- {
- ModeManager::ChannelModes.erase(ModeManager::ChannelModes.begin() + i);
- break;
- }
+ ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
+ want = cms->symbol;
+
+ if (want >= ModeManager::ChannelModes.size())
+ return;
+
+ if (ModeManager::ChannelModes[want] != cm)
+ return;
+
+ ModeManager::ChannelModes[want] = NULL;
+
+ RebuildStatusModes();
}
+ ChannelModesByName.erase(cm->name);
+
StackerDel(cm);
}
-ChannelMode *ModeManager::FindChannelModeByChar(char Mode)
+ChannelMode *ModeManager::FindChannelModeByChar(char mode)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm->mchar == Mode)
- return cm;
- }
+ unsigned want = mode;
+ if (want >= ModeManager::ChannelModes.size())
+ return NULL;
+
+ return ModeManager::ChannelModes[want];
+}
- return NULL;
+UserMode *ModeManager::FindUserModeByChar(char mode)
+{
+ unsigned want = mode;
+ if (want >= ModeManager::UserModes.size())
+ return NULL;
+
+ return ModeManager::UserModes[want];
}
-UserMode *ModeManager::FindUserModeByChar(char Mode)
+ChannelMode *ModeManager::FindChannelModeByName(const Anope::string &name)
{
- for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
- {
- UserMode *um = ModeManager::UserModes[i];
- if (um->mchar == Mode)
- return um;
- }
+ std::map<Anope::string, ChannelMode *>::iterator it = ChannelModesByName.find(name);
+ if (it != ChannelModesByName.end())
+ return it->second;
+ return NULL;
+}
+UserMode *ModeManager::FindUserModeByName(const Anope::string &name)
+{
+ std::map<Anope::string, UserMode *>::iterator it = UserModesByName.find(name);
+ if (it != UserModesByName.end())
+ return it->second;
return NULL;
}
-ChannelMode *ModeManager::FindChannelModeByName(const Anope::string &name)
+char ModeManager::GetStatusChar(char value)
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
- {
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm->name == name)
- return cm;
- }
+ unsigned want = value;
+ if (want >= ModeManager::ChannelModes.size())
+ return 0;
+
+ ChannelMode *cm = ModeManager::ChannelModes[want];
+ if (cm == NULL || cm->type != MODE_STATUS)
+ return 0;
+
+ return cm->mchar;
+}
- return NULL;
+const std::vector<ChannelMode *> &ModeManager::GetChannelModes()
+{
+ return ChannelModes;
}
-UserMode *ModeManager::FindUserModeByName(const Anope::string &name)
+const std::vector<UserMode *> &ModeManager::GetUserModes()
{
- for (unsigned i = 0; i < ModeManager::UserModes.size(); ++i)
- {
- UserMode *um = ModeManager::UserModes[i];
- if (um->name == name)
- return um;
- }
+ return UserModes;
+}
- return NULL;
+const std::vector<ChannelModeStatus *> &ModeManager::GetStatusChannelModesByRank()
+{
+ return ChannelModesByStatus;
}
-char ModeManager::GetStatusChar(char Value)
+static struct StatusSort
{
- for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
+ bool operator()(ChannelModeStatus *cm1, ChannelModeStatus *cm2) const
{
- ChannelMode *cm = ModeManager::ChannelModes[i];
- if (cm->type == MODE_STATUS)
- {
- ChannelModeStatus *cms = anope_dynamic_static_cast<ChannelModeStatus *>(cm);
-
- if (Value == cms->Symbol)
- return cms->mchar;
- }
+ return cm1->level > cm2->level;
}
+} statuscmp;
+
+void ModeManager::RebuildStatusModes()
+{
+ ChannelModesByStatus.clear();
+ for (unsigned j = 0; j < ModeManager::GetChannelModes().size(); ++j)
+ {
+ ChannelMode *cm = ModeManager::GetChannelModes()[j];
- return 0;
+ if (cm && cm->type == MODE_STATUS && std::find(ChannelModesByStatus.begin(), ChannelModesByStatus.end(), cm) == ChannelModesByStatus.end())
+ ChannelModesByStatus.push_back(anope_dynamic_static_cast<ChannelModeStatus *>(cm));
+ }
+ std::sort(ChannelModesByStatus.begin(), ChannelModesByStatus.end(), statuscmp);
}
void ModeManager::StackerAdd(const BotInfo *bi, Channel *c, ChannelMode *cm, bool Set, const Anope::string &Param)
@@ -537,74 +619,6 @@ void ModeManager::StackerDel(Mode *m)
}
}
-void ModeManager::UpdateDefaultMLock(ServerConfig *config)
-{
- ModeLockOn.clear();
- ModeLockOff.clear();
-
- Anope::string modes;
- spacesepstream sep(config->MLock);
- sep.GetToken(modes);
-
- int adding = -1;
- for (unsigned i = 0, end_mode = modes.length(); i < end_mode; ++i)
- {
- if (modes[i] == '+')
- adding = 1;
- else if (modes[i] == '-')
- adding = 0;
- else if (adding != -1)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(modes[i]);
-
- if (cm && cm->type != MODE_STATUS)
- {
- Anope::string param;
- if (adding == 1 && cm->type != MODE_REGULAR && !sep.GetToken(param)) // MODE_LIST OR MODE_PARAM
- {
- Log() << "Warning: Got default mlock mode " << cm->mchar << " with no param?";
- continue;
- }
-
- if (cm->type != MODE_LIST) // Only MODE_LIST can have duplicates
- {
- for (std::list<std::pair<Anope::string, Anope::string> >::iterator it = ModeLockOn.begin(), it_end = ModeLockOn.end(); it != it_end; ++it)
- if (it->first == cm->name)
- {
- ModeLockOn.erase(it);
- break;
- }
-
- for (std::list<Anope::string>::iterator it = ModeLockOff.begin(), it_end = ModeLockOff.end(); it != it_end; ++it)
- if (*it == cm->name)
- {
- ModeLockOff.erase(it);
- break;
- }
- }
-
- if (adding)
- ModeLockOn.push_back(std::make_pair(cm->name, param));
- else
- ModeLockOff.push_back(cm->name);
- }
- }
- }
-
- /* Set Bot Modes */
- DefaultBotModes.modes.clear();
- for (unsigned i = 0; i < config->BotModes.length(); ++i)
- {
- ChannelMode *cm = ModeManager::FindChannelModeByChar(config->BotModes[i]);
-
- if (cm && cm->type == MODE_STATUS)
- DefaultBotModes.modes.insert(cm->name);
- else
- /* We don't know the mode yet so just use the mode char */
- DefaultBotModes.modes.insert(config->BotModes[i]);
- }
-}
-
Entry::Entry(const Anope::string &m, const Anope::string &fh) : name(m), mask(fh), cidr_len(0)
{
Anope::string n, u, h;
@@ -689,7 +703,7 @@ const Anope::string Entry::GetMask() const
return this->mask;
}
-bool Entry::Matches(const User *u, bool full) const
+bool Entry::Matches(User *u, bool full) const
{
/* First check if this mode has defined any matches (usually for extbans). */
if (IRCD->IsExtbanValid(this->mask))