Author: dylan
Date: 2004-06-27 22:37:38 -0400 (Sun, 27 Jun 2004)
New Revision: 264
Added:
trunk/main/server/lib/Haver/Server/Object/POE.pm
trunk/main/server/lib/Haver/Server/POE/Broadcaster.pm
Modified:
trunk/main/server/bin/haverd.pl
trunk/main/server/lib/Haver/Server/Object.pm
trunk/main/server/lib/Haver/Server/Object/Channel.pm
trunk/main/server/lib/Haver/Server/Object/Index.pm
trunk/main/server/lib/Haver/Server/Object/User.pm
trunk/main/server/lib/Haver/Server/POE.pm
trunk/main/server/lib/Haver/Server/POE/Commands.pm
trunk/main/server/lib/Haver/Server/POE/Connection.pm
trunk/main/server/lib/Haver/Server/POE/Listener.pm
trunk/main/server/lib/Haver/Server/Registry.pm
Log:
Oy vey. I've re-written the server to be a bit
cleaner. it is still a mess, though.
haverd.pl should work, though.
Modified: trunk/main/server/bin/haverd.pl
===================================================================
--- trunk/main/server/bin/haverd.pl 2004-06-27 20:57:14 UTC (rev 263)
+++ trunk/main/server/bin/haverd.pl 2004-06-28 02:37:38 UTC (rev 264)
@@ -18,19 +18,9 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
use strict;
use warnings;
-use Haver::Preprocessor qw( :verbose :assert :dump :debug );
+use Haver::Preprocessor qw( -verbose -assert -debug );
use Haver::Server::POE;
-use Getopt::Long;
-my $confdir = './conf';
-my $datadir = './data';
-GetOptions (
- "confdir=s" => \$confdir,
- "datadir=s" => \$datadir,
-);
+Haver::Server::POE->boot('config.yml');
-
-Haver::Server::POE->boot(
- confdir => $confdir,
- datadir => $datadir,
-);
+POE::Kernel->run;
Modified: trunk/main/server/lib/Haver/Server/Object/Channel.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Object/Channel.pm 2004-06-27
20:57:14 UTC (rev 263)
+++ trunk/main/server/lib/Haver/Server/Object/Channel.pm 2004-06-28
02:37:38 UTC (rev 264)
@@ -21,9 +21,9 @@
use Haver::Server::Object;
use Haver::Server::Object::Index;
-use base qw( Haver::Server::Object Haver::Server::Object::Index );
+use base qw( Haver::Server::Object );
-our $VERSION = '0.05';
+our $VERSION = 0.09;
sub namespace {
return 'channel';
@@ -35,12 +35,5 @@
!$obj->isa(__PACKAGE__);
}
-sub send {
- my $me = shift;
- foreach my $user ($me->list_vals('user')) {
- $user->send(@_);
- }
-}
-
1;
Modified: trunk/main/server/lib/Haver/Server/Object/Index.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Object/Index.pm 2004-06-27 20:57:14 UTC
(rev 263)
+++ trunk/main/server/lib/Haver/Server/Object/Index.pm 2004-06-28 02:37:38 UTC
(rev 264)
@@ -23,99 +23,11 @@
our $VERSION = 0.05;
our $RELOAD = 1;
-our $IdPattern ||= qr/[a-z][a-z0-9_'.-]+/;
+
sub namespace {
return 'container';
}
-sub has_namespace {
- my ($me, $ns) = @_;
- return exists $me->{".$ns"};
-}
-sub is_valid_id {
- my ($this, $uid) = @_;
-
- if (defined $uid && $uid =~ /^$IdPattern$/) {
- return 1;
- } else {
- return 0;
- }
-}
-
-sub namespaces {
- my ($me) = @_;
- my @ns = ();
-
- @ns = grep(s/^\.//, keys %{ $me });
-
- return wantarray ? @ns : [EMAIL PROTECTED];
-}
-
-sub add {
- my ($me, $object) = @_;
- my $id = $object->id;
- my $ns = $object->namespace;
-
- if (not($me->contains($ns, $id)) && $me->can_contain($object)) {
- $me->{".$ns"}{$id} = $object;
- $me->{".$ns"}{$id}
- } else {
- return undef;
- }
-}
-
-sub fetch {
- my ($me, $ns, $id) = @_;
- if (@_ != 3) {
- croak "fetch must be called with exactly three arguments!";
- }
-
- return $me->{".$ns"}{$id} if $me->contains($ns, $id);
-}
-
-sub contains {
- my ($me, $ns, $id) = @_;
- if (@_ != 3) {
- croak "contains must be called with exactly three arguments!";
- }
-
- delete $me->{".$ns"}{$id} unless defined $me->{".$ns"}{$id};
- return exists $me->{".$ns"}{$id};
-}
-
-sub remove {
- my $me = shift;
- my ($ns, $id);
-
- if (@_ == 1 && ref $_[0]) {
- my $o = $_[0];
- $ns = $o->namespace;
- $id = $o->id;
- } elsif (@_ == 2) {
- ($ns, $id) = @_;
- } else {
- die "Wrong number of arguments.";
- }
- delete $me->{".$ns"}{$id};
-}
-
-sub list_ids {
- my ($me, $ns) = @_;
- my $h = $me->{".$ns"};
-
- wantarray ? keys %$h : [ keys %$h ];
-}
-sub list_vals {
- my ($me, $ns) = @_;
- my $h = $me->{".$ns"};
-
- wantarray ? values %$h : [ values %$h ];
-}
-sub can_contain {
- # Can contain anything, really.
- 1;
-}
-
1;
Added: trunk/main/server/lib/Haver/Server/Object/POE.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Object/POE.pm 2004-06-27 20:57:14 UTC
(rev 263)
+++ trunk/main/server/lib/Haver/Server/Object/POE.pm 2004-06-28 02:37:38 UTC
(rev 264)
@@ -0,0 +1,53 @@
+# vim: set ft=perl ts=4 sw=4:
+# Haver::Server::Object::POE - Add poe methods to Haver::Server::Objects
+#
+# Copyright (C) 2004 Dylan William Hardison.
+#
+# This module is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This module is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this module; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+package Haver::Server::Object;
+use strict;
+use warnings;
+
+use POE;
+
+our $VERSION = 0.01;
+
+sub wheel : lvalue {
+ my ($me) = @_;
+
+ $me->{wheel};
+}
+
+sub sid : lvalue {
+ my ($me) = @_;
+
+ $me->{sid};
+}
+
+sub put {
+ my ($me, $msg) = @_;
+
+ $me->{wheel}->put($msg);
+}
+
+sub post {
+ my $me = shift;
+
+ $poe_kernel->post($me->{sid}, @_);
+}
+
+
+1;
+
Modified: trunk/main/server/lib/Haver/Server/Object/User.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Object/User.pm 2004-06-27 20:57:14 UTC
(rev 263)
+++ trunk/main/server/lib/Haver/Server/Object/User.pm 2004-06-28 02:37:38 UTC
(rev 264)
@@ -23,8 +23,7 @@
use Haver::Preprocessor;
use Haver::Server::Object;
use Haver::Server::Object::Index;
-use Haver::Server::Globals qw( $Config );
-use base qw( Haver::Server::Object Haver::Server::Object::Index );
+use base qw( Haver::Server::Object );
our $VERSION = 0.05;
Modified: trunk/main/server/lib/Haver/Server/Object.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Object.pm 2004-06-27 20:57:14 UTC
(rev 263)
+++ trunk/main/server/lib/Haver/Server/Object.pm 2004-06-28 02:37:38 UTC
(rev 264)
@@ -18,17 +18,16 @@
package Haver::Server::Object;
use strict;
use warnings;
+use Haver::Preprocessor;
use Carp;
use Fatal qw(:void open close opendir closedir);
use Haver::Base;
-use Haver::Preprocessor;
-
-use YAML (); # Load, Dump
+use Storable (); # nstore, retrieve.
use File::Basename (); # fileparse
use File::Spec;
-use Scalar::Util (); # weaken
use File::Path ();
+
# Subclass Haver::Savable
use base 'Haver::Savable';
@@ -57,6 +56,9 @@
attrib => 'pl',
);
+
+our $IdPattern ||= qr/[a-z][a-z0-9_'.-]+/;
+
our %Types = (
# '' => 'public',
'+' => 'broadcast',
@@ -92,9 +94,15 @@
$me->SUPER::initialize();
- $me->{_fields} = {};
- $me->{_flags} = {};
+ $me->{_fields} = {};
+ $me->{_flags} = {};
$me->{id} ||= $ID++;
+
+ my @ns = @{ (delete $me->{namespaces}) || [] };
+
+ foreach my $ns (@ns) {
+ $me->{".$ns"} = {};
+ }
return $me;
}
@@ -102,13 +110,9 @@
## Accessor methods.
sub id {
- my ($me, $val) = @_;
+ my ($me) = @_;
- if (@_ == 2) {
- return $me->{id} = $val;
- } else {
- return $me->{id};
- }
+ return $me->{id};
}
sub filename {
@@ -118,11 +122,21 @@
sub directory {
my ($me) = @_;
- my ($vol, $dir) = File::Spec->splitpath($me->filename);
- return $vol.$dir;
+ return File::Spec->catdir($StorageDir, $me->namespace);
}
+
+sub saved_ids {
+ my ($me) = @_;
+ my $dir = $me->directory;
+ my $dh;
+ opendir $dh, $dir or return ();
+ my @dirs = readdir $dh;
+ closedir $dh;
+ return wantarray ? @dirs : [EMAIL PROTECTED];
+}
+
## Flag methods
sub get_flags {
my ($me, $key) = @_;
@@ -238,6 +252,16 @@
return \%data;
}
+sub _init_data {
+ my ($me) = @_;
+
+ $me->{_fields} = (delete $me->{'-default'}{fields}) || {};
+ $me->{_flags} = (delete $me->{'-default'}{flags}) || {};
+ delete $me->{'-default'};
+
+ 1;
+}
+
sub _load_data {
my ($me, $data) = @_;
@@ -247,8 +271,8 @@
ASSERT: $data->{Class} eq ref($me);
use warnings;
- $me->{_fields} = delete $data->{fields};
- $me->{_flags} = delete $data->{flags};
+ %{$me->{_fields}} = (%{$me->{_fields}}, %{delete $data->{fields}});
+ %{$me->{_flags}} = (%{$me->{_flags}}, %{delete $data->{flags}});
1;
}
@@ -266,6 +290,113 @@
return $me->namespace . '/' . $me->id;
}
+
+sub write_file {
+ my ($me, $file, $data) = @_;
+ Storable::nstore($data, $file);
+}
+
+sub read_file {
+ my ($me, $file) = @_;
+ Storable::retrieve($file);
+}
+
+
+
+
+sub has_namespace {
+ my ($me, $ns) = @_;
+ return exists $me->{".$ns"};
+}
+
+sub is_valid_id {
+ my ($this, $uid) = @_;
+
+ if (defined $uid && $uid =~ /^$IdPattern$/) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+sub namespaces {
+ my ($me) = @_;
+ my @ns = ();
+
+ @ns = grep(s/^\.//, keys %{ $me });
+
+ return wantarray ? @ns : [EMAIL PROTECTED];
+}
+
+sub add {
+ my ($me, $object) = @_;
+ my $id = $object->id;
+ my $ns = $object->namespace;
+
+ if (not($me->contains($ns, $id)) && $me->can_contain($object)) {
+ $me->{".$ns"}{$id} = $object;
+ $me->{".$ns"}{$id}
+ } else {
+ return undef;
+ }
+}
+
+sub fetch {
+ my ($me, $ns, $id) = @_;
+ if (@_ != 3) {
+ croak "fetch must be called with exactly three arguments!";
+ }
+
+ return $me->{".$ns"}{$id} if $me->contains($ns, $id);
+}
+
+sub contains {
+ my ($me, $ns, $id) = @_;
+ if (@_ != 3) {
+ croak "contains must be called with exactly three arguments!";
+ }
+
+ delete $me->{".$ns"}{$id} unless defined $me->{".$ns"}{$id};
+ return exists $me->{".$ns"}{$id};
+}
+
+sub remove {
+ my $me = shift;
+ my ($ns, $id);
+
+ if (@_ == 1 && ref $_[0]) {
+ my $o = $_[0];
+ $ns = $o->namespace;
+ $id = $o->id;
+ } elsif (@_ == 2) {
+ ($ns, $id) = @_;
+ } else {
+ die "Wrong number of arguments.";
+ }
+ delete $me->{".$ns"}{$id};
+}
+
+sub list_ids {
+ my ($me, $ns) = @_;
+ my $h = $me->{".$ns"};
+
+ wantarray ? keys %$h : [ keys %$h ];
+}
+sub list_vals {
+ my ($me, $ns) = @_;
+ my $h = $me->{".$ns"};
+
+ wantarray ? values %$h : [ values %$h ];
+}
+sub can_contain {
+ # Can contain anything, really.
+ 1;
+}
+
+
+
+
+
1;
=head1 NAME
Added: trunk/main/server/lib/Haver/Server/POE/Broadcaster.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE/Broadcaster.pm 2004-06-27
20:57:14 UTC (rev 263)
+++ trunk/main/server/lib/Haver/Server/POE/Broadcaster.pm 2004-06-28
02:37:38 UTC (rev 264)
@@ -0,0 +1,71 @@
+# vim: set ft=perl ts=4 sw=4:
+# Haver::Server::POE::Broadcaster - description
+#
+# Copyright (C) 2004 Dylan William Hardison.
+#
+# This module is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This module is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this module; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+package Haver::Server::POE::Broadcaster;
+use strict;
+use warnings;
+use POE;
+
+our $VERSION = 0.01;
+use Haver::Preprocessor;
+use Haver::Server::Registry qw( $Registry );
+
+use constant CHUNK => 10;
+
+sub create {
+ my ($this) = @_;
+
+ POE::Session->create(
+ package_states => [
+ $this => [qw(
+ _start
+ _stop
+ send
+ )],
+ ],
+ );
+}
+
+sub _start {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+
+ $kernel->alias_set('Broadcaster');
+}
+
+sub send {
+ my ($kernel, $heap, $target, $msg) = @_[KERNEL, HEAP, ARG0, ARG1];
+ # ASSERT: ref($target) eq 'ARRAY' and ref($msg) eq 'ARRAY';
+ my $n = @$target;
+ my $end = $n > CHUNK ? CHUNK : $n;
+ my @targ = splice(@$target, 0, $end);
+
+ foreach my $t (@targ) {
+ my $u = ref $t ? $t : $Registry->fetch('user', $t);
+ eval { $u->wheel->put($msg) };
+ warn $@ if $@;
+ }
+
+ if (@$target) {
+ $kernel->yield('send', $target, $msg);
+ }
+}
+
+sub _stop { }
+
+1;
+
Modified: trunk/main/server/lib/Haver/Server/POE/Commands.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE/Commands.pm 2004-06-27 20:57:14 UTC
(rev 263)
+++ trunk/main/server/lib/Haver/Server/POE/Commands.pm 2004-06-28 02:37:38 UTC
(rev 264)
@@ -28,7 +28,9 @@
use Haver::Preprocessor;
use Digest::SHA1 qw(sha1_base64);
use Haver::Util::Misc ();
+use Haver::Server::Registry qw( $Registry );
+
our $VERSION = 0.02;
our $RELOAD = 1;
our @Commands = qw(
@@ -37,11 +39,12 @@
PONG
AUTH
AUTH:PASS
- IN TO THIS
+ IN TO
MSG JOIN PART QUIT
USERS
);
+
sub _mkcmd {
my $func = $_;
$func =~ s/:/_/g;
@@ -59,6 +62,7 @@
return \%cmds;
}
+
sub do_unknown_cmd {
my ($kernel, $heap, $event, $args) = @_[KERNEL, HEAP, ARG0, ARG1];
@@ -85,8 +89,8 @@
} else {
my $user = new Haver::Server::Object::User(
id => $uid,
- sid => $_[SESSION]->ID,
wheel => $heap->{socket},
+ sid => $_[SESSION]->ID,
);
$user->set(
mode => $mode,
@@ -210,19 +214,19 @@
'IN', $heap->{scope}{cid},
'MSG', $heap->{uid}, @$args,
);
- $kernel->post('Registry', 'broadcast', $users, [EMAIL
PROTECTED]);
+ $kernel->post('Broadcaster', 'send', $users, [EMAIL PROTECTED]);
} elsif ($heap->{scope}{uid}) {
if (not ref $heap->{scope}{uid}) {
my $user = $Registry->fetch('user',
$heap->{scope}{uid});
- $user->send(['MSG', $heap->{uid}, @$args]);
+ $user->put(['MSG', $heap->{uid}, @$args]);
} else {
my @msg = ( 'MSG', $heap->{uid}, @$args );
- $kernel->post('Registry', 'broadcast',
$heap->{scope}{uid}, [EMAIL PROTECTED]);
+ $kernel->post('Broadcaster', 'send',
$heap->{scope}{uid}, [EMAIL PROTECTED]);
}
} else {
return unless check_perm_access($heap->{user}, 'global msg');
my $users = $Registry->list_ids('user');
- $kernel->post('Registry', 'broadcast', $users, ['MSG',
$heap->{uid}, @$args]);
+ $kernel->post('Broadcaster', 'send', $users, ['MSG',
$heap->{uid}, @$args]);
}
}
@@ -242,7 +246,7 @@
$chan->add($user);
$user->add($chan);
my $uids = $chan->list_ids('user');
- $kernel->post('Registry', 'broadcast', $uids,
+ $kernel->post('Broadcaster', 'send', $uids,
['IN', $cid, 'JOIN', $heap->{uid}],
);
} else {
@@ -261,7 +265,7 @@
if ($user->contains('channel', $cid)) {
my $chan = $Registry->fetch('channel', $cid);
my $uids = $chan->list_ids('user');
- $kernel->post('Registry', 'broadcast', $uids, ['IN', $cid,
'PART', $uid]);
+ $kernel->post('Broadcaster', 'send', $uids, ['IN', $cid,
'PART', $uid]);
$chan->remove($user);
$user->remove($chan);
} else {
@@ -287,6 +291,7 @@
$kernel->yield('shutdown', 'ACTIVE', @$args);
}
+my $PingTime = 60;
#> PONG($time)
sub cmd_PONG {
my ($kernel, $heap, $args) = @_[KERNEL, HEAP, ARG0];
@@ -295,7 +300,7 @@
if ($time eq $heap->{ping_time}) {
$kernel->alarm_remove($heap->{ping});
$heap->{ping} = $kernel->alarm_set('send_ping',
- time + $Config->{Server}{PingTime} +
int(rand(5)));
+ time + $PingTime + int(rand(5)));
$heap->{ping_time} = undef;
} else {
$kernel->yield('bye', 'BAD PING');
Modified: trunk/main/server/lib/Haver/Server/POE/Connection.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE/Connection.pm 2004-06-27
20:57:14 UTC (rev 263)
+++ trunk/main/server/lib/Haver/Server/POE/Connection.pm 2004-06-28
02:37:38 UTC (rev 264)
@@ -1,4 +1,4 @@
-# Haver::Server::Connection,
+# Haver::Server::POE::Connection,
# this creates a session, which represents the user...
#
# Copyright (C) 2003 Dylan William Hardison.
@@ -18,7 +18,7 @@
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# TODO, write POD. Soon.
-package Haver::Server::Connection;
+package Haver::Server::POE::Connection;
use strict;
use Carp qw(croak confess carp cluck);
@@ -31,52 +31,50 @@
use Haver::Protocol;
use Haver::Server::POE::Commands;
+use Haver::Server::Registry qw( $Registry );
+use Scalar::Util ();
use Digest::SHA1 qw( sha1_base64 );
-
our $RELOAD = 1;
-
sub create {
- my ($class, @args) = @_;
- my $C = "Haver::Server::POE::Commands";
+ my ($class) = shift;
+ # ASSERT: (@_ == 1 and ref($_[0]) eq 'HASH') or ((@_ % 2) == 0);
+ my $opts = @_ == 1 ? $_[0] : { @_ };
+
POE::Session->create(
package_states => [
$class => {
# POE states
- '_start' => '_start',
- '_stop' => '_stop',
- '_default' => '_default',
+ _start => '_start',
+ _stop => '_stop',
+ _default => '_default',
# Wheel states
- 'socket_input' => 'socket_input',
- 'socket_error' => 'socket_error',
- 'socket_flush' => 'socket_flush',
+ socket_input => 'socket_input',
+ socket_error => 'socket_error',
+ socket_flush => 'socket_flush',
# Utility states
- 'want' => 'on_want',
- 'cleanup' => 'on_cleanup',
- 'shutdown' => 'on_shutdown',
+ want => 'on_want',
+ cleanup => 'on_cleanup',
+ 'shutdown' => 'on_shutdown',
'warn' => 'on_warn',
'die' => 'on_die',
'accept' => 'on_accept',
- 'auth' => 'on_auth',
- 'send_ping' => 'on_send_ping',
-# 'broadcast' => 'on_broadcast',
-
+ auth => 'on_auth',
+ unknown_cmd => 'on_unknown_cmd',
},
- $C => $C->commands,
],
- heap => {
- },
- args => [EMAIL PROTECTED],
+ heap => {},
+ args => [ $opts ],
);
}
sub _start {
- my ($heap, $session, $kernel, $socket, $address, $port ) =
- @_[ HEAP, SESSION, KERNEL, ARG0, ARG1, ARG2];
+ my ($heap, $session, $kernel, $opt) = @_[ HEAP, SESSION, KERNEL,
ARG0];
+ my ($address, $socket, $port) = ($opt->{address}, $opt->{sock},
$opt->{port});
$address = Socket::inet_ntoa($address);
$kernel->post('Logger', 'note', 'Socket Birth');
@@ -102,8 +100,6 @@
%$heap = (
timer => $timer,
- ping => undef,
- ping_time => undef,
socket => $sock,
shutdown => 0,
plonk => 0,
@@ -113,7 +109,7 @@
uid => undef,
);
- $sock->put(['HAVER', 3, "line=$Config->{Server}{LineLimit}"]);
+ $sock->put(['HAVER', 3, "line=2048"]);
$kernel->yield('want', 'IDENT',
address => $address,
port => $port,
@@ -168,12 +164,6 @@
return if $heap->{plonk};
return if $heap->{shutdown};
- if ($heap->{ping} && !$heap->{ping_time}) {
- $kernel->alarm_remove($heap->{ping});
- $heap->{ping} = $kernel->alarm_set(
- 'send_ping',
- time + $Config->{Server}{PingTime});
- }
my $want = 0;
my $cmd = shift @$args;
@@ -196,6 +186,7 @@
$kernel->yield('die', 'SPEEDY');
}
}
+
sub socket_flush {
my ($kernel, $heap) = @_[KERNEL, HEAP];
@@ -214,6 +205,12 @@
}
+sub on_unknown_cmd {
+ my ($kernel, $heap, $event, $args) = @_[KERNEL, HEAP, ARG0, ARG1];
+
+ $kernel->yield('warn', UCMD => [$event], $heap->{scope}{cid});
+}
+
sub on_shutdown {
my ($kernel, $heap, $session, @args) = @_[KERNEL, HEAP, SESSION, ARG0
.. $#_];
return if $heap->{shutdown};
@@ -244,6 +241,7 @@
my @args = $opts{args} ? @{$opts{args}} : ();
$heap->{socket}->put(['WANT', $want, @args]);
}
+
sub on_cleanup {
my ($kernel, $heap, @args) = @_[KERNEL, HEAP, ARG0 .. $#_];
@@ -263,13 +261,11 @@
foreach my $chan ($user->list_vals('channel')) {
$user->remove($chan);
$chan->remove($user);
- push(@users, $chan->list_vals('user'));
+ push(@users, $chan->list_ids('user'));
}
my %users = map { ($_ => $_) } @users;
my $msg = ['QUIT', $uid, @args];
- foreach my $u (values %users) {
- eval { $u->send($msg) };
- }
+ $kernel->post('Broadcaster', 'send', [ keys %users ],
$msg);
}
if ($user) {
($heap->{port}, $heap->{address}) = $user->get('.port',
'.address');
@@ -315,13 +311,8 @@
my ($kernel, $heap, $uid, $user) = @_[KERNEL, HEAP, ARG0, ARG1];
$kernel->alarm_remove(delete $heap->{timer});
- $heap->{ping} = $kernel->alarm_set(
- 'send_ping',
- time + $Config->{Server}{PingTime});
- $heap->{ping_time} = undef;
-
-
+
$Registry->add($user);
$heap->{user} = $user;
$heap->{uid} = $uid;
@@ -350,19 +341,4 @@
);
}
-sub on_send_ping {
- my ($kernel, $heap) = @_[KERNEL, HEAP];
-
- my $time = time;
- $heap->{socket}->put(['PING', $time]);
-
- $heap->{ping} = $kernel->alarm_set(
- 'shutdown', time + $Config->{Server}{PingTime}, 'PING');
- $heap->{ping_time} = $time;
-
- $kernel->post('Logger', 'note', "Sending PING: $time");
-}
-
-
-
1;
Modified: trunk/main/server/lib/Haver/Server/POE/Listener.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE/Listener.pm 2004-06-27 20:57:14 UTC
(rev 263)
+++ trunk/main/server/lib/Haver/Server/POE/Listener.pm 2004-06-28 02:37:38 UTC
(rev 264)
@@ -32,61 +32,106 @@
use Haver::Server::POE::Connection;
sub create {
- my ($class, %opts) = @_;
+ my $class = shift;
+ # ASSERT: (@_ == 1 and ref($_[0]) eq 'HASH') or ((@_ % 2) == 0);
+ my $opts = @_ == 1 ? $_[0] : { @_ };
+
POE::Session->create(
package_states =>
[
- $class => [
- '_start',
- '_stop',
- 'socket_birth',
- 'socket_fail',
- ]
+ $class => [qw(
+ _start
+ _stop
+ socket_birth
+ socket_fail
+ listen
+ shutdown
+ )],
],
- heap => {
- port => $opts{port},
- },
- args => [EMAIL PROTECTED],
+ heap => $opts,
);
}
sub _start {
my ($kernel, $heap) = @_[KERNEL, HEAP];
- my $port = $heap->{port};
- DEBUG: "Listener starts.";
+ # DEBUG(session): "Listener starts.";
+ $heap->{conn} = {};
+ $heap->{kids} = {};
+ $kernel->alias_set('Listener');
+
+ my $ifaces = $heap->{interfaces};
+ return unless $ifaces;
+
+ foreach my $i (@$ifaces) {
+ $kernel->yield('listen', $i->{host}, $i->{port});
+ }
+
+}
+
+sub _stop {
+ my ($kernel, $heap) = @_[KERNEL,HEAP];
+ delete $heap->{listener};
+ delete $heap->{session};
+ #DEBUG(session): "Listener stops.";
+}
+
+sub _child {
+ my ($kernel, $heap, $type, $kid) = @_[KERNEL, HEAP, ARG0, ARG1];
+
+ if ($type eq 'create' or $type eq 'gain') {
+ $heap->{kids}{$kid->ID} = 1;
+ } elsif ($type eq 'lose') {
+ delete $heap->{kids}{$kid->ID};
+ } else {
+ die "I don't know how I got here!\n";
+ }
+}
+
+sub listen {
+ my ($kernel, $heap, $host, $port) = @_[KERNEL, HEAP, ARG0, ARG1];
$kernel->post('Logger', 'note', "Listening on port $port.");
- $heap->{listener} = POE::Wheel::SocketFactory->new(
- #BindAddress => '127.0.0.1',
+ my $wheel = POE::Wheel::SocketFactory->new(
BindPort => $port,
Reuse => 1,
SuccessEvent => 'socket_birth',
FailureEvent => 'socket_fail',
);
- $kernel->alias_set('Listener');
+ $heap->{conn}{$wheel->ID} = {
+ wheel => $wheel,
+ host => $host,
+ port => $port,
+ };
}
-sub _stop {
- my ($kernel, $heap) = @_[KERNEL,HEAP];
- delete $heap->{listener};
- delete $heap->{session};
- DEBUG: "Listener stops.";
-}
+
+
sub socket_birth {
- my ($kernel, $socket, $address, $port) = @_[ KERNEL, ARG0, ARG1, ARG2 ];
+ my ($kernel, $heap, $socket, $address, $port) = @_[KERNEL, HEAP, ARG0,
ARG1, ARG2];
+ Haver::Server::POE::Connection->create(
+ sock => $socket,
+ address => $address,
+ port => $port,
+ );
+}
- create Haver::Server::POE::Connection ($socket, $address, $port);
-}
sub socket_fail {
my ($kernel, $heap, $operation, $errnum, $errstr, $wheel_id) =
@_[KERNEL, HEAP, ARG0..ARG3];
- die "Listener: '$operation' failed: $errstr";
+ delete $heap->{conn}{$wheel_id};
+ $kernel->post('Logger', 'error', "Operation '$operation' failed:
$errstr ($errnum)");
}
sub shutdown {
- $_[KERNEL]->alias_remove('Listener');
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+ $kernel->alias_remove('Listener');
+
+ foreach my $kid (keys %{ $heap->{kids} }) {
+ $kernel->post($kid, 'shutdown');
+ }
+ %$heap = ();
}
1;
Modified: trunk/main/server/lib/Haver/Server/POE.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/POE.pm 2004-06-27 20:57:14 UTC (rev
263)
+++ trunk/main/server/lib/Haver/Server/POE.pm 2004-06-28 02:37:38 UTC (rev
264)
@@ -25,72 +25,76 @@
use POE;
use Haver::Preprocessor;
-use Haver::Config (
- default => {
- IKC => {
- Host => 'localhost',
- Name => 'HaverServer',
- Port => 4040,
- },
- Logs => {},
- Server => {
- LineLimit => 2048,
- PingTime => 60,
- Port => 7070,
- },
- },
-);
+use Haver::Config;
use Haver::Server::POE::Listener;
+use Haver::Server::POE::Broadcaster;
use Haver::Server::Registry;
use Haver::Server::Object::Channel;
use Haver::Server::Object::User;
+use Haver::Server::Object::POE;
use Haver::Server::Object::Index;
-use Haver::Server::Remote;
-
use Haver::Util::Logger;
use Haver::Util::Reload;
+
our $VERSION = 0.06;
-my ($Config, $Registry);
+my %Default = (
+ logger => {
+ levels => {},
+ },
+ listener => {
+ interfaces => [
+ { port => 7071 },
+ ]
+ },
+ broadcaster => { },
+ path => {
+ storage => "./store",
+ },
+ channels => [qw(
+ main
+ lobby
+ attic
+ basement
+ kitchen
+ )],
+);
-
sub boot {
- my ($this, %opts) = @_;
- $|++;
+ my ($this, $file) = @_;
- ASSERT: $opts{confdir};
- ASSERT: $opts{datadir};
- DEBUG: "Booting ", __PACKAGE__;
-
- $Config = instance Haver::Config(
- file => "$opts{confdir}/config.yml"
+ # ASSERT: defined $file;
+ # DEBUG(session): "Booting ", __PACKAGE__;
+
+ my $cfg = new Haver::Config (
+ file => $file,
+ default => \%Default,
);
- $Registry = instance Haver::Server::Registry;
+ $cfg->save;
+ init Haver::Util::Reload;
+ my $reg = instance Haver::Server::Registry;
+
+ my @cids = (Haver::Server::Object::Channel->saved_ids, @{
$cfg->{channels} });
+ foreach my $cid (@cids) {
+ DEBUG: $cid;
+ my $chan = Haver::Server::Object::Channel->new(id => $cid);
+ $chan->load;
+ $reg->add($chan);
+ }
- if ($Config->{Feature}{IKC}) {
- require POE::Component::IKC::Server;
- import POE::Component::IKC::Server;
- create_ikc_server(
- ip => $Config->{IKC}{Host} || 'localhost',
- port => $Config->{IKC}{Port} || '4040',
- name => $Config->{IKC}{Name} || 'HaverServer',
- );
+ if ($cfg->{path}{storage}) {
+ $Haver::Server::Object::StorageDir = $cfg->{path}{storage};
}
-
- Haver::Reload->init;
- $Config->{Server}{PingTime} ||= 60;
- Haver::Server::Object->store_dir( "$opts{datadir}/store" );
-
-
- $this->create;
+ $this->create(cfg => $cfg);
}
sub create {
- my ($class) = @_;
+ my ($class, %opt) = @_;
+
POE::Session->create(
package_states => [
$class => [
@@ -101,49 +105,38 @@
'shutdown',
]
],
- heap => {},
+ heap => {
+ cfg => $opt{cfg}
+ },
);
}
sub _start {
my ($kernel, $heap) = @_[KERNEL, HEAP];
- my $port = $Config->{Server}{Port} || 7070;
- DEBUG: "Server starts.";
- create Haver::Util::Logger (
- levels => $Config->{Logs},
- );
- create Haver::Server::POE::Listener (
- port => $port
- );
+
+ # DEBUG(session): "Server starts.";
+ create Haver::Util::Logger $heap->{cfg}{logger};
+ create Haver::Server::POE::Listener $heap->{cfg}{listener};
+ create Haver::Server::POE::Broadcaster $heap->{cfg}{broadcaster};
+
+
$kernel->sig('INT' => 'intterrupt');
$kernel->sig('DIE' => 'die');
}
sub _stop {
- DEBUG: "Server stops.";
-
- my @chans;
- $Store->{Channels} = [EMAIL PROTECTED];
-
- foreach my $chan ($Registry->list_vals('channel')) {
- if ($chan->has('_perm')) {
- push(@chans, $chan->id);
- $chan->save;
- }
- }
-
- $Store->save;
- $Config->save;
+ # DEBUG(session): "Server stops.";
}
sub die {
- print "Got DIE\n";
+ # DEBUG(session): "Got die!";
}
sub interrupt {
print "Got INT\n";
+ return 0;
}
sub shutdown {
}
Modified: trunk/main/server/lib/Haver/Server/Registry.pm
===================================================================
--- trunk/main/server/lib/Haver/Server/Registry.pm 2004-06-27 20:57:14 UTC
(rev 263)
+++ trunk/main/server/lib/Haver/Server/Registry.pm 2004-06-28 02:37:38 UTC
(rev 264)
@@ -22,12 +22,33 @@
use Haver::Preprocessor;
use Haver::Server::Object::Index;
-use base qw( Haver::Server::Object Haver::Server::Object::Index );
+use base qw( Haver::Server::Object Haver::Server::Object::Index Exporter );
use POE;
+use Carp;
our $VERSION = 0.04;
our $RELOAD = 1;
+our $Registry;
+our @EXPORT_OK = qw( $Registry );
+sub instance {
+ my $class = shift;
+
+ # don't warn about redefining a function.
+ do {
+ no warnings;
+ *instance = \&self;
+ };
+
+ return $Registry = $class->SUPER::new(@_);
+}
+
+sub self { $Registry }
+
+sub new {
+ croak "Can't call new on ", __PACKAGE__;
+}
+
sub namespace {
'registry',
}