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]); }
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]); }
public void AddingAndRemoving() { NbtCompound test = new NbtCompound(); NbtInt foo = new NbtInt( "Foo" ); test.Add( foo ); // adding duplicate object Assert.Throws<ArgumentException>( () => test.Add( foo ) ); // adding duplicate name Assert.Throws<ArgumentException>( () => test.Add( new NbtByte( "Foo" ) ) ); // adding unnamed tag Assert.Throws<ArgumentException>( () => test.Add( new NbtInt() ) ); // adding null Assert.Throws<ArgumentNullException>( () => test.Add( null ) ); // contains existing name Assert.IsTrue( test.Contains( "Foo" ) ); // contains existing object Assert.IsTrue( test.Contains( foo ) ); // contains non-existent name Assert.IsFalse( test.Contains( "Bar" ) ); // contains existing name / different object Assert.IsFalse( test.Contains( new NbtInt( "Foo" ) ) ); // removing non-existent name Assert.IsFalse( test.Remove( "Bar" ) ); // removing existing name Assert.IsTrue( test.Remove( "Foo" ) ); // removing non-existent name Assert.IsFalse( test.Remove( "Foo" ) ); // re-adding object test.Add( foo ); // removing existing object Assert.IsTrue( test.Remove( foo ) ); // clearing an empty NbtCompound Assert.AreEqual( test.Count, 0 ); test.Clear(); // re-adding after clearing test.Add( foo ); Assert.AreEqual( test.Count, 1 ); // clearing a non-empty NbtCompound test.Clear(); Assert.AreEqual( test.Count, 0 ); }
public void AddingAndRemoving() { var test = new NbtCompound(); var foo = new NbtInt("Foo"); test.Add(foo); // adding duplicate object Assert.Throws <ArgumentException>(() => test.Add(foo)); // adding duplicate name Assert.Throws <ArgumentException>(() => test.Add(new NbtByte("Foo"))); // adding unnamed tag Assert.Throws <ArgumentException>(() => test.Add(new NbtInt())); // adding null Assert.Throws <ArgumentNullException>(() => test.Add(null)); // contains existing name Assert.IsTrue(test.Contains("Foo")); // contains existing object Assert.IsTrue(test.Contains(foo)); // contains non-existent name Assert.IsFalse(test.Contains("Bar")); // contains existing name / different object Assert.IsFalse(test.Contains(new NbtInt("Foo"))); // removing non-existent name Assert.IsFalse(test.Remove("Bar")); // removing existing name Assert.IsTrue(test.Remove("Foo")); // removing non-existent name Assert.IsFalse(test.Remove("Foo")); // re-adding object test.Add(foo); // removing existing object Assert.IsTrue(test.Remove(foo)); // clearing an empty NbtCompound Assert.AreEqual(test.Count, 0); test.Clear(); // re-adding after clearing test.Add(foo); Assert.AreEqual(test.Count, 1); // clearing a non-empty NbtCompound test.Clear(); Assert.AreEqual(test.Count, 0); }
public override NbtCompound GetCompound() { Compound["x"] = new NbtInt("x", Coordinates.X); Compound["y"] = new NbtInt("y", Coordinates.Y); Compound["z"] = new NbtInt("z", Coordinates.Z); return(Compound); }
public override NbtCompound GetCompound() { Compound["x"] = new NbtInt("x", Coordinates.X); Compound["y"] = new NbtInt("y", Coordinates.Y); Compound["z"] = new NbtInt("z", Coordinates.Z); Compound["primary"] = new NbtInt("primary", Primary); Compound["secondary"] = new NbtInt("secondary", Secondary); return(Compound); }
public void GettersAndSetters() { var parent = new NbtCompound("Parent"); var child = new NbtCompound("Child"); var nestedChild = new NbtCompound("NestedChild"); var childList = new NbtList("ChildList"); var nestedChildList = new NbtList("NestedChildList"); childList.Add(new NbtInt(1)); var nestedInt = new NbtInt(1); nestedChildList.Add(nestedInt); parent.Add(child); parent.Add(childList); child.Add(nestedChild); child.Add(nestedChildList); // Accessing nested compound tags using indexers Assert.AreEqual(parent["Child"]["NestedChild"], nestedChild); Assert.AreEqual(parent["Child"]["NestedChildList"], nestedChildList); Assert.AreEqual(parent["Child"]["NestedChildList"][0], nestedInt); // Accessing nested compound tags using Get<T> Assert.AreEqual(parent.Get <NbtCompound>("Child").Get <NbtCompound>("NestedChild"), nestedChild); Assert.AreEqual(parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList"), nestedChildList); Assert.AreEqual(parent.Get <NbtCompound>("Child").Get <NbtList>("NestedChildList")[0], nestedInt); // Accessing with Get<T> and an invalid given type Assert.Throws <InvalidCastException>(() => parent.Get <NbtInt>("Child")); // Trying to use integer indexers on non-NbtList tags Assert.Throws <InvalidOperationException>(() => parent[0] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt[0] = nestedInt); // Trying to use string indexers on non-NbtCompound tags Assert.Throws <InvalidOperationException>(() => childList["test"] = nestedInt); Assert.Throws <InvalidOperationException>(() => nestedInt["test"] = nestedInt); // Trying to get a non-existent element by name Assert.IsNull(parent.Get <NbtTag>("NonExistentTag")); Assert.IsNull(parent["NonExistentTag"]); // Null indices on NbtCompound Assert.Throws <ArgumentNullException>(() => parent.Get <NbtTag>(null)); Assert.Throws <ArgumentNullException>(() => parent[null] = new NbtInt(1)); Assert.Throws <ArgumentNullException>(() => nestedInt = (NbtInt)parent[null]); // Out-of-range indices on NbtList Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[-1]); Assert.Throws <ArgumentOutOfRangeException>(() => childList[-1] = new NbtInt(1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(-1)); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = (NbtInt)childList[childList.Count]); Assert.Throws <ArgumentOutOfRangeException>(() => nestedInt = childList.Get <NbtInt>(childList.Count)); }
public void Renaming() { var compound = new NbtCompound(); compound.Add(new NbtInt("SameName", 1)); var tagToRename = new NbtInt("DifferentName", 1); compound.Add(tagToRename); Assert.DoesNotThrow(() => tagToRename.Name = "SomeOtherName"); Assert.Throws <ArgumentException>(() => tagToRename.Name = "SameName"); Assert.Throws <ArgumentNullException>(() => tagToRename.Name = null); }
public static int getInt(this NbtCompound tag, string name, int defaultValue = 0) { NbtInt tag1 = tag.Get <NbtInt>(name); if (tag1 == null) { return(defaultValue); } else { return(tag1.Value); } }
public static NbtCompound ExportAsStructure() { NbtCompound reactor = new NbtCompound("ReactorStructure"); int volume = (int)(Reactor.interiorDims.X * Reactor.interiorDims.Y * Reactor.interiorDims.Z); List <string> listPalette = new List <string>(); NbtList palette = new NbtList("palette", NbtTagType.Compound); NbtList blocks = new NbtList("blocks", NbtTagType.Compound); NbtString author = new NbtString("author", "Hellrage"); NbtCompound forgeDataVersion = new NbtCompound("ForgeDataVersion", new List <NbtInt> { new NbtInt("minecraft", 1343) }); NbtInt dataVersion = new NbtInt("DataVersion", 1342); for (int y = 1; y <= Reactor.interiorDims.Y; y++) { for (int z = 1; z <= Reactor.interiorDims.Z; z++) { for (int x = 1; x <= Reactor.interiorDims.X; x++) { Block block = Reactor.BlockAt(new Point3D(x, y, z)); NbtCompound palettenbt = GetNbtCompound(block); if (!listPalette.Contains(block.DisplayName)) { listPalette.Add(block.DisplayName); palette.Add(palettenbt); } NbtCompound blocknbt = new NbtCompound(); if (block.DisplayName.Contains("Active")) { blocknbt.Add(CreateActiveCooler(x - 1, y - 1, z - 1)); } blocknbt.Add(new NbtList("pos", new List <NbtInt> { new NbtInt(x - 1), new NbtInt(y - 1), new NbtInt(z - 1) })); blocknbt.Add(new NbtInt("state", listPalette.IndexOf(block.DisplayName))); blocks.Add(blocknbt); } } } reactor.Add(new NbtList("size", new List <NbtInt> { new NbtInt((int)Reactor.interiorDims.X), new NbtInt((int)Reactor.interiorDims.Y), new NbtInt((int)Reactor.interiorDims.Z) })); reactor.Add(new NbtList("entities", new List <NbtInt>(), NbtTagType.Compound)); reactor.Add(blocks); reactor.Add(author); reactor.Add(palette); reactor.Add(forgeDataVersion); reactor.Add(dataVersion); return(reactor); }
public override NbtCompound GetCompound() { Compound["x"] = new NbtInt("x", Coordinates.X); Compound["y"] = new NbtInt("y", Coordinates.Y); Compound["z"] = new NbtInt("z", Coordinates.Z); Compound["xStructureOffset"] = new NbtInt("xStructureOffset", Offset.X); Compound["yStructureOffset"] = new NbtInt("yStructureOffset", Offset.Y); Compound["zStructureOffset"] = new NbtInt("zStructureOffset", Offset.Z); Compound["xStructureSize"] = new NbtInt("xStructureSize", Size.X); Compound["yStructureSize"] = new NbtInt("yStructureSize", Size.Y); Compound["zStructureSize"] = new NbtInt("zStructureSize", Size.Z); Compound["showBoundingBox"] = new NbtByte("showBoundingBox", (byte)(ShowBoundingBox ? 1 : 0)); return(Compound); }
public void BasicUndo() { int before = 10; int after = 10; var actions = new Stack <UndoableAction>(); var tag = new NbtInt(); tag.ActionPerformed += a => actions.Push(a); tag.Value = before; tag.Value = after; actions.Pop().Undo(); Assert.AreEqual(tag.Value, before); }
public void NbtIntTest() { object dummy; NbtTag test = new NbtInt(2147483647); Assert.Throws <InvalidCastException>(() => dummy = test.ByteArrayValue); Assert.Throws <InvalidCastException>(() => dummy = test.ByteValue); Assert.AreEqual((double)2147483647, test.DoubleValue); Assert.AreEqual((float)2147483647, test.FloatValue); Assert.Throws <InvalidCastException>(() => dummy = test.IntArrayValue); Assert.AreEqual(2147483647, test.IntValue); Assert.AreEqual(2147483647L, test.LongValue); Assert.Throws <InvalidCastException>(() => dummy = test.ShortValue); Assert.AreEqual("2147483647", test.StringValue); }
public void Renaming() { var tagToRename = new NbtInt("DifferentName", 1); var compound = new NbtCompound { new NbtInt("SameName", 1), tagToRename }; // proper renaming, should not throw tagToRename.Name = "SomeOtherName"; // attempting to use a duplicate name Assert.Throws <ArgumentException>(() => tagToRename.Name = "SameName"); // assigning a null name to a tag inside a compound; should throw Assert.Throws <ArgumentNullException>(() => tagToRename.Name = null); // assigning a null name to a tag that's been removed; should not throw compound.Remove(tagToRename); tagToRename.Name = null; }
public static KeyValuePair <List <int>, NbtTag> GetTagByNode(TreeNode node) { List <int> indexes = GetIndexes(node); NbtTag tag = _nbtFile.RootTag; foreach (int index in indexes) { if (tag is NbtCompound) { tag = ((NbtCompound)tag).ToArray()[index]; } else if (tag is NbtList) { tag = ((NbtList)tag).ToArray()[index]; //TODO DOES NOT SAVE/CHANGE!!!! } else if (tag is NbtByteArray) //TODO cleanup/remove { Debug.WriteLine("USING"); tag = new NbtByte(((NbtByteArray)tag).ByteArrayValue[index]); } else if (tag is NbtIntArray)//TODO cleanup/remove { Debug.WriteLine("USING"); tag = new NbtInt(((NbtIntArray)tag).IntArrayValue[index]); } else { (new AlertForm($"The index {index.ToString()} in Tag {tag.ToString()} could not be found due to the tag probably not having any subnodes!") { Text = "Finding NbtTag from tree error", Icon = SystemIcons.Error }).ShowDialog(); return(new KeyValuePair <List <int>, NbtTag>(indexes, tag));//OR NULL? } } return(new KeyValuePair <List <int>, NbtTag>(indexes, tag)); }
public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return(generator?.GenerateChunkColumn(coordinates)); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue }; for (int i = 0; i < chunk.biomeId.Length; i++) { if (chunk.biomeId[i] > 22) { chunk.biomeId[i] = 0; } } if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y - yoffset; if (yi < 0 || yi >= 128) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); Func <int, byte, byte> dataConverter = (i, b) => b; // Anvil to PE friendly converstion if (Convert.ContainsKey(blockId)) { dataConverter = Convert[blockId].Item2; blockId = Convert[blockId].Item1; } else if (Ignore.BinarySearch(blockId) >= 0) { blockId = 0; } else if (Gaps.BinarySearch(blockId) >= 0) { Log.WarnFormat("Missing material on convert: {0}", blockId); blockId = 133; } if (blockId > 255) { blockId = 41; } //if (yi == 127 && blockId != 0) blockId = 30; if (yi == 0 && (blockId == 8 || blockId == 9)) { blockId = 7; } chunk.SetBlock(x, yi, z, (byte)blockId); byte metadata = Nibble4(data, anvilIndex); metadata = dataConverter(blockId, metadata); chunk.SetMetadata(x, yi, z, metadata); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); var block = BlockFactory.GetBlockById(chunk.GetBlock(x, yi, z)); if (block is BlockStairs || block is StoneSlab || block is WoodSlab) { chunk.SetSkylight(x, yi, z, 0xff); } if (blockId == 43 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 7) { chunk.SetMetadata(x, yi, z, 6); } else if (blockId == 44 && chunk.GetMetadata(x, yi, z) == 15) { chunk.SetMetadata(x, yi, z, 14); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 1) { chunk.SetBlock(x, yi, z, 198); chunk.SetMetadata(x, yi, z, 0); } else if (blockId == 3 && chunk.GetMetadata(x, yi, z) == 2) { chunk.SetBlock(x, yi, z, 143); //Coarse Dirt => Pat chunk.SetMetadata(x, yi, z, 0); // Podzol => (Podzol) } } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; if (blockEntity is Sign) { // Remove the JSON stuff and get the text out of extra data. // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}" CleanSignText(blockEntityTag, "Text1"); CleanSignText(blockEntityTag, "Text2"); CleanSignText(blockEntityTag, "Text3"); CleanSignText(blockEntityTag, "Text4"); } chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
/// <summary> /// Writes out the specified tag. /// </summary> /// <param name="tag">The tag.</param> /// <exception cref="System.ArgumentNullException"><paramref name="tag"/> is <c>null</c>.</exception> /// <exception cref="System.ObjectDisposedException">The stream is closed.</exception> /// <exception cref="System.IO.IOException">An I/O error occured.</exception> public void Write(NbtInt tag) { if (tag == null) throw new ArgumentNullException("tag", "tag is null."); Write(tag, true); }
public void InterfaceImplementation() { // prepare our test lists var referenceList = new List <NbtTag> { new NbtInt(1), new NbtInt(2), new NbtInt(3) }; var testTag = new NbtInt(4); var originalList = new NbtList(referenceList); // check IList implementation IList iList = originalList; CollectionAssert.AreEqual(referenceList, iList); // check IList<NbtTag> implementation IList <NbtTag> iGenericList = originalList; CollectionAssert.AreEqual(referenceList, iGenericList); Assert.IsFalse(iGenericList.IsReadOnly); // check IList.Add referenceList.Add(testTag); iList.Add(testTag); CollectionAssert.AreEqual(referenceList, iList); // check IList.IndexOf Assert.AreEqual(referenceList.IndexOf(testTag), iList.IndexOf(testTag)); Assert.IsTrue(iList.IndexOf(null) < 0); // check IList<NbtTag>.IndexOf Assert.AreEqual(referenceList.IndexOf(testTag), iGenericList.IndexOf(testTag)); Assert.IsTrue(iGenericList.IndexOf(null) < 0); // check IList.Contains Assert.IsTrue(iList.Contains(testTag)); // check IList.Remove iList.Remove(testTag); Assert.IsFalse(iList.Contains(testTag)); // check IList.Insert iList.Insert(0, testTag); Assert.AreEqual(0, iList.IndexOf(testTag)); // check IList.RemoveAt iList.RemoveAt(0); Assert.IsFalse(iList.Contains(testTag)); // check misc IList properties Assert.IsFalse(iList.IsFixedSize); Assert.IsFalse(iList.IsReadOnly); Assert.IsFalse(iList.IsSynchronized); Assert.NotNull(iList.SyncRoot); // check IList.CopyTo var exportTest = new NbtInt[iList.Count]; iList.CopyTo(exportTest, 0); CollectionAssert.AreEqual(iList, exportTest); // check IList.this[int] for (int i = 0; i < iList.Count; i++) { Assert.AreEqual(originalList[i], iList[i]); iList[i] = new NbtInt(i); } // check IList.Clear iList.Clear(); Assert.AreEqual(0, iList.Count); Assert.Less(iList.IndexOf(testTag), 0); }
static BlockFactory() { for (int i = 0; i < byte.MaxValue * 2; i++) { var block = GetBlockById(i); if (block != null) { if (block.IsTransparent) { TransparentBlocks[block.Id] = 1; } if (block.LightLevel > 0) { LuminousBlocks[block.Id] = (byte)block.LightLevel; } } } NameToId = BuildNameToId(); for (int i = 0; i < LegacyToRuntimeId.Length; ++i) { LegacyToRuntimeId[i] = -1; } var assembly = Assembly.GetAssembly(typeof(Block)); lock (lockObj) { Dictionary <string, int> idMapping = new Dictionary <string, int>(ResourceUtil.ReadResource <Dictionary <string, int> >("block_id_map.json", typeof(Block), "Data"), StringComparer.OrdinalIgnoreCase); int runtimeId = 0; BlockPalette = new BlockPalette(); using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.canonical_block_states.nbt")) { do { var compound = Packet.ReadNbtCompound(stream, true); var container = GetBlockStateContainer(compound); container.RuntimeId = runtimeId++; BlockPalette.Add(container); } while (stream.Position < stream.Length); } List <R12ToCurrentBlockMapEntry> legacyStateMap = new List <R12ToCurrentBlockMapEntry>(); using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".Data.r12_to_current_block_map.bin")) { while (stream.Position < stream.Length) { var length = VarInt.ReadUInt32(stream); byte[] bytes = new byte[length]; stream.Read(bytes, 0, bytes.Length); string stringId = Encoding.UTF8.GetString(bytes); bytes = new byte[2]; stream.Read(bytes, 0, bytes.Length); var meta = BitConverter.ToInt16(bytes); var compound = Packet.ReadNbtCompound(stream, true); legacyStateMap.Add(new R12ToCurrentBlockMapEntry(stringId, meta, GetBlockStateContainer(compound))); } } Dictionary <string, List <int> > idToStatesMap = new Dictionary <string, List <int> >(StringComparer.OrdinalIgnoreCase); for (var index = 0; index < BlockPalette.Count; index++) { var state = BlockPalette[index]; List <int> candidates; if (!idToStatesMap.TryGetValue(state.Name, out candidates)) { candidates = new List <int>(); } candidates.Add(index); idToStatesMap[state.Name] = candidates; } foreach (var pair in legacyStateMap) { if (!idMapping.TryGetValue(pair.StringId, out int id)) { continue; } var data = pair.Meta; if (data > 15) { continue; } var mappedState = pair.State; var mappedName = pair.State.Name; if (!idToStatesMap.TryGetValue(mappedName, out var matching)) { continue; } foreach (var match in matching) { var networkState = BlockPalette[match]; var thisStates = new HashSet <IBlockState>(mappedState.States); var otherStates = new HashSet <IBlockState>(networkState.States); otherStates.IntersectWith(thisStates); if (otherStates.Count == thisStates.Count) { BlockPalette[match].Id = id; BlockPalette[match].Data = data; BlockPalette[match].ItemInstance = new ItemPickInstance() { Id = (short)id, Metadata = data, WantNbt = false }; LegacyToRuntimeId[(id << 4) | (byte)data] = match; break; } } } foreach (var record in BlockPalette) { var states = new List <NbtTag>(); foreach (IBlockState state in record.States) { NbtTag stateTag = null; switch (state) { case BlockStateByte blockStateByte: stateTag = new NbtByte(state.Name, blockStateByte.Value); break; case BlockStateInt blockStateInt: stateTag = new NbtInt(state.Name, blockStateInt.Value); break; case BlockStateString blockStateString: stateTag = new NbtString(state.Name, blockStateString.Value); break; default: throw new ArgumentOutOfRangeException(nameof(state)); } states.Add(stateTag); } var nbt = new NbtFile() { BigEndian = false, UseVarInt = true, RootTag = new NbtCompound("states", states) }; byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None); record.StatesCacheNbt = nbtBinary; } } BlockStates = new HashSet <BlockStateContainer>(BlockPalette); }
internal void Write(NbtInt tag, bool writeHeader) { Write(tag.Name, tag.Value, writeHeader); }
public void CopyConstructorTest() { NbtByte byteTag = new NbtByte("byteTag", 1); NbtByte byteTagClone = (NbtByte)byteTag.Clone(); Assert.AreNotSame(byteTag, byteTagClone); Assert.AreEqual(byteTag.Name, byteTagClone.Name); Assert.AreEqual(byteTag.Value, byteTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtByte((NbtByte)null)); NbtByteArray byteArrTag = new NbtByteArray("byteArrTag", new byte[] { 1, 2, 3, 4 }); NbtByteArray byteArrTagClone = (NbtByteArray)byteArrTag.Clone(); Assert.AreNotSame(byteArrTag, byteArrTagClone); Assert.AreEqual(byteArrTag.Name, byteArrTagClone.Name); Assert.AreNotSame(byteArrTag.Value, byteArrTagClone.Value); CollectionAssert.AreEqual(byteArrTag.Value, byteArrTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtByteArray((NbtByteArray)null)); NbtCompound compTag = new NbtCompound("compTag", new NbtTag[] { new NbtByte("innerTag", 1) }); NbtCompound compTagClone = (NbtCompound)compTag.Clone(); Assert.AreNotSame(compTag, compTagClone); Assert.AreEqual(compTag.Name, compTagClone.Name); Assert.AreNotSame(compTag["innerTag"], compTagClone["innerTag"]); Assert.AreEqual(compTag["innerTag"].Name, compTagClone["innerTag"].Name); Assert.AreEqual(compTag["innerTag"].ByteValue, compTagClone["innerTag"].ByteValue); Assert.Throws<ArgumentNullException>(() => new NbtCompound((NbtCompound)null)); NbtDouble doubleTag = new NbtDouble("doubleTag", 1); NbtDouble doubleTagClone = (NbtDouble)doubleTag.Clone(); Assert.AreNotSame(doubleTag, doubleTagClone); Assert.AreEqual(doubleTag.Name, doubleTagClone.Name); Assert.AreEqual(doubleTag.Value, doubleTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtDouble((NbtDouble)null)); NbtFloat floatTag = new NbtFloat("floatTag", 1); NbtFloat floatTagClone = (NbtFloat)floatTag.Clone(); Assert.AreNotSame(floatTag, floatTagClone); Assert.AreEqual(floatTag.Name, floatTagClone.Name); Assert.AreEqual(floatTag.Value, floatTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtFloat((NbtFloat)null)); NbtInt intTag = new NbtInt("intTag", 1); NbtInt intTagClone = (NbtInt)intTag.Clone(); Assert.AreNotSame(intTag, intTagClone); Assert.AreEqual(intTag.Name, intTagClone.Name); Assert.AreEqual(intTag.Value, intTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtInt((NbtInt)null)); NbtIntArray intArrTag = new NbtIntArray("intArrTag", new[] { 1, 2, 3, 4 }); NbtIntArray intArrTagClone = (NbtIntArray)intArrTag.Clone(); Assert.AreNotSame(intArrTag, intArrTagClone); Assert.AreEqual(intArrTag.Name, intArrTagClone.Name); Assert.AreNotSame(intArrTag.Value, intArrTagClone.Value); CollectionAssert.AreEqual(intArrTag.Value, intArrTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtIntArray((NbtIntArray)null)); NbtList listTag = new NbtList("listTag", new NbtTag[] { new NbtByte(1) }); NbtList listTagClone = (NbtList)listTag.Clone(); Assert.AreNotSame(listTag, listTagClone); Assert.AreEqual(listTag.Name, listTagClone.Name); Assert.AreNotSame(listTag[0], listTagClone[0]); Assert.AreEqual(listTag[0].ByteValue, listTagClone[0].ByteValue); Assert.Throws<ArgumentNullException>(() => new NbtList((NbtList)null)); NbtLong longTag = new NbtLong("longTag", 1); NbtLong longTagClone = (NbtLong)longTag.Clone(); Assert.AreNotSame(longTag, longTagClone); Assert.AreEqual(longTag.Name, longTagClone.Name); Assert.AreEqual(longTag.Value, longTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtLong((NbtLong)null)); NbtShort shortTag = new NbtShort("shortTag", 1); NbtShort shortTagClone = (NbtShort)shortTag.Clone(); Assert.AreNotSame(shortTag, shortTagClone); Assert.AreEqual(shortTag.Name, shortTagClone.Name); Assert.AreEqual(shortTag.Value, shortTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtShort((NbtShort)null)); NbtString stringTag = new NbtString("stringTag", "foo"); NbtString stringTagClone = (NbtString)stringTag.Clone(); Assert.AreNotSame(stringTag, stringTagClone); Assert.AreEqual(stringTag.Name, stringTagClone.Name); Assert.AreEqual(stringTag.Value, stringTagClone.Value); Assert.Throws<ArgumentNullException>(() => new NbtString((NbtString)null)); }
public static ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz)); if (!File.Exists(filePath)) { return(generator.GenerateChunkColumn(coordinates)); } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { return(generator.GenerateChunkColumn(coordinates)); } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue }; for (int i = 0; i < chunk.biomeId.Length; i++) { if (chunk.biomeId[i] > 22) { chunk.biomeId[i] = 0; } } if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { int sy = sectionTag["Y"].ByteValue * 16; byte[] blocks = sectionTag["Blocks"].ByteArrayValue; byte[] data = sectionTag["Data"].ByteArrayValue; NbtTag addTag = sectionTag["Add"]; byte[] adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } byte[] blockLight = sectionTag["BlockLight"].ByteArrayValue; byte[] skyLight = sectionTag["SkyLight"].ByteArrayValue; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { int yi = sy + y - yoffset; if (yi < 0 || yi >= 128) { continue; } int anvilIndex = y * 16 * 16 + z * 16 + x; int blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); // Anvil to PE friendly converstion if (blockId == 125) { blockId = 5; } else if (blockId == 126) { blockId = 158; } else if (blockId == 75) { blockId = 50; } else if (blockId == 76) { blockId = 50; } else if (blockId == 123) { blockId = 89; } else if (blockId == 124) { blockId = 89; } else if (blockId == 152) { blockId = 73; } else if (_ignore.BinarySearch(blockId) >= 0) { blockId = 0; } else if (_gaps.BinarySearch(blockId) >= 0) { Debug.WriteLine("Missing material: " + blockId); blockId = 133; } if (blockId > 255) { blockId = 41; } if (yi == 127 && blockId != 0) { blockId = 30; } if (yi == 0 && (blockId == 8 || blockId == 9 /*|| blockId == 0*/)) { blockId = 7; } //if (blockId != 0) blockId = 41; chunk.SetBlock(x, yi, z, (byte)blockId); chunk.SetMetadata(x, yi, z, Nibble4(data, anvilIndex)); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); } } } } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag; string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
public static string ToSnbt(this NbtInt tag, SnbtOptions options) => tag.Value.ToString();
static BlockFactory() { for (int i = 0; i < byte.MaxValue * 2; i++) { var block = GetBlockById(i); if (block != null) { if (block.IsTransparent) { TransparentBlocks[block.Id] = 1; } if (block.LightLevel > 0) { LuminousBlocks[block.Id] = (byte)block.LightLevel; } } } NameToId = BuildNameToId(); for (int i = 0; i < LegacyToRuntimeId.Length; ++i) { LegacyToRuntimeId[i] = -1; } var assembly = Assembly.GetAssembly(typeof(Block)); lock (lockObj) { Dictionary <string, int> idMapping; using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".block_id_map.json")) using (var reader = new StreamReader(stream)) { idMapping = JsonConvert.DeserializeObject <Dictionary <string, int> >(reader.ReadToEnd()); } Dictionary <string, short> itemIdMapping; using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".item_id_map.json")) using (var reader = new StreamReader(stream)) { itemIdMapping = JsonConvert.DeserializeObject <Dictionary <string, short> >(reader.ReadToEnd()); } int runtimeId = 0; BlockPalette = new BlockPalette(); using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".canonical_block_states.nbt")) { var reader = new NbtFile(); reader.UseVarInt = true; reader.AllowAlternativeRootTag = true; do { reader.LoadFromStream(stream, NbtCompression.AutoDetect); var record = new BlockStateContainer(); var tag = reader.RootTag; string name = tag["name"].StringValue; record.Name = name; record.States = new List <IBlockState>(); if (idMapping.TryGetValue(name, out var id)) { record.Id = id; } var states = tag["states"]; if (states != null && states is NbtCompound compound) { foreach (var stateEntry in compound) { switch (stateEntry) { case NbtInt nbtInt: record.States.Add(new BlockStateInt() { Name = nbtInt.Name, Value = nbtInt.Value }); break; case NbtByte nbtByte: record.States.Add(new BlockStateByte() { Name = nbtByte.Name, Value = nbtByte.Value }); break; case NbtString nbtString: record.States.Add(new BlockStateString() { Name = nbtString.Name, Value = nbtString.Value }); break; } } } if (itemIdMapping.TryGetValue(name, out var itemId)) { record.ItemInstance = new ItemPickInstance() { Id = itemId, WantNbt = false, Metadata = 0 }; } record.RuntimeId = runtimeId++; BlockPalette.Add(record); } while (stream.Position < stream.Length); } /*using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json")) * using (var reader = new StreamReader(stream)) * { * BlockPalette = BlockPalette.FromJson(reader.ReadToEnd()); * }*/ foreach (var record in BlockPalette) { var states = new List <NbtTag>(); foreach (IBlockState state in record.States) { NbtTag stateTag = null; switch (state) { case BlockStateByte blockStateByte: stateTag = new NbtByte(state.Name, blockStateByte.Value); break; case BlockStateInt blockStateInt: stateTag = new NbtInt(state.Name, blockStateInt.Value); break; case BlockStateString blockStateString: stateTag = new NbtString(state.Name, blockStateString.Value); break; default: throw new ArgumentOutOfRangeException(nameof(state)); } states.Add(stateTag); } var nbt = new NbtFile() { BigEndian = false, UseVarInt = true, RootTag = new NbtCompound("states", states) }; byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None); record.StatesCacheNbt = nbtBinary; } } int palletSize = BlockPalette.Count; for (int i = 0; i < palletSize; i++) { if (BlockPalette[i].Data > 15) { continue; // TODO: figure out why palette contains blocks with meta more than 15 } if (BlockPalette[i].Data == -1) { continue; // These are blockstates that does not have a metadata mapping } LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i; } BlockStates = new HashSet <BlockStateContainer>(BlockPalette); }
public void Renaming() { var tagToRename = new NbtInt("DifferentName", 1); var compound = new NbtCompound { new NbtInt("SameName", 1), tagToRename }; // proper renaming, should not throw tagToRename.Name = "SomeOtherName"; // attempting to use a duplicate name Assert.Throws<ArgumentException>(() => tagToRename.Name = "SameName"); // assigning a null name to a tag inside a compound; should throw Assert.Throws<ArgumentNullException>(() => tagToRename.Name = null); // assigning a null name to a tag inside a compound; should not throw compound.Remove(tagToRename); tagToRename.Name = null; }
public void NbtIntTest() { object dummy; NbtTag test = new NbtInt( 2147483647 ); Assert.Throws<InvalidCastException>( () => dummy = test.ByteArrayValue ); Assert.Throws<InvalidCastException>( () => dummy = test.ByteValue ); Assert.AreEqual( (double)2147483647, test.DoubleValue ); Assert.AreEqual( (float)2147483647, test.FloatValue ); Assert.Throws<InvalidCastException>( () => dummy = test.IntArrayValue ); Assert.AreEqual( 2147483647, test.IntValue ); Assert.AreEqual( 2147483647L, test.LongValue ); Assert.Throws<InvalidCastException>( () => dummy = test.ShortValue ); Assert.AreEqual( "2147483647", test.StringValue ); }
/** * BEFORE any digits, requiring backtracking. */ private NbtTag ParseNumber() { bool more = true; NbtTagType type = NbtTagType.Int; String literal = ""; while (more) { char next; try { next = NextChar(); } catch (Exception) { next = ' '; //just end the number } if (next <= '9' && next >= '0' || next == '-') { literal += next; } else if (next == '.') { literal += next; type = NbtTagType.Double; } else { more = false; switch (next) { case 'l': case 'L': type = NbtTagType.Long; break; case 'b': case 'B': type = NbtTagType.Byte; break; case 'f': case 'F': type = NbtTagType.Float; break; default: //End of number, put it back. Position--; break; } } } NbtTag ret; switch (type) { case NbtTagType.Byte: ret = new NbtByte(byte.Parse(literal)); break; case NbtTagType.Int: ret = new NbtInt(int.Parse(literal)); break; case NbtTagType.Long: ret = new NbtLong(long.Parse(literal)); break; case NbtTagType.Float: ret = new NbtFloat(float.Parse(literal)); break; case NbtTagType.Double: ret = new NbtDouble(double.Parse(literal)); break; default: ret = null; break; } return(ret); }
public static NbtTag Serialize <T>(this T obj, NbtTag tag = null) where T : new() { tag ??= new NbtCompound(string.Empty); if (obj == null) { throw new NullReferenceException(); } PropertyInfo[] properties = obj.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in properties) { var attribute = propertyInfo.GetCustomAttribute(typeof(JsonPropertyNameAttribute)) as JsonPropertyNameAttribute; string propertyName = attribute?.Name ?? propertyInfo.Name; NbtTag nbtTag = tag[propertyName] ?? tag[LowercaseFirst(propertyName)]; if (nbtTag == null) { if (propertyInfo.PropertyType == typeof(bool)) { nbtTag = new NbtByte(propertyName); } else if (propertyInfo.PropertyType == typeof(byte)) { nbtTag = new NbtByte(propertyName); } else if (propertyInfo.PropertyType == typeof(short)) { nbtTag = new NbtShort(propertyName); } else if (propertyInfo.PropertyType == typeof(int)) { nbtTag = new NbtInt(propertyName); } else if (propertyInfo.PropertyType == typeof(long)) { nbtTag = new NbtLong(propertyName); } else if (propertyInfo.PropertyType == typeof(float)) { nbtTag = new NbtFloat(propertyName); } else if (propertyInfo.PropertyType == typeof(double)) { nbtTag = new NbtDouble(propertyName); } else if (propertyInfo.PropertyType == typeof(string)) { nbtTag = new NbtString(propertyName, ""); } else { continue; } } //var mex = property.Body as MemberExpression; //var target = Expression.Lambda(mex.Expression).Compile().DynamicInvoke(); switch (nbtTag.TagType) { case NbtTagType.Unknown: break; case NbtTagType.End: break; case NbtTagType.Byte: if (propertyInfo.PropertyType == typeof(bool)) { tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)((bool)propertyInfo.GetValue(obj) ? 1 : 0)); } else { tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)propertyInfo.GetValue(obj)); } break; case NbtTagType.Short: tag[nbtTag.Name] = new NbtShort(nbtTag.Name, (short)propertyInfo.GetValue(obj)); break; case NbtTagType.Int: if (propertyInfo.PropertyType == typeof(bool)) { tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (bool)propertyInfo.GetValue(obj) ? 1 : 0); } else { tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (int)propertyInfo.GetValue(obj)); } break; case NbtTagType.Long: tag[nbtTag.Name] = new NbtLong(nbtTag.Name, (long)propertyInfo.GetValue(obj)); break; case NbtTagType.Float: tag[nbtTag.Name] = new NbtFloat(nbtTag.Name, (float)propertyInfo.GetValue(obj)); break; case NbtTagType.Double: tag[nbtTag.Name] = new NbtDouble(nbtTag.Name, (double)propertyInfo.GetValue(obj)); break; case NbtTagType.ByteArray: tag[nbtTag.Name] = new NbtByteArray(nbtTag.Name, (byte[])propertyInfo.GetValue(obj)); break; case NbtTagType.String: tag[nbtTag.Name] = new NbtString(nbtTag.Name, (string)propertyInfo.GetValue(obj) ?? ""); break; case NbtTagType.List: break; case NbtTagType.Compound: break; case NbtTagType.IntArray: tag[nbtTag.Name] = new NbtIntArray(nbtTag.Name, (int[])propertyInfo.GetValue(obj)); break; } } return(tag); }
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); }
public ChunkColumn GetChunk(int X, int Z) { var width = 32; var depth = 32; var rx = X >> 5; var rz = Z >> 5; var filePath = Path.Combine(_basePath, string.Format(@"region\r.{0}.{1}.mca", rx, rz)); if (!File.Exists(filePath)) { return(_backEndGenerator.GenerateChunkColumn(new Vector2(X, Z))); } using (var regionFile = File.OpenRead(filePath)) { var buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); var xi = (X % width); if (xi < 0) { xi += 32; } var zi = (Z % depth); if (zi < 0) { zi += 32; } var tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); var offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); var offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; var length = regionFile.ReadByte(); //if (offset == 0 || length == 0) return _backEndGenerator.GenerateChunkColumn(new Vector2(X, Z)); if (offset == 0 || length == 0) { return(_backEndGenerator.GenerateChunkColumn(new Vector2(X, Z))); } regionFile.Seek(offset, SeekOrigin.Begin); var waste = new byte[4]; regionFile.Read(waste, 0, 4); var compressionMode = regionFile.ReadByte(); var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); var dataTag = nbt.RootTag["Level"]; var sections = dataTag["Sections"] as NbtList; var chunk = new ChunkColumn { X = X, Z = Z, BiomeId = dataTag["Biomes"].ByteArrayValue }; for (var i = 0; i < chunk.BiomeId.Length; i++) { if (chunk.BiomeId[i] > 22) { chunk.BiomeId[i] = 0; } } if (chunk.BiomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (var sectionTag in sections) { var sy = sectionTag["Y"].ByteValue * 16; var blocks = sectionTag["Blocks"].ByteArrayValue; var data = sectionTag["Data"].ByteArrayValue; var addTag = sectionTag["Add"]; var adddata = new byte[2048]; if (addTag != null) { adddata = addTag.ByteArrayValue; } var blockLight = sectionTag["BlockLight"].ByteArrayValue; var skyLight = sectionTag["SkyLight"].ByteArrayValue; for (var x = 0; x < 16; x++) { for (var z = 0; z < 16; z++) { for (var y = 0; y < 16; y++) { var yi = sy + y - _waterOffsetY; if (yi < 0 || yi >= 256) { continue; } var anvilIndex = y * 16 * 16 + z * 16 + x; var blockId = blocks[anvilIndex] + (Nibble4(adddata, anvilIndex) << 8); var b = BlockFactory.GetBlockById((ushort)blockId); b.Metadata = Nibble4(data, anvilIndex); chunk.SetBlock(x, yi, z, b); chunk.SetBlocklight(x, yi, z, Nibble4(blockLight, anvilIndex)); chunk.SetSkylight(x, yi, z, Nibble4(skyLight, anvilIndex)); } } } } var entities = dataTag["Entities"] as NbtList; var tileEntities = dataTag["TileEntities"] as NbtList; if (tileEntities != null) { foreach (var nbtTag in tileEntities) { var blockEntityTag = (NbtCompound)nbtTag; string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - _waterOffsetY; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); TileEntity blockEntity = TileEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; chunk.SetBlockEntity(new Vector3(x, y, z), blockEntityTag); } } } var tileTicks = dataTag["TileTicks"] as NbtList; chunk.IsDirty = false; return(chunk); } }
public void CopyConstructorTest() { NbtByte byteTag = new NbtByte("byteTag", 1); NbtByte byteTagClone = (NbtByte)byteTag.Clone(); Assert.AreNotSame(byteTag, byteTagClone); Assert.AreEqual(byteTag.Name, byteTagClone.Name); Assert.AreEqual(byteTag.Value, byteTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtByte((NbtByte)null)); NbtByteArray byteArrTag = new NbtByteArray("byteArrTag", new byte[] { 1, 2, 3, 4 }); NbtByteArray byteArrTagClone = (NbtByteArray)byteArrTag.Clone(); Assert.AreNotSame(byteArrTag, byteArrTagClone); Assert.AreEqual(byteArrTag.Name, byteArrTagClone.Name); Assert.AreNotSame(byteArrTag.Value, byteArrTagClone.Value); CollectionAssert.AreEqual(byteArrTag.Value, byteArrTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtByteArray((NbtByteArray)null)); NbtCompound compTag = new NbtCompound("compTag", new NbtTag[] { new NbtByte("innerTag", 1) }); NbtCompound compTagClone = (NbtCompound)compTag.Clone(); Assert.AreNotSame(compTag, compTagClone); Assert.AreEqual(compTag.Name, compTagClone.Name); Assert.AreNotSame(compTag["innerTag"], compTagClone["innerTag"]); Assert.AreEqual(compTag["innerTag"].Name, compTagClone["innerTag"].Name); Assert.AreEqual(compTag["innerTag"].ByteValue, compTagClone["innerTag"].ByteValue); Assert.Throws <ArgumentNullException>(() => new NbtCompound((NbtCompound)null)); NbtDouble doubleTag = new NbtDouble("doubleTag", 1); NbtDouble doubleTagClone = (NbtDouble)doubleTag.Clone(); Assert.AreNotSame(doubleTag, doubleTagClone); Assert.AreEqual(doubleTag.Name, doubleTagClone.Name); Assert.AreEqual(doubleTag.Value, doubleTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtDouble((NbtDouble)null)); NbtFloat floatTag = new NbtFloat("floatTag", 1); NbtFloat floatTagClone = (NbtFloat)floatTag.Clone(); Assert.AreNotSame(floatTag, floatTagClone); Assert.AreEqual(floatTag.Name, floatTagClone.Name); Assert.AreEqual(floatTag.Value, floatTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtFloat((NbtFloat)null)); NbtInt intTag = new NbtInt("intTag", 1); NbtInt intTagClone = (NbtInt)intTag.Clone(); Assert.AreNotSame(intTag, intTagClone); Assert.AreEqual(intTag.Name, intTagClone.Name); Assert.AreEqual(intTag.Value, intTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtInt((NbtInt)null)); NbtIntArray intArrTag = new NbtIntArray("intArrTag", new[] { 1, 2, 3, 4 }); NbtIntArray intArrTagClone = (NbtIntArray)intArrTag.Clone(); Assert.AreNotSame(intArrTag, intArrTagClone); Assert.AreEqual(intArrTag.Name, intArrTagClone.Name); Assert.AreNotSame(intArrTag.Value, intArrTagClone.Value); CollectionAssert.AreEqual(intArrTag.Value, intArrTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtIntArray((NbtIntArray)null)); NbtList listTag = new NbtList("listTag", new NbtTag[] { new NbtByte(1) }); NbtList listTagClone = (NbtList)listTag.Clone(); Assert.AreNotSame(listTag, listTagClone); Assert.AreEqual(listTag.Name, listTagClone.Name); Assert.AreNotSame(listTag[0], listTagClone[0]); Assert.AreEqual(listTag[0].ByteValue, listTagClone[0].ByteValue); Assert.Throws <ArgumentNullException>(() => new NbtList((NbtList)null)); NbtLong longTag = new NbtLong("longTag", 1); NbtLong longTagClone = (NbtLong)longTag.Clone(); Assert.AreNotSame(longTag, longTagClone); Assert.AreEqual(longTag.Name, longTagClone.Name); Assert.AreEqual(longTag.Value, longTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtLong((NbtLong)null)); NbtShort shortTag = new NbtShort("shortTag", 1); NbtShort shortTagClone = (NbtShort)shortTag.Clone(); Assert.AreNotSame(shortTag, shortTagClone); Assert.AreEqual(shortTag.Name, shortTagClone.Name); Assert.AreEqual(shortTag.Value, shortTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtShort((NbtShort)null)); NbtString stringTag = new NbtString("stringTag", "foo"); NbtString stringTagClone = (NbtString)stringTag.Clone(); Assert.AreNotSame(stringTag, stringTagClone); Assert.AreEqual(stringTag.Name, stringTagClone.Name); Assert.AreEqual(stringTag.Value, stringTagClone.Value); Assert.Throws <ArgumentNullException>(() => new NbtString((NbtString)null)); }
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); }
public void AddingAndRemoving() { var foo = new NbtInt("Foo"); var test = new NbtCompound { foo }; // adding duplicate object Assert.Throws <ArgumentException>(() => test.Add(foo)); // adding duplicate name Assert.Throws <ArgumentException>(() => test.Add(new NbtByte("Foo"))); // adding unnamed tag Assert.Throws <ArgumentException>(() => test.Add(new NbtInt())); // adding null Assert.Throws <ArgumentNullException>(() => test.Add(null)); // adding tag to self Assert.Throws <ArgumentException>(() => test.Add(test)); // contains existing name/object Assert.True(test.Contains("Foo")); Assert.Contains(foo, test); Assert.Throws <ArgumentNullException>(() => test.Contains((string)null)); Assert.Throws <ArgumentNullException>(() => test.Contains((NbtTag)null)); // contains non-existent name Assert.False(test.Contains("Bar")); // contains existing name / different object Assert.DoesNotContain(new NbtInt("Foo"), test); // removing non-existent name Assert.Throws <ArgumentNullException>(() => test.Remove((string)null)); Assert.False(test.Remove("Bar")); // removing existing name Assert.True(test.Remove("Foo")); // removing non-existent name Assert.False(test.Remove("Foo")); // re-adding object test.Add(foo); // removing existing object Assert.Throws <ArgumentNullException>(() => test.Remove((NbtTag)null)); Assert.True(test.Remove(foo)); Assert.False(test.Remove(foo)); // clearing an empty NbtCompound Assert.Empty(test); test.Clear(); // re-adding after clearing test.Add(foo); Assert.Single(test); // clearing a non-empty NbtCompound test.Clear(); Assert.Empty(test); }
public static NbtTag TreeToNBT(TreeNodeCollection tree) { NbtTag NBTTag = null; if (tree != null) { foreach (TreeNode node in tree) { string value = node.Text.Replace($"{node.Name}: ", string.Empty).Replace(".", ",");//TODO , or . by language try { switch (node.ImageKey) { case "buttonstring.png": { NBTTag = new NbtString(node.Name, value); break; } case "buttonint.png": { NBTTag = new NbtInt(node.Name, int.Parse(value)); break; } case "buttonbyte.png": { NBTTag = new NbtByte(node.Name, byte.Parse(value)); break; } case "buttonlong.png": { NBTTag = new NbtLong(node.Name, long.Parse(value)); break; } case "buttonshort.png": { NBTTag = new NbtShort(node.Name, short.Parse(value)); break; } case "buttonfloat.png": { NBTTag = new NbtFloat(node.Name, float.Parse(value)); break; } case "buttondouble.png": { NBTTag = new NbtDouble(node.Name, double.Parse(value)); break; } case "buttoncompound.png": { NBTTag = new NbtCompound(node.Name); foreach (object c in node.Nodes) { (new AlertForm(c.ToString())).ShowDialog(); if (c is TreeNode && ((TreeNode)c).Nodes.Count > 0) { ((NbtCompound)NBTTag).Add(TreeToNBT(((TreeNode)c).Nodes)); } else { (new AlertForm(c.GetType().ToString())).ShowDialog(); } } break; } case "buttonlist.png": { NBTTag = new NbtList(node.Name); foreach (object c in node.Nodes) { (new AlertForm(c.ToString())).ShowDialog(); if (c is TreeNode && ((TreeNode)c).Nodes.Count > 0) { ((NbtList)NBTTag).Add(TreeToNBT(((TreeNode)c).Nodes)); } else { (new AlertForm(c.GetType().ToString())).ShowDialog(); } } break; } case "buttonbytearray.png": { NBTTag = new NbtByteArray(node.Name, NodesToByteArray(node.Nodes)); (new AlertForm(NBTTag.ToString())).ShowDialog(); break; } case "buttonintarray.png": { NBTTag = new NbtIntArray(node.Name, NodesToIntArray(node.Nodes)); (new AlertForm(NBTTag.ToString())).ShowDialog(); break; } default: { throw new WarningException($"Warning: unhandeled node {node.ImageKey} can not be edited"); } } } catch (Exception exception) { if (exception is InvalidOperationException || exception is WarningException) { new AlertForm(exception.ToString()) { Text = "Warning!", Icon = System.Drawing.SystemIcons.Warning }.ShowDialog(); } else { new AlertForm(exception.ToString()) { Text = exception.GetType().ToString(), Icon = System.Drawing.SystemIcons.Error }.ShowDialog(); } } } } return(NBTTag); }
public void Renaming() { NbtCompound compound = new NbtCompound(); compound.Add( new NbtInt( "SameName", 1 ) ); var tagToRename = new NbtInt( "DifferentName", 1 ); compound.Add( tagToRename ); Assert.DoesNotThrow( () => tagToRename.Name = "SomeOtherName" ); Assert.Throws<ArgumentException>( () => tagToRename.Name = "SameName" ); Assert.Throws<ArgumentNullException>( () => tagToRename.Name = null ); }
public void InterfaceImplementation() { // prepare our test lists var referenceList = new List<NbtTag> { new NbtInt(1), new NbtInt(2), new NbtInt(3) }; var testTag = new NbtInt(4); var originalList = new NbtList(referenceList); // check IList implementation IList iList = originalList; CollectionAssert.AreEqual(referenceList, iList); // check IList<NbtTag> implementation IList<NbtTag> iGenericList = originalList; CollectionAssert.AreEqual(referenceList, iGenericList); Assert.IsFalse(iGenericList.IsReadOnly); // check IList.Add referenceList.Add(testTag); iList.Add(testTag); CollectionAssert.AreEqual(referenceList, iList); // check IList.IndexOf Assert.AreEqual(referenceList.IndexOf(testTag), iList.IndexOf(testTag)); Assert.IsTrue(iList.IndexOf(null) < 0); // check IList<NbtTag>.IndexOf Assert.AreEqual(referenceList.IndexOf(testTag), iGenericList.IndexOf(testTag)); Assert.IsTrue(iGenericList.IndexOf(null) < 0); // check IList.Contains Assert.IsTrue(iList.Contains(testTag)); // check IList.Remove iList.Remove(testTag); Assert.IsFalse(iList.Contains(testTag)); // check IList.Insert iList.Insert(0, testTag); Assert.AreEqual(0, iList.IndexOf(testTag)); // check IList.RemoveAt iList.RemoveAt(0); Assert.IsFalse(iList.Contains(testTag)); // check misc IList properties Assert.IsFalse(iList.IsFixedSize); Assert.IsFalse(iList.IsReadOnly); Assert.IsFalse(iList.IsSynchronized); Assert.NotNull(iList.SyncRoot); // check IList.CopyTo var exportTest = new NbtInt[iList.Count]; iList.CopyTo(exportTest, 0); CollectionAssert.AreEqual(iList, exportTest); // check IList.this[int] for (int i = 0; i < iList.Count; i++) { Assert.AreEqual(originalList[i], iList[i]); iList[i] = new NbtInt(i); } // check IList.Clear iList.Clear(); Assert.AreEqual(0, iList.Count); Assert.Less(iList.IndexOf(testTag), 0); }
public ChunkColumn GetChunk(ChunkCoordinates coordinates, string basePath, IWorldProvider generator, int yoffset) { int width = 32; int depth = 32; int rx = coordinates.X >> 5; int rz = coordinates.Z >> 5; string filePath = Path.Combine(basePath, string.Format(@"region{2}r.{0}.{1}.mca", rx, rz, Path.DirectorySeparatorChar)); if (!File.Exists(filePath)) { var chunkColumn = generator?.GenerateChunkColumn(coordinates); if (chunkColumn != null) { chunkColumn.NeedSave = true; } return(chunkColumn); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } using (var regionFile = File.OpenRead(filePath)) { byte[] buffer = new byte[8192]; regionFile.Read(buffer, 0, 8192); int xi = (coordinates.X % width); if (xi < 0) { xi += 32; } int zi = (coordinates.Z % depth); if (zi < 0) { zi += 32; } int tableOffset = (xi + zi * width) * 4; regionFile.Seek(tableOffset, SeekOrigin.Begin); byte[] offsetBuffer = new byte[4]; regionFile.Read(offsetBuffer, 0, 3); Array.Reverse(offsetBuffer); int offset = BitConverter.ToInt32(offsetBuffer, 0) << 4; byte[] bytes = BitConverter.GetBytes(offset >> 4); Array.Reverse(bytes); if (offset != 0 && offsetBuffer[0] != bytes[0] && offsetBuffer[1] != bytes[1] && offsetBuffer[2] != bytes[2]) { throw new Exception($"Not the same buffer\n{Package.HexDump(offsetBuffer)}\n{Package.HexDump(bytes)}"); } int length = regionFile.ReadByte(); if (offset == 0 || length == 0) { var chunkColumn = generator?.GenerateChunkColumn(coordinates); if (chunkColumn != null) { chunkColumn.NeedSave = true; } return(chunkColumn); //return new ChunkColumn //{ // x = coordinates.X, // z = coordinates.Z, //}; } regionFile.Seek(offset, SeekOrigin.Begin); byte[] waste = new byte[4]; regionFile.Read(waste, 0, 4); int compressionMode = regionFile.ReadByte(); if (compressionMode != 0x02) { throw new Exception($"CX={coordinates.X}, CZ={coordinates.Z}, NBT wrong compression. Expected 0x02, got 0x{compressionMode :X2}. " + $"Offset={offset}, length={length}\n{Package.HexDump(waste)}"); } var nbt = new NbtFile(); nbt.LoadFromStream(regionFile, NbtCompression.ZLib); NbtTag dataTag = nbt.RootTag["Level"]; NbtList sections = dataTag["Sections"] as NbtList; ChunkColumn chunk = new ChunkColumn { x = coordinates.X, z = coordinates.Z, biomeId = dataTag["Biomes"].ByteArrayValue, isAllAir = true }; if (chunk.biomeId.Length > 256) { throw new Exception(); } // This will turn into a full chunk column foreach (NbtTag sectionTag in sections) { ReadSection(yoffset, sectionTag, chunk); } NbtList entities = dataTag["Entities"] as NbtList; NbtList blockEntities = dataTag["TileEntities"] as NbtList; if (blockEntities != null) { foreach (var nbtTag in blockEntities) { var blockEntityTag = (NbtCompound)nbtTag.Clone(); string entityId = blockEntityTag["id"].StringValue; int x = blockEntityTag["x"].IntValue; int y = blockEntityTag["y"].IntValue - yoffset; int z = blockEntityTag["z"].IntValue; blockEntityTag["y"] = new NbtInt("y", y); BlockEntity blockEntity = BlockEntityFactory.GetBlockEntityById(entityId); if (blockEntity != null) { blockEntityTag.Name = string.Empty; if (blockEntity is Sign) { // Remove the JSON stuff and get the text out of extra data. // TAG_String("Text2"): "{"extra":["10c a loaf!"],"text":""}" CleanSignText(blockEntityTag, "Text1"); CleanSignText(blockEntityTag, "Text2"); CleanSignText(blockEntityTag, "Text3"); CleanSignText(blockEntityTag, "Text4"); } else if (blockEntity is ChestBlockEntity) { NbtList items = (NbtList)blockEntityTag["Items"]; if (items != null) { //for (byte i = 0; i < items.Count; i++) //{ // NbtCompound item = (NbtCompound) items[i]; // item.Add(new NbtShort("OriginalDamage", item["Damage"].ShortValue)); // byte metadata = (byte) (item["Damage"].ShortValue & 0xff); // item.Remove("Damage"); // item.Add(new NbtByte("Damage", metadata)); //} } } chunk.SetBlockEntity(new BlockCoordinates(x, y, z), blockEntityTag); } } } //NbtList tileTicks = dataTag["TileTicks"] as NbtList; chunk.isDirty = false; return(chunk); } }
public void Write_IntTag() { // Arrange MemoryStream stream = new MemoryStream(); NbtWriter writer = new NbtWriter(stream); NbtInt tag = new NbtInt("asdf", 305419896); byte[] expected = new byte[] { 0x03, 0x00, 0x04, 0x61, 0x73, 0x64, 0x66, 0x12, 0x34, 0x56, 0x78 }; // Act writer.Write(tag); byte[] result = stream.ToArray(); // Assert CollectionAssert.AreEqual(expected, result); }
public void SetPropertyValue <T>(NbtTag tag, Expression <Func <T> > property, bool upperFirst = true) { var propertyInfo = ((MemberExpression)property.Body).Member as PropertyInfo; if (propertyInfo == null) { throw new ArgumentException("The lambda expression 'property' should point to a valid Property"); } NbtTag nbtTag = tag[propertyInfo.Name]; if (nbtTag == null) { nbtTag = tag[LowercaseFirst(propertyInfo.Name)]; } if (nbtTag == null) { if (propertyInfo.PropertyType == typeof(bool)) { nbtTag = new NbtByte(propertyInfo.Name); } else if (propertyInfo.PropertyType == typeof(byte)) { nbtTag = new NbtByte(LowercaseFirst(propertyInfo.Name)); } else if (propertyInfo.PropertyType == typeof(short)) { nbtTag = new NbtShort(LowercaseFirst(propertyInfo.Name)); } else if (propertyInfo.PropertyType == typeof(int)) { nbtTag = new NbtInt(LowercaseFirst(propertyInfo.Name)); } else if (propertyInfo.PropertyType == typeof(long)) { nbtTag = new NbtLong(LowercaseFirst(propertyInfo.Name)); } else if (propertyInfo.PropertyType == typeof(float)) { nbtTag = new NbtFloat(LowercaseFirst(propertyInfo.Name)); } else if (propertyInfo.PropertyType == typeof(double)) { nbtTag = new NbtDouble(LowercaseFirst(propertyInfo.Name)); } else if (propertyInfo.PropertyType == typeof(string)) { nbtTag = new NbtString(LowercaseFirst(propertyInfo.Name), ""); } else { return; } } var mex = property.Body as MemberExpression; var target = Expression.Lambda(mex.Expression).Compile().DynamicInvoke(); switch (nbtTag.TagType) { case NbtTagType.Unknown: break; case NbtTagType.End: break; case NbtTagType.Byte: if (propertyInfo.PropertyType == typeof(bool)) { tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)((bool)propertyInfo.GetValue(target) ? 1 : 0)); } else { tag[nbtTag.Name] = new NbtByte(nbtTag.Name, (byte)propertyInfo.GetValue(target)); } break; case NbtTagType.Short: tag[nbtTag.Name] = new NbtShort(nbtTag.Name, (short)propertyInfo.GetValue(target)); break; case NbtTagType.Int: if (propertyInfo.PropertyType == typeof(bool)) { tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (bool)propertyInfo.GetValue(target) ? 1 : 0); } else { tag[nbtTag.Name] = new NbtInt(nbtTag.Name, (int)propertyInfo.GetValue(target)); } break; case NbtTagType.Long: tag[nbtTag.Name] = new NbtLong(nbtTag.Name, (long)propertyInfo.GetValue(target)); break; case NbtTagType.Float: tag[nbtTag.Name] = new NbtFloat(nbtTag.Name, (float)propertyInfo.GetValue(target)); break; case NbtTagType.Double: tag[nbtTag.Name] = new NbtDouble(nbtTag.Name, (double)propertyInfo.GetValue(target)); break; case NbtTagType.ByteArray: tag[nbtTag.Name] = new NbtByteArray(nbtTag.Name, (byte[])propertyInfo.GetValue(target)); break; case NbtTagType.String: tag[nbtTag.Name] = new NbtString(nbtTag.Name, (string)propertyInfo.GetValue(target) ?? ""); break; case NbtTagType.List: break; case NbtTagType.Compound: break; case NbtTagType.IntArray: tag[nbtTag.Name] = new NbtIntArray(nbtTag.Name, (int[])propertyInfo.GetValue(target)); break; default: throw new ArgumentOutOfRangeException(); } //return (T) propertyInfo.GetValue(target); }
static BlockFactory() { for (int i = 0; i < byte.MaxValue * 2; i++) { var block = GetBlockById(i); if (block != null) { if (block.IsTransparent) { TransparentBlocks[block.Id] = 1; } if (block.LightLevel > 0) { LuminousBlocks[block.Id] = (byte)block.LightLevel; } } } NameToId = BuildNameToId(); for (int i = 0; i < LegacyToRuntimeId.Length; ++i) { LegacyToRuntimeId[i] = -1; } var assembly = Assembly.GetAssembly(typeof(Block)); lock (lockObj) { using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json")) using (var reader = new StreamReader(stream)) { BlockPalette = BlockPalette.FromJson(reader.ReadToEnd()); } foreach (var record in BlockPalette) { var states = new List <NbtTag>(); foreach (IBlockState state in record.States) { NbtTag stateTag = null; switch (state) { case BlockStateByte blockStateByte: stateTag = new NbtByte(state.Name, blockStateByte.Value); break; case BlockStateInt blockStateInt: stateTag = new NbtInt(state.Name, blockStateInt.Value); break; case BlockStateString blockStateString: stateTag = new NbtString(state.Name, blockStateString.Value); break; default: throw new ArgumentOutOfRangeException(nameof(state)); } states.Add(stateTag); } var nbt = new NbtFile() { BigEndian = false, UseVarInt = true, RootTag = new NbtCompound("states", states) }; byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None); record.StatesCacheNbt = nbtBinary; } } int palletSize = BlockPalette.Count; for (int i = 0; i < palletSize; i++) { if (BlockPalette[i].Data > 15) { continue; // TODO: figure out why palette contains blocks with meta more than 15 } if (BlockPalette[i].Data == -1) { continue; // These are blockstates that does not have a metadata mapping } LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i; } BlockStates = new HashSet <BlockStateContainer>(BlockPalette); }
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 ) ); }