]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_services.cpp
2a7656f2f81fce569685845b292f0e1730a7d645
[user/henk/code/inspircd.git] / src / modules / m_services.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 using namespace std;
18
19 #include <stdio.h>
20 #include "users.h"
21 #include "channels.h"
22 #include "modules.h"
23 #include <string>
24 #include "helperfuncs.h"
25 #include "hashcomp.h"
26 #include "inspircd.h"
27
28 static bool kludgeme = false;
29
30 /* $ModDesc: Povides support for services +r user/chan modes and more */
31
32 class Channel_r : public ModeHandler
33 {
34         Server* Srv;
35  public:
36         Channel_r(Server* srv) : ModeHandler('r', 0, 0, false, MODETYPE_CHANNEL, false), Srv(srv) { }
37
38         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
39         {
40                 // only a u-lined server may add or remove the +r mode.
41                 if ((Srv->IsUlined(source->nick)) || (Srv->IsUlined(source->server)) || (!*source->server || (strchr(source->nick,'.'))))
42                 {
43                         log(DEBUG,"Allowing cmode +r, server and nick are: '%s','%s'",source->nick,source->server);
44                         channel->SetMode('r',adding);
45                         return MODEACTION_ALLOW;
46                 }
47                 else
48                 {
49                         log(DEBUG,"Only a server can set chanmode +r, server and nick are: '%s','%s'",source->nick,source->server);
50                         source->WriteServ("500 "+std::string(source->nick)+" :Only a server may modify the +r channel mode");
51                         return MODEACTION_DENY;
52                 }
53         }
54 };
55
56 class User_r : public ModeHandler
57 {
58         Server* Srv;
59  public:
60         User_r(Server* srv) : ModeHandler('r', 0, 0, false, MODETYPE_USER, false), Srv(srv) { }
61
62         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
63         {
64                 if ((kludgeme) || (Srv->IsUlined(source->nick)) || (Srv->IsUlined(source->server)) || (!*source->server || (strchr(source->nick,'.'))))
65                 {
66                         log(DEBUG,"Allowing umode +r, server and nick are: '%s','%s'",source->nick,source->server);
67                         dest->SetMode('r',adding);
68                         return MODEACTION_ALLOW;
69                 }
70                 else
71                 {
72                         log(DEBUG,"Only a server can set umode +r, server and nick are: '%s','%s'",source->nick, source->server);
73                         source->WriteServ("500 "+std::string(source->nick)+" :Only a server may modify the +r user mode");
74                         return MODEACTION_DENY;
75                 }
76         }
77 };
78
79 class Channel_R : public ModeHandler
80 {
81  public:
82         Channel_R() : ModeHandler('R', 0, 0, false, MODETYPE_CHANNEL, false) { }
83
84         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
85         {
86                 if (adding)
87                 {
88                         if (!channel->IsModeSet('R'))
89                         {
90                                 channel->SetMode('R',true);
91                                 return MODEACTION_ALLOW;
92                         }
93                 }
94                 else
95                 {
96                         if (channel->IsModeSet('R'))
97                         {
98                                 channel->SetMode('R',false);
99                                 return MODEACTION_ALLOW;
100                         }
101                 }
102
103                 return MODEACTION_DENY;
104         }
105 };
106
107 class User_R : public ModeHandler
108 {
109  public:
110         User_R() : ModeHandler('R', 0, 0, false, MODETYPE_USER, false) { }
111
112         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
113         {
114                 if (adding)
115                 {
116                         if (!dest->IsModeSet('R'))
117                         {
118                                 dest->SetMode('R',true);
119                                 return MODEACTION_ALLOW;
120                         }
121                 }
122                 else
123                 {
124                         if (dest->IsModeSet('R'))
125                         {
126                                 dest->SetMode('R',false);
127                                 return MODEACTION_ALLOW;
128                         }
129                 }
130
131                 return MODEACTION_DENY;
132         }
133 };
134
135 class Channel_M : public ModeHandler
136 {
137  public:
138         Channel_M() : ModeHandler('M', 0, 0, false, MODETYPE_CHANNEL, false) { }
139
140         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
141         {
142                 if (adding)
143                 {
144                         if (!channel->IsModeSet('M'))
145                         {
146                                 channel->SetMode('M',true);
147                                 return MODEACTION_ALLOW;
148                         }
149                 }
150                 else
151                 {
152                         if (channel->IsModeSet('M'))
153                         {
154                                 channel->SetMode('M',true);
155                                 return MODEACTION_ALLOW;
156                         }
157                 }
158
159                 return MODEACTION_DENY;
160         }
161 };
162
163 class ModuleServices : public Module
164 {
165         Server *Srv;
166         Channel_r* m1;
167         Channel_R* m2;
168         Channel_M* m3;
169         User_r* m4;
170         User_R* m5;
171  public:
172         ModuleServices(Server* Me)
173                 : Module::Module(Me)
174         {
175                 Srv = Me;
176                 m1 = new Channel_r(Me);
177                 m2 = new Channel_R();
178                 m3 = new Channel_M();
179                 m4 = new User_r(Me);
180                 m5 = new User_R();
181                 Srv->AddMode(m1, 'r');
182                 Srv->AddMode(m2, 'R');
183                 Srv->AddMode(m3, 'M');
184                 Srv->AddMode(m4, 'r');
185                 Srv->AddMode(m5, 'R');
186                 kludgeme = false;
187         }
188
189         virtual void On005Numeric(std::string &output)
190         {
191                 InsertMode(output, "rRM", 4);
192         }
193
194         /* <- :stitch.chatspike.net 307 w00t w00t :is a registered nick */
195         virtual void OnWhois(userrec* source, userrec* dest)
196         {
197                 if (dest->IsModeSet('r'))
198                 {
199                         /* user is registered */
200                         source->WriteServ("307 %s %s :is a registered nick", source->nick, dest->nick);
201                 }
202         }
203
204         void Implements(char* List)
205         {
206                 List[I_OnWhois] = List[I_OnUserPostNick] = List[I_OnUserPreMessage] = List[I_On005Numeric] = List[I_OnUserPreNotice] = List[I_OnUserPreJoin] = 1;
207         }
208
209         virtual void OnUserPostNick(userrec* user, const std::string &oldnick)
210         {
211                 /* On nickchange, if they have +r, remove it */
212                 if (user->IsModeSet('r'))
213                 {
214                         const char* modechange[2];
215                         modechange[0] = user->nick;
216                         modechange[1] = "-r";
217                         kludgeme = true;
218                         Srv->SendMode(modechange,2,user);
219                         kludgeme = false;
220                 }
221         }
222         
223         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text, char status)
224         {
225                 if (target_type == TYPE_CHANNEL)
226                 {
227                         chanrec* c = (chanrec*)dest;
228                         if ((c->IsModeSet('M')) && (!user->IsModeSet('r')))
229                         {
230                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"")))
231                                 {
232                                         // user is ulined, can speak regardless
233                                         return 0;
234                                 }
235                                 // user messaging a +M channel and is not registered
236                                 user->WriteServ("477 "+std::string(user->nick)+" "+std::string(c->name)+" :You need a registered nickname to speak on this channel");
237                                 return 1;
238                         }
239                 }
240                 if (target_type == TYPE_USER)
241                 {
242                         userrec* u = (userrec*)dest;
243                         if ((u->IsModeSet('R')) && (user->IsModeSet('r')))
244                         {
245                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
246                                 {
247                                         // user is ulined, can speak regardless
248                                         return 0;
249                                 }
250                                 // user messaging a +R user and is not registered
251                                 user->WriteServ("477 "+std::string(user->nick)+" "+std::string(u->nick)+" :You need a registered nickname to message this user");
252                                 return 1;
253                         }
254                 }
255                 return 0;
256         }
257         
258         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text, char status)
259         {
260                 return OnUserPreMessage(user,dest,target_type,text,status);
261         }
262         
263         virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname)
264         {
265                 if (chan)
266                 {
267                         if (chan->IsModeSet('R'))
268                         {
269                                 if (user->IsModeSet('r'))
270                                 {
271                                         if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
272                                         {
273                                                 // user is ulined, won't be stopped from joining
274                                                 return 0;
275                                         }
276                                         // joining a +R channel and not identified
277                                         user->WriteServ("477 "+std::string(user->nick)+" "+std::string(chan->name)+" :You need a registered nickname to join this channel");
278                                         return 1;
279                                 }
280                         }
281                 }
282                 return 0;
283         }
284
285         virtual ~ModuleServices()
286         {
287                 DELETE(m1);
288                 DELETE(m2);
289                 DELETE(m3);
290                 DELETE(m4);
291                 DELETE(m5);
292         }
293         
294         virtual Version GetVersion()
295         {
296                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
297         }
298 };
299
300
301 class ModuleServicesFactory : public ModuleFactory
302 {
303  public:
304         ModuleServicesFactory()
305         {
306         }
307         
308         ~ModuleServicesFactory()
309         {
310         }
311         
312         virtual Module * CreateModule(Server* Me)
313         {
314                 return new ModuleServices(Me);
315         }
316         
317 };
318
319
320 extern "C" void * init_module( void )
321 {
322         return new ModuleServicesFactory;
323 }
324