2012-04-19 20:58:29 +02:00
/*
* InspIRCd - - Internet Relay Chat Daemon
2007-07-16 17:30:04 +00:00
*
2020-01-11 22:02:47 +00:00
* Copyright ( C ) 2017 B00mX0r < b00mx0r @ aureus . pw >
2020-01-31 12:48:25 +00:00
* Copyright ( C ) 2013 , 2018 , 2020 Sadie Powell < sadie @ witchery . services >
2020-01-11 22:02:47 +00:00
* Copyright ( C ) 2012 - 2013 , 2016 , 2018 Attila Molnar < attilamolnar @ hush . com >
* Copyright ( C ) 2012 , 2019 Robby < robby @ chatbelgie . be >
* Copyright ( C ) 2009 - 2010 Daniel De Graaf < danieldg @ inspircd . org >
* Copyright ( C ) 2009 Uli Schlachter < psychon @ inspircd . org >
2012-04-19 20:58:29 +02:00
* Copyright ( C ) 2007 Robin Burchell < robin + git @ viroteck . net >
2020-01-11 22:02:47 +00:00
* Copyright ( C ) 2007 Dennis Friis < peavey @ inspircd . org >
2021-03-05 02:04:16 +00:00
* Copyright ( C ) 2004 , 2006 , 2008 , 2010 Craig Edwards < brain @ inspircd . org >
2007-07-16 17:30:04 +00:00
*
2012-04-19 20:58:29 +02:00
* This file is part of InspIRCd . InspIRCd is free software : you can
* redistribute it and / or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation , version 2.
2007-07-16 17:30:04 +00:00
*
2012-04-19 20:58:29 +02:00
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE . See the GNU General Public License for more
* details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
2007-07-16 17:30:04 +00:00
*/
2012-04-19 20:58:29 +02:00
2007-07-16 17:30:04 +00:00
# include "inspircd.h"
2018-01-27 12:24:47 +00:00
enum
{
// From UnrealIRCd.
2018-04-22 14:31:28 +01:00
ERR_CANNOTKNOCK = 480 ,
// From ircd-ratbox.
2020-02-18 18:00:26 +00:00
RPL_KNOCK = 710 ,
RPL_KNOCKDLVR = 711 ,
2018-04-22 14:31:28 +01:00
ERR_CHANOPEN = 713 ,
ERR_KNOCKONCHAN = 714
2018-01-27 12:24:47 +00:00
} ;
2020-05-13 14:09:38 +01:00
// Actions which can be taken when a user knocks on a channel.
enum KnockNotify : uint8_t
{
// Send a notice when a user knocks on a channel.
KN_SEND_NOTICE = 1 ,
// Send a numeric when a user knocks on a channel.
KN_SEND_NUMERIC = 2 ,
// Send a notice and a numeric when a user knocks on a channel.
KN_SEND_BOTH = KN_SEND_NOTICE | KN_SEND_NUMERIC ,
} ;
2007-07-16 17:30:04 +00:00
/** Handles the /KNOCK command
*/
2021-10-01 05:15:29 +01:00
class CommandKnock final
: public Command
2007-07-16 17:30:04 +00:00
{
2021-06-01 01:48:14 +01:00
SimpleChannelMode & noknockmode ;
2013-06-18 18:30:10 +02:00
ChanModeReference inviteonlymode ;
2022-01-25 13:59:42 +00:00
public :
2020-05-13 14:09:38 +01:00
int notify ;
2021-06-01 01:48:14 +01:00
CommandKnock ( Module * Creator , SimpleChannelMode & Noknockmode )
2013-06-18 18:30:10 +02:00
: Command ( Creator , " KNOCK " , 2 , 2 )
, noknockmode ( Noknockmode )
, inviteonlymode ( Creator , " inviteonly " )
2007-07-16 17:30:04 +00:00
{
2020-04-14 16:41:31 +01:00
syntax = { " <channel> :<reason> " } ;
2010-01-31 19:54:33 +00:00
Penalty = 5 ;
2007-07-16 17:30:04 +00:00
}
2008-06-11 11:35:23 +00:00
2019-01-25 02:52:11 +00:00
CmdResult Handle ( User * user , const Params & parameters ) override
2007-07-16 17:30:04 +00:00
{
2020-06-21 04:25:45 +01:00
Channel * c = ServerInstance - > Channels . Find ( parameters [ 0 ] ) ;
2007-07-16 17:30:04 +00:00
if ( ! c )
{
2017-12-19 14:15:30 -08:00
user - > WriteNumeric ( Numerics : : NoSuchChannel ( parameters [ 0 ] ) ) ;
2020-10-26 23:40:24 +00:00
return CmdResult : : FAILURE ;
2007-07-16 17:30:04 +00:00
}
2008-01-30 01:07:14 +00:00
if ( c - > HasUser ( user ) )
2007-07-16 17:30:04 +00:00
{
2016-02-25 16:12:09 +01:00
user - > WriteNumeric ( ERR_KNOCKONCHAN , c - > name , InspIRCd : : Format ( " Can't KNOCK on %s, you are already on that channel. " , c - > name . c_str ( ) ) ) ;
2020-10-26 23:40:24 +00:00
return CmdResult : : FAILURE ;
2007-07-16 17:30:04 +00:00
}
2013-06-18 18:30:10 +02:00
if ( c - > IsModeSet ( noknockmode ) )
2007-07-16 17:30:04 +00:00
{
2018-01-27 12:24:47 +00:00
user - > WriteNumeric ( ERR_CANNOTKNOCK , InspIRCd : : Format ( " Can't KNOCK on %s, +K is set. " , c - > name . c_str ( ) ) ) ;
2020-10-26 23:40:24 +00:00
return CmdResult : : FAILURE ;
2007-07-16 17:30:04 +00:00
}
2013-06-18 18:30:10 +02:00
if ( ! c - > IsModeSet ( inviteonlymode ) )
2007-07-16 17:30:04 +00:00
{
2016-02-25 16:12:09 +01:00
user - > WriteNumeric ( ERR_CHANOPEN , c - > name , InspIRCd : : Format ( " Can't KNOCK on %s, channel is not invite only so knocking is pointless! " , c - > name . c_str ( ) ) ) ;
2020-10-26 23:40:24 +00:00
return CmdResult : : FAILURE ;
2007-07-16 17:30:04 +00:00
}
2020-05-13 14:09:38 +01:00
if ( notify & KN_SEND_NOTICE )
2020-02-18 18:00:26 +00:00
{
2016-03-05 16:46:03 +01:00
c - > WriteNotice ( InspIRCd : : Format ( " User %s is KNOCKing on %s (%s) " , user - > nick . c_str ( ) , c - > name . c_str ( ) , parameters [ 1 ] . c_str ( ) ) ) ;
2020-02-18 18:00:26 +00:00
user - > WriteNotice ( " KNOCKing on " + c - > name ) ;
}
2012-09-13 01:15:44 +02:00
2020-05-13 14:09:38 +01:00
if ( notify & KN_SEND_NUMERIC )
2018-08-13 20:17:46 +01:00
{
2020-02-18 18:00:26 +00:00
Numeric : : Numeric numeric ( RPL_KNOCK ) ;
2018-08-13 20:17:46 +01:00
numeric . push ( c - > name ) . push ( user - > GetFullHost ( ) ) . push ( " is KNOCKing: " + parameters [ 1 ] ) ;
ClientProtocol : : Messages : : Numeric numericmsg ( numeric , c - > name ) ;
c - > Write ( ServerInstance - > GetRFCEvents ( ) . numeric , numericmsg ) ;
2020-02-18 18:00:26 +00:00
user - > WriteNumeric ( RPL_KNOCKDLVR , c - > name , " KNOCKing on channel " ) ;
2018-08-13 20:17:46 +01:00
}
2012-09-13 01:15:44 +02:00
2020-10-26 23:40:24 +00:00
return CmdResult : : SUCCESS ;
2007-07-16 17:30:04 +00:00
}
2009-09-03 15:53:15 +00:00
2019-01-25 02:52:11 +00:00
RouteDescriptor GetRouting ( User * user , const Params & parameters ) override
2009-09-03 15:53:15 +00:00
{
2010-01-19 15:16:24 +00:00
return ROUTE_OPT_BCAST ;
2009-09-03 15:53:15 +00:00
}
2007-07-16 17:30:04 +00:00
} ;
2021-10-01 04:37:03 +01:00
class ModuleKnock final
: public Module
2007-07-16 17:30:04 +00:00
{
2021-06-01 01:48:14 +01:00
SimpleChannelMode kn ;
2009-09-02 00:43:04 +00:00
CommandKnock cmd ;
2013-06-18 18:30:10 +02:00
2022-01-25 13:59:42 +00:00
public :
2013-06-18 18:30:10 +02:00
ModuleKnock ( )
2020-04-11 14:00:48 +01:00
: Module ( VF_VENDOR | VF_OPTCOMMON , " Adds the /KNOCK command which allows users to request access to an invite-only channel and channel mode K (noknock) which allows channels to disable usage of this command. " )
2020-04-09 18:57:50 +01:00
, kn ( this , " noknock " , ' K ' )
2013-06-18 18:30:10 +02:00
, cmd ( this , kn )
2012-10-13 03:12:29 +02:00
{
}
2019-01-25 02:52:11 +00:00
void ReadConfig ( ConfigStatus & status ) override
2007-07-16 17:30:04 +00:00
{
2020-10-31 23:21:15 +00:00
auto tag = ServerInstance - > Config - > ConfValue ( " knock " ) ;
2020-05-13 14:09:38 +01:00
cmd . notify = tag - > getEnum ( " notify " , KN_SEND_NOTICE , {
{ " both " , KN_SEND_BOTH } ,
{ " notice " , KN_SEND_NOTICE } ,
{ " numeric " , KN_SEND_NUMERIC } ,
} ) ;
2007-07-16 17:30:04 +00:00
}
} ;
MODULE_INIT ( ModuleKnock )