Пример #1
0
        public void ChangingListTagType()
        {
            var list = new NbtList();

            // changing list type to an out-of-range type
            Assert.Throws<ArgumentOutOfRangeException>(() => list.ListType = (NbtTagType)200);

            // failing to add or insert a tag should not change ListType
            Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, new NbtInt()));
            Assert.Throws<ArgumentException>(() => list.Add(new NbtInt("namedTagWhereUnnamedIsExpected")));
            Assert.AreEqual(NbtTagType.Unknown, list.ListType);

            // changing the type of an empty list to "End" is allowed, see https://github.com/fragmer/fNbt/issues/12
            Assert.DoesNotThrow(() => list.ListType = NbtTagType.End);
            Assert.AreEqual(list.ListType, NbtTagType.End);

            // changing the type of an empty list back to "Unknown" is allowed too!
            Assert.DoesNotThrow(() => list.ListType = NbtTagType.Unknown);
            Assert.AreEqual(list.ListType, NbtTagType.Unknown);

            // adding the first element should set the tag type
            list.Add(new NbtInt());
            Assert.AreEqual(list.ListType, NbtTagType.Int);

            // setting correct type for a non-empty list
            Assert.DoesNotThrow(() => list.ListType = NbtTagType.Int);

            // changing list type to an incorrect type
            Assert.Throws<ArgumentException>(() => list.ListType = NbtTagType.Short);

            // after the list is cleared, we should once again be allowed to change its TagType
            list.Clear();
            Assert.DoesNotThrow(() => list.ListType = NbtTagType.Short);
        }
Пример #2
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]);
        }
Пример #3
0
        public void IndexerTest()
        {
            var secondList = new NbtList {
                new NbtByte()
            };

            var testList = new NbtList();
            // Trying to set an out-of-range element
            Assert.Throws<ArgumentOutOfRangeException>(() => testList[0] = new NbtByte(1));

            // Make sure that setting did not affect ListType
            Assert.AreEqual(testList.ListType, NbtTagType.Unknown);
            Assert.AreEqual(testList.Count, 0);
            testList.Add(new NbtByte(1));

            // set a tag to null
            Assert.Throws<ArgumentNullException>(() => testList[0] = null);

            // set a tag to itself
            Assert.Throws<ArgumentException>(() => testList[0] = testList);

            // give a named tag where an unnamed tag was expected
            Assert.Throws<ArgumentException>(() => testList[0] = new NbtByte("NamedTag"));

            // give an unnamed tag that already has a parent
            Assert.Throws<ArgumentException>(() => testList[0] = secondList[0]);
        }
Пример #4
0
        public void ChangingListTagType()
        {
            var list = new NbtList();

            // changing type of an empty list
            Assert.DoesNotThrow( () => list.ListType = NbtTagType.Unknown );

            list.Add( new NbtInt() );

            // setting correct type for a non-empty list
            Assert.DoesNotThrow( () => list.ListType = NbtTagType.Int );

            // changing list type to an incorrect type
            Assert.Throws<ArgumentException>( () => list.ListType = NbtTagType.Short );
        }
Пример #5
0
 public void SaveTo(string file)
 {
     var nbt = new NbtFile(file);
     nbt.RootTag = new NbtCompound("");
     var list = new NbtList("servers", NbtTagType.Compound);
     foreach (var server in Servers)
     {
         var compound = new NbtCompound();
         compound.Add(new NbtString("name", server.Name));
         compound.Add(new NbtString("ip", server.Ip));
         compound.Add(new NbtByte("hideAddress", (byte)(server.HideAddress ? 1 : 0)));
         compound.Add(new NbtByte("acceptTextures", (byte)(server.AcceptTextures ? 1 : 0)));
         list.Add(compound);
     }
     nbt.RootTag.Add(list);
     nbt.SaveToFile(file, NbtCompression.None);
 }
		public override void SetCompound(NbtCompound compound)
		{
			Compound = compound;

			if (Compound["Items"] == null)
			{
				NbtList items = new NbtList("Items");
				for (byte i = 0; i < 2; i++)
				{
					items.Add(new NbtCompound()
					{
						new NbtByte("Count", 0),
						new NbtByte("Slot", i),
						new NbtShort("id", 0),
						new NbtByte("Damage", 0),
					});
				}
				Compound["Items"] = items;
			}
		}
Пример #7
0
        public NbtTag Serialize(string tagName)
        {
            var chunk    = (NbtCompound)Serializer.Serialize(this, tagName, true);
            var entities = new NbtList("Entities", NbtTagType.Compound);

            for (int i = 0; i < Entities.Count; i++)
            {
                entities.Add(Entities[i].Serialize(string.Empty));
            }
            chunk.Add(entities);
            var sections   = new NbtList("Sections", NbtTagType.Compound);
            var serializer = new NbtSerializer(typeof(Section));

            for (int i = 0; i < Sections.Length; i++)
            {
                if (!Sections[i].IsAir)
                {
                    sections.Add(serializer.Serialize(Sections[i]));
                }
            }
            chunk.Add(sections);
            return(chunk);
        }
Пример #8
0
        NbtTag HandleArray([CanBeNull] string tagName, [CanBeNull] Array value, [NotNull] PropertyInfo pinfo)
        {
            if (pinfo == null)
            {
                throw new ArgumentNullException("pinfo");
            }

            if (value == null)
            {
                NullPolicy np = GetNullPolicy(pinfo);
                switch (np)
                {
                case NullPolicy.Ignore:
                    return(null);

                case NullPolicy.InsertDefault:
                    return(MakeEmptyList(tagName, pinfo.PropertyType.GetElementType()));

                default:
                    throw MakeNullException(pinfo);
                }
            }

            if (value.Length == 0)
            {
                return(MakeEmptyList(tagName, pinfo.PropertyType.GetElementType()));
            }

            NullPolicy elementNullPolicy = GetElementNullPolicy(pinfo);
            NbtList    newList           = new NbtList(tagName);

            for (int i = 0; i < value.Length; i++)
            {
                newList.Add(HandleElement(null, value.GetValue(i), elementNullPolicy));
            }
            return(newList);
        }
Пример #9
0
        NbtTag HandleIListInner <T>([CanBeNull] string tagName, PropertyInfo pinfo, List <T> value)
        {
            Type elementType = typeof(T);

            if (value == null)
            {
                NullPolicy np = GetNullPolicy(pinfo);
                switch (np)
                {
                case NullPolicy.Ignore:
                    return(null);

                case NullPolicy.InsertDefault:
                    return(MakeEmptyList(tagName, elementType));

                default:
                    throw MakeNullException(pinfo);
                }
            }

            // Get list length
            int count = value.Count;

            if (count == 0)
            {
                return(MakeEmptyList(tagName, elementType));
            }

            NullPolicy elementNullPolicy = GetElementNullPolicy(pinfo);
            NbtList    newList           = new NbtList(tagName);

            foreach (T element in value)
            {
                newList.Add(HandleElement(null, element, elementNullPolicy));
            }
            return(newList);
        }
Пример #10
0
        public void NestedListAndCompoundTest()
        {
            byte[] data;
            {
                var root          = new NbtCompound("Root");
                var outerList     = new NbtList("OuterList", NbtTagType.Compound);
                var outerCompound = new NbtCompound();
                var innerList     = new NbtList("InnerList", NbtTagType.Compound);
                var innerCompound = new NbtCompound();

                innerList.Add(innerCompound);
                outerCompound.Add(innerList);
                outerList.Add(outerCompound);
                root.Add(outerList);

                var file = new NbtFile(root);
                data = file.SaveToBuffer(NbtCompression.None);
            }
            {
                var  file      = new NbtFile();
                long bytesRead = file.LoadFromBuffer(data, 0, data.Length, NbtCompression.None);
                Assert.AreEqual(bytesRead, data.Length);
                Assert.AreEqual(1, file.RootTag.Get <NbtList>("OuterList").Count);
                Assert.AreEqual(null, file.RootTag.Get <NbtList>("OuterList").Get <NbtCompound>(0).Name);
                Assert.AreEqual(1,
                                file.RootTag.Get <NbtList>("OuterList")
                                .Get <NbtCompound>(0)
                                .Get <NbtList>("InnerList")
                                .Count);
                Assert.AreEqual(null,
                                file.RootTag.Get <NbtList>("OuterList")
                                .Get <NbtCompound>(0)
                                .Get <NbtList>("InnerList")
                                .Get <NbtCompound>(0)
                                .Name);
            }
        }
Пример #11
0
        public ChestBlockEntity() : base("Chest")
        {
            Compound = new NbtCompound(string.Empty)
            {
                new NbtString("id", Id),
                new NbtList("Items", new NbtCompound()),
                new NbtInt("x", Coordinates.X),
                new NbtInt("y", Coordinates.Y),
                new NbtInt("z", Coordinates.Z)
            };

            NbtList items = (NbtList)Compound["Items"];

            for (byte i = 0; i < 27; i++)
            {
                items.Add(new NbtCompound
                {
                    new NbtByte("Slot", i),
                    new NbtShort("id", 0),
                    new NbtByte("Damage", 0),
                    new NbtByte("Count", 0),
                });
            }
        }
Пример #12
0
        public void Save()
        {
            NbtCompound root = new NbtCompound("base");
            root.Add(new NbtString("fileType", "map"));

            NbtList aList = new NbtList("areas", NbtTagType.Compound);
            foreach(Area alpha in areas) {
                aList.Add(alpha.Save());
            }
            root.Add(aList);

            NbtFile saveFile = new NbtFile(root);
            saveFile.BigEndian = true;
            saveFile.SaveToFile("mapfile.nbt", NbtCompression.None);
        }
