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