ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.298 by root, Sun Jul 8 14:50:07 2007 UTC vs.
Revision 1.304 by root, Wed Jul 11 16:55:18 2007 UTC

29use Fcntl; 29use Fcntl;
30use YAML::Syck (); 30use YAML::Syck ();
31use IO::AIO 2.32 (); 31use IO::AIO 2.32 ();
32use Time::HiRes; 32use Time::HiRes;
33use Compress::LZF; 33use Compress::LZF;
34use Digest::MD5 ();
34 35
35# configure various modules to our taste 36# configure various modules to our taste
36# 37#
37$Storable::canonical = 1; # reduce rsync transfers 38$Storable::canonical = 1; # reduce rsync transfers
38Coro::State::cctx_stacksize 256000; # 1-2MB stack, for deep recursions in maze generator 39Coro::State::cctx_stacksize 256000; # 1-2MB stack, for deep recursions in maze generator
409Coro::Storable. May, of course, block. Note that the executed sub may 410Coro::Storable. May, of course, block. Note that the executed sub may
410never block itself or use any form of Event handling. 411never block itself or use any form of Event handling.
411 412
412=cut 413=cut
413 414
415sub _store_scalar {
416 open my $fh, ">", \my $buf
417 or die "fork_call: cannot open fh-to-buf in child : $!";
418 Storable::store_fd $_[0], $fh;
419 close $fh;
420
421 $buf
422}
423
414sub fork_call(&@) { 424sub fork_call(&@) {
415 my ($cb, @args) = @_; 425 my ($cb, @args) = @_;
416 426
417# socketpair my $fh1, my $fh2, Socket::AF_UNIX, Socket::SOCK_STREAM, Socket::PF_UNSPEC 427# socketpair my $fh1, my $fh2, Socket::AF_UNIX, Socket::SOCK_STREAM, Socket::PF_UNSPEC
418# or die "socketpair: $!"; 428# or die "socketpair: $!";
433 return wantarray ? @$res : $res->[-1]; 443 return wantarray ? @$res : $res->[-1];
434 } else { 444 } else {
435 reset_signals; 445 reset_signals;
436 local $SIG{__WARN__}; 446 local $SIG{__WARN__};
437 local $SIG{__DIE__}; 447 local $SIG{__DIE__};
448 # just in case, this hack effectively disables event
449 # in the child. cleaner and slower would be canceling all watchers,
450 # but this works for the time being.
438 local $Coro::idle; 451 local $Coro::idle;
439 $Coro::current->prio (Coro::PRIO_MAX); 452 $Coro::current->prio (Coro::PRIO_MAX);
453
440 eval { 454 eval {
441 close $fh1; 455 close $fh1;
442 456
443 my @res = eval { $cb->(@args) }; 457 my @res = eval { $cb->(@args) };
444 458
445 open my $fh, ">", \my $buf 459 syswrite $fh2, _store_scalar $@ ? \"$@" : \@res;
446 or die "fork_call: cannot open fh-to-buf in child : $!";
447 Storable::store_fd +($@ ? \"$@" : \@res), $fh;
448 close $fh;
449
450 warn "writing ", length $buf;
451 my $x;
452 (length $buf) == ($x = syswrite $fh2, $buf)
453 or warn "error writing ".(length $buf)." != $x\n";
454 close $fh2; 460 close $fh2;
455 }; 461 };
456 462
457 warn $@ if $@; 463 warn $@ if $@;
458 _exit 0; 464 _exit 0;
1483 my ($path) = @_; 1489 my ($path) = @_;
1484 1490
1485 my ($match, $specificity); 1491 my ($match, $specificity);
1486 1492
1487 for my $region (list) { 1493 for my $region (list) {
1488 if ($region->match && $path =~ $region->match) { 1494 if ($region->{match} && $path =~ $region->{match}) {
1489 ($match, $specificity) = ($region, $region->specificity) 1495 ($match, $specificity) = ($region, $region->specificity)
1490 if $region->specificity > $specificity; 1496 if $region->specificity > $specificity;
1491 } 1497 }
1492 } 1498 }
1493 1499
2714 { 2720 {
2715 my $faces = $facedata->{faceinfo}; 2721 my $faces = $facedata->{faceinfo};
2716 2722
2717 while (my ($face, $info) = each %$faces) { 2723 while (my ($face, $info) = each %$faces) {
2718 my $idx = (cf::face::find $face) || cf::face::alloc $face; 2724 my $idx = (cf::face::find $face) || cf::face::alloc $face;
2719 cf::face::set $idx, $info->{visibility}, $info->{magicmap}; 2725 cf::face::set_visibility $idx, $info->{visibility};
2726 cf::face::set_magicmap $idx, $info->{magicmap};
2720 cf::face::set_data $idx, 0, $info->{data32}, $info->{chksum32}; 2727 cf::face::set_data $idx, 0, $info->{data32}, $info->{chksum32};
2721 cf::face::set_data $idx, 1, $info->{data64}, $info->{chksum64}; 2728 cf::face::set_data $idx, 1, $info->{data64}, $info->{chksum64};
2722 Coro::cede; 2729
2730 cf::cede_to_tick;
2723 } 2731 }
2724 2732
2725 while (my ($face, $info) = each %$faces) { 2733 while (my ($face, $info) = each %$faces) {
2726 next unless $info->{smooth}; 2734 next unless $info->{smooth};
2727 my $idx = cf::face::find $face 2735 my $idx = cf::face::find $face
2728 or next; 2736 or next;
2729 if (my $smooth = cf::face::find $info->{smooth}) { 2737 if (my $smooth = cf::face::find $info->{smooth}) {
2738 cf::face::set_smooth $idx, $smooth;
2730 cf::face::set_smooth $idx, $smooth, $info->{smoothlevel}; 2739 cf::face::set_smoothlevel $idx, $info->{smoothlevel};
2731 } else { 2740 } else {
2732 warn "smooth face '$info->{smooth}' not found for face '$face'"; 2741 warn "smooth face '$info->{smooth}' not found for face '$face'";
2733 } 2742 }
2734 Coro::cede; 2743
2744 cf::cede_to_tick;
2735 } 2745 }
2736 } 2746 }
2737 2747
2738 { 2748 {
2739 my $anims = $facedata->{animinfo}; 2749 my $anims = $facedata->{animinfo};
2740 2750
2741 while (my ($anim, $info) = each %$anims) { 2751 while (my ($anim, $info) = each %$anims) {
2742 cf::anim::set $anim, $info->{frames}, $info->{facings}; 2752 cf::anim::set $anim, $info->{frames}, $info->{facings};
2743 Coro::cede; 2753 cf::cede_to_tick;
2744 } 2754 }
2745 2755
2746 cf::anim::invalidate_all; # d'oh 2756 cf::anim::invalidate_all; # d'oh
2757 }
2758
2759 {
2760 # TODO: for gcfclient pleasure, we should give resources
2761 # that gcfclient doesn't grok a >10000 face index.
2762 my $res = $facedata->{resource};
2763 my $enc = JSON::XS->new->utf8->canonical;
2764
2765 while (my ($name, $info) = each %$res) {
2766 my $meta = $enc->encode ({
2767 name => $name,
2768 type => $info->{type},
2769 copyright => $info->{copyright}, #TODO#
2770 });
2771 my $data = pack "(w/a*)*", $meta, $info->{data};
2772 my $chk = Digest::MD5::md5 "$info->{chksum},$meta"; # mangle data checksum and metadata
2773
2774 my $idx = (cf::face::find $name) || cf::face::alloc $name;
2775 cf::face::set_type $idx, 1;
2776 cf::face::set_data $idx, 0, $data, $chk;
2777
2778 cf::cede_to_tick;
2779 }
2747 } 2780 }
2748 2781
2749 1 2782 1
2750} 2783}
2751 2784
2752sub reload_regions { 2785sub reload_regions {
2753 load_resource_file "$MAPDIR/regions" 2786 load_resource_file "$MAPDIR/regions"
2754 or die "unable to load regions file\n"; 2787 or die "unable to load regions file\n";
2788
2789 for (cf::region::list) {
2790 $_->{match} = qr/$_->{match}/
2791 if exists $_->{match};
2792 }
2755} 2793}
2756 2794
2757sub reload_facedata { 2795sub reload_facedata {
2758 load_facedata "$DATADIR/facedata" 2796 load_facedata "$DATADIR/facedata"
2759 or die "unable to load facedata\n"; 2797 or die "unable to load facedata\n";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines