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