--- deliantra/server/lib/cf.pm 2012/10/30 17:07:50 1.584 +++ deliantra/server/lib/cf.pm 2012/11/04 01:01:13 1.589 @@ -34,7 +34,10 @@ use Storable (); use Carp (); -use Guard (); +use AnyEvent (); +use AnyEvent::IO (); +use AnyEvent::DNS (); + use Coro (); use Coro::State; use Coro::Handle; @@ -50,6 +53,7 @@ use Coro::Storable; use Coro::Util (); +use Guard (); use JSON::XS 2.01 (); use BDB (); use Data::Dumper; @@ -338,7 +342,7 @@ } $EV::DIED = sub { - Carp::cluck "error in event callback: @_"; + warn "error in event callback: $@"; }; ############################################################################# @@ -3507,6 +3511,28 @@ our %FACEHASH; # hash => idx, #d# HACK for http server +# internal api, not fianlised +sub add_face { + my ($name, $type, $data) = @_; + + my $idx = cf::face::find $name; + + if ($idx) { + delete $FACEHASH{cf::face::get_chksum $idx}; + } else { + $idx = cf::face::alloc $name; + } + + my $hash = cf::face::mangle_chksum Digest::MD5::md5 $data; + + cf::face::set_type $idx, $type; + cf::face::set_data $idx, 0, $data, $hash; + cf::face::set_meta $idx, $type & 1 ? undef : undef; + $FACEHASH{$hash} = $idx;#d# + + $idx +} + sub load_facedata($) { my ($path) = @_; @@ -3523,19 +3549,13 @@ $facedata->{version} == 2 or cf::cleanup "$path: version mismatch, cannot proceed."; - # patch in the exptable - my $exp_table = $enc->encode ([map cf::level_to_min_exp $_, 1 .. cf::settings->max_level]); - $facedata->{resource}{"res/exp_table"} = { - type => FT_RSRC, - data => $exp_table, - hash => (Digest::MD5::md5 $exp_table), - }; cf::cede_to_tick; { my $faces = $facedata->{faceinfo}; - while (my ($face, $info) = each %$faces) { + for my $face (sort keys %$faces) { + my $info = $faces->{$face}; my $idx = (cf::face::find $face) || cf::face::alloc $face; cf::face::set_visibility $idx, $info->{visibility}; @@ -3584,8 +3604,8 @@ # TODO: different hash - must free and use new index, or cache ixface data queue my $idx = (cf::face::find $name) || cf::face::alloc $name; - cf::face::set_data $idx, 0, $info->{data}, $info->{hash}; cf::face::set_type $idx, $type; + cf::face::set_data $idx, 0, $info->{data}, $info->{hash}; cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already $FACEHASH{$info->{hash}} = $idx;#d# } else { @@ -3619,6 +3639,19 @@ $status } +sub reload_exp_table { + _reload_exp_table; + + add_face "res/exp_table" => FT_RSRC, + JSON::XS->new->utf8->canonical->encode ( + [map cf::level_to_min_exp $_, 1 .. cf::settings->max_level] + ); +} + +sub reload_materials { + _reload_materials; +} + sub reload_regions { # HACK to clear player env face cache, we need some signal framework # for this (global event?) @@ -3641,6 +3674,15 @@ sub reload_archetypes { load_resource_file "$DATADIR/archetypes" or die "unable to load archetypes\n"; + + add_face "res/skill_info" => FT_RSRC, + JSON::XS->new->utf8->canonical->encode ( + [map [cf::arch::skillvec ($_)->name], 0 .. cf::arch::skillvec_size - 1] + ); + add_face "res/spell_paths" => FT_RSRC, + JSON::XS->new->utf8->canonical->encode ( + [map [cf::spellpathnames ($_)], 0 .. NRSPELLPATHS - 1] + ); } sub reload_treasures { @@ -3671,9 +3713,9 @@ sub reload_resources { trace "reloading resource files...\n"; - reload_exp_table; reload_materials; reload_facedata; + reload_exp_table; reload_sound; reload_archetypes; reload_regions; @@ -3742,7 +3784,7 @@ $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority # we must not ever block the main coroutine - local $Coro::idle = sub { + $Coro::idle = sub { Carp::cluck "FATAL: Coro::idle was called, major BUG, use cf::sync_job!\n";#d# (async { $Coro::current->{desc} = "IDLE BUG HANDLER";