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.581 by root, Fri Feb 3 02:04:11 2012 UTC vs.
Revision 1.587 by root, Wed Oct 31 19:09:47 2012 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,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team 4# Copyright (©) 2006,2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5# 5#
6# Deliantra is free software: you can redistribute it and/or modify it under 6# Deliantra is free software: you can redistribute it and/or modify it under
7# the terms of the Affero GNU General Public License as published by the 7# the terms of the Affero GNU General Public License as published by the
8# Free Software Foundation, either version 3 of the License, or (at your 8# Free Software Foundation, either version 3 of the License, or (at your
9# 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 Affero GNU General Public License 16# You should have received a copy of the Affero GNU General Public License
17# and the GNU General Public License along with this program. If not, see 17# and the GNU General Public License along with this program. If not, see
18# <http://www.gnu.org/licenses/>. 18# <http://www.gnu.org/licenses/>.
19# 19#
20# 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>
21# 21#
22 22
23package cf; 23package cf;
24 24
32use Safe; 32use Safe;
33use Safe::Hole; 33use Safe::Hole;
34use Storable (); 34use Storable ();
35use Carp (); 35use Carp ();
36 36
37use Guard (); 37use AnyEvent ();
38use AnyEvent::IO ();
39use AnyEvent::DNS ();
40
38use Coro (); 41use Coro ();
39use Coro::State; 42use Coro::State;
40use Coro::Handle; 43use Coro::Handle;
41use Coro::EV; 44use Coro::EV;
42use Coro::AnyEvent; 45use Coro::AnyEvent;
48use Coro::AIO; 51use Coro::AIO;
49use Coro::BDB 1.6; 52use Coro::BDB 1.6;
50use Coro::Storable; 53use Coro::Storable;
51use Coro::Util (); 54use Coro::Util ();
52 55
56use Guard ();
53use JSON::XS 2.01 (); 57use JSON::XS 2.01 ();
54use BDB (); 58use BDB ();
55use Data::Dumper; 59use Data::Dumper;
56use Fcntl; 60use Fcntl;
57use YAML::XS (); 61use YAML::XS ();
129our $DB_ENV; 133our $DB_ENV;
130 134
131our @EXTRA_MODULES = qw(pod match mapscript incloader); 135our @EXTRA_MODULES = qw(pod match mapscript incloader);
132 136
133our %CFG; 137our %CFG;
138our %EXT_CFG; # cfgkeyname => [var-ref, defaultvalue]
134 139
135our $UPTIME; $UPTIME ||= time; 140our $UPTIME; $UPTIME ||= time;
136our $RUNTIME = 0; 141our $RUNTIME = 0;
137our $SERVER_TICK = 0; 142our $SERVER_TICK = 0;
138our $NOW; 143our $NOW;
335)) { 340)) {
336 @{"safe::$pkg\::wrap::ISA"} = @{"$pkg\::wrap::ISA"} = $pkg; 341 @{"safe::$pkg\::wrap::ISA"} = @{"$pkg\::wrap::ISA"} = $pkg;
337} 342}
338 343
339$EV::DIED = sub { 344$EV::DIED = sub {
340 Carp::cluck "error in event callback: @_"; 345 warn "error in event callback: $@";
341}; 346};
342 347
343############################################################################# 348#############################################################################
344 349
345sub fork_call(&@); 350sub fork_call(&@);
1531 }; 1536 };
1532 1537
1533 $grp 1538 $grp
1534} 1539}
1535 1540
1541sub _ext_cfg_reg($$$$) {
1542 my ($rvar, $varname, $cfgname, $default) = @_;
1543
1544 $cfgname = lc $varname
1545 unless length $cfgname;
1546
1547 $EXT_CFG{$cfgname} = [$rvar, $default];
1548
1549 $$rvar = exists $CFG{$cfgname} ? $CFG{$cfgname} : $default;
1550}
1551
1536sub load_extensions { 1552sub load_extensions {
1537 info "loading extensions..."; 1553 info "loading extensions...";
1554
1555 %EXT_CFG = ();
1538 1556
1539 cf::sync_job { 1557 cf::sync_job {
1540 my %todo; 1558 my %todo;
1541 1559
1542 for my $path (<$LIBDIR/*.ext>) { 1560 for my $path (<$LIBDIR/*.ext>) {
1585 unless exists $done{$_}; 1603 unless exists $done{$_};
1586 } 1604 }
1587 1605
1588 trace "... pass $pass, loading '$k' into '$v->{pkg}'\n"; 1606 trace "... pass $pass, loading '$k' into '$v->{pkg}'\n";
1589 1607
1608 my $source = $v->{source};
1609
1610 # support "CONF varname :confname = default" pseudo-statements
1611 $source =~ s{
1612 ^ CONF \s+ ([^\s:=]+) \s* (?:: \s* ([^\s:=]+) \s* )? = ([^\n#]+)
1613 }{
1614 "our \$$1; BEGIN { cf::_ext_cfg_reg \\\$$1, q\x00$1\x00, q\x00$2\x00, $3 }";
1615 }gmxe;
1616
1590 my $active = eval $v->{source}; 1617 my $active = eval $source;
1591 1618
1592 if (length $@) { 1619 if (length $@) {
1593 error "$v->{path}: $@\n"; 1620 error "$v->{path}: $@\n";
1594 1621
1595 cf::cleanup "mandatory extension '$k' failed to load, exiting." 1622 cf::cleanup "mandatory extension '$k' failed to load, exiting."
3480=cut 3507=cut
3481 3508
3482############################################################################# 3509#############################################################################
3483# the server's init and main functions 3510# the server's init and main functions
3484 3511
3512our %FACEHASH; # hash => idx, #d# HACK for http server
3513
3485sub load_facedata($) { 3514sub load_facedata($) {
3486 my ($path) = @_; 3515 my ($path) = @_;
3487 3516
3488 # HACK to clear player env face cache, we need some signal framework 3517 # HACK to clear player env face cache, we need some signal framework
3489 # for this (global event?) 3518 # for this (global event?)
3508 cf::cede_to_tick; 3537 cf::cede_to_tick;
3509 3538
3510 { 3539 {
3511 my $faces = $facedata->{faceinfo}; 3540 my $faces = $facedata->{faceinfo};
3512 3541
3513 while (my ($face, $info) = each %$faces) { 3542 for my $face (sort keys %$faces) {
3543 my $info = $faces->{$face};
3514 my $idx = (cf::face::find $face) || cf::face::alloc $face; 3544 my $idx = (cf::face::find $face) || cf::face::alloc $face;
3515 3545
3516 cf::face::set_visibility $idx, $info->{visibility}; 3546 cf::face::set_visibility $idx, $info->{visibility};
3517 cf::face::set_magicmap $idx, $info->{magicmap}; 3547 cf::face::set_magicmap $idx, $info->{magicmap};
3518 cf::face::set_data $idx, 0, $info->{data32}, $info->{hash32}; 3548 cf::face::set_data $idx, 0, $info->{data32}, $info->{hash32};
3519 cf::face::set_data $idx, 1, $info->{data64}, $info->{hash64}; 3549 cf::face::set_data $idx, 1, $info->{data64}, $info->{hash64};
3520 cf::face::set_data $idx, 2, $info->{glyph} , $info->{glyph} ; 3550 cf::face::set_data $idx, 2, $info->{glyph} , $info->{glyph} ;
3551 $FACEHASH{$info->{hash64}} = $idx;#d#
3521 3552
3522 cf::cede_to_tick; 3553 cf::cede_to_tick;
3523 } 3554 }
3524 3555
3525 while (my ($face, $info) = each %$faces) { 3556 while (my ($face, $info) = each %$faces) {
3559 my $idx = (cf::face::find $name) || cf::face::alloc $name; 3590 my $idx = (cf::face::find $name) || cf::face::alloc $name;
3560 3591
3561 cf::face::set_data $idx, 0, $info->{data}, $info->{hash}; 3592 cf::face::set_data $idx, 0, $info->{data}, $info->{hash};
3562 cf::face::set_type $idx, $type; 3593 cf::face::set_type $idx, $type;
3563 cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already 3594 cf::face::set_meta $idx, $type & 1 ? undef : $info->{meta}; # preserve meta unless prepended already
3595 $FACEHASH{$info->{hash}} = $idx;#d#
3564 } else { 3596 } else {
3565# $RESOURCE{$name} = $info; # unused 3597# $RESOURCE{$name} = $info; # unused
3566 } 3598 }
3567 3599
3568 cf::cede_to_tick; 3600 cf::cede_to_tick;
3713 LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen."; 3745 LOG llevInfo, "Copyright (C) 1992 Frank Tore Johansen.";
3714 3746
3715 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority 3747 $Coro::current->prio (Coro::PRIO_MAX); # give the main loop max. priority
3716 3748
3717 # we must not ever block the main coroutine 3749 # we must not ever block the main coroutine
3718 local $Coro::idle = sub { 3750 $Coro::idle = sub {
3719 Carp::cluck "FATAL: Coro::idle was called, major BUG, use cf::sync_job!\n";#d# 3751 Carp::cluck "FATAL: Coro::idle was called, major BUG, use cf::sync_job!\n";#d#
3720 (async { 3752 (async {
3721 $Coro::current->{desc} = "IDLE BUG HANDLER"; 3753 $Coro::current->{desc} = "IDLE BUG HANDLER";
3722 EV::loop EV::LOOP_ONESHOT; 3754 EV::loop EV::LOOP_ONESHOT;
3723 })->prio (Coro::PRIO_MAX); 3755 })->prio (Coro::PRIO_MAX);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines