]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_kicknorejoin.cpp
Increment serverstats::Collisions when a collision is handled, not when a module...
[user/henk/code/inspircd.git] / src / modules / m_kicknorejoin.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2008 Pippijn van Steenhoven <pip88nl@gmail.com>
6  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
7  *   Copyright (C) 2006-2007 Robin Burchell <robin+git@viroteck.net>
8  *   Copyright (C) 2006 John Brooks <john.brooks@dereferenced.net>
9  *   Copyright (C) 2006 Craig Edwards <craigedwards@brainbox.cc>
10  *   Copyright (C) 2006 Oliver Lupton <oliverlupton@gmail.com>
11  *
12  * This file is part of InspIRCd.  InspIRCd is free software: you can
13  * redistribute it and/or modify it under the terms of the GNU General Public
14  * License as published by the Free Software Foundation, version 2.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
19  * details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23  */
24
25
26 #include "inspircd.h"
27
28 typedef std::map<std::string, time_t> delaylist;
29
30 struct KickRejoinData
31 {
32         delaylist kicked;
33         unsigned int delay;
34
35         KickRejoinData(unsigned int Delay) : delay(Delay) { }
36 };
37
38 /** Handles channel mode +J
39  */
40 class KickRejoin : public ParamMode<KickRejoin, SimpleExtItem<KickRejoinData> >
41 {
42         static const unsigned int max = 60;
43  public:
44         KickRejoin(Module* Creator)
45                 : ParamMode<KickRejoin, SimpleExtItem<KickRejoinData> >(Creator, "kicknorejoin", 'J')
46         {
47         }
48
49         ModeAction OnSet(User* source, Channel* channel, std::string& parameter)
50         {
51                 int v = ConvToInt(parameter);
52                 if (v <= 0)
53                         return MODEACTION_DENY;
54
55                 if ((IS_LOCAL(source) && ((unsigned int)v > max)))
56                         v = max;
57
58                 ext.set(channel, new KickRejoinData(v));
59                 return MODEACTION_ALLOW;
60         }
61
62         void SerializeParam(Channel* chan, const KickRejoinData* krd, std::string& out)
63         {
64                 out.append(ConvToStr(krd->delay));
65         }
66 };
67
68 class ModuleKickNoRejoin : public Module
69 {
70         KickRejoin kr;
71
72 public:
73         ModuleKickNoRejoin()
74                 : kr(this)
75         {
76         }
77
78         ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE
79         {
80                 if (chan)
81                 {
82                         KickRejoinData* data = kr.ext.get(chan);
83                         if (data)
84                         {
85                                 delaylist& kicked = data->kicked;
86                                 for (delaylist::iterator iter = kicked.begin(); iter != kicked.end(); )
87                                 {
88                                         if (iter->second > ServerInstance->Time())
89                                         {
90                                                 if (iter->first == user->uuid)
91                                                 {
92                                                         user->WriteNumeric(ERR_DELAYREJOIN, "%s :You must wait %u seconds after being kicked to rejoin (+J)",
93                                                                 chan->name.c_str(), data->delay);
94                                                         return MOD_RES_DENY;
95                                                 }
96                                                 ++iter;
97                                         }
98                                         else
99                                         {
100                                                 // Expired record, remove.
101                                                 kicked.erase(iter++);
102                                         }
103                                 }
104                         }
105                 }
106                 return MOD_RES_PASSTHRU;
107         }
108
109         void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts) CXX11_OVERRIDE
110         {
111                 if ((!IS_LOCAL(memb->user)) || (source == memb->user))
112                         return;
113
114                 KickRejoinData* data = kr.ext.get(memb->chan);
115                 if (data)
116                 {
117                         data->kicked[memb->user->uuid] = ServerInstance->Time() + data->delay;
118                 }
119         }
120
121         Version GetVersion() CXX11_OVERRIDE
122         {
123                 return Version("Channel mode to delay rejoin after kick", VF_VENDOR);
124         }
125 };
126
127 MODULE_INIT(ModuleKickNoRejoin)