3
0
mirror of https://github.com/pragma-/pbot.git synced 2024-11-20 10:59:29 +01:00

Improve robustness of message history tracking

This commit is contained in:
Pragmatic Software 2016-12-01 04:57:25 -08:00
parent a5260ef056
commit d47edc100b
3 changed files with 100 additions and 22 deletions

View File

@ -381,6 +381,7 @@ sub check_flood {
}
foreach my $channel (@$channels) {
$channel = lc $channel;
# do not do flood processing if channel is not in bot's channel list or bot is not set as chanop for the channel
next if $channel =~ /^#/ and not $self->{pbot}->{chanops}->can_gain_ops($channel);
@ -453,7 +454,7 @@ sub check_flood {
}
# check for chat/join/private message flooding
if($max_messages > 0 and $self->{pbot}->{messagehistory}->{database}->get_max_messages($mode == $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE} ? $ancestor : $account, $channel) >= $max_messages) {
if($max_messages > 0 and $self->{pbot}->{messagehistory}->{database}->get_max_messages($account, $channel, $mode == $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE} ? $nick : undef) >= $max_messages) {
my $msg;
if($mode == $self->{pbot}->{messagehistory}->{MSG_CHAT}) {
$msg = $self->{pbot}->{messagehistory}->{database}->recall_message_by_count($account, $channel, $max_messages - 1)
@ -463,7 +464,7 @@ sub check_flood {
$msg = $joins->[0];
}
elsif($mode == $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}) {
my $nickchanges = $self->{pbot}->{messagehistory}->{database}->get_recent_messages($ancestor, $channel, $max_messages, $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE});
my $nickchanges = $self->{pbot}->{messagehistory}->{database}->get_recent_messages($ancestor, $channel, $max_messages, $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}, $nick);
$msg = $nickchanges->[0];
}
elsif($mode == $self->{pbot}->{messagehistory}->{MSG_DEPARTURE}) {

View File

@ -383,11 +383,12 @@ sub on_nickchange {
my $message_account = $self->{pbot}->{messagehistory}->{database}->get_message_account($nick, $user, $host);
$self->{pbot}->{messagehistory}->{database}->devalidate_all_channels($message_account, $self->{pbot}->{antiflood}->{NEEDS_CHECKBAN});
my $channels = $self->{pbot}->{nicklist}->get_channels($newnick);
my $channels = $self->{pbot}->{nicklist}->get_channels($nick);
foreach my $channel (@$channels) {
next if $channel !~ m/^#/;
$self->{pbot}->{messagehistory}->add_message($message_account, "$nick!$user\@$host", $channel, "NICKCHANGE $newnick", $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE});
}
$self->{pbot}->{messagehistory}->{database}->update_hostmask_data("$nick!$user\@$host", { last_seen => scalar gettimeofday });
my $newnick_account = $self->{pbot}->{messagehistory}->{database}->get_message_account($newnick, $user, $host, $nick);
$self->{pbot}->{messagehistory}->{database}->devalidate_all_channels($newnick_account, $self->{pbot}->{antiflood}->{NEEDS_CHECKBAN});

View File

@ -299,9 +299,10 @@ sub add_message_account {
}
eval {
my $sth = $self->{dbh}->prepare('INSERT INTO Hostmasks VALUES (?, ?, 0, 0)');
my $sth = $self->{dbh}->prepare('INSERT INTO Hostmasks VALUES (?, ?, ?, 0)');
$sth->bind_param(1, $mask);
$sth->bind_param(2, $id);
$sth->bind_param(3, scalar gettimeofday);
$sth->execute();
$self->{new_entries}++;
@ -780,26 +781,66 @@ sub add_message {
}
sub get_recent_messages {
my ($self, $id, $channel, $limit, $mode) = @_;
my ($self, $id, $channel, $limit, $mode, $nick) = @_;
$limit = 25 if not defined $limit;
$channel = lc $channel;
my $mode_query = '';
$mode_query = "AND mode = $mode" if defined $mode;
my $messages = eval {
my $sth = $self->{dbh}->prepare(<<SQL);
SELECT msg, mode, timestamp
FROM Messages
WHERE id = ? AND channel = ? $mode_query
ORDER BY timestamp ASC
LIMIT ? OFFSET (SELECT COUNT(*) FROM Messages WHERE id = ? AND channel = ? $mode_query) - ?
SQL
$sth->bind_param(1, $id);
$sth->bind_param(2, $channel);
$sth->bind_param(3, $limit);
$sth->bind_param(4, $id);
$sth->bind_param(5, $channel);
$sth->bind_param(6, $limit);
my $sql = "SELECT msg, mode, timestamp FROM Messages WHERE ";
my %akas;
if (defined $mode and $mode == $self->{pbot}->{messagehistory}->{MSG_NICKCHANGE}) {
%akas = $self->get_also_known_as($nick);
} else {
$akas{'this'} = { id => $id, type => $self->{alias_type}->{STRONG}, nickchange => 0 };
}
my $ids;
my %seen_id;
my $and = '';
foreach my $aka (keys %akas) {
next if $akas{$aka}->{type} == $self->{alias_type}->{WEAK};
next if $akas{$aka}->{nickchange} == 1;
next if exists $seen_id{$akas{$aka}->{id}};
$seen_id{$akas{$aka}->{id}} = 1;
$ids .= "${and}id = ?";
$and = ' AND ';
}
$sql .= "$ids AND channel = ? $mode_query ORDER BY timestamp ASC LIMIT ? OFFSET (SELECT COUNT(*) FROM Messages WHERE $ids AND channel = ? $mode_query) - ?";
my $sth = $self->{dbh}->prepare($sql);
my $param = 1;
%seen_id = ();
foreach my $aka (keys %akas) {
next if $akas{$aka}->{type} == $self->{alias_type}->{WEAK};
next if $akas{$aka}->{nickchange} == 1;
next if exists $seen_id{$akas{$aka}->{id}};
$seen_id{$akas{$aka}->{id}} = 1;
$sth->bind_param($param++, $akas{$aka}->{id});
}
$sth->bind_param($param++, $channel);
$sth->bind_param($param++, $limit);
%seen_id = ();
foreach my $aka (keys %akas) {
next if $akas{$aka}->{type} == $self->{alias_type}->{WEAK};
next if $akas{$aka}->{nickchange} == 1;
next if exists $seen_id{$akas{$aka}->{id}};
$seen_id{$akas{$aka}->{id}} = 1;
$sth->bind_param($param++, $akas{$aka}->{id});
}
$sth->bind_param($param++, $channel);
$sth->bind_param($param, $limit);
$sth->execute();
return $sth->fetchall_arrayref({});
};
@ -985,12 +1026,47 @@ sub recall_message_by_text {
}
sub get_max_messages {
my ($self, $id, $channel) = @_;
my ($self, $id, $channel, $use_aliases) = @_;
my $count = eval {
my $sth = $self->{dbh}->prepare('SELECT COUNT(*) FROM Messages WHERE id = ? AND channel = ?');
$sth->bind_param(1, $id);
$sth->bind_param(2, $channel);
my $sql = "SELECT COUNT(*) FROM Messages WHERE channel = ? AND ";
my %akas;
if (defined $use_aliases) {
%akas = $self->get_also_known_as($use_aliases);
} else {
$akas{'this'} = { id => $id, type => $self->{alias_type}->{STRONG}, nickchange => 0 };
}
my $ids;
my %seen_id;
my $and = '';
foreach my $aka (keys %akas) {
next if $akas{$aka}->{type} == $self->{alias_type}->{WEAK};
next if $akas{$aka}->{nickchange} == 1;
next if exists $seen_id{$akas{$aka}->{id}};
$seen_id{$akas{$aka}->{id}} = 1;
$ids .= "${and}id = ?";
$and = ' AND ';
}
$sql .= $ids;
my $sth = $self->{dbh}->prepare($sql);
my $param = 1;
$sth->bind_param($param++, $channel);
%seen_id = ();
foreach my $aka (keys %akas) {
next if $akas{$aka}->{type} == $self->{alias_type}->{WEAK};
next if $akas{$aka}->{nickchange} == 1;
next if exists $seen_id{$akas{$aka}->{id}};
$seen_id{$akas{$aka}->{id}} = 1;
$sth->bind_param($param++, $akas{$aka}->{id});
}
$sth->execute();
my $row = $sth->fetchrow_hashref();
$sth->finish();