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