2 * InspIRCd -- Internet Relay Chat Daemon
4 * Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
5 * Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
6 * Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
8 * This file is part of InspIRCd. InspIRCd is free software: you can
9 * redistribute it and/or modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation, version 2.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "builtinmodes.h"
28 ModeUserServerNoticeMask::ModeUserServerNoticeMask() : ModeHandler(NULL, "snomask", 's', PARAM_SETONLY, MODETYPE_USER)
33 ModeAction ModeUserServerNoticeMask::OnModeChange(User* source, User* dest, Channel*, std::string ¶meter, bool adding)
37 dest->SetMode(this, true);
38 // Process the parameter (remove chars we don't understand, remove redundant chars, etc.)
39 parameter = ProcessNoticeMasks(dest, parameter);
40 return MODEACTION_ALLOW;
44 if (dest->IsModeSet(this))
46 dest->SetMode(this, false);
47 dest->snomasks.reset();
48 return MODEACTION_ALLOW;
52 // Mode not set and trying to unset, deny
53 return MODEACTION_DENY;
56 std::string ModeUserServerNoticeMask::GetUserParameter(User* user)
59 if (!user->IsModeSet(this))
63 for (unsigned char n = 0; n < 64; n++)
65 if (user->snomasks[n])
66 ret.push_back(n + 'A');
71 void ModeUserServerNoticeMask::OnParameterMissing(User* user, User* dest, Channel* channel)
73 user->WriteNotice("*** The user mode +s requires a parameter (server notice mask). Please provide a parameter, e.g. '+s +*'.");
76 std::string ModeUserServerNoticeMask::ProcessNoticeMasks(User* user, const std::string& input)
79 std::bitset<64> curr = user->snomasks;
81 for (std::string::const_iterator i = input.begin(); i != input.end(); ++i)
92 for (size_t j = 0; j < 64; j++)
94 if (ServerInstance->SNO->IsSnomaskUsable(j+'A'))
99 // For local users check whether the given snomask is valid and enabled - IsSnomaskUsable() tests both.
100 // For remote users accept what we were told, unless the snomask char is not a letter.
103 if (!ServerInstance->SNO->IsSnomaskUsable(*i))
105 user->WriteNumeric(ERR_UNKNOWNSNOMASK, "%c :is unknown snomask char to me", *i);
109 else if (!(((*i >= 'a') && (*i <= 'z')) || ((*i >= 'A') && (*i <= 'Z'))))
112 size_t index = ((*i) - 'A');
113 curr[index] = adding;
118 std::string plus = "+";
119 std::string minus = "-";
121 // Apply changes and construct two strings consisting of the newly added and the removed snomask chars
122 for (size_t i = 0; i < 64; i++)
124 bool isset = curr[i];
125 if (user->snomasks[i] != isset)
127 user->snomasks[i] = isset;
128 std::string& appendhere = (isset ? plus : minus);
129 appendhere.push_back(i+'A');
133 // Create the final string that will be shown to the user and sent to servers
136 if (plus.length() > 1)
139 if (minus.length() > 1)
142 // Unset the snomask usermode itself if every snomask was unset
143 if (user->snomasks.none())
144 user->SetMode(this, false);