Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
183 lines (148 sloc) 5.76 KB
'''
Created on Jul 22, 2011
@author: Rio
'''
__all__ = ["MCJavaLevel"]
from mclevelbase import *
from level import MCLevel
import re
log = logging.getLogger(__name__)
warn, error, info, debug = log.warn, log.error, log.info, log.debug
from level import MCLevel
class MCJavaLevel(MCLevel):
def setBlockDataAt(self, *args): pass
def blockDataAt(self, *args): return 0;
@property
def Height(self):
return self.Blocks.shape[2]
@property
def Length(self):
return self.Blocks.shape[1]
@property
def Width(self):
return self.Blocks.shape[0]
def guessSize(self, data):
if data.shape[0] <= (32 * 32 * 64) * 2:
warn(u"Can't guess the size of a {0} byte level".format(data.shape[0]))
raise IOError, "MCJavaLevel attempted for smaller than 64 blocks cubed"
if data.shape[0] > (32 * 32 * 64) * 2:
Width = 64
Length = 64
Height = 64
if data.shape[0] > (64 * 64 * 64) * 2:
Width = 128
Length = 128
Height = 64
if data.shape[0] > (128 * 128 * 64) * 2:
Width = 256
Length = 256
Height = 64
if data.shape[0] > (256 * 256 * 64) * 2: #could also be 256*256*256
Width = 512
Length = 512
Height = 64
if data.shape[0] > 512 * 512 * 64 * 2: # just to load shadowmarch castle
Width = 512
Length = 512
Height = 256
return Width, Length, Height
@classmethod
def _isDataLevel(cls, data):
return (data[0] == 0x27 and
data[1] == 0x1B and
data[2] == 0xb7 and
data[3] == 0x88)
def __init__(self, filename, data):
self.filename = filename
if isinstance(data, basestring):
data = fromstring(data, dtype='uint8')
self.filedata = data
#try to take x,z,y from the filename
r = re.findall("\d+", os.path.basename(filename))
if r and len(r) >= 3:
(w, l, h) = map(int, r[-3:])
if w * l * h > data.shape[0]:
info("Not enough blocks for size " + str((w, l, h)))
w, l, h = self.guessSize(data)
else:
w, l, h = self.guessSize(data)
info(u"MCJavaLevel created for potential level of size " + str((w, l, h)))
blockCount = h * l * w
if blockCount > data.shape[0]:
raise ValueError, "Level file does not contain enough blocks! (size {s}) Try putting the size into the filename, e.g. server_level_{w}_{l}_{h}.dat".format(w=w, l=l, h=h, s=data.shape)
blockOffset = data.shape[0] - blockCount
blocks = data[blockOffset:blockOffset + blockCount]
maxBlockType = 64 #maximum allowed in classic
while max(blocks[-4096:]) > maxBlockType:
#guess the block array by starting at the end of the file
#and sliding the blockCount-sized window back until it
#looks like every block has a valid blockNumber
blockOffset -= 1
blocks = data[blockOffset:blockOffset + blockCount]
if blockOffset <= -data.shape[0]:
raise IOError, "Can't find a valid array of blocks <= #%d" % maxBlockType
self.Blocks = blocks
self.blockOffset = blockOffset
blocks.shape = (w, l, h)
blocks.strides = (1, w, w * l)
def saveInPlace(self):
s = StringIO()
if self.compressed:
g = gzip.GzipFile(fileobj=s, mode='wb')
else:
g = s
g.write(self.filedata.tostring())
g.flush()
g.close()
try:
os.rename(self.filename, self.filename + ".old")
except Exception, e:
pass;
try:
with open(self.filename, 'wb') as f:
f.write(s.getvalue())
except Exception, e:
info(u"Error while saving java level in place: {0}".format(e))
try:os.remove(self.filename);
except: pass
os.rename(self.filename + ".old", self.filename)
try:
os.remove(self.filename + ".old")
except Exception, e:
pass;
class MCSharpLevel(MCLevel):
""" int magic = convert(data.readShort());
logger.trace("Magic number: {}", magic);
if (magic != 1874)
throw new IOException("Only version 1 MCSharp levels supported (magic number was "+magic+")");
int width = convert(data.readShort());
int height = convert(data.readShort());
int depth = convert(data.readShort());
logger.trace("Width: {}", width);
logger.trace("Depth: {}", depth);
logger.trace("Height: {}", height);
int spawnX = convert(data.readShort());
int spawnY = convert(data.readShort());
int spawnZ = convert(data.readShort());
int spawnRotation = data.readUnsignedByte();
int spawnPitch = data.readUnsignedByte();
int visitRanks = data.readUnsignedByte();
int buildRanks = data.readUnsignedByte();
byte[][][] blocks = new byte[width][height][depth];
int i = 0;
BlockManager manager = BlockManager.getBlockManager();
for(int z = 0;z<depth;z++) {
for(int y = 0;y<height;y++) {
byte[] row = new byte[height];
data.readFully(row);
for(int x = 0;x<width;x++) {
blocks[x][y][z] = translateBlock(row[x]);
}
}
}
lvl.setBlocks(blocks, new byte[width][height][depth], width, height, depth);
lvl.setSpawnPosition(new Position(spawnX, spawnY, spawnZ));
lvl.setSpawnRotation(new Rotation(spawnRotation, spawnPitch));
lvl.setEnvironment(new Environment());
return lvl;
}"""