public void ValueTest() { // write one named tag for every value type, and read it back using (var ms = new MemoryStream()) { var writer = new NbtWriter(ms, "root"); Assert.AreEqual(ms, writer.BaseStream); { writer.WriteByte("byte", 1); writer.WriteShort("short", 2); writer.WriteInt("int", 3); writer.WriteLong("long", 4L); writer.WriteFloat("float", 5f); writer.WriteDouble("double", 6d); writer.WriteByteArray("byteArray", new byte[] { 10, 11, 12 }); writer.WriteIntArray("intArray", new[] { 20, 21, 22 }); writer.WriteLongArray("longArray", new long[] { 200, 210, 220 }); writer.WriteString("string", "123"); } Assert.IsFalse(writer.IsDone); writer.EndCompound(); Assert.IsTrue(writer.IsDone); writer.Finish(); ms.Position = 0; var file = new NbtFile(); file.LoadFromStream(ms, NbtCompression.None); TestFiles.AssertValueTest(file); } }
public void Serialize(MinecraftStream minecraftStream) { using var stream = new MinecraftStream(); using var dataStream = new MinecraftStream(); stream.WriteInt(Chunk.X); stream.WriteInt(Chunk.Z); stream.WriteBoolean(true); // full chunk int chunkSectionY = 0, mask = 0; foreach (var section in Chunk.Sections) { if ((changedSectionFilter & 1 << chunkSectionY) != 0) { mask |= 1 << chunkSectionY; section.WriteTo(dataStream); } chunkSectionY++; } stream.WriteVarInt(mask); Chunk.CalculateHeightmap(); var writer = new NbtWriter(stream, string.Empty); foreach (var(type, heightmap) in Chunk.Heightmaps) { writer.WriteLongArray(type.ToString().ToSnakeCase().ToUpper(), heightmap.GetDataArray().Cast <long>().ToArray()); } writer.EndCompound(); writer.Finish(); Chunk.BiomeContainer.WriteTo(stream); dataStream.Position = 0; stream.WriteVarInt((int)dataStream.Length); dataStream.CopyTo(stream); stream.WriteVarInt(0); minecraftStream.Lock.Wait(); minecraftStream.WriteVarInt(Id.GetVarIntLength() + (int)stream.Length); minecraftStream.WriteVarInt(Id); stream.Position = 0; stream.CopyTo(minecraftStream); minecraftStream.Lock.Release(); }
public void ErrorTest() { byte[] dummyByteArray = { 1, 2, 3, 4, 5 }; int[] dummyIntArray = { 1, 2, 3, 4, 5 }; long[] dummyLongArray = { 1, 2, 3, 4, 5 }; MemoryStream dummyStream = new MemoryStream(dummyByteArray); using (var ms = new MemoryStream()) { // null constructor parameters, or a non-writable stream Assert.Throws <ArgumentNullException>(() => new NbtWriter(null, "root")); Assert.Throws <ArgumentNullException>(() => new NbtWriter(ms, null)); Assert.Throws <ArgumentException>(() => new NbtWriter(new NonWritableStream(), "root")); var writer = new NbtWriter(ms, "root"); { // use negative list size Assert.Throws <ArgumentOutOfRangeException>(() => writer.BeginList("list", NbtTagType.Int, -1)); writer.BeginList("listOfLists", NbtTagType.List, 1); Assert.Throws <ArgumentOutOfRangeException>(() => writer.BeginList(NbtTagType.Int, -1)); writer.BeginList(NbtTagType.Int, 0); writer.EndList(); writer.EndList(); writer.BeginList("list", NbtTagType.Int, 1); // invalid list type Assert.Throws <ArgumentOutOfRangeException>(() => writer.BeginList(NbtTagType.End, 0)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.BeginList("list", NbtTagType.End, 0)); // call EndCompound when not in a compound Assert.Throws <NbtFormatException>(writer.EndCompound); // end list before all elements have been written Assert.Throws <NbtFormatException>(writer.EndList); // write the wrong kind of tag inside a list Assert.Throws <NbtFormatException>(() => writer.WriteShort(0)); // write a named tag where an unnamed tag is expected Assert.Throws <NbtFormatException>(() => writer.WriteInt("NamedInt", 0)); // write too many list elements writer.WriteTag(new NbtInt()); Assert.Throws <NbtFormatException>(() => writer.WriteInt(0)); writer.EndList(); // write a null tag Assert.Throws <ArgumentNullException>(() => writer.WriteTag(null)); // write an unnamed tag where a named tag is expected Assert.Throws <NbtFormatException>(() => writer.WriteTag(new NbtInt())); Assert.Throws <NbtFormatException>(() => writer.WriteInt(0)); // end a list when not in a list Assert.Throws <NbtFormatException>(writer.EndList); // unacceptable nulls: WriteString Assert.Throws <ArgumentNullException>(() => writer.WriteString(null)); Assert.Throws <ArgumentNullException>(() => writer.WriteString("NullString", null)); // unacceptable nulls: WriteByteArray from array Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray(null)); Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray(null, 0, 5)); Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray("NullByteArray", null)); Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray("NullByteArray", null, 0, 5)); // unacceptable nulls: WriteByteArray from stream Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray(null, 5)); Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray(null, 5, null)); Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray(dummyStream, 5, null)); Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray("NullBuffer", dummyStream, 5, null)); Assert.Throws <ArgumentNullException>(() => writer.WriteByteArray("NullStream", null, 5)); Assert.Throws <ArgumentNullException>( () => writer.WriteByteArray("NullStream", null, 5, dummyByteArray)); // unacceptable nulls: WriteIntArray Assert.Throws <ArgumentNullException>(() => writer.WriteIntArray(null)); Assert.Throws <ArgumentNullException>(() => writer.WriteIntArray(null, 0, 5)); Assert.Throws <ArgumentNullException>(() => writer.WriteIntArray("NullIntArray", null)); Assert.Throws <ArgumentNullException>(() => writer.WriteIntArray("NullIntArray", null, 0, 5)); // unacceptable nulls: WriteIntArray Assert.Throws <ArgumentNullException>(() => writer.WriteLongArray(null)); Assert.Throws <ArgumentNullException>(() => writer.WriteLongArray(null, 0, 5)); Assert.Throws <ArgumentNullException>(() => writer.WriteLongArray("NullLongArray", null)); Assert.Throws <ArgumentNullException>(() => writer.WriteLongArray("NullLongArray", null, 0, 5)); // non-readable streams are unacceptable Assert.Throws <ArgumentException>(() => writer.WriteByteArray(new NonReadableStream(), 0)); Assert.Throws <ArgumentException>( () => writer.WriteByteArray(new NonReadableStream(), 0, new byte[10])); Assert.Throws <ArgumentException>( () => writer.WriteByteArray("NonReadableStream", new NonReadableStream(), 0)); // trying to write array with out-of-range offset/count Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteByteArray(dummyByteArray, -1, 5)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteByteArray(dummyByteArray, 0, -1)); Assert.Throws <ArgumentException>(() => writer.WriteByteArray(dummyByteArray, 0, 6)); Assert.Throws <ArgumentException>(() => writer.WriteByteArray(dummyByteArray, 1, 5)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteByteArray("OutOfRangeByteArray", dummyByteArray, -1, 5)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteByteArray("OutOfRangeByteArray", dummyByteArray, 0, -1)); Assert.Throws <ArgumentException>( () => writer.WriteByteArray("OutOfRangeByteArray", dummyByteArray, 0, 6)); Assert.Throws <ArgumentException>( () => writer.WriteByteArray("OutOfRangeByteArray", dummyByteArray, 1, 5)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteIntArray(dummyIntArray, -1, 5)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteIntArray(dummyIntArray, 0, -1)); Assert.Throws <ArgumentException>(() => writer.WriteIntArray(dummyIntArray, 0, 6)); Assert.Throws <ArgumentException>(() => writer.WriteIntArray(dummyIntArray, 1, 5)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteIntArray("OutOfRangeIntArray", dummyIntArray, -1, 5)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteIntArray("OutOfRangeIntArray", dummyIntArray, 0, -1)); Assert.Throws <ArgumentException>( () => writer.WriteIntArray("OutOfRangeIntArray", dummyIntArray, 0, 6)); Assert.Throws <ArgumentException>( () => writer.WriteIntArray("OutOfRangeIntArray", dummyIntArray, 1, 5)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteLongArray(dummyLongArray, -1, 5)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteLongArray(dummyLongArray, 0, -1)); Assert.Throws <ArgumentException>(() => writer.WriteLongArray(dummyLongArray, 0, 6)); Assert.Throws <ArgumentException>(() => writer.WriteLongArray(dummyLongArray, 1, 5)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteLongArray("OutOfRangeLongArray", dummyLongArray, -1, 5)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteLongArray("OutOfRangeLongArray", dummyLongArray, 0, -1)); Assert.Throws <ArgumentException>( () => writer.WriteLongArray("OutOfRangeLongArray", dummyLongArray, 0, 6)); Assert.Throws <ArgumentException>( () => writer.WriteLongArray("OutOfRangeLongArray", dummyLongArray, 1, 5)); // out-of-range values for stream-reading overloads of WriteByteArray Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteByteArray(dummyStream, -1)); Assert.Throws <ArgumentOutOfRangeException>(() => writer.WriteByteArray("BadLength", dummyStream, -1)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteByteArray(dummyStream, -1, dummyByteArray)); Assert.Throws <ArgumentOutOfRangeException>( () => writer.WriteByteArray("BadLength", dummyStream, -1, dummyByteArray)); Assert.Throws <ArgumentException>(() => writer.WriteByteArray(dummyStream, 5, new byte[0])); Assert.Throws <ArgumentException>( () => writer.WriteByteArray("BadLength", dummyStream, 5, new byte[0])); // trying to read from non-readable stream Assert.Throws <ArgumentException>( () => writer.WriteByteArray("ByteStream", new NonReadableStream(), 0)); // finish too early Assert.Throws <NbtFormatException>(writer.Finish); writer.EndCompound(); writer.Finish(); // write tag after finishing Assert.Throws <NbtFormatException>(() => writer.WriteTag(new NbtInt())); } } }
public ChunkDataPacket(Client client, ChunkColumn column) : base(client) { PacketId = 0x22; MCSerializer serializer = new MCSerializer(); serializer.WriteInt(column.X); serializer.WriteInt(column.Z); serializer.WriteBool(true); serializer.WriteVarInt(column.SectionMask); NbtWriter heightmapWriter = new NbtWriter(serializer.Stream, "root"); BitStorage heightmapStorage = new BitStorage(9, 256); for (int y = 0; y < 256; y++) { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++) { if (column.GetBlock(x, y, z).StateId != 0) { heightmapStorage.Set(ChunkColumn.GetHeightmapIdx(x, z), y); } } } } heightmapWriter.WriteLongArray("MOTION_BLOCKING", heightmapStorage.Data); heightmapWriter.EndCompound(); heightmapWriter.Finish(); for (int y = 0; y < 256; y += 4) { for (int z = 0; z < 16; z += 4) { for (int x = 0; x < 16; x += 4) { serializer.WriteInt((int)column.GetBiome(x, y, z)); } } } MCSerializer dataSerializer = new MCSerializer(); int primaryBitMask = column.SectionMask; for (int y = 0; y < 16; y++) { if ((primaryBitMask & 0b1) == 1) { column.Sections[y].Write(dataSerializer); } primaryBitMask >>= 1; } byte[] encodedChunkData = dataSerializer.GetBytes(); serializer.WriteVarInt(encodedChunkData.Length); serializer.WriteBytes(encodedChunkData); // TODO: Block Entities serializer.WriteVarInt(0); Data = serializer.GetBytes(); }
public void ListTest() { // write short (1-element) lists of every possible kind using (var ms = new MemoryStream()) { var writer = new NbtWriter(ms, "Test"); writer.BeginList("LotsOfLists", NbtTagType.List, 12); { writer.BeginList(NbtTagType.Byte, 1); writer.WriteByte(1); writer.EndList(); writer.BeginList(NbtTagType.ByteArray, 1); writer.WriteByteArray(new byte[] { 1 }); writer.EndList(); writer.BeginList(NbtTagType.Compound, 1); writer.BeginCompound(); writer.EndCompound(); writer.EndList(); writer.BeginList(NbtTagType.Double, 1); writer.WriteDouble(1); writer.EndList(); writer.BeginList(NbtTagType.Float, 1); writer.WriteFloat(1); writer.EndList(); writer.BeginList(NbtTagType.Int, 1); writer.WriteInt(1); writer.EndList(); writer.BeginList(NbtTagType.IntArray, 1); writer.WriteIntArray(new[] { 1 }); writer.EndList(); writer.BeginList(NbtTagType.List, 1); writer.BeginList(NbtTagType.List, 0); writer.EndList(); writer.EndList(); writer.BeginList(NbtTagType.Long, 1); writer.WriteLong(1); writer.EndList(); writer.BeginList(NbtTagType.Short, 1); writer.WriteShort(1); writer.EndList(); writer.BeginList(NbtTagType.String, 1); writer.WriteString("ponies"); writer.EndList(); writer.BeginList(NbtTagType.LongArray, 1); writer.WriteLongArray(new[] { 1L }); writer.EndList(); } writer.EndList(); Assert.IsFalse(writer.IsDone); writer.EndCompound(); Assert.IsTrue(writer.IsDone); writer.Finish(); ms.Position = 0; var reader = new NbtReader(ms); Assert.DoesNotThrow(() => reader.ReadAsTag()); } }