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.301 by root, Tue Jul 10 07:01:51 2007 UTC vs.
Revision 1.308 by root, Mon Jul 16 14:09:40 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
1488 my ($path) = @_; 1489 my ($path) = @_;
1489 1490
1490 my ($match, $specificity); 1491 my ($match, $specificity);
1491 1492
1492 for my $region (list) { 1493 for my $region (list) {
1493 if ($region->match && $path =~ $region->match) { 1494 if ($region->{match} && $path =~ $region->{match}) {
1494 ($match, $specificity) = ($region, $region->specificity) 1495 ($match, $specificity) = ($region, $region->specificity)
1495 if $region->specificity > $specificity; 1496 if $region->specificity > $specificity;
1496 } 1497 }
1497 } 1498 }
1498 1499
1618 $self->init; # pass $1 etc. 1619 $self->init; # pass $1 etc.
1619 return $self; 1620 return $self;
1620 } 1621 }
1621 } 1622 }
1622 1623
1623 Carp::carp "unable to resolve path '$path' (base '$base')."; 1624 Carp::cluck "unable to resolve path '$path' (base '$base').";
1624 () 1625 ()
1625} 1626}
1626 1627
1627sub init { 1628sub init {
1628 my ($self) = @_; 1629 my ($self) = @_;
1906 1907
1907 undef $MAP_PREFETCH{$path}; 1908 undef $MAP_PREFETCH{$path};
1908 $MAP_PREFETCHER ||= cf::async { 1909 $MAP_PREFETCHER ||= cf::async {
1909 while (%MAP_PREFETCH) { 1910 while (%MAP_PREFETCH) {
1910 for my $path (keys %MAP_PREFETCH) { 1911 for my $path (keys %MAP_PREFETCH) {
1911 my $map = find $path 1912 if (my $map = find $path) {
1912 or next;
1913 $map->load; 1913 $map->load;
1914 }
1914 1915
1915 delete $MAP_PREFETCH{$path}; 1916 delete $MAP_PREFETCH{$path};
1916 } 1917 }
1917 } 1918 }
1918 undef $MAP_PREFETCHER; 1919 undef $MAP_PREFETCHER;
2255 2256
2256 local $self->{_prev_pos} = $link_pos; # ugly hack for rent.ext 2257 local $self->{_prev_pos} = $link_pos; # ugly hack for rent.ext
2257 $self->enter_map ($map, $x, $y); 2258 $self->enter_map ($map, $x, $y);
2258} 2259}
2259 2260
2260=item $player_object->goto ($path, $x, $y[, $check->($map)]) 2261=item $player_object->goto ($path, $x, $y[, $check->($map)[, $done->()]])
2261 2262
2262Moves the player to the given map-path and coordinates by first freezing 2263Moves the player to the given map-path and coordinates by first freezing
2263her, loading and preparing them map, calling the provided $check callback 2264her, loading and preparing them map, calling the provided $check callback
2264that has to return the map if sucecssful, and then unfreezes the player on 2265that has to return the map if sucecssful, and then unfreezes the player on
2265the new (success) or old (failed) map position. 2266the new (success) or old (failed) map position. In either case, $done will
2267be called at the end of this process.
2266 2268
2267=cut 2269=cut
2268 2270
2269our $GOTOGEN; 2271our $GOTOGEN;
2270 2272
2271sub cf::object::player::goto { 2273sub cf::object::player::goto {
2272 my ($self, $path, $x, $y, $check) = @_; 2274 my ($self, $path, $x, $y, $check, $done) = @_;
2273 2275
2274 # do generation counting so two concurrent goto's will be executed in-order 2276 # do generation counting so two concurrent goto's will be executed in-order
2275 my $gen = $self->{_goto_generation} = ++$GOTOGEN; 2277 my $gen = $self->{_goto_generation} = ++$GOTOGEN;
2276 2278
2277 $self->enter_link; 2279 $self->enter_link;
2297 2299
2298 if ($gen == $self->{_goto_generation}) { 2300 if ($gen == $self->{_goto_generation}) {
2299 delete $self->{_goto_generation}; 2301 delete $self->{_goto_generation};
2300 $self->leave_link ($map, $x, $y); 2302 $self->leave_link ($map, $x, $y);
2301 } 2303 }
2304
2305 $done->() if $done;
2302 })->prio (1); 2306 })->prio (1);
2303} 2307}
2304 2308
2305=item $player_object->enter_exit ($exit_object) 2309=item $player_object->enter_exit ($exit_object)
2306 2310
2464=cut 2468=cut
2465 2469
2466sub cf::client::ext_event($$%) { 2470sub cf::client::ext_event($$%) {
2467 my ($self, $type, %msg) = @_; 2471 my ($self, $type, %msg) = @_;
2468 2472
2473 return unless $self->extcmd;
2474
2469 $msg{msgtype} = "event_$type"; 2475 $msg{msgtype} = "event_$type";
2470 $self->send_packet ("ext " . $self->{json_coder}->encode (\%msg)); 2476 $self->send_packet ("ext " . $self->{json_coder}->encode (\%msg));
2471} 2477}
2472 2478
2473=item $success = $client->query ($flags, "text", \&cb) 2479=item $success = $client->query ($flags, "text", \&cb)
2719 { 2725 {
2720 my $faces = $facedata->{faceinfo}; 2726 my $faces = $facedata->{faceinfo};
2721 2727
2722 while (my ($face, $info) = each %$faces) { 2728 while (my ($face, $info) = each %$faces) {
2723 my $idx = (cf::face::find $face) || cf::face::alloc $face; 2729 my $idx = (cf::face::find $face) || cf::face::alloc $face;
2724 cf::face::set $idx, $info->{visibility}, $info->{magicmap}; 2730 cf::face::set_visibility $idx, $info->{visibility};
2731 cf::face::set_magicmap $idx, $info->{magicmap};
2725 cf::face::set_data $idx, 0, $info->{data32}, $info->{chksum32}; 2732 cf::face::set_data $idx, 0, $info->{data32}, $info->{chksum32};
2726 cf::face::set_data $idx, 1, $info->{data64}, $info->{chksum64}; 2733 cf::face::set_data $idx, 1, $info->{data64}, $info->{chksum64};
2727 Coro::cede; 2734
2735 cf::cede_to_tick;
2728 } 2736 }
2729 2737
2730 while (my ($face, $info) = each %$faces) { 2738 while (my ($face, $info) = each %$faces) {
2731 next unless $info->{smooth}; 2739 next unless $info->{smooth};
2732 my $idx = cf::face::find $face 2740 my $idx = cf::face::find $face
2733 or next; 2741 or next;
2734 if (my $smooth = cf::face::find $info->{smooth}) { 2742 if (my $smooth = cf::face::find $info->{smooth}) {
2743 cf::face::set_smooth $idx, $smooth;
2735 cf::face::set_smooth $idx, $smooth, $info->{smoothlevel}; 2744 cf::face::set_smoothlevel $idx, $info->{smoothlevel};
2736 } else { 2745 } else {
2737 warn "smooth face '$info->{smooth}' not found for face '$face'"; 2746 warn "smooth face '$info->{smooth}' not found for face '$face'";
2738 } 2747 }
2739 Coro::cede; 2748
2749 cf::cede_to_tick;
2740 } 2750 }
2741 } 2751 }
2742 2752
2743 { 2753 {
2744 my $anims = $facedata->{animinfo}; 2754 my $anims = $facedata->{animinfo};
2745 2755
2746 while (my ($anim, $info) = each %$anims) { 2756 while (my ($anim, $info) = each %$anims) {
2747 cf::anim::set $anim, $info->{frames}, $info->{facings}; 2757 cf::anim::set $anim, $info->{frames}, $info->{facings};
2748 Coro::cede; 2758 cf::cede_to_tick;
2749 } 2759 }
2750 2760
2751 cf::anim::invalidate_all; # d'oh 2761 cf::anim::invalidate_all; # d'oh
2762 }
2763
2764 {
2765 # TODO: for gcfclient pleasure, we should give resources
2766 # that gcfclient doesn't grok a >10000 face index.
2767 my $res = $facedata->{resource};
2768 my $enc = JSON::XS->new->utf8->canonical;
2769
2770 while (my ($name, $info) = each %$res) {
2771 my $meta = $enc->encode ({
2772 name => $name,
2773 type => $info->{type},
2774 copyright => $info->{copyright}, #TODO#
2775 });
2776
2777 my $idx = (cf::face::find $name) || cf::face::alloc $name;
2778
2779 if ($name =~ /\.jpg$/) {
2780 cf::face::set_data $idx, 0, $info->{data}, $info->{chksum};#d# temp hack
2781 cf::face::set_data $idx, 1, $info->{data}, $info->{chksum};#d# temp hack
2782 } else {
2783 my $data = pack "(w/a*)*", $meta, $info->{data};
2784 my $chk = Digest::MD5::md5 "$info->{chksum},$meta"; # mangle data checksum and metadata
2785
2786 cf::face::set_type $idx, 1;
2787 cf::face::set_data $idx, 0, $data, $chk;
2788 }
2789
2790 cf::cede_to_tick;
2791 }
2752 } 2792 }
2753 2793
2754 1 2794 1
2755} 2795}
2756 2796
2757sub reload_regions { 2797sub reload_regions {
2758 load_resource_file "$MAPDIR/regions" 2798 load_resource_file "$MAPDIR/regions"
2759 or die "unable to load regions file\n"; 2799 or die "unable to load regions file\n";
2800
2801 for (cf::region::list) {
2802 $_->{match} = qr/$_->{match}/
2803 if exists $_->{match};
2804 }
2760} 2805}
2761 2806
2762sub reload_facedata { 2807sub reload_facedata {
2763 load_facedata "$DATADIR/facedata" 2808 load_facedata "$DATADIR/facedata"
2764 or die "unable to load facedata\n"; 2809 or die "unable to load facedata\n";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines