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.479 by root, Thu Oct 8 05:04:27 2009 UTC vs.
Revision 1.490 by root, Sat Oct 24 06:16:40 2009 UTC

1# 1#
2# This file is part of Deliantra, the Roguelike Realtime MMORPG. 2# This file is part of Deliantra, the Roguelike Realtime MMORPG.
3# 3#
4# Copyright (©) 2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4# Copyright (©) 2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5# 5#
6# Deliantra is free software: you can redistribute it and/or modify 6# Deliantra is free software: you can redistribute it and/or modify it under
7# it under the terms of the GNU General Public License as published by 7# the terms of the Affero GNU General Public License as published by the
8# the Free Software Foundation, either version 3 of the License, or 8# Free Software Foundation, either version 3 of the License, or (at your
9# (at your option) any later version. 9# option) any later version.
10# 10#
11# This program is distributed in the hope that it will be useful, 11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details. 14# GNU General Public License for more details.
15# 15#
16# You should have received a copy of the GNU General Public License 16# You should have received a copy of the Affero GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>. 17# and the GNU General Public License along with this program. If not, see
18# <http://www.gnu.org/licenses/>.
18# 19#
19# The authors can be reached via e-mail to <support@deliantra.net> 20# The authors can be reached via e-mail to <support@deliantra.net>
20# 21#
21 22
22package cf; 23package cf;
23 24
24use 5.10.0; 25use 5.10.0;
25use utf8; 26use utf8;
53use JSON::XS 2.01 (); 54use JSON::XS 2.01 ();
54use BDB (); 55use BDB ();
55use Data::Dumper; 56use Data::Dumper;
56use Digest::MD5; 57use Digest::MD5;
57use Fcntl; 58use Fcntl;
58use YAML (); 59use YAML::XS ();
59use IO::AIO (); 60use IO::AIO ();
60use Time::HiRes; 61use Time::HiRes;
61use Compress::LZF; 62use Compress::LZF;
62use Digest::MD5 (); 63use Digest::MD5 ();
63 64
117our $BDB_DEADLOCK_WATCHER; 118our $BDB_DEADLOCK_WATCHER;
118our $BDB_CHECKPOINT_WATCHER; 119our $BDB_CHECKPOINT_WATCHER;
119our $BDB_TRICKLE_WATCHER; 120our $BDB_TRICKLE_WATCHER;
120our $DB_ENV; 121our $DB_ENV;
121 122
122our @EXTRA_MODULES = qw(pod mapscript); 123our @EXTRA_MODULES = qw(pod match mapscript);
123 124
124our %CFG; 125our %CFG;
125 126
126our $UPTIME; $UPTIME ||= time; 127our $UPTIME; $UPTIME ||= time;
127our $RUNTIME; 128our $RUNTIME;
169for (@REFLECT) { 170for (@REFLECT) {
170 my $reflect = JSON::XS::decode_json $_; 171 my $reflect = JSON::XS::decode_json $_;
171 $REFLECT{$reflect->{class}} = $reflect; 172 $REFLECT{$reflect->{class}} = $reflect;
172} 173}
173 174
175# this is decidedly evil
176$REFLECT{object}{flags} = { map +($_ => undef), grep $_, map /^FLAG_([A-Z0-9_]+)$/ && lc $1, keys %{"cf::"} };
177
174############################################################################# 178#############################################################################
175 179
176=head2 GLOBAL VARIABLES 180=head2 GLOBAL VARIABLES
177 181
178=over 4 182=over 4
224returns directly I<after> the tick processing (and consequently, can only wake one process 228returns directly I<after> the tick processing (and consequently, can only wake one process
225per tick), while cf::wait_for_tick wakes up all waiters after tick processing. 229per tick), while cf::wait_for_tick wakes up all waiters after tick processing.
226 230
227=item @cf::INVOKE_RESULTS 231=item @cf::INVOKE_RESULTS
228 232
229This array contains the results of the last C<invoke ()> call. When 233This array contains the results of the last C<invoke ()> call. When
230C<cf::override> is called C<@cf::INVOKE_RESULTS> is set to the parameters of 234C<cf::override> is called C<@cf::INVOKE_RESULTS> is set to the parameters of
231that call. 235that call.
232 236
233=item %cf::REFLECT 237=item %cf::REFLECT
234 238
235Contains, for each (C++) class name, a hash reference with information 239Contains, for each (C++) class name, a hash reference with information
236about object members (methods, scalars and arrays) and other metadata, 240about object members (methods, scalars, arrays and flags) and other
237which is useful for introspection. 241metadata, which is useful for introspection.
238 242
239=back 243=back
240 244
241=cut 245=cut
242 246
2337 : normalise $_ 2341 : normalise $_
2338 } @{ aio_readdir $UNIQUEDIR or [] } 2342 } @{ aio_readdir $UNIQUEDIR or [] }
2339 ] 2343 ]
2340} 2344}
2341 2345
2346=item cf::map::static_maps
2347
2348Returns an arrayref if paths of all static maps (all preinstalled F<.map>
2349file in the shared directory excluding F</styles>). May block.
2350
2351=cut
2352
2353sub static_maps() {
2354 my @dirs = "";
2355 my @maps;
2356
2357 while (@dirs) {
2358 my $dir = shift @dirs;
2359
2360 next if $dir eq "/styles";
2361
2362 my ($dirs, $files) = Coro::AIO::aio_scandir "$MAPDIR$dir", 2
2363 or return;
2364
2365 for (@$files) {
2366 s/\.map$// or next;
2367 utf8::decode $_;
2368 push @maps, "$dir/$_";
2369 }
2370
2371 push @dirs, map "$dir/$_", @$dirs;
2372 }
2373
2374 \@maps
2375}
2376
2342=back 2377=back
2343 2378
2344=head3 cf::object 2379=head3 cf::object
2345 2380
2346=cut 2381=cut
2761 2796
2762=cut 2797=cut
2763 2798
2764# non-persistent channels (usually the info channel) 2799# non-persistent channels (usually the info channel)
2765our %CHANNEL = ( 2800our %CHANNEL = (
2801 "c/motd" => {
2802 id => "infobox",
2803 title => "MOTD",
2804 reply => undef,
2805 tooltip => "The message of the day",
2806 },
2766 "c/identify" => { 2807 "c/identify" => {
2767 id => "infobox", 2808 id => "infobox",
2768 title => "Identify", 2809 title => "Identify",
2769 reply => undef, 2810 reply => undef,
2770 tooltip => "Items recently identified", 2811 tooltip => "Items recently identified",
2772 "c/examine" => { 2813 "c/examine" => {
2773 id => "infobox", 2814 id => "infobox",
2774 title => "Examine", 2815 title => "Examine",
2775 reply => undef, 2816 reply => undef,
2776 tooltip => "Signs and other items you examined", 2817 tooltip => "Signs and other items you examined",
2818 },
2819 "c/shopinfo" => {
2820 id => "infobox",
2821 title => "Shop Info",
2822 reply => undef,
2823 tooltip => "What your bargaining skill tells you about the shop",
2777 }, 2824 },
2778 "c/book" => { 2825 "c/book" => {
2779 id => "infobox", 2826 id => "infobox",
2780 title => "Book", 2827 title => "Book",
2781 reply => undef, 2828 reply => undef,
3379 3426
3380 warn "finished reloading resource files\n"; 3427 warn "finished reloading resource files\n";
3381} 3428}
3382 3429
3383sub reload_config { 3430sub reload_config {
3431 warn "reloading config file...\n";
3432
3384 open my $fh, "<:utf8", "$CONFDIR/config" 3433 open my $fh, "<:utf8", "$CONFDIR/config"
3385 or return; 3434 or return;
3386 3435
3387 local $/; 3436 local $/;
3388 *CFG = YAML::Load <$fh>; 3437 *CFG = YAML::XS::Load scalar <$fh>;
3389 3438
3390 $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_105_115", 5, 37]; 3439 $EMERGENCY_POSITION = $CFG{emergency_position} || ["/world/world_105_115", 5, 37];
3391 3440
3392 $cf::map::MAX_RESET = $CFG{map_max_reset} if exists $CFG{map_max_reset}; 3441 $cf::map::MAX_RESET = $CFG{map_max_reset} if exists $CFG{map_max_reset};
3393 $cf::map::DEFAULT_RESET = $CFG{map_default_reset} if exists $CFG{map_default_reset}; 3442 $cf::map::DEFAULT_RESET = $CFG{map_default_reset} if exists $CFG{map_default_reset};
3397 $CFG{mlockall} ? eval "mlockall()" : eval "munlockall()" 3446 $CFG{mlockall} ? eval "mlockall()" : eval "munlockall()"
3398 and die "WARNING: m(un)lockall failed: $!\n"; 3447 and die "WARNING: m(un)lockall failed: $!\n";
3399 }; 3448 };
3400 warn $@ if $@; 3449 warn $@ if $@;
3401 } 3450 }
3451
3452 warn "finished reloading resource files\n";
3402} 3453}
3403 3454
3404sub pidfile() { 3455sub pidfile() {
3405 sysopen my $fh, $PIDFILE, O_RDWR | O_CREAT 3456 sysopen my $fh, $PIDFILE, O_RDWR | O_CREAT
3406 or die "$PIDFILE: $!"; 3457 or die "$PIDFILE: $!";
3756 3807
3757 warn "unload completed, starting to reload now"; 3808 warn "unload completed, starting to reload now";
3758 3809
3759 warn "reloading cf.pm"; 3810 warn "reloading cf.pm";
3760 require cf; 3811 require cf;
3761 cf::_connect_to_perl; # nominally unnecessary, but cannot hurt 3812 cf::_connect_to_perl_1;
3762 3813
3763 warn "loading config and database again"; 3814 warn "loading config and database again";
3764 cf::reload_config; 3815 cf::reload_config;
3765 3816
3766 warn "loading extensions"; 3817 warn "loading extensions";
3974 } 4025 }
3975} 4026}
3976 4027
3977# load additional modules 4028# load additional modules
3978require "cf/$_.pm" for @EXTRA_MODULES; 4029require "cf/$_.pm" for @EXTRA_MODULES;
4030cf::_connect_to_perl_2;
3979 4031
3980END { cf::emergency_save } 4032END { cf::emergency_save }
3981 4033
39821 40341
3983 4035

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines