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() { var secondList = new NbtList { new NbtByte() }; var testList = new NbtList(); // Trying to set an out-of-range element Assert.Throws<ArgumentOutOfRangeException>(() => testList[0] = new NbtByte(1)); // Make sure that setting did not affect ListType Assert.AreEqual(testList.ListType, NbtTagType.Unknown); Assert.AreEqual(testList.Count, 0); testList.Add(new NbtByte(1)); // set a tag to null Assert.Throws<ArgumentNullException>(() => testList[0] = null); // set a tag to itself Assert.Throws<ArgumentException>(() => testList[0] = testList); // give a named tag where an unnamed tag was expected Assert.Throws<ArgumentException>(() => testList[0] = new NbtByte("NamedTag")); // give an unnamed tag that already has a parent Assert.Throws<ArgumentException>(() => testList[0] = secondList[0]); }
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 ModelUndo() { var compound = new NbtCompound(); //compound.Add(new NbtByte("test")); //Assert.AreEqual(compound.Count, 1); //model.UndoHistory.Undo(); //Assert.AreEqual(compound.Count, 0); var sub = new NbtCompound("test"); var b1 = new NbtByte("b1"); var b2 = new NbtByte("b2"); compound.Add(sub); sub.Add(b1); sub.Add(b2); var model = new NbtTreeModel(); var node = new NbtTagNode(model, null, compound); model.Import(node); model.UndoHistory.StartBatchOperation(); node.ReceiveDrop(new[] { node.Children.First() }, 0); model.UndoHistory.FinishBatchOperation(new DescriptionHolder(""), true); model.UndoHistory.StartBatchOperation(); node.Children.First().ReceiveDrop(new[] { node.Children.First().Children.First() }, 0); model.UndoHistory.FinishBatchOperation(new DescriptionHolder(""), true); model.UndoHistory.Undo(); }
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["facing"] = new NbtByte("facing", Facing); return(Compound); }
public static int getByte(this NbtCompound tag, string name, byte defaultValue = 0) { NbtByte tag1 = tag.Get <NbtByte>(name); if (tag1 == null) { return(defaultValue); } else { return(tag1.Value); } }
public void NbtByteTest() { object dummy; NbtTag test = new NbtByte( 250 ); Assert.Throws<InvalidCastException>( () => dummy = test.ByteArrayValue ); Assert.AreEqual( 250, test.ByteValue ); Assert.AreEqual( (double)250, test.DoubleValue ); Assert.AreEqual( (float)250, test.FloatValue ); Assert.Throws<InvalidCastException>( () => dummy = test.IntArrayValue ); Assert.AreEqual( 250, test.IntValue ); Assert.AreEqual( 250L, test.LongValue ); Assert.AreEqual( 250, test.ShortValue ); Assert.AreEqual( "250", test.StringValue ); }
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 Write_ByteTag() { // Arrange MemoryStream stream = new MemoryStream(); NbtWriter writer = new NbtWriter(stream); NbtByte tag = new NbtByte("asdf", 123); byte[] expected = new byte[] { 0x01, 0x00, 0x04, 0x61, 0x73, 0x64, 0x66, 0x7B }; // Act writer.Write(tag); byte[] result = stream.ToArray(); // Assert CollectionAssert.AreEqual(expected, result); }
public void NbtByteTest() { object dummy; NbtTag test = new NbtByte(250); Assert.Throws <InvalidCastException>(() => dummy = test.ByteArrayValue); Assert.AreEqual(250, test.ByteValue); Assert.AreEqual((double)250, test.DoubleValue); Assert.AreEqual((float)250, test.FloatValue); Assert.Throws <InvalidCastException>(() => dummy = test.IntArrayValue); Assert.AreEqual(250, test.IntValue); Assert.AreEqual(250L, test.LongValue); Assert.AreEqual(250, test.ShortValue); Assert.AreEqual("250", test.StringValue); }
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 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); }
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); }
/// <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(NbtByte tag) { if (tag == null) throw new ArgumentNullException("tag", "tag is null."); Write(tag, true); }
internal void Write(NbtByte tag, bool writeHeader) { Write(tag.Name, tag.Value, writeHeader); }
public static string ToSnbt(this NbtByte tag, SnbtOptions options) => (sbyte)tag.Value + OptionalSuffix(options, BYTE_SUFFIX);
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)); }
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); }
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 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 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 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); }
/** * 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 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); }