]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_delaymsg.cpp
Add Base64 encode/decode functions to the core
[user/henk/code/inspircd.git] / src / modules / m_delaymsg.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 #include <stdarg.h>
16
17 /* $ModDesc: Provides channelmode +d <int>, to deny messages to a channel until <int> seconds. */
18
19 class DelayMsgMode : public ModeHandler
20 {
21  private:
22         CUList empty;
23  public:
24         LocalIntExt jointime;
25         DelayMsgMode(Module* Parent) : ModeHandler(Parent, "delaymsg", 'd', PARAM_SETONLY, MODETYPE_CHANNEL)
26                 , jointime("delaymsg", Parent)
27         {
28                 levelrequired = OP_VALUE;
29         }
30
31         bool ResolveModeConflict(std::string &their_param, const std::string &our_param, Channel*)
32         {
33                 return (atoi(their_param.c_str()) < atoi(our_param.c_str()));
34         }
35
36         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding);
37 };
38
39 class ModuleDelayMsg : public Module
40 {
41  private:
42         DelayMsgMode djm;
43  public:
44         ModuleDelayMsg() : djm(this)
45         {
46                 if (!ServerInstance->Modes->AddMode(&djm))
47                         throw ModuleException("Could not add new modes!");
48                 ServerInstance->Extensions.Register(&djm.jointime);
49                 Implementation eventlist[] = { I_OnUserJoin, I_OnUserPreMessage};
50                 ServerInstance->Modules->Attach(eventlist, this, 2);
51         }
52         ~ModuleDelayMsg();
53         Version GetVersion();
54         void OnUserJoin(Membership* memb, bool sync, bool created, CUList&);
55         ModResult OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list);
56 };
57
58 ModeAction DelayMsgMode::OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
59 {
60         if (adding)
61         {
62                 /* Setting a new limit, sanity check */
63                 long limit = atoi(parameter.c_str());
64
65                 /* Wrap low values at 32768 */
66                 if (limit < 0)
67                         limit = 0x7FFF;
68
69                 parameter = ConvToStr(limit);
70         }
71         else
72         {
73                 /*
74                  * Clean up metadata
75                  */
76                 const UserMembList* names = channel->GetUsers();
77                 for (UserMembCIter n = names->begin(); n != names->end(); ++n)
78                         jointime.set(n->second, 0);
79         }
80         channel->SetModeParam('d', adding ? parameter : "");
81         return MODEACTION_ALLOW;
82 }
83
84 ModuleDelayMsg::~ModuleDelayMsg()
85 {
86 }
87
88 Version ModuleDelayMsg::GetVersion()
89 {
90         return Version("Provides channelmode +d <int>, to deny messages to a channel until <int> seconds.", VF_VENDOR);
91 }
92
93 void ModuleDelayMsg::OnUserJoin(Membership* memb, bool sync, bool created, CUList&)
94 {
95         if (memb->chan->IsModeSet('d'))
96         {
97                 djm.jointime.set(memb, ServerInstance->Time());
98         }
99 }
100
101 ModResult ModuleDelayMsg::OnUserPreMessage(User* user, void* dest, int target_type, std::string &text, char status, CUList &exempt_list)
102 {
103         /* Server origin */
104         if (!user)
105                 return MOD_RES_PASSTHRU;
106
107         if (target_type != TYPE_CHANNEL)
108                 return MOD_RES_PASSTHRU;
109
110         Channel* channel = (Channel*) dest;
111         Membership* memb = channel->GetUser(user);
112
113         if (!memb)
114                 return MOD_RES_PASSTHRU;
115         
116         time_t ts = djm.jointime.get(memb);
117
118         if (ts == 0)
119                 return MOD_RES_PASSTHRU;
120
121         std::string len = channel->GetModeParameter('d');
122
123         if (ts + atoi(len.c_str()) > ServerInstance->Time())
124         {
125                 if (channel->GetPrefixValue(user) < VOICE_VALUE)
126                 {
127                         user->WriteNumeric(404, "%s %s :You must wait %s seconds after joining to send to channel (+d)",
128                                 user->nick.c_str(), channel->name.c_str(), len.c_str());
129                         return MOD_RES_DENY;
130                 }
131         }
132         else
133         {
134                 /* Timer has expired, we can stop checking now */
135                 djm.jointime.set(memb, 0);
136         }
137         return MOD_RES_PASSTHRU;
138 }
139
140 MODULE_INIT(ModuleDelayMsg)
141