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