--- deliantra/server/lib/cf.pm 2007/03/26 16:53:33 1.228 +++ deliantra/server/lib/cf.pm 2007/04/13 05:08:51 1.237 @@ -18,6 +18,7 @@ use Coro::Signal; use Coro::Semaphore; use Coro::AIO; +use Coro::Storable; use BDB (); use Data::Dumper; @@ -30,6 +31,7 @@ # configure various modules to our taste # +$Storable::canonical = 1; # reduce rsync transfers Coro::State::cctx_stacksize 256000; # 1-2MB stack, for deep recursions in maze generator Compress::LZF::sfreeze_cr { }; # prime Compress::LZF so it does not use require later @@ -375,6 +377,17 @@ 1 } +=item cf::datalog type => key => value, ... + +Log a datalog packet of the given type with the given key-value pairs. + +=cut + +sub datalog($@) { + my ($type, %kv) = @_; + warn "DATALOG ", JSON::XS->new->ascii->encode ({ %kv, type => $type }); +} + =back =cut @@ -954,7 +967,7 @@ sub path($) { my $login = ref $_[0] ? $_[0]->ob->name : $_[0]; - (playerdir $login) . "/$login.pl" + (playerdir $login) . "/playerdata" } sub find_active($) { @@ -977,6 +990,13 @@ my $guard = cf::lock_acquire "user_find:$login"; $cf::PLAYER{$_[0]} || do { + # rename old playerfiles to new ones + #TODO: remove when no longer required + aio_link +(playerdir $login) . "/$login.pl.pst", (playerdir $login) . "/playerdata.pst"; + aio_link +(playerdir $login) . "/$login.pl" , (playerdir $login) . "/playerdata"; + aio_unlink +(playerdir $login) . "/$login.pl.pst"; + aio_unlink +(playerdir $login) . "/$login.pl"; + my $pl = load_pl path $login or return; $cf::PLAYER{$login} = $pl @@ -1115,13 +1135,13 @@ \@paths } -=item $player->ext_reply ($msgid, $msgtype, %msg) +=item $player->ext_reply ($msgid, %msg) Sends an ext reply to the player. =cut -sub ext_reply($$$%) { +sub ext_reply($$%) { my ($self, $id, %msg) = @_; $msg{msgid} = $id; @@ -1129,6 +1149,18 @@ $self->send ("ext " . cf::to_json \%msg); } +=item $player->ext_event ($type, %msg) + +Sends an ext event to the client. + +=cut + +sub ext_event($$%) { + my ($self, $type, %msg) = @_; + + $self->ns->ext_event ($type, %msg); +} + package cf; =back @@ -1944,6 +1976,8 @@ if ($exit->slaying eq "/!") { #TODO: this should de-fi-ni-te-ly not be a sync-job + # the problem is that $exit might not survive long enough + # so it needs to be done right now, right here cf::sync_job { prepare_random_map $exit }; } @@ -1961,9 +1995,9 @@ 1; }) { $self->message ("Something went wrong deep within the crossfire server. " - . "I'll try to bring you back to the map you were before. " - . "Please report this to the dungeon master!", - cf::NDI_UNIQUE | cf::NDI_RED); + . "I'll try to bring you back to the map you were before. " + . "Please report this to the dungeon master!", + cf::NDI_UNIQUE | cf::NDI_RED); warn "ERROR in enter_exit: $@"; $self->leave_link; @@ -1989,6 +2023,18 @@ $self->send_packet (sprintf "drawinfo %d %s", $flags || cf::NDI_BLACK, $text); } +=item $client->ext_event ($type, %msg) + +Sends an exti event to the client. + +=cut + +sub cf::client::ext_event($$%) { + my ($self, $type, %msg) = @_; + + $msg{msgtype} = "event_$type"; + $self->send_packet ("ext " . cf::to_json \%msg); +} =item $success = $client->query ($flags, "text", \&cb) @@ -2260,40 +2306,53 @@ ############################################################################# # the server's init and main functions -sub load_faces { - my $path = sprintf "%s/faces", cf::datadir; +sub load_facedata { + my $path = sprintf "%s/facedata", cf::datadir; - warn "loading faces from $path\n"; + warn "loading facedata from $path\n"; - my $faces; - 0 < aio_load $path, $faces + my $facedata; + 0 < aio_load $path, $facedata or die "$path: $!"; - Coro::cede; - $faces = Storable::thaw $faces; - Coro::cede; + $facedata = Coro::Storable::thaw $facedata; - my $meta = delete $faces->{""}; - $meta->{version} == 1 + $facedata->{version} == 2 or cf::cleanup "$path: version mismatch, cannot proceed."; - 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_data $idx, 0, $info->{data32}, $info->{chksum32}; - Coro::cede; + { + my $faces = $facedata->{faceinfo}; + + 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_data $idx, 0, $info->{data32}, $info->{chksum32}; + cf::face::set_data $idx, 1, $info->{data64}, $info->{chksum64}; + Coro::cede; + } + + while (my ($face, $info) = each %$faces) { + next unless $info->{smooth}; + my $idx = cf::face::find $face + or next; + if (my $smooth = cf::face::find $info->{smooth}) { + cf::face::set_smooth $idx, $smooth, $info->{smoothlevel}; + } else { + warn "smooth face '$info->{smooth}' not found for face '$face'"; + } + Coro::cede; + } } - while (my ($face, $info) = each %$faces) { - next unless $info->{smooth}; - my $idx = cf::face::find $face - or next; - if (my $smooth = cf::face::find $info->{smooth}) { - cf::face::set_smooth $idx, $smooth; - } else { - warn "smooth face '$info->{smooth}' not found for face '$face'"; + { + my $anims = $facedata->{animinfo}; + + while (my ($anim, $info) = each %$anims) { + cf::anim::set $anim, $info->{frames}, $info->{facings}; + Coro::cede; } - Coro::cede; + + cf::anim::invalidate_all; # d'oh } 1 @@ -2302,8 +2361,8 @@ sub reload_resources { load_resource_file sprintf "%s/%s/regions", cf::datadir, cf::mapdir or die "unable to load regions file\n";#d# - load_faces - or die "unable to load faces\n";#d# + load_facedata + or die "unable to load facedata\n";#d# } sub init {