]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_timedbans.cpp
Updated to keep lowermap const within hashcomp.cpp
[user/henk/code/inspircd.git] / src / modules / m_timedbans.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 /* $ModDesc: Adds timed bans */
18
19 /*
20  * ToDo:
21  *   Err... not a lot really.
22  */ 
23
24 #include <stdio.h>
25 #include <vector>
26 #include "users.h"
27 #include "channels.h"
28 #include "modules.h"
29 #include "helperfuncs.h"
30 #include "hashcomp.h"
31
32 Server *Srv;
33          
34 class TimedBan
35 {
36  public:
37         std::string channel;
38         std::string mask;
39         time_t expire;
40 };
41
42 typedef std::vector<TimedBan> timedbans;
43 timedbans TimedBanList;
44
45 void handle_tban(char **parameters, int pcnt, userrec *user)
46 {
47         chanrec* channel = Srv->FindChannel(parameters[0]);
48         if (channel)
49         {
50                 std::string cm = Srv->ChanMode(user,channel);
51                 if ((cm == "%") || (cm == "@"))
52                 {
53                         if (!Srv->IsValidMask(parameters[2]))
54                         {
55                                 Srv->SendServ(user->fd,"NOTICE "+std::string(user->nick)+" :Invalid ban mask");
56                                 return;
57                         }
58                         for (timedbans::iterator i = TimedBanList.begin(); i < TimedBanList.end(); i++)
59                         {
60                                 irc::string listitem = i->mask.c_str();
61                                 irc::string target = parameters[2];
62                                 irc::string listchan = i->channel.c_str();
63                                 irc::string targetchan = parameters[0];
64                                 if ((listitem == target) && (listchan == targetchan))
65                                 {
66                                         Srv->SendServ(user->fd,"NOTICE "+std::string(user->nick)+" :The ban "+std::string(parameters[2])+" is already on the banlist of "+std::string(parameters[0]));
67                                         return;
68                                 }
69                         }
70                         TimedBan T;
71                         std::string channelname = parameters[0];
72                         unsigned long expire = Srv->CalcDuration(parameters[1]) + time(NULL);
73                         if (Srv->CalcDuration(parameters[1]) < 1)
74                         {
75                                 Srv->SendServ(user->fd,"NOTICE "+std::string(user->nick)+" :Invalid ban time");
76                                 return;
77                         }
78                         char duration[MAXBUF];
79                         snprintf(duration,MAXBUF,"%lu",Srv->CalcDuration(parameters[1]));
80                         std::string mask = parameters[2];
81                         char *setban[3];
82                         setban[0] = parameters[0];
83                         setban[1] = "+b";
84                         setban[2] = parameters[2];
85                         // use CallCommandHandler to make it so that the user sets the mode
86                         // themselves
87                         Srv->CallCommandHandler("MODE",setban,3,user);
88                         T.channel = channelname;
89                         T.mask = mask;
90                         T.expire = expire;
91                         TimedBanList.push_back(T);
92                         Srv->SendChannelServerNotice(Srv->GetServerName(),channel,"NOTICE "+std::string(channel->name)+" :"+std::string(user->nick)+" added a timed ban on "+mask+" lasting for "+std::string(duration)+" seconds.");
93                         return;
94                 }
95                 else WriteServ(user->fd,"482 %s %s :You must be at least a half-operator to change modes on this channel",user->nick, channel->name);
96                 return;
97         }
98         WriteServ(user->fd,"401 %s %s :No such channel",user->nick, parameters[0]);
99 }
100
101 class ModuleTimedBans : public Module
102 {
103  public:
104         ModuleTimedBans()
105         {
106                 Srv = new Server;
107                 Srv->AddCommand("TBAN",handle_tban,0,3,"m_timedbans.so");
108                 TimedBanList.clear();
109         }
110         
111         virtual ~ModuleTimedBans()
112         {
113                 delete Srv;
114                 TimedBanList.clear();
115         }
116
117         virtual int OnDelBan(userrec* source, chanrec* chan, std::string banmask)
118         {
119                 for (timedbans::iterator i = TimedBanList.begin(); i < TimedBanList.end(); i++)
120                 {
121                         irc::string listitem = banmask.c_str();
122                         irc::string target = i->mask.c_str();
123                         if (listitem == target)
124                         {
125                                 TimedBanList.erase(i);
126                                 break;
127                         }
128                 }
129                 return 0;
130         }
131
132         virtual void OnBackgroundTimer(time_t curtime)
133         {
134                 bool again = true;
135                 while (again)
136                 {
137                         again = false;
138                         for (timedbans::iterator i = TimedBanList.begin(); i < TimedBanList.end(); i++)
139                         {
140                                 if (curtime > i->expire)
141                                 {
142                                         chanrec* cr = Srv->FindChannel(i->channel);
143                                         again = true;
144                                         if (cr)
145                                         {
146                                                 Srv->SendChannelServerNotice(Srv->GetServerName(),cr,"NOTICE "+std::string(cr->name)+" :Timed ban on "+i->mask+" expired.");
147                                                 char *setban[3];
148                                                 setban[0] = (char*)i->channel.c_str();
149                                                 setban[1] = "-b";
150                                                 setban[2] = (char*)i->mask.c_str();
151                                                 // kludge alert!
152                                                 // ::SendMode expects a userrec* to send the numeric replies
153                                                 // back to, so we create it a fake user that isnt in the user
154                                                 // hash and set its descriptor to FD_MAGIC_NUMBER so the data
155                                                 // falls into the abyss :p
156                                                 userrec* temp = new userrec;
157                                                 temp->fd = FD_MAGIC_NUMBER;
158                                                 Srv->SendMode(setban,3,temp);
159                                                 delete temp;
160                                         }
161                                         // we used to delete the item here, but we dont need to as the servermode above does it for us,
162                                         break;
163                                 }
164                         }
165                 }
166         }
167         
168         virtual Version GetVersion()
169         {
170                 return Version(1,0,0,0,VF_VENDOR);
171         }
172 };
173
174
175 class ModuleTimedBansFactory : public ModuleFactory
176 {
177  public:
178         ModuleTimedBansFactory()
179         {
180         }
181         
182         ~ModuleTimedBansFactory()
183         {
184         }
185         
186         virtual Module * CreateModule()
187         {
188                 return new ModuleTimedBans;
189         }
190         
191 };
192
193
194 extern "C" void * init_module( void )
195 {
196         return new ModuleTimedBansFactory;
197 }