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.387 by root, Mon Oct 15 23:49:10 2007 UTC vs.
Revision 1.395 by root, Sat Nov 10 22:41:59 2007 UTC

162 162
163The raw value load value from the last tick. 163The raw value load value from the last tick.
164 164
165=item %cf::CFG 165=item %cf::CFG
166 166
167Configuration for the server, loaded from C</etc/crossfire/config>, or 167Configuration for the server, loaded from C</etc/deliantra-server/config>, or
168from wherever your confdir points to. 168from wherever your confdir points to.
169 169
170=item cf::wait_for_tick, cf::wait_for_tick_begin 170=item cf::wait_for_tick, cf::wait_for_tick_begin
171 171
172These are functions that inhibit the current coroutine one tick. cf::wait_for_tick_begin only 172These are functions that inhibit the current coroutine one tick. cf::wait_for_tick_begin only
406 406
407BEGIN { *async = \&Coro::async_pool } 407BEGIN { *async = \&Coro::async_pool }
408 408
409=item cf::sync_job { BLOCK } 409=item cf::sync_job { BLOCK }
410 410
411The design of Crossfire TRT requires that the main coroutine ($Coro::main) 411The design of Deliantra requires that the main coroutine ($Coro::main)
412is always able to handle events or runnable, as Crossfire TRT is only 412is always able to handle events or runnable, as Deliantra is only
413partly reentrant. Thus "blocking" it by e.g. waiting for I/O is not 413partly reentrant. Thus "blocking" it by e.g. waiting for I/O is not
414acceptable. 414acceptable.
415 415
416If it must be done, put the blocking parts into C<sync_job>. This will run 416If it must be done, put the blocking parts into C<sync_job>. This will run
417the given BLOCK in another coroutine while waiting for the result. The 417the given BLOCK in another coroutine while waiting for the result. The
662attach callbacks/event handlers (a collection of which is called an "attachment") 662attach callbacks/event handlers (a collection of which is called an "attachment")
663to it. All such attachable objects support the following methods. 663to it. All such attachable objects support the following methods.
664 664
665In the following description, CLASS can be any of C<global>, C<object> 665In the following description, CLASS can be any of C<global>, C<object>
666C<player>, C<client> or C<map> (i.e. the attachable objects in 666C<player>, C<client> or C<map> (i.e. the attachable objects in
667Crossfire TRT). 667Deliantra).
668 668
669=over 4 669=over 4
670 670
671=item $attachable->attach ($attachment, key => $value...) 671=item $attachable->attach ($attachment, key => $value...)
672 672
1081 close $fh; 1081 close $fh;
1082 1082
1083 if (@$objs) { 1083 if (@$objs) {
1084 if (my $fh = aio_open "$filename.pst~", O_WRONLY | O_CREAT, 0600) { 1084 if (my $fh = aio_open "$filename.pst~", O_WRONLY | O_CREAT, 0600) {
1085 chmod SAVE_MODE, $fh; 1085 chmod SAVE_MODE, $fh;
1086 my $data = Coro::Storable::blocking_nfreeze { version => 1, objs => $objs }; 1086 my $data = Coro::Storable::nfreeze { version => 1, objs => $objs };
1087 aio_write $fh, 0, (length $data), $data, 0; 1087 aio_write $fh, 0, (length $data), $data, 0;
1088 aio_fsync $fh if $cf::USE_FSYNC; 1088 aio_fsync $fh if $cf::USE_FSYNC;
1089 close $fh; 1089 close $fh;
1090 aio_rename "$filename.pst~", "$filename.pst"; 1090 aio_rename "$filename.pst~", "$filename.pst";
1091 } 1091 }
1122 1122
1123 unless (aio_stat "$filename.pst") { 1123 unless (aio_stat "$filename.pst") {
1124 (aio_load "$filename.pst", $av) >= 0 1124 (aio_load "$filename.pst", $av) >= 0
1125 or return; 1125 or return;
1126 1126
1127 my $st = eval { Coro::Storable::thaw $av } 1127 my $st = eval { Coro::Storable::thaw $av };
1128 || eval { my $guard = Coro::Storable::guard; Storable::thaw $av }; #d# compatibility, remove
1129 $av = $st->{objs}; 1128 $av = $st->{objs};
1130 } 1129 }
1131 1130
1132 utf8::decode (my $decname = $filename); 1131 utf8::decode (my $decname = $filename);
1133 warn sprintf "loading %s (%d,%d)\n", 1132 warn sprintf "loading %s (%d,%d)\n",
1549 1548
1550Expand crossfire pod fragments into protocol xml. 1549Expand crossfire pod fragments into protocol xml.
1551 1550
1552=cut 1551=cut
1553 1552
1553use re 'eval';
1554
1555my $group;
1556my $interior; $interior = qr{
1557 # match a pod interior sequence sans C<< >>
1558 (?:
1559 \ (.*?)\ (?{ $group = $^N })
1560 | < (??{$interior}) >
1561 )
1562}x;
1563
1554sub expand_cfpod { 1564sub expand_cfpod {
1555 ((my $self), (local $_)) = @_; 1565 my ($self, $pod) = @_;
1556 1566
1557 # escape & and < 1567 my $xml;
1558 s/&/&amp;/g;
1559 s/(?<![BIUGHT])</&lt;/g;
1560 1568
1561 # this is buggy, it needs to properly take care of nested <'s 1569 while () {
1570 if ($pod =~ /\G( (?: [^BCGHITU]+ | .(?!<) )+ )/xgcs) {
1571 $group = $1;
1562 1572
1563 1 while 1573 $group =~ s/&/&amp;/g;
1564 # replace B<>, I<>, U<> etc. 1574 $group =~ s/</&lt;/g;
1565 s/B<([^\>]*)>/<b>$1<\/b>/ 1575
1566 || s/I<([^\>]*)>/<i>$1<\/i>/ 1576 $xml .= $group;
1567 || s/U<([^\>]*)>/<u>$1<\/u>/ 1577 } elsif ($pod =~ m%\G
1568 || s/T<([^\>]*)>/<big><b>$1<\/b><\/big>/ 1578 ([BCGHITU])
1569 # replace G<male|female> tags 1579 <
1570 || s{G<([^>|]*)\|([^>]*)>}{ 1580 (?:
1571 $self->gender ? $2 : $1 1581 ([^<>]*) (?{ $group = $^N })
1572 }ge 1582 | < $interior >
1573 # replace H<hint text> 1583 )
1574 || s{H<([^\>]*)>} 1584 >
1585 %gcsx
1575 { 1586 ) {
1587 my ($code, $data) = ($1, $group);
1588
1589 if ($code eq "B") {
1590 $xml .= "<b>" . expand_cfpod ($self, $data) . "</b>";
1591 } elsif ($code eq "I") {
1592 $xml .= "<i>" . expand_cfpod ($self, $data) . "</i>";
1593 } elsif ($code eq "U") {
1594 $xml .= "<u>" . expand_cfpod ($self, $data) . "</u>";
1595 } elsif ($code eq "C") {
1596 $xml .= "<tt>" . expand_cfpod ($self, $data) . "</tt>";
1597 } elsif ($code eq "T") {
1598 $xml .= "<big><b>" . expand_cfpod ($self, $data) . "</b></big>";
1599 } elsif ($code eq "G") {
1600 my ($male, $female) = split /\|/, $data;
1601 $data = $self->gender ? $female : $male;
1602 $xml .= expand_cfpod ($self, $data);
1603 } elsif ($code eq "H") {
1576 ("<fg name=\"lightblue\">[$1 (Use hintmode to suppress hints)]</fg>", 1604 $xml .= ("<fg name=\"lightblue\">[" . expand_cfpod ($self, $data) . " (Use hintmode to suppress hints)]</fg>",
1577 "<fg name=\"lightblue\">[Hint suppressed, see hintmode]</fg>", 1605 "<fg name=\"lightblue\">[Hint suppressed, see hintmode]</fg>",
1578 "") 1606 "")
1579 [$self->{hintmode}] 1607 [$self->{hintmode}];
1608 } else {
1609 $xml .= "error processing '$code($data)' directive";
1580 }ge; 1610 }
1611 } else {
1612 if ($pod =~ /\G(.+)/) {
1613 warn "parse error while expanding $pod (at $1)";
1614 }
1615 last;
1616 }
1617 }
1581 1618
1619 for ($xml) {
1582 # create single paragraphs (very hackish) 1620 # create single paragraphs (very hackish)
1583 s/(?<=\S)\n(?=\w)/ /g; 1621 s/(?<=\S)\n(?=\w)/ /g;
1584 1622
1585 # compress some whitespace 1623 # compress some whitespace
1586 s/\s+\n/\n/g; # ws line-ends 1624 s/\s+\n/\n/g; # ws line-ends
1587 s/\n\n+/\n/g; # double lines 1625 s/\n\n+/\n/g; # double lines
1588 s/^\n+//; # beginning lines 1626 s/^\n+//; # beginning lines
1589 s/\n+$//; # ending lines 1627 s/\n+$//; # ending lines
1628 }
1590 1629
1591 $_ 1630 $xml
1592} 1631}
1632
1633no re 'eval';
1593 1634
1594sub hintmode { 1635sub hintmode {
1595 $_[0]{hintmode} = $_[1] if @_ > 1; 1636 $_[0]{hintmode} = $_[1] if @_ > 1;
1596 $_[0]{hintmode} 1637 $_[0]{hintmode}
1597} 1638}
2667the message, with C<log> being the default. If C<$color> is negative, suppress 2708the message, with C<log> being the default. If C<$color> is negative, suppress
2668the message unless the client supports the msg packet. 2709the message unless the client supports the msg packet.
2669 2710
2670=cut 2711=cut
2671 2712
2713# non-persistent channels (usually the info channel)
2672our %CHANNEL = ( 2714our %CHANNEL = (
2673 "c/identify" => { 2715 "c/identify" => {
2674 id => "infobox", 2716 id => "infobox",
2675 title => "Identify", 2717 title => "Identify",
2676 reply => undef, 2718 reply => undef,
2680 id => "infobox", 2722 id => "infobox",
2681 title => "Examine", 2723 title => "Examine",
2682 reply => undef, 2724 reply => undef,
2683 tooltip => "Signs and other items you examined", 2725 tooltip => "Signs and other items you examined",
2684 }, 2726 },
2727 "c/book" => {
2728 id => "infobox",
2729 title => "Book",
2730 reply => undef,
2731 tooltip => "The contents of a note or book",
2732 },
2685 "c/lookat" => { 2733 "c/lookat" => {
2686 id => "infobox", 2734 id => "infobox",
2687 title => "Look", 2735 title => "Look",
2688 reply => undef, 2736 reply => undef,
2689 tooltip => "What you saw there", 2737 tooltip => "What you saw there",
2738 },
2739 "c/who" => {
2740 id => "infobox",
2741 title => "Players",
2742 reply => undef,
2743 tooltip => "Shows players who are currently online",
2744 },
2745 "c/body" => {
2746 id => "infobox",
2747 title => "Body Parts",
2748 reply => undef,
2749 tooltip => "Shows which body parts you posess and are available",
2750 },
2751 "c/uptime" => {
2752 id => "infobox",
2753 title => "Uptime",
2754 reply => undef,
2755 tooltip => "How long the server has been running since last restart",
2756 },
2757 "c/mapinfo" => {
2758 id => "infobox",
2759 title => "Map Info",
2760 reply => undef,
2761 tooltip => "Information related to the maps",
2690 }, 2762 },
2691); 2763);
2692 2764
2693sub cf::client::send_msg { 2765sub cf::client::send_msg {
2694 my ($self, $channel, $msg, $color, @extra) = @_; 2766 my ($self, $channel, $msg, $color, @extra) = @_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines