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 for(char letter = 'A'; letter <= 'z'; letter++)
27 ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
28 if (!mh || mh->IsListMode())
30 if (!channel->IsModeSet(mh))
32 items << " +" << mh->name;
33 if (mh->GetNumParams(true))
34 items << " " << channel->GetModeParameter(mh);
36 const std::string line = ":" + ServerInstance->Config->ServerName + " 961 " + user->nick + " " + channel->name;
37 user->SendText(line, items);
38 user->WriteNumeric(960, "%s :End of mode list", channel->name.c_str());
41 class CommandProp : public Command
44 CommandProp(Module* parent) : Command(parent, "PROP", 1)
46 syntax = "<user|channel> {[+-]<mode> [<value>]}*";
49 CmdResult Handle(const std::vector<std::string> ¶meters, User *src)
51 if (parameters.size() == 1)
53 Channel* chan = ServerInstance->FindChan(parameters[0]);
55 DisplayList(src, chan);
59 std::vector<std::string> modes;
60 modes.push_back(parameters[0]);
62 while (i < parameters.size())
64 std::string prop = parameters[i++];
65 bool plus = prop[0] != '-';
66 if (prop[0] == '+' || prop[0] == '-')
67 prop.erase(prop.begin());
69 ModeHandler* mh = ServerInstance->Modes->FindMode(prop, MODETYPE_CHANNEL);
72 modes[1].push_back(plus ? '+' : '-');
73 modes[1].push_back(mh->GetModeChar());
74 if (mh->GetNumParams(plus))
76 if (i != parameters.size())
77 modes.push_back(parameters[i++]);
81 ServerInstance->Modes->Process(modes, src);
86 class DummyZ : public ModeHandler
89 DummyZ(Module* parent) : ModeHandler(parent, "namebase", 'Z', PARAM_ALWAYS, MODETYPE_CHANNEL)
95 class ModuleNamedModes : public Module
100 ModuleNamedModes() : cmd(this), dummyZ(this)
104 Version GetVersion() CXX11_OVERRIDE
106 return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
111 ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
114 ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters) CXX11_OVERRIDE
117 return MOD_RES_PASSTHRU;
118 if (parameters[1].find('Z') == std::string::npos)
119 return MOD_RES_PASSTHRU;
120 if (parameters.size() <= 2)
122 DisplayList(source, channel);
126 std::vector<std::string> newparms;
127 newparms.push_back(parameters[0]);
128 newparms.push_back(parameters[1]);
130 std::string modelist = newparms[1];
132 unsigned int param_at = 2;
133 for(unsigned int i = 0; i < modelist.length(); i++)
135 unsigned char modechar = modelist[i];
136 if (modechar == '+' || modechar == '-')
138 adding = (modechar == '+');
141 ModeHandler *mh = ServerInstance->Modes->FindMode(modechar, MODETYPE_CHANNEL);
144 std::string name, value;
145 if (param_at < parameters.size())
146 name = parameters[param_at++];
147 std::string::size_type eq = name.find('=');
148 if (eq != std::string::npos)
150 value = name.substr(eq + 1);
151 name = name.substr(0, eq);
154 mh = ServerInstance->Modes->FindMode(name, MODETYPE_CHANNEL);
157 // Mode handler not found
158 modelist.erase(i--, 1);
162 if (mh->GetNumParams(adding))
166 // Mode needs a parameter but there wasn't one
167 modelist.erase(i--, 1);
171 newparms.push_back(value);
174 modelist[i] = mh->GetModeChar();
176 else if (mh && mh->GetNumParams(adding) && param_at < parameters.size())
178 newparms.push_back(parameters[param_at++]);
181 newparms[1] = modelist;
182 ServerInstance->Modes->Process(newparms, source);
187 MODULE_INIT(ModuleNamedModes)