Snippet: #ordf

Written in Ruby and posted on Nov 28, 2011 at 23:40 by apoc
   1  #
   2  # This script parses the CraftingManager.java file decompiled by mcp5 from
   3  # the Minecraft code. It generates ruby datastructures/constants etc.
   4  #
   5  
   6  craftingmanager_file = 'CraftingManager.java'
   7  lang_file = 'en_US.lang'
   8  block_file = 'Block.java'
   9  
  10  if ARGV.length >= 1
  11    lang_file = ARGV[0]
  12  elsif ARGV.length >= 2
  13    block_file ARGV[1]
  14  elsif ARGV.length >= 3
  15    craftingmanager_file ARGV[2]
  16  end
  17  
  18  if not File.exists? lang_file or not File.exists? craftingmanager_file or not File.exists? block_file
  19    puts "Options: %s <Path to en_US.lang> <Path to CraftingManager.java> <Path to Block.java>" % [$0]
  20    exit
  21  end
  22  
  23  # load language mappings:
  24  @@lang = {}
  25  IO.read(lang_file).scan(%r{^([^=]+)=(.*)$}).each do |pairs|
  26    @@lang[pairs[0].strip] = pairs[1].strip
  27  end
  28  
  29  # load block instance -> names
  30  @@blocks = {}
  31  block_java = IO.read(block_file)
  32  block_java.scan(%r{^([^=]+) = [^;]+setBlockName\("([^\"]+)"\)}).each do |m|
  33    @@blocks[m[0].strip] = m[1].strip
  34  end
  35  items = {} #unused
  36  block_java.scan(%r{^Item\.itemsList\[([^=]+)\.blockID\] = [^;]+setItemName\("([^\"]+)"\)}).each do |m|
  37    items[m[0]] = m[1]
  38  end
  39  
  40  # converts java constants to their real name in language file:
  41  def const_to_string(const)
  42    const.match /[^\.]+\.(.*)/
  43    const = $1
  44    if @@blocks.has_key? const
  45      lang_key = @@blocks[const]
  46    else
  47      lang_key = const
  48    end
  49    lang_name = nil
  50    @@lang.each_key do |key|
  51      if key.include? ".#{lang_key}."
  52        if not @@lang[key].empty?
  53          lang_name = @@lang[key]
  54          break
  55        end
  56      end
  57    end
  58    if lang_name and not lang_name.empty?
  59      name = lang_name
  60    elsif lang_name and lang_name.empty?
  61      puts
  62      puts "# WARNING!! empty lang name for #{const}"
  63      name = const
  64    else
  65      puts
  66      puts "# WARNING!! no lang found for #{const}"
  67      name = const
  68    end
  69  
  70    "'" + name.gsub("'", "") + "'"
  71  
  72  end
  73  
  74  # generate recipes 
  75  puts "# Generated: #{Time.now}"
  76  puts
  77  puts "::MinecraftRecipes = {"
  78  
  79  IO.read(craftingmanager_file).scan(%r{addRecipe\(([^;]+)\);}m).each do |recipe|
  80    recipe = recipe.first
  81  
  82    # each recipe contains an ItemStack and an Object array,
  83    # first seperate them both:
  84    raise 'item stack parse error' if not 
  85      recipe.match /new ItemStack\(([^,]+), (\d+)/
  86  
  87    product, amount = const_to_string($1), $2.to_i
  88  
  89    puts "# product:#{product.inspect} amount:#{amount.inspect}"
  90  
  91    # Object array contains the recipe itself and all ingridients
  92    # we are only interested in each ingridient and the amount
  93    raise 'recipe array parse error' if not 
  94      recipe.match /new Object\[\] {([^}]+)}/
  95    recipe_array = $1
  96  
  97    recipe_mapping = ''
  98    recipe_ingredients = {}
  99    tmp_amount = 0
 100    recipe_array.split(',').each do |arg|
 101      arg.strip!
 102      # recipe mappings
 103      if arg.match /^"([^"]+)"$/
 104        recipe_mapping += $1
 105  
 106      # item representation in mapping
 107      elsif arg.match /Character\.valueOf\('(.)'\)/
 108        tmp_amount = recipe_mapping.count($1)
 109  
 110      # the actual item or block within the recipe:
 111      elsif arg.match /^((Item|Block)\..*)$/
 112        item = const_to_string($1)
 113        recipe_ingredients[item] = tmp_amount
 114  
 115        if tmp_amount <= 0
 116          puts "# WARNING: ingredient with mapping?"
 117        end
 118  
 119      end
 120  
 121    end
 122  
 123  
 124    puts <<EOF
 125  #{product} => {
 126    :amount => #{amount},
 127    :ingredients => {
 128  EOF
 129  
 130    recipe_ingredients.each_pair do |item, amount|
 131      puts "    #{item} => #{amount},"
 132    end
 133  
 134  
 135    puts <<EOF
 136    }
 137  },
 138  EOF
 139    
 140    puts
 141  end
 142  
 143  puts "}"
 144  puts
 145