public void ChangingListTagType() { var list = new NbtList(); // changing list type to an out-of-range type Assert.Throws<ArgumentOutOfRangeException>(() => list.ListType = (NbtTagType)200); // failing to add or insert a tag should not change ListType Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, new NbtInt())); Assert.Throws<ArgumentException>(() => list.Add(new NbtInt("namedTagWhereUnnamedIsExpected"))); Assert.AreEqual(NbtTagType.Unknown, list.ListType); // changing the type of an empty list to "End" is allowed, see https://github.com/fragmer/fNbt/issues/12 Assert.DoesNotThrow(() => list.ListType = NbtTagType.End); Assert.AreEqual(list.ListType, NbtTagType.End); // changing the type of an empty list back to "Unknown" is allowed too! Assert.DoesNotThrow(() => list.ListType = NbtTagType.Unknown); Assert.AreEqual(list.ListType, NbtTagType.Unknown); // adding the first element should set the tag type list.Add(new NbtInt()); Assert.AreEqual(list.ListType, NbtTagType.Int); // setting correct type for a non-empty list Assert.DoesNotThrow(() => list.ListType = NbtTagType.Int); // changing list type to an incorrect type Assert.Throws<ArgumentException>(() => list.ListType = NbtTagType.Short); // after the list is cleared, we should once again be allowed to change its TagType list.Clear(); Assert.DoesNotThrow(() => list.ListType = NbtTagType.Short); }
public void IndexerTest() { NbtByte ourTag = new NbtByte(1); var secondList = new NbtList { new NbtByte() }; var testList = new NbtList(); // Trying to set an out-of-range element Assert.Throws<ArgumentOutOfRangeException>(() => testList[0] = new NbtByte(1)); // Make sure that setting did not affect ListType Assert.AreEqual(NbtTagType.Unknown, testList.ListType); Assert.AreEqual(0, testList.Count); testList.Add(ourTag); // set a tag to null Assert.Throws<ArgumentNullException>(() => testList[0] = null); // set a tag to itself Assert.Throws<ArgumentException>(() => testList[0] = testList); // give a named tag where an unnamed tag was expected Assert.Throws<ArgumentException>(() => testList[0] = new NbtByte("NamedTag")); // give a tag of wrong type Assert.Throws<ArgumentException>(() => testList[0] = new NbtInt(0)); // give an unnamed tag that already has a parent Assert.Throws<ArgumentException>(() => testList[0] = secondList[0]); // Make sure that none of the failed insertions went through Assert.AreEqual(ourTag, testList[0]); }
public void IndexerTest() { var secondList = new NbtList { new NbtByte() }; var testList = new NbtList(); // Trying to set an out-of-range element Assert.Throws<ArgumentOutOfRangeException>(() => testList[0] = new NbtByte(1)); // Make sure that setting did not affect ListType Assert.AreEqual(testList.ListType, NbtTagType.Unknown); Assert.AreEqual(testList.Count, 0); testList.Add(new NbtByte(1)); // set a tag to null Assert.Throws<ArgumentNullException>(() => testList[0] = null); // set a tag to itself Assert.Throws<ArgumentException>(() => testList[0] = testList); // give a named tag where an unnamed tag was expected Assert.Throws<ArgumentException>(() => testList[0] = new NbtByte("NamedTag")); // give an unnamed tag that already has a parent Assert.Throws<ArgumentException>(() => testList[0] = secondList[0]); }
public void ChangingListTagType() { var list = new NbtList(); // changing type of an empty list Assert.DoesNotThrow( () => list.ListType = NbtTagType.Unknown ); list.Add( new NbtInt() ); // setting correct type for a non-empty list Assert.DoesNotThrow( () => list.ListType = NbtTagType.Int ); // changing list type to an incorrect type Assert.Throws<ArgumentException>( () => list.ListType = NbtTagType.Short ); }
public void SaveTo(string file) { var nbt = new NbtFile(file); nbt.RootTag = new NbtCompound(""); var list = new NbtList("servers", NbtTagType.Compound); foreach (var server in Servers) { var compound = new NbtCompound(); compound.Add(new NbtString("name", server.Name)); compound.Add(new NbtString("ip", server.Ip)); compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0))); compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0))); list.Add(compound); } nbt.RootTag.Add(list); nbt.SaveToFile(file, NbtCompression.None); }
public override void SetCompound(NbtCompound compound) { Compound = compound; if (Compound["Items"] == null) { NbtList items = new NbtList("Items"); for (byte i = 0; i < 2; i++) { items.Add(new NbtCompound() { new NbtByte("Count", 0), new NbtByte("Slot", i), new NbtShort("id", 0), new NbtByte("Damage", 0), }); } Compound["Items"] = items; } }
public NbtTag Serialize(string tagName) { var chunk = (NbtCompound)Serializer.Serialize(this, tagName, true); var entities = new NbtList("Entities", NbtTagType.Compound); for (int i = 0; i < Entities.Count; i++) { entities.Add(Entities[i].Serialize(string.Empty)); } chunk.Add(entities); var sections = new NbtList("Sections", NbtTagType.Compound); var serializer = new NbtSerializer(typeof(Section)); for (int i = 0; i < Sections.Length; i++) { if (!Sections[i].IsAir) { sections.Add(serializer.Serialize(Sections[i])); } } chunk.Add(sections); return(chunk); }
NbtTag HandleArray([CanBeNull] string tagName, [CanBeNull] Array value, [NotNull] PropertyInfo pinfo) { if (pinfo == null) { throw new ArgumentNullException("pinfo"); } if (value == null) { NullPolicy np = GetNullPolicy(pinfo); switch (np) { case NullPolicy.Ignore: return(null); case NullPolicy.InsertDefault: return(MakeEmptyList(tagName, pinfo.PropertyType.GetElementType())); default: throw MakeNullException(pinfo); } } if (value.Length == 0) { return(MakeEmptyList(tagName, pinfo.PropertyType.GetElementType())); } NullPolicy elementNullPolicy = GetElementNullPolicy(pinfo); NbtList newList = new NbtList(tagName); for (int i = 0; i < value.Length; i++) { newList.Add(HandleElement(null, value.GetValue(i), elementNullPolicy)); } return(newList); }
NbtTag HandleIListInner <T>([CanBeNull] string tagName, PropertyInfo pinfo, List <T> value) { Type elementType = typeof(T); if (value == null) { NullPolicy np = GetNullPolicy(pinfo); switch (np) { case NullPolicy.Ignore: return(null); case NullPolicy.InsertDefault: return(MakeEmptyList(tagName, elementType)); default: throw MakeNullException(pinfo); } } // Get list length int count = value.Count; if (count == 0) { return(MakeEmptyList(tagName, elementType)); } NullPolicy elementNullPolicy = GetElementNullPolicy(pinfo); NbtList newList = new NbtList(tagName); foreach (T element in value) { newList.Add(HandleElement(null, element, elementNullPolicy)); } return(newList); }
public void NestedListAndCompoundTest() { byte[] data; { var root = new NbtCompound("Root"); var outerList = new NbtList("OuterList", NbtTagType.Compound); var outerCompound = new NbtCompound(); var innerList = new NbtList("InnerList", NbtTagType.Compound); var innerCompound = new NbtCompound(); innerList.Add(innerCompound); outerCompound.Add(innerList); outerList.Add(outerCompound); root.Add(outerList); var file = new NbtFile(root); data = file.SaveToBuffer(NbtCompression.None); } { var file = new NbtFile(); long bytesRead = file.LoadFromBuffer(data, 0, data.Length, NbtCompression.None); Assert.AreEqual(bytesRead, data.Length); Assert.AreEqual(1, file.RootTag.Get <NbtList>("OuterList").Count); Assert.AreEqual(null, file.RootTag.Get <NbtList>("OuterList").Get <NbtCompound>(0).Name); Assert.AreEqual(1, file.RootTag.Get <NbtList>("OuterList") .Get <NbtCompound>(0) .Get <NbtList>("InnerList") .Count); Assert.AreEqual(null, file.RootTag.Get <NbtList>("OuterList") .Get <NbtCompound>(0) .Get <NbtList>("InnerList") .Get <NbtCompound>(0) .Name); } }
public ChestBlockEntity() : base("Chest") { Compound = new NbtCompound(string.Empty) { new NbtString("id", Id), new NbtList("Items", new NbtCompound()), new NbtInt("x", Coordinates.X), new NbtInt("y", Coordinates.Y), new NbtInt("z", Coordinates.Z) }; NbtList items = (NbtList)Compound["Items"]; for (byte i = 0; i < 27; i++) { items.Add(new NbtCompound { new NbtByte("Slot", i), new NbtShort("id", 0), new NbtByte("Damage", 0), new NbtByte("Count", 0), }); } }
public void Save() { NbtCompound root = new NbtCompound("base"); root.Add(new NbtString("fileType", "map")); NbtList aList = new NbtList("areas", NbtTagType.Compound); foreach(Area alpha in areas) { aList.Add(alpha.Save()); } root.Add(aList); NbtFile saveFile = new NbtFile(root); saveFile.BigEndian = true; saveFile.SaveToFile("mapfile.nbt", NbtCompression.None); }
public static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk) { var nbt = new NbtFile(); NbtCompound levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtByte("MCPE BID", 1)); // Indicate that the chunks contain PE block ID's. levelTag.Add(new NbtInt("xPos", chunk.x)); levelTag.Add(new NbtInt("zPos", chunk.z)); levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId)); NbtList sectionsTag = new NbtList("Sections", NbtTagType.Compound); levelTag.Add(sectionsTag); for (int i = 0; i < 16; i++) { var section = chunk.chunks[i]; if (section.IsAllAir()) { continue; } NbtCompound sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte)i)); byte[] blocks = new byte[4096]; byte[] data = new byte[2048]; byte[] blockLight = new byte[2048]; byte[] skyLight = new byte[2048]; { for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int anvilIndex = y * 16 * 16 + z * 16 + x; byte blockId = section.GetBlock(x, y, z); blocks[anvilIndex] = blockId; SetNibble4(data, anvilIndex, section.GetMetadata(x, y, z)); SetNibble4(blockLight, anvilIndex, section.GetBlocklight(x, y, z)); SetNibble4(skyLight, anvilIndex, section.GetSkylight(x, y, z)); } } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } int[] heights = new int[256]; for (int h = 0; h < heights.Length; h++) { heights[h] = chunk.height[h]; } levelTag.Add(new NbtIntArray("HeightMap", heights)); // TODO: Save entities NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound); //foreach(var entity in ) levelTag.Add(entitiesTag); NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound); foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values) { NbtCompound nbtClone = (NbtCompound)blockEntityNbt.Clone(); nbtClone.Name = null; blockEntitiesTag.Add(nbtClone); } levelTag.Add(blockEntitiesTag); levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
public NbtTag Serialize(string tagName) { var chunk = new NbtCompound(tagName); var entities = new NbtList("Entities", NbtTagType.Compound); chunk.Add(entities); chunk.Add(new NbtInt("X", X)); chunk.Add(new NbtInt("Z", Z)); chunk.Add(new NbtByteArray("Blocks", Blocks)); chunk.Add(new NbtByteArray("Data", Metadata.Data)); chunk.Add(new NbtByteArray("SkyLight", SkyLight.Data)); chunk.Add(new NbtByteArray("BlockLight", BlockLight.Data)); var tiles = new NbtList("TileEntities", NbtTagType.Compound); foreach (var kvp in TileEntities) { var c = new NbtCompound(); c.Add(new NbtList("coordinates", new[] { new NbtInt(kvp.Key.X), new NbtInt(kvp.Key.Y), new NbtInt(kvp.Key.Z) })); c.Add(new NbtList("value", new[] { kvp.Value })); tiles.Add(c); } chunk.Add(tiles); // TODO: Entities return chunk; }
public void ManipulatingList() { var sameTags = new NbtTag[] { new NbtInt(0), new NbtInt(1), new NbtInt(2) }; var list = new NbtList("Test1", sameTags); // testing enumerator, indexer, Contains, and IndexOf int j = 0; foreach (NbtTag tag in list) { Assert.IsTrue(list.Contains(sameTags[j])); Assert.AreEqual(sameTags[j], tag); Assert.AreEqual(j, list.IndexOf(tag)); j++; } // adding an item of correct type list.Add(new NbtInt(3)); list.Insert(3, new NbtInt(4)); // adding an item of wrong type Assert.Throws<ArgumentException>(() => list.Add(new NbtString())); Assert.Throws<ArgumentException>(() => list.Insert(3, new NbtString())); Assert.Throws<ArgumentNullException>(() => list.Insert(3, null)); // testing array contents for (int i = 0; i < sameTags.Length; i++) { Assert.AreSame(sameTags[i], list[i]); Assert.AreEqual(i, ((NbtInt)list[i]).Value); } // test removal Assert.IsFalse(list.Remove(new NbtInt(5))); Assert.IsTrue(list.Remove(sameTags[0])); Assert.Throws<ArgumentNullException>(() => list.Remove(null)); list.RemoveAt(0); Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(10)); // Test some failure scenarios for Add: // adding a list to itself var loopList = new NbtList(); Assert.AreEqual(NbtTagType.Unknown, loopList.ListType); Assert.Throws<ArgumentException>(() => loopList.Add(loopList)); // adding same tag to multiple lists Assert.Throws<ArgumentException>(() => loopList.Add(list[0])); Assert.Throws<ArgumentException>(() => loopList.Insert(0, list[0])); // adding null tag Assert.Throws<ArgumentNullException>(() => loopList.Add(null)); // make sure that all those failed adds didn't affect the tag Assert.AreEqual(0, loopList.Count); Assert.AreEqual(NbtTagType.Unknown, loopList.ListType); // try creating a list with invalid tag type Assert.Throws<ArgumentOutOfRangeException>(() => new NbtList((NbtTagType)200)); }
private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset) { var nbt = new NbtFile(); NbtCompound levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtInt("xPos", chunk.x)); levelTag.Add(new NbtInt("zPos", chunk.z)); levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId)); NbtList sectionsTag = new NbtList("Sections"); levelTag.Add(sectionsTag); for (int i = 0; i < 8; i++) { NbtCompound sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte) i)); int sy = i*16; byte[] blocks = new byte[4096]; byte[] data = new byte[2048]; byte[] blockLight = new byte[2048]; byte[] skyLight = new byte[2048]; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y; if (yi < 0 || yi >= 256) continue; // ? int anvilIndex = (y + yoffset)*16*16 + z*16 + x; byte blockId = chunk.GetBlock(x, yi, z); // PE to Anvil friendly converstion if (blockId == 5) blockId = 125; else if (blockId == 158) blockId = 126; else if (blockId == 50) blockId = 75; else if (blockId == 50) blockId = 76; else if (blockId == 89) blockId = 123; else if (blockId == 89) blockId = 124; else if (blockId == 73) blockId = 152; blocks[anvilIndex] = blockId; SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z)); SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z)); SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z)); } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } // TODO: Save entities NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound); levelTag.Add(entitiesTag); NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound); levelTag.Add(blockEntitiesTag); foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values) { NbtCompound nbtClone = (NbtCompound) blockEntityNbt.Clone(); nbtClone.Name = null; blockEntitiesTag.Add(nbtClone); } levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return nbt; }
private NbtList GetSlots() { NbtList slots = new NbtList("Items"); for (byte i = 0; i < Size; i++) { MetadataSlot slot = (MetadataSlot) Slots[i]; slots.Add(new NbtCompound { new NbtByte("Count", slot.Value.Count), new NbtByte("Slot", i), new NbtShort("id", slot.Value.Id), new NbtByte("Damage", (byte) slot.Value.Metadata), }); } return slots; }
public void SavePlayer(PlayerEntity entity) { // TODO: Generalize to all mobs NbtFile file = new NbtFile(); var data = new NbtCompound(); data.Add(new NbtByte("OnGround", (byte)(entity.OnGround ? 1 : 0))); data.Add(new NbtShort("Air", entity.Air)); data.Add(new NbtShort("Health", entity.Health)); data.Add(new NbtInt("Dimension", 0)); // TODO data.Add(new NbtInt("foodLevel", entity.Food)); data.Add(new NbtInt("XpLevel", entity.XpLevel)); data.Add(new NbtInt("XpTotal", entity.XpTotal)); data.Add(new NbtFloat("foodExhaustionLevel", entity.FoodExhaustion)); data.Add(new NbtFloat("foodSaturationLevel", entity.FoodSaturation)); data.Add(new NbtFloat("XpP", entity.XpProgress)); data.Add(new NbtList("Equipment")); var inventory = new NbtList("Inventory"); for (int index = 0; index < entity.Inventory.Length; index++) { var slot = entity.Inventory[index]; if (slot.Empty) continue; slot.Index = NetworkSlotToDataSlot(index); inventory.Add(slot.ToNbt()); } data.Add(inventory); var motion = new NbtList("Motion"); motion.Add(new NbtDouble(entity.Velocity.X)); motion.Add(new NbtDouble(entity.Velocity.Y)); motion.Add(new NbtDouble(entity.Velocity.Z)); data.Add(motion); var pos = new NbtList("Pos"); pos.Add(new NbtDouble(entity.Position.X)); pos.Add(new NbtDouble(entity.Position.Y)); pos.Add(new NbtDouble(entity.Position.Z)); data.Add(pos); var rotation = new NbtList("Rotation"); rotation.Add(new NbtFloat(entity.Yaw)); rotation.Add(new NbtFloat(entity.Pitch)); data.Add(rotation); data.Add(new NbtCompound("abilities")); file.RootTag = data; if (!Directory.Exists(Path.Combine(LevelDirectory, "players"))) Directory.CreateDirectory(Path.Combine(LevelDirectory, "players")); using (Stream stream = File.Open(Path.Combine(LevelDirectory, "players", entity.Username + ".dat"), FileMode.OpenOrCreate)) file.SaveToStream(stream, NbtCompression.GZip); }
private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset) { var nbt = new NbtFile(); var levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtInt("xPos", chunk.X)); levelTag.Add(new NbtInt("zPos", chunk.Z)); levelTag.Add(new NbtByteArray("Biomes", chunk.BiomeId)); var sectionsTag = new NbtList("Sections"); levelTag.Add(sectionsTag); for (var i = 0; i < 8; i++) { var sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte) i)); var sy = i*16; var blocks = new byte[4096]; var data = new byte[2048]; var blockLight = new byte[2048]; var skyLight = new byte[2048]; for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 0; y < 16; y++) { var yi = sy + y; if (yi < 0 || yi >= 256) continue; // ? var anvilIndex = (y + yoffset)*16*16 + z*16 + x; var blockId = chunk.GetBlock(x, yi, z); blocks[anvilIndex] = (byte) blockId; SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z)); SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z)); SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z)); } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } levelTag.Add(new NbtList("Entities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileEntities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return nbt; }
public void Save(string p) { var myFile = new NbtFile(); var root = myFile.RootTag; root.Name = "Schematic"; root.Add(new NbtShort("Height", Height)); root.Add(new NbtShort("Length", Length)); root.Add(new NbtShort("Width", Width)); var nbttile = new NbtList("TileEntities", NbtTagType.Compound); var size = Width * Height * Length; _data = new byte[size]; _blocks = new byte[size]; for (int y = 0; y < Height; y++) { for (int z = 0; z < Length; z++) { for (int x = 0; x < Width; x++) { var d = GetBlock(x, y, z); _blocks[(y * Length + z) * Width + x] = (byte)d.ID; _data[(y * Length + z) * Width + x] = (byte)(d.Metta & 0x0F); if (d.Command != null) { var nbtc = new NbtCompound(); nbtc.Add(new NbtString("CustomName", "LuaBlock")); nbtc.Add(new NbtString("Command", d.Command)); nbtc.Add(new NbtString("id", "Control")); nbtc.Add(new NbtInt("x", x)); nbtc.Add(new NbtInt("y", y)); nbtc.Add(new NbtInt("z", z)); nbttile.Add(nbtc); } } } } root.Add(new NbtList("Entities", NbtTagType.Byte)); root.Add(nbttile); root.Add(new NbtList("TileTicks", NbtTagType.Byte)); root.Add(new NbtString("Materials", "Alpha")); root.Add(new NbtByteArray("Data", _data)); // root.Add(new NbtByteArray("Biomes", new byte[Width * Length])); root.Add(new NbtByteArray("Blocks", _blocks)); myFile.SaveToFile(p, NbtCompression.None); }
public static NbtCompound ToNbt(this ItemStack?value) { value ??= new ItemStack(0, 0) { Present = true }; var item = value.AsItem(); var compound = new NbtCompound { new NbtTag <string>("id", item.UnlocalizedName), new NbtTag <byte>("Count", (byte)value.Count), new NbtTag <byte>("Slot", (byte)value.Slot) }; ItemMeta meta = value.ItemMeta; if (meta.HasTags()) { compound.Add(new NbtTag <bool>("Unbreakable", meta.Unbreakable)); if (meta.Durability > 0) { compound.Add(new NbtTag <int>("Damage", meta.Durability)); } if (meta.CustomModelData > 0) { compound.Add(new NbtTag <int>("CustomModelData", meta.CustomModelData)); } if (meta.CanDestroy is not null) { var list = new NbtList(NbtTagType.String, "CanDestroy"); foreach (var block in meta.CanDestroy) { list.Add(new NbtTag <string>(string.Empty, block)); } compound.Add(list); } if (meta.Name is not null) { var displayCompound = new NbtCompound("display") { new NbtTag <string>("Name", new List <ChatMessage> { meta.Name }.ToJson()) }; if (meta.Lore is not null) { var list = new NbtList(NbtTagType.String, "Lore"); foreach (var lore in meta.Lore) { list.Add(new NbtTag <string>(string.Empty, new List <ChatMessage> { lore }.ToJson())); } displayCompound.Add(list); } compound.Add(displayCompound); } else if (meta.Lore is not null) { var displayCompound = new NbtCompound("display") { new NbtTag <string>("Name", new List <ChatMessage> { meta.Name }.ToJson()) }; var list = new NbtList(NbtTagType.String, "Lore"); foreach (var lore in meta.Lore) { list.Add(new NbtTag <string>(string.Empty, new List <ChatMessage> { lore }.ToJson())); } displayCompound.Add(list); compound.Add(displayCompound); } } return(compound); }
public static NbtCompound ExportReactor() { NbtCompound reactor = new NbtCompound("Schematic"); bool coolerIsActive = false; int volume = (int)(Reactor.interiorDims.X * Reactor.interiorDims.Y * Reactor.interiorDims.Z); byte[] blocks = new byte[volume]; byte[] data = new byte[volume]; bool extra = false; byte[] extraBlocks = new byte[volume]; byte[] extraBlocksNibble = new byte[(int)Math.Ceiling(volume / 2.0)]; NbtList tileEntities = new NbtList("TileEntities", NbtTagType.Compound); Dictionary <string, short> mappings = new Dictionary <string, short>(); for (int y = 1; y <= Reactor.interiorDims.Y; y++) { for (int z = 1; z <= Reactor.interiorDims.Z; z++) { for (int x = 1; x <= Reactor.interiorDims.X; x++) { coolerIsActive = false; Block block = Reactor.BlockAt(new Point3D(x, y, z)); int index = (int)((x - 1) + ((y - 1) * Reactor.interiorDims.Z + (z - 1)) * Reactor.interiorDims.X); blocks[index] = (byte)BlockIDLookup[block.BlockType]; if (block.BlockType == BlockTypes.FuelCell | block.BlockType == BlockTypes.Air) { data[index] = 0; } else if (block is Cooler cooler) { if (cooler.Active) { coolerIsActive = true; blocks[index] = 340 - 256; data[index] = 0; tileEntities.Add(CreateActiveCooler(x - 1, y - 1, z - 1)); } else { data[index] = (byte)BlockMetaLookup[cooler.CoolerType.ToString()]; } } else if (block.BlockType == BlockTypes.Moderator) { data[index] = (byte)BlockMetaLookup[((Moderator)block).ModeratorType.ToString()]; } if (coolerIsActive) { extraBlocks[index] = (byte)(340 >> 8); extra = true; } else if ((extraBlocks[index] = (byte)(BlockIDLookup[block.BlockType] >> 8)) > 0) { if (block.BlockType == BlockTypes.Air) { continue; } } if (coolerIsActive) { if (!mappings.ContainsKey("nuclearcraft:active_cooler")) { mappings.Add("nuclearcraft:active_cooler", 340); } else if (!mappings.ContainsKey(SchematicaMappingLookup[block.BlockType])) { mappings.Add(SchematicaMappingLookup[block.BlockType], (short)BlockIDLookup[block.BlockType]); } } } } } for (int i = 0; i < extraBlocksNibble.Length; i++) { if (i * 2 + 1 < extraBlocks.Length) { extraBlocksNibble[i] = (byte)((extraBlocks[i * 2 + 0] << 4) | extraBlocks[i * 2 + 1]); } else { extraBlocksNibble[i] = (byte)(extraBlocks[i * 2 + 0] << 4); } } reactor.Add(new NbtByteArray("Blocks", blocks)); reactor.Add(new NbtShort("Length", (short)Reactor.interiorDims.Z)); reactor.Add(new NbtString("Materials", "Alpha")); reactor.Add(new NbtShort("Height", (short)Reactor.interiorDims.Y)); reactor.Add(new NbtByteArray("Data", data)); reactor.Add(SetIcon()); NbtCompound mappingsC = new NbtCompound("SchematicaMapping"); foreach (KeyValuePair <string, short> kvp in mappings) { mappingsC.Add(new NbtShort(kvp.Key, kvp.Value)); } reactor.Add(mappingsC); reactor.Add(new NbtShort("Width", (short)Reactor.interiorDims.X)); if (extra) { reactor.Add(new NbtByteArray("AddBlocks", extraBlocksNibble)); } reactor.Add(tileEntities); reactor.Add(new NbtList("Entities", NbtTagType.Compound)); return(reactor); }
public void ManipulatingList() { var sameTags = new NbtTag[] { new NbtInt( 0 ), new NbtInt( 1 ), new NbtInt( 2 ) }; NbtList list = new NbtList( "Test1", sameTags ); // testing enumerator int j = 0; foreach( NbtTag tag in list ) { Assert.AreEqual( tag, sameTags[j++] ); } // adding an item of correct type list.Add( new NbtInt( 3 ) ); list.Insert( 3, new NbtInt( 4 ) ); // adding an item of wrong type Assert.Throws<ArgumentException>( () => list.Add( new NbtString() ) ); Assert.Throws<ArgumentException>( () => list.Insert( 3, new NbtString() ) ); // testing array contents for( int i = 0; i < sameTags.Length; i++ ) { Assert.AreSame( sameTags[i], list[i] ); Assert.AreEqual( ( (NbtInt)list[i] ).Value, i ); } // test removal Assert.IsFalse( list.Remove( new NbtInt( 5 ) ) ); Assert.IsTrue( list.Remove( sameTags[0] ) ); list.RemoveAt( 0 ); Assert.Throws<ArgumentOutOfRangeException>( () => list.RemoveAt( 10 ) ); }
public override NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c); c.Add(new NbtShort("BurnTime",BurnTime)); c.Add(new NbtShort("CookTime",CookTime)); NbtList Items = new NbtList("Items"); for (int i = 0; i < 3; i++) { if (Slots[i].ID != 0x00) { NbtCompound cc = new NbtCompound(); cc.Add(new NbtShort("id",Slots[i].ID)); cc.Add(new NbtShort("Damage",(short)Slots[i].Damage)); cc.Add(new NbtByte("Count",(byte)Slots[i].Count)); cc.Add(new NbtByte("Slot", (byte)i)); Items.Add(cc); } } c.Add(Items); return c; }
public NbtCompound writeToNbt(NbtCompound tag, bool deleteEntities) { tag.Add(new NbtByte("hasDoneGen2", this.hasDoneGen2 ? (byte)1 : (byte)0)); byte[] blockBytes = new byte[Chunk.BLOCK_COUNT]; int i, x, y, z; for (i = 0; i < Chunk.BLOCK_COUNT; i++) { blockBytes[i] = (byte)this.blocks[i].id; } tag.Add(new NbtByteArray("blocks", blockBytes)); tag.Add(new NbtByteArray("meta", this.metaData)); tag.Add(new NbtByteArray("light", this.lightLevel)); // Tile Entites. NbtList list = new NbtList("tileEntities", NbtTagType.Compound); foreach (TileEntityBase te in this.tileEntityDict.Values) { list.Add(te.writeToNbt(new NbtCompound())); } tag.Add(list); // Scheduled ticks. list = new NbtList("scheduledTicks", NbtTagType.Compound); ScheduledTick tick; for (i = 0; i < this.scheduledTicks.Count; i++) { tick = this.scheduledTicks[i]; list.Add(this.scheduledTicks[i].writeToNbt()); } tag.Add(list); // Entites. Entity entity; List <Entity> entitiesInChunk = new List <Entity>(); for (i = this.world.entityList.Count - 1; i >= 0; i--) { entity = this.world.entityList[i]; if (!(entity is EntityPlayer)) { x = MathHelper.floor((int)entity.transform.position.x / (float)Chunk.SIZE); y = MathHelper.floor((int)entity.transform.position.y / (float)Chunk.SIZE); z = MathHelper.floor((int)entity.transform.position.z / (float)Chunk.SIZE); if (x == this.chunkPos.x && y == this.chunkPos.y && z == this.chunkPos.z) { world.entityList.Remove(entity); entitiesInChunk.Add(entity); } } } NbtList list1 = new NbtList("entities", NbtTagType.Compound); for (i = 0; i < entitiesInChunk.Count; i++) { entity = entitiesInChunk[i]; list1.Add(entity.writeToNbt(new NbtCompound())); if (deleteEntities) { GameObject.Destroy(entity.gameObject); } } tag.Add(list1); return(tag); }
public INbtTag ReadNextTag(bool readName = true) { var firstType = this.ReadTagType(); string tagName = ""; if (readName) { tagName = this.ReadString(); } switch (firstType) { case NbtTagType.End: return(null); case NbtTagType.Byte: case NbtTagType.Short: case NbtTagType.Int: case NbtTagType.Long: case NbtTagType.Float: case NbtTagType.Double: case NbtTagType.String: { var tag = this.GetCurrentTag(firstType, !readName); if (readName) { tag.Name = tagName; } return(tag); } case NbtTagType.List: var listType = this.ReadTagType(); var list = new NbtList(listType, tagName); var length = this.ReadInt32(); if (length < 0) { throw new InvalidOperationException("Got negative list length."); } for (var i = 0; i < length; i++) { list.Add(this.GetCurrentTag(listType, false)); } return(list); case NbtTagType.Compound: return(this.ReadCompoundTag(tagName)); case NbtTagType.ByteArray: return(this.ReadArray(tagName, firstType)); case NbtTagType.IntArray: return(this.ReadArray(tagName, firstType)); case NbtTagType.LongArray: return(this.ReadArray(tagName, firstType)); case NbtTagType.Unknown: break; default: break; } return(null); }
public NbtTag Serialize(string tagName) { var chunk = (NbtCompound)Serializer.Serialize(this, tagName, true); var entities = new NbtList("Entities", NbtTagType.Compound); for (int i = 0; i < Entities.Count; i++) entities.Add(Entities[i].Serialize(string.Empty)); chunk.Add(entities); var sections = new NbtList("Sections", NbtTagType.Compound); var serializer = new NbtSerializer(typeof(Section)); for (int i = 0; i < Sections.Length; i++) { if (!Sections[i].IsAir) sections.Add(serializer.Serialize(Sections[i])); } chunk.Add(sections); return chunk; }
public void Serializing1() { // check the basics of saving/loading const NbtTagType expectedListType = NbtTagType.Int; const int elements = 10; // construct nbt file var writtenFile = new NbtFile(new NbtCompound("ListTypeTest")); var writtenList = new NbtList("Entities", null, expectedListType); for (int i = 0; i < elements; i++) { writtenList.Add(new NbtInt(i)); } writtenFile.RootTag.Add(writtenList); // test saving byte[] data = writtenFile.SaveToBuffer(NbtCompression.None); // test loading var readFile = new NbtFile(); long bytesRead = readFile.LoadFromBuffer(data, 0, data.Length, NbtCompression.None); Assert.AreEqual(bytesRead, data.Length); // check contents of loaded file Assert.NotNull(readFile.RootTag); Assert.IsInstanceOf<NbtList>(readFile.RootTag["Entities"]); var readList = (NbtList)readFile.RootTag["Entities"]; Assert.AreEqual(writtenList.ListType, readList.ListType); Assert.AreEqual(readList.Count, writtenList.Count); // check .ToArray CollectionAssert.AreEquivalent(readList, readList.ToArray()); CollectionAssert.AreEquivalent(readList, readList.ToArray<NbtInt>()); // check contents of loaded list for (int i = 0; i < elements; i++) { Assert.AreEqual(readList.Get<NbtInt>(i).Value, writtenList.Get<NbtInt>(i).Value); } }
public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false) { if (!skipInterfaceCheck && value is INbtSerializable) { return(((INbtSerializable)value).Serialize(tagName)); } else if (value is NbtTag) { return((NbtTag)value); } else if (value is byte) { return(new NbtByte(tagName, (byte)value)); } else if (value is sbyte) { return(new NbtByte(tagName, (byte)(sbyte)value)); } else if (value is bool) { return(new NbtByte(tagName, (byte)((bool)value ? 1 : 0))); } else if (value is byte[]) { return(new NbtByteArray(tagName, (byte[])value)); } else if (value is double) { return(new NbtDouble(tagName, (double)value)); } else if (value is float) { return(new NbtFloat(tagName, (float)value)); } else if (value is int) { return(new NbtInt(tagName, (int)value)); } else if (value is uint) { return(new NbtInt(tagName, (int)(uint)value)); } else if (value is int[]) { return(new NbtIntArray(tagName, (int[])value)); } else if (value is long) { return(new NbtLong(tagName, (long)value)); } else if (value is ulong) { return(new NbtLong(tagName, (long)(ulong)value)); } else if (value is short) { return(new NbtShort(tagName, (short)value)); } else if (value is ushort) { return(new NbtShort(tagName, (short)(ushort)value)); } else if (value is string) { return(new NbtString(tagName, (string)value)); } else if (value.GetType().IsArray) { var elementType = value.GetType().GetElementType(); var array = value as Array; var listType = NbtTagType.Compound; if (elementType == typeof(byte) || elementType == typeof(sbyte)) { listType = NbtTagType.Byte; } else if (elementType == typeof(bool)) { listType = NbtTagType.Byte; } else if (elementType == typeof(byte[])) { listType = NbtTagType.ByteArray; } else if (elementType == typeof(double)) { listType = NbtTagType.Double; } else if (elementType == typeof(float)) { listType = NbtTagType.Float; } else if (elementType == typeof(int) || elementType == typeof(uint)) { listType = NbtTagType.Int; } else if (elementType == typeof(int[])) { listType = NbtTagType.IntArray; } else if (elementType == typeof(long) || elementType == typeof(ulong)) { listType = NbtTagType.Long; } else if (elementType == typeof(short) || elementType == typeof(ushort)) { listType = NbtTagType.Short; } else if (elementType == typeof(string)) { listType = NbtTagType.String; } var list = new NbtList(tagName, listType); var innerSerializer = new NbtSerializer(elementType); for (int i = 0; i < array.Length; i++) { list.Add(innerSerializer.Serialize(array.GetValue(i))); } return(list); } else if (value is NbtFile) { return(((NbtFile)value).RootTag); } else { var compound = new NbtCompound(tagName); if (value == null) { return(compound); } var nameAttributes = Attribute.GetCustomAttributes(value.GetType(), typeof(TagNameAttribute)); if (nameAttributes.Length > 0) { compound = new NbtCompound(((TagNameAttribute)nameAttributes[0]).Name); } var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p, typeof(NbtIgnoreAttribute)).Any()); foreach (var property in properties) { if (!property.CanRead) { continue; } NbtTag tag = null; string name = property.Name; nameAttributes = Attribute.GetCustomAttributes(property, typeof(TagNameAttribute)); var ignoreOnNullAttribute = Attribute.GetCustomAttribute(property, typeof(IgnoreOnNullAttribute)); if (nameAttributes.Length != 0) { name = ((TagNameAttribute)nameAttributes[0]).Name; } var innerSerializer = new NbtSerializer(property.PropertyType); var propValue = property.GetValue(value, null); if (propValue == null) { if (ignoreOnNullAttribute != null) { continue; } if (property.PropertyType.IsValueType) { propValue = Activator.CreateInstance(property.PropertyType); } else if (property.PropertyType == typeof(string)) { propValue = ""; } } tag = innerSerializer.Serialize(propValue, name); compound.Add(tag); } return(compound); } }
public NbtFile ToNbt() // TODO: Entities { NbtFile file = new NbtFile(); NbtCompound level = new NbtCompound("Level"); // Entities // TODO level.Add(new NbtList("Entities", NbtTagType.Compound)); // Biomes level.Add(new NbtByteArray("Biomes", Biomes)); // Last Update // TODO: What is this level.Add(new NbtLong("LastUpdate", 15)); // Position level.Add(new NbtInt("xPos", (int)AbsolutePosition.X)); level.Add(new NbtInt("zPos", (int)AbsolutePosition.Z)); // Tile Entities var tileEntityList = new NbtList("TileEntities", NbtTagType.Compound); foreach (var tileEntity in TileEntities) { // Get properties tileEntityList.Add(tileEntity.Value.ToNbt(tileEntity.Key)); } level.Add(tileEntityList); // Terrain Populated // TODO: When is this 0? Will vanilla use this? level.Add(new NbtByte("TerrainPopualted", 0)); // Sections and height level.Add(new NbtIntArray("HeightMap", HeightMap)); NbtList sectionList = new NbtList("Sections", NbtTagType.Compound); foreach (var section in Sections) { if (!section.IsAir) { NbtCompound sectionTag = new NbtCompound(); sectionTag.Add(new NbtByte("Y", section.Y)); sectionTag.Add(new NbtByteArray("Blocks", section.Blocks)); sectionTag.Add(new NbtByteArray("Data", section.Metadata.Data)); sectionTag.Add(new NbtByteArray("SkyLight", section.SkyLight.Data)); sectionTag.Add(new NbtByteArray("BlockLight", section.BlockLight.Data)); sectionList.Add(sectionTag); } } level.Add(sectionList); var rootCompound = new NbtCompound(""); rootCompound.Add(level); file.RootTag = rootCompound; return file; }
public void NestedListAndCompoundTest() { byte[] data; { var root = new NbtCompound("Root"); var outerList = new NbtList("OuterList", NbtTagType.Compound); var outerCompound = new NbtCompound(); var innerList = new NbtList("InnerList", NbtTagType.Compound); var innerCompound = new NbtCompound(); innerList.Add(innerCompound); outerCompound.Add(innerList); outerList.Add(outerCompound); root.Add(outerList); var file = new NbtFile(root); data = file.SaveToBuffer(NbtCompression.None); } { var file = new NbtFile(); long bytesRead = file.LoadFromBuffer(data, 0, data.Length, NbtCompression.None); Assert.AreEqual(bytesRead, data.Length); Assert.AreEqual(1, file.RootTag.Get<NbtList>("OuterList").Count); Assert.AreEqual(null, file.RootTag.Get<NbtList>("OuterList").Get<NbtCompound>(0).Name); Assert.AreEqual(1, file.RootTag.Get<NbtList>("OuterList") .Get<NbtCompound>(0) .Get<NbtList>("InnerList") .Count); Assert.AreEqual(null, file.RootTag.Get<NbtList>("OuterList") .Get<NbtCompound>(0) .Get<NbtList>("InnerList") .Get<NbtCompound>(0) .Name); } }
public NbtCompound Save() { NbtCompound rtn = new NbtCompound(); rtn.Add(new NbtString("name", name)); NbtList ground = new NbtList("ground", NbtTagType.Compound); NbtList portal = new NbtList("portal", NbtTagType.Compound); NbtList decor = new NbtList("decor", NbtTagType.Compound); foreach(Point alpha in map.Keys) { if(map[alpha] is Platform) { ground.Add(new NbtCompound(new NbtByte[] { new NbtByte("x", (byte)alpha.X), new NbtByte("y", (byte)alpha.Y) })); } else if(map[alpha] is Portal) { portal.Add(new NbtCompound(new NbtTag[] { new NbtByte("x", (byte)alpha.X), new NbtByte("y", (byte)alpha.Y), new NbtString("linkTo", ((Portal)map[alpha]).Link.MyArea.Name), new NbtByte("linkX", (byte)((Portal)map[alpha]).Link.Location.X), new NbtByte("linkY", (byte)((Portal)map[alpha]).Link.Location.Y) })); } } rtn.AddRange(new NbtList[] { ground, portal, decor }); return rtn; }
private NbtTag ReadPayload(NbtTagType nbtType) { switch (nbtType) { case NbtTagType.Byte: return(new NbtByte(_reader.ReadSByte())); case NbtTagType.Short: return(new NbtShort(_reader.ReadInt16())); case NbtTagType.Int: return(new NbtInt(_reader.ReadInt32())); case NbtTagType.Long: return(new NbtLong(_reader.ReadInt64())); case NbtTagType.Float: return(new NbtFloat(_reader.ReadSingle())); case NbtTagType.Double: return(new NbtDouble(_reader.ReadDouble())); case NbtTagType.ByteArray: { var size = _reader.ReadInt32(); var array = new sbyte[size]; for (var i = 0; i < size; i++) { array[i] = _reader.ReadSByte(); } return(new NbtByteArray(array)); } case NbtTagType.String: return(new NbtString(new string(_reader.ReadChars(_reader.ReadUInt16(), false)))); case NbtTagType.List: { var contentType = (NbtTagType)_reader.ReadByte(); var size = _reader.ReadInt32(); var list = new NbtList(); for (var i = 0; i < size; i++) { list.Add(ReadPayload(contentType)); } return(list); } case NbtTagType.Compound: { var compound = new NbtCompound(); NbtTag tag; while ((tag = ReadTag()).Type != NbtTagType.End) { compound.Add(tag); } return(compound); } case NbtTagType.IntArray: { var size = _reader.ReadInt32(); var array = new int[size]; for (var i = 0; i < size; i++) { array[i] = _reader.ReadInt32(); } return(new NbtIntArray(array)); } case NbtTagType.LongArray: { var size = _reader.ReadInt32(); var array = new long[size]; for (var i = 0; i < size; i++) { array[i] = _reader.ReadInt64(); } return(new NbtLongArray(array)); } default: throw new NbtException($"Unknow tag. Tag id: {(sbyte)nbtType}"); } }
/** * AFTER the opening [ */ private NbtList ParseList() { bool more = true; //I'm sensing a pattern here... NbtList list = new NbtList(); NbtTag current = null; int index = -1; while (more) { char next; try { next = NextChar(); } catch (Exception) { throw new Exception(@"Unexpected EOF, expected ']'"); } switch (next) { case ']': more = false; goto case ','; //f****n fall through. case ',': if (current != null) { if (index != -1) { if (index >= list.Count) { for (int i = list.Count; i <= index; i++) { list.Add((NbtTag)current.GetType().GetConstructor(new Type[0]).Invoke(new object[0])); //HOLY FUCKNUGGETS } } list[index] = current; } else { list.Add(current); } index = -1; current = null; } break; case ' ': case '\t': case '\r': case '\n': break; case ':': //oh noes explicit index, doesn't even have to be in order. index = current.IntValue; current = null; break; default: Position--; current = ParseTag(); break; } } return(list); }
public void ManipulatingList() { var sameTags = new NbtTag[] { new NbtInt(0), new NbtInt(1), new NbtInt(2) }; var list = new NbtList("Test1", sameTags); // testing enumerator, indexer, Contains, and IndexOf int j = 0; foreach (NbtTag tag in list) { Assert.IsTrue(list.Contains(sameTags[j])); Assert.AreEqual(sameTags[j], tag); Assert.AreEqual(j, list.IndexOf(tag)); j++; } // adding an item of correct type list.Add(new NbtInt(3)); list.Insert(3, new NbtInt(4)); // adding an item of wrong type Assert.Throws <ArgumentException>(() => list.Add(new NbtString())); Assert.Throws <ArgumentException>(() => list.Insert(3, new NbtString())); Assert.Throws <ArgumentNullException>(() => list.Insert(3, null)); // testing array contents for (int i = 0; i < sameTags.Length; i++) { Assert.AreSame(sameTags[i], list[i]); Assert.AreEqual(i, ((NbtInt)list[i]).Value); } // test removal Assert.IsFalse(list.Remove(new NbtInt(5))); Assert.IsTrue(list.Remove(sameTags[0])); Assert.Throws <ArgumentNullException>(() => list.Remove(null)); list.RemoveAt(0); Assert.Throws <ArgumentOutOfRangeException>(() => list.RemoveAt(10)); // Test some failure scenarios for Add: // adding a list to itself var loopList = new NbtList(); Assert.AreEqual(NbtTagType.Unknown, loopList.ListType); Assert.Throws <ArgumentException>(() => loopList.Add(loopList)); // adding same tag to multiple lists Assert.Throws <ArgumentException>(() => loopList.Add(list[0])); Assert.Throws <ArgumentException>(() => loopList.Insert(0, list[0])); // adding null tag Assert.Throws <ArgumentNullException>(() => loopList.Add(null)); // make sure that all those failed adds didn't affect the tag Assert.AreEqual(0, loopList.Count); Assert.AreEqual(NbtTagType.Unknown, loopList.ListType); // try creating a list with invalid tag type Assert.Throws <ArgumentOutOfRangeException>(() => new NbtList((NbtTagType)200)); }
public void Serializing() { string fileName = Path.Combine( TempDir, "NbtListType.nbt" ); const NbtTagType expectedListType = NbtTagType.Int; const int elements = 10; // construct nbt file NbtFile writtenFile = new NbtFile( new NbtCompound( "ListTypeTest" ) ); NbtList writtenList = new NbtList( "Entities", null, expectedListType ); for( int i = 0; i < elements; i++ ) { writtenList.Add( new NbtInt( i ) ); } writtenFile.RootTag.Add( writtenList ); // test saving writtenFile.SaveToFile( fileName, NbtCompression.GZip ); // test loading NbtFile readFile = new NbtFile( fileName ); // check contents of loaded file Assert.NotNull( readFile.RootTag ); Assert.IsInstanceOf<NbtList>( readFile.RootTag["Entities"] ); NbtList readList = (NbtList)readFile.RootTag["Entities"]; Assert.AreEqual( readList.ListType, writtenList.ListType ); Assert.AreEqual( readList.Count, writtenList.Count ); // check .ToArray CollectionAssert.AreEquivalent( readList, readList.ToArray() ); CollectionAssert.AreEquivalent( readList, readList.ToArray<NbtInt>() ); // check contents of loaded list for( int i = 0; i < elements; i++ ) { Assert.AreEqual( readList.Get<NbtInt>( i ).Value, writtenList.Get<NbtInt>( i ).Value ); } }
public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user) { var adjacent = -Coordinates3D.One; // -1, no adjacent chest var self = descriptor.Coordinates; for (int i = 0; i < AdjacentBlocks.Length; i++) { var test = self + AdjacentBlocks[i]; if (world.GetBlockID(test) == ChestBlock.BlockID) { adjacent = test; var up = world.BlockRepository.GetBlockProvider(world.GetBlockID(test + Coordinates3D.Up)); if (up.Opaque && !(up is WallSignBlock)) // Wall sign blocks are an exception return false; // Obstructed break; } } var upSelf = world.BlockRepository.GetBlockProvider(world.GetBlockID(self + Coordinates3D.Up)); if (upSelf.Opaque && !(upSelf is WallSignBlock)) return false; // Obstructed if (adjacent != -Coordinates3D.One) { // Ensure that chests are always opened in the same arrangement if (adjacent.X < self.X || adjacent.Z < self.Z) { var _ = adjacent; adjacent = self; self = _; // Swap } } var window = new ChestWindow((InventoryWindow)user.Inventory, adjacent != -Coordinates3D.One); // Add items var entity = world.GetTileEntity(self); if (entity != null) { foreach (var item in (NbtList)entity["Items"]) { var slot = ItemStack.FromNbt((NbtCompound)item); window.ChestInventory[slot.Index] = slot; } } // Add adjacent items if (adjacent != -Coordinates3D.One) { entity = world.GetTileEntity(adjacent); if (entity != null) { foreach (var item in (NbtList)entity["Items"]) { var slot = ItemStack.FromNbt((NbtCompound)item); window.ChestInventory[slot.Index + ChestWindow.DoubleChestSecondaryIndex] = slot; } } } window.WindowChange += (sender, e) => { var entitySelf = new NbtList("Items", NbtTagType.Compound); var entityAdjacent = new NbtList("Items", NbtTagType.Compound); for (int i = 0; i < window.ChestInventory.Items.Length; i++) { var item = window.ChestInventory.Items[i]; if (!item.Empty) { if (i < ChestWindow.DoubleChestSecondaryIndex) { item.Index = i; entitySelf.Add(item.ToNbt()); } else { item.Index = i - ChestWindow.DoubleChestSecondaryIndex; entityAdjacent.Add(item.ToNbt()); } } } var newEntity = world.GetTileEntity(self); if (newEntity == null) newEntity = new NbtCompound(new[] { entitySelf }); else newEntity["Items"] = entitySelf; world.SetTileEntity(self, newEntity); if (adjacent != -Coordinates3D.One) { newEntity = world.GetTileEntity(adjacent); if (newEntity == null) newEntity = new NbtCompound(new[] { entityAdjacent }); else newEntity["Items"] = entityAdjacent; world.SetTileEntity(adjacent, newEntity); } }; user.OpenWindow(window); return false; }
public static NbtTag Serialize(object obj) { switch (obj) { case IDictionary dictionary: return(dictionary.ToNbtCompound()); case IEnumerable <sbyte> enumerable: return(new NbtByteArray(enumerable.ToArray())); case IEnumerable <int> enumerable: return(new NbtIntArray(enumerable.ToArray())); case IEnumerable <long> enumerable: return(new NbtLongArray(enumerable.ToArray())); case IEnumerable enumerable: { var list = new NbtList(); foreach (var obj1 in enumerable) { list.Add(Serialize(obj1)); } return(list); } } var type = obj.GetType(); var tag = new NbtCompound(); if (!type.GetCustomAttributes().Any(attribute => attribute is NbtCompoundAttribute)) { throw new SerializationException($"the object must inherit {typeof(NbtCompoundAttribute)}"); } foreach (var property in type.GetProperties()) { var value = property.GetValue(obj); if (value == null) { continue; } var attribute = property.GetCustomAttribute <NbtTagAttribute>(); if (attribute == null) { continue; } var name = attribute.Name; switch (attribute.Type) { case NbtTagType.End: break; case NbtTagType.Byte: tag.Add(NbtValue.CreateValue(value), name); break; case NbtTagType.Short: tag.Add(NbtValue.CreateValue(value), name); break; case NbtTagType.Int: tag.Add(NbtValue.CreateValue(value), name); break; case NbtTagType.Long: tag.Add(NbtValue.CreateValue(value), name); break; case NbtTagType.Float: tag.Add(NbtValue.CreateValue(value), name); break; case NbtTagType.Double: tag.Add(NbtValue.CreateValue(value), name); break; case NbtTagType.ByteArray: tag.Add(new NbtByteArray(((IEnumerable <sbyte>)value).ToArray()), name); break; case NbtTagType.String: tag.Add(NbtValue.CreateValue(value), name); break; case NbtTagType.List: tag.Add(Serialize(value), name); break; case NbtTagType.Compound: tag.Add(Serialize(value), name); break; case NbtTagType.IntArray: tag.Add(new NbtIntArray(((IEnumerable <int>)value).ToArray()), name); break; case NbtTagType.LongArray: tag.Add(new NbtLongArray(((IEnumerable <long>)value).ToArray()), name); break; default: throw new ArgumentOutOfRangeException(); } } return(tag); }
internal static bool ReadTag(this NbtTag tag, NbtBinaryReader readStream) { while (true) { NbtTag nbtTag; do { NbtTagType nbtTagType = readStream.ReadTagType(); switch (nbtTagType) { case NbtTagType.End: return(true); case NbtTagType.Byte: nbtTag = (NbtTag) new NbtByte(); break; case NbtTagType.Short: nbtTag = (NbtTag) new NbtShort(); break; case NbtTagType.Int: nbtTag = (NbtTag) new NbtInt(); break; case NbtTagType.Long: nbtTag = (NbtTag) new NbtLong(); break; case NbtTagType.Float: nbtTag = (NbtTag) new NbtFloat(); break; case NbtTagType.Double: nbtTag = (NbtTag) new NbtDouble(); break; case NbtTagType.ByteArray: nbtTag = (NbtTag) new NbtByteArray(); break; case NbtTagType.String: nbtTag = (NbtTag) new NbtString(); break; case NbtTagType.List: nbtTag = (NbtTag) new NbtList(); break; case NbtTagType.Compound: nbtTag = (NbtTag) new NbtCompound(); break; case NbtTagType.IntArray: nbtTag = (NbtTag) new NbtIntArray(); break; case NbtTagType.LongArray: nbtTag = (NbtTag) new NbtLongArray(); break; case NbtTagType.Unknown: return(true); break; default: throw new FormatException("Unsupported tag type found in NBT_Compound: " + (object)nbtTagType); } //nbtTag.Parent = (NbtTag) this; nbtTag.Name = readStream.ReadString(); }while (!nbtTag.ReadTag(readStream)); switch (tag.TagType) { case NbtTagType.Compound: NbtCompound compound = (NbtCompound)tag; compound.Add(nbtTag); break; case NbtTagType.List: NbtList list = (NbtList)tag; list.Add(nbtTag); break; } } }
public override void SaveChunk(Chunk cnk) { NbtFile c = new NbtFile(cnk.Filename); c.RootTag = NewNBTChunk(cnk.Position.X, cnk.Position.Z); NbtCompound Level = (NbtCompound)c.RootTag["Level"]; // BLOCKS ///////////////////////////////////////////////////// byte[] blocks = new byte[ChunkX * ChunkZ * ChunkY]; for (int x = 0; x < ChunkX; x++) { for (int y = 0; y < ChunkY; y++) { for (int z = 0; z < ChunkZ; z++) { blocks[GetBlockIndex(x, y, z)] = cnk.Blocks[x, y, z]; } } } Level.Set("xPos", new NbtInt("xPos", (int)cnk.Position.X)); Level.Set("zPos", new NbtInt("zPos", (int)cnk.Position.Z)); Level.Set("Blocks", new NbtByteArray("Blocks", blocks)); blocks = null; // LIGHTING /////////////////////////////////////////////////// byte[] lighting = CompressLightmap(cnk.SkyLight,true); Level.Set("SkyLight",new NbtByteArray("SkyLight", lighting)); lighting = CompressLightmap(cnk.BlockLight,false); Level.Set("BlockLight",new NbtByteArray("BlockLight", lighting)); lighting = CompressDatamap(cnk.Data); Level.Set("Data", new NbtByteArray("Data", lighting)); // HEIGHTMAP (Needed for lighting). byte[] hm = new byte[256]; for (int x = 0; x < ChunkX; x++) { for (int z = 0; z < ChunkZ; z++) { hm[z << 4 | x] = (byte)(cnk.HeightMap[x, z] & 0xff); // idk } } Level.Set("HeightMap", new NbtByteArray("HeightMap", hm)); NbtList ents = new NbtList("Entities"); // ENTITIES /////////////////////////////////////////////////// foreach (KeyValuePair<Guid, Entity> ent in cnk.Entities) { ents.Add(ent.Value.ToNBT()); } Level.Set("Entities",ents); NbtList tents = new NbtList("TileEntities"); // TILE ENTITIES ////////////////////////////////////////////// foreach (KeyValuePair<Guid, TileEntity> tent in cnk.TileEntities) { tents.Add(tent.Value.ToNBT()); } Level.Set("TileEntities",tents); // Tick when last saved. But ticks are process associated... Level.Set("LastUpdate", new NbtLong("LastUpdate", (long)Utils.UnixTimestamp())); c.RootTag.Set("Level",Level); c.SaveFile(GetChunkFilename((int)cnk.Position.X,(int)cnk.Position.Z)); // For debuggan File.WriteAllText(cnk.Filename + ".txt", c.RootTag.ToString()); Cache.SaveChunkMetadata(cnk); // This is probably what lags. }
public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user) { var adjacent = -Coordinates3D.One; // -1, no adjacent chest var self = descriptor.Coordinates; for (int i = 0; i < AdjacentBlocks.Length; i++) { var test = self + AdjacentBlocks[i]; if (world.GetBlockID(test) == ChestBlock.BlockID) { adjacent = test; var up = world.BlockRepository.GetBlockProvider(world.GetBlockID(test + Coordinates3D.Up)); if (up.Opaque) { return(false); // Obstructed } break; } } var upSelf = world.BlockRepository.GetBlockProvider(world.GetBlockID(self + Coordinates3D.Up)); if (upSelf.Opaque) { return(false); // Obstructed } if (adjacent != -Coordinates3D.One) { // Ensure that chests are always opened in the same arrangement if (adjacent.X < self.X || adjacent.Z < self.Z) { var _ = adjacent; adjacent = self; self = _; // Swap } } var window = new ChestWindow((InventoryWindow)user.Inventory, adjacent != -Coordinates3D.One); // Add items var entity = world.GetTileEntity(self); if (entity != null) { foreach (var item in (NbtList)entity["Items"]) { var slot = ItemStack.FromNbt((NbtCompound)item); window.ChestInventory[slot.Index] = slot; } } // Add adjacent items if (adjacent != -Coordinates3D.One) { entity = world.GetTileEntity(adjacent); if (entity != null) { foreach (var item in (NbtList)entity["Items"]) { var slot = ItemStack.FromNbt((NbtCompound)item); window.ChestInventory[slot.Index + ChestWindow.DoubleChestSecondaryIndex] = slot; } } } window.WindowChange += (sender, e) => { var entitySelf = new NbtList("Items", NbtTagType.Compound); var entityAdjacent = new NbtList("Items", NbtTagType.Compound); for (int i = 0; i < window.ChestInventory.Items.Length; i++) { var item = window.ChestInventory.Items[i]; if (!item.Empty) { if (i < ChestWindow.DoubleChestSecondaryIndex) { item.Index = i; entitySelf.Add(item.ToNbt()); } else { item.Index = i - ChestWindow.DoubleChestSecondaryIndex; entityAdjacent.Add(item.ToNbt()); } } } var newEntity = world.GetTileEntity(self); if (newEntity == null) { newEntity = new NbtCompound(new[] { entitySelf }); } else { newEntity["Items"] = entitySelf; } world.SetTileEntity(self, newEntity); if (adjacent != -Coordinates3D.One) { newEntity = world.GetTileEntity(adjacent); if (newEntity == null) { newEntity = new NbtCompound(new[] { entityAdjacent }); } else { newEntity["Items"] = entityAdjacent; } world.SetTileEntity(adjacent, newEntity); } }; user.OpenWindow(window); return(false); }
NbtTag SerializeList(string tagName, IList valueAsArray, Type elementType, NullPolicy elementNullPolicy) { NbtTagType listType; if (elementType == typeof(byte) || elementType == typeof(sbyte) || elementType == typeof(bool)) { listType = NbtTagType.Byte; } else if (elementType == typeof(byte[])) { listType = NbtTagType.ByteArray; } else if (elementType == typeof(double)) { listType = NbtTagType.Double; } else if (elementType == typeof(float)) { listType = NbtTagType.Float; } else if (elementType == typeof(int) || elementType == typeof(uint)) { listType = NbtTagType.Int; } else if (elementType == typeof(int[])) { listType = NbtTagType.IntArray; } else if (elementType == typeof(long) || elementType == typeof(ulong)) { listType = NbtTagType.Long; } else if (elementType == typeof(short) || elementType == typeof(ushort)) { listType = NbtTagType.Short; } else if (elementType == typeof(string)) { listType = NbtTagType.String; } else { listType = NbtTagType.Compound; } var list = new NbtList(tagName, listType); if (elementType.IsPrimitive) { // speedy serialization for basic types for (int i = 0; i < valueAsArray.Count; i++) { list.Add(SerializePrimitiveType(null, valueAsArray[i])); } } else if (SerializationUtil.IsDirectlyMappedType(elementType)) { // speedy serialization for directly-mapped types for (int i = 0; i < valueAsArray.Count; i++) { var value = valueAsArray[i]; if (value == null) { switch (elementNullPolicy) { case NullPolicy.Error: throw new NullReferenceException("Null elements not allowed for tag " + tagName); case NullPolicy.InsertDefault: list.Add(Serialize(SerializationUtil.GetDefaultValue(elementType), true)); break; case NullPolicy.Ignore: continue; } } else { list.Add(Serialize(valueAsArray[i], true)); } } } else { // serialize complex types var innerSerializer = new NbtSerializer(elementType); for (int i = 0; i < valueAsArray.Count; i++) { var value = valueAsArray[i]; if (value == null) { switch (elementNullPolicy) { case NullPolicy.Error: throw new NullReferenceException("Null elements not allowed for tag " + tagName); case NullPolicy.Ignore: continue; case NullPolicy.InsertDefault: // TODO break; } } else { list.Add(innerSerializer.Serialize(valueAsArray[i], null)); } } } return list; }
public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false) { if (!skipInterfaceCheck && value is INbtSerializable) return ((INbtSerializable)value).Serialize(tagName); else if (value is NbtTag) return (NbtTag)value; else if (value is byte) return new NbtByte(tagName, (byte)value); else if (value is sbyte) return new NbtByte(tagName, (byte)(sbyte)value); else if (value is bool) return new NbtByte(tagName, (byte)((bool)value ? 1 : 0)); else if (value is byte[]) return new NbtByteArray(tagName, (byte[])value); else if (value is double) return new NbtDouble(tagName, (double)value); else if (value is float) return new NbtFloat(tagName, (float)value); else if (value is int) return new NbtInt(tagName, (int)value); else if (value is uint) return new NbtInt(tagName, (int)(uint)value); else if (value is int[]) return new NbtIntArray(tagName, (int[])value); else if (value is long) return new NbtLong(tagName, (long)value); else if (value is ulong) return new NbtLong(tagName, (long)(ulong)value); else if (value is short) return new NbtShort(tagName, (short)value); else if (value is ushort) return new NbtShort(tagName, (short)(ushort)value); else if (value is string) return new NbtString(tagName, (string)value); else if (value.GetType().IsArray) { var elementType = value.GetType().GetElementType(); var array = value as Array; var listType = NbtTagType.Compound; if (elementType == typeof (byte) || elementType == typeof (sbyte)) listType = NbtTagType.Byte; else if (elementType == typeof (bool)) listType = NbtTagType.Byte; else if (elementType == typeof (byte[])) listType = NbtTagType.ByteArray; else if (elementType == typeof (double)) listType = NbtTagType.Double; else if (elementType == typeof (float)) listType = NbtTagType.Float; else if (elementType == typeof (int) || elementType == typeof (uint)) listType = NbtTagType.Int; else if (elementType == typeof (int[])) listType = NbtTagType.IntArray; else if (elementType == typeof (long) || elementType == typeof (ulong)) listType = NbtTagType.Long; else if (elementType == typeof (short) || elementType == typeof (ushort)) listType = NbtTagType.Short; else if (elementType == typeof (string)) listType = NbtTagType.String; var list = new NbtList(tagName, listType); var innerSerializer = new NbtSerializer(elementType); for (int i = 0; i < array.Length; i++) list.Add(innerSerializer.Serialize(array.GetValue(i))); return list; } else if (value is NbtFile) return ((NbtFile)value).RootTag; else { var compound = new NbtCompound(tagName); if (value == null) return compound; var nameAttributes = Attribute.GetCustomAttributes(value.GetType(), typeof (TagNameAttribute)); if (nameAttributes.Length > 0) compound = new NbtCompound(((TagNameAttribute)nameAttributes[0]).Name); var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p, typeof (NbtIgnoreAttribute)).Any()); foreach (var property in properties) { if (!property.CanRead) continue; NbtTag tag = null; string name = property.Name; nameAttributes = Attribute.GetCustomAttributes(property, typeof (TagNameAttribute)); var ignoreOnNullAttribute = Attribute.GetCustomAttribute(property, typeof(IgnoreOnNullAttribute)); if (nameAttributes.Length != 0) name = ((TagNameAttribute)nameAttributes[0]).Name; var innerSerializer = new NbtSerializer(property.PropertyType); var propValue = property.GetValue(value, null); if (propValue == null) { if (ignoreOnNullAttribute != null) continue; if (property.PropertyType.IsValueType) { propValue = Activator.CreateInstance(property.PropertyType); } else if (property.PropertyType == typeof (string)) propValue = ""; } tag = innerSerializer.Serialize(propValue, name); compound.Add(tag); } return compound; } }
public static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset) { var nbt = new NbtFile(); NbtCompound levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtInt("xPos", chunk.x)); levelTag.Add(new NbtInt("zPos", chunk.z)); levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId)); NbtList sectionsTag = new NbtList("Sections"); levelTag.Add(sectionsTag); for (int i = 0; i < 8; i++) { NbtCompound sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte)i)); int sy = i * 16; byte[] blocks = new byte[4096]; byte[] data = new byte[2048]; byte[] blockLight = new byte[2048]; byte[] skyLight = new byte[2048]; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y; if (yi < 0 || yi >= 256) { continue; // ? } int anvilIndex = (y + yoffset) * 16 * 16 + z * 16 + x; byte blockId = chunk.GetBlock(x, yi, z); // PE to Anvil friendly converstion if (blockId == 5) { blockId = 125; } else if (blockId == 158) { blockId = 126; } else if (blockId == 50) { blockId = 75; } else if (blockId == 50) { blockId = 76; } else if (blockId == 89) { blockId = 123; } else if (blockId == 89) { blockId = 124; } else if (blockId == 73) { blockId = 152; } blocks[anvilIndex] = blockId; SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z)); SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z)); SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z)); } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } // TODO: Save entities NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound); levelTag.Add(entitiesTag); NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound); levelTag.Add(blockEntitiesTag); foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values) { NbtCompound nbtClone = (NbtCompound)blockEntityNbt.Clone(); nbtClone.Name = null; blockEntitiesTag.Add(nbtClone); } levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset) { var nbt = new NbtFile(); var levelTag = new NbtCompound("Level"); nbt.RootTag.Add(levelTag); levelTag.Add(new NbtInt("xPos", chunk.X)); levelTag.Add(new NbtInt("zPos", chunk.Z)); levelTag.Add(new NbtByteArray("Biomes", chunk.BiomeId)); var sectionsTag = new NbtList("Sections"); levelTag.Add(sectionsTag); for (var i = 0; i < 8; i++) { var sectionTag = new NbtCompound(); sectionsTag.Add(sectionTag); sectionTag.Add(new NbtByte("Y", (byte)i)); var sy = i * 16; var blocks = new byte[4096]; var data = new byte[2048]; var blockLight = new byte[2048]; var skyLight = new byte[2048]; for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 0; y < 16; y++) { var yi = sy + y; if (yi < 0 || yi >= 256) { continue; // ? } var anvilIndex = (y + yoffset) * 16 * 16 + z * 16 + x; var blockId = chunk.GetBlock(x, yi, z); blocks[anvilIndex] = (byte)blockId; SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z)); SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z)); SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z)); } } } sectionTag.Add(new NbtByteArray("Blocks", blocks)); sectionTag.Add(new NbtByteArray("Data", data)); sectionTag.Add(new NbtByteArray("BlockLight", blockLight)); sectionTag.Add(new NbtByteArray("SkyLight", skyLight)); } levelTag.Add(new NbtList("Entities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileEntities", NbtTagType.Compound)); levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound)); return(nbt); }
public static void SavePlayer(this Level level, RemoteClient client) { if (string.IsNullOrEmpty(level.BaseDirectory)) return; try { Directory.CreateDirectory(Path.Combine(level.BaseDirectory, "players")); var file = new NbtFile(); file.RootTag.Add(new NbtInt("playerGameType", (int)client.GameMode)); file.RootTag.Add(new NbtShort("SelectedItemSlot", client.Entity.SelectedSlot)); file.RootTag.Add(new NbtInt("SpawnX", (int)client.Entity.SpawnPoint.X)); file.RootTag.Add(new NbtInt("SpawnY", (int)client.Entity.SpawnPoint.Y)); file.RootTag.Add(new NbtInt("SpawnZ", (int)client.Entity.SpawnPoint.Z)); file.RootTag.Add(new NbtInt("foodLevel", client.Entity.Food)); file.RootTag.Add(new NbtFloat("foodExhaustionLevel", client.Entity.FoodExhaustion)); file.RootTag.Add(new NbtFloat("foodSaturationLevel", client.Entity.FoodSaturation)); file.RootTag.Add(new NbtShort("Health", client.Entity.Health)); var inventory = new NbtList("Inventory", NbtTagType.Compound); var slots = client.Entity.Inventory.GetSlots(); for (int i = 0; i < slots.Length; i++) { var slot = (ItemStack)slots[i].Clone(); slot.Index = Level.NetworkSlotToDataSlot(i); if (!slot.Empty) inventory.Add(slot.ToNbt()); } file.RootTag.Add(inventory); var position = new NbtList("Pos", NbtTagType.Double); position.Add(new NbtDouble(client.Entity.Position.X)); position.Add(new NbtDouble(client.Entity.Position.Y)); position.Add(new NbtDouble(client.Entity.Position.Z)); file.RootTag.Add(position); var rotation = new NbtList("Rotation", NbtTagType.Float); rotation.Add(new NbtFloat(client.Entity.Yaw)); rotation.Add(new NbtFloat(client.Entity.Pitch)); file.RootTag.Add(rotation); var velocity = new NbtList("Motion", NbtTagType.Double); velocity.Add(new NbtDouble(client.Entity.Velocity.X)); velocity.Add(new NbtDouble(client.Entity.Velocity.Y)); velocity.Add(new NbtDouble(client.Entity.Velocity.Z)); file.RootTag.Add(velocity); file.SaveToFile(Path.Combine(level.BaseDirectory, "players", client.Username + ".dat"), NbtCompression.None); } catch { } // If exceptions happen here, the entire server dies }
public void GettersAndSetters() { NbtCompound parent = new NbtCompound( "Parent" ); NbtCompound child = new NbtCompound( "Child" ); NbtCompound nestedChild = new NbtCompound( "NestedChild" ); NbtList childList = new NbtList( "ChildList" ); NbtList nestedChildList = new NbtList( "NestedChildList" ); NbtInt testInt = new NbtInt( 1 ); childList.Add( testInt ); nestedChildList.Add( testInt ); parent.Add( child ); parent.Add( childList ); child.Add( nestedChild ); child.Add( nestedChildList ); // Accessing nested compound tags using indexers Assert.AreEqual( parent["Child"]["NestedChild"], nestedChild ); Assert.AreEqual( parent["Child"]["NestedChildList"], nestedChildList ); Assert.AreEqual( parent["Child"]["NestedChildList"][0], testInt ); // Accessing nested compound tags using Get<T> Assert.AreEqual( parent.Get<NbtCompound>( "Child" ).Get<NbtCompound>( "NestedChild" ), nestedChild ); Assert.AreEqual( parent.Get<NbtCompound>( "Child" ).Get<NbtList>( "NestedChildList" ), nestedChildList ); Assert.AreEqual( parent.Get<NbtCompound>( "Child" ).Get<NbtList>( "NestedChildList" )[0], testInt ); // Accessing with Get<T> and an invalid given type Assert.Throws<InvalidCastException>( () => parent.Get<NbtInt>( "Child" ) ); // Trying to use integer indexers on non-NbtList tags Assert.Throws<InvalidOperationException>( () => parent[0] = testInt ); Assert.Throws<InvalidOperationException>( () => testInt[0] = testInt ); // Trying to use string indexers on non-NbtCompound tags Assert.Throws<InvalidOperationException>( () => childList["test"] = testInt ); Assert.Throws<InvalidOperationException>( () => testInt["test"] = testInt ); // Trying to get a non-existent element by name Assert.IsNull( parent.Get<NbtTag>( "NonExistentTag" ) ); Assert.IsNull( parent["NonExistentTag"] ); // Null indices on NbtCompound Assert.Throws<ArgumentNullException>( () => parent.Get<NbtTag>( null ) ); Assert.Throws<ArgumentNullException>( () => parent[null] = testInt ); Assert.Throws<ArgumentNullException>( () => testInt = (NbtInt)parent[null] ); // Out-of-range indices on NbtList Assert.Throws<ArgumentOutOfRangeException>( () => testInt = (NbtInt)childList[-1] ); Assert.Throws<ArgumentOutOfRangeException>( () => childList[-1] = testInt ); Assert.Throws<ArgumentOutOfRangeException>( () => testInt = childList.Get<NbtInt>( -1 ) ); Assert.Throws<ArgumentOutOfRangeException>( () => testInt = (NbtInt)childList[childList.Count] ); Assert.Throws<ArgumentOutOfRangeException>( () => testInt = childList.Get<NbtInt>( childList.Count ) ); }