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.118 by root, Mon Jan 1 21:19:52 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
822 warn sprintf "loading %s (%d)\n",
823 $filename, length $data, scalar @{$av || []};#d#
812 return ($data, $av); 824 return ($data, $av);
813} 825}
814 826
815############################################################################# 827#############################################################################
816# command handling &c 828# command handling &c
1130 $map->instantiate; 1142 $map->instantiate;
1131 1143
1132 # per-player maps become, after loading, normal maps 1144 # per-player maps become, after loading, normal maps
1133 $map->per_player (0) if $path->{user_rel}; 1145 $map->per_player (0) if $path->{user_rel};
1134 } 1146 }
1147 #Coro::Timer::sleep 1;#d#
1135 1148
1136 $map->path ($key); 1149 $map->path ($key);
1137 $map->{path} = $path; 1150 $map->{path} = $path;
1151 $map->{last_save} = $cf::RUNTIME;
1138 $map->last_access ($cf::RUNTIME); 1152 $map->last_access ($cf::RUNTIME);
1139 1153
1140 if ($map->should_reset) { 1154 if ($map->should_reset) {
1141 $map->reset; 1155 $map->reset;
1142 $map = find_map $path; 1156 $map = find_map $path;
1203} 1217}
1204 1218
1205sub save { 1219sub save {
1206 my ($self) = @_; 1220 my ($self) = @_;
1207 1221
1222 $self->{last_save} = $cf::RUNTIME;
1223
1224 return unless $self->dirty;
1225
1208 my $save = $self->{path}->save_path; utf8::encode $save; 1226 my $save = $self->{path}->save_path; utf8::encode $save;
1209 my $uniq = $self->{path}->uniq_path; utf8::encode $uniq; 1227 my $uniq = $self->{path}->uniq_path; utf8::encode $uniq;
1210
1211 $self->{last_save} = $cf::RUNTIME;
1212
1213 return unless $self->dirty;
1214 1228
1215 $self->{load_path} = $save; 1229 $self->{load_path} = $save;
1216 1230
1217 return if $self->{deny_save}; 1231 return if $self->{deny_save};
1218 1232
1238 1252
1239sub reset_at { 1253sub reset_at {
1240 my ($self) = @_; 1254 my ($self) = @_;
1241 1255
1242 # TODO: safety, remove and allow resettable per-player maps 1256 # TODO: safety, remove and allow resettable per-player maps
1243 return 1e100 if $self->{path}{user_rel}; 1257 return 1e99 if $self->{path}{user_rel};
1244 return 1e100 if $self->{deny_reset}; 1258 return 1e99 if $self->{deny_reset};
1245 1259
1246 my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access; 1260 my $time = $self->fixed_resettime ? $self->{instantiate_time} : $self->last_access;
1247 my $to = $self->reset_timeout || $DEFAULT_RESET; 1261 my $to = List::Util::min $MAX_RESET, $self->reset_timeout || $DEFAULT_RESET;
1248 $to = $MAX_RESET if $to > $MAX_RESET;
1249 1262
1250 $time + $to 1263 $time + $to
1251} 1264}
1252 1265
1253sub should_reset { 1266sub should_reset {
1262 utf8::encode (my $save = $self->{path}->save_path); 1275 utf8::encode (my $save = $self->{path}->save_path);
1263 aioreq_pri 3; IO::AIO::aio_unlink $save; 1276 aioreq_pri 3; IO::AIO::aio_unlink $save;
1264 aioreq_pri 3; IO::AIO::aio_unlink "$save.pst"; 1277 aioreq_pri 3; IO::AIO::aio_unlink "$save.pst";
1265} 1278}
1266 1279
1280sub rename {
1281 my ($self, $new_path) = @_;
1282
1283 $self->unlink_save;
1284
1285 delete $cf::MAP{$self->path};
1286 $self->{path} = new cf::path $new_path;
1287 $self->path ($self->{path}->as_string);
1288 $cf::MAP{$self->path} = $self;
1289
1290 $self->save;
1291}
1292
1267sub reset { 1293sub reset {
1268 my ($self) = @_; 1294 my ($self) = @_;
1269 1295
1270 return if $self->players; 1296 return if $self->players;
1271 return if $self->{path}{user_rel};#d# 1297 return if $self->{path}{user_rel};#d#
1276 1302
1277 $_->clear_links_to ($self) for values %cf::MAP; 1303 $_->clear_links_to ($self) for values %cf::MAP;
1278 1304
1279 $self->unlink_save; 1305 $self->unlink_save;
1280 $self->destroy; 1306 $self->destroy;
1307}
1308
1309my $nuke_counter = "aaaa";
1310
1311sub nuke {
1312 my ($self) = @_;
1313
1314 $self->{deny_save} = 1;
1315 $self->reset_timeout (1);
1316 $self->rename ("{nuke}/" . ($nuke_counter++));
1317 $self->reset; # polite request, might not happen
1281} 1318}
1282 1319
1283sub customise_for { 1320sub customise_for {
1284 my ($map, $ob) = @_; 1321 my ($map, $ob) = @_;
1285 1322
1350 (ref $cf::CFG{"may_$access"} 1387 (ref $cf::CFG{"may_$access"}
1351 ? scalar grep $self->name eq $_, @{$cf::CFG{"may_$access"}} 1388 ? scalar grep $self->name eq $_, @{$cf::CFG{"may_$access"}}
1352 : $cf::CFG{"may_$access"}) 1389 : $cf::CFG{"may_$access"})
1353} 1390}
1354 1391
1392=item $player_object->enter_link
1393
1394Freezes the player and moves him/her to a special map (C<{link}>).
1395
1396The player should be reaosnably safe there for short amounts of time. You
1397I<MUST> call C<leave_link> as soon as possible, though.
1398
1399=item $player_object->leave_link ($map, $x, $y)
1400
1401Moves the player out of the specila link map onto the given map. If the
1402map is not valid (or omitted), the player will be moved back to the
1403location he/she was before the call to C<enter_link>, or, if that fails,
1404to the emergency map position.
1405
1406Might block.
1407
1408=cut
1409
1355sub cf::object::player::enter_link { 1410sub cf::object::player::enter_link {
1356 my ($self) = @_; 1411 my ($self) = @_;
1357 1412
1358 return if $self->map == $LINK_MAP; 1413 return if $self->map == $LINK_MAP;
1359 1414
1368 my ($self, $map, $x, $y) = @_; 1423 my ($self, $map, $x, $y) = @_;
1369 1424
1370 my $link_pos = delete $self->{_link_pos}; 1425 my $link_pos = delete $self->{_link_pos};
1371 1426
1372 unless ($map) { 1427 unless ($map) {
1373 $self->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
1374
1375 # restore original map position 1428 # restore original map position
1376 ($map, $x, $y) = @{ $link_pos || [] }; 1429 ($map, $x, $y) = @{ $link_pos || [] };
1377 $map = cf::map::find_map $map; 1430 $map = cf::map::find_map $map;
1378 1431
1379 unless ($map) { 1432 unless ($map) {
1394 1447
1395 $self->activate_recursive; 1448 $self->activate_recursive;
1396 $self->enter_map ($map, $x, $y); 1449 $self->enter_map ($map, $x, $y);
1397} 1450}
1398 1451
1399=item $player_object->goto_map ($map, $x, $y) 1452=item $player_object->goto_map ($path, $x, $y)
1400 1453
1401=cut 1454=cut
1402 1455
1403sub cf::object::player::goto_map { 1456sub cf::object::player::goto_map {
1404 my ($self, $path, $x, $y) = @_; 1457 my ($self, $path, $x, $y) = @_;
1411 my $map = cf::map::find_map $path->as_string; 1464 my $map = cf::map::find_map $path->as_string;
1412 $map = $map->customise_for ($self) if $map; 1465 $map = $map->customise_for ($self) if $map;
1413 1466
1414 warn "entering ", $map->path, " at ($x, $y)\n" 1467 warn "entering ", $map->path, " at ($x, $y)\n"
1415 if $map; 1468 if $map;
1469
1470 $map or $self->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
1416 1471
1417 $self->leave_link ($map, $x, $y); 1472 $self->leave_link ($map, $x, $y);
1418 })->prio (1); 1473 })->prio (1);
1419} 1474}
1420 1475
1831} 1886}
1832 1887
1833sub main { 1888sub main {
1834 # we must not ever block the main coroutine 1889 # we must not ever block the main coroutine
1835 local $Coro::idle = sub { 1890 local $Coro::idle = sub {
1836 Carp::cluck "FATAL: Coro::idle was called, major BUG\n";#d# 1891 Carp::cluck "FATAL: Coro::idle was called, major BUG, use cf::sync_job!\n";#d#
1837 (Coro::unblock_sub { 1892 (Coro::unblock_sub {
1838 Event::one_event; 1893 Event::one_event;
1839 })->(); 1894 })->();
1840 }; 1895 };
1841 1896

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines