diff options
Diffstat (limited to 'src/modes.cpp')
-rw-r--r-- | src/modes.cpp | 322 |
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)) |