ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
Revision: 1.106
Committed: Sun Dec 31 17:29:22 2006 UTC (17 years, 4 months ago) by root
Branch: MAIN
Changes since 1.105: +31 -8 lines
Log Message:
exit cleanly when reload fails, after all, we did an emergency_save

File Contents

# User Rev Content
1 root 1.1 package cf;
2    
3 root 1.96 use utf8;
4     use strict;
5    
6 root 1.1 use Symbol;
7     use List::Util;
8 root 1.6 use Storable;
9 root 1.23 use Opcode;
10     use Safe;
11     use Safe::Hole;
12 root 1.19
13 root 1.103 use Coro 3.3;
14 root 1.96 use Coro::Event;
15     use Coro::Timer;
16     use Coro::Signal;
17     use Coro::Semaphore;
18 root 1.105 use Coro::AIO;
19 root 1.96
20 root 1.105 use Fcntl;
21     use IO::AIO 2.31 ();
22 root 1.72 use YAML::Syck ();
23 root 1.32 use Time::HiRes;
24 root 1.96
25     use Event; $Event::Eval = 1; # no idea why this is required, but it is
26 root 1.1
27 root 1.72 # work around bug in YAML::Syck - bad news for perl6, will it be as broken wrt. unicode?
28     $YAML::Syck::ImplicitUnicode = 1;
29    
30 root 1.103 $Coro::main->prio (2); # run main coroutine ("the server") with very high priority
31 root 1.1
32 root 1.87 sub WF_AUTOCANCEL () { 1 } # automatically cancel this watcher on reload
33    
34 root 1.85 our %COMMAND = ();
35     our %COMMAND_TIME = ();
36     our %EXTCMD = ();
37    
38 root 1.1 our @EVENT;
39 root 1.88 our $LIBDIR = datadir . "/ext";
40 root 1.1
41 root 1.35 our $TICK = MAX_TIME * 1e-6;
42     our $TICK_WATCHER;
43     our $NEXT_TICK;
44 root 1.103 our $NOW;
45 root 1.35
46 root 1.70 our %CFG;
47    
48 root 1.84 our $UPTIME; $UPTIME ||= time;
49 root 1.103 our $RUNTIME;
50    
51     our %MAP; # all maps
52     our $LINK_MAP; # the special {link} map
53     our $FREEZE;
54    
55     binmode STDOUT;
56     binmode STDERR;
57    
58     # read virtual server time, if available
59     unless ($RUNTIME || !-e cf::localdir . "/runtime") {
60     open my $fh, "<", cf::localdir . "/runtime"
61     or die "unable to read runtime file: $!";
62     $RUNTIME = <$fh> + 0.;
63     }
64    
65     mkdir cf::localdir;
66     mkdir cf::localdir . "/" . cf::playerdir;
67     mkdir cf::localdir . "/" . cf::tmpdir;
68     mkdir cf::localdir . "/" . cf::uniquedir;
69    
70     our %EXT_CORO;
71 root 1.76
72 root 1.70 #############################################################################
73    
74     =head2 GLOBAL VARIABLES
75    
76     =over 4
77    
78 root 1.83 =item $cf::UPTIME
79    
80     The timestamp of the server start (so not actually an uptime).
81    
82 root 1.103 =item $cf::RUNTIME
83    
84     The time this server has run, starts at 0 and is increased by $cf::TICK on
85     every server tick.
86    
87 root 1.70 =item $cf::LIBDIR
88    
89     The perl library directory, where extensions and cf-specific modules can
90     be found. It will be added to C<@INC> automatically.
91    
92 root 1.103 =item $cf::NOW
93    
94     The time of the last (current) server tick.
95    
96 root 1.70 =item $cf::TICK
97    
98     The interval between server ticks, in seconds.
99    
100     =item %cf::CFG
101    
102     Configuration for the server, loaded from C</etc/crossfire/config>, or
103     from wherever your confdir points to.
104    
105     =back
106    
107     =cut
108    
109 root 1.1 BEGIN {
110     *CORE::GLOBAL::warn = sub {
111     my $msg = join "", @_;
112 root 1.103 utf8::encode $msg;
113    
114 root 1.1 $msg .= "\n"
115     unless $msg =~ /\n$/;
116    
117     LOG llevError, "cfperl: $msg";
118     };
119     }
120    
121 root 1.93 @safe::cf::global::ISA = @cf::global::ISA = 'cf::attachable';
122     @safe::cf::object::ISA = @cf::object::ISA = 'cf::attachable';
123     @safe::cf::player::ISA = @cf::player::ISA = 'cf::attachable';
124     @safe::cf::client::ISA = @cf::client::ISA = 'cf::attachable';
125     @safe::cf::map::ISA = @cf::map::ISA = 'cf::attachable';
126 root 1.41 @safe::cf::object::player::ISA = @cf::object::player::ISA = 'cf::object';
127 root 1.25
128 root 1.41 # we bless all objects into (empty) derived classes to force a method lookup
129 root 1.25 # within the Safe compartment.
130 root 1.86 for my $pkg (qw(
131 root 1.100 cf::global cf::attachable
132 root 1.86 cf::object cf::object::player
133 root 1.89 cf::client cf::player
134 root 1.86 cf::arch cf::living
135     cf::map cf::party cf::region
136     )) {
137 root 1.25 no strict 'refs';
138 root 1.41 @{"safe::$pkg\::wrap::ISA"} = @{"$pkg\::wrap::ISA"} = $pkg;
139 root 1.25 }
140 root 1.1
141 root 1.18 $Event::DIED = sub {
142     warn "error in event callback: @_";
143     };
144    
145 root 1.5 my %ext_pkg;
146 root 1.1 my @exts;
147     my @hook;
148    
149 root 1.70 =head2 UTILITY FUNCTIONS
150    
151     =over 4
152    
153     =cut
154 root 1.44
155 root 1.45 use JSON::Syck (); # TODO# replace by JSON::PC once working
156 root 1.44
157 root 1.70 =item $ref = cf::from_json $json
158    
159     Converts a JSON string into the corresponding perl data structure.
160    
161     =cut
162    
163 root 1.45 sub from_json($) {
164     $JSON::Syck::ImplicitUnicode = 1; # work around JSON::Syck bugs
165     JSON::Syck::Load $_[0]
166 root 1.44 }
167    
168 root 1.70 =item $json = cf::to_json $ref
169    
170     Converts a perl data structure into its JSON representation.
171    
172     =cut
173    
174 root 1.45 sub to_json($) {
175     $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs
176     JSON::Syck::Dump $_[0]
177 root 1.44 }
178    
179 root 1.106 =item cf::sync_job { BLOCK }
180    
181     The design of crossfire+ requires that the main coro ($Coro::main) is
182     always able to handle events or runnable, as crossfire+ is only partly
183     reentrant. Thus "blocking" it by e.g. waiting for I/O is not acceptable.
184    
185     If it must be done, put the blocking parts into C<sync_job>. This will run
186     the given BLOCK in another coroutine while waiting for the result. The
187     server will be frozen during this time, so the block should either finish
188     fast or be very important.
189    
190     =cut
191    
192 root 1.105 sub sync_job(&) {
193     my ($job) = @_;
194    
195     my $busy = 1;
196     my @res;
197    
198 root 1.106 # TODO: use suspend/resume instead
199 root 1.105 local $FREEZE = 1;
200    
201     my $coro = Coro::async {
202     @res = eval { $job->() };
203     warn $@ if $@;
204     undef $busy;
205     };
206    
207     if ($Coro::current == $Coro::main) {
208     $coro->prio (Coro::PRIO_MAX);
209     while ($busy) {
210     Coro::cede_notself;
211     Event::one_event unless Coro::nready;
212     }
213     } else {
214     $coro->join;
215     }
216    
217     wantarray ? @res : $res[0]
218     }
219    
220 root 1.103 =item $coro = cf::coro { BLOCK }
221    
222     Creates and returns a new coro. This coro is automcatially being canceled
223     when the extension calling this is being unloaded.
224    
225     =cut
226    
227     sub coro(&) {
228     my $cb = shift;
229    
230     my $coro; $coro = async {
231     eval {
232     $cb->();
233     };
234     warn $@ if $@;
235     };
236    
237     $coro->on_destroy (sub {
238     delete $EXT_CORO{$coro+0};
239     });
240     $EXT_CORO{$coro+0} = $coro;
241    
242     $coro
243     }
244    
245 root 1.70 =back
246    
247 root 1.71 =cut
248    
249 root 1.44 #############################################################################
250 root 1.39
251 root 1.93 =head2 ATTACHABLE OBJECTS
252    
253 root 1.94 Many objects in crossfire are so-called attachable objects. That means you can
254     attach callbacks/event handlers (a collection of which is called an "attachment")
255     to it. All such attachable objects support the following methods.
256    
257     In the following description, CLASS can be any of C<global>, C<object>
258     C<player>, C<client> or C<map> (i.e. the attachable objects in
259     crossfire+).
260 root 1.55
261     =over 4
262    
263 root 1.94 =item $attachable->attach ($attachment, key => $value...)
264    
265     =item $attachable->detach ($attachment)
266    
267     Attach/detach a pre-registered attachment to a specific object and give it
268     the specified key/value pairs as arguments.
269    
270     Example, attach a minesweeper attachment to the given object, making it a
271     10x10 minesweeper game:
272 root 1.46
273 root 1.94 $obj->attach (minesweeper => width => 10, height => 10);
274 root 1.53
275 root 1.93 =item $bool = $attachable->attached ($name)
276 root 1.46
277 root 1.93 Checks wether the named attachment is currently attached to the object.
278 root 1.46
279 root 1.94 =item cf::CLASS->attach ...
280 root 1.46
281 root 1.94 =item cf::CLASS->detach ...
282 root 1.92
283 root 1.94 Define an anonymous attachment and attach it to all objects of the given
284     CLASS. See the next function for an explanation of its arguments.
285 root 1.92
286 root 1.93 You can attach to global events by using the C<cf::global> class.
287 root 1.92
288 root 1.94 Example, log all player logins:
289    
290     cf::player->attach (
291     on_login => sub {
292     my ($pl) = @_;
293     ...
294     },
295     );
296    
297     Example, attach to the jeweler skill:
298    
299     cf::object->attach (
300     type => cf::SKILL,
301     subtype => cf::SK_JEWELER,
302     on_use_skill => sub {
303     my ($sk, $ob, $part, $dir, $msg) = @_;
304     ...
305     },
306     );
307    
308     =item cf::CLASS::attachment $name, ...
309    
310     Register an attachment by C<$name> through which attachable objects of the
311     given CLASS can refer to this attachment.
312    
313     Some classes such as crossfire maps and objects can specify attachments
314     that are attached at load/instantiate time, thus the need for a name.
315    
316     These calls expect any number of the following handler/hook descriptions:
317 root 1.46
318     =over 4
319    
320     =item prio => $number
321    
322     Set the priority for all following handlers/hooks (unless overwritten
323     by another C<prio> setting). Lower priority handlers get executed
324     earlier. The default priority is C<0>, and many built-in handlers are
325     registered at priority C<-1000>, so lower priorities should not be used
326     unless you know what you are doing.
327    
328 root 1.93 =item type => $type
329    
330     (Only for C<< cf::object->attach >> calls), limits the attachment to the
331     given type of objects only (the additional parameter C<subtype> can be
332     used to further limit to the given subtype).
333    
334 root 1.46 =item on_I<event> => \&cb
335    
336     Call the given code reference whenever the named event happens (event is
337     something like C<instantiate>, C<apply>, C<use_skill> and so on, and which
338     handlers are recognised generally depends on the type of object these
339     handlers attach to).
340    
341     See F<include/eventinc.h> for the full list of events supported, and their
342     class.
343    
344     =item package => package::
345    
346     Look for sub functions of the name C<< on_I<event> >> in the given
347     package and register them. Only handlers for eevents supported by the
348     object/class are recognised.
349    
350     =back
351    
352 root 1.94 Example, define an attachment called "sockpuppet" that calls the given
353     event handler when a monster attacks:
354    
355     cf::object::attachment sockpuppet =>
356     on_skill_attack => sub {
357     my ($self, $victim) = @_;
358     ...
359     }
360     }
361    
362 root 1.96 =item $attachable->valid
363    
364     Just because you have a perl object does not mean that the corresponding
365     C-level object still exists. If you try to access an object that has no
366     valid C counterpart anymore you get an exception at runtime. This method
367     can be used to test for existence of the C object part without causing an
368     exception.
369    
370 root 1.39 =cut
371    
372 root 1.40 # the following variables are defined in .xs and must not be re-created
373 root 1.100 our @CB_GLOBAL = (); # registry for all global events
374     our @CB_ATTACHABLE = (); # registry for all attachables
375     our @CB_OBJECT = (); # all objects (should not be used except in emergency)
376     our @CB_PLAYER = ();
377     our @CB_CLIENT = ();
378     our @CB_TYPE = (); # registry for type (cf-object class) based events
379     our @CB_MAP = ();
380 root 1.39
381 root 1.45 my %attachment;
382    
383 root 1.93 sub _attach_cb($$$$) {
384     my ($registry, $event, $prio, $cb) = @_;
385 root 1.39
386     use sort 'stable';
387    
388     $cb = [$prio, $cb];
389    
390     @{$registry->[$event]} = sort
391     { $a->[0] cmp $b->[0] }
392     @{$registry->[$event] || []}, $cb;
393     }
394    
395 root 1.100 # hack
396     my %attachable_klass = map +($_ => 1), KLASS_OBJECT, KLASS_CLIENT, KLASS_PLAYER, KLASS_MAP;
397    
398 root 1.39 # attach handles attaching event callbacks
399     # the only thing the caller has to do is pass the correct
400     # registry (== where the callback attaches to).
401 root 1.93 sub _attach {
402 root 1.45 my ($registry, $klass, @arg) = @_;
403 root 1.39
404 root 1.93 my $object_type;
405 root 1.39 my $prio = 0;
406     my %cb_id = map +("on_" . lc $EVENT[$_][0], $_) , grep $EVENT[$_][1] == $klass, 0 .. $#EVENT;
407    
408 root 1.100 #TODO: get rid of this hack
409     if ($attachable_klass{$klass}) {
410     %cb_id = (%cb_id, map +("on_" . lc $EVENT[$_][0], $_) , grep $EVENT[$_][1] == KLASS_ATTACHABLE, 0 .. $#EVENT);
411     }
412    
413 root 1.45 while (@arg) {
414     my $type = shift @arg;
415 root 1.39
416     if ($type eq "prio") {
417 root 1.45 $prio = shift @arg;
418 root 1.39
419 root 1.93 } elsif ($type eq "type") {
420     $object_type = shift @arg;
421     $registry = $CB_TYPE[$object_type] ||= [];
422    
423     } elsif ($type eq "subtype") {
424     defined $object_type or Carp::croak "subtype specified without type";
425     my $object_subtype = shift @arg;
426     $registry = $CB_TYPE[$object_type + $object_subtype * NUM_SUBTYPES] ||= [];
427    
428 root 1.39 } elsif ($type eq "package") {
429 root 1.45 my $pkg = shift @arg;
430 root 1.39
431     while (my ($name, $id) = each %cb_id) {
432     if (my $cb = $pkg->can ($name)) {
433 root 1.93 _attach_cb $registry, $id, $prio, $cb;
434 root 1.39 }
435     }
436    
437     } elsif (exists $cb_id{$type}) {
438 root 1.93 _attach_cb $registry, $cb_id{$type}, $prio, shift @arg;
439 root 1.39
440     } elsif (ref $type) {
441     warn "attaching objects not supported, ignoring.\n";
442    
443     } else {
444 root 1.45 shift @arg;
445 root 1.39 warn "attach argument '$type' not supported, ignoring.\n";
446     }
447     }
448     }
449    
450 root 1.93 sub _object_attach {
451 root 1.48 my ($obj, $name, %arg) = @_;
452 root 1.46
453 root 1.55 return if exists $obj->{_attachment}{$name};
454    
455 root 1.46 if (my $attach = $attachment{$name}) {
456     my $registry = $obj->registry;
457    
458 root 1.47 for (@$attach) {
459     my ($klass, @attach) = @$_;
460 root 1.93 _attach $registry, $klass, @attach;
461 root 1.47 }
462 root 1.46
463 root 1.48 $obj->{$name} = \%arg;
464 root 1.46 } else {
465     warn "object uses attachment '$name' that is not available, postponing.\n";
466     }
467    
468 root 1.50 $obj->{_attachment}{$name} = undef;
469 root 1.46 }
470    
471 root 1.93 sub cf::attachable::attach {
472     if (ref $_[0]) {
473     _object_attach @_;
474     } else {
475     _attach shift->_attach_registry, @_;
476     }
477 root 1.55 };
478 root 1.46
479 root 1.54 # all those should be optimised
480 root 1.93 sub cf::attachable::detach {
481 root 1.54 my ($obj, $name) = @_;
482 root 1.46
483 root 1.93 if (ref $obj) {
484     delete $obj->{_attachment}{$name};
485     reattach ($obj);
486     } else {
487     Carp::croak "cannot, currently, detach class attachments";
488     }
489 root 1.55 };
490    
491 root 1.93 sub cf::attachable::attached {
492 root 1.55 my ($obj, $name) = @_;
493    
494     exists $obj->{_attachment}{$name}
495 root 1.39 }
496    
497 root 1.100 for my $klass (qw(ATTACHABLE GLOBAL OBJECT PLAYER CLIENT MAP)) {
498 root 1.93 eval "#line " . __LINE__ . " 'cf.pm'
499     sub cf::\L$klass\E::_attach_registry {
500     (\\\@CB_$klass, KLASS_$klass)
501     }
502 root 1.45
503 root 1.93 sub cf::\L$klass\E::attachment {
504     my \$name = shift;
505 root 1.39
506 root 1.93 \$attachment{\$name} = [[KLASS_$klass, \@_]];
507     }
508     ";
509     die if $@;
510 root 1.52 }
511    
512 root 1.39 our $override;
513 root 1.45 our @invoke_results = (); # referenced from .xs code. TODO: play tricks with reify and mortals?
514 root 1.39
515 root 1.45 sub override {
516     $override = 1;
517     @invoke_results = ();
518 root 1.39 }
519    
520 root 1.45 sub do_invoke {
521 root 1.39 my $event = shift;
522 root 1.40 my $callbacks = shift;
523 root 1.39
524 root 1.45 @invoke_results = ();
525    
526 root 1.39 local $override;
527    
528 root 1.40 for (@$callbacks) {
529 root 1.39 eval { &{$_->[1]} };
530    
531     if ($@) {
532     warn "$@";
533 root 1.64 warn "... while processing $EVENT[$event][0](@_) event, skipping processing altogether.\n";
534 root 1.39 override;
535     }
536    
537     return 1 if $override;
538     }
539    
540     0
541     }
542    
543 root 1.96 =item $bool = cf::global::invoke (EVENT_CLASS_XXX, ...)
544 root 1.55
545 root 1.96 =item $bool = $attachable->invoke (EVENT_CLASS_XXX, ...)
546 root 1.55
547 root 1.96 Generate an object-specific event with the given arguments.
548 root 1.55
549 root 1.96 This API is preliminary (most likely, the EVENT_CLASS_xxx prefix will be
550 root 1.55 removed in future versions), and there is no public API to access override
551     results (if you must, access C<@cf::invoke_results> directly).
552    
553     =back
554    
555 root 1.71 =cut
556    
557 root 1.70 #############################################################################
558 root 1.45 # object support
559    
560 root 1.102 sub reattach {
561     # basically do the same as instantiate, without calling instantiate
562     my ($obj) = @_;
563    
564     my $registry = $obj->registry;
565    
566     @$registry = ();
567    
568     delete $obj->{_attachment} unless scalar keys %{ $obj->{_attachment} || {} };
569    
570     for my $name (keys %{ $obj->{_attachment} || {} }) {
571     if (my $attach = $attachment{$name}) {
572     for (@$attach) {
573     my ($klass, @attach) = @$_;
574     _attach $registry, $klass, @attach;
575     }
576     } else {
577     warn "object uses attachment '$name' that is not available, postponing.\n";
578     }
579     }
580     }
581    
582 root 1.100 cf::attachable->attach (
583     prio => -1000000,
584     on_instantiate => sub {
585     my ($obj, $data) = @_;
586 root 1.45
587 root 1.100 $data = from_json $data;
588 root 1.45
589 root 1.100 for (@$data) {
590     my ($name, $args) = @$_;
591 root 1.49
592 root 1.100 $obj->attach ($name, %{$args || {} });
593     }
594     },
595 root 1.102 on_reattach => \&reattach,
596 root 1.100 on_clone => sub {
597     my ($src, $dst) = @_;
598    
599     @{$dst->registry} = @{$src->registry};
600    
601     %$dst = %$src;
602    
603     %{$dst->{_attachment}} = %{$src->{_attachment}}
604     if exists $src->{_attachment};
605     },
606     );
607 root 1.45
608 root 1.46 sub object_freezer_save {
609 root 1.59 my ($filename, $rdata, $objs) = @_;
610 root 1.46
611 root 1.105 sync_job {
612     if (length $$rdata) {
613     warn sprintf "saving %s (%d,%d)\n",
614     $filename, length $$rdata, scalar @$objs;
615 root 1.60
616 root 1.105 if (my $fh = aio_open "$filename~", O_WRONLY | O_CREAT, 0600) {
617 root 1.60 chmod SAVE_MODE, $fh;
618 root 1.105 aio_write $fh, 0, (length $$rdata), $$rdata, 0;
619     aio_fsync $fh;
620 root 1.60 close $fh;
621 root 1.105
622     if (@$objs) {
623     if (my $fh = aio_open "$filename.pst~", O_WRONLY | O_CREAT, 0600) {
624     chmod SAVE_MODE, $fh;
625     my $data = Storable::nfreeze { version => 1, objs => $objs };
626     aio_write $fh, 0, (length $data), $data, 0;
627     aio_fsync $fh;
628     close $fh;
629     aio_rename "$filename.pst~", "$filename.pst";
630     }
631     } else {
632     aio_unlink "$filename.pst";
633     }
634    
635     aio_rename "$filename~", $filename;
636 root 1.60 } else {
637 root 1.105 warn "FATAL: $filename~: $!\n";
638 root 1.60 }
639 root 1.59 } else {
640 root 1.105 aio_unlink $filename;
641     aio_unlink "$filename.pst";
642 root 1.59 }
643 root 1.45 }
644     }
645    
646 root 1.80 sub object_freezer_as_string {
647     my ($rdata, $objs) = @_;
648    
649     use Data::Dumper;
650    
651 root 1.81 $$rdata . Dumper $objs
652 root 1.80 }
653    
654 root 1.46 sub object_thawer_load {
655     my ($filename) = @_;
656    
657 root 1.105 my ($data, $av);
658 root 1.61
659 root 1.105 (aio_load $filename, $data) >= 0
660     or return;
661 root 1.61
662 root 1.105 unless (aio_stat "$filename.pst") {
663     (aio_load "$filename.pst", $av) >= 0
664     or return;
665     $av = eval { (Storable::thaw <$av>)->{objs} };
666 root 1.61 }
667 root 1.45
668 root 1.105 return ($data, $av);
669 root 1.45 }
670    
671     #############################################################################
672 root 1.85 # command handling &c
673 root 1.39
674 root 1.85 =item cf::register_command $name => \&callback($ob,$args);
675 root 1.1
676 root 1.85 Register a callback for execution when the client sends the user command
677     $name.
678 root 1.5
679 root 1.85 =cut
680 root 1.5
681 root 1.85 sub register_command {
682     my ($name, $cb) = @_;
683 root 1.5
684 root 1.85 my $caller = caller;
685     #warn "registering command '$name/$time' to '$caller'";
686 root 1.1
687 root 1.85 push @{ $COMMAND{$name} }, [$caller, $cb];
688 root 1.1 }
689    
690 root 1.85 =item cf::register_extcmd $name => \&callback($pl,$packet);
691 root 1.1
692 root 1.85 Register a callbackf ro execution when the client sends an extcmd packet.
693 root 1.1
694 root 1.85 If the callback returns something, it is sent back as if reply was being
695     called.
696 root 1.1
697 root 1.85 =cut
698 root 1.1
699 root 1.16 sub register_extcmd {
700     my ($name, $cb) = @_;
701    
702     my $caller = caller;
703     #warn "registering extcmd '$name' to '$caller'";
704    
705 root 1.85 $EXTCMD{$name} = [$cb, $caller];
706 root 1.16 }
707    
708 root 1.93 cf::player->attach (
709 root 1.85 on_command => sub {
710     my ($pl, $name, $params) = @_;
711    
712     my $cb = $COMMAND{$name}
713     or return;
714    
715     for my $cmd (@$cb) {
716     $cmd->[1]->($pl->ob, $params);
717     }
718    
719     cf::override;
720     },
721     on_extcmd => sub {
722     my ($pl, $buf) = @_;
723    
724     my $msg = eval { from_json $buf };
725    
726     if (ref $msg) {
727     if (my $cb = $EXTCMD{$msg->{msgtype}}) {
728     if (my %reply = $cb->[0]->($pl, $msg)) {
729     $pl->ext_reply ($msg->{msgid}, %reply);
730     }
731     }
732     } else {
733     warn "player " . ($pl->ob->name) . " sent unparseable ext message: <$buf>\n";
734     }
735    
736     cf::override;
737     },
738 root 1.93 );
739 root 1.85
740 root 1.6 sub register {
741     my ($base, $pkg) = @_;
742    
743 root 1.45 #TODO
744 root 1.6 }
745    
746 root 1.1 sub load_extension {
747     my ($path) = @_;
748    
749     $path =~ /([^\/\\]+)\.ext$/ or die "$path";
750 root 1.5 my $base = $1;
751 root 1.1 my $pkg = $1;
752     $pkg =~ s/[^[:word:]]/_/g;
753 root 1.41 $pkg = "ext::$pkg";
754 root 1.1
755     warn "loading '$path' into '$pkg'\n";
756    
757     open my $fh, "<:utf8", $path
758     or die "$path: $!";
759    
760     my $source =
761     "package $pkg; use strict; use utf8;\n"
762     . "#line 1 \"$path\"\n{\n"
763     . (do { local $/; <$fh> })
764     . "\n};\n1";
765    
766     eval $source
767 root 1.82 or die $@ ? "$path: $@\n"
768     : "extension disabled.\n";
769 root 1.1
770     push @exts, $pkg;
771 root 1.5 $ext_pkg{$base} = $pkg;
772 root 1.1
773 root 1.6 # no strict 'refs';
774 root 1.23 # @{"$pkg\::ISA"} = ext::;
775 root 1.1
776 root 1.6 register $base, $pkg;
777 root 1.1 }
778    
779     sub unload_extension {
780     my ($pkg) = @_;
781    
782     warn "removing extension $pkg\n";
783    
784     # remove hooks
785 root 1.45 #TODO
786     # for my $idx (0 .. $#PLUGIN_EVENT) {
787     # delete $hook[$idx]{$pkg};
788     # }
789 root 1.1
790     # remove commands
791 root 1.85 for my $name (keys %COMMAND) {
792     my @cb = grep $_->[0] ne $pkg, @{ $COMMAND{$name} };
793 root 1.1
794     if (@cb) {
795 root 1.85 $COMMAND{$name} = \@cb;
796 root 1.1 } else {
797 root 1.85 delete $COMMAND{$name};
798 root 1.1 }
799     }
800    
801 root 1.15 # remove extcmds
802 root 1.85 for my $name (grep $EXTCMD{$_}[1] eq $pkg, keys %EXTCMD) {
803     delete $EXTCMD{$name};
804 root 1.15 }
805    
806 root 1.43 if (my $cb = $pkg->can ("unload")) {
807 elmex 1.31 eval {
808     $cb->($pkg);
809     1
810     } or warn "$pkg unloaded, but with errors: $@";
811     }
812    
813 root 1.1 Symbol::delete_package $pkg;
814     }
815    
816     sub load_extensions {
817     for my $ext (<$LIBDIR/*.ext>) {
818 root 1.3 next unless -r $ext;
819 root 1.2 eval {
820     load_extension $ext;
821     1
822     } or warn "$ext not loaded: $@";
823 root 1.1 }
824     }
825    
826 root 1.8 #############################################################################
827     # load/save/clean perl data associated with a map
828    
829 root 1.39 *cf::mapsupport::on_clean = sub {
830 root 1.13 my ($map) = @_;
831 root 1.7
832     my $path = $map->tmpname;
833     defined $path or return;
834    
835 root 1.46 unlink "$path.pst";
836 root 1.7 };
837    
838 root 1.93 cf::map->attach (prio => -10000, package => cf::mapsupport::);
839 root 1.39
840 root 1.8 #############################################################################
841     # load/save perl data associated with player->ob objects
842    
843 root 1.33 sub all_objects(@) {
844     @_, map all_objects ($_->inv), @_
845     }
846    
847 root 1.60 # TODO: compatibility cruft, remove when no longer needed
848 root 1.93 cf::player->attach (
849 root 1.39 on_load => sub {
850     my ($pl, $path) = @_;
851    
852     for my $o (all_objects $pl->ob) {
853     if (my $value = $o->get_ob_key_value ("_perl_data")) {
854     $o->set_ob_key_value ("_perl_data");
855 root 1.8
856 root 1.39 %$o = %{ Storable::thaw pack "H*", $value };
857     }
858 root 1.11 }
859 root 1.39 },
860 root 1.93 );
861 root 1.6
862 root 1.22 #############################################################################
863 root 1.70
864     =head2 CORE EXTENSIONS
865    
866     Functions and methods that extend core crossfire objects.
867    
868 root 1.95 =head3 cf::player
869    
870 root 1.70 =over 4
871 root 1.22
872 root 1.23 =item cf::player::exists $login
873    
874     Returns true when the given account exists.
875    
876     =cut
877    
878     sub cf::player::exists($) {
879     cf::player::find $_[0]
880     or -f sprintf "%s/%s/%s/%s.pl", cf::localdir, cf::playerdir, ($_[0]) x 2;
881     }
882    
883 root 1.95 =item $player->ext_reply ($msgid, $msgtype, %msg)
884    
885     Sends an ext reply to the player.
886    
887     =cut
888    
889     sub cf::player::ext_reply($$$%) {
890     my ($self, $id, %msg) = @_;
891    
892     $msg{msgid} = $id;
893    
894     $self->send ("ext " . to_json \%msg);
895     }
896    
897     =back
898    
899     =head3 cf::object::player
900    
901     =over 4
902    
903 root 1.79 =item $player_object->reply ($npc, $msg[, $flags])
904 root 1.28
905     Sends a message to the player, as if the npc C<$npc> replied. C<$npc>
906     can be C<undef>. Does the right thing when the player is currently in a
907     dialogue with the given NPC character.
908    
909     =cut
910    
911 root 1.22 # rough implementation of a future "reply" method that works
912     # with dialog boxes.
913 root 1.95 #TODO: the first argument must go, split into a $npc->reply_to ( method
914 root 1.23 sub cf::object::player::reply($$$;$) {
915     my ($self, $npc, $msg, $flags) = @_;
916    
917     $flags = cf::NDI_BROWN | cf::NDI_UNIQUE unless @_ >= 4;
918 root 1.22
919 root 1.24 if ($self->{record_replies}) {
920     push @{ $self->{record_replies} }, [$npc, $msg, $flags];
921     } else {
922     $msg = $npc->name . " says: $msg" if $npc;
923     $self->message ($msg, $flags);
924     }
925 root 1.22 }
926    
927 root 1.79 =item $player_object->may ("access")
928    
929     Returns wether the given player is authorized to access resource "access"
930     (e.g. "command_wizcast").
931    
932     =cut
933    
934     sub cf::object::player::may {
935     my ($self, $access) = @_;
936    
937     $self->flag (cf::FLAG_WIZ) ||
938     (ref $cf::CFG{"may_$access"}
939     ? scalar grep $self->name eq $_, @{$cf::CFG{"may_$access"}}
940     : $cf::CFG{"may_$access"})
941     }
942 root 1.70
943 root 1.95 =head3 cf::client
944    
945     =over 4
946    
947     =item $client->send_drawinfo ($text, $flags)
948    
949     Sends a drawinfo packet to the client. Circumvents output buffering so
950     should not be used under normal circumstances.
951    
952 root 1.70 =cut
953    
954 root 1.95 sub cf::client::send_drawinfo {
955     my ($self, $text, $flags) = @_;
956    
957     utf8::encode $text;
958     $self->send_packet (sprintf "drawinfo %d %s", $flags, $text);
959     }
960    
961    
962     =item $success = $client->query ($flags, "text", \&cb)
963    
964     Queues a query to the client, calling the given callback with
965     the reply text on a reply. flags can be C<cf::CS_QUERY_YESNO>,
966     C<cf::CS_QUERY_SINGLECHAR> or C<cf::CS_QUERY_HIDEINPUT> or C<0>.
967    
968     Queries can fail, so check the return code. Or don't, as queries will become
969     reliable at some point in the future.
970    
971     =cut
972    
973     sub cf::client::query {
974     my ($self, $flags, $text, $cb) = @_;
975    
976     return unless $self->state == ST_PLAYING
977     || $self->state == ST_SETUP
978     || $self->state == ST_CUSTOM;
979    
980     $self->state (ST_CUSTOM);
981    
982     utf8::encode $text;
983     push @{ $self->{query_queue} }, [(sprintf "query %d %s", $flags, $text), $cb];
984    
985     $self->send_packet ($self->{query_queue}[0][0])
986     if @{ $self->{query_queue} } == 1;
987     }
988    
989     cf::client->attach (
990     on_reply => sub {
991     my ($ns, $msg) = @_;
992    
993     # this weird shuffling is so that direct followup queries
994     # get handled first
995     my $queue = delete $ns->{query_queue};
996    
997     (shift @$queue)->[1]->($msg);
998    
999     push @{ $ns->{query_queue} }, @$queue;
1000    
1001     if (@{ $ns->{query_queue} } == @$queue) {
1002     if (@$queue) {
1003     $ns->send_packet ($ns->{query_queue}[0][0]);
1004     } else {
1005 root 1.98 $ns->state (ST_PLAYING) if $ns->state == ST_CUSTOM;
1006 root 1.95 }
1007     }
1008     },
1009     );
1010    
1011 root 1.96 =item $client->coro (\&cb)
1012    
1013     Create a new coroutine, running the specified callback. The coroutine will
1014     be automatically cancelled when the client gets destroyed (e.g. on logout,
1015     or loss of connection).
1016    
1017     =cut
1018    
1019     sub cf::client::coro {
1020     my ($self, $cb) = @_;
1021    
1022     my $coro; $coro = async {
1023     eval {
1024     $cb->();
1025     };
1026     warn $@ if $@;
1027 root 1.103 };
1028    
1029     $coro->on_destroy (sub {
1030 root 1.96 delete $self->{_coro}{$coro+0};
1031 root 1.103 });
1032 root 1.96
1033     $self->{_coro}{$coro+0} = $coro;
1034 root 1.103
1035     $coro
1036 root 1.96 }
1037    
1038     cf::client->attach (
1039     on_destroy => sub {
1040     my ($ns) = @_;
1041    
1042 root 1.97 $_->cancel for values %{ (delete $ns->{_coro}) || {} };
1043 root 1.96 },
1044     );
1045    
1046 root 1.95 =back
1047    
1048 root 1.70
1049     =head2 SAFE SCRIPTING
1050    
1051     Functions that provide a safe environment to compile and execute
1052     snippets of perl code without them endangering the safety of the server
1053     itself. Looping constructs, I/O operators and other built-in functionality
1054     is not available in the safe scripting environment, and the number of
1055 root 1.79 functions and methods that can be called is greatly reduced.
1056 root 1.70
1057     =cut
1058 root 1.23
1059 root 1.42 our $safe = new Safe "safe";
1060 root 1.23 our $safe_hole = new Safe::Hole;
1061    
1062     $SIG{FPE} = 'IGNORE';
1063    
1064     $safe->permit_only (Opcode::opset qw(:base_core :base_mem :base_orig :base_math sort time));
1065    
1066 root 1.25 # here we export the classes and methods available to script code
1067    
1068 root 1.70 =pod
1069    
1070     The following fucntions and emthods are available within a safe environment:
1071    
1072 elmex 1.91 cf::object contr pay_amount pay_player map
1073 root 1.70 cf::object::player player
1074     cf::player peaceful
1075 elmex 1.91 cf::map trigger
1076 root 1.70
1077     =cut
1078    
1079 root 1.25 for (
1080 elmex 1.91 ["cf::object" => qw(contr pay_amount pay_player map)],
1081 root 1.25 ["cf::object::player" => qw(player)],
1082     ["cf::player" => qw(peaceful)],
1083 elmex 1.91 ["cf::map" => qw(trigger)],
1084 root 1.25 ) {
1085     no strict 'refs';
1086     my ($pkg, @funs) = @$_;
1087 root 1.41 *{"safe::$pkg\::$_"} = $safe_hole->wrap (\&{"$pkg\::$_"})
1088 root 1.25 for @funs;
1089     }
1090 root 1.23
1091 root 1.70 =over 4
1092    
1093     =item @retval = safe_eval $code, [var => value, ...]
1094    
1095     Compiled and executes the given perl code snippet. additional var/value
1096     pairs result in temporary local (my) scalar variables of the given name
1097     that are available in the code snippet. Example:
1098    
1099     my $five = safe_eval '$first + $second', first => 1, second => 4;
1100    
1101     =cut
1102    
1103 root 1.23 sub safe_eval($;@) {
1104     my ($code, %vars) = @_;
1105    
1106     my $qcode = $code;
1107     $qcode =~ s/"/‟/g; # not allowed in #line filenames
1108     $qcode =~ s/\n/\\n/g;
1109    
1110     local $_;
1111 root 1.41 local @safe::cf::_safe_eval_args = values %vars;
1112 root 1.23
1113 root 1.42 my $eval =
1114 root 1.23 "do {\n"
1115     . "my (" . (join ",", map "\$$_", keys %vars) . ") = \@cf::_safe_eval_args;\n"
1116     . "#line 0 \"{$qcode}\"\n"
1117     . $code
1118     . "\n}"
1119 root 1.25 ;
1120    
1121     sub_generation_inc;
1122 root 1.42 my @res = wantarray ? $safe->reval ($eval) : scalar $safe->reval ($eval);
1123 root 1.25 sub_generation_inc;
1124    
1125 root 1.42 if ($@) {
1126     warn "$@";
1127     warn "while executing safe code '$code'\n";
1128     warn "with arguments " . (join " ", %vars) . "\n";
1129     }
1130    
1131 root 1.25 wantarray ? @res : $res[0]
1132 root 1.23 }
1133    
1134 root 1.69 =item cf::register_script_function $function => $cb
1135    
1136     Register a function that can be called from within map/npc scripts. The
1137     function should be reasonably secure and should be put into a package name
1138     like the extension.
1139    
1140     Example: register a function that gets called whenever a map script calls
1141     C<rent::overview>, as used by the C<rent> extension.
1142    
1143     cf::register_script_function "rent::overview" => sub {
1144     ...
1145     };
1146    
1147     =cut
1148    
1149 root 1.23 sub register_script_function {
1150     my ($fun, $cb) = @_;
1151    
1152     no strict 'refs';
1153 root 1.41 *{"safe::$fun"} = $safe_hole->wrap ($cb);
1154 root 1.23 }
1155    
1156 root 1.70 =back
1157    
1158 root 1.71 =cut
1159    
1160 root 1.23 #############################################################################
1161 root 1.65
1162     =head2 EXTENSION DATABASE SUPPORT
1163    
1164     Crossfire maintains a very simple database for extension use. It can
1165     currently store anything that can be serialised using Storable, which
1166     excludes objects.
1167    
1168     The parameter C<$family> should best start with the name of the extension
1169     using it, it should be unique.
1170    
1171     =over 4
1172    
1173     =item $hashref = cf::db_get $family
1174    
1175     Return a hashref for use by the extension C<$family>, which can be
1176     modified. After modifications, you have to call C<cf::db_dirty> or
1177     C<cf::db_sync>.
1178    
1179     =item $value = cf::db_get $family => $key
1180    
1181     Returns a single value from the database
1182    
1183     =item cf::db_put $family => $hashref
1184    
1185     Stores the given family hashref into the database. Updates are delayed, if
1186     you want the data to be synced to disk immediately, use C<cf::db_sync>.
1187    
1188     =item cf::db_put $family => $key => $value
1189    
1190     Stores the given C<$value> in the family hash. Updates are delayed, if you
1191     want the data to be synced to disk immediately, use C<cf::db_sync>.
1192    
1193     =item cf::db_dirty
1194    
1195     Marks the database as dirty, to be updated at a later time.
1196    
1197     =item cf::db_sync
1198    
1199     Immediately write the database to disk I<if it is dirty>.
1200    
1201     =cut
1202    
1203 root 1.78 our $DB;
1204    
1205 root 1.65 {
1206 root 1.66 my $path = cf::localdir . "/database.pst";
1207 root 1.65
1208     sub db_load() {
1209     warn "loading database $path\n";#d# remove later
1210 root 1.78 $DB = stat $path ? Storable::retrieve $path : { };
1211 root 1.65 }
1212    
1213     my $pid;
1214    
1215     sub db_save() {
1216     warn "saving database $path\n";#d# remove later
1217     waitpid $pid, 0 if $pid;
1218 root 1.67 if (0 == ($pid = fork)) {
1219 root 1.78 $DB->{_meta}{version} = 1;
1220     Storable::nstore $DB, "$path~";
1221 root 1.65 rename "$path~", $path;
1222     cf::_exit 0 if defined $pid;
1223     }
1224     }
1225    
1226     my $dirty;
1227    
1228     sub db_sync() {
1229     db_save if $dirty;
1230     undef $dirty;
1231     }
1232    
1233 root 1.87 my $idle = Event->idle (min => $TICK * 2.8, max => 10, repeat => 0, data => WF_AUTOCANCEL, cb => sub {
1234 root 1.65 db_sync;
1235     });
1236    
1237     sub db_dirty() {
1238     $dirty = 1;
1239     $idle->start;
1240     }
1241    
1242     sub db_get($;$) {
1243     @_ >= 2
1244 root 1.78 ? $DB->{$_[0]}{$_[1]}
1245     : ($DB->{$_[0]} ||= { })
1246 root 1.65 }
1247    
1248     sub db_put($$;$) {
1249     if (@_ >= 3) {
1250 root 1.78 $DB->{$_[0]}{$_[1]} = $_[2];
1251 root 1.65 } else {
1252 root 1.78 $DB->{$_[0]} = $_[1];
1253 root 1.65 }
1254     db_dirty;
1255     }
1256 root 1.67
1257 root 1.93 cf::global->attach (
1258     prio => 10000,
1259 root 1.67 on_cleanup => sub {
1260     db_sync;
1261     },
1262 root 1.93 );
1263 root 1.65 }
1264    
1265     #############################################################################
1266 root 1.34 # the server's main()
1267    
1268 root 1.73 sub cfg_load {
1269 root 1.72 open my $fh, "<:utf8", cf::confdir . "/config"
1270     or return;
1271    
1272     local $/;
1273     *CFG = YAML::Syck::Load <$fh>;
1274     }
1275    
1276 root 1.39 sub main {
1277 root 1.73 cfg_load;
1278 root 1.65 db_load;
1279 root 1.61 load_extensions;
1280 root 1.34 Event::loop;
1281     }
1282    
1283     #############################################################################
1284 root 1.22 # initialisation
1285    
1286 root 1.103 sub _perl_reload() {
1287 root 1.106 # can/must only be called in main
1288     if ($Coro::current != $Coro::main) {
1289     warn "can only reload from main coroutine\n";
1290     return;
1291     }
1292    
1293 root 1.103 warn "reloading...";
1294    
1295 root 1.106 local $FREEZE = 1;
1296     cf::emergency_save;
1297    
1298 root 1.103 eval {
1299 root 1.106 # if anything goes wrong in here, we should simply crash as we already saved
1300 root 1.65
1301     # cancel all watchers
1302 root 1.87 for (Event::all_watchers) {
1303     $_->cancel if $_->data & WF_AUTOCANCEL;
1304     }
1305 root 1.65
1306 root 1.103 # cancel all extension coros
1307     $_->cancel for values %EXT_CORO;
1308     %EXT_CORO = ();
1309    
1310 root 1.65 # unload all extensions
1311     for (@exts) {
1312 root 1.103 warn "unloading <$_>";
1313 root 1.65 unload_extension $_;
1314     }
1315    
1316     # unload all modules loaded from $LIBDIR
1317     while (my ($k, $v) = each %INC) {
1318     next unless $v =~ /^\Q$LIBDIR\E\/.*\.pm$/;
1319    
1320 root 1.103 warn "removing <$k>";
1321 root 1.65 delete $INC{$k};
1322    
1323     $k =~ s/\.pm$//;
1324     $k =~ s/\//::/g;
1325    
1326     if (my $cb = $k->can ("unload_module")) {
1327     $cb->();
1328     }
1329    
1330     Symbol::delete_package $k;
1331     }
1332    
1333     # sync database to disk
1334     cf::db_sync;
1335 root 1.103 IO::AIO::flush;
1336 root 1.65
1337     # get rid of safe::, as good as possible
1338     Symbol::delete_package "safe::$_"
1339 root 1.103 for qw(cf::attachable cf::object cf::object::player cf::client cf::player cf::map cf::party cf::region);
1340 root 1.65
1341     # remove register_script_function callbacks
1342     # TODO
1343    
1344     # unload cf.pm "a bit"
1345     delete $INC{"cf.pm"};
1346    
1347     # don't, removes xs symbols, too,
1348     # and global variables created in xs
1349     #Symbol::delete_package __PACKAGE__;
1350    
1351     # reload cf.pm
1352 root 1.103 warn "reloading cf.pm";
1353 root 1.65 require cf;
1354 root 1.100 cf::_connect_to_perl; # nominally unnecessary, but cannot hurt
1355    
1356 root 1.73 # load config and database again
1357     cf::cfg_load;
1358 root 1.65 cf::db_load;
1359    
1360     # load extensions
1361 root 1.103 warn "load extensions";
1362 root 1.65 cf::load_extensions;
1363    
1364     # reattach attachments to objects
1365 root 1.103 warn "reattach";
1366 root 1.65 _global_reattach;
1367     };
1368    
1369 root 1.106 if ($@) {
1370     warn $@;
1371     warn "error while reloading, exiting.";
1372     exit 1;
1373     }
1374    
1375     warn "reloaded successfully";
1376 root 1.65 };
1377    
1378     sub perl_reload() {
1379 root 1.103 _perl_reload;
1380 root 1.65 }
1381    
1382 root 1.85 register "<global>", __PACKAGE__;
1383    
1384     register_command "perl-reload" => sub {
1385 root 1.65 my ($who, $arg) = @_;
1386    
1387     if ($who->flag (FLAG_WIZ)) {
1388 root 1.103 $who->message ("reloading...");
1389     _perl_reload;
1390 root 1.65 }
1391     };
1392    
1393 root 1.27 unshift @INC, $LIBDIR;
1394 root 1.17
1395 root 1.35 $TICK_WATCHER = Event->timer (
1396 root 1.104 reentrant => 0,
1397     prio => 0,
1398     at => $NEXT_TICK || $TICK,
1399     data => WF_AUTOCANCEL,
1400     cb => sub {
1401 root 1.103 unless ($FREEZE) {
1402     cf::server_tick; # one server iteration
1403     $RUNTIME += $TICK;
1404     }
1405 root 1.35
1406     $NEXT_TICK += $TICK;
1407    
1408 root 1.78 # if we are delayed by four ticks or more, skip them all
1409 root 1.103 $NEXT_TICK = Event::time if Event::time >= $NEXT_TICK + $TICK * 4;
1410 root 1.35
1411     $TICK_WATCHER->at ($NEXT_TICK);
1412     $TICK_WATCHER->start;
1413     },
1414     );
1415    
1416 root 1.80 IO::AIO::max_poll_time $TICK * 0.2;
1417 root 1.77
1418     Event->io (fd => IO::AIO::poll_fileno,
1419     poll => 'r',
1420     prio => 5,
1421 root 1.87 data => WF_AUTOCANCEL,
1422 root 1.77 cb => \&IO::AIO::poll_cb);
1423    
1424 root 1.103 # we must not ever block the main coroutine
1425     $Coro::idle = sub {
1426     #Carp::cluck "FATAL: Coro::idle was called, major BUG\n";#d#
1427     warn "FATAL: Coro::idle was called, major BUG\n";
1428     (Coro::unblock_sub {
1429     Event::one_event;
1430     })->();
1431     };
1432    
1433 root 1.1 1
1434