--- deliantra/server/lib/cf.pm 2008/04/20 05:24:55 1.424 +++ deliantra/server/lib/cf.pm 2008/05/04 14:12:37 1.430 @@ -1143,18 +1143,18 @@ $decname, length $$rdata, scalar @$objs; if (my $fh = aio_open "$filename~", O_WRONLY | O_CREAT, 0600) { - chmod SAVE_MODE, $fh; + aio_chmod $fh, SAVE_MODE; aio_write $fh, 0, (length $$rdata), $$rdata, 0; aio_fsync $fh if $cf::USE_FSYNC; - close $fh; + aio_close $fh; if (@$objs) { if (my $fh = aio_open "$filename.pst~", O_WRONLY | O_CREAT, 0600) { - chmod SAVE_MODE, $fh; + aio_chmod $fh, SAVE_MODE; my $data = Coro::Storable::nfreeze { version => 1, objs => $objs }; aio_write $fh, 0, (length $data), $data, 0; aio_fsync $fh if $cf::USE_FSYNC; - close $fh; + aio_close $fh; aio_rename "$filename.pst~", "$filename.pst"; } } else { @@ -1458,6 +1458,7 @@ my $pl = cf::player::load_pl $f or return; + local $cf::PLAYER_LOADING{$login} = $pl; $f->resolve_delayed_derefs; $cf::PLAYER{$login} = $pl @@ -1572,7 +1573,8 @@ my $path = path $login; # a .pst is a dead give-away for a valid player - unless (-e "$path.pst") { + # if no pst file found, open and chekc for blocked users + if (aio_stat "$path.pst") { my $fh = aio_open $path, Fcntl::O_RDONLY, 0 or next; aio_read $fh, 0, 512, my $buf, 0 or next; $buf !~ /^password -------------$/m or next; # official not-valid tag @@ -2031,8 +2033,8 @@ cf::lock_wait "map_find:$path"; $cf::MAP{$path} || do { - my $guard1 = cf::lock_acquire "map_find:$path"; - my $guard2 = cf::lock_acquire "map_data:$path"; # just for the fun of it + my $guard1 = cf::lock_acquire "map_data:$path"; # just for the fun of it + my $guard2 = cf::lock_acquire "map_find:$path"; my $map = new_from_path cf::map $path or return; @@ -2045,8 +2047,8 @@ if ($map->should_reset) {#d#TODO# disabled, crashy (locking issue?) # doing this can freeze the server in a sync job, obviously #$cf::WAIT_FOR_TICK->wait; - undef $guard1; undef $guard2; + undef $guard1; $map->reset; return find $path; } @@ -2459,6 +2461,20 @@ =cut +our $SAY_CHANNEL = { + id => "say", + title => "Map", + reply => "say ", + tooltip => "Things said to and replied from npcs near you and other players on the same map only.", +}; + +our $CHAT_CHANNEL = { + id => "chat", + title => "Chat", + reply => "chat ", + tooltip => "Player chat and shouts, global to the server.", +}; + # rough implementation of a future "reply" method that works # with dialog boxes. #TODO: the first argument must go, split into a $npc->reply_to ( method @@ -2479,7 +2495,7 @@ } else { $msg = $npc->name . " says: $msg" if $npc; - $self->message ($msg, $flags); + $self->send_msg ($SAY_CHANNEL => $msg, $flags); } } } @@ -2684,8 +2700,6 @@ sub prepare_random_map { my ($exit) = @_; - my $guard = cf::lock_acquire "exit_prepare:$exit"; - # all this does is basically replace the /! path by # a new random map path (?random/...) with a seed # that depends on the exit object @@ -2697,6 +2711,8 @@ $rmp->{origin_map} = $exit->map->path; $rmp->{origin_x} = $exit->x; $rmp->{origin_y} = $exit->y; + + $exit->map->touch; } $rmp->{random_seed} ||= $exit->random_seed; @@ -2710,8 +2726,12 @@ undef $fh; aio_rename "$meta~", $meta; - $exit->slaying ("?random/$md5"); - $exit->msg (undef); + my $slaying = "?random/$md5"; + + if ($exit->valid) { + $exit->slaying ("?random/$md5"); + $exit->msg (undef); + } } } @@ -2720,31 +2740,33 @@ return unless $self->type == cf::PLAYER; - 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 }; - } - - my $slaying = cf::map::normalise $exit->slaying, $exit->map && $exit->map->path; - my $hp = $exit->stats->hp; - my $sp = $exit->stats->sp; - $self->enter_link; - # if exit is damned, update players death & WoR home-position - $self->contr->savebed ($slaying, $hp, $sp) - if $exit->flag (FLAG_DAMNED); - (async { - $Coro::current->{desc} = "enter_exit $slaying $hp $sp"; + $Coro::current->{desc} = "enter_exit"; - $self->deactivate_recursive; # just to be sure unless (eval { - $self->goto ($slaying, $hp, $sp); + $self->deactivate_recursive; # just to be sure + + # random map handling + { + my $guard = cf::lock_acquire "exit_prepare:$exit"; + + prepare_random_map $exit + if $exit->slaying eq "/!"; + } - 1; + my $map = cf::map::normalise $exit->slaying, $exit->map && $exit->map->path; + my $x = $exit->stats->hp; + my $y = $exit->stats->sp; + + $self->goto ($map, $x, $y); + + # if exit is damned, update players death & WoR home-position + $self->contr->savebed ($map, $x, $y) + if $exit->flag (cf::FLAG_DAMNED); + + 1 }) { $self->message ("Something went wrong deep within the crossfire server. " . "I'll try to bring you back to the map you were before. " @@ -2834,6 +2856,12 @@ reply => undef, tooltip => "Information related to the maps", }, + "c/party" => { + id => "party", + title => "Party", + reply => "gsay ", + tooltip => "Messages and chat related to your party", + }, ); sub cf::client::send_msg { @@ -3080,7 +3108,7 @@ cf::object contr pay_amount pay_player map x y force_find force_add destroy - insert remove name archname title slaying race decrease_ob_nr + insert remove name archname title slaying race decrease split cf::object::player player @@ -3096,7 +3124,7 @@ for ( ["cf::object" => qw(contr pay_amount pay_player map force_find force_add x y insert remove inv name archname title slaying race - decrease_ob_nr destroy)], + decrease split destroy)], ["cf::object::player" => qw(player)], ["cf::player" => qw(peaceful)], ["cf::map" => qw(trigger)],