2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
6 * This file is part of InspIRCd. InspIRCd is free software: you can
7 * redistribute it and/or modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation, version 2.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 RPL_ENDOFPROPLIST = 960,
29 static void DisplayList(LocalUser* user, Channel* channel)
31 Numeric::ParamBuilder<1> numeric(user, RPL_PROPLIST);
32 numeric.AddStatic(channel->name);
34 const ModeParser::ModeHandlerMap& mhs = ServerInstance->Modes->GetModes(MODETYPE_CHANNEL);
35 for (ModeParser::ModeHandlerMap::const_iterator i = mhs.begin(); i != mhs.end(); ++i)
37 ModeHandler* mh = i->second;
38 if (!channel->IsModeSet(mh))
40 numeric.Add("+" + mh->name);
41 ParamModeBase* pm = mh->IsParameterMode();
44 if ((pm->IsParameterSecret()) && (!channel->HasUser(user)) && (!user->HasPrivPermission("channels/auspex")))
45 numeric.Add("<" + mh->name + ">");
47 numeric.Add(channel->GetModeParameter(mh));
51 user->WriteNumeric(RPL_ENDOFPROPLIST, channel->name, "End of mode list");
54 class CommandProp : public SplitCommand
57 CommandProp(Module* parent)
58 : SplitCommand(parent, "PROP", 1)
60 syntax = "<channel> [[(+|-)]<mode> [<value>]]";
63 CmdResult HandleLocal(LocalUser* src, const Params& parameters) CXX11_OVERRIDE
65 Channel* const chan = ServerInstance->FindChan(parameters[0]);
68 src->WriteNumeric(Numerics::NoSuchChannel(parameters[0]));
72 if (parameters.size() == 1)
74 DisplayList(src, chan);
78 Modes::ChangeList modes;
79 while (i < parameters.size())
81 std::string prop = parameters[i++];
84 bool plus = prop[0] != '-';
85 if (prop[0] == '+' || prop[0] == '-')
86 prop.erase(prop.begin());
88 ModeHandler* mh = ServerInstance->Modes->FindMode(prop, MODETYPE_CHANNEL);
91 if (mh->NeedsParam(plus))
93 if (i != parameters.size())
94 modes.push(mh, plus, parameters[i++]);
100 ServerInstance->Modes->ProcessSingle(src, chan, NULL, modes, ModeParser::MODE_CHECKACCESS);
105 class DummyZ : public ModeHandler
108 DummyZ(Module* parent) : ModeHandler(parent, "namebase", 'Z', PARAM_ALWAYS, MODETYPE_CHANNEL)
113 // Handle /MODE #chan Z
114 void DisplayList(User* user, Channel* chan) CXX11_OVERRIDE
117 ::DisplayList(static_cast<LocalUser*>(user), chan);
121 class ModuleNamedModes : public Module
126 ModuleNamedModes() : cmd(this), dummyZ(this)
130 Version GetVersion() CXX11_OVERRIDE
132 return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
135 void Prioritize() CXX11_OVERRIDE
137 ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
140 ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes) CXX11_OVERRIDE
143 return MOD_RES_PASSTHRU;
145 Modes::ChangeList::List& list = modes.getlist();
146 for (Modes::ChangeList::List::iterator i = list.begin(); i != list.end(); )
148 Modes::Change& curr = *i;
149 // Replace all namebase (dummyZ) modes being changed with the actual
150 // mode handler and parameter. The parameter format of the namebase mode is
151 // <modename>[=<parameter>].
152 if (curr.mh == &dummyZ)
154 std::string name = curr.param;
156 std::string::size_type eq = name.find('=');
157 if (eq != std::string::npos)
159 value.assign(name, eq + 1, std::string::npos);
163 ModeHandler* mh = ServerInstance->Modes->FindMode(name, MODETYPE_CHANNEL);
166 // Mode handler not found
172 if (mh->NeedsParam(curr.adding))
176 // Mode needs a parameter but there wasn't one
181 // Change parameter to the text after the '='
185 // Put the actual ModeHandler in place of the namebase handler
192 return MOD_RES_PASSTHRU;
196 MODULE_INIT(ModuleNamedModes)