--- deliantra/server/lib/cf.pm 2008/05/03 15:17:13 1.429 +++ deliantra/server/lib/cf.pm 2008/07/13 20:15:51 1.438 @@ -27,21 +27,22 @@ use Symbol; use List::Util; use Socket; -use EV 3.2; +use EV; use Opcode; use Safe; use Safe::Hole; use Storable (); -use Coro 4.50 (); +use Coro (); use Coro::State; use Coro::Handle; -use Coro::EV; +use Coro::AnyEvent; use Coro::Timer; use Coro::Signal; use Coro::Semaphore; +use Coro::AnyEvent; use Coro::AIO; -use Coro::BDB; +use Coro::BDB 1.6; use Coro::Storable; use Coro::Util (); @@ -51,11 +52,13 @@ use Digest::MD5; use Fcntl; use YAML (); -use IO::AIO 2.51 (); +use IO::AIO (); use Time::HiRes; use Compress::LZF; use Digest::MD5 (); +AnyEvent::detect; + # configure various modules to our taste # $Storable::canonical = 1; # reduce rsync transfers @@ -92,12 +95,10 @@ our %RESOURCE; our $TICK = MAX_TIME * 1e-6; # this is a CONSTANT(!) -our $AIO_POLL_WATCHER; our $NEXT_RUNTIME_WRITE; # when should the runtime file be written our $NEXT_TICK; our $USE_FSYNC = 1; # use fsync to write maps - default off -our $BDB_POLL_WATCHER; our $BDB_DEADLOCK_WATCHER; our $BDB_CHECKPOINT_WATCHER; our $BDB_TRICKLE_WATCHER; @@ -1525,6 +1526,8 @@ $pl->invoke (cf::EVENT_PLAYER_LOGOUT, 1) if $pl->active; $pl->deactivate; + my $killer = cf::arch::get "killer_quit"; $pl->killer ($killer); $killer->destroy; + $pl->ob->check_score; $pl->invoke (cf::EVENT_PLAYER_QUIT); $pl->ns->destroy if $pl->ns; @@ -2613,6 +2616,9 @@ the new (success) or old (failed) map position. In either case, $done will be called at the end of this process. +Note that $check will be called with a potentially non-loaded map, so if +it needs a loaded map it has to call C<< ->load >>. + =cut our $GOTOGEN; @@ -2700,8 +2706,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 @@ -2713,6 +2717,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; @@ -2726,8 +2732,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); + } } } @@ -2736,31 +2746,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. " @@ -3117,8 +3129,8 @@ 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 split destroy)], + insert remove inv nrof name archname title slaying race + decrease split destroy change_exp)], ["cf::object::player" => qw(player)], ["cf::player" => qw(peaceful)], ["cf::map" => qw(trigger)], @@ -3389,6 +3401,8 @@ sub init { my $guard = freeze_mainloop; + evthread_start IO::AIO::poll_fileno; + reload_resources; } @@ -3430,7 +3444,6 @@ load_extensions; $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority - evthread_start IO::AIO::poll_fileno; } EV::loop; @@ -3781,12 +3794,13 @@ BDB::min_parallel 8; BDB::max_poll_reqs $TICK * 0.1; - $Coro::BDB::WATCHER->priority (1); + $AnyEvent::BDB::WATCHER->priority (1); unless ($DB_ENV) { $DB_ENV = BDB::db_env_create; - $DB_ENV->set_flags (BDB::AUTO_COMMIT | BDB::REGION_INIT | BDB::TXN_NOSYNC - | BDB::LOG_AUTOREMOVE, 1); + $DB_ENV->set_flags (BDB::AUTO_COMMIT | BDB::REGION_INIT); + $DB_ENV->set_flags (&BDB::LOG_AUTOREMOVE ) if BDB::VERSION v0, v4.7; + $DB_ENV->log_set_config (&BDB::LOG_AUTO_REMOVE) if BDB::VERSION v4.7; $DB_ENV->set_timeout (30, BDB::SET_TXN_TIMEOUT); $DB_ENV->set_timeout (30, BDB::SET_LOCK_TIMEOUT); @@ -3822,7 +3836,7 @@ IO::AIO::min_parallel 8; IO::AIO::max_poll_time $TICK * 0.1; - $Coro::AIO::WATCHER->priority (1); + undef $AnyEvent::AIO::WATCHER; } my $_log_backtrace;