]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_silence.cpp
4f851f6a1301dd1e321d9549e4e205b0254089df
[user/henk/code/inspircd.git] / src / modules / m_silence.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 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 #include <stdio.h>
18 #include <string>
19 #include <vector>
20 #include "users.h"
21 #include "channels.h"
22 #include "modules.h"
23 #include "helperfuncs.h"
24 #include "hashcomp.h"
25
26 /* $ModDesc: Provides support for the /SILENCE command */
27
28
29 // This typedef holds a silence list. Each user may or may not have a
30 // silencelist, if a silence list is empty for a user, he/she does not
31 // have one of these structures associated with their user record.
32 typedef std::vector<std::string> silencelist;
33
34
35 void handle_silence(char **parameters, int pcnt, userrec *user)
36 {
37         if (!pcnt)
38         {
39                 // no parameters, show the current silence list.
40                 // Use Extensible::GetExt to fetch the silence list
41                 silencelist* sl = (silencelist*)user->GetExt("silence_list");
42                 // if the user has a silence list associated with their user record, show it
43                 if (sl)
44                 {
45                         for (silencelist::const_iterator c = sl->begin(); c < sl->end(); c++)
46                         {
47                                 WriteServ(user->fd,"271 %s %s %s!*@*",user->nick, user->nick,c->c_str());
48                         }
49                 }
50                 WriteServ(user->fd,"272 %s :End of Silence List",user->nick);
51         }
52         else if (pcnt > 0)
53         {
54                 // one or more parameters, add or delete entry from the list (only the first parameter is used)
55                 char *nick = parameters[0];
56                 if (nick[0] == '-')
57                 {
58                         // removing an item from the list
59                         nick++;
60                         // fetch their silence list
61                         silencelist* sl = (silencelist*)user->GetExt("silence_list");
62                         // does it contain any entries and does it exist?
63                         if (sl)
64                         {
65                                 if (sl->size())
66                                 {
67                                         for (silencelist::iterator i = sl->begin(); i != sl->end(); i++)
68                                         {
69                                                 // search through for the item
70                                                 irc::string listitem = i->c_str();
71                                                 irc::string target = nick;
72                                                 if (listitem == target)
73                                                 {
74                                                         sl->erase(i);
75                                                         WriteServ(user->fd,"950 %s %s :Removed %s!*@* from silence list",user->nick, user->nick,nick);
76                                                         // we have modified the vector from within a loop, we must now bail out
77                                                         return;
78                                                 }
79                                         }
80                                 }
81                                 if (!sl->size())
82                                 {
83                                         // tidy up -- if a user's list is empty, theres no use having it
84                                         // hanging around in the user record.
85                                         delete sl;
86                                         user->Shrink("silence_list");
87                                 }
88                         }
89                 }
90                 else if (nick[0] == '+')
91                 {
92                         nick++;
93                         // fetch the user's current silence list
94                         silencelist* sl = (silencelist*)user->GetExt("silence_list");
95                         // what, they dont have one??? WE'RE ALL GONNA DIE! ...no, we just create an empty one.
96                         if (!sl)
97                         {
98                                 sl = new silencelist;
99                                 user->Extend(std::string("silence_list"),(char*)sl);
100                         }
101                         // add the nick to it -- silence only takes nicks for some reason even though its list shows masks
102                         for (silencelist::iterator n = sl->begin(); n != sl->end();  n++)
103                         {
104                                 irc::string listitem = n->c_str();
105                                 irc::string target = nick;
106                                 if (listitem == target)
107                                 {
108                                         WriteServ(user->fd,"952 %s %s :%s is already on your silence list",user->nick, user->nick,nick);
109                                         return;
110                                 }
111                         }
112                         sl->push_back(std::string(nick));
113                         WriteServ(user->fd,"951 %s %s :Added %s!*@* to silence list",user->nick, user->nick,nick);
114                         return;
115                 }
116         }
117         return;
118 }
119
120
121 class ModuleSilence : public Module
122 {
123         Server *Srv;
124  public:
125  
126         ModuleSilence()
127         {
128                 Srv = new Server;
129                 Srv->AddCommand("SILENCE",handle_silence,0,0,"m_silence.so");
130         }
131
132         virtual void OnUserQuit(userrec* user)
133         {
134                 // when the user quits tidy up any silence list they might have just to keep things tidy
135                 // and to prevent a HONKING BIG MEMORY LEAK!
136                 silencelist* sl = (silencelist*)user->GetExt("silence_list");
137                 if (sl)
138                 {
139                         delete sl;
140                         user->Shrink("silence_list");
141                 }
142         }
143
144         virtual void On005Numeric(std::string &output)
145         {
146                 // we don't really have a limit...
147                 output = output + " SILENCE=999";
148         }
149         
150         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text)
151         {
152                 // im not sure how unreal's silence operates but ours is sensible. It blocks notices and
153                 // privmsgs from people on the silence list, directed privately at the user.
154                 // channel messages are unaffected (ever tried to follow the flow of conversation in
155                 // a channel when you've set an ignore on the two most talkative people?)
156                 if (target_type == TYPE_USER)
157                 {
158                         userrec* u = (userrec*)dest;
159                         silencelist* sl = (silencelist*)u->GetExt("silence_list");
160                         if (sl)
161                         {
162                                 for (silencelist::const_iterator c = sl->begin(); c != sl->end(); c++)
163                                 {
164                                         irc::string listitem = c->c_str();
165                                         irc::string target = user->nick;
166                                         if (listitem == target)
167                                         {
168                                                 return 1;
169                                         }
170                                 }
171                         }
172                 }
173                 return 0;
174         }
175
176         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text)
177         {
178                 if (target_type == TYPE_USER)
179                 {
180                         userrec* u = (userrec*)dest;
181                         silencelist* sl = (silencelist*)u->GetExt("silence_list");
182                         if (sl)
183                         {
184                                 for (silencelist::const_iterator c = sl->begin(); c != sl->end(); c++)
185                                 {
186                                         irc::string listitem = c->c_str();
187                                         irc::string target = user->nick;
188                                         if (listitem == target)
189                                         {
190                                                 return 1;
191                                         }
192                                 }
193                         }
194                 }
195                 return 0;
196         }
197
198         virtual ~ModuleSilence()
199         {
200                 delete Srv;
201         }
202         
203         virtual Version GetVersion()
204         {
205                 return Version(1,0,0,1,VF_VENDOR);
206         }
207 };
208
209
210 class ModuleSilenceFactory : public ModuleFactory
211 {
212  public:
213         ModuleSilenceFactory()
214         {
215         }
216         
217         ~ModuleSilenceFactory()
218         {
219         }
220         
221         virtual Module * CreateModule()
222         {
223                 return new ModuleSilence;
224         }
225         
226 };
227
228
229 extern "C" void * init_module( void )
230 {
231         return new ModuleSilenceFactory;
232 }
233