]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_knock.cpp
Fix for bug #415, affects only trunk (wish i'd known this before i started!)
[user/henk/code/inspircd.git] / src / modules / m_knock.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/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 support for /KNOCK and mode +K */
17
18 /** Handles the /KNOCK command
19  */
20 class cmd_knock : public command_t
21 {
22  public:
23         cmd_knock (InspIRCd* Instance) : command_t(Instance,"KNOCK", 0, 2)
24         {
25                 this->source = "m_knock.so";
26                 syntax = "<channel> <reason>";
27                 TRANSLATE3(TR_TEXT, TR_TEXT, TR_END);
28         }
29         
30         CmdResult Handle (const char** parameters, int pcnt, userrec *user)
31         {
32                 chanrec* c = ServerInstance->FindChan(parameters[0]);
33
34                 if (!c)
35                 {
36                         user->WriteServ("401 %s %s :No such channel",user->nick, parameters[0]);
37                         return CMD_FAILURE;
38                 }
39
40                 std::string line;
41
42                 if (c->IsModeSet('K'))
43                 {
44                         user->WriteServ("480 %s :Can't KNOCK on %s, +K is set.",user->nick, c->name);
45                         return CMD_FAILURE;
46                 }
47
48                 for (int i = 1; i < pcnt - 1; i++)
49                 {
50                         line = line + std::string(parameters[i]) + " ";
51                 }
52                 line = line + std::string(parameters[pcnt-1]);
53
54                 if (!c->modes[CM_INVITEONLY])
55                 {
56                         user->WriteServ("480 %s :Can't KNOCK on %s, channel is not invite only so knocking is pointless!",user->nick, c->name);
57                         return CMD_FAILURE;
58                 }
59
60                 c->WriteChannelWithServ((char*)ServerInstance->Config->ServerName,  "NOTICE %s :User %s is KNOCKing on %s (%s)", c->name, user->nick, c->name, line.c_str());
61                 user->WriteServ("NOTICE %s :KNOCKing on %s",user->nick,c->name);
62                 return CMD_SUCCESS;
63         }
64 };
65
66 /** Handles channel mode +K
67  */
68 class Knock : public ModeHandler
69 {
70  public:
71         Knock(InspIRCd* Instance) : ModeHandler(Instance, 'K', 0, 0, false, MODETYPE_CHANNEL, false) { }
72
73         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
74         {
75                 if (adding)
76                 {
77                         if (!channel->IsModeSet('K'))
78                         {
79                                 channel->SetMode('K',true);
80                                 return MODEACTION_ALLOW;
81                         }
82                 }
83                 else
84                 {
85                         if (channel->IsModeSet('K'))
86                         {
87                                 channel->SetMode('K',false);
88                                 return MODEACTION_ALLOW;
89                         }
90                 }
91
92                 return MODEACTION_DENY;
93         }
94 };
95
96 class ModuleKnock : public Module
97 {
98         cmd_knock* mycommand;
99         Knock* kn;
100  public:
101         ModuleKnock(InspIRCd* Me) : Module(Me)
102         {
103                 kn = new Knock(ServerInstance);
104
105                 if (!ServerInstance->AddMode(kn, 'K'))
106                         throw ModuleException("Could not add new modes!");
107
108                 mycommand = new cmd_knock(ServerInstance);
109                 ServerInstance->AddCommand(mycommand);
110         }
111
112         void Implements(char* List)
113         {
114         }
115
116         virtual ~ModuleKnock()
117         {
118                 ServerInstance->Modes->DelMode(kn);
119                 delete kn;
120         }
121
122         virtual Version GetVersion()
123         {
124                 return Version(1, 1, 0, 1, VF_COMMON | VF_VENDOR, API_VERSION);
125         }
126 };
127
128 MODULE_INIT(ModuleKnock)