2014-11-15 02:18:33 +01:00
# File: NickList.pm
# Author: pragma_
#
# Purpose: Maintains lists of nicks currently present in channels.
2019-06-26 18:34:19 +02:00
# Used to retrieve list of channels a nick is present in or to
2014-11-15 02:18:33 +01:00
# determine if a nick is present in a channel.
2017-03-05 22:33:31 +01:00
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
2014-11-15 02:18:33 +01:00
package PBot::NickList ;
2020-02-15 23:38:32 +01:00
2020-02-08 20:04:13 +01:00
use parent 'PBot::Class' ;
2014-11-15 02:18:33 +01:00
2020-02-08 20:04:13 +01:00
use warnings ; use strict ;
2019-07-11 03:40:53 +02:00
use feature 'unicode_strings' ;
2016-09-25 09:03:37 +02:00
use Text::Levenshtein qw/fastdistance/ ;
2014-11-15 02:18:33 +01:00
use Data::Dumper ;
2020-02-15 23:38:32 +01:00
2018-02-28 20:13:56 +01:00
$ Data:: Dumper:: Sortkeys = 1 ;
2016-09-25 09:03:37 +02:00
use Time::HiRes qw/gettimeofday/ ;
2020-05-17 08:13:13 +02:00
use Time::Duration qw/concise ago/ ;
2014-11-15 02:18:33 +01:00
2020-05-18 01:47:48 +02:00
use Getopt::Long qw/GetOptionsFromArray/ ;
2014-11-15 02:18:33 +01:00
sub initialize {
2020-02-15 23:38:32 +01:00
my ( $ self , % conf ) = @ _ ;
$ self - > { nicklist } = { } ;
$ self - > { pbot } - > { registry } - > add_default ( 'text' , 'nicklist' , 'debug' , '0' ) ;
2020-05-04 22:21:35 +02:00
$ self - > { pbot } - > { commands } - > register ( sub { $ self - > cmd_nicklist ( @ _ ) } , "nicklist" , 1 ) ;
2020-02-15 23:38:32 +01:00
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.namreply' , sub { $ self - > on_namreply ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.join' , sub { $ self - > on_join ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.part' , sub { $ self - > on_part ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.quit' , sub { $ self - > on_quit ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.kick' , sub { $ self - > on_kick ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.nick' , sub { $ self - > on_nickchange ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.public' , sub { $ self - > on_activity ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'irc.caction' , sub { $ self - > on_activity ( @ _ ) } ) ;
# handlers for the bot itself joining/leaving channels
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'pbot.join' , sub { $ self - > on_join_channel ( @ _ ) } ) ;
$ self - > { pbot } - > { event_dispatcher } - > register_handler ( 'pbot.part' , sub { $ self - > on_part_channel ( @ _ ) } ) ;
2014-11-15 02:18:33 +01:00
}
2020-05-04 22:21:35 +02:00
sub cmd_nicklist {
my ( $ self , $ context ) = @ _ ;
2020-01-25 21:28:05 +01:00
2020-05-17 08:13:13 +02:00
my $ nicklist ;
2020-05-18 09:04:12 +02:00
my $ usage = "Usage: nicklist (<channel [nick]> | <nick>) [-sort <by>] [-hostmask] [-join]; -hostmask to show hostmasks instead of nicks; -join to include join time" ;
2020-05-18 01:47:48 +02:00
my $ getopt_error ;
local $ SIG { __WARN__ } = sub {
$ getopt_error = shift ;
chomp $ getopt_error ;
} ;
Getopt::Long:: Configure ( "bundling_override" ) ;
my $ sort_method = 'nick' ;
my $ full_hostmask = 0 ;
my $ include_join = 0 ;
my @ args = $ self - > { pbot } - > { interpreter } - > split_line ( $ context - > { arguments } , strip_quotes = > 1 ) ;
GetOptionsFromArray (
\ @ args ,
'sort|s=s' = > \ $ sort_method ,
'hostmask|hm' = > \ $ full_hostmask ,
'join|j' = > \ $ include_join ,
) ;
return "$getopt_error; $usage" if defined $ getopt_error ;
2020-05-18 08:31:25 +02:00
return "Too many arguments -- $usage" if @ args > 2 ;
return $ usage if @ args == 0 or not length $ args [ 0 ] ;
2020-05-18 01:47:48 +02:00
my % sort = (
'spoken' = > sub {
if ( $ _ [ 1 ] eq '+' ) {
return $ _ [ 0 ] - > { $ b } - > { timestamp } <=> $ _ [ 0 ] - > { $ a } - > { timestamp } ;
} else {
return $ _ [ 0 ] - > { $ a } - > { timestamp } <=> $ _ [ 0 ] - > { $ b } - > { timestamp } ;
}
} ,
'join' = > sub {
if ( $ _ [ 1 ] eq '+' ) {
return $ _ [ 0 ] - > { $ b } - > { join } <=> $ _ [ 0 ] - > { $ a } - > { join } ;
} else {
return $ _ [ 0 ] - > { $ a } - > { join } <=> $ _ [ 0 ] - > { $ b } - > { join } ;
}
} ,
'host' = > sub {
if ( $ _ [ 1 ] eq '+' ) {
return lc $ _ [ 0 ] - > { $ a } - > { host } cmp lc $ _ [ 0 ] - > { $ b } - > { host } ;
} else {
return lc $ _ [ 0 ] - > { $ b } - > { host } cmp lc $ _ [ 0 ] - > { $ a } - > { host } ;
}
} ,
'nick' = > sub {
if ( $ _ [ 1 ] eq '+' ) {
return lc $ _ [ 0 ] - > { $ a } - > { nick } cmp lc $ _ [ 0 ] - > { $ b } - > { nick } ;
} else {
return lc $ _ [ 0 ] - > { $ b } - > { nick } cmp lc $ _ [ 0 ] - > { $ a } - > { nick } ;
}
} ,
) ;
my $ sort_direction = '+' ;
if ( $ sort_method =~ s/^(\+|\-)// ) {
$ sort_direction = $ 1 ;
}
if ( not exists $ sort { $ sort_method } ) {
2020-05-18 09:04:12 +02:00
return "Invalid sort method '$sort_method'; valid methods are: " . join ( ', ' , sort keys % sort ) . "; prefix with - to invert sort direction." ;
2020-05-18 01:47:48 +02:00
}
if ( $ args [ 0 ] !~ /^#/ ) {
unshift @ args , $ context - > { from } ;
}
2020-01-25 21:28:05 +01:00
2020-02-15 23:38:32 +01:00
if ( @ args == 1 ) {
2020-05-18 01:47:48 +02:00
if ( not exists $ self - > { nicklist } - > { lc $ args [ 0 ] } ) {
return "No nicklist for channel $args[0]." ;
2020-05-04 22:21:35 +02:00
}
2020-05-17 08:13:13 +02:00
2020-05-18 01:47:48 +02:00
my $ count = keys % { $ self - > { nicklist } - > { lc $ args [ 0 ] } } ;
$ nicklist = "$count nick" . ( $ count == 1 ? '' : 's' ) . " in $args[0]:\n" ;
foreach my $ entry ( sort { $ sort { $ sort_method } - > ( $ self - > { nicklist } - > { lc $ args [ 0 ] } , $ sort_direction ) } keys % { $ self - > { nicklist } - > { lc $ args [ 0 ] } } ) {
if ( $ full_hostmask ) {
$ nicklist . = " $self->{nicklist}->{lc $args[0]}->{$entry}->{hostmask}" ;
} else {
$ nicklist . = " $self->{nicklist}->{lc $args[0]}->{$entry}->{nick}" ;
}
2020-05-17 08:13:13 +02:00
my $ sep = ': ' ;
2020-05-18 01:47:48 +02:00
if ( $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { $ entry } - > { timestamp } > 0 ) {
my $ duration = concise ago ( gettimeofday - $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { $ entry } - > { timestamp } ) ;
2020-05-17 08:13:13 +02:00
$ nicklist . = "${sep}last spoken $duration" ;
$ sep = ', ' ;
}
2020-05-18 01:47:48 +02:00
if ( $ include_join and $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { $ entry } - > { join } > 0 ) {
my $ duration = concise ago ( gettimeofday - $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { $ entry } - > { join } ) ;
$ nicklist . = "${sep}joined $duration" ;
$ sep = ', ' ;
}
foreach my $ key ( sort keys % { $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { $ entry } } ) {
next if grep { $ key eq $ _ } qw/nick user host join timestamp hostmask/ ;
if ( $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { $ entry } - > { $ key } == 1 ) {
$ nicklist . = "$sep$key" ;
} else {
$ nicklist . = "$sep$key => $self->{nicklist}->{lc $args[0]}->{$entry}->{$key}" ;
}
2020-05-17 08:13:13 +02:00
$ sep = ', ' ;
}
$ nicklist . = "\n" ;
}
2020-02-15 23:38:32 +01:00
} else {
2020-05-17 08:13:13 +02:00
if ( not exists $ self - > { nicklist } - > { lc $ args [ 0 ] } ) {
2020-05-18 01:47:48 +02:00
return "No nicklist for channel $args[0]." ;
2020-05-17 08:13:13 +02:00
} elsif ( not exists $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { lc $ args [ 1 ] } ) {
return "No such nick $args[1] in channel $args[0]." ;
}
$ nicklist = "Nicklist information for $self->{nicklist}->{lc $args[0]}->{lc $args[1]}->{hostmask} in $args[0]: " ;
my $ sep = '' ;
if ( $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { lc $ args [ 1 ] } - > { timestamp } > 0 ) {
my $ duration = concise ago ( gettimeofday - $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { lc $ args [ 1 ] } - > { timestamp } ) ;
$ nicklist . = "last spoken $duration" ;
$ sep = ', ' ;
}
2020-05-18 01:47:48 +02:00
if ( $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { lc $ args [ 1 ] } - > { join } > 0 ) {
my $ duration = concise ago ( gettimeofday - $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { lc $ args [ 1 ] } - > { join } ) ;
$ nicklist . = "${sep}joined $duration" ;
$ sep = ', ' ;
}
2020-05-17 08:13:13 +02:00
foreach my $ key ( sort keys % { $ self - > { nicklist } - > { lc $ args [ 0 ] } - > { lc $ args [ 1 ] } } ) {
2020-05-18 01:47:48 +02:00
next if grep { $ key eq $ _ } qw/nick user host join timestamp hostmask/ ;
2020-05-17 08:13:13 +02:00
$ nicklist . = "$sep$key => $self->{nicklist}->{lc $args[0]}->{lc $args[1]}->{$key}" ;
$ sep = ', ' ;
}
$ nicklist . = 'no details' if $ sep eq '' ;
2018-08-03 21:31:45 +02:00
}
2020-05-17 08:13:13 +02:00
2020-02-15 23:38:32 +01:00
return $ nicklist ;
2014-11-15 02:18:33 +01:00
}
2016-09-25 09:03:37 +02:00
sub update_timestamp {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick ) = @ _ ;
my $ orig_nick = $ nick ;
$ channel = lc $ channel ;
$ nick = lc $ nick ;
if ( exists $ self - > { nicklist } - > { $ channel } and exists $ self - > { nicklist } - > { $ channel } - > { $ nick } ) { $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { timestamp } = gettimeofday ; }
else {
$ self - > { pbot } - > { logger } - > log ( "Adding nick '$orig_nick' to channel '$channel'\n" ) if $ self - > { pbot } - > { registry } - > get_value ( 'nicklist' , 'debug' ) ;
$ self - > { nicklist } - > { $ channel } - > { $ nick } = { nick = > $ orig_nick , timestamp = > scalar gettimeofday } ;
}
2016-09-25 09:03:37 +02:00
}
2014-11-15 02:18:33 +01:00
sub remove_channel {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel ) = @ _ ;
delete $ self - > { nicklist } - > { lc $ channel } ;
2014-11-15 02:18:33 +01:00
}
sub add_nick {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick ) = @ _ ;
if ( not exists $ self - > { nicklist } - > { lc $ channel } - > { lc $ nick } ) {
$ self - > { pbot } - > { logger } - > log ( "Adding nick '$nick' to channel '$channel'\n" ) if $ self - > { pbot } - > { registry } - > get_value ( 'nicklist' , 'debug' ) ;
$ self - > { nicklist } - > { lc $ channel } - > { lc $ nick } = { nick = > $ nick , timestamp = > 0 } ;
}
2014-11-15 02:18:33 +01:00
}
sub remove_nick {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick ) = @ _ ;
$ self - > { pbot } - > { logger } - > log ( "Removing nick '$nick' from channel '$channel'\n" ) if $ self - > { pbot } - > { registry } - > get_value ( 'nicklist' , 'debug' ) ;
delete $ self - > { nicklist } - > { lc $ channel } - > { lc $ nick } ;
2014-11-15 02:18:33 +01:00
}
sub get_channels {
2020-02-15 23:38:32 +01:00
my ( $ self , $ nick ) = @ _ ;
my @ channels ;
2014-11-15 02:18:33 +01:00
2020-02-15 23:38:32 +01:00
$ nick = lc $ nick ;
2014-11-15 02:18:33 +01:00
2020-02-15 23:38:32 +01:00
foreach my $ channel ( keys % { $ self - > { nicklist } } ) {
if ( exists $ self - > { nicklist } - > { $ channel } - > { $ nick } ) { push @ channels , $ channel ; }
2014-11-15 02:18:33 +01:00
}
2019-06-26 18:34:19 +02:00
2020-02-15 23:38:32 +01:00
return \ @ channels ;
2014-11-15 02:18:33 +01:00
}
2020-02-06 19:47:19 +01:00
sub get_nicks {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel ) = @ _ ;
$ channel = lc $ channel ;
my @ nicks ;
return @ nicks if not exists $ self - > { nicklist } - > { $ channel } ;
foreach my $ nick ( keys % { $ self - > { nicklist } - > { $ channel } } ) { push @ nicks , $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { nick } ; }
return @ nicks ;
2020-02-06 19:47:19 +01:00
}
2018-08-03 21:31:45 +02:00
sub set_meta {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick , $ key , $ value ) = @ _ ;
$ channel = lc $ channel ;
$ nick = lc $ nick ;
if ( not exists $ self - > { nicklist } - > { $ channel } or not exists $ self - > { nicklist } - > { $ channel } - > { $ nick } ) {
if ( exists $ self - > { nicklist } - > { $ channel } and $ nick =~ m/[*?]/ ) {
my $ regex = quotemeta $ nick ;
$ regex =~ s/\\\*/.*?/g ;
$ regex =~ s/\\\?/./g ;
my $ found = 0 ;
foreach my $ n ( keys % { $ self - > { nicklist } - > { $ channel } } ) {
if ( exists $ self - > { nicklist } - > { $ channel } - > { $ n } - > { hostmask } and $ self - > { nicklist } - > { $ channel } - > { $ n } - > { hostmask } =~ m/$regex/i ) {
$ self - > { nicklist } - > { $ channel } - > { $ n } - > { $ key } = $ value ;
$ found + + ;
}
}
return $ found ;
} else {
$ self - > { pbot } - > { logger } - > log ( "Nicklist: Attempt to set invalid meta ($key => $value) for $nick in $channel.\n" ) ;
return 0 ;
2020-01-23 01:50:45 +01:00
}
}
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
$ self - > { nicklist } - > { $ channel } - > { $ nick } - > { $ key } = $ value ;
return 1 ;
2018-08-03 21:31:45 +02:00
}
sub delete_meta {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick , $ key ) = @ _ ;
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
$ channel = lc $ channel ;
$ nick = lc $ nick ;
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
if ( not exists $ self - > { nicklist } - > { $ channel } or not exists $ self - > { nicklist } - > { $ channel } - > { $ nick } or not exists $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { $ key } ) {
return undef ;
}
return delete $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { $ key } ;
2018-08-03 21:31:45 +02:00
}
sub get_meta {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick , $ key ) = @ _ ;
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
$ channel = lc $ channel ;
$ nick = lc $ nick ;
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
if ( not exists $ self - > { nicklist } - > { $ channel } or not exists $ self - > { nicklist } - > { $ channel } - > { $ nick } or not exists $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { $ key } ) {
return undef ;
}
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
return $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { $ key } ;
2018-08-03 21:31:45 +02:00
}
2017-08-12 10:28:23 +02:00
sub is_present_any_channel {
2020-02-15 23:38:32 +01:00
my ( $ self , $ nick ) = @ _ ;
2017-08-12 10:28:23 +02:00
2020-02-15 23:38:32 +01:00
$ nick = lc $ nick ;
2017-08-12 10:28:23 +02:00
2020-02-15 23:38:32 +01:00
foreach my $ channel ( keys % { $ self - > { nicklist } } ) {
if ( exists $ self - > { nicklist } - > { $ channel } - > { $ nick } ) { return $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { nick } ; }
2017-08-12 10:28:23 +02:00
}
2020-02-15 23:38:32 +01:00
return 0 ;
2017-08-12 10:28:23 +02:00
}
2014-11-15 02:18:33 +01:00
sub is_present {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick ) = @ _ ;
2014-11-15 02:18:33 +01:00
2020-02-15 23:38:32 +01:00
$ channel = lc $ channel ;
$ nick = lc $ nick ;
2015-06-08 13:43:00 +02:00
2020-02-15 23:38:32 +01:00
if ( exists $ self - > { nicklist } - > { $ channel } and exists $ self - > { nicklist } - > { $ channel } - > { $ nick } ) { return $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { nick } ; }
else { return 0 ; }
2014-11-15 02:18:33 +01:00
}
2016-09-25 09:03:37 +02:00
sub is_present_similar {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel , $ nick , $ similar ) = @ _ ;
2016-09-25 09:03:37 +02:00
2020-02-15 23:38:32 +01:00
$ channel = lc $ channel ;
$ nick = lc $ nick ;
2016-09-25 09:03:37 +02:00
2020-02-15 23:38:32 +01:00
return 0 if not exists $ self - > { nicklist } - > { $ channel } ;
return $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { nick } if $ self - > is_present ( $ channel , $ nick ) ;
return 0 if $ nick =~ m/(?:^\$|\s)/ ; # not nick-like
2016-09-25 21:59:03 +02:00
2020-02-15 23:38:32 +01:00
my $ percentage = $ self - > { pbot } - > { registry } - > get_value ( 'interpreter' , 'nick_similarity' ) ;
$ percentage = 0.20 if not defined $ percentage ;
2016-09-25 09:03:37 +02:00
2020-02-15 23:38:32 +01:00
$ percentage = $ similar if defined $ similar ;
2017-05-21 08:44:45 +02:00
2020-02-15 23:38:32 +01:00
my $ now = gettimeofday ;
foreach my $ person ( sort { $ self - > { nicklist } - > { $ channel } - > { $ b } - > { timestamp } <=> $ self - > { nicklist } - > { $ channel } - > { $ a } - > { timestamp } } keys % { $ self - > { nicklist } - > { $ channel } } )
{
return 0 if $ now - $ self - > { nicklist } - > { $ channel } - > { $ person } - > { timestamp } > 3600 ; # 1 hour
my $ distance = fastdistance ( $ nick , $ person ) ;
my $ length = length $ nick > length $ person ? length $ nick : length $ person ;
2016-09-25 09:03:37 +02:00
2020-02-15 23:38:32 +01:00
if ( $ length != 0 && $ distance / $ length <= $ percentage ) { return $ self - > { nicklist } - > { $ channel } - > { $ person } - > { nick } ; }
2016-09-25 09:03:37 +02:00
}
2020-02-15 23:38:32 +01:00
return 0 ;
2016-09-25 09:03:37 +02:00
}
2015-06-08 13:43:00 +02:00
sub random_nick {
2020-02-15 23:38:32 +01:00
my ( $ self , $ channel ) = @ _ ;
2015-06-08 13:43:00 +02:00
2020-02-15 23:38:32 +01:00
$ channel = lc $ channel ;
2015-06-08 13:43:00 +02:00
2020-02-15 23:38:32 +01:00
if ( exists $ self - > { nicklist } - > { $ channel } ) {
my $ now = gettimeofday ;
my @ nicks = grep { $ now - $ self - > { nicklist } - > { $ channel } - > { $ _ } - > { timestamp } < 3600 * 2 } keys % { $ self - > { nicklist } - > { $ channel } } ;
2019-06-26 18:34:19 +02:00
2020-02-15 23:38:32 +01:00
my $ nick = $ nicks [ rand @ nicks ] ;
return $ self - > { nicklist } - > { $ channel } - > { $ nick } - > { nick } ;
} else {
return undef ;
}
2015-06-08 13:43:00 +02:00
}
2014-11-15 02:18:33 +01:00
sub on_namreply {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
my ( $ channel , $ nicks ) = ( $ event - > { event } - > { args } [ 2 ] , $ event - > { event } - > { args } [ 3 ] ) ;
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
foreach my $ nick ( split ' ' , $ nicks ) {
my $ stripped_nick = $ nick ;
$ stripped_nick =~ s/^[@+%]//g ; # remove OP/Voice/etc indicator from nick
$ self - > add_nick ( $ channel , $ stripped_nick ) ;
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
my ( $ account_id , $ hostmask ) = $ self - > { pbot } - > { messagehistory } - > { database } - > find_message_account_by_nick ( $ stripped_nick ) ;
2019-12-31 01:12:10 +01:00
2020-02-15 23:38:32 +01:00
if ( defined $ hostmask ) {
my ( $ user , $ host ) = $ hostmask =~ m/[^!]+!([^@]+)@(.*)/ ;
$ self - > set_meta ( $ channel , $ stripped_nick , 'hostmask' , $ hostmask ) ;
$ self - > set_meta ( $ channel , $ stripped_nick , 'user' , $ user ) ;
$ self - > set_meta ( $ channel , $ stripped_nick , 'host' , $ host ) ;
}
2019-12-31 00:57:31 +01:00
2020-02-15 23:38:32 +01:00
if ( $ nick =~ m/\@/ ) { $ self - > set_meta ( $ channel , $ stripped_nick , '+o' , 1 ) ; }
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
if ( $ nick =~ m/\+/ ) { $ self - > set_meta ( $ channel , $ stripped_nick , '+v' , 1 ) ; }
2018-08-03 21:31:45 +02:00
2020-02-15 23:38:32 +01:00
if ( $ nick =~ m/\%/ ) { $ self - > set_meta ( $ channel , $ stripped_nick , '+h' , 1 ) ; }
2018-08-03 21:31:45 +02:00
}
2020-02-15 23:38:32 +01:00
return 0 ;
2014-11-15 02:18:33 +01:00
}
2016-09-25 09:03:37 +02:00
sub on_activity {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
my ( $ nick , $ user , $ host , $ channel ) = ( $ event - > { event } - > nick , $ event - > { event } - > user , $ event - > { event } - > host , $ event - > { event } - > { to } [ 0 ] ) ;
$ self - > update_timestamp ( $ channel , $ nick ) ;
return 0 ;
2016-09-25 09:03:37 +02:00
}
2014-11-15 02:18:33 +01:00
sub on_join {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
my ( $ nick , $ user , $ host , $ channel ) = ( $ event - > { event } - > nick , $ event - > { event } - > user , $ event - > { event } - > host , $ event - > { event } - > to ) ;
$ self - > add_nick ( $ channel , $ nick ) ;
$ self - > set_meta ( $ channel , $ nick , 'hostmask' , "$nick!$user\@$host" ) ;
$ self - > set_meta ( $ channel , $ nick , 'user' , $ user ) ;
$ self - > set_meta ( $ channel , $ nick , 'host' , $ host ) ;
2020-05-18 01:47:48 +02:00
$ self - > set_meta ( $ channel , $ nick , 'join' , gettimeofday ) ;
2020-02-15 23:38:32 +01:00
return 0 ;
2014-11-15 02:18:33 +01:00
}
sub on_part {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
my ( $ nick , $ user , $ host , $ channel ) = ( $ event - > { event } - > nick , $ event - > { event } - > user , $ event - > { event } - > host , $ event - > { event } - > to ) ;
$ self - > remove_nick ( $ channel , $ nick ) ;
return 0 ;
2014-11-15 02:18:33 +01:00
}
sub on_quit {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
my ( $ nick , $ user , $ host ) = ( $ event - > { event } - > nick , $ event - > { event } - > user , $ event - > { event } - > host ) ;
2014-11-15 02:18:33 +01:00
2020-02-15 23:38:32 +01:00
foreach my $ channel ( keys % { $ self - > { nicklist } } ) {
if ( $ self - > is_present ( $ channel , $ nick ) ) { $ self - > remove_nick ( $ channel , $ nick ) ; }
2014-11-15 02:18:33 +01:00
}
2020-02-15 23:38:32 +01:00
return 0 ;
2014-11-15 02:18:33 +01:00
}
sub on_kick {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
my ( $ nick , $ channel ) = ( $ event - > { event } - > to , $ event - > { event } - > { args } [ 0 ] ) ;
$ self - > remove_nick ( $ channel , $ nick ) ;
return 0 ;
2014-11-15 02:18:33 +01:00
}
sub on_nickchange {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
my ( $ nick , $ user , $ host , $ newnick ) = ( $ event - > { event } - > nick , $ event - > { event } - > user , $ event - > { event } - > host , $ event - > { event } - > args ) ;
foreach my $ channel ( keys % { $ self - > { nicklist } } ) {
if ( $ self - > is_present ( $ channel , $ nick ) ) {
my $ meta = delete $ self - > { nicklist } - > { $ channel } - > { lc $ nick } ;
$ meta - > { nick } = $ newnick ;
$ meta - > { timestamp } = gettimeofday ;
$ self - > { nicklist } - > { $ channel } - > { lc $ newnick } = $ meta ;
}
2014-11-15 02:18:33 +01:00
}
2020-02-15 23:38:32 +01:00
return 0 ;
2014-11-15 02:18:33 +01:00
}
sub on_join_channel {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
$ self - > remove_channel ( $ event - > { channel } ) ; # clear nicklist to remove any stale nicks before repopulating with namreplies
return 0 ;
2014-11-15 02:18:33 +01:00
}
sub on_part_channel {
2020-02-15 23:38:32 +01:00
my ( $ self , $ event_type , $ event ) = @ _ ;
$ self - > remove_channel ( $ event - > { channel } ) ;
return 0 ;
2014-11-15 02:18:33 +01:00
}
1 ;