$t->cmd("set shout 0");
$t->cmd("set seek 0");
$t->cmd("set style 12");
-$t->cmd("observe $remoteglotconf::target");
-print "FICS ready.\n";
my $ev1 = AnyEvent->io(
fh => fileno($t),
}
}
);
+if (defined($remoteglotconf::target)) {
+ if ($remoteglotconf::target =~ /^http:/) {
+ fetch_pgn($remoteglotconf::target);
+ } else {
+ $t->cmd("observe $remoteglotconf::target");
+ }
+}
+print "FICS ready.\n";
+
# Engine events have already been set up by Engine.pm.
EV::run;
} elsif ($msg =~ /^pgn (.*?)$/) {
my $url = $1;
$t->cmd("tell $who Starting to poll '$url'.");
- AnyEvent::HTTP::http_get($url, sub {
- handle_pgn(@_, $url);
- });
+ fetch_pgn($url);
} elsif ($msg =~ /^stoppgn$/) {
$t->cmd("tell $who Stopping poll.");
$http_timer = undef;
#print "FICS: [$line]\n";
}
+# Starts periodic fetching of PGNs from the given URL.
+sub fetch_pgn {
+ my ($url) = @_;
+ AnyEvent::HTTP::http_get($url, sub {
+ handle_pgn(@_, $url);
+ });
+}
+
+my ($last_pgn_white, $last_pgn_black);
+my @last_pgn_uci_moves = ();
+my $pgn_hysteresis_counter = 0;
+
sub handle_pgn {
my ($body, $header, $url) = @_;
my $pgn = Chess::PGN::Parse->new(undef, $body);
}
$pos->{'history'} = \@uci_moves;
$pos->{'pretty_history'} = $moves;
- handle_position($pos);
+
+ # Sometimes, PGNs lose a move or two for a short while,
+ # or people push out new ones non-atomically.
+ # Thus, if we PGN doesn't change names but becomes
+ # shorter, we mistrust it for a few seconds.
+ my $trust_pgn = 1;
+ if (defined($last_pgn_white) && defined($last_pgn_black) &&
+ $last_pgn_white eq $pgn->white &&
+ $last_pgn_black eq $pgn->black &&
+ scalar(@uci_moves) < scalar(@last_pgn_uci_moves)) {
+ if (++$pgn_hysteresis_counter < 3) {
+ $trust_pgn = 0;
+ }
+ }
+ if ($trust_pgn) {
+ $last_pgn_white = $pgn->white;
+ $last_pgn_black = $pgn->black;
+ @last_pgn_uci_moves = @uci_moves;
+ $pgn_hysteresis_counter = 0;
+ handle_position($pos);
+ }
}
$http_timer = AnyEvent->timer(after => 1.0, cb => sub {
- AnyEvent::HTTP::http_get($url, sub {
- handle_pgn(@_, $url);
- });
+ fetch_pgn($url);
});
}