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/>.
20 /* $ModDesc: Provides the ability to manipulate modes via long names. */
24 static void DisplayList(User* user, Channel* channel)
26 std::stringstream items;
27 for(char letter = 'A'; letter <= 'z'; letter++)
29 ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
30 if (!mh || mh->IsListMode())
32 if (!channel->IsModeSet(letter))
34 items << " +" << mh->name;
35 if (mh->GetNumParams(true))
37 if ((letter == 'k') && (!channel->HasUser(user)) && (!user->HasPrivPermission("channels/auspex")))
40 items << " " << channel->GetModeParameter(letter);
44 snprintf(pfx, MAXBUF, ":%s 961 %s %s", ServerInstance->Config->ServerName.c_str(), user->nick.c_str(), channel->name.c_str());
45 user->SendText(std::string(pfx), items);
46 user->WriteNumeric(960, "%s %s :End of mode list", user->nick.c_str(), channel->name.c_str());
49 class CommandProp : public Command
52 CommandProp(Module* parent) : Command(parent, "PROP", 1)
54 syntax = "<user|channel> {[+-]<mode> [<value>]}*";
57 CmdResult Handle(const std::vector<std::string> ¶meters, User *src)
59 if (parameters.size() == 1)
61 Channel* chan = ServerInstance->FindChan(parameters[0]);
63 DisplayList(src, chan);
67 std::vector<std::string> modes;
68 modes.push_back(parameters[0]);
70 while (i < parameters.size())
72 std::string prop = parameters[i++];
75 bool plus = prop[0] != '-';
76 if (prop[0] == '+' || prop[0] == '-')
77 prop.erase(prop.begin());
79 for(char letter = 'A'; letter <= 'z'; letter++)
81 ModeHandler* mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
82 if (mh && mh->name == prop)
84 modes[1].append((plus ? "+" : "-") + std::string(1, letter));
85 if (mh->GetNumParams(plus))
87 if (i != parameters.size())
88 modes.push_back(parameters[i++]);
93 ServerInstance->SendGlobalMode(modes, src);
98 class DummyZ : public ModeHandler
101 DummyZ(Module* parent) : ModeHandler(parent, "namebase", 'Z', PARAM_ALWAYS, MODETYPE_CHANNEL)
107 class ModuleNamedModes : public Module
112 ModuleNamedModes() : cmd(this), dummyZ(this)
118 ServerInstance->Modules->AddService(cmd);
119 ServerInstance->Modules->AddService(dummyZ);
121 Implementation eventlist[] = { I_OnPreMode };
122 ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
127 return Version("Provides the ability to manipulate modes via long names.",VF_VENDOR);
132 ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_FIRST);
135 ModResult OnPreMode(User* source, User* dest, Channel* channel, const std::vector<std::string>& parameters)
138 return MOD_RES_PASSTHRU;
139 if (parameters[1].find('Z') == std::string::npos)
140 return MOD_RES_PASSTHRU;
141 if (parameters.size() <= 2)
143 DisplayList(source, channel);
147 std::vector<std::string> newparms;
148 newparms.push_back(parameters[0]);
149 newparms.push_back(parameters[1]);
151 std::string modelist = newparms[1];
153 unsigned int param_at = 2;
154 for(unsigned int i = 0; i < modelist.length(); i++)
156 unsigned char modechar = modelist[i];
157 if (modechar == '+' || modechar == '-')
159 adding = (modechar == '+');
162 ModeHandler *mh = ServerInstance->Modes->FindMode(modechar, MODETYPE_CHANNEL);
166 std::string name, value;
167 if (param_at < parameters.size())
168 name = parameters[param_at++];
169 std::string::size_type eq = name.find('=');
170 if (eq != std::string::npos)
172 value = name.substr(eq + 1);
173 name = name.substr(0, eq);
175 for(char letter = 'A'; modechar == 0 && letter <= 'z'; letter++)
177 mh = ServerInstance->Modes->FindMode(letter, MODETYPE_CHANNEL);
178 if (mh && mh->name == name)
180 if (mh->GetNumParams(adding))
184 newparms.push_back(value);
197 modelist[i] = modechar;
199 modelist.erase(i--, 1);
201 else if (mh && mh->GetNumParams(adding) && param_at < parameters.size())
203 newparms.push_back(parameters[param_at++]);
206 newparms[1] = modelist;
207 ServerInstance->Modes->Process(newparms, source, false);
212 MODULE_INIT(ModuleNamedModes)