]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_remove.cpp
Updated to keep lowermap const within hashcomp.cpp
[user/henk/code/inspircd.git] / src / modules / m_remove.cpp
1 /* Support for a dancer-style /remove command, an alternative to /kick to try and avoid auto-rejoin-on-kick scripts */
2 /* Written by Om, 25-03-05 */
3
4 #include <stdio.h>
5 #include <string>
6 #include "users.h"
7 #include "channels.h"
8 #include "modules.h"
9
10 /* $ModDesc: Provides a /remove command, this is mostly an alternative to /kick, except makes users appear to have parted the channel */
11
12 /*      
13  * This module supports the use of the +q and +a usermodes, but should work without them too.
14  * Usage of the command is restricted to +hoaq, and you cannot remove a user with a "higher" level than yourself.
15  * eg: +h can remove +hv and users with no modes. +a can remove +aohv and users with no modes.
16 */
17
18 Server *Srv;
19
20 /* This little function just converts a chanmode character (~ & @ & +) into an integer (5 4 3 2 1) */
21 int chartolevel(std::string privs)
22 {
23         int level;
24         if(privs == "~")
25                 level = 5;
26         else
27         if(privs == "&")
28                 level = 4;
29         else
30         if(privs == "@")
31                 level = 3;
32         else
33         if(privs == "%") {
34                 level = 2;
35         } else {
36                 level = 1;
37         }
38         return level;
39 }
40          
41 void handle_remove(char **parameters, int pcnt, userrec *user)
42 {
43         /* Look up the user we're meant to be removing from the channel */
44         userrec* target = Srv->FindNick(std::string(parameters[0]));
45         /* And the channel we're meant to be removing them from */
46         chanrec* channel = Srv->FindChannel(std::string(parameters[1]));
47         /* And see if the person calling the command has access to use it on the channel */
48         std::string privs = Srv->ChanMode(user, channel);
49         /* Check what privs the person being removed has */
50         std::string targetprivs = Srv->ChanMode(target, channel);
51         int tlevel;
52         int ulevel;
53         int n = 2;
54         std::string result;
55         
56         /* This turns all the parameters after the first two into a single string, so the part reason can be multi-word */
57         while (n < pcnt)
58         {
59                 result=result + std::string(" ") + std::string(parameters[n]);
60                 n++;
61         }
62         
63         /* If the target nick exists... */
64         if (target && channel)
65         {
66                 for (int x = 0; x < strlen(parameters[1]); x++)
67                 {
68                                 if ((parameters[1][0] != '#') || (parameters[1][x] == ' ') || (parameters[1][x] == ','))
69                                 {
70                                         Srv->SendTo(NULL,user,"NOTICE "+std::string(user->nick)+" :*** Invalid characters in channel name");
71                                         return;
72                                 }
73                 }
74                 
75                 /* This is adding support for the +q and +a channel modes, basically if they are enabled, and the remover has them set. */
76                 /* Then we change the @|%|+ to & if they are +a, or ~ if they are +q */
77                 if (user->GetExt("cm_protect_"+std::string(channel->name)))
78                         privs = std::string("&");
79                 if (user->GetExt("cm_founder_"+std::string(channel->name)))
80                         privs = std::string("~");
81                         
82                 /* Now it's the same idea, except for the target */
83                 if (target->GetExt("cm_protect_"+std::string(channel->name)))
84                         targetprivs = std::string("&");
85                 if (target->GetExt("cm_founder_"+std::string(channel->name)))
86                         targetprivs = std::string("~");
87                         
88                 tlevel = chartolevel(targetprivs);
89                 ulevel = chartolevel(privs);
90                 
91                 /* If the user calling the command is either an admin, owner, operator or a half-operator on the channel */
92                 if(ulevel > 1)
93                 {
94                         /* For now, we'll let everyone remove their level and below, eg ops can remove ops, halfops, voices, and those with no mode (no moders actually are set to 1) */
95                         if(ulevel >= tlevel)
96                         {
97                                 Srv->PartUserFromChannel(target,std::string(parameters[1]), "Remove by "+std::string(user->nick)+":"+result);
98                                 Srv->SendTo(NULL,user,"NOTICE "+std::string(channel->name)+" : "+std::string(user->nick)+" removed "+std::string(target->nick)+ " from the channel");
99                                 Srv->SendTo(NULL,target,"NOTICE "+std::string(target->nick)+" :*** "+std::string(user->nick)+" removed you from "+std::string(channel->name)+" with the message:"+std::string(result));
100                         } else {
101                                 Srv->SendTo(NULL,user,"NOTICE "+std::string(user->nick)+" :*** You do not have access to remove "+std::string(target->nick)+" from the "+std::string(channel->name));
102                         }
103                 } else {
104                         Srv->SendTo(NULL,user,"NOTICE "+std::string(user->nick)+" :*** You do not have access to use /remove on "+std::string(channel->name));
105                 }
106         }
107 }
108
109
110 class ModuleRemove : public Module
111 {
112  public:
113         ModuleRemove()
114         {
115                 Srv = new Server;
116                 Srv->AddCommand("REMOVE", handle_remove, 0, 3, "m_remove.so");
117         }
118
119         virtual void On005Numeric(std::string &output)
120         {
121                 output = output + std::string(" REMOVE");
122         }
123         
124         virtual ~ModuleRemove()
125         {
126                 delete Srv;
127         }
128         
129         virtual Version GetVersion()
130         {
131                 return Version(1,0,0,1,VF_VENDOR);
132         }
133         
134 };
135
136 // stuff down here is the module-factory stuff. For basic modules you can ignore this.
137
138 class ModuleRemoveFactory : public ModuleFactory
139 {
140  public:
141         ModuleRemoveFactory()
142         {
143         }
144         
145         ~ModuleRemoveFactory()
146         {
147         }
148         
149         virtual Module * CreateModule()
150         {
151                 return new ModuleRemove;
152         }
153         
154 };
155
156
157 extern "C" void * init_module( void )
158 {
159         return new ModuleRemoveFactory;
160 }
161