Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!C:Perl\bin\perl.exe
- # Version: 7 - Oct 30th, 2013
- # Version: 6 - July 12th, 2013
- # Version: 5 - Jan 19th, 2013
- #
- # Generate a Minecraft block and item id report.
- # Recursively searches the current directory for minecraft config files.
- # Shows total for each config file and errors if an id is already used.
- # Then creates a table of all ids.
- #
- # Requires PERL to be installed. Top line of this script must be path to your Perl executable.
- # Runs outside of Minecraft.
- # Change the $startDir variable to .minecraft directory in your %APPDATA% folder.
- # Doesn't alter any config files, just creates the text file "minecraft_id.rpt"
- use strict;
- use warnings;
- use File::Path;
- use FileHandle;
- # the directory separators are / not \, its a annoying difference between Unix and Windows
- # Perl uses the Unix way, \ is used to escape special characters in Perl
- my $startDir = "C:/Users/Bruce/AppData/Roaming/.minecraft"; # more typical start directory
- #my $startDir = "C:/Users/Bruce/Minecraft/Minecraft_1.6.2_ver_1/data/.minecraft"; # start directory
- #my $startDir = "C:/Users/Bruce/Downloads/Fuzzzies Config Pack v3.5.12"; # lastest configs
- my $repFile = "minecraft_id.rpt"; # report file
- my (%data, %biome);
- my $debug = 0;
- my $REP = OpenOutRef($repFile);
- if ( -d $startDir ) {
- print $REP "startDir = $startDir\n\n";
- RecurseDir($startDir);
- }
- else {
- print $REP "Error unable to find the startDir\n";
- exit 1;
- }
- print $REP "\n----------------------------------------------------------------\n";
- foreach my $id ( sort {$a <=> $b} keys %biome ) {
- printf $REP ("%-5d %s\n", $id, $biome{$id});
- }
- print $REP "----------------------------------------------------------------\n";
- foreach my $id ( sort {$a <=> $b} keys %data ) {
- printf $REP ("%-5d %s\n", $id, $data{$id});
- }
- close($REP);
- exit 0;
- #########################################
- # ID lines don't seem to have a set syntax,
- # so have to add a parser for each type.
- #########################################
- sub ReadCfgFile {
- my ($cfgFile) = @_;
- my $file = $cfgFile;
- $file =~ s/$startDir\///g;
- print $REP "Reading $file\n";
- my $CFG = OpenInRef($cfgFile);
- my $type = "";
- my $count = 0;
- my $error = 0;
- my $indent = 0;
- my $str = "";
- my ($item,$id,@section);
- my $prevLine = "";
- my $sec = "";
- my $secMatch = '(block|blocks|entity|item|items|id|ids|terrain block ids|biome|biome ids|multipart item ids|liquid ids|terrain block ids)';
- while ( my $line = <$CFG> ) {
- chomp($line);
- $line =~ s/^\s*#.+//;
- next if ( $line =~ /^\s*$/ );
- ($item,$id) = ("",0);
- ### section start on previous line
- if ( $line =~ /^\s*\{\s*$/ ) {
- $sec = $prevLine;
- $sec =~ s/"//g;
- $section[$indent] = $sec;
- print $REP " sec2 add indent=$indent sec=$sec\n" if ($debug);
- if ( $sec =~ /^\b$secMatch\b/i ) {
- $type = $sec;
- print $REP " indent=$indent type=$type\n" if ($debug);
- }
- $indent++;
- }
- # section start with {
- elsif ( $line =~ /^\s*(.+)\s*\{\s*$/ ) {
- $sec = $1;
- chop($sec);
- $sec =~ s/"//g;
- $sec =~ s/biome ids/biome/;
- #$sec =~ s/liquid ids/item/;
- #$sec =~ s/items/item/;
- #$sec =~ s/blocks/blocks/;
- #$sec =~ s/multipart item ids/item/;
- $section[$indent] = $sec;
- print $REP " sec1 add indent=$indent sec=$sec\n" if ($debug);
- if ( $sec =~ /^\b$secMatch\b/i ) {
- $type = $section[$indent];
- print $REP " indent=$indent type=$type\n" if ($debug);
- }
- $indent++;
- }
- # section end
- elsif ( $line =~ /^\s*\}\s*$/ ) {
- $indent-- if ($indent);
- print $REP " sec3 sub indent=$indent\n" if ($debug);
- if ( $section[$indent] =~ /^\b$secMatch\b/i ) {
- $type = "";
- }
- }
- ### Type blocks in { }
- elsif ( $type ) {
- if ( $section[0] =~ /(tweaks)/ ) {
- print $REP " t0 skip this section\n" if ($debug);
- # dont parse
- }
- #print $REP " inside type block type=$type\n";
- # I:block=val
- elsif ( $line =~ /I:(block|item)=(\d+)/i ) {
- ($type,$id) = ($1,$2);
- $item = $section[0];
- print $REP " t1 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:type.item.id=val
- elsif ( $line =~ /I:$type.(\w+)\.id\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$2);
- print $REP " t2 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:item=val.id=val
- elsif ( $line =~ /I:(\w+)\.id\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$2);
- print $REP " t3 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:item=valID=val
- elsif ( $line =~ /I:(\w+)(Block|Item)Id\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$3);
- print $REP " t4 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:item=valID=val
- elsif ( $line =~ /I:(\w+)Id\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$2);
- print $REP " t5 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:name=val
- elsif ( $line =~ /I:(\w+)\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$2);
- print $REP " t6 type=$type name=$item id=$id\n" if ($debug);
- }
- # S:item_ItemID=val
- elsif ( $line =~ /S:(\w+)_ItemID\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$2);
- print $REP " t7 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:stuff_(Block|Item)item=val
- elsif ( $line =~ /I:.+_(Block|Item)(\w+)\s*=\s*(\d+)/i ) {
- ($item,$id) = ($2,$3);
- print $REP " t8 type=$type name=$item id=$id\n" if ($debug);
- }
- # item=val
- elsif ( $line =~ /(\w+)\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$2);
- print $REP " t9 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:"Ash Block ID"=163
- elsif ( $line =~ /I:\"(.+)\"\s*=\s*(\d+)/i ) {
- ($item,$id) = ($1,$2);
- print $REP " t10 type=$type name=$item id=$id\n" if ($debug);
- }
- $str = "$type.$item";
- }
- ### Item outside type blocks
- else {
- $type = "";
- # item.id=val
- if ( $line =~ /^\s*(\w+)\.id\s*=\s*(\d+)$/i ) {
- ($item,$id) = ($1,$2);
- $str = $item;
- print $REP " o1 type=$type name=$item id=$id\n" if ($debug);
- }
- # item.id=val
- elsif ( $line =~ /^\s*(\w+)_ID\s*=\s*(\d+)$/i ) {
- ($item,$id) = ($1,$2);
- $str = $item;
- print $REP " o2 type=$type name=$item id=$id\n" if ($debug);
- }
- # itemid=val
- elsif ( $line =~ /^\s*(\w+)id\s*=\s*(\d+)\s*$/i ) {
- ($item,$id) = ($1,$2);
- $str = $item;
- print $REP " o3 type=$type name=$item id=$id\n" if ($debug);
- }
- # type.item.id=val
- elsif ( $line =~ /^\s*(item|block|entity)\.(\w+)\.id\s*=\s*(\d+)\s*$/i ) {
- ($type,$item,$id) = ($1,$2,$3);
- $str = "$type.$item";
- $type = "";
- print $REP " o4 type=$type name=$item id=$id\n" if ($debug);
- }
- # I:itemId=val
- elsif ( $line =~ /^\s*I:(\w+)Id=(\d+)/ ) {
- ($item,$id) = ($1,$2);
- my $str2 = "";
- if ( $indent ) {
- foreach ( my $i=0; $i < $indent; $i++ ) {
- $str2 .= $section[$i].".";
- }
- chop($str2);
- $str = $str2.".".$item;
- }
- else {
- $str = "";
- }
- print $REP " o5 type=$type name=$item id=$id\n" if ($debug);
- }
- elsif ( $indent == 2 && $line =~ /^\s*I:(block|item)=(\d+)$/ && $section[1] =~ /id/i ) {
- $line =~ /^\s*I:(block|item)=(\d+)$/;
- ($type,$id) = ($1,$2);
- $str = "$type.$section[0]";
- #print $REP " type=$type id=$id sec0=$section[0] sec1=$section[1]\n";
- print $REP " o6 type=$type name=$item id=$id\n" if ($debug);
- }
- # special items
- elsif ( $line =~ /(propolisPipe)=(\d+)/ ) {
- ($item,$id) = ($1,$2);
- $type = "item";
- $str = "$type.$item";
- print $REP " o7 type=$type name=$item id=$id\n" if ($debug);
- }
- else {
- #print $REP " parse failed line=$line\n";
- }
- }
- ###############################################
- if ( $id && $type eq "biome" ) {
- if ( !defined($biome{$id}) ) {
- $biome{$id} = sprintf("%-35s %s", $file, $str);
- $count++;
- }
- else {
- print $REP " ERROR: biome id $id is already used for $biome{$id}, change: $str\n";
- $error++;
- }
- }
- elsif ( $id && !defined($data{$id}) ) {
- $data{$id} = sprintf("%-35s %s", $file, $str);
- $count++;
- }
- elsif ( $id ) {
- print $REP " ERROR: id $id is already used for $data{$id}, change: $str\n";
- $error++;
- }
- if ( $line =~ /^\s*(\w+)\s*$/ ) {
- $prevLine = $1;
- print $REP " prevLine=$prevLine\n" if ($debug);
- }
- }
- close($CFG);
- print $REP " count = $count\n";
- if ( $error ) {
- print $REP " errors = $error\n";
- }
- }
- #########################################
- sub RecurseDir {
- my($path) = @_;
- my(@file) = ReadDir($path);
- foreach my $file ( sort @file ) {
- if ( ($file ne ".") && ($file ne "..") ) {
- next if ( $path =~ /\bsaves\b/ ); # dont look in the saves folder
- my $cur_path = $path."/".$file;
- if ( -l $cur_path ) {
- # dont follow links
- }
- elsif ( -d $cur_path && -X $cur_path ) {
- RecurseDir($cur_path);
- }
- else {
- # find config files
- if ( $file =~ /(cfg|conf|properties)/ && $file !~ /^\./ && $file !~ /\~$/ ) {
- ReadCfgFile($cur_path);
- }
- }
- }
- }
- }
- #########################################
- sub ReadDir {
- my($dir) = @_;
- if ( opendir(DIR, $dir) ) {
- my @file = readdir(DIR);
- chomp(@file);
- closedir(DIR);
- return @file;
- }
- else {
- print $REP "Error: Unable to open directory $dir\n $!";
- exit 1;
- }
- }
- #########################################
- sub OpenOutRef {
- my ($outFile) = (@_);
- my $OUTFILE = FileHandle->new;
- if ( $OUTFILE->open("> $outFile") == 0 ) {
- print "Error unable to open out file: $outFile\n";
- exit 1;
- }
- return $OUTFILE;
- }
- sub OpenInRef {
- my ($inFile) = (@_);
- my $INFILE = FileHandle->new;
- if ( $INFILE->open("< $inFile") == 0 ) {
- print $REP "Error unable to open in file: $inFile\n";
- exit 1;
- }
- return $INFILE;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement