--- deliantra/Deliantra-Client/DC/Protocol.pm 2007/04/04 02:43:30 1.95 +++ deliantra/Deliantra-Client/DC/Protocol.pm 2007/04/06 07:45:35 1.96 @@ -6,6 +6,7 @@ use Crossfire::Protocol::Constants; use CFPlus; +use CFPlus::DB; use CFPlus::UI; use CFPlus::Pod; use CFPlus::Macro; @@ -39,31 +40,28 @@ map ["$cmd$_", $text], sort { (length $a) <=> (length $b) } @args - } sort { $a->{par} <=> $b->{par} } - CFPlus::Pod::find command => "*"; + } sort { $a->{par} <=> $b->{par} } + CFPlus::Pod::find command => "*"; - $self->connect_ext (event_capabilities => sub { - my ($cap) = @_; + $self->connect_ext (event_capabilities => sub { + my ($cap) = @_; - if (my $ts = $cap->{tileset}) { - if (my ($default) = grep $_->[2] & 1, @$ts) { - $self->{tileset} = $default; - $self->{tilesize} = $default->[3]; - $self->setup_req (tileset => $default->[0]); - - my $w = int $self->{mapw} * 32 / $self->{tilesize}; - my $h = int $self->{maph} * 32 / $self->{tilesize}; - - $self->setup_req (mapsize => "${w}x${h}"); - } - } - }); + if (my $ts = $cap->{tileset}) { + if (my ($default) = grep $_->[2] & 1, @$ts) { + $self->{tileset} = $default; + $self->{tilesize} = $default->[3]; + $self->setup_req (tileset => $default->[0]); - $self->{map_widget}->add_command (@$_) - for @cmd_help; + my $w = int $self->{mapw} * 32 / $self->{tilesize}; + my $h = int $self->{maph} * 32 / $self->{tilesize}; - $self->{noface} = new_from_file CFPlus::Texture - CFPlus::find_rcfile "noface.png", minify => 1, mipmap => 1; + $self->setup_req (mapsize => "${w}x${h}"); + } + } + }); + + $self->{map_widget}->add_command (@$_) + for @cmd_help; { $self->{dialogue} = my $tex = new_from_file CFPlus::Texture @@ -71,17 +69,16 @@ $self->{map}->set_texture (1, @$tex{qw(name w h s t)}, @{$tex->{minified}}); } - $self->{open_container} = 0; + { + $self->{noface} = my $tex = new_from_file CFPlus::Texture + CFPlus::find_rcfile "noface.png", minify => 1, mipmap => 1; + $self->{map}->set_texture (2, @$tex{qw(name w h s t)}, @{$tex->{minified}}); + } - # "global" - $self->{tilecache} = CFPlus::db_table "tilecache" - or die "tilecache: unable to open database table"; - $self->{facemap} = CFPlus::db_table "facemap" - or die "facemap: unable to open database table"; + $self->{open_container} = 0; # per server - $self->{mapcache} = CFPlus::db_table "mapcache_$self->{host}_$self->{port}" - or die "mapcache_$self->{host}_$self->{port}: unable to open database table"; + $self->{mapcache} = "mapcache_$self->{host}_$self->{port}"; $self } @@ -393,7 +390,7 @@ my ($hash, $x, $y, $w, $h) = @$map_info; my $data = $self->{map}->get_rect ($x, $y, $w, $h); - $self->{mapcache}->put ($hash => Compress::LZF::compress $data); + CFPlus::DB::put $self->{mapcache} => $hash => Compress::LZF::compress $data, sub { }; #warn sprintf "SAVEmap[%s] length %d\n", $hash, length $data;#d# } @@ -411,16 +408,22 @@ sub load_map($$$) { my ($self, $hash, $x, $y) = @_; - if (defined (my $data = $self->{mapcache}->get ($hash))) { - $data = Compress::LZF::decompress $data; - #warn sprintf "LOADmap[%s,%d,%d] length %d\n", $hash, $x, $y, length $data;#d# - for my $id ($self->{map}->set_rect ($x, $y, $data)) { - my $data = $self->{tilecache}->get ($id) - or next; + CFPlus::DB::get $self->{mapcache} => $hash, sub { + my ($data) = @_; - $self->set_texture ($id => $data); + if (defined $data) { + $data = Compress::LZF::decompress $data; + #warn sprintf "LOADmap[%s,%d,%d] length %d\n", $hash, $x, $y, length $data;#d# + for my $id ($self->{map}->set_rect ($x, $y, $data)) { + CFPlus::DB::get tilecache => $id, sub { + my ($data) = @_; + + $self->set_texture ($id => $data) + if defined $data; + }; + } } - } + }; } # hardcode /world/world_xxx_xxx map names, the savings are enourmous, @@ -544,54 +547,25 @@ } sub face_find { - my ($self, $facenum, $face) = @_; + my ($self, $facenum, $face, $cb) = @_; my $hash = "$face->{chksum},$face->{name}"; - my $id = $self->{facemap}->get ($hash); + my $id = CFPlus::DB::get_tile_id_sync $hash; - unless ($id) { - # create new id for face - # I love transactions - for (1..100) { - my $txn = $CFPlus::DB_ENV->txn_begin; - my $status = $self->{facemap}->db_get (id => $id); - if ($status == 0 || $status == BerkeleyDB::DB_NOTFOUND) { - $id = ($id || 64) + 1; - if ($self->{facemap}->put (id => $id) == 0 - && $self->{facemap}->put ($hash => $id) == 0) { - $txn->txn_commit; + $face->{id} = $id; + $self->{faceid}[$facenum] = $id; - goto gotid; - } - } - $txn->txn_abort; - } + $self->{map}->set_tileid ($facenum => $id); - CFPlus::fatal "maximum number of transaction retries reached - database problems?"; - } - -gotid: - $face->{id} = $id; - $self->{map}->set_face ($facenum => $id); - $self->{faceid}[$facenum] = $id;#d# - - my $face = $self->{tilecache}->get ($id); - - if ($face) { - #$self->face_prefetch; - $face - } else { - my $tex = $self->{noface}; - $self->{map}->set_texture ($id, @$tex{qw(name w h s t)}, @{$tex->{minified}}); - undef - }; + CFPlus::DB::get tilecache => $id, $cb; } sub face_update { my ($self, $facenum, $face, $changed) = @_; - $self->{tilecache}->put ($face->{id} => $face->{image}) if $changed; + CFPlus::DB::put tilecache => $face->{id} => $face->{image}, sub { } + if $changed; $self->set_texture ($face->{id} => delete $face->{image}); }