]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_kicknorejoin.cpp
Remove VF_COMMON from mode-provider modules (no longer needed due to better CAPAB...
[user/henk/code/inspircd.git] / src / modules / m_kicknorejoin.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2010 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #include "inspircd.h"
15
16 /* $ModDesc: Provides channel mode +J (delay rejoin after kick) */
17
18 typedef std::map<User*, time_t> delaylist;
19
20 /** Handles channel mode +J
21  */
22 class KickRejoin : public ParamChannelModeHandler
23 {
24  public:
25         SimpleExtItem<delaylist> ext;
26         KickRejoin(Module* Creator) : ParamChannelModeHandler(Creator, "kicknorejoin", 'J'), ext("norejoinusers", Creator) { }
27
28         bool ParamValidate(std::string& parameter)
29         {
30                 int v = atoi(parameter.c_str());
31                 if (v <= 0)
32                         return false;
33                 parameter = ConvToStr(v);
34                 return true;
35         }
36
37         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
38         {
39                 ModeAction rv = ParamChannelModeHandler::OnModeChange(source, dest, channel, parameter, adding);
40                 if (rv == MODEACTION_ALLOW && !adding)
41                         ext.unset(channel);
42                 return rv;
43         }
44 };
45
46 class ModuleKickNoRejoin : public Module
47 {
48         KickRejoin kr;
49
50 public:
51
52         ModuleKickNoRejoin()
53                 : kr(this)
54         {
55                 if (!ServerInstance->Modes->AddMode(&kr))
56                         throw ModuleException("Could not add new modes!");
57                 ServerInstance->Extensions.Register(&kr.ext);
58                 Implementation eventlist[] = { I_OnUserPreJoin, I_OnUserKick };
59                 ServerInstance->Modules->Attach(eventlist, this, 2);
60         }
61
62         ModResult OnUserPreJoin(User* user, Channel* chan, const char* cname, std::string &privs, const std::string &keygiven)
63         {
64                 if (chan)
65                 {
66                         delaylist* dl = kr.ext.get(chan);
67                         if (dl)
68                         {
69                                 std::vector<User*> itemstoremove;
70
71                                 for (delaylist::iterator iter = dl->begin(); iter != dl->end(); iter++)
72                                 {
73                                         if (iter->second > ServerInstance->Time())
74                                         {
75                                                 if (iter->first == user)
76                                                 {
77                                                         user->WriteNumeric(ERR_DELAYREJOIN, "%s %s :You must wait %s seconds after being kicked to rejoin (+J)",
78                                                                 user->nick.c_str(), chan->name.c_str(), chan->GetModeParameter(&kr).c_str());
79                                                         return MOD_RES_DENY;
80                                                 }
81                                         }
82                                         else
83                                         {
84                                                 // Expired record, remove.
85                                                 itemstoremove.push_back(iter->first);
86                                         }
87                                 }
88
89                                 for (unsigned int i = 0; i < itemstoremove.size(); i++)
90                                         dl->erase(itemstoremove[i]);
91
92                                 if (!dl->size())
93                                         kr.ext.unset(chan);
94                         }
95                 }
96                 return MOD_RES_PASSTHRU;
97         }
98
99         void OnUserKick(User* source, Membership* memb, const std::string &reason, CUList& excepts)
100         {
101                 if (memb->chan->IsModeSet(&kr) && (source != memb->user))
102                 {
103                         delaylist* dl = kr.ext.get(memb->chan);
104                         if (dl)
105                         {
106                                 dl = new delaylist;
107                                 kr.ext.set(memb->chan, dl);
108                         }
109                         (*dl)[memb->user] = ServerInstance->Time() + atoi(memb->chan->GetModeParameter(&kr).c_str());
110                 }
111         }
112
113         ~ModuleKickNoRejoin()
114         {
115         }
116
117         Version GetVersion()
118         {
119                 return Version("Channel mode to delay rejoin after kick", VF_VENDOR);
120         }
121 };
122
123
124 MODULE_INIT(ModuleKickNoRejoin)