Пример #13
0
        public static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk)
        {
            var nbt = new NbtFile();

            NbtCompound levelTag = new NbtCompound("Level");

            nbt.RootTag.Add(levelTag);

            levelTag.Add(new NbtByte("MCPE BID", 1));             // Indicate that the chunks contain PE block ID's.

            levelTag.Add(new NbtInt("xPos", chunk.x));
            levelTag.Add(new NbtInt("zPos", chunk.z));
            levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId));

            NbtList sectionsTag = new NbtList("Sections", NbtTagType.Compound);

            levelTag.Add(sectionsTag);

            for (int i = 0; i < 16; i++)
            {
                var section = chunk.chunks[i];
                if (section.IsAllAir())
                {
                    continue;
                }

                NbtCompound sectionTag = new NbtCompound();
                sectionsTag.Add(sectionTag);
                sectionTag.Add(new NbtByte("Y", (byte)i));

                byte[] blocks     = new byte[4096];
                byte[] data       = new byte[2048];
                byte[] blockLight = new byte[2048];
                byte[] skyLight   = new byte[2048];

                {
                    for (int x = 0; x < 16; x++)
                    {
                        for (int z = 0; z < 16; z++)
                        {
                            for (int y = 0; y < 16; y++)
                            {
                                int  anvilIndex = y * 16 * 16 + z * 16 + x;
                                byte blockId    = section.GetBlock(x, y, z);
                                blocks[anvilIndex] = blockId;
                                SetNibble4(data, anvilIndex, section.GetMetadata(x, y, z));
                                SetNibble4(blockLight, anvilIndex, section.GetBlocklight(x, y, z));
                                SetNibble4(skyLight, anvilIndex, section.GetSkylight(x, y, z));
                            }
                        }
                    }
                }
                sectionTag.Add(new NbtByteArray("Blocks", blocks));
                sectionTag.Add(new NbtByteArray("Data", data));
                sectionTag.Add(new NbtByteArray("BlockLight", blockLight));
                sectionTag.Add(new NbtByteArray("SkyLight", skyLight));
            }

            int[] heights = new int[256];
            for (int h = 0; h < heights.Length; h++)
            {
                heights[h] = chunk.height[h];
            }
            levelTag.Add(new NbtIntArray("HeightMap", heights));

            // TODO: Save entities
            NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound);

            //foreach(var entity in )
            levelTag.Add(entitiesTag);

            NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound);

            foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values)
            {
                NbtCompound nbtClone = (NbtCompound)blockEntityNbt.Clone();
                nbtClone.Name = null;
                blockEntitiesTag.Add(nbtClone);
            }

            levelTag.Add(blockEntitiesTag);

            levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound));

            return(nbt);
        }
Пример #14
0
        public NbtTag Serialize(string tagName)
        {
            var chunk = new NbtCompound(tagName);
            var entities = new NbtList("Entities", NbtTagType.Compound);
            chunk.Add(entities);
            chunk.Add(new NbtInt("X", X));
            chunk.Add(new NbtInt("Z", Z));
            chunk.Add(new NbtByteArray("Blocks", Blocks));
            chunk.Add(new NbtByteArray("Data", Metadata.Data));
            chunk.Add(new NbtByteArray("SkyLight", SkyLight.Data));
            chunk.Add(new NbtByteArray("BlockLight", BlockLight.Data));

            var tiles = new NbtList("TileEntities", NbtTagType.Compound);
            foreach (var kvp in TileEntities)
            {
                var c = new NbtCompound();
                c.Add(new NbtList("coordinates", new[] {
                    new NbtInt(kvp.Key.X),
                    new NbtInt(kvp.Key.Y),
                    new NbtInt(kvp.Key.Z)
                 }));
                 c.Add(new NbtList("value", new[] { kvp.Value }));
                 tiles.Add(c);
            }
            chunk.Add(tiles);

            // TODO: Entities
            return chunk;
        }
Пример #15
0
        public void ManipulatingList()
        {
            var sameTags = new NbtTag[] {
                new NbtInt(0),
                new NbtInt(1),
                new NbtInt(2)
            };

            var list = new NbtList("Test1", sameTags);

            // testing enumerator, indexer, Contains, and IndexOf
            int j = 0;
            foreach (NbtTag tag in list) {
                Assert.IsTrue(list.Contains(sameTags[j]));
                Assert.AreEqual(sameTags[j], tag);
                Assert.AreEqual(j, list.IndexOf(tag));
                j++;
            }

            // adding an item of correct type
            list.Add(new NbtInt(3));
            list.Insert(3, new NbtInt(4));

            // adding an item of wrong type
            Assert.Throws<ArgumentException>(() => list.Add(new NbtString()));
            Assert.Throws<ArgumentException>(() => list.Insert(3, new NbtString()));
            Assert.Throws<ArgumentNullException>(() => list.Insert(3, null));

            // testing array contents
            for (int i = 0; i < sameTags.Length; i++) {
                Assert.AreSame(sameTags[i], list[i]);
                Assert.AreEqual(i, ((NbtInt)list[i]).Value);
            }

            // test removal
            Assert.IsFalse(list.Remove(new NbtInt(5)));
            Assert.IsTrue(list.Remove(sameTags[0]));
            Assert.Throws<ArgumentNullException>(() => list.Remove(null));
            list.RemoveAt(0);
            Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(10));

            // Test some failure scenarios for Add:
            // adding a list to itself
            var loopList = new NbtList();
            Assert.AreEqual(NbtTagType.Unknown, loopList.ListType);
            Assert.Throws<ArgumentException>(() => loopList.Add(loopList));

            // adding same tag to multiple lists
            Assert.Throws<ArgumentException>(() => loopList.Add(list[0]));
            Assert.Throws<ArgumentException>(() => loopList.Insert(0, list[0]));

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

            // make sure that all those failed adds didn't affect the tag
            Assert.AreEqual(0, loopList.Count);
            Assert.AreEqual(NbtTagType.Unknown, loopList.ListType);

            // try creating a list with invalid tag type
            Assert.Throws<ArgumentOutOfRangeException>(() => new NbtList((NbtTagType)200));
        }
Пример #16
0
        private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset)
        {
            var nbt = new NbtFile();

            NbtCompound levelTag = new NbtCompound("Level");
            nbt.RootTag.Add(levelTag);

            levelTag.Add(new NbtInt("xPos", chunk.x));
            levelTag.Add(new NbtInt("zPos", chunk.z));
            levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId));

            NbtList sectionsTag = new NbtList("Sections");
            levelTag.Add(sectionsTag);

            for (int i = 0; i < 8; i++)
            {
                NbtCompound sectionTag = new NbtCompound();
                sectionsTag.Add(sectionTag);
                sectionTag.Add(new NbtByte("Y", (byte) i));
                int sy = i*16;

                byte[] blocks = new byte[4096];
                byte[] data = new byte[2048];
                byte[] blockLight = new byte[2048];
                byte[] skyLight = new byte[2048];

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int y = 0; y < 16; y++)
                        {
                            int yi = sy + y;
                            if (yi < 0 || yi >= 256) continue; // ?

                            int anvilIndex = (y + yoffset)*16*16 + z*16 + x;
                            byte blockId = chunk.GetBlock(x, yi, z);

                            // PE to Anvil friendly converstion
                            if (blockId == 5) blockId = 125;
                            else if (blockId == 158) blockId = 126;
                            else if (blockId == 50) blockId = 75;
                            else if (blockId == 50) blockId = 76;
                            else if (blockId == 89) blockId = 123;
                            else if (blockId == 89) blockId = 124;
                            else if (blockId == 73) blockId = 152;

                            blocks[anvilIndex] = blockId;
                            SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z));
                            SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z));
                            SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z));
                        }
                    }
                }

                sectionTag.Add(new NbtByteArray("Blocks", blocks));
                sectionTag.Add(new NbtByteArray("Data", data));
                sectionTag.Add(new NbtByteArray("BlockLight", blockLight));
                sectionTag.Add(new NbtByteArray("SkyLight", skyLight));
            }

            // TODO: Save entities
            NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound);
            levelTag.Add(entitiesTag);

            NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound);
            levelTag.Add(blockEntitiesTag);
            foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values)
            {
                NbtCompound nbtClone = (NbtCompound) blockEntityNbt.Clone();
                nbtClone.Name = null;
                blockEntitiesTag.Add(nbtClone);
            }

            levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound));

            return nbt;
        }
Пример #17
0
		private NbtList GetSlots()
		{
			NbtList slots = new NbtList("Items");
			for (byte i = 0; i < Size; i++)
			{
				MetadataSlot slot = (MetadataSlot) Slots[i];
				slots.Add(new NbtCompound
				{
					new NbtByte("Count", slot.Value.Count),
					new NbtByte("Slot", i),
					new NbtShort("id", slot.Value.Id),
					new NbtByte("Damage", (byte) slot.Value.Metadata),
				});
			}

			return slots;
		}
Пример #18
0
        public void SavePlayer(PlayerEntity entity)
        {
            // TODO: Generalize to all mobs
            NbtFile file = new NbtFile();
            var data = new NbtCompound();
            data.Add(new NbtByte("OnGround", (byte)(entity.OnGround ? 1 : 0)));
            data.Add(new NbtShort("Air", entity.Air));
            data.Add(new NbtShort("Health", entity.Health));
            data.Add(new NbtInt("Dimension", 0)); // TODO
            data.Add(new NbtInt("foodLevel", entity.Food));
            data.Add(new NbtInt("XpLevel", entity.XpLevel));
            data.Add(new NbtInt("XpTotal", entity.XpTotal));
            data.Add(new NbtFloat("foodExhaustionLevel", entity.FoodExhaustion));
            data.Add(new NbtFloat("foodSaturationLevel", entity.FoodSaturation));
            data.Add(new NbtFloat("XpP", entity.XpProgress));
            data.Add(new NbtList("Equipment"));
            var inventory = new NbtList("Inventory");
            for (int index = 0; index < entity.Inventory.Length; index++)
            {
                var slot = entity.Inventory[index];
                if (slot.Empty)
                    continue;
                slot.Index = NetworkSlotToDataSlot(index);
                inventory.Add(slot.ToNbt());
            }
            data.Add(inventory);
            var motion = new NbtList("Motion");
            motion.Add(new NbtDouble(entity.Velocity.X));
            motion.Add(new NbtDouble(entity.Velocity.Y));
            motion.Add(new NbtDouble(entity.Velocity.Z));
            data.Add(motion);

            var pos = new NbtList("Pos");
            pos.Add(new NbtDouble(entity.Position.X));
            pos.Add(new NbtDouble(entity.Position.Y));
            pos.Add(new NbtDouble(entity.Position.Z));
            data.Add(pos);

            var rotation = new NbtList("Rotation");
            rotation.Add(new NbtFloat(entity.Yaw));
            rotation.Add(new NbtFloat(entity.Pitch));
            data.Add(rotation);

            data.Add(new NbtCompound("abilities"));

            file.RootTag = data;
            if (!Directory.Exists(Path.Combine(LevelDirectory, "players")))
                Directory.CreateDirectory(Path.Combine(LevelDirectory, "players"));
            using (Stream stream = File.Open(Path.Combine(LevelDirectory, "players", entity.Username + ".dat"), FileMode.OpenOrCreate))
                file.SaveToStream(stream, NbtCompression.GZip);
        }
Пример #19
0
        private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset)
        {
            var nbt = new NbtFile();

            var levelTag = new NbtCompound("Level");
            nbt.RootTag.Add(levelTag);

            levelTag.Add(new NbtInt("xPos", chunk.X));
            levelTag.Add(new NbtInt("zPos", chunk.Z));
            levelTag.Add(new NbtByteArray("Biomes", chunk.BiomeId));

            var sectionsTag = new NbtList("Sections");
            levelTag.Add(sectionsTag);

            for (var i = 0; i < 8; i++)
            {
                var sectionTag = new NbtCompound();
                sectionsTag.Add(sectionTag);
                sectionTag.Add(new NbtByte("Y", (byte) i));
                var sy = i*16;

                var blocks = new byte[4096];
                var data = new byte[2048];
                var blockLight = new byte[2048];
                var skyLight = new byte[2048];

                for (var x = 0; x < 16; x++)
                {
                    for (var z = 0; z < 16; z++)
                    {
                        for (var y = 0; y < 16; y++)
                        {
                            var yi = sy + y;
                            if (yi < 0 || yi >= 256) continue; // ?

                            var anvilIndex = (y + yoffset)*16*16 + z*16 + x;
                            var blockId = chunk.GetBlock(x, yi, z);

                            blocks[anvilIndex] = (byte) blockId;
                            SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z));
                            SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z));
                            SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z));
                        }
                    }
                }

                sectionTag.Add(new NbtByteArray("Blocks", blocks));
                sectionTag.Add(new NbtByteArray("Data", data));
                sectionTag.Add(new NbtByteArray("BlockLight", blockLight));
                sectionTag.Add(new NbtByteArray("SkyLight", skyLight));
            }

            levelTag.Add(new NbtList("Entities", NbtTagType.Compound));
            levelTag.Add(new NbtList("TileEntities", NbtTagType.Compound));
            levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound));

            return nbt;
        }
Пример #20
0
        public void Save(string p)
        {
            var myFile = new NbtFile();

            var root = myFile.RootTag;
            root.Name = "Schematic";

            root.Add(new NbtShort("Height", Height));
            root.Add(new NbtShort("Length", Length));
            root.Add(new NbtShort("Width", Width));

            var nbttile = new NbtList("TileEntities", NbtTagType.Compound);
            var size = Width * Height * Length;
            _data = new byte[size];
            _blocks = new byte[size];

            for (int y = 0; y < Height; y++)
            {
                for (int z = 0; z < Length; z++)
                {
                    for (int x = 0; x < Width; x++)
                    {
                        var d = GetBlock(x, y, z);
                        _blocks[(y * Length + z) * Width + x] = (byte)d.ID;
                        _data[(y * Length + z) * Width + x] = (byte)(d.Metta & 0x0F);

                        if (d.Command != null)
                        {
                            var nbtc = new NbtCompound();
                            nbtc.Add(new NbtString("CustomName", "LuaBlock"));
                            nbtc.Add(new NbtString("Command", d.Command));
                            nbtc.Add(new NbtString("id", "Control"));
                            nbtc.Add(new NbtInt("x", x));
                            nbtc.Add(new NbtInt("y", y));
                            nbtc.Add(new NbtInt("z", z));

                            nbttile.Add(nbtc);
                        }
                    }
                }
            }
            root.Add(new NbtList("Entities", NbtTagType.Byte));
            root.Add(nbttile);
            root.Add(new NbtList("TileTicks", NbtTagType.Byte));

            root.Add(new NbtString("Materials", "Alpha"));

            root.Add(new NbtByteArray("Data", _data));
             //   root.Add(new NbtByteArray("Biomes", new byte[Width * Length]));
            root.Add(new NbtByteArray("Blocks", _blocks));

            myFile.SaveToFile(p, NbtCompression.None);
        }
Пример #21
0
    public static NbtCompound ToNbt(this ItemStack?value)
    {
        value ??= new ItemStack(0, 0)
        {
            Present = true
        };

        var item = value.AsItem();

        var compound = new NbtCompound
        {
            new NbtTag <string>("id", item.UnlocalizedName),
            new NbtTag <byte>("Count", (byte)value.Count),
            new NbtTag <byte>("Slot", (byte)value.Slot)
        };

        ItemMeta meta = value.ItemMeta;

        if (meta.HasTags())
        {
            compound.Add(new NbtTag <bool>("Unbreakable", meta.Unbreakable));

            if (meta.Durability > 0)
            {
                compound.Add(new NbtTag <int>("Damage", meta.Durability));
            }

            if (meta.CustomModelData > 0)
            {
                compound.Add(new NbtTag <int>("CustomModelData", meta.CustomModelData));
            }

            if (meta.CanDestroy is not null)
            {
                var list = new NbtList(NbtTagType.String, "CanDestroy");

                foreach (var block in meta.CanDestroy)
                {
                    list.Add(new NbtTag <string>(string.Empty, block));
                }

                compound.Add(list);
            }

            if (meta.Name is not null)
            {
                var displayCompound = new NbtCompound("display")
                {
                    new NbtTag <string>("Name", new List <ChatMessage> {
                        meta.Name
                    }.ToJson())
                };

                if (meta.Lore is not null)
                {
                    var list = new NbtList(NbtTagType.String, "Lore");

                    foreach (var lore in meta.Lore)
                    {
                        list.Add(new NbtTag <string>(string.Empty, new List <ChatMessage> {
                            lore
                        }.ToJson()));
                    }

                    displayCompound.Add(list);
                }

                compound.Add(displayCompound);
            }
            else if (meta.Lore is not null)
            {
                var displayCompound = new NbtCompound("display")
                {
                    new NbtTag <string>("Name", new List <ChatMessage> {
                        meta.Name
                    }.ToJson())
                };

                var list = new NbtList(NbtTagType.String, "Lore");

                foreach (var lore in meta.Lore)
                {
                    list.Add(new NbtTag <string>(string.Empty, new List <ChatMessage> {
                        lore
                    }.ToJson()));
                }

                displayCompound.Add(list);

                compound.Add(displayCompound);
            }
        }

        return(compound);
    }
        public static NbtCompound ExportReactor()
        {
            NbtCompound reactor        = new NbtCompound("Schematic");
            bool        coolerIsActive = false;
            int         volume         = (int)(Reactor.interiorDims.X * Reactor.interiorDims.Y * Reactor.interiorDims.Z);

            byte[] blocks = new byte[volume];
            byte[] data   = new byte[volume];
            bool   extra  = false;

            byte[]  extraBlocks                 = new byte[volume];
            byte[]  extraBlocksNibble           = new byte[(int)Math.Ceiling(volume / 2.0)];
            NbtList tileEntities                = new NbtList("TileEntities", NbtTagType.Compound);
            Dictionary <string, short> mappings = new Dictionary <string, short>();

            for (int y = 1; y <= Reactor.interiorDims.Y; y++)
            {
                for (int z = 1; z <= Reactor.interiorDims.Z; z++)
                {
                    for (int x = 1; x <= Reactor.interiorDims.X; x++)
                    {
                        coolerIsActive = false;
                        Block block = Reactor.BlockAt(new Point3D(x, y, z));
                        int   index = (int)((x - 1) + ((y - 1) * Reactor.interiorDims.Z + (z - 1)) * Reactor.interiorDims.X);
                        blocks[index] = (byte)BlockIDLookup[block.BlockType];
                        if (block.BlockType == BlockTypes.FuelCell | block.BlockType == BlockTypes.Air)
                        {
                            data[index] = 0;
                        }
                        else if (block is Cooler cooler)
                        {
                            if (cooler.Active)
                            {
                                coolerIsActive = true;
                                blocks[index]  = 340 - 256;
                                data[index]    = 0;
                                tileEntities.Add(CreateActiveCooler(x - 1, y - 1, z - 1));
                            }
                            else
                            {
                                data[index] = (byte)BlockMetaLookup[cooler.CoolerType.ToString()];
                            }
                        }
                        else if (block.BlockType == BlockTypes.Moderator)
                        {
                            data[index] = (byte)BlockMetaLookup[((Moderator)block).ModeratorType.ToString()];
                        }

                        if (coolerIsActive)
                        {
                            extraBlocks[index] = (byte)(340 >> 8);
                            extra = true;
                        }
                        else
                        if ((extraBlocks[index] = (byte)(BlockIDLookup[block.BlockType] >> 8)) > 0)
                        {
                            if (block.BlockType == BlockTypes.Air)
                            {
                                continue;
                            }
                        }
                        if (coolerIsActive)
                        {
                            if (!mappings.ContainsKey("nuclearcraft:active_cooler"))
                            {
                                mappings.Add("nuclearcraft:active_cooler", 340);
                            }
                            else
                            if (!mappings.ContainsKey(SchematicaMappingLookup[block.BlockType]))
                            {
                                mappings.Add(SchematicaMappingLookup[block.BlockType], (short)BlockIDLookup[block.BlockType]);
                            }
                        }
                    }
                }
            }

            for (int i = 0; i < extraBlocksNibble.Length; i++)
            {
                if (i * 2 + 1 < extraBlocks.Length)
                {
                    extraBlocksNibble[i] = (byte)((extraBlocks[i * 2 + 0] << 4) | extraBlocks[i * 2 + 1]);
                }
                else
                {
                    extraBlocksNibble[i] = (byte)(extraBlocks[i * 2 + 0] << 4);
                }
            }

            reactor.Add(new NbtByteArray("Blocks", blocks));
            reactor.Add(new NbtShort("Length", (short)Reactor.interiorDims.Z));
            reactor.Add(new NbtString("Materials", "Alpha"));
            reactor.Add(new NbtShort("Height", (short)Reactor.interiorDims.Y));
            reactor.Add(new NbtByteArray("Data", data));
            reactor.Add(SetIcon());
            NbtCompound mappingsC = new NbtCompound("SchematicaMapping");

            foreach (KeyValuePair <string, short> kvp in mappings)
            {
                mappingsC.Add(new NbtShort(kvp.Key, kvp.Value));
            }
            reactor.Add(mappingsC);
            reactor.Add(new NbtShort("Width", (short)Reactor.interiorDims.X));
            if (extra)
            {
                reactor.Add(new NbtByteArray("AddBlocks", extraBlocksNibble));
            }
            reactor.Add(tileEntities);
            reactor.Add(new NbtList("Entities", NbtTagType.Compound));



            return(reactor);
        }
Пример #23
0
        public void ManipulatingList()
        {
            var sameTags = new NbtTag[] {
                new NbtInt( 0 ),
                new NbtInt( 1 ),
                new NbtInt( 2 )
            };

            NbtList list = new NbtList( "Test1", sameTags );

            // testing enumerator
            int j = 0;
            foreach( NbtTag tag in list ) {
                Assert.AreEqual( tag, sameTags[j++] );
            }

            // adding an item of correct type
            list.Add( new NbtInt( 3 ) );
            list.Insert( 3, new NbtInt( 4 ) );

            // adding an item of wrong type
            Assert.Throws<ArgumentException>( () => list.Add( new NbtString() ) );
            Assert.Throws<ArgumentException>( () => list.Insert( 3, new NbtString() ) );

            // testing array contents
            for( int i = 0; i < sameTags.Length; i++ ) {
                Assert.AreSame( sameTags[i], list[i] );
                Assert.AreEqual( ( (NbtInt)list[i] ).Value, i );
            }

            // test removal
            Assert.IsFalse( list.Remove( new NbtInt( 5 ) ) );
            Assert.IsTrue( list.Remove( sameTags[0] ) );
            list.RemoveAt( 0 );
            Assert.Throws<ArgumentOutOfRangeException>( () => list.RemoveAt( 10 ) );
        }
Пример #24
0
        public override NbtCompound ToNBT()
        {
            NbtCompound c = new NbtCompound();
            Base2NBT(ref c);
            c.Add(new NbtShort("BurnTime",BurnTime));
            c.Add(new NbtShort("CookTime",CookTime));
            NbtList Items = new NbtList("Items");
            for (int i = 0; i < 3; i++)
            {
                if (Slots[i].ID != 0x00)
                {
                    NbtCompound cc = new NbtCompound();

                    cc.Add(new NbtShort("id",Slots[i].ID));
                    cc.Add(new NbtShort("Damage",(short)Slots[i].Damage));
                    cc.Add(new NbtByte("Count",(byte)Slots[i].Count));
                    cc.Add(new NbtByte("Slot", (byte)i));

                    Items.Add(cc);
                }
            }
            c.Add(Items);
            return c;
        }
Пример #25
0
        public NbtCompound writeToNbt(NbtCompound tag, bool deleteEntities)
        {
            tag.Add(new NbtByte("hasDoneGen2", this.hasDoneGen2 ? (byte)1 : (byte)0));
            byte[] blockBytes = new byte[Chunk.BLOCK_COUNT];
            int    i, x, y, z;

            for (i = 0; i < Chunk.BLOCK_COUNT; i++)
            {
                blockBytes[i] = (byte)this.blocks[i].id;
            }
            tag.Add(new NbtByteArray("blocks", blockBytes));
            tag.Add(new NbtByteArray("meta", this.metaData));
            tag.Add(new NbtByteArray("light", this.lightLevel));

            // Tile Entites.
            NbtList list = new NbtList("tileEntities", NbtTagType.Compound);

            foreach (TileEntityBase te in this.tileEntityDict.Values)
            {
                list.Add(te.writeToNbt(new NbtCompound()));
            }
            tag.Add(list);

            // Scheduled ticks.
            list = new NbtList("scheduledTicks", NbtTagType.Compound);
            ScheduledTick tick;

            for (i = 0; i < this.scheduledTicks.Count; i++)
            {
                tick = this.scheduledTicks[i];
                list.Add(this.scheduledTicks[i].writeToNbt());
            }
            tag.Add(list);

            // Entites.
            Entity        entity;
            List <Entity> entitiesInChunk = new List <Entity>();

            for (i = this.world.entityList.Count - 1; i >= 0; i--)
            {
                entity = this.world.entityList[i];
                if (!(entity is EntityPlayer))
                {
                    x = MathHelper.floor((int)entity.transform.position.x / (float)Chunk.SIZE);
                    y = MathHelper.floor((int)entity.transform.position.y / (float)Chunk.SIZE);
                    z = MathHelper.floor((int)entity.transform.position.z / (float)Chunk.SIZE);

                    if (x == this.chunkPos.x && y == this.chunkPos.y && z == this.chunkPos.z)
                    {
                        world.entityList.Remove(entity);
                        entitiesInChunk.Add(entity);
                    }
                }
            }
            NbtList list1 = new NbtList("entities", NbtTagType.Compound);

            for (i = 0; i < entitiesInChunk.Count; i++)
            {
                entity = entitiesInChunk[i];
                list1.Add(entity.writeToNbt(new NbtCompound()));
                if (deleteEntities)
                {
                    GameObject.Destroy(entity.gameObject);
                }
            }
            tag.Add(list1);

            return(tag);
        }
Пример #26
0
    public INbtTag ReadNextTag(bool readName = true)
    {
        var firstType = this.ReadTagType();

        string tagName = "";

        if (readName)
        {
            tagName = this.ReadString();
        }

        switch (firstType)
        {
        case NbtTagType.End:
            return(null);

        case NbtTagType.Byte:
        case NbtTagType.Short:
        case NbtTagType.Int:
        case NbtTagType.Long:
        case NbtTagType.Float:
        case NbtTagType.Double:
        case NbtTagType.String:
        {
            var tag = this.GetCurrentTag(firstType, !readName);

            if (readName)
            {
                tag.Name = tagName;
            }

            return(tag);
        }

        case NbtTagType.List:
            var listType = this.ReadTagType();

            var list = new NbtList(listType, tagName);

            var length = this.ReadInt32();

            if (length < 0)
            {
                throw new InvalidOperationException("Got negative list length.");
            }

            for (var i = 0; i < length; i++)
            {
                list.Add(this.GetCurrentTag(listType, false));
            }

            return(list);

        case NbtTagType.Compound:
            return(this.ReadCompoundTag(tagName));

        case NbtTagType.ByteArray:
            return(this.ReadArray(tagName, firstType));

        case NbtTagType.IntArray:
            return(this.ReadArray(tagName, firstType));

        case NbtTagType.LongArray:
            return(this.ReadArray(tagName, firstType));

        case NbtTagType.Unknown:
            break;

        default:
            break;
        }

        return(null);
    }
Пример #27
0
 public NbtTag Serialize(string tagName)
 {
     var chunk = (NbtCompound)Serializer.Serialize(this, tagName, true);
     var entities = new NbtList("Entities", NbtTagType.Compound);
     for (int i = 0; i < Entities.Count; i++)
         entities.Add(Entities[i].Serialize(string.Empty));
     chunk.Add(entities);
     var sections = new NbtList("Sections", NbtTagType.Compound);
     var serializer = new NbtSerializer(typeof(Section));
     for (int i = 0; i < Sections.Length; i++)
     {
         if (!Sections[i].IsAir)
             sections.Add(serializer.Serialize(Sections[i]));
     }
     chunk.Add(sections);
     return chunk;
 }
Пример #28
0
        public void Serializing1()
        {
            // check the basics of saving/loading
            const NbtTagType expectedListType = NbtTagType.Int;
            const int elements = 10;

            // construct nbt file
            var writtenFile = new NbtFile(new NbtCompound("ListTypeTest"));
            var writtenList = new NbtList("Entities", null, expectedListType);
            for (int i = 0; i < elements; i++) {
                writtenList.Add(new NbtInt(i));
            }
            writtenFile.RootTag.Add(writtenList);

            // test saving
            byte[] data = writtenFile.SaveToBuffer(NbtCompression.None);

            // test loading
            var readFile = new NbtFile();
            long bytesRead = readFile.LoadFromBuffer(data, 0, data.Length, NbtCompression.None);
            Assert.AreEqual(bytesRead, data.Length);

            // check contents of loaded file
            Assert.NotNull(readFile.RootTag);
            Assert.IsInstanceOf<NbtList>(readFile.RootTag["Entities"]);
            var readList = (NbtList)readFile.RootTag["Entities"];
            Assert.AreEqual(writtenList.ListType, readList.ListType);
            Assert.AreEqual(readList.Count, writtenList.Count);

            // check .ToArray
            CollectionAssert.AreEquivalent(readList, readList.ToArray());
            CollectionAssert.AreEquivalent(readList, readList.ToArray<NbtInt>());

            // check contents of loaded list
            for (int i = 0; i < elements; i++) {
                Assert.AreEqual(readList.Get<NbtInt>(i).Value, writtenList.Get<NbtInt>(i).Value);
            }
        }
Пример #29
0
        public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false)
        {
            if (!skipInterfaceCheck && value is INbtSerializable)
            {
                return(((INbtSerializable)value).Serialize(tagName));
            }
            else if (value is NbtTag)
            {
                return((NbtTag)value);
            }
            else if (value is byte)
            {
                return(new NbtByte(tagName, (byte)value));
            }
            else if (value is sbyte)
            {
                return(new NbtByte(tagName, (byte)(sbyte)value));
            }
            else if (value is bool)
            {
                return(new NbtByte(tagName, (byte)((bool)value ? 1 : 0)));
            }
            else if (value is byte[])
            {
                return(new NbtByteArray(tagName, (byte[])value));
            }
            else if (value is double)
            {
                return(new NbtDouble(tagName, (double)value));
            }
            else if (value is float)
            {
                return(new NbtFloat(tagName, (float)value));
            }
            else if (value is int)
            {
                return(new NbtInt(tagName, (int)value));
            }
            else if (value is uint)
            {
                return(new NbtInt(tagName, (int)(uint)value));
            }
            else if (value is int[])
            {
                return(new NbtIntArray(tagName, (int[])value));
            }
            else if (value is long)
            {
                return(new NbtLong(tagName, (long)value));
            }
            else if (value is ulong)
            {
                return(new NbtLong(tagName, (long)(ulong)value));
            }
            else if (value is short)
            {
                return(new NbtShort(tagName, (short)value));
            }
            else if (value is ushort)
            {
                return(new NbtShort(tagName, (short)(ushort)value));
            }
            else if (value is string)
            {
                return(new NbtString(tagName, (string)value));
            }
            else if (value.GetType().IsArray)
            {
                var elementType = value.GetType().GetElementType();
                var array       = value as Array;
                var listType    = NbtTagType.Compound;
                if (elementType == typeof(byte) || elementType == typeof(sbyte))
                {
                    listType = NbtTagType.Byte;
                }
                else if (elementType == typeof(bool))
                {
                    listType = NbtTagType.Byte;
                }
                else if (elementType == typeof(byte[]))
                {
                    listType = NbtTagType.ByteArray;
                }
                else if (elementType == typeof(double))
                {
                    listType = NbtTagType.Double;
                }
                else if (elementType == typeof(float))
                {
                    listType = NbtTagType.Float;
                }
                else if (elementType == typeof(int) || elementType == typeof(uint))
                {
                    listType = NbtTagType.Int;
                }
                else if (elementType == typeof(int[]))
                {
                    listType = NbtTagType.IntArray;
                }
                else if (elementType == typeof(long) || elementType == typeof(ulong))
                {
                    listType = NbtTagType.Long;
                }
                else if (elementType == typeof(short) || elementType == typeof(ushort))
                {
                    listType = NbtTagType.Short;
                }
                else if (elementType == typeof(string))
                {
                    listType = NbtTagType.String;
                }
                var list            = new NbtList(tagName, listType);
                var innerSerializer = new NbtSerializer(elementType);
                for (int i = 0; i < array.Length; i++)
                {
                    list.Add(innerSerializer.Serialize(array.GetValue(i)));
                }
                return(list);
            }
            else if (value is NbtFile)
            {
                return(((NbtFile)value).RootTag);
            }
            else
            {
                var compound = new NbtCompound(tagName);

                if (value == null)
                {
                    return(compound);
                }
                var nameAttributes = Attribute.GetCustomAttributes(value.GetType(), typeof(TagNameAttribute));

                if (nameAttributes.Length > 0)
                {
                    compound = new NbtCompound(((TagNameAttribute)nameAttributes[0]).Name);
                }

                var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p,
                                                                                                typeof(NbtIgnoreAttribute)).Any());

                foreach (var property in properties)
                {
                    if (!property.CanRead)
                    {
                        continue;
                    }

                    NbtTag tag = null;

                    string name = property.Name;
                    nameAttributes = Attribute.GetCustomAttributes(property, typeof(TagNameAttribute));
                    var ignoreOnNullAttribute = Attribute.GetCustomAttribute(property, typeof(IgnoreOnNullAttribute));
                    if (nameAttributes.Length != 0)
                    {
                        name = ((TagNameAttribute)nameAttributes[0]).Name;
                    }

                    var innerSerializer = new NbtSerializer(property.PropertyType);
                    var propValue       = property.GetValue(value, null);

                    if (propValue == null)
                    {
                        if (ignoreOnNullAttribute != null)
                        {
                            continue;
                        }
                        if (property.PropertyType.IsValueType)
                        {
                            propValue = Activator.CreateInstance(property.PropertyType);
                        }
                        else if (property.PropertyType == typeof(string))
                        {
                            propValue = "";
                        }
                    }

                    tag = innerSerializer.Serialize(propValue, name);
                    compound.Add(tag);
                }

                return(compound);
            }
        }
Пример #30
0
        public NbtFile ToNbt() // TODO: Entities
        {
            NbtFile file = new NbtFile();
            NbtCompound level = new NbtCompound("Level");
            
            // Entities // TODO
            level.Add(new NbtList("Entities", NbtTagType.Compound));

            // Biomes
            level.Add(new NbtByteArray("Biomes", Biomes));

            // Last Update // TODO: What is this
            level.Add(new NbtLong("LastUpdate", 15));

            // Position
            level.Add(new NbtInt("xPos", (int)AbsolutePosition.X));
            level.Add(new NbtInt("zPos", (int)AbsolutePosition.Z));

            // Tile Entities
            var tileEntityList = new NbtList("TileEntities", NbtTagType.Compound);
            foreach (var tileEntity in TileEntities)
            {
                // Get properties
                tileEntityList.Add(tileEntity.Value.ToNbt(tileEntity.Key));
            }
            level.Add(tileEntityList);

            // Terrain Populated // TODO: When is this 0? Will vanilla use this?
            level.Add(new NbtByte("TerrainPopualted", 0));

            // Sections and height
            level.Add(new NbtIntArray("HeightMap", HeightMap));
            NbtList sectionList = new NbtList("Sections", NbtTagType.Compound);
            foreach (var section in Sections)
            {
                if (!section.IsAir)
                {
                    NbtCompound sectionTag = new NbtCompound();
                    sectionTag.Add(new NbtByte("Y", section.Y));
                    sectionTag.Add(new NbtByteArray("Blocks", section.Blocks));
                    sectionTag.Add(new NbtByteArray("Data", section.Metadata.Data));
                    sectionTag.Add(new NbtByteArray("SkyLight", section.SkyLight.Data));
                    sectionTag.Add(new NbtByteArray("BlockLight", section.BlockLight.Data));
                    sectionList.Add(sectionTag);
                }
            }
            level.Add(sectionList);

            var rootCompound = new NbtCompound("");
            rootCompound.Add(level);
            file.RootTag = rootCompound;

            return file;
        }
Пример #31
0
        public void NestedListAndCompoundTest()
        {
            byte[] data;
            {
                var root = new NbtCompound("Root");
                var outerList = new NbtList("OuterList", NbtTagType.Compound);
                var outerCompound = new NbtCompound();
                var innerList = new NbtList("InnerList", NbtTagType.Compound);
                var innerCompound = new NbtCompound();

                innerList.Add(innerCompound);
                outerCompound.Add(innerList);
                outerList.Add(outerCompound);
                root.Add(outerList);

                var file = new NbtFile(root);
                data = file.SaveToBuffer(NbtCompression.None);
            }
            {
                var file = new NbtFile();
                long bytesRead = file.LoadFromBuffer(data, 0, data.Length, NbtCompression.None);
                Assert.AreEqual(bytesRead, data.Length);
                Assert.AreEqual(1, file.RootTag.Get<NbtList>("OuterList").Count);
                Assert.AreEqual(null, file.RootTag.Get<NbtList>("OuterList").Get<NbtCompound>(0).Name);
                Assert.AreEqual(1,
                                file.RootTag.Get<NbtList>("OuterList")
                                    .Get<NbtCompound>(0)
                                    .Get<NbtList>("InnerList")
                                    .Count);
                Assert.AreEqual(null,
                                file.RootTag.Get<NbtList>("OuterList")
                                    .Get<NbtCompound>(0)
                                    .Get<NbtList>("InnerList")
                                    .Get<NbtCompound>(0)
                                    .Name);
            }
        }
Пример #32
0
        public NbtCompound Save()
        {
            NbtCompound rtn = new NbtCompound();

            rtn.Add(new NbtString("name", name));

            NbtList ground = new NbtList("ground", NbtTagType.Compound);
            NbtList portal = new NbtList("portal", NbtTagType.Compound);
            NbtList decor = new NbtList("decor", NbtTagType.Compound);
            foreach(Point alpha in map.Keys) {
                if(map[alpha] is Platform) {
                    ground.Add(new NbtCompound(new NbtByte[] {
                        new NbtByte("x", (byte)alpha.X),
                        new NbtByte("y", (byte)alpha.Y)
                    }));
                } else if(map[alpha] is Portal) {
                    portal.Add(new NbtCompound(new NbtTag[] {
                        new NbtByte("x", (byte)alpha.X),
                        new NbtByte("y", (byte)alpha.Y),
                        new NbtString("linkTo", ((Portal)map[alpha]).Link.MyArea.Name),
                        new NbtByte("linkX", (byte)((Portal)map[alpha]).Link.Location.X),
                        new NbtByte("linkY", (byte)((Portal)map[alpha]).Link.Location.Y)
                    }));
                }
            }

            rtn.AddRange(new NbtList[] { ground, portal, decor });

            return rtn;
        }
Пример #33
0
        private NbtTag ReadPayload(NbtTagType nbtType)
        {
            switch (nbtType)
            {
            case NbtTagType.Byte:
                return(new NbtByte(_reader.ReadSByte()));

            case NbtTagType.Short:
                return(new NbtShort(_reader.ReadInt16()));

            case NbtTagType.Int:
                return(new NbtInt(_reader.ReadInt32()));

            case NbtTagType.Long:
                return(new NbtLong(_reader.ReadInt64()));

            case NbtTagType.Float:
                return(new NbtFloat(_reader.ReadSingle()));

            case NbtTagType.Double:
                return(new NbtDouble(_reader.ReadDouble()));

            case NbtTagType.ByteArray:
            {
                var size  = _reader.ReadInt32();
                var array = new sbyte[size];
                for (var i = 0; i < size; i++)
                {
                    array[i] = _reader.ReadSByte();
                }
                return(new NbtByteArray(array));
            }

            case NbtTagType.String:
                return(new NbtString(new string(_reader.ReadChars(_reader.ReadUInt16(), false))));

            case NbtTagType.List:
            {
                var contentType = (NbtTagType)_reader.ReadByte();
                var size        = _reader.ReadInt32();
                var list        = new NbtList();
                for (var i = 0; i < size; i++)
                {
                    list.Add(ReadPayload(contentType));
                }
                return(list);
            }

            case NbtTagType.Compound:
            {
                var    compound = new NbtCompound();
                NbtTag tag;
                while ((tag = ReadTag()).Type != NbtTagType.End)
                {
                    compound.Add(tag);
                }
                return(compound);
            }

            case NbtTagType.IntArray:
            {
                var size  = _reader.ReadInt32();
                var array = new int[size];
                for (var i = 0; i < size; i++)
                {
                    array[i] = _reader.ReadInt32();
                }
                return(new NbtIntArray(array));
            }

            case NbtTagType.LongArray:
            {
                var size  = _reader.ReadInt32();
                var array = new long[size];
                for (var i = 0; i < size; i++)
                {
                    array[i] = _reader.ReadInt64();
                }
                return(new NbtLongArray(array));
            }

            default:
                throw new NbtException($"Unknow tag. Tag id: {(sbyte)nbtType}");
            }
        }
Пример #34
0
        /**
         * AFTER the opening [
         */
        private NbtList ParseList()
        {
            bool    more    = true; //I'm sensing a pattern here...
            NbtList list    = new NbtList();
            NbtTag  current = null;
            int     index   = -1;

            while (more)
            {
                char next;
                try
                {
                    next = NextChar();
                }
                catch (Exception)
                {
                    throw new Exception(@"Unexpected EOF, expected ']'");
                }
                switch (next)
                {
                case ']':
                    more = false;
                    goto case ',';     //f****n fall through.

                case ',':
                    if (current != null)
                    {
                        if (index != -1)
                        {
                            if (index >= list.Count)
                            {
                                for (int i = list.Count; i <= index; i++)
                                {
                                    list.Add((NbtTag)current.GetType().GetConstructor(new Type[0]).Invoke(new object[0]));     //HOLY FUCKNUGGETS
                                }
                            }
                            list[index] = current;
                        }
                        else
                        {
                            list.Add(current);
                        }
                        index   = -1;
                        current = null;
                    }
                    break;

                case ' ':
                case '\t':
                case '\r':
                case '\n':
                    break;

                case ':':     //oh noes explicit index, doesn't even have to be in order.
                    index   = current.IntValue;
                    current = null;
                    break;

                default:
                    Position--;
                    current = ParseTag();
                    break;
                }
            }
            return(list);
        }
Пример #35
0
        public void ManipulatingList()
        {
            var sameTags = new NbtTag[] {
                new NbtInt(0),
                new NbtInt(1),
                new NbtInt(2)
            };

            var list = new NbtList("Test1", sameTags);

            // testing enumerator, indexer, Contains, and IndexOf
            int j = 0;

            foreach (NbtTag tag in list)
            {
                Assert.IsTrue(list.Contains(sameTags[j]));
                Assert.AreEqual(sameTags[j], tag);
                Assert.AreEqual(j, list.IndexOf(tag));
                j++;
            }

            // adding an item of correct type
            list.Add(new NbtInt(3));
            list.Insert(3, new NbtInt(4));

            // adding an item of wrong type
            Assert.Throws <ArgumentException>(() => list.Add(new NbtString()));
            Assert.Throws <ArgumentException>(() => list.Insert(3, new NbtString()));
            Assert.Throws <ArgumentNullException>(() => list.Insert(3, null));

            // testing array contents
            for (int i = 0; i < sameTags.Length; i++)
            {
                Assert.AreSame(sameTags[i], list[i]);
                Assert.AreEqual(i, ((NbtInt)list[i]).Value);
            }

            // test removal
            Assert.IsFalse(list.Remove(new NbtInt(5)));
            Assert.IsTrue(list.Remove(sameTags[0]));
            Assert.Throws <ArgumentNullException>(() => list.Remove(null));
            list.RemoveAt(0);
            Assert.Throws <ArgumentOutOfRangeException>(() => list.RemoveAt(10));

            // Test some failure scenarios for Add:
            // adding a list to itself
            var loopList = new NbtList();

            Assert.AreEqual(NbtTagType.Unknown, loopList.ListType);
            Assert.Throws <ArgumentException>(() => loopList.Add(loopList));

            // adding same tag to multiple lists
            Assert.Throws <ArgumentException>(() => loopList.Add(list[0]));
            Assert.Throws <ArgumentException>(() => loopList.Insert(0, list[0]));

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

            // make sure that all those failed adds didn't affect the tag
            Assert.AreEqual(0, loopList.Count);
            Assert.AreEqual(NbtTagType.Unknown, loopList.ListType);

            // try creating a list with invalid tag type
            Assert.Throws <ArgumentOutOfRangeException>(() => new NbtList((NbtTagType)200));
        }
Пример #36
0
        public void Serializing()
        {
            string fileName = Path.Combine( TempDir, "NbtListType.nbt" );
            const NbtTagType expectedListType = NbtTagType.Int;
            const int elements = 10;

            // construct nbt file
            NbtFile writtenFile = new NbtFile( new NbtCompound( "ListTypeTest" ) );
            NbtList writtenList = new NbtList( "Entities", null, expectedListType );
            for( int i = 0; i < elements; i++ ) {
                writtenList.Add( new NbtInt( i ) );
            }
            writtenFile.RootTag.Add( writtenList );

            // test saving
            writtenFile.SaveToFile( fileName, NbtCompression.GZip );

            // test loading
            NbtFile readFile = new NbtFile( fileName );

            // check contents of loaded file
            Assert.NotNull( readFile.RootTag );
            Assert.IsInstanceOf<NbtList>( readFile.RootTag["Entities"] );
            NbtList readList = (NbtList)readFile.RootTag["Entities"];
            Assert.AreEqual( readList.ListType, writtenList.ListType );
            Assert.AreEqual( readList.Count, writtenList.Count );

            // check .ToArray
            CollectionAssert.AreEquivalent( readList, readList.ToArray() );
            CollectionAssert.AreEquivalent( readList, readList.ToArray<NbtInt>() );

            // check contents of loaded list
            for( int i = 0; i < elements; i++ ) {
                Assert.AreEqual( readList.Get<NbtInt>( i ).Value, writtenList.Get<NbtInt>( i ).Value );
            }
        }
Пример #37
0
        public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
        {
            var adjacent = -Coordinates3D.One; // -1, no adjacent chest
            var self = descriptor.Coordinates;
            for (int i = 0; i < AdjacentBlocks.Length; i++)
            {
                var test = self + AdjacentBlocks[i];
                if (world.GetBlockID(test) == ChestBlock.BlockID)
                {
                    adjacent = test;
                    var up = world.BlockRepository.GetBlockProvider(world.GetBlockID(test + Coordinates3D.Up));
                    if (up.Opaque && !(up is WallSignBlock)) // Wall sign blocks are an exception
                        return false; // Obstructed
                    break;
                }
            }
            var upSelf = world.BlockRepository.GetBlockProvider(world.GetBlockID(self + Coordinates3D.Up));
            if (upSelf.Opaque && !(upSelf is WallSignBlock))
                return false; // Obstructed

            if (adjacent != -Coordinates3D.One)
            {
                // Ensure that chests are always opened in the same arrangement
                if (adjacent.X < self.X ||
                    adjacent.Z < self.Z)
                {
                    var _ = adjacent;
                    adjacent = self;
                    self = _; // Swap
                }
            }

            var window = new ChestWindow((InventoryWindow)user.Inventory, adjacent != -Coordinates3D.One);
            // Add items
            var entity = world.GetTileEntity(self);
            if (entity != null)
            {
                foreach (var item in (NbtList)entity["Items"])
                {
                    var slot = ItemStack.FromNbt((NbtCompound)item);
                    window.ChestInventory[slot.Index] = slot;
                }
            }
            // Add adjacent items
            if (adjacent != -Coordinates3D.One)
            {
                entity = world.GetTileEntity(adjacent);
                if (entity != null)
                {
                    foreach (var item in (NbtList)entity["Items"])
                    {
                        var slot = ItemStack.FromNbt((NbtCompound)item);
                        window.ChestInventory[slot.Index + ChestWindow.DoubleChestSecondaryIndex] = slot;
                    }
                }
            }
            window.WindowChange += (sender, e) =>
                {
                    var entitySelf = new NbtList("Items", NbtTagType.Compound);
                    var entityAdjacent = new NbtList("Items", NbtTagType.Compound);
                    for (int i = 0; i < window.ChestInventory.Items.Length; i++)
                    {
                        var item = window.ChestInventory.Items[i];
                        if (!item.Empty)
                        {
                            if (i < ChestWindow.DoubleChestSecondaryIndex)
                            {
                                item.Index = i;
                                entitySelf.Add(item.ToNbt());
                            }
                            else
                            {
                                item.Index = i - ChestWindow.DoubleChestSecondaryIndex;
                                entityAdjacent.Add(item.ToNbt());
                            }
                        }
                    }
                    var newEntity = world.GetTileEntity(self);
                    if (newEntity == null)
                        newEntity = new NbtCompound(new[] { entitySelf });
                    else
                        newEntity["Items"] = entitySelf;
                    world.SetTileEntity(self, newEntity);
                    if (adjacent != -Coordinates3D.One)
                    {
                        newEntity = world.GetTileEntity(adjacent);
                        if (newEntity == null)
                            newEntity = new NbtCompound(new[] { entityAdjacent });
                        else
                            newEntity["Items"] = entityAdjacent;
                        world.SetTileEntity(adjacent, newEntity);
                    }
                };
            user.OpenWindow(window);
            return false;
        }
Пример #38
0
        public static NbtTag Serialize(object obj)
        {
            switch (obj)
            {
            case IDictionary dictionary:
                return(dictionary.ToNbtCompound());

            case IEnumerable <sbyte> enumerable:
                return(new NbtByteArray(enumerable.ToArray()));

            case IEnumerable <int> enumerable:
                return(new NbtIntArray(enumerable.ToArray()));

            case IEnumerable <long> enumerable:
                return(new NbtLongArray(enumerable.ToArray()));

            case IEnumerable enumerable:
            {
                var list = new NbtList();
                foreach (var obj1 in enumerable)
                {
                    list.Add(Serialize(obj1));
                }
                return(list);
            }
            }

            var type = obj.GetType();
            var tag  = new NbtCompound();

            if (!type.GetCustomAttributes().Any(attribute => attribute is NbtCompoundAttribute))
            {
                throw new SerializationException($"the object must inherit {typeof(NbtCompoundAttribute)}");
            }

            foreach (var property in type.GetProperties())
            {
                var value = property.GetValue(obj);
                if (value == null)
                {
                    continue;
                }
                var attribute = property.GetCustomAttribute <NbtTagAttribute>();
                if (attribute == null)
                {
                    continue;
                }
                var name = attribute.Name;
                switch (attribute.Type)
                {
                case NbtTagType.End:
                    break;

                case NbtTagType.Byte:
                    tag.Add(NbtValue.CreateValue(value), name);
                    break;

                case NbtTagType.Short:
                    tag.Add(NbtValue.CreateValue(value), name);
                    break;

                case NbtTagType.Int:
                    tag.Add(NbtValue.CreateValue(value), name);
                    break;

                case NbtTagType.Long:
                    tag.Add(NbtValue.CreateValue(value), name);
                    break;

                case NbtTagType.Float:
                    tag.Add(NbtValue.CreateValue(value), name);
                    break;

                case NbtTagType.Double:
                    tag.Add(NbtValue.CreateValue(value), name);
                    break;

                case NbtTagType.ByteArray:
                    tag.Add(new NbtByteArray(((IEnumerable <sbyte>)value).ToArray()), name);
                    break;

                case NbtTagType.String:
                    tag.Add(NbtValue.CreateValue(value), name);
                    break;

                case NbtTagType.List:
                    tag.Add(Serialize(value), name);
                    break;

                case NbtTagType.Compound:
                    tag.Add(Serialize(value), name);
                    break;

                case NbtTagType.IntArray:
                    tag.Add(new NbtIntArray(((IEnumerable <int>)value).ToArray()), name);
                    break;

                case NbtTagType.LongArray:
                    tag.Add(new NbtLongArray(((IEnumerable <long>)value).ToArray()), name);
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            return(tag);
        }
Пример #39
0
        internal static bool ReadTag(this NbtTag tag, NbtBinaryReader readStream)
        {
            while (true)
            {
                NbtTag nbtTag;
                do
                {
                    NbtTagType nbtTagType = readStream.ReadTagType();
                    switch (nbtTagType)
                    {
                    case NbtTagType.End:
                        return(true);

                    case NbtTagType.Byte:
                        nbtTag = (NbtTag) new NbtByte();
                        break;

                    case NbtTagType.Short:
                        nbtTag = (NbtTag) new NbtShort();
                        break;

                    case NbtTagType.Int:
                        nbtTag = (NbtTag) new NbtInt();
                        break;

                    case NbtTagType.Long:
                        nbtTag = (NbtTag) new NbtLong();
                        break;

                    case NbtTagType.Float:
                        nbtTag = (NbtTag) new NbtFloat();
                        break;

                    case NbtTagType.Double:
                        nbtTag = (NbtTag) new NbtDouble();
                        break;

                    case NbtTagType.ByteArray:
                        nbtTag = (NbtTag) new NbtByteArray();
                        break;

                    case NbtTagType.String:
                        nbtTag = (NbtTag) new NbtString();
                        break;

                    case NbtTagType.List:
                        nbtTag = (NbtTag) new NbtList();
                        break;

                    case NbtTagType.Compound:
                        nbtTag = (NbtTag) new NbtCompound();
                        break;

                    case NbtTagType.IntArray:
                        nbtTag = (NbtTag) new NbtIntArray();
                        break;

                    case NbtTagType.LongArray:
                        nbtTag = (NbtTag) new NbtLongArray();
                        break;

                    case NbtTagType.Unknown:
                        return(true);

                        break;

                    default:
                        throw new FormatException("Unsupported tag type found in NBT_Compound: " + (object)nbtTagType);
                    }
                    //nbtTag.Parent = (NbtTag) this;
                    nbtTag.Name = readStream.ReadString();
                }while (!nbtTag.ReadTag(readStream));

                switch (tag.TagType)
                {
                case NbtTagType.Compound:
                    NbtCompound compound = (NbtCompound)tag;
                    compound.Add(nbtTag);
                    break;

                case NbtTagType.List:
                    NbtList list = (NbtList)tag;
                    list.Add(nbtTag);
                    break;
                }
            }
        }
Пример #40
0
		public override void SaveChunk(Chunk cnk)
		{
			NbtFile c = new NbtFile(cnk.Filename);

            c.RootTag = NewNBTChunk(cnk.Position.X, cnk.Position.Z);
            NbtCompound Level = (NbtCompound)c.RootTag["Level"];

			// BLOCKS /////////////////////////////////////////////////////
			byte[] blocks = new byte[ChunkX * ChunkZ * ChunkY];
			for (int x = 0; x < ChunkX; x++)
			{
				for (int y = 0; y < ChunkY; y++)
				{
					for (int z = 0; z < ChunkZ; z++)
					{
						blocks[GetBlockIndex(x, y, z)] = cnk.Blocks[x, y, z];
					}
				}
            }
            Level.Set("xPos", new NbtInt("xPos", (int)cnk.Position.X));
            Level.Set("zPos", new NbtInt("zPos", (int)cnk.Position.Z));
            Level.Set("Blocks", new NbtByteArray("Blocks", blocks));
			blocks = null;

			// LIGHTING ///////////////////////////////////////////////////
			byte[] lighting = CompressLightmap(cnk.SkyLight,true);
			Level.Set("SkyLight",new NbtByteArray("SkyLight", lighting));

			lighting = CompressLightmap(cnk.BlockLight,false);
            Level.Set("BlockLight",new NbtByteArray("BlockLight", lighting));
			
			lighting = CompressDatamap(cnk.Data);
            Level.Set("Data", new NbtByteArray("Data", lighting));

			// HEIGHTMAP (Needed for lighting).
			byte[] hm = new byte[256];
			for (int x = 0; x < ChunkX; x++)
			{
				for (int z = 0; z < ChunkZ; z++)
				{
                    hm[z << 4 | x] = (byte)(cnk.HeightMap[x, z] & 0xff); // idk
				}
			}
            Level.Set("HeightMap", new NbtByteArray("HeightMap", hm));


			NbtList ents = new NbtList("Entities");
			// ENTITIES ///////////////////////////////////////////////////
			foreach (KeyValuePair<Guid, Entity> ent in cnk.Entities)
			{
				ents.Add(ent.Value.ToNBT());
			}
			Level.Set("Entities",ents);

			NbtList tents = new NbtList("TileEntities");
			// TILE ENTITIES //////////////////////////////////////////////
			foreach (KeyValuePair<Guid, TileEntity> tent in cnk.TileEntities)
			{
				tents.Add(tent.Value.ToNBT());
			}
			Level.Set("TileEntities",tents);

            // Tick when last saved.  But ticks are process associated...
            Level.Set("LastUpdate", new NbtLong("LastUpdate", (long)Utils.UnixTimestamp()));

			c.RootTag.Set("Level",Level);
			
            c.SaveFile(GetChunkFilename((int)cnk.Position.X,(int)cnk.Position.Z));
			
            // For debuggan
            File.WriteAllText(cnk.Filename + ".txt", c.RootTag.ToString());

            Cache.SaveChunkMetadata(cnk); // This is probably what lags.
        }
Пример #41
0
        public override bool BlockRightClicked(BlockDescriptor descriptor, BlockFace face, IWorld world, IRemoteClient user)
        {
            var adjacent = -Coordinates3D.One; // -1, no adjacent chest
            var self     = descriptor.Coordinates;

            for (int i = 0; i < AdjacentBlocks.Length; i++)
            {
                var test = self + AdjacentBlocks[i];
                if (world.GetBlockID(test) == ChestBlock.BlockID)
                {
                    adjacent = test;
                    var up = world.BlockRepository.GetBlockProvider(world.GetBlockID(test + Coordinates3D.Up));
                    if (up.Opaque)
                    {
                        return(false); // Obstructed
                    }
                    break;
                }
            }
            var upSelf = world.BlockRepository.GetBlockProvider(world.GetBlockID(self + Coordinates3D.Up));

            if (upSelf.Opaque)
            {
                return(false); // Obstructed
            }
            if (adjacent != -Coordinates3D.One)
            {
                // Ensure that chests are always opened in the same arrangement
                if (adjacent.X < self.X ||
                    adjacent.Z < self.Z)
                {
                    var _ = adjacent;
                    adjacent = self;
                    self     = _; // Swap
                }
            }

            var window = new ChestWindow((InventoryWindow)user.Inventory, adjacent != -Coordinates3D.One);
            // Add items
            var entity = world.GetTileEntity(self);

            if (entity != null)
            {
                foreach (var item in (NbtList)entity["Items"])
                {
                    var slot = ItemStack.FromNbt((NbtCompound)item);
                    window.ChestInventory[slot.Index] = slot;
                }
            }
            // Add adjacent items
            if (adjacent != -Coordinates3D.One)
            {
                entity = world.GetTileEntity(adjacent);
                if (entity != null)
                {
                    foreach (var item in (NbtList)entity["Items"])
                    {
                        var slot = ItemStack.FromNbt((NbtCompound)item);
                        window.ChestInventory[slot.Index + ChestWindow.DoubleChestSecondaryIndex] = slot;
                    }
                }
            }
            window.WindowChange += (sender, e) =>
            {
                var entitySelf     = new NbtList("Items", NbtTagType.Compound);
                var entityAdjacent = new NbtList("Items", NbtTagType.Compound);
                for (int i = 0; i < window.ChestInventory.Items.Length; i++)
                {
                    var item = window.ChestInventory.Items[i];
                    if (!item.Empty)
                    {
                        if (i < ChestWindow.DoubleChestSecondaryIndex)
                        {
                            item.Index = i;
                            entitySelf.Add(item.ToNbt());
                        }
                        else
                        {
                            item.Index = i - ChestWindow.DoubleChestSecondaryIndex;
                            entityAdjacent.Add(item.ToNbt());
                        }
                    }
                }
                var newEntity = world.GetTileEntity(self);
                if (newEntity == null)
                {
                    newEntity = new NbtCompound(new[] { entitySelf });
                }
                else
                {
                    newEntity["Items"] = entitySelf;
                }
                world.SetTileEntity(self, newEntity);
                if (adjacent != -Coordinates3D.One)
                {
                    newEntity = world.GetTileEntity(adjacent);
                    if (newEntity == null)
                    {
                        newEntity = new NbtCompound(new[] { entityAdjacent });
                    }
                    else
                    {
                        newEntity["Items"] = entityAdjacent;
                    }
                    world.SetTileEntity(adjacent, newEntity);
                }
            };
            user.OpenWindow(window);
            return(false);
        }
Пример #42
0
        NbtTag SerializeList(string tagName, IList valueAsArray, Type elementType, NullPolicy elementNullPolicy)
        {
            NbtTagType listType;
            if (elementType == typeof(byte) || elementType == typeof(sbyte) || elementType == typeof(bool)) {
                listType = NbtTagType.Byte;
            } else if (elementType == typeof(byte[])) {
                listType = NbtTagType.ByteArray;
            } else if (elementType == typeof(double)) {
                listType = NbtTagType.Double;
            } else if (elementType == typeof(float)) {
                listType = NbtTagType.Float;
            } else if (elementType == typeof(int) || elementType == typeof(uint)) {
                listType = NbtTagType.Int;
            } else if (elementType == typeof(int[])) {
                listType = NbtTagType.IntArray;
            } else if (elementType == typeof(long) || elementType == typeof(ulong)) {
                listType = NbtTagType.Long;
            } else if (elementType == typeof(short) || elementType == typeof(ushort)) {
                listType = NbtTagType.Short;
            } else if (elementType == typeof(string)) {
                listType = NbtTagType.String;
            } else {
                listType = NbtTagType.Compound;
            }

            var list = new NbtList(tagName, listType);

            if (elementType.IsPrimitive) {
                // speedy serialization for basic types
                for (int i = 0; i < valueAsArray.Count; i++) {
                    list.Add(SerializePrimitiveType(null, valueAsArray[i]));
                }
            } else if (SerializationUtil.IsDirectlyMappedType(elementType)) {
                // speedy serialization for directly-mapped types
                for (int i = 0; i < valueAsArray.Count; i++) {
                    var value = valueAsArray[i];
                    if (value == null) {
                        switch (elementNullPolicy) {
                            case NullPolicy.Error:
                                throw new NullReferenceException("Null elements not allowed for tag " + tagName);
                            case NullPolicy.InsertDefault:
                                list.Add(Serialize(SerializationUtil.GetDefaultValue(elementType), true));
                                break;
                            case NullPolicy.Ignore:
                                continue;
                        }
                    } else {
                        list.Add(Serialize(valueAsArray[i], true));
                    }
                }
            } else {
                // serialize complex types
                var innerSerializer = new NbtSerializer(elementType);
                for (int i = 0; i < valueAsArray.Count; i++) {
                    var value = valueAsArray[i];
                    if (value == null) {
                        switch (elementNullPolicy) {
                            case NullPolicy.Error:
                                throw new NullReferenceException("Null elements not allowed for tag " + tagName);
                            case NullPolicy.Ignore:
                                continue;
                            case NullPolicy.InsertDefault:
                                // TODO
                                break;
                        }
                    } else {
                        list.Add(innerSerializer.Serialize(valueAsArray[i], null));
                    }
                }
            }
            return list;
        }
Пример #43
0
        public NbtTag Serialize(object value, string tagName, bool skipInterfaceCheck = false)
        {
            if (!skipInterfaceCheck && value is INbtSerializable)
                return ((INbtSerializable)value).Serialize(tagName);
            else if (value is NbtTag)
                return (NbtTag)value;
            else if (value is byte)
                return new NbtByte(tagName, (byte)value);
            else if (value is sbyte)
                return new NbtByte(tagName, (byte)(sbyte)value);
            else if (value is bool)
                return new NbtByte(tagName, (byte)((bool)value ? 1 : 0));
            else if (value is byte[])
                return new NbtByteArray(tagName, (byte[])value);
            else if (value is double)
                return new NbtDouble(tagName, (double)value);
            else if (value is float)
                return new NbtFloat(tagName, (float)value);
            else if (value is int)
                return new NbtInt(tagName, (int)value);
            else if (value is uint)
                return new NbtInt(tagName, (int)(uint)value);
            else if (value is int[])
                return new NbtIntArray(tagName, (int[])value);
            else if (value is long)
                return new NbtLong(tagName, (long)value);
            else if (value is ulong)
                return new NbtLong(tagName, (long)(ulong)value);
            else if (value is short)
                return new NbtShort(tagName, (short)value);
            else if (value is ushort)
                return new NbtShort(tagName, (short)(ushort)value);
            else if (value is string)
                return new NbtString(tagName, (string)value);
            else if (value.GetType().IsArray)
            {
                var elementType = value.GetType().GetElementType();
                var array = value as Array;
                var listType = NbtTagType.Compound;
                if (elementType == typeof (byte) || elementType == typeof (sbyte))
                    listType = NbtTagType.Byte;
                else if (elementType == typeof (bool))
                    listType = NbtTagType.Byte;
                else if (elementType == typeof (byte[]))
                    listType = NbtTagType.ByteArray;
                else if (elementType == typeof (double))
                    listType = NbtTagType.Double;
                else if (elementType == typeof (float))
                    listType = NbtTagType.Float;
                else if (elementType == typeof (int) || elementType == typeof (uint))
                    listType = NbtTagType.Int;
                else if (elementType == typeof (int[]))
                    listType = NbtTagType.IntArray;
                else if (elementType == typeof (long) || elementType == typeof (ulong))
                    listType = NbtTagType.Long;
                else if (elementType == typeof (short) || elementType == typeof (ushort))
                    listType = NbtTagType.Short;
                else if (elementType == typeof (string))
                    listType = NbtTagType.String;
                var list = new NbtList(tagName, listType);
                var innerSerializer = new NbtSerializer(elementType);
                for (int i = 0; i < array.Length; i++)
                    list.Add(innerSerializer.Serialize(array.GetValue(i)));
                return list;
            }
            else if (value is NbtFile)
                return ((NbtFile)value).RootTag;
            else
            {
                var compound = new NbtCompound(tagName);

                if (value == null) return compound;
                var nameAttributes = Attribute.GetCustomAttributes(value.GetType(), typeof (TagNameAttribute));

                if (nameAttributes.Length > 0)
                    compound = new NbtCompound(((TagNameAttribute)nameAttributes[0]).Name);

                var properties = Type.GetProperties().Where(p => !Attribute.GetCustomAttributes(p,
                    typeof (NbtIgnoreAttribute)).Any());

                foreach (var property in properties)
                {
                    if (!property.CanRead)
                        continue;

                    NbtTag tag = null;

                    string name = property.Name;
                    nameAttributes = Attribute.GetCustomAttributes(property, typeof (TagNameAttribute));
                    var ignoreOnNullAttribute = Attribute.GetCustomAttribute(property, typeof(IgnoreOnNullAttribute));
                    if (nameAttributes.Length != 0)
                        name = ((TagNameAttribute)nameAttributes[0]).Name;

                    var innerSerializer = new NbtSerializer(property.PropertyType);
                    var propValue = property.GetValue(value, null);

                    if (propValue == null)
                    {
                        if (ignoreOnNullAttribute != null) continue;
                        if (property.PropertyType.IsValueType)
                        {
                            propValue = Activator.CreateInstance(property.PropertyType);
                        }
                        else if (property.PropertyType == typeof (string))
                            propValue = "";
                    }

                    tag = innerSerializer.Serialize(propValue, name);
                    compound.Add(tag);
                }

                return compound;
            }
        }
Пример #44
0
        public static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset)
        {
            var nbt = new NbtFile();

            NbtCompound levelTag = new NbtCompound("Level");

            nbt.RootTag.Add(levelTag);

            levelTag.Add(new NbtInt("xPos", chunk.x));
            levelTag.Add(new NbtInt("zPos", chunk.z));
            levelTag.Add(new NbtByteArray("Biomes", chunk.biomeId));

            NbtList sectionsTag = new NbtList("Sections");

            levelTag.Add(sectionsTag);

            for (int i = 0; i < 8; i++)
            {
                NbtCompound sectionTag = new NbtCompound();
                sectionsTag.Add(sectionTag);
                sectionTag.Add(new NbtByte("Y", (byte)i));
                int sy = i * 16;

                byte[] blocks     = new byte[4096];
                byte[] data       = new byte[2048];
                byte[] blockLight = new byte[2048];
                byte[] skyLight   = new byte[2048];

                for (int x = 0; x < 16; x++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        for (int y = 0; y < 16; y++)
                        {
                            int yi = sy + y;
                            if (yi < 0 || yi >= 256)
                            {
                                continue;                                                  // ?
                            }
                            int  anvilIndex = (y + yoffset) * 16 * 16 + z * 16 + x;
                            byte blockId    = chunk.GetBlock(x, yi, z);

                            // PE to Anvil friendly converstion
                            if (blockId == 5)
                            {
                                blockId = 125;
                            }
                            else if (blockId == 158)
                            {
                                blockId = 126;
                            }
                            else if (blockId == 50)
                            {
                                blockId = 75;
                            }
                            else if (blockId == 50)
                            {
                                blockId = 76;
                            }
                            else if (blockId == 89)
                            {
                                blockId = 123;
                            }
                            else if (blockId == 89)
                            {
                                blockId = 124;
                            }
                            else if (blockId == 73)
                            {
                                blockId = 152;
                            }

                            blocks[anvilIndex] = blockId;
                            SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z));
                            SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z));
                            SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z));
                        }
                    }
                }

                sectionTag.Add(new NbtByteArray("Blocks", blocks));
                sectionTag.Add(new NbtByteArray("Data", data));
                sectionTag.Add(new NbtByteArray("BlockLight", blockLight));
                sectionTag.Add(new NbtByteArray("SkyLight", skyLight));
            }

            // TODO: Save entities
            NbtList entitiesTag = new NbtList("Entities", NbtTagType.Compound);

            levelTag.Add(entitiesTag);

            NbtList blockEntitiesTag = new NbtList("TileEntities", NbtTagType.Compound);

            levelTag.Add(blockEntitiesTag);
            foreach (NbtCompound blockEntityNbt in chunk.BlockEntities.Values)
            {
                NbtCompound nbtClone = (NbtCompound)blockEntityNbt.Clone();
                nbtClone.Name = null;
                blockEntitiesTag.Add(nbtClone);
            }

            levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound));

            return(nbt);
        }
Пример #45
0
        private static NbtFile CreateNbtFromChunkColumn(ChunkColumn chunk, int yoffset)
        {
            var nbt = new NbtFile();

            var levelTag = new NbtCompound("Level");

            nbt.RootTag.Add(levelTag);

            levelTag.Add(new NbtInt("xPos", chunk.X));
            levelTag.Add(new NbtInt("zPos", chunk.Z));
            levelTag.Add(new NbtByteArray("Biomes", chunk.BiomeId));

            var sectionsTag = new NbtList("Sections");

            levelTag.Add(sectionsTag);

            for (var i = 0; i < 8; i++)
            {
                var sectionTag = new NbtCompound();
                sectionsTag.Add(sectionTag);
                sectionTag.Add(new NbtByte("Y", (byte)i));
                var sy = i * 16;

                var blocks     = new byte[4096];
                var data       = new byte[2048];
                var blockLight = new byte[2048];
                var skyLight   = new byte[2048];

                for (var x = 0; x < 16; x++)
                {
                    for (var z = 0; z < 16; z++)
                    {
                        for (var y = 0; y < 16; y++)
                        {
                            var yi = sy + y;
                            if (yi < 0 || yi >= 256)
                            {
                                continue;                                                  // ?
                            }
                            var anvilIndex = (y + yoffset) * 16 * 16 + z * 16 + x;
                            var blockId    = chunk.GetBlock(x, yi, z);

                            blocks[anvilIndex] = (byte)blockId;
                            SetNibble4(data, anvilIndex, chunk.GetMetadata(x, yi, z));
                            SetNibble4(blockLight, anvilIndex, chunk.GetBlocklight(x, yi, z));
                            SetNibble4(skyLight, anvilIndex, chunk.GetSkylight(x, yi, z));
                        }
                    }
                }

                sectionTag.Add(new NbtByteArray("Blocks", blocks));
                sectionTag.Add(new NbtByteArray("Data", data));
                sectionTag.Add(new NbtByteArray("BlockLight", blockLight));
                sectionTag.Add(new NbtByteArray("SkyLight", skyLight));
            }

            levelTag.Add(new NbtList("Entities", NbtTagType.Compound));
            levelTag.Add(new NbtList("TileEntities", NbtTagType.Compound));
            levelTag.Add(new NbtList("TileTicks", NbtTagType.Compound));

            return(nbt);
        }
Пример #46
0
 public static void SavePlayer(this Level level, RemoteClient client)
 {
     if (string.IsNullOrEmpty(level.BaseDirectory))
         return;
     try
     {
         Directory.CreateDirectory(Path.Combine(level.BaseDirectory, "players"));
         var file = new NbtFile();
         file.RootTag.Add(new NbtInt("playerGameType", (int)client.GameMode));
         file.RootTag.Add(new NbtShort("SelectedItemSlot", client.Entity.SelectedSlot));
         file.RootTag.Add(new NbtInt("SpawnX", (int)client.Entity.SpawnPoint.X));
         file.RootTag.Add(new NbtInt("SpawnY", (int)client.Entity.SpawnPoint.Y));
         file.RootTag.Add(new NbtInt("SpawnZ", (int)client.Entity.SpawnPoint.Z));
         file.RootTag.Add(new NbtInt("foodLevel", client.Entity.Food));
         file.RootTag.Add(new NbtFloat("foodExhaustionLevel", client.Entity.FoodExhaustion));
         file.RootTag.Add(new NbtFloat("foodSaturationLevel", client.Entity.FoodSaturation));
         file.RootTag.Add(new NbtShort("Health", client.Entity.Health));
         var inventory = new NbtList("Inventory", NbtTagType.Compound);
         var slots = client.Entity.Inventory.GetSlots();
         for (int i = 0; i < slots.Length; i++)
         {
             var slot = (ItemStack)slots[i].Clone();
             slot.Index = Level.NetworkSlotToDataSlot(i);
             if (!slot.Empty)
                 inventory.Add(slot.ToNbt());
         }
         file.RootTag.Add(inventory);
         var position = new NbtList("Pos", NbtTagType.Double);
         position.Add(new NbtDouble(client.Entity.Position.X));
         position.Add(new NbtDouble(client.Entity.Position.Y));
         position.Add(new NbtDouble(client.Entity.Position.Z));
         file.RootTag.Add(position);
         var rotation = new NbtList("Rotation", NbtTagType.Float);
         rotation.Add(new NbtFloat(client.Entity.Yaw));
         rotation.Add(new NbtFloat(client.Entity.Pitch));
         file.RootTag.Add(rotation);
         var velocity = new NbtList("Motion", NbtTagType.Double);
         velocity.Add(new NbtDouble(client.Entity.Velocity.X));
         velocity.Add(new NbtDouble(client.Entity.Velocity.Y));
         velocity.Add(new NbtDouble(client.Entity.Velocity.Z));
         file.RootTag.Add(velocity);
         file.SaveToFile(Path.Combine(level.BaseDirectory, "players", client.Username + ".dat"), NbtCompression.None);
     }
     catch { } // If exceptions happen here, the entire server dies
 }
Пример #47
-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 ) );
        }