diff options
author | Peter Powell <petpow@saberuk.com> | 2019-01-28 21:24:39 +0000 |
---|---|---|
committer | Peter Powell <petpow@saberuk.com> | 2019-01-28 21:27:10 +0000 |
commit | c202169f925b8316264b931d3900ed481c65e4b7 (patch) | |
tree | 29a3c509d56a862e050ca2d20273c71f4f5fe32d /src | |
parent | a032cd90ad5582914759e226085efee5aae1a1ef (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.cpp | 46 |
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 |