Last active
January 10, 2016 15:01
-
-
Save mimicmod/ecd1bcc4e89e34037542 to your computer and use it in GitHub Desktop.
Chat responder with multiple responses support - script for the Globster direct connect client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl | |
use strict; | |
use warnings; | |
use Net::DBus::Reactor; | |
use Net::DBus; | |
use XML::Simple; | |
# create xml object | |
my $xml = new XML::Simple; | |
# read XML file | |
my $config = $xml->XMLin($ARGV[0], ForceArray => ['hub', 'bottalkresponse', 'botmuteresponse', 'responder', 'response'], SearchPath => [ '/etc/globster' ]); | |
$ENV{DBUS_SESSION_BUS_ADDRESS} = $config->{'dbusaddr'} ? $config->{'dbusaddr'} : $ENV{DBUS_SESSION_BUS_ADDRESS}; | |
# Hubs to link (Globster hub ids) | |
my @hubs = @{$config->{'hub'}}; | |
my $g = Net::DBus->find->get_service("net.blicky.Globster")->get_object("/net/blicky/Globster"); | |
my %objs = map +($_->{'hubid'}, $g->get_child_object("/Hub/$_->{'hubid'}")), @hubs; | |
my @ignored; | |
my @resplast; | |
my @msgqueue; | |
sub is_authority { | |
my ($user, $array) = @_; | |
for my $item (@{$array}) { | |
if ($item eq $user) { | |
return 1; | |
} | |
} | |
return 0; | |
} | |
sub is_ignored { | |
my $found = 0; | |
my ($user, $hubid, $array) = @_; | |
for my $item (@{$array}) { | |
if ($item->{'user'} eq $user && $item->{'hubid'} == $hubid && $item->{'expiry'} > time) { | |
$found = 1; | |
last; | |
} | |
} | |
return $found; | |
} | |
sub ignored_cleanup { | |
my $ignorelist = $_[0]; | |
my $offset = 0; | |
for my $item (@{$ignorelist}) { | |
$offset++ if $item->{'expiry'} <= time; | |
} | |
splice(@{$ignorelist}, 0, $offset); | |
} | |
sub send_reply { | |
my($hubid, $reply) = @_; | |
$objs{$hubid}->SendChat(-1, $reply, 0); | |
} | |
sub send_msg_queue { | |
my $mq = shift; | |
for my $item (@{$mq}) { | |
if ($item->{'time'} <= time) { | |
send_reply $item->{'hub'}, $item->{'message'}; | |
} | |
} | |
} | |
sub msg_queue_cleanup { | |
my $mq = $_[0]; | |
my $offset = 0; | |
for my $item (@{$mq}) { | |
$offset++ if $item->{'time'} <= time; | |
} | |
splice(@{$mq}, 0, $offset); | |
} | |
for my $hub (@hubs) { | |
$resplast[$hub->{'hubid'}]{'username'} = ''; | |
$resplast[$hub->{'hubid'}]{'keyword'} = ''; | |
$resplast[$hub->{'hubid'}]{'count'} = 0; | |
$objs{$hub->{'hubid'}}->connect_to_signal('ReceiveChat', sub { | |
my($group, $user, $message, $me) = @_; | |
return if $group != -1 || $user == -1 || !$user; # Do not reply to own messages | |
my $username = [$objs{$hub->{'hubid'}}->UserInfo($user, [ 1 ])]->[1]{$user}[0]; | |
my $rr = ''; | |
my @botauthority = split(',', $hub->{'botauthority'}); | |
if ($message =~ /$hub->{'bottalk'}/ && is_authority($username, \@botauthority)) { | |
$hub->{'state'} = 1; | |
my @bottalkresponses = @{$hub->{'bottalkresponse'}}; | |
$rr = $bottalkresponses[rand @bottalkresponses]; | |
} | |
if ($message =~ /$hub->{'botmute'}/ && is_authority($username, \@botauthority)) { | |
$hub->{'state'} = 0; | |
my @botmuteresponses = @{$hub->{'botmuteresponse'}}; | |
$rr = $botmuteresponses[rand @botmuteresponses]; | |
} | |
if ($hub->{'state'} == 1 && !is_ignored($username, $hub->{'hubid'}, \@ignored)) { | |
my @responders = @{$hub->{'responder'}}; | |
for my $responder (@responders) { | |
my $str = $responder->{'keyword'}; | |
if ($message =~ /$str/) { | |
if ($str eq $resplast[$hub->{'hubid'}]{'keyword'} && $username eq $resplast[$hub->{'hubid'}]{'username'}) { | |
$resplast[$hub->{'hubid'}]{'counter'}++; | |
} else { | |
$resplast[$hub->{'hubid'}]{'keyword'} = $str; | |
$resplast[$hub->{'hubid'}]{'username'} = $username; | |
$resplast[$hub->{'hubid'}]{'counter'} = 0; | |
} | |
if ($resplast[$hub->{'hubid'}]{'counter'} > $hub->{'maxrepeat'} - 1) { | |
$rr = $hub->{'repeatresponse'}; | |
my %ignored_user; | |
$ignored_user{'user'} = $username; | |
$ignored_user{'expiry'} = time + $hub->{'ignoretime'}; | |
$ignored_user{'hubid'} = $hub->{'hubid'}; | |
push(@ignored, \%ignored_user); | |
$resplast[$hub->{'hubid'}]{'counter'} = 0; | |
} else { | |
my @responses = @{$responder->{'response'}}; | |
$rr = $responses[rand @responses]; | |
} | |
last; | |
} | |
} | |
} | |
if ($rr ne '') { | |
$rr =~ s/%\[userNI\]/$username/g; | |
my $delay = $hub->{'respdelay'} ? $hub->{'respdelay'} : 0; | |
my %qr; | |
$qr{'message'} = $rr; | |
$qr{'time'} = time + $delay; | |
$qr{'hub'} = $hub->{'hubid'}; | |
push(@msgqueue, \%qr); | |
} | |
}); | |
} | |
my $reactor = Net::DBus::Reactor->main; | |
$reactor->add_timeout(1000, Net::DBus::Callback->new( method => sub { | |
send_msg_queue(\@msgqueue); | |
msg_queue_cleanup(\@msgqueue); | |
ignored_cleanup(\@ignored); | |
})); | |
$reactor->run; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment