]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_services.cpp
a3573137014c0cbb0f1d41c1b40c65ec54f13c71
[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
27 /* $ModDesc: Povides support for services +r user/chan modes and more */
28
29 class ModuleServices : public Module
30 {
31         Server *Srv; 
32  public:
33         ModuleServices(Server* Me)
34                 : Module::Module(Me)
35         {
36                 Srv = Me;
37
38                 Srv->AddExtendedMode('r',MT_CHANNEL,false,0,0);
39                 Srv->AddExtendedMode('r',MT_CLIENT,false,0,0);
40                 Srv->AddExtendedMode('R',MT_CHANNEL,false,0,0);
41                 Srv->AddExtendedMode('R',MT_CLIENT,false,0,0);
42                 Srv->AddExtendedMode('M',MT_CHANNEL,false,0,0);
43         }
44
45         virtual void On005Numeric(std::string &output)
46         {
47                 std::stringstream line(output);
48                 std::string temp1, temp2;
49                 while (!line.eof())
50                 {
51                         line >> temp1;
52                         if (temp1.substr(0,10) == "CHANMODES=")
53                         {
54                                 // append the chanmode to the end
55                                 temp1 = temp1.substr(10,temp1.length());
56                                 temp1 = "CHANMODES=" + temp1 + "rRM";
57                         }
58                         temp2 = temp2 + temp1 + " ";
59                 }
60                 if (temp2.length())
61                         output = temp2.substr(0,temp2.length()-1);
62         }
63
64         void Implements(char* List)
65         {
66                 List[I_OnUserPostNick] = List[I_OnUserPreMessage] = List[I_OnExtendedMode] = List[I_On005Numeric] = List[I_OnUserPreNotice] = List[I_OnUserPreJoin] = 1;
67         }
68
69         virtual void OnUserPostNick(userrec* user, std::string oldnick)
70         {
71                 /* On nickchange, if they have +r, remove it */
72                 if (strchr(user->modes,'r'))
73                 {
74                         char* modechange[2];
75                         modechange[0] = user->nick;
76                         modechange[1] = "-r";
77                         Srv->SendMode(modechange,2,user);
78                 }
79         }
80         
81         virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
82         {
83                 
84                 if (modechar == 'r')
85                 {
86                         if (type == MT_CHANNEL)
87                         {
88                                 // only a u-lined server may add or remove the +r mode.
89                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"") || (strchr(user->nick,'.'))))
90                                 {
91                                         log(DEBUG,"Allowing umode +r, server and nick are: '%s','%s'",user->nick,user->server);
92                                         return 1;
93                                 }
94                                 else
95                                 {
96                                         log(DEBUG,"Only a server can set chanmode +r, server and nick are: '%s','%s'",user->nick,user->server);
97                                         Srv->SendServ(user->fd,"500 "+std::string(user->nick)+" :Only a server may modify the +r channel mode");
98                                 }
99                         }
100                         else
101                         {
102                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"") || (strchr(user->nick,'.'))))
103                                 {
104                                         log(DEBUG,"Allowing umode +r, server and nick are: '%s','%s'",user->nick,user->server);
105                                         return 1;
106                                 }
107                                 else
108                                 {
109                                         log(DEBUG,"Only a server can set umode +r, server and nick are: '%s','%s'",user->nick,user->server);
110                                         Srv->SendServ(user->fd,"500 "+std::string(user->nick)+" :Only a server may modify the +r user mode");
111                                 }
112                         }
113                 }
114                 else if (modechar == 'R')
115                 {
116                         return 1;
117                 }
118                 else if (modechar == 'M')
119                 {
120                         if (type == MT_CHANNEL)
121                         {
122                                 return 1;
123                         }
124                 }
125
126                 return 0;
127         }
128
129         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text)
130         {
131                 if (target_type == TYPE_CHANNEL)
132                 {
133                         chanrec* c = (chanrec*)dest;
134                         if ((c->IsCustomModeSet('M')) && (!strchr(user->modes,'r')))
135                         {
136                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"")))
137                                 {
138                                         // user is ulined, can speak regardless
139                                         return 0;
140                                 }
141                                 // user messaging a +M channel and is not registered
142                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(c->name)+" :You need a registered nickname to speak on this channel");
143                                 return 1;
144                         }
145                 }
146                 if (target_type == TYPE_USER)
147                 {
148                         userrec* u = (userrec*)dest;
149                         if ((strchr(u->modes,'R')) && (!strchr(user->modes,'r')))
150                         {
151                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
152                                 {
153                                         // user is ulined, can speak regardless
154                                         return 0;
155                                 }
156                                 // user messaging a +R user and is not registered
157                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(u->nick)+" :You need a registered nickname to message this user");
158                                 return 1;
159                         }
160                 }
161                 return 0;
162         }
163         
164         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text)
165         {
166                 if (target_type == TYPE_CHANNEL)
167                 {
168                         chanrec* c = (chanrec*)dest;
169                         if ((c->IsCustomModeSet('M')) && (!strchr(user->modes,'r')))
170                         {
171                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
172                                 {
173                                         // user is ulined, can speak regardless
174                                         return 0;
175                                 }
176                                 // user noticing a +M channel and is not registered
177                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(c->name)+" :You need a registered nickname to speak on this channel");
178                                 return 1;
179                         }
180                 }
181                 if (target_type == TYPE_USER)
182                 {
183                         userrec* u = (userrec*)dest;
184                         if ((strchr(u->modes,'R')) && (!strchr(user->modes,'r')))
185                         {
186                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
187                                 {
188                                         // user is ulined, can speak regardless
189                                         return 0;
190                                 }
191                                 // user noticing a +R user and is not registered
192                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(u->nick)+" :You need a registered nickname to message this user");
193                                 return 1;
194                         }
195                 }
196                 return 0;
197         }
198         
199         virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname)
200         {
201                 if (chan)
202                 {
203                         if (chan->IsCustomModeSet('R'))
204                         {
205                                 if (!strchr(user->modes,'r'))
206                                 {
207                                         if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
208                                         {
209                                                 // user is ulined, won't be stopped from joining
210                                                 return 0;
211                                         }
212                                         // joining a +R channel and not identified
213                                         Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(chan->name)+" :You need a registered nickname to join this channel");
214                                         return 1;
215                                 }
216                         }
217                 }
218                 return 0;
219         }
220
221         virtual ~ModuleServices()
222         {
223         }
224         
225         virtual Version GetVersion()
226         {
227                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
228         }
229 };
230
231
232 class ModuleServicesFactory : public ModuleFactory
233 {
234  public:
235         ModuleServicesFactory()
236         {
237         }
238         
239         ~ModuleServicesFactory()
240         {
241         }
242         
243         virtual Module * CreateModule(Server* Me)
244         {
245                 return new ModuleServices(Me);
246         }
247         
248 };
249
250
251 extern "C" void * init_module( void )
252 {
253         return new ModuleServicesFactory;
254 }
255