diff options
-rw-r--r-- | include/modes.h | 11 | ||||
-rw-r--r-- | src/channels.c | 63 | ||||
-rw-r--r-- | src/core/db_plain.cpp | 3 | ||||
-rw-r--r-- | src/modes.cpp | 51 | ||||
-rw-r--r-- | src/modules/mysql/db_mysql.h | 1 | ||||
-rw-r--r-- | src/protocol/inspircd12.cpp | 2 |
6 files changed, 78 insertions, 53 deletions
diff --git a/include/modes.h b/include/modes.h index 9eac4043b..777087d49 100644 --- a/include/modes.h +++ b/include/modes.h @@ -36,7 +36,7 @@ enum ChannelModeName CMODE_PRIVATE, CMODE_REGISTERED, CMODE_SECRET, CMODE_TOPIC, CMODE_AUDITORIUM, CMODE_SSL, CMODE_ADMINONLY, CMODE_NOCTCP, CMODE_FILTER, CMODE_NOKNOCK, CMODE_REDIRECT, CMODE_REGMODERATED, CMODE_NONICK, CMODE_OPERONLY, CMODE_NOKICK, CMODE_REGISTEREDONLY, CMODE_STRIPCOLOR, CMODE_NONOTICE, CMODE_NOINVITE, CMODE_ALLINVITE, - CMODE_BLOCKCAPS, CMODE_PERM, CMODE_NICKFLOOD, CMODE_JOINFLOOD, CMODE_DELAYEDJOIN, + CMODE_BLOCKCAPS, CMODE_PERM, CMODE_NICKFLOOD, CMODE_JOINFLOOD, CMODE_DELAYEDJOIN, CMODE_NOREJOIN, /* b/e/I */ CMODE_BAN, CMODE_EXCEPT, @@ -82,12 +82,15 @@ class CoreExport Mode ModeClass Class; /* Mode char for this */ char ModeChar; + /* Type of mode this is */ + ModeType Type; /** Default constructor * @param mClass The type of mode this is * @param modeChar The mode char + * @param type The mode type */ - Mode(ModeClass mClass, char modeChar); + Mode(ModeClass mClass, char modeChar, ModeType type); /** Default destructor */ @@ -102,8 +105,6 @@ class CoreExport UserMode : public Mode /* Mode name */ UserModeName Name; - /* Mode type, regular or param */ - ModeType Type; /** Default constructor * @param nName The mode name @@ -140,8 +141,6 @@ class CoreExport ChannelMode : public Mode /* Mode name */ ChannelModeName Name; - /* Type of mode this is */ - ModeType Type; /** Default constructor * @param mName The mode name diff --git a/src/channels.c b/src/channels.c index 5ea729d44..e5c1fac32 100644 --- a/src/channels.c +++ b/src/channels.c @@ -390,17 +390,9 @@ void Channel::SetModeInternal(ChannelMode *cm, const std::string ¶m, bool En /* Remove the mode */ if (cm->Type == MODE_PARAM) { - ChannelModeParam *cmp = dynamic_cast<ChannelModeParam *>(cmp); - - if (!cmp->MinusNoArg) - { - /* Get the current param set on the channel and send it with the mode */ - std::string cparam; - if (GetParam(cmp->Name, cparam)) - RemoveMode(NULL, cm, cparam); - } - else - RemoveMode(NULL, cm); + std::string cparam; + GetParam(cm->Name, cparam); + RemoveMode(NULL, cm, cparam); } else if (cm->Type == MODE_REGULAR) RemoveMode(NULL, cm); @@ -556,15 +548,29 @@ void Channel::SetMode(BotInfo *bi, ChannelMode *cm, const std::string ¶m, bo if (!cm) return; /* Don't set modes already set */ - if ((cm->Type == MODE_REGULAR || cm->Type == MODE_PARAM) && HasMode(cm->Name)) + if (cm->Type == MODE_REGULAR && HasMode(cm->Name)) return; - + else if (cm->Type == MODE_PARAM && HasMode(cm->Name)) + { + std::string cparam; + if (GetParam(cm->Name, cparam)) + { + if (cparam == param) + { + return; + } + } + } else if (cm->Type == MODE_STATUS) { User *u = finduser(param); if (u && HasUserStatus(u, dynamic_cast<ChannelModeStatus *>(cm))) return; } + else if (cm->Type == MODE_LIST) + { + // XXX this needs rewritten + } ModeManager::StackerAdd(bi, this, cm, true, param); SetModeInternal(cm, param, EnforceMLock); @@ -614,9 +620,22 @@ void Channel::RemoveMode(BotInfo *bi, ChannelMode *cm, const std::string ¶m, if (u && !HasUserStatus(u, dynamic_cast<ChannelModeStatus *>(cm))) return; } + else if (cm->Type == MODE_LIST) + { + // XXX this needs to be rewritten sometime + } + + /* If this mode needs no param when being unset, empty the param */ + bool SendParam = true; + if (cm->Type == MODE_PARAM) + { + ChannelModeParam *cmp = dynamic_cast<ChannelModeParam *>(cm); + if (cmp->MinusNoArg) + SendParam = false; + } ModeManager::StackerAdd(bi, this, cm, false, param); - RemoveModeInternal(cm, param, EnforceMLock); + RemoveModeInternal(cm, SendParam ? param : "", EnforceMLock); } /** @@ -686,7 +705,6 @@ const bool Channel::HasParam(ChannelModeName Name) void Channel::ClearModes(BotInfo *bi) { ChannelMode *cm; - ChannelModeParam *cmp; for (size_t n = CMODE_BEGIN + 1; n != CMODE_END; ++n) { @@ -700,18 +718,9 @@ void Channel::ClearModes(BotInfo *bi) } else if (cm->Type == MODE_PARAM) { - cmp = dynamic_cast<ChannelModeParam *>(cm); - - if (!cmp->MinusNoArg) - { - std::string buf; - if (this->GetParam(cmp->Name, buf)) - this->RemoveMode(NULL, cm, buf); - } - else - { - this->RemoveMode(NULL, cm); - } + std::string param; + this->GetParam(cm->Name, param); + this->RemoveMode(NULL, cm, param); } } } diff --git a/src/core/db_plain.cpp b/src/core/db_plain.cpp index fb73d2860..ca10a3a03 100644 --- a/src/core/db_plain.cpp +++ b/src/core/db_plain.cpp @@ -272,6 +272,7 @@ ChannelModeInfo ChannelModes[] = { {"PERM", CMODE_PERM}, {"NICKFLOOD", CMODE_NICKFLOOD}, {"JOINFLOOD", CMODE_JOINFLOOD}, + {"CMODE_NOREJOIN", CMODE_NOREJOIN}, {"", static_cast<ChannelModeName>(-1)} }; @@ -1041,7 +1042,7 @@ class DBPlain : public Module std::string Param; for (j = 0; ChannelModes[j].Value != -1; ++j) if (ci->GetParam(ChannelModes[j].Value, Param)) - db << "MD MLP " << ChannelModes[j].Name << " " << Param; + db << "MD MLP " << ChannelModes[j].Name << " " << Param << endl; if (!ci->memos.memos.empty()) { MemoInfo *memos = &ci->memos; diff --git a/src/modes.cpp b/src/modes.cpp index 64a3fc349..5d20c8b7e 100644 --- a/src/modes.cpp +++ b/src/modes.cpp @@ -101,8 +101,9 @@ void SetDefaultMLock() /** Default constructor * @param mClass The type of mode this is * @param modeChar The mode char + * @param modeType The mode type */ -Mode::Mode(ModeClass mClass, char modeChar) : Class(mClass), ModeChar(modeChar) +Mode::Mode(ModeClass mClass, char modeChar, ModeType modeType) : Class(mClass), ModeChar(modeChar), Type(modeType) { } @@ -116,7 +117,7 @@ Mode::~Mode() * @param mName The mode name * @param modeChar The mode char */ -UserMode::UserMode(UserModeName mName, char modeChar) : Mode(MC_USER, modeChar), Name(mName), Type(MODE_REGULAR) +UserMode::UserMode(UserModeName mName, char modeChar) : Mode(MC_USER, modeChar, MODE_REGULAR), Name(mName) { } @@ -139,7 +140,7 @@ UserModeParam::UserModeParam(UserModeName mName, char modeChar) : UserMode(mName * @param mName The mode name * @param modeChar The mode char */ -ChannelMode::ChannelMode(ChannelModeName mName, char modeChar) : Mode(MC_CHANNEL, modeChar), Name(mName), Type(MODE_REGULAR) +ChannelMode::ChannelMode(ChannelModeName mName, char modeChar) : Mode(MC_CHANNEL, modeChar, MODE_REGULAR), Name(mName) { } @@ -410,11 +411,24 @@ void StackerInfo::AddMode(void *Mode, bool Set, const std::string &Param) UserMode *um = NULL; std::list<std::pair<void *, std::string> > *list, *otherlist; std::list<std::pair<void *, std::string > >::iterator it; + bool IsParam = false; if (Type == ST_CHANNEL) + { cm = static_cast<ChannelMode *>(Mode); + if (cm->Type == MODE_PARAM) + { + IsParam = true; + } + } else if (Type == ST_USER) + { um = static_cast<UserMode *>(Mode); + if (um->Type == MODE_PARAM) + { + IsParam = true; + } + } if (Set) { list = &AddModes; @@ -426,26 +440,27 @@ void StackerInfo::AddMode(void *Mode, bool Set, const std::string &Param) otherlist = &AddModes; } - /* Note that this whole thing works fine with status and list modes, because those have parameters - * which make them unique. - */ - it = std::find(list->begin(), list->end(), std::make_pair(Mode, Param)); - if (it != list->end()) + /* Loop through the list and find if this mode is already on here */ + for (it = list->begin(); it != list->end(); ++it) { - /* It can't be on the list twice */ - list->erase(it); - /* Note that we remove the mode and not return here because the new mode trying - * to be set may have a different parameter than the one already in the stacker, - * this new mode gets added to the list soon. + /* The param must match too (can have multiple status or list modes), but + * if it is a param mode it can match no matter what the param is */ + if (it->first == Mode && (it->second == Param || IsParam)) + { + list->erase(it); + /* It can only be on this list once */ + break; + } } - /* Not possible for a mode to be on both lists at once */ - else + /* If the mode is on the other list, remove it from there (eg, we dont want +o-o Adam Adam) */ + for (it = otherlist->begin(); it != otherlist->end(); ++it) { - it = std::find(otherlist->begin(), otherlist->end(), std::make_pair(Mode, Param)); - if (it != otherlist->end()) + /* The param must match too (can have multiple status or list modes), but + * if it is a param mode it can match no matter what the param is + */ + if (it->first == Mode && (it->second == Param || IsParam)) { - /* Remove it from the other list now were doing the opposite */ otherlist->erase(it); return; /* Note that we return here because this is like setting + and - on the same mode within the same diff --git a/src/modules/mysql/db_mysql.h b/src/modules/mysql/db_mysql.h index 322eff2e4..3c7d2b351 100644 --- a/src/modules/mysql/db_mysql.h +++ b/src/modules/mysql/db_mysql.h @@ -77,6 +77,7 @@ ChannelModeInfo ChannelModes[] = { {"PERM", CMODE_PERM}, {"NICKFLOOD", CMODE_NICKFLOOD}, {"JOINFLOOD", CMODE_JOINFLOOD}, + {"CMODE_NOREJOIN", CMODE_NOREJOIN}, {"", static_cast<ChannelModeName>(-1)} }; diff --git a/src/protocol/inspircd12.cpp b/src/protocol/inspircd12.cpp index 9252c17e7..a87367c48 100644 --- a/src/protocol/inspircd12.cpp +++ b/src/protocol/inspircd12.cpp @@ -1040,7 +1040,7 @@ int anope_event_capab(const char *source, int ac, const char **av) ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NICKFLOOD, 'F', true)); continue; case 'J': - ModeManager::AddChannelMode(new ChannelModeParam(CMODE_JOINFLOOD, 'J', true)); + ModeManager::AddChannelMode(new ChannelModeParam(CMODE_NOREJOIN, 'J', true)); continue; case 'L': ModeManager::AddChannelMode(new ChannelModeParam(CMODE_REDIRECT, true)); |