ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/lib/cf.pm
Revision: 1.105
Committed: Sun Dec 31 17:17:23 2006 UTC (17 years, 4 months ago) by root
Branch: MAIN
Changes since 1.104: +66 -29 lines
Log Message:
many minor changes everywhere, random maps crash sometimes but design is in place

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