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