… | |
… | |
3235 | =cut |
3235 | =cut |
3236 | |
3236 | |
3237 | sub cf::client::ext_msg($$@) { |
3237 | sub cf::client::ext_msg($$@) { |
3238 | my ($self, $type, @msg) = @_; |
3238 | my ($self, $type, @msg) = @_; |
3239 | |
3239 | |
3240 | if ($self->extcmd == 2) { |
|
|
3241 | $self->send_big_packet ("ext " . $self->{json_coder}->encode ([$type, @msg])); |
3240 | $self->send_big_packet ("ext " . $self->{json_coder}->encode ([$type, @msg])); |
3242 | } elsif ($self->extcmd == 1) { # TODO: remove |
|
|
3243 | push @msg, msgtype => "event_$type"; |
|
|
3244 | $self->send_big_packet ("ext " . $self->{json_coder}->encode ({@msg})); |
|
|
3245 | } |
|
|
3246 | } |
3241 | } |
3247 | |
3242 | |
3248 | =item $client->ext_reply ($msgid, @msg) |
3243 | =item $client->ext_reply ($msgid, @msg) |
3249 | |
3244 | |
3250 | Sends an ext reply to the client. |
3245 | Sends an ext reply to the client. |
3251 | |
3246 | |
3252 | =cut |
3247 | =cut |
3253 | |
3248 | |
3254 | sub cf::client::ext_reply($$@) { |
3249 | sub cf::client::ext_reply($$@) { |
3255 | my ($self, $id, @msg) = @_; |
3250 | my ($self, $id, @msg) = @_; |
3256 | |
|
|
3257 | return unless $self->extcmd == 2; |
|
|
3258 | |
3251 | |
3259 | $self->send_big_packet ("ext " . $self->{json_coder}->encode (["reply-$id", @msg])); |
3252 | $self->send_big_packet ("ext " . $self->{json_coder}->encode (["reply-$id", @msg])); |
3260 | } |
3253 | } |
3261 | |
3254 | |
3262 | =item $success = $client->query ($flags, "text", \&cb) |
3255 | =item $success = $client->query ($flags, "text", \&cb) |
… | |
… | |
3509 | ############################################################################# |
3502 | ############################################################################# |
3510 | # the server's init and main functions |
3503 | # the server's init and main functions |
3511 | |
3504 | |
3512 | our %FACEHASH; # hash => idx, #d# HACK for http server |
3505 | our %FACEHASH; # hash => idx, #d# HACK for http server |
3513 | |
3506 | |
|
|
3507 | # internal api, not fianlised |
|
|
3508 | sub add_face { |
|
|
3509 | my ($name, $type, $data) = @_; |
|
|
3510 | |
|
|
3511 | my $idx = cf::face::find $name; |
|
|
3512 | |
|
|
3513 | if ($idx) { |
|
|
3514 | delete $FACEHASH{cf::face::get_chksum $idx}; |
|
|
3515 | } else { |
|
|
3516 | $idx = cf::face::alloc $name; |
|
|
3517 | } |
|
|
3518 | |
|
|
3519 | my $hash = cf::face::mangle_chksum Digest::MD5::md5 $data; |
|
|
3520 | |
|
|
3521 | cf::face::set_type $idx, $type; |
|
|
3522 | cf::face::set_data $idx, 0, $data, $hash; |
|
|
3523 | cf::face::set_meta $idx, $type & 1 ? undef : undef; |
|
|
3524 | $FACEHASH{$hash} = $idx;#d# |
|
|
3525 | |
|
|
3526 | $idx |
|
|
3527 | } |
|
|
3528 | |
3514 | sub load_facedata($) { |
3529 | sub load_facedata($) { |
3515 | my ($path) = @_; |
3530 | my ($path) = @_; |
3516 | |
3531 | |
3517 | # HACK to clear player env face cache, we need some signal framework |
3532 | # HACK to clear player env face cache, we need some signal framework |
3518 | # for this (global event?) |
3533 | # for this (global event?) |
… | |
… | |
3525 | my $facedata = decode_storable load_file $path; |
3540 | my $facedata = decode_storable load_file $path; |
3526 | |
3541 | |
3527 | $facedata->{version} == 2 |
3542 | $facedata->{version} == 2 |
3528 | or cf::cleanup "$path: version mismatch, cannot proceed."; |
3543 | or cf::cleanup "$path: version mismatch, cannot proceed."; |
3529 | |
3544 | |
3530 | # patch in the exptable |
|
|
3531 | my $exp_table = $enc->encode ([map cf::level_to_min_exp $_, 1 .. cf::settings->max_level]); |
|
|
3532 | $facedata->{resource}{"res/exp_table"} = { |
|
|
3533 | type => FT_RSRC, |
|
|
3534 | data => $exp_table, |
|
|
3535 | hash => (Digest::MD5::md5 $exp_table), |
|
|
3536 | }; |
|
|
3537 | cf::cede_to_tick; |
3545 | cf::cede_to_tick; |
3538 | |
3546 | |
3539 | { |
3547 | { |
3540 | my $faces = $facedata->{faceinfo}; |
3548 | my $faces = $facedata->{faceinfo}; |
3541 | |
3549 | |
… | |
… | |
3587 | while (my ($name, $info) = each %$res) { |
3595 | while (my ($name, $info) = each %$res) { |
3588 | if (defined (my $type = $info->{type})) { |
3596 | if (defined (my $type = $info->{type})) { |
3589 | # TODO: different hash - must free and use new index, or cache ixface data queue |
3597 | # TODO: different hash - must free and use new index, or cache ixface data queue |
3590 | my $idx = (cf::face::find $name) || cf::face::alloc $name; |
3598 | my $idx = (cf::face::find $name) || cf::face::alloc $name; |
3591 | |
3599 | |
|
|
3600 | cf::face::set_type $idx, $type; |
3592 | cf::face::set_data $idx, 0, $info->{data}, $info->{hash}; |
3601 | cf::face::set_data $idx, 0, $info->{data}, $info->{hash}; |
3593 | cf::face::set_type $idx, $type; |
|
|
3594 | cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already |
3602 | cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already |
3595 | $FACEHASH{$info->{hash}} = $idx;#d# |
3603 | $FACEHASH{$info->{hash}} = $idx;#d# |
3596 | } else { |
3604 | } else { |
3597 | # $RESOURCE{$name} = $info; # unused |
3605 | # $RESOURCE{$name} = $info; # unused |
3598 | } |
3606 | } |
… | |
… | |
3622 | cf::arch::commit_load; |
3630 | cf::arch::commit_load; |
3623 | |
3631 | |
3624 | $status |
3632 | $status |
3625 | } |
3633 | } |
3626 | |
3634 | |
|
|
3635 | sub reload_exp_table { |
|
|
3636 | _reload_exp_table; |
|
|
3637 | |
|
|
3638 | add_face "res/exp_table" => FT_RSRC, |
|
|
3639 | JSON::XS->new->utf8->canonical->encode ( |
|
|
3640 | [map cf::level_to_min_exp $_, 1 .. cf::settings->max_level] |
|
|
3641 | ); |
|
|
3642 | } |
|
|
3643 | |
|
|
3644 | sub reload_materials { |
|
|
3645 | _reload_materials; |
|
|
3646 | } |
|
|
3647 | |
3627 | sub reload_regions { |
3648 | sub reload_regions { |
3628 | # HACK to clear player env face cache, we need some signal framework |
3649 | # HACK to clear player env face cache, we need some signal framework |
3629 | # for this (global event?) |
3650 | # for this (global event?) |
3630 | %ext::player_env::MUSIC_FACE_CACHE = (); |
3651 | %ext::player_env::MUSIC_FACE_CACHE = (); |
3631 | |
3652 | |
… | |
… | |
3644 | } |
3665 | } |
3645 | |
3666 | |
3646 | sub reload_archetypes { |
3667 | sub reload_archetypes { |
3647 | load_resource_file "$DATADIR/archetypes" |
3668 | load_resource_file "$DATADIR/archetypes" |
3648 | or die "unable to load archetypes\n"; |
3669 | or die "unable to load archetypes\n"; |
|
|
3670 | |
|
|
3671 | add_face "res/skill_info" => FT_RSRC, |
|
|
3672 | JSON::XS->new->utf8->canonical->encode ( |
|
|
3673 | [map [cf::arch::skillvec ($_)->name], 0 .. cf::arch::skillvec_size - 1] |
|
|
3674 | ); |
|
|
3675 | add_face "res/spell_paths" => FT_RSRC, |
|
|
3676 | JSON::XS->new->utf8->canonical->encode ( |
|
|
3677 | [map [cf::spellpathnames ($_)], 0 .. NRSPELLPATHS - 1] |
|
|
3678 | ); |
3649 | } |
3679 | } |
3650 | |
3680 | |
3651 | sub reload_treasures { |
3681 | sub reload_treasures { |
3652 | load_resource_file "$DATADIR/treasures" |
3682 | load_resource_file "$DATADIR/treasures" |
3653 | or die "unable to load treasurelists\n"; |
3683 | or die "unable to load treasurelists\n"; |
… | |
… | |
3674 | } |
3704 | } |
3675 | |
3705 | |
3676 | sub reload_resources { |
3706 | sub reload_resources { |
3677 | trace "reloading resource files...\n"; |
3707 | trace "reloading resource files...\n"; |
3678 | |
3708 | |
3679 | reload_exp_table; |
|
|
3680 | reload_materials; |
3709 | reload_materials; |
3681 | reload_facedata; |
3710 | reload_facedata; |
|
|
3711 | reload_exp_table; |
3682 | reload_sound; |
3712 | reload_sound; |
3683 | reload_archetypes; |
3713 | reload_archetypes; |
3684 | reload_regions; |
3714 | reload_regions; |
3685 | reload_treasures; |
3715 | reload_treasures; |
3686 | |
3716 | |