2019-04-24 12:55:48 +02:00
|
|
|
#!/usr/bin/env perl
|
|
|
|
|
|
|
|
# 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/.
|
|
|
|
|
2019-09-01 20:01:18 +02:00
|
|
|
package Plugins::Spinach::Stats;
|
2019-04-24 12:55:48 +02:00
|
|
|
|
|
|
|
use warnings;
|
|
|
|
use strict;
|
|
|
|
|
2019-07-11 03:40:53 +02:00
|
|
|
use feature 'unicode_strings';
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
use DBI;
|
|
|
|
use Carp qw(shortmess);
|
2019-04-24 12:55:48 +02:00
|
|
|
|
|
|
|
sub new {
|
|
|
|
my ($class, %conf) = @_;
|
|
|
|
my $self = bless {}, $class;
|
|
|
|
$self->initialize(%conf);
|
|
|
|
return $self;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub initialize {
|
|
|
|
my ($self, %conf) = @_;
|
2019-05-09 22:25:33 +02:00
|
|
|
$self->{pbot} = $conf{pbot} // Carp::croak("Missing pbot reference to " . __FILE__);
|
2019-04-24 12:55:48 +02:00
|
|
|
$self->{filename} = $conf{filename} // 'stats.sqlite';
|
|
|
|
}
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
sub begin {
|
|
|
|
my $self = shift;
|
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
$self->{pbot}->{logger}->log("Opening Spinach stats SQLite database: $self->{filename}\n");
|
2019-04-25 08:04:09 +02:00
|
|
|
|
|
|
|
$self->{dbh} = DBI->connect("dbi:SQLite:dbname=$self->{filename}", "", "", { RaiseError => 1, PrintError => 0 }) or die $DBI::errstr;
|
|
|
|
|
|
|
|
eval {
|
|
|
|
$self->{dbh}->do(<< 'SQL');
|
|
|
|
CREATE TABLE IF NOT EXISTS Stats (
|
|
|
|
id INTEGER PRIMARY KEY,
|
|
|
|
nick TEXT NOT NULL COLLATE NOCASE,
|
|
|
|
channel TEXT NOT NULL COLLATE NOCASE,
|
|
|
|
high_score INTEGER DEFAULT 0,
|
|
|
|
low_score INTEGER DEFAULT 0,
|
|
|
|
avg_score INTEGER DEFAULT 0,
|
|
|
|
times_first INTEGER DEFAULT 0,
|
|
|
|
times_second INTEGER DEFAULT 0,
|
|
|
|
times_third INTEGER DEFAULT 0,
|
|
|
|
good_lies INTEGER DEFAULT 0,
|
|
|
|
players_deceived INTEGER DEFAULT 0,
|
|
|
|
questions_played INTEGER DEFAULT 0,
|
|
|
|
games_played INTEGER DEFAULT 0,
|
|
|
|
good_guesses INTEGER DEFAULT 0,
|
|
|
|
bad_guesses INTEGER DEFAULT 0
|
|
|
|
)
|
|
|
|
SQL
|
|
|
|
};
|
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
$self->{pbot}->{logger}->log("Error creating database: $@\n") if $@;
|
2019-04-24 12:55:48 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
sub end {
|
|
|
|
my $self = shift;
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-28 18:19:42 +02:00
|
|
|
if (exists $self->{dbh} and defined $self->{dbh}) {
|
2019-05-09 22:25:33 +02:00
|
|
|
$self->{pbot}->{logger}->log("Closing stats SQLite database\n");
|
2019-04-25 08:04:09 +02:00
|
|
|
$self->{dbh}->disconnect();
|
|
|
|
delete $self->{dbh};
|
2019-04-24 12:55:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
sub add_player {
|
2019-05-09 22:25:33 +02:00
|
|
|
my ($self, $id, $nick, $channel) = @_;
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
eval {
|
|
|
|
my $sth = $self->{dbh}->prepare('INSERT INTO Stats (id, nick, channel) VALUES (?, ?, ?)');
|
|
|
|
$sth->execute($id, $nick, $channel);
|
2019-04-25 08:04:09 +02:00
|
|
|
};
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
if ($@) {
|
|
|
|
$self->{pbot}->{logger}->log("Spinach stats: failed to add new player ($id, $nick $channel): $@\n");
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
return $id;
|
2019-04-24 12:55:48 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
sub get_player_id {
|
|
|
|
my ($self, $nick, $channel, $dont_create_new) = @_;
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
my ($account_id) = $self->{pbot}->{messagehistory}->{database}->find_message_account_by_nick($nick);
|
|
|
|
$account_id = $self->{pbot}->{messagehistory}->{database}->get_ancestor_id($account_id);
|
|
|
|
|
|
|
|
return undef if not $account_id;
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
my $id = eval {
|
2019-05-09 22:25:33 +02:00
|
|
|
my $sth = $self->{dbh}->prepare('SELECT id FROM Stats WHERE id = ? AND channel = ?');
|
|
|
|
$sth->execute($account_id, $channel);
|
2019-04-25 08:04:09 +02:00
|
|
|
my $row = $sth->fetchrow_hashref();
|
|
|
|
return $row->{id};
|
|
|
|
};
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
if ($@) {
|
|
|
|
$self->{pbot}->{logger}->log("Spinach stats: failed to get player id: $@\n");
|
|
|
|
return undef;
|
|
|
|
}
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
$id = $self->add_player($account_id, $nick, $channel) if not defined $id and not $dont_create_new;
|
2019-04-25 08:04:09 +02:00
|
|
|
return $id;
|
|
|
|
}
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
sub get_player_data {
|
|
|
|
my ($self, $id, @columns) = @_;
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-09 22:25:33 +02:00
|
|
|
return undef if not $id;
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
my $player_data = eval {
|
|
|
|
my $sql = 'SELECT ';
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-05-28 18:19:42 +02:00
|
|
|
if (not @columns) {
|
2019-04-25 08:04:09 +02:00
|
|
|
$sql .= '*';
|
|
|
|
} else {
|
|
|
|
my $comma = '';
|
|
|
|
foreach my $column (@columns) {
|
|
|
|
$sql .= "$comma$column";
|
|
|
|
$comma = ', ';
|
|
|
|
}
|
|
|
|
}
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
$sql .= ' FROM Stats WHERE id = ?';
|
|
|
|
my $sth = $self->{dbh}->prepare($sql);
|
2019-05-09 22:25:33 +02:00
|
|
|
$sth->execute($id);
|
2019-04-25 08:04:09 +02:00
|
|
|
return $sth->fetchrow_hashref();
|
|
|
|
};
|
|
|
|
print STDERR $@ if $@;
|
|
|
|
return $player_data;
|
|
|
|
}
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
sub update_player_data {
|
|
|
|
my ($self, $id, $data) = @_;
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
eval {
|
|
|
|
my $sql = 'UPDATE Stats SET ';
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
my $comma = '';
|
|
|
|
foreach my $key (keys %$data) {
|
|
|
|
$sql .= "$comma$key = ?";
|
|
|
|
$comma = ', ';
|
2019-04-24 12:55:48 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
$sql .= ' WHERE id = ?';
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
my $sth = $self->{dbh}->prepare($sql);
|
2019-04-24 12:55:48 +02:00
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
my $param = 1;
|
|
|
|
foreach my $key (keys %$data) {
|
|
|
|
$sth->bind_param($param++, $data->{$key});
|
2019-04-24 12:55:48 +02:00
|
|
|
}
|
|
|
|
|
2019-04-25 08:04:09 +02:00
|
|
|
$sth->bind_param($param, $id);
|
|
|
|
$sth->execute();
|
|
|
|
};
|
|
|
|
print STDERR $@ if $@;
|
|
|
|
}
|
|
|
|
|
|
|
|
sub get_all_players {
|
|
|
|
my ($self, $channel) = @_;
|
|
|
|
|
|
|
|
my $players = eval {
|
|
|
|
my $sth = $self->{dbh}->prepare('SELECT * FROM Stats WHERE channel = ?');
|
2019-05-09 22:25:33 +02:00
|
|
|
$sth->execute($channel);
|
2019-04-25 08:04:09 +02:00
|
|
|
return $sth->fetchall_arrayref({});
|
|
|
|
};
|
2019-05-09 22:25:33 +02:00
|
|
|
$self->{pbot}->{logger}->log($@) if $@;
|
2019-04-25 08:04:09 +02:00
|
|
|
return $players;
|
2019-04-24 12:55:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
1;
|