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