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.353 by root, Sun Sep 2 08:43:46 2007 UTC vs.
Revision 1.356 by root, Tue Sep 4 05:43:21 2007 UTC

87our %CFG; 87our %CFG;
88 88
89our $UPTIME; $UPTIME ||= time; 89our $UPTIME; $UPTIME ||= time;
90our $RUNTIME; 90our $RUNTIME;
91 91
92our %PLAYER; # all users 92our (%PLAYER, %PLAYER_LOADING); # all users
93our %MAP; # all maps 93our (%MAP, %MAP_LOADING ); # all maps
94our $LINK_MAP; # the special {link} map, which is always available 94our $LINK_MAP; # the special {link} map, which is always available
95 95
96# used to convert map paths into valid unix filenames by replacing / by ∕ 96# used to convert map paths into valid unix filenames by replacing / by ∕
97our $PATH_SEP = "∕"; # U+2215, chosen purely for visual reasons 97our $PATH_SEP = "∕"; # U+2215, chosen purely for visual reasons
98 98
481sub fork_call(&@) { 481sub fork_call(&@) {
482 my ($cb, @args) = @_; 482 my ($cb, @args) = @_;
483 483
484 # we seemingly have to make a local copy of the whole thing, 484 # we seemingly have to make a local copy of the whole thing,
485 # otherwise perl prematurely frees the stuff :/ 485 # otherwise perl prematurely frees the stuff :/
486 # TODO: investigate and fix (liekly this will be rather laborious) 486 # TODO: investigate and fix (likely this will be rather laborious)
487 487
488 my @res = Coro::Util::fork_eval { 488 my @res = Coro::Util::fork_eval {
489 reset_signals; 489 reset_signals;
490 &$cb 490 &$cb
491 }, @args; 491 }, @args;
1004 }, 1004 },
1005); 1005);
1006 1006
1007sub object_freezer_save { 1007sub object_freezer_save {
1008 my ($filename, $rdata, $objs) = @_; 1008 my ($filename, $rdata, $objs) = @_;
1009
1010 my $guard = cf::lock_acquire "io";
1009 1011
1010 sync_job { 1012 sync_job {
1011 if (length $$rdata) { 1013 if (length $$rdata) {
1012 warn sprintf "saving %s (%d,%d)\n", 1014 warn sprintf "saving %s (%d,%d)\n",
1013 $filename, length $$rdata, scalar @$objs; 1015 $filename, length $$rdata, scalar @$objs;
1037 } 1039 }
1038 } else { 1040 } else {
1039 aio_unlink $filename; 1041 aio_unlink $filename;
1040 aio_unlink "$filename.pst"; 1042 aio_unlink "$filename.pst";
1041 } 1043 }
1042 } 1044 };
1045
1046 undef $guard;
1043} 1047}
1044 1048
1045sub object_freezer_as_string { 1049sub object_freezer_as_string {
1046 my ($rdata, $objs) = @_; 1050 my ($rdata, $objs) = @_;
1047 1051
1052 1056
1053sub object_thawer_load { 1057sub object_thawer_load {
1054 my ($filename) = @_; 1058 my ($filename) = @_;
1055 1059
1056 my ($data, $av); 1060 my ($data, $av);
1061
1062 my $guard = cf::lock_acquire "io";
1057 1063
1058 (aio_load $filename, $data) >= 0 1064 (aio_load $filename, $data) >= 0
1059 or return; 1065 or return;
1060 1066
1061 unless (aio_stat "$filename.pst") { 1067 unless (aio_stat "$filename.pst") {
1062 (aio_load "$filename.pst", $av) >= 0 1068 (aio_load "$filename.pst", $av) >= 0
1063 or return; 1069 or return;
1070
1071 undef $guard;
1064 $av = eval { (Storable::thaw $av)->{objs} }; 1072 $av = eval { (Storable::thaw $av)->{objs} };
1065 } 1073 }
1066 1074
1067 warn sprintf "loading %s (%d)\n", 1075 warn sprintf "loading %s (%d)\n",
1068 $filename, length $data, scalar @{$av || []}; 1076 $filename, length $data, scalar @{$av || []};
1077
1069 return ($data, $av); 1078 ($data, $av)
1070} 1079}
1071 1080
1072=head2 COMMAND CALLBACKS 1081=head2 COMMAND CALLBACKS
1073 1082
1074=over 4 1083=over 4
1304 aio_link +(playerdir $login) . "/$login.pl.pst", (playerdir $login) . "/playerdata.pst"; 1313 aio_link +(playerdir $login) . "/$login.pl.pst", (playerdir $login) . "/playerdata.pst";
1305 aio_link +(playerdir $login) . "/$login.pl" , (playerdir $login) . "/playerdata"; 1314 aio_link +(playerdir $login) . "/$login.pl" , (playerdir $login) . "/playerdata";
1306 aio_unlink +(playerdir $login) . "/$login.pl.pst"; 1315 aio_unlink +(playerdir $login) . "/$login.pl.pst";
1307 aio_unlink +(playerdir $login) . "/$login.pl"; 1316 aio_unlink +(playerdir $login) . "/$login.pl";
1308 1317
1309 my $pl = load_pl path $login 1318 my $f = new_from_file cf::object::thawer path $login
1310 or return; 1319 or return;
1320
1321 $f->next;
1322 my $pl = cf::player::load_pl $f
1323 or return;
1324 local $cf::PLAYER_LOADING{$login} = $pl;
1325 $f->resolve_delayed_derefs;
1311 $cf::PLAYER{$login} = $pl 1326 $cf::PLAYER{$login} = $pl
1312 } 1327 }
1313 } 1328 }
1314} 1329}
1315 1330
1413 or return []; 1428 or return [];
1414 1429
1415 my @logins; 1430 my @logins;
1416 1431
1417 for my $login (@$dirs) { 1432 for my $login (@$dirs) {
1433 my $path = path $login;
1434
1435 # a .pst is a dead give-away for a valid player
1436 unless (-e "$path.pst") {
1418 my $fh = aio_open path $login, Fcntl::O_RDONLY, 0 or next; 1437 my $fh = aio_open $path, Fcntl::O_RDONLY, 0 or next;
1419 aio_read $fh, 0, 512, my $buf, 0 or next; 1438 aio_read $fh, 0, 512, my $buf, 0 or next;
1420 $buf !~ /^password -------------$/m or next; # official not-valid tag 1439 $buf !~ /^password -------------$/m or next; # official not-valid tag
1440 }
1421 1441
1422 utf8::decode $login; 1442 utf8::decode $login;
1423 push @logins, $login; 1443 push @logins, $login;
1424 } 1444 }
1425 1445
1750 1770
1751sub load_header_from($) { 1771sub load_header_from($) {
1752 my ($self, $path) = @_; 1772 my ($self, $path) = @_;
1753 1773
1754 utf8::encode $path; 1774 utf8::encode $path;
1755 #aio_open $path, O_RDONLY, 0 1775 my $f = new_from_file cf::object::thawer $path
1756 # or return;
1757
1758 $self->_load_header ($path)
1759 or return; 1776 or return;
1777
1778 $self->_load_header ($f)
1779 or return;
1780
1781 local $MAP_LOADING{$self->{path}} = $self;
1782 $f->resolve_delayed_derefs;
1760 1783
1761 $self->{load_path} = $path; 1784 $self->{load_path} = $path;
1762 1785
1763 1 1786 1
1764} 1787}
1865 $self->alloc; 1888 $self->alloc;
1866 1889
1867 $self->pre_load; 1890 $self->pre_load;
1868 cf::cede_to_tick; 1891 cf::cede_to_tick;
1869 1892
1893 my $f = new_from_file cf::object::thawer $self->{load_path};
1894 $f->skip_block;
1870 $self->_load_objects ($self->{load_path}, 1) 1895 $self->_load_objects ($f)
1871 or return; 1896 or return;
1872 1897
1873 $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1) 1898 $self->set_object_flag (cf::FLAG_OBJ_ORIGINAL, 1)
1874 if delete $self->{load_original}; 1899 if delete $self->{load_original};
1875 1900
1876 if (my $uniq = $self->uniq_path) { 1901 if (my $uniq = $self->uniq_path) {
1877 utf8::encode $uniq; 1902 utf8::encode $uniq;
1878 if (aio_open $uniq, O_RDONLY, 0) { 1903 unless (aio_stat $uniq) {
1904 if (my $f = new_from_file cf::object::thawer $uniq) {
1879 $self->clear_unique_items; 1905 $self->clear_unique_items;
1880 $self->_load_objects ($uniq, 0); 1906 $self->_load_objects ($f);
1907 $f->resolve_delayed_derefs;
1908 }
1881 } 1909 }
1882 } 1910 }
1911
1912 $f->resolve_delayed_derefs;
1883 1913
1884 cf::cede_to_tick; 1914 cf::cede_to_tick;
1885 # now do the right thing for maps 1915 # now do the right thing for maps
1886 $self->link_multipart_objects; 1916 $self->link_multipart_objects;
1887 $self->difficulty ($self->estimate_difficulty) 1917 $self->difficulty ($self->estimate_difficulty)
2185 map { $_, inv_recursive_ $_->inv } @_ 2215 map { $_, inv_recursive_ $_->inv } @_
2186} 2216}
2187 2217
2188sub inv_recursive { 2218sub inv_recursive {
2189 inv_recursive_ inv $_[0] 2219 inv_recursive_ inv $_[0]
2220}
2221
2222=item $ref = $ob->ref
2223
2224creates and returns a persistent reference to an objetc that can be stored as a string.
2225
2226=item $ob = cf::object::deref ($refstring)
2227
2228returns the objetc referenced by refstring. may return undef when it cnanot find the object,
2229even if the object actually exists. May block.
2230
2231=cut
2232
2233sub deref {
2234 my ($ref) = @_;
2235
2236 # temporary compatibility#TODO#remove
2237 $ref =~ s{^<}{player/<};
2238
2239 if ($ref =~ m{^player\/(<1\.\d+>)/(.*)$}) {
2240 my ($uuid, $name) = ($1, $2);
2241 my $pl = $cf::PLAYER_LOADING{$name} || cf::player::find $name
2242 or return;
2243 $pl->ob->uuid eq $uuid
2244 or return;
2245
2246 $pl->ob
2247 } else {
2248 warn "$ref: cannot resolve object reference\n";
2249 undef
2250 }
2190} 2251}
2191 2252
2192package cf; 2253package cf;
2193 2254
2194=back 2255=back
3369 or die; 3430 or die;
3370 3431
3371 $map->width (50); 3432 $map->width (50);
3372 $map->height (50); 3433 $map->height (50);
3373 $map->alloc; 3434 $map->alloc;
3374 $map->_load_objects ("/tmp/x.map", 1); 3435 $map->_load_objects ("/tmp/x.map", 1); #TODO: does not work
3375 my $t = Event::time - $t; 3436 my $t = Event::time - $t;
3376 3437
3377 #next unless $t < 0.0013;#d# 3438 #next unless $t < 0.0013;#d#
3378 if ($t < $min) { 3439 if ($t < $min) {
3379 $min = $t; 3440 $min = $t;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines