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/>.
22 static void DisplayList(User* user, Channel* channel)
24 std::stringstream items;
25 const ModeParser::ModeHandlerMap& mhs = ServerInstance->Modes->GetModes(MODETYPE_CHANNEL);
26 for (ModeParser::ModeHandlerMap::const_iterator i = mhs.begin(); i != mhs.end(); ++i)
28 ModeHandler* mh = i->second;
29 if (!channel->IsModeSet(mh))
31 items << " +" << mh->name;
32 if (mh->GetNumParams(true))
33 items << " " << channel->GetModeParameter(mh);
35 const std::string line = ":" + ServerInstance->Config->ServerName + " 961 " + user->nick + " " + channel->name;
36 user->SendText(line, items);
37 user->WriteNumeric(960, "%s :End of mode list", channel->name.c_str());
40 class CommandProp : public Command
43 CommandProp(Module* parent) : Command(parent, "PROP", 1)
45 syntax = "<user|channel> {[+-]<mode> [<value>]}*";
48 CmdResult Handle(const std::vector<std::string> ¶meters, User *src)
50 if (parameters.size() == 1)
52 Channel* chan = ServerInstance->FindChan(parameters[0]);
54 DisplayList(src, chan);
58 std::vector<std::string> modes;
59 modes.push_back(parameters[0]);
61 while (i < parameters.size())
63 std::string prop = parameters[i++];
64 bool plus = prop[0] != '-';
65 if (prop[0] == '+' || prop[0] == '-')
66 prop.erase(prop.begin());
68 ModeHandler* mh = ServerInstance->Modes->FindMode(prop, MODETYPE_CHANNEL);
71 modes[1].push_back(plus ? '+' : '-');
72 modes[1].push_back(mh->GetModeChar());
73 if (mh->GetNumParams(plus))
75 if (i != parameters.size())
76 modes.push_back(parameters[i++]);
80 ServerInstance->Modes->Process(modes, src);
85 class DummyZ : public ModeHandler
88 DummyZ(Module* parent) : ModeHandler(parent, "namebase", 'Z', PARAM_ALWAYS, MODETYPE_CHANNEL)
93 // Handle /MODE #chan Z
94 void DisplayList(User* user, Channel* chan)
96 ::DisplayList(user, chan);
100 class ModuleNamedModes : public Module
105 ModuleNamedModes() : cmd(this), dummyZ(this)
109 Version GetVersion() CXX11_OVERRIDE
111 return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
116 ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
119 ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes) CXX11_OVERRIDE
122 return MOD_RES_PASSTHRU;
124 Modes::ChangeList::List& list = modes.getlist();
125 for (Modes::ChangeList::List::iterator i = list.begin(); i != list.end(); )
127 Modes::Change& curr = *i;
128 // Replace all namebase (dummyZ) modes being changed with the actual
129 // mode handler and parameter. The parameter format of the namebase mode is
130 // <modename>[=<parameter>].
131 if (curr.mh == &dummyZ)
133 std::string name = curr.param;
135 std::string::size_type eq = name.find('=');
136 if (eq != std::string::npos)
138 value = name.substr(eq + 1);
139 name = name.substr(0, eq);
142 ModeHandler* mh = ServerInstance->Modes->FindMode(name, MODETYPE_CHANNEL);
145 // Mode handler not found
151 if (mh->GetNumParams(curr.adding))
155 // Mode needs a parameter but there wasn't one
160 // Change parameter to the text after the '='
164 // Put the actual ModeHandler in place of the namebase handler
171 return MOD_RES_PASSTHRU;
175 MODULE_INIT(ModuleNamedModes)