summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mode.h42
-rw-r--r--src/mode.cpp45
-rw-r--r--src/users.cpp6
3 files changed, 41 insertions, 52 deletions
diff --git a/include/mode.h b/include/mode.h
index fc6684a6f..b2e06257f 100644
--- a/include/mode.h
+++ b/include/mode.h
@@ -432,6 +432,20 @@ class CoreExport ModeParser
*/
ModeAction TryMode(User* user, User* targu, Channel* targc, bool adding, unsigned char mode, std::string &param, bool SkipACL);
+ /** Returns a list of user or channel mode characters.
+ * Used for constructing the parts of the mode list in the 004 numeric.
+ * @param mt Controls whether to list user modes or channel modes
+ * @param needparam Return modes only if they require a parameter to be set
+ * @return The available mode letters that satisfy the given conditions
+ */
+ std::string CreateModeList(ModeType mt, bool needparam = false);
+
+ /** Recreate the cached mode list that is displayed in the 004 numeric
+ * in Cached004ModeList.
+ * Called when a mode handler is added or removed.
+ */
+ void RecreateModeListFor004Numeric();
+
/** The string representing the last set of modes to be parsed.
* Use GetLastParse() to get this value, to be used for display purposes.
*/
@@ -443,6 +457,10 @@ class CoreExport ModeParser
unsigned int seq;
+ /** Cached mode list for use in 004 numeric
+ */
+ std::string Cached004ModeList;
+
public:
ModeParser();
~ModeParser();
@@ -527,20 +545,13 @@ class CoreExport ModeParser
*/
ModeHandler* FindPrefix(unsigned const char pfxletter);
- /** Returns a list of mode characters which are usermodes.
- * This is used in the 004 numeric when users connect.
+ /** Returns a list of modes, space seperated by type:
+ * 1. User modes
+ * 2. Channel modes
+ * 3. Channel modes that require a parameter when set
+ * This is sent to users as the last part of the 004 numeric
*/
- std::string UserModeList();
-
- /** Returns a list of channel mode characters which are listmodes.
- * This is used in the 004 numeric when users connect.
- */
- std::string ChannelModeList();
-
- /** Returns a list of channel mode characters which take parameters.
- * This is used in the 004 numeric when users connect.
- */
- std::string ParaModeList();
+ const std::string& GetModeListFor004Numeric();
/** Generates a list of modes, comma seperated by type:
* 1; Listmodes EXCEPT those with a prefix
@@ -555,3 +566,8 @@ class CoreExport ModeParser
*/
std::string BuildPrefixes(bool lettersAndModes = true);
};
+
+inline const std::string& ModeParser::GetModeListFor004Numeric()
+{
+ return Cached004ModeList;
+}
diff --git a/src/mode.cpp b/src/mode.cpp
index 3da983627..b4bb72c42 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -613,6 +613,7 @@ bool ModeParser::AddMode(ModeHandler* mh)
return false;
modehandlers[pos] = mh;
+ RecreateModeListFor004Numeric();
return true;
}
@@ -655,6 +656,7 @@ bool ModeParser::DelMode(ModeHandler* mh)
}
modehandlers[pos] = NULL;
+ RecreateModeListFor004Numeric();
return true;
}
@@ -673,52 +675,25 @@ ModeHandler* ModeParser::FindMode(unsigned const char modeletter, ModeType mt)
return modehandlers[pos];
}
-std::string ModeParser::UserModeList()
+std::string ModeParser::CreateModeList(ModeType mt, bool needparam)
{
- char modestr[256];
- int pointer = 0;
+ std::string modestr;
+ unsigned char mask = ((mt == MODETYPE_CHANNEL) ? MASK_CHANNEL : MASK_USER);
for (unsigned char mode = 'A'; mode <= 'z'; mode++)
{
- unsigned char pos = (mode-65) | MASK_USER;
+ unsigned char pos = (mode-65) | mask;
- if (modehandlers[pos])
- modestr[pointer++] = mode;
+ if ((modehandlers[pos]) && ((!needparam) || (modehandlers[pos]->GetNumParams(true))))
+ modestr.push_back(mode);
}
- modestr[pointer++] = 0;
- return modestr;
-}
-
-std::string ModeParser::ChannelModeList()
-{
- char modestr[256];
- int pointer = 0;
-
- for (unsigned char mode = 'A'; mode <= 'z'; mode++)
- {
- unsigned char pos = (mode-65) | MASK_CHANNEL;
- if (modehandlers[pos])
- modestr[pointer++] = mode;
- }
- modestr[pointer++] = 0;
return modestr;
}
-std::string ModeParser::ParaModeList()
+void ModeParser::RecreateModeListFor004Numeric()
{
- char modestr[256];
- int pointer = 0;
-
- for (unsigned char mode = 'A'; mode <= 'z'; mode++)
- {
- unsigned char pos = (mode-65) | MASK_CHANNEL;
-
- if ((modehandlers[pos]) && (modehandlers[pos]->GetNumParams(true)))
- modestr[pointer++] = mode;
- }
- modestr[pointer++] = 0;
- return modestr;
+ Cached004ModeList = CreateModeList(MODETYPE_USER) + " " + CreateModeList(MODETYPE_CHANNEL) + " " + CreateModeList(MODETYPE_CHANNEL, true);
}
ModeHandler* ModeParser::FindPrefix(unsigned const char pfxletter)
diff --git a/src/users.cpp b/src/users.cpp
index 7e1df61fe..49c5c5e42 100644
--- a/src/users.cpp
+++ b/src/users.cpp
@@ -731,10 +731,8 @@ void LocalUser::FullConnect()
this->WriteNumeric(RPL_YOURHOSTIS, "%s :Your host is %s, running version %s",this->nick.c_str(),ServerInstance->Config->ServerName.c_str(),BRANCH);
this->WriteNumeric(RPL_SERVERCREATED, "%s :This server was created %s %s", this->nick.c_str(), __TIME__, __DATE__);
- std::string umlist = ServerInstance->Modes->UserModeList();
- std::string cmlist = ServerInstance->Modes->ChannelModeList();
- std::string pmlist = ServerInstance->Modes->ParaModeList();
- this->WriteNumeric(RPL_SERVERVERSION, "%s %s %s %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName.c_str(), BRANCH, umlist.c_str(), cmlist.c_str(), pmlist.c_str());
+ const std::string& modelist = ServerInstance->Modes->GetModeListFor004Numeric();
+ this->WriteNumeric(RPL_SERVERVERSION, "%s %s %s %s", this->nick.c_str(), ServerInstance->Config->ServerName.c_str(), BRANCH, modelist.c_str());
ServerInstance->ISupport.SendTo(this);
this->WriteNumeric(RPL_YOURUUID, "%s %s :your unique ID", this->nick.c_str(), this->uuid.c_str());