From 8733e976299634c8bce83bc8908a99ff669bc2fd Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Tue, 26 Dec 2023 14:50:54 +0100 Subject: [PATCH] Add a very crude function for manual overrides. Needed when the feed is hung but we have some other way of getting the moves. No real undo yet (you can go back in history and do other moves, but not delete anything), and it's pretty slow and sluggish. --- config.pm | 3 +++ remoteglot.pl | 38 +++++++++++++++++++++++++++++++++++++- www/js/remoteglot.js | 23 +++++++++++++++++++++++ www/manual-override.pl | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100755 www/manual-override.pl diff --git a/config.pm b/config.pm index f95d1f7..ec20c34 100644 --- a/config.pm +++ b/config.pm @@ -78,6 +78,9 @@ our $dbistr = "dbi:Pg:dbname=remoteglot"; our $dbiuser = undef; our $dbipass = undef; +# For manual moves made from the web interface. +our $adminpass = undef; + eval { my $config_filename = $ENV{'REMOTEGLOT_CONFIG'} // 'config.local.pm'; require $config_filename; diff --git a/remoteglot.pl b/remoteglot.pl index a792396..8b3a0b7 100755 --- a/remoteglot.pl +++ b/remoteglot.pl @@ -338,9 +338,12 @@ sub handle_pgn { if ($pgn->result eq '1-0' || $pgn->result eq '1/2-1/2' || $pgn->result eq '0-1') { $pos->{'result'} = $pgn->result; } - $pos->{'history'} = \@repretty_moves; + my @extra_moves = (); + $pos = extend_from_manual_override($pos, \@repretty_moves, \@extra_moves); extract_clock($pgn, $pos); + $pos->{'history'} = \@repretty_moves; + $pos->{'extra_moves'} = \@extra_moves; # Sometimes, PGNs lose a move or two for a short while, # or people push out new ones non-atomically. @@ -771,6 +774,11 @@ sub output_screen { } return unless (exists($pos_calculating->{'board'})); + + my $extra_moves = $pos_calculating->{'extra_moves'}; + if (defined($extra_moves) && scalar @$extra_moves > 0) { + $text .= " Manual move extensions: " . join(' ', @$extra_moves) . "\n"; + } if (exists($info->{'pv1'}) && exists($info->{'pv2'})) { # multi-PV @@ -1241,6 +1249,34 @@ sub plot_score { return undef; } +sub extend_from_manual_override { + my ($pos, $moves, $extra_moves) = @_; + + my $q = $dbh->prepare('SELECT next_move FROM game_extensions WHERE fen=? AND history=? AND player_w=? AND player_b=? AND (CURRENT_TIMESTAMP - ts) < INTERVAL \'1 hour\''); + while (1) { + my $player_w = $pos->{'player_w'}; + my $player_b = $pos->{'player_b'}; + if ($player_w =~ /^base64:(.*)$/) { + $player_w = MIME::Base64::decode_base64($1); + } + if ($player_b =~ /^base64:(.*)$/) { + $player_b = MIME::Base64::decode_base64($1); + } + #use Data::Dumper; print Dumper([$pos->fen(), JSON::XS::encode_json($moves), $player_w, $player_b]); + $q->execute($pos->fen(), JSON::XS::encode_json($moves), $player_w, $player_b); + my $ref = $q->fetchrow_hashref; + if (defined($ref)) { + my $move = $ref->{'next_move'}; + ($pos) = $pos->make_pretty_move($move); + push @$moves, $move; + push @$extra_moves, $move; + } else { + last; + } + } + return $pos; +} + sub extract_clock { my ($pgn, $pos) = @_; diff --git a/www/js/remoteglot.js b/www/js/remoteglot.js index 54fc90b..51a470f 100644 --- a/www/js/remoteglot.js +++ b/www/js/remoteglot.js @@ -125,6 +125,9 @@ let reverse_dragging_from = null; /** @type {?number} @private */ let unique = null; +/** @type {?string} @private */ +let admin_password = null; + /** @type {boolean} @private */ let enable_sound = false; @@ -1277,6 +1280,9 @@ function update_board() { } else { document.getElementById("searchstats").textContent = ""; } + if (admin_password !== null) { + document.getElementById("searchstats").innerHTML += " | ADMIN MODE (if password is right)"; + } // Update the board itself. base_fen = data['position']['fen']; @@ -2214,6 +2220,18 @@ function onSnapEnd(source, target) { promotion: 'q' // NOTE: always promote to a queen for example simplicity }); + if (admin_password !== null) { + let url = '/manual-override.pl'; + url += '?fen=' + encodeURIComponent(display_fen); + url += '&history=' + encodeURIComponent(JSON.stringify(current_analysis_data['position']['history'])); + url += '&move=' + encodeURIComponent(move.san); + url += '&player_w=' + encodeURIComponent(current_analysis_data['position']['player_w']); + url += '&player_b=' + encodeURIComponent(current_analysis_data['position']['player_b']); + url += '&password=' + encodeURIComponent(admin_password); + fetch(url); + return; + } + // Move ahead on the line we're on -- this includes history if we've // gone backwards. if (current_display_line && @@ -2459,6 +2477,11 @@ function init() { set_sound(false); } + let admin_match = window.location.href.match(/\?password=([a-zA-Z0-9_-]+)/); + if (admin_match !== null) { + admin_password = admin_match[1]; + } + // Create board. board = new window.ChessBoard('board', { onMoveEnd: function() { board_is_animating = false; }, diff --git a/www/manual-override.pl b/www/manual-override.pl new file mode 100755 index 0000000..616e5ea --- /dev/null +++ b/www/manual-override.pl @@ -0,0 +1,33 @@ +#! /usr/bin/perl +use strict; +use warnings; +use DBI; +use DBD::Pg; +use CGI; +use Encode; +use lib qw(..); +require 'config.pm'; + +my $dbh = DBI->connect($remoteglotconf::dbistr, $remoteglotconf::dbiuser, $remoteglotconf::dbipass) + or die DBI->errstr; +$dbh->{RaiseError} = 1; + +my $cgi = CGI->new; +my $password = Encode::decode_utf8($cgi->param('password')); +if (!defined($password) || $password ne $remoteglotconf::adminpass) { + print CGI->header(-type=>'text/plain; charset=utf-8', -status=>'403 Denied'); + print "Nope.\n"; + exit; +} + +$dbh->do('INSERT INTO game_extensions ( fen, history, player_w, player_b, ts, next_move ) VALUES ( ?, ?, ?, ?, CURRENT_TIMESTAMP, ? )', + undef, + Encode::decode_utf8($cgi->param('fen')), + Encode::decode_utf8($cgi->param('history')), + Encode::decode_utf8($cgi->param('player_w')), + Encode::decode_utf8($cgi->param('player_b')), + Encode::decode_utf8($cgi->param('move'))); +system("touch", $remoteglotconf::json_output); + +print CGI->header(-type=>'text/plain; charset=utf-8'); +print "OK\n"; -- 2.39.2