ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/ext/login.ext
(Generate patch)

Comparing deliantra/server/ext/login.ext (file contents):
Revision 1.11 by root, Sun Jan 7 02:39:14 2007 UTC vs.
Revision 1.18 by root, Mon Jan 8 14:29:05 2007 UTC

158 nuke_str $pass; 158 nuke_str $pass;
159 # password matches, wonderful 159 # password matches, wonderful
160 my $pl = cf::player::find $user or next; 160 my $pl = cf::player::find $user or next;
161 $pl->connect ($ns); 161 $pl->connect ($ns);
162 check_clean_save $pl; 162 check_clean_save $pl;
163 $pl->{clean_save} = 1;
163 last; 164 last;
164 } elsif (can_cleanup $buf, $mtime) { 165 } elsif (can_cleanup $buf, $mtime) {
165 Coro::Timer::sleep 1; 166 Coro::Timer::sleep 1;
166 167
167 $ns->send_drawinfo ( 168 $ns->send_drawinfo (
255 last; 256 last;
256 } 257 }
257 }); 258 });
258} 259}
259 260
260# "Quitting will delete your character PERMANENTLY. If you are sure you want to do this, then use the quit_character command instead of quit." 261cf::register_command quit => sub {
261# "Quitting will delete your character.\nAre you sure you want to quit (y/n):" 262 my ($ob, $arg) = @_;
262# quit, quit_character, save 263
264 $ob->reply (undef,
265 "Quitting will delete your character PERMANENTLY: It will be gone forever and any progress will be lost. "
266 . "If you are sure you want to do this, then use the quit_character command instead of quit.",
267 cf::NDI_UNIQUE | cf::NDI_RED);
268};
269
270cf::register_command quit_character => sub {
271 my ($ob, $arg) = @_;
272
273 my $pl = $ob->contr;
274
275 $pl->ns->query (cf::CS_QUERY_SINGLECHAR, "Do you want to PERMANENTLY delete your character and all associated data (y/n)?", sub {
276 if ($_[0] !~ /^[yY]/) {
277 $ob->reply (undef,
278 "Ok, not not quitting then.",
279 cf::NDI_UNIQUE | cf::NDI_RED);
280 } else {
281 $ob->reply (undef,
282 "Ok, quitting, hope to see you again.",
283 cf::NDI_UNIQUE | cf::NDI_RED);
284 $pl->ns->flush;
285 $pl->quit_character;
286 }
287 });
288};
263 289
264cf::object->attach ( 290cf::object->attach (
265 type => cf::SAVEBED, 291 type => cf::SAVEBED,
266 on_apply => sub { 292 on_apply => sub {
267 my ($bed, $ob) = @_; 293 my ($bed, $ob) = @_;
268 294
269 return cf::override 0 unless $ob->type == cf::PLAYER; 295 return cf::override 0 unless $ob->type == cf::PLAYER;
270 296
271 my $pl = $ob->pl; 297 my $pl = $ob->contr;
272 298
273 # update respawn position 299 # update respawn position
274 $pl->savebed ($bed->map->path, $bed->x, $bed->y); 300 $pl->savebed ($bed->map->path, $bed->x, $bed->y);
275 301
276 $pl->killer ("left"); 302 $pl->killer ("left");
282 if ($_[0] !~ /^[yY]/) { 308 if ($_[0] !~ /^[yY]/) {
283 $pl->invoke (cf::EVENT_PLAYER_LOGOUT, 1); 309 $pl->invoke (cf::EVENT_PLAYER_LOGOUT, 1);
284 $pl->deactivate; 310 $pl->deactivate;
285 $pl->ns->destroy; 311 $pl->ns->destroy;
286 } else { 312 } else {
287 cf::async { 313 cf::async { $pl->save };
288 $pl->{clean_save} = 1;
289 $pl->save;
290 };
291 } 314 }
292 }); 315 });
293 }, 316 },
294); 317);
295 318
306 329
307 if ($cleanly) { 330 if ($cleanly) {
308 $_->ob->message ("$name left the game.", cf::NDI_DK_ORANGE | cf::NDI_UNIQUE) for cf::player::list; 331 $_->ob->message ("$name left the game.", cf::NDI_DK_ORANGE | cf::NDI_UNIQUE) for cf::player::list;
309 } else { 332 } else {
310 $_->ob->message ("$name uncerimoniously disconnected.", cf::NDI_DK_ORANGE | cf::NDI_UNIQUE) for cf::player::list; 333 $_->ob->message ("$name uncerimoniously disconnected.", cf::NDI_DK_ORANGE | cf::NDI_UNIQUE) for cf::player::list;
334 delete $pl->{clean_save};
311 } 335 }
312 }, 336 },
313); 337);
314 338
315cf::client->attach ( 339cf::client->attach (
317); 341);
318 342
319############################################################################# 343#############################################################################
320 344
321our $SCHEDULE_INTERVAL = 10; # time the player scheduler sleeps between runs 345our $SCHEDULE_INTERVAL = 10; # time the player scheduler sleeps between runs
322our $SWAP_TIMEOUT = 30; # time after which an unused player is evicted form memory
323our $SAVE_TIMEOUT = 20; # save players every n seconds 346our $SAVE_TIMEOUT = 200; # save players every n seconds
324our $SAVE_INTERVAL = 0.1; # save at max. one player every $SAVE_INTERVAL 347our $SAVE_INTERVAL = 0.1; # save at max. one player every $SAVE_INTERVAL
325 348
326our $SCHEDULER = cf::async_ext { 349our $SCHEDULER = cf::async_ext {
327 while () { 350 while () {
328 Coro::Timer::sleep $SCHEDULE_INTERVAL; 351 Coro::Timer::sleep $SCHEDULE_INTERVAL;
340 eval { 363 eval {
341 if ($pl->{last_save} + $SAVE_TIMEOUT <= $cf::RUNTIME) { 364 if ($pl->{last_save} + $SAVE_TIMEOUT <= $cf::RUNTIME) {
342 $pl->save; 365 $pl->save;
343 Coro::Timer::sleep $SAVE_INTERVAL; 366 Coro::Timer::sleep $SAVE_INTERVAL;
344 } 367 }
368
369 unless ($pl->active) {
370 # check refcounts, this is tricky and needs to be adjusted to fit server internals
371 my $ob = $pl->ob;
372 Scalar::Util::weaken $pl;
373 Scalar::Util::weaken $ob;
374 my $a_ = $pl->refcnt;
375 my $b_ = $ob->refcnt;
376 my $pl_ref = $pl->refcnt_cnt;
377 my $ob_ref = $ob->refcnt_cnt;
378
379 if ($pl_ref == 2 && $ob_ref == 1) {
380 warn "player-scheduler destroy ", $ob->name;#d#
381 #delete $cf::PLAYER{$ob->name};
382 ## pl_ref == one from object + one from cf::PLAYER
383 ## ob_ref == one from simply being an object
384 #$ob->destroy;
385 #$pl->destroy;
386 } else {
387 warn "player-scheduler refcnt ", $ob->name, " $pl_ref,$a_ $ob_ref,$b_\n";#d#
388 }
389 }
345 }; 390 };
346 warn $@ if $@; 391 warn $@ if $@;
347 Coro::cede; 392 Coro::cede;
348 }; 393 };
349 } 394 }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines