]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_nicklock.cpp
Merge pull request #92 from Robby-/insp20-headers
[user/henk/code/inspircd.git] / src / modules / m_nicklock.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org>
6  *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
7  *   Copyright (C) 2005-2006 Craig Edwards <craigedwards@brainbox.cc>
8  *
9  * This file is part of InspIRCd.  InspIRCd is free software: you can
10  * redistribute it and/or modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation, version 2.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #include "inspircd.h"
24
25 /* $ModDesc: Provides the NICKLOCK command, allows an oper to chage a users nick and lock them to it until they quit */
26
27 /** Handle /NICKLOCK
28  */
29 class CommandNicklock : public Command
30 {
31  public:
32         LocalIntExt& locked;
33         CommandNicklock (Module* Creator, LocalIntExt& ext) : Command(Creator,"NICKLOCK", 2),
34                 locked(ext)
35         {
36                 flags_needed = 'o';
37                 syntax = "<oldnick> <newnick>";
38                 TRANSLATE3(TR_NICK, TR_TEXT, TR_END);
39         }
40
41         CmdResult Handle(const std::vector<std::string>& parameters, User *user)
42         {
43                 User* target = ServerInstance->FindNick(parameters[0]);
44
45                 if (!target)
46                 {
47                         user->WriteServ("NOTICE %s :*** No such nickname: '%s'", user->nick.c_str(), parameters[0].c_str());
48                         return CMD_FAILURE;
49                 }
50
51                 /* Do local sanity checks and bails */
52                 if (IS_LOCAL(user))
53                 {
54                         if (!ServerInstance->IsNick(parameters[1].c_str(), ServerInstance->Config->Limits.NickMax))
55                         {
56                                 user->WriteServ("NOTICE %s :*** Invalid nickname '%s'", user->nick.c_str(), parameters[1].c_str());
57                                 return CMD_FAILURE;
58                         }
59
60                         user->WriteServ("947 %s %s :Nickname now locked.", user->nick.c_str(), parameters[1].c_str());
61                 }
62
63                 /* If we made it this far, extend the user */
64                 if (IS_LOCAL(target))
65                 {
66                         locked.set(target, 1);
67
68                         std::string oldnick = target->nick;
69                         if (target->ForceNickChange(parameters[1].c_str()))
70                                 ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used NICKLOCK to change and hold "+oldnick+" to "+parameters[1]);
71                         else
72                         {
73                                 std::string newnick = target->nick;
74                                 ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used NICKLOCK, but "+oldnick+" failed nick change to "+parameters[1]+" and was locked to "+newnick+" instead");
75                         }
76                 }
77
78                 return CMD_SUCCESS;
79         }
80
81         RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
82         {
83                 User* dest = ServerInstance->FindNick(parameters[0]);
84                 if (dest)
85                         return ROUTE_OPT_UCAST(dest->server);
86                 return ROUTE_LOCALONLY;
87         }
88 };
89
90 /** Handle /NICKUNLOCK
91  */
92 class CommandNickunlock : public Command
93 {
94  public:
95         LocalIntExt& locked;
96         CommandNickunlock (Module* Creator, LocalIntExt& ext) : Command(Creator,"NICKUNLOCK", 1),
97                 locked(ext)
98         {
99                 flags_needed = 'o';
100                 syntax = "<locked-nick>";
101                 TRANSLATE2(TR_NICK, TR_END);
102         }
103
104         CmdResult Handle (const std::vector<std::string>& parameters, User *user)
105         {
106                 User* target = ServerInstance->FindNick(parameters[0]);
107
108                 if (!target)
109                 {
110                         user->WriteServ("NOTICE %s :*** No such nickname: '%s'", user->nick.c_str(), parameters[0].c_str());
111                         return CMD_FAILURE;
112                 }
113
114                 if (IS_LOCAL(target))
115                 {
116                         if (locked.set(target, 0))
117                         {
118                                 ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used NICKUNLOCK on "+target->nick);
119                                 user->SendText(":%s 945 %s %s :Nickname now unlocked.",
120                                         ServerInstance->Config->ServerName.c_str(),user->nick.c_str(),target->nick.c_str());
121                         }
122                         else
123                         {
124                                 user->SendText(":%s 946 %s %s :This user's nickname is not locked.",
125                                         ServerInstance->Config->ServerName.c_str(),user->nick.c_str(),target->nick.c_str());
126                                 return CMD_FAILURE;
127                         }
128                 }
129
130                 return CMD_SUCCESS;
131         }
132
133         RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
134         {
135                 User* dest = ServerInstance->FindNick(parameters[0]);
136                 if (dest)
137                         return ROUTE_OPT_UCAST(dest->server);
138                 return ROUTE_LOCALONLY;
139         }
140 };
141
142
143 class ModuleNickLock : public Module
144 {
145         LocalIntExt locked;
146         CommandNicklock cmd1;
147         CommandNickunlock cmd2;
148  public:
149         ModuleNickLock()
150                 : locked("nick_locked", this), cmd1(this, locked), cmd2(this, locked)
151         {
152                 ServerInstance->AddCommand(&cmd1);
153                 ServerInstance->AddCommand(&cmd2);
154                 ServerInstance->Extensions.Register(&locked);
155                 ServerInstance->Modules->Attach(I_OnUserPreNick, this);
156         }
157
158         ~ModuleNickLock()
159         {
160         }
161
162         Version GetVersion()
163         {
164                 return Version("Provides the NICKLOCK command, allows an oper to chage a users nick and lock them to it until they quit", VF_OPTCOMMON | VF_VENDOR);
165         }
166
167         ModResult OnUserPreNick(User* user, const std::string &newnick)
168         {
169                 if (!IS_LOCAL(user))
170                         return MOD_RES_PASSTHRU;
171
172                 if (ServerInstance->NICKForced.get(user)) /* Allow forced nick changes */
173                         return MOD_RES_PASSTHRU;
174
175                 if (locked.get(user))
176                 {
177                         user->WriteNumeric(447, "%s :You cannot change your nickname (your nick is locked)",user->nick.c_str());
178                         return MOD_RES_DENY;
179                 }
180                 return MOD_RES_PASSTHRU;
181         }
182
183         void Prioritize()
184         {
185                 Module *nflood = ServerInstance->Modules->Find("m_nickflood.so");
186                 ServerInstance->Modules->SetPriority(this, I_OnUserPreJoin, PRIORITY_BEFORE, &nflood);
187         }
188 };
189
190 MODULE_INIT(ModuleNickLock)