Created
March 5, 2012 03:20
-
-
Save agrif/1976292 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## MCRegion to Anvil converter | |
## | |
## to use: | |
## | |
## Download http://libredstone.org/libredstone-0.0.0.tar.bz2, run | |
## ./configure.sh | |
## and | |
## make | |
## Make sure you have python and numpy installed. Then download | |
## this script into ./bindings/, cd into there, and run: | |
## | |
## python mcregion_to_anvil.py path/to/old/ output/ | |
## | |
## If you'd like, both paths can be the same, in which case level.dat | |
## is backed up to level.dat_mcr. Also if you'd like, you can `make | |
## install` libredstone then run this script from anywhere. | |
## | |
## It's like Jens' converter, but it produces a usable level.dat for | |
## (e.g.) Minecraft Overviewer. Also it's not java, which can be nice | |
## sometimes. Still no biomes though. | |
import redstone as rs | |
import numpy | |
import os.path, os | |
import sys | |
import shutil | |
if len(sys.argv) != 3: | |
sys.stderr.write('Usage: {cmd} <src> <dest>\n'.format(cmd=sys.argv[0])) | |
sys.exit(1) | |
_, src, dest = sys.argv | |
src = os.path.expanduser(src) | |
dest = os.path.expanduser(dest) | |
if not os.path.exists(src): | |
sys.stderr.write('Usage: {cmd} <src> <dest>\n'.format(cmd=sys.argv[0])) | |
sys.exit(1) | |
# make the destination directory | |
if not os.path.exists(dest): | |
os.mkdir(dest) | |
# | |
# convert level.dat | |
# | |
if dest == src: | |
shutil.copyfile(os.path.join(src, 'level.dat'), os.path.join(src, 'level.dat_mcr')) | |
dat = rs.NBT.parse_from_file(os.path.join(src, 'level.dat')) | |
dat['Data']['version'].value = 19133 | |
dat.write_to_file(os.path.join(dest, 'level.dat')) | |
# | |
# create and convert region files | |
# | |
def old_data_bytes(s): | |
dat = numpy.frombuffer(s, dtype=numpy.uint8) | |
return dat.reshape((16, 16, 128)) | |
def old_data_nibbles(s): | |
dat = numpy.frombuffer(s, dtype=numpy.uint8) | |
dat = dat.reshape((16, 16, 64)) | |
dat_expanded = numpy.empty((16, 16, 128), dtype=numpy.uint8) | |
dat_expanded[:,:,::2] = dat & 0x0F | |
dat_expanded[:,:,1::2] = (dat & 0xF0) >> 4 | |
return dat_expanded | |
def new_data_bytes(a): | |
return numpy.swapaxes(a, 0, 2).tostring() | |
def new_data_nibbles(a): | |
a = numpy.swapaxes(a, 0, 2) | |
dat = numpy.empty((16, 16, 8), dtype=numpy.uint8) | |
dat[:,:,:] = (a[:,:,::2] & 0x0F) | ((a[:,:,1::2] & 0x0F) << 4) | |
return dat.tostring() | |
def convert_chunk(dat): | |
# convert height map | |
height = map(ord, dat['Level']['HeightMap'].value) | |
dat['Level']['HeightMap'] = rs.Tag.new0(rs.TAG_INT_ARRAY) | |
dat['Level']['HeightMap'].value = height | |
# get current data arrays | |
blocks = old_data_bytes(dat['Level']['Blocks'].value) | |
data = old_data_nibbles(dat['Level']['Data'].value) | |
skylight = old_data_nibbles(dat['Level']['SkyLight'].value) | |
blocklight = old_data_nibbles(dat['Level']['BlockLight'].value) | |
# delete current data arrays | |
del dat['Level']['Blocks'] | |
del dat['Level']['Data'] | |
del dat['Level']['SkyLight'] | |
del dat['Level']['BlockLight'] | |
# add the Sections tag | |
dat['Level']['Sections'] = rs.Tag.new0(rs.TAG_LIST) | |
dat['Level']['Sections'].list_set_type(rs.TAG_COMPOUND) | |
# iterate through all possible sections | |
for y in xrange(8): | |
sec_blocks = blocks[:,:,16*y:16*y + 16] | |
if not sec_blocks.any(): | |
continue | |
sec_data = data[:,:,16*y:16*y + 16] | |
sec_skylight = skylight[:,:,16*y:16*y + 16] | |
sec_blocklight = blocklight[:,:,16*y:16*y + 16] | |
section = rs.Tag.new0(rs.TAG_COMPOUND) | |
section['Y'] = rs.Tag.new0(rs.TAG_BYTE) | |
section['Y'].value = y | |
section['Blocks'] = rs.Tag.new0(rs.TAG_BYTE_ARRAY) | |
section['Data'] = rs.Tag.new0(rs.TAG_BYTE_ARRAY) | |
section['SkyLight'] = rs.Tag.new0(rs.TAG_BYTE_ARRAY) | |
section['BlockLight'] = rs.Tag.new0(rs.TAG_BYTE_ARRAY) | |
section['Blocks'].value = new_data_bytes(sec_blocks) | |
section['Data'].value = new_data_nibbles(sec_data) | |
section['SkyLight'].value = new_data_nibbles(sec_skylight) | |
section['BlockLight'].value = new_data_nibbles(sec_blocklight) | |
dat['Level']['Sections'].list_insert(0, section) | |
dat['Level']['Sections'].list_reverse() | |
return dat | |
destregiondir = os.path.join(dest, 'region') | |
if not os.path.exists(destregiondir): | |
os.mkdir(destregiondir) | |
for mcr in os.listdir(os.path.join(src, 'region')): | |
try: | |
_, rx, rz, _ = mcr.split('.') | |
rx = int(rx) | |
rz = int(rz) | |
except: | |
continue | |
srcmcr = os.path.join(src, 'region', mcr) | |
destmca = os.path.join(dest, 'region', 'r.{x}.{z}.mca'.format(x=rx, z=rz)) | |
if os.path.exists(destmca): | |
os.unlink(destmca) | |
reg = rs.Region.open(srcmcr) | |
destreg = rs.Region.open(destmca, True) | |
print "converting", mcr | |
for x in xrange(32): | |
for z in xrange(32): | |
if not reg.contains_chunk(x, z): | |
continue | |
dat = rs.NBT.parse_from_region(reg, x, z) | |
newdat = convert_chunk(dat) | |
newdat.write_to_region(destreg, x, z) | |
destreg.flush() |
Not working for me. I keep getting:
Traceback (most recent call last):
File "mcregion_to_anvil.py", line 22, in <module>
import redstone as rs
File "/Users/jon/Downloads/libredstone-0.0.0/bindings/redstone.py", line 35, in <module>
rs = ctypes.CDLL(find_library('redstone'))
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/ctypes/__init__.py", line 365, in __init__
self._handle = _dlopen(self._name, mode)
OSError: dlopen(libredstone.dylib, 6): image not found
I ran python mcregion_to_anvil.py /Users/jon/Downloads/libredstone-0.0.0/bindings/input/target_world /Users/jon/Downloads/libredstone-0.0.0/bindings/output
in the bindings folder, and output is where I want the converted file to appear.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks a million for this :D