def toNbt(self, slotIdx=None) -> Optional[nbt.TAG_Compound]: if self.isEmpty(): return None else: result = nbt.TAG_Compound() result.tags.append(nbt.TAG_String(f'minecraft:{self.item}', 'id')) result.tags.append(nbt.TAG_Byte(self.amount, 'Count')) if slotIdx is not None: result.tags.append(nbt.TAG_Byte(slotIdx, 'Slot')) return result
def toNbt(self) -> nbt.TAG_Compound: data = nbt.TAG_Compound() motion = nbt.TAG_List(name="Motion", type=nbt.TAG_Double) motion.append(nbt.TAG_Double(self.velocity[0])) motion.append(nbt.TAG_Double(self.velocity[1])) motion.append(nbt.TAG_Double(self.velocity[2])) data.tags.append(motion) pos = nbt.TAG_List(name="Pos", type=nbt.TAG_Double) pos.append(nbt.TAG_Double(self.pos[0])) pos.append(nbt.TAG_Double(self.pos[1])) pos.append(nbt.TAG_Double(self.pos[2])) data.tags.append(pos) data.tags.append( nbt.TAG_String(name="id", value=f"minecraft:{self.kind.name}")) data.tags.append(nbt.TAG_Float(name="Health", value=self.health)) data.tags.append(nbt.TAG_Byte(name="OnGround", value=self.onGround)) data.tags.append( nbt.TAG_Int(name="PortalCooldown", value=self.portalCooldown)) if self.extra is not None: extra = self.extra.toNbt() data.tags += extra.tags return data
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 create_chest_block_entity(self, chest_x, chest_y, chest_z, b_type, amount): items = nbt.TAG_List(name="Items", type=nbt.TAG_Compound) # TODO make this variable by using the config file stacks = min(amount // 64, 27) remainder = amount % 64 if stacks < 27 else 0 for i in range(stacks): chest_entry = nbt.TAG_Compound() chest_entry.tags.extend([ nbt.TAG_Byte(name="Count", value=64), nbt.TAG_Byte(name="Slot", value=i), nbt.TAG_String(name="id", value=b_type), ]) items.tags.append(chest_entry) if stacks < 27: chest_entry = nbt.TAG_Compound() chest_entry.tags.extend([ nbt.TAG_Byte(name="Count", value=amount % 64), nbt.TAG_Byte(name="Slot", value=stacks), nbt.TAG_String(name="id", value=b_type), ]) items.tags.append(chest_entry) block_entity = nbt.TAG_Compound() block_entity.tags.extend([ nbt.TAG_String(name="id", value="minecraft:chest"), nbt.TAG_Int(name="x", value=chest_x), nbt.TAG_Int(name="y", value=chest_y), nbt.TAG_Int(name="z", value=chest_z), nbt.TAG_Byte(name="keepPacked", value=0), ]) block_entity.tags.append(items) new_amount = amount - (stacks * 64 + remainder) return block_entity, new_amount
def save(self) -> nbt.NBTFile: """ Saves the chunk data to a :class:`NBTFile` Notes ----- Does not contain most data a regular chunk would have, but minecraft stills accept it. """ root = nbt.NBTFile() root.tags.append(nbt.TAG_Int(name='DataVersion', value=self.version)) level = nbt.TAG_Compound() # Needs to be in a separate line because it just gets # ignored if you pass it as a kwarg in the constructor level.name = 'Level' level.tags.extend([ nbt.TAG_List(name='Entities', type=nbt.TAG_Compound), nbt.TAG_List(name='TileEntities', type=nbt.TAG_Compound), nbt.TAG_List(name='LiquidTicks', type=nbt.TAG_Compound), nbt.TAG_Int(name='xPos', value=self.x), nbt.TAG_Int(name='zPos', value=self.z), nbt.TAG_Long(name='LastUpdate', value=0), nbt.TAG_Long(name='InhabitedTime', value=0), nbt.TAG_Byte(name='isLightOn', value=1), nbt.TAG_String(name='Status', value='full') ]) sections = nbt.TAG_List(name='Sections', type=nbt.TAG_Compound) for s in self.sections: if s: p = s.palette() # Minecraft does not save sections that are just air # So we can just skip them if len(p) == 1 and p[0].name() == 'minecraft:air': continue sections.tags.append(s.save()) level.tags.append(sections) root.tags.append(level) return root
def toNbt(self) -> nbt.TAG_Compound: tag = super().toNbt() inventory = nbt.TAG_List(type=nbt.TAG_Compound, name='Inventory') for (slotIdx, item) in enumerate(self.inventory): stackTag = item.stack.toNbt(slotIdx) if stackTag is not None: inventory.append(stackTag) tag.tags.append(inventory) gameMode = 1 if self.creative else 0 tag.tags.append(nbt.TAG_Int(gameMode, 'playerGameType')) abilities = nbt.TAG_Compound() abilities.name = 'abilities' abilities.tags.append(nbt.TAG_Byte(int(self.flying), 'flying')) tag.tags.append(abilities) tag.tags.append(nbt.TAG_String(self.dimension, 'dimension')) return tag
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
STR_Byte_Array = matchNumList('B') STR_Int_Array = matchNumList('I') STR_Long_Array = matchNumList('L') STR_List = delimited( pp.delimitedList(STR_TAG).setParseAction(lambda t: tuple(t)), start='[', end=']') STR_Compound = matchDict(STR_String, STR_TAG) STR_TAG << (STR_Number | STR_String | STR_Byte_Array | STR_Int_Array | STR_Long_Array | STR_List | STR_Compound) # ---------------------------------------------------------------------- STR_Byte.addParseAction(lambda t: nbt.TAG_Byte(t[0])) STR_Short.addParseAction(lambda t: nbt.TAG_Short(t[0])) STR_Int.addParseAction(lambda t: nbt.TAG_Int(t[0])) STR_Long.addParseAction(lambda t: nbt.TAG_Long(t[0])) STR_Float.addParseAction(lambda t: nbt.TAG_Float(t[0])) STR_Double.addParseAction(lambda t: nbt.TAG_Double(t[0])) STR_String.addParseAction(lambda t: nbt.TAG_String(t[0])) def make_tag_array(vals, tag_type, value_constructor=list): tag = tag_type() tag.value = value_constructor(vals) return tag STR_Byte_Array.addParseAction(lambda t: make_tag_array(
output[key] = convert_template(value) return output elif isinstance(template, NBTListStructure): if template.default_value: return template.default_value return NBTListEntry() else: return template.create_entry_from_template() template = loader.load_template(entity_id) entry = NBTCompoundEntry(convert_template(template)) return entry if __name__ == "__main__": print(create_entry_from_nbt(nbt.TAG_Byte(value=4))) compound = nbt.TAG_Compound() compound["test1"] = nbt.TAG_Int(value=-100) compound["test2"] = nbt.TAG_String(value="hello!") test1 = create_entry_from_nbt(compound) print(test1) print(create_nbt_from_entry(test1)) print("=" * 16) test2 = create_entry_from_nbt( nbt.TAG_List(value=[ nbt.TAG_String(value="test1"), nbt.TAG_String(value="test2"), nbt.TAG_String(value="test3"),
def save_chunk(self, data) -> nbt.NBTFile: """ Saves the chunk data to a :class:`NBTFile` Notes ----- Does not contain most data a regular chunk would have, but minecraft stills accept it. """ root = nbt.NBTFile() root.tags.append(nbt.TAG_Int(name="DataVersion", value=self.version)) level = nbt.TAG_Compound() # Needs to be in a separate line because it just gets # ignored if you pass it as a kwarg in the constructor level.name = "Level" if data: if data.get("Biomes") is not None: level.tags.append(data["Biomes"]) if data.get("Heightmaps") is not None: level.tags.append(data["Heightmaps"]) # level.tags.append(data["CarvingMasks"]) if data.get("Entities") is not None: level.tags.append(data["Entities"]) if data.get("TileEntities") is not None: level.tags.append(data["TileEntities"]) # if data.get("TileTicks") is not None: # level.tags.append(data["TileTicks"]) if data.get("LiquidTicks") is not None: level.tags.append(data["LiquidTicks"]) ######## if data.get("Lights") is not None: level.tags.append(data["Lights"]) if data.get("LiquidsToBeTicked") is not None: level.tags.append(data["LiquidsToBeTicked"]) if data.get("ToBeTicked") is not None: level.tags.append(data["ToBeTicked"]) if data.get("CarvingMasks") is not None: level.tags.append(data["CarvingMasks"]) ########## if data.get("PostProcessing") is not None: level.tags.append(data["PostProcessing"]) if data.get("Structures") is not None: level.tags.append(data["Structures"]) level.tags.extend([ # nbt.TAG_List(name="Entities", type=nbt.TAG_Compound), # nbt.TAG_List(name="TileEntities", type=nbt.TAG_Compound), # nbt.TAG_List(name="LiquidTicks", type=nbt.TAG_Compound), nbt.TAG_Int(name="xPos", value=self.x), nbt.TAG_Int(name="zPos", value=self.z), # nbt.TAG_Long(name="LastUpdate", value=data["LastUpdate"]), nbt.TAG_Long(name="LastUpdate", value=0), # nbt.TAG_Long(name="InhabitedTime", value=data["InhabitedTime"]), nbt.TAG_Long(name="InhabitedTime", value=0), nbt.TAG_Byte(name="isLightOn", value=1), nbt.TAG_String(name="Status", value="full"), ]) # entities = self.add_entities(data["Entities"]) # level.tags.append(entities) # nbt.TAG_List(name="Entities", type=nbt.TAG_Compound) else: level.tags.extend([ # nbt.TAG_List(name="Entities", type=nbt.TAG_Compound), nbt.TAG_List(name="TileEntities", type=nbt.TAG_Compound), nbt.TAG_List(name="LiquidTicks", type=nbt.TAG_Compound), nbt.TAG_Int(name="xPos", value=self.x), nbt.TAG_Int(name="zPos", value=self.z), nbt.TAG_Long(name="LastUpdate", value=0), nbt.TAG_Long(name="InhabitedTime", value=0), nbt.TAG_Byte(name="isLightOn", value=1), nbt.TAG_String(name="Status", value="full"), ]) sections = nbt.TAG_List(name="Sections", type=nbt.TAG_Compound) for s in self.sections: if s: p = s.palette() # Minecraft does not save sections that are just air # So we can just skip them if len(p) == 1 and p[0].name() == "minecraft:air": continue sections.tags.append(s.save()) level.tags.append(sections) root.tags.append(level) return root