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