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;