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.156 by root, Tue Jan 9 22:07:08 2007 UTC vs.
Revision 1.158 by root, Wed Jan 10 19:52:43 2007 UTC

367 367
368############################################################################# 368#############################################################################
369 369
370package cf::path; 370package cf::path;
371 371
372use overload
373 '""' => \&as_string;
374
372# used to convert map paths into valid unix filenames by repalcing / by ∕ 375# used to convert map paths into valid unix filenames by repalcing / by ∕
373our $PATH_SEP = "∕"; # U+2215, chosen purely for visual reasons 376our $PATH_SEP = "∕"; # U+2215, chosen purely for visual reasons
374 377
375sub new { 378sub new {
376 my ($class, $path, $base) = @_; 379 my ($class, $path, $base) = @_;
384 # ?random/... random maps 387 # ?random/... random maps
385 # /! non-realised random map exit 388 # /! non-realised random map exit
386 # /... normal maps 389 # /... normal maps
387 # ~/... per-player maps without a specific player (DO NOT USE) 390 # ~/... per-player maps without a specific player (DO NOT USE)
388 # ~user/... per-player map of a specific user 391 # ~user/... per-player map of a specific user
392
393 $path =~ s/$PATH_SEP/\//go;
389 394
390 if ($path =~ /^{/) { 395 if ($path =~ /^{/) {
391 # fine as it is 396 # fine as it is
392 } elsif ($path =~ s{^\?random/}{}) { 397 } elsif ($path =~ s{^\?random/}{}) {
393 Coro::AIO::aio_load "$cf::RANDOM_MAPS/$path.meta", my $data; 398 Coro::AIO::aio_load "$cf::RANDOM_MAPS/$path.meta", my $data;
1240 my @paths; 1245 my @paths;
1241 1246
1242 for (@$files) { 1247 for (@$files) {
1243 utf8::decode $_; 1248 utf8::decode $_;
1244 next if /\.(?:pl|pst)$/; 1249 next if /\.(?:pl|pst)$/;
1245 next unless /^$PATH_SEP/; 1250 next unless /^$PATH_SEP/o;
1246 1251
1247 s/$PATH_SEP/\//g;
1248 push @paths, new cf::path "~" . $pl->ob->name . "/" . $_; 1252 push @paths, new cf::path "~" . $pl->ob->name . "/" . $_;
1249 } 1253 }
1250 1254
1251 \@paths 1255 \@paths
1252} 1256}
1439 Coro::cede; 1443 Coro::cede;
1440 1444
1441 $self->in_memory (cf::MAP_IN_MEMORY); 1445 $self->in_memory (cf::MAP_IN_MEMORY);
1442} 1446}
1443 1447
1448# find and load all maps in the 3x3 area around a map
1449sub load_diag {
1450 my ($map) = @_;
1451
1452 my @diag; # diagonal neighbours
1453
1454 for (0 .. 3) {
1455 my $neigh = $map->tile_path ($_)
1456 or next;
1457 $neigh = find $neigh, $map
1458 or next;
1459 $neigh->load;
1460
1461 push @diag, [$neigh->tile_path (($_ + 3) % 4), $neigh],
1462 [$neigh->tile_path (($_ + 1) % 4), $neigh];
1463 }
1464
1465 for (@diag) {
1466 my $neigh = find @$_
1467 or next;
1468 $neigh->load;
1469 }
1470}
1471
1444sub find_sync { 1472sub find_sync {
1445 my ($path, $origin) = @_; 1473 my ($path, $origin) = @_;
1446 1474
1447 cf::sync_job { cf::map::find $path, $origin } 1475 cf::sync_job { find $path, $origin }
1448} 1476}
1449 1477
1450sub do_load_sync { 1478sub do_load_sync {
1451 my ($map) = @_; 1479 my ($map) = @_;
1452 1480
1453 cf::sync_job { $map->load }; 1481 cf::sync_job { $map->load };
1482}
1483
1484our %MAP_PREFETCH;
1485our $MAP_PREFETCHER = Coro::async {
1486 while () {
1487 while (%MAP_PREFETCH) {
1488 my $key = each %MAP_PREFETCH
1489 or next;
1490 my $path = delete $MAP_PREFETCH{$key};
1491
1492 my $map = find $path
1493 or next;
1494 $map->load;
1495 }
1496 Coro::schedule;
1497 }
1498};
1499
1500sub find_async {
1501 my ($path, $origin) = @_;
1502
1503 $path = new cf::path $path, $origin && $origin->path;
1504 my $key = $path->as_string;
1505
1506 if (my $map = $cf::MAP{$key}) {
1507 return $map if $map->in_memory == cf::MAP_IN_MEMORY;
1508 }
1509
1510 $MAP_PREFETCH{$key} = $path;
1511 $MAP_PREFETCHER->ready;
1512
1513 ()
1454} 1514}
1455 1515
1456sub save { 1516sub save {
1457 my ($self) = @_; 1517 my ($self) = @_;
1458 1518
1576 } 1636 }
1577 1637
1578 $map 1638 $map
1579} 1639}
1580 1640
1641=item cf::map::unique_maps
1642
1643Returns an arrayref of cf::path's of all shared maps that have
1644instantiated unique items. May block.
1645
1646=cut
1647
1648sub unique_maps() {
1649 my $files = aio_readdir cf::localdir . "/" . cf::uniquedir
1650 or return;
1651
1652 my @paths;
1653
1654 for (@$files) {
1655 utf8::decode $_;
1656 next if /\.pst$/;
1657 next unless /^$PATH_SEP/o;
1658
1659 push @paths, new cf::path $_;
1660 }
1661
1662 \@paths
1663}
1664
1581package cf; 1665package cf;
1582 1666
1583=back 1667=back
1584 1668
1585=head3 cf::object 1669=head3 cf::object
1707 # use -1 or undef as default coordinates, not 0, 0 1791 # use -1 or undef as default coordinates, not 0, 0
1708 ($x, $y) = ($map->enter_x, $map->enter_y) 1792 ($x, $y) = ($map->enter_x, $map->enter_y)
1709 if $x <=0 && $y <= 0; 1793 if $x <=0 && $y <= 0;
1710 1794
1711 $map->load; 1795 $map->load;
1796 $map->load_diag;
1712 1797
1713 return unless $self->contr->active; 1798 return unless $self->contr->active;
1714 $self->activate_recursive; 1799 $self->activate_recursive;
1715 $self->enter_map ($map, $x, $y); 1800 $self->enter_map ($map, $x, $y);
1716} 1801}
1753 1838
1754sub cf::object::player::goto { 1839sub cf::object::player::goto {
1755 my ($self, $path, $x, $y) = @_; 1840 my ($self, $path, $x, $y) = @_;
1756 1841
1757 $path = new cf::path $path; 1842 $path = new cf::path $path;
1758 $path ne "/" or Carp::cluck ("oy");#d#
1759 1843
1760 $self->enter_link; 1844 $self->enter_link;
1761 1845
1762 (async { 1846 (async {
1763 my $map = cf::map::find $path->as_string; 1847 my $map = cf::map::find $path->as_string;
1840 1924
1841 1; 1925 1;
1842 }) { 1926 }) {
1843 $self->message ("Something went wrong deep within the crossfire server. " 1927 $self->message ("Something went wrong deep within the crossfire server. "
1844 . "I'll try to bring you back to the map you were before. " 1928 . "I'll try to bring you back to the map you were before. "
1845 . "Please report this to the dungeon master", 1929 . "Please report this to the dungeon master!",
1846 cf::NDI_UNIQUE | cf::NDI_RED); 1930 cf::NDI_UNIQUE | cf::NDI_RED);
1847 1931
1848 warn "ERROR in enter_exit: $@"; 1932 warn "ERROR in enter_exit: $@";
1849 $self->leave_link; 1933 $self->leave_link;
1850 } 1934 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines