--- deliantra/server/lib/cf.pm 2008/09/16 16:03:02 1.446 +++ deliantra/server/lib/cf.pm 2008/09/23 04:29:11 1.453 @@ -65,10 +65,13 @@ # $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 $Coro::main->prio (Coro::PRIO_MAX); # run main coroutine ("the server") with very high priority +# make sure c-lzf reinitialises itself +Compress::LZF::set_serializer "Storable", "Storable::net_mstore", "Storable::mretrieve"; +Compress::LZF::sfreeze_cr { }; # prime Compress::LZF so it does not use require later + sub WF_AUTOCANCEL () { 1 } # automatically cancel this watcher on reload our %COMMAND = (); @@ -80,7 +83,7 @@ our %EXT_CORO = (); # coroutines bound to extensions our %EXT_MAP = (); # pluggable maps -our $RELOAD; # number of reloads so far +our $RELOAD; # number of reloads so far, non-zero while in reload our @EVENT; our $CONFDIR = confdir; @@ -127,6 +130,8 @@ our $JITTER; # average jitter our $TICK_START; # for load detecting purposes +our @POST_INIT; + binmode STDOUT; binmode STDERR; @@ -304,6 +309,20 @@ sub encode_json($) { $json_coder->encode ($_[0]) } sub decode_json($) { $json_coder->decode ($_[0]) } +=item cf::post_init { BLOCK } + +Execute the given codeblock, I all extensions have been (re-)loaded, +but I the server starts ticking again. + +The cdoeblock will have a single boolean argument to indicate whether this +is a reload or not. + +=cut + +sub post_init(&) { + push @POST_INIT, shift; +} + =item cf::lock_wait $string Wait until the given lock is available. See cf::lock_acquire. @@ -340,6 +359,7 @@ # wait for lock, if any while ($LOCK{$key}) { + #local $Coro::current->{desc} = "$Coro::current->{desc} "; push @{ $LOCK{$key} }, $Coro::current; Coro::schedule; } @@ -732,7 +752,7 @@ =head2 ATTACHABLE OBJECTS -Many objects in crossfire are so-called attachable objects. That means you can +Many objects in deliantra are so-called attachable objects. That means you can attach callbacks/event handlers (a collection of which is called an "attachment") to it. All such attachable objects support the following methods. @@ -792,7 +812,7 @@ Register an attachment by C<$name> through which attachable objects of the given CLASS can refer to this attachment. -Some classes such as crossfire maps and objects can specify attachments +Some classes such as deliantra maps and objects can specify attachments that are attached at load/instantiate time, thus the need for a name. These calls expect any number of the following handler/hook descriptions: @@ -1390,7 +1410,7 @@ =head2 CORE EXTENSIONS -Functions and methods that extend core crossfire objects. +Functions and methods that extend core deliantra objects. =cut @@ -1443,7 +1463,7 @@ my ($login) = @_; $cf::PLAYER{$login} - or cf::sync_job { !aio_stat path $login } + or !aio_stat path $login } sub find($) { @@ -1624,9 +1644,9 @@ \@paths } -=item $protocol_xml = $player->expand_cfpod ($crossfire_pod) +=item $protocol_xml = $player->expand_cfpod ($cfpod) -Expand crossfire pod fragments into protocol xml. +Expand deliantra pod fragments into protocol xml. =item $player->ext_reply ($msgid, @msg) @@ -2694,7 +2714,7 @@ 1 }) { - $self->message ("Something went wrong deep within the crossfire server. " + $self->message ("Something went wrong deep within the deliantra 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); @@ -2770,6 +2790,12 @@ reply => undef, tooltip => "Shows which body parts you posess and are available", }, + "c/skills" => { + id => "infobox", + title => "Skills", + reply => undef, + tooltip => "Shows your experience per skill and item power", + }, "c/uptime" => { id => "infobox", title => "Uptime", @@ -2793,7 +2819,8 @@ sub cf::client::send_msg { my ($self, $channel, $msg, $color, @extra) = @_; - $msg = $self->pl->expand_cfpod ($msg); + $msg = $self->pl->expand_cfpod ($msg) + unless $color & cf::NDI_VERBATIM; $color &= cf::NDI_CLIENT_MASK; # just in case... @@ -3332,14 +3359,6 @@ warn "finished reloading resource files\n"; } -sub init { - my $guard = freeze_mainloop; - - evthread_start IO::AIO::poll_fileno; - - reload_resources; -} - sub reload_config { open my $fh, "<:utf8", "$CONFDIR/config" or return; @@ -3381,7 +3400,20 @@ } sub main { - atomic; + cf::init_globals; # initialise logging + + LOG llevInfo, "Welcome to Deliantra, v" . VERSION; + LOG llevInfo, "Copyright (C) 2005-2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team."; + LOG llevInfo, "Copyright (C) 1994 Mark Wedel."; + LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen."; + + cf::init_experience; + cf::init_anim; + cf::init_attackmess; + cf::init_dynamic; + cf::init_block; + + $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority # we must not ever block the main coroutine local $Coro::idle = sub { @@ -3392,19 +3424,33 @@ })->prio (Coro::PRIO_MAX); }; - { - my $guard = freeze_mainloop; + evthread_start IO::AIO::poll_fileno; + + cf::sync_job { + reload_resources; reload_config; db_init; + + cf::load_settings; + cf::load_materials; + cf::init_uuid; + cf::init_signals; + cf::init_commands; + cf::init_skills; + + cf::init_beforeplay; + + atomic; + load_extensions; - $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority - } + utime time, time, $RUNTIMEFILE; - utime time, time, $RUNTIMEFILE; + # no (long-running) fork's whatsoever before this point(!) + POSIX::close delete $ENV{LOCKUTIL_LOCK_FD} if exists $ENV{LOCKUTIL_LOCK_FD}; - # no (long-running) fork's whatsoever before this point(!) - POSIX::close delete $ENV{LOCKUTIL_LOCK_FD} if exists $ENV{LOCKUTIL_LOCK_FD}; + (pop @POST_INIT)->(0) while @POST_INIT; + }; EV::loop; } @@ -3572,11 +3618,9 @@ _gv_clear *{"$pkg$name"}; # use PApp::Util; PApp::Util::sv_dump *{"$pkg$name"}; } - warn "cleared package #$pkg\n";#d# + warn "cleared package $pkg\n";#d# } -our $RELOAD; # how many times to reload - sub do_reload_perl() { # can/must only be called in main if ($Coro::current != $Coro::main) { @@ -3680,6 +3724,9 @@ warn "reattaching attachments to players"; reattach $_ for values %PLAYER; + warn "running post_load"; + (pop @POST_INIT)->(1) while @POST_INIT; + warn "leaving sync_job"; 1 @@ -3699,7 +3746,7 @@ # doing reload synchronously and two reloads happen back-to-back, # coro crashes during coro_state_free->destroy here. - $RELOAD_WATCHER ||= EV::timer 0, 0, sub { + $RELOAD_WATCHER ||= EV::timer $TICK * 1.5, 0, sub { do_reload_perl; undef $RELOAD_WATCHER; };