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