--- deliantra/server/lib/cf.pm 2007/06/30 03:00:54 1.289 +++ deliantra/server/lib/cf.pm 2007/07/08 14:50:07 1.298 @@ -250,7 +250,7 @@ =cut -our $json_coder = JSON::XS->new->convert_blessed->utf8->max_size (1e6); # accept ~1mb max +our $json_coder = JSON::XS->new->utf8->max_size (1e6); # accept ~1mb max sub to_json ($) { $json_coder->encode ($_[0]) } sub from_json ($) { $json_coder->decode ($_[0]) } @@ -423,22 +423,35 @@ 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__}; + local $Coro::idle; + $Coro::current->prio (Coro::PRIO_MAX); eval { close $fh1; my @res = eval { $cb->(@args) }; - syswrite $fh2, Coro::Storable::freeze +($@ ? \"$@" : \@res); + + open my $fh, ">", \my $buf + or die "fork_call: cannot open fh-to-buf in child : $!"; + Storable::store_fd +($@ ? \"$@" : \@res), $fh; + close $fh; + + warn "writing ", length $buf; + my $x; + (length $buf) == ($x = syswrite $fh2, $buf) + or warn "error writing ".(length $buf)." != $x\n"; + close $fh2; }; warn $@ if $@; @@ -1088,7 +1101,7 @@ on_extcmd => sub { my ($pl, $buf) = @_; - my $msg = eval { from_json $buf }; + my $msg = eval { $pl->ns->{json_coder}->decode ($buf) }; if (ref $msg) { if (my $cb = $EXTCMD{$msg->{msgtype}}) { @@ -1402,14 +1415,31 @@ $self->gender ? $2 : $1 }ge # replace H - || s/H<([^\>]*)>/[$1]<\/fg>/g; + || s{H<([^\>]*)>} + { + ("[$1 (Use hintmode to suppress hints)]", + "[Hint suppressed, see hintmode]", + "") + [$self->{hintmode}] + }ge; # create single paragraphs (very hackish) s/(?<=\S)\n(?=\w)/ /g; + # compress some whitespace + s/\s+\n/\n/g; # ws line-ends + s/\n\n+/\n/g; # double lines + s/^\n+//; # beginning lines + s/\n+$//; # ending lines + $_ } +sub hintmode { + $_[0]{hintmode} = $_[1] if @_ > 1; + $_[0]{hintmode} +} + =item $player->ext_reply ($msgid, %msg) Sends an ext reply to the player. @@ -1420,7 +1450,7 @@ my ($self, $id, %msg) = @_; $msg{msgid} = $id; - $self->send ("ext " . cf::to_json \%msg); + $self->send ("ext " . $self->ns->{json_coder}->encode (\%msg)); } =item $player->ext_event ($type, %msg) @@ -2342,6 +2372,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 { @@ -2392,8 +2426,10 @@ $msg = $self->pl->expand_cfpod ($msg); + return unless @extra || length $msg; + if ($self->can_msg) { - $self->send_packet ("msg " . cf::to_json [$color, $type, $msg, @extra]); + $self->send_packet ("msg " . $self->{json_coder}->encode ([$color, $type, $msg, @extra])); } else { # replace some tags by gcfclient-compatible ones for ($msg) { @@ -2426,7 +2462,7 @@ my ($self, $type, %msg) = @_; $msg{msgtype} = "event_$type"; - $self->send_packet ("ext " . cf::to_json \%msg); + $self->send_packet ("ext " . $self->{json_coder}->encode (\%msg)); } =item $success = $client->query ($flags, "text", \&cb) @@ -2459,6 +2495,11 @@ } cf::client->attach ( + on_connect => sub { + my ($ns) = @_; + + $ns->{json_coder} = JSON::XS->new->utf8->max_size (1e6)->convert_blessed; + }, on_reply => sub { my ($ns, $msg) = @_; @@ -2483,13 +2524,13 @@ on_exticmd => sub { my ($ns, $buf) = @_; - my $msg = eval { from_json $buf }; + my $msg = eval { $ns->{json_coder}->decode ($buf) }; if (ref $msg) { if (my $cb = $EXTICMD{$msg->{msgtype}}) { if (my %reply = $cb->($ns, $msg)) { $reply{msgid} = $msg->{msgid}; - $ns->send ("ext " . cf::to_json \%reply); + $ns->send ("ext " . $ns->{json_coder}->encode (\%reply)); } } } else { @@ -2556,15 +2597,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)],