]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_redirect.cpp
Alter SetModeParam to take const char* to save on casts, notice a load of modules...
[user/henk/code/inspircd.git] / src / modules / m_redirect.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 using namespace std;
18
19 #include <stdio.h>
20 #include "users.h"
21 #include "channels.h"
22 #include "modules.h"
23 #include "helperfuncs.h"
24
25 /* $ModDesc: Provides channel mode +L (limit redirection) */
26
27 class Redirect : public ModeHandler
28 {
29  public:
30         Redirect() : ModeHandler('L', 1, 0, false, MODETYPE_CHANNEL, false) { }
31
32         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
33         {
34                 if (adding)
35                 {
36                         chanrec* c = NULL;
37
38                         if (!IsValidChannelName(parameter.c_str()))
39                         {
40                                 WriteServ(user->fd,"403 %s %s :Invalid channel name",user->nick, parameter.c_str());
41                                 parameter = "";
42                                 return MODEACTION_DENY;
43                         }
44
45                         c = Srv->FindChannel(parameter);
46                         if (c)
47                         {
48                                 /* Fix by brain: Dont let a channel be linked to *itself* either */
49                                 if ((c == target) || (c->IsModeSet('L')))
50                                 {
51                                         WriteServ(user->fd,"690 %s :Circular redirection, mode +L to %s not allowed.",user->nick,parameter.c_str());
52                                         parameter = "";
53                                         return MODEACTION_DENY;
54                                 }
55                         }
56
57                         c->SetMode('L', true);
58                         c->SetModeParam('L', parameter);
59                         return MODEACTION_ALLOW;
60                 }
61         }
62 };
63
64 class ModuleRedirect : public Module
65 {
66         Server *Srv;
67         
68  public:
69  
70         ModuleRedirect(Server* Me)
71                 : Module::Module(Me)
72         {
73                 Srv = Me;
74                 Srv->AddExtendedMode('L',MT_CHANNEL,false,1,0);
75         }
76         
77         virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
78         {
79                 if ((modechar == 'L') && (type == MT_CHANNEL))
80                 {
81                         if (mode_on)
82                         {
83                                 std::string ChanToJoin = params[0];
84                                 chanrec *c;
85
86                                 if (!IsValidChannelName(ChanToJoin.c_str()))
87                                 {
88                                         WriteServ(user->fd,"403 %s %s :Invalid channel name",user->nick, ChanToJoin.c_str());
89                                         return 0;
90                                 }
91
92                                 c = Srv->FindChannel(ChanToJoin);
93                                 if (c)
94                                 {
95                                         /* Fix by brain: Dont let a channel be linked to *itself* either */
96                                         if ((c == target) || (c->IsModeSet('L')))
97                                         {
98                                                 WriteServ(user->fd,"690 %s :Circular redirection, mode +L to %s not allowed.",user->nick,params[0].c_str());
99                                                 return 0;
100                                         }
101                                 }
102                         }
103                         return 1;
104                 }
105                 return 0;
106         }
107
108         void Implements(char* List)
109         {
110                 List[I_On005Numeric] = List[I_OnUserPreJoin] = List[I_OnExtendedMode] = 1;
111         }
112
113         virtual void On005Numeric(std::string &output)
114         {
115                 InsertMode(output, "L", 3);
116         }
117         
118         virtual int OnUserPreJoin(userrec* user, chanrec* chan, const char* cname)
119         {
120                 if (chan)
121                 {
122                         if (chan->IsModeSet('L'))
123                         {
124                                 if (Srv->CountUsers(chan) >= chan->limit)
125                                 {
126                                         std::string channel = chan->GetModeParameter('L');
127                                         WriteServ(user->fd,"470 %s :%s has become full, so you are automatically being transferred to the linked channel %s",user->nick,cname,channel.c_str());
128                                         Srv->JoinUserToChannel(user,channel.c_str(),"");
129                                         return 1;
130                                 }
131                         }
132                 }
133                 return 0;
134         }
135
136         virtual ~ModuleRedirect()
137         {
138         }
139         
140         virtual Version GetVersion()
141         {
142                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
143         }
144 };
145
146
147 class ModuleRedirectFactory : public ModuleFactory
148 {
149  public:
150         ModuleRedirectFactory()
151         {
152         }
153         
154         ~ModuleRedirectFactory()
155         {
156         }
157         
158         virtual Module * CreateModule(Server* Me)
159         {
160                 return new ModuleRedirect(Me);
161         }
162         
163 };
164
165
166 extern "C" void * init_module( void )
167 {
168         return new ModuleRedirectFactory;
169 }
170