2020-04-29 06:33:49 +02:00
# File: BanList.pm
2011-02-13 06:07:02 +01:00
#
2021-08-02 00:53:58 +02:00
# Purpose: Implements functions related to maintaining and tracking channel
# bans/mutes. Maintains ban/mute queues and timeouts.
2011-02-13 06:07:02 +01:00
2021-07-11 00:00:22 +02:00
# SPDX-FileCopyrightText: 2021 Pragmatic Software <pragma78@gmail.com>
# SPDX-License-Identifier: MIT
2017-03-05 22:33:31 +01:00
2021-07-21 07:44:51 +02:00
package PBot::Core::BanList ;
2020-02-15 23:38:32 +01:00
2021-07-21 07:44:51 +02:00
use parent 'PBot::Core::Class' ;
2011-02-13 06:07:02 +01:00
2021-06-19 06:23:34 +02:00
use PBot::Imports ;
2019-07-11 03:40:53 +02:00
2011-02-13 06:07:02 +01:00
use Time::HiRes qw/gettimeofday/ ;
use Time::Duration ;
2020-04-29 06:33:49 +02:00
use POSIX qw/strftime/ ;
2020-02-15 23:38:32 +01:00
2011-02-13 06:07:02 +01:00
sub initialize {
2020-02-15 23:38:32 +01:00
my ( $ self , % conf ) = @ _ ;
2014-05-23 07:03:54 +02:00
2020-04-29 06:33:49 +02:00
$ self - > { pbot } - > { registry } - > add_default ( 'text' , 'banlist' , 'chanserv_ban_timeout' , '604800' ) ;
$ self - > { pbot } - > { registry } - > add_default ( 'text' , 'banlist' , 'mute_timeout' , '604800' ) ;
$ self - > { pbot } - > { registry } - > add_default ( 'text' , 'banlist' , 'debug' , '0' ) ;
2020-05-31 11:39:33 +02:00
$ self - > { pbot } - > { registry } - > add_default ( 'text' , 'banlist' , 'mute_mode_char' , 'q' ) ;
2020-04-29 06:33:49 +02:00
2021-07-24 01:41:32 +02:00
my $ data_dir = $ self - > { pbot } - > { registry } - > get_value ( 'general' , 'data_dir' ) ;
2021-07-24 04:22:25 +02:00
$ self - > { 'ban-exemptions' } = PBot::Core::Storage::DualIndexHashObject - > new (
2021-07-24 01:41:32 +02:00
pbot = > $ self - > { pbot } ,
name = > 'Ban exemptions' ,
filename = > "$data_dir/ban-exemptions" ,
) ;
2021-07-24 04:22:25 +02:00
$ self - > { banlist } = PBot::Core::Storage::DualIndexHashObject - > new (
2020-04-29 06:33:49 +02:00
pbot = > $ self - > { pbot } ,
name = > 'Ban List' ,
2021-07-24 01:41:32 +02:00
filename = > "$data_dir/banlist" ,
2020-05-15 02:42:11 +02:00
save_queue_timeout = > 15 ,
2020-04-29 06:33:49 +02:00
) ;
2014-11-01 01:15:21 +01:00
2021-07-24 04:22:25 +02:00
$ self - > { quietlist } = PBot::Core::Storage::DualIndexHashObject - > new (
2020-04-29 06:33:49 +02:00
pbot = > $ self - > { pbot } ,
name = > 'Quiet List' ,
2021-07-24 01:41:32 +02:00
filename = > "$data_dir/quietlist" ,
2020-05-15 02:42:11 +02:00
save_queue_timeout = > 15 ,
2020-04-29 06:33:49 +02:00
) ;
2020-02-08 20:04:13 +01:00
2021-07-24 01:41:32 +02:00
$ self - > { 'ban-exemptions' } - > load ;
2020-04-29 06:33:49 +02:00
$ self - > { banlist } - > load ;
$ self - > { quietlist } - > load ;
2021-07-24 01:41:32 +02:00
$ self - > enqueue_timeouts ( $ self - > { banlist } , 'b' ) ;
2020-05-31 11:39:33 +02:00
$ self - > enqueue_timeouts ( $ self - > { quietlist } , $ self - > { pbot } - > { registry } - > get_value ( 'banlist' , 'mute_mode_char' ) ) ;
2020-04-29 06:33:49 +02:00
$ self - > { ban_queue } = { } ;
$ self - > { unban_queue } = { } ;
2021-06-22 02:26:24 +02:00
$ self - > { pbot } - > { event_queue } - > enqueue ( sub { $ self - > flush_unban_queue } , 30 , 'Flush unban queue' ) ;
2011-02-13 06:07:02 +01:00
}
2021-08-02 00:53:58 +02:00
sub checkban {
my ( $ self , $ channel , $ mode , $ mask ) = @ _ ;
$ mask = $ self - > nick_to_banmask ( $ mask ) ;
2020-05-31 11:39:33 +02:00
2021-08-02 00:53:58 +02:00
my $ data ;
2020-05-31 11:39:33 +02:00
2021-08-02 00:53:58 +02:00
if ( $ mode eq 'b' ) {
$ data = $ self - > { banlist } - > get_data ( $ channel , $ mask ) ;
} elsif ( $ mode eq $ self - > { pbot } - > { registry } - > get_value ( 'banlist' , 'mute_mode_char' ) ) {
$ data = $ self - > { quietlist } - > get_data ( $ channel , $ mask ) ;
2020-05-31 11:39:33 +02:00
}
2021-08-02 00:53:58 +02:00
if ( not defined $ data ) {
return "$mask is not " . ( $ mode eq 'b' ? 'banned' : 'muted' ) . "." ;
}
2014-11-01 01:15:21 +01:00
2021-08-02 00:53:58 +02:00
my $ result = "$mask " . ( $ mode eq 'b' ? 'banned' : 'quieted' ) . " in $channel " ;
2014-11-01 01:15:21 +01:00
2021-08-02 00:53:58 +02:00
if ( defined $ data - > { timestamp } ) {
my $ date = strftime "%a %b %e %H:%M:%S %Y %Z" , localtime $ data - > { timestamp } ;
my $ ago = concise ago ( time - $ data - > { timestamp } ) ;
$ result . = "on $date ($ago) " ;
}
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
$ result . = "by $data->{owner} " if defined $ data - > { owner } ;
$ result . = "for $data->{reason} " if defined $ data - > { reason } ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
if ( exists $ data - > { timeout } and $ data - > { timeout } > 0 ) {
my $ duration = concise duration ( $ data - > { timeout } - gettimeofday ) ;
$ result . = "($duration remaining)" ;
}
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
return $ result ;
}
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
sub is_ban_exempted {
my ( $ self , $ channel , $ hostmask ) = @ _ ;
$ channel = lc $ channel ;
$ hostmask = lc $ hostmask ;
return 1 if $ self - > { 'ban-exemptions' } - > exists ( $ channel , $ hostmask ) ;
2020-04-29 06:33:49 +02:00
return 0 ;
}
2021-08-02 00:53:58 +02:00
sub is_banned {
my ( $ self , $ channel , $ nick , $ user , $ host ) = @ _ ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
my $ message_account = $ self - > { pbot } - > { messagehistory } - > { database } - > get_message_account ( $ nick , $ user , $ host ) ;
my @ nickserv_accounts = $ self - > { pbot } - > { messagehistory } - > { database } - > get_nickserv_accounts ( $ message_account ) ;
push @ nickserv_accounts , undef ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
my $ banned = undef ;
foreach my $ nickserv_account ( @ nickserv_accounts ) {
my $ baninfos = $ self - > get_baninfo ( $ channel , "$nick!$user\@$host" , $ nickserv_account ) ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
if ( defined $ baninfos ) {
foreach my $ baninfo ( @$ baninfos ) {
my $ u = $ self - > { pbot } - > { users } - > loggedin ( $ baninfo - > { channel } , "$nick!$user\@$host" ) ;
my $ whitelisted = $ self - > { pbot } - > { capabilities } - > userhas ( $ u , 'is-whitelisted' ) ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
if ( $ self - > is_ban_exempted ( $ baninfo - > { channel } , $ baninfo - > { mask } ) || $ whitelisted ) {
$ self - > { pbot } - > { logger } - > log ( "[BanList] is_banned: $nick!$user\@$host banned as $baninfo->{mask} in $baninfo->{channel}, but allowed through whitelist\n" ) ;
} else {
if ( $ channel eq lc $ baninfo - > { channel } ) {
my $ mode = $ baninfo - > { type } eq 'b' ? "banned" : "quieted" ;
$ self - > { pbot } - > { logger } - > log ( "[BanList] is_banned: $nick!$user\@$host $mode as $baninfo->{mask} in $baninfo->{channel} by $baninfo->{owner}\n" ) ;
$ banned = $ baninfo ;
last ;
}
2020-04-29 06:33:49 +02:00
}
}
}
}
2021-08-02 00:53:58 +02:00
return $ banned ;
2020-04-29 06:33:49 +02:00
}
2021-08-02 00:53:58 +02:00
sub has_ban_timeout {
my ( $ self , $ channel , $ mask , $ mode ) = @ _ ;
$ mode || = 'b' ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
my $ list = $ mode eq 'b' ? $ self - > { banlist } : $ self - > { quietlist } ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
my $ data = $ list - > get_data ( $ channel , $ mask ) ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
if ( defined $ data && $ data - > { timeout } > 0 ) {
return 1 ;
} else {
return 0 ;
2020-04-29 06:33:49 +02:00
}
}
2021-08-02 00:53:58 +02:00
sub ban_user_timed {
my ( $ self , $ channel , $ mode , $ mask , $ length , $ owner , $ reason , $ immediately ) = @ _ ;
2020-05-31 11:39:33 +02:00
2021-08-02 00:53:58 +02:00
$ channel = lc $ channel ;
$ mask = lc $ mask ;
2017-05-21 11:20:44 +02:00
2021-08-02 00:53:58 +02:00
$ mask = $ self - > nick_to_banmask ( $ mask ) ;
$ self - > ban_user ( $ channel , $ mode , $ mask , $ immediately ) ;
2020-02-15 23:38:32 +01:00
2021-08-02 00:53:58 +02:00
my $ data = {
timeout = > $ length > 0 ? gettimeofday + $ length : - 1 ,
owner = > $ owner ,
reason = > $ reason ,
timestamp = > time ,
} ;
2020-02-15 23:38:32 +01:00
2021-08-02 00:53:58 +02:00
if ( $ mode eq 'b' ) {
$ self - > { banlist } - > remove ( $ channel , $ mask , 'timeout' ) ;
$ self - > { banlist } - > add ( $ channel , $ mask , $ data ) ;
} elsif ( $ mode eq $ self - > { pbot } - > { registry } - > get_value ( 'banlist' , 'mute_mode_char' ) ) {
$ self - > { quietlist } - > remove ( $ channel , $ mask , 'timeout' ) ;
$ self - > { quietlist } - > add ( $ channel , $ mask , $ data ) ;
2020-04-29 06:33:49 +02:00
}
2021-08-02 00:53:58 +02:00
my $ method = $ mode eq 'b' ? 'unban' : 'unmute' ;
$ self - > { pbot } - > { event_queue } - > dequeue_event ( "$method $channel $mask" ) ;
2020-04-29 06:33:49 +02:00
2021-08-02 00:53:58 +02:00
if ( $ length > 0 ) {
$ self - > enqueue_unban ( $ channel , $ mode , $ mask , $ length ) ;
2017-05-21 11:20:44 +02:00
}
2014-11-01 01:15:21 +01:00
}
2020-04-29 06:33:49 +02:00
sub ban_user {
my ( $ self , $ channel , $ mode , $ mask , $ immediately ) = @ _ ;
$ mode || = 'b' ;
$ self - > { pbot } - > { logger } - > log ( "Banning $channel +$mode $mask\n" ) ;
$ self - > add_to_ban_queue ( $ channel , $ mode , $ mask ) ;
if ( not defined $ immediately or $ immediately != 0 ) {
$ self - > flush_ban_queue ;
}
}
2020-02-15 23:38:32 +01:00
2020-04-29 06:33:49 +02:00
sub unban_user {
my ( $ self , $ channel , $ mode , $ mask , $ immediately ) = @ _ ;
$ mask = lc $ mask ;
$ channel = lc $ channel ;
$ mode || = 'b' ;
$ self - > { pbot } - > { logger } - > log ( "Unbanning $channel -$mode $mask\n" ) ;
$ self - > unmode_user ( $ channel , $ mode , $ mask , $ immediately ) ;
}
2020-02-15 23:38:32 +01:00
2020-04-29 06:33:49 +02:00
sub unmode_user {
my ( $ self , $ channel , $ mode , $ mask , $ immediately ) = @ _ ;
2014-11-01 01:15:21 +01:00
2020-04-29 06:33:49 +02:00
$ mask = lc $ mask ;
$ channel = lc $ channel ;
$ self - > { pbot } - > { logger } - > log ( "Removing mode $mode from $mask in $channel\n" ) ;
my $ bans = $ self - > get_bans ( $ channel , $ mask ) ;
my % unbanned ;
if ( not defined $ bans ) {
2020-04-30 23:27:10 +02:00
push @$ bans , { mask = > $ mask , type = > $ mode } ;
2020-04-29 06:33:49 +02:00
}
foreach my $ ban ( @$ bans ) {
2020-04-30 23:27:10 +02:00
next if $ ban - > { type } ne $ mode ;
2020-04-29 07:36:13 +02:00
next if exists $ unbanned { $ ban - > { mask } } ;
$ unbanned { $ ban - > { mask } } = 1 ;
$ self - > add_to_unban_queue ( $ channel , $ mode , $ ban - > { mask } ) ;
2020-04-29 06:33:49 +02:00
}
$ self - > flush_unban_queue if $ immediately ;
}
sub get_bans {
my ( $ self , $ channel , $ mask ) = @ _ ;
my $ masks ;
my ( $ message_account , $ hostmask ) ;
if ( $ mask !~ m/[!@]/ ) {
( $ message_account , $ hostmask ) = $ self - > { pbot } - > { messagehistory } - > { database } - > find_message_account_by_nick ( $ mask ) ;
$ hostmask = $ mask if not defined $ message_account ;
} else {
$ message_account = $ self - > { pbot } - > { messagehistory } - > { database } - > get_message_account_id ( $ mask ) ;
$ hostmask = $ mask ;
}
if ( defined $ message_account ) {
my $ nickserv = $ self - > { pbot } - > { messagehistory } - > { database } - > get_current_nickserv_account ( $ message_account ) ;
$ masks = $ self - > get_baninfo ( $ channel , $ hostmask , $ nickserv ) ;
}
my % akas = $ self - > { pbot } - > { messagehistory } - > { database } - > get_also_known_as ( $ hostmask ) ;
foreach my $ aka ( keys % akas ) {
next if $ akas { $ aka } - > { type } == $ self - > { pbot } - > { messagehistory } - > { database } - > { alias_type } - > { WEAK } ;
next if $ akas { $ aka } - > { nickchange } == 1 ;
my $ nickserv = $ self - > { pbot } - > { messagehistory } - > { database } - > get_current_nickserv_account ( $ akas { $ aka } - > { id } ) ;
my $ b = $ self - > get_baninfo ( $ channel , $ aka , $ nickserv ) ;
if ( defined $ b ) {
push @$ masks , @$ b ;
}
}
return $ masks ;
2011-02-13 10:05:48 +01:00
}
sub get_baninfo {
2020-04-29 06:33:49 +02:00
my ( $ self , $ channel , $ mask , $ nickserv ) = @ _ ;
my ( $ bans , $ ban_nickserv ) ;
2013-07-28 12:31:12 +02:00
2020-04-29 06:33:49 +02:00
$ nickserv = undef if not length $ nickserv ;
$ nickserv = lc $ nickserv if defined $ nickserv ;
2013-07-30 15:12:21 +02:00
2020-04-29 06:33:49 +02:00
if ( $ self - > { pbot } - > { registry } - > get_value ( 'banlist' , 'debug' ) ) {
my $ ns = defined $ nickserv ? $ nickserv : "[undefined]" ;
$ self - > { pbot } - > { logger } - > log ( "[get-baninfo] Getting baninfo for $mask in $channel using nickserv $ns\n" ) ;
2020-02-15 23:38:32 +01:00
}
2013-08-03 19:26:49 +02:00
2020-02-15 23:38:32 +01:00
my ( $ nick , $ user , $ host ) = $ mask =~ m/([^!]+)!([^@]+)@(.*)/ ;
2015-06-14 01:08:57 +02:00
2020-04-29 06:33:49 +02:00
my @ lists = (
2020-05-31 11:39:33 +02:00
[ 'b' , $ self - > { banlist } ] ,
[ $ self - > { pbot } - > { registry } - > get_value ( 'banlist' , 'mute_mode_char' ) , $ self - > { quietlist } ] ,
2020-04-29 06:33:49 +02:00
) ;
2013-07-28 12:31:12 +02:00
2020-04-29 06:33:49 +02:00
foreach my $ entry ( @ lists ) {
my ( $ mode , $ list ) = @$ entry ;
foreach my $ banmask ( $ list - > get_keys ( $ channel ) ) {
if ( $ banmask =~ m/^\$a:(.*)/ ) { $ ban_nickserv = lc $ 1 ; }
else { $ ban_nickserv = "" ; }
2015-06-14 01:08:57 +02:00
2020-04-29 06:33:49 +02:00
my $ banmask_regex = quotemeta $ banmask ;
$ banmask_regex =~ s/\\\*/.*?/g ;
$ banmask_regex =~ s/\\\?/./g ;
2015-06-14 01:08:57 +02:00
2020-04-29 06:33:49 +02:00
my $ banned ;
$ banned = 1 if defined $ nickserv and $ nickserv eq $ ban_nickserv ;
$ banned = 1 if $ mask =~ m/^$banmask_regex$/i ;
2015-06-14 01:08:57 +02:00
2020-04-29 06:33:49 +02:00
if ( $ banmask =~ m {\@gateway/web/irccloud.com} and $ host =~ m {^gateway/web/irccloud.com} ) {
my ( $ bannick , $ banuser , $ banhost ) = $ banmask =~ m/([^!]+)!([^@]+)@(.*)/ ;
$ banned = $ 1 if lc $ user eq lc $ banuser ;
2020-02-15 23:38:32 +01:00
}
2015-06-14 01:08:57 +02:00
2020-02-15 23:38:32 +01:00
if ( $ banned ) {
2020-04-29 06:33:49 +02:00
my $ data = $ list - > get_data ( $ channel , $ banmask ) ;
my $ baninfo = {
mask = > $ banmask ,
channel = > $ channel ,
owner = > $ data - > { owner } ,
when = > $ data - > { timestamp } ,
type = > $ mode ,
reason = > $ data - > { reason } ,
timeout = > $ data - > { timeout } ,
} ;
2020-02-15 23:38:32 +01:00
push @$ bans , $ baninfo ;
}
}
2011-02-13 10:05:48 +01:00
}
2020-02-15 23:38:32 +01:00
return $ bans ;
2011-02-13 06:07:02 +01:00
}
2020-04-29 06:33:49 +02:00
sub nick_to_banmask {
my ( $ self , $ mask ) = @ _ ;
if ( $ mask !~ m/[!@\$]/ ) {
my ( $ message_account , $ hostmask ) = $ self - > { pbot } - > { messagehistory } - > { database } - > find_message_account_by_nick ( $ mask ) ;
if ( defined $ hostmask ) {
my $ nickserv = $ self - > { pbot } - > { messagehistory } - > { database } - > get_current_nickserv_account ( $ message_account ) ;
if ( defined $ nickserv && length $ nickserv ) { $ mask = '$a:' . $ nickserv ; }
else {
my ( $ nick , $ user , $ host ) = $ hostmask =~ m/([^!]+)!([^@]+)@(.*)/ ;
$ mask = "*!$user\@" . $ self - > { pbot } - > { antiflood } - > address_to_mask ( $ host ) ;
}
} else {
$ mask . = '!*@*' ;
}
}
2020-06-13 22:22:44 +02:00
# make sure $mask always has full wildcards
# there's probably a better way to do this...
if ( $ mask !~ /^\$/ ) {
if ( $ mask !~ /!/ ) {
$ mask . = '!*@*' ;
} elsif ( $ mask !~ /@/ ) {
$ mask =~ s/\*?$/*@*/ ;
} else {
$ mask =~ s/\@$/@*/ ;
}
2020-06-13 04:53:43 +02:00
}
2020-04-29 06:33:49 +02:00
return $ mask ;
}
sub add_to_ban_queue {
my ( $ self , $ channel , $ mode , $ mask ) = @ _ ;
if ( not grep { $ _ eq $ mask } @ { $ self - > { ban_queue } - > { $ channel } - > { $ mode } } ) {
push @ { $ self - > { ban_queue } - > { $ channel } - > { $ mode } } , $ mask ;
$ self - > { pbot } - > { logger } - > log ( "Added +$mode $mask for $channel to ban queue.\n" ) ;
}
}
2021-08-02 00:53:58 +02:00
sub add_to_unban_queue {
my ( $ self , $ channel , $ mode , $ mask ) = @ _ ;
if ( not grep { $ _ eq $ mask } @ { $ self - > { unban_queue } - > { $ channel } - > { $ mode } } ) {
push @ { $ self - > { unban_queue } - > { $ channel } - > { $ mode } } , $ mask ;
$ self - > { pbot } - > { logger } - > log ( "Added -$mode $mask for $channel to unban queue.\n" ) ;
}
}
2020-04-29 06:33:49 +02:00
sub flush_ban_queue {
my $ self = shift ;
my $ MAX_COMMANDS = 4 ;
my $ commands = 0 ;
foreach my $ channel ( keys % { $ self - > { ban_queue } } ) {
my $ done = 0 ;
while ( not $ done ) {
my ( $ list , $ count , $ modes ) ;
$ list = '' ;
$ modes = '+' ;
$ count = 0 ;
foreach my $ mode ( keys % { $ self - > { ban_queue } - > { $ channel } } ) {
while ( @ { $ self - > { ban_queue } - > { $ channel } - > { $ mode } } ) {
my $ target = pop @ { $ self - > { ban_queue } - > { $ channel } - > { $ mode } } ;
$ list . = " $target" ;
$ modes . = $ mode ;
2021-06-25 03:28:49 +02:00
last if + + $ count >= $ self - > { pbot } - > { isupport } - > { MODES } // 1 ;
2020-04-29 06:33:49 +02:00
}
if ( not @ { $ self - > { ban_queue } - > { $ channel } - > { $ mode } } ) {
delete $ self - > { ban_queue } - > { $ channel } - > { $ mode } ;
}
2021-06-25 03:28:49 +02:00
last if $ count >= $ self - > { pbot } - > { isupport } - > { MODES } // 1 ;
2020-04-29 06:33:49 +02:00
}
if ( not keys % { $ self - > { ban_queue } - > { $ channel } } ) {
delete $ self - > { ban_queue } - > { $ channel } ;
$ done = 1 ;
}
if ( $ count ) {
$ self - > { pbot } - > { chanops } - > add_op_command ( $ channel , "mode $channel $modes $list" ) ;
$ self - > { pbot } - > { chanops } - > gain_ops ( $ channel ) ;
return if + + $ commands >= $ MAX_COMMANDS ;
}
}
}
}
sub flush_unban_queue {
my $ self = shift ;
my $ MAX_COMMANDS = 4 ;
my $ commands = 0 ;
foreach my $ channel ( keys % { $ self - > { unban_queue } } ) {
my $ done = 0 ;
while ( not $ done ) {
my ( $ list , $ count , $ modes ) ;
$ list = '' ;
$ modes = '-' ;
$ count = 0 ;
foreach my $ mode ( keys % { $ self - > { unban_queue } - > { $ channel } } ) {
while ( @ { $ self - > { unban_queue } - > { $ channel } - > { $ mode } } ) {
my $ target = pop @ { $ self - > { unban_queue } - > { $ channel } - > { $ mode } } ;
$ list . = " $target" ;
$ modes . = $ mode ;
2021-06-25 03:28:49 +02:00
last if + + $ count >= $ self - > { pbot } - > { isupport } - > { MODES } // 1 ;
2020-04-29 06:33:49 +02:00
}
if ( not @ { $ self - > { unban_queue } - > { $ channel } - > { $ mode } } ) {
delete $ self - > { unban_queue } - > { $ channel } - > { $ mode } ;
}
2021-06-25 03:28:49 +02:00
last if $ count >= $ self - > { pbot } - > { isupport } - > { MODES } // 1 ;
2020-04-29 06:33:49 +02:00
}
if ( not keys % { $ self - > { unban_queue } - > { $ channel } } ) {
delete $ self - > { unban_queue } - > { $ channel } ;
$ done = 1 ;
}
if ( $ count ) {
$ self - > { pbot } - > { chanops } - > add_op_command ( $ channel , "mode $channel $modes $list" ) ;
$ self - > { pbot } - > { chanops } - > gain_ops ( $ channel ) ;
return if + + $ commands >= $ MAX_COMMANDS ;
}
}
}
}
sub enqueue_unban {
my ( $ self , $ channel , $ mode , $ hostmask , $ interval ) = @ _ ;
my $ method = $ mode eq 'b' ? 'unban' : 'unmute' ;
2021-06-22 02:26:24 +02:00
$ self - > { pbot } - > { event_queue } - > enqueue_event (
2020-04-29 06:33:49 +02:00
sub {
2021-08-02 00:53:58 +02:00
$ self - > { pbot } - > { event_queue } - > update_interval ( "$method $channel $hostmask" , 60 * 5 , 1 ) ; # try again in 5 minutes
2020-04-29 06:33:49 +02:00
return if not $ self - > { pbot } - > { joined_channels } ;
$ self - > unban_user ( $ channel , $ mode , $ hostmask ) ;
} , $ interval , "$method $channel $hostmask" , 1
) ;
}
sub enqueue_timeouts {
my ( $ self , $ list , $ mode ) = @ _ ;
my $ now = time ;
foreach my $ channel ( $ list - > get_keys ) {
foreach my $ mask ( $ list - > get_keys ( $ channel ) ) {
my $ timeout = $ list - > get_data ( $ channel , $ mask , 'timeout' ) ;
2020-04-29 07:36:13 +02:00
next if defined $ timeout and $ timeout <= 0 ;
next if not defined $ timeout ;
2020-04-29 06:33:49 +02:00
my $ interval = $ timeout - $ now ;
$ interval = 10 if $ interval < 10 ;
$ self - > enqueue_unban ( $ channel , $ mode , $ mask , $ interval ) ;
}
}
}
2011-02-13 06:07:02 +01:00
1 ;