added ZipSchematic class for reading alpha levels out of zip files, possibly reading the fixed boundaries out of schematic.dat

This commit is contained in:
David Vierra 2010-11-15 00:47:55 -10:00
parent 37ae6a0fb1
commit b7eb1175b6

View File

@ -121,7 +121,10 @@ import itertools
import traceback
import os;
import sys;
import tempfile
from contextlib import closing
from zipfile import ZipFile, ZIP_STORED, is_zipfile
from collections import deque;
import blockrotation
@ -689,6 +692,12 @@ class MCLevel(object):
if not os.path.exists(filename):
raise IOError, "File not found: "+filename
if (ZipSchematic._isLevel(filename)):
info( "Zipfile found, attempting zipped infinite level" )
lev = ZipSchematic(filename);
info( "Detected zipped Infdev level" )
return lev
if (MCInfdevOldLevel._isLevel(filename)):
info( u"Detected Infdev level.dat" )
if (loadInfinite):
@ -933,7 +942,7 @@ class MCLevel(object):
def generateLights(self, dirtyChunks = None):
pass;
def extractSchematic(self, box):
def adjustExtractionParameters(self, box):
x,y,z = box.origin
w,h,l = box.size
destX = destY = destZ = 0;
@ -974,18 +983,59 @@ class MCLevel(object):
l = self.Length - z
if l <= 0: return
box = BoundingBox ( (x,y,z), (w,h,l) )
return box, (destX, destY, destZ)
def extractSchematic(self, box):
box, destPoint = self.adjustExtractionParameters(box);
tempSchematic = MCSchematic(shape=box.size)
tempSchematic.materials = self.materials
tempSchematic.copyBlocksFrom(self, box, (destX, destY, destZ))
return tempSchematic
tempSchematic.copyBlocksFrom(self, box, destPoint)
return tempSchematic
def extractZipSchematic(self, box, zipfilename):
box, destPoint = self.adjustExtractionParameters(box);
destPoint = (0,0,0)
filename = tempfile.mktemp("schematic")
tempSchematic = MCInfdevOldLevel(filename, create = True);
tempSchematic.createChunksInBox(BoundingBox(destPoint, box.size))
tempSchematic.copyBlocksFrom(self, box, destPoint)
tempSchematic.saveInPlace(); #lights not needed for this format - crashes minecraft though
schematicDat = TAG_Compound()
schematicDat.name = "Mega Schematic"
schematicDat["Width"] = TAG_Int(box.size[0]);
schematicDat["Height"] = TAG_Int(box.size[1]);
schematicDat["Length"] = TAG_Int(box.size[2]);
schematicDat.save(os.path.join(filename, "schematic.dat"))
zipdir(filename, zipfilename)
import shutil
shutil.rmtree(filename)
#zipfilename = filename + ".zip"
#zf = ZipFile(zipfilename, "w")
#zf.add(filename);
def zipdir(basedir, archivename):
assert os.path.isdir(basedir)
with closing(ZipFile(archivename, "w", ZIP_STORED)) as z:
for root, dirs, files in os.walk(basedir):
#NOTE: ignore empty directories
for fn in files:
absfn = os.path.join(root, fn)
zfn = absfn[len(basedir)+len(os.sep):] #XXX: relative path
z.write(absfn, zfn)
fromFile = MCLevel.fromFile
@ -2987,7 +3037,26 @@ class MCAlphaDimension (MCInfdevOldLevel):
MCInfdevOldLevel.saveInPlace(self);
else:
self.parentWorld.saveInPlace();
class ZipSchematic (MCInfdevOldLevel):
def __init__(self, filename):
tempdir = tempfile.mktemp("schematic")
zf = ZipFile(filename)
zf.extractall(tempdir)
MCInfdevOldLevel.__init__(self, tempdir)
schematicDat = os.path.join(tempdir, "schematic.dat")
if os.path.exists(schematicDat):
schematicDat = nbt.load(schematicDat);
self.Width = schematicDat['Width'].value;
self.Height = schematicDat['Height'].value;
self.Length = schematicDat['Length'].value;
@classmethod
def _isLevel(cls, filename):
return is_zipfile(filename)
class MCIndevLevel(MCLevel):
""" IMPORTANT: self.Blocks and self.Data are indexed with [y,z,x]