def generate_schematic(data, layout, blank_name, name, low_state, high_state) -> None: blankschem = nbt.NBTFile(blank_name, "rb") nbtfile = nbt.NBTFile() nbtfile.name = "Schematic" nbtfile, low_id, high_id = generate_palette(nbtfile, blankschem, low_state, high_state) Width, Lenght, Height = get_dimensions(blankschem) nbtfile.tags.extend([ nbt.TAG_Int(name="DataVersion", value=blankschem["DataVersion"].value), nbt.TAG_Int(name="Version", value=blankschem["Version"].value), nbt.TAG_Short(name="Length", value=Lenght), nbt.TAG_Short(name="Height", value=Height), nbt.TAG_Short(name="Width", value=Width), nbt.TAG_Int_Array(name="Offset"), ]) nbtfile = generate_meta(nbtfile, blankschem) nbtfile.tags.append(nbt.TAG_Byte_Array(name="BlockData")) nbtfile["BlockData"].value = generate_block_data(data, layout, blankschem, high_id, low_id) nbtfile.write_file(name)
def _as_schematic(self): nbtfile = nbt.NBTFile() nbtfile.name = "Schematic" nbtfile.tags.append(nbt.TAG_Short(name="Height", value=self.height)) nbtfile.tags.append(nbt.TAG_Short(name="Width", value=self.width)) nbtfile.tags.append(nbt.TAG_Short(name="Length", value=self.depth)) nbtfile.tags.append(nbt.TAG_Int(name="WEOffsetX", value=-1)) nbtfile.tags.append(nbt.TAG_Int(name="WEOffsetY", value=0)) nbtfile.tags.append(nbt.TAG_Int(name="WEOffsetZ", value=-1)) nbtfile.tags.append(nbt.TAG_Int(name="WEOriginX", value=0)) nbtfile.tags.append(nbt.TAG_Int(name="WEOriginY", value=0)) nbtfile.tags.append(nbt.TAG_Int(name="WEOriginZ", value=0)) # YZX ordering data = bytearray() blocks = bytearray() for y in range(self.height): for z in range(self.depth): for x in range(self.width): block_id, block_data = self.reader.get(x, y, z) blocks.append(block_id) data.append(block_data) blocks_tag = nbt.TAG_Byte_Array() blocks_tag.value = blocks data_tag = nbt.TAG_Byte_Array() data_tag.value = data nbtfile["Blocks"] = blocks_tag nbtfile["Data"] = data_tag nbtfile.tags.append(nbt.TAG_String(name="Materials", value=u"Alpha")) nbtfile["Entities"] = nbt.TAG_List(type=nbt.TAG_Compound) nbtfile["TileEntities"] = nbt.TAG_List(type=nbt.TAG_Compound) output = BytesIO() nbtfile.write_file(fileobj=output) as_nbt = output.getvalue() output.close() return as_nbt
def create_empty_section(self, section_y): new_section = nbt.TAG_Compound() data = nbt.TAG_Byte_Array(u"Data") skylight = nbt.TAG_Byte_Array(u"SkyLight") blocklight = nbt.TAG_Byte_Array(u"BlockLight") y = nbt.TAG_Byte() blocks = nbt.TAG_Byte_Array(u"Blocks") # TAG_Byte_Array(u'Data'): [2048 byte(s)] # TAG_Byte_Array(u'SkyLight'): [2048 byte(s)] # TAG_Byte_Array(u'BlockLight'): [2048 byte(s)] # TAG_Byte(u'Y'): 0 # TAG_Byte_Array(u'Blocks'): [4096 byte(s)] data.value = bytearray(2048) skylight.value = bytearray(2048) blocklight.value = bytearray(2048) y.name = u"Y" y.value = section_y blocks.value = bytearray(4096) new_section.tags.extend([data, skylight, blocklight, y, blocks]) return new_section
def gendefaultnbt(self): '''returns an nbt object''' nbtfile = nbt.NBTFile() colors = nbt.TAG_Byte_Array(name="colors") colors.value = bytearray(16384) data = nbt.TAG_Compound() data.name = "data" data.tags = [ nbt.TAG_Int(value=0, name="zCenter"), nbt.TAG_Byte(value=1, name="trackingPosition"), nbt.TAG_Short(value=128, name="width"), nbt.TAG_Byte(value=1, name="scale"), nbt.TAG_Byte(value=0, name="dimension"), nbt.TAG_Int(value=64, name="xCenter"), colors, nbt.TAG_Short(value=128, name="height") ] nbtfile.tags.append(data) return nbtfile
def save_to_nbtfile(barray, map_id): nbtfile = nbt.NBTFile() colors = nbt.TAG_Byte_Array(name="colors") colors.value = barray data = nbt.TAG_Compound() data.name = "data" data.tags = [ nbt.TAG_Byte(value=1, name="scale"), #地图缩放 nbt.TAG_Byte(value=0, name="dimension"), #维度 nbt.TAG_Byte(value=0, name="trackingPosition"), #箭头永不显示 nbt.TAG_Byte(value=1, name="locked"), #被锁定 nbt.TAG_Int(value=0, name="xCenter"), nbt.TAG_Int(value=0, name="zCenter"), nbt.TAG_Short(value=128, name="width"), nbt.TAG_Short(value=128, name="height"), colors ] nbtfile.tags.append(data) nbtfile.write_file("server/world/data/map_{}.dat".format(map_id))
def to_schem(img_path): # Open file and convert to RGB im = Image.open(img_path) rgb_im = im.convert('RGBA') blockjson = json.load(open('block.json')) palette_blocks = [] indices = {} # Creating palette palette = nbt.TAG_Compound() palette.name = 'Palette' # Initializing new NBT genfile = nbt.NBTFile() genfile.name = 'Schematic' # Setting basic NBT values genfile.tags.append(nbt.TAG_Int(name='Version', value=2)) genfile.tags.append(nbt.TAG_Short(name='Width', value=im.size[0])) genfile.tags.append(nbt.TAG_Short(name='Height', value=1)) genfile.tags.append(nbt.TAG_Short(name='Length', value=im.size[1])) genfile.tags.append(nbt.TAG_Int(name='DataVersion', value=2230)) # Creating block data blockdata = nbt.TAG_Byte_Array() blockdata.name = 'BlockData' # Iterating over each coordinate in the image for c in [(x, z) for x in range(im.size[0]) for z in range(im.size[1])]: # Get the color data from the pixel at coord c rgb = rgb_im.getpixel(c) # Getting the block with the closest color to the image pixel and # appending it to the palette list closest = min(blockjson, key=lambda k: math.dist(rgb, blockjson[k])) if closest not in palette_blocks: palette_blocks.append(closest) # The palette holds all the blocks that are used in a schematic. The field name # is the block name and the value is the index. This index is referenced in the # BlockData field to identify which block is present at a given coord palette[f'minecraft:{closest}'] = nbt.TAG_Int( value=palette_blocks.index(closest)) # Index blocks by x + z * Width + y * Width * Length. If we keep the same # order as the image coordinates the image comes out flipped. indices[c[0] + c[1] * im.size[0] + 1 * im.size[0] * im.size[1]] = palette_blocks.index(closest) # Set the palette length to length of the de-duped palette list genfile.tags.append( nbt.TAG_Int(name='PaletteMax', value=len(palette_blocks))) genfile.tags.append(palette) # A list of integers each referencing a block index from the palette is created # by sorting the indices dict. This list is then turned into a byte array as # that is the type needed by the NBT file. This prevents the image from being # flipped. blockdata.value = bytearray([indices[i] for i in sorted(indices)]) genfile.tags.append(blockdata) return genfile