summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeter Powell <petpow@saberuk.com>2019-01-28 21:24:39 +0000
committerPeter Powell <petpow@saberuk.com>2019-01-28 21:27:10 +0000
commitc202169f925b8316264b931d3900ed481c65e4b7 (patch)
tree29a3c509d56a862e050ca2d20273c71f4f5fe32d /src
parenta032cd90ad5582914759e226085efee5aae1a1ef (diff)
Fix sending the modes in RPL_CHANNELMODEIS as one big parameter.
Diffstat (limited to 'src')
-rw-r--r--src/coremods/core_user/cmd_mode.cpp46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/coremods/core_user/cmd_mode.cpp b/src/coremods/core_user/cmd_mode.cpp
index 101f748f1..ffeb9a2e3 100644
--- a/src/coremods/core_user/cmd_mode.cpp
+++ b/src/coremods/core_user/cmd_mode.cpp
@@ -144,12 +144,56 @@ static std::string GetSnomasks(const User* user)
return snomaskstr;
}
+namespace
+{
+ void GetModeList(Numeric::Numeric& num, Channel* chan, User* user)
+ {
+ // We should only show the value of secret parameters (i.e. key) if
+ // the user is a member of the channel.
+ bool show_secret = chan->HasUser(user);
+
+ std::string& modes = num.push("+").GetParams().back();
+ std::string param;
+ for (unsigned char chr = 65; chr < 123; ++chr)
+ {
+ // Check that the mode exists and is set.
+ ModeHandler* mh = ServerInstance->Modes->FindMode(chr, MODETYPE_CHANNEL);
+ if (!mh || !chan->IsModeSet(mh))
+ continue;
+
+ // Add the mode to the set list.
+ modes.push_back(mh->GetModeChar());
+
+ // If the mode has a parameter we need to include that too.
+ ParamModeBase* pm = mh->IsParameterMode();
+ if (!pm)
+ continue;
+
+ // If a mode has a secret parameter and the user is not privy to
+ // the value of it then we use <name> instead of the value.
+ if (pm->IsParameterSecret() && !show_secret)
+ {
+ num.push("<" + pm->name + ">");
+ continue;
+ }
+
+ // Retrieve the parameter and add it to the mode list.
+ pm->GetParameter(chan, param);
+ num.push(param);
+ param.clear();
+ }
+ }
+}
+
void CommandMode::DisplayCurrentModes(User* user, User* targetuser, Channel* targetchannel)
{
if (targetchannel)
{
// Display channel's current mode string
- user->WriteNumeric(RPL_CHANNELMODEIS, targetchannel->name, (std::string("+") + targetchannel->ChanModes(targetchannel->HasUser(user))));
+ Numeric::Numeric modenum(RPL_CHANNELMODEIS);
+ modenum.push(targetchannel->name);
+ GetModeList(modenum, targetchannel, user);
+ user->WriteNumeric(modenum);
user->WriteNumeric(RPL_CHANNELCREATED, targetchannel->name, (unsigned long)targetchannel->age);
}
else