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.63 by root, Fri Sep 8 17:41:41 2006 UTC vs.
Revision 1.70 by root, Sun Oct 1 10:55:37 2006 UTC

21 21
22our $TICK = MAX_TIME * 1e-6; 22our $TICK = MAX_TIME * 1e-6;
23our $TICK_WATCHER; 23our $TICK_WATCHER;
24our $NEXT_TICK; 24our $NEXT_TICK;
25 25
26our %CFG;
27
28#############################################################################
29
30=head2 GLOBAL VARIABLES
31
32=over 4
33
34=item $cf::LIBDIR
35
36The perl library directory, where extensions and cf-specific modules can
37be found. It will be added to C<@INC> automatically.
38
39=item $cf::TICK
40
41The interval between server ticks, in seconds.
42
43=item %cf::CFG
44
45Configuration for the server, loaded from C</etc/crossfire/config>, or
46from wherever your confdir points to.
47
48=back
49
50=cut
51
26BEGIN { 52BEGIN {
27 *CORE::GLOBAL::warn = sub { 53 *CORE::GLOBAL::warn = sub {
28 my $msg = join "", @_; 54 my $msg = join "", @_;
29 $msg .= "\n" 55 $msg .= "\n"
30 unless $msg =~ /\n$/; 56 unless $msg =~ /\n$/;
51my @exts; 77my @exts;
52my @hook; 78my @hook;
53my %command; 79my %command;
54my %extcmd; 80my %extcmd;
55 81
56############################################################################# 82=head2 UTILITY FUNCTIONS
57# utility functions 83
84=over 4
85
86=cut
58 87
59use JSON::Syck (); # TODO# replace by JSON::PC once working 88use JSON::Syck (); # TODO# replace by JSON::PC once working
89
90=item $ref = cf::from_json $json
91
92Converts a JSON string into the corresponding perl data structure.
93
94=cut
60 95
61sub from_json($) { 96sub from_json($) {
62 $JSON::Syck::ImplicitUnicode = 1; # work around JSON::Syck bugs 97 $JSON::Syck::ImplicitUnicode = 1; # work around JSON::Syck bugs
63 JSON::Syck::Load $_[0] 98 JSON::Syck::Load $_[0]
64} 99}
65 100
101=item $json = cf::to_json $ref
102
103Converts a perl data structure into its JSON representation.
104
105=cut
106
66sub to_json($) { 107sub to_json($) {
67 $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs 108 $JSON::Syck::ImplicitUnicode = 0; # work around JSON::Syck bugs
68 JSON::Syck::Dump $_[0] 109 JSON::Syck::Dump $_[0]
69} 110}
70 111
71############################################################################# 112=back
72# "new" plug-in system
73 113
114#############################################################################
115
74=head3 EVENTS AND OBJECT ATTACHMENTS 116=head2 EVENTS AND OBJECT ATTACHMENTS
75 117
76=over 4 118=over 4
77 119
78=item $object->attach ($attachment, key => $value...) 120=item $object->attach ($attachment, key => $value...)
79 121
353 for (@$callbacks) { 395 for (@$callbacks) {
354 eval { &{$_->[1]} }; 396 eval { &{$_->[1]} };
355 397
356 if ($@) { 398 if ($@) {
357 warn "$@"; 399 warn "$@";
358 warn "... while processing $EVENT[$event][0] event, skipping processing altogether.\n"; 400 warn "... while processing $EVENT[$event][0](@_) event, skipping processing altogether.\n";
359 override; 401 override;
360 } 402 }
361 403
362 return 1 if $override; 404 return 1 if $override;
363 } 405 }
379removed in future versions), and there is no public API to access override 421removed in future versions), and there is no public API to access override
380results (if you must, access C<@cf::invoke_results> directly). 422results (if you must, access C<@cf::invoke_results> directly).
381 423
382=back 424=back
383 425
384=head2 methods valid for all pointers 426#############################################################################
427
428=head2 METHODS VALID FOR ALL CORE OBJECTS
385 429
386=over 4 430=over 4
387 431
388=item $object->valid 432=item $object->valid, $player->valid, $map->valid
389
390=item $player->valid
391
392=item $map->valid
393 433
394Just because you have a perl object does not mean that the corresponding 434Just because you have a perl object does not mean that the corresponding
395C-level object still exists. If you try to access an object that has no 435C-level object still exists. If you try to access an object that has no
396valid C counterpart anymore you get an exception at runtime. This method 436valid C counterpart anymore you get an exception at runtime. This method
397can be used to test for existence of the C object part without causing an 437can be used to test for existence of the C object part without causing an
643 1 683 1
644 } or warn "$ext not loaded: $@"; 684 } or warn "$ext not loaded: $@";
645 } 685 }
646} 686}
647 687
648sub _perl_reload(&) {
649 my ($msg) = @_;
650
651 $msg->("reloading...");
652
653 eval {
654 # 1. cancel all watchers
655 $_->cancel for Event::all_watchers;
656
657 # 2. unload all extensions
658 for (@exts) {
659 $msg->("unloading <$_>");
660 unload_extension $_;
661 }
662
663 # 3. unload all modules loaded from $LIBDIR
664 while (my ($k, $v) = each %INC) {
665 next unless $v =~ /^\Q$LIBDIR\E\/.*\.pm$/;
666
667 $msg->("removing <$k>");
668 delete $INC{$k};
669
670 $k =~ s/\.pm$//;
671 $k =~ s/\//::/g;
672
673 if (my $cb = $k->can ("unload_module")) {
674 $cb->();
675 }
676
677 Symbol::delete_package $k;
678 }
679
680 # 4. get rid of safe::, as good as possible
681 Symbol::delete_package "safe::$_"
682 for qw(cf::object cf::object::player cf::player cf::map cf::party cf::region);
683
684 # 5. remove register_script_function callbacks
685 # TODO
686
687 # 6. unload cf.pm "a bit"
688 delete $INC{"cf.pm"};
689
690 # don't, removes xs symbols, too,
691 # and global variables created in xs
692 #Symbol::delete_package __PACKAGE__;
693
694 # 7. reload cf.pm
695 $msg->("reloading cf.pm");
696 require cf;
697
698 $msg->("load extensions");
699 cf::load_extensions;
700
701 $msg->("reattach");
702 _global_reattach;
703 };
704 $msg->($@) if $@;
705
706 $msg->("reloaded");
707};
708
709sub perl_reload() {
710 _perl_reload {
711 warn $_[0];
712 print "$_[0]\n";
713 };
714}
715
716register_command "perl-reload", 0, sub {
717 my ($who, $arg) = @_;
718
719 if ($who->flag (FLAG_WIZ)) {
720 _perl_reload {
721 warn $_[0];
722 $who->message ($_[0]);
723 };
724 }
725};
726
727############################################################################# 688#############################################################################
728# extcmd framework, basically convert ext <msg> 689# extcmd framework, basically convert ext <msg>
729# into pkg::->on_extcmd_arg1 (...) while shortcutting a few 690# into pkg::->on_extcmd_arg1 (...) while shortcutting a few
730 691
731attach_to_players 692attach_to_players
783 } 744 }
784 }, 745 },
785; 746;
786 747
787############################################################################# 748#############################################################################
788# core extensions - in perl 749
750=head2 CORE EXTENSIONS
751
752Functions and methods that extend core crossfire objects.
753
754=over 4
789 755
790=item cf::player::exists $login 756=item cf::player::exists $login
791 757
792Returns true when the given account exists. 758Returns true when the given account exists.
793 759
833 $msg{msgid} = $id; 799 $msg{msgid} = $id;
834 800
835 $self->send ("ext " . to_json \%msg); 801 $self->send ("ext " . to_json \%msg);
836} 802}
837 803
804=back
805
806=cut
807
838############################################################################# 808#############################################################################
839# map scripting support 809
810=head2 SAFE SCRIPTING
811
812Functions that provide a safe environment to compile and execute
813snippets of perl code without them endangering the safety of the server
814itself. Looping constructs, I/O operators and other built-in functionality
815is not available in the safe scripting environment, and the number of
816functions and methods that cna be called is greatly reduced.
817
818=cut
840 819
841our $safe = new Safe "safe"; 820our $safe = new Safe "safe";
842our $safe_hole = new Safe::Hole; 821our $safe_hole = new Safe::Hole;
843 822
844$SIG{FPE} = 'IGNORE'; 823$SIG{FPE} = 'IGNORE';
845 824
846$safe->permit_only (Opcode::opset qw(:base_core :base_mem :base_orig :base_math sort time)); 825$safe->permit_only (Opcode::opset qw(:base_core :base_mem :base_orig :base_math sort time));
847 826
848# here we export the classes and methods available to script code 827# here we export the classes and methods available to script code
828
829=pod
830
831The following fucntions and emthods are available within a safe environment:
832
833 cf::object contr pay_amount pay_player
834 cf::object::player player
835 cf::player peaceful
836
837=cut
849 838
850for ( 839for (
851 ["cf::object" => qw(contr pay_amount pay_player)], 840 ["cf::object" => qw(contr pay_amount pay_player)],
852 ["cf::object::player" => qw(player)], 841 ["cf::object::player" => qw(player)],
853 ["cf::player" => qw(peaceful)], 842 ["cf::player" => qw(peaceful)],
856 my ($pkg, @funs) = @$_; 845 my ($pkg, @funs) = @$_;
857 *{"safe::$pkg\::$_"} = $safe_hole->wrap (\&{"$pkg\::$_"}) 846 *{"safe::$pkg\::$_"} = $safe_hole->wrap (\&{"$pkg\::$_"})
858 for @funs; 847 for @funs;
859} 848}
860 849
850=over 4
851
852=item @retval = safe_eval $code, [var => value, ...]
853
854Compiled and executes the given perl code snippet. additional var/value
855pairs result in temporary local (my) scalar variables of the given name
856that are available in the code snippet. Example:
857
858 my $five = safe_eval '$first + $second', first => 1, second => 4;
859
860=cut
861
861sub safe_eval($;@) { 862sub safe_eval($;@) {
862 my ($code, %vars) = @_; 863 my ($code, %vars) = @_;
863 864
864 my $qcode = $code; 865 my $qcode = $code;
865 $qcode =~ s/"/‟/g; # not allowed in #line filenames 866 $qcode =~ s/"/‟/g; # not allowed in #line filenames
887 } 888 }
888 889
889 wantarray ? @res : $res[0] 890 wantarray ? @res : $res[0]
890} 891}
891 892
893=item cf::register_script_function $function => $cb
894
895Register a function that can be called from within map/npc scripts. The
896function should be reasonably secure and should be put into a package name
897like the extension.
898
899Example: register a function that gets called whenever a map script calls
900C<rent::overview>, as used by the C<rent> extension.
901
902 cf::register_script_function "rent::overview" => sub {
903 ...
904 };
905
906=cut
907
892sub register_script_function { 908sub register_script_function {
893 my ($fun, $cb) = @_; 909 my ($fun, $cb) = @_;
894 910
895 no strict 'refs'; 911 no strict 'refs';
896 *{"safe::$fun"} = $safe_hole->wrap ($cb); 912 *{"safe::$fun"} = $safe_hole->wrap ($cb);
897} 913}
898 914
915=back
916
917#############################################################################
918
919=head2 EXTENSION DATABASE SUPPORT
920
921Crossfire maintains a very simple database for extension use. It can
922currently store anything that can be serialised using Storable, which
923excludes objects.
924
925The parameter C<$family> should best start with the name of the extension
926using it, it should be unique.
927
928=over 4
929
930=item $hashref = cf::db_get $family
931
932Return a hashref for use by the extension C<$family>, which can be
933modified. After modifications, you have to call C<cf::db_dirty> or
934C<cf::db_sync>.
935
936=item $value = cf::db_get $family => $key
937
938Returns a single value from the database
939
940=item cf::db_put $family => $hashref
941
942Stores the given family hashref into the database. Updates are delayed, if
943you want the data to be synced to disk immediately, use C<cf::db_sync>.
944
945=item cf::db_put $family => $key => $value
946
947Stores the given C<$value> in the family hash. Updates are delayed, if you
948want the data to be synced to disk immediately, use C<cf::db_sync>.
949
950=item cf::db_dirty
951
952Marks the database as dirty, to be updated at a later time.
953
954=item cf::db_sync
955
956Immediately write the database to disk I<if it is dirty>.
957
958=cut
959
960{
961 my $db;
962 my $path = cf::localdir . "/database.pst";
963
964 sub db_load() {
965 warn "loading database $path\n";#d# remove later
966 $db = stat $path ? Storable::retrieve $path : { };
967 }
968
969 my $pid;
970
971 sub db_save() {
972 warn "saving database $path\n";#d# remove later
973 waitpid $pid, 0 if $pid;
974 if (0 == ($pid = fork)) {
975 $db->{_meta}{version} = 1;
976 Storable::nstore $db, "$path~";
977 rename "$path~", $path;
978 cf::_exit 0 if defined $pid;
979 }
980 }
981
982 my $dirty;
983
984 sub db_sync() {
985 db_save if $dirty;
986 undef $dirty;
987 }
988
989 my $idle = Event->idle (min => $TICK * 2.8, max => 10, repeat => 0, cb => sub {
990 db_sync;
991 });
992
993 sub db_dirty() {
994 $dirty = 1;
995 $idle->start;
996 }
997
998 sub db_get($;$) {
999 @_ >= 2
1000 ? $db->{$_[0]}{$_[1]}
1001 : ($db->{$_[0]} ||= { })
1002 }
1003
1004 sub db_put($$;$) {
1005 if (@_ >= 3) {
1006 $db->{$_[0]}{$_[1]} = $_[2];
1007 } else {
1008 $db->{$_[0]} = $_[1];
1009 }
1010 db_dirty;
1011 }
1012
1013 attach_global
1014 prio => 10000,
1015 on_cleanup => sub {
1016 db_sync;
1017 },
1018 ;
1019}
1020
899############################################################################# 1021#############################################################################
900# the server's main() 1022# the server's main()
901 1023
902sub main { 1024sub main {
1025 db_load;
903 load_extensions; 1026 load_extensions;
904 Event::loop; 1027 Event::loop;
905} 1028}
906 1029
907############################################################################# 1030#############################################################################
908# initialisation 1031# initialisation
1032
1033sub _perl_reload(&) {
1034 my ($msg) = @_;
1035
1036 $msg->("reloading...");
1037
1038 eval {
1039 # cancel all watchers
1040 $_->cancel for Event::all_watchers;
1041
1042 # unload all extensions
1043 for (@exts) {
1044 $msg->("unloading <$_>");
1045 unload_extension $_;
1046 }
1047
1048 # unload all modules loaded from $LIBDIR
1049 while (my ($k, $v) = each %INC) {
1050 next unless $v =~ /^\Q$LIBDIR\E\/.*\.pm$/;
1051
1052 $msg->("removing <$k>");
1053 delete $INC{$k};
1054
1055 $k =~ s/\.pm$//;
1056 $k =~ s/\//::/g;
1057
1058 if (my $cb = $k->can ("unload_module")) {
1059 $cb->();
1060 }
1061
1062 Symbol::delete_package $k;
1063 }
1064
1065 # sync database to disk
1066 cf::db_sync;
1067
1068 # get rid of safe::, as good as possible
1069 Symbol::delete_package "safe::$_"
1070 for qw(cf::object cf::object::player cf::player cf::map cf::party cf::region);
1071
1072 # remove register_script_function callbacks
1073 # TODO
1074
1075 # unload cf.pm "a bit"
1076 delete $INC{"cf.pm"};
1077
1078 # don't, removes xs symbols, too,
1079 # and global variables created in xs
1080 #Symbol::delete_package __PACKAGE__;
1081
1082 # reload cf.pm
1083 $msg->("reloading cf.pm");
1084 require cf;
1085
1086 # load database again
1087 cf::db_load;
1088
1089 # load extensions
1090 $msg->("load extensions");
1091 cf::load_extensions;
1092
1093 # reattach attachments to objects
1094 $msg->("reattach");
1095 _global_reattach;
1096 };
1097 $msg->($@) if $@;
1098
1099 $msg->("reloaded");
1100};
1101
1102sub perl_reload() {
1103 _perl_reload {
1104 warn $_[0];
1105 print "$_[0]\n";
1106 };
1107}
1108
1109register_command "perl-reload", 0, sub {
1110 my ($who, $arg) = @_;
1111
1112 if ($who->flag (FLAG_WIZ)) {
1113 _perl_reload {
1114 warn $_[0];
1115 $who->message ($_[0]);
1116 };
1117 }
1118};
909 1119
910register "<global>", __PACKAGE__; 1120register "<global>", __PACKAGE__;
911 1121
912unshift @INC, $LIBDIR; 1122unshift @INC, $LIBDIR;
913 1123

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines