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.113 by root, Mon Jan 1 15:32:40 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;
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 {
1269 1282
1270 $self->unlink_save; 1283 $self->unlink_save;
1271 1284
1272 delete $cf::MAP{$self->path}; 1285 delete $cf::MAP{$self->path};
1273 $self->{path} = new cf::path $new_path; 1286 $self->{path} = new cf::path $new_path;
1274 $self->path ($self->{path}->path); 1287 $self->path ($self->{path}->as_string);
1275 $cf::MAP{$self->path} = $self; 1288 $cf::MAP{$self->path} = $self;
1276 1289
1277 $self->save; 1290 $self->save;
1278} 1291}
1279 1292
1289 1302
1290 $_->clear_links_to ($self) for values %cf::MAP; 1303 $_->clear_links_to ($self) for values %cf::MAP;
1291 1304
1292 $self->unlink_save; 1305 $self->unlink_save;
1293 $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
1294} 1318}
1295 1319
1296sub customise_for { 1320sub customise_for {
1297 my ($map, $ob) = @_; 1321 my ($map, $ob) = @_;
1298 1322
1363 (ref $cf::CFG{"may_$access"} 1387 (ref $cf::CFG{"may_$access"}
1364 ? scalar grep $self->name eq $_, @{$cf::CFG{"may_$access"}} 1388 ? scalar grep $self->name eq $_, @{$cf::CFG{"may_$access"}}
1365 : $cf::CFG{"may_$access"}) 1389 : $cf::CFG{"may_$access"})
1366} 1390}
1367 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
1368sub cf::object::player::enter_link { 1410sub cf::object::player::enter_link {
1369 my ($self) = @_; 1411 my ($self) = @_;
1370 1412
1371 return if $self->map == $LINK_MAP; 1413 return if $self->map == $LINK_MAP;
1372 1414
1381 my ($self, $map, $x, $y) = @_; 1423 my ($self, $map, $x, $y) = @_;
1382 1424
1383 my $link_pos = delete $self->{_link_pos}; 1425 my $link_pos = delete $self->{_link_pos};
1384 1426
1385 unless ($map) { 1427 unless ($map) {
1386 $self->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
1387
1388 # restore original map position 1428 # restore original map position
1389 ($map, $x, $y) = @{ $link_pos || [] }; 1429 ($map, $x, $y) = @{ $link_pos || [] };
1390 $map = cf::map::find_map $map; 1430 $map = cf::map::find_map $map;
1391 1431
1392 unless ($map) { 1432 unless ($map) {
1407 1447
1408 $self->activate_recursive; 1448 $self->activate_recursive;
1409 $self->enter_map ($map, $x, $y); 1449 $self->enter_map ($map, $x, $y);
1410} 1450}
1411 1451
1412=item $player_object->goto_map ($map, $x, $y) 1452=item $player_object->goto_map ($path, $x, $y)
1413 1453
1414=cut 1454=cut
1415 1455
1416sub cf::object::player::goto_map { 1456sub cf::object::player::goto_map {
1417 my ($self, $path, $x, $y) = @_; 1457 my ($self, $path, $x, $y) = @_;
1424 my $map = cf::map::find_map $path->as_string; 1464 my $map = cf::map::find_map $path->as_string;
1425 $map = $map->customise_for ($self) if $map; 1465 $map = $map->customise_for ($self) if $map;
1426 1466
1427 warn "entering ", $map->path, " at ($x, $y)\n" 1467 warn "entering ", $map->path, " at ($x, $y)\n"
1428 if $map; 1468 if $map;
1469
1470 $map or $self->message ("The exit is closed", cf::NDI_UNIQUE | cf::NDI_RED);
1429 1471
1430 $self->leave_link ($map, $x, $y); 1472 $self->leave_link ($map, $x, $y);
1431 })->prio (1); 1473 })->prio (1);
1432} 1474}
1433 1475
1844} 1886}
1845 1887
1846sub main { 1888sub main {
1847 # we must not ever block the main coroutine 1889 # we must not ever block the main coroutine
1848 local $Coro::idle = sub { 1890 local $Coro::idle = sub {
1849 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#
1850 (Coro::unblock_sub { 1892 (Coro::unblock_sub {
1851 Event::one_event; 1893 Event::one_event;
1852 })->(); 1894 })->();
1853 }; 1895 };
1854 1896

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines