Author: nornagon
Date: 2004-12-29 07:27:08 -0500 (Wed, 29 Dec 2004)
New Revision: 447

Modified:
   trunk/clients/termvisual/termvisual.pl
Log:
Term::Visual client does some stuff, now.

Modified: trunk/clients/termvisual/termvisual.pl
===================================================================
--- trunk/clients/termvisual/termvisual.pl      2004-12-29 00:55:39 UTC (rev 
446)
+++ trunk/clients/termvisual/termvisual.pl      2004-12-29 12:27:08 UTC (rev 
447)
@@ -1,110 +1,283 @@
 #!/usr/bin/perl
 
+# vim: set ts=4 sw=4 expandtab si ai sta:
+# Term::Visual Haver client
+# This is Free Software, under the terms of the GPL.
+
 use strict;
 use warnings;
 use Carp;
+
 use POE;
+use POE::Wheel::SocketFactory;
+use POE::Wheel::ReadWrite;
+use POE::Filter::Haver;
+
+use Socket;
 use Term::Visual;
 use Haver::Protocol;
 use Haver::Config;
 
-my $config;
+my ($config, %ucommands, %scommands);
 
 POE::Session->create(
-       inline_states => {
-               _start          => \&handle_start,
-               user_input      => \&handle_user_input,
-               shutdown        => \&handle_shutdown,
-               _stop           => \&handle_stop,
-       },
+    inline_states => {
+        _start      => \&handle_start,
+        user_input  => \&handle_user_input,
+        socket_connected    => \&handle_socket_connected,
+        socket_error    => \&handle_socket_error,
+        socket_input    => \&handle_socket_input,
+        shutdown    => \&handle_shutdown,
+        _stop       => \&handle_stop,
+    },
 );
 
-my %commands = (
-       quit    => \&command_quit,
-       connect => \&command_connect,
-);
-       
+###########################################################
+#                        HANDLERS                         #
+###########################################################
+    
 sub handle_start {
-       my ($kernel, $heap) = @_[KERNEL, HEAP];
+    my ($kernel, $heap) = @_[KERNEL, HEAP];
 
-       $heap->{config} = Haver::Config->new(
-               file => "config",
-               default => {
-                       UID             => $ENV{USER} || 'A_User',
-                       Channel => 'lobby',
-                       HistSize        => 50,
-                       BufferSize      => 1000,
-                       Server  => 'localhost',
-                       Port    => '7070',
-                       CommandChars    => '/.',
-               },
-       );
+    $heap->{config} = Haver::Config->new(
+        file => "config",
+        default => {
+            UID     => $ENV{USER} || 'A_User',
+            Channel => 'lobby',
+            HistSize    => 50,
+            BufferSize  => 1000,
+            Server  => 'localhost',
+            Port    => '7070',
+            CommandChars    => '/.',
+        },
+    );
 
-       $heap->{vt} = Term::Visual->new( Alias => "user_interface" );
+    $heap->{vt} = Term::Visual->new( Alias => "user_interface" );
 
-       $heap->{window_id} = $heap->{vt}->create_window(
-               Window_Name             => "foo",
-#              Status                  => { 0 => { format => "template for 
status line 1.",
-#                                                              fields => 
[qw(text)] },
-#                                                 },
-               Buffer_Size             => $heap->{config}{BufferSize},
-               History_Size    => $heap->{config}{HistSize},
-               Status_Height   => 1,
-               Title                   => "Haver"
-       );
-       
-       $kernel->post( user_interface => send_me_input => "user_input" );
+    $heap->{window_id} = $heap->{vt}->create_window(
+        Window_Name     => "foo",
+        Status          => { 0 => { format => "Server: %s",
+                               fields => [qw(server)] },
+                           },
+        Buffer_Size     => $heap->{config}{BufferSize},
+        History_Size    => $heap->{config}{HistSize},
+        Status_Height   => 1,
+        Title           => "Haver"
+    );
+    
+    $kernel->post( user_interface => send_me_input => "user_input" );   
 
-#      $vt->set_status_field($window_id, text => "status field");
-#      $kernel->alarm(update_time => int(time() / 60) * 60 + 60);
+    $heap->{vt}->set_status_field($heap->{window_id}, server => "[none]");
+#   $kernel->alarm(update_time => int(time() / 60) * 60 + 60);
 }
 
 sub handle_stop {
 }
 
 sub handle_shutdown {
-       my ($kernel, $heap) = @_[KERNEL, HEAP];
-#      $heap->{vt}->delete_window($heap->{window_id});
-#      $heap->{vt}->shutdown;
-       $heap->{config}->save;
-       exit;
+    my ($kernel, $heap) = @_[KERNEL, HEAP];
+    $heap->{config}->save;
+    $heap->{vt}->delete_window($heap->{window_id});
+    $heap->{vt}->shutdown;
+    exit;
 }
 
 sub handle_user_input {
-       my ($kernel, $heap, $input, $exception) = @_[KERNEL, HEAP, ARG0, ARG1];
+    my ($kernel, $heap, $input, $exception) = @_[KERNEL, HEAP, ARG0, ARG1];
 
-       if (defined $exception) {
-               warn "Got exception: $exception";
-               $heap->{config}->save;
-               command_quit();
-               exit;
-       }
+    if (defined $exception) {
+        warn "Got exception: $exception";
+        $kernel->yield("shutdown");
+        return;
+    }
 
-       if ($input =~ /^\s*[$heap->{config}{CommandChars}](.+)$/x) {
-               my @args = split / /, $1;
-               my $cmd = shift @args;
-               if (exists $commands{$cmd}) {
-                       &{$commands{$cmd}}(@args);
-               } else {
-                       $heap->{vt}->print($heap->{window_id}, "Unknown 
command: $cmd");
-               }
-               return;
-       }
-       
-       $heap->{vt}->print($heap->{window_id}, "$input");
+    # Handle user commands.
+    # A command character followed directly by some text equates a command.
+    # Eg: /quit; .connect
+    if ($input =~ /^\s*[$heap->{config}{CommandChars}](.+)$/x) {
+        my @input = split / /, $1;
+        if (exists $ucommands{$input[0]}) {
+            my $cmd = shift @input;
+            &{$ucommands{$cmd}}(@input);
+        } else {
+            $heap->{vt}->print($heap->{window_id}, "Unknown command: 
$input[0]");
+        }
+    } else {
+        chan_msg('lobby', $input);
+    }
 }
 
+#---------------------SOCKET EVENTS-----------------------#
+
+sub handle_socket_connected {
+    my ($heap, $socket) = @_[HEAP, ARG0];
+    
+    $heap->{vt}->print($heap->{window_id}, "Connected.");
+    delete $heap->{socketfactory};
+    $heap->{socket} = new POE::Wheel::ReadWrite(
+        Handle  => $socket,
+        InputEvent  => 'socket_input',
+        ErrorEvent  => 'socket_error',
+        Filter  => new POE::Filter::Haver,
+    );
+
+    $heap->{vt}->set_status_field($heap->{window_id},
+        server => $heap->{config}{Server});
+
+    $heap->{socket}->put(['HAVER', 'Term::Visual/0.01']);
+}
+
+sub handle_socket_error {
+    my ($heap, $syscall, $errno, $error) = @_[HEAP, ARG0 .. ARG2];
+    $error = "Normal disconnection" unless $errno;
+    $heap->{vt}->print($heap->{window_id}, "Encountered $syscall ".
+        "error $errno: $error");
+}
+
+sub handle_socket_input {
+    my ($heap, $input) = @_[HEAP, ARG0];
+    $heap->{vt}->print($heap->{window_id}, 'Received '.join(' ', @$input));
+    if (exists $scommands{$$input[0]}) {
+        my $cmd = shift @$input;
+        &{$scommands{$cmd}}(@$input);
+    } else {
+        $heap->{vt}->print($heap->{window_id}, "Can't handle $$input[0]");
+    }
+}
+
+###########################################################
+#                     SERVER COMMANDS                     #
+###########################################################
+
+%scommands = (
+    HAVER   => \&server_haver,
+    WANT    => \&server_want,
+    ACCEPT  => \&server_accept,
+    LIST    => \&server_list,
+    JOIN    => \&server_join,
+    MSG     => \&server_msg,
+);
+
+sub server_haver {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    $heap->{vt}->print($heap->{window_id}, "Server version: ".shift);
+}
+
+sub server_want {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    my ($want) = $_[0];
+    if ($want eq 'IDENT') {
+        $heap->{socket}->put(['IDENT', $heap->{config}{UID}]);
+    } else {
+        $heap->{vt}->print($heap->{window_id}, "Unhandlable WANT: $want");
+    }
+}
+
+sub server_accept {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    my ($uid) = $_[0];
+    $heap->{vt}->print($heap->{window_id}, "UID accepted: $uid");
+}
+
+sub server_list {
+    my $cid = shift;
+    my $type = shift;
+    if ($type ne 'user') {
+        vt_print("Unknown LIST type: $type");
+        return;
+    }
+    vt_print("Users in $cid: ".join(" ", @_));
+}
+
+sub server_join {
+    my ($cid, $user) = @_;
+    vt_print("$user has joined $cid");
+}
+
+sub server_msg {
+    my ($cid, $user, $msg) = @_;
+    vt_print("$cid:<$user> $msg");
+}
+
+###########################################################
+#                      USER COMMANDS                      #
+###########################################################
+
+%ucommands = (
+    quit    => \&command_quit,
+    connect => \&command_connect,
+    save    => \&command_save,
+    join    => \&command_join,
+    names   => \&command_names,
+);
+
 sub command_quit {
-       my $heap = $poe_kernel->get_active_session()->get_heap();
-       $heap->{vt}->print($heap->{window_id}, "Shutting down...");
-       $heap->{config}->save;
-       exit;
+#   my $heap = $poe_kernel->get_active_session()->get_heap();
+#   $heap->{vt}->print($heap->{window_id}, "Shutting down...");
+    $poe_kernel->yield("shutdown");
+    return;
 }
 
 sub command_connect {
-       my $heap = $poe_kernel->get_active_session()->get_heap();
-       $heap->{vt}->print($heap->{window_id}, "Connect command received");
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    my ($server, $port);
+
+    $server = $_[0] || undef;
+    $port   = $_[1] || undef;
+
+    $port = 7070 if (!defined $port && defined $server);
+
+    if (defined $server) {
+        $heap->{config}{Server} = $server;
+        $heap->{config}{Port}   = $port;
+    }
+    
+    $heap->{vt}->print($heap->{window_id},
+        "Connecting to $heap->{config}{Server}:$heap->{config}{Port}...");
+
+    $heap->{socketfactory} = POE::Wheel::SocketFactory->new(
+        RemoteAddress   => $heap->{config}{Server},
+        RemotePort      => $heap->{config}{Port},
+        SuccessEvent    => 'socket_connected',
+        FailureEvent    => 'socket_error',
+    );
 }
 
+sub command_save {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    $heap->{config}->save;
+    $heap->{vt}->print($heap->{window_id}, "Configuration saved.");
+}
+
+sub command_join {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    my $cid = $_[0] || undef;
+    if (!defined $cid) {
+        $heap->{vt}->print($heap->{window_id}, "Syntax: /join <cid>");
+        return;
+    }
+    $heap->{vt}->print($heap->{window_id}, "Joining channel $cid");
+    $heap->{socket}->put(['JOIN', $cid]);
+}
+
+sub command_names {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    vt_print("Retrieving name list...");
+    $heap->{socket}->put(['LIST', 'lobby', 'user']);
+}
+
+# Misc functions
+
+sub vt_print {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    $heap->{vt}->print($heap->{window_id}, @_);
+}
+
+sub chan_msg {
+    my $heap = $poe_kernel->get_active_session()->get_heap();
+    my ($chan, $msg) = (shift, shift);
+    $heap->{socket}->put(['MSG', $chan, $msg]);
+}
+
 POE::Kernel->run();
 exit 0;


Reply via email to