]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_services.cpp
Change 974 numeric to 490 to avoid collision with Insp's failed to load module error
[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_OnUserPreMessage] = List[I_OnExtendedMode] = List[I_On005Numeric] = List[I_OnUserPreNotice] = List[I_OnUserPreJoin] = 1;
67         }
68         
69         virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
70         {
71                 
72                 if (modechar == 'r')
73                 {
74                         if (type == MT_CHANNEL)
75                         {
76                                 // only a u-lined server may add or remove the +r mode.
77                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"") || (strchr(user->nick,'.'))))
78                                 {
79                                         log(DEBUG,"Allowing umode +r, server and nick are: '%s','%s'",user->nick,user->server);
80                                         return 1;
81                                 }
82                                 else
83                                 {
84                                         log(DEBUG,"Only a server can set chanmode +r, server and nick are: '%s','%s'",user->nick,user->server);
85                                         Srv->SendServ(user->fd,"500 "+std::string(user->nick)+" :Only a server may modify the +r channel mode");
86                                 }
87                         }
88                         else
89                         {
90                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"") || (strchr(user->nick,'.'))))
91                                 {
92                                         log(DEBUG,"Allowing umode +r, server and nick are: '%s','%s'",user->nick,user->server);
93                                         return 1;
94                                 }
95                                 else
96                                 {
97                                         log(DEBUG,"Only a server can set umode +r, server and nick are: '%s','%s'",user->nick,user->server);
98                                         Srv->SendServ(user->fd,"500 "+std::string(user->nick)+" :Only a server may modify the +r user mode");
99                                 }
100                         }
101                 }
102                 else if (modechar == 'R')
103                 {
104                         return 1;
105                 }
106                 else if (modechar == 'M')
107                 {
108                         if (type == MT_CHANNEL)
109                         {
110                                 return 1;
111                         }
112                 }
113
114                 return 0;
115         }
116
117         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text)
118         {
119                 if (target_type == TYPE_CHANNEL)
120                 {
121                         chanrec* c = (chanrec*)dest;
122                         if ((c->IsCustomModeSet('M')) && (!strchr(user->modes,'r')))
123                         {
124                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)) || (!strcmp(user->server,"")))
125                                 {
126                                         // user is ulined, can speak regardless
127                                         return 0;
128                                 }
129                                 // user messaging a +M channel and is not registered
130                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(c->name)+" :You need a registered nickname to speak on this channel");
131                                 return 1;
132                         }
133                 }
134                 if (target_type == TYPE_USER)
135                 {
136                         userrec* u = (userrec*)dest;
137                         if ((strchr(u->modes,'R')) && (!strchr(user->modes,'r')))
138                         {
139                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
140                                 {
141                                         // user is ulined, can speak regardless
142                                         return 0;
143                                 }
144                                 // user messaging a +R user and is not registered
145                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(u->nick)+" :You need a registered nickname to message this user");
146                                 return 1;
147                         }
148                 }
149                 return 0;
150         }
151         
152         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text)
153         {
154                 if (target_type == TYPE_CHANNEL)
155                 {
156                         chanrec* c = (chanrec*)dest;
157                         if ((c->IsCustomModeSet('M')) && (!strchr(user->modes,'r')))
158                         {
159                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
160                                 {
161                                         // user is ulined, can speak regardless
162                                         return 0;
163                                 }
164                                 // user noticing a +M channel and is not registered
165                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(c->name)+" :You need a registered nickname to speak on this channel");
166                                 return 1;
167                         }
168                 }
169                 if (target_type == TYPE_USER)
170                 {
171                         userrec* u = (userrec*)dest;
172                         if ((strchr(u->modes,'R')) && (!strchr(user->modes,'r')))
173                         {
174                                 if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
175                                 {
176                                         // user is ulined, can speak regardless
177                                         return 0;
178                                 }
179                                 // user noticing a +R user and is not registered
180                                 Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(u->nick)+" :You need a registered nickname to message this user");
181                                 return 1;
182                         }
183                 }
184                 return 0;
185         }
186         
187         virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname)
188         {
189                 if (chan)
190                 {
191                         if (chan->IsCustomModeSet('R'))
192                         {
193                                 if (!strchr(user->modes,'r'))
194                                 {
195                                         if ((Srv->IsUlined(user->nick)) || (Srv->IsUlined(user->server)))
196                                         {
197                                                 // user is ulined, won't be stopped from joining
198                                                 return 0;
199                                         }
200                                         // joining a +R channel and not identified
201                                         Srv->SendServ(user->fd,"477 "+std::string(user->nick)+" "+std::string(chan->name)+" :You need a registered nickname to join this channel");
202                                         return 1;
203                                 }
204                         }
205                 }
206                 return 0;
207         }
208
209         virtual ~ModuleServices()
210         {
211         }
212         
213         virtual Version GetVersion()
214         {
215                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
216         }
217 };
218
219
220 class ModuleServicesFactory : public ModuleFactory
221 {
222  public:
223         ModuleServicesFactory()
224         {
225         }
226         
227         ~ModuleServicesFactory()
228         {
229         }
230         
231         virtual Module * CreateModule(Server* Me)
232         {
233                 return new ModuleServices(Me);
234         }
235         
236 };
237
238
239 extern "C" void * init_module( void )
240 {
241         return new ModuleServicesFactory;
242 }
243