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.141 by root, Fri Jan 5 20:08:53 2007 UTC vs.
Revision 1.144 by root, Sun Jan 7 18:01:10 2007 UTC

47our %CFG; 47our %CFG;
48 48
49our $UPTIME; $UPTIME ||= time; 49our $UPTIME; $UPTIME ||= time;
50our $RUNTIME; 50our $RUNTIME;
51 51
52our %PLAYER; # all users
52our %MAP; # all maps 53our %MAP; # all maps
53our $LINK_MAP; # the special {link} map 54our $LINK_MAP; # the special {link} map
54our $RANDOM_MAPS = cf::localdir . "/random"; 55our $RANDOM_MAPS = cf::localdir . "/random";
55our %EXT_CORO; 56our %EXT_CORO; # coroutines bound to extensions
56 57
57binmode STDOUT; 58binmode STDOUT;
58binmode STDERR; 59binmode STDERR;
59 60
60# read virtual server time, if available 61# read virtual server time, if available
1071 1072
1072=head2 CORE EXTENSIONS 1073=head2 CORE EXTENSIONS
1073 1074
1074Functions and methods that extend core crossfire objects. 1075Functions and methods that extend core crossfire objects.
1075 1076
1077=cut
1078
1079package cf::player;
1080
1076=head3 cf::player 1081=head3 cf::player
1077 1082
1078=over 4 1083=over 4
1079 1084
1080=item cf::player::exists $login 1085=item cf::player::find $login
1081 1086
1082Returns true when the given account exists. 1087Returns the given player object, loading it if necessary (might block).
1083 1088
1084=cut 1089=cut
1085 1090
1086sub cf::player::exists($) { 1091sub path($) {
1087 cf::player::find $_[0] 1092 sprintf "%s/%s/%s/%s.pl",
1088 or -f sprintf "%s/%s/%s/%s.pl", cf::localdir, cf::playerdir, ($_[0]) x 2; 1093 cf::localdir, cf::playerdir,
1094 (ref $_[0] ? $_[0]->ob->name : $_[0]) x 2
1095}
1096
1097sub find_active($) {
1098 $cf::PLAYER{$_[0]}
1099 and $cf::PLAYER{$_[0]}->active
1100 and $cf::PLAYER{$_[0]}
1101}
1102
1103sub exists($) {
1104 my ($login) = @_;
1105
1106 $cf::PLAYER{$login}
1107 or cf::sync_job { !aio_stat $login }
1108}
1109
1110sub find($) {
1111 return $cf::PLAYER{$_[0]} || do {
1112 my $login = $_[0];
1113
1114 my $guard = cf::lock_acquire "user_find:$login";
1115
1116 $cf::PLAYER{$login} ||= (load_pl path $login or return);
1117 };
1118}
1119
1120sub save($) {
1121 my ($pl) = @_;
1122
1123 return if $pl->{deny_save};
1124
1125 my $path = path $pl;
1126 my $guard = cf::lock_acquire "user_save:$path";
1127
1128 return if $pl->{deny_save};
1129 $pl->{last_save} = $cf::RUNTIME;
1130
1131 Coro::cede;
1132 $pl->save_pl ($path);
1133 Coro::cede;
1134}
1135
1136sub new($) {
1137 my ($login) = @_;
1138
1139 my $self = create;
1140
1141 $self->ob->name ($login);
1142 $self->{deny_save} = 1;
1143
1144 $cf::PLAYER{$login} = $self;
1145
1146 $self
1089} 1147}
1090 1148
1091=item $player->ext_reply ($msgid, $msgtype, %msg) 1149=item $player->ext_reply ($msgid, $msgtype, %msg)
1092 1150
1093Sends an ext reply to the player. 1151Sends an ext reply to the player.
1094 1152
1095=cut 1153=cut
1096 1154
1097sub cf::player::ext_reply($$$%) { 1155sub ext_reply($$$%) {
1098 my ($self, $id, %msg) = @_; 1156 my ($self, $id, %msg) = @_;
1099 1157
1100 $msg{msgid} = $id; 1158 $msg{msgid} = $id;
1101 1159
1102 $self->send ("ext " . to_json \%msg); 1160 $self->send ("ext " . cf::to_json \%msg);
1103} 1161}
1162
1163package cf;
1104 1164
1105=back 1165=back
1106 1166
1107 1167
1108=head3 cf::map 1168=head3 cf::map
1304 1364
1305 return if $self->{deny_save}; 1365 return if $self->{deny_save};
1306 1366
1307 local $self->{last_access} = $self->last_access;#d# 1367 local $self->{last_access} = $self->last_access;#d#
1308 1368
1369 cf::async {
1370 $_->contr->save for $self->players;
1371 };
1372
1309 if ($uniq) { 1373 if ($uniq) {
1310 $self->save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS); 1374 $self->save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS);
1311 $self->save_objects ($uniq, cf::IO_UNIQUES); 1375 $self->save_objects ($uniq, cf::IO_UNIQUES);
1312 } else { 1376 } else {
1313 $self->save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES); 1377 $self->save_objects ($save, cf::IO_HEADER | cf::IO_OBJECTS | cf::IO_UNIQUES);
1410} 1474}
1411 1475
1412sub emergency_save { 1476sub emergency_save {
1413 my $freeze_guard = cf::freeze_mainloop; 1477 my $freeze_guard = cf::freeze_mainloop;
1414 1478
1415 warn "enter emergency map save\n"; 1479 warn "enter emergency perl save\n";
1416 1480
1417 cf::sync_job { 1481 cf::sync_job {
1482 warn "begin emergency player save\n";
1483 $_->save for values %cf::PLAYER;
1484 warn "end emergency player save\n";
1485
1418 warn "begin emergency map save\n"; 1486 warn "begin emergency map save\n";
1419 $_->save for values %cf::MAP; 1487 $_->save for values %cf::MAP;
1488 warn "end emergency map save\n";
1420 }; 1489 };
1421 1490
1422 warn "end emergency map save\n"; 1491 warn "leave emergency perl save\n";
1423} 1492}
1424 1493
1425package cf; 1494package cf;
1426 1495
1427=back 1496=back
1526 ($x, $y) = ($map->enter_x, $map->enter_y) 1595 ($x, $y) = ($map->enter_x, $map->enter_y)
1527 if $x <=0 && $y <= 0; 1596 if $x <=0 && $y <= 0;
1528 1597
1529 $map->load; 1598 $map->load;
1530 1599
1600 return unless $self->contr->active;
1531 $self->activate_recursive; 1601 $self->activate_recursive;
1532 $self->enter_map ($map, $x, $y); 1602 $self->enter_map ($map, $x, $y);
1533} 1603}
1534 1604
1535cf::player->attach ( 1605cf::player->attach (
1547 my ($pl) = @_; 1617 my ($pl) = @_;
1548 1618
1549 # try to abort aborted map switching on player login :) 1619 # try to abort aborted map switching on player login :)
1550 # should happen only on crashes 1620 # should happen only on crashes
1551 if ($pl->ob->{_link_pos}) { 1621 if ($pl->ob->{_link_pos}) {
1552
1553 $pl->ob->enter_link; 1622 $pl->ob->enter_link;
1554 (async { 1623 (async {
1555 # we need this sleep as the login has a concurrent enter_exit running 1624 # we need this sleep as the login has a concurrent enter_exit running
1556 # and this sleep increases chances of the player not ending up in scorn 1625 # and this sleep increases chances of the player not ending up in scorn
1557 $pl->ob->reply (undef, 1626 $pl->ob->reply (undef,
2103 cf::load_extensions; 2172 cf::load_extensions;
2104 2173
2105 # reattach attachments to objects 2174 # reattach attachments to objects
2106 warn "reattach"; 2175 warn "reattach";
2107 _global_reattach; 2176 _global_reattach;
2177 reattach $_ for values %MAP;
2108 }; 2178 };
2109 2179
2110 if ($@) { 2180 if ($@) {
2111 warn $@; 2181 warn $@;
2112 warn "error while reloading, exiting."; 2182 warn "error while reloading, exiting.";
2128 $LINK_MAP->{path} = bless { path => "{link}" }, "cf::path"; 2198 $LINK_MAP->{path} = bless { path => "{link}" }, "cf::path";
2129 $LINK_MAP->in_memory (MAP_IN_MEMORY); 2199 $LINK_MAP->in_memory (MAP_IN_MEMORY);
2130 2200
2131 # dirty hack because... archetypes are not yet loaded 2201 # dirty hack because... archetypes are not yet loaded
2132 Event->timer ( 2202 Event->timer (
2133 after => 2, 2203 after => 10,
2134 cb => sub { 2204 cb => sub {
2135 $_[0]->w->cancel; 2205 $_[0]->w->cancel;
2136 2206
2137 # provide some exits "home" 2207 # provide some exits "home"
2138 my $exit = cf::object::new "exit"; 2208 my $exit = cf::object::new "exit";

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines