--- deliantra/server/lib/cf.pm 2007/07/03 06:00:48 1.294 +++ deliantra/server/lib/cf.pm 2007/07/10 07:01:51 1.301 @@ -411,6 +411,15 @@ =cut +sub _store_scalar { + open my $fh, ">", \my $buf + or die "fork_call: cannot open fh-to-buf in child : $!"; + Storable::store_fd $_[0], $fh; + close $fh; + + $buf +} + sub fork_call(&@) { my ($cb, @args) = @_; @@ -423,22 +432,31 @@ close $fh2; my $res = (Coro::Handle::unblock $fh1)->readline (undef); + warn "pst<$res>" unless $res =~ /^pst/; $res = Coro::Storable::thaw $res; waitpid $pid, 0; # should not block anymore, we expect the child to simply behave - die $$res unless "ARRAY" eq ref $res; + Carp::confess $$res unless "ARRAY" eq ref $res; return wantarray ? @$res : $res->[-1]; } else { reset_signals; local $SIG{__WARN__}; local $SIG{__DIE__}; + # just in case, this hack effectively disables event + # in the child. cleaner and slower would be canceling all watchers, + # but this works for the time being. + local $Coro::idle; + $Coro::current->prio (Coro::PRIO_MAX); + eval { close $fh1; my @res = eval { $cb->(@args) }; - syswrite $fh2, Coro::Storable::freeze +($@ ? \"$@" : \@res); + + syswrite $fh2, _store_scalar $@ ? \"$@" : \@res; + close $fh2; }; warn $@ if $@; @@ -1414,10 +1432,10 @@ s/(?<=\S)\n(?=\w)/ /g; # compress some whitespace - 1 while s/\s*\n\s*\n\s*/\n/; - - s/^\s+//; - s/\s+$//; + s/\s+\n/\n/g; # ws line-ends + s/\n\n+/\n/g; # double lines + s/^\n+//; # beginning lines + s/\n+$//; # ending lines $_ } @@ -2359,6 +2377,10 @@ $self->enter_link; + # if exit is damned, update players death & WoR home-position + $self->contr->savebed ($slaying, $hp, $sp) + if $exit->flag (FLAG_DAMNED); + (async { $self->deactivate_recursive; # just to be sure unless (eval { @@ -2580,15 +2602,24 @@ The following functions and methods are available within a safe environment: - cf::object contr pay_amount pay_player map - cf::object::player player - cf::player peaceful - cf::map trigger + cf::object + contr pay_amount pay_player map x y force_find force_add + insert remove + + cf::object::player + player + + cf::player + peaceful + + cf::map + trigger =cut for ( - ["cf::object" => qw(contr pay_amount pay_player map)], + ["cf::object" => qw(contr pay_amount pay_player map force_find force_add x y + insert remove)], ["cf::object::player" => qw(player)], ["cf::player" => qw(peaceful)], ["cf::map" => qw(trigger)],