ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/Deliantra-Client/DC/Protocol.pm
(Generate patch)

Comparing deliantra/Deliantra-Client/DC/Protocol.pm (file contents):
Revision 1.94 by root, Fri Mar 16 02:33:49 2007 UTC vs.
Revision 1.97 by root, Fri Apr 6 08:09:43 2007 UTC

4use strict; 4use strict;
5 5
6use Crossfire::Protocol::Constants; 6use Crossfire::Protocol::Constants;
7 7
8use CFPlus; 8use CFPlus;
9use CFPlus::DB;
9use CFPlus::UI; 10use CFPlus::UI;
10use CFPlus::Pod; 11use CFPlus::Pod;
11use CFPlus::Macro; 12use CFPlus::Macro;
12use CFPlus::Item; 13use CFPlus::Item;
13 14
37 for @args; 38 for @args;
38 39
39 map ["$cmd$_", $text], 40 map ["$cmd$_", $text],
40 sort { (length $a) <=> (length $b) } 41 sort { (length $a) <=> (length $b) }
41 @args 42 @args
42 } sort { $a->{par} <=> $b->{par} } 43 } sort { $a->{par} <=> $b->{par} }
43 CFPlus::Pod::find command => "*"; 44 CFPlus::Pod::find command => "*";
44 45
46 $self->connect_ext (event_capabilities => sub {
47 my ($cap) = @_;
48
49 if (my $ts = $cap->{tileset}) {
50 if (my ($default) = grep $_->[2] & 1, @$ts) {
51 $self->{tileset} = $default;
52 $self->{tilesize} = $default->[3];
53 $self->setup_req (tileset => $default->[0]);
54
55 my $w = int $self->{mapw} * 32 / $self->{tilesize};
56 my $h = int $self->{maph} * 32 / $self->{tilesize};
57
58 $self->setup_req (mapsize => "${w}x${h}");
59 }
60 }
61 });
62
45 $self->{map_widget}->add_command (@$_) 63 $self->{map_widget}->add_command (@$_)
46 for @cmd_help; 64 for @cmd_help;
47
48 $self->{noface} = new_from_file CFPlus::Texture
49 CFPlus::find_rcfile "noface.png", minify => 1, mipmap => 1;
50 65
51 { 66 {
52 $self->{dialogue} = my $tex = new_from_file CFPlus::Texture 67 $self->{dialogue} = my $tex = new_from_file CFPlus::Texture
53 CFPlus::find_rcfile "dialogue.png", minify => 1, mipmap => 1; 68 CFPlus::find_rcfile "dialogue.png", minify => 1, mipmap => 1;
54 $self->{map}->set_texture (1, @$tex{qw(name w h s t)}, @{$tex->{minified}}); 69 $self->{map}->set_texture (1, @$tex{qw(name w h s t)}, @{$tex->{minified}});
55 } 70 }
56 71
72 {
73 $self->{noface} = my $tex = new_from_file CFPlus::Texture
74 CFPlus::find_rcfile "noface.png", minify => 1, mipmap => 1;
75 $self->{map}->set_texture (2, @$tex{qw(name w h s t)}, @{$tex->{minified}});
76 }
77
57 $self->{open_container} = 0; 78 $self->{open_container} = 0;
58 79
59 # "global"
60 $self->{tilecache} = CFPlus::db_table "tilecache"
61 or die "tilecache: unable to open database table";
62 $self->{facemap} = CFPlus::db_table "facemap"
63 or die "facemap: unable to open database table";
64
65 # per server 80 # per server
66 $self->{mapcache} = CFPlus::db_table "mapcache_$self->{host}_$self->{port}" 81 $self->{mapcache} = "mapcache_$self->{host}_$self->{port}";
67 or die "mapcache_$self->{host}_$self->{port}: unable to open database table";
68 82
69 $self 83 $self
70} 84}
71 85
72sub logprint { 86sub logprint {
374 or return; 388 or return;
375 389
376 my ($hash, $x, $y, $w, $h) = @$map_info; 390 my ($hash, $x, $y, $w, $h) = @$map_info;
377 391
378 my $data = $self->{map}->get_rect ($x, $y, $w, $h); 392 my $data = $self->{map}->get_rect ($x, $y, $w, $h);
379 $self->{mapcache}->put ($hash => Compress::LZF::compress $data); 393 CFPlus::DB::put $self->{mapcache} => $hash => Compress::LZF::compress $data, sub { };
380 #warn sprintf "SAVEmap[%s] length %d\n", $hash, length $data;#d# 394 #warn sprintf "SAVEmap[%s] length %d\n", $hash, length $data;#d#
381} 395}
382 396
383sub map_clear { 397sub map_clear {
384 my ($self) = @_; 398 my ($self) = @_;
388 402
389 $self->{map}->clear; 403 $self->{map}->clear;
390 delete $self->{map_widget}{magicmap}; 404 delete $self->{map_widget}{magicmap};
391} 405}
392 406
407sub bg_fetch {
408 my ($self) = @_;
409
410 my $id;
411
412 do {
413 $id = pop @{$self->{bg_fetch}}
414 or return;
415 } while $self->{texture}[$id];
416
417 CFPlus::DB::get tilecache => $id, sub {
418 my ($data) = @_;
419
420 $self->set_texture ($id => $data)
421 if defined $data;
422
423 $self->bg_fetch;
424 };
425}
393 426
394sub load_map($$$) { 427sub load_map($$$) {
395 my ($self, $hash, $x, $y) = @_; 428 my ($self, $hash, $x, $y) = @_;
396 429
397 if (defined (my $data = $self->{mapcache}->get ($hash))) { 430 CFPlus::DB::get $self->{mapcache} => $hash, sub {
431 my ($data) = @_;
432
433 if (defined $data) {
398 $data = Compress::LZF::decompress $data; 434 $data = Compress::LZF::decompress $data;
399 #warn sprintf "LOADmap[%s,%d,%d] length %d\n", $hash, $x, $y, length $data;#d# 435 #warn sprintf "LOADmap[%s,%d,%d] length %d\n", $hash, $x, $y, length $data;#d#
400 for my $id ($self->{map}->set_rect ($x, $y, $data)) {
401 my $data = $self->{tilecache}->get ($id)
402 or next;
403 436
404 $self->set_texture ($id => $data); 437 my $inprogress = @{ $self->{bg_fetch} || [] };
438 push @{ $self->{bg_fetch} }, $self->{map}->set_rect ($x, $y, $data);
439 $self->bg_fetch unless $inprogress;
405 } 440 }
406 } 441 };
407} 442}
408 443
409# hardcode /world/world_xxx_xxx map names, the savings are enourmous, 444# hardcode /world/world_xxx_xxx map names, the savings are enourmous,
410# (server resource,s latency, bandwidth), so this hack is warranted. 445# (server resource,s latency, bandwidth), so this hack is warranted.
411# the right fix is to make real tiled maps with an overview file 446# the right fix is to make real tiled maps with an overview file
525 $self->load_map ($hash, $x, $y); 560 $self->load_map ($hash, $x, $y);
526 $self->flood_fill (0, 0, 0, "", $hash, $flags); 561 $self->flood_fill (0, 0, 0, "", $hash, $flags);
527} 562}
528 563
529sub face_find { 564sub face_find {
530 my ($self, $facenum, $face) = @_; 565 my ($self, $facenum, $face, $cb) = @_;
531 566
532 my $hash = "$face->{chksum},$face->{name}"; 567 my $hash = "$face->{chksum},$face->{name}";
533 568
534 my $id = $self->{facemap}->get ($hash); 569 my $id = CFPlus::DB::get_tile_id_sync $hash;
535 570
536 unless ($id) {
537 # create new id for face
538 # I love transactions
539 for (1..100) {
540 my $txn = $CFPlus::DB_ENV->txn_begin;
541 my $status = $self->{facemap}->db_get (id => $id);
542 if ($status == 0 || $status == BerkeleyDB::DB_NOTFOUND) {
543 $id = ($id || 64) + 1;
544 if ($self->{facemap}->put (id => $id) == 0
545 && $self->{facemap}->put ($hash => $id) == 0) {
546 $txn->txn_commit;
547
548 goto gotid;
549 }
550 }
551 $txn->txn_abort;
552 }
553
554 CFPlus::fatal "maximum number of transaction retries reached - database problems?";
555 }
556
557gotid:
558 $face->{id} = $id; 571 $face->{id} = $id;
559 $self->{map}->set_face ($facenum => $id);
560 $self->{faceid}[$facenum] = $id;#d# 572 $self->{faceid}[$facenum] = $id;
561 573
562 my $face = $self->{tilecache}->get ($id); 574 $self->{map}->set_tileid ($facenum => $id);
563 575
564 if ($face) { 576 CFPlus::DB::get tilecache => $id, $cb;
565 #$self->face_prefetch;
566 $face
567 } else {
568 my $tex = $self->{noface};
569 $self->{map}->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}});
570 undef
571 };
572} 577}
573 578
574sub face_update { 579sub face_update {
575 my ($self, $facenum, $face, $changed) = @_; 580 my ($self, $facenum, $face, $changed) = @_;
576 581
577 $self->{tilecache}->put ($face->{id} => $face->{image}) if $changed; 582 CFPlus::DB::put tilecache => $face->{id} => $face->{image}, sub { }
583 if $changed;
578 584
579 $self->set_texture ($face->{id} => delete $face->{image}); 585 $self->set_texture ($face->{id} => delete $face->{image});
580} 586}
581 587
582sub set_texture { 588sub set_texture {
679} 685}
680 686
681sub setup { 687sub setup {
682 my ($self, $setup) = @_; 688 my ($self, $setup) = @_;
683 689
690 $self->{map_widget}->set_tilesize ($self->{tilesize});
684 $::MAP->resize ($self->{mapw}, $self->{maph}); 691 $::MAP->resize ($self->{mapw}, $self->{maph});
685} 692}
686 693
687sub addme_success { 694sub addme_success {
688 my ($self) = @_; 695 my ($self) = @_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines