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.112 by root, Mon Jan 1 13:31:47 2007 UTC vs.
Revision 1.116 by root, Mon Jan 1 17:30:34 2007 UTC

289 289
290 $path = $path->as_string if ref $path; 290 $path = $path->as_string if ref $path;
291 291
292 my $self = bless { }, $class; 292 my $self = bless { }, $class;
293 293
294 # {... are special paths that are not touched
295 # ?xxx/... are special absolute paths
296 # ?random/... random maps
297 # /! non-realised random map exit
298 # /... normal maps
299 # ~/... per-player maps without a specific player (DO NOT USE)
300 # ~user/... per-player map of a specific user
301
302 if ($path =~ /^{/) {
303 # fine as it is
294 if ($path =~ s{^\?random/}{}) { 304 } elsif ($path =~ s{^\?random/}{}) {
295 Coro::AIO::aio_load "$cf::RANDOM_MAPS/$path.meta", my $data; 305 Coro::AIO::aio_load "$cf::RANDOM_MAPS/$path.meta", my $data;
296 $self->{random} = cf::from_json $data; 306 $self->{random} = cf::from_json $data;
297 } else { 307 } else {
298 if ($path =~ s{^~([^/]+)?}{}) { 308 if ($path =~ s{^~([^/]+)?}{}) {
299 $self->{user_rel} = 1; 309 $self->{user_rel} = 1;
804 or return; 814 or return;
805 815
806 unless (aio_stat "$filename.pst") { 816 unless (aio_stat "$filename.pst") {
807 (aio_load "$filename.pst", $av) >= 0 817 (aio_load "$filename.pst", $av) >= 0
808 or return; 818 or return;
809 $av = eval { (Storable::thaw <$av>)->{objs} }; 819 $av = eval { (Storable::thaw $av)->{objs} };
810 } 820 }
811 821
812 return ($data, $av); 822 return ($data, $av);
813} 823}
814 824
1133 $map->per_player (0) if $path->{user_rel}; 1143 $map->per_player (0) if $path->{user_rel};
1134 } 1144 }
1135 1145
1136 $map->path ($key); 1146 $map->path ($key);
1137 $map->{path} = $path; 1147 $map->{path} = $path;
1148 $map->{last_save} = $cf::RUNTIME;
1138 $map->last_access ($cf::RUNTIME); 1149 $map->last_access ($cf::RUNTIME);
1139 1150
1140 if ($map->should_reset) { 1151 if ($map->should_reset) {
1141 $map->reset; 1152 $map->reset;
1142 $map = find_map $path; 1153 $map = find_map $path;
1238 1249
1239sub reset_at { 1250sub reset_at {
1240 my ($self) = @_; 1251 my ($self) = @_;
1241 1252
1242 # TODO: safety, remove and allow resettable per-player maps 1253 # TODO: safety, remove and allow resettable per-player maps
1243 return 1e100 if $self->{path}{user_rel}; 1254 return 1e99 if $self->{path}{user_rel};
1244 return 1e100 if $self->{deny_reset}; 1255 return 1e99 if $self->{deny_reset};
1245 1256
1246 my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access; 1257 my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access;
1247 my $to = $self->reset_timeout || $DEFAULT_RESET; 1258 my $to = List::Util::min $MAX_RESET, $self->reset_timeout || $DEFAULT_RESET;
1248 $to = $MAX_RESET if $to > $MAX_RESET;
1249 1259
1250 $time + $to 1260 $time + $to
1251} 1261}
1252 1262
1253sub should_reset { 1263sub should_reset {
1262 utf8::encode (my $save = $self->{path}->save_path); 1272 utf8::encode (my $save = $self->{path}->save_path);
1263 aioreq_pri 3; IO::AIO::aio_unlink $save; 1273 aioreq_pri 3; IO::AIO::aio_unlink $save;
1264 aioreq_pri 3; IO::AIO::aio_unlink "$save.pst"; 1274 aioreq_pri 3; IO::AIO::aio_unlink "$save.pst";
1265} 1275}
1266 1276
1277sub rename {
1278 my ($self, $new_path) = @_;
1279
1280 $self->unlink_save;
1281
1282 delete $cf::MAP{$self->path};
1283 $self->{path} = new cf::path $new_path;
1284 $self->path ($self->{path}->as_string);
1285 $cf::MAP{$self->path} = $self;
1286
1287 $self->save;
1288}
1289
1267sub reset { 1290sub reset {
1268 my ($self) = @_; 1291 my ($self) = @_;
1269 1292
1270 return if $self->players; 1293 return if $self->players;
1271 return if $self->{path}{user_rel};#d# 1294 return if $self->{path}{user_rel};#d#
1276 1299
1277 $_->clear_links_to ($self) for values %cf::MAP; 1300 $_->clear_links_to ($self) for values %cf::MAP;
1278 1301
1279 $self->unlink_save; 1302 $self->unlink_save;
1280 $self->destroy; 1303 $self->destroy;
1304}
1305
1306my $nuke_counter = "aaaa";
1307
1308sub nuke {
1309 my ($self) = @_;
1310
1311 $self->{deny_save} = 1;
1312 $self->reset_timeout (1);
1313 $self->rename ("{nuke}/" . ($nuke_counter++));
1314 $self->reset; # polite request, might not happen
1281} 1315}
1282 1316
1283sub customise_for { 1317sub customise_for {
1284 my ($map, $ob) = @_; 1318 my ($map, $ob) = @_;
1285 1319
1350 (ref $cf::CFG{"may_$access"} 1384 (ref $cf::CFG{"may_$access"}
1351 ? scalar grep $self->name eq $_, @{$cf::CFG{"may_$access"}} 1385 ? scalar grep $self->name eq $_, @{$cf::CFG{"may_$access"}}
1352 : $cf::CFG{"may_$access"}) 1386 : $cf::CFG{"may_$access"})
1353} 1387}
1354 1388
1389=item $player_object->enter_link
1390
1391Freezes the player and moves him/her to a special map (C<{link}>).
1392
1393The player should be reaosnably safe there for short amounts of time. You
1394I<MUST> call C<leave_link> as soon as possible, though.
1395
1396=item $player_object->leave_link ($map, $x, $y)
1397
1398Moves the player out of the specila link map onto the given map. If the
1399map is not valid (or omitted), the player will be moved back to the
1400location he/she was before the call to C<enter_link>, or, if that fails,
1401to the emergency map position.
1402
1403Might block.
1404
1405=cut
1406
1355sub cf::object::player::enter_link { 1407sub cf::object::player::enter_link {
1356 my ($self) = @_; 1408 my ($self) = @_;
1357 1409
1358 return if $self->map == $LINK_MAP; 1410 return if $self->map == $LINK_MAP;
1359 1411
1368 my ($self, $map, $x, $y) = @_; 1420 my ($self, $map, $x, $y) = @_;
1369 1421
1370 my $link_pos = delete $self->{_link_pos}; 1422 my $link_pos = delete $self->{_link_pos};
1371 1423
1372 unless ($map) { 1424 unless ($map) {
1373 $self->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
1374
1375 # restore original map position 1425 # restore original map position
1376 ($map, $x, $y) = @{ $link_pos || [] }; 1426 ($map, $x, $y) = @{ $link_pos || [] };
1377 $map = cf::map::find_map $map; 1427 $map = cf::map::find_map $map;
1378 1428
1379 unless ($map) { 1429 unless ($map) {
1411 my $map = cf::map::find_map $path->as_string; 1461 my $map = cf::map::find_map $path->as_string;
1412 $map = $map->customise_for ($self) if $map; 1462 $map = $map->customise_for ($self) if $map;
1413 1463
1414 warn "entering ", $map->path, " at ($x, $y)\n" 1464 warn "entering ", $map->path, " at ($x, $y)\n"
1415 if $map; 1465 if $map;
1466
1467 $map or $self->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
1416 1468
1417 $self->leave_link ($map, $x, $y); 1469 $self->leave_link ($map, $x, $y);
1418 })->prio (1); 1470 })->prio (1);
1419} 1471}
1420 1472
1831} 1883}
1832 1884
1833sub main { 1885sub main {
1834 # we must not ever block the main coroutine 1886 # we must not ever block the main coroutine
1835 local $Coro::idle = sub { 1887 local $Coro::idle = sub {
1836 Carp::cluck "FATAL: Coro::idle was called, major BUG\n";#d# 1888 Carp::cluck "FATAL: Coro::idle was called, major BUG, use cf::sync_job!\n";#d#
1837 (Coro::unblock_sub { 1889 (Coro::unblock_sub {
1838 Event::one_event; 1890 Event::one_event;
1839 })->(); 1891 })->();
1840 }; 1892 };
1841 1893

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines