--- deliantra/server/lib/cf.pm 2007/03/14 00:04:58 1.225 +++ deliantra/server/lib/cf.pm 2007/04/04 02:20:27 1.233 @@ -23,22 +23,25 @@ use Data::Dumper; use Digest::MD5; use Fcntl; -use IO::AIO 2.32 (); use YAML::Syck (); +use IO::AIO 2.32 (); use Time::HiRes; use Compress::LZF; +# configure various modules to our taste +# 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 -$Event::Eval = 1; # no idea why this is required, but it is -sub WF_AUTOCANCEL () { 1 } # automatically cancel this watcher on reload +$Event::Eval = 1; # no idea why this is required, but it is # work around bug in YAML::Syck - bad news for perl6, will it be as broken wrt. unicode? $YAML::Syck::ImplicitUnicode = 1; $Coro::main->prio (Coro::PRIO_MAX); # run main coroutine ("the server") with very high priority +sub WF_AUTOCANCEL () { 1 } # automatically cancel this watcher on reload + our %COMMAND = (); our %COMMAND_TIME = (); @@ -207,30 +210,16 @@ } || "[unable to dump $_[0]: '$@']"; } -use JSON::Syck (); # TODO# replace by JSON::PC once working +use JSON::XS qw(to_json from_json); # TODO# replace by JSON::PC once working =item $ref = cf::from_json $json Converts a JSON string into the corresponding perl data structure. -=cut - -sub from_json($) { - $JSON::Syck::ImplicitUnicode = 1; # work around JSON::Syck bugs - JSON::Syck::Load $_[0] -} - =item $json = cf::to_json $ref Converts a perl data structure into its JSON representation. -=cut - -sub to_json($) { - $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs - JSON::Syck::Dump $_[0] -} - =item cf::lock_wait $string Wait until the given lock is available. See cf::lock_acquire. @@ -386,6 +375,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 @@ -1126,13 +1126,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; @@ -1140,6 +1140,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 @@ -1955,6 +1967,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 }; } @@ -1972,9 +1986,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; @@ -2000,6 +2014,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) @@ -2106,7 +2132,7 @@ =pod -The following fucntions and emthods are available within a safe environment: +The following functions and methods are available within a safe environment: cf::object contr pay_amount pay_player map cf::object::player player @@ -2271,10 +2297,10 @@ ############################################################################# # 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 @@ -2284,10 +2310,15 @@ $faces = Storable::thaw $faces; Coro::cede; + my $meta = delete $faces->{""}; + $meta->{version} == 1 + 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}; + cf::face::set_data $idx, 1, $info->{data64}, $info->{chksum64}; Coro::cede; } @@ -2297,7 +2328,6 @@ or next; if (my $smooth = cf::face::find $info->{smooth}) { cf::face::set_smooth $idx, $smooth; - warn "smooth $idx,$smooth ($face,$info->{smooth})\n";#d# } else { warn "smooth face '$info->{smooth}' not found for face '$face'"; } @@ -2310,8 +2340,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 {