summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/modes.h11
-rw-r--r--src/channels.c63
-rw-r--r--src/core/db_plain.cpp3
-rw-r--r--src/modes.cpp51
-rw-r--r--src/modules/mysql/db_mysql.h1
-rw-r--r--src/protocol/inspircd12.cpp2
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 &param, 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 &param, 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 &param,
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));