]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_kicknorejoin.cpp
Automatically attach modules to events
[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 /** Handles channel mode +J
31  */
32 class KickRejoin : public ModeHandler
33 {
34         static const unsigned int max = 60;
35  public:
36         SimpleExtItem<delaylist> ext;
37         KickRejoin(Module* Creator)
38                 : ModeHandler(Creator, "kicknorejoin", 'J', PARAM_SETONLY, MODETYPE_CHANNEL)
39                 , ext("norejoinusers", Creator)
40         {
41         }
42
43         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE
44         {
45                 if (adding)
46                 {
47                         int v = ConvToInt(parameter);
48                         if (v <= 0)
49                                 return MODEACTION_DENY;
50                         if (parameter == channel->GetModeParameter(this))
51                                 return MODEACTION_DENY;
52
53                         if ((IS_LOCAL(source) && ((unsigned int)v > max)))
54                                 v = max;
55
56                         parameter = ConvToStr(v);
57                 }
58                 else
59                 {
60                         if (!channel->IsModeSet(this))
61                                 return MODEACTION_DENY;
62
63                         ext.unset(channel);
64                 }
65                 return MODEACTION_ALLOW;
66         }
67 };
68
69 class ModuleKickNoRejoin : public Module
70 {
71         KickRejoin kr;
72
73 public:
74         ModuleKickNoRejoin()
75                 : kr(this)
76         {
77         }
78
79         void init() CXX11_OVERRIDE
80         {
81                 ServerInstance->Modules->AddService(kr);
82                 ServerInstance->Modules->AddService(kr.ext);
83         }
84
85         ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE
86         {
87                 if (chan)
88                 {
89                         delaylist* dl = kr.ext.get(chan);
90                         if (dl)
91                         {
92                                 for (delaylist::iterator iter = dl->begin(); iter != dl->end(); )
93                                 {
94                                         if (iter->second > ServerInstance->Time())
95                                         {
96                                                 if (iter->first == user->uuid)
97                                                 {
98                                                         std::string modeparam = chan->GetModeParameter(&kr);
99                                                         user->WriteNumeric(ERR_DELAYREJOIN, "%s %s :You must wait %s seconds after being kicked to rejoin (+J)",
100                                                                 user->nick.c_str(), chan->name.c_str(), modeparam.c_str());
101                                                         return MOD_RES_DENY;
102                                                 }
103                                                 ++iter;
104                                         }
105                                         else
106                                         {
107                                                 // Expired record, remove.
108                                                 dl->erase(iter++);
109                                         }
110                                 }
111
112                                 if (dl->empty())
113                                         kr.ext.unset(chan);
114                         }
115                 }
116                 return MOD_RES_PASSTHRU;
117         }
118
119         void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts) CXX11_OVERRIDE
120         {
121                 if (memb->chan->IsModeSet(&kr) && (IS_LOCAL(memb->user)) && (source != memb->user))
122                 {
123                         delaylist* dl = kr.ext.get(memb->chan);
124                         if (!dl)
125                         {
126                                 dl = new delaylist;
127                                 kr.ext.set(memb->chan, dl);
128                         }
129                         (*dl)[memb->user->uuid] = ServerInstance->Time() + ConvToInt(memb->chan->GetModeParameter(&kr));
130                 }
131         }
132
133         Version GetVersion() CXX11_OVERRIDE
134         {
135                 return Version("Channel mode to delay rejoin after kick", VF_VENDOR);
136         }
137 };
138
139 MODULE_INIT(ModuleKickNoRejoin)