]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modes/umode_s.cpp
Move SetNoticeMask(), FormatNoticeMasks() and ProcessNoticeMasks() from the User...
[user/henk/code/inspircd.git] / src / modes / umode_s.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
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>
7  *
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.
11  *
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
15  * details.
16  *
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/>.
19  */
20
21
22 #include "inspircd.h"
23 #include "mode.h"
24 #include "channels.h"
25 #include "users.h"
26 #include "builtinmodes.h"
27
28 ModeUserServerNoticeMask::ModeUserServerNoticeMask() : ModeHandler(NULL, "snomask", 's', PARAM_SETONLY, MODETYPE_USER)
29 {
30         oper = true;
31 }
32
33 ModeAction ModeUserServerNoticeMask::OnModeChange(User* source, User* dest, Channel*, std::string &parameter, bool adding)
34 {
35         /* Set the array fields */
36         if (adding)
37         {
38                 /* Fix for bug #310 reported by Smartys */
39                 if (!dest->IsModeSet(this))
40                         dest->snomasks.reset();
41
42                 dest->SetMode(this, true);
43                 parameter = ProcessNoticeMasks(dest, parameter.c_str());
44                 return MODEACTION_ALLOW;
45         }
46         else
47         {
48                 if (dest->IsModeSet(this))
49                 {
50                         dest->SetMode(this, false);
51                         return MODEACTION_ALLOW;
52                 }
53         }
54
55         /* Allow the change */
56         return MODEACTION_DENY;
57 }
58
59 std::string ModeUserServerNoticeMask::GetUserParameter(User* user)
60 {
61         std::string masks = FormatNoticeMasks(user);
62         if (masks.length())
63                 masks = "+" + masks;
64         return masks;
65 }
66
67 void ModeUserServerNoticeMask::OnParameterMissing(User* user, User* dest, Channel* channel)
68 {
69         user->WriteNotice("*** The user mode +s requires a parameter (server notice mask). Please provide a parameter, e.g. '+s +*'.");
70 }
71
72 std::string ModeUserServerNoticeMask::ProcessNoticeMasks(User* user, const char *sm)
73 {
74         bool adding = true, oldadding = false;
75         const char *c = sm;
76         std::string output;
77
78         while (c && *c)
79         {
80                 switch (*c)
81                 {
82                         case '+':
83                                 adding = true;
84                         break;
85                         case '-':
86                                 adding = false;
87                         break;
88                         case '*':
89                                 for (unsigned char d = 'a'; d <= 'z'; d++)
90                                 {
91                                         if (!ServerInstance->SNO->masks[d - 'a'].Description.empty())
92                                         {
93                                                 if ((!user->IsNoticeMaskSet(d) && adding) || (user->IsNoticeMaskSet(d) && !adding))
94                                                 {
95                                                         if ((oldadding != adding) || (!output.length()))
96                                                                 output += (adding ? '+' : '-');
97
98                                                         SetNoticeMask(user, d, adding);
99
100                                                         output += d;
101                                                 }
102                                                 oldadding = adding;
103                                                 char u = toupper(d);
104                                                 if ((!user->IsNoticeMaskSet(u) && adding) || (user->IsNoticeMaskSet(u) && !adding))
105                                                 {
106                                                         if ((oldadding != adding) || (!output.length()))
107                                                                 output += (adding ? '+' : '-');
108
109                                                         SetNoticeMask(user, u, adding);
110
111                                                         output += u;
112                                                 }
113                                                 oldadding = adding;
114                                         }
115                                 }
116                         break;
117                         default:
118                                 if (isalpha(*c))
119                                 {
120                                         if ((!user->IsNoticeMaskSet(*c) && adding) || (user->IsNoticeMaskSet(*c) && !adding))
121                                         {
122                                                 if ((oldadding != adding) || (!output.length()))
123                                                         output += (adding ? '+' : '-');
124
125                                                 SetNoticeMask(user, *c, adding);
126
127                                                 output += *c;
128                                         }
129                                 }
130                                 else
131                                         user->WriteNumeric(ERR_UNKNOWNSNOMASK, "%s %c :is unknown snomask char to me", user->nick.c_str(), *c);
132
133                                 oldadding = adding;
134                         break;
135                 }
136
137                 c++;
138         }
139
140         std::string s = this->FormatNoticeMasks(user);
141         if (s.length() == 0)
142         {
143                 user->SetMode(this, false);
144         }
145
146         return output;
147 }
148
149 std::string ModeUserServerNoticeMask::FormatNoticeMasks(User* user)
150 {
151         std::string data;
152
153         for (unsigned char n = 0; n < 64; n++)
154         {
155                 if (user->snomasks[n])
156                         data.push_back(n + 65);
157         }
158
159         return data;
160 }
161
162 void ModeUserServerNoticeMask::SetNoticeMask(User* user, unsigned char sm, bool value)
163 {
164         if (!isalpha(sm))
165                 return;
166         user->snomasks[sm-65] = value;
167 }