private bool CustomRead(NbtCompound node, bool ignoreProperty) { if (!node.TryGet <NbtString>(nameof(Name), out var str)) { return(false); } NbtCompound property = null; if (!ignoreProperty) { node.TryGet(nameof(Properties), out property); } Name = str.Value; // TODO: BlockProperty if (property != null) { Properties = NbtBlockProperty.CreateFromNbt(Name, property); } return(true); }
/// <inheritdoc /> protected override void ReadFrom(NbtCompound compound) { if (compound == null) { return; } if (compound.TryGet <NbtByte>("Rot", out var rotation) || compound.TryGet <NbtByte>("rot", out rotation)) { Rotation = rotation.Value; } }
public static BlockEntity ReadFrom(NbtCompound compound, World world, Block block) { if (compound.TryGet("id", out var tag) || compound.TryGet("ID", out tag)) { var id = tag.StringValue; BlockEntity blockEntity = null; switch (id.ToLower()) { case "minecraft:chest": case "chest": blockEntity = new ChestBlockEntity(block, world, ChestTexture); break; case "minecraft:ender_chest": case "ender_chest": case "enderchest": blockEntity = new EnderChestBlockEntity(block, world, EnderChestTexture); break; case "minecraft:sign": case "sign": blockEntity = new SignBlockEntity(world, block); break; case "minecraft:skull": case "skull": blockEntity = new SkullBlockEntity(world, block, SkullTexture); break; default: Log.Warn($"Missing block entity type: {id}"); break; } if (blockEntity != null) { blockEntity.Read(compound); } return(blockEntity); } return(null); }
private string GetTextValue(NbtCompound compound, string key) { NbtString text; compound.TryGet(key, out text); return(text != null ? (text.StringValue ?? string.Empty) : string.Empty); }
public override void SetCompound(NbtCompound compound) { Compound = compound; if (compound.TryGet("primary", out NbtInt primary)) { Primary = primary.Value; } if (compound.TryGet("secondary", out NbtInt secondary)) { Secondary = secondary.Value; } _nextUpdate = 0; }
public override void SetCompound(NbtCompound compound) { NbtByte color; compound.TryGet("color", out color); Color = color.ByteValue; }
private void ReadFromNewFormat(NbtCompound heightmaps) { for (var id = 0; id < HeightMapTypes.Length; id++) { if (heightmaps.TryGet <NbtLongArray>(HeightMapTypes[id], out var longarray)) { HeightMaps[id] = DynBitArray.CreateFromLongArray(longarray.Value, 9); } } }
public override void SetCompound(NbtCompound compound) { Compound = compound; if (compound.TryGet("Item", out var item)) { var id = item["id"].ShortValue; var damage = item["Damage"].ShortValue; var count = item["Count"].ShortValue; ItemInFrame = ItemFactory.GetItem(id, damage, count); } if (compound.TryGet("ItemRotation", out var rotation)) { Rotation = rotation.ByteValue; } if (compound.TryGet("ItemDropChance", out var dropChance)) { DropChance = dropChance.FloatValue; } }
/// <inheritdoc /> protected override void ReadFrom(NbtCompound compound) { base.ReadFrom(compound); if (compound.TryGet("Items", out NbtList list)) { foreach (var item in list) { if (item.TagType != NbtTagType.Compound) { continue; } NbtCompound itemCompound = (NbtCompound)item; var count = itemCompound["Count"].ByteValue; var slot = itemCompound["Slot"].ByteValue; var id = itemCompound["id"].ShortValue; if (itemCompound.TryGet("Damage", out NbtShort damageTag)) { } //ItemFactory. //var damage = itemCompound["Damage"].ShortValue; } } if (compound.TryGet("BurnTime", out NbtShort burnTime)) { BurnTime = burnTime.Value; } if (compound.TryGet("CookTime", out NbtShort cookTime)) { CookTime = cookTime.Value; } if (compound.TryGet("CookTimeTotal", out NbtShort cookTimeTotal)) { CookTimeTotal = cookTimeTotal.Value; } }
public void Read(IInterpretContext context, NbtCompound level) { var oldversion = level.TryGet <NbtIntArray>(FieldHeightMap, out var heightmap); var newversion = level.TryGet <NbtCompound>(FieldHeightMaps, out var heightmaps); if (oldversion) { State = AttributeVersion.Pre113; ReadFromClassicFormat(heightmap.Value); } else if (newversion) { State = AttributeVersion.Post113; ReadFromNewFormat(heightmaps); } else { State = AttributeVersion.NotCalculated; } }
public override void readFromNbt(NbtCompound tag) { base.readFromNbt(tag); this.setTile( Block.getBlockFromId(tag.Get <NbtInt>("blockId").Value), tag.Get <NbtInt>("meta").Value); tag.TryGet <NbtCompound>("blockNbt", out this.blockNbt); this.startPos = NbtHelper.readDirectBlockPos(tag, "start"); }
/// <summary> /// Get Id of BlockEntity from an Nbt storage. Returns <see langword="null"/> if malformed. /// This method will not create any BlockEntity. /// </summary> /// <param name="compound">Nbt storage</param> /// <returns>Id of the compound.</returns> public static string GetIdFromNbtCompound(NbtCompound compound) { if (compound.TryGet(FieldId, out NbtString blockid)) { return(blockid.Value); } else { return(null); } }
private void AssertTagValue <TExpected>(NbtCompound parentTag, string expectedTagName, object expectedValue, Func <TExpected, object> getValue) where TExpected : NbtTag { Assert.True(parentTag.TryGet(expectedTagName, out NbtTag tag), $"expected tag [{expectedTagName}] is not contains."); Assert.IsAssignableFrom <TExpected>(tag, $"actual tag type is [{tag.GetType()}], but expected [{typeof(TExpected)}]"); var actual = getValue((TExpected)tag); Assert.AreEqual(expectedValue, actual); }
protected override bool GetBlockData(NbtCompound section) { if (!section.TryGet(FieldY, out NbtByte nbtY)) { return(false); } int y = nbtY.Value; if (y == 255) { return(true); } if (y >= 16) { return(false); } if (!section.TryGet(FieldPalette, out NbtList list)) { return(false); } if (!section.TryGet(FieldBlockStates, out NbtLongArray blocks)) { return(false); } if (SnapshotStrategy == NbtSnapshotStrategy.Enable) { _paletteList[y] = list; _blockStateRaw[y] = blocks.Value; } else { _palette[y] = ToNamespacedBlockList(list); _blockStates[y] = DynBitArray.CreateFromLongArray(blocks.Value); } return(true); }
private static bool TryGetMemberTag(MemberInfo memberInfo, NbtCompound compound, out NbtTag tag) { tag = null; var attribute = GetAttribute(memberInfo); if (attribute == null) { return(false); } string childName = attribute.Name ?? memberInfo.Name; return(compound.TryGet(childName, out tag)); }
public static void SetNbt(NbtCompound compound, NbtTag value, params string[] path) { NbtCompound tag = compound; foreach (var item in path) { if (!tag.Contains(item)) { tag.Add(new NbtCompound(item)); } tag = (NbtCompound)tag[item]; // exception if existing non-compound tag is present } if (tag.TryGet(value.Name, out NbtTag existing) && existing.TagType == value.TagType) { tag.Remove(value.Name); } tag.Add(value); }
public void ReadFromNbtCompound(INbtIoCapable target, NbtCompound compound) { foreach (var entry in _nbtEntries) { var result = compound.TryGet(entry.Attribute.TagName ?? entry.Field.Name, out var tag); if (!result) { if (!entry.Attribute.Optional) { ExceptionHelper.ThrowParseMissingError(entry.Field.Name, ParseErrorLevel.Exception); } continue; } SetValueToClassMember(tag, entry, target); } }
public override void SetCompound(NbtCompound compound) { if (compound.TryGet("Locked", out var locked)) { Locked = locked.ByteValue == 1; } if (compound.TryGet("OnGround", out var onGround)) { OnGround = onGround.ByteValue == 1; } if (compound.TryGet("Owner", out var owner)) { Owner = owner.LongValue; } if (compound.TryGet("Size", out var size)) { Size = size.IntValue; } int x = 0, y = 0, z = 0; if (compound.TryGet("BaseX", out var baseX)) { x = baseX.IntValue; } if (compound.TryGet("BaseY", out var baseY)) { y = baseY.IntValue; } if (compound.TryGet("BaseZ", out var baseZ)) { z = baseZ.IntValue; } BaseCoordinates = new BlockCoordinates(x, y, z); Text = GetTextValue(compound, "Text"); }
private void HandleChunk(bool cacheEnabled, uint subChunkCount, byte[] chunkData, int cx, int cz, Action <ChunkColumn> callback) { if (cacheEnabled) { Log.Warn($"Unsupported cache enabled!"); } bool gotLight = false; try { using (MemoryStream stream = new MemoryStream(chunkData)) { NbtBinaryReader defStream = new NbtBinaryReader(stream, true); //int count = defStream.ReadByte(); if (subChunkCount < 1) { Log.Warn("Nothing to read"); return; } ChunkColumn chunkColumn = new ChunkColumn(); chunkColumn.IsDirty = true; chunkColumn.X = cx; chunkColumn.Z = cz; for (int s = 0; s < subChunkCount; s++) { var section = chunkColumn.Sections[s] as ChunkSection; int version = defStream.ReadByte(); if (version == 1 || version == 8) { int storageSize = defStream.ReadByte(); if (section == null) { section = new ChunkSection(chunkColumn, s, true, 2); } for (int storage = 0; storage < storageSize; storage++) { int paletteAndFlag = defStream.ReadByte(); bool isRuntime = (paletteAndFlag & 1) != 0; int bitsPerBlock = paletteAndFlag >> 1; int blocksPerWord = (int)Math.Floor(32f / bitsPerBlock); int wordCount = (int)Math.Ceiling(4096.0f / blocksPerWord); uint[] words = new uint[wordCount]; for (int w = 0; w < wordCount; w++) { int word = defStream.ReadInt32(); words[w] = SwapBytes((uint)word); } uint[] pallete = new uint[0]; if (isRuntime) { int palleteSize = VarInt.ReadSInt32(stream); pallete = new uint[palleteSize]; for (int pi = 0; pi < pallete.Length; pi++) { var ui = (uint)VarInt.ReadSInt32(stream); pallete[pi] = ui; } if (palleteSize == 0) { Log.Warn($"Pallete size is 0"); continue; } } int position = 0; for (int w = 0; w < wordCount; w++) { uint word = words[w]; for (int block = 0; block < blocksPerWord; block++) { if (position >= 4096) { break; // padding bytes } uint state = (uint)((word >> ((position % blocksPerWord) * bitsPerBlock)) & ((1 << bitsPerBlock) - 1)); int x = (position >> 8) & 0xF; int y = position & 0xF; int z = (position >> 4) & 0xF; if (state >= pallete.Length) { continue; } BlockState translated = GetBlockState(pallete[state]); if (translated != null) { if (translated.Block is Water) { string a = ""; } section.Set(storage, x, y, z, translated); } position++; } if (position >= 4096) { break; } } } } else { if (section == null) { section = new ChunkSection(chunkColumn, s, true, 1); } #region OldFormat byte[] blockIds = new byte[4096]; defStream.Read(blockIds, 0, blockIds.Length); NibbleArray data = new NibbleArray(4096); defStream.Read(data.Data, 0, data.Data.Length); for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int idx = (x << 8) + (z << 4) + y; var id = blockIds[idx]; var meta = data[idx]; var ruid = BlockFactory.GetBlockStateID(id, meta); BlockState result = null; if (!_convertedStates.TryGetValue( ruid, out result)) { if (id == 124 || id == 123) { result = BlockFactory.GetBlockState("minecraft:redstone_lamp"); if (id == 124) { result = result.WithProperty("lit", "true"); } } else if (id > 0 && result == null) { var reverseMap = MiNET.Worlds.AnvilWorldProvider.Convert.FirstOrDefault( map => map.Value.Item1 == id); if (reverseMap.Value != null) { id = (byte)reverseMap.Key; } var res = BlockFactory.GetBlockStateID(id, meta); if (AnvilWorldProvider.BlockStateMapper.TryGetValue(res, out var res2)) { var t = BlockFactory.GetBlockState(res2); t = TranslateBlockState(t, id, meta); result = t; } else { Log.Info($"Did not find anvil statemap: {result.Name}"); result = TranslateBlockState( BlockFactory.GetBlockState(res), id, meta); } } if (result == null) { var results = BlockFactory.RuntimeIdTable.Where(xx => xx.Id == id) .ToArray(); if (results.Length > 0) { var first = results.FirstOrDefault(xx => xx.Data == meta); if (first == default) { first = results[0]; } result = TranslateBlockState( BlockFactory.GetBlockState((uint)first.RuntimeId), id, meta); } } if (result == null) { result = new BlockState() { Name = $"{id}:{meta.ToString()}", Model = BlockFactory.UnknownBlockModel, Block = new Block(0) { } }; Log.Info($"Unknown block: {id}:{meta}"); } if (result != null) { _convertedStates.TryAdd(ruid, result); } } if (result != null) { section.Set(x, y, z, result); } else { Log.Info($"Unknown block: {id}:{meta}"); } } } } #endregion } if (UseAlexChunks) { // Log.Info($"Alex chunk!"); var rawSky = new API.Utils.NibbleArray(4096); defStream.Read(rawSky.Data, 0, rawSky.Data.Length); var rawBlock = new API.Utils.NibbleArray(4096); defStream.Read(rawBlock.Data, 0, rawBlock.Data.Length); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { var peIndex = (x * 256) + (z * 16) + y; var sky = rawSky[peIndex]; var block = rawBlock[peIndex]; var idx = y << 8 | z << 4 | x; section.SkyLight[idx] = sky; section.BlockLight[idx] = block; } } } gotLight = true; } section.RemoveInvalidBlocks(); section.IsDirty = true; //Make sure the section is saved. chunkColumn.Sections[s] = section; } /* byte[] ba = new byte[512]; * if (defStream.Read(ba, 0, 256 * 2) != 256 * 2) Log.Error($"Out of data height"); * * Buffer.BlockCopy(ba, 0, chunkColumn.Height, 0, 512);*/ int[] biomeIds = new int[256]; for (int i = 0; i < biomeIds.Length; i++) { biomeIds[i] = defStream.ReadByte(); } chunkColumn.BiomeId = biomeIds; if (stream.Position >= stream.Length - 1) { callback?.Invoke(chunkColumn); return; } int borderBlock = VarInt.ReadSInt32(stream); if (borderBlock > 0) { byte[] buf = new byte[borderBlock]; int len = defStream.Read(buf, 0, borderBlock); } if (stream.Position < stream.Length - 1) { int loop = 0; while (stream.Position < stream.Length - 1) { try { NbtFile file = new NbtFile() { BigEndian = false, UseVarInt = true }; file.LoadFromStream(stream, NbtCompression.None); if (file.RootTag.Name == "alex") { NbtCompound alexCompound = (NbtCompound)file.RootTag; for (int ci = 0; ci < subChunkCount; ci++) { var section = (ChunkSection)chunkColumn.Sections[ci]; var rawSky = new API.Utils.NibbleArray(4096); if (alexCompound.TryGet($"skylight-{ci}", out NbtByteArray skyData)) { rawSky.Data = skyData.Value; } //defStream.Read(rawSky.Data, 0, rawSky.Data.Length); var rawBlock = new API.Utils.NibbleArray(4096); if (alexCompound.TryGet($"blocklight-{ci}", out NbtByteArray blockData)) { rawBlock.Data = blockData.Value; } for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { var peIndex = (x * 256) + (z * 16) + y; var sky = rawSky[peIndex]; var block = rawBlock[peIndex]; var idx = y << 8 | z << 4 | x; section.SkyLight[idx] = sky; section.BlockLight[idx] = block; } } } chunkColumn.Sections[ci] = section; } gotLight = true; } if (stream.Position < stream.Length - 1) { // pre = stream.ReadByte(); } } catch (Exception ex) { // Log.Warn(ex, $"Reading chunk extra data (Loop={loop})"); } loop++; } } if (stream.Position < stream.Length - 1) { Log.Warn( $"Still have data to read\n{Packet.HexDump(defStream.ReadBytes((int) (stream.Length - stream.Position)))}"); } if (gotLight) { chunkColumn.SkyLightDirty = false; chunkColumn.BlockLightDirty = false; } chunkColumn.CalculateHeight(!gotLight && ClientSideLighting); //Done processing this chunk, send to world callback?.Invoke(chunkColumn); } } catch (Exception ex) { Log.Error($"Exception in chunk loading: {ex.ToString()}"); } finally { } }
public static bool hasKey(this NbtCompound tag, string key) { NbtTag result; return(tag.TryGet(key, out result)); }
public void GettersAndSetters() { // construct a document for us to test. var nestedChild = new NbtCompound("NestedChild"); var nestedInt = new NbtInt(1); var nestedChildList = new NbtList("NestedChildList") { nestedInt }; var child = new NbtCompound("Child") { nestedChild, nestedChildList }; var childList = new NbtList("ChildList") { new NbtInt(1) }; var parent = new NbtCompound("Parent") { child, childList }; // Accessing nested compound tags using indexers Assert.AreEqual(parent["Child"]["NestedChild"], nestedChild); Assert.AreEqual(parent["Child"]["NestedChildList"], nestedChildList); Assert.AreEqual(parent["Child"]["NestedChildList"][0], nestedInt); // Accessing nested compound tags using Get and Get<T> Assert.AreEqual(parent.Get<NbtCompound>("Child").Get<NbtCompound>("NestedChild"), nestedChild); Assert.AreEqual(parent.Get<NbtCompound>("Child").Get<NbtList>("NestedChildList"), nestedChildList); Assert.AreEqual(parent.Get<NbtCompound>("Child").Get<NbtList>("NestedChildList")[0], nestedInt); Assert.AreEqual((parent.Get("Child") as NbtCompound).Get("NestedChild"), nestedChild); Assert.AreEqual((parent.Get("Child") as NbtCompound).Get("NestedChildList"), nestedChildList); Assert.AreEqual((parent.Get("Child") as NbtCompound).Get("NestedChildList")[0], nestedInt); // Accessing with Get<T> and an invalid given type Assert.Throws<InvalidCastException>(() => parent.Get<NbtInt>("Child")); // Using TryGet and TryGet<T> NbtTag dummyTag; Assert.IsTrue(parent.TryGet("Child", out dummyTag)); NbtCompound dummyCompoundTag; Assert.IsTrue(parent.TryGet("Child", out dummyCompoundTag)); // Trying to use integer indexers on non-NbtList tags Assert.Throws<InvalidOperationException>(() => parent[0] = nestedInt); Assert.Throws<InvalidOperationException>(() => nestedInt[0] = nestedInt); // Trying to use string indexers on non-NbtCompound tags Assert.Throws<InvalidOperationException>(() => childList["test"] = nestedInt); Assert.Throws<InvalidOperationException>(() => nestedInt["test"] = nestedInt); // Trying to get a non-existent element by name Assert.IsNull(parent.Get<NbtTag>("NonExistentTag")); Assert.IsNull(parent["NonExistentTag"]); // Null indices on NbtCompound Assert.Throws<ArgumentNullException>(() => parent.Get<NbtTag>(null)); Assert.Throws<ArgumentNullException>(() => parent[null] = new NbtInt(1)); Assert.Throws<ArgumentNullException>(() => nestedInt = (NbtInt)parent[null]); // Out-of-range indices on NbtList Assert.Throws<ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[-1]); Assert.Throws<ArgumentOutOfRangeException>(() => childList[-1] = new NbtInt(1)); Assert.Throws<ArgumentOutOfRangeException>(() => nestedInt = childList.Get<NbtInt>(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[childList.Count]); Assert.Throws<ArgumentOutOfRangeException>(() => nestedInt = childList.Get<NbtInt>(childList.Count)); // Using setter correctly parent["NewChild"] = new NbtByte("NewChild"); // Using setter incorrectly object dummyObject; Assert.Throws<ArgumentNullException>(() => parent["Child"] = null); Assert.NotNull(parent["Child"]); Assert.Throws<ArgumentException>(() => parent["Child"] = new NbtByte("NotChild")); Assert.Throws<InvalidOperationException>(() => dummyObject = parent[0]); Assert.Throws<InvalidOperationException>(() => parent[0] = new NbtByte("NewerChild")); // Try adding tag to self var selfTest = new NbtCompound("SelfTest"); Assert.Throws<ArgumentException>(() => selfTest["SelfTest"] = selfTest); // Try adding a tag that already has a parent Assert.Throws<ArgumentException>(() => selfTest[child.Name] = child); }
protected override bool GetBlockData(NbtCompound section) { if (!section.TryGet(FieldY, out NbtByte y)) { return(false); } if (y.Value == 255) { return(true); } if (y.Value >= 16) { return(false); } // Old format with numeric block ID if (!section.TryGet(FieldBlocks, out NbtByteArray blocks)) { return(false); } if (blocks.Value.Length != 4096) { return(false); } _blocks[y.Value] = blocks.Value; var addSuccess = section.TryGet(FieldAdd, out NbtByteArray add); if (addSuccess && add.Value.Length != 2048) { return(false); } if (addSuccess) { _add[y.Value] = add.Value; } var dataSuccess = section.TryGet(FieldData, out NbtByteArray data); if (dataSuccess && data.Value.Length != 2048) { return(false); } if (dataSuccess) { _data[y.Value] = data.Value; } if (section.TryGet <NbtByteArray>(FieldBlockLight, out var bl)) { _blocklight[y.Value] = bl.Value; } else { _blocklight[y.Value] = new byte[2048]; } if (section.TryGet <NbtByteArray>(FieldSkyLight, out var sl)) { _skylight[y.Value] = sl.Value; } else { _skylight[y.Value] = new byte[2048]; } return(true); }
private string GetTextValue(NbtCompound compound, string key) { NbtString text; compound.TryGet(key, out text); return text != null ? (text.StringValue ?? string.Empty) : string.Empty; }
public void GettersAndSetters() { // construct a document for us to test. var nestedChild = new NbtCompound("NestedChild"); var nestedInt = new NbtInt(1); var nestedChildList = new NbtList("NestedChildList") { nestedInt }; var child = new NbtCompound("Child") { nestedChild, nestedChildList }; var childList = new NbtList("ChildList") { new NbtInt(1) }; var parent = new NbtCompound("Parent") { child, childList }; // Accessing nested compound tags using indexers Assert.AreEqual(nestedChild, parent["Child"]["NestedChild"]); Assert.AreEqual(nestedChildList, parent["Child"]["NestedChildList"]); Assert.AreEqual(nestedInt, parent["Child"]["NestedChildList"][0]); // Accessing nested compound tags using Get and Get<T> Assert.Throws <ArgumentNullException>(() => parent.Get <NbtCompound>(null)); Assert.IsNull(parent.Get <NbtCompound>("NonExistingChild")); Assert.AreEqual(nestedChild, parent.Get <NbtCompound>("Child").Get <NbtCompound>("NestedChild")); Assert.AreEqual(nestedChildList, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")); Assert.AreEqual(nestedInt, parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")[0]); Assert.Throws <ArgumentNullException>(() => parent.Get(null)); Assert.IsNull(parent.Get("NonExistingChild")); Assert.AreEqual(nestedChild, (parent.Get("Child") as NbtCompound).Get("NestedChild")); Assert.AreEqual(nestedChildList, (parent.Get("Child") as NbtCompound).Get("NestedChildList")); Assert.AreEqual(nestedInt, (parent.Get("Child") as NbtCompound).Get("NestedChildList")[0]); // Accessing with Get<T> and an invalid given type Assert.Throws <InvalidCastException>(() => parent.Get <NbtInt>("Child")); // Using TryGet and TryGet<T> NbtTag dummyTag; Assert.Throws <ArgumentNullException>(() => parent.TryGet(null, out dummyTag)); Assert.IsFalse(parent.TryGet("NonExistingChild", out dummyTag)); Assert.IsTrue(parent.TryGet("Child", out dummyTag)); NbtCompound dummyCompoundTag; Assert.Throws <ArgumentNullException>(() => parent.TryGet(null, out dummyCompoundTag)); Assert.IsFalse(parent.TryGet("NonExistingChild", out dummyCompoundTag)); Assert.IsTrue(parent.TryGet("Child", out dummyCompoundTag)); // Trying to use integer indexers on non-NbtList tags Assert.Throws <InvalidOperationException>(() => parent[0] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt[0] = nestedInt); // Trying to use string indexers on non-NbtCompound tags Assert.Throws <InvalidOperationException>(() => childList["test"] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt["test"] = nestedInt); // Trying to get a non-existent element by name Assert.IsNull(parent.Get <NbtTag>("NonExistentTag")); Assert.IsNull(parent["NonExistentTag"]); // Null indices on NbtCompound Assert.Throws <ArgumentNullException>(() => parent.Get <NbtTag>(null)); Assert.Throws <ArgumentNullException>(() => parent[null] = new NbtInt(1)); Assert.Throws <ArgumentNullException>(() => nestedInt = (NbtInt)parent[null]); // Out-of-range indices on NbtList Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[-1]); Assert.Throws <ArgumentOutOfRangeException>(() => childList[-1] = new NbtInt(1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[childList.Count]); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(childList.Count)); // Using setter correctly parent["NewChild"] = new NbtByte("NewChild"); // Using setter incorrectly object dummyObject; Assert.Throws <ArgumentNullException>(() => parent["Child"] = null); Assert.NotNull(parent["Child"]); Assert.Throws <ArgumentException>(() => parent["Child"] = new NbtByte("NotChild")); Assert.Throws <InvalidOperationException>(() => dummyObject = parent[0]); Assert.Throws <InvalidOperationException>(() => parent[0] = new NbtByte("NewerChild")); // Try adding tag to self var selfTest = new NbtCompound("SelfTest"); Assert.Throws <ArgumentException>(() => selfTest["SelfTest"] = selfTest); // Try adding a tag that already has a parent Assert.Throws <ArgumentException>(() => selfTest[child.Name] = child); }