… | |
… | |
80 | our $NEXT_TICK; |
80 | our $NEXT_TICK; |
81 | our $NOW; |
81 | our $NOW; |
82 | our $USE_FSYNC = 1; # use fsync to write maps - default off |
82 | our $USE_FSYNC = 1; # use fsync to write maps - default off |
83 | |
83 | |
84 | our $BDB_POLL_WATCHER; |
84 | our $BDB_POLL_WATCHER; |
|
|
85 | our $BDB_DEADLOCK_WATCHER; |
85 | our $BDB_CHECKPOINT_WATCHER; |
86 | our $BDB_CHECKPOINT_WATCHER; |
86 | our $BDB_TRICKLE_WATCHER; |
87 | our $BDB_TRICKLE_WATCHER; |
87 | our $DB_ENV; |
88 | our $DB_ENV; |
88 | |
89 | |
89 | our %CFG; |
90 | our %CFG; |
… | |
… | |
2464 | if ($path =~ /^\*(.*)$/) { |
2465 | if ($path =~ /^\*(.*)$/) { |
2465 | if (my @obs = grep $_->map, ext::map_tags::find $1) { |
2466 | if (my @obs = grep $_->map, ext::map_tags::find $1) { |
2466 | my $ob = $obs[rand @obs]; |
2467 | my $ob = $obs[rand @obs]; |
2467 | |
2468 | |
2468 | # see if we actually can go there |
2469 | # see if we actually can go there |
2469 | # todo: use ob_blocked to check all tiles of the destination "object" |
2470 | if (@obs = grep !$self->blocked ($_->map, $_->x, $_->y), $ob, $ob->tail) { |
2470 | # for suitability. |
2471 | $ob = $obs[rand @obs]; |
|
|
2472 | } else { |
|
|
2473 | $self->message ("Wow, it's pretty crowded in there.", cf::NDI_UNIQUE | cf::NDI_RED); |
|
|
2474 | } |
|
|
2475 | # else put us there anyways for now #d# |
2471 | |
2476 | |
2472 | ($path, $x, $y) = ($ob->map, $ob->x, $ob->y); |
2477 | ($path, $x, $y) = ($ob->map, $ob->x, $ob->y); |
|
|
2478 | } else { |
|
|
2479 | ($path, $x, $y) = (undef, undef, undef); |
2473 | } |
2480 | } |
2474 | } |
2481 | } |
2475 | |
2482 | |
2476 | my $map = eval { |
2483 | my $map = eval { |
2477 | my $map = cf::map::find $path; |
2484 | my $map = defined $path ? cf::map::find $path : undef; |
2478 | |
2485 | |
2479 | if ($map) { |
2486 | if ($map) { |
2480 | $map = $map->customise_for ($self); |
2487 | $map = $map->customise_for ($self); |
2481 | $map = $check->($map) if $check && $map; |
2488 | $map = $check->($map) if $check && $map; |
2482 | } else { |
2489 | } else { |
2483 | $self->message ("The exit to '$path' is closed", cf::NDI_UNIQUE | cf::NDI_RED); |
2490 | $self->message ("The exit to '$path' is closed.", cf::NDI_UNIQUE | cf::NDI_RED); |
2484 | } |
2491 | } |
2485 | |
2492 | |
2486 | $map |
2493 | $map |
2487 | }; |
2494 | }; |
2488 | |
2495 | |
… | |
… | |
3458 | my $signal = new Coro::Signal; |
3465 | my $signal = new Coro::Signal; |
3459 | push @WAIT_FOR_TICK_BEGIN, $signal; |
3466 | push @WAIT_FOR_TICK_BEGIN, $signal; |
3460 | $signal->wait; |
3467 | $signal->wait; |
3461 | } |
3468 | } |
3462 | |
3469 | |
3463 | our $stat_fh; |
|
|
3464 | sysopen $stat_fh, "/tmp/cfstats", Fcntl::O_APPEND | Fcntl::O_CREAT | Fcntl::O_WRONLY, 0600;#d# |
|
|
3465 | |
|
|
3466 | $TICK_WATCHER = Event->timer ( |
3470 | $TICK_WATCHER = Event->timer ( |
3467 | reentrant => 0, |
3471 | reentrant => 0, |
3468 | parked => 1, |
3472 | parked => 1, |
3469 | prio => 0, |
3473 | prio => 0, |
3470 | at => $NEXT_TICK || $TICK, |
3474 | at => $NEXT_TICK || $TICK, |
… | |
… | |
3474 | Carp::cluck "major BUG: server tick called outside of main coro, skipping it" |
3478 | Carp::cluck "major BUG: server tick called outside of main coro, skipping it" |
3475 | unless ++$bug_warning > 10; |
3479 | unless ++$bug_warning > 10; |
3476 | return; |
3480 | return; |
3477 | } |
3481 | } |
3478 | |
3482 | |
3479 | my @pl = cf::player::list; my $stats = sprintf "%.2f %d %d %d", $RUNTIME, (scalar @pl), cf::object::actives_size, cf::object::objects_size; #d# |
|
|
3480 | |
|
|
3481 | $NOW = $tick_start = Event::time; |
3483 | $NOW = $tick_start = Event::time; |
3482 | |
3484 | |
3483 | cf::server_tick; # one server iteration |
3485 | cf::server_tick; # one server iteration |
3484 | |
3486 | |
3485 | $RUNTIME += $TICK; |
3487 | $RUNTIME += $TICK; |
… | |
… | |
3491 | write_runtime |
3493 | write_runtime |
3492 | or warn "ERROR: unable to write runtime file: $!"; |
3494 | or warn "ERROR: unable to write runtime file: $!"; |
3493 | }; |
3495 | }; |
3494 | } |
3496 | } |
3495 | |
3497 | |
3496 | # my $AFTER = Event::time; |
|
|
3497 | # warn $AFTER - $NOW;#d# |
|
|
3498 | |
|
|
3499 | if (my $sig = shift @WAIT_FOR_TICK_BEGIN) { |
3498 | if (my $sig = shift @WAIT_FOR_TICK_BEGIN) { |
3500 | $sig->send; |
3499 | $sig->send; |
3501 | } |
3500 | } |
3502 | while (my $sig = shift @WAIT_FOR_TICK) { |
3501 | while (my $sig = shift @WAIT_FOR_TICK) { |
3503 | $sig->send; |
3502 | $sig->send; |
… | |
… | |
3513 | |
3512 | |
3514 | $LOAD = ($NOW - $tick_start) / $TICK; |
3513 | $LOAD = ($NOW - $tick_start) / $TICK; |
3515 | $LOADAVG = $LOADAVG * 0.75 + $LOAD * 0.25; |
3514 | $LOADAVG = $LOADAVG * 0.75 + $LOAD * 0.25; |
3516 | |
3515 | |
3517 | _post_tick; |
3516 | _post_tick; |
3518 | |
|
|
3519 | # gather some statistics#d# |
|
|
3520 | $stats .= sprintf " %d\n", 10000 * ($NOW - $tick_start);#d# |
|
|
3521 | IO::AIO::aio_write $stat_fh, undef, undef, $stats, 0;#d# |
|
|
3522 | }, |
3517 | }, |
3523 | ); |
3518 | ); |
3524 | |
3519 | |
3525 | { |
3520 | { |
3526 | BDB::min_parallel 8; |
3521 | BDB::min_parallel 8; |
… | |
… | |
3549 | ) |
3544 | ) |
3550 | }; |
3545 | }; |
3551 | |
3546 | |
3552 | unless ($DB_ENV) { |
3547 | unless ($DB_ENV) { |
3553 | $DB_ENV = BDB::db_env_create; |
3548 | $DB_ENV = BDB::db_env_create; |
|
|
3549 | $DB_ENV->set_flags (BDB::AUTO_COMMIT | BDB::REGION_INIT | BDB::TXN_NOSYNC |
|
|
3550 | | BDB::LOG_AUTOREMOVE, 1); |
|
|
3551 | $DB_ENV->set_timeout (30, BDB::SET_TXN_TIMEOUT); |
|
|
3552 | $DB_ENV->set_timeout (30, BDB::SET_LOCK_TIMEOUT); |
3554 | |
3553 | |
3555 | cf::sync_job { |
3554 | cf::sync_job { |
3556 | eval { |
3555 | eval { |
3557 | BDB::db_env_open |
3556 | BDB::db_env_open |
3558 | $DB_ENV, |
3557 | $DB_ENV, |
… | |
… | |
3560 | BDB::INIT_LOCK | BDB::INIT_LOG | BDB::INIT_MPOOL | BDB::INIT_TXN |
3559 | BDB::INIT_LOCK | BDB::INIT_LOG | BDB::INIT_MPOOL | BDB::INIT_TXN |
3561 | | BDB::RECOVER | BDB::REGISTER | BDB::USE_ENVIRON | BDB::CREATE, |
3560 | | BDB::RECOVER | BDB::REGISTER | BDB::USE_ENVIRON | BDB::CREATE, |
3562 | 0666; |
3561 | 0666; |
3563 | |
3562 | |
3564 | cf::cleanup "db_env_open($BDBDIR): $!" if $!; |
3563 | cf::cleanup "db_env_open($BDBDIR): $!" if $!; |
3565 | |
|
|
3566 | $DB_ENV->set_flags (BDB::AUTO_COMMIT | BDB::REGION_INIT | BDB::TXN_NOSYNC |
|
|
3567 | | BDB::LOG_AUTOREMOVE, 1); |
|
|
3568 | $DB_ENV->set_lk_detect; |
|
|
3569 | }; |
3564 | }; |
3570 | |
3565 | |
3571 | cf::cleanup "db_env_open(db): $@" if $@; |
3566 | cf::cleanup "db_env_open(db): $@" if $@; |
3572 | }; |
3567 | }; |
3573 | } |
3568 | } |
3574 | |
3569 | |
|
|
3570 | $BDB_DEADLOCK_WATCHER = Event->timer ( |
|
|
3571 | after => 3, |
|
|
3572 | interval => 1, |
|
|
3573 | hard => 1, |
|
|
3574 | prio => 0, |
|
|
3575 | data => WF_AUTOCANCEL, |
|
|
3576 | cb => sub { |
|
|
3577 | BDB::db_env_lock_detect $DB_ENV, 0, BDB::LOCK_DEFAULT, 0, sub { }; |
|
|
3578 | }, |
|
|
3579 | ); |
3575 | $BDB_CHECKPOINT_WATCHER = Event->timer ( |
3580 | $BDB_CHECKPOINT_WATCHER = Event->timer ( |
3576 | after => 11, |
3581 | after => 11, |
3577 | interval => 60, |
3582 | interval => 60, |
3578 | hard => 1, |
3583 | hard => 1, |
3579 | prio => 0, |
3584 | prio => 0, |