#!/usr/bin/perl use strict; use Term::ReadLine; use IO::Socket; use IO::Select; use threads; use threads::shared; ## This is the IGS go server. Welcome to text mode. ## You must create a username on their website to get this to work my @pair = (qw(igs.joyjoy.net 6969)); my $cmds : shared = ""; my $prompt : shared = "igs> "; my $done : shared = 0; my $term = new Term::ReadLine "igs"; my $listener = new threads( \&listener ); &sender; $listener->join; exit; sub sender { while( defined(my $line = $term->readline($prompt)) ) { lock $cmds; $cmds .= "$line\n"; return if $done; } } sub listener { my $sock = new IO::Socket::INET( PeerAddr => $pair[0], PeerPort => $pair[1], Proto => "tcp" ) or logger->error("pfft: $!"); my $sele = new IO::Select; my $eb_count = 0; my $last = time+60; $sele->add( $sock ); while( $sock->connected ) { if( $sele->can_read(0.1) ) { my $buf = undef; my $sock_addr = recv( $sock, $buf, 1024, 0 ); if( not defined $sock_addr ) { die "socket error"; } if( not $buf ) { #print "empty \$buf...\n"; if( (++ $eb_count) >= 20 ) { warn "connection terminated\n(return to quit)\n"; $done = 1; return; } } our $ayt; $ayt -- if $ayt and $buf =~ s/(?:\s*|\b)yes\s*(?=\n)//s; $prompt = $1 if $buf =~ s/([^\r\n]+?)$//s; if( $buf ) { print $buf; $term->set_prompt( $prompt ); $term->forced_update_display; $eb_count = 0; } } if( $cmds ) { lock $cmds; print $sock $cmds; $cmds = ""; } if( $last+60 < (my $now = time) ) { our $ayt ++; print $sock "ayt\n"; $last = $now; } } shutdown $sock, 2; }