]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_kicknorejoin.cpp
Remove $Core and $Mod* comments apart from $ModDep.
[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                 Implementation eventlist[] = { I_OnUserPreJoin, I_OnUserKick };
84                 ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
85         }
86
87         ModResult OnUserPreJoin(LocalUser* user, Channel* chan, const std::string& cname, std::string& privs, const std::string& keygiven) CXX11_OVERRIDE
88         {
89                 if (chan)
90                 {
91                         delaylist* dl = kr.ext.get(chan);
92                         if (dl)
93                         {
94                                 for (delaylist::iterator iter = dl->begin(); iter != dl->end(); )
95                                 {
96                                         if (iter->second > ServerInstance->Time())
97                                         {
98                                                 if (iter->first == user->uuid)
99                                                 {
100                                                         std::string modeparam = chan->GetModeParameter(&kr);
101                                                         user->WriteNumeric(ERR_DELAYREJOIN, "%s %s :You must wait %s seconds after being kicked to rejoin (+J)",
102                                                                 user->nick.c_str(), chan->name.c_str(), modeparam.c_str());
103                                                         return MOD_RES_DENY;
104                                                 }
105                                                 ++iter;
106                                         }
107                                         else
108                                         {
109                                                 // Expired record, remove.
110                                                 dl->erase(iter++);
111                                         }
112                                 }
113
114                                 if (dl->empty())
115                                         kr.ext.unset(chan);
116                         }
117                 }
118                 return MOD_RES_PASSTHRU;
119         }
120
121         void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts) CXX11_OVERRIDE
122         {
123                 if (memb->chan->IsModeSet(&kr) && (IS_LOCAL(memb->user)) && (source != memb->user))
124                 {
125                         delaylist* dl = kr.ext.get(memb->chan);
126                         if (!dl)
127                         {
128                                 dl = new delaylist;
129                                 kr.ext.set(memb->chan, dl);
130                         }
131                         (*dl)[memb->user->uuid] = ServerInstance->Time() + ConvToInt(memb->chan->GetModeParameter(&kr));
132                 }
133         }
134
135         Version GetVersion() CXX11_OVERRIDE
136         {
137                 return Version("Channel mode to delay rejoin after kick", VF_VENDOR);
138         }
139 };
140
141 MODULE_INIT(ModuleKickNoRejoin)