module MinecraftMerge::Main

Constants

GZIP_MAGIC

Public Instance Methods

do_merge(orig, ours, theirs) click to toggle source
# File lib/minecraft-merge.rb, line 124
def do_merge(orig, ours, theirs)
  dats = [orig, ours, theirs].map { |filename|
    if File.stat(filename).size.nonzero?
      File.open(filename, 'rb') { |s| NBTFile.read(s) }
    else
      ["", NBTFile::Types::Compound.new]
    end
  }

  orig_data, our_data, their_data = dats.map { |(label, root)|
    chunk_data = root["Level"] || {}
    {'Blocks' => chunk_data["Blocks"]}
  }

  ours_changed = our_data != orig_data
  theirs_changed = their_data != orig_data

  # do a stupid merge for now; keep our stuff in case of a conflict
  if theirs_changed and not ours_changed
    FileUtils.cp(theirs, ours)
  end
end
main(*args) click to toggle source
# File lib/minecraft-merge.rb, line 37
def main(*args)
  parser = OptionParser.new do |opts|
  end
  parser.banner = "Usage: #{parser.program_name} merge ORIG OURS THEIRS\n" +
                  "       #{parser.program_name} setup [REPOSITORY]\n"
  parser.parse!(args)

  if args.empty?
    parser.warn("No subcommand given")
    return 1
  end
  subcommand = args.shift

  case subcommand
  when 'merge'
    if args.length != 3
      parser.warn("Wrong number of arguments for merge (3 required)")
      return 1
    end
    do_merge(*args)

  when 'install'
    if args.length > 0
      parser.warn("Wrong number of arguments for install (0 needed)")
      return 1
    end

    unless system "git", "config", "--global", "merge.minecraft.name", "Minecraft merge driver" and
           system "git", "config", "--global", "merge.minecraft.driver", "minecraft-merge merge %O %A %B" and
           system "git", "config", "--global", "filter.minecraft.clean", "minecraft-merge decompress" and
           system "git", "config", "--global", "filter.minecraft.smudge", "minecraft-merge compress"
      return 1
    end

  when 'setup'
    if args.length > 1
      parser.warn("Wrong number of arguments for setup (1 optional)")
      return 1
    end

    work_dir = args[0] || Dir.pwd
    Dir.chdir work_dir

    File.open(".gitignore", "w+") do |s|
      s.puts "session.lock"
      s.puts "level.dat_old"
    end

    File.open(".gitattributes", "w+") do |s|
      s.puts "*.dat binary -delta merge=minecraft"
    end

    unless system "git", "add", ".gitignore", ".gitattributes" and
           system "git", "commit", "-m", "set up attributes"
      return 1
    end

  when 'compress'
    data = $stdin.read
    if data[0, GZIP_MAGIC.length] == GZIP_MAGIC
      $stdout.write data
      $stdout.flush
    else
      writer = Zlib::GzipWriter.new($stdout)
      writer.write data
      writer.close
    end

  when 'decompress'
    data = $stdin.read
    if data[0, GZIP_MAGIC.length] == GZIP_MAGIC
      reader = Zlib::GzipReader.new(StringIO.new(data))
      $stdout.write reader.read
      reader.close
      $stdout.flush
    else
      $stdout.write data
      $stdout.flush
    end

  else
    parser.warn("Unknown subcommand #{subcommand}")
    return 1
  end
  return 0
end