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.336 by root, Tue Aug 21 00:31:18 2007 UTC vs.
Revision 1.354 by root, Sun Sep 2 12:26:54 2007 UTC

21use Coro::Semaphore; 21use Coro::Semaphore;
22use Coro::AIO; 22use Coro::AIO;
23use Coro::Storable; 23use Coro::Storable;
24use Coro::Util (); 24use Coro::Util ();
25 25
26use JSON::XS 1.4 (); 26use JSON::XS ();
27use BDB (); 27use BDB ();
28use Data::Dumper; 28use Data::Dumper;
29use Digest::MD5; 29use Digest::MD5;
30use Fcntl; 30use Fcntl;
31use YAML::Syck (); 31use YAML::Syck ();
272Wait until the given lock is available and then acquires it and returns 272Wait until the given lock is available and then acquires it and returns
273a Coro::guard object. If the guard object gets destroyed (goes out of scope, 273a Coro::guard object. If the guard object gets destroyed (goes out of scope,
274for example when the coroutine gets canceled), the lock is automatically 274for example when the coroutine gets canceled), the lock is automatically
275returned. 275returned.
276 276
277Locks are *not* recursive, locking from the same coro twice results in a
278deadlocked coro.
279
277Lock names should begin with a unique identifier (for example, cf::map::find 280Lock names should begin with a unique identifier (for example, cf::map::find
278uses map_find and cf::map::load uses map_load). 281uses map_find and cf::map::load uses map_load).
279 282
280=item $locked = cf::lock_active $string 283=item $locked = cf::lock_active $string
281 284
575 if (1) { 578 if (1) {
576 $md5 = 579 $md5 =
577 join "\x00", 580 join "\x00",
578 $processversion, 581 $processversion,
579 map { 582 map {
580 Coro::cede; 583 cf::cede_to_tick;
581 ($src->[$_], Digest::MD5::md5_hex $data[$_]) 584 ($src->[$_], Digest::MD5::md5_hex $data[$_])
582 } 0.. $#$src; 585 } 0.. $#$src;
583 586
584 587
585 my $dbmd5 = db_get cache => "$id/md5"; 588 my $dbmd5 = db_get cache => "$id/md5";
1149 my ($type, $reply, @payload) = 1152 my ($type, $reply, @payload) =
1150 "ARRAY" eq ref $msg 1153 "ARRAY" eq ref $msg
1151 ? @$msg 1154 ? @$msg
1152 : ($msg->{msgtype}, $msg->{msgid}, %$msg); # TODO: version 1, remove 1155 : ($msg->{msgtype}, $msg->{msgid}, %$msg); # TODO: version 1, remove
1153 1156
1157 my @reply;
1158
1154 if (my $cb = $EXTCMD{$type}) { 1159 if (my $cb = $EXTCMD{$type}) {
1155 my @reply = $cb->($pl, @payload); 1160 @reply = $cb->($pl, @payload);
1156
1157 $pl->ext_reply ($reply, @reply)
1158 if $reply;
1159 } 1161 }
1162
1163 $pl->ext_reply ($reply, @reply)
1164 if $reply;
1165
1160 } else { 1166 } else {
1161 warn "player " . ($pl->ob->name) . " sent unparseable ext message: <$buf>\n"; 1167 warn "player " . ($pl->ob->name) . " sent unparseable ext message: <$buf>\n";
1162 } 1168 }
1163 1169
1164 cf::override; 1170 cf::override;
1319 1325
1320 aio_mkdir playerdir $pl, 0770; 1326 aio_mkdir playerdir $pl, 0770;
1321 $pl->{last_save} = $cf::RUNTIME; 1327 $pl->{last_save} = $cf::RUNTIME;
1322 1328
1323 $pl->save_pl ($path); 1329 $pl->save_pl ($path);
1324 Coro::cede; 1330 cf::cede_to_tick;
1325} 1331}
1326 1332
1327sub new($) { 1333sub new($) {
1328 my ($login) = @_; 1334 my ($login) = @_;
1329 1335
1407 or return []; 1413 or return [];
1408 1414
1409 my @logins; 1415 my @logins;
1410 1416
1411 for my $login (@$dirs) { 1417 for my $login (@$dirs) {
1418 my $path = path $login;
1419
1420 # a .pst is a dead give-away for a valid player
1421 unless (-e "$path.pst") {
1412 my $fh = aio_open path $login, Fcntl::O_RDONLY, 0 or next; 1422 my $fh = aio_open $path, Fcntl::O_RDONLY, 0 or next;
1413 aio_read $fh, 0, 512, my $buf, 0 or next; 1423 aio_read $fh, 0, 512, my $buf, 0 or next;
1414 $buf !~ /^password -------------$/m or next; # official not-valid tag 1424 $buf !~ /^password -------------$/m or next; # official not-valid tag
1425 }
1415 1426
1416 utf8::decode $login; 1427 utf8::decode $login;
1417 push @logins, $login; 1428 push @logins, $login;
1418 } 1429 }
1419 1430
1457sub expand_cfpod { 1468sub expand_cfpod {
1458 ((my $self), (local $_)) = @_; 1469 ((my $self), (local $_)) = @_;
1459 1470
1460 # escape & and < 1471 # escape & and <
1461 s/&/&amp;/g; 1472 s/&/&amp;/g;
1462 s/(?<![BIUGH])</&lt;/g; 1473 s/(?<![BIUGHT])</&lt;/g;
1463 1474
1464 # this is buggy, it needs to properly take care of nested <'s 1475 # this is buggy, it needs to properly take care of nested <'s
1465 1476
1466 1 while 1477 1 while
1467 # replace B<>, I<>, U<> etc. 1478 # replace B<>, I<>, U<> etc.
1468 s/B<([^\>]*)>/<b>$1<\/b>/ 1479 s/B<([^\>]*)>/<b>$1<\/b>/
1469 || s/I<([^\>]*)>/<i>$1<\/i>/ 1480 || s/I<([^\>]*)>/<i>$1<\/i>/
1470 || s/U<([^\>]*)>/<u>$1<\/u>/ 1481 || s/U<([^\>]*)>/<u>$1<\/u>/
1482 || s/T<([^\>]*)>/<big><b>$1<\/b><\/big>/
1471 # replace G<male|female> tags 1483 # replace G<male|female> tags
1472 || s{G<([^>|]*)\|([^>]*)>}{ 1484 || s{G<([^>|]*)\|([^>]*)>}{
1473 $self->gender ? $2 : $1 1485 $self->gender ? $2 : $1
1474 }ge 1486 }ge
1475 # replace H<hint text> 1487 # replace H<hint text>
1846 local $self->{deny_reset} = 1; # loading can take a long time 1858 local $self->{deny_reset} = 1; # loading can take a long time
1847 1859
1848 my $path = $self->{path}; 1860 my $path = $self->{path};
1849 1861
1850 { 1862 {
1863 my $guard1 = cf::lock_acquire "map_data:$path";
1851 my $guard = cf::lock_acquire "map_load:$path"; 1864 my $guard2 = cf::lock_acquire "map_load:$path";
1852 1865
1853 return if $self->in_memory != cf::MAP_SWAPPED; 1866 return if $self->in_memory != cf::MAP_SWAPPED;
1854 1867
1855 $self->in_memory (cf::MAP_LOADING); 1868 $self->in_memory (cf::MAP_LOADING);
1856 1869
1857 $self->alloc; 1870 $self->alloc;
1858 1871
1859 $self->pre_load; 1872 $self->pre_load;
1860 Coro::cede; 1873 cf::cede_to_tick;
1861 1874
1862 $self->_load_objects ($self->{load_path}, 1) 1875 $self->_load_objects ($self->{load_path}, 1)
1863 or return; 1876 or return;
1864 1877
1865 $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1) 1878 $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1)
1871 $self->clear_unique_items; 1884 $self->clear_unique_items;
1872 $self->_load_objects ($uniq, 0); 1885 $self->_load_objects ($uniq, 0);
1873 } 1886 }
1874 } 1887 }
1875 1888
1876 Coro::cede; 1889 cf::cede_to_tick;
1877 # now do the right thing for maps 1890 # now do the right thing for maps
1878 $self->link_multipart_objects; 1891 $self->link_multipart_objects;
1879 $self->difficulty ($self->estimate_difficulty) 1892 $self->difficulty ($self->estimate_difficulty)
1880 unless $self->difficulty; 1893 unless $self->difficulty;
1881 Coro::cede; 1894 cf::cede_to_tick;
1882 1895
1883 unless ($self->{deny_activate}) { 1896 unless ($self->{deny_activate}) {
1884 $self->decay_objects; 1897 $self->decay_objects;
1885 $self->fix_auto_apply; 1898 $self->fix_auto_apply;
1886 $self->update_buttons; 1899 $self->update_buttons;
1887 Coro::cede; 1900 cf::cede_to_tick;
1888 $self->set_darkness_map; 1901 $self->set_darkness_map;
1889 Coro::cede; 1902 cf::cede_to_tick;
1890 $self->activate; 1903 $self->activate;
1891 } 1904 }
1892 1905
1893 $self->{last_save} = $cf::RUNTIME; 1906 $self->{last_save} = $cf::RUNTIME;
1894 $self->last_access ($cf::RUNTIME); 1907 $self->last_access ($cf::RUNTIME);
1944} 1957}
1945 1958
1946sub do_load_sync { 1959sub do_load_sync {
1947 my ($map) = @_; 1960 my ($map) = @_;
1948 1961
1962 cf::LOG cf::llevDebug | cf::logBacktrace, "do_load_sync"
1963 if $Coro::current == $Coro::main;
1964
1949 cf::sync_job { $map->load }; 1965 cf::sync_job { $map->load };
1950} 1966}
1951 1967
1952our %MAP_PREFETCH; 1968our %MAP_PREFETCH;
1953our $MAP_PREFETCHER = undef; 1969our $MAP_PREFETCHER = undef;
1954 1970
1955sub find_async { 1971sub find_async {
1956 my ($path, $origin) = @_; 1972 my ($path, $origin, $load) = @_;
1957 1973
1958 $path = normalise $path, $origin && $origin->{path}; 1974 $path = normalise $path, $origin && $origin->{path};
1959 1975
1960 if (my $map = $cf::MAP{$path}) { 1976 if (my $map = $cf::MAP{$path}) {
1961 return $map if $map->in_memory == cf::MAP_IN_MEMORY; 1977 return $map if !$load || $map->in_memory == cf::MAP_IN_MEMORY;
1962 } 1978 }
1963 1979
1964 undef $MAP_PREFETCH{$path}; 1980 $MAP_PREFETCH{$path} |= $load;
1981
1965 $MAP_PREFETCHER ||= cf::async { 1982 $MAP_PREFETCHER ||= cf::async {
1966 while (%MAP_PREFETCH) { 1983 while (%MAP_PREFETCH) {
1967 for my $path (keys %MAP_PREFETCH) { 1984 while (my ($k, $v) = each %MAP_PREFETCH) {
1968 if (my $map = find $path) { 1985 if (my $map = find $k) {
1969 $map->load; 1986 $map->load if $v;
1970 } 1987 }
1971 1988
1972 delete $MAP_PREFETCH{$path}; 1989 delete $MAP_PREFETCH{$k};
1973 } 1990 }
1974 } 1991 }
1975 undef $MAP_PREFETCHER; 1992 undef $MAP_PREFETCHER;
1976 }; 1993 };
1977 $MAP_PREFETCHER->prio (6); 1994 $MAP_PREFETCHER->prio (6);
1980} 1997}
1981 1998
1982sub save { 1999sub save {
1983 my ($self) = @_; 2000 my ($self) = @_;
1984 2001
1985 my $lock = cf::lock_acquire "map_data:" . $self->path; 2002 my $lock = cf::lock_acquire "map_data:$self->{path}";
1986 2003
1987 $self->{last_save} = $cf::RUNTIME; 2004 $self->{last_save} = $cf::RUNTIME;
1988 2005
1989 return unless $self->dirty; 2006 return unless $self->dirty;
1990 2007
2013 my ($self) = @_; 2030 my ($self) = @_;
2014 2031
2015 # save first because save cedes 2032 # save first because save cedes
2016 $self->save; 2033 $self->save;
2017 2034
2018 my $lock = cf::lock_acquire "map_data:" . $self->path; 2035 my $lock = cf::lock_acquire "map_data:$self->{path}";
2019 2036
2020 return if $self->players; 2037 return if $self->players;
2021 return if $self->in_memory != cf::MAP_IN_MEMORY; 2038 return if $self->in_memory != cf::MAP_IN_MEMORY;
2022 return if $self->{deny_save}; 2039 return if $self->{deny_save};
2023 2040
2075my $nuke_counter = "aaaa"; 2092my $nuke_counter = "aaaa";
2076 2093
2077sub nuke { 2094sub nuke {
2078 my ($self) = @_; 2095 my ($self) = @_;
2079 2096
2097 {
2098 my $lock = cf::lock_acquire "map_data:$self->{path}";
2099
2080 delete $cf::MAP{$self->path}; 2100 delete $cf::MAP{$self->path};
2081 2101
2082 $self->unlink_save; 2102 $self->unlink_save;
2083 2103
2084 bless $self, "cf::map"; 2104 bless $self, "cf::map";
2085 delete $self->{deny_reset}; 2105 delete $self->{deny_reset};
2086 $self->{deny_save} = 1; 2106 $self->{deny_save} = 1;
2087 $self->reset_timeout (1); 2107 $self->reset_timeout (1);
2088 $self->path ($self->{path} = "{nuke}/" . ($nuke_counter++)); 2108 $self->path ($self->{path} = "{nuke}/" . ($nuke_counter++));
2089 2109
2090 $cf::MAP{$self->path} = $self; 2110 $cf::MAP{$self->path} = $self;
2111 }
2091 2112
2092 $self->reset; # polite request, might not happen 2113 $self->reset; # polite request, might not happen
2093} 2114}
2094 2115
2095=item $maps = cf::map::tmp_maps 2116=item $maps = cf::map::tmp_maps
2489the message, with C<log> being the default. If C<$color> is negative, suppress 2510the message, with C<log> being the default. If C<$color> is negative, suppress
2490the message unless the client supports the msg packet. 2511the message unless the client supports the msg packet.
2491 2512
2492=cut 2513=cut
2493 2514
2515our %CHANNEL = (
2516 "c/identify" => {
2517 id => "identify",
2518 title => "Identify",
2519 reply => undef,
2520 tooltip => "Items recently identified",
2521 },
2522 "c/examine" => {
2523 id => "examine",
2524 title => "Examine",
2525 reply => undef,
2526 tooltip => "Signs and other items you examined",
2527 },
2528);
2529
2494sub cf::client::send_msg { 2530sub cf::client::send_msg {
2495 my ($self, $channel, $msg, $color, @extra) = @_; 2531 my ($self, $channel, $msg, $color, @extra) = @_;
2496 2532
2497 $msg = $self->pl->expand_cfpod ($msg); 2533 $msg = $self->pl->expand_cfpod ($msg);
2498 2534
2499 $color &= cf::NDI_CLIENT_MASK; # just in case... 2535 $color &= cf::NDI_CLIENT_MASK; # just in case...
2536
2537 # check predefined channels, for the benefit of C
2538 $channel = $CHANNEL{$channel} if $CHANNEL{$channel};
2500 2539
2501 if (ref $channel) { 2540 if (ref $channel) {
2502 # send meta info to client, if not yet sent 2541 # send meta info to client, if not yet sent
2503 unless (exists $self->{channel}{$channel->{id}}) { 2542 unless (exists $self->{channel}{$channel->{id}}) {
2504 $self->{channel}{$channel->{id}} = $channel; 2543 $self->{channel}{$channel->{id}} = $channel;
2505 $self->ext_msg (channel_info => $channel); 2544 $self->ext_msg (channel_info => $channel)
2545 if $self->can_msg;
2506 } 2546 }
2507 2547
2508 $channel = $channel->{id}; 2548 $channel = $channel->{id};
2509 } 2549 }
2510 2550
2551=cut 2591=cut
2552 2592
2553sub cf::client::ext_msg($$@) { 2593sub cf::client::ext_msg($$@) {
2554 my ($self, $type, @msg) = @_; 2594 my ($self, $type, @msg) = @_;
2555 2595
2556 my $extcmd = $self->extcmd;
2557
2558 if ($extcmd == 2) { 2596 if ($self->extcmd == 2) {
2559 $self->send_packet ("ext " . $self->{json_coder}->encode ([$type, @msg])); 2597 $self->send_packet ("ext " . $self->{json_coder}->encode ([$type, @msg]));
2560 } elsif ($extcmd == 1) { # TODO: remove 2598 } elsif ($self->extcmd == 1) { # TODO: remove
2561 push @msg, msgtype => "event_$type"; 2599 push @msg, msgtype => "event_$type";
2562 $self->send_packet ("ext " . $self->{json_coder}->encode ({@msg})); 2600 $self->send_packet ("ext " . $self->{json_coder}->encode ({@msg}));
2563 } 2601 }
2564} 2602}
2565 2603
2572sub cf::client::ext_reply($$@) { 2610sub cf::client::ext_reply($$@) {
2573 my ($self, $id, @msg) = @_; 2611 my ($self, $id, @msg) = @_;
2574 2612
2575 if ($self->extcmd == 2) { 2613 if ($self->extcmd == 2) {
2576 $self->send_packet ("ext " . $self->{json_coder}->encode (["reply-$id", @msg])); 2614 $self->send_packet ("ext " . $self->{json_coder}->encode (["reply-$id", @msg]));
2577 } elsif ($self->ns->extcmd == 1) { 2615 } elsif ($self->extcmd == 1) {
2578 #TODO: version 1, remove 2616 #TODO: version 1, remove
2579 unshift @msg, msgtype => "reply", msgid => $id; 2617 unshift @msg, msgtype => "reply", msgid => $id;
2580 $self->send_packet ("ext " . $self->{json_coder}->encode ({@msg})); 2618 $self->send_packet ("ext " . $self->{json_coder}->encode ({@msg}));
2581 } 2619 }
2582} 2620}
2646 my ($type, $reply, @payload) = 2684 my ($type, $reply, @payload) =
2647 "ARRAY" eq ref $msg 2685 "ARRAY" eq ref $msg
2648 ? @$msg 2686 ? @$msg
2649 : ($msg->{msgtype}, $msg->{msgid}, %$msg); # TODO: version 1, remove 2687 : ($msg->{msgtype}, $msg->{msgid}, %$msg); # TODO: version 1, remove
2650 2688
2689 my @reply;
2690
2651 if (my $cb = $EXTICMD{$type}) { 2691 if (my $cb = $EXTICMD{$type}) {
2652 my @reply = $cb->($ns, @payload); 2692 @reply = $cb->($ns, @payload);
2653
2654 $ns->ext_reply ($reply, @reply)
2655 if $reply;
2656 } 2693 }
2694
2695 $ns->ext_reply ($reply, @reply)
2696 if $reply;
2697
2657 } else { 2698 } else {
2658 warn "client " . ($ns->pl ? $ns->pl->ob->name : $ns->host) . " sent unparseable exti message: <$buf>\n"; 2699 warn "client " . ($ns->pl ? $ns->pl->ob->name : $ns->host) . " sent unparseable exti message: <$buf>\n";
2659 } 2700 }
2660 2701
2661 cf::override; 2702 cf::override;
2722 2763
2723The following functions and methods are available within a safe environment: 2764The following functions and methods are available within a safe environment:
2724 2765
2725 cf::object 2766 cf::object
2726 contr pay_amount pay_player map x y force_find force_add 2767 contr pay_amount pay_player map x y force_find force_add
2727 insert remove name archname title slaying race 2768 insert remove name archname title slaying race decrease_ob_nr
2728 2769
2729 cf::object::player 2770 cf::object::player
2730 player 2771 player
2731 2772
2732 cf::player 2773 cf::player
2737 2778
2738=cut 2779=cut
2739 2780
2740for ( 2781for (
2741 ["cf::object" => qw(contr pay_amount pay_player map force_find force_add x y 2782 ["cf::object" => qw(contr pay_amount pay_player map force_find force_add x y
2742 insert remove inv name archname title slaying race)], 2783 insert remove inv name archname title slaying race
2784 decrease_ob_nr)],
2743 ["cf::object::player" => qw(player)], 2785 ["cf::object::player" => qw(player)],
2744 ["cf::player" => qw(peaceful)], 2786 ["cf::player" => qw(peaceful)],
2745 ["cf::map" => qw(trigger)], 2787 ["cf::map" => qw(trigger)],
2746) { 2788) {
2747 no strict 'refs'; 2789 no strict 'refs';
2823# the server's init and main functions 2865# the server's init and main functions
2824 2866
2825sub load_facedata($) { 2867sub load_facedata($) {
2826 my ($path) = @_; 2868 my ($path) = @_;
2827 2869
2870 # HACK to clear player env face cache, we need some signal framework
2871 # for this (global event?)
2872 %ext::player_env::MUSIC_FACE_CACHE = ();
2873
2828 my $enc = JSON::XS->new->utf8->canonical; 2874 my $enc = JSON::XS->new->utf8->canonical->relaxed;
2829 2875
2830 warn "loading facedata from $path\n"; 2876 warn "loading facedata from $path\n";
2831 2877
2832 my $facedata; 2878 my $facedata;
2833 0 < aio_load $path, $facedata 2879 0 < aio_load $path, $facedata
2839 or cf::cleanup "$path: version mismatch, cannot proceed."; 2885 or cf::cleanup "$path: version mismatch, cannot proceed.";
2840 2886
2841 # patch in the exptable 2887 # patch in the exptable
2842 $facedata->{resource}{"res/exp_table"} = { 2888 $facedata->{resource}{"res/exp_table"} = {
2843 type => FT_RSRC, 2889 type => FT_RSRC,
2844 data => $enc->encode ([map cf::level_to_min_exp $_, 0 .. cf::settings->max_level]), 2890 data => $enc->encode ([map cf::level_to_min_exp $_, 1 .. cf::settings->max_level]),
2845 }; 2891 };
2846 cf::cede_to_tick; 2892 cf::cede_to_tick;
2847 2893
2848 { 2894 {
2849 my $faces = $facedata->{faceinfo}; 2895 my $faces = $facedata->{faceinfo};
2902 name => $name, 2948 name => $name,
2903 %{ $info->{meta} || {} }, 2949 %{ $info->{meta} || {} },
2904 }); 2950 });
2905 2951
2906 $data = pack "(w/a*)*", $meta, $info->{data}; 2952 $data = pack "(w/a*)*", $meta, $info->{data};
2953 } else {
2954 $data = $info->{data};
2907 } 2955 }
2908 2956
2909 cf::face::set_data $idx, 0, $data, Digest::MD5::md5 $data; 2957 cf::face::set_data $idx, 0, $data, Digest::MD5::md5 $data;
2910 cf::face::set_type $idx, $info->{type}; 2958 cf::face::set_type $idx, $info->{type};
2911 2959
2941 $ns->fx_want ($k, $v); 2989 $ns->fx_want ($k, $v);
2942 } 2990 }
2943}; 2991};
2944 2992
2945sub reload_regions { 2993sub reload_regions {
2994 # HACK to clear player env face cache, we need some signal framework
2995 # for this (global event?)
2996 %ext::player_env::MUSIC_FACE_CACHE = ();
2997
2946 load_resource_file "$MAPDIR/regions" 2998 load_resource_file "$MAPDIR/regions"
2947 or die "unable to load regions file\n"; 2999 or die "unable to load regions file\n";
2948 3000
2949 for (cf::region::list) { 3001 for (cf::region::list) {
2950 $_->{match} = qr/$_->{match}/ 3002 $_->{match} = qr/$_->{match}/
2986 3038
2987sub init { 3039sub init {
2988 reload_resources; 3040 reload_resources;
2989} 3041}
2990 3042
2991sub cfg_load { 3043sub reload_config {
2992 open my $fh, "<:utf8", "$CONFDIR/config" 3044 open my $fh, "<:utf8", "$CONFDIR/config"
2993 or return; 3045 or return;
2994 3046
2995 local $/; 3047 local $/;
2996 *CFG = YAML::Syck::Load <$fh>; 3048 *CFG = YAML::Syck::Load <$fh>;
3016 (async { 3068 (async {
3017 Event::one_event; 3069 Event::one_event;
3018 })->prio (Coro::PRIO_MAX); 3070 })->prio (Coro::PRIO_MAX);
3019 }; 3071 };
3020 3072
3021 cfg_load; 3073 reload_config;
3022 db_init; 3074 db_init;
3023 load_extensions; 3075 load_extensions;
3024 3076
3025 $TICK_WATCHER->start; 3077 $TICK_WATCHER->start;
3026 Event::loop; 3078 Event::loop;
3219 warn "reloading cf.pm"; 3271 warn "reloading cf.pm";
3220 require cf; 3272 require cf;
3221 cf::_connect_to_perl; # nominally unnecessary, but cannot hurt 3273 cf::_connect_to_perl; # nominally unnecessary, but cannot hurt
3222 3274
3223 warn "loading config and database again"; 3275 warn "loading config and database again";
3224 cf::cfg_load; 3276 cf::reload_config;
3225 3277
3226 warn "loading extensions"; 3278 warn "loading extensions";
3227 cf::load_extensions; 3279 cf::load_extensions;
3228 3280
3229 warn "reattaching attachments to objects/players"; 3281 warn "reattaching attachments to objects/players";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines