예제 #1
0
        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]);
        }
예제 #2
0
파일: ListTests.cs 프로젝트: fragmer/fNbt
        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]);
        }
예제 #3
0
        public void AddingAndRemoving()
        {
            NbtCompound test = new NbtCompound();

            NbtInt foo =  new NbtInt( "Foo" );

            test.Add( foo );

            // adding duplicate object
            Assert.Throws<ArgumentException>( () => test.Add( foo ) );

            // adding duplicate name
            Assert.Throws<ArgumentException>( () => test.Add( new NbtByte( "Foo" ) ) );

            // adding unnamed tag
            Assert.Throws<ArgumentException>( () => test.Add( new NbtInt() ) );

            // adding null
            Assert.Throws<ArgumentNullException>( () => test.Add( null ) );

            // contains existing name
            Assert.IsTrue( test.Contains( "Foo" ) );

            // contains existing object
            Assert.IsTrue( test.Contains( foo ) );

            // contains non-existent name
            Assert.IsFalse( test.Contains( "Bar" ) );

            // contains existing name / different object
            Assert.IsFalse( test.Contains( new NbtInt( "Foo" ) ) );

            // removing non-existent name
            Assert.IsFalse( test.Remove( "Bar" ) );

            // removing existing name
            Assert.IsTrue( test.Remove( "Foo" ) );

            // removing non-existent name
            Assert.IsFalse( test.Remove( "Foo" ) );

            // re-adding object
            test.Add( foo );

            // removing existing object
            Assert.IsTrue( test.Remove( foo ) );

            // clearing an empty NbtCompound
            Assert.AreEqual( test.Count, 0 );
            test.Clear();

            // re-adding after clearing
            test.Add( foo );
            Assert.AreEqual( test.Count, 1 );

            // clearing a non-empty NbtCompound
            test.Clear();
            Assert.AreEqual( test.Count, 0 );
        }
예제 #4
0
        public void AddingAndRemoving()
        {
            var test = new NbtCompound();

            var foo = new NbtInt("Foo");

            test.Add(foo);

            // adding duplicate object
            Assert.Throws <ArgumentException>(() => test.Add(foo));

            // adding duplicate name
            Assert.Throws <ArgumentException>(() => test.Add(new NbtByte("Foo")));

            // adding unnamed tag
            Assert.Throws <ArgumentException>(() => test.Add(new NbtInt()));

            // adding null
            Assert.Throws <ArgumentNullException>(() => test.Add(null));

            // contains existing name
            Assert.IsTrue(test.Contains("Foo"));

            // contains existing object
            Assert.IsTrue(test.Contains(foo));

            // contains non-existent name
            Assert.IsFalse(test.Contains("Bar"));

            // contains existing name / different object
            Assert.IsFalse(test.Contains(new NbtInt("Foo")));

            // removing non-existent name
            Assert.IsFalse(test.Remove("Bar"));

            // removing existing name
            Assert.IsTrue(test.Remove("Foo"));

            // removing non-existent name
            Assert.IsFalse(test.Remove("Foo"));

            // re-adding object
            test.Add(foo);

            // removing existing object
            Assert.IsTrue(test.Remove(foo));

            // clearing an empty NbtCompound
            Assert.AreEqual(test.Count, 0);
            test.Clear();

            // re-adding after clearing
            test.Add(foo);
            Assert.AreEqual(test.Count, 1);

            // clearing a non-empty NbtCompound
            test.Clear();
            Assert.AreEqual(test.Count, 0);
        }
예제 #5
0
        public override NbtCompound GetCompound()
        {
            Compound["x"] = new NbtInt("x", Coordinates.X);
            Compound["y"] = new NbtInt("y", Coordinates.Y);
            Compound["z"] = new NbtInt("z", Coordinates.Z);

            return(Compound);
        }
예제 #6
0
        public override NbtCompound GetCompound()
        {
            Compound["x"]         = new NbtInt("x", Coordinates.X);
            Compound["y"]         = new NbtInt("y", Coordinates.Y);
            Compound["z"]         = new NbtInt("z", Coordinates.Z);
            Compound["primary"]   = new NbtInt("primary", Primary);
            Compound["secondary"] = new NbtInt("secondary", Secondary);

            return(Compound);
        }
예제 #7
0
        public void GettersAndSetters()
        {
            var parent          = new NbtCompound("Parent");
            var child           = new NbtCompound("Child");
            var nestedChild     = new NbtCompound("NestedChild");
            var childList       = new NbtList("ChildList");
            var nestedChildList = new NbtList("NestedChildList");

            childList.Add(new NbtInt(1));
            var nestedInt = new NbtInt(1);

            nestedChildList.Add(nestedInt);
            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], nestedInt);

            // 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], nestedInt);

            // 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]    = 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.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] = 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));
        }
예제 #8
0
        public void Renaming()
        {
            var compound = new NbtCompound();

            compound.Add(new NbtInt("SameName", 1));
            var tagToRename = new NbtInt("DifferentName", 1);

            compound.Add(tagToRename);
            Assert.DoesNotThrow(() => tagToRename.Name = "SomeOtherName");
            Assert.Throws <ArgumentException>(() => tagToRename.Name     = "SameName");
            Assert.Throws <ArgumentNullException>(() => tagToRename.Name = null);
        }
예제 #9
0
    public static int getInt(this NbtCompound tag, string name, int defaultValue = 0)
    {
        NbtInt tag1 = tag.Get <NbtInt>(name);

        if (tag1 == null)
        {
            return(defaultValue);
        }
        else
        {
            return(tag1.Value);
        }
    }
        public static NbtCompound ExportAsStructure()
        {
            NbtCompound   reactor          = new NbtCompound("ReactorStructure");
            int           volume           = (int)(Reactor.interiorDims.X * Reactor.interiorDims.Y * Reactor.interiorDims.Z);
            List <string> listPalette      = new List <string>();
            NbtList       palette          = new NbtList("palette", NbtTagType.Compound);
            NbtList       blocks           = new NbtList("blocks", NbtTagType.Compound);
            NbtString     author           = new NbtString("author", "Hellrage");
            NbtCompound   forgeDataVersion = new NbtCompound("ForgeDataVersion", new List <NbtInt> {
                new NbtInt("minecraft", 1343)
            });
            NbtInt dataVersion = new NbtInt("DataVersion", 1342);

            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++)
                    {
                        Block       block      = Reactor.BlockAt(new Point3D(x, y, z));
                        NbtCompound palettenbt = GetNbtCompound(block);
                        if (!listPalette.Contains(block.DisplayName))
                        {
                            listPalette.Add(block.DisplayName);
                            palette.Add(palettenbt);
                        }
                        NbtCompound blocknbt = new NbtCompound();
                        if (block.DisplayName.Contains("Active"))
                        {
                            blocknbt.Add(CreateActiveCooler(x - 1, y - 1, z - 1));
                        }
                        blocknbt.Add(new NbtList("pos", new List <NbtInt> {
                            new NbtInt(x - 1), new NbtInt(y - 1), new NbtInt(z - 1)
                        }));
                        blocknbt.Add(new NbtInt("state", listPalette.IndexOf(block.DisplayName)));
                        blocks.Add(blocknbt);
                    }
                }
            }

            reactor.Add(new NbtList("size", new List <NbtInt> {
                new NbtInt((int)Reactor.interiorDims.X), new NbtInt((int)Reactor.interiorDims.Y), new NbtInt((int)Reactor.interiorDims.Z)
            }));
            reactor.Add(new NbtList("entities", new List <NbtInt>(), NbtTagType.Compound));
            reactor.Add(blocks);
            reactor.Add(author);
            reactor.Add(palette);
            reactor.Add(forgeDataVersion);
            reactor.Add(dataVersion);
            return(reactor);
        }
예제 #11
0
        public override NbtCompound GetCompound()
        {
            Compound["x"] = new NbtInt("x", Coordinates.X);
            Compound["y"] = new NbtInt("y", Coordinates.Y);
            Compound["z"] = new NbtInt("z", Coordinates.Z);
            Compound["xStructureOffset"] = new NbtInt("xStructureOffset", Offset.X);
            Compound["yStructureOffset"] = new NbtInt("yStructureOffset", Offset.Y);
            Compound["zStructureOffset"] = new NbtInt("zStructureOffset", Offset.Z);
            Compound["xStructureSize"]   = new NbtInt("xStructureSize", Size.X);
            Compound["yStructureSize"]   = new NbtInt("yStructureSize", Size.Y);
            Compound["zStructureSize"]   = new NbtInt("zStructureSize", Size.Z);
            Compound["showBoundingBox"]  = new NbtByte("showBoundingBox", (byte)(ShowBoundingBox ? 1 : 0));

            return(Compound);
        }
예제 #12
0
        public void BasicUndo()
        {
            int before  = 10;
            int after   = 10;
            var actions = new Stack <UndoableAction>();
            var tag     = new NbtInt();

            tag.ActionPerformed += a => actions.Push(a);

            tag.Value = before;
            tag.Value = after;
            actions.Pop().Undo();

            Assert.AreEqual(tag.Value, before);
        }
예제 #13
0
        public void NbtIntTest()
        {
            object dummy;
            NbtTag test = new NbtInt(2147483647);

            Assert.Throws <InvalidCastException>(() => dummy = test.ByteArrayValue);
            Assert.Throws <InvalidCastException>(() => dummy = test.ByteValue);
            Assert.AreEqual((double)2147483647, test.DoubleValue);
            Assert.AreEqual((float)2147483647, test.FloatValue);
            Assert.Throws <InvalidCastException>(() => dummy = test.IntArrayValue);
            Assert.AreEqual(2147483647, test.IntValue);
            Assert.AreEqual(2147483647L, test.LongValue);
            Assert.Throws <InvalidCastException>(() => dummy = test.ShortValue);
            Assert.AreEqual("2147483647", test.StringValue);
        }
예제 #14
0
        public void Renaming()
        {
            var tagToRename = new NbtInt("DifferentName", 1);
            var compound    = new NbtCompound {
                new NbtInt("SameName", 1),
                tagToRename
            };

            // proper renaming, should not throw
            tagToRename.Name = "SomeOtherName";

            // attempting to use a duplicate name
            Assert.Throws <ArgumentException>(() => tagToRename.Name = "SameName");

            // assigning a null name to a tag inside a compound; should throw
            Assert.Throws <ArgumentNullException>(() => tagToRename.Name = null);

            // assigning a null name to a tag that's been removed; should not throw
            compound.Remove(tagToRename);
            tagToRename.Name = null;
        }
예제 #15
0
        public static KeyValuePair <List <int>, NbtTag> GetTagByNode(TreeNode node)
        {
            List <int> indexes = GetIndexes(node);
            NbtTag     tag     = _nbtFile.RootTag;

            foreach (int index in indexes)
            {
                if (tag is NbtCompound)
                {
                    tag = ((NbtCompound)tag).ToArray()[index];
                }
                else if (tag is NbtList)
                {
                    tag = ((NbtList)tag).ToArray()[index]; //TODO DOES NOT SAVE/CHANGE!!!!
                }
                else if (tag is NbtByteArray)              //TODO cleanup/remove
                {
                    Debug.WriteLine("USING");
                    tag = new NbtByte(((NbtByteArray)tag).ByteArrayValue[index]);
                }
                else if (tag is NbtIntArray)//TODO cleanup/remove
                {
                    Debug.WriteLine("USING");
                    tag = new NbtInt(((NbtIntArray)tag).IntArrayValue[index]);
                }
                else
                {
                    (new AlertForm($"The index {index.ToString()} in Tag {tag.ToString()} could not be found due to the tag probably not having any subnodes!")
                    {
                        Text = "Finding NbtTag from tree error",
                        Icon = SystemIcons.Error
                    }).ShowDialog();
                    return(new KeyValuePair <List <int>, NbtTag>(indexes, tag));//OR NULL?
                }
            }
            return(new KeyValuePair <List <int>, NbtTag>(indexes, tag));
        }
예제 #16
0
        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
                };

                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.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");
                            }

                            chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag);
                        }
                    }
                }

                //NbtList tileTicks = dataTag["TileTicks"] as NbtList;

                chunk.isDirty = false;
                return(chunk);
            }
        }
예제 #17
0
		/// <summary>
		/// Writes out the specified tag.
		/// </summary>
		/// <param name="tag">The tag.</param>
		/// <exception cref="System.ArgumentNullException"><paramref name="tag"/> is <c>null</c>.</exception>
		/// <exception cref="System.ObjectDisposedException">The stream is closed.</exception>
		/// <exception cref="System.IO.IOException">An I/O error occured.</exception>
		public void Write(NbtInt tag)
		{
			if (tag == null)
				throw new ArgumentNullException("tag", "tag is null.");

			Write(tag, true);
		}
예제 #18
0
        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);
        }
예제 #19
0
        static BlockFactory()
        {
            for (int i = 0; i < byte.MaxValue * 2; i++)
            {
                var block = GetBlockById(i);
                if (block != null)
                {
                    if (block.IsTransparent)
                    {
                        TransparentBlocks[block.Id] = 1;
                    }
                    if (block.LightLevel > 0)
                    {
                        LuminousBlocks[block.Id] = (byte)block.LightLevel;
                    }
                }
            }

            NameToId = BuildNameToId();

            for (int i = 0; i < LegacyToRuntimeId.Length; ++i)
            {
                LegacyToRuntimeId[i] = -1;
            }

            var assembly = Assembly.GetAssembly(typeof(Block));

            lock (lockObj)
            {
                Dictionary <string, int> idMapping = new Dictionary <string, int>(ResourceUtil.ReadResource <Dictionary <string, int> >("block_id_map.json", typeof(Block), "Data"), StringComparer.OrdinalIgnoreCase);

                int runtimeId = 0;
                BlockPalette = new BlockPalette();

                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.canonical_block_states.nbt"))
                {
                    do
                    {
                        var compound  = Packet.ReadNbtCompound(stream, true);
                        var container = GetBlockStateContainer(compound);

                        container.RuntimeId = runtimeId++;
                        BlockPalette.Add(container);
                    } while (stream.Position < stream.Length);
                }

                List <R12ToCurrentBlockMapEntry> legacyStateMap = new List <R12ToCurrentBlockMapEntry>();
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.r12_to_current_block_map.bin"))
                {
                    while (stream.Position < stream.Length)
                    {
                        var    length = VarInt.ReadUInt32(stream);
                        byte[] bytes  = new byte[length];
                        stream.Read(bytes, 0, bytes.Length);

                        string stringId = Encoding.UTF8.GetString(bytes);

                        bytes = new byte[2];
                        stream.Read(bytes, 0, bytes.Length);
                        var meta = BitConverter.ToInt16(bytes);

                        var compound = Packet.ReadNbtCompound(stream, true);

                        legacyStateMap.Add(new R12ToCurrentBlockMapEntry(stringId, meta, GetBlockStateContainer(compound)));
                    }
                }

                Dictionary <string, List <int> > idToStatesMap = new Dictionary <string, List <int> >(StringComparer.OrdinalIgnoreCase);

                for (var index = 0; index < BlockPalette.Count; index++)
                {
                    var        state = BlockPalette[index];
                    List <int> candidates;

                    if (!idToStatesMap.TryGetValue(state.Name, out candidates))
                    {
                        candidates = new List <int>();
                    }

                    candidates.Add(index);

                    idToStatesMap[state.Name] = candidates;
                }

                foreach (var pair in legacyStateMap)
                {
                    if (!idMapping.TryGetValue(pair.StringId, out int id))
                    {
                        continue;
                    }

                    var data = pair.Meta;

                    if (data > 15)
                    {
                        continue;
                    }

                    var mappedState = pair.State;
                    var mappedName  = pair.State.Name;

                    if (!idToStatesMap.TryGetValue(mappedName, out var matching))
                    {
                        continue;
                    }

                    foreach (var match in matching)
                    {
                        var networkState = BlockPalette[match];

                        var thisStates  = new HashSet <IBlockState>(mappedState.States);
                        var otherStates = new HashSet <IBlockState>(networkState.States);

                        otherStates.IntersectWith(thisStates);

                        if (otherStates.Count == thisStates.Count)
                        {
                            BlockPalette[match].Id   = id;
                            BlockPalette[match].Data = data;

                            BlockPalette[match].ItemInstance = new ItemPickInstance()
                            {
                                Id       = (short)id,
                                Metadata = data,
                                WantNbt  = false
                            };

                            LegacyToRuntimeId[(id << 4) | (byte)data] = match;

                            break;
                        }
                    }
                }

                foreach (var record in BlockPalette)
                {
                    var states = new List <NbtTag>();
                    foreach (IBlockState state in record.States)
                    {
                        NbtTag stateTag = null;
                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                            stateTag = new NbtByte(state.Name, blockStateByte.Value);
                            break;

                        case BlockStateInt blockStateInt:
                            stateTag = new NbtInt(state.Name, blockStateInt.Value);
                            break;

                        case BlockStateString blockStateString:
                            stateTag = new NbtString(state.Name, blockStateString.Value);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                        states.Add(stateTag);
                    }

                    var nbt = new NbtFile()
                    {
                        BigEndian = false,
                        UseVarInt = true,
                        RootTag   = new NbtCompound("states", states)
                    };

                    byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None);

                    record.StatesCacheNbt = nbtBinary;
                }
            }

            BlockStates = new HashSet <BlockStateContainer>(BlockPalette);
        }
예제 #20
0
		internal void Write(NbtInt tag, bool writeHeader)
		{
			Write(tag.Name, tag.Value, writeHeader);
		}
예제 #21
0
파일: MiscTests.cs 프로젝트: fragmer/fNbt
        public void CopyConstructorTest()
        {
            NbtByte byteTag = new NbtByte("byteTag", 1);
            NbtByte byteTagClone = (NbtByte)byteTag.Clone();
            Assert.AreNotSame(byteTag, byteTagClone);
            Assert.AreEqual(byteTag.Name, byteTagClone.Name);
            Assert.AreEqual(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.AreNotSame(byteArrTag, byteArrTagClone);
            Assert.AreEqual(byteArrTag.Name, byteArrTagClone.Name);
            Assert.AreNotSame(byteArrTag.Value, byteArrTagClone.Value);
            CollectionAssert.AreEqual(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.AreNotSame(compTag, compTagClone);
            Assert.AreEqual(compTag.Name, compTagClone.Name);
            Assert.AreNotSame(compTag["innerTag"], compTagClone["innerTag"]);
            Assert.AreEqual(compTag["innerTag"].Name, compTagClone["innerTag"].Name);
            Assert.AreEqual(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.AreNotSame(doubleTag, doubleTagClone);
            Assert.AreEqual(doubleTag.Name, doubleTagClone.Name);
            Assert.AreEqual(doubleTag.Value, doubleTagClone.Value);
            Assert.Throws<ArgumentNullException>(() => new NbtDouble((NbtDouble)null));

            NbtFloat floatTag = new NbtFloat("floatTag", 1);
            NbtFloat floatTagClone = (NbtFloat)floatTag.Clone();
            Assert.AreNotSame(floatTag, floatTagClone);
            Assert.AreEqual(floatTag.Name, floatTagClone.Name);
            Assert.AreEqual(floatTag.Value, floatTagClone.Value);
            Assert.Throws<ArgumentNullException>(() => new NbtFloat((NbtFloat)null));

            NbtInt intTag = new NbtInt("intTag", 1);
            NbtInt intTagClone = (NbtInt)intTag.Clone();
            Assert.AreNotSame(intTag, intTagClone);
            Assert.AreEqual(intTag.Name, intTagClone.Name);
            Assert.AreEqual(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.AreNotSame(intArrTag, intArrTagClone);
            Assert.AreEqual(intArrTag.Name, intArrTagClone.Name);
            Assert.AreNotSame(intArrTag.Value, intArrTagClone.Value);
            CollectionAssert.AreEqual(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.AreNotSame(listTag, listTagClone);
            Assert.AreEqual(listTag.Name, listTagClone.Name);
            Assert.AreNotSame(listTag[0], listTagClone[0]);
            Assert.AreEqual(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.AreNotSame(longTag, longTagClone);
            Assert.AreEqual(longTag.Name, longTagClone.Name);
            Assert.AreEqual(longTag.Value, longTagClone.Value);
            Assert.Throws<ArgumentNullException>(() => new NbtLong((NbtLong)null));

            NbtShort shortTag = new NbtShort("shortTag", 1);
            NbtShort shortTagClone = (NbtShort)shortTag.Clone();
            Assert.AreNotSame(shortTag, shortTagClone);
            Assert.AreEqual(shortTag.Name, shortTagClone.Name);
            Assert.AreEqual(shortTag.Value, shortTagClone.Value);
            Assert.Throws<ArgumentNullException>(() => new NbtShort((NbtShort)null));

            NbtString stringTag = new NbtString("stringTag", "foo");
            NbtString stringTagClone = (NbtString)stringTag.Clone();
            Assert.AreNotSame(stringTag, stringTagClone);
            Assert.AreEqual(stringTag.Name, stringTagClone.Name);
            Assert.AreEqual(stringTag.Value, stringTagClone.Value);
            Assert.Throws<ArgumentNullException>(() => new NbtString((NbtString)null));
        }
예제 #22
0
        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);

                                // Anvil to PE friendly converstion
                                if (blockId == 125)
                                {
                                    blockId = 5;
                                }
                                else if (blockId == 126)
                                {
                                    blockId = 158;
                                }
                                else if (blockId == 75)
                                {
                                    blockId = 50;
                                }
                                else if (blockId == 76)
                                {
                                    blockId = 50;
                                }
                                else if (blockId == 123)
                                {
                                    blockId = 89;
                                }
                                else if (blockId == 124)
                                {
                                    blockId = 89;
                                }
                                else if (blockId == 152)
                                {
                                    blockId = 73;
                                }
                                else if (_ignore.BinarySearch(blockId) >= 0)
                                {
                                    blockId = 0;
                                }
                                else if (_gaps.BinarySearch(blockId) >= 0)
                                {
                                    Debug.WriteLine("Missing material: " + blockId);
                                    blockId = 133;
                                }

                                if (blockId > 255)
                                {
                                    blockId = 41;
                                }

                                if (yi == 127 && blockId != 0)
                                {
                                    blockId = 30;
                                }
                                if (yi == 0 && (blockId == 8 || blockId == 9 /*|| blockId == 0*/))
                                {
                                    blockId = 7;
                                }

                                //if (blockId != 0) blockId = 41;

                                chunk.SetBlock(x, yi, z, (byte)blockId);
                                chunk.SetMetadata(x, yi, z, Nibble4(data, anvilIndex));
                                chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex));
                                chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex));
                            }
                        }
                    }
                }

                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);
            }
        }
예제 #23
0
 public static string ToSnbt(this NbtInt tag, SnbtOptions options) => tag.Value.ToString();
예제 #24
0
        static BlockFactory()
        {
            for (int i = 0; i < byte.MaxValue * 2; i++)
            {
                var block = GetBlockById(i);
                if (block != null)
                {
                    if (block.IsTransparent)
                    {
                        TransparentBlocks[block.Id] = 1;
                    }
                    if (block.LightLevel > 0)
                    {
                        LuminousBlocks[block.Id] = (byte)block.LightLevel;
                    }
                }
            }

            NameToId = BuildNameToId();

            for (int i = 0; i < LegacyToRuntimeId.Length; ++i)
            {
                LegacyToRuntimeId[i] = -1;
            }

            var assembly = Assembly.GetAssembly(typeof(Block));

            lock (lockObj)
            {
                Dictionary <string, int> idMapping;
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".block_id_map.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        idMapping = JsonConvert.DeserializeObject <Dictionary <string, int> >(reader.ReadToEnd());
                    }

                Dictionary <string, short> itemIdMapping;
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".item_id_map.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        itemIdMapping = JsonConvert.DeserializeObject <Dictionary <string, short> >(reader.ReadToEnd());
                    }

                int runtimeId = 0;
                BlockPalette = new BlockPalette();
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".canonical_block_states.nbt"))
                {
                    var reader = new NbtFile();
                    reader.UseVarInt = true;
                    reader.AllowAlternativeRootTag = true;

                    do
                    {
                        reader.LoadFromStream(stream, NbtCompression.AutoDetect);
                        var record = new BlockStateContainer();

                        var    tag  = reader.RootTag;
                        string name = tag["name"].StringValue;
                        record.Name   = name;
                        record.States = new List <IBlockState>();

                        if (idMapping.TryGetValue(name, out var id))
                        {
                            record.Id = id;
                        }

                        var states = tag["states"];
                        if (states != null && states is NbtCompound compound)
                        {
                            foreach (var stateEntry in compound)
                            {
                                switch (stateEntry)
                                {
                                case NbtInt nbtInt:
                                    record.States.Add(new BlockStateInt()
                                    {
                                        Name  = nbtInt.Name,
                                        Value = nbtInt.Value
                                    });
                                    break;

                                case NbtByte nbtByte:
                                    record.States.Add(new BlockStateByte()
                                    {
                                        Name  = nbtByte.Name,
                                        Value = nbtByte.Value
                                    });
                                    break;

                                case NbtString nbtString:
                                    record.States.Add(new BlockStateString()
                                    {
                                        Name  = nbtString.Name,
                                        Value = nbtString.Value
                                    });
                                    break;
                                }
                            }
                        }

                        if (itemIdMapping.TryGetValue(name, out var itemId))
                        {
                            record.ItemInstance = new ItemPickInstance()
                            {
                                Id       = itemId,
                                WantNbt  = false,
                                Metadata = 0
                            };
                        }

                        record.RuntimeId = runtimeId++;
                        BlockPalette.Add(record);
                    } while (stream.Position < stream.Length);
                }

                /*using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json"))
                 * using (var reader = new StreamReader(stream))
                 * {
                 *      BlockPalette = BlockPalette.FromJson(reader.ReadToEnd());
                 * }*/

                foreach (var record in BlockPalette)
                {
                    var states = new List <NbtTag>();
                    foreach (IBlockState state in record.States)
                    {
                        NbtTag stateTag = null;
                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                            stateTag = new NbtByte(state.Name, blockStateByte.Value);
                            break;

                        case BlockStateInt blockStateInt:
                            stateTag = new NbtInt(state.Name, blockStateInt.Value);
                            break;

                        case BlockStateString blockStateString:
                            stateTag = new NbtString(state.Name, blockStateString.Value);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                        states.Add(stateTag);
                    }

                    var nbt = new NbtFile()
                    {
                        BigEndian = false,
                        UseVarInt = true,
                        RootTag   = new NbtCompound("states", states)
                    };

                    byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None);

                    record.StatesCacheNbt = nbtBinary;
                }
            }
            int palletSize = BlockPalette.Count;

            for (int i = 0; i < palletSize; i++)
            {
                if (BlockPalette[i].Data > 15)
                {
                    continue;                                            // TODO: figure out why palette contains blocks with meta more than 15
                }
                if (BlockPalette[i].Data == -1)
                {
                    continue;                                             // These are blockstates that does not have a metadata mapping
                }
                LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i;
            }

            BlockStates = new HashSet <BlockStateContainer>(BlockPalette);
        }
예제 #25
0
        public void Renaming()
        {
            var tagToRename = new NbtInt("DifferentName", 1);
            var compound = new NbtCompound {
                new NbtInt("SameName", 1),
                tagToRename
            };

            // proper renaming, should not throw
            tagToRename.Name = "SomeOtherName";

            // attempting to use a duplicate name
            Assert.Throws<ArgumentException>(() => tagToRename.Name = "SameName");

            // assigning a null name to a tag inside a compound; should throw
            Assert.Throws<ArgumentNullException>(() => tagToRename.Name = null);

            // assigning a null name to a tag inside a compound; should not throw
            compound.Remove(tagToRename);
            tagToRename.Name = null;
        }
예제 #26
0
 public void NbtIntTest()
 {
     object dummy;
     NbtTag test = new NbtInt( 2147483647 );
     Assert.Throws<InvalidCastException>( () => dummy = test.ByteArrayValue );
     Assert.Throws<InvalidCastException>( () => dummy = test.ByteValue );
     Assert.AreEqual( (double)2147483647, test.DoubleValue );
     Assert.AreEqual( (float)2147483647, test.FloatValue );
     Assert.Throws<InvalidCastException>( () => dummy = test.IntArrayValue );
     Assert.AreEqual( 2147483647, test.IntValue );
     Assert.AreEqual( 2147483647L, test.LongValue );
     Assert.Throws<InvalidCastException>( () => dummy = test.ShortValue );
     Assert.AreEqual( "2147483647", test.StringValue );
 }
예제 #27
0
        /**
         * BEFORE any digits, requiring backtracking.
         */
        private NbtTag ParseNumber()
        {
            bool       more    = true;
            NbtTagType type    = NbtTagType.Int;
            String     literal = "";

            while (more)
            {
                char next;
                try
                {
                    next = NextChar();
                }
                catch (Exception)
                {
                    next = ' '; //just end the number
                }
                if (next <= '9' && next >= '0' || next == '-')
                {
                    literal += next;
                }
                else if (next == '.')
                {
                    literal += next;
                    type     = NbtTagType.Double;
                }
                else
                {
                    more = false;
                    switch (next)
                    {
                    case 'l':
                    case 'L':
                        type = NbtTagType.Long;
                        break;

                    case 'b':
                    case 'B':
                        type = NbtTagType.Byte;
                        break;

                    case 'f':
                    case 'F':
                        type = NbtTagType.Float;
                        break;

                    default:
                        //End of number, put it back.
                        Position--;
                        break;
                    }
                }
            }
            NbtTag ret;

            switch (type)
            {
            case NbtTagType.Byte:
                ret = new NbtByte(byte.Parse(literal));
                break;

            case NbtTagType.Int:
                ret = new NbtInt(int.Parse(literal));
                break;

            case NbtTagType.Long:
                ret = new NbtLong(long.Parse(literal));
                break;

            case NbtTagType.Float:
                ret = new NbtFloat(float.Parse(literal));
                break;

            case NbtTagType.Double:
                ret = new NbtDouble(double.Parse(literal));
                break;

            default:
                ret = null;
                break;
            }
            return(ret);
        }
예제 #28
0
        public static NbtTag Serialize <T>(this T obj, NbtTag tag = null) where T : new()
        {
            tag ??= new NbtCompound(string.Empty);

            if (obj == null)
            {
                throw new NullReferenceException();
            }

            PropertyInfo[] properties = obj.GetType().GetProperties();
            foreach (PropertyInfo propertyInfo in properties)
            {
                var    attribute    = propertyInfo.GetCustomAttribute(typeof(JsonPropertyNameAttribute)) as JsonPropertyNameAttribute;
                string propertyName = attribute?.Name ?? propertyInfo.Name;
                NbtTag nbtTag       = tag[propertyName] ?? tag[LowercaseFirst(propertyName)];

                if (nbtTag == null)
                {
                    if (propertyInfo.PropertyType == typeof(bool))
                    {
                        nbtTag = new NbtByte(propertyName);
                    }
                    else if (propertyInfo.PropertyType == typeof(byte))
                    {
                        nbtTag = new NbtByte(propertyName);
                    }
                    else if (propertyInfo.PropertyType == typeof(short))
                    {
                        nbtTag = new NbtShort(propertyName);
                    }
                    else if (propertyInfo.PropertyType == typeof(int))
                    {
                        nbtTag = new NbtInt(propertyName);
                    }
                    else if (propertyInfo.PropertyType == typeof(long))
                    {
                        nbtTag = new NbtLong(propertyName);
                    }
                    else if (propertyInfo.PropertyType == typeof(float))
                    {
                        nbtTag = new NbtFloat(propertyName);
                    }
                    else if (propertyInfo.PropertyType == typeof(double))
                    {
                        nbtTag = new NbtDouble(propertyName);
                    }
                    else if (propertyInfo.PropertyType == typeof(string))
                    {
                        nbtTag = new NbtString(propertyName, "");
                    }
                    else
                    {
                        continue;
                    }
                }

                //var mex = property.Body as MemberExpression;
                //var target = Expression.Lambda(mex.Expression).Compile().DynamicInvoke();

                switch (nbtTag.TagType)
                {
                case NbtTagType.Unknown:
                    break;

                case NbtTagType.End:
                    break;

                case NbtTagType.Byte:
                    if (propertyInfo.PropertyType == typeof(bool))
                    {
                        tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)((bool)propertyInfo.GetValue(obj) ? 1 : 0));
                    }
                    else
                    {
                        tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)propertyInfo.GetValue(obj));
                    }
                    break;

                case NbtTagType.Short:
                    tag[nbtTag.Name] = new NbtShort(nbtTag.Name, (short)propertyInfo.GetValue(obj));
                    break;

                case NbtTagType.Int:
                    if (propertyInfo.PropertyType == typeof(bool))
                    {
                        tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (bool)propertyInfo.GetValue(obj) ? 1 : 0);
                    }
                    else
                    {
                        tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (int)propertyInfo.GetValue(obj));
                    }
                    break;

                case NbtTagType.Long:
                    tag[nbtTag.Name] = new NbtLong(nbtTag.Name, (long)propertyInfo.GetValue(obj));
                    break;

                case NbtTagType.Float:
                    tag[nbtTag.Name] = new NbtFloat(nbtTag.Name, (float)propertyInfo.GetValue(obj));
                    break;

                case NbtTagType.Double:
                    tag[nbtTag.Name] = new NbtDouble(nbtTag.Name, (double)propertyInfo.GetValue(obj));
                    break;

                case NbtTagType.ByteArray:
                    tag[nbtTag.Name] = new NbtByteArray(nbtTag.Name, (byte[])propertyInfo.GetValue(obj));
                    break;

                case NbtTagType.String:
                    tag[nbtTag.Name] = new NbtString(nbtTag.Name, (string)propertyInfo.GetValue(obj) ?? "");
                    break;

                case NbtTagType.List:
                    break;

                case NbtTagType.Compound:
                    break;

                case NbtTagType.IntArray:
                    tag[nbtTag.Name] = new NbtIntArray(nbtTag.Name, (int[])propertyInfo.GetValue(obj));
                    break;
                }
            }

            return(tag);
        }
예제 #29
0
        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.AreEqual(nestedChild, parent["Child"]["NestedChild"]);
            Assert.AreEqual(nestedChildList, parent["Child"]["NestedChildList"]);
            Assert.AreEqual(nestedInt, parent["Child"]["NestedChildList"][0]);

            // Accessing nested compound tags using Get and Get<T>
            Assert.Throws <ArgumentNullException>(() => parent.Get <NbtCompound>(null));
            Assert.IsNull(parent.Get <NbtCompound>("NonExistingChild"));
            Assert.AreEqual(nestedChild, parent.Get <NbtCompound>("Child").Get <NbtCompound>("NestedChild"));
            Assert.AreEqual(nestedChildList, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList"));
            Assert.AreEqual(nestedInt, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")[0]);
            Assert.Throws <ArgumentNullException>(() => parent.Get(null));
            Assert.IsNull(parent.Get("NonExistingChild"));
            Assert.AreEqual(nestedChild, (parent.Get("Child") as NbtCompound).Get("NestedChild"));
            Assert.AreEqual(nestedChildList, (parent.Get("Child") as NbtCompound).Get("NestedChildList"));
            Assert.AreEqual(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.IsFalse(parent.TryGet("NonExistingChild", out dummyTag));
            Assert.IsTrue(parent.TryGet("Child", out dummyTag));
            NbtCompound dummyCompoundTag;

            Assert.Throws <ArgumentNullException>(() => parent.TryGet(null, out dummyCompoundTag));
            Assert.IsFalse(parent.TryGet("NonExistingChild", out dummyCompoundTag));
            Assert.IsTrue(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.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] = 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);
        }
예제 #30
0
        public ChunkColumn GetChunk(int X, int Z)
        {
            var width = 32;
            var depth = 32;

            var rx = X >> 5;
            var rz = Z >> 5;

            var filePath = Path.Combine(_basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz));

            if (!File.Exists(filePath))
            {
                return(_backEndGenerator.GenerateChunkColumn(new Vector2(X, Z)));
            }

            using (var regionFile = File.OpenRead(filePath))
            {
                var buffer = new byte[8192];

                regionFile.Read(buffer, 0, 8192);

                var xi = (X % width);
                if (xi < 0)
                {
                    xi += 32;
                }
                var zi = (Z % depth);
                if (zi < 0)
                {
                    zi += 32;
                }
                var tableOffset = (xi + zi * width) * 4;

                regionFile.Seek(tableOffset, SeekOrigin.Begin);

                var offsetBuffer = new byte[4];
                regionFile.Read(offsetBuffer, 0, 3);
                Array.Reverse(offsetBuffer);
                var offset = BitConverter.ToInt32(offsetBuffer, 0) << 4;

                var length = regionFile.ReadByte();

                //if (offset == 0 || length == 0) return _backEndGenerator.GenerateChunkColumn(new Vector2(X, Z));

                if (offset == 0 || length == 0)
                {
                    return(_backEndGenerator.GenerateChunkColumn(new Vector2(X, Z)));
                }

                regionFile.Seek(offset, SeekOrigin.Begin);
                var waste = new byte[4];
                regionFile.Read(waste, 0, 4);
                var compressionMode = regionFile.ReadByte();

                var nbt = new NbtFile();
                nbt.LoadFromStream(regionFile, NbtCompression.ZLib);

                var dataTag = nbt.RootTag["Level"];

                var sections = dataTag["Sections"] as NbtList;

                var chunk = new ChunkColumn
                {
                    X       = X,
                    Z       = Z,
                    BiomeId = dataTag["Biomes"].ByteArrayValue
                };

                for (var 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 (var sectionTag in sections)
                {
                    var sy      = sectionTag["Y"].ByteValue * 16;
                    var blocks  = sectionTag["Blocks"].ByteArrayValue;
                    var data    = sectionTag["Data"].ByteArrayValue;
                    var addTag  = sectionTag["Add"];
                    var adddata = new byte[2048];
                    if (addTag != null)
                    {
                        adddata = addTag.ByteArrayValue;
                    }
                    var blockLight = sectionTag["BlockLight"].ByteArrayValue;
                    var skyLight   = sectionTag["SkyLight"].ByteArrayValue;

                    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 - _waterOffsetY;
                                if (yi < 0 || yi >= 256)
                                {
                                    continue;
                                }

                                var anvilIndex = y * 16 * 16 + z * 16 + x;
                                var blockId    = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8);


                                var b = BlockFactory.GetBlockById((ushort)blockId);
                                b.Metadata = Nibble4(data, anvilIndex);
                                chunk.SetBlock(x, yi, z, b);
                                chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex));
                                chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex));
                            }
                        }
                    }
                }

                var entities     = dataTag["Entities"] as NbtList;
                var tileEntities = dataTag["TileEntities"] as NbtList;

                if (tileEntities != null)
                {
                    foreach (var nbtTag in tileEntities)
                    {
                        var    blockEntityTag = (NbtCompound)nbtTag;
                        string entityId       = blockEntityTag["id"].StringValue;
                        int    x = blockEntityTag["x"].IntValue;
                        int    y = blockEntityTag["y"].IntValue - _waterOffsetY;
                        int    z = blockEntityTag["z"].IntValue;
                        blockEntityTag["y"] = new NbtInt("y", y);

                        TileEntity blockEntity = TileEntityFactory.GetBlockEntityById(entityId);
                        if (blockEntity != null)
                        {
                            blockEntityTag.Name = string.Empty;
                            chunk.SetBlockEntity(new Vector3(x, y, z), blockEntityTag);
                        }
                    }
                }

                var tileTicks = dataTag["TileTicks"] as NbtList;

                chunk.IsDirty = false;
                return(chunk);
            }
        }
예제 #31
0
        public void CopyConstructorTest()
        {
            NbtByte byteTag      = new NbtByte("byteTag", 1);
            NbtByte byteTagClone = (NbtByte)byteTag.Clone();

            Assert.AreNotSame(byteTag, byteTagClone);
            Assert.AreEqual(byteTag.Name, byteTagClone.Name);
            Assert.AreEqual(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.AreNotSame(byteArrTag, byteArrTagClone);
            Assert.AreEqual(byteArrTag.Name, byteArrTagClone.Name);
            Assert.AreNotSame(byteArrTag.Value, byteArrTagClone.Value);
            CollectionAssert.AreEqual(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.AreNotSame(compTag, compTagClone);
            Assert.AreEqual(compTag.Name, compTagClone.Name);
            Assert.AreNotSame(compTag["innerTag"], compTagClone["innerTag"]);
            Assert.AreEqual(compTag["innerTag"].Name, compTagClone["innerTag"].Name);
            Assert.AreEqual(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.AreNotSame(doubleTag, doubleTagClone);
            Assert.AreEqual(doubleTag.Name, doubleTagClone.Name);
            Assert.AreEqual(doubleTag.Value, doubleTagClone.Value);
            Assert.Throws <ArgumentNullException>(() => new NbtDouble((NbtDouble)null));

            NbtFloat floatTag      = new NbtFloat("floatTag", 1);
            NbtFloat floatTagClone = (NbtFloat)floatTag.Clone();

            Assert.AreNotSame(floatTag, floatTagClone);
            Assert.AreEqual(floatTag.Name, floatTagClone.Name);
            Assert.AreEqual(floatTag.Value, floatTagClone.Value);
            Assert.Throws <ArgumentNullException>(() => new NbtFloat((NbtFloat)null));

            NbtInt intTag      = new NbtInt("intTag", 1);
            NbtInt intTagClone = (NbtInt)intTag.Clone();

            Assert.AreNotSame(intTag, intTagClone);
            Assert.AreEqual(intTag.Name, intTagClone.Name);
            Assert.AreEqual(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.AreNotSame(intArrTag, intArrTagClone);
            Assert.AreEqual(intArrTag.Name, intArrTagClone.Name);
            Assert.AreNotSame(intArrTag.Value, intArrTagClone.Value);
            CollectionAssert.AreEqual(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.AreNotSame(listTag, listTagClone);
            Assert.AreEqual(listTag.Name, listTagClone.Name);
            Assert.AreNotSame(listTag[0], listTagClone[0]);
            Assert.AreEqual(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.AreNotSame(longTag, longTagClone);
            Assert.AreEqual(longTag.Name, longTagClone.Name);
            Assert.AreEqual(longTag.Value, longTagClone.Value);
            Assert.Throws <ArgumentNullException>(() => new NbtLong((NbtLong)null));

            NbtShort shortTag      = new NbtShort("shortTag", 1);
            NbtShort shortTagClone = (NbtShort)shortTag.Clone();

            Assert.AreNotSame(shortTag, shortTagClone);
            Assert.AreEqual(shortTag.Name, shortTagClone.Name);
            Assert.AreEqual(shortTag.Value, shortTagClone.Value);
            Assert.Throws <ArgumentNullException>(() => new NbtShort((NbtShort)null));

            NbtString stringTag      = new NbtString("stringTag", "foo");
            NbtString stringTagClone = (NbtString)stringTag.Clone();

            Assert.AreNotSame(stringTag, stringTagClone);
            Assert.AreEqual(stringTag.Name, stringTagClone.Name);
            Assert.AreEqual(stringTag.Value, stringTagClone.Value);
            Assert.Throws <ArgumentNullException>(() => new NbtString((NbtString)null));
        }
예제 #32
0
        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.AreEqual(parent["Child"]["NestedChild"], nestedChild);
            Assert.AreEqual(parent["Child"]["NestedChildList"], nestedChildList);
            Assert.AreEqual(parent["Child"]["NestedChildList"][0], nestedInt);

            // Accessing nested compound tags using Get and 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], nestedInt);
            Assert.AreEqual((parent.Get("Child") as NbtCompound).Get("NestedChild"), nestedChild);
            Assert.AreEqual((parent.Get("Child") as NbtCompound).Get("NestedChildList"), nestedChildList);
            Assert.AreEqual((parent.Get("Child") as NbtCompound).Get("NestedChildList")[0], nestedInt);

            // Accessing with Get<T> and an invalid given type
            Assert.Throws<InvalidCastException>(() => parent.Get<NbtInt>("Child"));

            // Using TryGet and TryGet<T>
            NbtTag dummyTag;
            Assert.IsTrue(parent.TryGet("Child", out dummyTag));
            NbtCompound dummyCompoundTag;
            Assert.IsTrue(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.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] = 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);
        }
예제 #33
0
    public void AddingAndRemoving()
    {
        var foo  = new NbtInt("Foo");
        var test = new NbtCompound {
            foo
        };

        // adding duplicate object
        Assert.Throws <ArgumentException>(() => test.Add(foo));

        // adding duplicate name
        Assert.Throws <ArgumentException>(() => test.Add(new NbtByte("Foo")));

        // adding unnamed tag
        Assert.Throws <ArgumentException>(() => test.Add(new NbtInt()));

        // adding null
        Assert.Throws <ArgumentNullException>(() => test.Add(null));

        // adding tag to self
        Assert.Throws <ArgumentException>(() => test.Add(test));

        // contains existing name/object
        Assert.True(test.Contains("Foo"));
        Assert.Contains(foo, test);
        Assert.Throws <ArgumentNullException>(() => test.Contains((string)null));
        Assert.Throws <ArgumentNullException>(() => test.Contains((NbtTag)null));

        // contains non-existent name
        Assert.False(test.Contains("Bar"));

        // contains existing name / different object
        Assert.DoesNotContain(new NbtInt("Foo"), test);

        // removing non-existent name
        Assert.Throws <ArgumentNullException>(() => test.Remove((string)null));
        Assert.False(test.Remove("Bar"));

        // removing existing name
        Assert.True(test.Remove("Foo"));

        // removing non-existent name
        Assert.False(test.Remove("Foo"));

        // re-adding object
        test.Add(foo);

        // removing existing object
        Assert.Throws <ArgumentNullException>(() => test.Remove((NbtTag)null));
        Assert.True(test.Remove(foo));
        Assert.False(test.Remove(foo));

        // clearing an empty NbtCompound
        Assert.Empty(test);
        test.Clear();

        // re-adding after clearing
        test.Add(foo);
        Assert.Single(test);

        // clearing a non-empty NbtCompound
        test.Clear();
        Assert.Empty(test);
    }
예제 #34
0
        public static NbtTag TreeToNBT(TreeNodeCollection tree)
        {
            NbtTag NBTTag = null;

            if (tree != null)
            {
                foreach (TreeNode node in tree)
                {
                    string value = node.Text.Replace($"{node.Name}: ", string.Empty).Replace(".", ",");//TODO , or . by language
                    try
                    {
                        switch (node.ImageKey)
                        {
                        case "buttonstring.png":
                        {
                            NBTTag = new NbtString(node.Name, value);
                            break;
                        }

                        case "buttonint.png":
                        {
                            NBTTag = new NbtInt(node.Name, int.Parse(value));
                            break;
                        }

                        case "buttonbyte.png":
                        {
                            NBTTag = new NbtByte(node.Name, byte.Parse(value));
                            break;
                        }

                        case "buttonlong.png":
                        {
                            NBTTag = new NbtLong(node.Name, long.Parse(value));
                            break;
                        }

                        case "buttonshort.png":
                        {
                            NBTTag = new NbtShort(node.Name, short.Parse(value));
                            break;
                        }

                        case "buttonfloat.png":
                        {
                            NBTTag = new NbtFloat(node.Name, float.Parse(value));
                            break;
                        }

                        case "buttondouble.png":
                        {
                            NBTTag = new NbtDouble(node.Name, double.Parse(value));
                            break;
                        }

                        case "buttoncompound.png":
                        {
                            NBTTag = new NbtCompound(node.Name);
                            foreach (object c in node.Nodes)
                            {
                                (new AlertForm(c.ToString())).ShowDialog();
                                if (c is TreeNode && ((TreeNode)c).Nodes.Count > 0)
                                {
                                    ((NbtCompound)NBTTag).Add(TreeToNBT(((TreeNode)c).Nodes));
                                }
                                else
                                {
                                    (new AlertForm(c.GetType().ToString())).ShowDialog();
                                }
                            }
                            break;
                        }

                        case "buttonlist.png":
                        {
                            NBTTag = new NbtList(node.Name);
                            foreach (object c in node.Nodes)
                            {
                                (new AlertForm(c.ToString())).ShowDialog();
                                if (c is TreeNode && ((TreeNode)c).Nodes.Count > 0)
                                {
                                    ((NbtList)NBTTag).Add(TreeToNBT(((TreeNode)c).Nodes));
                                }
                                else
                                {
                                    (new AlertForm(c.GetType().ToString())).ShowDialog();
                                }
                            }
                            break;
                        }

                        case "buttonbytearray.png":
                        {
                            NBTTag = new NbtByteArray(node.Name, NodesToByteArray(node.Nodes));
                            (new AlertForm(NBTTag.ToString())).ShowDialog();
                            break;
                        }

                        case "buttonintarray.png":
                        {
                            NBTTag = new NbtIntArray(node.Name, NodesToIntArray(node.Nodes));
                            (new AlertForm(NBTTag.ToString())).ShowDialog();
                            break;
                        }

                        default:
                        {
                            throw new WarningException($"Warning: unhandeled node {node.ImageKey} can not be edited");
                        }
                        }
                    }
                    catch (Exception exception)
                    {
                        if (exception is InvalidOperationException || exception is WarningException)
                        {
                            new AlertForm(exception.ToString())
                            {
                                Text = "Warning!",
                                Icon = System.Drawing.SystemIcons.Warning
                            }.ShowDialog();
                        }
                        else
                        {
                            new AlertForm(exception.ToString())
                            {
                                Text = exception.GetType().ToString(),
                                Icon = System.Drawing.SystemIcons.Error
                            }.ShowDialog();
                        }
                    }
                }
            }
            return(NBTTag);
        }
예제 #35
0
 public void Renaming()
 {
     NbtCompound compound = new NbtCompound();
     compound.Add( new NbtInt( "SameName", 1 ) );
     var tagToRename = new NbtInt( "DifferentName", 1 );
     compound.Add( tagToRename );
     Assert.DoesNotThrow( () => tagToRename.Name = "SomeOtherName" );
     Assert.Throws<ArgumentException>( () => tagToRename.Name = "SameName" );
     Assert.Throws<ArgumentNullException>( () => tagToRename.Name = null );
 }
예제 #36
0
파일: ListTests.cs 프로젝트: fragmer/fNbt
        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);
        }
예제 #37
0
        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;

            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);
                        }
                    }
                }

                //NbtList tileTicks = dataTag["TileTicks"] as NbtList;

                chunk.isDirty = false;
                return(chunk);
            }
        }
예제 #38
0
		public void Write_IntTag()
		{
			// Arrange
			MemoryStream stream = new MemoryStream();
			NbtWriter writer = new NbtWriter(stream);
			NbtInt tag = new NbtInt("asdf", 305419896);
			byte[] expected = new byte[] { 0x03, 0x00, 0x04, 0x61, 0x73, 0x64, 0x66, 0x12, 0x34, 0x56, 0x78 };

			// Act
			writer.Write(tag);
			byte[] result = stream.ToArray();

			// Assert
			CollectionAssert.AreEqual(expected, result);
		}
예제 #39
0
        public void SetPropertyValue <T>(NbtTag tag, Expression <Func <T> > property, bool upperFirst = true)
        {
            var propertyInfo = ((MemberExpression)property.Body).Member as PropertyInfo;

            if (propertyInfo == null)
            {
                throw new ArgumentException("The lambda expression 'property' should point to a valid Property");
            }

            NbtTag nbtTag = tag[propertyInfo.Name];

            if (nbtTag == null)
            {
                nbtTag = tag[LowercaseFirst(propertyInfo.Name)];
            }

            if (nbtTag == null)
            {
                if (propertyInfo.PropertyType == typeof(bool))
                {
                    nbtTag = new NbtByte(propertyInfo.Name);
                }
                else if (propertyInfo.PropertyType == typeof(byte))
                {
                    nbtTag = new NbtByte(LowercaseFirst(propertyInfo.Name));
                }
                else if (propertyInfo.PropertyType == typeof(short))
                {
                    nbtTag = new NbtShort(LowercaseFirst(propertyInfo.Name));
                }
                else if (propertyInfo.PropertyType == typeof(int))
                {
                    nbtTag = new NbtInt(LowercaseFirst(propertyInfo.Name));
                }
                else if (propertyInfo.PropertyType == typeof(long))
                {
                    nbtTag = new NbtLong(LowercaseFirst(propertyInfo.Name));
                }
                else if (propertyInfo.PropertyType == typeof(float))
                {
                    nbtTag = new NbtFloat(LowercaseFirst(propertyInfo.Name));
                }
                else if (propertyInfo.PropertyType == typeof(double))
                {
                    nbtTag = new NbtDouble(LowercaseFirst(propertyInfo.Name));
                }
                else if (propertyInfo.PropertyType == typeof(string))
                {
                    nbtTag = new NbtString(LowercaseFirst(propertyInfo.Name), "");
                }
                else
                {
                    return;
                }
            }

            var mex    = property.Body as MemberExpression;
            var target = Expression.Lambda(mex.Expression).Compile().DynamicInvoke();

            switch (nbtTag.TagType)
            {
            case NbtTagType.Unknown:
                break;

            case NbtTagType.End:
                break;

            case NbtTagType.Byte:
                if (propertyInfo.PropertyType == typeof(bool))
                {
                    tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)((bool)propertyInfo.GetValue(target) ? 1 : 0));
                }
                else
                {
                    tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)propertyInfo.GetValue(target));
                }
                break;

            case NbtTagType.Short:
                tag[nbtTag.Name] = new NbtShort(nbtTag.Name, (short)propertyInfo.GetValue(target));
                break;

            case NbtTagType.Int:
                if (propertyInfo.PropertyType == typeof(bool))
                {
                    tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (bool)propertyInfo.GetValue(target) ? 1 : 0);
                }
                else
                {
                    tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (int)propertyInfo.GetValue(target));
                }
                break;

            case NbtTagType.Long:
                tag[nbtTag.Name] = new NbtLong(nbtTag.Name, (long)propertyInfo.GetValue(target));
                break;

            case NbtTagType.Float:
                tag[nbtTag.Name] = new NbtFloat(nbtTag.Name, (float)propertyInfo.GetValue(target));
                break;

            case NbtTagType.Double:
                tag[nbtTag.Name] = new NbtDouble(nbtTag.Name, (double)propertyInfo.GetValue(target));
                break;

            case NbtTagType.ByteArray:
                tag[nbtTag.Name] = new NbtByteArray(nbtTag.Name, (byte[])propertyInfo.GetValue(target));
                break;

            case NbtTagType.String:
                tag[nbtTag.Name] = new NbtString(nbtTag.Name, (string)propertyInfo.GetValue(target) ?? "");
                break;

            case NbtTagType.List:
                break;

            case NbtTagType.Compound:
                break;

            case NbtTagType.IntArray:
                tag[nbtTag.Name] = new NbtIntArray(nbtTag.Name, (int[])propertyInfo.GetValue(target));
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            //return (T) propertyInfo.GetValue(target);
        }
예제 #40
0
파일: BlockFactory.cs 프로젝트: sccGg/MiNET
        static BlockFactory()
        {
            for (int i = 0; i < byte.MaxValue * 2; i++)
            {
                var block = GetBlockById(i);
                if (block != null)
                {
                    if (block.IsTransparent)
                    {
                        TransparentBlocks[block.Id] = 1;
                    }
                    if (block.LightLevel > 0)
                    {
                        LuminousBlocks[block.Id] = (byte)block.LightLevel;
                    }
                }
            }

            NameToId = BuildNameToId();

            for (int i = 0; i < LegacyToRuntimeId.Length; ++i)
            {
                LegacyToRuntimeId[i] = -1;
            }

            var assembly = Assembly.GetAssembly(typeof(Block));

            lock (lockObj)
            {
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        BlockPalette = BlockPalette.FromJson(reader.ReadToEnd());
                    }

                foreach (var record in BlockPalette)
                {
                    var states = new List <NbtTag>();
                    foreach (IBlockState state in record.States)
                    {
                        NbtTag stateTag = null;
                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                            stateTag = new NbtByte(state.Name, blockStateByte.Value);
                            break;

                        case BlockStateInt blockStateInt:
                            stateTag = new NbtInt(state.Name, blockStateInt.Value);
                            break;

                        case BlockStateString blockStateString:
                            stateTag = new NbtString(state.Name, blockStateString.Value);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                        states.Add(stateTag);
                    }

                    var nbt = new NbtFile()
                    {
                        BigEndian = false,
                        UseVarInt = true,
                        RootTag   = new NbtCompound("states", states)
                    };

                    byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None);

                    record.StatesCacheNbt = nbtBinary;
                }
            }
            int palletSize = BlockPalette.Count;

            for (int i = 0; i < palletSize; i++)
            {
                if (BlockPalette[i].Data > 15)
                {
                    continue;                                            // TODO: figure out why palette contains blocks with meta more than 15
                }
                if (BlockPalette[i].Data == -1)
                {
                    continue;                                             // These are blockstates that does not have a metadata mapping
                }
                LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i;
            }

            BlockStates = new HashSet <BlockStateContainer>(BlockPalette);
        }
예제 #41
-1
        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 ) );
        }