summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mode.cpp19
-rw-r--r--src/modules/m_namedmodes.cpp136
2 files changed, 143 insertions, 12 deletions
diff --git a/src/mode.cpp b/src/mode.cpp
index 1ac2b9e64..98b5fe8c4 100644
--- a/src/mode.cpp
+++ b/src/mode.cpp
@@ -392,22 +392,15 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
return;
}
- std::string mode_sequence = parameters[1];
+ ModResult MOD_RESULT;
+ FIRST_MOD_RESULT(OnPreMode, MOD_RESULT, (user, targetuser, targetchannel, parameters));
bool SkipAccessChecks = false;
- if (!IS_LOCAL(user) || ServerInstance->ULine(user->server))
- {
+ if (!IS_LOCAL(user) || ServerInstance->ULine(user->server) || MOD_RESULT == MOD_RES_ALLOW)
SkipAccessChecks = true;
- }
- else
- {
- ModResult MOD_RESULT;
- FIRST_MOD_RESULT(OnPreMode, MOD_RESULT, (user, targetuser, targetchannel, parameters));
- if (MOD_RESULT == MOD_RES_DENY)
- return;
- SkipAccessChecks = (MOD_RESULT == MOD_RES_ALLOW);
- }
+ else if (MOD_RESULT == MOD_RES_DENY)
+ return;
if (targetuser && !SkipAccessChecks && user != targetuser)
{
@@ -415,6 +408,8 @@ void ModeParser::Process(const std::vector<std::string>& parameters, User *user,
return;
}
+ std::string mode_sequence = parameters[1];
+
std::string output_mode;
std::ostringstream output_parameters;
LastParseParams.push_back(output_mode);
diff --git a/src/modules/m_namedmodes.cpp b/src/modules/m_namedmodes.cpp
new file mode 100644
index 000000000..4bf8960e1
--- /dev/null
+++ b/src/modules/m_namedmodes.cpp
@@ -0,0 +1,136 @@
+/* +------------------------------------+
+ * | Inspire Internet Relay Chat Daemon |
+ * +------------------------------------+
+ *
+ * InspIRCd: (C) 2002-2009 InspIRCd Development Team
+ * See: http://wiki.inspircd.org/Credits
+ *
+ * This program is free but copyrighted software; see
+ * the file COPYING for details.
+ *
+ * ---------------------------------------------------
+ */
+
+#include "inspircd.h"
+
+class ModuleNamedModes : public Module
+{
+ public:
+ ModuleNamedModes()
+ {
+ Implementation eventlist[] = { I_OnPreMode, I_On005Numeric };
+ ServerInstance->Modules->Attach(eventlist, this, 2);
+ }
+
+ Version GetVersion()
+ {
+ return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
+ }
+
+ void On005Numeric(std::string& line)
+ {
+ std::string::size_type pos = line.find(" CHANMODES=");
+ if (pos != std::string::npos)
+ {
+ pos += 11;
+ while (line[pos] > 'A' && line[pos] < 'Z')
+ pos++;
+ line.insert(pos, 1, 'Z');
+ }
+ }
+
+ void DisplayList(User* user, Channel* channel)
+ {
+ for(char letter = 'A'; letter <= 'z'; letter++)
+ {
+ ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
+ if (!mh || mh->IsListMode())
+ continue;
+ if (!channel->IsModeSet(letter))
+ continue;
+ std::string item = mh->name;
+ if (mh->GetNumParams(true))
+ item += "=" + channel->GetModeParameter(letter);
+ user->WriteNumeric(961, "%s %s %s", user->nick.c_str(), channel->name.c_str(), item.c_str());
+ }
+ user->WriteNumeric(960, "%s %s :End of mode list", user->nick.c_str(), channel->name.c_str());
+ }
+
+ ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters)
+ {
+ if (!channel)
+ return MOD_RES_PASSTHRU;
+ if (parameters[1].find('Z') == std::string::npos)
+ return MOD_RES_PASSTHRU;
+ if (parameters.size() <= 2)
+ {
+ DisplayList(source, channel);
+ return MOD_RES_DENY;
+ }
+
+ std::vector<std::string> newparms;
+ newparms.push_back(parameters[0]);
+ newparms.push_back(parameters[1]);
+
+ std::string modelist = newparms[1];
+ bool adding = true;
+ unsigned int param_at = 2;
+ for(unsigned int i = 0; i < modelist.length(); i++)
+ {
+ unsigned char modechar = modelist[i];
+ if (modechar == '+' || modechar == '-')
+ {
+ adding = (modechar == '+');
+ continue;
+ }
+ ModeHandler *mh = ServerInstance->Modes->FindMode(modechar, MODETYPE_CHANNEL);
+ if (modechar == 'Z')
+ {
+ modechar = 0;
+ std::string name, value;
+ if (param_at < parameters.size())
+ name = parameters[param_at++];
+ std::string::size_type eq = name.find('=');
+ if (eq != std::string::npos)
+ {
+ value = name.substr(eq + 1);
+ name = name.substr(0, eq);
+ }
+ for(char letter = 'A'; modechar == 0 && letter <= 'z'; letter++)
+ {
+ mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
+ if (mh && mh->name == name)
+ {
+ if (mh->GetNumParams(adding))
+ {
+ if (!value.empty())
+ {
+ newparms.push_back(value);
+ modechar = letter;
+ break;
+ }
+ }
+ else
+ {
+ modechar = letter;
+ break;
+ }
+ }
+ }
+ if (modechar)
+ modelist[i] = modechar;
+ else
+ modelist.erase(i, 1);
+ }
+ else if (mh && mh->GetNumParams(adding) && param_at < parameters.size())
+ {
+ newparms.push_back(parameters[param_at++]);
+ }
+ }
+ newparms[1] = modelist;
+ ServerInstance->Modes->Process(newparms, source, false);
+ return MOD_RES_DENY;
+ }
+};
+
+MODULE_INIT(ModuleNamedModes)