--- deliantra/server/utils/cfutil.in 2011/05/14 17:41:57 1.115 +++ deliantra/server/utils/cfutil.in 2011/05/15 20:14:30 1.116 @@ -109,8 +109,8 @@ END { system "rm", "-rf", $TMPDIR } -my $s_INT = EV::signal INT => sub { exit 1 }; -my $s_TERM = EV::signal TERM => sub { exit 1 }; +my $s_INT = AE::signal INT => sub { exit 1 }; +my $s_TERM = AE::signal TERM => sub { exit 1 }; our %hash; @@ -123,7 +123,7 @@ if (exists $hash{$hash}) { # hash collision, but some files are simply identical if (${$hash{$hash}[1]} ne $$dataref) { - warn "hash collision $hash{$hash}[0] vs. $id (increase the default \$clen in make_hash?)\n"; + warn "ERROR: hash collision $hash{$hash}[0] vs. $id (increase the default \$clen in make_hash?)\n"; exit 1; } else { print "$hash{$hash}[0] and $id are identical (which is fine).\n" if $VERBOSE >= 3; @@ -192,7 +192,7 @@ print "\nInstalling '$path' to '$DATADIR/maps'\n\n"; if (!-f "$path/regions") { - warn "'$path' does not look like a maps directory ('regions' file is missing).\n"; + warn "ERROR: '$path' does not look like a maps directory ('regions' file is missing).\n"; exit 1 unless $FORCE; } @@ -212,6 +212,7 @@ our @ARC; our %ARC; our $TRS; + our %PNG; our $NFILE; our $PATH; @@ -238,7 +239,7 @@ my ($size, $mtime) = (stat _)[7,9]; if (0 > aio_load $path, $png) { - warn "$path: $!, skipping.\n"; + warn "ERROR: $path: $!, skipping.\n"; next; } @@ -250,25 +251,25 @@ } elsif ($stem =~ s/\.64x64\.png~?$//) { $T = 64; } else { - warn "$path: weird filename, skipping.\n"; + warn "ERROR: $path: weird filename, skipping.\n"; next; } # quickly extract width and height of the (necessarily PNG) image unless ($png =~ /^\x89PNG\x0d\x0a\x1a\x0a....IHDR(........)/s) { - warn "$path: not a recognized png file, skipping.\n"; + warn "ERROR: $path: not a recognized png file, skipping.\n"; next; } my ($w, $h) = unpack "NN", $1; if ($w < $T || $h < $T) { - warn "$path: too small ($w $h), skipping.\n"; + warn "ERROR: $path: too small ($w $h), skipping.\n"; next; } if ($w % $T || $h % $T) { - warn "$path: weird png size ($w $h), skipping.\n"; + warn "ERROR: $path: weird png size ($w $h), skipping.\n"; next; } @@ -399,6 +400,56 @@ (my $face = $stem) =~ s/^.*\///; + for (@{ $fi->{derive} }) { + my ($dir, $type) = @$_; + + my $geom = "${T}x${T}"; + my $dpath = "$dir/$type:$face.$geom.png~"; + + if ($type eq "buildmaterial") { + my $ov = "$PATH/mapbuilding/buildmaterial.png"; + make_file [$path, $ov], $dpath, sub { + fork_exec { + system "$CONVERT -size 64x64 xc:transparent \\( \Q$path\E -geometry 52x52+6+6 \\) -composite \Q$ov\E -composite -geometry $geom png:\Q$dpath\E~"; + optipng "$dpath~"; + rename "$dpath~", $dpath; + }; + }; + } elsif ($type eq "buildmaterial-box") { + my $ov = "$PATH/mapbuilding/buildmaterial-box.png"; + make_file [$path, $ov], $dpath, sub { + fork_exec { + system "$CONVERT \Q$ov\E " + . "\\( \Q$path\E -trim -geometry 34x31\\> " + . "-gravity center -background transparent -extent 37x34 +gravity " + . "-geometry +22+6 \\) -composite " + . "-geometry $geom png:\Q$dpath\E~"; + optipng "$dpath~"; + rename "$dpath~", $dpath; + }; + }; + } elsif ($type eq "buildmaterial-sbox") { + my $ov = "$PATH/mapbuilding/buildmaterial-sbox.png"; + make_file [$path, $ov], $dpath, sub { + fork_exec { + system "$CONVERT \Q$ov\E " + . "\\( \Q$path\E -trim -geometry 16x24\\> " + . "-gravity center -background transparent -extent 18x26 +gravity " + . "-geometry +26+16 \\) -composite " + . "-geometry $geom png:\Q$dpath\E~"; + optipng "$dpath~"; + rename "$dpath~", $dpath; + }; + }; + } else { + warn "ERROR: facename $type:$face contains unsupported derivation type.\n"; + } + + aio_load $dpath, my $png; + IO::AIO::aio_unlink $dpath unless $CACHE; + commit_png "$dir/$type:$face", "$type:$face", $png, $T; + } + # split all bigfaces, but avoid smoothfaces (*_S) if (($w > $T || $h > $T) && $face !~ /_S\./) { # split @@ -412,7 +463,7 @@ } my $mtime = (lstat $path)[9]; - my @todo = grep { $_->[3] <= $mtime } @tile; + my @todo = grep { $_->[3] < $mtime } @tile; if (@todo) { fork_exec { open my $convert, "|-", $CONVERT, @@ -458,7 +509,7 @@ commit_png $stem, $face, $png, $T; } - aio_unlink $path if $delete; + IO::AIO::aio_unlink $path if $delete; } } @@ -468,7 +519,7 @@ my $data; if (0 > aio_load $path, $data) { - warn "$path: $!, skipping.\n"; + warn "ERROR: $path: $!, skipping.\n"; return; } @@ -484,9 +535,9 @@ $fg = "white" if $fg eq "none"; # lots of faces have no fg colour yet (my $fgi = $COLOR{$fg}) - // warn "WARNING: $path: $face specifies unknown foreground colour '$fg'.\n"; + // warn "ERROR: $path: $face specifies unknown foreground colour '$fg'.\n"; (my $bgi = $COLOR{$bg}) - // warn "WARNING: $path: $face specifies unknown background colour '$bg'.\n"; + // warn "ERROR: $path: $face specifies unknown background colour '$bg'.\n"; my $fi = $FACEINFO{$face} ||= { }; $fi->{visibility} = $visibility * 1; @@ -565,8 +616,13 @@ my $face = $_; $face =~ s/\+\d+\+\d+$//; # remove tile offset coordinates - my $info = $FACEINFO{$face} ||= { }; - $info->{arc} = $o; + # handle derived faces + if ($face =~ /^([^:]+):(.*)/) { + my ($type, $base) = ($1, $2); + push @{ $FACEINFO{$base}{derive} }, [$dir, $type]; + } + + $FACEINFO{$face}{arc} = $o; next if $face =~ /^blank.x11$|^empty.x11$/; } @@ -592,7 +648,7 @@ my $trs; if (0 > aio_load $path, $trs) { - warn "$path: $!, skipping.\n"; + warn "ERROR: $path: $!, skipping.\n"; return; } @@ -607,7 +663,7 @@ if (0 < aio_load $_[0], $data) { if ($_[1]) { $data = eval { $_[1]->($data) }; - warn "$_[0]: $@" if $@; + warn "ERROR: $_[0]: $@" if $@; } } @@ -716,7 +772,7 @@ "cc/by/2.5" => "Licensed under Creative Commons Attribution 2.5 http://creativecommons.org/licenses/by/2.5/", "cc/by/3.0" => "Licensed under Creative Commons Attribution 3.0 http://creativecommons.org/licenses/by/3.0/", })->{$meta->{license}} - || warn "$dir/$file: license tag '$meta->{license}' not found."; + || warn "ERROR: $dir/$file: license tag '$meta->{license}' not found."; } if (!exists $meta->{author} && $meta->{source} =~ m%^http://www.jamendo.com/en/artist/(.*)$%) { @@ -737,7 +793,7 @@ $data = eval $data; die if $@; $data = JSON::XS::encode_json $data; } else { - warn "$dir/$file: unknown filter $filter, skipping\n"; + warn "ERROR: $dir/$file: unknown filter $filter, skipping\n"; } } @@ -794,7 +850,7 @@ } } elsif ($file =~ /\.png$/) { - push @c_png, ["$path/$file", 0]; + $PNG{$file} = $path; } elsif ($file =~ /\.faceinfo$/) { $c_any->put ([\&process_faceinfo, $path, $file]); @@ -857,7 +913,7 @@ "\n"; if (!-d "$path/treasures") { - warn "'$path' does not look like an arch directory ('treasures' directory is missing).\n"; + warn "FATAL: '$path' does not look like an arch directory ('treasures' directory is missing).\n"; exit 1 unless $FORCE; } @@ -874,6 +930,29 @@ $_->join for @a_arc; # need to parse all archetypes before png processing print "ended arc processing...\n" if $VERBOSE; + # fill png queue + for (keys %FACEINFO) { + # we only expect source pngs to exist for non-derived + # faces, i.e. no split tiles (+x+x) and no face derivates + # (xxx:) + /^[^:]+\....$/ + or next; + + my $seen; + + if (exists $PNG{"$_.32x32.png"}) { + push @c_png, ["$PNG{\"$_.32x32.png\"}/$_.32x32.png"]; + $seen = 1; + } + if (exists $PNG{"$_.64x64.png"}) { + push @c_png, ["$PNG{\"$_.64x64.png\"}/$_.64x64.png"]; + $seen = 1; + } + + warn "ERROR: $_: face not found, expect problems.\n" + unless $seen; + } + print "starting png processing...\n" if $VERBOSE; # eight png crunchers work fine for my 4x smp machine @@ -911,7 +990,7 @@ ++$progress; } } else { - warn "WARNING: archetype '$o->{_name}' tries to inherit from undefined archetype '$other', skipping.\n"; + warn "ERROR: archetype '$o->{_name}' tries to inherit from undefined archetype '$other', skipping.\n"; delete $ARC{$o->{_name}}; } } @@ -958,8 +1037,8 @@ { print "processing facedata...\n" if $VERBOSE; while (my ($k, $v) = each %FACEINFO) { - length $v->{data32} or warn "WARNING: face '$k' has no png32. this will not work (shoddy gcfclient will crash of course).\n"; - length $v->{data64} or warn "WARNING: face '$k' has no png64. this will not work very well.\n"; + length $v->{data32} or warn "ERROR: face '$k' has no png32 - this will not work.\n"; + length $v->{data64} or warn "ERROR: face '$k' has no png64 - this will not work.\n"; make_hash $k, $v->{data32}, $v->{hash32}; make_hash $k, $v->{data64}, $v->{hash64}; @@ -967,11 +1046,11 @@ #length $v->{data32} <= 10000 or warn "WARNING: face '$k' has face32 larger than 10000 bytes, will not work with crossfire client.\n"; #length $v->{data64} <= 10000 or warn "WARNING: face '$k' has face64 larger than 10000 bytes.\n"; - $v->{glyph} // warn "WARNING: face '$k' has glyph."; - $v->{visibility} // warn "WARNING: face '$k' has no visibility info, missing faceinfo entry?\n"; - $v->{magicmap} // warn "WARNING: face '$k' has foreground colour."; + $v->{glyph} // warn "ERROR: face '$k' has no glyph - missing faceinfo entry?\n"; + $v->{visibility} // warn "ERROR: face '$k' has no visibility info - missing faceinfo entry?\n"; + $v->{magicmap} // warn "ERROR: face '$k' has no foreground colour - missing faceinfo entry?\n"; - delete @$v{qw(arc stem)}; # not used by the server + delete @$v{qw(arc stem derive)}; # not used by the server } print "processing resources...\n" if $VERBOSE;