server-1.12/lib/adm/collect_images.pl

160 lines
4.9 KiB
Perl
Executable File

#!/usr/bin/perl
#
# this script goes through and collects the various image sets into crossfire-x.png
# files, where x is the numbers from the image_info file. This
# collects all the images at once, whether or not they have
# been changed or not.
# This script collects all the images. If given a -archive option, it
# does some additional work - checksumming the images, making a bmaps.client
# file, and then tarring that data up. This data can then be used on the
# client as a fast way to 'bootstrap' the clients images.
use FileHandle;
die("No arch directory - will not rebuild $mode image file") if (! -e "arch");
$archive = 0;
$src_path = ".";
$TMPDIR="/tmp";
# What we will call the collection of images.
$ARCHNAME="crossfire-images";
$DESTDIR="$TMPDIR/$ARCHNAME";
# Maximum expected file
$MAXFILESIZE=100000;
if ($ARGV[0] eq "-src") {
$src_path = $ARGV[1];
print "Using $ARGV[1] as source directory\n";
die("$src_path doesn't exist.") if (! -d $src_path);
shift;
shift;
}
if ($ARGV[0] eq "-archive") {
$archive =1;
print "Will generate appropriate files for image archive\n";
die("$DESTDIR already exists - remove if you really want to remake the images") if (-d $DESTDIR);
die("$0: unable to mkdir $DESTDIR: $1\n") if (!mkdir($DESTDIR, 0755));
}
open(IMAGEINFO,"$src_path/image_info") || die("Can't open image_info file: $!\n");
binmode(IMAGEINFO);
while (<IMAGEINFO>) {
# Ignore lines that start with comments or just empty lines
next if /^#/;
next if /^\s*$/;
($setnum, $ext, @rest) = split /:/;
# We don't actually need that data in this script, but may as well do sanity
# checking.
if ($#rest != 4) {
print STDERR "image_info: line is corrupt:\n$_";
}
if ($extension[$setnum]) {
print STDERR "Warning: set $setnum is duplicated in image_info file\n";
}
$extension[$setnum] = $ext;
}
close(IMAGEINFO);
for ($count=0; $count<=$#extension; $count++) {
$ESRV[$count] = new FileHandle;
$fh = $ESRV[$count];
open($fh, ">crossfire.$count") ||
die("Can't open crossfire.$count for write: $!\n");
binmode( $fh );
}
open(BMAPS,"bmaps.paths") || die("Can't open bmaps.paths: $!\n");
binmode(BMAPS);
$_ = <BMAPS>;
while(<BMAPS>) {
chop;
# we need to insert the extension for the images between the name
# and the number (.171 or whatever) extension, so split on that.
die("Unknown line: '$_'\n") unless /^\\(\d{5})\s+(\S+)\.(\w\w\w)$/o;
$num = $1;
$file = $2;
$file1 = $3;
print "$num $file\n" if ($num % 500) == 0 ;
# This probably isn't the most efficient way to do this if a
# large number of images are added, as we try to open each
# instance.
# OTOH, we are doing one directory
# at a time, so we should be hitting the DNLC at a very high
# rate.
for ($count=0; $count<=$#extension; $count++) {
$filename = "$file.$extension[$count].$file1.png";
$fh = $ESRV[$count];
$length = -s "$filename";
if (open(FILE,"$filename")) {
binmode( FILE );
print $fh "IMAGE $num $length $file.$file1\n";
print "Error reading file $filename" if (!read(FILE, $buf, $length));
$position = tell $fh;
print $fh $buf;
close(FILE);
if ($archive) {
# Now figure out the checksum
# Same as what is used for the client/server - code basically
# taken write form that.
$sum = 0;
for ($i=0; $i<$length; $i++) {
if ($sum & 01) {
$sum = ($sum >> 1) | 0x80000000;
} else {
$sum >>= 1;
}
$sum += ord(substr $buf, $i, 1);
$sum &= 0xffffffff;
}
# Do some name translation to figure out our output file name.
@comps = split /\//, $file;
$destfile = $comps[$#comps];
push @csums, "$destfile.$file1 $sum crossfire.$extension[$count]\@$position:$length\n";
} # if archive
}
elsif ($count==0) {
# set 0 should have all the sets
print "Error: Image $filename not found for set 0!\n";
}
}
}
for ($count=0; $count<=$#extension; $count++) {
close($ESRV[$count]);
}
close(BMAPS);
if ($archive) {
open(OUT,">$DESTDIR/bmaps.client") || die("Can not open $DESTDIR/bmaps.client\n");
binmode(OUT);
print OUT sort @csums;
close(OUT);
open(OUT,">$DESTDIR/README") || die("Can not open $DESTDIR/README\n");
print OUT "These image files for the client should be located in\n";
print OUT "\$prefix/share/crossfire-client. \$prefix is the location given in the -prefix\n";
print OUT "option when configure is run to build the client. The default is /usr/local.\n";
print OUT "In that case these files should be put in /usr/local/share/crossfire-client\n";
print OUT "The client will print a messgae if it is unable to find the image information\n";
print OUT "with the location is looked for them.\n";
close(OUT);
for ($count=0; $count<=$#extension; $count++) {
system("cp crossfire.$count $DESTDIR/crossfire.$extension[$count]");
}
system("cd $DESTDIR; tar cf $TMPDIR/$ARCHNAME.tar .");
system("mv $TMPDIR/$ARCHNAME.tar ../");
system("rm -rf $TMPDIR/$ARCHNAME");
}