3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-12-24 11:42:35 +01:00

Check WHO when joining channels

When joining a channel, check the WHO list for that channel in order
to obtain all hostmask, nickserv and gecos information and check for
potential ban evasions.
This commit is contained in:
Pragmatic Software 2016-09-02 02:17:10 -07:00
parent 87d02af264
commit 687a5e0ae2

View File

@ -31,16 +31,20 @@ sub initialize {
$self->{pbot}->{commands}->register(sub { $self->dumpnicks(@_) }, "dumpnicks", 60); $self->{pbot}->{commands}->register(sub { $self->dumpnicks(@_) }, "dumpnicks", 60);
$self->{pbot}->{event_dispatcher}->register_handler('irc.namreply', sub { $self->on_namreply(@_) }); $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.join', sub { $self->on_join(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.part', sub { $self->on_part(@_) }); $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.quit', sub { $self->on_quit(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.kick', sub { $self->on_kick(@_) }); $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.nick', sub { $self->on_nickchange(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.whospcrpl', sub { $self->on_whospcrpl(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('irc.endofwho', sub { $self->on_endofwho(@_) });
# handlers for the bot itself joining/leaving channels # 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.join', sub { $self->on_join_channel(@_) });
$self->{pbot}->{event_dispatcher}->register_handler('pbot.part', sub { $self->on_part_channel(@_) }); $self->{pbot}->{event_dispatcher}->register_handler('pbot.part', sub { $self->on_part_channel(@_) });
$self->{pbot}->{timer}->register(sub { $self->check_pending_whos }, 10);
} }
sub dumpnicks { sub dumpnicks {
@ -171,6 +175,7 @@ sub on_nickchange {
sub on_join_channel { sub on_join_channel {
my ($self, $event_type, $event) = @_; my ($self, $event_type, $event) = @_;
$self->remove_channel($event->{channel}); # clear nicklist to remove any stale nicks before repopulating with namreplies $self->remove_channel($event->{channel}); # clear nicklist to remove any stale nicks before repopulating with namreplies
$self->send_who($event->{channel});
return 0; return 0;
} }
@ -180,4 +185,69 @@ sub on_part_channel {
return 0; return 0;
} }
my %who_queue;
my %who_cache;
my $last_who_id;
my $who_pending = 0;
sub on_whospcrpl {
my ($self, $event_type, $event) = @_;
my ($ignored, $id, $user, $host, $nick, $nickserv, $gecos) = @{$event->{event}->{args}};
$last_who_id = $id;
my $hostmask = "$nick!$user\@$host";
my $channel = $who_cache{$id};
delete $who_queue{$id};
return 0 if not defined $channel;
$self->{pbot}->{logger}->log("WHO id: $id, hostmask: $hostmask, $nickserv, $gecos.\n");
my $account_id = $self->{pbot}->{messagehistory}->{database}->get_message_account($nick, $user, $host);
if ($nickserv ne '0') {
$self->{pbot}->{messagehistory}->{database}->link_aliases($account_id, undef, $nickserv);
$self->{pbot}->{antiflood}->check_nickserv_accounts($nick, $nickserv);
}
$self->{pbot}->{messagehistory}->{database}->link_aliases($account_id, $hostmask, undef);
$self->{pbot}->{messagehistory}->{database}->devalidate_channel($account_id, $channel);
$self->{pbot}->{antiflood}->check_bans($account_id, $hostmask, $channel);
return 0;
}
sub on_endofwho {
my ($self, $event_type, $event) = @_;
$self->{pbot}->{logger}->log("WHO session $last_who_id ($who_cache{$last_who_id}) completed.\n");
delete $who_cache{$last_who_id};
$who_pending = 0;
return 0;
}
sub send_who {
my ($self, $channel) = @_;
$self->{pbot}->{logger}->log("pending WHO to $channel\n");
for (my $id = 1; $id < 99; $id++) {
if (not exists $who_cache{$id}) {
$who_cache{$id} = $channel;
$who_queue{$id} = $channel;
last;
}
}
}
sub check_pending_whos {
my $self = shift;
return if $who_pending;
foreach my $id (keys %who_queue) {
$self->{pbot}->{logger}->log("sending WHO to $who_queue{$id} [$id]\n");
$self->{pbot}->{conn}->sl("WHO $who_queue{$id} %tuhnar,$id");
$who_pending = 1;
last;
}
}
1; 1;