ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
(Generate patch)

Comparing deliantra/server/lib/cf.pm (file contents):
Revision 1.513 by root, Mon Apr 12 05:22:38 2010 UTC vs.
Revision 1.531 by root, Wed Apr 28 21:07:41 2010 UTC

106our $RANDOMDIR = "$LOCALDIR/random"; 106our $RANDOMDIR = "$LOCALDIR/random";
107our $BDBDIR = "$LOCALDIR/db"; 107our $BDBDIR = "$LOCALDIR/db";
108our $PIDFILE = "$LOCALDIR/pid"; 108our $PIDFILE = "$LOCALDIR/pid";
109our $RUNTIMEFILE = "$LOCALDIR/runtime"; 109our $RUNTIMEFILE = "$LOCALDIR/runtime";
110 110
111our %RESOURCE; 111our %RESOURCE; # unused
112 112
113our $OUTPUT_RATE_MIN = 4000; 113our $OUTPUT_RATE_MIN = 3000;
114our $OUTPUT_RATE_MAX = 100000; 114our $OUTPUT_RATE_MAX = 1000000;
115
116our $MAX_LINKS = 32; # how many chained exits to follow
117our $VERBOSE_IO = 1;
115 118
116our $TICK = MAX_TIME * 1e-6; # this is a CONSTANT(!) 119our $TICK = MAX_TIME * 1e-6; # this is a CONSTANT(!)
117our $NEXT_RUNTIME_WRITE; # when should the runtime file be written 120our $NEXT_RUNTIME_WRITE; # when should the runtime file be written
118our $NEXT_TICK; 121our $NEXT_TICK;
119our $USE_FSYNC = 1; # use fsync to write maps - default on 122our $USE_FSYNC = 1; # use fsync to write maps - default on
165 168
166our $EMERGENCY_POSITION; 169our $EMERGENCY_POSITION;
167 170
168sub cf::map::normalise; 171sub cf::map::normalise;
169 172
173sub in_main() {
174 $Coro::current == $Coro::main
175}
176
170############################################################################# 177#############################################################################
171 178
172%REFLECT = (); 179%REFLECT = ();
173for (@REFLECT) { 180for (@REFLECT) {
174 my $reflect = JSON::XS::decode_json $_; 181 my $reflect = JSON::XS::decode_json $_;
261$Coro::State::DIEHOOK = sub { 268$Coro::State::DIEHOOK = sub {
262 return unless $^S eq 0; # "eq", not "==" 269 return unless $^S eq 0; # "eq", not "=="
263 270
264 warn Carp::longmess $_[0]; 271 warn Carp::longmess $_[0];
265 272
266 if ($Coro::current == $Coro::main) {#d# 273 if (in_main) {#d#
267 warn "DIEHOOK called in main context, Coro bug?\n";#d# 274 warn "DIEHOOK called in main context, Coro bug?\n";#d#
268 return;#d# 275 return;#d#
269 }#d# 276 }#d#
270 277
271 # kill coroutine otherwise 278 # kill coroutine otherwise
399} 406}
400 407
401=item cf::periodic $interval, $cb 408=item cf::periodic $interval, $cb
402 409
403Like EV::periodic, but randomly selects a starting point so that the actions 410Like EV::periodic, but randomly selects a starting point so that the actions
404get spread over timer. 411get spread over time.
405 412
406=cut 413=cut
407 414
408sub periodic($$) { 415sub periodic($$) {
409 my ($interval, $cb) = @_; 416 my ($interval, $cb) = @_;
587 reset_signals; 594 reset_signals;
588 &$cb 595 &$cb
589 }, @args; 596 }, @args;
590 597
591 wantarray ? @res : $res[-1] 598 wantarray ? @res : $res[-1]
599}
600
601sub objinfo {
602 (
603 "counter value" => cf::object::object_count,
604 "objects created" => cf::object::create_count,
605 "objects destroyed" => cf::object::destroy_count,
606 "freelist size" => cf::object::free_count,
607 "allocated objects" => cf::object::objects_size,
608 "active objects" => cf::object::actives_size,
609 )
592} 610}
593 611
594=item $coin = coin_from_name $name 612=item $coin = coin_from_name $name
595 613
596=cut 614=cut
1177 1195
1178 sync_job { 1196 sync_job {
1179 if (length $$rdata) { 1197 if (length $$rdata) {
1180 utf8::decode (my $decname = $filename); 1198 utf8::decode (my $decname = $filename);
1181 warn sprintf "saving %s (%d,%d)\n", 1199 warn sprintf "saving %s (%d,%d)\n",
1182 $decname, length $$rdata, scalar @$objs; 1200 $decname, length $$rdata, scalar @$objs
1201 if $VERBOSE_IO;
1183 1202
1184 if (my $fh = aio_open "$filename~", O_WRONLY | O_CREAT, 0600) { 1203 if (my $fh = aio_open "$filename~", O_WRONLY | O_CREAT, 0600) {
1185 aio_chmod $fh, SAVE_MODE; 1204 aio_chmod $fh, SAVE_MODE;
1186 aio_write $fh, 0, (length $$rdata), $$rdata, 0; 1205 aio_write $fh, 0, (length $$rdata), $$rdata, 0;
1187 if ($cf::USE_FSYNC) { 1206 if ($cf::USE_FSYNC) {
1244 $av = $st->{objs}; 1263 $av = $st->{objs};
1245 } 1264 }
1246 1265
1247 utf8::decode (my $decname = $filename); 1266 utf8::decode (my $decname = $filename);
1248 warn sprintf "loading %s (%d,%d)\n", 1267 warn sprintf "loading %s (%d,%d)\n",
1249 $decname, length $data, scalar @{$av || []}; 1268 $decname, length $data, scalar @{$av || []}
1269 if $VERBOSE_IO;
1250 1270
1251 ($data, $av) 1271 ($data, $av)
1252} 1272}
1253 1273
1254=head2 COMMAND CALLBACKS 1274=head2 COMMAND CALLBACKS
1425 if (length $@) { 1445 if (length $@) {
1426 warn "$v->{path}: $@\n"; 1446 warn "$v->{path}: $@\n";
1427 1447
1428 cf::cleanup "mandatory extension '$k' failed to load, exiting." 1448 cf::cleanup "mandatory extension '$k' failed to load, exiting."
1429 if exists $v->{meta}{mandatory}; 1449 if exists $v->{meta}{mandatory};
1450
1451 warn "$v->{base}: optional extension cannot be loaded, skipping.\n";
1452 delete $todo{$k};
1430 } else { 1453 } else {
1431 $done{$k} = delete $todo{$k}; 1454 $done{$k} = delete $todo{$k};
1432 push @EXTS, $v->{pkg}; 1455 push @EXTS, $v->{pkg};
1433 $progress = 1; 1456 $progress = 1;
1434 1457
1612 $pl->password ("*"); # this should lock out the player until we have nuked the dir 1635 $pl->password ("*"); # this should lock out the player until we have nuked the dir
1613 1636
1614 $pl->invoke (cf::EVENT_PLAYER_LOGOUT, 1) if $pl->active; 1637 $pl->invoke (cf::EVENT_PLAYER_LOGOUT, 1) if $pl->active;
1615 $pl->deactivate; 1638 $pl->deactivate;
1616 my $killer = cf::arch::get "killer_quit"; $pl->killer ($killer); $killer->destroy; 1639 my $killer = cf::arch::get "killer_quit"; $pl->killer ($killer); $killer->destroy;
1617 $pl->ob->check_score;
1618 $pl->invoke (cf::EVENT_PLAYER_QUIT); 1640 $pl->invoke (cf::EVENT_PLAYER_QUIT);
1619 $pl->ns->destroy if $pl->ns; 1641 $pl->ns->destroy if $pl->ns;
1620 1642
1621 my $path = playerdir $pl; 1643 my $path = playerdir $pl;
1622 my $temp = "$path~$cf::RUNTIME~deleting~"; 1644 my $temp = "$path~$cf::RUNTIME~deleting~";
1677 \@logins 1699 \@logins
1678} 1700}
1679 1701
1680=item $player->maps 1702=item $player->maps
1681 1703
1704=item cf::player::maps $login
1705
1682Returns an arrayref of map paths that are private for this 1706Returns an arrayref of map paths that are private for this
1683player. May block. 1707player. May block.
1684 1708
1685=cut 1709=cut
1686 1710
1747 1771
1748=cut 1772=cut
1749 1773
1750sub find_by_path($) { 1774sub find_by_path($) {
1751 my ($path) = @_; 1775 my ($path) = @_;
1776
1777 $path =~ s/^~[^\/]*//; # skip ~login
1752 1778
1753 my ($match, $specificity); 1779 my ($match, $specificity);
1754 1780
1755 for my $region (list) { 1781 for my $region (list) {
1756 if ($region->{match} && $path =~ $region->{match}) { 1782 if ($region->{match} && $path =~ $region->{match}) {
1820 1846
1821 $EXT_MAP{$pkg} = [$prio, qr<$regex>]; 1847 $EXT_MAP{$pkg} = [$prio, qr<$regex>];
1822} 1848}
1823 1849
1824# also paths starting with '/' 1850# also paths starting with '/'
1825$EXT_MAP{"cf::map"} = [0, qr{^(?=/)}]; 1851$EXT_MAP{"cf::map::wrap"} = [0, qr{^(?=/)}];
1826 1852
1827sub thawer_merge { 1853sub thawer_merge {
1828 my ($self, $merge) = @_; 1854 my ($self, $merge) = @_;
1829 1855
1830 # we have to keep some variables in memory intact 1856 # we have to keep some variables in memory intact
2140 or next; 2166 or next;
2141 $neigh = find $neigh, $map 2167 $neigh = find $neigh, $map
2142 or next; 2168 or next;
2143 $neigh->load; 2169 $neigh->load;
2144 2170
2171 # now find the diagonal neighbours
2145 push @neigh, 2172 push @neigh,
2146 [$neigh->tile_path (($_ + 3) % 4), $neigh], 2173 [$neigh->tile_path (($_ + 3) % 4), $neigh],
2147 [$neigh->tile_path (($_ + 1) % 4), $neigh]; 2174 [$neigh->tile_path (($_ + 1) % 4), $neigh];
2148 } 2175 }
2149 2176
2201 $MAP_PREFETCHER->prio (6); 2228 $MAP_PREFETCHER->prio (6);
2202 2229
2203 () 2230 ()
2204} 2231}
2205 2232
2233# common code, used by both ->save and ->swapout
2206sub save { 2234sub _save {
2207 my ($self) = @_; 2235 my ($self) = @_;
2208
2209 my $lock = cf::lock_acquire "map_data:$self->{path}";
2210 2236
2211 $self->{last_save} = $cf::RUNTIME; 2237 $self->{last_save} = $cf::RUNTIME;
2212 2238
2213 return unless $self->dirty; 2239 return unless $self->dirty;
2214 2240
2234 } else { 2260 } else {
2235 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES); 2261 $self->_save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES);
2236 } 2262 }
2237} 2263}
2238 2264
2265sub save {
2266 my ($self) = @_;
2267
2268 my $lock = cf::lock_acquire "map_data:$self->{path}";
2269
2270 $self->_save;
2271}
2272
2239sub swap_out { 2273sub swap_out {
2240 my ($self) = @_; 2274 my ($self) = @_;
2241 2275
2242 # save first because save cedes
2243 $self->save;
2244
2245 my $lock = cf::lock_acquire "map_data:$self->{path}"; 2276 my $lock = cf::lock_acquire "map_data:$self->{path}";
2246 2277
2247 return if $self->players;
2248 return if $self->in_memory != cf::MAP_ACTIVE; 2278 return if $self->in_memory != cf::MAP_ACTIVE;
2249 return if $self->{deny_save}; 2279 return if $self->{deny_save};
2280 return if $self->players;
2250 2281
2282 # first deactivate the map and "unlink" it from the core
2283 $self->deactivate;
2284 $_->clear_links_to ($self) for values %cf::MAP;
2251 $self->in_memory (cf::MAP_SWAPPED); 2285 $self->in_memory (cf::MAP_SWAPPED);
2286
2287 # then atomically save
2288 $self->_save;
2289
2290 # then free the map
2291 $self->clear;
2292}
2293
2294sub reset_at {
2295 my ($self) = @_;
2296
2297 # TODO: safety, remove and allow resettable per-player maps
2298 return 1e99 if $self->{deny_reset};
2299
2300 my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access;
2301 my $to = List::Util::min $MAX_RESET, $self->reset_timeout || $DEFAULT_RESET;
2302
2303 $time + $to
2304}
2305
2306sub should_reset {
2307 my ($self) = @_;
2308
2309 $self->reset_at <= $cf::RUNTIME
2310}
2311
2312sub reset {
2313 my ($self) = @_;
2314
2315 my $lock = cf::lock_acquire "map_data:$self->{path}";
2316
2317 return if $self->players;
2318
2319 warn "resetting map ", $self->path, "\n";
2320
2321 $self->in_memory (cf::MAP_SWAPPED);
2322
2323 # need to save uniques path
2324 unless ($self->{deny_save}) {
2325 my $uniq = $self->uniq_path; utf8::encode $uniq;
2326
2327 $self->_save_objects ($uniq, cf::IO_UNIQUES)
2328 if $uniq;
2329 }
2330
2331 delete $cf::MAP{$self->path};
2252 2332
2253 $self->deactivate; 2333 $self->deactivate;
2254 $_->clear_links_to ($self) for values %cf::MAP; 2334 $_->clear_links_to ($self) for values %cf::MAP;
2255 $self->clear; 2335 $self->clear;
2256}
2257
2258sub reset_at {
2259 my ($self) = @_;
2260
2261 # TODO: safety, remove and allow resettable per-player maps
2262 return 1e99 if $self->{deny_reset};
2263
2264 my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access;
2265 my $to = List::Util::min $MAX_RESET, $self->reset_timeout || $DEFAULT_RESET;
2266
2267 $time + $to
2268}
2269
2270sub should_reset {
2271 my ($self) = @_;
2272
2273 $self->reset_at <= $cf::RUNTIME
2274}
2275
2276sub reset {
2277 my ($self) = @_;
2278
2279 my $lock = cf::lock_acquire "map_data:$self->{path}";
2280
2281 return if $self->players;
2282
2283 warn "resetting map ", $self->path, "\n";
2284
2285 $self->in_memory (cf::MAP_SWAPPED);
2286
2287 # need to save uniques path
2288 unless ($self->{deny_save}) {
2289 my $uniq = $self->uniq_path; utf8::encode $uniq;
2290
2291 $self->_save_objects ($uniq, cf::IO_UNIQUES)
2292 if $uniq;
2293 }
2294
2295 delete $cf::MAP{$self->path};
2296
2297 $self->deactivate;
2298 $_->clear_links_to ($self) for values %cf::MAP;
2299 $self->clear;
2300 2336
2301 $self->unlink_save; 2337 $self->unlink_save;
2302 $self->destroy; 2338 $self->destroy;
2303} 2339}
2304 2340
2312 2348
2313 delete $cf::MAP{$self->path}; 2349 delete $cf::MAP{$self->path};
2314 2350
2315 $self->unlink_save; 2351 $self->unlink_save;
2316 2352
2317 bless $self, "cf::map"; 2353 bless $self, "cf::map::wrap";
2318 delete $self->{deny_reset}; 2354 delete $self->{deny_reset};
2319 $self->{deny_save} = 1; 2355 $self->{deny_save} = 1;
2320 $self->reset_timeout (1); 2356 $self->reset_timeout (1);
2321 $self->path ($self->{path} = "{nuke}/" . ($nuke_counter++)); 2357 $self->path ($self->{path} = "{nuke}/" . ($nuke_counter++));
2322 2358
2552 2588
2553Freezes the player and moves him/her to a special map (C<{link}>). 2589Freezes the player and moves him/her to a special map (C<{link}>).
2554 2590
2555The player should be reasonably safe there for short amounts of time (e.g. 2591The player should be reasonably safe there for short amounts of time (e.g.
2556for loading a map). You I<MUST> call C<leave_link> as soon as possible, 2592for loading a map). You I<MUST> call C<leave_link> as soon as possible,
2557though, as the palyer cannot control the character while it is on the link 2593though, as the player cannot control the character while it is on the link
2558map. 2594map.
2559 2595
2560Will never block. 2596Will never block.
2561 2597
2562=item $player_object->leave_link ($map, $x, $y) 2598=item $player_object->leave_link ($map, $x, $y)
2583sub cf::object::player::enter_link { 2619sub cf::object::player::enter_link {
2584 my ($self) = @_; 2620 my ($self) = @_;
2585 2621
2586 $self->deactivate_recursive; 2622 $self->deactivate_recursive;
2587 2623
2624 ++$self->{_link_recursion};
2625
2588 return if UNIVERSAL::isa $self->map, "ext::map_link"; 2626 return if UNIVERSAL::isa $self->map, "ext::map_link";
2589 2627
2590 $self->{_link_pos} ||= [$self->map->{path}, $self->x, $self->y] 2628 $self->{_link_pos} ||= [$self->map->{path}, $self->x, $self->y]
2591 if $self->map && $self->map->{path} ne "{link}"; 2629 if $self->map && $self->map->{path} ne "{link}";
2592 2630
2593 $self->enter_map ($LINK_MAP || link_map, 10, 10); 2631 $self->enter_map ($LINK_MAP || link_map, 3, 3);
2594} 2632}
2595 2633
2596sub cf::object::player::leave_link { 2634sub cf::object::player::leave_link {
2597 my ($self, $map, $x, $y) = @_; 2635 my ($self, $map, $x, $y) = @_;
2598 2636
2623 $map->load_neighbours; 2661 $map->load_neighbours;
2624 2662
2625 return unless $self->contr->active; 2663 return unless $self->contr->active;
2626 2664
2627 local $self->{_prev_pos} = $link_pos; # ugly hack for rent.ext 2665 local $self->{_prev_pos} = $link_pos; # ugly hack for rent.ext
2628 $self->enter_map ($map, $x, $y); 2666 if ($self->enter_map ($map, $x, $y)) {
2629 2667 # entering was successful
2668 delete $self->{_link_recursion};
2630 # only activate afterwards, to support waiting in hooks 2669 # only activate afterwards, to support waiting in hooks
2631 $self->activate_recursive; 2670 $self->activate_recursive;
2632} 2671 }
2633 2672
2673}
2674
2634=item $player_object->goto ($path, $x, $y[, $check->($map)[, $done->()]]) 2675=item $player_object->goto ($path, $x, $y[, $check->($map, $x, $y, $player)[, $done->($player)]])
2635 2676
2636Moves the player to the given map-path and coordinates by first freezing 2677Moves the player to the given map-path and coordinates by first freezing
2637her, loading and preparing them map, calling the provided $check callback 2678her, loading and preparing them map, calling the provided $check callback
2638that has to return the map if sucecssful, and then unfreezes the player on 2679that has to return the map if sucecssful, and then unfreezes the player on
2639the new (success) or old (failed) map position. In either case, $done will 2680the new (success) or old (failed) map position. In either case, $done will
2646 2687
2647our $GOTOGEN; 2688our $GOTOGEN;
2648 2689
2649sub cf::object::player::goto { 2690sub cf::object::player::goto {
2650 my ($self, $path, $x, $y, $check, $done) = @_; 2691 my ($self, $path, $x, $y, $check, $done) = @_;
2692
2693 if ($self->{_link_recursion} >= $MAX_LINKS) {
2694 warn "FATAL: link recursion exceeded, ", $self->name, " goto $path $x $y, redirecting.";
2695 $self->failmsg ("Something went wrong inside the server - please contact an administrator!");
2696 ($path, $x, $y) = @$EMERGENCY_POSITION;
2697 }
2651 2698
2652 # do generation counting so two concurrent goto's will be executed in-order 2699 # do generation counting so two concurrent goto's will be executed in-order
2653 my $gen = $self->{_goto_generation} = ++$GOTOGEN; 2700 my $gen = $self->{_goto_generation} = ++$GOTOGEN;
2654 2701
2655 $self->enter_link; 2702 $self->enter_link;
2679 my $map = eval { 2726 my $map = eval {
2680 my $map = defined $path ? cf::map::find $path : undef; 2727 my $map = defined $path ? cf::map::find $path : undef;
2681 2728
2682 if ($map) { 2729 if ($map) {
2683 $map = $map->customise_for ($self); 2730 $map = $map->customise_for ($self);
2684 $map = $check->($map) if $check && $map; 2731 $map = $check->($map, $x, $y, $self) if $check && $map;
2685 } else { 2732 } else {
2686 $self->message ("The exit to '$path' is closed.", cf::NDI_UNIQUE | cf::NDI_RED); 2733 $self->message ("The exit to '$path' is closed.", cf::NDI_UNIQUE | cf::NDI_RED);
2687 } 2734 }
2688 2735
2689 $map 2736 $map
2697 if ($gen == $self->{_goto_generation}) { 2744 if ($gen == $self->{_goto_generation}) {
2698 delete $self->{_goto_generation}; 2745 delete $self->{_goto_generation};
2699 $self->leave_link ($map, $x, $y); 2746 $self->leave_link ($map, $x, $y);
2700 } 2747 }
2701 2748
2702 $done->() if $done; 2749 $done->($self) if $done;
2703 })->prio (1); 2750 })->prio (1);
2704} 2751}
2705 2752
2706=item $player_object->enter_exit ($exit_object) 2753=item $player_object->enter_exit ($exit_object)
2707 2754
3381 my $idx = (cf::face::find $name) || cf::face::alloc $name; 3428 my $idx = (cf::face::find $name) || cf::face::alloc $name;
3382 3429
3383 cf::face::set_data $idx, 0, $info->{data}, $info->{hash}; 3430 cf::face::set_data $idx, 0, $info->{data}, $info->{hash};
3384 cf::face::set_type $idx, $info->{type}; 3431 cf::face::set_type $idx, $info->{type};
3385 } else { 3432 } else {
3386 $RESOURCE{$name} = $info; 3433 $RESOURCE{$name} = $info; # unused
3387 } 3434 }
3388 3435
3389 cf::cede_to_tick; 3436 cf::cede_to_tick;
3390 } 3437 }
3391 } 3438 }
3392 3439
3393 cf::global->invoke (EVENT_GLOBAL_RESOURCE_UPDATE); 3440 cf::global->invoke (EVENT_GLOBAL_RESOURCE_UPDATE);
3394 3441
3395 1 3442 1
3396} 3443}
3397
3398cf::global->attach (on_resource_update => sub {
3399 if (my $soundconf = $RESOURCE{"res/sound.conf"}) {
3400 $soundconf = JSON::XS->new->utf8->relaxed->decode ($soundconf->{data});
3401
3402 for (0 .. SOUND_CAST_SPELL_0 - 1) {
3403 my $sound = $soundconf->{compat}[$_]
3404 or next;
3405
3406 my $face = cf::face::find "sound/$sound->[1]";
3407 cf::sound::set $sound->[0] => $face;
3408 cf::sound::old_sound_index $_, $face; # gcfclient-compat
3409 }
3410
3411 while (my ($k, $v) = each %{$soundconf->{event}}) {
3412 my $face = cf::face::find "sound/$v";
3413 cf::sound::set $k => $face;
3414 }
3415 }
3416});
3417 3444
3418register_exticmd fx_want => sub { 3445register_exticmd fx_want => sub {
3419 my ($ns, $want) = @_; 3446 my ($ns, $want) = @_;
3420 3447
3421 while (my ($k, $v) = each %$want) { 3448 while (my ($k, $v) = each %$want) {
3460sub reload_treasures { 3487sub reload_treasures {
3461 load_resource_file "$DATADIR/treasures" 3488 load_resource_file "$DATADIR/treasures"
3462 or die "unable to load treasurelists\n"; 3489 or die "unable to load treasurelists\n";
3463} 3490}
3464 3491
3492sub reload_sound {
3493 warn "loading sound config from $DATADIR/sound\n";
3494
3495 0 < Coro::AIO::aio_load "$DATADIR/sound", my $data
3496 or die "$DATADIR/sound $!";
3497
3498 my $soundconf = JSON::XS->new->utf8->relaxed->decode ($data);
3499
3500 for (0 .. SOUND_CAST_SPELL_0 - 1) {
3501 my $sound = $soundconf->{compat}[$_]
3502 or next;
3503
3504 my $face = cf::face::find "sound/$sound->[1]";
3505 cf::sound::set $sound->[0] => $face;
3506 cf::sound::old_sound_index $_, $face; # gcfclient-compat
3507 }
3508
3509 while (my ($k, $v) = each %{$soundconf->{event}}) {
3510 my $face = cf::face::find "sound/$v";
3511 cf::sound::set $k => $face;
3512 }
3513}
3514
3465sub reload_resources { 3515sub reload_resources {
3466 warn "reloading resource files...\n"; 3516 warn "reloading resource files...\n";
3467 3517
3468 reload_facedata; 3518 reload_facedata;
3519 reload_sound;
3469 reload_archetypes; 3520 reload_archetypes;
3470 reload_regions; 3521 reload_regions;
3471 reload_treasures; 3522 reload_treasures;
3472 3523
3473 warn "finished reloading resource files\n"; 3524 warn "finished reloading resource files\n";
3480 or return; 3531 or return;
3481 3532
3482 local $/; 3533 local $/;
3483 *CFG = YAML::XS::Load scalar <$fh>; 3534 *CFG = YAML::XS::Load scalar <$fh>;
3484 3535
3485 $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_105_115", 5, 37]; 3536 $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_104_115", 49, 38];
3486 3537
3487 $cf::map::MAX_RESET = $CFG{map_max_reset} if exists $CFG{map_max_reset}; 3538 $cf::map::MAX_RESET = $CFG{map_max_reset} if exists $CFG{map_max_reset};
3488 $cf::map::DEFAULT_RESET = $CFG{map_default_reset} if exists $CFG{map_default_reset}; 3539 $cf::map::DEFAULT_RESET = $CFG{map_default_reset} if exists $CFG{map_default_reset};
3489 3540
3490 if (exists $CFG{mlockall}) { 3541 if (exists $CFG{mlockall}) {
3531 3582
3532 LOG llevInfo, "Welcome to Deliantra, v" . VERSION; 3583 LOG llevInfo, "Welcome to Deliantra, v" . VERSION;
3533 LOG llevInfo, "Copyright (C) 2005-2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team."; 3584 LOG llevInfo, "Copyright (C) 2005-2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team.";
3534 LOG llevInfo, "Copyright (C) 1994 Mark Wedel."; 3585 LOG llevInfo, "Copyright (C) 1994 Mark Wedel.";
3535 LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen."; 3586 LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen.";
3536
3537 cf::init_experience;
3538 cf::init_anim;
3539 cf::init_attackmess;
3540 cf::init_dynamic;
3541 3587
3542 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority 3588 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority
3543 3589
3544 # we must not ever block the main coroutine 3590 # we must not ever block the main coroutine
3545 local $Coro::idle = sub { 3591 local $Coro::idle = sub {
3551 }; 3597 };
3552 3598
3553 evthread_start IO::AIO::poll_fileno; 3599 evthread_start IO::AIO::poll_fileno;
3554 3600
3555 cf::sync_job { 3601 cf::sync_job {
3602 cf::init_experience;
3603 cf::init_anim;
3604 cf::init_attackmess;
3605 cf::init_dynamic;
3606
3556 cf::load_settings; 3607 cf::load_settings;
3557 cf::load_materials; 3608 cf::load_materials;
3558 3609
3559 reload_resources; 3610 reload_resources;
3560 reload_config; 3611 reload_config;
3576 use POSIX (); 3627 use POSIX ();
3577 POSIX::close delete $ENV{LOCKUTIL_LOCK_FD} if exists $ENV{LOCKUTIL_LOCK_FD}; 3628 POSIX::close delete $ENV{LOCKUTIL_LOCK_FD} if exists $ENV{LOCKUTIL_LOCK_FD};
3578 3629
3579 (pop @POST_INIT)->(0) while @POST_INIT; 3630 (pop @POST_INIT)->(0) while @POST_INIT;
3580 }; 3631 };
3632
3633 cf::object::thawer::errors_are_fatal 0;
3634 warn "parse errors in files are no longer fatal from this point on.\n";
3581 3635
3582 main_loop; 3636 main_loop;
3583} 3637}
3584 3638
3585############################################################################# 3639#############################################################################
3762 my $leaf_symtab = *{$stem_symtab->{$leaf}}{HASH}; 3816 my $leaf_symtab = *{$stem_symtab->{$leaf}}{HASH};
3763 for my $name (keys %$leaf_symtab) { 3817 for my $name (keys %$leaf_symtab) {
3764 _gv_clear *{"$pkg$name"}; 3818 _gv_clear *{"$pkg$name"};
3765# use PApp::Util; PApp::Util::sv_dump *{"$pkg$name"}; 3819# use PApp::Util; PApp::Util::sv_dump *{"$pkg$name"};
3766 } 3820 }
3767 warn "cleared package $pkg\n";#d#
3768} 3821}
3769 3822
3770sub do_reload_perl() { 3823sub do_reload_perl() {
3771 # can/must only be called in main 3824 # can/must only be called in main
3772 if ($Coro::current != $Coro::main) { 3825 if (in_main) {
3773 warn "can only reload from main coroutine"; 3826 warn "can only reload from main coroutine";
3774 return; 3827 return;
3775 } 3828 }
3776 3829
3777 return if $RELOAD++; 3830 return if $RELOAD++;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines