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.93 by root, Fri Dec 22 03:43:05 2006 UTC vs.
Revision 1.98 by root, Fri Apr 6 19:17:25 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 return unless $self->{map}; # stop when destroyed
421
422 $self->set_texture ($id => $data)
423 if defined $data;
424
425 $self->bg_fetch;
426 };
427}
393 428
394sub load_map($$$) { 429sub load_map($$$) {
395 my ($self, $hash, $x, $y) = @_; 430 my ($self, $hash, $x, $y) = @_;
396 431
397 if (defined (my $data = $self->{mapcache}->get ($hash))) { 432 CFPlus::DB::get $self->{mapcache} => $hash, sub {
433 my ($data) = @_;
434
435 if (defined $data) {
398 $data = Compress::LZF::decompress $data; 436 $data = Compress::LZF::decompress $data;
399 #warn sprintf "LOADmap[%s,%d,%d] length %d\n", $hash, $x, $y, length $data;#d# 437 #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 438
404 $self->set_texture ($id => $data); 439 my $inprogress = @{ $self->{bg_fetch} || [] };
440 unshift @{ $self->{bg_fetch} }, $self->{map}->set_rect ($x, $y, $data);
441 $self->bg_fetch unless $inprogress;
405 } 442 }
406 } 443 };
407} 444}
408 445
409# hardcode /world/world_xxx_xxx map names, the savings are enourmous, 446# hardcode /world/world_xxx_xxx map names, the savings are enourmous,
410# (server resource,s latency, bandwidth), so this hack is warranted. 447# (server resource,s latency, bandwidth), so this hack is warranted.
411# the right fix is to make real tiled maps with an overview file 448# the right fix is to make real tiled maps with an overview file
525 $self->load_map ($hash, $x, $y); 562 $self->load_map ($hash, $x, $y);
526 $self->flood_fill (0, 0, 0, "", $hash, $flags); 563 $self->flood_fill (0, 0, 0, "", $hash, $flags);
527} 564}
528 565
529sub face_find { 566sub face_find {
530 my ($self, $facenum, $face) = @_; 567 my ($self, $facenum, $face, $cb) = @_;
531 568
532 my $hash = "$face->{chksum},$face->{name}"; 569 my $hash = "$face->{chksum},$face->{name}";
533 570
534 my $id = $self->{facemap}->get ($hash); 571 my $id = CFPlus::DB::get_tile_id_sync $hash;
535 572
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; 573 $face->{id} = $id;
559 $self->{map}->set_face ($facenum => $id);
560 $self->{faceid}[$facenum] = $id;#d# 574 $self->{faceid}[$facenum] = $id;
561 575
562 my $face = $self->{tilecache}->get ($id); 576 $self->{map}->set_tileid ($facenum => $id);
563 577
564 if ($face) { 578 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} 579}
573 580
574sub face_update { 581sub face_update {
575 my ($self, $facenum, $face, $changed) = @_; 582 my ($self, $facenum, $face, $changed) = @_;
576 583
577 $self->{tilecache}->put ($face->{id} => $face->{image}) if $changed; 584 CFPlus::DB::put tilecache => $face->{id} => $face->{image}, sub { }
585 if $changed;
578 586
579 $self->set_texture ($face->{id} => delete $face->{image}); 587 $self->set_texture ($face->{id} => delete $face->{image});
580} 588}
581 589
582sub set_texture { 590sub set_texture {
583 my ($self, $id, $data) = @_; 591 my ($self, $id, $data) = @_;
584 592
585 $self->{texture}[$id] ||= do { 593 $self->{texture}[$id] = my $tex =
586 my $tex =
587 new_from_image CFPlus::Texture 594 new_from_image CFPlus::Texture
588 $data, minify => 1, mipmap => 1; 595 $data, minify => 1, mipmap => 1;
589 596
590 $self->{map}->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}}); 597 $self->{map}->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}});
591 $self->{map_widget}->update; 598 $self->{map_widget}->update;
592
593 $tex
594 };
595} 599}
596 600
597sub sound_play { 601sub sound_play {
598 my ($self, $x, $y, $soundnum, $type) = @_; 602 my ($self, $x, $y, $soundnum, $type) = @_;
599 603
679} 683}
680 684
681sub setup { 685sub setup {
682 my ($self, $setup) = @_; 686 my ($self, $setup) = @_;
683 687
688 $self->{map_widget}->set_tilesize ($self->{tilesize});
684 $::MAP->resize ($self->{mapw}, $self->{maph}); 689 $::MAP->resize ($self->{mapw}, $self->{maph});
685} 690}
686 691
687sub addme_success { 692sub addme_success {
688 my ($self) = @_; 693 my ($self) = @_;
928 933
929 $self->update_server_info; 934 $self->update_server_info;
930 935
931 $self->send_command ("output-sync $::CFG->{output_sync}"); 936 $self->send_command ("output-sync $::CFG->{output_sync}");
932 $self->send_command ("output-count $::CFG->{output_count}"); 937 $self->send_command ("output-count $::CFG->{output_count}");
938 $self->send_command ("output-rate $::CFG->{output_rate}") if $::CFG->{output_rate} > 0;
933 $self->send_command ("pickup $::CFG->{pickup}"); 939 $self->send_command ("pickup $::CFG->{pickup}");
934} 940}
935 941
936sub buildat { 942sub buildat {
937 my ($self, $builditem, $x, $y) = @_; 943 my ($self, $builditem, $x, $y) = @_;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines