public void ChangingInvalidListTagType() { var list = new NbtList(); list.Tags.Add(new NbtInt()); Assert.Throws<Exception>(() => list.SetListType(NbtTagType.TAG_Short)); }
public SlotData(short itemID = -1, byte itemCount = 0, short itemDamage = 0, NbtList itemEnchantments = null) { ItemID = itemID; ItemCount = itemCount; ItemDamage = itemDamage; ItemEnchantments = itemEnchantments; }
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 ChangingValidListTagType() { var list = new NbtList(); list.Tags.Add(new NbtInt()); Assert.DoesNotThrow(() => list.SetListType(NbtTagType.TAG_Int)); }
public static Rotation FromNbt(NbtList nbtTag) { Rotation rot = new Rotation(0f, 0f); rot.Yaw = nbtTag.Get<NbtFloat>(0).Value; rot.Pitch = nbtTag.Get<NbtFloat>(1).Value; return rot; }
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]); }
internal NbtTag SaveSection() { // Create the tags to save this section NbtList section = new NbtList("Entities"); foreach(McEntity entity in Entities) { section.Tags.Add(entity.SaveEntity()); } return section; }
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 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 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 Inventory(int id, BlockEntity blockEntity, short inventorySize, NbtList slots) { Id = id; BlockEntity = blockEntity; Size = inventorySize; Coordinates = BlockEntity.Coordinates; Slots = new ItemStacks(); for (byte i = 0; i < Size; i++) { Slots.Add(new ItemStack()); } for (byte i = 0; i < slots.Count; i++) { NbtCompound item = (NbtCompound) slots[i]; Slots[item["Slot"].ByteValue] = new ItemStack(item["id"].ShortValue, item["Count"].ByteValue, item["Damage"].ByteValue); } }
public Inventory(int id, BlockEntity blockEntity, short inventorySize, NbtList slots) { Id = id; BlockEntity = blockEntity; Size = inventorySize; Coordinates = BlockEntity.Coordinates; Slots = new MetadataSlots(); for (byte i = 0; i < Size; i++) { if (i < slots.Count) { NbtCompound item = (NbtCompound)slots[i]; Slots[i] = new MetadataSlot(new ItemStack(item["id"].ShortValue, item["Count"].ByteValue)); } else { Slots[i] = new MetadataSlot(new ItemStack()); } } }
public void TestNbtListType() { var file = new NbtFile(); file.RootTag = new NbtCompound("ListTypeTest"); NbtTagType mytype = NbtTagType.TAG_Compound; NbtList list = new NbtList("Entities", null, mytype); file.RootTag.Tags.Add(list); file.SaveFile("TestFiles/NbtListType.nbt"); NbtFile read = new NbtFile(); read.LoadFile("TestFiles/NbtListType.nbt"); Assert.NotNull(read); Console.WriteLine(read.RootTag.ToString()); NbtList readlist = (NbtList)read.RootTag.Tags.ToArray()[0]; Assert.NotNull(readlist); Assert.AreEqual(mytype, readlist.ListType); }
public void InitializingListFromCollection() { // auto-detecting list type var test1 = new NbtList("Test1", new NbtTag[] { new NbtInt(1), new NbtInt(2), new NbtInt(3) }); Assert.AreEqual(test1.ListType, NbtTagType.Int); // correct explicitly-given list type Assert.DoesNotThrow(() => new NbtList("Test2", new NbtTag[] { new NbtInt(1), new NbtInt(2), new NbtInt(3) }, NbtTagType.Int)); // wrong explicitly-given list type Assert.Throws<ArgumentException>(() => new NbtList("Test3", new NbtTag[] { new NbtInt(1), new NbtInt(2), new NbtInt(3) }, NbtTagType.Float)); // auto-detecting mixed list given Assert.Throws<ArgumentException>(() => new NbtList("Test4", new NbtTag[] { new NbtFloat(1), new NbtByte(2), new NbtInt(3) })); // using AddRange Assert.DoesNotThrow(() => new NbtList().AddRange(new NbtTag[] { new NbtInt(1), new NbtInt(2), new NbtInt(3) })); }
public IntListByteProvider(NbtList list) : base(list) { }
public NbtTag ReadAsTag() { switch (state) { case NbtParseState.Error: throw new InvalidReaderStateException(ErroneousStateError); case NbtParseState.AtStreamEnd: throw new EndOfStreamException(); case NbtParseState.AtStreamBeginning: case NbtParseState.AtCompoundEnd: ReadToFollowing(); break; } // get this tag NbtTag parent; if (TagType == NbtTagType.Compound) { parent = new NbtCompound(TagName); } else if (TagType == NbtTagType.List) { parent = new NbtList(TagName, ListType); } else if (atValue) { NbtTag result = ReadValueAsTag(); ReadToFollowing(); // if we're at a value tag, there are no child tags to read return(result); } else { // end tags cannot be read-as-tags (there is no corresponding NbtTag object) throw new InvalidOperationException(NoValueToReadError); } int startingDepth = Depth; int parentDepth = Depth; do { ReadToFollowing(); // Going up the file tree, or end of document: wrap up while (Depth <= parentDepth && parent.Parent != null) { parent = parent.Parent; parentDepth--; } if (Depth <= startingDepth) { break; } NbtTag thisTag; if (TagType == NbtTagType.Compound) { thisTag = new NbtCompound(TagName); AddToParent(thisTag, parent); parent = thisTag; parentDepth = Depth; } else if (TagType == NbtTagType.List) { thisTag = new NbtList(TagName, ListType); AddToParent(thisTag, parent); parent = thisTag; parentDepth = Depth; } else if (TagType != NbtTagType.End) { thisTag = ReadValueAsTag(); AddToParent(thisTag, parent); } } while (true); return(parent); }
internal void Base2NBT(ref NbtCompound c,string _id) { c.Add(new NbtFloat("FallDistance", FallDistance)); c.Add(new NbtByte("OnGround", OnGround)); c.Add(new NbtString("id", _id)); NbtList motion = new NbtList("Motion"); motion.Tags.AddRange(new NbtDouble[]{ new NbtDouble("", Motion.X), new NbtDouble("", Motion.Y), new NbtDouble("", Motion.Z) }); c.Add(motion); NbtList pos = new NbtList("Pos"); pos.Tags.AddRange(new NbtDouble[]{ new NbtDouble("", Math.IEEERemainder(Pos.X,16)), new NbtDouble("", Pos.Y), new NbtDouble("", Math.IEEERemainder(Pos.Z,16)) }); c.Add(pos); c.Add(Rotation.ToNBT()); }
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 GettersAndSetters() { // construct a document for us to test. var nestedChild = new NbtCompound("NestedChild"); var nestedInt = new NbtInt(1); var nestedChildList = new NbtList("NestedChildList") { nestedInt }; var child = new NbtCompound("Child") { nestedChild, nestedChildList }; var childList = new NbtList("ChildList") { new NbtInt(1) }; var parent = new NbtCompound("Parent") { child, childList }; // Accessing nested compound tags using indexers Assert.Equal(nestedChild, parent["Child"]["NestedChild"]); Assert.Equal(nestedChildList, parent["Child"]["NestedChildList"]); Assert.Equal(nestedInt, parent["Child"]["NestedChildList"][0]); // Accessing nested compound tags using Get and Get<T> Assert.Throws <ArgumentNullException>(() => parent.Get <NbtCompound>(null)); Assert.Null(parent.Get <NbtCompound>("NonExistingChild")); Assert.Equal(nestedChild, parent.Get <NbtCompound>("Child").Get <NbtCompound>("NestedChild")); Assert.Equal(nestedChildList, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")); Assert.Equal(nestedInt, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")[0]); Assert.Throws <ArgumentNullException>(() => parent.Get(null)); Assert.Null(parent.Get("NonExistingChild")); Assert.Equal(nestedChild, (parent.Get("Child") as NbtCompound).Get("NestedChild")); Assert.Equal(nestedChildList, (parent.Get("Child") as NbtCompound).Get("NestedChildList")); Assert.Equal(nestedInt, (parent.Get("Child") as NbtCompound).Get("NestedChildList")[0]); // Accessing with Get<T> and an invalid given type Assert.Throws <InvalidCastException>(() => parent.Get <NbtInt>("Child")); // Using TryGet and TryGet<T> NbtTag dummyTag; Assert.Throws <ArgumentNullException>(() => parent.TryGet(null, out dummyTag)); Assert.False(parent.TryGet("NonExistingChild", out dummyTag)); Assert.True(parent.TryGet("Child", out dummyTag)); NbtCompound dummyCompoundTag; Assert.Throws <ArgumentNullException>(() => parent.TryGet(null, out dummyCompoundTag)); Assert.False(parent.TryGet("NonExistingChild", out dummyCompoundTag)); Assert.True(parent.TryGet("Child", out dummyCompoundTag)); // Trying to use integer indexers on non-NbtList tags Assert.Throws <InvalidOperationException>(() => parent[0] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt[0] = nestedInt); // Trying to use string indexers on non-NbtCompound tags Assert.Throws <InvalidOperationException>(() => childList["test"] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt["test"] = nestedInt); // Trying to get a non-existent element by name Assert.Null(parent.Get <NbtTag>("NonExistentTag")); Assert.Null(parent["NonExistentTag"]); // Null indices on NbtCompound Assert.Throws <ArgumentNullException>(() => parent.Get <NbtTag>(null)); Assert.Throws <ArgumentNullException>(() => parent[null] = new NbtInt(1)); Assert.Throws <ArgumentNullException>(() => nestedInt = (NbtInt)parent[null]); // Out-of-range indices on NbtList Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[-1]); Assert.Throws <ArgumentOutOfRangeException>(() => childList[-1] = new NbtInt(1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[childList.Count]); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(childList.Count)); // Using setter correctly parent["NewChild"] = new NbtByte("NewChild"); // Using setter incorrectly object dummyObject; Assert.Throws <ArgumentNullException>(() => parent["Child"] = null); Assert.NotNull(parent["Child"]); Assert.Throws <ArgumentException>(() => parent["Child"] = new NbtByte("NotChild")); Assert.Throws <InvalidOperationException>(() => dummyObject = parent[0]); Assert.Throws <InvalidOperationException>(() => parent[0] = new NbtByte("NewerChild")); // Try adding tag to self var selfTest = new NbtCompound("SelfTest"); Assert.Throws <ArgumentException>(() => selfTest["SelfTest"] = selfTest); // Try adding a tag that already has a parent Assert.Throws <ArgumentException>(() => selfTest[child.Name] = child); }
public static List <T> ToFrameworkList <T>(this NbtList list, INbtIoConfig config = null) where T : INbtIoCapable, new() { return(new List <T>(list.OfType <NbtCompound>().Select(c => CreateAndReadFromNbt <T>(c, config)))); }
public void InterfaceImplementation() { // prepare our test lists var referenceList = new List <NbtTag> { new NbtInt(1), new NbtInt(2), new NbtInt(3) }; var testTag = new NbtInt(4); var originalList = new NbtList(referenceList); // check IList implementation IList iList = originalList; Assert.Equal(referenceList, iList); // check IList<NbtTag> implementation IList <NbtTag> iGenericList = originalList; Assert.Equal(referenceList, iGenericList); Assert.False(iGenericList.IsReadOnly); // check IList.Add referenceList.Add(testTag); iList.Add(testTag); Assert.Equal(referenceList, iList); // check IList.IndexOf Assert.Equal(referenceList.IndexOf(testTag), iList.IndexOf(testTag)); Assert.True(iList.IndexOf(null) < 0); // check IList<NbtTag>.IndexOf Assert.Equal(referenceList.IndexOf(testTag), iGenericList.IndexOf(testTag)); Assert.True(iGenericList.IndexOf(null) < 0); // check IList.Contains Assert.True(iList.Contains(testTag)); Assert.False(iList.Contains(null)); // check IList.Remove iList.Remove(testTag); Assert.False(iList.Contains(testTag)); // check IList.Insert iList.Insert(0, testTag); Assert.Equal(0, iList.IndexOf(testTag)); // check IList.RemoveAt iList.RemoveAt(0); Assert.False(iList.Contains(testTag)); // check misc IList properties Assert.False(iList.IsFixedSize); Assert.False(iList.IsReadOnly); Assert.False(iList.IsSynchronized); Assert.NotNull(iList.SyncRoot); // check IList.CopyTo var exportTest = new NbtInt[iList.Count]; iList.CopyTo(exportTest, 0); Assert.Equal(iList, exportTest); // check IList.this[int] for (int i = 0; i < iList.Count; i++) { Assert.Equal(originalList[i], iList[i]); iList[i] = new NbtInt(i); } // check IList.Clear iList.Clear(); Assert.Equal(0, iList.Count); //Assert.Less(iList.IndexOf(testTag), 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 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 static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz)); if (!File.Exists(filePath)) { return(generator.GenerateChunkColumn(coordinates)); } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return(generator.GenerateChunkColumn(coordinates)); } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue }; for (int i = 0; i < chunk.biomeId.Length; i++) { if (chunk.biomeId[i] > 22) { chunk.biomeId[i] = 0; } } if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; 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 - yoffset; if (yi < 0 || yi >= 128) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); Func <int, byte, byte> dataConverter = (i, b) => b; // Anvil to PE friendly converstion if (_convert.ContainsKey(blockId)) { dataConverter = _convert[blockId].Item2; blockId = _convert[blockId].Item1; } else if (_ignore.BinarySearch(blockId) >= 0) { blockId = 0; } else if (_gaps.BinarySearch(blockId) >= 0) { Log.WarnFormat("Missing material on convert: {0}", blockId); blockId = 133; } if (blockId > 255) { blockId = 41; } if (yi == 127 && blockId != 0) { blockId = 30; } if (yi == 0 && (blockId == 8 || blockId == 9)) { blockId = 7; } chunk.SetBlock(x, yi, z, (byte)blockId); byte metadata = Nibble4(data, anvilIndex); metadata = dataConverter(blockId, metadata); chunk.SetMetadata(x, yi, z, metadata); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z)); if (block is BlockStairs || block is StoneSlab || block is WoodSlab) { chunk.SetSkylight(x, yi, z, 0xff); } if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15) { chunk.SetMetadata(x, yi, z, 14); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1) { chunk.SetBlock(x, yi, z, 198); chunk.SetMetadata(x, yi, z, 0); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2) { chunk.SetBlock(x, yi, z, 143); //Coarse Dirt => Pat chunk.SetMetadata(x, yi, z, 0); // Podzol => (Podzol) } } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag; string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
// Compile with unsafe NbtTag ReadTag(byte typeId, bool readTagName) { if (typeId == 0) { return(invalid); } NbtTag tag = default(NbtTag); tag.Name = readTagName ? ReadString() : null; tag.TagId = (NbtTagType)typeId; switch ((NbtTagType)typeId) { case NbtTagType.Int8: tag.Value = reader.ReadByte(); break; case NbtTagType.Int16: tag.Value = ReadInt16(); break; case NbtTagType.Int32: tag.Value = ReadInt32(); break; case NbtTagType.Int64: tag.Value = ReadInt64(); break; case NbtTagType.Real32: int temp32 = ReadInt32(); tag.Value = *(float *)&temp32; break; case NbtTagType.Real64: long temp64 = ReadInt64(); tag.Value = *(double *)&temp64; break; case NbtTagType.Int8Array: tag.Value = reader.ReadBytes(ReadInt32()); break; case NbtTagType.String: tag.Value = ReadString(); break; case NbtTagType.List: NbtList list = new NbtList(); list.ChildTagId = (NbtTagType)reader.ReadByte(); list.ChildrenValues = new object[ReadInt32()]; for (int i = 0; i < list.ChildrenValues.Length; i++) { list.ChildrenValues[i] = ReadTag((byte)list.ChildTagId, false); } tag.Value = list; break; case NbtTagType.Compound: Dictionary <string, NbtTag> children = new Dictionary <string, NbtTag>(); NbtTag child; while ((child = ReadTag(reader.ReadByte(), true)).TagId != NbtTagType.Invalid) { children[child.Name] = child; } tag.Value = children; break; case NbtTagType.Int32Array: int[] array = new int[ReadInt32()]; for (int i = 0; i < array.Length; i++) { array[i] = ReadInt32(); } tag.Value = array; break; default: throw new InvalidDataException("Unrecognised tag id: " + typeId); } return(tag); }
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 (var i = 0; i < AdjacentBlocks.Length; i++) { var test = self + AdjacentBlocks[i]; if (world.GetBlockId(test) == 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) { 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 (var 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 async Task WriteAsync(DataType type, FieldAttribute attribute, object value, int length = 32767) { switch (type) { case DataType.Auto: { if (value is Player player) { await this.WriteUnsignedByteAsync(0xff); } else { await this.WriteAutoAsync(value); } break; } case DataType.Angle: { await this.WriteAngleAsync((Angle)value); break; } case DataType.Boolean: { await this.WriteBooleanAsync((bool)value); break; } case DataType.Byte: { await this.WriteByteAsync((sbyte)value); break; } case DataType.UnsignedByte: { await this.WriteUnsignedByteAsync((byte)value); break; } case DataType.Short: { await this.WriteShortAsync((short)value); break; } case DataType.UnsignedShort: { await this.WriteUnsignedShortAsync((ushort)value); break; } case DataType.Int: { await this.WriteIntAsync((int)value); break; } case DataType.Long: { await this.WriteLongAsync((long)value); break; } case DataType.Float: { await this.WriteFloatAsync((float)value); break; } case DataType.Double: { await this.WriteDoubleAsync((double)value); break; } case DataType.String: { // TODO: add casing options on Field attribute and support custom naming enums. var val = value.GetType().IsEnum ? value.ToString().ToCamelCase() : value.ToString(); await this.WriteStringAsync(val, length); break; } case DataType.Chat: { await this.WriteChatAsync((ChatMessage)value); break; } case DataType.VarInt: { await this.WriteVarIntAsync((int)value); break; } case DataType.VarLong: { await this.WriteVarLongAsync((long)value); break; } case DataType.Position: { if (value is Position position) { if (attribute.Absolute) { await this.WriteDoubleAsync(position.X); await this.WriteDoubleAsync(position.Y); await this.WriteDoubleAsync(position.Z); break; } await this.WritePositionAsync(position); } else if (value is SoundPosition soundPosition) { await this.WriteIntAsync(soundPosition.X); await this.WriteIntAsync(soundPosition.Y); await this.WriteIntAsync(soundPosition.Z); } break; } case DataType.Velocity: { var velocity = (Velocity)value; await this.WriteShortAsync(velocity.X); await this.WriteShortAsync(velocity.Y); await this.WriteShortAsync(velocity.Z); break; } case DataType.UUID: { await this.WriteUuidAsync((Guid)value); break; } case DataType.Array: { if (value is List <CommandNode> nodes) { foreach (var node in nodes) { await node.CopyToAsync(this); } } else if (value is List <PlayerInfoAction> actions) { await this.WriteVarIntAsync(actions.Count); foreach (var action in actions) { await action.WriteAsync(this); } } else if (value is List <int> ids) { foreach (var id in ids) { await this.WriteVarIntAsync(id); } } else if (value is List <string> values) { foreach (var vals in values) { await this.WriteStringAsync(vals); } } else if (value is List <long> vals) { foreach (var val in vals) { await this.WriteLongAsync(val); } } else if (value is List <Tag> tags) { await this.WriteVarIntAsync(tags.Count); foreach (var tag in tags) { await this.WriteStringAsync(tag.Name); await this.WriteVarIntAsync(tag.Count); foreach (var entry in tag.Entries) { await this.WriteVarIntAsync(entry); } } } break; } case DataType.ByteArray: { var array = (byte[])value; if (attribute.CountLength) { await this.WriteVarIntAsync(array.Length); await this.WriteAsync(array); } else { await this.WriteAsync(array); } break; } case DataType.Slot: { await this.WriteSlotAsync((ItemStack)value); break; } case DataType.EntityMetadata: { var ent = (Entity)value; await ent.WriteAsync(this); await this.WriteUnsignedByteAsync(0xff); break; } case DataType.NbtTag: { if (value is MixedCodec codecs) { var dimensions = new NbtCompound(codecs.Dimensions.Name) { new NbtString("type", codecs.Dimensions.Name) }; var list = new NbtList("value", NbtTagType.Compound); foreach (var(_, codec) in codecs.Dimensions) { codec.Write(list); } dimensions.Add(list); #region biomes var biomeCompound = new NbtCompound(codecs.Biomes.Name) { new NbtString("type", codecs.Biomes.Name) }; var biomes = new NbtList("value", NbtTagType.Compound); foreach (var(_, biome) in codecs.Biomes) { biome.Write(biomes); } biomeCompound.Add(biomes); #endregion var compound = new NbtCompound("") { dimensions, biomeCompound }; var nbt = new NbtFile(compound); nbt.SaveToStream(this, NbtCompression.None); } else if (value is DimensionCodec codec) { var nbt = new NbtFile(codec.ToNbt()); nbt.SaveToStream(this, NbtCompression.None); } break; } default: throw new ArgumentOutOfRangeException(nameof(type)); } }
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); }
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.Contains(sameTags[j], list); Assert.Equal(sameTags[j], tag); Assert.Equal(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.Same(sameTags[i], list[i]); Assert.Equal(i, ((NbtInt)list[i]).Value); } // test removal Assert.False(list.Remove(new NbtInt(5))); Assert.True(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.Equal(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.Empty(loopList); Assert.Equal(NbtTagType.Unknown, loopList.ListType); // try creating a list with invalid tag type Assert.Throws <ArgumentOutOfRangeException>(() => new NbtList((NbtTagType)200)); }
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 ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue, isAllAir = true }; if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; 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 - yoffset; if (yi < 0 || yi >= 128) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); // Anvil to PE friendly converstion Func <int, byte, byte> dataConverter = (i, b) => b; // Default no-op converter if (Convert.ContainsKey(blockId)) { dataConverter = Convert[blockId].Item2; blockId = Convert[blockId].Item1; } else { if (BlockFactory.GetBlockById((byte)blockId).GetType() == typeof(Block)) { Log.Warn($"No block implemented for block ID={blockId}, Meta={data}"); //blockId = 57; } } chunk.isAllAir = chunk.isAllAir && blockId == 0; if (blockId > 255) { Log.Warn($"Failed mapping for block ID={blockId}, Meta={data}"); blockId = 41; } //if (yi == 127 && blockId != 0) blockId = 30; if (yi == 0 && (blockId == 8 || blockId == 9)) { blockId = 7; } chunk.SetBlock(x, yi, z, (byte)blockId); byte metadata = Nibble4(data, anvilIndex); metadata = dataConverter(blockId, metadata); chunk.SetMetadata(x, yi, z, metadata); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z)); if (block is BlockStairs || block is StoneSlab || block is WoodSlab) { chunk.SetSkylight(x, yi, z, 0xff); } if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15) { chunk.SetMetadata(x, yi, z, 14); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1) { // Dirt Course => (Grass Path) chunk.SetBlock(x, yi, z, 198); chunk.SetMetadata(x, yi, z, 0); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2) { // Dirt Podzol => (Podzol) chunk.SetBlock(x, yi, z, 243); chunk.SetMetadata(x, yi, z, 0); } } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; if (blockEntity is Sign) { // Remove the JSON stuff and get the text out of extra data. // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}" CleanSignText(blockEntityTag, "Text1"); CleanSignText(blockEntityTag, "Text2"); CleanSignText(blockEntityTag, "Text3"); CleanSignText(blockEntityTag, "Text4"); } else if (blockEntity is ChestBlockEntity) { NbtList items = (NbtList)blockEntityTag["Items"]; if (items != null) { //for (byte i = 0; i < items.Count; i++) //{ // NbtCompound item = (NbtCompound) items[i]; // item.Add(new NbtShort("OriginalDamage", item["Damage"].ShortValue)); // byte metadata = (byte) (item["Damage"].ShortValue & 0xff); // item.Remove("Damage"); // item.Add(new NbtByte("Damage", metadata)); //} } } chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
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 CopyConstructorTest() { NbtByte byteTag = new NbtByte("byteTag", 1); NbtByte byteTagClone = (NbtByte)byteTag.Clone(); Assert.NotSame(byteTag, byteTagClone); Assert.Equal(byteTag.Name, byteTagClone.Name); Assert.Equal(byteTag.Value, byteTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtByte((NbtByte)null)); NbtByteArray byteArrTag = new NbtByteArray("byteArrTag", new byte[] { 1, 2, 3, 4 }); NbtByteArray byteArrTagClone = (NbtByteArray)byteArrTag.Clone(); Assert.NotSame(byteArrTag, byteArrTagClone); Assert.Equal(byteArrTag.Name, byteArrTagClone.Name); Assert.NotSame(byteArrTag.Value, byteArrTagClone.Value); Assert.Equal(byteArrTag.Value, byteArrTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtByteArray((NbtByteArray)null)); NbtCompound compTag = new NbtCompound("compTag", new NbtTag[] { new NbtByte("innerTag", 1) }); NbtCompound compTagClone = (NbtCompound)compTag.Clone(); Assert.NotSame(compTag, compTagClone); Assert.Equal(compTag.Name, compTagClone.Name); Assert.NotSame(compTag["innerTag"], compTagClone["innerTag"]); Assert.Equal(compTag["innerTag"].Name, compTagClone["innerTag"].Name); Assert.Equal(compTag["innerTag"].ByteValue, compTagClone["innerTag"].ByteValue); Assert.Throws <ArgumentNullException>(() => new NbtCompound((NbtCompound)null)); NbtDouble doubleTag = new NbtDouble("doubleTag", 1); NbtDouble doubleTagClone = (NbtDouble)doubleTag.Clone(); Assert.NotSame(doubleTag, doubleTagClone); Assert.Equal(doubleTag.Name, doubleTagClone.Name); Assert.Equal(doubleTag.Value, doubleTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtDouble((NbtDouble)null)); NbtFloat floatTag = new NbtFloat("floatTag", 1); NbtFloat floatTagClone = (NbtFloat)floatTag.Clone(); Assert.NotSame(floatTag, floatTagClone); Assert.Equal(floatTag.Name, floatTagClone.Name); Assert.Equal(floatTag.Value, floatTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtFloat((NbtFloat)null)); NbtInt intTag = new NbtInt("intTag", 1); NbtInt intTagClone = (NbtInt)intTag.Clone(); Assert.NotSame(intTag, intTagClone); Assert.Equal(intTag.Name, intTagClone.Name); Assert.Equal(intTag.Value, intTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtInt((NbtInt)null)); NbtIntArray intArrTag = new NbtIntArray("intArrTag", new[] { 1, 2, 3, 4 }); NbtIntArray intArrTagClone = (NbtIntArray)intArrTag.Clone(); Assert.NotSame(intArrTag, intArrTagClone); Assert.Equal(intArrTag.Name, intArrTagClone.Name); Assert.NotSame(intArrTag.Value, intArrTagClone.Value); Assert.Equal(intArrTag.Value, intArrTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtIntArray((NbtIntArray)null)); NbtList listTag = new NbtList("listTag", new NbtTag[] { new NbtByte(1) }); NbtList listTagClone = (NbtList)listTag.Clone(); Assert.NotSame(listTag, listTagClone); Assert.Equal(listTag.Name, listTagClone.Name); Assert.NotSame(listTag[0], listTagClone[0]); Assert.Equal(listTag[0].ByteValue, listTagClone[0].ByteValue); Assert.Throws <ArgumentNullException>(() => new NbtList((NbtList)null)); NbtLong longTag = new NbtLong("longTag", 1); NbtLong longTagClone = (NbtLong)longTag.Clone(); Assert.NotSame(longTag, longTagClone); Assert.Equal(longTag.Name, longTagClone.Name); Assert.Equal(longTag.Value, longTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtLong((NbtLong)null)); NbtShort shortTag = new NbtShort("shortTag", 1); NbtShort shortTagClone = (NbtShort)shortTag.Clone(); Assert.NotSame(shortTag, shortTagClone); Assert.Equal(shortTag.Name, shortTagClone.Name); Assert.Equal(shortTag.Value, shortTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtShort((NbtShort)null)); NbtString stringTag = new NbtString("stringTag", "foo"); NbtString stringTagClone = (NbtString)stringTag.Clone(); Assert.NotSame(stringTag, stringTagClone); Assert.Equal(stringTag.Name, stringTagClone.Name); Assert.Equal(stringTag.Value, stringTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtString((NbtString)null)); }
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}"); } }
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 LongListByteProvider(NbtList list) : base(list) { }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: MinecraftWorldConverter.exe [path] [optional(default:256):sectorSize]"); return; } short sectorSize = 256; if (args.Length > 2) { sectorSize = short.Parse(args[1]); } LevelLoader loader = new LevelLoader(args[0]); var str = new MemoryStream(); NewLevelWriter writer = new NewLevelWriter(str, sectorSize); for (int x = 0; x < 32; x++) { for (int z = 0; z < 32; z++) { var tag = loader.Read(x, z); if (tag != null) { var compound = (tag as NbtCompound).GetValue<NbtCompound>("Level"); for (int y = 0; y < 16; y++) { NbtCompound root = new NbtCompound { Name = "Level" }; root.Childs = new List<NbtNode>(); //entities NbtList entities = compound.GetValue<NbtList>("Entities"); NbtList newEntities = new NbtList { Name = "Entities", TagId = entities.TagId}; root.Childs.Add(newEntities); newEntities.Childs = new List<object>(); foreach (var item in entities.Childs) { var list = item as List<NbtNode>; var position = list.Single(a => a.Name == "Pos") as NbtList; var locationY = (double)position.Childs[1]; if (locationY > y * 16 && locationY < (y + 1) * 16) { newEntities.Childs.Add(item); } } root.Childs.Add(compound.Childs.Single(a => a.Name == "Biomes")); root.Childs.Add(compound.Childs.Single(a => a.Name == "LastUpdate")); root.Childs.Add(compound.Childs.Single(a => a.Name == "xPos")); root.Childs.Add(new NbtInt { Name = "yPos", Value = y }); root.Childs.Add(compound.Childs.Single(a => a.Name == "zPos")); //tile entities NbtList tileEntities = compound.GetValue<NbtList>("TileEntities"); NbtList newTileEntities = new NbtList { Name = "TileEntities", TagId = tileEntities.TagId }; root.Childs.Add(newTileEntities); newTileEntities.Childs = new List<object>(); foreach (var item in tileEntities.Childs) { var list = item as List<NbtNode>; var position = list.Single(a => a.Name == "y") as NbtInt; var locationY = position.Value; if (locationY > y * 16 && locationY < (y + 1) * 16) { newTileEntities.Childs.Add(item); } } root.Childs.Add(compound.Childs.Single(a => a.Name == "HeightMap")); //tile entities NbtList data = compound.GetValue<NbtList>("Sections"); bool b = false; foreach (var item in data.Childs) { var list = item as List<NbtNode>; var position = list.Single(a => a.Name == "Y") as NbtByte; var locationY = position.Value; if (locationY == y) { b = true; NbtCompound newData = new NbtCompound { Name = "Section" }; newData.Childs = new List<NbtNode>(); foreach (var it in list) { newData.Childs.Add(it); } root.Childs.Add(newData); } } if (!b) { } writer.Write(x, (short)y, z, new NbtCompound { Childs = new List<NbtNode> { root } }); } } } } File.WriteAllBytes(args[0] +"." + sectorSize + ".new", str.ToArray()); Console.WriteLine("Maximum: " + writer._sizes.Max()); Console.WriteLine("Minimum: " + writer._sizes.Min()); Console.WriteLine("Average: " + writer._sizes.Average()); }
public void NbtListTest() { object dummy; NbtTag test = new NbtList( "Derp" ); Assert.Throws<InvalidCastException>( () => dummy = test.ByteArrayValue ); Assert.Throws<InvalidCastException>( () => dummy = test.ByteValue ); Assert.Throws<InvalidCastException>( () => dummy = test.DoubleValue ); Assert.Throws<InvalidCastException>( () => dummy = test.FloatValue ); Assert.Throws<InvalidCastException>( () => dummy = test.IntArrayValue ); Assert.Throws<InvalidCastException>( () => dummy = test.IntValue ); Assert.Throws<InvalidCastException>( () => dummy = test.LongValue ); Assert.Throws<InvalidCastException>( () => dummy = test.ShortValue ); Assert.Throws<InvalidCastException>( () => dummy = test.StringValue ); }
public ShortListByteProvider(NbtList list) : base(list) { }
internal static bool ReadTag(this NbtTag tag, NbtBinaryReader readStream) { while (true) { NbtTag nbtTag = null; NbtTagType nbtTagType; // = readStream.ReadTagType(); do { nbtTagType = readStream.ReadTagType(); switch (nbtTagType) { case NbtTagType.End: break; 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: break; default: throw new FormatException("Unsupported tag type found in NBT_Compound: " + (object)nbtTagType); } if (nbtTag != null) { nbtTag.Name = readStream.ReadString(); } //nbtTag.Parent = (NbtTag) this; //nbtTag.Name = readStream.ReadString(); }while (nbtTagType != NbtTagType.End && nbtTagType != NbtTagType.Unknown); 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 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); } }
internal NbtTag SaveSection() { // Create the tags to save this section NbtCompound section = new NbtCompound("Map"); section.Tags.Add(new NbtShort("Width", Width)); section.Tags.Add(new NbtShort("Height", Height)); section.Tags.Add(new NbtShort("Length", Length)); section.Tags.Add(new NbtByteArray("Blocks", Blocks.Data)); section.Tags.Add(new NbtByteArray("Data", Data.Data)); NbtList spawn = new NbtList("Spawn"); spawn.Tags.Add(new NbtShort(Spawn.X)); spawn.Tags.Add(new NbtShort(Spawn.Y)); spawn.Tags.Add(new NbtShort(Spawn.Z)); section.Tags.Add(spawn); return section; }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("Usage: MinecraftWorldConverter.exe [path] [optional(default:256):sectorSize]"); return; } short sectorSize = 256; if (args.Length > 2) { sectorSize = short.Parse(args[1]); } LevelLoader loader = new LevelLoader(args[0]); var str = new MemoryStream(); NewLevelWriter writer = new NewLevelWriter(str, sectorSize); for (int x = 0; x < 32; x++) { for (int z = 0; z < 32; z++) { var tag = loader.Read(x, z); if (tag != null) { var compound = (tag as NbtCompound).GetValue <NbtCompound>("Level"); for (int y = 0; y < 16; y++) { NbtCompound root = new NbtCompound { Name = "Level" }; root.Childs = new List <NbtNode>(); //entities NbtList entities = compound.GetValue <NbtList>("Entities"); NbtList newEntities = new NbtList { Name = "Entities", TagId = entities.TagId }; root.Childs.Add(newEntities); newEntities.Childs = new List <object>(); foreach (var item in entities.Childs) { var list = item as List <NbtNode>; var position = list.Single(a => a.Name == "Pos") as NbtList; var locationY = (double)position.Childs[1]; if (locationY > y * 16 && locationY < (y + 1) * 16) { newEntities.Childs.Add(item); } } root.Childs.Add(compound.Childs.Single(a => a.Name == "Biomes")); root.Childs.Add(compound.Childs.Single(a => a.Name == "LastUpdate")); root.Childs.Add(compound.Childs.Single(a => a.Name == "xPos")); root.Childs.Add(new NbtInt { Name = "yPos", Value = y }); root.Childs.Add(compound.Childs.Single(a => a.Name == "zPos")); //tile entities NbtList tileEntities = compound.GetValue <NbtList>("TileEntities"); NbtList newTileEntities = new NbtList { Name = "TileEntities", TagId = tileEntities.TagId }; root.Childs.Add(newTileEntities); newTileEntities.Childs = new List <object>(); foreach (var item in tileEntities.Childs) { var list = item as List <NbtNode>; var position = list.Single(a => a.Name == "y") as NbtInt; var locationY = position.Value; if (locationY > y * 16 && locationY < (y + 1) * 16) { newTileEntities.Childs.Add(item); } } root.Childs.Add(compound.Childs.Single(a => a.Name == "HeightMap")); //tile entities NbtList data = compound.GetValue <NbtList>("Sections"); bool b = false; foreach (var item in data.Childs) { var list = item as List <NbtNode>; var position = list.Single(a => a.Name == "Y") as NbtByte; var locationY = position.Value; if (locationY == y) { b = true; NbtCompound newData = new NbtCompound { Name = "Section" }; newData.Childs = new List <NbtNode>(); foreach (var it in list) { newData.Childs.Add(it); } root.Childs.Add(newData); } } if (!b) { } writer.Write(x, (short)y, z, new NbtCompound { Childs = new List <NbtNode> { root } }); } } } } File.WriteAllBytes(args[0] + "." + sectorSize + ".new", str.ToArray()); Console.WriteLine("Maximum: " + writer._sizes.Max()); Console.WriteLine("Minimum: " + writer._sizes.Min()); Console.WriteLine("Average: " + writer._sizes.Average()); }
public void InterfaceImplementation() { // prepare our test lists var referenceList = new List<NbtTag> { new NbtInt(1), new NbtInt(2), new NbtInt(3) }; var testTag = new NbtInt(4); var originalList = new NbtList(referenceList); // check IList implementation IList iList = originalList; CollectionAssert.AreEqual(referenceList, iList); // check IList<NbtTag> implementation IList<NbtTag> iGenericList = originalList; CollectionAssert.AreEqual(referenceList, iGenericList); Assert.IsFalse(iGenericList.IsReadOnly); // check IList.Add referenceList.Add(testTag); iList.Add(testTag); CollectionAssert.AreEqual(referenceList, iList); // check IList.IndexOf Assert.AreEqual(referenceList.IndexOf(testTag), iList.IndexOf(testTag)); Assert.IsTrue(iList.IndexOf(null) < 0); // check IList<NbtTag>.IndexOf Assert.AreEqual(referenceList.IndexOf(testTag), iGenericList.IndexOf(testTag)); Assert.IsTrue(iGenericList.IndexOf(null) < 0); // check IList.Contains Assert.IsTrue(iList.Contains(testTag)); // check IList.Remove iList.Remove(testTag); Assert.IsFalse(iList.Contains(testTag)); // check IList.Insert iList.Insert(0, testTag); Assert.AreEqual(0, iList.IndexOf(testTag)); // check IList.RemoveAt iList.RemoveAt(0); Assert.IsFalse(iList.Contains(testTag)); // check misc IList properties Assert.IsFalse(iList.IsFixedSize); Assert.IsFalse(iList.IsReadOnly); Assert.IsFalse(iList.IsSynchronized); Assert.NotNull(iList.SyncRoot); // check IList.CopyTo var exportTest = new NbtInt[iList.Count]; iList.CopyTo(exportTest, 0); CollectionAssert.AreEqual(iList, exportTest); // check IList.this[int] for (int i = 0; i < iList.Count; i++) { Assert.AreEqual(originalList[i], iList[i]); iList[i] = new NbtInt(i); } // check IList.Clear iList.Clear(); Assert.AreEqual(0, iList.Count); Assert.Less(iList.IndexOf(testTag), 0); }
public void Translate(string path) { var file = new NbtFile(); if (Endianness == Endianness.Little) { file.BigEndian = false; } file.LoadFromFile(path); var root = (NbtCompound)file.RootTag; if (RemoveKeys.Any()) { foreach (var key in RemoveKeys) { root.Remove(key); } file.SaveToFile(path, file.FileCompression); } if (ConvertStructure) { var palettes = root.Get <NbtList>("palettes"); var palette = palettes != null ? (NbtList)palettes[0] : root.Get <NbtList>("palette"); NbtList new_palette = null; if (palette != null) { new_palette = new NbtList(palette.Tags.Cast <NbtCompound>().Select(PackBlockState)); root["palette"] = new_palette; if (palettes != null) { var new_palettes = new NbtList(); foreach (NbtList p in palettes) { var compound = new NbtCompound(); for (int i = 0; i < palettes.Count; i++) { compound[i.ToString()] = PackBlockState((NbtCompound)p[i]); } } root["palettes"] = new_palettes; } } var entities = root.Get <NbtList>("entities"); if (entities != null) { var sorted = entities.Tags.Cast <NbtCompound>() .OrderBy(x => x.Get <NbtList>("pos")[1].DoubleValue) .ThenBy(x => x.Get <NbtList>("pos")[0].DoubleValue) .ThenBy(x => x.Get <NbtList>("pos")[2].DoubleValue).ToList(); entities.Clear(); foreach (var entity in sorted) { entity.Sort(new SpecificOrder("blockPos", "pos", "nbt"), false); entity.Get <NbtCompound>("nbt").Sort(new SpecificOrder("id"), false); } root["entities"] = new NbtList(sorted); } var blocks = root.Get <NbtList>("blocks"); var new_blocks = blocks.Tags.Cast <NbtCompound>() .OrderBy(x => x.Get <NbtList>("pos")[1].IntValue) .ThenBy(x => x.Get <NbtList>("pos")[0].IntValue) .ThenBy(x => x.Get <NbtList>("pos")[2].IntValue).ToList(); blocks.Clear(); foreach (var block in new_blocks) { if (new_palette != null) { var state = block.Get <NbtInt>("state"); block["state"] = (NbtTag)new_palette[state.Value].Clone(); } block.Sort(new SpecificOrder("pos", "state", "nbt"), false); } // overwrite existing, then rename root["blocks"] = new NbtList(new_blocks); root["blocks"].Name = "data"; } root.Sort(new SpecificOrder("size", "data", "entities", "palette"), false); if (!Mini) { Options.ShouldIndent = tag => { if (tag.Parent == null || tag.Parent == root) { return(true); } var top_parent = tag; while (top_parent.Parent != root) { top_parent = top_parent.Parent; } if (top_parent == root["data"]) { return(false); } if (top_parent == root["entities"]) { return(false); } return(true); }; } File.WriteAllText(Path.ChangeExtension(path, NewExtension), root.ToSnbt(Options) + Environment.NewLine); }
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)); }
/// <summary> /// Render a spell preview /// </summary> /// <param name="spell">The spell to render</param> /// <returns>An Image of the spell's grid</returns> public static Image RenderSpell(Spell spell) { NbtCompound spellNbt = null; try { spellNbt = (NbtCompound)TextNbtParser.Parse(spell.Source); } catch (Exception) { //Console.WriteLine(e); } if (spellNbt == null) { return(BlankImage); } NbtList piecesNbt = (NbtList)spellNbt["spellList"]; Piece[] pieces = new Piece[piecesNbt.Count]; int index = 0; foreach (NbtCompound p in piecesNbt) { pieces[index++] = new Piece(p); } Bitmap image = new Bitmap(ImageWidth, ImageHeight); Graphics g = Graphics.FromImage(image); g.Clear(BackgroundColor); //Piece pass foreach (Piece piece in pieces) { int x = piece.X; int y = piece.Y; string key = piece.Key; x *= (TileWidth + Spacing); y *= (TileHeight + Spacing); g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; g.DrawImage(PieceImage.Get(key), x, y, TileWidth, TileHeight); if (key == "constantNumber") { string value = piece.ConstantValue; g.DrawString(value, new Font(FontFamily.GenericMonospace, 40 / value.Length), new SolidBrush(Color.White), new RectangleF(x, y, TileWidth, TileHeight)); } } //Connector pass foreach (Piece piece in pieces) { int x = piece.X; int y = piece.Y; string key = piece.Key; int pixx = x * (TileWidth + Spacing); int pixy = y * (TileHeight + Spacing); if (key == "connector") { g.DrawImage(PieceImage.ConnectorImages[(int)piece.Parameters[0]], pixx, pixy, TileWidth, TileHeight); foreach (Piece.Side i in Enum.GetValues(typeof(Piece.Side))) { bool con = piece.HasConnection(pieces, i); if (con) { g.DrawImage(PieceImage.ConnectorImages[(int)i], pixx, pixy, TileWidth, TileHeight); } } } } //Parameter pass foreach (Piece piece in pieces) { int x = piece.X; int y = piece.Y; string key = piece.Key; x *= (TileWidth + Spacing); y *= (TileHeight + Spacing); Piece.Side[] par = piece.Parameters; if (par != null) { foreach (int param in par) { if (param > 0 && param <= 4) { Point p = new Point(x, y); p.Offset(ParameterOffset[param]); g.DrawImage(PieceImage.ParameterImages[param], new Rectangle(p, new Size(TileWidth / 2, TileHeight / 2))); } } } } return(image); }
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 async ValueTask HandleAsync(Server server, Player player) { var container = player.OpenedContainer ?? player.Inventory; var(slot, forPlayer) = container.GetDifference(ClickedSlot); if (this.IsPlayerInventory || forPlayer) { container = player.Inventory; } switch (Mode) { case InventoryOperationMode.MouseClick: await HandleMouseClick(container, server, player, slot); break; case InventoryOperationMode.ShiftMouseClick: { if (ClickedItem == null) { return; } //TODO implement shift click break; } case InventoryOperationMode.NumberKeys: { var localSlot = Button + 36; var currentItem = player.Inventory.GetItem(localSlot); if (currentItem.IsAir() && ClickedItem != null) { container.RemoveItem(slot); player.Inventory.SetItem(localSlot, ClickedItem); } else if (!currentItem.IsAir() && ClickedItem != null) { container.SetItem(slot, currentItem); player.Inventory.SetItem(localSlot, ClickedItem); } else { container.SetItem(slot, currentItem); player.Inventory.RemoveItem(localSlot); } break; } case InventoryOperationMode.MiddleMouseClick: break; case InventoryOperationMode.Drop: { if (ClickedSlot != Outsideinventory) { ItemStack?removedItem; if (Button == 0) { container.RemoveItem(slot, 1, out removedItem); } else { container.RemoveItem(slot, 64, out removedItem); } if (removedItem == null) { return; } var loc = new VectorF(player.Position.X, (float)player.HeadY - 0.3f, player.Position.Z); var item = new ItemEntity { EntityId = player + player.World.GetTotalLoadedEntities() + 1, Count = 1, Id = removedItem.AsItem().Id, Glowing = true, World = player.World, Position = loc }; var lookDir = player.GetLookDirection(); var vel = Velocity.FromDirection(loc, lookDir); //TODO Get this shooting out from the player properly. server.BroadcastPacket(new SpawnEntityPacket { EntityId = item.EntityId, Uuid = item.Uuid, Type = EntityType.Item, Position = item.Position, Pitch = 0, Yaw = 0, Data = 1, Velocity = vel }); server.BroadcastPacket(new EntityMetadata { EntityId = item.EntityId, Entity = item }); } break; } case InventoryOperationMode.MouseDrag: HandleDragClick(container, player, slot); break; case InventoryOperationMode.DoubleClick: { if (ClickedItem == null || ClickedItem.Count >= 64) { return; } TakeFromContainer(container, player.Inventory); break; } } if (container is IBlockEntity tileEntityContainer) { var blockEntity = await player.World.GetBlockEntityAsync(tileEntityContainer.BlockPosition); if (blockEntity is null) { return; } if (blockEntity.TryGetTag("Items", out var list)) { var items = list as NbtList; var itemsToBeRemoved = new HashSet <int>(); var itemsToBeUpdated = new HashSet <NbtCompound>(); items !.Clear(); this.FillNbtList(items, container); } else { var items = new NbtList(NbtTagType.Compound, "Items"); this.FillNbtList(items, container); blockEntity.Add(items); } } }
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 ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; Log.Debug($"Generating chunk @{coordinates}"); string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { var chunkColumn = generator?.GenerateChunkColumn(coordinates); if (chunkColumn != null) { chunkColumn.NeedSave = true; } return(chunkColumn); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; byte[] bytes = BitConverter.GetBytes(offset >> 4); Array.Reverse(bytes); if (offset != 0 && offsetBuffer[0] != bytes[0] && offsetBuffer[1] != bytes[1] && offsetBuffer[2] != bytes[2]) { throw new Exception($"Not the same buffer\n{Package.HexDump(offsetBuffer)}\n{Package.HexDump(bytes)}"); } int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { var chunkColumn = generator?.GenerateChunkColumn(coordinates); if (chunkColumn != null) { chunkColumn.NeedSave = true; } return(chunkColumn); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); if (compressionMode != 0x02) { throw new Exception($"CX={coordinates.X}, CZ={coordinates.Z}, NBT wrong compression. Expected 0x02, got 0x{compressionMode :X2}. " + $"Offset={offset}, length={length}\n{Package.HexDump(waste)}"); } var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue, isAllAir = true }; if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { ReadSection(yoffset, sectionTag, chunk); } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; if (blockEntity is Sign) { // Remove the JSON stuff and get the text out of extra data. // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}" CleanSignText(blockEntityTag, "Text1"); CleanSignText(blockEntityTag, "Text2"); CleanSignText(blockEntityTag, "Text3"); CleanSignText(blockEntityTag, "Text4"); } else if (blockEntity is ChestBlockEntity) { NbtList items = (NbtList)blockEntityTag["Items"]; if (items != null) { //for (byte i = 0; i < items.Count; i++) //{ // NbtCompound item = (NbtCompound) items[i]; // item.Add(new NbtShort("OriginalDamage", item["Damage"].ShortValue)); // byte metadata = (byte) (item["Damage"].ShortValue & 0xff); // item.Remove("Damage"); // item.Add(new NbtByte("Damage", metadata)); //} } } chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } else { if (Log.IsDebugEnabled) { Log.Debug($"Loaded unknown block entity: {blockEntityTag}"); } } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
public override NbtCompound ToNBT() { NbtCompound c = new NbtCompound(); Base2NBT(ref c); c.Tags.Add(new NbtShort("BurnTime",BurnTime)); c.Tags.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.Tags.Add(new NbtShort("id",Slots[i].ID)); cc.Tags.Add(new NbtShort("Damage",(short)Slots[i].Damage)); cc.Tags.Add(new NbtByte("Count",(byte)Slots[i].Count)); cc.Tags.Add(new NbtByte("Slot", (byte)i)); Items.Tags.Add(cc); } } c.Tags.Add(Items); return c; }
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); }
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 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); } }
// returns slot IDs not occupied with an item protected abstract IEnumerable <byte> GetFreeSlots(NbtList invtag);
/// <summary> /// Serialize an fNbt.NbtTag to a JSON-ish representation Minecraft likes /// </summary> /// <param name="tag">The tag to serialize</param> /// <returns>The serialized tag</returns> public static string Serialize(NbtTag tag) { StringBuilder sb = new StringBuilder(); switch (tag.TagType) { case NbtTagType.List: if (((NbtList)tag).Count == 0) { sb.Append("[]"); } else { sb.Append("["); NbtList list = (NbtList)tag; for (int i = 0; i < list.Count; i++) { NbtTag subTag = list[i]; sb.Append(i); sb.Append(":"); sb.Append(Serialize(subTag)); sb.Append(","); } sb.Remove(sb.Length - 1, 1); sb.Append("]"); } break; case NbtTagType.Compound: if (((NbtCompound)tag).Count == 0) { sb.Append("{}"); } else { sb.Append("{"); foreach (NbtTag subTag in (NbtCompound)tag) { sb.Append(subTag.Name); //fine mojang. you win. dont quote your suckin names. //btw did vs seriously just autocorrect that to suckin or am i high? sb.Append(":"); sb.Append(Serialize(subTag)); sb.Append(","); } sb.Remove(sb.Length - 1, 1); sb.Append("}"); } break; case NbtTagType.String: sb.Append('"'); sb.Append(tag.StringValue.Replace("\"", "\\\"").Replace("\\", "\\\\")); sb.Append('"'); break; case NbtTagType.Int: case NbtTagType.Double: sb.Append(tag.StringValue); break; case NbtTagType.Long: sb.Append(tag.StringValue); sb.Append("l"); break; case NbtTagType.Byte: sb.Append(tag.StringValue); sb.Append("b"); break; case NbtTagType.Float: sb.Append(tag.StringValue); sb.Append("f"); break; default: //Not supposed to happen throw new NotImplementedException("Emitting a " + tag.GetType().ToString()); } return(sb.ToString()); }
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 ) ); }