--- deliantra/server/lib/cf.pm 2007/07/08 14:50:07 1.298 +++ deliantra/server/lib/cf.pm 2007/07/11 16:55:18 1.304 @@ -31,6 +31,7 @@ use IO::AIO 2.32 (); use Time::HiRes; use Compress::LZF; +use Digest::MD5 (); # configure various modules to our taste # @@ -411,6 +412,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) = @_; @@ -435,22 +445,18 @@ 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) }; - 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"; + syswrite $fh2, _store_scalar $@ ? \"$@" : \@res; close $fh2; }; @@ -1485,7 +1491,7 @@ my ($match, $specificity); for my $region (list) { - if ($region->match && $path =~ $region->match) { + if ($region->{match} && $path =~ $region->{match}) { ($match, $specificity) = ($region, $region->specificity) if $region->specificity > $specificity; } @@ -2716,10 +2722,12 @@ while (my ($face, $info) = each %$faces) { my $idx = (cf::face::find $face) || cf::face::alloc $face; - cf::face::set $idx, $info->{visibility}, $info->{magicmap}; + cf::face::set_visibility $idx, $info->{visibility}; + cf::face::set_magicmap $idx, $info->{magicmap}; cf::face::set_data $idx, 0, $info->{data32}, $info->{chksum32}; cf::face::set_data $idx, 1, $info->{data64}, $info->{chksum64}; - Coro::cede; + + cf::cede_to_tick; } while (my ($face, $info) = each %$faces) { @@ -2727,11 +2735,13 @@ my $idx = cf::face::find $face or next; if (my $smooth = cf::face::find $info->{smooth}) { - cf::face::set_smooth $idx, $smooth, $info->{smoothlevel}; + cf::face::set_smooth $idx, $smooth; + cf::face::set_smoothlevel $idx, $info->{smoothlevel}; } else { warn "smooth face '$info->{smooth}' not found for face '$face'"; } - Coro::cede; + + cf::cede_to_tick; } } @@ -2740,18 +2750,46 @@ while (my ($anim, $info) = each %$anims) { cf::anim::set $anim, $info->{frames}, $info->{facings}; - Coro::cede; + cf::cede_to_tick; } cf::anim::invalidate_all; # d'oh } + { + # TODO: for gcfclient pleasure, we should give resources + # that gcfclient doesn't grok a >10000 face index. + my $res = $facedata->{resource}; + my $enc = JSON::XS->new->utf8->canonical; + + while (my ($name, $info) = each %$res) { + my $meta = $enc->encode ({ + name => $name, + type => $info->{type}, + copyright => $info->{copyright}, #TODO# + }); + my $data = pack "(w/a*)*", $meta, $info->{data}; + my $chk = Digest::MD5::md5 "$info->{chksum},$meta"; # mangle data checksum and metadata + + my $idx = (cf::face::find $name) || cf::face::alloc $name; + cf::face::set_type $idx, 1; + cf::face::set_data $idx, 0, $data, $chk; + + cf::cede_to_tick; + } + } + 1 } sub reload_regions { load_resource_file "$MAPDIR/regions" or die "unable to load regions file\n"; + + for (cf::region::list) { + $_->{match} = qr/$_->{match}/ + if exists $_->{match}; + } } sub reload_facedata {