diff --git a/Substrate.Tests/AnvilTests.cs b/Substrate.Tests/AnvilTests.cs new file mode 100644 index 00000000..9b13fc87 --- /dev/null +++ b/Substrate.Tests/AnvilTests.cs @@ -0,0 +1,542 @@ +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Substrate.Core; +using Substrate.Nbt; +using Substrate.TileEntities; + +namespace Substrate.Tests +{ + [TestClass] + public class AnvilTests + { + [TestMethod] + public void PaletteSectionReadsAndWritesPre116PackedStates() + { + AssertSectionRoundTrip(2230, false); + } + + [TestMethod] + public void PaletteSectionReadsAndWrites116PaddedStates() + { + AssertSectionRoundTrip(2586, true); + } + + [TestMethod] + public void AquaticChunkSavePreservesDataVersionAndBlockChanges() + { + AquaticChunk chunk = AquaticChunk.Create(3, -2); + chunk.Blocks.SetID(4, 65, 7, BlockType.STONE); + + MemoryStream stream = new MemoryStream(); + Assert.IsTrue(chunk.Save(stream)); + stream.Position = 0; + + NbtTree saved = new NbtTree(stream); + Assert.AreEqual(1631, saved.Root["DataVersion"].ToTagInt().Data); + AquaticChunk reloaded = AquaticChunk.CreateVerified(saved); + Assert.IsNotNull(reloaded); + Assert.AreEqual(3, reloaded.X); + Assert.AreEqual(-2, reloaded.Z); + Assert.AreEqual(BlockType.STONE, reloaded.Blocks.GetID(4, 65, 7)); + } + + [TestMethod] + public void PalettePropertiesSurviveAnUnmodifiedRoundTrip() + { + TagNodeList palette = new TagNodeList(TagType.TAG_COMPOUND); + palette.Add(PaletteEntry("minecraft:air")); + TagNodeCompound north = PaletteEntry("minecraft:oak_stairs"); + north["Properties"] = Properties("facing", "north"); + TagNodeCompound south = PaletteEntry("minecraft:oak_stairs"); + south["Properties"] = Properties("facing", "south"); + palette.Add(north); + palette.Add(south); + + int[] states = new int[4096]; + states[0] = 1; + states[1] = 2; + TagNodeCompound tree = BuildSection(states, false); + tree["Palette"] = palette; + + TagNodeList rebuilt = new AquaticSection(tree, 2230).BuildTree().ToTagCompound()["Palette"].ToTagList(); + Assert.AreEqual(3, rebuilt.Count); + Assert.AreEqual("north", rebuilt[0].ToTagCompound()["Properties"].ToTagCompound()["facing"].ToTagString().Data); + Assert.AreEqual("south", rebuilt[1].ToTagCompound()["Properties"].ToTagCompound()["facing"].ToTagString().Data); + } + + [TestMethod] + public void ModernChunkReadsNegativeSectionsAndPreservesModernTags() + { + int[] states = new int[4096]; + states[0] = 1; + TagNodeCompound section = BuildModernSection(-4, states); + TagNodeList sections = new TagNodeList(TagType.TAG_COMPOUND); + sections.Add(section); + + TagNodeCompound root = new TagNodeCompound(); + root["DataVersion"] = new TagNodeInt(5000); + root["xPos"] = new TagNodeInt(8); + root["zPos"] = new TagNodeInt(-9); + root["Status"] = new TagNodeString("full"); + root["sections"] = sections; + root["block_entities"] = new TagNodeList(TagType.TAG_COMPOUND); + + AquaticChunk chunk = AquaticChunk.CreateVerified(new NbtTree(root)); + Assert.IsNotNull(chunk); + Assert.AreEqual(-64, chunk.MinimumY); + Assert.AreEqual(384, chunk.Blocks.YDim); + Assert.AreEqual(BlockType.STONE, chunk.Blocks.GetID(0, 0, 0)); + Assert.AreEqual(BlockType.STONE, chunk.GetBlockID(0, -64, 0)); + Assert.IsTrue(chunk.IsTerrainPopulated); + TagNodeCompound properties = Properties("variant", "potent"); + chunk.SetBlockState(1, 319, 2, "minecraft:potent_sulfur", properties); + + MemoryStream stream = new MemoryStream(); + Assert.IsTrue(chunk.Save(stream)); + stream.Position = 0; + NbtTree saved = new NbtTree(stream); + Assert.IsFalse(saved.Root.ContainsKey("Level")); + Assert.AreEqual(5000, saved.Root["DataVersion"].ToTagInt().Data); + Assert.IsTrue(saved.Root.ContainsKey("sections")); + Assert.IsFalse(saved.Root.ContainsKey("Biomes")); + Assert.AreEqual(0, saved.Root["isLightOn"].ToTagByte().Data); + + TagNodeCompound savedSection = saved.Root["sections"].ToTagList()[0].ToTagCompound(); + Assert.IsTrue(savedSection.ContainsKey("block_states")); + Assert.IsTrue(savedSection.ContainsKey("biomes")); + Assert.IsFalse(savedSection.ContainsKey("SkyLight")); + Assert.IsFalse(savedSection.ContainsKey("BlockLight")); + + AquaticChunk reloaded = AquaticChunk.CreateVerified(saved); + Assert.AreEqual("minecraft:potent_sulfur", reloaded.GetBlockName(1, 319, 2)); + } + + [TestMethod] + public void MissingHeightMapUsesMotionBlockingBlocksAndFluids() + { + int[] states = new int[4096]; + states[(10 * 16 + 0) * 16 + 0] = 1; // glass + states[(12 * 16 + 0) * 16 + 1] = 2; // water + states[(9 * 16 + 0) * 16 + 2] = 3; // stone below leaves + states[(14 * 16 + 0) * 16 + 2] = 4; // leaves + states[(8 * 16 + 0) * 16 + 3] = 3; // stone below tall grass + states[(15 * 16 + 0) * 16 + 3] = 5; // tall grass + states[(7 * 16 + 0) * 16 + 4] = 3; // stone below leaf litter + states[(13 * 16 + 0) * 16 + 4] = 6; // leaf litter + + TagNodeCompound section = BuildModernSection(0, states); + TagNodeList palette = section["block_states"].ToTagCompound()["palette"].ToTagList(); + palette.Clear(); + palette.Add(PaletteEntry("minecraft:air")); + palette.Add(PaletteEntry("minecraft:glass")); + palette.Add(PaletteEntry("minecraft:water")); + palette.Add(PaletteEntry("minecraft:stone")); + palette.Add(PaletteEntry("minecraft:oak_leaves")); + palette.Add(PaletteEntry("minecraft:tall_grass")); + palette.Add(PaletteEntry("minecraft:leaf_litter")); + + TagNodeList sections = new TagNodeList(TagType.TAG_COMPOUND); + sections.Add(section); + TagNodeCompound root = new TagNodeCompound(); + root["DataVersion"] = new TagNodeInt(5000); + root["xPos"] = new TagNodeInt(0); + root["zPos"] = new TagNodeInt(0); + root["Status"] = new TagNodeString("full"); + root["sections"] = sections; + root["block_entities"] = new TagNodeList(TagType.TAG_COMPOUND); + + AquaticChunk chunk = AquaticChunk.CreateVerified(new NbtTree(root)); + Assert.AreEqual(11, chunk.Blocks.GetHeight(0, 0)); + Assert.AreEqual(13, chunk.Blocks.GetHeight(1, 0)); + Assert.AreEqual(10, chunk.Blocks.GetHeight(2, 0)); + Assert.AreEqual(9, chunk.Blocks.GetHeight(3, 0)); + Assert.AreEqual(8, chunk.Blocks.GetHeight(4, 0)); + } + + [TestMethod] + public void RegionFileRoundTripsOversizedExternalChunkStreams() + { + string directory = Path.Combine(Path.GetTempPath(), "Substrate-Anvil-" + Guid.NewGuid().ToString("N")); + Directory.CreateDirectory(directory); + try { + string regionPath = Path.Combine(directory, "r.-2.3.mca"); + byte[] data = new byte[1100 * 1024]; + new Random(12345).NextBytes(data); + + using (RegionFile region = new RegionFile(regionPath)) { + using (Stream output = region.GetChunkDataOutputStream(2, 4)) + output.Write(data, 0, data.Length); + + Assert.IsTrue(File.Exists(Path.Combine(directory, "c.-62.100.mcc"))); + using (Stream input = region.GetChunkDataInputStream(2, 4)) { + MemoryStream copy = new MemoryStream(); + input.CopyTo(copy); + CollectionAssert.AreEqual(data, copy.ToArray()); + } + } + } finally { + Directory.Delete(directory, true); + } + } + + [TestMethod] + public void BlockInfoRegistersEveryUpdateAquaticBlock() + { + const string names = + "blue_ice carved_pumpkin dried_kelp_block oak_wood spruce_wood birch_wood jungle_wood acacia_wood dark_oak_wood " + + "stripped_oak_log stripped_spruce_log stripped_birch_log stripped_jungle_log stripped_acacia_log stripped_dark_oak_log " + + "stripped_oak_wood stripped_spruce_wood stripped_birch_wood stripped_jungle_wood stripped_acacia_wood stripped_dark_oak_wood " + + "tube_coral_block brain_coral_block bubble_coral_block fire_coral_block horn_coral_block " + + "dead_tube_coral_block dead_brain_coral_block dead_bubble_coral_block dead_fire_coral_block dead_horn_coral_block " + + "prismarine_slab prismarine_stairs prismarine_brick_slab prismarine_brick_stairs dark_prismarine_slab dark_prismarine_stairs petrified_oak_slab " + + "acacia_trapdoor birch_trapdoor dark_oak_trapdoor jungle_trapdoor spruce_trapdoor " + + "cave_air void_air kelp kelp_plant seagrass tall_seagrass turtle_egg " + + "tube_coral brain_coral bubble_coral fire_coral horn_coral " + + "tube_coral_fan brain_coral_fan bubble_coral_fan fire_coral_fan horn_coral_fan " + + "dead_tube_coral_fan dead_brain_coral_fan dead_bubble_coral_fan dead_fire_coral_fan dead_horn_coral_fan " + + "tube_coral_wall_fan brain_coral_wall_fan bubble_coral_wall_fan fire_coral_wall_fan horn_coral_wall_fan " + + "dead_tube_coral_wall_fan dead_brain_coral_wall_fan dead_bubble_coral_wall_fan dead_fire_coral_wall_fan dead_horn_coral_wall_fan " + + "acacia_button birch_button dark_oak_button jungle_button spruce_button " + + "acacia_pressure_plate birch_pressure_plate dark_oak_pressure_plate jungle_pressure_plate spruce_pressure_plate " + + "bubble_column conduit sea_pickle"; + + string[] expected = names.Split(' '); + Assert.AreEqual(88, expected.Length); + Assert.AreEqual(expected.Length, BlockInfo.AquaticBlocks.Count); + foreach (string name in expected) { + BlockInfo info; + Assert.IsTrue(BlockInfo.BlockNameTable.TryGetValue("minecraft:" + name, out info), name); + Assert.IsTrue(info.Registered, name); + Assert.AreEqual("minecraft:" + name, info.StrID); + } + + Assert.AreEqual(BlockState.FLUID, BlockInfo.BlockNameTable["minecraft:bubble_column"].State); + Assert.AreEqual(BlockInfo.MAX_LUMINANCE, BlockInfo.BlockNameTable["minecraft:conduit"].Luminance); + } + + [TestMethod] + public void BlockInfoRegistersCompleteMinecraft262Registry() + { + Assert.AreEqual("26.2", BlockInfo.ModernBlockRegistryVersion); + Assert.AreEqual(1196, BlockInfo.ModernBlocks.Count); + + HashSet registrations = new HashSet(); + foreach (BlockInfo info in BlockInfo.ModernBlocks) { + Assert.IsTrue(info.Registered); + registrations.Add(info); + } + + Assert.AreSame(BlockInfo.Stone, BlockInfo.BlockNameTable["minecraft:stone"]); + Assert.IsTrue(BlockInfo.BlockNameTable.ContainsKey("minecraft:blue_ice")); + Assert.IsTrue(BlockInfo.BlockNameTable.ContainsKey("minecraft:trial_spawner")); + Assert.IsTrue(BlockInfo.BlockNameTable.ContainsKey("minecraft:creaking_heart")); + Assert.IsTrue(BlockInfo.BlockNameTable.ContainsKey("minecraft:potent_sulfur")); + Assert.IsTrue(BlockInfo.BlockNameTable.ContainsKey("minecraft:chiseled_cinnabar")); + } + + [TestMethod] + public void ModernRegistryPreservesLegacyBlockIds() + { + foreach (KeyValuePair item in ItemInfo.StrTable) { + BlockInfo block; + if (item.Value.ID < 256 && BlockInfo.BlockNameTable.TryGetValue(item.Key, out block)) + Assert.AreEqual(item.Value.ID, block.ID, item.Key); + } + + Assert.AreEqual(BlockType.WOOD_PLANK, BlockInfo.BlockNameTable["minecraft:oak_planks"].ID); + Assert.AreEqual(BlockType.WOOD_PLANK, BlockInfo.BlockNameTable["minecraft:spruce_planks"].ID); + Assert.AreEqual(BlockType.WOOD, BlockInfo.BlockNameTable["minecraft:birch_log"].ID); + Assert.AreEqual(BlockType.WOOL, BlockInfo.BlockNameTable["minecraft:red_wool"].ID); + Assert.AreEqual(BlockType.BRICK_BLOCK, BlockInfo.BlockNameTable["minecraft:bricks"].ID); + Assert.AreEqual(BlockType.SIGN_POST, BlockInfo.BlockNameTable["minecraft:oak_sign"].ID); + } + + [TestMethod] + public void LegacyIdsAndDataSerializeAsModernBlockStates() + { + AquaticSection section = new AquaticSection(0); + section.Blocks[0, 0, 0] = BlockType.WOOD_PLANK; + section.Data[0, 0, 0] = 1; + section.Blocks[1, 0, 0] = BlockType.WOOL; + section.Data[1, 0, 0] = 14; + section.Blocks[2, 0, 0] = BlockType.WOOD; + section.Data[2, 0, 0] = 6; + section.Blocks[3, 0, 0] = BlockType.SIGN_POST; + section.Data[3, 0, 0] = 4; + section.Blocks[4, 0, 0] = BlockType.BRICK_BLOCK; + + AquaticSection roundTrip = new AquaticSection(section.BuildTree().ToTagCompound()); + Assert.AreEqual("minecraft:spruce_planks", roundTrip.GetBlockName(0, 0, 0)); + Assert.AreEqual("minecraft:red_wool", roundTrip.GetBlockName(1, 0, 0)); + Assert.AreEqual("minecraft:birch_log", roundTrip.GetBlockName(2, 0, 0)); + Assert.AreEqual("x", roundTrip.GetBlockProperties(2, 0, 0)["axis"].ToTagString().Data); + Assert.AreEqual("minecraft:oak_sign", roundTrip.GetBlockName(3, 0, 0)); + Assert.AreEqual("4", roundTrip.GetBlockProperties(3, 0, 0)["rotation"].ToTagString().Data); + Assert.AreEqual("minecraft:bricks", roundTrip.GetBlockName(4, 0, 0)); + } + + [TestMethod] + public void SetIdAndDataWritesModernStatesAndRetainsLegacyValues() + { + AquaticChunk chunk = AquaticChunk.Create(0, 0); + chunk.Blocks.SetID(0, 64, 0, BlockType.STAINED_GLASS, 11); + chunk.Blocks.SetID(1, 64, 0, BlockInfo.AcaciaWood.ID, 12); + + MemoryStream stream = new MemoryStream(); + Assert.IsTrue(chunk.Save(stream)); + stream.Position = 0; + AquaticChunk roundTrip = AquaticChunk.CreateVerified(new NbtTree(stream)); + + Assert.AreEqual("minecraft:blue_stained_glass", + roundTrip.GetBlockName(0, 64, 0)); + Assert.AreEqual("minecraft:acacia_wood", + roundTrip.GetBlockName(1, 64, 0)); + Assert.AreEqual(BlockType.STAINED_GLASS, + roundTrip.Blocks.GetID(0, 64, 0)); + Assert.AreEqual(11, roundTrip.Blocks.GetData(0, 64, 0)); + Assert.AreEqual(BlockInfo.AcaciaWood.ID, + roundTrip.Blocks.GetID(1, 64, 0)); + Assert.AreEqual(12, roundTrip.Blocks.GetData(1, 64, 0)); + +#pragma warning disable 612, 618 + AlphaBlockCollection legacy = new AlphaBlockCollection(16, 128, 16); +#pragma warning restore 612, 618 + legacy.SetID(2, 65, 3, BlockType.STAINED_GLASS, 11); + Assert.AreEqual(BlockType.STAINED_GLASS, legacy.GetID(2, 65, 3)); + Assert.AreEqual(11, legacy.GetData(2, 65, 3)); + } + + [TestMethod] + public void PublicLegacyBlockStateConversionReturnsIdAndDataOrThrows() + { + int id; + int data; + BlockInfo.GetLegacyBlockState( + AcquaticBlocks.BlueStainedGlass, out id, out data); + Assert.AreEqual(BlockType.STAINED_GLASS, id); + Assert.AreEqual(11, data); + + BlockInfo.GetLegacyBlockState( + AcquaticBlocks.AcaciaWood, out id, out data); + Assert.AreEqual(BlockInfo.AcaciaWood.ID, id); + Assert.AreEqual(12, data); + + TagNodeCompound properties = new TagNodeCompound(); + properties[BlockProperties.Axis] = new TagNodeString("y"); + BlockInfo.GetLegacyBlockState( + AcquaticBlocks.AcaciaLog, properties, out id, out data); + Assert.AreEqual(BlockInfo.AcaciaWood.ID, id); + Assert.AreEqual(0, data); + + bool threw = false; + try { + BlockInfo.GetLegacyBlockState( + AcquaticBlocks.LeafLitter, out id, out data); + } + catch (ArgumentException) { + threw = true; + } + Assert.IsTrue(threw); + } + + [TestMethod] + public void SignTextReadsAndWritesModernFrontText() + { + TileEntitySign sign = new TileEntitySign(); + sign.X = 12; + sign.Y = 64; + sign.Z = 34; + sign.Text1 = "{\"text\":\"First\"}"; + sign.Text2 = "{\"text\":\"Second\"}"; + TagNodeCompound tree = sign.BuildTree().ToTagCompound(); + + TagNodeCompound front = tree["front_text"].ToTagCompound(); + TagNodeList messages = front["messages"].ToTagList(); + Assert.AreEqual(4, messages.Count); + Assert.AreEqual(TagType.TAG_STRING, messages.ValueType); + Assert.AreEqual("First", messages[0].ToTagString().Data); + Assert.AreEqual("Second", messages[1].ToTagString().Data); + Assert.AreEqual("black", front["color"].ToTagString().Data); + Assert.AreEqual(0, front["has_glowing_text"].ToTagByte().Data); + Assert.IsInstanceOfType(tree["components"], typeof(TagNodeCompound)); + Assert.AreEqual(0, tree["keepPacked"].ToTagByte().Data); + + tree.Remove("Text1"); + tree.Remove("Text2"); + tree.Remove("Text3"); + tree.Remove("Text4"); + front["color"] = new TagNodeString("blue"); + TileEntitySign loaded = TileEntityFactory.Create(tree) as TileEntitySign; + Assert.IsNotNull(loaded); + Assert.AreEqual(sign.Text1, loaded.Text1); + Assert.AreEqual(sign.Text2, loaded.Text2); + Assert.AreEqual("blue", + loaded.BuildTree().ToTagCompound()["front_text"].ToTagCompound()["color"].ToTagString().Data); + } + + [TestMethod] + public void SignTextReadsLegacyStringComponents() + { + TileEntitySign sign = new TileEntitySign(); + TagNodeCompound tree = sign.BuildTree().ToTagCompound(); + TagNodeList messages = new TagNodeList(TagType.TAG_STRING); + messages.Add(new TagNodeString("{\"text\":\"Legacy\"}")); + messages.Add(new TagNodeString("{\"text\":\"Second\"}")); + messages.Add(new TagNodeString("{\"text\":\"\"}")); + messages.Add(new TagNodeString("{\"text\":\"\"}")); + tree["front_text"].ToTagCompound()["messages"] = messages; + + TileEntitySign loaded = TileEntityFactory.Create(tree) as TileEntitySign; + + Assert.IsNotNull(loaded); + Assert.AreEqual("{\"text\":\"Legacy\"}", loaded.Text1); + Assert.AreEqual("{\"text\":\"Second\"}", loaded.Text2); + } + + [TestMethod] + public void SignTextReadsNativeMinecraft262PlainStrings() + { + TileEntitySign sign = new TileEntitySign(); + sign.X = 80; + sign.Y = 63; + sign.Z = 243; + TagNodeCompound tree = sign.BuildTree().ToTagCompound(); + tree.Remove("Text1"); + tree.Remove("Text2"); + tree.Remove("Text3"); + tree.Remove("Text4"); + TagNodeList messages = new TagNodeList(TagType.TAG_STRING); + messages.Add(new TagNodeString("This")); + messages.Add(new TagNodeString("Is")); + messages.Add(new TagNodeString("A")); + messages.Add(new TagNodeString("Message")); + tree["front_text"].ToTagCompound()["messages"] = messages; + + TileEntitySign loaded = TileEntityFactory.Create(tree) as TileEntitySign; + + Assert.IsNotNull(loaded); + Assert.AreEqual("{\"text\":\"This\"}", loaded.Text1); + Assert.AreEqual("{\"text\":\"Is\"}", loaded.Text2); + Assert.AreEqual("{\"text\":\"A\"}", loaded.Text3); + Assert.AreEqual("{\"text\":\"Message\"}", loaded.Text4); + } + + [TestMethod] + public void Minecraft262ConstantsCoverBlocksAndProperties() + { + Assert.AreEqual(1196, typeof(AcquaticBlocks).GetFields().Length); + Assert.AreEqual("minecraft:air", AcquaticBlocks.Air); + Assert.AreEqual("minecraft:leaf_litter", AcquaticBlocks.LeafLitter); + Assert.AreEqual("minecraft:potent_sulfur", AcquaticBlocks.PotentSulfur); + + Assert.AreEqual(93, typeof(BlockProperties).GetFields().Length); + Assert.AreEqual("facing", BlockProperties.Facing); + Assert.AreEqual("segment_amount", BlockProperties.SegmentAmount); + Assert.AreEqual("waterlogged", BlockProperties.Waterlogged); + } + + [TestMethod] + public void AquaticPaletteUsesRegisteredBlockInfo() + { + int[] states = new int[4096]; + states[0] = 1; + TagNodeCompound sectionTree = BuildSection(states, false); + sectionTree["Palette"].ToTagList()[1].ToTagCompound()["Name"] = new TagNodeString("minecraft:blue_ice"); + + AquaticSection section = new AquaticSection(sectionTree, 1631); + BlockInfo blueIce = BlockInfo.BlockNameTable["minecraft:blue_ice"]; + Assert.AreEqual(blueIce.ID, section.Blocks[0, 0, 0]); + Assert.AreEqual("minecraft:blue_ice", section.GetBlockName(0, 0, 0)); + } + + private static void AssertSectionRoundTrip(int dataVersion, bool padded) + { + int[] states = new int[4096]; + for (int i = 0; i < states.Length; i++) states[i] = (i % 17 == 0) ? 1 : 0; + + TagNodeCompound sectionTree = BuildSection(states, padded); + AquaticSection section = new AquaticSection(sectionTree, dataVersion); + Assert.AreEqual(BlockType.STONE, section.Blocks[0, 0, 0]); + Assert.AreEqual(BlockType.AIR, section.Blocks[1, 0, 0]); + Assert.AreEqual(BlockType.STONE, section.Blocks[1, 0, 1]); + + section.Blocks[2, 3, 4] = BlockType.STONE; + TagNodeCompound rebuilt = section.BuildTree().ToTagCompound(); + AquaticSection roundTrip = new AquaticSection(rebuilt, dataVersion); + Assert.AreEqual(BlockType.STONE, roundTrip.Blocks[2, 3, 4]); + Assert.AreEqual(BlockType.STONE, roundTrip.Blocks[0, 0, 0]); + } + + private static TagNodeCompound BuildSection(int[] states, bool padded) + { + TagNodeList palette = new TagNodeList(TagType.TAG_COMPOUND); + palette.Add(PaletteEntry("minecraft:air")); + palette.Add(PaletteEntry("minecraft:stone")); + + TagNodeCompound section = new TagNodeCompound(); + section["Y"] = new TagNodeByte(0); + section["Palette"] = palette; + section["BlockStates"] = new TagNodeLongArray(Pack(states, 4, padded)); + section["SkyLight"] = new TagNodeByteArray(new byte[2048]); + section["BlockLight"] = new TagNodeByteArray(new byte[2048]); + return section; + } + + private static TagNodeCompound BuildModernSection(int y, int[] states) + { + TagNodeList palette = new TagNodeList(TagType.TAG_COMPOUND); + palette.Add(PaletteEntry("minecraft:air")); + palette.Add(PaletteEntry("minecraft:stone")); + TagNodeCompound blockStates = new TagNodeCompound(); + blockStates["palette"] = palette; + blockStates["data"] = new TagNodeLongArray(Pack(states, 4, true)); + + TagNodeList biomePalette = new TagNodeList(TagType.TAG_STRING); + biomePalette.Add(new TagNodeString("minecraft:plains")); + TagNodeCompound biomes = new TagNodeCompound(); + biomes["palette"] = biomePalette; + + TagNodeCompound section = new TagNodeCompound(); + section["Y"] = new TagNodeByte(unchecked((byte)(sbyte)y)); + section["block_states"] = blockStates; + section["biomes"] = biomes; + return section; + } + + private static TagNodeCompound PaletteEntry(string name) + { + TagNodeCompound entry = new TagNodeCompound(); + entry["Name"] = new TagNodeString(name); + return entry; + } + + private static TagNodeCompound Properties(string name, string value) + { + TagNodeCompound properties = new TagNodeCompound(); + properties[name] = new TagNodeString(value); + return properties; + } + + private static long[] Pack(int[] values, int bits, bool padded) + { + int perLong = 64 / bits; + int length = padded ? (values.Length + perLong - 1) / perLong : (values.Length * bits + 63) / 64; + long[] result = new long[length]; + for (int i = 0; i < values.Length; i++) { + if (padded) { + int word = i / perLong; + result[word] |= (long)((ulong)values[i] << ((i % perLong) * bits)); + } else { + int bit = i * bits; + int word = bit / 64; + int offset = bit % 64; + result[word] |= (long)((ulong)values[i] << offset); + if (offset + bits > 64) result[word + 1] |= (long)((ulong)values[i] >> (64 - offset)); + } + } + return result; + } + } +} diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/custom_boss_events.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/custom_boss_events.dat new file mode 100644 index 00000000..5f51792d Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/custom_boss_events.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/game_rules.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/game_rules.dat new file mode 100644 index 00000000..f3f214ec Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/game_rules.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/random_sequences.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/random_sequences.dat new file mode 100644 index 00000000..a586be67 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/random_sequences.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/scheduled_events.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/scheduled_events.dat new file mode 100644 index 00000000..d588c93d Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/scheduled_events.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/scoreboard.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/scoreboard.dat new file mode 100644 index 00000000..5f51792d Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/scoreboard.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/stopwatches.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/stopwatches.dat new file mode 100644 index 00000000..3861bed7 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/stopwatches.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/wandering_trader.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/wandering_trader.dat new file mode 100644 index 00000000..3cdc1ba7 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/wandering_trader.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/weather.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/weather.dat new file mode 100644 index 00000000..54c2bf11 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/weather.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/world_clocks.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/world_clocks.dat new file mode 100644 index 00000000..8d308720 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/world_clocks.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/data/minecraft/world_gen_settings.dat b/Substrate.Tests/Data/26_2-creative/data/minecraft/world_gen_settings.dat new file mode 100644 index 00000000..c3dcd77a Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/data/minecraft/world_gen_settings.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/chunk_tickets.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/chunk_tickets.dat new file mode 100644 index 00000000..5f51792d Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/chunk_tickets.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/raids.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/raids.dat new file mode 100644 index 00000000..863b2dd7 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/raids.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/world_border.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/world_border.dat new file mode 100644 index 00000000..5ef8028c Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/data/minecraft/world_border.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/entities/r.-1.0.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/entities/r.-1.0.mca new file mode 100644 index 00000000..2f6850ac Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/entities/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/entities/r.0.0.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/entities/r.0.0.mca new file mode 100644 index 00000000..6bb10067 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/entities/r.0.0.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.-1.-1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.-1.-1.mca new file mode 100644 index 00000000..e69de29b diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.-1.0.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.-1.0.mca new file mode 100644 index 00000000..e69de29b diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.-1.1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.-1.1.mca new file mode 100644 index 00000000..e69de29b diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.0.-1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.0.-1.mca new file mode 100644 index 00000000..e69de29b diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.0.0.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.0.0.mca new file mode 100644 index 00000000..6b88f75c Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.0.0.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.0.1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/poi/r.0.1.mca new file mode 100644 index 00000000..e69de29b diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.-1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.-1.mca new file mode 100644 index 00000000..585676e3 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.-1.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.0.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.0.mca new file mode 100644 index 00000000..c4b7a264 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.0.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.1.mca new file mode 100644 index 00000000..d1811f11 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.-1.1.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.-1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.-1.mca new file mode 100644 index 00000000..6217770a Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.-1.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.0.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.0.mca new file mode 100644 index 00000000..a67df5b0 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.0.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.1.mca b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.1.mca new file mode 100644 index 00000000..e99992eb Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/overworld/region/r.0.1.mca differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/chunk_tickets.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/chunk_tickets.dat new file mode 100644 index 00000000..5f51792d Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/chunk_tickets.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/ender_dragon_fight.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/ender_dragon_fight.dat new file mode 100644 index 00000000..78f7e153 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/ender_dragon_fight.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/raids.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/raids.dat new file mode 100644 index 00000000..863b2dd7 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/raids.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/world_border.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/world_border.dat new file mode 100644 index 00000000..5ef8028c Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_end/data/minecraft/world_border.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/chunk_tickets.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/chunk_tickets.dat new file mode 100644 index 00000000..5f51792d Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/chunk_tickets.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/raids.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/raids.dat new file mode 100644 index 00000000..863b2dd7 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/raids.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/world_border.dat b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/world_border.dat new file mode 100644 index 00000000..5ef8028c Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/dimensions/minecraft/the_nether/data/minecraft/world_border.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/icon.png b/Substrate.Tests/Data/26_2-creative/icon.png new file mode 100644 index 00000000..6dbc609c Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/icon.png differ diff --git a/Substrate.Tests/Data/26_2-creative/level.dat b/Substrate.Tests/Data/26_2-creative/level.dat new file mode 100644 index 00000000..dae55fa1 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/level.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/level.dat_old b/Substrate.Tests/Data/26_2-creative/level.dat_old new file mode 100644 index 00000000..dbd55c9d Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/level.dat_old differ diff --git a/Substrate.Tests/Data/26_2-creative/players/advancements/893ab0bc-920e-449e-b904-9498ac87eb68.json b/Substrate.Tests/Data/26_2-creative/players/advancements/893ab0bc-920e-449e-b904-9498ac87eb68.json new file mode 100644 index 00000000..fe9d2bc8 --- /dev/null +++ b/Substrate.Tests/Data/26_2-creative/players/advancements/893ab0bc-920e-449e-b904-9498ac87eb68.json @@ -0,0 +1,16 @@ +{ + "minecraft:recipes/decorations/crafting_table": { + "criteria": { + "unlock_right_away": "2026-07-25 12:32:33 -0700" + }, + "done": true + }, + "minecraft:adventure/adventuring_time": { + "criteria": { + "minecraft:beach": "2026-07-25 12:32:35 -0700", + "minecraft:forest": "2026-07-25 12:34:46 -0700" + }, + "done": false + }, + "DataVersion": 4903 +} \ No newline at end of file diff --git a/Substrate.Tests/Data/26_2-creative/players/data/893ab0bc-920e-449e-b904-9498ac87eb68.dat b/Substrate.Tests/Data/26_2-creative/players/data/893ab0bc-920e-449e-b904-9498ac87eb68.dat new file mode 100644 index 00000000..20d6a149 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/players/data/893ab0bc-920e-449e-b904-9498ac87eb68.dat differ diff --git a/Substrate.Tests/Data/26_2-creative/players/data/893ab0bc-920e-449e-b904-9498ac87eb68.dat_old b/Substrate.Tests/Data/26_2-creative/players/data/893ab0bc-920e-449e-b904-9498ac87eb68.dat_old new file mode 100644 index 00000000..20d6a149 Binary files /dev/null and b/Substrate.Tests/Data/26_2-creative/players/data/893ab0bc-920e-449e-b904-9498ac87eb68.dat_old differ diff --git a/Substrate.Tests/Data/26_2-creative/players/stats/893ab0bc-920e-449e-b904-9498ac87eb68.json b/Substrate.Tests/Data/26_2-creative/players/stats/893ab0bc-920e-449e-b904-9498ac87eb68.json new file mode 100644 index 00000000..0c22d81c --- /dev/null +++ b/Substrate.Tests/Data/26_2-creative/players/stats/893ab0bc-920e-449e-b904-9498ac87eb68.json @@ -0,0 +1,16 @@ +{ + "stats": { + "minecraft:custom": { + "minecraft:time_since_rest": 2653, + "minecraft:walk_one_cm": 1450, + "minecraft:total_world_time": 3526, + "minecraft:leave_game": 1, + "minecraft:play_time": 2653, + "minecraft:time_since_death": 2653 + }, + "minecraft:picked_up": { + "minecraft:leaf_litter": 1 + } + }, + "DataVersion": 4903 +} \ No newline at end of file diff --git a/Substrate.Tests/Data/26_2-creative/session.lock b/Substrate.Tests/Data/26_2-creative/session.lock new file mode 100644 index 00000000..0d7e5f85 --- /dev/null +++ b/Substrate.Tests/Data/26_2-creative/session.lock @@ -0,0 +1 @@ +☃ \ No newline at end of file diff --git a/Substrate.Tests/Data/26_2-missing-heightmaps/dimensions/minecraft/overworld/region/r.4.3.mca b/Substrate.Tests/Data/26_2-missing-heightmaps/dimensions/minecraft/overworld/region/r.4.3.mca new file mode 100644 index 00000000..91faf748 Binary files /dev/null and b/Substrate.Tests/Data/26_2-missing-heightmaps/dimensions/minecraft/overworld/region/r.4.3.mca differ diff --git a/Substrate.Tests/Data/26_2-missing-heightmaps/dimensions/minecraft/overworld/region/r.5.0.mca b/Substrate.Tests/Data/26_2-missing-heightmaps/dimensions/minecraft/overworld/region/r.5.0.mca new file mode 100644 index 00000000..e37b89c0 Binary files /dev/null and b/Substrate.Tests/Data/26_2-missing-heightmaps/dimensions/minecraft/overworld/region/r.5.0.mca differ diff --git a/Substrate.Tests/Data/26_2-missing-heightmaps/level.dat b/Substrate.Tests/Data/26_2-missing-heightmaps/level.dat new file mode 100644 index 00000000..56ce2b9d Binary files /dev/null and b/Substrate.Tests/Data/26_2-missing-heightmaps/level.dat differ diff --git a/Substrate.Tests/Substrate.Tests.csproj b/Substrate.Tests/Substrate.Tests.csproj index c909dc4b..d3a343c2 100644 --- a/Substrate.Tests/Substrate.Tests.csproj +++ b/Substrate.Tests/Substrate.Tests.csproj @@ -18,7 +18,7 @@ Substrate.Tests.net40-client - v4.0 + v4.8 true full @@ -105,12 +105,16 @@ + + + {7264a1c4-ab4a-4437-b252-7379b98b5509} Substrate %28NET4%29 + Configuration=Debug @@ -140,4 +144,4 @@ --> - \ No newline at end of file + diff --git a/Substrate.Tests/TileEntityBannerTests.cs b/Substrate.Tests/TileEntityBannerTests.cs new file mode 100644 index 00000000..9620c4cd --- /dev/null +++ b/Substrate.Tests/TileEntityBannerTests.cs @@ -0,0 +1,36 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Substrate.Nbt; +using Substrate.TileEntities; + +namespace Substrate.Tests +{ + [TestClass] + public class TileEntityBannerTests + { + [TestMethod] + public void CompoundPatternEntriesValidateAndLoad() + { + TagNodeCompound tree = new TagNodeCompound(); + tree["id"] = new TagNodeString(TileEntityBanner.TypeId); + tree["x"] = new TagNodeInt(1); + tree["y"] = new TagNodeInt(2); + tree["z"] = new TagNodeInt(3); + tree["Base"] = new TagNodeInt(0); + + TagNodeList patterns = new TagNodeList(TagType.TAG_COMPOUND); + for (int i = 0; i < 5; i++) { + TagNodeCompound pattern = new TagNodeCompound(); + pattern["Color"] = new TagNodeInt(i); + pattern["Pattern"] = new TagNodeString("bs"); + patterns.Add(pattern); + } + tree["Patterns"] = patterns; + + TileEntityBanner banner = new TileEntityBanner(); + + Assert.IsTrue(banner.ValidateTree(tree)); + Assert.IsNotNull(banner.LoadTreeSafe(tree)); + Assert.AreEqual(5, banner.Patterns.Length); + } + } +} diff --git a/Substrate.Tests/TileTickTests.cs b/Substrate.Tests/TileTickTests.cs new file mode 100644 index 00000000..b16ec6e3 --- /dev/null +++ b/Substrate.Tests/TileTickTests.cs @@ -0,0 +1,48 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Substrate.Nbt; + +namespace Substrate.Tests +{ + [TestClass] + public class TileTickTests + { + [TestMethod] + public void StringBlockIdLoadsAndRoundTrips() + { + TagNodeCompound tree = CreateTick(new TagNodeString("minecraft:flowing_lava")); + + TileTick tick = TileTick.FromTreeSafe(tree); + + Assert.IsNotNull(tick); + Assert.AreEqual(BlockType.LAVA, tick.ID); + Assert.AreEqual("minecraft:flowing_lava", tick.StringID); + Assert.AreEqual(TagType.TAG_STRING, tick.BuildTree()["i"].GetTagType()); + Assert.AreEqual("minecraft:flowing_lava", tick.BuildTree()["i"].ToTagString().Data); + } + + [TestMethod] + public void NumericBlockIdRemainsSupported() + { + TagNodeCompound tree = CreateTick(new TagNodeInt(BlockType.LAVA)); + + TileTick tick = TileTick.FromTreeSafe(tree); + + Assert.IsNotNull(tick); + Assert.AreEqual(BlockType.LAVA, tick.ID); + Assert.IsNull(tick.StringID); + Assert.AreEqual(TagType.TAG_INT, tick.BuildTree()["i"].GetTagType()); + } + + private static TagNodeCompound CreateTick(TagNode id) + { + TagNodeCompound tree = new TagNodeCompound(); + tree["i"] = id; + tree["t"] = new TagNodeInt(5); + tree["p"] = new TagNodeInt(0); + tree["x"] = new TagNodeInt(1); + tree["y"] = new TagNodeInt(2); + tree["z"] = new TagNodeInt(3); + return tree; + } + } +} diff --git a/Substrate.Tests/WorldTests.cs b/Substrate.Tests/WorldTests.cs index fbc87d4f..1fcb6e14 100644 --- a/Substrate.Tests/WorldTests.cs +++ b/Substrate.Tests/WorldTests.cs @@ -1,13 +1,245 @@ using System; using System.Collections.Generic; +using System.IO; using System.Text; using Substrate; +using Substrate.Nbt; +using Substrate.TileEntities; using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Security.Cryptography; +using System.Security.Policy; namespace Substrate.Tests { [TestClass] public class WorldTests { + [TestMethod] + public void TallGrassHeight() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\26_2-missing-heightmaps\"); + var bm = world.GetBlockManager() as AnvilBlockManager; + var height = bm.GetHeight(2939, 504); + var block = bm.GetBlock(2939, 111, 504); + Assert.AreEqual("minecraft:tall_grass", bm.GetStringID(2939, 111, 504)); + Assert.IsFalse(block.Info.ObscuresLight); + Assert.AreEqual(BlockState.NONSOLID, block.Info.State); + Assert.AreEqual(111, height); + } + + [TestMethod] + public void OpenTest_262_missing_heightmaps() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\26_2-missing-heightmaps\"); + var bm = world.GetBlockManager() as AnvilBlockManager; + var height = bm.GetHeight(2431, 1911); + Assert.AreEqual(111, height); + } + [TestMethod] + public void LegacyBrickBlockSavesWithModernName() + { + string source = Path.GetFullPath(@"..\..\Data\26_2-missing-heightmaps\"); + string copy = Path.Combine(Path.GetTempPath(), "Substrate-" + Guid.NewGuid().ToString("N")); + CopyDirectory(source, copy); + try { + NbtWorld world = NbtWorld.Open(copy); + AnvilBlockManager blocks = world.GetBlockManager() as AnvilBlockManager; + blocks.SetID(2431, 111, 1911, BlockInfo.BrickBlock.ID); + blocks.SetData(2431, 111, 1911, 0); + world.Save(); + + world = NbtWorld.Open(copy); + blocks = world.GetBlockManager() as AnvilBlockManager; + Assert.AreEqual(BlockInfo.BrickBlock.ID, blocks.GetID(2431, 111, 1911)); + Assert.AreEqual("minecraft:bricks", blocks.GetStringID(2431, 111, 1911)); + blocks = null; + world = null; + } + finally { + GC.Collect(); + GC.WaitForPendingFinalizers(); + Directory.Delete(copy, true); + } + } + + [TestMethod] + public void GlassPaneConnectionsAreSavedFromNeighboringWalls() + { + string source = Path.GetFullPath(@"..\..\Data\26_2-missing-heightmaps\"); + string copy = Path.Combine(Path.GetTempPath(), "Substrate-" + Guid.NewGuid().ToString("N")); + CopyDirectory(source, copy); + try { + NbtWorld world = NbtWorld.Open(copy); + AnvilBlockManager blocks = world.GetBlockManager() as AnvilBlockManager; + const int x = 2430; + const int y = 112; + const int z = 1911; + blocks.SetID(x, y, z - 1, BlockType.STONE); + blocks.SetID(x, y, z + 1, BlockType.STONE); + blocks.SetID(x - 1, y, z, BlockType.AIR); + blocks.SetID(x + 1, y, z, BlockType.AIR); + blocks.SetID(x, y, z, BlockType.GLASS_PANE); + blocks.SetData(x, y, z, 0); + world.Save(); + + world = NbtWorld.Open(copy); + blocks = world.GetBlockManager() as AnvilBlockManager; + Assert.AreEqual("true", blocks.GetBlockProperty(x, y, z, BlockProperties.North)); + Assert.AreEqual("false", blocks.GetBlockProperty(x, y, z, BlockProperties.East)); + Assert.AreEqual("true", blocks.GetBlockProperty(x, y, z, BlockProperties.South)); + Assert.AreEqual("false", blocks.GetBlockProperty(x, y, z, BlockProperties.West)); + blocks = null; + world = null; + } + finally { + GC.Collect(); + GC.WaitForPendingFinalizers(); + Directory.Delete(copy, true); + } + } + + [TestMethod] + public void LegacyConnectedBlocksSaveModernNeighborStates() + { + string source = Path.GetFullPath(@"..\..\Data\26_2-missing-heightmaps\"); + string copy = Path.Combine(Path.GetTempPath(), "Substrate-" + Guid.NewGuid().ToString("N")); + CopyDirectory(source, copy); + try { + NbtWorld world = NbtWorld.Open(copy); + AnvilBlockManager blocks = world.GetBlockManager() as AnvilBlockManager; + const int y = 112; + + blocks.SetID(2418, y, 1905, BlockType.STONE); + blocks.SetID(2418, y, 1907, BlockType.STONE); + blocks.SetID(2418, y, 1906, BlockType.IRON_BARS); + + blocks.SetID(2421, y, 1906, BlockType.STONE); + blocks.SetID(2423, y, 1906, BlockType.STONE); + blocks.SetID(2422, y, 1906, BlockType.FENCE); + + blocks.SetID(2426, y, 1905, BlockType.STONE); + blocks.SetID(2426, y, 1906, BlockType.COBBLESTONE_WALL); + + blocks.SetID(2418, y, 1911, BlockType.REDSTONE_WIRE); + blocks.SetID(2418, y, 1912, BlockType.REDSTONE_WIRE); + blocks.SetID(2418, y, 1913, BlockType.REDSTONE_WIRE); + + blocks.SetID(2421, y, 1912, BlockType.TRIPWIRE_HOOK); + blocks.SetID(2423, y, 1912, BlockType.TRIPWIRE_HOOK); + blocks.SetID(2422, y, 1912, BlockType.TRIPWIRE); + + blocks.SetID(2426, y - 1, 1912, BlockType.END_STONE); + blocks.SetID(2426, y, 1911, 200); // chorus flower + blocks.SetID(2426, y, 1912, 199); // chorus plant + world.Save(); + + world = NbtWorld.Open(copy); + blocks = world.GetBlockManager() as AnvilBlockManager; + Assert.AreEqual("true", blocks.GetBlockProperty(2418, y, 1906, BlockProperties.North)); + Assert.AreEqual("true", blocks.GetBlockProperty(2418, y, 1906, BlockProperties.South)); + Assert.AreEqual("true", blocks.GetBlockProperty(2422, y, 1906, BlockProperties.East)); + Assert.AreEqual("true", blocks.GetBlockProperty(2422, y, 1906, BlockProperties.West)); + Assert.AreEqual("low", blocks.GetBlockProperty(2426, y, 1906, BlockProperties.North)); + Assert.AreEqual("none", blocks.GetBlockProperty(2426, y, 1906, BlockProperties.South)); + Assert.AreEqual("side", blocks.GetBlockProperty(2418, y, 1912, BlockProperties.North)); + Assert.AreEqual("side", blocks.GetBlockProperty(2418, y, 1912, BlockProperties.South)); + Assert.AreEqual("true", blocks.GetBlockProperty(2422, y, 1912, BlockProperties.East)); + Assert.AreEqual("true", blocks.GetBlockProperty(2422, y, 1912, BlockProperties.West)); + Assert.AreEqual("true", blocks.GetBlockProperty(2426, y, 1912, BlockProperties.North)); + Assert.AreEqual("true", blocks.GetBlockProperty(2426, y, 1912, BlockProperties.Down)); + blocks = null; + world = null; + } + finally { + GC.Collect(); + GC.WaitForPendingFinalizers(); + Directory.Delete(copy, true); + } + } + + [TestMethod] + public void SignTextSurvivesModernWorldSave() + { + string source = Path.GetFullPath(@"..\..\Data\26_2-missing-heightmaps\"); + string copy = Path.Combine(Path.GetTempPath(), "Substrate-" + Guid.NewGuid().ToString("N")); + CopyDirectory(source, copy); + try { + NbtWorld world = NbtWorld.Open(copy); + AnvilBlockManager blocks = world.GetBlockManager() as AnvilBlockManager; + const int x = 2430; + const int y = 112; + const int z = 1911; + AlphaBlock block = new AlphaBlock(BlockType.SIGN_POST); + TileEntitySign sign = block.GetTileEntity() as TileEntitySign; + Assert.IsNotNull(sign); + sign.Text1 = "{\"text\":\"Duwamish\"}"; + sign.Text2 = "{\"text\":\"Avenue\"}"; + blocks.SetBlock(x, y, z, block); + blocks.SetData(x, y, z, 0); + world.Save(); + + world = NbtWorld.Open(copy); + blocks = world.GetBlockManager() as AnvilBlockManager; + sign = blocks.GetTileEntity(x, y, z) as TileEntitySign; + Assert.IsNotNull(sign); + Assert.AreEqual(x, sign.X); + Assert.AreEqual(y, sign.Y); + Assert.AreEqual(z, sign.Z); + Assert.AreEqual("{\"text\":\"Duwamish\"}", sign.Text1); + Assert.AreEqual("{\"text\":\"Avenue\"}", sign.Text2); + TagNodeCompound front = sign.Source["front_text"].ToTagCompound(); + TagNodeList messages = front["messages"].ToTagList(); + Assert.AreEqual(4, messages.Count); + Assert.AreEqual(TagType.TAG_STRING, messages.ValueType); + Assert.AreEqual("Duwamish", messages[0].ToTagString().Data); + Assert.AreEqual("Avenue", messages[1].ToTagString().Data); + blocks = null; + world = null; + } + finally { + GC.Collect(); + GC.WaitForPendingFinalizers(); + Directory.Delete(copy, true); + } + } + + private static void CopyDirectory(string source, string destination) + { + Directory.CreateDirectory(destination); + foreach (string file in Directory.GetFiles(source)) + File.Copy(file, Path.Combine(destination, Path.GetFileName(file))); + foreach (string directory in Directory.GetDirectories(source)) + CopyDirectory(directory, Path.Combine(destination, Path.GetFileName(directory))); + } + [TestMethod] + public void OpenTest_262_creative() + { + NbtWorld world = NbtWorld.Open(@"..\..\Data\26_2-creative\"); + Assert.IsNotNull(world); + Assert.AreEqual(80, world.Level.Spawn.X); + Assert.AreEqual(63, world.Level.Spawn.Y); + Assert.AreEqual(240, world.Level.Spawn.Z); + + AnvilWorld anvil = world as AnvilWorld; + var block = anvil.GetBlockManager().GetBlock(79, 62, 249); + Assert.AreEqual("minecraft:sand", block.Info.StrID); + Assert.AreSame(BlockInfo.Sand, block.Info); + Assert.AreEqual(12, block.Info.ID); + block = anvil.GetBlockManager().GetBlock(79, 63, 249); + var height = anvil.GetBlockManager().GetHeight(79, 249); + Assert.AreEqual(63, height); + Assert.AreEqual(AcquaticBlocks.LeafLitter, block.Info.StrID); + Assert.AreEqual("2", anvil.GetBlockManager().GetBlockProperty(79, 63, 249, BlockProperties.SegmentAmount)); + Assert.AreEqual("north", anvil.GetBlockManager().GetBlockProperty(79, 63, 249, BlockProperties.Facing)); + anvil.GetBlockManager().SetID(79, 63, 249, BlockType.SIGN_POST); + Assert.IsInstanceOfType( + anvil.GetBlockManager().GetTileEntity(79, 63, 249), + typeof(TileEntitySign)); + Assert.IsNotNull(anvil); + Assert.IsTrue(anvil.GetRegionManager().GetRegionPath().EndsWith( + Path.Combine("dimensions", "minecraft", "overworld", "region"))); + Assert.IsTrue(anvil.GetChunkManager().ChunkExists(-22, -11)); + } + [TestMethod] public void OpenTest_1_6_4_survival() { @@ -29,6 +261,53 @@ public void OpenTest_1_7_10_survival() Assert.IsNotNull(world); } + [TestMethod] + public void SetBlockByNameUsesPaletteOrLegacyIdAndData() + { + NbtWorld modernWorld = NbtWorld.Open(@"..\..\Data\26_2-creative\"); + BlockManager modern = modernWorld.GetBlockManager() as BlockManager; + Assert.IsNotNull(modern); + modern.SetBlock(79, 63, 249, AcquaticBlocks.LeafLitter); + Assert.AreEqual( + AcquaticBlocks.LeafLitter, modern.GetStringID(79, 63, 249)); + modern.SetBlock( + 79, 64, 249, AcquaticBlocks.OakWallSign, + facing: BlockFacing.East); + Assert.AreEqual( + AcquaticBlocks.OakWallSign, modern.GetStringID(79, 64, 249)); + Assert.AreEqual("east", + modern.GetBlockProperty( + 79, 64, 249, BlockProperties.Facing)); + Assert.IsNull(modern.GetBlockProperty( + 79, 64, 249, BlockProperties.Waterlogged)); + + NbtWorld legacyWorld = NbtWorld.Open(@"..\..\Data\1_7_10-creative\"); + BlockManager legacy = legacyWorld.GetBlockManager() as BlockManager; + Assert.IsNotNull(legacy); + int x = legacyWorld.Level.Spawn.X; + int y = legacyWorld.Level.Spawn.Y; + int z = legacyWorld.Level.Spawn.Z; + legacy.SetBlock(x, y, z, AcquaticBlocks.BlueStainedGlass); + Assert.AreEqual(BlockType.STAINED_GLASS, legacy.GetID(x, y, z)); + Assert.AreEqual(11, legacy.GetData(x, y, z)); + + legacy.SetBlock( + x, y + 1, z, AcquaticBlocks.AcaciaLog, + axis: BlockAxis.X); + Assert.AreEqual( + BlockInfo.AcaciaWood.ID, legacy.GetID(x, y + 1, z)); + Assert.AreEqual(4, legacy.GetData(x, y + 1, z)); + + bool threw = false; + try { + legacy.SetBlock(x, y, z, AcquaticBlocks.LeafLitter); + } + catch (ArgumentException) { + threw = true; + } + Assert.IsTrue(threw); + } + [TestMethod] public void OpenTest_1_8_3_survival() { @@ -63,5 +342,51 @@ public void OpenTest_1_9_2_debug() NbtWorld world = NbtWorld.Open(@"..\..\Data\1_9_2-debug\"); Assert.IsNotNull(world); } + + [TestMethod] + public void AnvilWorldUsesLegacyOverworldRegionLocation() + { + string directory = Path.Combine(Path.GetTempPath(), "Substrate-World-" + Guid.NewGuid().ToString("N")); + try { + AnvilWorld.Create(directory).Save(); + + AnvilWorld world = AnvilWorld.Open(directory); + string expected = Path.Combine(directory, "region"); + Assert.AreEqual(expected, world.GetRegionManager().GetRegionPath()); + + world.GetRegionManager().CreateRegion(0, 0); + Assert.IsTrue(File.Exists(Path.Combine(expected, "r.0.0.mca"))); + } + finally { + if (Directory.Exists(directory)) + Directory.Delete(directory, true); + } + } + + [TestMethod] + public void AnvilWorldUsesNamespacedOverworldRegionLocation() + { + string directory = Path.Combine(Path.GetTempPath(), "Substrate-World-" + Guid.NewGuid().ToString("N")); + try { + AnvilWorld.Create(directory).Save(); + + string legacy = Path.Combine(directory, "region"); + string modern = Path.Combine(directory, "dimensions", "minecraft", "overworld", "region"); + Directory.CreateDirectory(Path.GetDirectoryName(modern)); + Directory.Move(legacy, modern); + + AnvilWorld world = NbtWorld.Open(directory) as AnvilWorld; + Assert.IsNotNull(world); + Assert.AreEqual(modern, world.GetRegionManager().GetRegionPath()); + + world.GetRegionManager().CreateRegion(0, 0); + Assert.IsTrue(File.Exists(Path.Combine(modern, "r.0.0.mca"))); + Assert.IsFalse(Directory.Exists(legacy)); + } + finally { + if (Directory.Exists(directory)) + Directory.Delete(directory, true); + } + } } } diff --git a/SubstrateCS/Source/AcquaticBlocks.cs b/SubstrateCS/Source/AcquaticBlocks.cs new file mode 100644 index 00000000..0b7d6662 --- /dev/null +++ b/SubstrateCS/Source/AcquaticBlocks.cs @@ -0,0 +1,1203 @@ +namespace Substrate +{ + /// Namespaced identifiers for every block in Minecraft Java Edition 26.2. + public static class AcquaticBlocks + { + public const string AcaciaButton = "minecraft:acacia_button"; + public const string AcaciaDoor = "minecraft:acacia_door"; + public const string AcaciaFence = "minecraft:acacia_fence"; + public const string AcaciaFenceGate = "minecraft:acacia_fence_gate"; + public const string AcaciaHangingSign = "minecraft:acacia_hanging_sign"; + public const string AcaciaLeaves = "minecraft:acacia_leaves"; + public const string AcaciaLog = "minecraft:acacia_log"; + public const string AcaciaPlanks = "minecraft:acacia_planks"; + public const string AcaciaPressurePlate = "minecraft:acacia_pressure_plate"; + public const string AcaciaSapling = "minecraft:acacia_sapling"; + public const string AcaciaShelf = "minecraft:acacia_shelf"; + public const string AcaciaSign = "minecraft:acacia_sign"; + public const string AcaciaSlab = "minecraft:acacia_slab"; + public const string AcaciaStairs = "minecraft:acacia_stairs"; + public const string AcaciaTrapdoor = "minecraft:acacia_trapdoor"; + public const string AcaciaWallHangingSign = "minecraft:acacia_wall_hanging_sign"; + public const string AcaciaWallSign = "minecraft:acacia_wall_sign"; + public const string AcaciaWood = "minecraft:acacia_wood"; + public const string ActivatorRail = "minecraft:activator_rail"; + public const string Air = "minecraft:air"; + public const string Allium = "minecraft:allium"; + public const string AmethystBlock = "minecraft:amethyst_block"; + public const string AmethystCluster = "minecraft:amethyst_cluster"; + public const string AncientDebris = "minecraft:ancient_debris"; + public const string Andesite = "minecraft:andesite"; + public const string AndesiteSlab = "minecraft:andesite_slab"; + public const string AndesiteStairs = "minecraft:andesite_stairs"; + public const string AndesiteWall = "minecraft:andesite_wall"; + public const string Anvil = "minecraft:anvil"; + public const string AttachedMelonStem = "minecraft:attached_melon_stem"; + public const string AttachedPumpkinStem = "minecraft:attached_pumpkin_stem"; + public const string Azalea = "minecraft:azalea"; + public const string AzaleaLeaves = "minecraft:azalea_leaves"; + public const string AzureBluet = "minecraft:azure_bluet"; + public const string Bamboo = "minecraft:bamboo"; + public const string BambooBlock = "minecraft:bamboo_block"; + public const string BambooButton = "minecraft:bamboo_button"; + public const string BambooDoor = "minecraft:bamboo_door"; + public const string BambooFence = "minecraft:bamboo_fence"; + public const string BambooFenceGate = "minecraft:bamboo_fence_gate"; + public const string BambooHangingSign = "minecraft:bamboo_hanging_sign"; + public const string BambooMosaic = "minecraft:bamboo_mosaic"; + public const string BambooMosaicSlab = "minecraft:bamboo_mosaic_slab"; + public const string BambooMosaicStairs = "minecraft:bamboo_mosaic_stairs"; + public const string BambooPlanks = "minecraft:bamboo_planks"; + public const string BambooPressurePlate = "minecraft:bamboo_pressure_plate"; + public const string BambooSapling = "minecraft:bamboo_sapling"; + public const string BambooShelf = "minecraft:bamboo_shelf"; + public const string BambooSign = "minecraft:bamboo_sign"; + public const string BambooSlab = "minecraft:bamboo_slab"; + public const string BambooStairs = "minecraft:bamboo_stairs"; + public const string BambooTrapdoor = "minecraft:bamboo_trapdoor"; + public const string BambooWallHangingSign = "minecraft:bamboo_wall_hanging_sign"; + public const string BambooWallSign = "minecraft:bamboo_wall_sign"; + public const string Barrel = "minecraft:barrel"; + public const string Barrier = "minecraft:barrier"; + public const string Basalt = "minecraft:basalt"; + public const string Beacon = "minecraft:beacon"; + public const string Bedrock = "minecraft:bedrock"; + public const string BeeNest = "minecraft:bee_nest"; + public const string Beehive = "minecraft:beehive"; + public const string Beetroots = "minecraft:beetroots"; + public const string Bell = "minecraft:bell"; + public const string BigDripleaf = "minecraft:big_dripleaf"; + public const string BigDripleafStem = "minecraft:big_dripleaf_stem"; + public const string BirchButton = "minecraft:birch_button"; + public const string BirchDoor = "minecraft:birch_door"; + public const string BirchFence = "minecraft:birch_fence"; + public const string BirchFenceGate = "minecraft:birch_fence_gate"; + public const string BirchHangingSign = "minecraft:birch_hanging_sign"; + public const string BirchLeaves = "minecraft:birch_leaves"; + public const string BirchLog = "minecraft:birch_log"; + public const string BirchPlanks = "minecraft:birch_planks"; + public const string BirchPressurePlate = "minecraft:birch_pressure_plate"; + public const string BirchSapling = "minecraft:birch_sapling"; + public const string BirchShelf = "minecraft:birch_shelf"; + public const string BirchSign = "minecraft:birch_sign"; + public const string BirchSlab = "minecraft:birch_slab"; + public const string BirchStairs = "minecraft:birch_stairs"; + public const string BirchTrapdoor = "minecraft:birch_trapdoor"; + public const string BirchWallHangingSign = "minecraft:birch_wall_hanging_sign"; + public const string BirchWallSign = "minecraft:birch_wall_sign"; + public const string BirchWood = "minecraft:birch_wood"; + public const string BlackBanner = "minecraft:black_banner"; + public const string BlackBed = "minecraft:black_bed"; + public const string BlackCandle = "minecraft:black_candle"; + public const string BlackCandleCake = "minecraft:black_candle_cake"; + public const string BlackCarpet = "minecraft:black_carpet"; + public const string BlackConcrete = "minecraft:black_concrete"; + public const string BlackConcretePowder = "minecraft:black_concrete_powder"; + public const string BlackGlazedTerracotta = "minecraft:black_glazed_terracotta"; + public const string BlackShulkerBox = "minecraft:black_shulker_box"; + public const string BlackStainedGlass = "minecraft:black_stained_glass"; + public const string BlackStainedGlassPane = "minecraft:black_stained_glass_pane"; + public const string BlackTerracotta = "minecraft:black_terracotta"; + public const string BlackWallBanner = "minecraft:black_wall_banner"; + public const string BlackWool = "minecraft:black_wool"; + public const string Blackstone = "minecraft:blackstone"; + public const string BlackstoneSlab = "minecraft:blackstone_slab"; + public const string BlackstoneStairs = "minecraft:blackstone_stairs"; + public const string BlackstoneWall = "minecraft:blackstone_wall"; + public const string BlastFurnace = "minecraft:blast_furnace"; + public const string BlueBanner = "minecraft:blue_banner"; + public const string BlueBed = "minecraft:blue_bed"; + public const string BlueCandle = "minecraft:blue_candle"; + public const string BlueCandleCake = "minecraft:blue_candle_cake"; + public const string BlueCarpet = "minecraft:blue_carpet"; + public const string BlueConcrete = "minecraft:blue_concrete"; + public const string BlueConcretePowder = "minecraft:blue_concrete_powder"; + public const string BlueGlazedTerracotta = "minecraft:blue_glazed_terracotta"; + public const string BlueIce = "minecraft:blue_ice"; + public const string BlueOrchid = "minecraft:blue_orchid"; + public const string BlueShulkerBox = "minecraft:blue_shulker_box"; + public const string BlueStainedGlass = "minecraft:blue_stained_glass"; + public const string BlueStainedGlassPane = "minecraft:blue_stained_glass_pane"; + public const string BlueTerracotta = "minecraft:blue_terracotta"; + public const string BlueWallBanner = "minecraft:blue_wall_banner"; + public const string BlueWool = "minecraft:blue_wool"; + public const string BoneBlock = "minecraft:bone_block"; + public const string Bookshelf = "minecraft:bookshelf"; + public const string BrainCoral = "minecraft:brain_coral"; + public const string BrainCoralBlock = "minecraft:brain_coral_block"; + public const string BrainCoralFan = "minecraft:brain_coral_fan"; + public const string BrainCoralWallFan = "minecraft:brain_coral_wall_fan"; + public const string BrewingStand = "minecraft:brewing_stand"; + public const string BrickSlab = "minecraft:brick_slab"; + public const string BrickStairs = "minecraft:brick_stairs"; + public const string BrickWall = "minecraft:brick_wall"; + public const string Bricks = "minecraft:bricks"; + public const string BrownBanner = "minecraft:brown_banner"; + public const string BrownBed = "minecraft:brown_bed"; + public const string BrownCandle = "minecraft:brown_candle"; + public const string BrownCandleCake = "minecraft:brown_candle_cake"; + public const string BrownCarpet = "minecraft:brown_carpet"; + public const string BrownConcrete = "minecraft:brown_concrete"; + public const string BrownConcretePowder = "minecraft:brown_concrete_powder"; + public const string BrownGlazedTerracotta = "minecraft:brown_glazed_terracotta"; + public const string BrownMushroom = "minecraft:brown_mushroom"; + public const string BrownMushroomBlock = "minecraft:brown_mushroom_block"; + public const string BrownShulkerBox = "minecraft:brown_shulker_box"; + public const string BrownStainedGlass = "minecraft:brown_stained_glass"; + public const string BrownStainedGlassPane = "minecraft:brown_stained_glass_pane"; + public const string BrownTerracotta = "minecraft:brown_terracotta"; + public const string BrownWallBanner = "minecraft:brown_wall_banner"; + public const string BrownWool = "minecraft:brown_wool"; + public const string BubbleColumn = "minecraft:bubble_column"; + public const string BubbleCoral = "minecraft:bubble_coral"; + public const string BubbleCoralBlock = "minecraft:bubble_coral_block"; + public const string BubbleCoralFan = "minecraft:bubble_coral_fan"; + public const string BubbleCoralWallFan = "minecraft:bubble_coral_wall_fan"; + public const string BuddingAmethyst = "minecraft:budding_amethyst"; + public const string Bush = "minecraft:bush"; + public const string Cactus = "minecraft:cactus"; + public const string CactusFlower = "minecraft:cactus_flower"; + public const string Cake = "minecraft:cake"; + public const string Calcite = "minecraft:calcite"; + public const string CalibratedSculkSensor = "minecraft:calibrated_sculk_sensor"; + public const string Campfire = "minecraft:campfire"; + public const string Candle = "minecraft:candle"; + public const string CandleCake = "minecraft:candle_cake"; + public const string Carrots = "minecraft:carrots"; + public const string CartographyTable = "minecraft:cartography_table"; + public const string CarvedPumpkin = "minecraft:carved_pumpkin"; + public const string Cauldron = "minecraft:cauldron"; + public const string CaveAir = "minecraft:cave_air"; + public const string CaveVines = "minecraft:cave_vines"; + public const string CaveVinesPlant = "minecraft:cave_vines_plant"; + public const string ChainCommandBlock = "minecraft:chain_command_block"; + public const string CherryButton = "minecraft:cherry_button"; + public const string CherryDoor = "minecraft:cherry_door"; + public const string CherryFence = "minecraft:cherry_fence"; + public const string CherryFenceGate = "minecraft:cherry_fence_gate"; + public const string CherryHangingSign = "minecraft:cherry_hanging_sign"; + public const string CherryLeaves = "minecraft:cherry_leaves"; + public const string CherryLog = "minecraft:cherry_log"; + public const string CherryPlanks = "minecraft:cherry_planks"; + public const string CherryPressurePlate = "minecraft:cherry_pressure_plate"; + public const string CherrySapling = "minecraft:cherry_sapling"; + public const string CherryShelf = "minecraft:cherry_shelf"; + public const string CherrySign = "minecraft:cherry_sign"; + public const string CherrySlab = "minecraft:cherry_slab"; + public const string CherryStairs = "minecraft:cherry_stairs"; + public const string CherryTrapdoor = "minecraft:cherry_trapdoor"; + public const string CherryWallHangingSign = "minecraft:cherry_wall_hanging_sign"; + public const string CherryWallSign = "minecraft:cherry_wall_sign"; + public const string CherryWood = "minecraft:cherry_wood"; + public const string Chest = "minecraft:chest"; + public const string ChippedAnvil = "minecraft:chipped_anvil"; + public const string ChiseledBookshelf = "minecraft:chiseled_bookshelf"; + public const string ChiseledCinnabar = "minecraft:chiseled_cinnabar"; + public const string ChiseledCopper = "minecraft:chiseled_copper"; + public const string ChiseledDeepslate = "minecraft:chiseled_deepslate"; + public const string ChiseledNetherBricks = "minecraft:chiseled_nether_bricks"; + public const string ChiseledPolishedBlackstone = "minecraft:chiseled_polished_blackstone"; + public const string ChiseledQuartzBlock = "minecraft:chiseled_quartz_block"; + public const string ChiseledRedSandstone = "minecraft:chiseled_red_sandstone"; + public const string ChiseledResinBricks = "minecraft:chiseled_resin_bricks"; + public const string ChiseledSandstone = "minecraft:chiseled_sandstone"; + public const string ChiseledStoneBricks = "minecraft:chiseled_stone_bricks"; + public const string ChiseledSulfur = "minecraft:chiseled_sulfur"; + public const string ChiseledTuff = "minecraft:chiseled_tuff"; + public const string ChiseledTuffBricks = "minecraft:chiseled_tuff_bricks"; + public const string ChorusFlower = "minecraft:chorus_flower"; + public const string ChorusPlant = "minecraft:chorus_plant"; + public const string Cinnabar = "minecraft:cinnabar"; + public const string CinnabarBrickSlab = "minecraft:cinnabar_brick_slab"; + public const string CinnabarBrickStairs = "minecraft:cinnabar_brick_stairs"; + public const string CinnabarBrickWall = "minecraft:cinnabar_brick_wall"; + public const string CinnabarBricks = "minecraft:cinnabar_bricks"; + public const string CinnabarSlab = "minecraft:cinnabar_slab"; + public const string CinnabarStairs = "minecraft:cinnabar_stairs"; + public const string CinnabarWall = "minecraft:cinnabar_wall"; + public const string Clay = "minecraft:clay"; + public const string ClosedEyeblossom = "minecraft:closed_eyeblossom"; + public const string CoalBlock = "minecraft:coal_block"; + public const string CoalOre = "minecraft:coal_ore"; + public const string CoarseDirt = "minecraft:coarse_dirt"; + public const string CobbledDeepslate = "minecraft:cobbled_deepslate"; + public const string CobbledDeepslateSlab = "minecraft:cobbled_deepslate_slab"; + public const string CobbledDeepslateStairs = "minecraft:cobbled_deepslate_stairs"; + public const string CobbledDeepslateWall = "minecraft:cobbled_deepslate_wall"; + public const string Cobblestone = "minecraft:cobblestone"; + public const string CobblestoneSlab = "minecraft:cobblestone_slab"; + public const string CobblestoneStairs = "minecraft:cobblestone_stairs"; + public const string CobblestoneWall = "minecraft:cobblestone_wall"; + public const string Cobweb = "minecraft:cobweb"; + public const string Cocoa = "minecraft:cocoa"; + public const string CommandBlock = "minecraft:command_block"; + public const string Comparator = "minecraft:comparator"; + public const string Composter = "minecraft:composter"; + public const string Conduit = "minecraft:conduit"; + public const string CopperBars = "minecraft:copper_bars"; + public const string CopperBlock = "minecraft:copper_block"; + public const string CopperBulb = "minecraft:copper_bulb"; + public const string CopperChain = "minecraft:copper_chain"; + public const string CopperChest = "minecraft:copper_chest"; + public const string CopperDoor = "minecraft:copper_door"; + public const string CopperGolemStatue = "minecraft:copper_golem_statue"; + public const string CopperGrate = "minecraft:copper_grate"; + public const string CopperLantern = "minecraft:copper_lantern"; + public const string CopperOre = "minecraft:copper_ore"; + public const string CopperTorch = "minecraft:copper_torch"; + public const string CopperTrapdoor = "minecraft:copper_trapdoor"; + public const string CopperWallTorch = "minecraft:copper_wall_torch"; + public const string Cornflower = "minecraft:cornflower"; + public const string CrackedDeepslateBricks = "minecraft:cracked_deepslate_bricks"; + public const string CrackedDeepslateTiles = "minecraft:cracked_deepslate_tiles"; + public const string CrackedNetherBricks = "minecraft:cracked_nether_bricks"; + public const string CrackedPolishedBlackstoneBricks = "minecraft:cracked_polished_blackstone_bricks"; + public const string CrackedStoneBricks = "minecraft:cracked_stone_bricks"; + public const string Crafter = "minecraft:crafter"; + public const string CraftingTable = "minecraft:crafting_table"; + public const string CreakingHeart = "minecraft:creaking_heart"; + public const string CreeperHead = "minecraft:creeper_head"; + public const string CreeperWallHead = "minecraft:creeper_wall_head"; + public const string CrimsonButton = "minecraft:crimson_button"; + public const string CrimsonDoor = "minecraft:crimson_door"; + public const string CrimsonFence = "minecraft:crimson_fence"; + public const string CrimsonFenceGate = "minecraft:crimson_fence_gate"; + public const string CrimsonFungus = "minecraft:crimson_fungus"; + public const string CrimsonHangingSign = "minecraft:crimson_hanging_sign"; + public const string CrimsonHyphae = "minecraft:crimson_hyphae"; + public const string CrimsonNylium = "minecraft:crimson_nylium"; + public const string CrimsonPlanks = "minecraft:crimson_planks"; + public const string CrimsonPressurePlate = "minecraft:crimson_pressure_plate"; + public const string CrimsonRoots = "minecraft:crimson_roots"; + public const string CrimsonShelf = "minecraft:crimson_shelf"; + public const string CrimsonSign = "minecraft:crimson_sign"; + public const string CrimsonSlab = "minecraft:crimson_slab"; + public const string CrimsonStairs = "minecraft:crimson_stairs"; + public const string CrimsonStem = "minecraft:crimson_stem"; + public const string CrimsonTrapdoor = "minecraft:crimson_trapdoor"; + public const string CrimsonWallHangingSign = "minecraft:crimson_wall_hanging_sign"; + public const string CrimsonWallSign = "minecraft:crimson_wall_sign"; + public const string CryingObsidian = "minecraft:crying_obsidian"; + public const string CutCopper = "minecraft:cut_copper"; + public const string CutCopperSlab = "minecraft:cut_copper_slab"; + public const string CutCopperStairs = "minecraft:cut_copper_stairs"; + public const string CutRedSandstone = "minecraft:cut_red_sandstone"; + public const string CutRedSandstoneSlab = "minecraft:cut_red_sandstone_slab"; + public const string CutSandstone = "minecraft:cut_sandstone"; + public const string CutSandstoneSlab = "minecraft:cut_sandstone_slab"; + public const string CyanBanner = "minecraft:cyan_banner"; + public const string CyanBed = "minecraft:cyan_bed"; + public const string CyanCandle = "minecraft:cyan_candle"; + public const string CyanCandleCake = "minecraft:cyan_candle_cake"; + public const string CyanCarpet = "minecraft:cyan_carpet"; + public const string CyanConcrete = "minecraft:cyan_concrete"; + public const string CyanConcretePowder = "minecraft:cyan_concrete_powder"; + public const string CyanGlazedTerracotta = "minecraft:cyan_glazed_terracotta"; + public const string CyanShulkerBox = "minecraft:cyan_shulker_box"; + public const string CyanStainedGlass = "minecraft:cyan_stained_glass"; + public const string CyanStainedGlassPane = "minecraft:cyan_stained_glass_pane"; + public const string CyanTerracotta = "minecraft:cyan_terracotta"; + public const string CyanWallBanner = "minecraft:cyan_wall_banner"; + public const string CyanWool = "minecraft:cyan_wool"; + public const string DamagedAnvil = "minecraft:damaged_anvil"; + public const string Dandelion = "minecraft:dandelion"; + public const string DarkOakButton = "minecraft:dark_oak_button"; + public const string DarkOakDoor = "minecraft:dark_oak_door"; + public const string DarkOakFence = "minecraft:dark_oak_fence"; + public const string DarkOakFenceGate = "minecraft:dark_oak_fence_gate"; + public const string DarkOakHangingSign = "minecraft:dark_oak_hanging_sign"; + public const string DarkOakLeaves = "minecraft:dark_oak_leaves"; + public const string DarkOakLog = "minecraft:dark_oak_log"; + public const string DarkOakPlanks = "minecraft:dark_oak_planks"; + public const string DarkOakPressurePlate = "minecraft:dark_oak_pressure_plate"; + public const string DarkOakSapling = "minecraft:dark_oak_sapling"; + public const string DarkOakShelf = "minecraft:dark_oak_shelf"; + public const string DarkOakSign = "minecraft:dark_oak_sign"; + public const string DarkOakSlab = "minecraft:dark_oak_slab"; + public const string DarkOakStairs = "minecraft:dark_oak_stairs"; + public const string DarkOakTrapdoor = "minecraft:dark_oak_trapdoor"; + public const string DarkOakWallHangingSign = "minecraft:dark_oak_wall_hanging_sign"; + public const string DarkOakWallSign = "minecraft:dark_oak_wall_sign"; + public const string DarkOakWood = "minecraft:dark_oak_wood"; + public const string DarkPrismarine = "minecraft:dark_prismarine"; + public const string DarkPrismarineSlab = "minecraft:dark_prismarine_slab"; + public const string DarkPrismarineStairs = "minecraft:dark_prismarine_stairs"; + public const string DaylightDetector = "minecraft:daylight_detector"; + public const string DeadBrainCoral = "minecraft:dead_brain_coral"; + public const string DeadBrainCoralBlock = "minecraft:dead_brain_coral_block"; + public const string DeadBrainCoralFan = "minecraft:dead_brain_coral_fan"; + public const string DeadBrainCoralWallFan = "minecraft:dead_brain_coral_wall_fan"; + public const string DeadBubbleCoral = "minecraft:dead_bubble_coral"; + public const string DeadBubbleCoralBlock = "minecraft:dead_bubble_coral_block"; + public const string DeadBubbleCoralFan = "minecraft:dead_bubble_coral_fan"; + public const string DeadBubbleCoralWallFan = "minecraft:dead_bubble_coral_wall_fan"; + public const string DeadBush = "minecraft:dead_bush"; + public const string DeadFireCoral = "minecraft:dead_fire_coral"; + public const string DeadFireCoralBlock = "minecraft:dead_fire_coral_block"; + public const string DeadFireCoralFan = "minecraft:dead_fire_coral_fan"; + public const string DeadFireCoralWallFan = "minecraft:dead_fire_coral_wall_fan"; + public const string DeadHornCoral = "minecraft:dead_horn_coral"; + public const string DeadHornCoralBlock = "minecraft:dead_horn_coral_block"; + public const string DeadHornCoralFan = "minecraft:dead_horn_coral_fan"; + public const string DeadHornCoralWallFan = "minecraft:dead_horn_coral_wall_fan"; + public const string DeadTubeCoral = "minecraft:dead_tube_coral"; + public const string DeadTubeCoralBlock = "minecraft:dead_tube_coral_block"; + public const string DeadTubeCoralFan = "minecraft:dead_tube_coral_fan"; + public const string DeadTubeCoralWallFan = "minecraft:dead_tube_coral_wall_fan"; + public const string DecoratedPot = "minecraft:decorated_pot"; + public const string Deepslate = "minecraft:deepslate"; + public const string DeepslateBrickSlab = "minecraft:deepslate_brick_slab"; + public const string DeepslateBrickStairs = "minecraft:deepslate_brick_stairs"; + public const string DeepslateBrickWall = "minecraft:deepslate_brick_wall"; + public const string DeepslateBricks = "minecraft:deepslate_bricks"; + public const string DeepslateCoalOre = "minecraft:deepslate_coal_ore"; + public const string DeepslateCopperOre = "minecraft:deepslate_copper_ore"; + public const string DeepslateDiamondOre = "minecraft:deepslate_diamond_ore"; + public const string DeepslateEmeraldOre = "minecraft:deepslate_emerald_ore"; + public const string DeepslateGoldOre = "minecraft:deepslate_gold_ore"; + public const string DeepslateIronOre = "minecraft:deepslate_iron_ore"; + public const string DeepslateLapisOre = "minecraft:deepslate_lapis_ore"; + public const string DeepslateRedstoneOre = "minecraft:deepslate_redstone_ore"; + public const string DeepslateTileSlab = "minecraft:deepslate_tile_slab"; + public const string DeepslateTileStairs = "minecraft:deepslate_tile_stairs"; + public const string DeepslateTileWall = "minecraft:deepslate_tile_wall"; + public const string DeepslateTiles = "minecraft:deepslate_tiles"; + public const string DetectorRail = "minecraft:detector_rail"; + public const string DiamondBlock = "minecraft:diamond_block"; + public const string DiamondOre = "minecraft:diamond_ore"; + public const string Diorite = "minecraft:diorite"; + public const string DioriteSlab = "minecraft:diorite_slab"; + public const string DioriteStairs = "minecraft:diorite_stairs"; + public const string DioriteWall = "minecraft:diorite_wall"; + public const string Dirt = "minecraft:dirt"; + public const string DirtPath = "minecraft:dirt_path"; + public const string Dispenser = "minecraft:dispenser"; + public const string DragonEgg = "minecraft:dragon_egg"; + public const string DragonHead = "minecraft:dragon_head"; + public const string DragonWallHead = "minecraft:dragon_wall_head"; + public const string DriedGhast = "minecraft:dried_ghast"; + public const string DriedKelpBlock = "minecraft:dried_kelp_block"; + public const string DripstoneBlock = "minecraft:dripstone_block"; + public const string Dropper = "minecraft:dropper"; + public const string EmeraldBlock = "minecraft:emerald_block"; + public const string EmeraldOre = "minecraft:emerald_ore"; + public const string EnchantingTable = "minecraft:enchanting_table"; + public const string EndGateway = "minecraft:end_gateway"; + public const string EndPortal = "minecraft:end_portal"; + public const string EndPortalFrame = "minecraft:end_portal_frame"; + public const string EndRod = "minecraft:end_rod"; + public const string EndStone = "minecraft:end_stone"; + public const string EndStoneBrickSlab = "minecraft:end_stone_brick_slab"; + public const string EndStoneBrickStairs = "minecraft:end_stone_brick_stairs"; + public const string EndStoneBrickWall = "minecraft:end_stone_brick_wall"; + public const string EndStoneBricks = "minecraft:end_stone_bricks"; + public const string EnderChest = "minecraft:ender_chest"; + public const string ExposedChiseledCopper = "minecraft:exposed_chiseled_copper"; + public const string ExposedCopper = "minecraft:exposed_copper"; + public const string ExposedCopperBars = "minecraft:exposed_copper_bars"; + public const string ExposedCopperBulb = "minecraft:exposed_copper_bulb"; + public const string ExposedCopperChain = "minecraft:exposed_copper_chain"; + public const string ExposedCopperChest = "minecraft:exposed_copper_chest"; + public const string ExposedCopperDoor = "minecraft:exposed_copper_door"; + public const string ExposedCopperGolemStatue = "minecraft:exposed_copper_golem_statue"; + public const string ExposedCopperGrate = "minecraft:exposed_copper_grate"; + public const string ExposedCopperLantern = "minecraft:exposed_copper_lantern"; + public const string ExposedCopperTrapdoor = "minecraft:exposed_copper_trapdoor"; + public const string ExposedCutCopper = "minecraft:exposed_cut_copper"; + public const string ExposedCutCopperSlab = "minecraft:exposed_cut_copper_slab"; + public const string ExposedCutCopperStairs = "minecraft:exposed_cut_copper_stairs"; + public const string ExposedLightningRod = "minecraft:exposed_lightning_rod"; + public const string Farmland = "minecraft:farmland"; + public const string Fern = "minecraft:fern"; + public const string Fire = "minecraft:fire"; + public const string FireCoral = "minecraft:fire_coral"; + public const string FireCoralBlock = "minecraft:fire_coral_block"; + public const string FireCoralFan = "minecraft:fire_coral_fan"; + public const string FireCoralWallFan = "minecraft:fire_coral_wall_fan"; + public const string FireflyBush = "minecraft:firefly_bush"; + public const string FletchingTable = "minecraft:fletching_table"; + public const string FlowerPot = "minecraft:flower_pot"; + public const string FloweringAzalea = "minecraft:flowering_azalea"; + public const string FloweringAzaleaLeaves = "minecraft:flowering_azalea_leaves"; + public const string Frogspawn = "minecraft:frogspawn"; + public const string FrostedIce = "minecraft:frosted_ice"; + public const string Furnace = "minecraft:furnace"; + public const string GildedBlackstone = "minecraft:gilded_blackstone"; + public const string Glass = "minecraft:glass"; + public const string GlassPane = "minecraft:glass_pane"; + public const string GlowLichen = "minecraft:glow_lichen"; + public const string Glowstone = "minecraft:glowstone"; + public const string GoldBlock = "minecraft:gold_block"; + public const string GoldOre = "minecraft:gold_ore"; + public const string GoldenDandelion = "minecraft:golden_dandelion"; + public const string Granite = "minecraft:granite"; + public const string GraniteSlab = "minecraft:granite_slab"; + public const string GraniteStairs = "minecraft:granite_stairs"; + public const string GraniteWall = "minecraft:granite_wall"; + public const string GrassBlock = "minecraft:grass_block"; + public const string Gravel = "minecraft:gravel"; + public const string GrayBanner = "minecraft:gray_banner"; + public const string GrayBed = "minecraft:gray_bed"; + public const string GrayCandle = "minecraft:gray_candle"; + public const string GrayCandleCake = "minecraft:gray_candle_cake"; + public const string GrayCarpet = "minecraft:gray_carpet"; + public const string GrayConcrete = "minecraft:gray_concrete"; + public const string GrayConcretePowder = "minecraft:gray_concrete_powder"; + public const string GrayGlazedTerracotta = "minecraft:gray_glazed_terracotta"; + public const string GrayShulkerBox = "minecraft:gray_shulker_box"; + public const string GrayStainedGlass = "minecraft:gray_stained_glass"; + public const string GrayStainedGlassPane = "minecraft:gray_stained_glass_pane"; + public const string GrayTerracotta = "minecraft:gray_terracotta"; + public const string GrayWallBanner = "minecraft:gray_wall_banner"; + public const string GrayWool = "minecraft:gray_wool"; + public const string GreenBanner = "minecraft:green_banner"; + public const string GreenBed = "minecraft:green_bed"; + public const string GreenCandle = "minecraft:green_candle"; + public const string GreenCandleCake = "minecraft:green_candle_cake"; + public const string GreenCarpet = "minecraft:green_carpet"; + public const string GreenConcrete = "minecraft:green_concrete"; + public const string GreenConcretePowder = "minecraft:green_concrete_powder"; + public const string GreenGlazedTerracotta = "minecraft:green_glazed_terracotta"; + public const string GreenShulkerBox = "minecraft:green_shulker_box"; + public const string GreenStainedGlass = "minecraft:green_stained_glass"; + public const string GreenStainedGlassPane = "minecraft:green_stained_glass_pane"; + public const string GreenTerracotta = "minecraft:green_terracotta"; + public const string GreenWallBanner = "minecraft:green_wall_banner"; + public const string GreenWool = "minecraft:green_wool"; + public const string Grindstone = "minecraft:grindstone"; + public const string HangingRoots = "minecraft:hanging_roots"; + public const string HayBlock = "minecraft:hay_block"; + public const string HeavyCore = "minecraft:heavy_core"; + public const string HeavyWeightedPressurePlate = "minecraft:heavy_weighted_pressure_plate"; + public const string HoneyBlock = "minecraft:honey_block"; + public const string HoneycombBlock = "minecraft:honeycomb_block"; + public const string Hopper = "minecraft:hopper"; + public const string HornCoral = "minecraft:horn_coral"; + public const string HornCoralBlock = "minecraft:horn_coral_block"; + public const string HornCoralFan = "minecraft:horn_coral_fan"; + public const string HornCoralWallFan = "minecraft:horn_coral_wall_fan"; + public const string Ice = "minecraft:ice"; + public const string InfestedChiseledStoneBricks = "minecraft:infested_chiseled_stone_bricks"; + public const string InfestedCobblestone = "minecraft:infested_cobblestone"; + public const string InfestedCrackedStoneBricks = "minecraft:infested_cracked_stone_bricks"; + public const string InfestedDeepslate = "minecraft:infested_deepslate"; + public const string InfestedMossyStoneBricks = "minecraft:infested_mossy_stone_bricks"; + public const string InfestedStone = "minecraft:infested_stone"; + public const string InfestedStoneBricks = "minecraft:infested_stone_bricks"; + public const string IronBars = "minecraft:iron_bars"; + public const string IronBlock = "minecraft:iron_block"; + public const string IronChain = "minecraft:iron_chain"; + public const string IronDoor = "minecraft:iron_door"; + public const string IronOre = "minecraft:iron_ore"; + public const string IronTrapdoor = "minecraft:iron_trapdoor"; + public const string JackOLantern = "minecraft:jack_o_lantern"; + public const string Jigsaw = "minecraft:jigsaw"; + public const string Jukebox = "minecraft:jukebox"; + public const string JungleButton = "minecraft:jungle_button"; + public const string JungleDoor = "minecraft:jungle_door"; + public const string JungleFence = "minecraft:jungle_fence"; + public const string JungleFenceGate = "minecraft:jungle_fence_gate"; + public const string JungleHangingSign = "minecraft:jungle_hanging_sign"; + public const string JungleLeaves = "minecraft:jungle_leaves"; + public const string JungleLog = "minecraft:jungle_log"; + public const string JunglePlanks = "minecraft:jungle_planks"; + public const string JunglePressurePlate = "minecraft:jungle_pressure_plate"; + public const string JungleSapling = "minecraft:jungle_sapling"; + public const string JungleShelf = "minecraft:jungle_shelf"; + public const string JungleSign = "minecraft:jungle_sign"; + public const string JungleSlab = "minecraft:jungle_slab"; + public const string JungleStairs = "minecraft:jungle_stairs"; + public const string JungleTrapdoor = "minecraft:jungle_trapdoor"; + public const string JungleWallHangingSign = "minecraft:jungle_wall_hanging_sign"; + public const string JungleWallSign = "minecraft:jungle_wall_sign"; + public const string JungleWood = "minecraft:jungle_wood"; + public const string Kelp = "minecraft:kelp"; + public const string KelpPlant = "minecraft:kelp_plant"; + public const string Ladder = "minecraft:ladder"; + public const string Lantern = "minecraft:lantern"; + public const string LapisBlock = "minecraft:lapis_block"; + public const string LapisOre = "minecraft:lapis_ore"; + public const string LargeAmethystBud = "minecraft:large_amethyst_bud"; + public const string LargeFern = "minecraft:large_fern"; + public const string Lava = "minecraft:lava"; + public const string LavaCauldron = "minecraft:lava_cauldron"; + public const string LeafLitter = "minecraft:leaf_litter"; + public const string Lectern = "minecraft:lectern"; + public const string Lever = "minecraft:lever"; + public const string Light = "minecraft:light"; + public const string LightBlueBanner = "minecraft:light_blue_banner"; + public const string LightBlueBed = "minecraft:light_blue_bed"; + public const string LightBlueCandle = "minecraft:light_blue_candle"; + public const string LightBlueCandleCake = "minecraft:light_blue_candle_cake"; + public const string LightBlueCarpet = "minecraft:light_blue_carpet"; + public const string LightBlueConcrete = "minecraft:light_blue_concrete"; + public const string LightBlueConcretePowder = "minecraft:light_blue_concrete_powder"; + public const string LightBlueGlazedTerracotta = "minecraft:light_blue_glazed_terracotta"; + public const string LightBlueShulkerBox = "minecraft:light_blue_shulker_box"; + public const string LightBlueStainedGlass = "minecraft:light_blue_stained_glass"; + public const string LightBlueStainedGlassPane = "minecraft:light_blue_stained_glass_pane"; + public const string LightBlueTerracotta = "minecraft:light_blue_terracotta"; + public const string LightBlueWallBanner = "minecraft:light_blue_wall_banner"; + public const string LightBlueWool = "minecraft:light_blue_wool"; + public const string LightGrayBanner = "minecraft:light_gray_banner"; + public const string LightGrayBed = "minecraft:light_gray_bed"; + public const string LightGrayCandle = "minecraft:light_gray_candle"; + public const string LightGrayCandleCake = "minecraft:light_gray_candle_cake"; + public const string LightGrayCarpet = "minecraft:light_gray_carpet"; + public const string LightGrayConcrete = "minecraft:light_gray_concrete"; + public const string LightGrayConcretePowder = "minecraft:light_gray_concrete_powder"; + public const string LightGrayGlazedTerracotta = "minecraft:light_gray_glazed_terracotta"; + public const string LightGrayShulkerBox = "minecraft:light_gray_shulker_box"; + public const string LightGrayStainedGlass = "minecraft:light_gray_stained_glass"; + public const string LightGrayStainedGlassPane = "minecraft:light_gray_stained_glass_pane"; + public const string LightGrayTerracotta = "minecraft:light_gray_terracotta"; + public const string LightGrayWallBanner = "minecraft:light_gray_wall_banner"; + public const string LightGrayWool = "minecraft:light_gray_wool"; + public const string LightWeightedPressurePlate = "minecraft:light_weighted_pressure_plate"; + public const string LightningRod = "minecraft:lightning_rod"; + public const string Lilac = "minecraft:lilac"; + public const string LilyOfTheValley = "minecraft:lily_of_the_valley"; + public const string LilyPad = "minecraft:lily_pad"; + public const string LimeBanner = "minecraft:lime_banner"; + public const string LimeBed = "minecraft:lime_bed"; + public const string LimeCandle = "minecraft:lime_candle"; + public const string LimeCandleCake = "minecraft:lime_candle_cake"; + public const string LimeCarpet = "minecraft:lime_carpet"; + public const string LimeConcrete = "minecraft:lime_concrete"; + public const string LimeConcretePowder = "minecraft:lime_concrete_powder"; + public const string LimeGlazedTerracotta = "minecraft:lime_glazed_terracotta"; + public const string LimeShulkerBox = "minecraft:lime_shulker_box"; + public const string LimeStainedGlass = "minecraft:lime_stained_glass"; + public const string LimeStainedGlassPane = "minecraft:lime_stained_glass_pane"; + public const string LimeTerracotta = "minecraft:lime_terracotta"; + public const string LimeWallBanner = "minecraft:lime_wall_banner"; + public const string LimeWool = "minecraft:lime_wool"; + public const string Lodestone = "minecraft:lodestone"; + public const string Loom = "minecraft:loom"; + public const string MagentaBanner = "minecraft:magenta_banner"; + public const string MagentaBed = "minecraft:magenta_bed"; + public const string MagentaCandle = "minecraft:magenta_candle"; + public const string MagentaCandleCake = "minecraft:magenta_candle_cake"; + public const string MagentaCarpet = "minecraft:magenta_carpet"; + public const string MagentaConcrete = "minecraft:magenta_concrete"; + public const string MagentaConcretePowder = "minecraft:magenta_concrete_powder"; + public const string MagentaGlazedTerracotta = "minecraft:magenta_glazed_terracotta"; + public const string MagentaShulkerBox = "minecraft:magenta_shulker_box"; + public const string MagentaStainedGlass = "minecraft:magenta_stained_glass"; + public const string MagentaStainedGlassPane = "minecraft:magenta_stained_glass_pane"; + public const string MagentaTerracotta = "minecraft:magenta_terracotta"; + public const string MagentaWallBanner = "minecraft:magenta_wall_banner"; + public const string MagentaWool = "minecraft:magenta_wool"; + public const string MagmaBlock = "minecraft:magma_block"; + public const string MangroveButton = "minecraft:mangrove_button"; + public const string MangroveDoor = "minecraft:mangrove_door"; + public const string MangroveFence = "minecraft:mangrove_fence"; + public const string MangroveFenceGate = "minecraft:mangrove_fence_gate"; + public const string MangroveHangingSign = "minecraft:mangrove_hanging_sign"; + public const string MangroveLeaves = "minecraft:mangrove_leaves"; + public const string MangroveLog = "minecraft:mangrove_log"; + public const string MangrovePlanks = "minecraft:mangrove_planks"; + public const string MangrovePressurePlate = "minecraft:mangrove_pressure_plate"; + public const string MangrovePropagule = "minecraft:mangrove_propagule"; + public const string MangroveRoots = "minecraft:mangrove_roots"; + public const string MangroveShelf = "minecraft:mangrove_shelf"; + public const string MangroveSign = "minecraft:mangrove_sign"; + public const string MangroveSlab = "minecraft:mangrove_slab"; + public const string MangroveStairs = "minecraft:mangrove_stairs"; + public const string MangroveTrapdoor = "minecraft:mangrove_trapdoor"; + public const string MangroveWallHangingSign = "minecraft:mangrove_wall_hanging_sign"; + public const string MangroveWallSign = "minecraft:mangrove_wall_sign"; + public const string MangroveWood = "minecraft:mangrove_wood"; + public const string MediumAmethystBud = "minecraft:medium_amethyst_bud"; + public const string Melon = "minecraft:melon"; + public const string MelonStem = "minecraft:melon_stem"; + public const string MossBlock = "minecraft:moss_block"; + public const string MossCarpet = "minecraft:moss_carpet"; + public const string MossyCobblestone = "minecraft:mossy_cobblestone"; + public const string MossyCobblestoneSlab = "minecraft:mossy_cobblestone_slab"; + public const string MossyCobblestoneStairs = "minecraft:mossy_cobblestone_stairs"; + public const string MossyCobblestoneWall = "minecraft:mossy_cobblestone_wall"; + public const string MossyStoneBrickSlab = "minecraft:mossy_stone_brick_slab"; + public const string MossyStoneBrickStairs = "minecraft:mossy_stone_brick_stairs"; + public const string MossyStoneBrickWall = "minecraft:mossy_stone_brick_wall"; + public const string MossyStoneBricks = "minecraft:mossy_stone_bricks"; + public const string MovingPiston = "minecraft:moving_piston"; + public const string Mud = "minecraft:mud"; + public const string MudBrickSlab = "minecraft:mud_brick_slab"; + public const string MudBrickStairs = "minecraft:mud_brick_stairs"; + public const string MudBrickWall = "minecraft:mud_brick_wall"; + public const string MudBricks = "minecraft:mud_bricks"; + public const string MuddyMangroveRoots = "minecraft:muddy_mangrove_roots"; + public const string MushroomStem = "minecraft:mushroom_stem"; + public const string Mycelium = "minecraft:mycelium"; + public const string NetherBrickFence = "minecraft:nether_brick_fence"; + public const string NetherBrickSlab = "minecraft:nether_brick_slab"; + public const string NetherBrickStairs = "minecraft:nether_brick_stairs"; + public const string NetherBrickWall = "minecraft:nether_brick_wall"; + public const string NetherBricks = "minecraft:nether_bricks"; + public const string NetherGoldOre = "minecraft:nether_gold_ore"; + public const string NetherPortal = "minecraft:nether_portal"; + public const string NetherQuartzOre = "minecraft:nether_quartz_ore"; + public const string NetherSprouts = "minecraft:nether_sprouts"; + public const string NetherWart = "minecraft:nether_wart"; + public const string NetherWartBlock = "minecraft:nether_wart_block"; + public const string NetheriteBlock = "minecraft:netherite_block"; + public const string Netherrack = "minecraft:netherrack"; + public const string NoteBlock = "minecraft:note_block"; + public const string OakButton = "minecraft:oak_button"; + public const string OakDoor = "minecraft:oak_door"; + public const string OakFence = "minecraft:oak_fence"; + public const string OakFenceGate = "minecraft:oak_fence_gate"; + public const string OakHangingSign = "minecraft:oak_hanging_sign"; + public const string OakLeaves = "minecraft:oak_leaves"; + public const string OakLog = "minecraft:oak_log"; + public const string OakPlanks = "minecraft:oak_planks"; + public const string OakPressurePlate = "minecraft:oak_pressure_plate"; + public const string OakSapling = "minecraft:oak_sapling"; + public const string OakShelf = "minecraft:oak_shelf"; + public const string OakSign = "minecraft:oak_sign"; + public const string OakSlab = "minecraft:oak_slab"; + public const string OakStairs = "minecraft:oak_stairs"; + public const string OakTrapdoor = "minecraft:oak_trapdoor"; + public const string OakWallHangingSign = "minecraft:oak_wall_hanging_sign"; + public const string OakWallSign = "minecraft:oak_wall_sign"; + public const string OakWood = "minecraft:oak_wood"; + public const string Observer = "minecraft:observer"; + public const string Obsidian = "minecraft:obsidian"; + public const string OchreFroglight = "minecraft:ochre_froglight"; + public const string OpenEyeblossom = "minecraft:open_eyeblossom"; + public const string OrangeBanner = "minecraft:orange_banner"; + public const string OrangeBed = "minecraft:orange_bed"; + public const string OrangeCandle = "minecraft:orange_candle"; + public const string OrangeCandleCake = "minecraft:orange_candle_cake"; + public const string OrangeCarpet = "minecraft:orange_carpet"; + public const string OrangeConcrete = "minecraft:orange_concrete"; + public const string OrangeConcretePowder = "minecraft:orange_concrete_powder"; + public const string OrangeGlazedTerracotta = "minecraft:orange_glazed_terracotta"; + public const string OrangeShulkerBox = "minecraft:orange_shulker_box"; + public const string OrangeStainedGlass = "minecraft:orange_stained_glass"; + public const string OrangeStainedGlassPane = "minecraft:orange_stained_glass_pane"; + public const string OrangeTerracotta = "minecraft:orange_terracotta"; + public const string OrangeTulip = "minecraft:orange_tulip"; + public const string OrangeWallBanner = "minecraft:orange_wall_banner"; + public const string OrangeWool = "minecraft:orange_wool"; + public const string OxeyeDaisy = "minecraft:oxeye_daisy"; + public const string OxidizedChiseledCopper = "minecraft:oxidized_chiseled_copper"; + public const string OxidizedCopper = "minecraft:oxidized_copper"; + public const string OxidizedCopperBars = "minecraft:oxidized_copper_bars"; + public const string OxidizedCopperBulb = "minecraft:oxidized_copper_bulb"; + public const string OxidizedCopperChain = "minecraft:oxidized_copper_chain"; + public const string OxidizedCopperChest = "minecraft:oxidized_copper_chest"; + public const string OxidizedCopperDoor = "minecraft:oxidized_copper_door"; + public const string OxidizedCopperGolemStatue = "minecraft:oxidized_copper_golem_statue"; + public const string OxidizedCopperGrate = "minecraft:oxidized_copper_grate"; + public const string OxidizedCopperLantern = "minecraft:oxidized_copper_lantern"; + public const string OxidizedCopperTrapdoor = "minecraft:oxidized_copper_trapdoor"; + public const string OxidizedCutCopper = "minecraft:oxidized_cut_copper"; + public const string OxidizedCutCopperSlab = "minecraft:oxidized_cut_copper_slab"; + public const string OxidizedCutCopperStairs = "minecraft:oxidized_cut_copper_stairs"; + public const string OxidizedLightningRod = "minecraft:oxidized_lightning_rod"; + public const string PackedIce = "minecraft:packed_ice"; + public const string PackedMud = "minecraft:packed_mud"; + public const string PaleHangingMoss = "minecraft:pale_hanging_moss"; + public const string PaleMossBlock = "minecraft:pale_moss_block"; + public const string PaleMossCarpet = "minecraft:pale_moss_carpet"; + public const string PaleOakButton = "minecraft:pale_oak_button"; + public const string PaleOakDoor = "minecraft:pale_oak_door"; + public const string PaleOakFence = "minecraft:pale_oak_fence"; + public const string PaleOakFenceGate = "minecraft:pale_oak_fence_gate"; + public const string PaleOakHangingSign = "minecraft:pale_oak_hanging_sign"; + public const string PaleOakLeaves = "minecraft:pale_oak_leaves"; + public const string PaleOakLog = "minecraft:pale_oak_log"; + public const string PaleOakPlanks = "minecraft:pale_oak_planks"; + public const string PaleOakPressurePlate = "minecraft:pale_oak_pressure_plate"; + public const string PaleOakSapling = "minecraft:pale_oak_sapling"; + public const string PaleOakShelf = "minecraft:pale_oak_shelf"; + public const string PaleOakSign = "minecraft:pale_oak_sign"; + public const string PaleOakSlab = "minecraft:pale_oak_slab"; + public const string PaleOakStairs = "minecraft:pale_oak_stairs"; + public const string PaleOakTrapdoor = "minecraft:pale_oak_trapdoor"; + public const string PaleOakWallHangingSign = "minecraft:pale_oak_wall_hanging_sign"; + public const string PaleOakWallSign = "minecraft:pale_oak_wall_sign"; + public const string PaleOakWood = "minecraft:pale_oak_wood"; + public const string PearlescentFroglight = "minecraft:pearlescent_froglight"; + public const string Peony = "minecraft:peony"; + public const string PetrifiedOakSlab = "minecraft:petrified_oak_slab"; + public const string PiglinHead = "minecraft:piglin_head"; + public const string PiglinWallHead = "minecraft:piglin_wall_head"; + public const string PinkBanner = "minecraft:pink_banner"; + public const string PinkBed = "minecraft:pink_bed"; + public const string PinkCandle = "minecraft:pink_candle"; + public const string PinkCandleCake = "minecraft:pink_candle_cake"; + public const string PinkCarpet = "minecraft:pink_carpet"; + public const string PinkConcrete = "minecraft:pink_concrete"; + public const string PinkConcretePowder = "minecraft:pink_concrete_powder"; + public const string PinkGlazedTerracotta = "minecraft:pink_glazed_terracotta"; + public const string PinkPetals = "minecraft:pink_petals"; + public const string PinkShulkerBox = "minecraft:pink_shulker_box"; + public const string PinkStainedGlass = "minecraft:pink_stained_glass"; + public const string PinkStainedGlassPane = "minecraft:pink_stained_glass_pane"; + public const string PinkTerracotta = "minecraft:pink_terracotta"; + public const string PinkTulip = "minecraft:pink_tulip"; + public const string PinkWallBanner = "minecraft:pink_wall_banner"; + public const string PinkWool = "minecraft:pink_wool"; + public const string Piston = "minecraft:piston"; + public const string PistonHead = "minecraft:piston_head"; + public const string PitcherCrop = "minecraft:pitcher_crop"; + public const string PitcherPlant = "minecraft:pitcher_plant"; + public const string PlayerHead = "minecraft:player_head"; + public const string PlayerWallHead = "minecraft:player_wall_head"; + public const string Podzol = "minecraft:podzol"; + public const string PointedDripstone = "minecraft:pointed_dripstone"; + public const string PolishedAndesite = "minecraft:polished_andesite"; + public const string PolishedAndesiteSlab = "minecraft:polished_andesite_slab"; + public const string PolishedAndesiteStairs = "minecraft:polished_andesite_stairs"; + public const string PolishedBasalt = "minecraft:polished_basalt"; + public const string PolishedBlackstone = "minecraft:polished_blackstone"; + public const string PolishedBlackstoneBrickSlab = "minecraft:polished_blackstone_brick_slab"; + public const string PolishedBlackstoneBrickStairs = "minecraft:polished_blackstone_brick_stairs"; + public const string PolishedBlackstoneBrickWall = "minecraft:polished_blackstone_brick_wall"; + public const string PolishedBlackstoneBricks = "minecraft:polished_blackstone_bricks"; + public const string PolishedBlackstoneButton = "minecraft:polished_blackstone_button"; + public const string PolishedBlackstonePressurePlate = "minecraft:polished_blackstone_pressure_plate"; + public const string PolishedBlackstoneSlab = "minecraft:polished_blackstone_slab"; + public const string PolishedBlackstoneStairs = "minecraft:polished_blackstone_stairs"; + public const string PolishedBlackstoneWall = "minecraft:polished_blackstone_wall"; + public const string PolishedCinnabar = "minecraft:polished_cinnabar"; + public const string PolishedCinnabarSlab = "minecraft:polished_cinnabar_slab"; + public const string PolishedCinnabarStairs = "minecraft:polished_cinnabar_stairs"; + public const string PolishedCinnabarWall = "minecraft:polished_cinnabar_wall"; + public const string PolishedDeepslate = "minecraft:polished_deepslate"; + public const string PolishedDeepslateSlab = "minecraft:polished_deepslate_slab"; + public const string PolishedDeepslateStairs = "minecraft:polished_deepslate_stairs"; + public const string PolishedDeepslateWall = "minecraft:polished_deepslate_wall"; + public const string PolishedDiorite = "minecraft:polished_diorite"; + public const string PolishedDioriteSlab = "minecraft:polished_diorite_slab"; + public const string PolishedDioriteStairs = "minecraft:polished_diorite_stairs"; + public const string PolishedGranite = "minecraft:polished_granite"; + public const string PolishedGraniteSlab = "minecraft:polished_granite_slab"; + public const string PolishedGraniteStairs = "minecraft:polished_granite_stairs"; + public const string PolishedSulfur = "minecraft:polished_sulfur"; + public const string PolishedSulfurSlab = "minecraft:polished_sulfur_slab"; + public const string PolishedSulfurStairs = "minecraft:polished_sulfur_stairs"; + public const string PolishedSulfurWall = "minecraft:polished_sulfur_wall"; + public const string PolishedTuff = "minecraft:polished_tuff"; + public const string PolishedTuffSlab = "minecraft:polished_tuff_slab"; + public const string PolishedTuffStairs = "minecraft:polished_tuff_stairs"; + public const string PolishedTuffWall = "minecraft:polished_tuff_wall"; + public const string Poppy = "minecraft:poppy"; + public const string Potatoes = "minecraft:potatoes"; + public const string PotentSulfur = "minecraft:potent_sulfur"; + public const string PottedAcaciaSapling = "minecraft:potted_acacia_sapling"; + public const string PottedAllium = "minecraft:potted_allium"; + public const string PottedAzaleaBush = "minecraft:potted_azalea_bush"; + public const string PottedAzureBluet = "minecraft:potted_azure_bluet"; + public const string PottedBamboo = "minecraft:potted_bamboo"; + public const string PottedBirchSapling = "minecraft:potted_birch_sapling"; + public const string PottedBlueOrchid = "minecraft:potted_blue_orchid"; + public const string PottedBrownMushroom = "minecraft:potted_brown_mushroom"; + public const string PottedCactus = "minecraft:potted_cactus"; + public const string PottedCherrySapling = "minecraft:potted_cherry_sapling"; + public const string PottedClosedEyeblossom = "minecraft:potted_closed_eyeblossom"; + public const string PottedCornflower = "minecraft:potted_cornflower"; + public const string PottedCrimsonFungus = "minecraft:potted_crimson_fungus"; + public const string PottedCrimsonRoots = "minecraft:potted_crimson_roots"; + public const string PottedDandelion = "minecraft:potted_dandelion"; + public const string PottedDarkOakSapling = "minecraft:potted_dark_oak_sapling"; + public const string PottedDeadBush = "minecraft:potted_dead_bush"; + public const string PottedFern = "minecraft:potted_fern"; + public const string PottedFloweringAzaleaBush = "minecraft:potted_flowering_azalea_bush"; + public const string PottedGoldenDandelion = "minecraft:potted_golden_dandelion"; + public const string PottedJungleSapling = "minecraft:potted_jungle_sapling"; + public const string PottedLilyOfTheValley = "minecraft:potted_lily_of_the_valley"; + public const string PottedMangrovePropagule = "minecraft:potted_mangrove_propagule"; + public const string PottedOakSapling = "minecraft:potted_oak_sapling"; + public const string PottedOpenEyeblossom = "minecraft:potted_open_eyeblossom"; + public const string PottedOrangeTulip = "minecraft:potted_orange_tulip"; + public const string PottedOxeyeDaisy = "minecraft:potted_oxeye_daisy"; + public const string PottedPaleOakSapling = "minecraft:potted_pale_oak_sapling"; + public const string PottedPinkTulip = "minecraft:potted_pink_tulip"; + public const string PottedPoppy = "minecraft:potted_poppy"; + public const string PottedRedMushroom = "minecraft:potted_red_mushroom"; + public const string PottedRedTulip = "minecraft:potted_red_tulip"; + public const string PottedSpruceSapling = "minecraft:potted_spruce_sapling"; + public const string PottedTorchflower = "minecraft:potted_torchflower"; + public const string PottedWarpedFungus = "minecraft:potted_warped_fungus"; + public const string PottedWarpedRoots = "minecraft:potted_warped_roots"; + public const string PottedWhiteTulip = "minecraft:potted_white_tulip"; + public const string PottedWitherRose = "minecraft:potted_wither_rose"; + public const string PowderSnow = "minecraft:powder_snow"; + public const string PowderSnowCauldron = "minecraft:powder_snow_cauldron"; + public const string PoweredRail = "minecraft:powered_rail"; + public const string Prismarine = "minecraft:prismarine"; + public const string PrismarineBrickSlab = "minecraft:prismarine_brick_slab"; + public const string PrismarineBrickStairs = "minecraft:prismarine_brick_stairs"; + public const string PrismarineBricks = "minecraft:prismarine_bricks"; + public const string PrismarineSlab = "minecraft:prismarine_slab"; + public const string PrismarineStairs = "minecraft:prismarine_stairs"; + public const string PrismarineWall = "minecraft:prismarine_wall"; + public const string Pumpkin = "minecraft:pumpkin"; + public const string PumpkinStem = "minecraft:pumpkin_stem"; + public const string PurpleBanner = "minecraft:purple_banner"; + public const string PurpleBed = "minecraft:purple_bed"; + public const string PurpleCandle = "minecraft:purple_candle"; + public const string PurpleCandleCake = "minecraft:purple_candle_cake"; + public const string PurpleCarpet = "minecraft:purple_carpet"; + public const string PurpleConcrete = "minecraft:purple_concrete"; + public const string PurpleConcretePowder = "minecraft:purple_concrete_powder"; + public const string PurpleGlazedTerracotta = "minecraft:purple_glazed_terracotta"; + public const string PurpleShulkerBox = "minecraft:purple_shulker_box"; + public const string PurpleStainedGlass = "minecraft:purple_stained_glass"; + public const string PurpleStainedGlassPane = "minecraft:purple_stained_glass_pane"; + public const string PurpleTerracotta = "minecraft:purple_terracotta"; + public const string PurpleWallBanner = "minecraft:purple_wall_banner"; + public const string PurpleWool = "minecraft:purple_wool"; + public const string PurpurBlock = "minecraft:purpur_block"; + public const string PurpurPillar = "minecraft:purpur_pillar"; + public const string PurpurSlab = "minecraft:purpur_slab"; + public const string PurpurStairs = "minecraft:purpur_stairs"; + public const string QuartzBlock = "minecraft:quartz_block"; + public const string QuartzBricks = "minecraft:quartz_bricks"; + public const string QuartzPillar = "minecraft:quartz_pillar"; + public const string QuartzSlab = "minecraft:quartz_slab"; + public const string QuartzStairs = "minecraft:quartz_stairs"; + public const string Rail = "minecraft:rail"; + public const string RawCopperBlock = "minecraft:raw_copper_block"; + public const string RawGoldBlock = "minecraft:raw_gold_block"; + public const string RawIronBlock = "minecraft:raw_iron_block"; + public const string RedBanner = "minecraft:red_banner"; + public const string RedBed = "minecraft:red_bed"; + public const string RedCandle = "minecraft:red_candle"; + public const string RedCandleCake = "minecraft:red_candle_cake"; + public const string RedCarpet = "minecraft:red_carpet"; + public const string RedConcrete = "minecraft:red_concrete"; + public const string RedConcretePowder = "minecraft:red_concrete_powder"; + public const string RedGlazedTerracotta = "minecraft:red_glazed_terracotta"; + public const string RedMushroom = "minecraft:red_mushroom"; + public const string RedMushroomBlock = "minecraft:red_mushroom_block"; + public const string RedNetherBrickSlab = "minecraft:red_nether_brick_slab"; + public const string RedNetherBrickStairs = "minecraft:red_nether_brick_stairs"; + public const string RedNetherBrickWall = "minecraft:red_nether_brick_wall"; + public const string RedNetherBricks = "minecraft:red_nether_bricks"; + public const string RedSand = "minecraft:red_sand"; + public const string RedSandstone = "minecraft:red_sandstone"; + public const string RedSandstoneSlab = "minecraft:red_sandstone_slab"; + public const string RedSandstoneStairs = "minecraft:red_sandstone_stairs"; + public const string RedSandstoneWall = "minecraft:red_sandstone_wall"; + public const string RedShulkerBox = "minecraft:red_shulker_box"; + public const string RedStainedGlass = "minecraft:red_stained_glass"; + public const string RedStainedGlassPane = "minecraft:red_stained_glass_pane"; + public const string RedTerracotta = "minecraft:red_terracotta"; + public const string RedTulip = "minecraft:red_tulip"; + public const string RedWallBanner = "minecraft:red_wall_banner"; + public const string RedWool = "minecraft:red_wool"; + public const string RedstoneBlock = "minecraft:redstone_block"; + public const string RedstoneLamp = "minecraft:redstone_lamp"; + public const string RedstoneOre = "minecraft:redstone_ore"; + public const string RedstoneTorch = "minecraft:redstone_torch"; + public const string RedstoneWallTorch = "minecraft:redstone_wall_torch"; + public const string RedstoneWire = "minecraft:redstone_wire"; + public const string ReinforcedDeepslate = "minecraft:reinforced_deepslate"; + public const string Repeater = "minecraft:repeater"; + public const string RepeatingCommandBlock = "minecraft:repeating_command_block"; + public const string ResinBlock = "minecraft:resin_block"; + public const string ResinBrickSlab = "minecraft:resin_brick_slab"; + public const string ResinBrickStairs = "minecraft:resin_brick_stairs"; + public const string ResinBrickWall = "minecraft:resin_brick_wall"; + public const string ResinBricks = "minecraft:resin_bricks"; + public const string ResinClump = "minecraft:resin_clump"; + public const string RespawnAnchor = "minecraft:respawn_anchor"; + public const string RootedDirt = "minecraft:rooted_dirt"; + public const string RoseBush = "minecraft:rose_bush"; + public const string Sand = "minecraft:sand"; + public const string Sandstone = "minecraft:sandstone"; + public const string SandstoneSlab = "minecraft:sandstone_slab"; + public const string SandstoneStairs = "minecraft:sandstone_stairs"; + public const string SandstoneWall = "minecraft:sandstone_wall"; + public const string Scaffolding = "minecraft:scaffolding"; + public const string Sculk = "minecraft:sculk"; + public const string SculkCatalyst = "minecraft:sculk_catalyst"; + public const string SculkSensor = "minecraft:sculk_sensor"; + public const string SculkShrieker = "minecraft:sculk_shrieker"; + public const string SculkVein = "minecraft:sculk_vein"; + public const string SeaLantern = "minecraft:sea_lantern"; + public const string SeaPickle = "minecraft:sea_pickle"; + public const string Seagrass = "minecraft:seagrass"; + public const string ShortDryGrass = "minecraft:short_dry_grass"; + public const string ShortGrass = "minecraft:short_grass"; + public const string Shroomlight = "minecraft:shroomlight"; + public const string ShulkerBox = "minecraft:shulker_box"; + public const string SkeletonSkull = "minecraft:skeleton_skull"; + public const string SkeletonWallSkull = "minecraft:skeleton_wall_skull"; + public const string SlimeBlock = "minecraft:slime_block"; + public const string SmallAmethystBud = "minecraft:small_amethyst_bud"; + public const string SmallDripleaf = "minecraft:small_dripleaf"; + public const string SmithingTable = "minecraft:smithing_table"; + public const string Smoker = "minecraft:smoker"; + public const string SmoothBasalt = "minecraft:smooth_basalt"; + public const string SmoothQuartz = "minecraft:smooth_quartz"; + public const string SmoothQuartzSlab = "minecraft:smooth_quartz_slab"; + public const string SmoothQuartzStairs = "minecraft:smooth_quartz_stairs"; + public const string SmoothRedSandstone = "minecraft:smooth_red_sandstone"; + public const string SmoothRedSandstoneSlab = "minecraft:smooth_red_sandstone_slab"; + public const string SmoothRedSandstoneStairs = "minecraft:smooth_red_sandstone_stairs"; + public const string SmoothSandstone = "minecraft:smooth_sandstone"; + public const string SmoothSandstoneSlab = "minecraft:smooth_sandstone_slab"; + public const string SmoothSandstoneStairs = "minecraft:smooth_sandstone_stairs"; + public const string SmoothStone = "minecraft:smooth_stone"; + public const string SmoothStoneSlab = "minecraft:smooth_stone_slab"; + public const string SnifferEgg = "minecraft:sniffer_egg"; + public const string Snow = "minecraft:snow"; + public const string SnowBlock = "minecraft:snow_block"; + public const string SoulCampfire = "minecraft:soul_campfire"; + public const string SoulFire = "minecraft:soul_fire"; + public const string SoulLantern = "minecraft:soul_lantern"; + public const string SoulSand = "minecraft:soul_sand"; + public const string SoulSoil = "minecraft:soul_soil"; + public const string SoulTorch = "minecraft:soul_torch"; + public const string SoulWallTorch = "minecraft:soul_wall_torch"; + public const string Spawner = "minecraft:spawner"; + public const string Sponge = "minecraft:sponge"; + public const string SporeBlossom = "minecraft:spore_blossom"; + public const string SpruceButton = "minecraft:spruce_button"; + public const string SpruceDoor = "minecraft:spruce_door"; + public const string SpruceFence = "minecraft:spruce_fence"; + public const string SpruceFenceGate = "minecraft:spruce_fence_gate"; + public const string SpruceHangingSign = "minecraft:spruce_hanging_sign"; + public const string SpruceLeaves = "minecraft:spruce_leaves"; + public const string SpruceLog = "minecraft:spruce_log"; + public const string SprucePlanks = "minecraft:spruce_planks"; + public const string SprucePressurePlate = "minecraft:spruce_pressure_plate"; + public const string SpruceSapling = "minecraft:spruce_sapling"; + public const string SpruceShelf = "minecraft:spruce_shelf"; + public const string SpruceSign = "minecraft:spruce_sign"; + public const string SpruceSlab = "minecraft:spruce_slab"; + public const string SpruceStairs = "minecraft:spruce_stairs"; + public const string SpruceTrapdoor = "minecraft:spruce_trapdoor"; + public const string SpruceWallHangingSign = "minecraft:spruce_wall_hanging_sign"; + public const string SpruceWallSign = "minecraft:spruce_wall_sign"; + public const string SpruceWood = "minecraft:spruce_wood"; + public const string StickyPiston = "minecraft:sticky_piston"; + public const string Stone = "minecraft:stone"; + public const string StoneBrickSlab = "minecraft:stone_brick_slab"; + public const string StoneBrickStairs = "minecraft:stone_brick_stairs"; + public const string StoneBrickWall = "minecraft:stone_brick_wall"; + public const string StoneBricks = "minecraft:stone_bricks"; + public const string StoneButton = "minecraft:stone_button"; + public const string StonePressurePlate = "minecraft:stone_pressure_plate"; + public const string StoneSlab = "minecraft:stone_slab"; + public const string StoneStairs = "minecraft:stone_stairs"; + public const string Stonecutter = "minecraft:stonecutter"; + public const string StrippedAcaciaLog = "minecraft:stripped_acacia_log"; + public const string StrippedAcaciaWood = "minecraft:stripped_acacia_wood"; + public const string StrippedBambooBlock = "minecraft:stripped_bamboo_block"; + public const string StrippedBirchLog = "minecraft:stripped_birch_log"; + public const string StrippedBirchWood = "minecraft:stripped_birch_wood"; + public const string StrippedCherryLog = "minecraft:stripped_cherry_log"; + public const string StrippedCherryWood = "minecraft:stripped_cherry_wood"; + public const string StrippedCrimsonHyphae = "minecraft:stripped_crimson_hyphae"; + public const string StrippedCrimsonStem = "minecraft:stripped_crimson_stem"; + public const string StrippedDarkOakLog = "minecraft:stripped_dark_oak_log"; + public const string StrippedDarkOakWood = "minecraft:stripped_dark_oak_wood"; + public const string StrippedJungleLog = "minecraft:stripped_jungle_log"; + public const string StrippedJungleWood = "minecraft:stripped_jungle_wood"; + public const string StrippedMangroveLog = "minecraft:stripped_mangrove_log"; + public const string StrippedMangroveWood = "minecraft:stripped_mangrove_wood"; + public const string StrippedOakLog = "minecraft:stripped_oak_log"; + public const string StrippedOakWood = "minecraft:stripped_oak_wood"; + public const string StrippedPaleOakLog = "minecraft:stripped_pale_oak_log"; + public const string StrippedPaleOakWood = "minecraft:stripped_pale_oak_wood"; + public const string StrippedSpruceLog = "minecraft:stripped_spruce_log"; + public const string StrippedSpruceWood = "minecraft:stripped_spruce_wood"; + public const string StrippedWarpedHyphae = "minecraft:stripped_warped_hyphae"; + public const string StrippedWarpedStem = "minecraft:stripped_warped_stem"; + public const string StructureBlock = "minecraft:structure_block"; + public const string StructureVoid = "minecraft:structure_void"; + public const string SugarCane = "minecraft:sugar_cane"; + public const string Sulfur = "minecraft:sulfur"; + public const string SulfurBrickSlab = "minecraft:sulfur_brick_slab"; + public const string SulfurBrickStairs = "minecraft:sulfur_brick_stairs"; + public const string SulfurBrickWall = "minecraft:sulfur_brick_wall"; + public const string SulfurBricks = "minecraft:sulfur_bricks"; + public const string SulfurSlab = "minecraft:sulfur_slab"; + public const string SulfurSpike = "minecraft:sulfur_spike"; + public const string SulfurStairs = "minecraft:sulfur_stairs"; + public const string SulfurWall = "minecraft:sulfur_wall"; + public const string Sunflower = "minecraft:sunflower"; + public const string SuspiciousGravel = "minecraft:suspicious_gravel"; + public const string SuspiciousSand = "minecraft:suspicious_sand"; + public const string SweetBerryBush = "minecraft:sweet_berry_bush"; + public const string TallDryGrass = "minecraft:tall_dry_grass"; + public const string TallGrass = "minecraft:tall_grass"; + public const string TallSeagrass = "minecraft:tall_seagrass"; + public const string Target = "minecraft:target"; + public const string Terracotta = "minecraft:terracotta"; + public const string TestBlock = "minecraft:test_block"; + public const string TestInstanceBlock = "minecraft:test_instance_block"; + public const string TintedGlass = "minecraft:tinted_glass"; + public const string Tnt = "minecraft:tnt"; + public const string Torch = "minecraft:torch"; + public const string Torchflower = "minecraft:torchflower"; + public const string TorchflowerCrop = "minecraft:torchflower_crop"; + public const string TrappedChest = "minecraft:trapped_chest"; + public const string TrialSpawner = "minecraft:trial_spawner"; + public const string Tripwire = "minecraft:tripwire"; + public const string TripwireHook = "minecraft:tripwire_hook"; + public const string TubeCoral = "minecraft:tube_coral"; + public const string TubeCoralBlock = "minecraft:tube_coral_block"; + public const string TubeCoralFan = "minecraft:tube_coral_fan"; + public const string TubeCoralWallFan = "minecraft:tube_coral_wall_fan"; + public const string Tuff = "minecraft:tuff"; + public const string TuffBrickSlab = "minecraft:tuff_brick_slab"; + public const string TuffBrickStairs = "minecraft:tuff_brick_stairs"; + public const string TuffBrickWall = "minecraft:tuff_brick_wall"; + public const string TuffBricks = "minecraft:tuff_bricks"; + public const string TuffSlab = "minecraft:tuff_slab"; + public const string TuffStairs = "minecraft:tuff_stairs"; + public const string TuffWall = "minecraft:tuff_wall"; + public const string TurtleEgg = "minecraft:turtle_egg"; + public const string TwistingVines = "minecraft:twisting_vines"; + public const string TwistingVinesPlant = "minecraft:twisting_vines_plant"; + public const string Vault = "minecraft:vault"; + public const string VerdantFroglight = "minecraft:verdant_froglight"; + public const string Vine = "minecraft:vine"; + public const string VoidAir = "minecraft:void_air"; + public const string WallTorch = "minecraft:wall_torch"; + public const string WarpedButton = "minecraft:warped_button"; + public const string WarpedDoor = "minecraft:warped_door"; + public const string WarpedFence = "minecraft:warped_fence"; + public const string WarpedFenceGate = "minecraft:warped_fence_gate"; + public const string WarpedFungus = "minecraft:warped_fungus"; + public const string WarpedHangingSign = "minecraft:warped_hanging_sign"; + public const string WarpedHyphae = "minecraft:warped_hyphae"; + public const string WarpedNylium = "minecraft:warped_nylium"; + public const string WarpedPlanks = "minecraft:warped_planks"; + public const string WarpedPressurePlate = "minecraft:warped_pressure_plate"; + public const string WarpedRoots = "minecraft:warped_roots"; + public const string WarpedShelf = "minecraft:warped_shelf"; + public const string WarpedSign = "minecraft:warped_sign"; + public const string WarpedSlab = "minecraft:warped_slab"; + public const string WarpedStairs = "minecraft:warped_stairs"; + public const string WarpedStem = "minecraft:warped_stem"; + public const string WarpedTrapdoor = "minecraft:warped_trapdoor"; + public const string WarpedWallHangingSign = "minecraft:warped_wall_hanging_sign"; + public const string WarpedWallSign = "minecraft:warped_wall_sign"; + public const string WarpedWartBlock = "minecraft:warped_wart_block"; + public const string Water = "minecraft:water"; + public const string WaterCauldron = "minecraft:water_cauldron"; + public const string WaxedChiseledCopper = "minecraft:waxed_chiseled_copper"; + public const string WaxedCopperBars = "minecraft:waxed_copper_bars"; + public const string WaxedCopperBlock = "minecraft:waxed_copper_block"; + public const string WaxedCopperBulb = "minecraft:waxed_copper_bulb"; + public const string WaxedCopperChain = "minecraft:waxed_copper_chain"; + public const string WaxedCopperChest = "minecraft:waxed_copper_chest"; + public const string WaxedCopperDoor = "minecraft:waxed_copper_door"; + public const string WaxedCopperGolemStatue = "minecraft:waxed_copper_golem_statue"; + public const string WaxedCopperGrate = "minecraft:waxed_copper_grate"; + public const string WaxedCopperLantern = "minecraft:waxed_copper_lantern"; + public const string WaxedCopperTrapdoor = "minecraft:waxed_copper_trapdoor"; + public const string WaxedCutCopper = "minecraft:waxed_cut_copper"; + public const string WaxedCutCopperSlab = "minecraft:waxed_cut_copper_slab"; + public const string WaxedCutCopperStairs = "minecraft:waxed_cut_copper_stairs"; + public const string WaxedExposedChiseledCopper = "minecraft:waxed_exposed_chiseled_copper"; + public const string WaxedExposedCopper = "minecraft:waxed_exposed_copper"; + public const string WaxedExposedCopperBars = "minecraft:waxed_exposed_copper_bars"; + public const string WaxedExposedCopperBulb = "minecraft:waxed_exposed_copper_bulb"; + public const string WaxedExposedCopperChain = "minecraft:waxed_exposed_copper_chain"; + public const string WaxedExposedCopperChest = "minecraft:waxed_exposed_copper_chest"; + public const string WaxedExposedCopperDoor = "minecraft:waxed_exposed_copper_door"; + public const string WaxedExposedCopperGolemStatue = "minecraft:waxed_exposed_copper_golem_statue"; + public const string WaxedExposedCopperGrate = "minecraft:waxed_exposed_copper_grate"; + public const string WaxedExposedCopperLantern = "minecraft:waxed_exposed_copper_lantern"; + public const string WaxedExposedCopperTrapdoor = "minecraft:waxed_exposed_copper_trapdoor"; + public const string WaxedExposedCutCopper = "minecraft:waxed_exposed_cut_copper"; + public const string WaxedExposedCutCopperSlab = "minecraft:waxed_exposed_cut_copper_slab"; + public const string WaxedExposedCutCopperStairs = "minecraft:waxed_exposed_cut_copper_stairs"; + public const string WaxedExposedLightningRod = "minecraft:waxed_exposed_lightning_rod"; + public const string WaxedLightningRod = "minecraft:waxed_lightning_rod"; + public const string WaxedOxidizedChiseledCopper = "minecraft:waxed_oxidized_chiseled_copper"; + public const string WaxedOxidizedCopper = "minecraft:waxed_oxidized_copper"; + public const string WaxedOxidizedCopperBars = "minecraft:waxed_oxidized_copper_bars"; + public const string WaxedOxidizedCopperBulb = "minecraft:waxed_oxidized_copper_bulb"; + public const string WaxedOxidizedCopperChain = "minecraft:waxed_oxidized_copper_chain"; + public const string WaxedOxidizedCopperChest = "minecraft:waxed_oxidized_copper_chest"; + public const string WaxedOxidizedCopperDoor = "minecraft:waxed_oxidized_copper_door"; + public const string WaxedOxidizedCopperGolemStatue = "minecraft:waxed_oxidized_copper_golem_statue"; + public const string WaxedOxidizedCopperGrate = "minecraft:waxed_oxidized_copper_grate"; + public const string WaxedOxidizedCopperLantern = "minecraft:waxed_oxidized_copper_lantern"; + public const string WaxedOxidizedCopperTrapdoor = "minecraft:waxed_oxidized_copper_trapdoor"; + public const string WaxedOxidizedCutCopper = "minecraft:waxed_oxidized_cut_copper"; + public const string WaxedOxidizedCutCopperSlab = "minecraft:waxed_oxidized_cut_copper_slab"; + public const string WaxedOxidizedCutCopperStairs = "minecraft:waxed_oxidized_cut_copper_stairs"; + public const string WaxedOxidizedLightningRod = "minecraft:waxed_oxidized_lightning_rod"; + public const string WaxedWeatheredChiseledCopper = "minecraft:waxed_weathered_chiseled_copper"; + public const string WaxedWeatheredCopper = "minecraft:waxed_weathered_copper"; + public const string WaxedWeatheredCopperBars = "minecraft:waxed_weathered_copper_bars"; + public const string WaxedWeatheredCopperBulb = "minecraft:waxed_weathered_copper_bulb"; + public const string WaxedWeatheredCopperChain = "minecraft:waxed_weathered_copper_chain"; + public const string WaxedWeatheredCopperChest = "minecraft:waxed_weathered_copper_chest"; + public const string WaxedWeatheredCopperDoor = "minecraft:waxed_weathered_copper_door"; + public const string WaxedWeatheredCopperGolemStatue = "minecraft:waxed_weathered_copper_golem_statue"; + public const string WaxedWeatheredCopperGrate = "minecraft:waxed_weathered_copper_grate"; + public const string WaxedWeatheredCopperLantern = "minecraft:waxed_weathered_copper_lantern"; + public const string WaxedWeatheredCopperTrapdoor = "minecraft:waxed_weathered_copper_trapdoor"; + public const string WaxedWeatheredCutCopper = "minecraft:waxed_weathered_cut_copper"; + public const string WaxedWeatheredCutCopperSlab = "minecraft:waxed_weathered_cut_copper_slab"; + public const string WaxedWeatheredCutCopperStairs = "minecraft:waxed_weathered_cut_copper_stairs"; + public const string WaxedWeatheredLightningRod = "minecraft:waxed_weathered_lightning_rod"; + public const string WeatheredChiseledCopper = "minecraft:weathered_chiseled_copper"; + public const string WeatheredCopper = "minecraft:weathered_copper"; + public const string WeatheredCopperBars = "minecraft:weathered_copper_bars"; + public const string WeatheredCopperBulb = "minecraft:weathered_copper_bulb"; + public const string WeatheredCopperChain = "minecraft:weathered_copper_chain"; + public const string WeatheredCopperChest = "minecraft:weathered_copper_chest"; + public const string WeatheredCopperDoor = "minecraft:weathered_copper_door"; + public const string WeatheredCopperGolemStatue = "minecraft:weathered_copper_golem_statue"; + public const string WeatheredCopperGrate = "minecraft:weathered_copper_grate"; + public const string WeatheredCopperLantern = "minecraft:weathered_copper_lantern"; + public const string WeatheredCopperTrapdoor = "minecraft:weathered_copper_trapdoor"; + public const string WeatheredCutCopper = "minecraft:weathered_cut_copper"; + public const string WeatheredCutCopperSlab = "minecraft:weathered_cut_copper_slab"; + public const string WeatheredCutCopperStairs = "minecraft:weathered_cut_copper_stairs"; + public const string WeatheredLightningRod = "minecraft:weathered_lightning_rod"; + public const string WeepingVines = "minecraft:weeping_vines"; + public const string WeepingVinesPlant = "minecraft:weeping_vines_plant"; + public const string WetSponge = "minecraft:wet_sponge"; + public const string Wheat = "minecraft:wheat"; + public const string WhiteBanner = "minecraft:white_banner"; + public const string WhiteBed = "minecraft:white_bed"; + public const string WhiteCandle = "minecraft:white_candle"; + public const string WhiteCandleCake = "minecraft:white_candle_cake"; + public const string WhiteCarpet = "minecraft:white_carpet"; + public const string WhiteConcrete = "minecraft:white_concrete"; + public const string WhiteConcretePowder = "minecraft:white_concrete_powder"; + public const string WhiteGlazedTerracotta = "minecraft:white_glazed_terracotta"; + public const string WhiteShulkerBox = "minecraft:white_shulker_box"; + public const string WhiteStainedGlass = "minecraft:white_stained_glass"; + public const string WhiteStainedGlassPane = "minecraft:white_stained_glass_pane"; + public const string WhiteTerracotta = "minecraft:white_terracotta"; + public const string WhiteTulip = "minecraft:white_tulip"; + public const string WhiteWallBanner = "minecraft:white_wall_banner"; + public const string WhiteWool = "minecraft:white_wool"; + public const string Wildflowers = "minecraft:wildflowers"; + public const string WitherRose = "minecraft:wither_rose"; + public const string WitherSkeletonSkull = "minecraft:wither_skeleton_skull"; + public const string WitherSkeletonWallSkull = "minecraft:wither_skeleton_wall_skull"; + public const string YellowBanner = "minecraft:yellow_banner"; + public const string YellowBed = "minecraft:yellow_bed"; + public const string YellowCandle = "minecraft:yellow_candle"; + public const string YellowCandleCake = "minecraft:yellow_candle_cake"; + public const string YellowCarpet = "minecraft:yellow_carpet"; + public const string YellowConcrete = "minecraft:yellow_concrete"; + public const string YellowConcretePowder = "minecraft:yellow_concrete_powder"; + public const string YellowGlazedTerracotta = "minecraft:yellow_glazed_terracotta"; + public const string YellowShulkerBox = "minecraft:yellow_shulker_box"; + public const string YellowStainedGlass = "minecraft:yellow_stained_glass"; + public const string YellowStainedGlassPane = "minecraft:yellow_stained_glass_pane"; + public const string YellowTerracotta = "minecraft:yellow_terracotta"; + public const string YellowWallBanner = "minecraft:yellow_wall_banner"; + public const string YellowWool = "minecraft:yellow_wool"; + public const string ZombieHead = "minecraft:zombie_head"; + public const string ZombieWallHead = "minecraft:zombie_wall_head"; + } +} diff --git a/SubstrateCS/Source/AlphaBlockCollection.cs b/SubstrateCS/Source/AlphaBlockCollection.cs index 80ee4b32..dda8b6a4 100644 --- a/SubstrateCS/Source/AlphaBlockCollection.cs +++ b/SubstrateCS/Source/AlphaBlockCollection.cs @@ -390,10 +390,21 @@ public void SetID (int x, int y, int z, int id) } } - _dirty = true; - } - - internal void SetID (int index, int id) + _dirty = true; + } + + /// + /// Sets a legacy numeric block ID and its metadata as one operation. + /// Palette-backed chunks translate the pair to the corresponding + /// namespaced block state when they are saved. + /// + public void SetID (int x, int y, int z, int id, int data) + { + SetID(x, y, z, id); + SetData(x, y, z, data); + } + + internal void SetID (int index, int id) { int x, y, z; _blocks.GetMultiIndex(index, out x, out y, out z); diff --git a/SubstrateCS/Source/AnvilChunk.cs b/SubstrateCS/Source/AnvilChunk.cs index 7ec2e358..11f6b4cb 100644 --- a/SubstrateCS/Source/AnvilChunk.cs +++ b/SubstrateCS/Source/AnvilChunk.cs @@ -13,14 +13,7 @@ public class AnvilChunk : IChunk, INbtObject, ICopyable { new SchemaNodeCompound("Level") { - new SchemaNodeList("Sections", TagType.TAG_COMPOUND, new SchemaNodeCompound() { - new SchemaNodeArray("Blocks", 4096), - new SchemaNodeArray("Data", 2048), - new SchemaNodeArray("SkyLight", 2048), - new SchemaNodeArray("BlockLight", 2048), - new SchemaNodeScaler("Y", TagType.TAG_BYTE), - new SchemaNodeArray("Add", 2048, SchemaOptions.OPTIONAL), - }), + new SchemaNodeList("Sections", TagType.TAG_COMPOUND, AnvilSection.SectionSchema), new SchemaNodeArray("Biomes", 256, SchemaOptions.OPTIONAL), new SchemaNodeIntArray("HeightMap", 256), new SchemaNodeList("Entities", TagType.TAG_COMPOUND, SchemaOptions.CREATE_ON_MISSING), diff --git a/SubstrateCS/Source/AnvilRegion.cs b/SubstrateCS/Source/AnvilRegion.cs index 343aade7..5f6f851a 100644 --- a/SubstrateCS/Source/AnvilRegion.cs +++ b/SubstrateCS/Source/AnvilRegion.cs @@ -76,6 +76,13 @@ protected override IChunk CreateChunkCore (int cx, int cz) protected override IChunk CreateChunkVerifiedCore (NbtTree tree) { + TagNode dataVersion; + if (tree.Root.ToTagCompound().TryGetValue("DataVersion", out dataVersion) && + dataVersion.ToTagInt() != null && + dataVersion.ToTagInt().Data >= 1628) { + return AquaticChunk.CreateVerified(tree); + } + return AnvilChunk.CreateVerified(tree); } } diff --git a/SubstrateCS/Source/AnvilSection.cs b/SubstrateCS/Source/AnvilSection.cs index c8d14380..091e2cf3 100644 --- a/SubstrateCS/Source/AnvilSection.cs +++ b/SubstrateCS/Source/AnvilSection.cs @@ -114,8 +114,7 @@ private bool CheckAddBlocksEmpty () #region INbtObject Members - public AnvilSection LoadTree (TagNode tree) - { + public AnvilSection LoadTree(TagNode tree) { TagNodeCompound ctree = tree as TagNodeCompound; if (ctree == null) { return null; diff --git a/SubstrateCS/Source/AnvilWorld.cs b/SubstrateCS/Source/AnvilWorld.cs index a99a7177..d51ad843 100644 --- a/SubstrateCS/Source/AnvilWorld.cs +++ b/SubstrateCS/Source/AnvilWorld.cs @@ -17,6 +17,9 @@ namespace Substrate public class AnvilWorld : NbtWorld { private const string _REGION_DIR = "region"; + private const string _DIMENSIONS_DIR = "dimensions"; + private const string _MINECRAFT_NAMESPACE = "minecraft"; + private const string _OVERWORLD_DIMENSION = "overworld"; private const string _PLAYER_DIR = "players"; private string _levelFile = "level.dat"; @@ -169,6 +172,12 @@ public override void Save () } } + public override void SaveBlocks() { + foreach (KeyValuePair cm in _chunkMgrs) { + cm.Value.Save(); + } + } + /// /// Gets the currently managing chunks in the default dimension. /// @@ -318,7 +327,7 @@ private void OpenDimension (string dim) { string path = Path; if (String.IsNullOrEmpty(dim)) { - path = IO.Path.Combine(path, _REGION_DIR); + path = GetOverworldRegionPath(); } else { path = IO.Path.Combine(path, dim); @@ -342,6 +351,36 @@ private void OpenDimension (string dim) _caches[dim] = cc; } + private string GetOverworldRegionPath () + { + string legacyPath = IO.Path.Combine(Path, _REGION_DIR); + string dimensionPath = IO.Path.Combine( + IO.Path.Combine(IO.Path.Combine(Path, _DIMENSIONS_DIR), _MINECRAFT_NAMESPACE), + _OVERWORLD_DIMENSION); + dimensionPath = IO.Path.Combine(dimensionPath, _REGION_DIR); + + bool legacyExists = Directory.Exists(legacyPath); + bool dimensionExists = Directory.Exists(dimensionPath); + if (!dimensionExists) + return legacyPath; + if (!legacyExists) + return dimensionPath; + + bool legacyHasRegions = HasRegionFiles(legacyPath); + bool dimensionHasRegions = HasRegionFiles(dimensionPath); + if (dimensionHasRegions && !legacyHasRegions) + return dimensionPath; + + // Preserve the traditional location when both locations are equally + // plausible. This avoids silently migrating or splitting old worlds. + return legacyPath; + } + + private static bool HasRegionFiles (string path) + { + return Directory.GetFiles(path, "r.*.*.mca").Length != 0; + } + private AnvilWorld OpenWorld (string path) { if (!Directory.Exists(path)) { @@ -414,8 +453,12 @@ internal static void OnResolveOpen (object sender, OpenWorldEventArgs e) return; } - string regPath = IO.Path.Combine(e.Path, _REGION_DIR); - if (!Directory.Exists(regPath)) { + string legacyPath = IO.Path.Combine(world.Path, _REGION_DIR); + string dimensionPath = IO.Path.Combine( + IO.Path.Combine(IO.Path.Combine(world.Path, _DIMENSIONS_DIR), _MINECRAFT_NAMESPACE), + _OVERWORLD_DIMENSION); + dimensionPath = IO.Path.Combine(dimensionPath, _REGION_DIR); + if (!Directory.Exists(legacyPath) && !Directory.Exists(dimensionPath)) { return; } diff --git a/SubstrateCS/Source/AquaticBiomeCollection.cs b/SubstrateCS/Source/AquaticBiomeCollection.cs new file mode 100644 index 00000000..d948f004 --- /dev/null +++ b/SubstrateCS/Source/AquaticBiomeCollection.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate +{ + public class AquaticBiomeCollection + { + public const int OCEAN = 0; + public const int PLAINS = 1; + public const int DESERT = 2; + public const int EXTREME_HILLS = 3; + public const int FOREST = 4; + public const int TAIGA = 5; + public const int SWAMPLAND = 6; + public const int RIVER = 7; + public const int HELL = 8; + public const int SKY = 9; + public const int FROZEN_OCEAN = 10; + public const int FROZEN_RIVER = 11; + public const int ICE_PLAINS = 12; + public const int ICE_MOUNTAINS = 13; + public const int MUSHROOM_ISLAND = 14; + public const int MUSHROOM_ISLAND_SHORE = 15; + public const int BEACH = 16; + public const int DESERT_HILLS = 17; + public const int FOREST_HILLS = 18; + public const int TAIGA_HILLS = 19; + public const int EXTREME_HILLS_EDGE = 20; + public const int JUNGLE = 21; + public const int JUNGLE_HILLS = 22; + + private readonly int _xdim; + private readonly int _zdim; + + private IDataArray2 _biomeMap; + + public AquaticBiomeCollection(IDataArray2 biomeMap) + { + _biomeMap = biomeMap; + + _xdim = _biomeMap.XDim; + _zdim = _biomeMap.ZDim; + } + + public int GetBiome(int x, int z) + { + return _biomeMap[x, z]; + } + + public void SetBiome(int x, int z, int newBiome) + { + _biomeMap[x, z] = newBiome; + } + + } +} diff --git a/SubstrateCS/Source/AquaticChunk.cs b/SubstrateCS/Source/AquaticChunk.cs new file mode 100644 index 00000000..789a8883 --- /dev/null +++ b/SubstrateCS/Source/AquaticChunk.cs @@ -0,0 +1,631 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Substrate.Nbt; +using Substrate.Core; +using System.IO; + +namespace Substrate +{ + public class AquaticChunk : IChunk, INbtObject, ICopyable + { + public static SchemaNodeCompound LevelSchema = new SchemaNodeCompound() + { + new SchemaNodeCompound("Level") + { + new SchemaNodeList("Sections", TagType.TAG_COMPOUND, AquaticSection.SectionSchema), + new SchemaNodeList("Lights", TagType.TAG_LIST, SchemaOptions.OPTIONAL), + new SchemaNodeList("PostProcessing", TagType.TAG_LIST, SchemaOptions.OPTIONAL), + new SchemaNodeIntArray("Biomes", 256, SchemaOptions.OPTIONAL), + new SchemaNodeCompound("Heightmaps", SchemaOptions.OPTIONAL) { + new SchemaNodeLongArray("OCEAN_FLOOR", 36, SchemaOptions.OPTIONAL), + new SchemaNodeLongArray("MOTION_BLOCKING_NO_LEAVES", 36, SchemaOptions.OPTIONAL), + new SchemaNodeLongArray("MOTION_BLOCKING", 36, SchemaOptions.OPTIONAL), + new SchemaNodeLongArray("WORLD_SURFACE", 36, SchemaOptions.OPTIONAL), + new SchemaNodeLongArray("LIGHT_BLOCKING", 36, SchemaOptions.OPTIONAL), + }, + new SchemaNodeList("Entities", TagType.TAG_COMPOUND, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeList("TileEntities", TagType.TAG_COMPOUND, TileEntity.Schema, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeList("TileTicks", TagType.TAG_COMPOUND, TileTick.Schema, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("LastUpdate", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), + new SchemaNodeScaler("xPos", TagType.TAG_INT), + new SchemaNodeScaler("zPos", TagType.TAG_INT), + new SchemaNodeScaler("TerrainPopulated", TagType.TAG_BYTE, SchemaOptions.CREATE_ON_MISSING), + }, + }; + + private const int XDIM = 16; + private const int YDIM = 256; + private const int ZDIM = 16; + + private NbtTree _tree; + + private int _cx; + private int _cz; + + private AquaticSection[] _sections; + + private IDataArray3 _blocks; + private IDataArray3 _data; + private IDataArray3 _blockLight; + private IDataArray3 _skyLight; + + private ZXIntArray _heightMap; + private IDataArray2 _biomes; + private int _dataVersion; + private bool _modern; + private int _minimumSectionY; + + private TagNodeList _entities; + private TagNodeList _tileEntities; + private TagNodeList _tileTicks; + + private AlphaBlockCollection _blockManager; + private EntityCollection _entityManager; + private AquaticBiomeCollection _biomeManager; + + + private AquaticChunk() + { + _sections = new AquaticSection[16]; + } + + public int X + { + get { return _cx; } + } + + public int Z + { + get { return _cz; } + } + + public AquaticSection[] Sections + { + get { return _sections; } + } + + public AlphaBlockCollection Blocks + { + get { return _blockManager; } + } + + public AquaticBiomeCollection Biomes + { + get { return _biomeManager; } + } + + public EntityCollection Entities + { + get { return _entityManager; } + } + + public NbtTree Tree + { + get { return _tree; } + } + + public bool IsTerrainPopulated + { + get { + TagNodeCompound chunk = ChunkTag; + if (_modern) { + TagNode statusNode; + chunk.TryGetValue("Status", out statusNode); + TagNodeString status = statusNode as TagNodeString; + return status != null && status.Data == "full"; + } + TagNode valueNode; + chunk.TryGetValue("TerrainPopulated", out valueNode); + TagNodeByte value = valueNode as TagNodeByte; + return value != null && value.Data != 0; + } + set { + if (_modern) ChunkTag["Status"] = new TagNodeString(value ? "full" : "empty"); + else ChunkTag["TerrainPopulated"] = new TagNodeByte((byte)(value ? 1 : 0)); + } + } + + /// The lowest world block Y represented by . + public int MinimumY { get { return _minimumSectionY * 16; } } + + /// Gets a numeric block ID using a world Y coordinate. + public int GetBlockID(int x, int y, int z) + { + return _blockManager.GetID(x, y - MinimumY, z); + } + + /// Sets a numeric block ID using a world Y coordinate. + public void SetBlockID(int x, int y, int z, int id) + { + _blockManager.SetID(x, y - MinimumY, z, id); + } + + /// Gets a namespaced block name using a world Y coordinate. + public string GetBlockName(int x, int y, int z) + { + AquaticSection section = GetSectionForWorldY(y); + return section.GetBlockName(x, y & 15, z); + } + + /// Gets a copy of the block-state properties at a world Y coordinate. + public TagNodeCompound GetBlockProperties(int x, int y, int z) + { + AquaticSection section = GetSectionForWorldY(y); + TagNodeCompound properties = section.GetBlockProperties(x, y & 15, z); + return properties == null ? null : properties.Copy() as TagNodeCompound; + } + + /// Sets a namespaced block state using a world Y coordinate. + public void SetBlockState(int x, int y, int z, string name, TagNodeCompound properties) + { + AquaticSection section = GetSectionForWorldY(y); + section.SetBlockState(x, y & 15, z, name, properties); + _blockManager.IsDirty = true; + } + + private AquaticSection GetSectionForWorldY(int y) + { + int sectionY = (int)Math.Floor(y / 16.0); + int index = sectionY - _minimumSectionY; + if (index < 0 || index >= _sections.Length) throw new ArgumentOutOfRangeException("y"); + return _sections[index]; + } + + private TagNodeCompound ChunkTag { + get { + TagNode level; + return _tree.Root.TryGetValue("Level", out level) + ? level as TagNodeCompound + : _tree.Root; + } + } + + public static AquaticChunk Create (int x, int z) + { + AquaticChunk c = new AquaticChunk(); + + c._cx = x; + c._cz = z; + + c.BuildNBTTree(); + return c; + } + + public static AquaticChunk Create (NbtTree tree) + { + AquaticChunk c = new AquaticChunk(); + + return c.LoadTree(tree.Root); + } + + public static AquaticChunk CreateVerified (NbtTree tree) + { + AquaticChunk c = new AquaticChunk(); + + return c.LoadTreeSafe(tree.Root); + } + + /// + /// Updates the chunk's global world coordinates. + /// + /// Global X-coordinate. + /// Global Z-coordinate. + public virtual void SetLocation (int x, int z) + { + int diffx = (x - _cx) * XDIM; + int diffz = (z - _cz) * ZDIM; + + // Update chunk position + + _cx = x; + _cz = z; + + ChunkTag["xPos"].ToTagInt().Data = x; + ChunkTag["zPos"].ToTagInt().Data = z; + + // Update tile entity coordinates + + List tileEntites = new List(); + foreach (TagNodeCompound tag in _tileEntities) { + TileEntity te = TileEntityFactory.Create(tag); + if (te == null) { + te = TileEntity.FromTreeSafe(tag); + } + + if (te != null) { + te.MoveBy(diffx, 0, diffz); + tileEntites.Add(te); + } + } + + _tileEntities.Clear(); + foreach (TileEntity te in tileEntites) { + _tileEntities.Add(te.BuildTree()); + } + + // Update tile tick coordinates + + if (_tileTicks != null) { + List tileTicks = new List(); + foreach (TagNodeCompound tag in _tileTicks) { + TileTick tt = TileTick.FromTreeSafe(tag); + + if (tt != null) { + tt.MoveBy(diffx, 0, diffz); + tileTicks.Add(tt); + } + } + + _tileTicks.Clear(); + foreach (TileTick tt in tileTicks) { + _tileTicks.Add(tt.BuildTree()); + } + } + + // Update entity coordinates + + List entities = new List(); + foreach (TypedEntity entity in _entityManager) { + entity.MoveBy(diffx, 0, diffz); + entities.Add(entity); + } + + _entities.Clear(); + foreach (TypedEntity entity in entities) { + _entityManager.Add(entity); + } + } + + public bool Save (Stream outStream) + { + if (outStream == null || !outStream.CanWrite) { + return false; + } + + BuildConditional(); + + NbtTree tree; + if (_modern) { + tree = new NbtTree(BuildTree().ToTagCompound(), _tree.Name); + } else { + tree = _tree.Copy(); + tree.Root["Level"] = BuildTree(); + } + + tree.WriteTo(outStream); + + return true; + } + + #region INbtObject Members + + public AquaticChunk LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null) { + return null; + } + + _tree = new NbtTree(ctree); + TagNodeInt version = _tree.Root["DataVersion"] as TagNodeInt; + _dataVersion = version == null ? 1631 : version.Data; + + TagNodeCompound level; + TagNode levelNode; + _modern = !_tree.Root.TryGetValue("Level", out levelNode); + level = _modern ? _tree.Root : levelNode as TagNodeCompound; + + string sectionsKey = _modern ? "sections" : "Sections"; + TagNodeList sections = level[sectionsKey] as TagNodeList; + _minimumSectionY = _modern ? -4 : 0; + int maximumSectionY = _modern ? 19 : 15; + _sections = new AquaticSection[maximumSectionY - _minimumSectionY + 1]; + foreach (TagNodeCompound section in sections) { + AquaticSection aquaticSection = new AquaticSection(section, _dataVersion); + int sectionIndex = aquaticSection.Y - _minimumSectionY; + if (sectionIndex < 0 || sectionIndex >= _sections.Length) + continue; + _sections[sectionIndex] = aquaticSection; + } + + IDataArray3[] blocksBA = new IDataArray3[_sections.Length]; + YZXNibbleArray[] dataBA = new YZXNibbleArray[_sections.Length]; + YZXNibbleArray[] skyLightBA = new YZXNibbleArray[_sections.Length]; + YZXNibbleArray[] blockLightBA = new YZXNibbleArray[_sections.Length]; + + for (int i = 0; i < _sections.Length; i++) { + if (_sections[i] == null) + _sections[i] = new AquaticSection(i + _minimumSectionY, _dataVersion, _modern); + + blocksBA[i] = _sections[i].Blocks; + dataBA[i] = _sections[i].Data; + skyLightBA[i] = _sections[i].SkyLight; + blockLightBA[i] = _sections[i].BlockLight; + } + + _blocks = new CompositeDataArray3(blocksBA); + _data = new CompositeDataArray3(dataBA); + _skyLight = new CompositeDataArray3(skyLightBA); + _blockLight = new CompositeDataArray3(blockLightBA); + + TagNode optionalNode; + bool rebuildHeightMap = false; + level.TryGetValue("HeightMap", out optionalNode); + TagNodeIntArray legacyHeight = optionalNode as TagNodeIntArray; + if (legacyHeight == null) { + level.TryGetValue("Heightmaps", out optionalNode); + int[] modernHeight = ReadHeightMap( + optionalNode as TagNodeCompound, _minimumSectionY * 16); + rebuildHeightMap = modernHeight == null; + legacyHeight = new TagNodeIntArray(modernHeight ?? new int[XDIM * ZDIM]); + } + _heightMap = new ZXIntArray(XDIM, ZDIM, legacyHeight); + + level.TryGetValue("Biomes", out optionalNode); + if (optionalNode is TagNodeIntArray) + _biomes = new ZXIntArray(XDIM, ZDIM, optionalNode as TagNodeIntArray); + else if (optionalNode is TagNodeByteArray) + _biomes = new ZXByteArray(XDIM, ZDIM, optionalNode as TagNodeByteArray); + else { + TagNodeIntArray defaultBiomes = new TagNodeIntArray(new int[256]); + if (!_modern) level["Biomes"] = defaultBiomes; + _biomes = new ZXIntArray(XDIM, ZDIM, defaultBiomes); + for (int x = 0; x < XDIM; x++) + for (int z = 0; z < ZDIM; z++) + _biomes[x, z] = BiomeType.Default; + } + + string entitiesKey = _modern ? "entities" : "Entities"; + string tileEntitiesKey = _modern ? "block_entities" : "TileEntities"; + level.TryGetValue(entitiesKey, out optionalNode); + _entities = optionalNode as TagNodeList; + if (_entities == null) _entities = new TagNodeList(TagType.TAG_COMPOUND); + level.TryGetValue(tileEntitiesKey, out optionalNode); + _tileEntities = optionalNode as TagNodeList; + if (_tileEntities == null) _tileEntities = new TagNodeList(TagType.TAG_COMPOUND); + + if (!_modern && level.ContainsKey("TileTicks")) + _tileTicks = level["TileTicks"] as TagNodeList; + else + _tileTicks = new TagNodeList(TagType.TAG_COMPOUND); + + // List-type patch up + if (_entities.Count == 0 && _entities.ValueType != TagType.TAG_COMPOUND) { + level[entitiesKey] = new TagNodeList(TagType.TAG_COMPOUND); + _entities = level[entitiesKey] as TagNodeList; + } + + if (_tileEntities.Count == 0 && _tileEntities.ValueType != TagType.TAG_COMPOUND) { + level[tileEntitiesKey] = new TagNodeList(TagType.TAG_COMPOUND); + _tileEntities = level[tileEntitiesKey] as TagNodeList; + } + + if (_tileTicks.Count == 0 && _tileTicks.ValueType != TagType.TAG_COMPOUND) { + if (!_modern) level["TileTicks"] = new TagNodeList(TagType.TAG_COMPOUND); + _tileTicks = !_modern + ? level["TileTicks"] as TagNodeList + : new TagNodeList(TagType.TAG_COMPOUND); + } + + _cx = level["xPos"].ToTagInt(); + _cz = level["zPos"].ToTagInt(); + + _blockManager = new AlphaBlockCollection(_blocks, _data, _blockLight, _skyLight, _heightMap, _tileEntities, _tileTicks); + if (rebuildHeightMap) + RebuildHeightMap(); + _entityManager = new EntityCollection(_entities); + _biomeManager = new AquaticBiomeCollection(_biomes); + + return this; + } + + public AquaticChunk LoadTreeSafe(TagNode tree) { + if (!ValidateTree(tree)) { + return null; + } + + return LoadTree(tree); + } + + private bool ShouldIncludeSection (AquaticSection section) + { + int y = (section.Y + 1) * section.Blocks.YDim; + for (int i = 0; i < _heightMap.Length; i++) + if (_heightMap[i] > y) + return true; + + return !section.CheckEmpty(); + } + + public TagNode BuildTree () + { + TagNodeCompound level = ChunkTag; + TagNodeCompound levelCopy = new TagNodeCompound(); + foreach (KeyValuePair node in level) + levelCopy.Add(node.Key, node.Value); + + // The legacy incremental light engine uses zero-based Y values, + // while modern chunks keep heightmaps in world coordinates + // starting at -64. Its results are therefore not reliable after + // editing a modern chunk. Ask Minecraft's light engine to rebuild + // the affected chunk instead of saving stale arrays as valid. + bool requiresRelight = _modern && _blockManager.IsDirty; + TagNodeList sections = new TagNodeList(TagType.TAG_COMPOUND); + for (int i = 0; i < _sections.Length; i++) { + if (!ShouldIncludeSection(_sections[i])) + continue; + TagNodeCompound section = _sections[i].BuildTree().ToTagCompound(); + if (requiresRelight) { + section.Remove("SkyLight"); + section.Remove("BlockLight"); + } + sections.Add(section); + } + + levelCopy[_modern ? "sections" : "Sections"] = sections; + if (requiresRelight) + levelCopy["isLightOn"] = new TagNodeByte(0); + + if (!_modern && _tileTicks.Count == 0) + levelCopy.Remove("TileTicks"); + + return levelCopy; + } + + public bool ValidateTree (TagNode tree) + { + TagNodeCompound root = tree as TagNodeCompound; + if (root != null && !root.ContainsKey("Level")) { + TagNode sections, x, z; + return root.TryGetValue("sections", out sections) && sections is TagNodeList && + root.TryGetValue("xPos", out x) && x is TagNodeInt && + root.TryGetValue("zPos", out z) && z is TagNodeInt; + } + NbtVerifier v = new NbtVerifier(tree, LevelSchema); + return v.Verify(); + } + + private static int[] ReadHeightMap(TagNodeCompound heightmaps, int minimumY) + { + if (heightmaps == null) return null; + TagNode node; + heightmaps.TryGetValue("MOTION_BLOCKING_NO_LEAVES", out node); + TagNodeLongArray source = node as TagNodeLongArray; + if (source == null) { + heightmaps.TryGetValue("MOTION_BLOCKING", out node); + source = node as TagNodeLongArray; + } + if (source == null) { + heightmaps.TryGetValue("WORLD_SURFACE", out node); + source = node as TagNodeLongArray; + } + if (source == null) return null; + + int[] result = new int[XDIM * ZDIM]; + const int bits = 9; + int valuesPerLong = 64 / bits; + int paddedLength = (result.Length + valuesPerLong - 1) / valuesPerLong; + bool padded = source.Data.Length >= paddedLength; + for (int i = 0; i < result.Length; i++) + result[i] = AquaticSection.ReadPacked(source.Data, i, bits, padded) + minimumY; + return result; + } + + private void RebuildHeightMap() + { + int minimumY = _minimumSectionY * 16; + for (int x = 0; x < XDIM; x++) { + for (int z = 0; z < ZDIM; z++) { + for (int y = _blocks.YDim - 1; y >= 0; y--) { + BlockInfo info = _blockManager.GetInfo(x, y, z); + string name = _sections[y / 16].GetBlockName(x, y & 15, z); + if (IsMotionBlocking(info, name)) { + _heightMap[x, z] = minimumY + y + 1; + break; + } + } + } + } + } + + private static bool IsMotionBlocking(BlockInfo info, string name) + { + if (info == null || info.State == BlockState.NONSOLID) + return false; + if (name == "minecraft:leaf_litter") + return false; + return name == null || !name.EndsWith("_leaves", StringComparison.Ordinal); + } + + #endregion + + #region ICopyable Members + + public AquaticChunk Copy () + { + return AquaticChunk.Create(_tree.Copy()); + } + + #endregion + + private void BuildConditional () + { + TagNodeCompound level = ChunkTag; + if (_tileTicks != _blockManager.TileTicks && _blockManager.TileTicks.Count > 0) { + _tileTicks = _blockManager.TileTicks; + level["TileTicks"] = _tileTicks; + } + } + + private void BuildNBTTree () + { + _dataVersion = 1631; + int elements2 = XDIM * ZDIM; + + _sections = new AquaticSection[16]; + TagNodeList sections = new TagNodeList(TagType.TAG_COMPOUND); + + for (int i = 0; i < _sections.Length; i++) { + _sections[i] = new AquaticSection(i, _dataVersion); + sections.Add(_sections[i].BuildTree()); + } + + FusedDataArray3[] blocksBA = new FusedDataArray3[_sections.Length]; + YZXNibbleArray[] dataBA = new YZXNibbleArray[_sections.Length]; + YZXNibbleArray[] skyLightBA = new YZXNibbleArray[_sections.Length]; + YZXNibbleArray[] blockLightBA = new YZXNibbleArray[_sections.Length]; + + for (int i = 0; i < _sections.Length; i++) { + blocksBA[i] = new FusedDataArray3(_sections[i].AddBlocks, _sections[i].Blocks); + dataBA[i] = _sections[i].Data; + skyLightBA[i] = _sections[i].SkyLight; + blockLightBA[i] = _sections[i].BlockLight; + } + + _blocks = new CompositeDataArray3(blocksBA); + _data = new CompositeDataArray3(dataBA); + _skyLight = new CompositeDataArray3(skyLightBA); + _blockLight = new CompositeDataArray3(blockLightBA); + + TagNodeIntArray heightMap = new TagNodeIntArray(new int[elements2]); + _heightMap = new ZXIntArray(XDIM, ZDIM, heightMap); + + TagNodeIntArray biomes = new TagNodeIntArray(new int[elements2]); + _biomes = new ZXIntArray(XDIM, ZDIM, biomes); + for (int x = 0; x < XDIM; x++) + for (int z = 0; z < ZDIM; z++) + _biomes[x, z] = BiomeType.Default; + + _entities = new TagNodeList(TagType.TAG_COMPOUND); + _tileEntities = new TagNodeList(TagType.TAG_COMPOUND); + _tileTicks = new TagNodeList(TagType.TAG_COMPOUND); + + TagNodeCompound level = new TagNodeCompound(); + level.Add("Sections", sections); + level.Add("HeightMap", heightMap); + level.Add("Biomes", biomes); + level.Add("Entities", _entities); + level.Add("TileEntities", _tileEntities); + level.Add("TileTicks", _tileTicks); + level.Add("LastUpdate", new TagNodeLong(Timestamp())); + level.Add("xPos", new TagNodeInt(_cx)); + level.Add("zPos", new TagNodeInt(_cz)); + level.Add("TerrainPopulated", new TagNodeByte()); + + _tree = new NbtTree(); + _tree.Root.Add("DataVersion", new TagNodeInt(_dataVersion)); + _tree.Root.Add("Level", level); + + _blockManager = new AlphaBlockCollection(_blocks, _data, _blockLight, _skyLight, _heightMap, _tileEntities); + _entityManager = new EntityCollection(_entities); + _biomeManager = new AquaticBiomeCollection(_biomes); + } + + private int Timestamp () + { + DateTime epoch = new DateTime(1970, 1, 1, 0, 0, 0, 0); + return (int)((DateTime.UtcNow - epoch).Ticks / (10000L * 1000L)); + } + } +} diff --git a/SubstrateCS/Source/AquaticSection.cs b/SubstrateCS/Source/AquaticSection.cs new file mode 100644 index 00000000..2f9deb54 --- /dev/null +++ b/SubstrateCS/Source/AquaticSection.cs @@ -0,0 +1,487 @@ +using System; +using System.Collections.Generic; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate +{ + /// Represents a palette-based Anvil section (Minecraft 1.13 through 1.17). + public class AquaticSection : INbtObject, ICopyable + { + public static readonly SchemaNodeCompound SectionSchema = new SchemaNodeCompound() { + new SchemaNodeList("Palette", TagType.TAG_COMPOUND, new SchemaNodeCompound() { + new SchemaNodeString("Name", null), + new SchemaNodeCompound("Properties", SchemaOptions.OPTIONAL), + }), + new SchemaNodeLongArray("BlockStates", 0, SchemaOptions.OPTIONAL), + new SchemaNodeArray("SkyLight", 2048, SchemaOptions.OPTIONAL), + new SchemaNodeArray("BlockLight", 2048, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("Y", TagType.TAG_BYTE), + }; + public static readonly SchemaNodeCompound ModernSectionSchema = new SchemaNodeCompound() { + new SchemaNodeCompound("block_states") { + new SchemaNodeList("palette", TagType.TAG_COMPOUND, new SchemaNodeCompound() { + new SchemaNodeString("Name", null), + new SchemaNodeCompound("Properties", SchemaOptions.OPTIONAL), + }), + new SchemaNodeLongArray("data", 0, SchemaOptions.OPTIONAL), + }, + new SchemaNodeCompound("biomes", SchemaOptions.OPTIONAL), + new SchemaNodeArray("SkyLight", 2048, SchemaOptions.OPTIONAL), + new SchemaNodeArray("BlockLight", 2048, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("Y", TagType.TAG_BYTE), + }; + + private const int Size = 16; + private const int BlockCount = 4096; + private TagNodeCompound _tree; + private byte _y; + private YZXShortDataArray _blocks; + private YZXNibbleArray _data; + private YZXNibbleArray _blockLight; + private YZXNibbleArray _skyLight; + private YZXNibbleArray _addBlocks; + private TagNodeByteArray _blockLightTag; + private TagNodeByteArray _skyLightTag; + private PaletteBlock[] _palette; + private byte[] _originalPaletteIndices8; + private ushort[] _originalPaletteIndices16; + private int _dataVersion; + private bool _modern; + + private AquaticSection() { } + + public AquaticSection(int y) : this(y, 1631, false) { } + + public AquaticSection(int y, int dataVersion) : this(y, dataVersion, false) { } + + internal AquaticSection(int y, int dataVersion, bool modern) + { + if (y < -128 || y > 127) throw new ArgumentOutOfRangeException("y"); + _y = unchecked((byte)(sbyte)y); + _dataVersion = dataVersion; + _modern = modern; + BuildNbtTree(); + } + + public AquaticSection(TagNodeCompound tree) : this(tree, 1631) { } + + public AquaticSection(TagNodeCompound tree, int dataVersion) + { + _dataVersion = dataVersion; + if (LoadTree(tree) == null) throw new ArgumentException("Invalid palette section.", "tree"); + } + + public int Y { + get { return (sbyte)_y; } + set { + if (value < -128 || value > 127) throw new ArgumentOutOfRangeException("value"); + _y = unchecked((byte)(sbyte)value); + _tree["Y"] = new TagNodeByte(_y); + } + } + + public YZXShortDataArray Blocks { get { return _blocks; } } + public YZXNibbleArray Data { get { return _data; } } + public YZXNibbleArray BlockLight { get { return _blockLight; } } + public YZXNibbleArray SkyLight { get { return _skyLight; } } + public YZXNibbleArray AddBlocks + { + get + { + if (_addBlocks == null) + _addBlocks = new YZXNibbleArray( + Size, Size, Size, new TagNodeByteArray(new byte[BlockCount / 2])); + return _addBlocks; + } + } + public PaletteBlock[] Palette { get { return _palette; } } + + public bool CheckEmpty() + { + for (int i = 0; i < _blocks.Length; i++) { + if (_blocks[i] != 0) return false; + if (HasOriginalPaletteIndices && + IsOriginalState(i) && + _palette[GetOriginalPaletteIndex(i)].Name != "minecraft:air") return false; + } + return true; + } + + /// Gets the namespaced block-state name at local section coordinates. + public string GetBlockName(int x, int y, int z) + { + return GetPaletteBlock(x, y, z).Name; + } + + /// Gets the block-state properties at local section coordinates. + public TagNodeCompound GetBlockProperties(int x, int y, int z) + { + return GetPaletteBlock(x, y, z).Properties; + } + + /// Sets a namespaced block state without requiring a legacy numeric block ID. + public void SetBlockState(int x, int y, int z, string name, TagNodeCompound properties) + { + int index = _blocks.GetIndex(x, y, z); + BlockInfo blockInfo; + ItemInfo itemInfo; + int id = BlockInfo.BlockNameTable.TryGetValue(name, out blockInfo) + ? blockInfo.ID + : (ItemInfo.StrTable.TryGetValue(name, out itemInfo) ? itemInfo.ID : 0); + PaletteBlock state = new PaletteBlock(name, properties == null ? null : properties.Copy() as TagNodeCompound, id, 0); + int paletteIndex = Array.IndexOf(_palette, state); + if (paletteIndex < 0) { + PaletteBlock[] expanded = new PaletteBlock[_palette.Length + 1]; + _palette.CopyTo(expanded, 0); + paletteIndex = _palette.Length; + expanded[paletteIndex] = state; + _palette = expanded; + } + _blocks[index] = id; + _data[index] = 0; + SetOriginalPaletteIndex(index, paletteIndex); + } + + private PaletteBlock GetPaletteBlock(int x, int y, int z) + { + int index = _blocks.GetIndex(x, y, z); + if (HasOriginalPaletteIndices && IsOriginalState(index)) + return _palette[GetOriginalPaletteIndex(index)]; + return FindPaletteBlock(_blocks[index], _data[index]); + } + + public AquaticSection LoadTree(TagNode tree) + { + TagNodeCompound section = tree as TagNodeCompound; + if (section == null) return null; + TagNodeByte y = section["Y"] as TagNodeByte; + TagNode paletteNode; + section.TryGetValue("Palette", out paletteNode); + TagNodeList paletteTag = paletteNode as TagNodeList; + TagNodeCompound blockStatesContainer = null; + if (paletteTag == null) { + TagNode containerNode; + section.TryGetValue("block_states", out containerNode); + blockStatesContainer = containerNode as TagNodeCompound; + if (blockStatesContainer != null) { + blockStatesContainer.TryGetValue("palette", out paletteNode); + paletteTag = paletteNode as TagNodeList; + _modern = true; + } + } + if (y == null || paletteTag == null || paletteTag.Count == 0) return null; + + _y = y.Data; + _tree = section; + _palette = new PaletteBlock[paletteTag.Count]; + for (int i = 0; i < paletteTag.Count; i++) + _palette[i] = PaletteBlock.FromTree(paletteTag[i] as TagNodeCompound); + + short[,,] ids = new short[Size, Size, Size]; + TagNodeByteArray metadataTag = new TagNodeByteArray(new byte[BlockCount / 2]); + _blocks = new YZXShortDataArray(ids); + _data = new YZXNibbleArray(Size, Size, Size, metadataTag); + if (_palette.Length <= byte.MaxValue + 1) + _originalPaletteIndices8 = new byte[BlockCount]; + else + _originalPaletteIndices16 = new ushort[BlockCount]; + + TagNode statesNode; + if (_modern) blockStatesContainer.TryGetValue("data", out statesNode); + else section.TryGetValue("BlockStates", out statesNode); + TagNodeLongArray states = statesNode as TagNodeLongArray; + int bits = Math.Max(4, BitsFor(_palette.Length)); + for (int i = 0; i < BlockCount; i++) { + int paletteIndex = _palette.Length == 1 ? 0 : ReadPacked(states == null ? null : states.Data, i, bits, UsesPaddedPacking); + if (paletteIndex < 0 || paletteIndex >= _palette.Length) paletteIndex = 0; + _blocks[i] = _palette[paletteIndex].ID; + _data[i] = _palette[paletteIndex].Data; + SetOriginalPaletteIndex(i, paletteIndex); + } + + _skyLight = NibbleArray(section, "SkyLight", out _skyLightTag); + _blockLight = NibbleArray(section, "BlockLight", out _blockLightTag); + return this; + } + + private static YZXNibbleArray NibbleArray(TagNodeCompound tree, string name, out TagNodeByteArray tag) + { + TagNode value; + tree.TryGetValue(name, out value); + tag = value as TagNodeByteArray; + if (tag == null || tag.Data.Length != BlockCount / 2) { + tag = new TagNodeByteArray(new byte[BlockCount / 2]); + tree[name] = tag; + } + return new YZXNibbleArray(Size, Size, Size, tag); + } + + public AquaticSection LoadTreeSafe(TagNode tree) + { + return ValidateTree(tree) ? LoadTree(tree) : null; + } + + public TagNode BuildTree() + { + List palette = new List(); + int[] indices = new int[BlockCount]; + for (int i = 0; i < BlockCount; i++) { + PaletteBlock block; + if (HasOriginalPaletteIndices && IsOriginalState(i)) { + block = _palette[GetOriginalPaletteIndex(i)]; + } else { + block = FindPaletteBlock(_blocks[i], _data[i]); + } + int index = palette.IndexOf(block); + if (index < 0) { + index = palette.Count; + palette.Add(block); + } + indices[i] = index; + } + + TagNodeCompound copy = new TagNodeCompound(); + foreach (KeyValuePair node in _tree) copy[node.Key] = node.Value; + TagNodeList paletteTag = new TagNodeList(TagType.TAG_COMPOUND); + foreach (PaletteBlock block in palette) paletteTag.Add(block.BuildTree()); + TagNodeLongArray packed = null; + if (palette.Count != 1) { + int bits = Math.Max(4, BitsFor(palette.Count)); + packed = new TagNodeLongArray(WritePacked(indices, bits, UsesPaddedPacking)); + } + if (_modern) { + TagNodeCompound container = new TagNodeCompound(); + container["palette"] = paletteTag; + if (packed != null) container["data"] = packed; + copy["block_states"] = container; + copy.Remove("Palette"); + copy.Remove("BlockStates"); + } else { + copy["Palette"] = paletteTag; + if (packed == null) copy.Remove("BlockStates"); + else copy["BlockStates"] = packed; + } + return copy; + } + + private PaletteBlock FindPaletteBlock(int id, int data) + { + for (int i = 0; i < _palette.Length; i++) + if (_palette[i].ID == id && _palette[i].Data == data) return _palette[i]; + + string legacyName; + TagNodeCompound legacyProperties; + if (BlockInfo.TryGetLegacyBlockState(id, data, out legacyName, out legacyProperties)) + return new PaletteBlock(legacyName, legacyProperties, id, data); + + BlockInfo blockInfo = BlockInfo.BlockTable[id]; + if (blockInfo != null && blockInfo.StrID != null) + return new PaletteBlock(blockInfo.StrID, null, id, data); + ItemInfo itemInfo = ItemInfo.ItemTable[id]; + if (itemInfo != null && itemInfo.StringId != null) + return new PaletteBlock(itemInfo.StringId, null, id, data); + return new PaletteBlock("minecraft:air", null, 0, 0); + } + + private bool HasOriginalPaletteIndices + { + get { return _originalPaletteIndices8 != null || _originalPaletteIndices16 != null; } + } + + private int GetOriginalPaletteIndex(int index) + { + return _originalPaletteIndices16 != null + ? _originalPaletteIndices16[index] + : _originalPaletteIndices8[index]; + } + + private void SetOriginalPaletteIndex(int index, int paletteIndex) + { + if (paletteIndex < 0 || paletteIndex >= BlockCount) + throw new ArgumentOutOfRangeException("paletteIndex"); + + if (_originalPaletteIndices16 != null) { + _originalPaletteIndices16[index] = (ushort)paletteIndex; + return; + } + + if (_originalPaletteIndices8 == null) + _originalPaletteIndices8 = new byte[BlockCount]; + + if (paletteIndex <= byte.MaxValue) { + _originalPaletteIndices8[index] = (byte)paletteIndex; + return; + } + + _originalPaletteIndices16 = new ushort[BlockCount]; + for (int i = 0; i < BlockCount; i++) + _originalPaletteIndices16[i] = _originalPaletteIndices8[i]; + _originalPaletteIndices8 = null; + _originalPaletteIndices16[index] = (ushort)paletteIndex; + } + + private bool IsOriginalState(int index) + { + int paletteIndex = GetOriginalPaletteIndex(index); + if (paletteIndex < 0 || paletteIndex >= _palette.Length) return false; + PaletteBlock original = _palette[paletteIndex]; + return _blocks[index] == original.ID && _data[index] == original.Data; + } + + public bool ValidateTree(TagNode tree) + { + TagNodeCompound compound = tree as TagNodeCompound; + return compound != null && new NbtVerifier(tree, + compound.ContainsKey("block_states") ? ModernSectionSchema : SectionSchema).Verify(); + } + + public AquaticSection Copy() + { + AquaticSection copy = new AquaticSection(); + copy._dataVersion = _dataVersion; + return copy.LoadTree(_tree.Copy()); + } + + private bool UsesPaddedPacking { get { return _modern || _dataVersion >= 2529; } } + + private static int BitsFor(int count) + { + int bits = 0; + for (int value = count - 1; value > 0; value >>= 1) bits++; + return bits; + } + + internal static int ReadPacked(long[] values, int index, int bits, bool padded) + { + if (values == null || values.Length == 0) return 0; + ulong mask = (1UL << bits) - 1; + if (padded) { + int perLong = 64 / bits; + int word = index / perLong; + return word < values.Length ? (int)(((ulong)values[word] >> ((index % perLong) * bits)) & mask) : 0; + } + long bitIndex = (long)index * bits; + int first = (int)(bitIndex >> 6); + int offset = (int)(bitIndex & 63); + if (first >= values.Length) return 0; + ulong result = (ulong)values[first] >> offset; + if (offset + bits > 64 && first + 1 < values.Length) + result |= (ulong)values[first + 1] << (64 - offset); + return (int)(result & mask); + } + + internal static long[] WritePacked(int[] values, int bits, bool padded) + { + ulong mask = (1UL << bits) - 1; + int length = padded + ? (values.Length + (64 / bits) - 1) / (64 / bits) + : (values.Length * bits + 63) / 64; + long[] result = new long[length]; + for (int i = 0; i < values.Length; i++) { + if (padded) { + int perLong = 64 / bits; + int word = i / perLong; + result[word] = (long)((ulong)result[word] | (((ulong)values[i] & mask) << ((i % perLong) * bits))); + } else { + long bitIndex = (long)i * bits; + int word = (int)(bitIndex >> 6); + int offset = (int)(bitIndex & 63); + result[word] = (long)((ulong)result[word] | (((ulong)values[i] & mask) << offset)); + if (offset + bits > 64) + result[word + 1] = (long)((ulong)result[word + 1] | (((ulong)values[i] & mask) >> (64 - offset))); + } + } + return result; + } + + private void BuildNbtTree() + { + _blocks = new YZXShortDataArray(new short[Size, Size, Size]); + _data = new YZXNibbleArray(Size, Size, Size, new TagNodeByteArray(new byte[BlockCount / 2])); + _skyLightTag = new TagNodeByteArray(new byte[BlockCount / 2]); + _blockLightTag = new TagNodeByteArray(new byte[BlockCount / 2]); + _skyLight = new YZXNibbleArray(Size, Size, Size, _skyLightTag); + _blockLight = new YZXNibbleArray(Size, Size, Size, _blockLightTag); + _palette = new[] { new PaletteBlock("minecraft:air", null, 0, 0) }; + _tree = new TagNodeCompound(); + _tree["Y"] = new TagNodeByte(_y); + TagNodeList palette = new TagNodeList(TagType.TAG_COMPOUND) { _palette[0].BuildTree() }; + if (_modern) { + TagNodeCompound container = new TagNodeCompound(); + container["palette"] = palette; + _tree["block_states"] = container; + } else { + _tree["Palette"] = palette; + } + _tree["SkyLight"] = _skyLightTag; + _tree["BlockLight"] = _blockLightTag; + } + } + + public struct PaletteBlock : IEquatable + { + public readonly string Name; + public readonly TagNodeCompound Properties; + public readonly int ID; + public readonly int Data; + + public PaletteBlock(BlockInfo blockInfo, string[] properties) + : this(blockInfo == null ? "minecraft:air" : blockInfo.StrID, null, + blockInfo == null ? 0 : blockInfo.ID, 0) { } + + internal PaletteBlock(string name, TagNodeCompound properties, int id, int data) + { + Name = String.IsNullOrEmpty(name) ? "minecraft:air" : name; + Properties = properties; + ID = id; + Data = data; + } + + internal static PaletteBlock FromTree(TagNodeCompound tree) + { + TagNode nameNode; + if (tree == null || !tree.TryGetValue("Name", out nameNode)) nameNode = null; + TagNodeString nameTag = nameNode as TagNodeString; + string name = nameTag == null ? "minecraft:air" : nameTag.Data; + TagNode propertiesNode; + if (tree == null || !tree.TryGetValue("Properties", out propertiesNode)) propertiesNode = null; + TagNodeCompound properties = propertiesNode as TagNodeCompound; + int legacyId; + int legacyData; + if (BlockInfo.TryGetLegacyBlockState(name, properties, out legacyId, out legacyData)) + return new PaletteBlock(name, properties, legacyId, legacyData); + BlockInfo blockInfo; + if (name != null && BlockInfo.BlockNameTable.TryGetValue(name, out blockInfo)) + return new PaletteBlock(name, properties, blockInfo.ID, 0); + ItemInfo info; + if (name != null && ItemInfo.StrTable.TryGetValue(name, out info)) + return new PaletteBlock(name, properties, info.ID, 0); + return new PaletteBlock(name, properties, 0, 0); + } + + internal TagNodeCompound BuildTree() + { + TagNodeCompound result = new TagNodeCompound(); + result["Name"] = new TagNodeString(Name); + if (Properties != null && Properties.Count > 0) result["Properties"] = Properties; + return result; + } + + public bool Equals(PaletteBlock other) + { + if (Name != other.Name) return false; + if (Properties == null || Properties.Count == 0) return other.Properties == null || other.Properties.Count == 0; + if (other.Properties == null || Properties.Count != other.Properties.Count) return false; + foreach (KeyValuePair property in Properties) { + TagNodeString left = property.Value as TagNodeString; + TagNodeString right = other.Properties[property.Key] as TagNodeString; + if (left == null || right == null || left.Data != right.Data) return false; + } + return true; + } + + public override bool Equals(object obj) { return obj is PaletteBlock && Equals((PaletteBlock)obj); } + public override int GetHashCode() { return Name.GetHashCode(); } + } +} diff --git a/SubstrateCS/Source/BlockInfo.cs b/SubstrateCS/Source/BlockInfo.cs index 4d0702f0..8d7b2fa7 100644 --- a/SubstrateCS/Source/BlockInfo.cs +++ b/SubstrateCS/Source/BlockInfo.cs @@ -1,7 +1,10 @@ using System; using System.Collections.Generic; using Substrate.Nbt; -using System.Collections; +using System.Collections; +using System.Diagnostics; +using System.IO; +using System.Reflection; namespace Substrate { @@ -180,10 +183,20 @@ public static class BlockType public const int DROPPER = 158; public const int STAINED_CLAY = 159; public const int STAINED_GLASS_PANE = 160; + public const int ACACIA_WOOD_STAIRS = 163; + public const int DARK_OAK_WOOD_STAIRS = 164; public const int HAY_BLOCK = 170; public const int CARPET = 171; public const int HARDENED_CLAY = 172; - public const int COAL_BLOCK = 173; + public const int COAL_BLOCK = 173; + public const int DOUBLE_PLANT = 175; + public const int CONCRETE = 251; + public const int CONCRETE_POWDER = 252; + public const int SEA_LANTERN = 169; + public const int STANDING_BANNER = 176; + public const int WALL_BANNER = 177; + public const int PURPUR = 201; + public const int PURPUR_STAIRS = 203; } /// @@ -245,6 +258,19 @@ public class BlockInfo private static readonly int[] _opacityTable; private static readonly int[] _luminanceTable; + private static readonly Dictionary _blockNameTable = new Dictionary(); + private static readonly Dictionary _legacyBlockStates = new Dictionary(); + private static readonly Dictionary _legacyBlockIds = new Dictionary(); + private static readonly Dictionary _legacyBlockStateKeys = new Dictionary(); + private static readonly Dictionary _legacyDefaultBlockNames = new Dictionary(); + private static int _nextNamedBlockId = MAX_BLOCKS - 1; + + private struct LegacyBlockState + { + public string Name; + public TagNodeCompound Properties; + } + private class CacheTableArray : ICacheTable { private T[] _cache; @@ -310,6 +336,7 @@ public bool Test (int data) private int _id = 0; private string _name = ""; + private string _strId; private int _tick = 0; private int _opacity = MAX_OPACITY; private int _luminance = MIN_LUMINANCE; @@ -333,6 +360,25 @@ public static ICacheTable BlockTable get { return _blockTableCache; } } + public static Dictionary BlockNameTable { + get { + return _blockNameTable; + } + } + + /// + /// Gets all block types introduced by Minecraft Java Edition 1.13 (Update Aquatic). + /// + public static IList AquaticBlocks { get; private set; } + + /// + /// Gets every vanilla block type available through Minecraft Java Edition 26.2. + /// + public static IList ModernBlocks { get; private set; } + + /// The Minecraft version used to generate . + public const string ModernBlockRegistryVersion = "26.2"; + /// /// Gets the lookup table for id-to-opacity values. /// @@ -357,6 +403,12 @@ public int ID get { return _id; } } + public string StrID { + get { + return _strId; + } + } + /// /// Get's the name of the block type. /// @@ -442,13 +494,280 @@ internal BlockInfo (int id) /// The id of the block. /// The name of the block. /// All user-constructed objects are registered automatically. - public BlockInfo (int id, string name) + public BlockInfo (int id, string name, string strId = null) { _id = id; _name = name; _blockTable[_id] = this; _registered = true; - } + _strId = strId; + if (strId != null) { + Debug.Assert(!_blockNameTable.ContainsKey(strId)); + _blockNameTable[strId] = this; + } + } + + private static BlockInfo RegisterNamedBlock(string stringId, string name) + { + if (_nextNamedBlockId < 256) + throw new InvalidOperationException("The internal block ID table is too small for the modern block registry."); + return new BlockInfo(_nextNamedBlockId--, name, stringId); + } + + private static BlockInfo RegisterTransparentNamedBlock(string stringId, string name) + { + return RegisterNamedBlock(stringId, name).SetOpacity(0); + } + + private static void RegisterAquaticBlocks() + { + List blocks = new List(); + + string[] solidBlocks = { + "blue_ice", "carved_pumpkin", "dried_kelp_block", + "oak_wood", "spruce_wood", "birch_wood", "jungle_wood", "acacia_wood", "dark_oak_wood", + "stripped_oak_log", "stripped_spruce_log", "stripped_birch_log", "stripped_jungle_log", + "stripped_acacia_log", "stripped_dark_oak_log", + "stripped_oak_wood", "stripped_spruce_wood", "stripped_birch_wood", "stripped_jungle_wood", + "stripped_acacia_wood", "stripped_dark_oak_wood", + "tube_coral_block", "brain_coral_block", "bubble_coral_block", "fire_coral_block", "horn_coral_block", + "dead_tube_coral_block", "dead_brain_coral_block", "dead_bubble_coral_block", + "dead_fire_coral_block", "dead_horn_coral_block" + }; + foreach (string id in solidBlocks) + blocks.Add(RegisterNamedBlock("minecraft:" + id, DisplayName(id))); + + string[] partialBlocks = { + "prismarine_slab", "prismarine_stairs", "prismarine_brick_slab", "prismarine_brick_stairs", + "dark_prismarine_slab", "dark_prismarine_stairs", "petrified_oak_slab", + "acacia_trapdoor", "birch_trapdoor", "dark_oak_trapdoor", "jungle_trapdoor", "spruce_trapdoor" + }; + foreach (string id in partialBlocks) + blocks.Add(RegisterTransparentNamedBlock("minecraft:" + id, DisplayName(id))); + + string[] nonSolidBlocks = { + "cave_air", "void_air", "kelp", "kelp_plant", "seagrass", "tall_seagrass", "turtle_egg", + "tube_coral", "brain_coral", "bubble_coral", "fire_coral", "horn_coral", + "tube_coral_fan", "brain_coral_fan", "bubble_coral_fan", "fire_coral_fan", "horn_coral_fan", + "dead_tube_coral_fan", "dead_brain_coral_fan", "dead_bubble_coral_fan", + "dead_fire_coral_fan", "dead_horn_coral_fan", + "tube_coral_wall_fan", "brain_coral_wall_fan", "bubble_coral_wall_fan", + "fire_coral_wall_fan", "horn_coral_wall_fan", + "dead_tube_coral_wall_fan", "dead_brain_coral_wall_fan", "dead_bubble_coral_wall_fan", + "dead_fire_coral_wall_fan", "dead_horn_coral_wall_fan", + "acacia_button", "birch_button", "dark_oak_button", "jungle_button", "spruce_button", + "acacia_pressure_plate", "birch_pressure_plate", "dark_oak_pressure_plate", + "jungle_pressure_plate", "spruce_pressure_plate" + }; + foreach (string id in nonSolidBlocks) + blocks.Add(RegisterTransparentNamedBlock("minecraft:" + id, DisplayName(id)).SetState(BlockState.NONSOLID)); + + blocks.Add(RegisterTransparentNamedBlock("minecraft:bubble_column", "Bubble Column").SetState(BlockState.FLUID)); + blocks.Add(RegisterTransparentNamedBlock("minecraft:conduit", "Conduit").SetLuminance(MAX_LUMINANCE)); + blocks.Add(RegisterTransparentNamedBlock("minecraft:sea_pickle", "Sea Pickle") + .SetState(BlockState.NONSOLID).SetLuminance(6)); + + AquaticBlocks = blocks.AsReadOnly(); + } + + private static void RegisterModernBlocks() + { + LoadLegacyBlockStates(); + List blocks = new List(); + Assembly assembly = Assembly.GetExecutingAssembly(); + using (Stream stream = assembly.GetManifestResourceStream("Substrate.Data.BlockRegistry-26.2.txt")) { + if (stream == null) + throw new InvalidOperationException("The embedded Minecraft 26.2 block registry is missing."); + + using (StreamReader reader = new StreamReader(stream)) { + string stringId; + while ((stringId = reader.ReadLine()) != null) { + stringId = stringId.Trim(); + if (stringId.Length == 0) continue; + + BlockInfo info; + if (!_blockNameTable.TryGetValue(stringId, out info)) { + ItemInfo legacyItem; + int legacyId; + if (ItemInfo.StrTable.TryGetValue(stringId, out legacyItem) + && legacyItem.ID >= 0 && legacyItem.ID < 256) + legacyId = legacyItem.ID; + else if (!_legacyBlockIds.TryGetValue(stringId, out legacyId)) + legacyId = -1; + if (legacyId >= 0) { + info = _blockTable[legacyId]; + if (info == null) { + int separator = stringId.IndexOf(':'); + string path = separator < 0 ? stringId : stringId.Substring(separator + 1); + info = new BlockInfo(legacyId, DisplayName(path), stringId); + } + string defaultName; + if (info._strId == null + && (!_legacyDefaultBlockNames.TryGetValue(legacyId, out defaultName) + || defaultName == stringId)) + info._strId = stringId; + _blockNameTable[stringId] = info; + } + else { + int separator = stringId.IndexOf(':'); + string path = separator < 0 ? stringId : stringId.Substring(separator + 1); + info = RegisterNamedBlock(stringId, DisplayName(path)); + } + } + blocks.Add(info); + } + } + } + ModernBlocks = blocks.AsReadOnly(); + } + + private static void LoadLegacyBlockStates() + { + Assembly assembly = Assembly.GetExecutingAssembly(); + using (Stream stream = assembly.GetManifestResourceStream("Substrate.Data.LegacyBlockStates.txt")) { + if (stream == null) + throw new InvalidOperationException("The embedded legacy block-state registry is missing."); + + using (StreamReader reader = new StreamReader(stream)) { + string line; + while ((line = reader.ReadLine()) != null) { + int separator = line.IndexOf('|'); + int dataSeparator = line.IndexOf(':'); + if (separator <= dataSeparator || dataSeparator <= 0) continue; + + int id; + int data; + if (!Int32.TryParse(line.Substring(0, dataSeparator), out id) + || !Int32.TryParse(line.Substring(dataSeparator + 1, separator - dataSeparator - 1), out data)) + continue; + + string stateText = line.Substring(separator + 1); + int propertiesStart = stateText.IndexOf('['); + string name = propertiesStart < 0 ? stateText : stateText.Substring(0, propertiesStart); + TagNodeCompound properties = null; + if (propertiesStart >= 0 && stateText.EndsWith("]")) { + properties = new TagNodeCompound(); + string propertyText = stateText.Substring(propertiesStart + 1, stateText.Length - propertiesStart - 2); + foreach (string pair in propertyText.Split(',')) { + int equals = pair.IndexOf('='); + if (equals > 0) + properties[pair.Substring(0, equals)] = new TagNodeString(pair.Substring(equals + 1)); + } + } + + int key = (id << 4) | (data & 15); + _legacyBlockStates[key] = new LegacyBlockState { Name = name, Properties = properties }; + _legacyBlockStateKeys[LegacyBlockStateKey(name, properties)] = key; + if (data == 0 && !_legacyDefaultBlockNames.ContainsKey(id)) + _legacyDefaultBlockNames[id] = name; + if (!_legacyBlockIds.ContainsKey(name)) + _legacyBlockIds[name] = id; + } + } + } + } + + internal static bool TryGetLegacyBlockState(int id, int data, out string name, out TagNodeCompound properties) + { + LegacyBlockState state; + if (_legacyBlockStates.TryGetValue((id << 4) | (data & 15), out state)) { + name = state.Name; + properties = state.Properties == null ? null : state.Properties.Copy() as TagNodeCompound; + return true; + } + name = null; + properties = null; + return false; + } + + /// + /// Converts a legacy numeric block ID and metadata value to its + /// complete Aquatic block name and property set. + /// + public static void GetModernBlockState ( + int id, int data, out string name, out TagNodeCompound properties) + { + if (!TryGetLegacyBlockState(id, data, out name, out properties)) + throw new ArgumentException( + "Legacy block state " + id + ":" + data + + " has no Aquatic representation."); + } + + internal static bool TryGetLegacyBlockState(string name, TagNodeCompound properties, out int id, out int data) + { + int key; + if (_legacyBlockStateKeys.TryGetValue(LegacyBlockStateKey(name, properties), out key)) { + id = key >> 4; + data = key & 15; + return true; + } + id = 0; + data = 0; + return false; + } + + /// + /// Converts a namespaced block name to its pre-Aquatic numeric ID and + /// metadata value. + /// + /// + /// Thrown when is null. + /// + /// + /// Thrown when the block has no exact pre-Aquatic representation. + /// + public static void GetLegacyBlockState( + string name, out int id, out int data) + { + GetLegacyBlockState(name, null, out id, out data); + } + + /// + /// Converts a namespaced block state to its pre-Aquatic numeric ID and + /// metadata value. + /// + /// + /// Block-state properties required to distinguish states such as log + /// axis and door orientation. May be null for blocks without properties. + /// + /// + /// Thrown when is null. + /// + /// + /// Thrown when the block state has no exact pre-Aquatic representation. + /// + public static void GetLegacyBlockState( + string name, TagNodeCompound properties, out int id, out int data) + { + if (name == null) + throw new ArgumentNullException("name"); + if (!TryGetLegacyBlockState(name, properties, out id, out data)) + throw new ArgumentException( + "Block state '" + LegacyBlockStateKey(name, properties) + + "' has no pre-Aquatic ID and data representation.", + "name"); + } + + private static string LegacyBlockStateKey(string name, TagNodeCompound properties) + { + if (properties == null || properties.Count == 0) return name; + List values = new List(); + foreach (KeyValuePair property in properties) { + TagNodeString value = property.Value as TagNodeString; + if (value != null) values.Add(property.Key + "=" + value.Data); + } + values.Sort(StringComparer.Ordinal); + return name + "[" + String.Join(",", values.ToArray()) + "]"; + } + + private static string DisplayName(string id) + { + string[] words = id.Split('_'); + for (int i = 0; i < words.Length; i++) + if (words[i].Length > 0) + words[i] = Char.ToUpperInvariant(words[i][0]) + words[i].Substring(1); + return String.Join(" ", words); + } /// /// Sets a new opacity value for this block type. @@ -729,10 +1048,14 @@ public bool TestData (int data) public static BlockInfoEx Dropper; public static BlockInfo StainedClay; public static BlockInfo StainedGlassPane; + public static BlockInfo AcaciaWood; public static BlockInfo HayBlock; public static BlockInfo Carpet; public static BlockInfo HardenedClay; - public static BlockInfo CoalBlock; + public static BlockInfo CoalBlock; + public static BlockInfo DoublePlant; + public static BlockInfoEx StandingBanner; + public static BlockInfoEx WallBanner; static BlockInfo () { @@ -744,7 +1067,7 @@ static BlockInfo () _opacityTableCache = new CacheTableArray(_opacityTable); _luminanceTableCache = new CacheTableArray(_luminanceTable); - Air = new BlockInfo(0, "Air").SetOpacity(0).SetState(BlockState.NONSOLID); + Air = new BlockInfo(0, "Air", "minecraft:air").SetOpacity(0).SetState(BlockState.NONSOLID); Stone = new BlockInfo(1, "Stone"); Grass = new BlockInfo(2, "Grass").SetTick(10); Dirt = new BlockInfo(3, "Dirt"); @@ -906,12 +1229,20 @@ static BlockInfo () Dropper = (BlockInfoEx)new BlockInfoEx(158, "Dropper").SetTick(10); StainedClay = new BlockInfo(159, "Stained Clay"); StainedGlassPane = new BlockInfo(160, "Stained Glass Pane").SetOpacity(0); + AcaciaWood = new BlockInfo(162, "Acacia Wood"); HayBlock = new BlockInfo(170, "Hay Block"); Carpet = new BlockInfo(171, "Carpet").SetOpacity(0); HardenedClay = new BlockInfo(172, "Hardened Clay"); - CoalBlock = new BlockInfo(173, "Block of Coal"); - - for (int i = 0; i < MAX_BLOCKS; i++) { + CoalBlock = new BlockInfo(173, "Block of Coal"); + DoublePlant = new BlockInfo(BlockType.DOUBLE_PLANT, "Double Plant") + .SetOpacity(0).SetState(BlockState.NONSOLID).SetTick(10); + WallBanner = new BlockInfoEx(BlockType.WALL_BANNER, "Wall Banner"); + StandingBanner = new BlockInfoEx(BlockType.STANDING_BANNER, "Standing Banner"); + + RegisterAquaticBlocks(); + RegisterModernBlocks(); + + for (int i = 0; i < MAX_BLOCKS; i++) { if (_blockTable[i] == null) { _blockTable[i] = new BlockInfo(i); } @@ -951,8 +1282,8 @@ static BlockInfo () Chest.SetTileEntity("Chest"); Furnace.SetTileEntity("Furnace"); BurningFurnace.SetTileEntity("Furnace"); - SignPost.SetTileEntity("Sign"); - WallSign.SetTileEntity("Sign"); + SignPost.SetTileEntity("minecraft:sign"); + WallSign.SetTileEntity("minecraft:sign"); EnchantmentTable.SetTileEntity("EnchantTable"); BrewingStand.SetTileEntity("Cauldron"); EndPortal.SetTileEntity("Airportal"); @@ -962,6 +1293,8 @@ static BlockInfo () TrappedChest.SetTileEntity("Chest"); Hopper.SetTileEntity("Hopper"); Dropper.SetTileEntity("Dropper"); + StandingBanner.SetTileEntity("minecraft:banner"); + WallBanner.SetTileEntity("minecraft:banner"); // Set Data Limits diff --git a/SubstrateCS/Source/BlockManager.cs b/SubstrateCS/Source/BlockManager.cs index f9c328f8..48e8c4a9 100644 --- a/SubstrateCS/Source/BlockManager.cs +++ b/SubstrateCS/Source/BlockManager.cs @@ -1,596 +1,1181 @@ -using System; -using Substrate.Core; - -namespace Substrate -{ - public class AlphaBlockManager : BlockManager - { - public AlphaBlockManager (IChunkManager cm) - : base(cm) - { - IChunk c = AlphaChunk.Create(0, 0); - - chunkXDim = c.Blocks.XDim; - chunkYDim = c.Blocks.YDim; - chunkZDim = c.Blocks.ZDim; - chunkXMask = chunkXDim - 1; - chunkYMask = chunkYDim - 1; - chunkZMask = chunkZDim - 1; - chunkXLog = Log2(chunkXDim); - chunkYLog = Log2(chunkYDim); - chunkZLog = Log2(chunkZDim); - } - } - - public class AnvilBlockManager : BlockManager - { - public AnvilBlockManager (IChunkManager cm) - : base(cm) - { - IChunk c = AnvilChunk.Create(0, 0); - - chunkXDim = c.Blocks.XDim; - chunkYDim = c.Blocks.YDim; - chunkZDim = c.Blocks.ZDim; - chunkXMask = chunkXDim - 1; - chunkYMask = chunkYDim - 1; - chunkZMask = chunkZDim - 1; - chunkXLog = Log2(chunkXDim); - chunkYLog = Log2(chunkYDim); - chunkZLog = Log2(chunkZDim); - } - } - - /// - /// Represents an Alpha-compatible interface for globally managing blocks. - /// - public abstract class BlockManager : IVersion10BlockManager, IBlockManager - { - public const int MIN_X = -32000000; - public const int MAX_X = 32000000; - public const int MIN_Y = 0; - public const int MAX_Y = 256; - public const int MIN_Z = -32000000; - public const int MAX_Z = 32000000; - - protected int chunkXDim; - protected int chunkYDim; - protected int chunkZDim; - protected int chunkXMask; - protected int chunkYMask; - protected int chunkZMask; - protected int chunkXLog; - protected int chunkYLog; - protected int chunkZLog; - - protected IChunkManager chunkMan; - - protected ChunkRef cache; - - private bool _autoLight = true; - private bool _autoFluid = false; - private bool _autoTileTick = false; - - /// - /// Gets or sets a value indicating whether changes to blocks will trigger automatic lighting updates. - /// - public bool AutoLight - { - get { return _autoLight; } - set { _autoLight = value; } - } - - /// - /// Gets or sets a value indicating whether changes to blocks will trigger automatic fluid updates. - /// - public bool AutoFluid - { - get { return _autoFluid; } - set { _autoFluid = value; } - } - - /// - /// Gets or sets a value indicating whether changes to blocks will trigger automatic fluid updates. - /// - public bool AutoTileTick - { - get { return _autoTileTick; } - set { _autoTileTick = value; } - } - - /// - /// Constructs a new instance on top of the given . - /// - /// An instance. - public BlockManager (IChunkManager cm) - { - chunkMan = cm; - } - - /// - /// Returns a new object from global coordinates. - /// - /// Global X-coordinate of block. - /// Global Y-coordinate of block. - /// Global Z-coordiante of block. - /// A new object representing context-independent data of a single block. - /// Context-independent data excludes data such as lighting. object actually contain a copy - /// of the data they represent, so changes to the will not affect this container, and vice-versa. - public AlphaBlock GetBlock (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return null; - } - - return cache.Blocks.GetBlock(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - /// Returns a new object from global coordaintes. - /// - /// Global X-coordinate of block. - /// Global Y-coordinate of block. - /// Global Z-coordinate of block. - /// A new object representing context-dependent data of a single block. - /// Context-depdendent data includes all data associated with this block. Since a represents - /// a view of a block within this container, any updates to data in the container will be reflected in the , - /// and vice-versa for updates to the . - public AlphaBlockRef GetBlockRef (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return new AlphaBlockRef(); - } - - return cache.Blocks.GetBlockRef(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - /// Updates a block with values from a object. - /// - /// Global X-coordinate of a block. - /// Global Y-coordinate of a block. - /// Global Z-coordinate of a block. - /// A object to copy block data from. - public void SetBlock (int x, int y, int z, AlphaBlock block) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetBlock(x & chunkXMask, y & chunkYMask, z & chunkZMask, block); - } - - /// - /// Gets a reference object to a single chunk given global coordinates to a block within that chunk. - /// - /// Global X-coordinate of a block. - /// Global Y-coordinate of a block. - /// Global Z-coordinate of a block. - /// A to a single chunk containing the given block. - public ChunkRef GetChunk (int x, int y, int z) - { - x >>= chunkXLog; - z >>= chunkZLog; - return chunkMan.GetChunkRef(x, z); - } - - protected int Log2 (int x) - { - int c = 0; - while (x > 1) { - x >>= 1; - c++; - } - return c; - } - - /// - /// Called by other block-specific 'get' and 'set' functions to filter - /// out operations on some blocks. Override this method in derrived - /// classes to filter the entire BlockManager. - /// - protected virtual bool Check (int x, int y, int z) - { - return (x >= MIN_X) && (x < MAX_X) && - (y >= MIN_Y) && (y < MAX_Y) && - (z >= MIN_Z) && (z < MAX_Z); - } - - #region IBlockContainer Members - - IBlock IBlockCollection.GetBlock (int x, int y, int z) - { - return GetBlock(x, y, z); - } - - IBlock IBlockCollection.GetBlockRef (int x, int y, int z) - { - return GetBlockRef(x, y, z); - } - - /// - public void SetBlock (int x, int y, int z, IBlock block) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetBlock(x, y, z, block); - } - - /// - public BlockInfo GetInfo (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return null; - } - - return cache.Blocks.GetInfo(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public int GetID (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null) { - return 0; - } - - return cache.Blocks.GetID(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void SetID (int x, int y, int z, int id) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - bool autolight = cache.Blocks.AutoLight; - bool autofluid = cache.Blocks.AutoFluid; - bool autoTileTick = cache.Blocks.AutoTileTick; - - cache.Blocks.AutoLight = _autoLight; - cache.Blocks.AutoFluid = _autoFluid; - cache.Blocks.AutoTileTick = _autoTileTick; - - cache.Blocks.SetID(x & chunkXMask, y & chunkYMask, z & chunkZMask, id); - - cache.Blocks.AutoFluid = autofluid; - cache.Blocks.AutoLight = autolight; - cache.Blocks.AutoTileTick = autoTileTick; - } - - #endregion - - - #region IDataBlockCollection Members - - IDataBlock IDataBlockCollection.GetBlock (int x, int y, int z) - { - return GetBlock(x, y, z); - } - - IDataBlock IDataBlockCollection.GetBlockRef (int x, int y, int z) - { - return GetBlockRef(x, y, z); - } - - /// - public void SetBlock (int x, int y, int z, IDataBlock block) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetBlock(x, y, z, block); - } - - /// - public int GetData (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null) { - return 0; - } - - return cache.Blocks.GetData(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void SetData (int x, int y, int z, int data) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetData(x & chunkXMask, y & chunkYMask, z & chunkZMask, data); - } - - #endregion - - - #region ILitBlockContainer Members - - ILitBlock ILitBlockCollection.GetBlock (int x, int y, int z) - { - throw new NotImplementedException(); - } - - ILitBlock ILitBlockCollection.GetBlockRef (int x, int y, int z) - { - return GetBlockRef(x, y, z); - } - - /// - public void SetBlock (int x, int y, int z, ILitBlock block) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetBlock(x, y, z, block); - } - - /// - public int GetBlockLight (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null) { - return 0; - } - - return cache.Blocks.GetBlockLight(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public int GetSkyLight (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null) { - return 0; - } - - return cache.Blocks.GetSkyLight(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void SetBlockLight (int x, int y, int z, int light) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetBlockLight(x & chunkXMask, y & chunkYMask, z & chunkZMask, light); - } - - /// - public void SetSkyLight (int x, int y, int z, int light) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetSkyLight(x & chunkXMask, y & chunkYMask, z & chunkZMask, light); - } - - /// - public int GetHeight (int x, int z) - { - cache = GetChunk(x, 0, z); - if (cache == null || !Check(x, 0, z)) { - return 0; - } - - return cache.Blocks.GetHeight(x & chunkXMask, z & chunkZMask); - } - - /// - public void SetHeight (int x, int z, int height) - { - cache = GetChunk(x, 0, z); - if (cache == null || !Check(x, 0, z)) { - return; - } - - cache.Blocks.SetHeight(x & chunkXMask, z & chunkZMask, height); - } - - /// - public void UpdateBlockLight (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.UpdateBlockLight(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void UpdateSkyLight (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.UpdateBlockLight(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - #endregion - - - #region IPropertyBlockContainer Members - - IPropertyBlock IPropertyBlockCollection.GetBlock (int x, int y, int z) - { - return GetBlock(x, y, z); - } - - IPropertyBlock IPropertyBlockCollection.GetBlockRef (int x, int y, int z) - { - return GetBlockRef(x, y, z); - } - - /// - public void SetBlock (int x, int y, int z, IPropertyBlock block) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetBlock(x, y, z, block); - } - - /// - public TileEntity GetTileEntity (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return null; - } - - return cache.Blocks.GetTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void SetTileEntity (int x, int y, int z, TileEntity te) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask, te); - } - - /// - public void CreateTileEntity (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.CreateTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void ClearTileEntity (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.ClearTileEntity(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - #endregion - - - #region IActiveBlockContainer Members - - IActiveBlock IActiveBlockCollection.GetBlock (int x, int y, int z) - { - return GetBlock(x, y, z); - } - - IActiveBlock IActiveBlockCollection.GetBlockRef (int x, int y, int z) - { - return GetBlockRef(x, y, z); - } - - /// - public void SetBlock (int x, int y, int z, IActiveBlock block) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetBlock(x, y, z, block); - } - - /// - public int GetTileTickValue (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return 0; - } - - return cache.Blocks.GetTileTickValue(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void SetTileTickValue (int x, int y, int z, int tickValue) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetTileTickValue(x & chunkXMask, y & chunkYMask, z & chunkZMask, tickValue); - } - - /// - public TileTick GetTileTick (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return null; - } - - return cache.Blocks.GetTileTick(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void SetTileTick (int x, int y, int z, TileTick te) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.SetTileTick(x & chunkXMask, y & chunkYMask, z & chunkZMask, te); - } - - /// - public void CreateTileTick (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.CreateTileTick(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - /// - public void ClearTileTick (int x, int y, int z) - { - cache = GetChunk(x, y, z); - if (cache == null || !Check(x, y, z)) { - return; - } - - cache.Blocks.ClearTileTick(x & chunkXMask, y & chunkYMask, z & chunkZMask); - } - - #endregion - } -} +using System; +using System.Text; +using Substrate.Core; +using Substrate.Nbt; + +namespace Substrate +{ + public class AlphaBlockManager : BlockManager + { + public AlphaBlockManager (IChunkManager cm) + : base(cm) + { + IChunk c = AlphaChunk.Create(0, 0); + + chunkXDim = c.Blocks.XDim; + chunkYDim = c.Blocks.YDim; + chunkZDim = c.Blocks.ZDim; + chunkXMask = chunkXDim - 1; + chunkYMask = chunkYDim - 1; + chunkZMask = chunkZDim - 1; + chunkXLog = Log2(chunkXDim); + chunkYLog = Log2(chunkYDim); + chunkZLog = Log2(chunkZDim); + } + } + + public class AnvilBlockManager : BlockManager + { + public AnvilBlockManager (IChunkManager cm) + : base(cm) + { + IChunk c = AnvilChunk.Create(0, 0); + + chunkXDim = c.Blocks.XDim; + chunkYDim = c.Blocks.YDim; + chunkZDim = c.Blocks.ZDim; + chunkXMask = chunkXDim - 1; + chunkYMask = chunkYDim - 1; + chunkZMask = chunkZDim - 1; + chunkXLog = Log2(chunkXDim); + chunkYLog = Log2(chunkYDim); + chunkZLog = Log2(chunkZDim); + } + } + + /// + /// Represents an Alpha-compatible interface for globally managing blocks. + /// + public abstract class BlockManager : IVersion10BlockManager, IBlockManager + { + public const int MIN_X = -32000000; + public const int MAX_X = 32000000; + public const int MIN_Y = 0; + public const int MAX_Y = 256; + public const int MIN_Z = -32000000; + public const int MAX_Z = 32000000; + + protected int chunkXDim; + protected int chunkYDim; + protected int chunkZDim; + protected int chunkXMask; + protected int chunkYMask; + protected int chunkZMask; + protected int chunkXLog; + protected int chunkYLog; + protected int chunkZLog; + + protected IChunkManager chunkMan; + + protected ChunkRef cache; + + private bool _autoLight = true; + private bool _autoFluid = false; + private bool _autoTileTick = false; + + /// + /// Gets or sets a value indicating whether changes to blocks will trigger automatic lighting updates. + /// + public bool AutoLight + { + get { return _autoLight; } + set { _autoLight = value; } + } + + /// + /// Gets or sets a value indicating whether changes to blocks will trigger automatic fluid updates. + /// + public bool AutoFluid + { + get { return _autoFluid; } + set { _autoFluid = value; } + } + + /// + /// Gets or sets a value indicating whether changes to blocks will trigger automatic fluid updates. + /// + public bool AutoTileTick + { + get { return _autoTileTick; } + set { _autoTileTick = value; } + } + + public int ChunkXLog { + get { + return chunkXLog; + } + } + public int ChunkYLog { + get { + return chunkYLog; + } + } + + public int ChunkZLog { + get { + return chunkZLog; + } + } + + /// + /// Constructs a new instance on top of the given . + /// + /// An instance. + public BlockManager (IChunkManager cm) + { + chunkMan = cm; + } + + /// + /// Returns a new object from global coordinates. + /// + /// Global X-coordinate of block. + /// Global Y-coordinate of block. + /// Global Z-coordiante of block. + /// A new object representing context-independent data of a single block. + /// Context-independent data excludes data such as lighting. object actually contain a copy + /// of the data they represent, so changes to the will not affect this container, and vice-versa. + public AlphaBlock GetBlock (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return null; + } + + return cache.Blocks.GetBlock(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + /// Returns a new object from global coordaintes. + /// + /// Global X-coordinate of block. + /// Global Y-coordinate of block. + /// Global Z-coordinate of block. + /// A new object representing context-dependent data of a single block. + /// Context-depdendent data includes all data associated with this block. Since a represents + /// a view of a block within this container, any updates to data in the container will be reflected in the , + /// and vice-versa for updates to the . + public AlphaBlockRef GetBlockRef (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return new AlphaBlockRef(); + } + + return cache.Blocks.GetBlockRef(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + /// Updates a block with values from a object. + /// + /// Global X-coordinate of a block. + /// Global Y-coordinate of a block. + /// Global Z-coordinate of a block. + /// A object to copy block data from. + public void SetBlock (int x, int y, int z, AlphaBlock block) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetBlock(x & chunkXMask, LocalY(y), z & chunkZMask, block); + } + + /// + /// Gets a reference object to a single chunk given global coordinates to a block within that chunk. + /// + /// Global X-coordinate of a block. + /// Global Y-coordinate of a block. + /// Global Z-coordinate of a block. + /// A to a single chunk containing the given block. + public ChunkRef GetChunk (int x, int y, int z) + { + x >>= chunkXLog; + z >>= chunkZLog; + return chunkMan.GetChunkRef(x, z); + } + + protected int Log2 (int x) + { + int c = 0; + while (x > 1) { + x >>= 1; + c++; + } + return c; + } + + /// + /// Called by other block-specific 'get' and 'set' functions to filter + /// out operations on some blocks. Override this method in derrived + /// classes to filter the entire BlockManager. + /// + protected virtual bool Check (int x, int y, int z) + { + int minimumY = cache == null ? MIN_Y : cache.MinimumY; + int maximumY = cache == null ? MAX_Y : minimumY + cache.Blocks.YDim; + return (x >= MIN_X) && (x < MAX_X) && + (y >= minimumY) && (y < maximumY) && + (z >= MIN_Z) && (z < MAX_Z); + } + + private int LocalY (int y) + { + return y - cache.MinimumY; + } + + #region IBlockContainer Members + + IBlock IBlockCollection.GetBlock (int x, int y, int z) + { + return GetBlock(x, y, z); + } + + IBlock IBlockCollection.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + /// + public void SetBlock (int x, int y, int z, IBlock block) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetBlock(x & chunkXMask, LocalY(y), z & chunkZMask, block); + } + + /// + /// Sets a block by its namespaced identifier. + /// + /// + /// Palette-backed Aquatic chunks store the name directly. Older chunks + /// convert it to the corresponding numeric ID and metadata value. + /// + public void SetBlock (int x, int y, int z, string name) + { + SetBlock(x, y, z, name, (TagNodeCompound)null); + } + + /// + /// Sets a block by its namespaced identifier and block-state + /// properties. + /// + /// + /// Palette-backed Aquatic chunks store the complete state directly. + /// Older chunks require an exact ID and metadata representation. + /// + public void SetBlock ( + int x, int y, int z, string name, TagNodeCompound properties) + { + if (name == null) + throw new ArgumentNullException("name"); + if (!BlockInfo.BlockNameTable.ContainsKey(name)) + throw new ArgumentException( + "Unknown block identifier: " + name, "name"); + + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) + return; + + int localX = x & chunkXMask; + int localZ = z & chunkZMask; + if (cache.GetBlockName(localX, y, localZ) != null) { + BlockInfo modernInfo = BlockInfo.BlockNameTable[name]; + SetID(x, y, z, modernInfo.ID); + cache = GetChunk(x, y, z); + cache.SetBlockState(localX, y, localZ, name, properties); + UpdateDerivedConnections(x, y, z); + return; + } + + int id; + int data; + BlockInfo.GetLegacyBlockState( + name, properties, out id, out data); + SetID(x, y, z, id, data); + } + + /// Sets a directional block. + public void SetBlock ( + int x, int y, int z, string name, BlockFacing facing) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Facing, facing); + SetBlock(x, y, z, name, properties); + } + + /// Sets a directional, waterloggable block. + public void SetBlock ( + int x, int y, int z, string name, + BlockFacing facing, bool waterlogged) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Facing, facing); + AddBooleanProperty( + properties, BlockProperties.Waterlogged, waterlogged); + SetBlock(x, y, z, name, properties); + } + + /// Sets a log, pillar, or other axis-oriented block. + public void SetBlock ( + int x, int y, int z, string name, BlockAxis axis) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Axis, axis); + SetBlock(x, y, z, name, properties); + } + + /// Sets a waterloggable slab. + public void SetBlock ( + int x, int y, int z, string name, + BlockSlabType type, bool waterlogged) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Type, type); + AddBooleanProperty( + properties, BlockProperties.Waterlogged, waterlogged); + SetBlock(x, y, z, name, properties); + } + + /// Sets a stair block. + public void SetBlock ( + int x, int y, int z, string name, + BlockFacing facing, BlockHalf half, + BlockStairShape shape, bool waterlogged) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Facing, facing); + AddEnumProperty(properties, BlockProperties.Half, half); + AddEnumProperty(properties, BlockProperties.Shape, shape); + AddBooleanProperty( + properties, BlockProperties.Waterlogged, waterlogged); + SetBlock(x, y, z, name, properties); + } + + /// Sets a door block. + public void SetBlock ( + int x, int y, int z, string name, + BlockFacing facing, BlockHalf half, BlockHinge hinge, + bool open, bool powered) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Facing, facing); + AddEnumProperty(properties, BlockProperties.Half, half); + AddEnumProperty(properties, BlockProperties.Hinge, hinge); + AddBooleanProperty(properties, BlockProperties.Open, open); + AddBooleanProperty(properties, BlockProperties.Powered, powered); + SetBlock(x, y, z, name, properties); + } + + /// Sets a trapdoor, button, or lever-style block. + public void SetBlock ( + int x, int y, int z, string name, + BlockFacing facing, BlockHalf half, + bool open, bool powered, bool waterlogged) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Facing, facing); + AddEnumProperty(properties, BlockProperties.Half, half); + AddBooleanProperty(properties, BlockProperties.Open, open); + AddBooleanProperty(properties, BlockProperties.Powered, powered); + AddBooleanProperty( + properties, BlockProperties.Waterlogged, waterlogged); + SetBlock(x, y, z, name, properties); + } + + /// Sets a fence gate. + public void SetBlock ( + int x, int y, int z, string name, + BlockFacing facing, bool open, bool powered, bool inWall) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Facing, facing); + AddBooleanProperty(properties, BlockProperties.Open, open); + AddBooleanProperty(properties, BlockProperties.Powered, powered); + AddBooleanProperty(properties, BlockProperties.InWall, inWall); + SetBlock(x, y, z, name, properties); + } + + /// + /// Sets a block using commonly authored block-state properties. + /// Nullable values that are not supplied are omitted from the state. + /// + public void SetBlock ( + int x, + int y, + int z, + string name, + BlockFacing? facing = null, + BlockAxis? axis = null, + BlockHalf? half = null, + BlockHinge? hinge = null, + BlockFace? face = null, + BlockSlabType? type = null, + BlockStairShape? shape = null, + BlockAttachment? attachment = null, + BlockChestType? chestType = null, + BlockBedPart? part = null, + BlockComparatorMode? mode = null, + BlockBambooLeaves? leaves = null, + BlockSculkSensorPhase? sculkSensorPhase = null, + BlockVerticalDirection? verticalDirection = null, + BlockThickness? thickness = null, + BlockTilt? tilt = null, + bool? waterlogged = null, + bool? powered = null, + bool? open = null, + bool? lit = null, + bool? attached = null, + bool? enabled = null, + bool? extended = null, + bool? occupied = null, + bool? persistent = null, + bool? snowy = null, + bool? hanging = null, + bool? inWall = null, + bool? locked = null, + bool? conditional = null, + bool? triggered = null, + bool? unstable = null, + bool? berries = null, + bool? bottom = null, + bool? up = null, + bool? down = null, + bool? north = null, + bool? east = null, + bool? south = null, + bool? west = null, + int? age = null, + int? level = null, + int? power = null, + int? rotation = null, + int? distance = null, + int? layers = null, + int? stage = null, + int? moisture = null, + int? delay = null) + { + TagNodeCompound properties = new TagNodeCompound(); + AddEnumProperty(properties, BlockProperties.Facing, facing); + AddEnumProperty(properties, BlockProperties.Axis, axis); + AddEnumProperty(properties, BlockProperties.Half, half); + AddEnumProperty(properties, BlockProperties.Hinge, hinge); + AddEnumProperty(properties, BlockProperties.Face, face); + AddEnumProperty(properties, BlockProperties.Type, type); + AddEnumProperty(properties, BlockProperties.Shape, shape); + AddEnumProperty(properties, BlockProperties.Attachment, attachment); + AddEnumProperty(properties, BlockProperties.Type, chestType); + AddEnumProperty(properties, BlockProperties.Part, part); + AddEnumProperty(properties, BlockProperties.Mode, mode); + AddEnumProperty(properties, BlockProperties.Leaves, leaves); + AddEnumProperty(properties, + BlockProperties.SculkSensorPhase, sculkSensorPhase); + AddEnumProperty(properties, + BlockProperties.VerticalDirection, verticalDirection); + AddEnumProperty(properties, BlockProperties.Thickness, thickness); + AddEnumProperty(properties, BlockProperties.Tilt, tilt); + + AddBooleanProperty(properties, BlockProperties.Waterlogged, waterlogged); + AddBooleanProperty(properties, BlockProperties.Powered, powered); + AddBooleanProperty(properties, BlockProperties.Open, open); + AddBooleanProperty(properties, BlockProperties.Lit, lit); + AddBooleanProperty(properties, BlockProperties.Attached, attached); + AddBooleanProperty(properties, BlockProperties.Enabled, enabled); + AddBooleanProperty(properties, BlockProperties.Extended, extended); + AddBooleanProperty(properties, BlockProperties.Occupied, occupied); + AddBooleanProperty(properties, BlockProperties.Persistent, persistent); + AddBooleanProperty(properties, BlockProperties.Snowy, snowy); + AddBooleanProperty(properties, BlockProperties.Hanging, hanging); + AddBooleanProperty(properties, BlockProperties.InWall, inWall); + AddBooleanProperty(properties, BlockProperties.Locked, locked); + AddBooleanProperty(properties, BlockProperties.Conditional, conditional); + AddBooleanProperty(properties, BlockProperties.Triggered, triggered); + AddBooleanProperty(properties, BlockProperties.Unstable, unstable); + AddBooleanProperty(properties, BlockProperties.Berries, berries); + AddBooleanProperty(properties, BlockProperties.Bottom, bottom); + AddBooleanProperty(properties, BlockProperties.Up, up); + AddBooleanProperty(properties, BlockProperties.Down, down); + AddBooleanProperty(properties, BlockProperties.North, north); + AddBooleanProperty(properties, BlockProperties.East, east); + AddBooleanProperty(properties, BlockProperties.South, south); + AddBooleanProperty(properties, BlockProperties.West, west); + + AddIntegerProperty(properties, BlockProperties.Age, age); + AddIntegerProperty(properties, BlockProperties.Level, level); + AddIntegerProperty(properties, BlockProperties.Power, power); + AddIntegerProperty(properties, BlockProperties.Rotation, rotation); + AddIntegerProperty(properties, BlockProperties.Distance, distance); + AddIntegerProperty(properties, BlockProperties.Layers, layers); + AddIntegerProperty(properties, BlockProperties.Stage, stage); + AddIntegerProperty(properties, BlockProperties.Moisture, moisture); + AddIntegerProperty(properties, BlockProperties.Delay, delay); + + SetBlock(x, y, z, name, properties); + } + + private static void AddBooleanProperty( + TagNodeCompound properties, string name, bool? value) + { + if (value.HasValue) + properties[name] = new TagNodeString( + value.Value ? "true" : "false"); + } + + private static void AddIntegerProperty( + TagNodeCompound properties, string name, int? value) + { + if (value.HasValue) + properties[name] = new TagNodeString( + value.Value.ToString( + System.Globalization.CultureInfo.InvariantCulture)); + } + + private static void AddEnumProperty( + TagNodeCompound properties, string name, T value) + where T : struct + { + AddEnumProperty(properties, name, new Nullable(value)); + } + + private static void AddEnumProperty( + TagNodeCompound properties, string name, T? value) + where T : struct + { + if (!value.HasValue) + return; + string source = value.Value.ToString(); + StringBuilder result = new StringBuilder(); + for (int i = 0; i < source.Length; i++) { + char c = source[i]; + if (i > 0 && Char.IsUpper(c)) + result.Append('_'); + result.Append(Char.ToLowerInvariant(c)); + } + properties[name] = new TagNodeString(result.ToString()); + } + + /// + public BlockInfo GetInfo (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return null; + } + + return cache.Blocks.GetInfo(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public int GetID (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null) { + return 0; + } + + return cache.Blocks.GetID(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void SetID (int x, int y, int z, int id) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + bool autolight = cache.Blocks.AutoLight; + bool autofluid = cache.Blocks.AutoFluid; + bool autoTileTick = cache.Blocks.AutoTileTick; + + cache.Blocks.AutoLight = _autoLight; + cache.Blocks.AutoFluid = _autoFluid; + cache.Blocks.AutoTileTick = _autoTileTick; + + cache.Blocks.SetID(x & chunkXMask, LocalY(y), z & chunkZMask, id); + + cache.Blocks.AutoFluid = autofluid; + cache.Blocks.AutoLight = autolight; + cache.Blocks.AutoTileTick = autoTileTick; + + UpdateDerivedConnections(x, y, z); + } + + /// + /// Sets a legacy numeric block ID and metadata value atomically. + /// Anvil palette chunks serialize the pair as its modern namespaced + /// block state; older chunks retain the ID and data values. + /// + public void SetID (int x, int y, int z, int id, int data) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + bool autolight = cache.Blocks.AutoLight; + bool autofluid = cache.Blocks.AutoFluid; + bool autoTileTick = cache.Blocks.AutoTileTick; + + cache.Blocks.AutoLight = _autoLight; + cache.Blocks.AutoFluid = _autoFluid; + cache.Blocks.AutoTileTick = _autoTileTick; + + cache.Blocks.SetID( + x & chunkXMask, LocalY(y), z & chunkZMask, id, data); + + cache.Blocks.AutoFluid = autofluid; + cache.Blocks.AutoLight = autolight; + cache.Blocks.AutoTileTick = autoTileTick; + + UpdateDerivedConnections(x, y, z); + } + + /// + public string GetStringID(int x, int y, int z) { + cache = GetChunk(x, y, z); + if (cache == null) { + return null; + } + + string modernName = cache.GetBlockName(x & chunkXMask, y, z & chunkZMask); + if (modernName != null) + return modernName; + BlockInfo info = cache.Blocks.GetInfo(x & chunkXMask, LocalY(y), z & chunkZMask); + return info == null ? null : info.StrID; + } + + /// Gets a copy of the modern block-state properties at global coordinates. + public TagNodeCompound GetBlockProperties (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) + return null; + + return cache.GetBlockProperties(x & chunkXMask, y, z & chunkZMask); + } + + /// Gets a modern string block-state property at global coordinates. + public string GetBlockProperty (int x, int y, int z, string property) + { + TagNodeCompound properties = GetBlockProperties(x, y, z); + TagNode value; + TagNodeString stringValue; + return properties != null + && properties.TryGetValue(property, out value) + && (stringValue = value as TagNodeString) != null + ? stringValue.Data + : null; + } + + /// + public void SetStringID(int x, int y, int z, string id) { + SetBlock(x, y, z, id); + } + + #endregion + + + #region IDataBlockCollection Members + + IDataBlock IDataBlockCollection.GetBlock (int x, int y, int z) + { + return GetBlock(x, y, z); + } + + IDataBlock IDataBlockCollection.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + /// + public void SetBlock (int x, int y, int z, IDataBlock block) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetBlock(x & chunkXMask, LocalY(y), z & chunkZMask, block); + } + + /// + public int GetData (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null) { + return 0; + } + + return cache.Blocks.GetData(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void SetData (int x, int y, int z, int data) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetData(x & chunkXMask, LocalY(y), z & chunkZMask, data); + UpdateDerivedConnections(x, y, z); + } + + private void UpdateDerivedConnections (int x, int y, int z) + { + UpdateDerivedState(x, y, z); + UpdateDerivedState(x - 1, y, z); + UpdateDerivedState(x + 1, y, z); + UpdateDerivedState(x, y, z - 1); + UpdateDerivedState(x, y, z + 1); + UpdateDerivedState(x, y - 1, z); + UpdateDerivedState(x, y + 1, z); + } + + private void UpdateDerivedState (int x, int y, int z) + { + ChunkRef blockChunk = GetChunk(x, y, z); + if (blockChunk == null) return; + int localY = y - blockChunk.MinimumY; + if (localY < 0 || localY >= blockChunk.Blocks.YDim) return; + + int localX = x & chunkXMask; + int localZ = z & chunkZMask; + int id = blockChunk.Blocks.GetID(localX, localY, localZ); + if (!HasDerivedConnections(id)) return; + + int data = blockChunk.Blocks.GetData(localX, localY, localZ); + string name; + TagNodeCompound properties; + if (!BlockInfo.TryGetLegacyBlockState(id, data, out name, out properties)) return; + if (properties == null) properties = new TagNodeCompound(); + + if (IsPaneOrBars(id)) { + SetBooleanConnection(properties, "north", PaneConnectsTo(x, y, z - 1)); + SetBooleanConnection(properties, "east", PaneConnectsTo(x + 1, y, z)); + SetBooleanConnection(properties, "south", PaneConnectsTo(x, y, z + 1)); + SetBooleanConnection(properties, "west", PaneConnectsTo(x - 1, y, z)); + } + else if (IsFence(id)) { + SetBooleanConnection(properties, "north", FenceConnectsTo(x, y, z - 1)); + SetBooleanConnection(properties, "east", FenceConnectsTo(x + 1, y, z)); + SetBooleanConnection(properties, "south", FenceConnectsTo(x, y, z + 1)); + SetBooleanConnection(properties, "west", FenceConnectsTo(x - 1, y, z)); + } + else if (id == BlockType.COBBLESTONE_WALL) { + bool north = WallConnectsTo(x, y, z - 1); + bool east = WallConnectsTo(x + 1, y, z); + bool south = WallConnectsTo(x, y, z + 1); + bool west = WallConnectsTo(x - 1, y, z); + SetWallConnection(properties, "north", north); + SetWallConnection(properties, "east", east); + SetWallConnection(properties, "south", south); + SetWallConnection(properties, "west", west); + bool straight = (north && south && !east && !west) || (east && west && !north && !south); + SetBooleanConnection(properties, "up", !straight || GetBlockIDAt(x, y + 1, z) != BlockType.AIR); + } + else if (id == BlockType.REDSTONE_WIRE) { + SetWireConnection(properties, "north", x, y, z - 1); + SetWireConnection(properties, "east", x + 1, y, z); + SetWireConnection(properties, "south", x, y, z + 1); + SetWireConnection(properties, "west", x - 1, y, z); + } + else if (id == BlockType.TRIPWIRE) { + SetBooleanConnection(properties, "north", IsTripwireConnector(GetBlockIDAt(x, y, z - 1))); + SetBooleanConnection(properties, "east", IsTripwireConnector(GetBlockIDAt(x + 1, y, z))); + SetBooleanConnection(properties, "south", IsTripwireConnector(GetBlockIDAt(x, y, z + 1))); + SetBooleanConnection(properties, "west", IsTripwireConnector(GetBlockIDAt(x - 1, y, z))); + } + else if (id == 199) { + SetBooleanConnection(properties, "north", IsChorusConnector(GetBlockIDAt(x, y, z - 1), false)); + SetBooleanConnection(properties, "east", IsChorusConnector(GetBlockIDAt(x + 1, y, z), false)); + SetBooleanConnection(properties, "south", IsChorusConnector(GetBlockIDAt(x, y, z + 1), false)); + SetBooleanConnection(properties, "west", IsChorusConnector(GetBlockIDAt(x - 1, y, z), false)); + SetBooleanConnection(properties, "up", IsChorusConnector(GetBlockIDAt(x, y + 1, z), false)); + SetBooleanConnection(properties, "down", IsChorusConnector(GetBlockIDAt(x, y - 1, z), true)); + } + blockChunk.SetBlockState(localX, y, localZ, name, properties); + } + + private bool PaneConnectsTo (int x, int y, int z) + { + ChunkRef neighbor = GetChunk(x, y, z); + if (neighbor == null) return false; + int localY = y - neighbor.MinimumY; + if (localY < 0 || localY >= neighbor.Blocks.YDim) return false; + int id = neighbor.Blocks.GetID(x & chunkXMask, localY, z & chunkZMask); + BlockInfo info = BlockInfo.BlockTable[id]; + return IsPaneOrBars(id) + || (info != null && info.State == BlockState.SOLID); + } + + private bool FenceConnectsTo (int x, int y, int z) + { + int id = GetBlockIDAt(x, y, z); + BlockInfo info = BlockInfo.BlockTable[id]; + return IsFence(id) || IsFenceGate(id) + || (info != null && info.State == BlockState.SOLID); + } + + private bool WallConnectsTo (int x, int y, int z) + { + int id = GetBlockIDAt(x, y, z); + BlockInfo info = BlockInfo.BlockTable[id]; + return id == BlockType.COBBLESTONE_WALL || IsFenceGate(id) + || (info != null && info.State == BlockState.SOLID); + } + + private void SetWireConnection (TagNodeCompound properties, string direction, int x, int y, int z) + { + int neighbor = GetBlockIDAt(x, y, z); + string value = IsRedstoneConnector(neighbor) ? "side" : "none"; + BlockInfo info = BlockInfo.BlockTable[neighbor]; + if (info != null && info.State == BlockState.SOLID + && GetBlockIDAt(x, y + 1, z) == BlockType.REDSTONE_WIRE) + value = "up"; + properties[direction] = new TagNodeString(value); + } + + private int GetBlockIDAt (int x, int y, int z) + { + ChunkRef blockChunk = GetChunk(x, y, z); + if (blockChunk == null) return BlockType.AIR; + int localY = y - blockChunk.MinimumY; + if (localY < 0 || localY >= blockChunk.Blocks.YDim) return BlockType.AIR; + return blockChunk.Blocks.GetID(x & chunkXMask, localY, z & chunkZMask); + } + + private static void SetBooleanConnection (TagNodeCompound properties, string name, bool connected) + { + properties[name] = new TagNodeString(connected ? "true" : "false"); + } + + private static void SetWallConnection (TagNodeCompound properties, string name, bool connected) + { + properties[name] = new TagNodeString(connected ? "low" : "none"); + } + + private static bool HasDerivedConnections (int id) + { + return IsPaneOrBars(id) || IsFence(id) || id == BlockType.COBBLESTONE_WALL + || id == BlockType.REDSTONE_WIRE || id == BlockType.TRIPWIRE || id == 199; + } + + private static bool IsPaneOrBars (int id) + { + return id == BlockType.GLASS_PANE || id == BlockType.STAINED_GLASS_PANE + || id == BlockType.IRON_BARS; + } + + private static bool IsFence (int id) + { + return id == BlockType.FENCE || id == BlockType.NETHER_BRICK_FENCE + || (id >= 188 && id <= 192); + } + + private static bool IsFenceGate (int id) + { + return id == BlockType.FENCE_GATE || (id >= 183 && id <= 187); + } + + private static bool IsRedstoneConnector (int id) + { + return id == BlockType.REDSTONE_WIRE || id == 69 || id == 75 || id == 76 + || id == 93 || id == 94 || id == 123 || id == 124 + || id == 149 || id == 150 || id == 151 || id == 178; + } + + private static bool IsTripwireConnector (int id) + { + return id == BlockType.TRIPWIRE || id == BlockType.TRIPWIRE_HOOK; + } + + private static bool IsChorusConnector (int id, bool allowEndStone) + { + return id == 199 || id == 200 || (allowEndStone && id == BlockType.END_STONE); + } + + #endregion + + + #region ILitBlockContainer Members + + ILitBlock ILitBlockCollection.GetBlock (int x, int y, int z) + { + throw new NotImplementedException(); + } + + ILitBlock ILitBlockCollection.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + /// + public void SetBlock (int x, int y, int z, ILitBlock block) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetBlock(x & chunkXMask, LocalY(y), z & chunkZMask, block); + } + + /// + public int GetBlockLight (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null) { + return 0; + } + + return cache.Blocks.GetBlockLight(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public int GetSkyLight (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null) { + return 0; + } + + return cache.Blocks.GetSkyLight(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void SetBlockLight (int x, int y, int z, int light) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetBlockLight(x & chunkXMask, LocalY(y), z & chunkZMask, light); + } + + /// + public void SetSkyLight (int x, int y, int z, int light) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetSkyLight(x & chunkXMask, LocalY(y), z & chunkZMask, light); + } + + /// + public int GetHeight (int x, int z) + { + cache = GetChunk(x, 0, z); + if (cache == null || !Check(x, 0, z)) { + return 0; + } + + return cache.Blocks.GetHeight(x & chunkXMask, z & chunkZMask); + } + + /// + public void SetHeight (int x, int z, int height) + { + cache = GetChunk(x, 0, z); + if (cache == null || !Check(x, 0, z)) { + return; + } + + cache.Blocks.SetHeight(x & chunkXMask, z & chunkZMask, height); + } + + /// + public void UpdateBlockLight (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.UpdateBlockLight(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void UpdateSkyLight (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.UpdateBlockLight(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + #endregion + + + #region IPropertyBlockContainer Members + + IPropertyBlock IPropertyBlockCollection.GetBlock (int x, int y, int z) + { + return GetBlock(x, y, z); + } + + IPropertyBlock IPropertyBlockCollection.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + /// + public void SetBlock (int x, int y, int z, IPropertyBlock block) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetBlock(x & chunkXMask, LocalY(y), z & chunkZMask, block); + } + + /// + public TileEntity GetTileEntity (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return null; + } + + return cache.Blocks.GetTileEntity(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void SetTileEntity (int x, int y, int z, TileEntity te) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetTileEntity(x & chunkXMask, LocalY(y), z & chunkZMask, te); + } + + /// + public void CreateTileEntity (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.CreateTileEntity(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void ClearTileEntity (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.ClearTileEntity(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + #endregion + + + #region IActiveBlockContainer Members + + IActiveBlock IActiveBlockCollection.GetBlock (int x, int y, int z) + { + return GetBlock(x, y, z); + } + + IActiveBlock IActiveBlockCollection.GetBlockRef (int x, int y, int z) + { + return GetBlockRef(x, y, z); + } + + /// + public void SetBlock (int x, int y, int z, IActiveBlock block) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetBlock(x & chunkXMask, LocalY(y), z & chunkZMask, block); + } + + /// + public int GetTileTickValue (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return 0; + } + + return cache.Blocks.GetTileTickValue(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void SetTileTickValue (int x, int y, int z, int tickValue) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetTileTickValue(x & chunkXMask, LocalY(y), z & chunkZMask, tickValue); + } + + /// + public TileTick GetTileTick (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return null; + } + + return cache.Blocks.GetTileTick(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void SetTileTick (int x, int y, int z, TileTick te) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.SetTileTick(x & chunkXMask, LocalY(y), z & chunkZMask, te); + } + + /// + public void CreateTileTick (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.CreateTileTick(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + /// + public void ClearTileTick (int x, int y, int z) + { + cache = GetChunk(x, y, z); + if (cache == null || !Check(x, y, z)) { + return; + } + + cache.Blocks.ClearTileTick(x & chunkXMask, LocalY(y), z & chunkZMask); + } + + #endregion + } +} diff --git a/SubstrateCS/Source/BlockProperties.cs b/SubstrateCS/Source/BlockProperties.cs new file mode 100644 index 00000000..bb631ede --- /dev/null +++ b/SubstrateCS/Source/BlockProperties.cs @@ -0,0 +1,126 @@ +namespace Substrate +{ + public enum BlockFacing { Down, Up, North, South, West, East } + public enum BlockAxis { X, Y, Z } + public enum BlockHalf { Top, Bottom, Upper, Lower } + public enum BlockHinge { Left, Right } + public enum BlockFace { Floor, Wall, Ceiling } + public enum BlockSlabType { Top, Bottom, Double } + public enum BlockStairShape + { + Straight, InnerLeft, InnerRight, OuterLeft, OuterRight + } + public enum BlockAttachment + { + Floor, Ceiling, SingleWall, DoubleWall + } + public enum BlockChestType { Single, Left, Right } + public enum BlockBedPart { Head, Foot } + public enum BlockComparatorMode { Compare, Subtract } + public enum BlockBambooLeaves { None, Small, Large } + public enum BlockSculkSensorPhase { Inactive, Active, Cooldown } + public enum BlockVerticalDirection { Up, Down } + public enum BlockThickness + { + Tip, TipMerge, Frustum, Middle, Base + } + public enum BlockTilt { None, Unstable, Partial, Full } + + /// Block-state property keys available in Minecraft Java Edition 26.2. + public static class BlockProperties + { + public const string Age = "age"; + public const string Attached = "attached"; + public const string Attachment = "attachment"; + public const string Axis = "axis"; + public const string Berries = "berries"; + public const string Bites = "bites"; + public const string Bloom = "bloom"; + public const string Bottom = "bottom"; + public const string CanSummon = "can_summon"; + public const string Candles = "candles"; + public const string Charges = "charges"; + public const string Conditional = "conditional"; + public const string CopperGolemPose = "copper_golem_pose"; + public const string Cracked = "cracked"; + public const string Crafting = "crafting"; + public const string CreakingHeartState = "creaking_heart_state"; + public const string Delay = "delay"; + public const string Disarmed = "disarmed"; + public const string Distance = "distance"; + public const string Down = "down"; + public const string Drag = "drag"; + public const string Dusted = "dusted"; + public const string East = "east"; + public const string Eggs = "eggs"; + public const string Enabled = "enabled"; + public const string Extended = "extended"; + public const string Eye = "eye"; + public const string Face = "face"; + public const string Facing = "facing"; + public const string FlowerAmount = "flower_amount"; + public const string Half = "half"; + public const string Hanging = "hanging"; + public const string HasBook = "has_book"; + public const string HasBottle0 = "has_bottle_0"; + public const string HasBottle1 = "has_bottle_1"; + public const string HasBottle2 = "has_bottle_2"; + public const string HasRecord = "has_record"; + public const string Hatch = "hatch"; + public const string Hinge = "hinge"; + public const string HoneyLevel = "honey_level"; + public const string Hydration = "hydration"; + public const string InWall = "in_wall"; + public const string Instrument = "instrument"; + public const string Inverted = "inverted"; + public const string Layers = "layers"; + public const string Leaves = "leaves"; + public const string Level = "level"; + public const string Lit = "lit"; + public const string Locked = "locked"; + public const string Mode = "mode"; + public const string Moisture = "moisture"; + public const string Natural = "natural"; + public const string North = "north"; + public const string Note = "note"; + public const string Occupied = "occupied"; + public const string Ominous = "ominous"; + public const string Open = "open"; + public const string Orientation = "orientation"; + public const string Part = "part"; + public const string Persistent = "persistent"; + public const string Pickles = "pickles"; + public const string PotentSulfurState = "potent_sulfur_state"; + public const string Power = "power"; + public const string Powered = "powered"; + public const string Rotation = "rotation"; + public const string SculkSensorPhase = "sculk_sensor_phase"; + public const string SegmentAmount = "segment_amount"; + public const string Shape = "shape"; + public const string Short = "short"; + public const string Shrieking = "shrieking"; + public const string SideChain = "side_chain"; + public const string SignalFire = "signal_fire"; + public const string Slot0Occupied = "slot_0_occupied"; + public const string Slot1Occupied = "slot_1_occupied"; + public const string Slot2Occupied = "slot_2_occupied"; + public const string Slot3Occupied = "slot_3_occupied"; + public const string Slot4Occupied = "slot_4_occupied"; + public const string Slot5Occupied = "slot_5_occupied"; + public const string Snowy = "snowy"; + public const string South = "south"; + public const string Stage = "stage"; + public const string Thickness = "thickness"; + public const string Tilt = "tilt"; + public const string Tip = "tip"; + public const string TrialSpawnerState = "trial_spawner_state"; + public const string Triggered = "triggered"; + public const string Type = "type"; + public const string Unstable = "unstable"; + public const string Up = "up"; + public const string VaultState = "vault_state"; + public const string VerticalDirection = "vertical_direction"; + public const string Waterlogged = "waterlogged"; + public const string West = "west"; + } +} diff --git a/SubstrateCS/Source/ChunkRef.cs b/SubstrateCS/Source/ChunkRef.cs index bb19bdc6..63cb2c06 100644 --- a/SubstrateCS/Source/ChunkRef.cs +++ b/SubstrateCS/Source/ChunkRef.cs @@ -1,7 +1,8 @@ using System; using System.IO; -using System.Collections.Generic; -using Substrate.Core; +using System.Collections.Generic; +using Substrate.Core; +using Substrate.Nbt; namespace Substrate { @@ -17,7 +18,7 @@ public class ChunkRef : IChunk private IChunk _chunk; private AlphaBlockCollection _blocks; - private AnvilBiomeCollection _biomes; + //private AnvilBiomeCollection _biomes; private EntityCollection _entities; private int _cx; @@ -60,8 +61,8 @@ public int LocalZ /// /// Gets the collection of all blocks and their data stored in the chunk. /// - public AlphaBlockCollection Blocks - { + public AlphaBlockCollection Blocks + { get { if (_blocks == null) @@ -70,11 +71,45 @@ public AlphaBlockCollection Blocks } return _blocks; } - } + } + + /// Gets the lowest world Y coordinate represented by this chunk. + public int MinimumY + { + get + { + AquaticChunk aquatic = GetChunk() as AquaticChunk; + return aquatic == null ? 0 : aquatic.MinimumY; + } + } + + /// Gets a copy of the modern block-state properties at local X/Z and world Y coordinates. + public TagNodeCompound GetBlockProperties (int x, int y, int z) + { + AquaticChunk aquatic = GetChunk() as AquaticChunk; + return aquatic == null ? null : aquatic.GetBlockProperties(x, y, z); + } + + /// Gets the namespaced block name at local X/Z and world Y coordinates. + public string GetBlockName (int x, int y, int z) + { + AquaticChunk aquatic = GetChunk() as AquaticChunk; + return aquatic == null ? null : aquatic.GetBlockName(x, y, z); + } + + /// Sets a namespaced block state at local X/Z and world Y coordinates. + public bool SetBlockState (int x, int y, int z, string name, TagNodeCompound properties) + { + AquaticChunk aquatic = GetChunk() as AquaticChunk; + if (aquatic == null) return false; + aquatic.SetBlockState(x, y, z, name, properties); + return true; + } /// /// Gets the collection of all blocks and their data stored in the chunk. /// + /* public AnvilBiomeCollection Biomes { get @@ -85,7 +120,7 @@ public AnvilBiomeCollection Biomes } return _biomes; } - } + }*/ /// /// Gets the collection of all entities stored in the chunk. @@ -288,7 +323,7 @@ private IChunk GetChunk () if (_chunk != null) { _blocks = _chunk.Blocks; - _biomes = _chunk.Biomes; + //_biomes = _chunk.Biomes; _entities = _chunk.Entities; // Set callback functions in the underlying block collection @@ -323,12 +358,14 @@ private AlphaBlockCollection ResolveNeighborHandler (int relx, int rely, int rel /// Chunk-local Y-coordinate. /// Chunk-local Z-coordinate. /// BlockKey containing the global block coordinates. - private BlockKey TranslateCoordinatesHandler (int lx, int ly, int lz) - { - int x = X * _blocks.XDim + lx; - int z = Z * _blocks.ZDim + lz; - - return new BlockKey(x, ly, z); - } + private BlockKey TranslateCoordinatesHandler (int lx, int ly, int lz) + { + int x = X * _blocks.XDim + lx; + AquaticChunk aquaticChunk = _chunk as AquaticChunk; + int y = ly + (aquaticChunk == null ? 0 : aquaticChunk.MinimumY); + int z = Z * _blocks.ZDim + lz; + + return new BlockKey(x, y, z); + } } } diff --git a/SubstrateCS/Source/Core/BlockLight.cs b/SubstrateCS/Source/Core/BlockLight.cs index 89c78b26..fa1beddd 100644 --- a/SubstrateCS/Source/Core/BlockLight.cs +++ b/SubstrateCS/Source/Core/BlockLight.cs @@ -678,7 +678,7 @@ private void QueueRelight (BlockKey key) } } - + /* private IBoundedLitBlockCollection LocalChunk (int lx, int ly, int lz) { if (ly < 0 || ly >= _ydim) { @@ -713,6 +713,7 @@ private IBoundedLitBlockCollection LocalChunk (int lx, int ly, int lz) return _blockset; } } + */ private int NeighborLight (IBoundedLitBlockCollection[,] chunkMap, int x, int y, int z) { @@ -773,7 +774,7 @@ private int NeighborSkyLight (IBoundedLitBlockCollection[,] chunkMap, int x, int return (info.Opacity > 0) ? light : light - 1; } - + /* private int NeighborHeight (int x, int z) { IBoundedLitBlockCollection src = LocalChunk(x, 0, z); @@ -786,7 +787,7 @@ private int NeighborHeight (int x, int z) return src.GetHeight(x, z); } - + */ private void TestBlockLight (IBoundedLitBlockCollection chunk, int x1, int y1, int z1, int x2, int y2, int z2) { @@ -861,7 +862,7 @@ private void TestSkyLight (IBoundedLitBlockCollection chunk, int x1, int y1, int private IBoundedLitBlockCollection OnResolveNeighbor (int relX, int relY, int relZ) { - if (ResolveNeighbor != null) { + if (ResolveNeighbor != null && relX >= 0 && relY >= 0 && relZ >= 0) { IBoundedLitBlockCollection n = ResolveNeighbor(relX, relY, relZ); if (n == null) { diff --git a/SubstrateCS/Source/Core/ChunkInterface.cs b/SubstrateCS/Source/Core/ChunkInterface.cs index fab7ee91..c875a67c 100644 --- a/SubstrateCS/Source/Core/ChunkInterface.cs +++ b/SubstrateCS/Source/Core/ChunkInterface.cs @@ -33,7 +33,7 @@ public interface IChunk /// /// Gets access to an representing all biome data of a chunk. /// - AnvilBiomeCollection Biomes { get; } + //AnvilBiomeCollection Biomes { get; } /// /// Gets or sets the flag indicating that the terrain generator has created terrain features. diff --git a/SubstrateCS/Source/Core/RegionFile.cs b/SubstrateCS/Source/Core/RegionFile.cs index 155c7860..1444f4bb 100644 --- a/SubstrateCS/Source/Core/RegionFile.cs +++ b/SubstrateCS/Source/Core/RegionFile.cs @@ -11,8 +11,10 @@ public class RegionFile : IDisposable { private static Regex _namePattern = new Regex("r\\.(-?[0-9]+)\\.(-?[0-9]+)\\.mc[ar]$"); - private const int VERSION_GZIP = 1; - private const int VERSION_DEFLATE = 2; + private const int VERSION_GZIP = 1; + private const int VERSION_DEFLATE = 2; + private const int VERSION_NONE = 3; + private const int EXTERNAL_STREAM_FLAG = 0x80; private const int SECTOR_BYTES = 4096; private const int SECTOR_INTS = SECTOR_BYTES / 4; @@ -270,20 +272,26 @@ public Stream GetChunkDataInputStream (int x, int z) return null; } - byte version = (byte)file.ReadByte(); - if (version == VERSION_GZIP) { - byte[] data = new byte[length - 1]; - file.Read(data, 0, data.Length); - Stream ret = new GZipStream(new MemoryStream(data), CompressionMode.Decompress); + byte version = (byte)file.ReadByte(); + bool external = (version & EXTERNAL_STREAM_FLAG) != 0; + version = (byte)(version & ~EXTERNAL_STREAM_FLAG); + byte[] data; + if (external) { + string externalPath = GetExternalChunkPath(x, z); + if (!File.Exists(externalPath)) return null; + data = File.ReadAllBytes(externalPath); + } else { + data = new byte[length - 1]; + file.Read(data, 0, data.Length); + } + if (version == VERSION_GZIP) { + Stream ret = new GZipStream(new MemoryStream(data), CompressionMode.Decompress); return ret; } - else if (version == VERSION_DEFLATE) { - byte[] data = new byte[length - 1]; - file.Read(data, 0, data.Length); - - Stream ret = new ZlibStream(new MemoryStream(data), CompressionMode.Decompress, true); - return ret; + else if (version == VERSION_DEFLATE) { + Stream ret = new ZlibStream(new MemoryStream(data), CompressionMode.Decompress, true); + return ret; /*MemoryStream sinkZ = new MemoryStream(); ZlibStream zOut = new ZlibStream(sinkZ, CompressionMode.Decompress, true); @@ -293,7 +301,7 @@ public Stream GetChunkDataInputStream (int x, int z) sinkZ.Seek(0, SeekOrigin.Begin); return sinkZ;*/ - } + } else if (version == VERSION_NONE) return new MemoryStream(data, false); Debugln("READ", x, z, "unknown version " + version); return null; @@ -373,10 +381,11 @@ protected void Write (int x, int z, byte[] data, int length, int timestamp) int sectorsAllocated = offset & 0xFF; int sectorsNeeded = (length + CHUNK_HEADER_SIZE) / SectorBytes + 1; - // maximum chunk size is 1MB - if (sectorsNeeded >= 256) { - return; - } + // Oversized chunks use the external .mcc stream format. + if (sectorsNeeded >= 256) { + WriteExternal(x, z, data, length, timestamp); + return; + } if (sectorNumber != 0 && sectorsAllocated == sectorsNeeded) { /* we can simply overwrite the old sectors */ @@ -440,12 +449,39 @@ protected void Write (int x, int z, byte[] data, int length, int timestamp) } } } - SetTimestamp(x, z, timestamp); + SetTimestamp(x, z, timestamp); + string externalPath = GetExternalChunkPath(x, z); + if (File.Exists(externalPath)) File.Delete(externalPath); } catch (IOException e) { Console.WriteLine(e.StackTrace); } - } + } + + private void WriteExternal(int x, int z, byte[] data, int length, int timestamp) + { + // Allocate the single region sector containing the external-stream marker. + Write(x, z, new byte[0], 0, timestamp); + int sectorNumber = GetOffset(x, z) >> 8; + lock (fileLock) { + file.Seek(sectorNumber * SectorBytes, SeekOrigin.Begin); + byte[] lengthBytes = BitConverter.GetBytes(1); + if (BitConverter.IsLittleEndian) Array.Reverse(lengthBytes); + file.Write(lengthBytes, 0, lengthBytes.Length); + file.WriteByte(VERSION_DEFLATE | EXTERNAL_STREAM_FLAG); + } + byte[] externalData = new byte[length]; + Array.Copy(data, externalData, length); + File.WriteAllBytes(GetExternalChunkPath(x, z), externalData); + } + + private string GetExternalChunkPath(int x, int z) + { + RegionKey region = parseCoordinatesFromName(); + int globalX = region.X * 32 + x; + int globalZ = region.Z * 32 + z; + return Path.Combine(Path.GetDirectoryName(fileName), "c." + globalX + "." + globalZ + ".mcc"); + } /* write a chunk data to the region file at specified sector number */ private void Write (int sectorNumber, byte[] data, int length) diff --git a/SubstrateCS/Source/Core/UnboundedBlockInterface.cs b/SubstrateCS/Source/Core/UnboundedBlockInterface.cs index a7c8b5f0..95a01318 100644 --- a/SubstrateCS/Source/Core/UnboundedBlockInterface.cs +++ b/SubstrateCS/Source/Core/UnboundedBlockInterface.cs @@ -55,6 +55,24 @@ public interface IBlockCollection /// The id (type) to assign to a block at the given coordinates. void SetID (int x, int y, int z, int id); + /// + /// Gets a block's id (type) from an unbounded block container. + /// + /// The global X-coordinate of a block. + /// The global Y-coordinate of a block. + /// The global Z-coordinate of a block. + /// The block id (type) from the block container at the given coordinates. + string GetStringID(int x, int y, int z); + + /// + /// Sets a block's id (type) within an unbounded block container. + /// + /// The global X-coordinate of a block. + /// The global Y-coordinate of a block. + /// The global Z-coordinate of a block. + /// The id (type) to assign to a block at the given coordinates. + void SetStringID(int x, int y, int z, string id); + /// /// Gets info and attributes on a block's type within an unbounded block container. /// diff --git a/SubstrateCS/Source/Core/YZXShortDataArray.cs b/SubstrateCS/Source/Core/YZXShortDataArray.cs new file mode 100644 index 00000000..d32891f3 --- /dev/null +++ b/SubstrateCS/Source/Core/YZXShortDataArray.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Substrate.Core +{ + public class YZXShortDataArray : IDataArray3 + { + private readonly short[,,] _dataArray; + public YZXShortDataArray(short[,,] dataArray) + { + _dataArray = dataArray; + } + + public int this[int x, int y, int z] + { + get { return _dataArray[y, z, x]; } + set + { + _dataArray[y, z, x] = (short)value; + } + } + + public int XDim + { + get { return _dataArray.GetLength(2); } + } + + public int YDim + { + get { return _dataArray.GetLength(0); } + } + + public int ZDim + { + get { return _dataArray.GetLength(1); } + } + + public int GetIndex (int x, int y, int z) + { + return XDim * (y * ZDim + z) + x; + } + + public void GetMultiIndex (int index, out int x, out int y, out int z) + { + int xzdim = XDim * ZDim; + y = index / xzdim; + + int zx = index - (y * xzdim); + z = zx / XDim; + x = zx - (z * XDim); + } + + public int this[int i] + { + get { + int x, y, z; + GetMultiIndex(i, out x, out y, out z); + return _dataArray[y, z, x]; + } + set + { + int x, y, z; + GetMultiIndex(i, out x, out y, out z); + _dataArray[y, z, x] = (short)value; + } + } + + public int Length + { + get { return XDim * YDim * ZDim; } + } + + public int DataWidth + { + get { return 16; } + } + + public void Clear () + { + for (int y = 0; y < YDim; y++) { + for (int z = 0; z < ZDim; z++) { + for (int x = 0; x < XDim; x++) { + _dataArray[y, z, x] = 0; + } + } + } + } + } +} diff --git a/SubstrateCS/Source/Data.cs b/SubstrateCS/Source/Data.cs index 4314a472..09420766 100644 --- a/SubstrateCS/Source/Data.cs +++ b/SubstrateCS/Source/Data.cs @@ -12,6 +12,7 @@ public enum WoodType OAK = 0, SPRUCE = 1, BIRCH = 2, + JUNGLE = 3, } public enum LeafType @@ -217,6 +218,16 @@ public enum WallSignOrientation SOUTH = 5, } + public enum StoneType { + STONE = 0, + GRANITE = 1, + POLISHED_GRANITE = 2, + DIORITE = 3, + POLISHED_DORITE = 4, + ANDESITE = 5, + POLISHED_ANDESITE = 6 + } + public enum FurnaceOrientation { EAST = 2, @@ -247,6 +258,8 @@ public enum SlabType COBBLESTONE = 3, BRICK = 4, STONE_BRICK = 5, + NETHER_BRICK = 6, + QUARTZ = 7 } [Flags] @@ -343,6 +356,7 @@ public enum StoneBrickType NORMAL = 0, MOSSY = 1, CRACKED = 2, + CHISELED = 3, } public enum HugeMushroomType diff --git a/SubstrateCS/Source/Data/BlockRegistry-26.2.txt b/SubstrateCS/Source/Data/BlockRegistry-26.2.txt new file mode 100644 index 00000000..0941ee54 --- /dev/null +++ b/SubstrateCS/Source/Data/BlockRegistry-26.2.txt @@ -0,0 +1,1196 @@ +minecraft:acacia_button +minecraft:acacia_door +minecraft:acacia_fence +minecraft:acacia_fence_gate +minecraft:acacia_hanging_sign +minecraft:acacia_leaves +minecraft:acacia_log +minecraft:acacia_planks +minecraft:acacia_pressure_plate +minecraft:acacia_sapling +minecraft:acacia_shelf +minecraft:acacia_sign +minecraft:acacia_slab +minecraft:acacia_stairs +minecraft:acacia_trapdoor +minecraft:acacia_wall_hanging_sign +minecraft:acacia_wall_sign +minecraft:acacia_wood +minecraft:activator_rail +minecraft:air +minecraft:allium +minecraft:amethyst_block +minecraft:amethyst_cluster +minecraft:ancient_debris +minecraft:andesite +minecraft:andesite_slab +minecraft:andesite_stairs +minecraft:andesite_wall +minecraft:anvil +minecraft:attached_melon_stem +minecraft:attached_pumpkin_stem +minecraft:azalea +minecraft:azalea_leaves +minecraft:azure_bluet +minecraft:bamboo +minecraft:bamboo_block +minecraft:bamboo_button +minecraft:bamboo_door +minecraft:bamboo_fence +minecraft:bamboo_fence_gate +minecraft:bamboo_hanging_sign +minecraft:bamboo_mosaic +minecraft:bamboo_mosaic_slab +minecraft:bamboo_mosaic_stairs +minecraft:bamboo_planks +minecraft:bamboo_pressure_plate +minecraft:bamboo_sapling +minecraft:bamboo_shelf +minecraft:bamboo_sign +minecraft:bamboo_slab +minecraft:bamboo_stairs +minecraft:bamboo_trapdoor +minecraft:bamboo_wall_hanging_sign +minecraft:bamboo_wall_sign +minecraft:barrel +minecraft:barrier +minecraft:basalt +minecraft:beacon +minecraft:bedrock +minecraft:bee_nest +minecraft:beehive +minecraft:beetroots +minecraft:bell +minecraft:big_dripleaf +minecraft:big_dripleaf_stem +minecraft:birch_button +minecraft:birch_door +minecraft:birch_fence +minecraft:birch_fence_gate +minecraft:birch_hanging_sign +minecraft:birch_leaves +minecraft:birch_log +minecraft:birch_planks +minecraft:birch_pressure_plate +minecraft:birch_sapling +minecraft:birch_shelf +minecraft:birch_sign +minecraft:birch_slab +minecraft:birch_stairs +minecraft:birch_trapdoor +minecraft:birch_wall_hanging_sign +minecraft:birch_wall_sign +minecraft:birch_wood +minecraft:black_banner +minecraft:black_bed +minecraft:black_candle +minecraft:black_candle_cake +minecraft:black_carpet +minecraft:black_concrete +minecraft:black_concrete_powder +minecraft:black_glazed_terracotta +minecraft:black_shulker_box +minecraft:black_stained_glass +minecraft:black_stained_glass_pane +minecraft:black_terracotta +minecraft:black_wall_banner +minecraft:black_wool +minecraft:blackstone +minecraft:blackstone_slab +minecraft:blackstone_stairs +minecraft:blackstone_wall +minecraft:blast_furnace +minecraft:blue_banner +minecraft:blue_bed +minecraft:blue_candle +minecraft:blue_candle_cake +minecraft:blue_carpet +minecraft:blue_concrete +minecraft:blue_concrete_powder +minecraft:blue_glazed_terracotta +minecraft:blue_ice +minecraft:blue_orchid +minecraft:blue_shulker_box +minecraft:blue_stained_glass +minecraft:blue_stained_glass_pane +minecraft:blue_terracotta +minecraft:blue_wall_banner +minecraft:blue_wool +minecraft:bone_block +minecraft:bookshelf +minecraft:brain_coral +minecraft:brain_coral_block +minecraft:brain_coral_fan +minecraft:brain_coral_wall_fan +minecraft:brewing_stand +minecraft:brick_slab +minecraft:brick_stairs +minecraft:brick_wall +minecraft:bricks +minecraft:brown_banner +minecraft:brown_bed +minecraft:brown_candle +minecraft:brown_candle_cake +minecraft:brown_carpet +minecraft:brown_concrete +minecraft:brown_concrete_powder +minecraft:brown_glazed_terracotta +minecraft:brown_mushroom +minecraft:brown_mushroom_block +minecraft:brown_shulker_box +minecraft:brown_stained_glass +minecraft:brown_stained_glass_pane +minecraft:brown_terracotta +minecraft:brown_wall_banner +minecraft:brown_wool +minecraft:bubble_column +minecraft:bubble_coral +minecraft:bubble_coral_block +minecraft:bubble_coral_fan +minecraft:bubble_coral_wall_fan +minecraft:budding_amethyst +minecraft:bush +minecraft:cactus +minecraft:cactus_flower +minecraft:cake +minecraft:calcite +minecraft:calibrated_sculk_sensor +minecraft:campfire +minecraft:candle +minecraft:candle_cake +minecraft:carrots +minecraft:cartography_table +minecraft:carved_pumpkin +minecraft:cauldron +minecraft:cave_air +minecraft:cave_vines +minecraft:cave_vines_plant +minecraft:chain_command_block +minecraft:cherry_button +minecraft:cherry_door +minecraft:cherry_fence +minecraft:cherry_fence_gate +minecraft:cherry_hanging_sign +minecraft:cherry_leaves +minecraft:cherry_log +minecraft:cherry_planks +minecraft:cherry_pressure_plate +minecraft:cherry_sapling +minecraft:cherry_shelf +minecraft:cherry_sign +minecraft:cherry_slab +minecraft:cherry_stairs +minecraft:cherry_trapdoor +minecraft:cherry_wall_hanging_sign +minecraft:cherry_wall_sign +minecraft:cherry_wood +minecraft:chest +minecraft:chipped_anvil +minecraft:chiseled_bookshelf +minecraft:chiseled_cinnabar +minecraft:chiseled_copper +minecraft:chiseled_deepslate +minecraft:chiseled_nether_bricks +minecraft:chiseled_polished_blackstone +minecraft:chiseled_quartz_block +minecraft:chiseled_red_sandstone +minecraft:chiseled_resin_bricks +minecraft:chiseled_sandstone +minecraft:chiseled_stone_bricks +minecraft:chiseled_sulfur +minecraft:chiseled_tuff +minecraft:chiseled_tuff_bricks +minecraft:chorus_flower +minecraft:chorus_plant +minecraft:cinnabar +minecraft:cinnabar_brick_slab +minecraft:cinnabar_brick_stairs +minecraft:cinnabar_brick_wall +minecraft:cinnabar_bricks +minecraft:cinnabar_slab +minecraft:cinnabar_stairs +minecraft:cinnabar_wall +minecraft:clay +minecraft:closed_eyeblossom +minecraft:coal_block +minecraft:coal_ore +minecraft:coarse_dirt +minecraft:cobbled_deepslate +minecraft:cobbled_deepslate_slab +minecraft:cobbled_deepslate_stairs +minecraft:cobbled_deepslate_wall +minecraft:cobblestone +minecraft:cobblestone_slab +minecraft:cobblestone_stairs +minecraft:cobblestone_wall +minecraft:cobweb +minecraft:cocoa +minecraft:command_block +minecraft:comparator +minecraft:composter +minecraft:conduit +minecraft:copper_bars +minecraft:copper_block +minecraft:copper_bulb +minecraft:copper_chain +minecraft:copper_chest +minecraft:copper_door +minecraft:copper_golem_statue +minecraft:copper_grate +minecraft:copper_lantern +minecraft:copper_ore +minecraft:copper_torch +minecraft:copper_trapdoor +minecraft:copper_wall_torch +minecraft:cornflower +minecraft:cracked_deepslate_bricks +minecraft:cracked_deepslate_tiles +minecraft:cracked_nether_bricks +minecraft:cracked_polished_blackstone_bricks +minecraft:cracked_stone_bricks +minecraft:crafter +minecraft:crafting_table +minecraft:creaking_heart +minecraft:creeper_head +minecraft:creeper_wall_head +minecraft:crimson_button +minecraft:crimson_door +minecraft:crimson_fence +minecraft:crimson_fence_gate +minecraft:crimson_fungus +minecraft:crimson_hanging_sign +minecraft:crimson_hyphae +minecraft:crimson_nylium +minecraft:crimson_planks +minecraft:crimson_pressure_plate +minecraft:crimson_roots +minecraft:crimson_shelf +minecraft:crimson_sign +minecraft:crimson_slab +minecraft:crimson_stairs +minecraft:crimson_stem +minecraft:crimson_trapdoor +minecraft:crimson_wall_hanging_sign +minecraft:crimson_wall_sign +minecraft:crying_obsidian +minecraft:cut_copper +minecraft:cut_copper_slab +minecraft:cut_copper_stairs +minecraft:cut_red_sandstone +minecraft:cut_red_sandstone_slab +minecraft:cut_sandstone +minecraft:cut_sandstone_slab +minecraft:cyan_banner +minecraft:cyan_bed +minecraft:cyan_candle +minecraft:cyan_candle_cake +minecraft:cyan_carpet +minecraft:cyan_concrete +minecraft:cyan_concrete_powder +minecraft:cyan_glazed_terracotta +minecraft:cyan_shulker_box +minecraft:cyan_stained_glass +minecraft:cyan_stained_glass_pane +minecraft:cyan_terracotta +minecraft:cyan_wall_banner +minecraft:cyan_wool +minecraft:damaged_anvil +minecraft:dandelion +minecraft:dark_oak_button +minecraft:dark_oak_door +minecraft:dark_oak_fence +minecraft:dark_oak_fence_gate +minecraft:dark_oak_hanging_sign +minecraft:dark_oak_leaves +minecraft:dark_oak_log +minecraft:dark_oak_planks +minecraft:dark_oak_pressure_plate +minecraft:dark_oak_sapling +minecraft:dark_oak_shelf +minecraft:dark_oak_sign +minecraft:dark_oak_slab +minecraft:dark_oak_stairs +minecraft:dark_oak_trapdoor +minecraft:dark_oak_wall_hanging_sign +minecraft:dark_oak_wall_sign +minecraft:dark_oak_wood +minecraft:dark_prismarine +minecraft:dark_prismarine_slab +minecraft:dark_prismarine_stairs +minecraft:daylight_detector +minecraft:dead_brain_coral +minecraft:dead_brain_coral_block +minecraft:dead_brain_coral_fan +minecraft:dead_brain_coral_wall_fan +minecraft:dead_bubble_coral +minecraft:dead_bubble_coral_block +minecraft:dead_bubble_coral_fan +minecraft:dead_bubble_coral_wall_fan +minecraft:dead_bush +minecraft:dead_fire_coral +minecraft:dead_fire_coral_block +minecraft:dead_fire_coral_fan +minecraft:dead_fire_coral_wall_fan +minecraft:dead_horn_coral +minecraft:dead_horn_coral_block +minecraft:dead_horn_coral_fan +minecraft:dead_horn_coral_wall_fan +minecraft:dead_tube_coral +minecraft:dead_tube_coral_block +minecraft:dead_tube_coral_fan +minecraft:dead_tube_coral_wall_fan +minecraft:decorated_pot +minecraft:deepslate +minecraft:deepslate_brick_slab +minecraft:deepslate_brick_stairs +minecraft:deepslate_brick_wall +minecraft:deepslate_bricks +minecraft:deepslate_coal_ore +minecraft:deepslate_copper_ore +minecraft:deepslate_diamond_ore +minecraft:deepslate_emerald_ore +minecraft:deepslate_gold_ore +minecraft:deepslate_iron_ore +minecraft:deepslate_lapis_ore +minecraft:deepslate_redstone_ore +minecraft:deepslate_tile_slab +minecraft:deepslate_tile_stairs +minecraft:deepslate_tile_wall +minecraft:deepslate_tiles +minecraft:detector_rail +minecraft:diamond_block +minecraft:diamond_ore +minecraft:diorite +minecraft:diorite_slab +minecraft:diorite_stairs +minecraft:diorite_wall +minecraft:dirt +minecraft:dirt_path +minecraft:dispenser +minecraft:dragon_egg +minecraft:dragon_head +minecraft:dragon_wall_head +minecraft:dried_ghast +minecraft:dried_kelp_block +minecraft:dripstone_block +minecraft:dropper +minecraft:emerald_block +minecraft:emerald_ore +minecraft:enchanting_table +minecraft:end_gateway +minecraft:end_portal +minecraft:end_portal_frame +minecraft:end_rod +minecraft:end_stone +minecraft:end_stone_brick_slab +minecraft:end_stone_brick_stairs +minecraft:end_stone_brick_wall +minecraft:end_stone_bricks +minecraft:ender_chest +minecraft:exposed_chiseled_copper +minecraft:exposed_copper +minecraft:exposed_copper_bars +minecraft:exposed_copper_bulb +minecraft:exposed_copper_chain +minecraft:exposed_copper_chest +minecraft:exposed_copper_door +minecraft:exposed_copper_golem_statue +minecraft:exposed_copper_grate +minecraft:exposed_copper_lantern +minecraft:exposed_copper_trapdoor +minecraft:exposed_cut_copper +minecraft:exposed_cut_copper_slab +minecraft:exposed_cut_copper_stairs +minecraft:exposed_lightning_rod +minecraft:farmland +minecraft:fern +minecraft:fire +minecraft:fire_coral +minecraft:fire_coral_block +minecraft:fire_coral_fan +minecraft:fire_coral_wall_fan +minecraft:firefly_bush +minecraft:fletching_table +minecraft:flower_pot +minecraft:flowering_azalea +minecraft:flowering_azalea_leaves +minecraft:frogspawn +minecraft:frosted_ice +minecraft:furnace +minecraft:gilded_blackstone +minecraft:glass +minecraft:glass_pane +minecraft:glow_lichen +minecraft:glowstone +minecraft:gold_block +minecraft:gold_ore +minecraft:golden_dandelion +minecraft:granite +minecraft:granite_slab +minecraft:granite_stairs +minecraft:granite_wall +minecraft:grass_block +minecraft:gravel +minecraft:gray_banner +minecraft:gray_bed +minecraft:gray_candle +minecraft:gray_candle_cake +minecraft:gray_carpet +minecraft:gray_concrete +minecraft:gray_concrete_powder +minecraft:gray_glazed_terracotta +minecraft:gray_shulker_box +minecraft:gray_stained_glass +minecraft:gray_stained_glass_pane +minecraft:gray_terracotta +minecraft:gray_wall_banner +minecraft:gray_wool +minecraft:green_banner +minecraft:green_bed +minecraft:green_candle +minecraft:green_candle_cake +minecraft:green_carpet +minecraft:green_concrete +minecraft:green_concrete_powder +minecraft:green_glazed_terracotta +minecraft:green_shulker_box +minecraft:green_stained_glass +minecraft:green_stained_glass_pane +minecraft:green_terracotta +minecraft:green_wall_banner +minecraft:green_wool +minecraft:grindstone +minecraft:hanging_roots +minecraft:hay_block +minecraft:heavy_core +minecraft:heavy_weighted_pressure_plate +minecraft:honey_block +minecraft:honeycomb_block +minecraft:hopper +minecraft:horn_coral +minecraft:horn_coral_block +minecraft:horn_coral_fan +minecraft:horn_coral_wall_fan +minecraft:ice +minecraft:infested_chiseled_stone_bricks +minecraft:infested_cobblestone +minecraft:infested_cracked_stone_bricks +minecraft:infested_deepslate +minecraft:infested_mossy_stone_bricks +minecraft:infested_stone +minecraft:infested_stone_bricks +minecraft:iron_bars +minecraft:iron_block +minecraft:iron_chain +minecraft:iron_door +minecraft:iron_ore +minecraft:iron_trapdoor +minecraft:jack_o_lantern +minecraft:jigsaw +minecraft:jukebox +minecraft:jungle_button +minecraft:jungle_door +minecraft:jungle_fence +minecraft:jungle_fence_gate +minecraft:jungle_hanging_sign +minecraft:jungle_leaves +minecraft:jungle_log +minecraft:jungle_planks +minecraft:jungle_pressure_plate +minecraft:jungle_sapling +minecraft:jungle_shelf +minecraft:jungle_sign +minecraft:jungle_slab +minecraft:jungle_stairs +minecraft:jungle_trapdoor +minecraft:jungle_wall_hanging_sign +minecraft:jungle_wall_sign +minecraft:jungle_wood +minecraft:kelp +minecraft:kelp_plant +minecraft:ladder +minecraft:lantern +minecraft:lapis_block +minecraft:lapis_ore +minecraft:large_amethyst_bud +minecraft:large_fern +minecraft:lava +minecraft:lava_cauldron +minecraft:leaf_litter +minecraft:lectern +minecraft:lever +minecraft:light +minecraft:light_blue_banner +minecraft:light_blue_bed +minecraft:light_blue_candle +minecraft:light_blue_candle_cake +minecraft:light_blue_carpet +minecraft:light_blue_concrete +minecraft:light_blue_concrete_powder +minecraft:light_blue_glazed_terracotta +minecraft:light_blue_shulker_box +minecraft:light_blue_stained_glass +minecraft:light_blue_stained_glass_pane +minecraft:light_blue_terracotta +minecraft:light_blue_wall_banner +minecraft:light_blue_wool +minecraft:light_gray_banner +minecraft:light_gray_bed +minecraft:light_gray_candle +minecraft:light_gray_candle_cake +minecraft:light_gray_carpet +minecraft:light_gray_concrete +minecraft:light_gray_concrete_powder +minecraft:light_gray_glazed_terracotta +minecraft:light_gray_shulker_box +minecraft:light_gray_stained_glass +minecraft:light_gray_stained_glass_pane +minecraft:light_gray_terracotta +minecraft:light_gray_wall_banner +minecraft:light_gray_wool +minecraft:light_weighted_pressure_plate +minecraft:lightning_rod +minecraft:lilac +minecraft:lily_of_the_valley +minecraft:lily_pad +minecraft:lime_banner +minecraft:lime_bed +minecraft:lime_candle +minecraft:lime_candle_cake +minecraft:lime_carpet +minecraft:lime_concrete +minecraft:lime_concrete_powder +minecraft:lime_glazed_terracotta +minecraft:lime_shulker_box +minecraft:lime_stained_glass +minecraft:lime_stained_glass_pane +minecraft:lime_terracotta +minecraft:lime_wall_banner +minecraft:lime_wool +minecraft:lodestone +minecraft:loom +minecraft:magenta_banner +minecraft:magenta_bed +minecraft:magenta_candle +minecraft:magenta_candle_cake +minecraft:magenta_carpet +minecraft:magenta_concrete +minecraft:magenta_concrete_powder +minecraft:magenta_glazed_terracotta +minecraft:magenta_shulker_box +minecraft:magenta_stained_glass +minecraft:magenta_stained_glass_pane +minecraft:magenta_terracotta +minecraft:magenta_wall_banner +minecraft:magenta_wool +minecraft:magma_block +minecraft:mangrove_button +minecraft:mangrove_door +minecraft:mangrove_fence +minecraft:mangrove_fence_gate +minecraft:mangrove_hanging_sign +minecraft:mangrove_leaves +minecraft:mangrove_log +minecraft:mangrove_planks +minecraft:mangrove_pressure_plate +minecraft:mangrove_propagule +minecraft:mangrove_roots +minecraft:mangrove_shelf +minecraft:mangrove_sign +minecraft:mangrove_slab +minecraft:mangrove_stairs +minecraft:mangrove_trapdoor +minecraft:mangrove_wall_hanging_sign +minecraft:mangrove_wall_sign +minecraft:mangrove_wood +minecraft:medium_amethyst_bud +minecraft:melon +minecraft:melon_stem +minecraft:moss_block +minecraft:moss_carpet +minecraft:mossy_cobblestone +minecraft:mossy_cobblestone_slab +minecraft:mossy_cobblestone_stairs +minecraft:mossy_cobblestone_wall +minecraft:mossy_stone_brick_slab +minecraft:mossy_stone_brick_stairs +minecraft:mossy_stone_brick_wall +minecraft:mossy_stone_bricks +minecraft:moving_piston +minecraft:mud +minecraft:mud_brick_slab +minecraft:mud_brick_stairs +minecraft:mud_brick_wall +minecraft:mud_bricks +minecraft:muddy_mangrove_roots +minecraft:mushroom_stem +minecraft:mycelium +minecraft:nether_brick_fence +minecraft:nether_brick_slab +minecraft:nether_brick_stairs +minecraft:nether_brick_wall +minecraft:nether_bricks +minecraft:nether_gold_ore +minecraft:nether_portal +minecraft:nether_quartz_ore +minecraft:nether_sprouts +minecraft:nether_wart +minecraft:nether_wart_block +minecraft:netherite_block +minecraft:netherrack +minecraft:note_block +minecraft:oak_button +minecraft:oak_door +minecraft:oak_fence +minecraft:oak_fence_gate +minecraft:oak_hanging_sign +minecraft:oak_leaves +minecraft:oak_log +minecraft:oak_planks +minecraft:oak_pressure_plate +minecraft:oak_sapling +minecraft:oak_shelf +minecraft:oak_sign +minecraft:oak_slab +minecraft:oak_stairs +minecraft:oak_trapdoor +minecraft:oak_wall_hanging_sign +minecraft:oak_wall_sign +minecraft:oak_wood +minecraft:observer +minecraft:obsidian +minecraft:ochre_froglight +minecraft:open_eyeblossom +minecraft:orange_banner +minecraft:orange_bed +minecraft:orange_candle +minecraft:orange_candle_cake +minecraft:orange_carpet +minecraft:orange_concrete +minecraft:orange_concrete_powder +minecraft:orange_glazed_terracotta +minecraft:orange_shulker_box +minecraft:orange_stained_glass +minecraft:orange_stained_glass_pane +minecraft:orange_terracotta +minecraft:orange_tulip +minecraft:orange_wall_banner +minecraft:orange_wool +minecraft:oxeye_daisy +minecraft:oxidized_chiseled_copper +minecraft:oxidized_copper +minecraft:oxidized_copper_bars +minecraft:oxidized_copper_bulb +minecraft:oxidized_copper_chain +minecraft:oxidized_copper_chest +minecraft:oxidized_copper_door +minecraft:oxidized_copper_golem_statue +minecraft:oxidized_copper_grate +minecraft:oxidized_copper_lantern +minecraft:oxidized_copper_trapdoor +minecraft:oxidized_cut_copper +minecraft:oxidized_cut_copper_slab +minecraft:oxidized_cut_copper_stairs +minecraft:oxidized_lightning_rod +minecraft:packed_ice +minecraft:packed_mud +minecraft:pale_hanging_moss +minecraft:pale_moss_block +minecraft:pale_moss_carpet +minecraft:pale_oak_button +minecraft:pale_oak_door +minecraft:pale_oak_fence +minecraft:pale_oak_fence_gate +minecraft:pale_oak_hanging_sign +minecraft:pale_oak_leaves +minecraft:pale_oak_log +minecraft:pale_oak_planks +minecraft:pale_oak_pressure_plate +minecraft:pale_oak_sapling +minecraft:pale_oak_shelf +minecraft:pale_oak_sign +minecraft:pale_oak_slab +minecraft:pale_oak_stairs +minecraft:pale_oak_trapdoor +minecraft:pale_oak_wall_hanging_sign +minecraft:pale_oak_wall_sign +minecraft:pale_oak_wood +minecraft:pearlescent_froglight +minecraft:peony +minecraft:petrified_oak_slab +minecraft:piglin_head +minecraft:piglin_wall_head +minecraft:pink_banner +minecraft:pink_bed +minecraft:pink_candle +minecraft:pink_candle_cake +minecraft:pink_carpet +minecraft:pink_concrete +minecraft:pink_concrete_powder +minecraft:pink_glazed_terracotta +minecraft:pink_petals +minecraft:pink_shulker_box +minecraft:pink_stained_glass +minecraft:pink_stained_glass_pane +minecraft:pink_terracotta +minecraft:pink_tulip +minecraft:pink_wall_banner +minecraft:pink_wool +minecraft:piston +minecraft:piston_head +minecraft:pitcher_crop +minecraft:pitcher_plant +minecraft:player_head +minecraft:player_wall_head +minecraft:podzol +minecraft:pointed_dripstone +minecraft:polished_andesite +minecraft:polished_andesite_slab +minecraft:polished_andesite_stairs +minecraft:polished_basalt +minecraft:polished_blackstone +minecraft:polished_blackstone_brick_slab +minecraft:polished_blackstone_brick_stairs +minecraft:polished_blackstone_brick_wall +minecraft:polished_blackstone_bricks +minecraft:polished_blackstone_button +minecraft:polished_blackstone_pressure_plate +minecraft:polished_blackstone_slab +minecraft:polished_blackstone_stairs +minecraft:polished_blackstone_wall +minecraft:polished_cinnabar +minecraft:polished_cinnabar_slab +minecraft:polished_cinnabar_stairs +minecraft:polished_cinnabar_wall +minecraft:polished_deepslate +minecraft:polished_deepslate_slab +minecraft:polished_deepslate_stairs +minecraft:polished_deepslate_wall +minecraft:polished_diorite +minecraft:polished_diorite_slab +minecraft:polished_diorite_stairs +minecraft:polished_granite +minecraft:polished_granite_slab +minecraft:polished_granite_stairs +minecraft:polished_sulfur +minecraft:polished_sulfur_slab +minecraft:polished_sulfur_stairs +minecraft:polished_sulfur_wall +minecraft:polished_tuff +minecraft:polished_tuff_slab +minecraft:polished_tuff_stairs +minecraft:polished_tuff_wall +minecraft:poppy +minecraft:potatoes +minecraft:potent_sulfur +minecraft:potted_acacia_sapling +minecraft:potted_allium +minecraft:potted_azalea_bush +minecraft:potted_azure_bluet +minecraft:potted_bamboo +minecraft:potted_birch_sapling +minecraft:potted_blue_orchid +minecraft:potted_brown_mushroom +minecraft:potted_cactus +minecraft:potted_cherry_sapling +minecraft:potted_closed_eyeblossom +minecraft:potted_cornflower +minecraft:potted_crimson_fungus +minecraft:potted_crimson_roots +minecraft:potted_dandelion +minecraft:potted_dark_oak_sapling +minecraft:potted_dead_bush +minecraft:potted_fern +minecraft:potted_flowering_azalea_bush +minecraft:potted_golden_dandelion +minecraft:potted_jungle_sapling +minecraft:potted_lily_of_the_valley +minecraft:potted_mangrove_propagule +minecraft:potted_oak_sapling +minecraft:potted_open_eyeblossom +minecraft:potted_orange_tulip +minecraft:potted_oxeye_daisy +minecraft:potted_pale_oak_sapling +minecraft:potted_pink_tulip +minecraft:potted_poppy +minecraft:potted_red_mushroom +minecraft:potted_red_tulip +minecraft:potted_spruce_sapling +minecraft:potted_torchflower +minecraft:potted_warped_fungus +minecraft:potted_warped_roots +minecraft:potted_white_tulip +minecraft:potted_wither_rose +minecraft:powder_snow +minecraft:powder_snow_cauldron +minecraft:powered_rail +minecraft:prismarine +minecraft:prismarine_brick_slab +minecraft:prismarine_brick_stairs +minecraft:prismarine_bricks +minecraft:prismarine_slab +minecraft:prismarine_stairs +minecraft:prismarine_wall +minecraft:pumpkin +minecraft:pumpkin_stem +minecraft:purple_banner +minecraft:purple_bed +minecraft:purple_candle +minecraft:purple_candle_cake +minecraft:purple_carpet +minecraft:purple_concrete +minecraft:purple_concrete_powder +minecraft:purple_glazed_terracotta +minecraft:purple_shulker_box +minecraft:purple_stained_glass +minecraft:purple_stained_glass_pane +minecraft:purple_terracotta +minecraft:purple_wall_banner +minecraft:purple_wool +minecraft:purpur_block +minecraft:purpur_pillar +minecraft:purpur_slab +minecraft:purpur_stairs +minecraft:quartz_block +minecraft:quartz_bricks +minecraft:quartz_pillar +minecraft:quartz_slab +minecraft:quartz_stairs +minecraft:rail +minecraft:raw_copper_block +minecraft:raw_gold_block +minecraft:raw_iron_block +minecraft:red_banner +minecraft:red_bed +minecraft:red_candle +minecraft:red_candle_cake +minecraft:red_carpet +minecraft:red_concrete +minecraft:red_concrete_powder +minecraft:red_glazed_terracotta +minecraft:red_mushroom +minecraft:red_mushroom_block +minecraft:red_nether_brick_slab +minecraft:red_nether_brick_stairs +minecraft:red_nether_brick_wall +minecraft:red_nether_bricks +minecraft:red_sand +minecraft:red_sandstone +minecraft:red_sandstone_slab +minecraft:red_sandstone_stairs +minecraft:red_sandstone_wall +minecraft:red_shulker_box +minecraft:red_stained_glass +minecraft:red_stained_glass_pane +minecraft:red_terracotta +minecraft:red_tulip +minecraft:red_wall_banner +minecraft:red_wool +minecraft:redstone_block +minecraft:redstone_lamp +minecraft:redstone_ore +minecraft:redstone_torch +minecraft:redstone_wall_torch +minecraft:redstone_wire +minecraft:reinforced_deepslate +minecraft:repeater +minecraft:repeating_command_block +minecraft:resin_block +minecraft:resin_brick_slab +minecraft:resin_brick_stairs +minecraft:resin_brick_wall +minecraft:resin_bricks +minecraft:resin_clump +minecraft:respawn_anchor +minecraft:rooted_dirt +minecraft:rose_bush +minecraft:sand +minecraft:sandstone +minecraft:sandstone_slab +minecraft:sandstone_stairs +minecraft:sandstone_wall +minecraft:scaffolding +minecraft:sculk +minecraft:sculk_catalyst +minecraft:sculk_sensor +minecraft:sculk_shrieker +minecraft:sculk_vein +minecraft:sea_lantern +minecraft:sea_pickle +minecraft:seagrass +minecraft:short_dry_grass +minecraft:short_grass +minecraft:shroomlight +minecraft:shulker_box +minecraft:skeleton_skull +minecraft:skeleton_wall_skull +minecraft:slime_block +minecraft:small_amethyst_bud +minecraft:small_dripleaf +minecraft:smithing_table +minecraft:smoker +minecraft:smooth_basalt +minecraft:smooth_quartz +minecraft:smooth_quartz_slab +minecraft:smooth_quartz_stairs +minecraft:smooth_red_sandstone +minecraft:smooth_red_sandstone_slab +minecraft:smooth_red_sandstone_stairs +minecraft:smooth_sandstone +minecraft:smooth_sandstone_slab +minecraft:smooth_sandstone_stairs +minecraft:smooth_stone +minecraft:smooth_stone_slab +minecraft:sniffer_egg +minecraft:snow +minecraft:snow_block +minecraft:soul_campfire +minecraft:soul_fire +minecraft:soul_lantern +minecraft:soul_sand +minecraft:soul_soil +minecraft:soul_torch +minecraft:soul_wall_torch +minecraft:spawner +minecraft:sponge +minecraft:spore_blossom +minecraft:spruce_button +minecraft:spruce_door +minecraft:spruce_fence +minecraft:spruce_fence_gate +minecraft:spruce_hanging_sign +minecraft:spruce_leaves +minecraft:spruce_log +minecraft:spruce_planks +minecraft:spruce_pressure_plate +minecraft:spruce_sapling +minecraft:spruce_shelf +minecraft:spruce_sign +minecraft:spruce_slab +minecraft:spruce_stairs +minecraft:spruce_trapdoor +minecraft:spruce_wall_hanging_sign +minecraft:spruce_wall_sign +minecraft:spruce_wood +minecraft:sticky_piston +minecraft:stone +minecraft:stone_brick_slab +minecraft:stone_brick_stairs +minecraft:stone_brick_wall +minecraft:stone_bricks +minecraft:stone_button +minecraft:stone_pressure_plate +minecraft:stone_slab +minecraft:stone_stairs +minecraft:stonecutter +minecraft:stripped_acacia_log +minecraft:stripped_acacia_wood +minecraft:stripped_bamboo_block +minecraft:stripped_birch_log +minecraft:stripped_birch_wood +minecraft:stripped_cherry_log +minecraft:stripped_cherry_wood +minecraft:stripped_crimson_hyphae +minecraft:stripped_crimson_stem +minecraft:stripped_dark_oak_log +minecraft:stripped_dark_oak_wood +minecraft:stripped_jungle_log +minecraft:stripped_jungle_wood +minecraft:stripped_mangrove_log +minecraft:stripped_mangrove_wood +minecraft:stripped_oak_log +minecraft:stripped_oak_wood +minecraft:stripped_pale_oak_log +minecraft:stripped_pale_oak_wood +minecraft:stripped_spruce_log +minecraft:stripped_spruce_wood +minecraft:stripped_warped_hyphae +minecraft:stripped_warped_stem +minecraft:structure_block +minecraft:structure_void +minecraft:sugar_cane +minecraft:sulfur +minecraft:sulfur_brick_slab +minecraft:sulfur_brick_stairs +minecraft:sulfur_brick_wall +minecraft:sulfur_bricks +minecraft:sulfur_slab +minecraft:sulfur_spike +minecraft:sulfur_stairs +minecraft:sulfur_wall +minecraft:sunflower +minecraft:suspicious_gravel +minecraft:suspicious_sand +minecraft:sweet_berry_bush +minecraft:tall_dry_grass +minecraft:tall_grass +minecraft:tall_seagrass +minecraft:target +minecraft:terracotta +minecraft:test_block +minecraft:test_instance_block +minecraft:tinted_glass +minecraft:tnt +minecraft:torch +minecraft:torchflower +minecraft:torchflower_crop +minecraft:trapped_chest +minecraft:trial_spawner +minecraft:tripwire +minecraft:tripwire_hook +minecraft:tube_coral +minecraft:tube_coral_block +minecraft:tube_coral_fan +minecraft:tube_coral_wall_fan +minecraft:tuff +minecraft:tuff_brick_slab +minecraft:tuff_brick_stairs +minecraft:tuff_brick_wall +minecraft:tuff_bricks +minecraft:tuff_slab +minecraft:tuff_stairs +minecraft:tuff_wall +minecraft:turtle_egg +minecraft:twisting_vines +minecraft:twisting_vines_plant +minecraft:vault +minecraft:verdant_froglight +minecraft:vine +minecraft:void_air +minecraft:wall_torch +minecraft:warped_button +minecraft:warped_door +minecraft:warped_fence +minecraft:warped_fence_gate +minecraft:warped_fungus +minecraft:warped_hanging_sign +minecraft:warped_hyphae +minecraft:warped_nylium +minecraft:warped_planks +minecraft:warped_pressure_plate +minecraft:warped_roots +minecraft:warped_shelf +minecraft:warped_sign +minecraft:warped_slab +minecraft:warped_stairs +minecraft:warped_stem +minecraft:warped_trapdoor +minecraft:warped_wall_hanging_sign +minecraft:warped_wall_sign +minecraft:warped_wart_block +minecraft:water +minecraft:water_cauldron +minecraft:waxed_chiseled_copper +minecraft:waxed_copper_bars +minecraft:waxed_copper_block +minecraft:waxed_copper_bulb +minecraft:waxed_copper_chain +minecraft:waxed_copper_chest +minecraft:waxed_copper_door +minecraft:waxed_copper_golem_statue +minecraft:waxed_copper_grate +minecraft:waxed_copper_lantern +minecraft:waxed_copper_trapdoor +minecraft:waxed_cut_copper +minecraft:waxed_cut_copper_slab +minecraft:waxed_cut_copper_stairs +minecraft:waxed_exposed_chiseled_copper +minecraft:waxed_exposed_copper +minecraft:waxed_exposed_copper_bars +minecraft:waxed_exposed_copper_bulb +minecraft:waxed_exposed_copper_chain +minecraft:waxed_exposed_copper_chest +minecraft:waxed_exposed_copper_door +minecraft:waxed_exposed_copper_golem_statue +minecraft:waxed_exposed_copper_grate +minecraft:waxed_exposed_copper_lantern +minecraft:waxed_exposed_copper_trapdoor +minecraft:waxed_exposed_cut_copper +minecraft:waxed_exposed_cut_copper_slab +minecraft:waxed_exposed_cut_copper_stairs +minecraft:waxed_exposed_lightning_rod +minecraft:waxed_lightning_rod +minecraft:waxed_oxidized_chiseled_copper +minecraft:waxed_oxidized_copper +minecraft:waxed_oxidized_copper_bars +minecraft:waxed_oxidized_copper_bulb +minecraft:waxed_oxidized_copper_chain +minecraft:waxed_oxidized_copper_chest +minecraft:waxed_oxidized_copper_door +minecraft:waxed_oxidized_copper_golem_statue +minecraft:waxed_oxidized_copper_grate +minecraft:waxed_oxidized_copper_lantern +minecraft:waxed_oxidized_copper_trapdoor +minecraft:waxed_oxidized_cut_copper +minecraft:waxed_oxidized_cut_copper_slab +minecraft:waxed_oxidized_cut_copper_stairs +minecraft:waxed_oxidized_lightning_rod +minecraft:waxed_weathered_chiseled_copper +minecraft:waxed_weathered_copper +minecraft:waxed_weathered_copper_bars +minecraft:waxed_weathered_copper_bulb +minecraft:waxed_weathered_copper_chain +minecraft:waxed_weathered_copper_chest +minecraft:waxed_weathered_copper_door +minecraft:waxed_weathered_copper_golem_statue +minecraft:waxed_weathered_copper_grate +minecraft:waxed_weathered_copper_lantern +minecraft:waxed_weathered_copper_trapdoor +minecraft:waxed_weathered_cut_copper +minecraft:waxed_weathered_cut_copper_slab +minecraft:waxed_weathered_cut_copper_stairs +minecraft:waxed_weathered_lightning_rod +minecraft:weathered_chiseled_copper +minecraft:weathered_copper +minecraft:weathered_copper_bars +minecraft:weathered_copper_bulb +minecraft:weathered_copper_chain +minecraft:weathered_copper_chest +minecraft:weathered_copper_door +minecraft:weathered_copper_golem_statue +minecraft:weathered_copper_grate +minecraft:weathered_copper_lantern +minecraft:weathered_copper_trapdoor +minecraft:weathered_cut_copper +minecraft:weathered_cut_copper_slab +minecraft:weathered_cut_copper_stairs +minecraft:weathered_lightning_rod +minecraft:weeping_vines +minecraft:weeping_vines_plant +minecraft:wet_sponge +minecraft:wheat +minecraft:white_banner +minecraft:white_bed +minecraft:white_candle +minecraft:white_candle_cake +minecraft:white_carpet +minecraft:white_concrete +minecraft:white_concrete_powder +minecraft:white_glazed_terracotta +minecraft:white_shulker_box +minecraft:white_stained_glass +minecraft:white_stained_glass_pane +minecraft:white_terracotta +minecraft:white_tulip +minecraft:white_wall_banner +minecraft:white_wool +minecraft:wildflowers +minecraft:wither_rose +minecraft:wither_skeleton_skull +minecraft:wither_skeleton_wall_skull +minecraft:yellow_banner +minecraft:yellow_bed +minecraft:yellow_candle +minecraft:yellow_candle_cake +minecraft:yellow_carpet +minecraft:yellow_concrete +minecraft:yellow_concrete_powder +minecraft:yellow_glazed_terracotta +minecraft:yellow_shulker_box +minecraft:yellow_stained_glass +minecraft:yellow_stained_glass_pane +minecraft:yellow_terracotta +minecraft:yellow_wall_banner +minecraft:yellow_wool +minecraft:zombie_head +minecraft:zombie_wall_head diff --git a/SubstrateCS/Source/Data/LegacyBlockStates.txt b/SubstrateCS/Source/Data/LegacyBlockStates.txt new file mode 100644 index 00000000..faf977e8 --- /dev/null +++ b/SubstrateCS/Source/Data/LegacyBlockStates.txt @@ -0,0 +1,1683 @@ +# Legacy Java block-state mappings derived from PrismarineJS minecraft-data (MIT). +0:0|minecraft:air +1:0|minecraft:stone +1:1|minecraft:granite +1:2|minecraft:polished_granite +1:3|minecraft:diorite +1:4|minecraft:polished_diorite +1:5|minecraft:andesite +1:6|minecraft:polished_andesite +2:0|minecraft:grass_block[snowy=false] +3:0|minecraft:dirt +3:1|minecraft:coarse_dirt +3:2|minecraft:podzol[snowy=false] +4:0|minecraft:cobblestone +5:0|minecraft:oak_planks +5:1|minecraft:spruce_planks +5:2|minecraft:birch_planks +5:3|minecraft:jungle_planks +5:4|minecraft:acacia_planks +5:5|minecraft:dark_oak_planks +6:0|minecraft:oak_sapling[stage=0] +6:1|minecraft:spruce_sapling[stage=0] +6:2|minecraft:birch_sapling[stage=0] +6:3|minecraft:jungle_sapling[stage=0] +6:4|minecraft:acacia_sapling[stage=0] +6:5|minecraft:dark_oak_sapling[stage=0] +6:8|minecraft:oak_sapling[stage=1] +6:9|minecraft:spruce_sapling[stage=1] +6:10|minecraft:birch_sapling[stage=1] +6:11|minecraft:jungle_sapling[stage=1] +6:12|minecraft:acacia_sapling[stage=1] +6:13|minecraft:dark_oak_sapling[stage=1] +7:0|minecraft:bedrock +8:0|minecraft:water[level=0] +8:1|minecraft:water[level=1] +8:2|minecraft:water[level=2] +8:3|minecraft:water[level=3] +8:4|minecraft:water[level=4] +8:5|minecraft:water[level=5] +8:6|minecraft:water[level=6] +8:7|minecraft:water[level=7] +8:8|minecraft:water[level=8] +8:9|minecraft:water[level=9] +8:10|minecraft:water[level=10] +8:11|minecraft:water[level=11] +8:12|minecraft:water[level=12] +8:13|minecraft:water[level=13] +8:14|minecraft:water[level=14] +8:15|minecraft:water[level=15] +9:0|minecraft:water[level=0] +9:1|minecraft:water[level=1] +9:2|minecraft:water[level=2] +9:3|minecraft:water[level=3] +9:4|minecraft:water[level=4] +9:5|minecraft:water[level=5] +9:6|minecraft:water[level=6] +9:7|minecraft:water[level=7] +9:8|minecraft:water[level=8] +9:9|minecraft:water[level=9] +9:10|minecraft:water[level=10] +9:11|minecraft:water[level=11] +9:12|minecraft:water[level=12] +9:13|minecraft:water[level=13] +9:14|minecraft:water[level=14] +9:15|minecraft:water[level=15] +10:0|minecraft:lava[level=0] +10:1|minecraft:lava[level=1] +10:2|minecraft:lava[level=2] +10:3|minecraft:lava[level=3] +10:4|minecraft:lava[level=4] +10:5|minecraft:lava[level=5] +10:6|minecraft:lava[level=6] +10:7|minecraft:lava[level=7] +10:8|minecraft:lava[level=8] +10:9|minecraft:lava[level=9] +10:10|minecraft:lava[level=10] +10:11|minecraft:lava[level=11] +10:12|minecraft:lava[level=12] +10:13|minecraft:lava[level=13] +10:14|minecraft:lava[level=14] +10:15|minecraft:lava[level=15] +11:0|minecraft:lava[level=0] +11:1|minecraft:lava[level=1] +11:2|minecraft:lava[level=2] +11:3|minecraft:lava[level=3] +11:4|minecraft:lava[level=4] +11:5|minecraft:lava[level=5] +11:6|minecraft:lava[level=6] +11:7|minecraft:lava[level=7] +11:8|minecraft:lava[level=8] +11:9|minecraft:lava[level=9] +11:10|minecraft:lava[level=10] +11:11|minecraft:lava[level=11] +11:12|minecraft:lava[level=12] +11:13|minecraft:lava[level=13] +11:14|minecraft:lava[level=14] +11:15|minecraft:lava[level=15] +12:0|minecraft:sand +12:1|minecraft:red_sand +13:0|minecraft:gravel +14:0|minecraft:gold_ore +15:0|minecraft:iron_ore +16:0|minecraft:coal_ore +17:0|minecraft:oak_log[axis=y] +17:1|minecraft:spruce_log[axis=y] +17:2|minecraft:birch_log[axis=y] +17:3|minecraft:jungle_log[axis=y] +17:4|minecraft:oak_log[axis=x] +17:5|minecraft:spruce_log[axis=x] +17:6|minecraft:birch_log[axis=x] +17:7|minecraft:jungle_log[axis=x] +17:8|minecraft:oak_log[axis=z] +17:9|minecraft:spruce_log[axis=z] +17:10|minecraft:birch_log[axis=z] +17:11|minecraft:jungle_log[axis=z] +17:12|minecraft:oak_wood +17:13|minecraft:spruce_wood +17:14|minecraft:birch_wood +17:15|minecraft:jungle_wood +18:0|minecraft:oak_leaves[persistent=false,distance=1] +18:1|minecraft:spruce_leaves[persistent=false,distance=1] +18:2|minecraft:birch_leaves[persistent=false,distance=1] +18:3|minecraft:jungle_leaves[persistent=false,distance=1] +18:4|minecraft:oak_leaves[persistent=true,distance=1] +18:5|minecraft:spruce_leaves[persistent=true,distance=1] +18:6|minecraft:birch_leaves[persistent=true,distance=1] +18:7|minecraft:jungle_leaves[persistent=true,distance=1] +18:8|minecraft:oak_leaves[persistent=false,distance=1] +18:9|minecraft:spruce_leaves[persistent=false,distance=1] +18:10|minecraft:birch_leaves[persistent=false,distance=1] +18:11|minecraft:jungle_leaves[persistent=false,distance=1] +18:12|minecraft:oak_leaves[persistent=true,distance=1] +18:13|minecraft:spruce_leaves[persistent=true,distance=1] +18:14|minecraft:birch_leaves[persistent=true,distance=1] +18:15|minecraft:jungle_leaves[persistent=true,distance=1] +19:0|minecraft:sponge +19:1|minecraft:wet_sponge +20:0|minecraft:glass +21:0|minecraft:lapis_ore +22:0|minecraft:lapis_block +23:0|minecraft:dispenser[triggered=false,facing=down] +23:1|minecraft:dispenser[triggered=false,facing=up] +23:2|minecraft:dispenser[triggered=false,facing=north] +23:3|minecraft:dispenser[triggered=false,facing=south] +23:4|minecraft:dispenser[triggered=false,facing=west] +23:5|minecraft:dispenser[triggered=false,facing=east] +23:8|minecraft:dispenser[triggered=true,facing=down] +23:9|minecraft:dispenser[triggered=true,facing=up] +23:10|minecraft:dispenser[triggered=true,facing=north] +23:11|minecraft:dispenser[triggered=true,facing=south] +23:12|minecraft:dispenser[triggered=true,facing=west] +23:13|minecraft:dispenser[triggered=true,facing=east] +24:0|minecraft:sandstone +24:1|minecraft:chiseled_sandstone +24:2|minecraft:cut_sandstone +25:0|minecraft:note_block +26:0|minecraft:red_bed[part=foot,facing=south,occupied=false] +26:1|minecraft:red_bed[part=foot,facing=west,occupied=false] +26:2|minecraft:red_bed[part=foot,facing=north,occupied=false] +26:3|minecraft:red_bed[part=foot,facing=east,occupied=false] +26:4|minecraft:red_bed[part=foot,facing=south,occupied=true] +26:5|minecraft:red_bed[part=foot,facing=west,occupied=true] +26:6|minecraft:red_bed[part=foot,facing=north,occupied=true] +26:7|minecraft:red_bed[part=foot,facing=east,occupied=true] +26:8|minecraft:red_bed[part=head,facing=south,occupied=false] +26:9|minecraft:red_bed[part=head,facing=west,occupied=false] +26:10|minecraft:red_bed[part=head,facing=north,occupied=false] +26:11|minecraft:red_bed[part=head,facing=east,occupied=false] +26:12|minecraft:red_bed[part=head,facing=south,occupied=true] +26:13|minecraft:red_bed[part=head,facing=west,occupied=true] +26:14|minecraft:red_bed[part=head,facing=north,occupied=true] +26:15|minecraft:red_bed[part=head,facing=east,occupied=true] +27:0|minecraft:powered_rail[shape=north_south,powered=false] +27:1|minecraft:powered_rail[shape=east_west,powered=false] +27:2|minecraft:powered_rail[shape=ascending_east,powered=false] +27:3|minecraft:powered_rail[shape=ascending_west,powered=false] +27:4|minecraft:powered_rail[shape=ascending_north,powered=false] +27:5|minecraft:powered_rail[shape=ascending_south,powered=false] +27:8|minecraft:powered_rail[shape=north_south,powered=true] +27:9|minecraft:powered_rail[shape=east_west,powered=true] +27:10|minecraft:powered_rail[shape=ascending_east,powered=true] +27:11|minecraft:powered_rail[shape=ascending_west,powered=true] +27:12|minecraft:powered_rail[shape=ascending_north,powered=true] +27:13|minecraft:powered_rail[shape=ascending_south,powered=true] +28:0|minecraft:detector_rail[shape=north_south,powered=false] +28:1|minecraft:detector_rail[shape=east_west,powered=false] +28:2|minecraft:detector_rail[shape=ascending_east,powered=false] +28:3|minecraft:detector_rail[shape=ascending_west,powered=false] +28:4|minecraft:detector_rail[shape=ascending_north,powered=false] +28:5|minecraft:detector_rail[shape=ascending_south,powered=false] +28:8|minecraft:detector_rail[shape=north_south,powered=true] +28:9|minecraft:detector_rail[shape=east_west,powered=true] +28:10|minecraft:detector_rail[shape=ascending_east,powered=true] +28:11|minecraft:detector_rail[shape=ascending_west,powered=true] +28:12|minecraft:detector_rail[shape=ascending_north,powered=true] +28:13|minecraft:detector_rail[shape=ascending_south,powered=true] +29:0|minecraft:sticky_piston[facing=down,extended=false] +29:1|minecraft:sticky_piston[facing=up,extended=false] +29:2|minecraft:sticky_piston[facing=north,extended=false] +29:3|minecraft:sticky_piston[facing=south,extended=false] +29:4|minecraft:sticky_piston[facing=west,extended=false] +29:5|minecraft:sticky_piston[facing=east,extended=false] +29:8|minecraft:sticky_piston[facing=down,extended=true] +29:9|minecraft:sticky_piston[facing=up,extended=true] +29:10|minecraft:sticky_piston[facing=north,extended=true] +29:11|minecraft:sticky_piston[facing=south,extended=true] +29:12|minecraft:sticky_piston[facing=west,extended=true] +29:13|minecraft:sticky_piston[facing=east,extended=true] +30:0|minecraft:cobweb +31:0|minecraft:dead_bush +31:1|minecraft:short_grass +31:2|minecraft:fern +32:0|minecraft:dead_bush +33:0|minecraft:piston[facing=down,extended=false] +33:1|minecraft:piston[facing=up,extended=false] +33:2|minecraft:piston[facing=north,extended=false] +33:3|minecraft:piston[facing=south,extended=false] +33:4|minecraft:piston[facing=west,extended=false] +33:5|minecraft:piston[facing=east,extended=false] +33:8|minecraft:piston[facing=down,extended=true] +33:9|minecraft:piston[facing=up,extended=true] +33:10|minecraft:piston[facing=north,extended=true] +33:11|minecraft:piston[facing=south,extended=true] +33:12|minecraft:piston[facing=west,extended=true] +33:13|minecraft:piston[facing=east,extended=true] +34:0|minecraft:piston_head[short=false,facing=down,type=normal] +34:1|minecraft:piston_head[short=false,facing=up,type=normal] +34:2|minecraft:piston_head[short=false,facing=north,type=normal] +34:3|minecraft:piston_head[short=false,facing=south,type=normal] +34:4|minecraft:piston_head[short=false,facing=west,type=normal] +34:5|minecraft:piston_head[short=false,facing=east,type=normal] +34:8|minecraft:piston_head[short=false,facing=down,type=sticky] +34:9|minecraft:piston_head[short=false,facing=up,type=sticky] +34:10|minecraft:piston_head[short=false,facing=north,type=sticky] +34:11|minecraft:piston_head[short=false,facing=south,type=sticky] +34:12|minecraft:piston_head[short=false,facing=west,type=sticky] +34:13|minecraft:piston_head[short=false,facing=east,type=sticky] +35:0|minecraft:white_wool +35:1|minecraft:orange_wool +35:2|minecraft:magenta_wool +35:3|minecraft:light_blue_wool +35:4|minecraft:yellow_wool +35:5|minecraft:lime_wool +35:6|minecraft:pink_wool +35:7|minecraft:gray_wool +35:8|minecraft:light_gray_wool +35:9|minecraft:cyan_wool +35:10|minecraft:purple_wool +35:11|minecraft:blue_wool +35:12|minecraft:brown_wool +35:13|minecraft:green_wool +35:14|minecraft:red_wool +35:15|minecraft:black_wool +36:0|minecraft:moving_piston[facing=down,type=normal] +36:1|minecraft:moving_piston[facing=up,type=normal] +36:2|minecraft:moving_piston[facing=north,type=normal] +36:3|minecraft:moving_piston[facing=south,type=normal] +36:4|minecraft:moving_piston[facing=west,type=normal] +36:5|minecraft:moving_piston[facing=east,type=normal] +36:8|minecraft:moving_piston[facing=down,type=sticky] +36:9|minecraft:moving_piston[facing=up,type=sticky] +36:10|minecraft:moving_piston[facing=north,type=sticky] +36:11|minecraft:moving_piston[facing=south,type=sticky] +36:12|minecraft:moving_piston[facing=west,type=sticky] +36:13|minecraft:moving_piston[facing=east,type=sticky] +37:0|minecraft:dandelion +38:0|minecraft:poppy +38:1|minecraft:blue_orchid +38:2|minecraft:allium +38:3|minecraft:azure_bluet +38:4|minecraft:red_tulip +38:5|minecraft:orange_tulip +38:6|minecraft:white_tulip +38:7|minecraft:pink_tulip +38:8|minecraft:oxeye_daisy +39:0|minecraft:brown_mushroom +40:0|minecraft:red_mushroom +41:0|minecraft:gold_block +42:0|minecraft:iron_block +43:0|minecraft:stone_slab[type=double] +43:1|minecraft:sandstone_slab[type=double] +43:2|minecraft:petrified_oak_slab[type=double] +43:3|minecraft:cobblestone_slab[type=double] +43:4|minecraft:brick_slab[type=double] +43:5|minecraft:stone_brick_slab[type=double] +43:6|minecraft:nether_brick_slab[type=double] +43:7|minecraft:quartz_slab[type=double] +43:8|minecraft:smooth_stone +43:9|minecraft:smooth_sandstone +43:10|minecraft:petrified_oak_slab[type=double] +43:11|minecraft:cobblestone_slab[type=double] +43:12|minecraft:brick_slab[type=double] +43:13|minecraft:stone_brick_slab[type=double] +43:14|minecraft:nether_brick_slab[type=double] +43:15|minecraft:smooth_quartz +44:0|minecraft:stone_slab[type=bottom] +44:1|minecraft:sandstone_slab[type=bottom] +44:2|minecraft:petrified_oak_slab[type=bottom] +44:3|minecraft:cobblestone_slab[type=bottom] +44:4|minecraft:brick_slab[type=bottom] +44:5|minecraft:stone_brick_slab[type=bottom] +44:6|minecraft:nether_brick_slab[type=bottom] +44:7|minecraft:quartz_slab[type=bottom] +44:8|minecraft:stone_slab[type=top] +44:9|minecraft:sandstone_slab[type=top] +44:10|minecraft:petrified_oak_slab[type=top] +44:11|minecraft:cobblestone_slab[type=top] +44:12|minecraft:brick_slab[type=top] +44:13|minecraft:stone_brick_slab[type=top] +44:14|minecraft:nether_brick_slab[type=top] +44:15|minecraft:quartz_slab[type=top] +45:0|minecraft:bricks +46:0|minecraft:tnt[unstable=false] +46:1|minecraft:tnt[unstable=true] +47:0|minecraft:bookshelf +48:0|minecraft:mossy_cobblestone +49:0|minecraft:obsidian +50:1|minecraft:wall_torch[facing=east] +50:2|minecraft:wall_torch[facing=west] +50:3|minecraft:wall_torch[facing=south] +50:4|minecraft:wall_torch[facing=north] +50:5|minecraft:torch +51:0|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=0] +51:1|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=1] +51:2|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=2] +51:3|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=3] +51:4|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=4] +51:5|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=5] +51:6|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=6] +51:7|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=7] +51:8|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=8] +51:9|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=9] +51:10|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=10] +51:11|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=11] +51:12|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=12] +51:13|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=13] +51:14|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=14] +51:15|minecraft:fire[east=false,south=false,north=false,west=false,up=false,age=15] +52:0|minecraft:spawner +53:0|minecraft:oak_stairs[half=bottom,shape=outer_right,facing=east] +53:1|minecraft:oak_stairs[half=bottom,shape=outer_right,facing=west] +53:2|minecraft:oak_stairs[half=bottom,shape=outer_right,facing=south] +53:3|minecraft:oak_stairs[half=bottom,shape=outer_right,facing=north] +53:4|minecraft:oak_stairs[half=top,shape=outer_right,facing=east] +53:5|minecraft:oak_stairs[half=top,shape=outer_right,facing=west] +53:6|minecraft:oak_stairs[half=top,shape=outer_right,facing=south] +53:7|minecraft:oak_stairs[half=top,shape=outer_right,facing=north] +54:2|minecraft:chest[facing=north,type=single] +54:3|minecraft:chest[facing=south,type=single] +54:4|minecraft:chest[facing=west,type=single] +54:5|minecraft:chest[facing=east,type=single] +55:0|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=0] +55:1|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=1] +55:2|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=2] +55:3|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=3] +55:4|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=4] +55:5|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=5] +55:6|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=6] +55:7|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=7] +55:8|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=8] +55:9|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=9] +55:10|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=10] +55:11|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=11] +55:12|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=12] +55:13|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=13] +55:14|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=14] +55:15|minecraft:redstone_wire[east=none,south=none,north=none,west=none,power=15] +56:0|minecraft:diamond_ore +57:0|minecraft:diamond_block +58:0|minecraft:crafting_table +59:0|minecraft:wheat[age=0] +59:1|minecraft:wheat[age=1] +59:2|minecraft:wheat[age=2] +59:3|minecraft:wheat[age=3] +59:4|minecraft:wheat[age=4] +59:5|minecraft:wheat[age=5] +59:6|minecraft:wheat[age=6] +59:7|minecraft:wheat[age=7] +60:0|minecraft:farmland[moisture=0] +60:1|minecraft:farmland[moisture=1] +60:2|minecraft:farmland[moisture=2] +60:3|minecraft:farmland[moisture=3] +60:4|minecraft:farmland[moisture=4] +60:5|minecraft:farmland[moisture=5] +60:6|minecraft:farmland[moisture=6] +60:7|minecraft:farmland[moisture=7] +61:2|minecraft:furnace[facing=north,lit=false] +61:3|minecraft:furnace[facing=south,lit=false] +61:4|minecraft:furnace[facing=west,lit=false] +61:5|minecraft:furnace[facing=east,lit=false] +62:2|minecraft:furnace[facing=north,lit=true] +62:3|minecraft:furnace[facing=south,lit=true] +62:4|minecraft:furnace[facing=west,lit=true] +62:5|minecraft:furnace[facing=east,lit=true] +63:0|minecraft:oak_sign[rotation=0] +63:1|minecraft:oak_sign[rotation=1] +63:2|minecraft:oak_sign[rotation=2] +63:3|minecraft:oak_sign[rotation=3] +63:4|minecraft:oak_sign[rotation=4] +63:5|minecraft:oak_sign[rotation=5] +63:6|minecraft:oak_sign[rotation=6] +63:7|minecraft:oak_sign[rotation=7] +63:8|minecraft:oak_sign[rotation=8] +63:9|minecraft:oak_sign[rotation=9] +63:10|minecraft:oak_sign[rotation=10] +63:11|minecraft:oak_sign[rotation=11] +63:12|minecraft:oak_sign[rotation=12] +63:13|minecraft:oak_sign[rotation=13] +63:14|minecraft:oak_sign[rotation=14] +63:15|minecraft:oak_sign[rotation=15] +64:0|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=east,open=false] +64:1|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=south,open=false] +64:2|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=west,open=false] +64:3|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=north,open=false] +64:4|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=east,open=true] +64:5|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=south,open=true] +64:6|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=west,open=true] +64:7|minecraft:oak_door[hinge=right,half=lower,powered=false,facing=north,open=true] +64:8|minecraft:oak_door[hinge=left,half=upper,powered=false,facing=east,open=false] +64:9|minecraft:oak_door[hinge=right,half=upper,powered=false,facing=east,open=false] +64:10|minecraft:oak_door[hinge=left,half=upper,powered=true,facing=east,open=false] +64:11|minecraft:oak_door[hinge=right,half=upper,powered=true,facing=east,open=false] +65:2|minecraft:ladder[facing=north] +65:3|minecraft:ladder[facing=south] +65:4|minecraft:ladder[facing=west] +65:5|minecraft:ladder[facing=east] +66:0|minecraft:rail[shape=north_south] +66:1|minecraft:rail[shape=east_west] +66:2|minecraft:rail[shape=ascending_east] +66:3|minecraft:rail[shape=ascending_west] +66:4|minecraft:rail[shape=ascending_north] +66:5|minecraft:rail[shape=ascending_south] +66:6|minecraft:rail[shape=south_east] +66:7|minecraft:rail[shape=south_west] +66:8|minecraft:rail[shape=north_west] +66:9|minecraft:rail[shape=north_east] +67:0|minecraft:cobblestone_stairs[half=bottom,shape=straight,facing=east] +67:1|minecraft:cobblestone_stairs[half=bottom,shape=straight,facing=west] +67:2|minecraft:cobblestone_stairs[half=bottom,shape=straight,facing=south] +67:3|minecraft:cobblestone_stairs[half=bottom,shape=straight,facing=north] +67:4|minecraft:cobblestone_stairs[half=top,shape=straight,facing=east] +67:5|minecraft:cobblestone_stairs[half=top,shape=straight,facing=west] +67:6|minecraft:cobblestone_stairs[half=top,shape=straight,facing=south] +67:7|minecraft:cobblestone_stairs[half=top,shape=straight,facing=north] +68:2|minecraft:oak_wall_sign[facing=north] +68:3|minecraft:oak_wall_sign[facing=south] +68:4|minecraft:oak_wall_sign[facing=west] +68:5|minecraft:oak_wall_sign[facing=east] +69:0|minecraft:lever[powered=false,facing=north,face=ceiling] +69:1|minecraft:lever[powered=false,facing=east,face=wall] +69:2|minecraft:lever[powered=false,facing=west,face=wall] +69:3|minecraft:lever[powered=false,facing=south,face=wall] +69:4|minecraft:lever[powered=false,facing=north,face=wall] +69:5|minecraft:lever[powered=false,facing=east,face=floor] +69:6|minecraft:lever[powered=false,facing=north,face=floor] +69:7|minecraft:lever[powered=false,facing=east,face=ceiling] +69:8|minecraft:lever[powered=true,facing=north,face=ceiling] +69:9|minecraft:lever[powered=true,facing=east,face=wall] +69:10|minecraft:lever[powered=true,facing=west,face=wall] +69:11|minecraft:lever[powered=true,facing=south,face=wall] +69:12|minecraft:lever[powered=true,facing=north,face=wall] +69:13|minecraft:lever[powered=true,facing=east,face=floor] +69:14|minecraft:lever[powered=true,facing=north,face=floor] +69:15|minecraft:lever[powered=true,facing=east,face=ceiling] +70:0|minecraft:stone_pressure_plate[powered=false] +70:1|minecraft:stone_pressure_plate[powered=true] +71:0|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=east,open=false] +71:1|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=south,open=false] +71:2|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=west,open=false] +71:3|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=north,open=false] +71:4|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=east,open=true] +71:5|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=south,open=true] +71:6|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=west,open=true] +71:7|minecraft:iron_door[hinge=right,half=lower,powered=false,facing=north,open=true] +71:8|minecraft:iron_door[hinge=left,half=upper,powered=false,facing=east,open=false] +71:9|minecraft:iron_door[hinge=right,half=upper,powered=false,facing=east,open=false] +71:10|minecraft:iron_door[hinge=left,half=upper,powered=true,facing=east,open=false] +71:11|minecraft:iron_door[hinge=right,half=upper,powered=true,facing=east,open=false] +72:0|minecraft:oak_pressure_plate[powered=false] +72:1|minecraft:oak_pressure_plate[powered=true] +73:0|minecraft:redstone_ore[lit=false] +74:0|minecraft:redstone_ore[lit=true] +75:1|minecraft:redstone_wall_torch[facing=east,lit=false] +75:2|minecraft:redstone_wall_torch[facing=west,lit=false] +75:3|minecraft:redstone_wall_torch[facing=south,lit=false] +75:4|minecraft:redstone_wall_torch[facing=north,lit=false] +75:5|minecraft:redstone_torch[lit=false] +76:1|minecraft:redstone_wall_torch[facing=east,lit=true] +76:2|minecraft:redstone_wall_torch[facing=west,lit=true] +76:3|minecraft:redstone_wall_torch[facing=south,lit=true] +76:4|minecraft:redstone_wall_torch[facing=north,lit=true] +76:5|minecraft:redstone_torch[lit=true] +77:0|minecraft:stone_button[powered=false,facing=east,face=ceiling] +77:1|minecraft:stone_button[powered=false,facing=east,face=wall] +77:2|minecraft:stone_button[powered=false,facing=west,face=wall] +77:3|minecraft:stone_button[powered=false,facing=south,face=wall] +77:4|minecraft:stone_button[powered=false,facing=north,face=wall] +77:5|minecraft:stone_button[powered=false,facing=east,face=floor] +77:8|minecraft:stone_button[powered=true,facing=south,face=ceiling] +77:9|minecraft:stone_button[powered=true,facing=east,face=wall] +77:10|minecraft:stone_button[powered=true,facing=west,face=wall] +77:11|minecraft:stone_button[powered=true,facing=south,face=wall] +77:12|minecraft:stone_button[powered=true,facing=north,face=wall] +77:13|minecraft:stone_button[powered=true,facing=south,face=floor] +78:0|minecraft:snow[layers=1] +78:1|minecraft:snow[layers=2] +78:2|minecraft:snow[layers=3] +78:3|minecraft:snow[layers=4] +78:4|minecraft:snow[layers=5] +78:5|minecraft:snow[layers=6] +78:6|minecraft:snow[layers=7] +78:7|minecraft:snow[layers=8] +79:0|minecraft:ice +80:0|minecraft:snow_block +81:0|minecraft:cactus[age=0] +81:1|minecraft:cactus[age=1] +81:2|minecraft:cactus[age=2] +81:3|minecraft:cactus[age=3] +81:4|minecraft:cactus[age=4] +81:5|minecraft:cactus[age=5] +81:6|minecraft:cactus[age=6] +81:7|minecraft:cactus[age=7] +81:8|minecraft:cactus[age=8] +81:9|minecraft:cactus[age=9] +81:10|minecraft:cactus[age=10] +81:11|minecraft:cactus[age=11] +81:12|minecraft:cactus[age=12] +81:13|minecraft:cactus[age=13] +81:14|minecraft:cactus[age=14] +81:15|minecraft:cactus[age=15] +82:0|minecraft:clay +83:0|minecraft:sugar_cane[age=0] +83:1|minecraft:sugar_cane[age=1] +83:2|minecraft:sugar_cane[age=2] +83:3|minecraft:sugar_cane[age=3] +83:4|minecraft:sugar_cane[age=4] +83:5|minecraft:sugar_cane[age=5] +83:6|minecraft:sugar_cane[age=6] +83:7|minecraft:sugar_cane[age=7] +83:8|minecraft:sugar_cane[age=8] +83:9|minecraft:sugar_cane[age=9] +83:10|minecraft:sugar_cane[age=10] +83:11|minecraft:sugar_cane[age=11] +83:12|minecraft:sugar_cane[age=12] +83:13|minecraft:sugar_cane[age=13] +83:14|minecraft:sugar_cane[age=14] +83:15|minecraft:sugar_cane[age=15] +84:0|minecraft:jukebox[has_record=false] +84:1|minecraft:jukebox[has_record=true] +85:0|minecraft:oak_fence[east=false,south=false,north=false,west=false] +86:0|minecraft:carved_pumpkin[facing=south] +86:1|minecraft:carved_pumpkin[facing=west] +86:2|minecraft:carved_pumpkin[facing=north] +86:3|minecraft:carved_pumpkin[facing=east] +87:0|minecraft:netherrack +88:0|minecraft:soul_sand +89:0|minecraft:glowstone +90:1|minecraft:nether_portal[axis=x] +90:2|minecraft:nether_portal[axis=z] +91:0|minecraft:jack_o_lantern[facing=south] +91:1|minecraft:jack_o_lantern[facing=west] +91:2|minecraft:jack_o_lantern[facing=north] +91:3|minecraft:jack_o_lantern[facing=east] +92:0|minecraft:cake[bites=0] +92:1|minecraft:cake[bites=1] +92:2|minecraft:cake[bites=2] +92:3|minecraft:cake[bites=3] +92:4|minecraft:cake[bites=4] +92:5|minecraft:cake[bites=5] +92:6|minecraft:cake[bites=6] +93:0|minecraft:repeater[delay=1,facing=south,locked=false,powered=false] +93:1|minecraft:repeater[delay=1,facing=west,locked=false,powered=false] +93:2|minecraft:repeater[delay=1,facing=north,locked=false,powered=false] +93:3|minecraft:repeater[delay=1,facing=east,locked=false,powered=false] +93:4|minecraft:repeater[delay=2,facing=south,locked=false,powered=false] +93:5|minecraft:repeater[delay=2,facing=west,locked=false,powered=false] +93:6|minecraft:repeater[delay=2,facing=north,locked=false,powered=false] +93:7|minecraft:repeater[delay=2,facing=east,locked=false,powered=false] +93:8|minecraft:repeater[delay=3,facing=south,locked=false,powered=false] +93:9|minecraft:repeater[delay=3,facing=west,locked=false,powered=false] +93:10|minecraft:repeater[delay=3,facing=north,locked=false,powered=false] +93:11|minecraft:repeater[delay=3,facing=east,locked=false,powered=false] +93:12|minecraft:repeater[delay=4,facing=south,locked=false,powered=false] +93:13|minecraft:repeater[delay=4,facing=west,locked=false,powered=false] +93:14|minecraft:repeater[delay=4,facing=north,locked=false,powered=false] +93:15|minecraft:repeater[delay=4,facing=east,locked=false,powered=false] +94:0|minecraft:repeater[delay=1,facing=south,locked=false,powered=true] +94:1|minecraft:repeater[delay=1,facing=west,locked=false,powered=true] +94:2|minecraft:repeater[delay=1,facing=north,locked=false,powered=true] +94:3|minecraft:repeater[delay=1,facing=east,locked=false,powered=true] +94:4|minecraft:repeater[delay=2,facing=south,locked=false,powered=true] +94:5|minecraft:repeater[delay=2,facing=west,locked=false,powered=true] +94:6|minecraft:repeater[delay=2,facing=north,locked=false,powered=true] +94:7|minecraft:repeater[delay=2,facing=east,locked=false,powered=true] +94:8|minecraft:repeater[delay=3,facing=south,locked=false,powered=true] +94:9|minecraft:repeater[delay=3,facing=west,locked=false,powered=true] +94:10|minecraft:repeater[delay=3,facing=north,locked=false,powered=true] +94:11|minecraft:repeater[delay=3,facing=east,locked=false,powered=true] +94:12|minecraft:repeater[delay=4,facing=south,locked=false,powered=true] +94:13|minecraft:repeater[delay=4,facing=west,locked=false,powered=true] +94:14|minecraft:repeater[delay=4,facing=north,locked=false,powered=true] +94:15|minecraft:repeater[delay=4,facing=east,locked=false,powered=true] +95:0|minecraft:white_stained_glass +95:1|minecraft:orange_stained_glass +95:2|minecraft:magenta_stained_glass +95:3|minecraft:light_blue_stained_glass +95:4|minecraft:yellow_stained_glass +95:5|minecraft:lime_stained_glass +95:6|minecraft:pink_stained_glass +95:7|minecraft:gray_stained_glass +95:8|minecraft:light_gray_stained_glass +95:9|minecraft:cyan_stained_glass +95:10|minecraft:purple_stained_glass +95:11|minecraft:blue_stained_glass +95:12|minecraft:brown_stained_glass +95:13|minecraft:green_stained_glass +95:14|minecraft:red_stained_glass +95:15|minecraft:black_stained_glass +96:0|minecraft:oak_trapdoor[half=bottom,facing=north,open=false,powered=false] +96:1|minecraft:oak_trapdoor[half=bottom,facing=south,open=false,powered=false] +96:2|minecraft:oak_trapdoor[half=bottom,facing=west,open=false,powered=false] +96:3|minecraft:oak_trapdoor[half=bottom,facing=east,open=false,powered=false] +96:4|minecraft:oak_trapdoor[half=bottom,facing=north,open=true,powered=true] +96:5|minecraft:oak_trapdoor[half=bottom,facing=south,open=true,powered=true] +96:6|minecraft:oak_trapdoor[half=bottom,facing=west,open=true,powered=true] +96:7|minecraft:oak_trapdoor[half=bottom,facing=east,open=true,powered=true] +96:8|minecraft:oak_trapdoor[half=top,facing=north,open=false,powered=false] +96:9|minecraft:oak_trapdoor[half=top,facing=south,open=false,powered=false] +96:10|minecraft:oak_trapdoor[half=top,facing=west,open=false,powered=false] +96:11|minecraft:oak_trapdoor[half=top,facing=east,open=false,powered=false] +96:12|minecraft:oak_trapdoor[half=top,facing=north,open=true,powered=true] +96:13|minecraft:oak_trapdoor[half=top,facing=south,open=true,powered=true] +96:14|minecraft:oak_trapdoor[half=top,facing=west,open=true,powered=true] +96:15|minecraft:oak_trapdoor[half=top,facing=east,open=true,powered=true] +97:0|minecraft:infested_stone +97:1|minecraft:infested_cobblestone +97:2|minecraft:infested_stone_bricks +97:3|minecraft:infested_mossy_stone_bricks +97:4|minecraft:infested_cracked_stone_bricks +97:5|minecraft:infested_chiseled_stone_bricks +98:0|minecraft:stone_bricks +98:1|minecraft:mossy_stone_bricks +98:2|minecraft:cracked_stone_bricks +98:3|minecraft:chiseled_stone_bricks +99:0|minecraft:brown_mushroom_block[north=false,east=false,south=false,west=false,up=false,down=false] +99:1|minecraft:brown_mushroom_block[north=true,east=false,south=false,west=true,up=true,down=false] +99:2|minecraft:brown_mushroom_block[north=true,east=false,south=false,west=false,up=true,down=false] +99:3|minecraft:brown_mushroom_block[north=true,east=true,south=false,west=false,up=true,down=false] +99:4|minecraft:brown_mushroom_block[north=false,east=false,south=false,west=true,up=true,down=false] +99:5|minecraft:brown_mushroom_block[north=false,east=false,south=false,west=false,up=true,down=false] +99:6|minecraft:brown_mushroom_block[north=false,east=true,south=false,west=false,up=true,down=false] +99:7|minecraft:brown_mushroom_block[north=false,east=false,south=true,west=true,up=true,down=false] +99:8|minecraft:brown_mushroom_block[north=false,east=false,south=true,west=false,up=true,down=false] +99:9|minecraft:brown_mushroom_block[north=false,east=true,south=true,west=false,up=true,down=false] +99:10|minecraft:mushroom_stem[north=true,east=true,south=true,west=true,up=false,down=false] +99:14|minecraft:brown_mushroom_block[north=true,east=true,south=true,west=true,up=true,down=true] +99:15|minecraft:mushroom_stem[north=true,east=true,south=true,west=true,up=true,down=true] +100:0|minecraft:red_mushroom_block[north=false,east=false,south=false,west=false,up=false,down=false] +100:1|minecraft:red_mushroom_block[north=true,east=false,south=false,west=true,up=true,down=false] +100:2|minecraft:red_mushroom_block[north=true,east=false,south=false,west=false,up=true,down=false] +100:3|minecraft:red_mushroom_block[north=true,east=true,south=false,west=false,up=true,down=false] +100:4|minecraft:red_mushroom_block[north=false,east=false,south=false,west=true,up=true,down=false] +100:5|minecraft:red_mushroom_block[north=false,east=false,south=false,west=false,up=true,down=false] +100:6|minecraft:red_mushroom_block[north=false,east=true,south=false,west=false,up=true,down=false] +100:7|minecraft:red_mushroom_block[north=false,east=false,south=true,west=true,up=true,down=false] +100:8|minecraft:red_mushroom_block[north=false,east=false,south=true,west=false,up=true,down=false] +100:9|minecraft:red_mushroom_block[north=false,east=true,south=true,west=false,up=true,down=false] +100:10|minecraft:mushroom_stem[north=true,east=true,south=true,west=true,up=false,down=false] +100:14|minecraft:red_mushroom_block[north=true,east=true,south=true,west=true,up=true,down=true] +100:15|minecraft:mushroom_stem[north=true,east=true,south=true,west=true,up=true,down=true] +101:0|minecraft:iron_bars[east=false,south=false,north=false,west=false] +102:0|minecraft:glass_pane[east=false,south=false,north=false,west=false] +103:0|minecraft:melon +104:0|minecraft:pumpkin_stem[age=0] +104:1|minecraft:pumpkin_stem[age=1] +104:2|minecraft:pumpkin_stem[age=2] +104:3|minecraft:pumpkin_stem[age=3] +104:4|minecraft:pumpkin_stem[age=4] +104:5|minecraft:pumpkin_stem[age=5] +104:6|minecraft:pumpkin_stem[age=6] +104:7|minecraft:pumpkin_stem[age=7] +105:0|minecraft:melon_stem[age=0] +105:1|minecraft:melon_stem[age=1] +105:2|minecraft:melon_stem[age=2] +105:3|minecraft:melon_stem[age=3] +105:4|minecraft:melon_stem[age=4] +105:5|minecraft:melon_stem[age=5] +105:6|minecraft:melon_stem[age=6] +105:7|minecraft:melon_stem[age=7] +106:0|minecraft:vine[east=false,south=false,north=false,west=false,up=false] +106:1|minecraft:vine[east=false,south=true,north=false,west=false,up=false] +106:2|minecraft:vine[east=false,south=false,north=false,west=true,up=false] +106:3|minecraft:vine[east=false,south=true,north=false,west=true,up=false] +106:4|minecraft:vine[east=false,south=false,north=true,west=false,up=false] +106:5|minecraft:vine[east=false,south=true,north=true,west=false,up=false] +106:6|minecraft:vine[east=false,south=false,north=true,west=true,up=false] +106:7|minecraft:vine[east=false,south=true,north=true,west=true,up=false] +106:8|minecraft:vine[east=true,south=false,north=false,west=false,up=false] +106:9|minecraft:vine[east=true,south=true,north=false,west=false,up=false] +106:10|minecraft:vine[east=true,south=false,north=false,west=true,up=false] +106:11|minecraft:vine[east=true,south=true,north=false,west=true,up=false] +106:12|minecraft:vine[east=true,south=false,north=true,west=false,up=false] +106:13|minecraft:vine[east=true,south=true,north=true,west=false,up=false] +106:14|minecraft:vine[east=true,south=false,north=true,west=true,up=false] +106:15|minecraft:vine[east=true,south=true,north=true,west=true,up=false] +107:0|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=south,open=false] +107:1|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=west,open=false] +107:2|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=north,open=false] +107:3|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=east,open=false] +107:4|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=south,open=true] +107:5|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=west,open=true] +107:6|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=north,open=true] +107:7|minecraft:oak_fence_gate[in_wall=false,powered=false,facing=east,open=true] +107:8|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=south,open=false] +107:9|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=west,open=false] +107:10|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=north,open=false] +107:11|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=east,open=false] +107:12|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=south,open=true] +107:13|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=west,open=true] +107:14|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=north,open=true] +107:15|minecraft:oak_fence_gate[in_wall=false,powered=true,facing=east,open=true] +108:0|minecraft:brick_stairs[half=bottom,shape=straight,facing=east] +108:1|minecraft:brick_stairs[half=bottom,shape=straight,facing=west] +108:2|minecraft:brick_stairs[half=bottom,shape=straight,facing=south] +108:3|minecraft:brick_stairs[half=bottom,shape=straight,facing=north] +108:4|minecraft:brick_stairs[half=top,shape=straight,facing=east] +108:5|minecraft:brick_stairs[half=top,shape=straight,facing=west] +108:6|minecraft:brick_stairs[half=top,shape=straight,facing=south] +108:7|minecraft:brick_stairs[half=top,shape=straight,facing=north] +109:0|minecraft:stone_brick_stairs[half=bottom,shape=straight,facing=east] +109:1|minecraft:stone_brick_stairs[half=bottom,shape=straight,facing=west] +109:2|minecraft:stone_brick_stairs[half=bottom,shape=straight,facing=south] +109:3|minecraft:stone_brick_stairs[half=bottom,shape=straight,facing=north] +109:4|minecraft:stone_brick_stairs[half=top,shape=straight,facing=east] +109:5|minecraft:stone_brick_stairs[half=top,shape=straight,facing=west] +109:6|minecraft:stone_brick_stairs[half=top,shape=straight,facing=south] +109:7|minecraft:stone_brick_stairs[half=top,shape=straight,facing=north] +110:0|minecraft:mycelium[snowy=false] +111:0|minecraft:lily_pad +112:0|minecraft:nether_bricks +113:0|minecraft:nether_brick_fence[east=false,south=false,north=false,west=false] +114:0|minecraft:nether_brick_stairs[half=bottom,shape=straight,facing=east] +114:1|minecraft:nether_brick_stairs[half=bottom,shape=straight,facing=west] +114:2|minecraft:nether_brick_stairs[half=bottom,shape=straight,facing=south] +114:3|minecraft:nether_brick_stairs[half=bottom,shape=straight,facing=north] +114:4|minecraft:nether_brick_stairs[half=top,shape=straight,facing=east] +114:5|minecraft:nether_brick_stairs[half=top,shape=straight,facing=west] +114:6|minecraft:nether_brick_stairs[half=top,shape=straight,facing=south] +114:7|minecraft:nether_brick_stairs[half=top,shape=straight,facing=north] +115:0|minecraft:nether_wart[age=0] +115:1|minecraft:nether_wart[age=1] +115:2|minecraft:nether_wart[age=2] +115:3|minecraft:nether_wart[age=3] +116:0|minecraft:enchanting_table +117:0|minecraft:brewing_stand[has_bottle_0=false,has_bottle_1=false,has_bottle_2=false] +117:1|minecraft:brewing_stand[has_bottle_0=true,has_bottle_1=false,has_bottle_2=false] +117:2|minecraft:brewing_stand[has_bottle_0=false,has_bottle_1=true,has_bottle_2=false] +117:3|minecraft:brewing_stand[has_bottle_0=true,has_bottle_1=true,has_bottle_2=false] +117:4|minecraft:brewing_stand[has_bottle_0=false,has_bottle_1=false,has_bottle_2=true] +117:5|minecraft:brewing_stand[has_bottle_0=true,has_bottle_1=false,has_bottle_2=true] +117:6|minecraft:brewing_stand[has_bottle_0=false,has_bottle_1=true,has_bottle_2=true] +117:7|minecraft:brewing_stand[has_bottle_0=true,has_bottle_1=true,has_bottle_2=true] +118:0|minecraft:cauldron[level=0] +118:1|minecraft:cauldron[level=1] +118:2|minecraft:cauldron[level=2] +118:3|minecraft:cauldron[level=3] +119:0|minecraft:end_portal +120:0|minecraft:end_portal_frame[eye=false,facing=south] +120:1|minecraft:end_portal_frame[eye=false,facing=west] +120:2|minecraft:end_portal_frame[eye=false,facing=north] +120:3|minecraft:end_portal_frame[eye=false,facing=east] +120:4|minecraft:end_portal_frame[eye=true,facing=south] +120:5|minecraft:end_portal_frame[eye=true,facing=west] +120:6|minecraft:end_portal_frame[eye=true,facing=north] +120:7|minecraft:end_portal_frame[eye=true,facing=east] +121:0|minecraft:end_stone +122:0|minecraft:dragon_egg +123:0|minecraft:redstone_lamp[lit=false] +124:0|minecraft:redstone_lamp[lit=true] +125:0|minecraft:oak_slab[type=double] +125:1|minecraft:spruce_slab[type=double] +125:2|minecraft:birch_slab[type=double] +125:3|minecraft:jungle_slab[type=double] +125:4|minecraft:acacia_slab[type=double] +125:5|minecraft:dark_oak_slab[type=double] +126:0|minecraft:oak_slab[type=bottom] +126:1|minecraft:spruce_slab[type=bottom] +126:2|minecraft:birch_slab[type=bottom] +126:3|minecraft:jungle_slab[type=bottom] +126:4|minecraft:acacia_slab[type=bottom] +126:5|minecraft:dark_oak_slab[type=bottom] +126:8|minecraft:oak_slab[type=top] +126:9|minecraft:spruce_slab[type=top] +126:10|minecraft:birch_slab[type=top] +126:11|minecraft:jungle_slab[type=top] +126:12|minecraft:acacia_slab[type=top] +126:13|minecraft:dark_oak_slab[type=top] +127:0|minecraft:cocoa[facing=south,age=0] +127:1|minecraft:cocoa[facing=west,age=0] +127:2|minecraft:cocoa[facing=north,age=0] +127:3|minecraft:cocoa[facing=east,age=0] +127:4|minecraft:cocoa[facing=south,age=1] +127:5|minecraft:cocoa[facing=west,age=1] +127:6|minecraft:cocoa[facing=north,age=1] +127:7|minecraft:cocoa[facing=east,age=1] +127:8|minecraft:cocoa[facing=south,age=2] +127:9|minecraft:cocoa[facing=west,age=2] +127:10|minecraft:cocoa[facing=north,age=2] +127:11|minecraft:cocoa[facing=east,age=2] +128:0|minecraft:sandstone_stairs[half=bottom,shape=straight,facing=east] +128:1|minecraft:sandstone_stairs[half=bottom,shape=straight,facing=west] +128:2|minecraft:sandstone_stairs[half=bottom,shape=straight,facing=south] +128:3|minecraft:sandstone_stairs[half=bottom,shape=straight,facing=north] +128:4|minecraft:sandstone_stairs[half=top,shape=straight,facing=east] +128:5|minecraft:sandstone_stairs[half=top,shape=straight,facing=west] +128:6|minecraft:sandstone_stairs[half=top,shape=straight,facing=south] +128:7|minecraft:sandstone_stairs[half=top,shape=straight,facing=north] +129:0|minecraft:emerald_ore +130:2|minecraft:ender_chest[facing=north] +130:3|minecraft:ender_chest[facing=south] +130:4|minecraft:ender_chest[facing=west] +130:5|minecraft:ender_chest[facing=east] +131:0|minecraft:tripwire_hook[powered=false,attached=false,facing=south] +131:1|minecraft:tripwire_hook[powered=false,attached=false,facing=west] +131:2|minecraft:tripwire_hook[powered=false,attached=false,facing=north] +131:3|minecraft:tripwire_hook[powered=false,attached=false,facing=east] +131:4|minecraft:tripwire_hook[powered=false,attached=true,facing=south] +131:5|minecraft:tripwire_hook[powered=false,attached=true,facing=west] +131:6|minecraft:tripwire_hook[powered=false,attached=true,facing=north] +131:7|minecraft:tripwire_hook[powered=false,attached=true,facing=east] +131:8|minecraft:tripwire_hook[powered=true,attached=false,facing=south] +131:9|minecraft:tripwire_hook[powered=true,attached=false,facing=west] +131:10|minecraft:tripwire_hook[powered=true,attached=false,facing=north] +131:11|minecraft:tripwire_hook[powered=true,attached=false,facing=east] +131:12|minecraft:tripwire_hook[powered=true,attached=true,facing=south] +131:13|minecraft:tripwire_hook[powered=true,attached=true,facing=west] +131:14|minecraft:tripwire_hook[powered=true,attached=true,facing=north] +131:15|minecraft:tripwire_hook[powered=true,attached=true,facing=east] +132:0|minecraft:tripwire[disarmed=false,east=false,powered=false,south=false,north=false,west=false,attached=false] +132:1|minecraft:tripwire[disarmed=false,east=false,powered=true,south=false,north=false,west=false,attached=false] +132:4|minecraft:tripwire[disarmed=false,east=false,powered=false,south=false,north=false,west=false,attached=true] +132:5|minecraft:tripwire[disarmed=false,east=false,powered=true,south=false,north=false,west=false,attached=true] +132:8|minecraft:tripwire[disarmed=true,east=false,powered=false,south=false,north=false,west=false,attached=false] +132:9|minecraft:tripwire[disarmed=true,east=false,powered=true,south=false,north=false,west=false,attached=false] +132:12|minecraft:tripwire[disarmed=true,east=false,powered=false,south=false,north=false,west=false,attached=true] +132:13|minecraft:tripwire[disarmed=true,east=false,powered=true,south=false,north=false,west=false,attached=true] +133:0|minecraft:emerald_block +134:0|minecraft:spruce_stairs[half=bottom,shape=straight,facing=east] +134:1|minecraft:spruce_stairs[half=bottom,shape=straight,facing=west] +134:2|minecraft:spruce_stairs[half=bottom,shape=straight,facing=south] +134:3|minecraft:spruce_stairs[half=bottom,shape=straight,facing=north] +134:4|minecraft:spruce_stairs[half=top,shape=straight,facing=east] +134:5|minecraft:spruce_stairs[half=top,shape=straight,facing=west] +134:6|minecraft:spruce_stairs[half=top,shape=straight,facing=south] +134:7|minecraft:spruce_stairs[half=top,shape=straight,facing=north] +135:0|minecraft:birch_stairs[half=bottom,shape=straight,facing=east] +135:1|minecraft:birch_stairs[half=bottom,shape=straight,facing=west] +135:2|minecraft:birch_stairs[half=bottom,shape=straight,facing=south] +135:3|minecraft:birch_stairs[half=bottom,shape=straight,facing=north] +135:4|minecraft:birch_stairs[half=top,shape=straight,facing=east] +135:5|minecraft:birch_stairs[half=top,shape=straight,facing=west] +135:6|minecraft:birch_stairs[half=top,shape=straight,facing=south] +135:7|minecraft:birch_stairs[half=top,shape=straight,facing=north] +136:0|minecraft:jungle_stairs[half=bottom,shape=straight,facing=east] +136:1|minecraft:jungle_stairs[half=bottom,shape=straight,facing=west] +136:2|minecraft:jungle_stairs[half=bottom,shape=straight,facing=south] +136:3|minecraft:jungle_stairs[half=bottom,shape=straight,facing=north] +136:4|minecraft:jungle_stairs[half=top,shape=straight,facing=east] +136:5|minecraft:jungle_stairs[half=top,shape=straight,facing=west] +136:6|minecraft:jungle_stairs[half=top,shape=straight,facing=south] +136:7|minecraft:jungle_stairs[half=top,shape=straight,facing=north] +137:0|minecraft:command_block[conditional=false,facing=down] +137:1|minecraft:command_block[conditional=false,facing=up] +137:2|minecraft:command_block[conditional=false,facing=north] +137:3|minecraft:command_block[conditional=false,facing=south] +137:4|minecraft:command_block[conditional=false,facing=west] +137:5|minecraft:command_block[conditional=false,facing=east] +137:8|minecraft:command_block[conditional=true,facing=down] +137:9|minecraft:command_block[conditional=true,facing=up] +137:10|minecraft:command_block[conditional=true,facing=north] +137:11|minecraft:command_block[conditional=true,facing=south] +137:12|minecraft:command_block[conditional=true,facing=west] +137:13|minecraft:command_block[conditional=true,facing=east] +138:0|minecraft:beacon +139:0|minecraft:cobblestone_wall[east=false,south=false,north=false,west=false,up=false] +139:1|minecraft:mossy_cobblestone_wall[east=false,south=false,north=false,west=false,up=false] +140:0|minecraft:flower_pot +140:1|minecraft:potted_poppy +140:2|minecraft:potted_dandelion +140:3|minecraft:potted_oak_sapling +140:4|minecraft:potted_spruce_sapling +140:5|minecraft:potted_birch_sapling +140:6|minecraft:potted_jungle_sapling +140:7|minecraft:potted_red_mushroom +140:8|minecraft:potted_brown_mushroom +140:9|minecraft:potted_cactus +140:10|minecraft:potted_dead_bush +140:11|minecraft:potted_fern +140:12|minecraft:potted_acacia_sapling +140:13|minecraft:potted_dark_oak_sapling +140:14|minecraft:potted_blue_orchid +140:15|minecraft:potted_allium +141:0|minecraft:carrots[age=0] +141:1|minecraft:carrots[age=1] +141:2|minecraft:carrots[age=2] +141:3|minecraft:carrots[age=3] +141:4|minecraft:carrots[age=4] +141:5|minecraft:carrots[age=5] +141:6|minecraft:carrots[age=6] +141:7|minecraft:carrots[age=7] +142:0|minecraft:potatoes[age=0] +142:1|minecraft:potatoes[age=1] +142:2|minecraft:potatoes[age=2] +142:3|minecraft:potatoes[age=3] +142:4|minecraft:potatoes[age=4] +142:5|minecraft:potatoes[age=5] +142:6|minecraft:potatoes[age=6] +142:7|minecraft:potatoes[age=7] +143:0|minecraft:oak_button[powered=false,facing=east,face=ceiling] +143:1|minecraft:oak_button[powered=false,facing=east,face=wall] +143:2|minecraft:oak_button[powered=false,facing=west,face=wall] +143:3|minecraft:oak_button[powered=false,facing=south,face=wall] +143:4|minecraft:oak_button[powered=false,facing=north,face=wall] +143:5|minecraft:oak_button[powered=false,facing=east,face=floor] +143:8|minecraft:oak_button[powered=true,facing=south,face=ceiling] +143:9|minecraft:oak_button[powered=true,facing=east,face=wall] +143:10|minecraft:oak_button[powered=true,facing=west,face=wall] +143:11|minecraft:oak_button[powered=true,facing=south,face=wall] +143:12|minecraft:oak_button[powered=true,facing=north,face=wall] +143:13|minecraft:oak_button[powered=true,facing=south,face=floor] +144:0|minecraft:skeleton_skull[rotation=0] +144:1|minecraft:skeleton_skull[rotation=4] +144:2|minecraft:skeleton_wall_skull[facing=north] +144:3|minecraft:skeleton_wall_skull[facing=south] +144:4|minecraft:skeleton_wall_skull[facing=west] +144:5|minecraft:skeleton_wall_skull[facing=east] +144:8|minecraft:skeleton_skull[rotation=8] +144:9|minecraft:skeleton_skull[rotation=12] +144:10|minecraft:skeleton_wall_skull[facing=north] +144:11|minecraft:skeleton_wall_skull[facing=south] +144:12|minecraft:skeleton_wall_skull[facing=west] +144:13|minecraft:skeleton_wall_skull[facing=east] +145:0|minecraft:anvil[facing=south] +145:1|minecraft:anvil[facing=west] +145:2|minecraft:anvil[facing=north] +145:3|minecraft:anvil[facing=east] +145:4|minecraft:chipped_anvil[facing=south] +145:5|minecraft:chipped_anvil[facing=west] +145:6|minecraft:chipped_anvil[facing=north] +145:7|minecraft:chipped_anvil[facing=east] +145:8|minecraft:damaged_anvil[facing=south] +145:9|minecraft:damaged_anvil[facing=west] +145:10|minecraft:damaged_anvil[facing=north] +145:11|minecraft:damaged_anvil[facing=east] +146:2|minecraft:trapped_chest[facing=north,type=single] +146:3|minecraft:trapped_chest[facing=south,type=single] +146:4|minecraft:trapped_chest[facing=west,type=single] +146:5|minecraft:trapped_chest[facing=east,type=single] +147:0|minecraft:light_weighted_pressure_plate[power=0] +147:1|minecraft:light_weighted_pressure_plate[power=1] +147:2|minecraft:light_weighted_pressure_plate[power=2] +147:3|minecraft:light_weighted_pressure_plate[power=3] +147:4|minecraft:light_weighted_pressure_plate[power=4] +147:5|minecraft:light_weighted_pressure_plate[power=5] +147:6|minecraft:light_weighted_pressure_plate[power=6] +147:7|minecraft:light_weighted_pressure_plate[power=7] +147:8|minecraft:light_weighted_pressure_plate[power=8] +147:9|minecraft:light_weighted_pressure_plate[power=9] +147:10|minecraft:light_weighted_pressure_plate[power=10] +147:11|minecraft:light_weighted_pressure_plate[power=11] +147:12|minecraft:light_weighted_pressure_plate[power=12] +147:13|minecraft:light_weighted_pressure_plate[power=13] +147:14|minecraft:light_weighted_pressure_plate[power=14] +147:15|minecraft:light_weighted_pressure_plate[power=15] +148:0|minecraft:heavy_weighted_pressure_plate[power=0] +148:1|minecraft:heavy_weighted_pressure_plate[power=1] +148:2|minecraft:heavy_weighted_pressure_plate[power=2] +148:3|minecraft:heavy_weighted_pressure_plate[power=3] +148:4|minecraft:heavy_weighted_pressure_plate[power=4] +148:5|minecraft:heavy_weighted_pressure_plate[power=5] +148:6|minecraft:heavy_weighted_pressure_plate[power=6] +148:7|minecraft:heavy_weighted_pressure_plate[power=7] +148:8|minecraft:heavy_weighted_pressure_plate[power=8] +148:9|minecraft:heavy_weighted_pressure_plate[power=9] +148:10|minecraft:heavy_weighted_pressure_plate[power=10] +148:11|minecraft:heavy_weighted_pressure_plate[power=11] +148:12|minecraft:heavy_weighted_pressure_plate[power=12] +148:13|minecraft:heavy_weighted_pressure_plate[power=13] +148:14|minecraft:heavy_weighted_pressure_plate[power=14] +148:15|minecraft:heavy_weighted_pressure_plate[power=15] +149:0|minecraft:comparator[mode=compare,powered=false,facing=south] +149:1|minecraft:comparator[mode=compare,powered=false,facing=west] +149:2|minecraft:comparator[mode=compare,powered=false,facing=north] +149:3|minecraft:comparator[mode=compare,powered=false,facing=east] +149:4|minecraft:comparator[mode=subtract,powered=false,facing=south] +149:5|minecraft:comparator[mode=subtract,powered=false,facing=west] +149:6|minecraft:comparator[mode=subtract,powered=false,facing=north] +149:7|minecraft:comparator[mode=subtract,powered=false,facing=east] +149:8|minecraft:comparator[mode=compare,powered=false,facing=south] +149:9|minecraft:comparator[mode=compare,powered=false,facing=west] +149:10|minecraft:comparator[mode=compare,powered=false,facing=north] +149:11|minecraft:comparator[mode=compare,powered=false,facing=east] +149:12|minecraft:comparator[mode=subtract,powered=false,facing=south] +149:13|minecraft:comparator[mode=subtract,powered=false,facing=west] +149:14|minecraft:comparator[mode=subtract,powered=false,facing=north] +149:15|minecraft:comparator[mode=subtract,powered=false,facing=east] +150:0|minecraft:comparator[mode=compare,powered=true,facing=south] +150:1|minecraft:comparator[mode=compare,powered=true,facing=west] +150:2|minecraft:comparator[mode=compare,powered=true,facing=north] +150:3|minecraft:comparator[mode=compare,powered=true,facing=east] +150:4|minecraft:comparator[mode=subtract,powered=true,facing=south] +150:5|minecraft:comparator[mode=subtract,powered=true,facing=west] +150:6|minecraft:comparator[mode=subtract,powered=true,facing=north] +150:7|minecraft:comparator[mode=subtract,powered=true,facing=east] +150:8|minecraft:comparator[mode=compare,powered=true,facing=south] +150:9|minecraft:comparator[mode=compare,powered=true,facing=west] +150:10|minecraft:comparator[mode=compare,powered=true,facing=north] +150:11|minecraft:comparator[mode=compare,powered=true,facing=east] +150:12|minecraft:comparator[mode=subtract,powered=true,facing=south] +150:13|minecraft:comparator[mode=subtract,powered=true,facing=west] +150:14|minecraft:comparator[mode=subtract,powered=true,facing=north] +150:15|minecraft:comparator[mode=subtract,powered=true,facing=east] +151:0|minecraft:daylight_detector[inverted=false,power=0] +151:1|minecraft:daylight_detector[inverted=false,power=1] +151:2|minecraft:daylight_detector[inverted=false,power=2] +151:3|minecraft:daylight_detector[inverted=false,power=3] +151:4|minecraft:daylight_detector[inverted=false,power=4] +151:5|minecraft:daylight_detector[inverted=false,power=5] +151:6|minecraft:daylight_detector[inverted=false,power=6] +151:7|minecraft:daylight_detector[inverted=false,power=7] +151:8|minecraft:daylight_detector[inverted=false,power=8] +151:9|minecraft:daylight_detector[inverted=false,power=9] +151:10|minecraft:daylight_detector[inverted=false,power=10] +151:11|minecraft:daylight_detector[inverted=false,power=11] +151:12|minecraft:daylight_detector[inverted=false,power=12] +151:13|minecraft:daylight_detector[inverted=false,power=13] +151:14|minecraft:daylight_detector[inverted=false,power=14] +151:15|minecraft:daylight_detector[inverted=false,power=15] +152:0|minecraft:redstone_block +153:0|minecraft:nether_quartz_ore +154:0|minecraft:hopper[facing=down,enabled=true] +154:2|minecraft:hopper[facing=north,enabled=true] +154:3|minecraft:hopper[facing=south,enabled=true] +154:4|minecraft:hopper[facing=west,enabled=true] +154:5|minecraft:hopper[facing=east,enabled=true] +154:8|minecraft:hopper[facing=down,enabled=false] +154:10|minecraft:hopper[facing=north,enabled=false] +154:11|minecraft:hopper[facing=south,enabled=false] +154:12|minecraft:hopper[facing=west,enabled=false] +154:13|minecraft:hopper[facing=east,enabled=false] +155:0|minecraft:quartz_block +155:1|minecraft:chiseled_quartz_block +155:2|minecraft:quartz_pillar[axis=y] +155:3|minecraft:quartz_pillar[axis=x] +155:4|minecraft:quartz_pillar[axis=z] +155:6|minecraft:quartz_pillar[axis=x] +155:10|minecraft:quartz_pillar[axis=z] +156:0|minecraft:quartz_stairs[half=bottom,shape=straight,facing=east] +156:1|minecraft:quartz_stairs[half=bottom,shape=straight,facing=west] +156:2|minecraft:quartz_stairs[half=bottom,shape=straight,facing=south] +156:3|minecraft:quartz_stairs[half=bottom,shape=straight,facing=north] +156:4|minecraft:quartz_stairs[half=top,shape=straight,facing=east] +156:5|minecraft:quartz_stairs[half=top,shape=straight,facing=west] +156:6|minecraft:quartz_stairs[half=top,shape=straight,facing=south] +156:7|minecraft:quartz_stairs[half=top,shape=straight,facing=north] +157:0|minecraft:activator_rail[shape=north_south,powered=false] +157:1|minecraft:activator_rail[shape=east_west,powered=false] +157:2|minecraft:activator_rail[shape=ascending_east,powered=false] +157:3|minecraft:activator_rail[shape=ascending_west,powered=false] +157:4|minecraft:activator_rail[shape=ascending_north,powered=false] +157:5|minecraft:activator_rail[shape=ascending_south,powered=false] +157:8|minecraft:activator_rail[shape=north_south,powered=true] +157:9|minecraft:activator_rail[shape=east_west,powered=true] +157:10|minecraft:activator_rail[shape=ascending_east,powered=true] +157:11|minecraft:activator_rail[shape=ascending_west,powered=true] +157:12|minecraft:activator_rail[shape=ascending_north,powered=true] +157:13|minecraft:activator_rail[shape=ascending_south,powered=true] +158:0|minecraft:dropper[triggered=false,facing=down] +158:1|minecraft:dropper[triggered=false,facing=up] +158:2|minecraft:dropper[triggered=false,facing=north] +158:3|minecraft:dropper[triggered=false,facing=south] +158:4|minecraft:dropper[triggered=false,facing=west] +158:5|minecraft:dropper[triggered=false,facing=east] +158:8|minecraft:dropper[triggered=true,facing=down] +158:9|minecraft:dropper[triggered=true,facing=up] +158:10|minecraft:dropper[triggered=true,facing=north] +158:11|minecraft:dropper[triggered=true,facing=south] +158:12|minecraft:dropper[triggered=true,facing=west] +158:13|minecraft:dropper[triggered=true,facing=east] +159:0|minecraft:white_terracotta +159:1|minecraft:orange_terracotta +159:2|minecraft:magenta_terracotta +159:3|minecraft:light_blue_terracotta +159:4|minecraft:yellow_terracotta +159:5|minecraft:lime_terracotta +159:6|minecraft:pink_terracotta +159:7|minecraft:gray_terracotta +159:8|minecraft:light_gray_terracotta +159:9|minecraft:cyan_terracotta +159:10|minecraft:purple_terracotta +159:11|minecraft:blue_terracotta +159:12|minecraft:brown_terracotta +159:13|minecraft:green_terracotta +159:14|minecraft:red_terracotta +159:15|minecraft:black_terracotta +160:0|minecraft:white_stained_glass_pane[east=false,south=false,north=false,west=false] +160:1|minecraft:orange_stained_glass_pane[east=false,south=false,north=false,west=false] +160:2|minecraft:magenta_stained_glass_pane[east=false,south=false,north=false,west=false] +160:3|minecraft:light_blue_stained_glass_pane[east=false,south=false,north=false,west=false] +160:4|minecraft:yellow_stained_glass_pane[east=false,south=false,north=false,west=false] +160:5|minecraft:lime_stained_glass_pane[east=false,south=false,north=false,west=false] +160:6|minecraft:pink_stained_glass_pane[east=false,south=false,north=false,west=false] +160:7|minecraft:gray_stained_glass_pane[east=false,south=false,north=false,west=false] +160:8|minecraft:light_gray_stained_glass_pane[east=false,south=false,north=false,west=false] +160:9|minecraft:cyan_stained_glass_pane[east=false,south=false,north=false,west=false] +160:10|minecraft:purple_stained_glass_pane[east=false,south=false,north=false,west=false] +160:11|minecraft:blue_stained_glass_pane[east=false,south=false,north=false,west=false] +160:12|minecraft:brown_stained_glass_pane[east=false,south=false,north=false,west=false] +160:13|minecraft:green_stained_glass_pane[east=false,south=false,north=false,west=false] +160:14|minecraft:red_stained_glass_pane[east=false,south=false,north=false,west=false] +160:15|minecraft:black_stained_glass_pane[east=false,south=false,north=false,west=false] +161:0|minecraft:acacia_leaves[persistent=false,distance=1] +161:1|minecraft:dark_oak_leaves[persistent=false,distance=1] +161:4|minecraft:acacia_leaves[persistent=true,distance=1] +161:5|minecraft:dark_oak_leaves[persistent=true,distance=1] +161:8|minecraft:acacia_leaves[persistent=false,distance=1] +161:9|minecraft:dark_oak_leaves[persistent=false,distance=1] +161:12|minecraft:acacia_leaves[persistent=true,distance=1] +161:13|minecraft:dark_oak_leaves[persistent=true,distance=1] +162:0|minecraft:acacia_log[axis=y] +162:1|minecraft:dark_oak_log[axis=y] +162:4|minecraft:acacia_log[axis=x] +162:5|minecraft:dark_oak_log[axis=x] +162:8|minecraft:acacia_log[axis=z] +162:9|minecraft:dark_oak_log[axis=z] +162:12|minecraft:acacia_wood +162:13|minecraft:dark_oak_wood +163:0|minecraft:acacia_stairs[half=bottom,shape=straight,facing=east] +163:1|minecraft:acacia_stairs[half=bottom,shape=straight,facing=west] +163:2|minecraft:acacia_stairs[half=bottom,shape=straight,facing=south] +163:3|minecraft:acacia_stairs[half=bottom,shape=straight,facing=north] +163:4|minecraft:acacia_stairs[half=top,shape=straight,facing=east] +163:5|minecraft:acacia_stairs[half=top,shape=straight,facing=west] +163:6|minecraft:acacia_stairs[half=top,shape=straight,facing=south] +163:7|minecraft:acacia_stairs[half=top,shape=straight,facing=north] +164:0|minecraft:dark_oak_stairs[half=bottom,shape=straight,facing=east] +164:1|minecraft:dark_oak_stairs[half=bottom,shape=straight,facing=west] +164:2|minecraft:dark_oak_stairs[half=bottom,shape=straight,facing=south] +164:3|minecraft:dark_oak_stairs[half=bottom,shape=straight,facing=north] +164:4|minecraft:dark_oak_stairs[half=top,shape=straight,facing=east] +164:5|minecraft:dark_oak_stairs[half=top,shape=straight,facing=west] +164:6|minecraft:dark_oak_stairs[half=top,shape=straight,facing=south] +164:7|minecraft:dark_oak_stairs[half=top,shape=straight,facing=north] +165:0|minecraft:slime_block +166:0|minecraft:barrier +167:0|minecraft:iron_trapdoor[half=bottom,facing=north,open=false] +167:1|minecraft:iron_trapdoor[half=bottom,facing=south,open=false] +167:2|minecraft:iron_trapdoor[half=bottom,facing=west,open=false] +167:3|minecraft:iron_trapdoor[half=bottom,facing=east,open=false] +167:4|minecraft:iron_trapdoor[half=bottom,facing=north,open=true] +167:5|minecraft:iron_trapdoor[half=bottom,facing=south,open=true] +167:6|minecraft:iron_trapdoor[half=bottom,facing=west,open=true] +167:7|minecraft:iron_trapdoor[half=bottom,facing=east,open=true] +167:8|minecraft:iron_trapdoor[half=top,facing=north,open=false] +167:9|minecraft:iron_trapdoor[half=top,facing=south,open=false] +167:10|minecraft:iron_trapdoor[half=top,facing=west,open=false] +167:11|minecraft:iron_trapdoor[half=top,facing=east,open=false] +167:12|minecraft:iron_trapdoor[half=top,facing=north,open=true] +167:13|minecraft:iron_trapdoor[half=top,facing=south,open=true] +167:14|minecraft:iron_trapdoor[half=top,facing=west,open=true] +167:15|minecraft:iron_trapdoor[half=top,facing=east,open=true] +168:0|minecraft:prismarine +168:1|minecraft:prismarine_bricks +168:2|minecraft:dark_prismarine +169:0|minecraft:sea_lantern +170:0|minecraft:hay_block[axis=y] +170:4|minecraft:hay_block[axis=x] +170:8|minecraft:hay_block[axis=z] +171:0|minecraft:white_carpet +171:1|minecraft:orange_carpet +171:2|minecraft:magenta_carpet +171:3|minecraft:light_blue_carpet +171:4|minecraft:yellow_carpet +171:5|minecraft:lime_carpet +171:6|minecraft:pink_carpet +171:7|minecraft:gray_carpet +171:8|minecraft:light_gray_carpet +171:9|minecraft:cyan_carpet +171:10|minecraft:purple_carpet +171:11|minecraft:blue_carpet +171:12|minecraft:brown_carpet +171:13|minecraft:green_carpet +171:14|minecraft:red_carpet +171:15|minecraft:black_carpet +172:0|minecraft:terracotta +173:0|minecraft:coal_block +174:0|minecraft:packed_ice +175:0|minecraft:sunflower[half=lower] +175:1|minecraft:lilac[half=lower] +175:2|minecraft:tall_grass[half=lower] +175:3|minecraft:large_fern[half=lower] +175:4|minecraft:rose_bush[half=lower] +175:5|minecraft:peony[half=lower] +175:8|minecraft:sunflower[half=upper] +175:9|minecraft:lilac[half=upper] +175:10|minecraft:tall_grass[half=upper] +175:11|minecraft:large_fern[half=upper] +175:12|minecraft:rose_bush[half=upper] +175:13|minecraft:peony[half=upper] +176:0|minecraft:white_banner[rotation=0] +176:1|minecraft:white_banner[rotation=1] +176:2|minecraft:white_banner[rotation=2] +176:3|minecraft:white_banner[rotation=3] +176:4|minecraft:white_banner[rotation=4] +176:5|minecraft:white_banner[rotation=5] +176:6|minecraft:white_banner[rotation=6] +176:7|minecraft:white_banner[rotation=7] +176:8|minecraft:white_banner[rotation=8] +176:9|minecraft:white_banner[rotation=9] +176:10|minecraft:white_banner[rotation=10] +176:11|minecraft:white_banner[rotation=11] +176:12|minecraft:white_banner[rotation=12] +176:13|minecraft:white_banner[rotation=13] +176:14|minecraft:white_banner[rotation=14] +176:15|minecraft:white_banner[rotation=15] +177:2|minecraft:white_wall_banner[facing=north] +177:3|minecraft:white_wall_banner[facing=south] +177:4|minecraft:white_wall_banner[facing=west] +177:5|minecraft:white_wall_banner[facing=east] +178:0|minecraft:daylight_detector[inverted=true,power=0] +178:1|minecraft:daylight_detector[inverted=true,power=1] +178:2|minecraft:daylight_detector[inverted=true,power=2] +178:3|minecraft:daylight_detector[inverted=true,power=3] +178:4|minecraft:daylight_detector[inverted=true,power=4] +178:5|minecraft:daylight_detector[inverted=true,power=5] +178:6|minecraft:daylight_detector[inverted=true,power=6] +178:7|minecraft:daylight_detector[inverted=true,power=7] +178:8|minecraft:daylight_detector[inverted=true,power=8] +178:9|minecraft:daylight_detector[inverted=true,power=9] +178:10|minecraft:daylight_detector[inverted=true,power=10] +178:11|minecraft:daylight_detector[inverted=true,power=11] +178:12|minecraft:daylight_detector[inverted=true,power=12] +178:13|minecraft:daylight_detector[inverted=true,power=13] +178:14|minecraft:daylight_detector[inverted=true,power=14] +178:15|minecraft:daylight_detector[inverted=true,power=15] +179:0|minecraft:red_sandstone +179:1|minecraft:chiseled_red_sandstone +179:2|minecraft:cut_red_sandstone +180:0|minecraft:red_sandstone_stairs[half=bottom,shape=straight,facing=east] +180:1|minecraft:red_sandstone_stairs[half=bottom,shape=straight,facing=west] +180:2|minecraft:red_sandstone_stairs[half=bottom,shape=straight,facing=south] +180:3|minecraft:red_sandstone_stairs[half=bottom,shape=straight,facing=north] +180:4|minecraft:red_sandstone_stairs[half=top,shape=straight,facing=east] +180:5|minecraft:red_sandstone_stairs[half=top,shape=straight,facing=west] +180:6|minecraft:red_sandstone_stairs[half=top,shape=straight,facing=south] +180:7|minecraft:red_sandstone_stairs[half=top,shape=straight,facing=north] +181:0|minecraft:red_sandstone_slab[type=double] +181:8|minecraft:smooth_red_sandstone +182:0|minecraft:red_sandstone_slab[type=bottom] +182:8|minecraft:red_sandstone_slab[type=top] +183:0|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=south,open=false] +183:1|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=west,open=false] +183:2|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=north,open=false] +183:3|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=east,open=false] +183:4|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=south,open=true] +183:5|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=west,open=true] +183:6|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=north,open=true] +183:7|minecraft:spruce_fence_gate[in_wall=false,powered=false,facing=east,open=true] +183:8|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=south,open=false] +183:9|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=west,open=false] +183:10|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=north,open=false] +183:11|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=east,open=false] +183:12|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=south,open=true] +183:13|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=west,open=true] +183:14|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=north,open=true] +183:15|minecraft:spruce_fence_gate[in_wall=false,powered=true,facing=east,open=true] +184:0|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=south,open=false] +184:1|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=west,open=false] +184:2|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=north,open=false] +184:3|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=east,open=false] +184:4|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=south,open=true] +184:5|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=west,open=true] +184:6|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=north,open=true] +184:7|minecraft:birch_fence_gate[in_wall=false,powered=false,facing=east,open=true] +184:8|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=south,open=false] +184:9|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=west,open=false] +184:10|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=north,open=false] +184:11|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=east,open=false] +184:12|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=south,open=true] +184:13|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=west,open=true] +184:14|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=north,open=true] +184:15|minecraft:birch_fence_gate[in_wall=false,powered=true,facing=east,open=true] +185:0|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=south,open=false] +185:1|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=west,open=false] +185:2|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=north,open=false] +185:3|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=east,open=false] +185:4|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=south,open=true] +185:5|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=west,open=true] +185:6|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=north,open=true] +185:7|minecraft:jungle_fence_gate[in_wall=false,powered=false,facing=east,open=true] +185:8|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=south,open=false] +185:9|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=west,open=false] +185:10|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=north,open=false] +185:11|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=east,open=false] +185:12|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=south,open=true] +185:13|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=west,open=true] +185:14|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=north,open=true] +185:15|minecraft:jungle_fence_gate[in_wall=false,powered=true,facing=east,open=true] +186:0|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=south,open=false] +186:1|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=west,open=false] +186:2|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=north,open=false] +186:3|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=east,open=false] +186:4|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=south,open=true] +186:5|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=west,open=true] +186:6|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=north,open=true] +186:7|minecraft:dark_oak_fence_gate[in_wall=false,powered=false,facing=east,open=true] +186:8|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=south,open=false] +186:9|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=west,open=false] +186:10|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=north,open=false] +186:11|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=east,open=false] +186:12|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=south,open=true] +186:13|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=west,open=true] +186:14|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=north,open=true] +186:15|minecraft:dark_oak_fence_gate[in_wall=false,powered=true,facing=east,open=true] +187:0|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=south,open=false] +187:1|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=west,open=false] +187:2|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=north,open=false] +187:3|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=east,open=false] +187:4|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=south,open=true] +187:5|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=west,open=true] +187:6|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=north,open=true] +187:7|minecraft:acacia_fence_gate[in_wall=false,powered=false,facing=east,open=true] +187:8|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=south,open=false] +187:9|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=west,open=false] +187:10|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=north,open=false] +187:11|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=east,open=false] +187:12|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=south,open=true] +187:13|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=west,open=true] +187:14|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=north,open=true] +187:15|minecraft:acacia_fence_gate[in_wall=false,powered=true,facing=east,open=true] +188:0|minecraft:spruce_fence[east=false,south=false,north=false,west=false] +189:0|minecraft:birch_fence[east=false,south=false,north=false,west=false] +190:0|minecraft:jungle_fence[east=false,south=false,north=false,west=false] +191:0|minecraft:dark_oak_fence[east=false,south=false,north=false,west=false] +192:0|minecraft:acacia_fence[east=false,south=false,north=false,west=false] +193:0|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=east,open=false] +193:1|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=south,open=false] +193:2|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=west,open=false] +193:3|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=north,open=false] +193:4|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=east,open=true] +193:5|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=south,open=true] +193:6|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=west,open=true] +193:7|minecraft:spruce_door[hinge=right,half=lower,powered=false,facing=north,open=true] +193:8|minecraft:spruce_door[hinge=left,half=upper,powered=false,facing=east,open=false] +193:9|minecraft:spruce_door[hinge=right,half=upper,powered=false,facing=east,open=false] +193:10|minecraft:spruce_door[hinge=left,half=upper,powered=true,facing=east,open=false] +193:11|minecraft:spruce_door[hinge=right,half=upper,powered=true,facing=east,open=false] +194:0|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=east,open=false] +194:1|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=south,open=false] +194:2|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=west,open=false] +194:3|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=north,open=false] +194:4|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=east,open=true] +194:5|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=south,open=true] +194:6|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=west,open=true] +194:7|minecraft:birch_door[hinge=right,half=lower,powered=false,facing=north,open=true] +194:8|minecraft:birch_door[hinge=left,half=upper,powered=false,facing=east,open=false] +194:9|minecraft:birch_door[hinge=right,half=upper,powered=false,facing=east,open=false] +194:10|minecraft:birch_door[hinge=left,half=upper,powered=true,facing=east,open=false] +194:11|minecraft:birch_door[hinge=right,half=upper,powered=true,facing=east,open=false] +195:0|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=east,open=false] +195:1|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=south,open=false] +195:2|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=west,open=false] +195:3|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=north,open=false] +195:4|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=east,open=true] +195:5|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=south,open=true] +195:6|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=west,open=true] +195:7|minecraft:jungle_door[hinge=right,half=lower,powered=false,facing=north,open=true] +195:8|minecraft:jungle_door[hinge=left,half=upper,powered=false,facing=east,open=false] +195:9|minecraft:jungle_door[hinge=right,half=upper,powered=false,facing=east,open=false] +195:10|minecraft:jungle_door[hinge=left,half=upper,powered=true,facing=east,open=false] +195:11|minecraft:jungle_door[hinge=right,half=upper,powered=true,facing=east,open=false] +196:0|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=east,open=false] +196:1|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=south,open=false] +196:2|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=west,open=false] +196:3|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=north,open=false] +196:4|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=east,open=true] +196:5|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=south,open=true] +196:6|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=west,open=true] +196:7|minecraft:acacia_door[hinge=right,half=lower,powered=false,facing=north,open=true] +196:8|minecraft:acacia_door[hinge=left,half=upper,powered=false,facing=east,open=false] +196:9|minecraft:acacia_door[hinge=right,half=upper,powered=false,facing=east,open=false] +196:10|minecraft:acacia_door[hinge=left,half=upper,powered=true,facing=east,open=false] +196:11|minecraft:acacia_door[hinge=right,half=upper,powered=true,facing=east,open=false] +197:0|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=east,open=false] +197:1|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=south,open=false] +197:2|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=west,open=false] +197:3|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=north,open=false] +197:4|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=east,open=true] +197:5|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=south,open=true] +197:6|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=west,open=true] +197:7|minecraft:dark_oak_door[hinge=right,half=lower,powered=false,facing=north,open=true] +197:8|minecraft:dark_oak_door[hinge=left,half=upper,powered=false,facing=east,open=false] +197:9|minecraft:dark_oak_door[hinge=right,half=upper,powered=false,facing=east,open=false] +197:10|minecraft:dark_oak_door[hinge=left,half=upper,powered=true,facing=east,open=false] +197:11|minecraft:dark_oak_door[hinge=right,half=upper,powered=true,facing=east,open=false] +198:0|minecraft:end_rod[facing=down] +198:1|minecraft:end_rod[facing=up] +198:2|minecraft:end_rod[facing=north] +198:3|minecraft:end_rod[facing=south] +198:4|minecraft:end_rod[facing=west] +198:5|minecraft:end_rod[facing=east] +199:0|minecraft:chorus_plant[east=false,south=false,north=false,west=false,up=false,down=false] +200:0|minecraft:chorus_flower[age=0] +200:1|minecraft:chorus_flower[age=1] +200:2|minecraft:chorus_flower[age=2] +200:3|minecraft:chorus_flower[age=3] +200:4|minecraft:chorus_flower[age=4] +200:5|minecraft:chorus_flower[age=5] +201:0|minecraft:purpur_block +202:0|minecraft:purpur_pillar[axis=y] +202:4|minecraft:purpur_pillar[axis=x] +202:8|minecraft:purpur_pillar[axis=z] +203:0|minecraft:purpur_stairs[half=bottom,shape=straight,facing=east] +203:1|minecraft:purpur_stairs[half=bottom,shape=straight,facing=west] +203:2|minecraft:purpur_stairs[half=bottom,shape=straight,facing=south] +203:3|minecraft:purpur_stairs[half=bottom,shape=straight,facing=north] +203:4|minecraft:purpur_stairs[half=top,shape=straight,facing=east] +203:5|minecraft:purpur_stairs[half=top,shape=straight,facing=west] +203:6|minecraft:purpur_stairs[half=top,shape=straight,facing=south] +203:7|minecraft:purpur_stairs[half=top,shape=straight,facing=north] +204:0|minecraft:purpur_slab[type=double] +205:0|minecraft:purpur_slab[type=bottom] +205:8|minecraft:purpur_slab[type=top] +206:0|minecraft:end_stone_bricks +207:0|minecraft:beetroots[age=0] +207:1|minecraft:beetroots[age=1] +207:2|minecraft:beetroots[age=2] +207:3|minecraft:beetroots[age=3] +208:0|minecraft:dirt_path +209:0|minecraft:end_gateway +210:0|minecraft:repeating_command_block[conditional=false,facing=down] +210:1|minecraft:repeating_command_block[conditional=false,facing=up] +210:2|minecraft:repeating_command_block[conditional=false,facing=north] +210:3|minecraft:repeating_command_block[conditional=false,facing=south] +210:4|minecraft:repeating_command_block[conditional=false,facing=west] +210:5|minecraft:repeating_command_block[conditional=false,facing=east] +210:8|minecraft:repeating_command_block[conditional=true,facing=down] +210:9|minecraft:repeating_command_block[conditional=true,facing=up] +210:10|minecraft:repeating_command_block[conditional=true,facing=north] +210:11|minecraft:repeating_command_block[conditional=true,facing=south] +210:12|minecraft:repeating_command_block[conditional=true,facing=west] +210:13|minecraft:repeating_command_block[conditional=true,facing=east] +211:0|minecraft:chain_command_block[conditional=false,facing=down] +211:1|minecraft:chain_command_block[conditional=false,facing=up] +211:2|minecraft:chain_command_block[conditional=false,facing=north] +211:3|minecraft:chain_command_block[conditional=false,facing=south] +211:4|minecraft:chain_command_block[conditional=false,facing=west] +211:5|minecraft:chain_command_block[conditional=false,facing=east] +211:8|minecraft:chain_command_block[conditional=true,facing=down] +211:9|minecraft:chain_command_block[conditional=true,facing=up] +211:10|minecraft:chain_command_block[conditional=true,facing=north] +211:11|minecraft:chain_command_block[conditional=true,facing=south] +211:12|minecraft:chain_command_block[conditional=true,facing=west] +211:13|minecraft:chain_command_block[conditional=true,facing=east] +212:0|minecraft:frosted_ice[age=0] +212:1|minecraft:frosted_ice[age=1] +212:2|minecraft:frosted_ice[age=2] +212:3|minecraft:frosted_ice[age=3] +213:0|minecraft:magma_block +214:0|minecraft:nether_wart_block +215:0|minecraft:red_nether_bricks +216:0|minecraft:bone_block[axis=y] +216:4|minecraft:bone_block[axis=x] +216:8|minecraft:bone_block[axis=z] +217:0|minecraft:structure_void +218:0|minecraft:observer[powered=false,facing=down] +218:1|minecraft:observer[powered=false,facing=up] +218:2|minecraft:observer[powered=false,facing=north] +218:3|minecraft:observer[powered=false,facing=south] +218:4|minecraft:observer[powered=false,facing=west] +218:5|minecraft:observer[powered=false,facing=east] +218:8|minecraft:observer[powered=true,facing=down] +218:9|minecraft:observer[powered=true,facing=up] +218:10|minecraft:observer[powered=true,facing=north] +218:11|minecraft:observer[powered=true,facing=south] +218:12|minecraft:observer[powered=true,facing=west] +218:13|minecraft:observer[powered=true,facing=east] +219:0|minecraft:white_shulker_box[facing=down] +219:1|minecraft:white_shulker_box[facing=up] +219:2|minecraft:white_shulker_box[facing=north] +219:3|minecraft:white_shulker_box[facing=south] +219:4|minecraft:white_shulker_box[facing=west] +219:5|minecraft:white_shulker_box[facing=east] +220:0|minecraft:orange_shulker_box[facing=down] +220:1|minecraft:orange_shulker_box[facing=up] +220:2|minecraft:orange_shulker_box[facing=north] +220:3|minecraft:orange_shulker_box[facing=south] +220:4|minecraft:orange_shulker_box[facing=west] +220:5|minecraft:orange_shulker_box[facing=east] +221:0|minecraft:magenta_shulker_box[facing=down] +221:1|minecraft:magenta_shulker_box[facing=up] +221:2|minecraft:magenta_shulker_box[facing=north] +221:3|minecraft:magenta_shulker_box[facing=south] +221:4|minecraft:magenta_shulker_box[facing=west] +221:5|minecraft:magenta_shulker_box[facing=east] +222:0|minecraft:light_blue_shulker_box[facing=down] +222:1|minecraft:light_blue_shulker_box[facing=up] +222:2|minecraft:light_blue_shulker_box[facing=north] +222:3|minecraft:light_blue_shulker_box[facing=south] +222:4|minecraft:light_blue_shulker_box[facing=west] +222:5|minecraft:light_blue_shulker_box[facing=east] +223:0|minecraft:yellow_shulker_box[facing=down] +223:1|minecraft:yellow_shulker_box[facing=up] +223:2|minecraft:yellow_shulker_box[facing=north] +223:3|minecraft:yellow_shulker_box[facing=south] +223:4|minecraft:yellow_shulker_box[facing=west] +223:5|minecraft:yellow_shulker_box[facing=east] +224:0|minecraft:lime_shulker_box[facing=down] +224:1|minecraft:lime_shulker_box[facing=up] +224:2|minecraft:lime_shulker_box[facing=north] +224:3|minecraft:lime_shulker_box[facing=south] +224:4|minecraft:lime_shulker_box[facing=west] +224:5|minecraft:lime_shulker_box[facing=east] +225:0|minecraft:pink_shulker_box[facing=down] +225:1|minecraft:pink_shulker_box[facing=up] +225:2|minecraft:pink_shulker_box[facing=north] +225:3|minecraft:pink_shulker_box[facing=south] +225:4|minecraft:pink_shulker_box[facing=west] +225:5|minecraft:pink_shulker_box[facing=east] +226:0|minecraft:gray_shulker_box[facing=down] +226:1|minecraft:gray_shulker_box[facing=up] +226:2|minecraft:gray_shulker_box[facing=north] +226:3|minecraft:gray_shulker_box[facing=south] +226:4|minecraft:gray_shulker_box[facing=west] +226:5|minecraft:gray_shulker_box[facing=east] +227:0|minecraft:light_gray_shulker_box[facing=down] +227:1|minecraft:light_gray_shulker_box[facing=up] +227:2|minecraft:light_gray_shulker_box[facing=north] +227:3|minecraft:light_gray_shulker_box[facing=south] +227:4|minecraft:light_gray_shulker_box[facing=west] +227:5|minecraft:light_gray_shulker_box[facing=east] +228:0|minecraft:cyan_shulker_box[facing=down] +228:1|minecraft:cyan_shulker_box[facing=up] +228:2|minecraft:cyan_shulker_box[facing=north] +228:3|minecraft:cyan_shulker_box[facing=south] +228:4|minecraft:cyan_shulker_box[facing=west] +228:5|minecraft:cyan_shulker_box[facing=east] +229:0|minecraft:purple_shulker_box[facing=down] +229:1|minecraft:purple_shulker_box[facing=up] +229:2|minecraft:purple_shulker_box[facing=north] +229:3|minecraft:purple_shulker_box[facing=south] +229:4|minecraft:purple_shulker_box[facing=west] +229:5|minecraft:purple_shulker_box[facing=east] +230:0|minecraft:blue_shulker_box[facing=down] +230:1|minecraft:blue_shulker_box[facing=up] +230:2|minecraft:blue_shulker_box[facing=north] +230:3|minecraft:blue_shulker_box[facing=south] +230:4|minecraft:blue_shulker_box[facing=west] +230:5|minecraft:blue_shulker_box[facing=east] +231:0|minecraft:brown_shulker_box[facing=down] +231:1|minecraft:brown_shulker_box[facing=up] +231:2|minecraft:brown_shulker_box[facing=north] +231:3|minecraft:brown_shulker_box[facing=south] +231:4|minecraft:brown_shulker_box[facing=west] +231:5|minecraft:brown_shulker_box[facing=east] +232:0|minecraft:green_shulker_box[facing=down] +232:1|minecraft:green_shulker_box[facing=up] +232:2|minecraft:green_shulker_box[facing=north] +232:3|minecraft:green_shulker_box[facing=south] +232:4|minecraft:green_shulker_box[facing=west] +232:5|minecraft:green_shulker_box[facing=east] +233:0|minecraft:red_shulker_box[facing=down] +233:1|minecraft:red_shulker_box[facing=up] +233:2|minecraft:red_shulker_box[facing=north] +233:3|minecraft:red_shulker_box[facing=south] +233:4|minecraft:red_shulker_box[facing=west] +233:5|minecraft:red_shulker_box[facing=east] +234:0|minecraft:black_shulker_box[facing=down] +234:1|minecraft:black_shulker_box[facing=up] +234:2|minecraft:black_shulker_box[facing=north] +234:3|minecraft:black_shulker_box[facing=south] +234:4|minecraft:black_shulker_box[facing=west] +234:5|minecraft:black_shulker_box[facing=east] +235:0|minecraft:white_glazed_terracotta[facing=south] +235:1|minecraft:white_glazed_terracotta[facing=west] +235:2|minecraft:white_glazed_terracotta[facing=north] +235:3|minecraft:white_glazed_terracotta[facing=east] +236:0|minecraft:orange_glazed_terracotta[facing=south] +236:1|minecraft:orange_glazed_terracotta[facing=west] +236:2|minecraft:orange_glazed_terracotta[facing=north] +236:3|minecraft:orange_glazed_terracotta[facing=east] +237:0|minecraft:magenta_glazed_terracotta[facing=south] +237:1|minecraft:magenta_glazed_terracotta[facing=west] +237:2|minecraft:magenta_glazed_terracotta[facing=north] +237:3|minecraft:magenta_glazed_terracotta[facing=east] +238:0|minecraft:light_blue_glazed_terracotta[facing=south] +238:1|minecraft:light_blue_glazed_terracotta[facing=west] +238:2|minecraft:light_blue_glazed_terracotta[facing=north] +238:3|minecraft:light_blue_glazed_terracotta[facing=east] +239:0|minecraft:yellow_glazed_terracotta[facing=south] +239:1|minecraft:yellow_glazed_terracotta[facing=west] +239:2|minecraft:yellow_glazed_terracotta[facing=north] +239:3|minecraft:yellow_glazed_terracotta[facing=east] +240:0|minecraft:lime_glazed_terracotta[facing=south] +240:1|minecraft:lime_glazed_terracotta[facing=west] +240:2|minecraft:lime_glazed_terracotta[facing=north] +240:3|minecraft:lime_glazed_terracotta[facing=east] +241:0|minecraft:pink_glazed_terracotta[facing=south] +241:1|minecraft:pink_glazed_terracotta[facing=west] +241:2|minecraft:pink_glazed_terracotta[facing=north] +241:3|minecraft:pink_glazed_terracotta[facing=east] +242:0|minecraft:gray_glazed_terracotta[facing=south] +242:1|minecraft:gray_glazed_terracotta[facing=west] +242:2|minecraft:gray_glazed_terracotta[facing=north] +242:3|minecraft:gray_glazed_terracotta[facing=east] +243:0|minecraft:light_gray_glazed_terracotta[facing=south] +243:1|minecraft:light_gray_glazed_terracotta[facing=west] +243:2|minecraft:light_gray_glazed_terracotta[facing=north] +243:3|minecraft:light_gray_glazed_terracotta[facing=east] +244:0|minecraft:cyan_glazed_terracotta[facing=south] +244:1|minecraft:cyan_glazed_terracotta[facing=west] +244:2|minecraft:cyan_glazed_terracotta[facing=north] +244:3|minecraft:cyan_glazed_terracotta[facing=east] +245:0|minecraft:purple_glazed_terracotta[facing=south] +245:1|minecraft:purple_glazed_terracotta[facing=west] +245:2|minecraft:purple_glazed_terracotta[facing=north] +245:3|minecraft:purple_glazed_terracotta[facing=east] +246:0|minecraft:blue_glazed_terracotta[facing=south] +246:1|minecraft:blue_glazed_terracotta[facing=west] +246:2|minecraft:blue_glazed_terracotta[facing=north] +246:3|minecraft:blue_glazed_terracotta[facing=east] +247:0|minecraft:brown_glazed_terracotta[facing=south] +247:1|minecraft:brown_glazed_terracotta[facing=west] +247:2|minecraft:brown_glazed_terracotta[facing=north] +247:3|minecraft:brown_glazed_terracotta[facing=east] +248:0|minecraft:green_glazed_terracotta[facing=south] +248:1|minecraft:green_glazed_terracotta[facing=west] +248:2|minecraft:green_glazed_terracotta[facing=north] +248:3|minecraft:green_glazed_terracotta[facing=east] +249:0|minecraft:red_glazed_terracotta[facing=south] +249:1|minecraft:red_glazed_terracotta[facing=west] +249:2|minecraft:red_glazed_terracotta[facing=north] +249:3|minecraft:red_glazed_terracotta[facing=east] +250:0|minecraft:black_glazed_terracotta[facing=south] +250:1|minecraft:black_glazed_terracotta[facing=west] +250:2|minecraft:black_glazed_terracotta[facing=north] +250:3|minecraft:black_glazed_terracotta[facing=east] +251:0|minecraft:white_concrete +251:1|minecraft:orange_concrete +251:2|minecraft:magenta_concrete +251:3|minecraft:light_blue_concrete +251:4|minecraft:yellow_concrete +251:5|minecraft:lime_concrete +251:6|minecraft:pink_concrete +251:7|minecraft:gray_concrete +251:8|minecraft:light_gray_concrete +251:9|minecraft:cyan_concrete +251:10|minecraft:purple_concrete +251:11|minecraft:blue_concrete +251:12|minecraft:brown_concrete +251:13|minecraft:green_concrete +251:14|minecraft:red_concrete +251:15|minecraft:black_concrete +252:0|minecraft:white_concrete_powder +252:1|minecraft:orange_concrete_powder +252:2|minecraft:magenta_concrete_powder +252:3|minecraft:light_blue_concrete_powder +252:4|minecraft:yellow_concrete_powder +252:5|minecraft:lime_concrete_powder +252:6|minecraft:pink_concrete_powder +252:7|minecraft:gray_concrete_powder +252:8|minecraft:light_gray_concrete_powder +252:9|minecraft:cyan_concrete_powder +252:10|minecraft:purple_concrete_powder +252:11|minecraft:blue_concrete_powder +252:12|minecraft:brown_concrete_powder +252:13|minecraft:green_concrete_powder +252:14|minecraft:red_concrete_powder +252:15|minecraft:black_concrete_powder +255:0|minecraft:structure_block[mode=save] +255:1|minecraft:structure_block[mode=load] +255:2|minecraft:structure_block[mode=corner] +255:3|minecraft:structure_block[mode=data] diff --git a/SubstrateCS/Source/Item.cs b/SubstrateCS/Source/Item.cs index 28cdd8e5..8629e829 100644 --- a/SubstrateCS/Source/Item.cs +++ b/SubstrateCS/Source/Item.cs @@ -12,7 +12,7 @@ public class Item : INbtObject, ICopyable { private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("") { - new SchemaNodeScaler("id", TagType.TAG_SHORT), + new SchemaNodeScaler("id", TagType.TAG_STRING), new SchemaNodeScaler("Damage", TagType.TAG_SHORT), new SchemaNodeScaler("Count", TagType.TAG_BYTE), new SchemaNodeCompound("tag", new SchemaNodeCompound("") { @@ -25,7 +25,7 @@ public class Item : INbtObject, ICopyable private TagNodeCompound _source; - private short _id; + private string _id; private byte _count; private short _damage; @@ -44,10 +44,10 @@ public Item () /// Constructs an instance representing the given item id. /// /// An item id. - public Item (int id) + public Item (string id) : this() { - _id = (short)id; + _id = id; } #region Properties @@ -57,16 +57,22 @@ public Item (int id) /// public ItemInfo Info { - get { return ItemInfo.ItemTable[_id]; } + get { + ItemInfo itemInfo; + if (ItemInfo.StrTable.TryGetValue(_id, out itemInfo)) { + return itemInfo; + } + return null; + } } /// /// Gets or sets the current type (id) of the item. /// - public int ID + public string ID { get { return _id; } - set { _id = (short)value; } + set { _id = value; } } /// @@ -149,7 +155,7 @@ public Item LoadTree (TagNode tree) _enchantments.Clear(); - _id = ctree["id"].ToTagShort(); + _id = ctree["id"].ToTagString(); _count = ctree["Count"].ToTagByte(); _damage = ctree["Damage"].ToTagShort(); @@ -183,7 +189,7 @@ public Item LoadTreeSafe (TagNode tree) public TagNode BuildTree () { TagNodeCompound tree = new TagNodeCompound(); - tree["id"] = new TagNodeShort(_id); + tree["id"] = new TagNodeString(_id); tree["Count"] = new TagNodeByte(_count); tree["Damage"] = new TagNodeShort(_damage); diff --git a/SubstrateCS/Source/ItemInfo.cs b/SubstrateCS/Source/ItemInfo.cs index a779e2a6..a07934a1 100644 --- a/SubstrateCS/Source/ItemInfo.cs +++ b/SubstrateCS/Source/ItemInfo.cs @@ -191,6 +191,31 @@ public static class ItemType /// in the class. public class ItemInfo { + /// + /// The maximum number of sequential blocks starting at 0 that can be registered. + /// + public const int MAX_BLOCKS = 4096; + + /// + /// The maximum opacity value that can be assigned to a block (fully opaque). + /// + public const int MAX_OPACITY = 15; + + /// + /// The minimum opacity value that can be assigned to a block (fully transparent). + /// + public const int MIN_OPACITY = 0; + + /// + /// The maximum luminance value that can be assigned to a block. + /// + public const int MAX_LUMINANCE = 15; + + /// + /// The minimum luminance value that can be assigned to a block. + /// + public const int MIN_LUMINANCE = 0; + private static Random _rand = new Random(); private class CacheTableDict : ICacheTable @@ -226,13 +251,25 @@ IEnumerator IEnumerable.GetEnumerator () } } - private static readonly Dictionary _itemTable; + private static readonly Dictionary _itemTable = new Dictionary(); + private static readonly Dictionary _strTable = new Dictionary(); + + public static Dictionary StrTable { + get { + return _strTable; + } + } private int _id = 0; - private string _name = ""; - private int _stack = 1; + private string _name = "", _stringId = null; + private int _stack; + private int _opacity; + private readonly BlockState _state; + private int _luminance = MIN_LUMINANCE; + private bool _transmitLight; + private bool _blocksFluid; - private static readonly CacheTableDict _itemTableCache; + private static readonly CacheTableDict _itemTableCache = new CacheTableDict(_itemTable); /// /// Gets the lookup table for id-to-info values. @@ -242,6 +279,36 @@ public static ICacheTable ItemTable get { return _itemTableCache; } } + /// + /// Gets the block's opacity value. An opacity of 0 is fully transparent to light. + /// + public int Opacity { + get { return _opacity; } + } + + /// + /// Gets the block's luminance value. + /// + /// Blocks with luminance act as light sources and transmit light to other blocks. + public int Luminance { + get { return _luminance; } + } + + /// + /// Checks whether the block transmits light to neighboring blocks. + /// + /// A block may stop the transmission of light, but still be illuminated. + public bool TransmitsLight { + get { return _transmitLight; } + } + + /// + /// Checks whether the block partially or fully blocks the transmission of light. + /// + public bool ObscuresLight { + get { return _opacity > MIN_OPACITY || !_transmitLight; } + } + /// /// Gets the id of the item type. /// @@ -258,6 +325,12 @@ public string Name get { return _name; } } + public string StringId { + get { + return _stringId; + } + } + /// /// Gets the maximum stack size allowed for this item type. /// @@ -276,16 +349,34 @@ public ItemInfo (int id) _itemTable[_id] = this; } + private readonly int _tick; + /// /// Constructs a new record for the given item id and name. /// /// The id of an item type. /// The name of an item type. - public ItemInfo (int id, string name) - { + public ItemInfo(int id, int meta, string name, string stringId = null, int stack = 1, int opacity = MAX_OPACITY, BlockState state = BlockState.SOLID, bool? blocksFluid = null, int tick = 0) { _id = id; _name = name; + _stringId = stringId; _itemTable[_id] = this; + _opacity = opacity; + _stack = stack; + _state = state; + _tick = tick; + + if (blocksFluid != null) { + _blocksFluid = blocksFluid.Value; + } else if (_state == BlockState.SOLID) { + _blocksFluid = true; + } else { + _blocksFluid = false; + } + + if (stringId != null) { + _strTable[stringId] = this; + } } /// @@ -309,350 +400,717 @@ public static ItemInfo GetRandomItem () return list[_rand.Next(list.Count)]; } - public static ItemInfo IronShovel; - public static ItemInfo IronPickaxe; - public static ItemInfo IronAxe; - public static ItemInfo FlintAndSteel; - public static ItemInfo Apple; - public static ItemInfo Bow; - public static ItemInfo Arrow; - public static ItemInfo Coal; - public static ItemInfo Diamond; - public static ItemInfo IronIngot; - public static ItemInfo GoldIngot; - public static ItemInfo IronSword; - public static ItemInfo WoodenSword; - public static ItemInfo WoodenShovel; - public static ItemInfo WoodenPickaxe; - public static ItemInfo WoodenAxe; - public static ItemInfo StoneSword; - public static ItemInfo StoneShovel; - public static ItemInfo StonePickaxe; - public static ItemInfo StoneAxe; - public static ItemInfo DiamondSword; - public static ItemInfo DiamondShovel; - public static ItemInfo DiamondPickaxe; - public static ItemInfo DiamondAxe; - public static ItemInfo Stick; - public static ItemInfo Bowl; - public static ItemInfo MushroomSoup; - public static ItemInfo GoldSword; - public static ItemInfo GoldShovel; - public static ItemInfo GoldPickaxe; - public static ItemInfo GoldAxe; - public static ItemInfo String; - public static ItemInfo Feather; - public static ItemInfo Gunpowder; - public static ItemInfo WoodenHoe; - public static ItemInfo StoneHoe; - public static ItemInfo IronHoe; - public static ItemInfo DiamondHoe; - public static ItemInfo GoldHoe; - public static ItemInfo Seeds; - public static ItemInfo Wheat; - public static ItemInfo Bread; - public static ItemInfo LeatherCap; - public static ItemInfo LeatherTunic; - public static ItemInfo LeatherPants; - public static ItemInfo LeatherBoots; - public static ItemInfo ChainHelmet; - public static ItemInfo ChainChestplate; - public static ItemInfo ChainLeggings; - public static ItemInfo ChainBoots; - public static ItemInfo IronHelmet; - public static ItemInfo IronChestplate; - public static ItemInfo IronLeggings; - public static ItemInfo IronBoots; - public static ItemInfo DiamondHelmet; - public static ItemInfo DiamondChestplate; - public static ItemInfo DiamondLeggings; - public static ItemInfo DiamondBoots; - public static ItemInfo GoldHelmet; - public static ItemInfo GoldChestplate; - public static ItemInfo GoldLeggings; - public static ItemInfo GoldBoots; - public static ItemInfo Flint; - public static ItemInfo RawPorkchop; - public static ItemInfo CookedPorkchop; - public static ItemInfo Painting; - public static ItemInfo GoldenApple; - public static ItemInfo Sign; - public static ItemInfo WoodenDoor; - public static ItemInfo Bucket; - public static ItemInfo WaterBucket; - public static ItemInfo LavaBucket; - public static ItemInfo Minecart; - public static ItemInfo Saddle; - public static ItemInfo IronDoor; - public static ItemInfo RedstoneDust; - public static ItemInfo Snowball; - public static ItemInfo Boat; - public static ItemInfo Leather; - public static ItemInfo Milk; - public static ItemInfo ClayBrick; - public static ItemInfo Clay; - public static ItemInfo SugarCane; - public static ItemInfo Paper; - public static ItemInfo Book; - public static ItemInfo Slimeball; - public static ItemInfo StorageMinecart; - public static ItemInfo PoweredMinecart; - public static ItemInfo Egg; - public static ItemInfo Compass; - public static ItemInfo FishingRod; - public static ItemInfo Clock; - public static ItemInfo GlowstoneDust; - public static ItemInfo RawFish; - public static ItemInfo CookedFish; - public static ItemInfo Dye; - public static ItemInfo Bone; - public static ItemInfo Sugar; - public static ItemInfo Cake; - public static ItemInfo Bed; - public static ItemInfo RedstoneRepeater; - public static ItemInfo Cookie; - public static ItemInfo Map; - public static ItemInfo Shears; - public static ItemInfo MelonSlice; - public static ItemInfo PumpkinSeeds; - public static ItemInfo MelonSeeds; - public static ItemInfo RawBeef; - public static ItemInfo Steak; - public static ItemInfo RawChicken; - public static ItemInfo CookedChicken; - public static ItemInfo RottenFlesh; - public static ItemInfo EnderPearl; - public static ItemInfo BlazeRod; - public static ItemInfo GhastTear; - public static ItemInfo GoldNugget; - public static ItemInfo NetherWart; - public static ItemInfo Potion; - public static ItemInfo GlassBottle; - public static ItemInfo SpiderEye; - public static ItemInfo FermentedSpiderEye; - public static ItemInfo BlazePowder; - public static ItemInfo MagmaCream; - public static ItemInfo BrewingStand; - public static ItemInfo Cauldron; - public static ItemInfo EyeOfEnder; - public static ItemInfo GlisteringMelon; - public static ItemInfo SpawnEgg; - public static ItemInfo BottleOEnchanting; - public static ItemInfo FireCharge; - public static ItemInfo BookAndQuill; - public static ItemInfo WrittenBook; - public static ItemInfo Emerald; - public static ItemInfo ItemFrame; - public static ItemInfo FlowerPot; - public static ItemInfo Carrot; - public static ItemInfo Potato; - public static ItemInfo BakedPotato; - public static ItemInfo PoisonPotato; - public static ItemInfo EmptyMap; - public static ItemInfo GoldenCarrot; - public static ItemInfo MobHead; - public static ItemInfo CarrotOnStick; - public static ItemInfo NetherStar; - public static ItemInfo PumpkinPie; - public static ItemInfo FireworkRocket; - public static ItemInfo FireworkStar; - public static ItemInfo EnchantedBook; - public static ItemInfo RedstoneComparator; - public static ItemInfo NetherBrick; - public static ItemInfo NetherQuartz; - public static ItemInfo TntMinecart; - public static ItemInfo HopperMinecart; - public static ItemInfo IronHorseArmor; - public static ItemInfo GoldHorseArmor; - public static ItemInfo DiamondHorseArmor; - public static ItemInfo Lead; - public static ItemInfo NameTag; - public static ItemInfo MusicDisc13; - public static ItemInfo MusicDiscCat; - public static ItemInfo MusicDiscBlocks; - public static ItemInfo MusicDiscChirp; - public static ItemInfo MusicDiscFar; - public static ItemInfo MusicDiscMall; - public static ItemInfo MusicDiscMellohi; - public static ItemInfo MusicDiscStal; - public static ItemInfo MusicDiscStrad; - public static ItemInfo MusicDiscWard; - public static ItemInfo MusicDisc11; - - static ItemInfo () - { - _itemTable = new Dictionary(); - _itemTableCache = new CacheTableDict(_itemTable); - - IronShovel = new ItemInfo(256, "Iron Shovel"); - IronPickaxe = new ItemInfo(257, "Iron Pickaxe"); - IronAxe = new ItemInfo(258, "Iron Axe"); - FlintAndSteel = new ItemInfo(259, "Flint and Steel"); - Apple = new ItemInfo(260, "Apple").SetStackSize(64); - Bow = new ItemInfo(261, "Bow"); - Arrow = new ItemInfo(262, "Arrow").SetStackSize(64); - Coal = new ItemInfo(263, "Coal").SetStackSize(64); - Diamond = new ItemInfo(264, "Diamond").SetStackSize(64); - IronIngot = new ItemInfo(265, "Iron Ingot").SetStackSize(64); - GoldIngot = new ItemInfo(266, "Gold Ingot").SetStackSize(64); - IronSword = new ItemInfo(267, "Iron Sword"); - WoodenSword = new ItemInfo(268, "Wooden Sword"); - WoodenShovel = new ItemInfo(269, "Wooden Shovel"); - WoodenPickaxe = new ItemInfo(270, "Wooden Pickaxe"); - WoodenAxe = new ItemInfo(271, "Wooden Axe"); - StoneSword = new ItemInfo(272, "Stone Sword"); - StoneShovel = new ItemInfo(273, "Stone Shovel"); - StonePickaxe = new ItemInfo(274, "Stone Pickaxe"); - StoneAxe = new ItemInfo(275, "Stone Axe"); - DiamondSword = new ItemInfo(276, "Diamond Sword"); - DiamondShovel = new ItemInfo(277, "Diamond Shovel"); - DiamondPickaxe = new ItemInfo(278, "Diamond Pickaxe"); - DiamondAxe = new ItemInfo(279, "Diamond Axe"); - Stick = new ItemInfo(280, "Stick").SetStackSize(64); - Bowl = new ItemInfo(281, "Bowl").SetStackSize(64); - MushroomSoup = new ItemInfo(282, "Mushroom Soup"); - GoldSword = new ItemInfo(283, "Gold Sword"); - GoldShovel = new ItemInfo(284, "Gold Shovel"); - GoldPickaxe = new ItemInfo(285, "Gold Pickaxe"); - GoldAxe = new ItemInfo(286, "Gold Axe"); - String = new ItemInfo(287, "String").SetStackSize(64); - Feather = new ItemInfo(288, "Feather").SetStackSize(64); - Gunpowder = new ItemInfo(289, "Gunpowder").SetStackSize(64); - WoodenHoe = new ItemInfo(290, "Wooden Hoe"); - StoneHoe = new ItemInfo(291, "Stone Hoe"); - IronHoe = new ItemInfo(292, "Iron Hoe"); - DiamondHoe = new ItemInfo(293, "Diamond Hoe"); - GoldHoe = new ItemInfo(294, "Gold Hoe"); - Seeds = new ItemInfo(295, "Seeds").SetStackSize(64); - Wheat = new ItemInfo(296, "Wheat").SetStackSize(64); - Bread = new ItemInfo(297, "Bread").SetStackSize(64); - LeatherCap = new ItemInfo(298, "Leather Cap"); - LeatherTunic = new ItemInfo(299, "Leather Tunic"); - LeatherPants = new ItemInfo(300, "Leather Pants"); - LeatherBoots = new ItemInfo(301, "Leather Boots"); - ChainHelmet = new ItemInfo(302, "Chain Helmet"); - ChainChestplate = new ItemInfo(303, "Chain Chestplate"); - ChainLeggings = new ItemInfo(304, "Chain Leggings"); - ChainBoots = new ItemInfo(305, "Chain Boots"); - IronHelmet = new ItemInfo(306, "Iron Helmet"); - IronChestplate = new ItemInfo(307, "Iron Chestplate"); - IronLeggings = new ItemInfo(308, "Iron Leggings"); - IronBoots = new ItemInfo(309, "Iron Boots"); - DiamondHelmet = new ItemInfo(310, "Diamond Helmet"); - DiamondChestplate = new ItemInfo(311, "Diamond Chestplate"); - DiamondLeggings = new ItemInfo(312, "Diamond Leggings"); - DiamondBoots = new ItemInfo(313, "Diamond Boots"); - GoldHelmet = new ItemInfo(314, "Gold Helmet"); - GoldChestplate = new ItemInfo(315, "Gold Chestplate"); - GoldLeggings = new ItemInfo(316, "Gold Leggings"); - GoldBoots = new ItemInfo(317, "Gold Boots"); - Flint = new ItemInfo(318, "Flint").SetStackSize(64); - RawPorkchop = new ItemInfo(319, "Raw Porkchop").SetStackSize(64); - CookedPorkchop = new ItemInfo(320, "Cooked Porkchop").SetStackSize(64); - Painting = new ItemInfo(321, "Painting").SetStackSize(64); - GoldenApple = new ItemInfo(322, "Golden Apple").SetStackSize(64); - Sign = new ItemInfo(323, "Sign"); - WoodenDoor = new ItemInfo(324, "Door"); - Bucket = new ItemInfo(325, "Bucket"); - WaterBucket = new ItemInfo(326, "Water Bucket"); - LavaBucket = new ItemInfo(327, "Lava Bucket"); - Minecart = new ItemInfo(328, "Minecart"); - Saddle = new ItemInfo(329, "Saddle"); - IronDoor = new ItemInfo(330, "Iron Door"); - RedstoneDust = new ItemInfo(331, "Redstone Dust").SetStackSize(64); - Snowball = new ItemInfo(332, "Snowball").SetStackSize(16); - Boat = new ItemInfo(333, "Boat"); - Leather = new ItemInfo(334, "Leather").SetStackSize(64); - Milk = new ItemInfo(335, "Milk"); - ClayBrick = new ItemInfo(336, "Clay Brick").SetStackSize(64); - Clay = new ItemInfo(337, "Clay").SetStackSize(64); - SugarCane = new ItemInfo(338, "Sugar Cane").SetStackSize(64); - Paper = new ItemInfo(339, "Paper").SetStackSize(64); - Book = new ItemInfo(340, "Book").SetStackSize(64); - Slimeball = new ItemInfo(341, "Slimeball").SetStackSize(64); - StorageMinecart = new ItemInfo(342, "Storage Minecart"); - PoweredMinecart = new ItemInfo(343, "Powered Minecart"); - Egg = new ItemInfo(344, "Egg").SetStackSize(16); - Compass = new ItemInfo(345, "Compass"); - FishingRod = new ItemInfo(346, "Fishing Rod"); - Clock = new ItemInfo(347, "Clock"); - GlowstoneDust = new ItemInfo(348, "Glowstone Dust").SetStackSize(64); - RawFish = new ItemInfo(349, "Raw Fish").SetStackSize(64); - CookedFish = new ItemInfo(350, "Cooked Fish").SetStackSize(64); - Dye = new ItemInfo(351, "Dye").SetStackSize(64); - Bone = new ItemInfo(352, "Bone").SetStackSize(64); - Sugar = new ItemInfo(353, "Sugar").SetStackSize(64); - Cake = new ItemInfo(354, "Cake"); - Bed = new ItemInfo(355, "Bed"); - RedstoneRepeater = new ItemInfo(356, "Redstone Repeater").SetStackSize(64); - Cookie = new ItemInfo(357, "Cookie").SetStackSize(8); - Map = new ItemInfo(358, "Map"); - Shears = new ItemInfo(359, "Shears"); - MelonSlice = new ItemInfo(360, "Melon Slice").SetStackSize(64); - PumpkinSeeds = new ItemInfo(361, "Pumpkin Seeds").SetStackSize(64); - MelonSeeds = new ItemInfo(362, "Melon Seeds").SetStackSize(64); - RawBeef = new ItemInfo(363, "Raw Beef").SetStackSize(64); - Steak = new ItemInfo(364, "Steak").SetStackSize(64); - RawChicken = new ItemInfo(365, "Raw Chicken").SetStackSize(64); - CookedChicken = new ItemInfo(366, "Cooked Chicken").SetStackSize(64); - RottenFlesh = new ItemInfo(367, "Rotten Flesh").SetStackSize(64); - EnderPearl = new ItemInfo(368, "Ender Pearl").SetStackSize(64); - BlazeRod = new ItemInfo(369, "Blaze Rod").SetStackSize(64); - GhastTear = new ItemInfo(370, "Ghast Tear").SetStackSize(64); - GoldNugget = new ItemInfo(371, "Gold Nugget").SetStackSize(64); - NetherWart = new ItemInfo(372, "Nether Wart").SetStackSize(64); - Potion = new ItemInfo(373, "Potion"); - GlassBottle = new ItemInfo(374, "Glass Bottle").SetStackSize(64); - SpiderEye = new ItemInfo(375, "Spider Eye").SetStackSize(64); - FermentedSpiderEye = new ItemInfo(376, "Fermented Spider Eye").SetStackSize(64); - BlazePowder = new ItemInfo(377, "Blaze Powder").SetStackSize(64); - MagmaCream = new ItemInfo(378, "Magma Cream").SetStackSize(64); - BrewingStand = new ItemInfo(379, "Brewing Stand").SetStackSize(64); - Cauldron = new ItemInfo(380, "Cauldron"); - EyeOfEnder = new ItemInfo(381, "Eye of Ender").SetStackSize(64); - GlisteringMelon = new ItemInfo(382, "Glistering Melon").SetStackSize(64); - SpawnEgg = new ItemInfo(383, "Spawn Egg").SetStackSize(64); - BottleOEnchanting = new ItemInfo(384, "Bottle O' Enchanting").SetStackSize(64); - FireCharge = new ItemInfo(385, "Fire Charge").SetStackSize(64); - BookAndQuill = new ItemInfo(386, "Book and Quill"); - WrittenBook = new ItemInfo(387, "Written Book"); - Emerald = new ItemInfo(388, "Emerald").SetStackSize(64); - ItemFrame = new ItemInfo(389, "Item Frame").SetStackSize(64); - FlowerPot = new ItemInfo(390, "Flower Pot").SetStackSize(64); - Carrot = new ItemInfo(391, "Carrot").SetStackSize(64); - Potato = new ItemInfo(392, "Potato").SetStackSize(64); - BakedPotato = new ItemInfo(393, "Baked Potato").SetStackSize(64); - PoisonPotato = new ItemInfo(394, "Poisonous Potato").SetStackSize(64); - EmptyMap = new ItemInfo(395, "Empty Map").SetStackSize(64); - GoldenCarrot = new ItemInfo(396, "Golden Carrot").SetStackSize(64); - MobHead = new ItemInfo(397, "Mob Head").SetStackSize(64); - CarrotOnStick = new ItemInfo(398, "Carrot on a Stick"); - NetherStar = new ItemInfo(399, "Nether Star").SetStackSize(64); - PumpkinPie = new ItemInfo(400, "Pumpkin Pie").SetStackSize(64); - FireworkRocket = new ItemInfo(401, "Firework Rocket"); - FireworkStar = new ItemInfo(402, "Firework Star").SetStackSize(64); - EnchantedBook = new ItemInfo(403, "Enchanted Book"); - RedstoneComparator = new ItemInfo(404, "Redstone Comparator").SetStackSize(64); - NetherBrick = new ItemInfo(405, "Nether Brick").SetStackSize(64); - NetherQuartz = new ItemInfo(406, "Nether Quartz").SetStackSize(64); - TntMinecart = new ItemInfo(407, "Minecart with TNT"); - HopperMinecart = new ItemInfo(408, "Minecart with Hopper"); - IronHorseArmor = new ItemInfo(417, "Iron Horse Armor"); - GoldHorseArmor = new ItemInfo(418, "Gold Horse Armor"); - DiamondHorseArmor = new ItemInfo(419, "Diamond Horse Armor"); - Lead = new ItemInfo(420, "Lead").SetStackSize(64); - NameTag = new ItemInfo(421, "Name Tag").SetStackSize(64); - MusicDisc13 = new ItemInfo(2256, "13 Disc"); - MusicDiscCat = new ItemInfo(2257, "Cat Disc"); - MusicDiscBlocks = new ItemInfo(2258, "Blocks Disc"); - MusicDiscChirp = new ItemInfo(2259, "Chirp Disc"); - MusicDiscFar = new ItemInfo(2260, "Far Disc"); - MusicDiscMall = new ItemInfo(2261, "Mall Disc"); - MusicDiscMellohi = new ItemInfo(2262, "Mellohi Disc"); - MusicDiscStal = new ItemInfo(2263, "Stal Disc"); - MusicDiscStrad = new ItemInfo(2264, "Strad Disc"); - MusicDiscWard = new ItemInfo(2265, "Ward Disc"); - MusicDisc11 = new ItemInfo(2266, "11 Disc"); - } + public static ItemInfo Air = new ItemInfo(0, 0, "Air", "minecraft:air", opacity: 0, state: BlockState.NONSOLID); + public static ItemInfo Stone = new ItemInfo(1, 0, "Stone", "minecraft:stone"); + public static ItemInfo Granite = new ItemInfo(1, 1, "Granite", "minecraft:stone"); + public static ItemInfo PolishedGranite = new ItemInfo(1, 2, "Polished Granite", "minecraft:stone"); + public static ItemInfo Diorite = new ItemInfo(1, 3, "Diorite", "minecraft:stone"); + public static ItemInfo PolishedDiorite = new ItemInfo(1, 4, "Polished Diorite", "minecraft:stone"); + public static ItemInfo Andesite = new ItemInfo(1, 5, "Andesite", "minecraft:stone"); + public static ItemInfo PolishedAndesite = new ItemInfo(1, 6, "Polished Andesite", "minecraft:stone"); + public static ItemInfo Grass = new ItemInfo(2, 0, "Grass", "minecraft:grass", tick:10); + public static ItemInfo Dirt = new ItemInfo(3, 0, "Dirt", "minecraft:dirt"); + public static ItemInfo CoarseDirt = new ItemInfo(3, 1, "Coarse Dirt", "minecraft:dirt"); + public static ItemInfo Podzol = new ItemInfo(3, 2, "Podzol", "minecraft:dirt"); + public static ItemInfo Cobblestone = new ItemInfo(4, 0, "Cobblestone", "minecraft:cobblestone"); + public static ItemInfo OakWoodPlank = new ItemInfo(5, 0, "Oak Wood Plank", "minecraft:planks"); + public static ItemInfo SpruceWoodPlank = new ItemInfo(5, 1, "Spruce Wood Plank", "minecraft:planks"); + public static ItemInfo BirchWoodPlank = new ItemInfo(5, 2, "Birch Wood Plank", "minecraft:planks"); + public static ItemInfo JungleWoodPlank = new ItemInfo(5, 3, "Jungle Wood Plank", "minecraft:planks"); + public static ItemInfo AcaciaWoodPlank = new ItemInfo(5, 4, "Acacia Wood Plank", "minecraft:planks"); + public static ItemInfo DarkOakWoodPlank = new ItemInfo(5, 5, "Dark Oak Wood Plank", "minecraft:planks"); + public static ItemInfo OakSapling = new ItemInfo(6, 0, "Oak Sapling", "minecraft:sapling"); + public static ItemInfo SpruceSapling = new ItemInfo(6, 1, "Spruce Sapling", "minecraft:sapling"); + public static ItemInfo BirchSapling = new ItemInfo(6, 2, "Birch Sapling", "minecraft:sapling"); + public static ItemInfo JungleSapling = new ItemInfo(6, 3, "Jungle Sapling", "minecraft:sapling"); + public static ItemInfo AcaciaSapling = new ItemInfo(6, 4, "Acacia Sapling", "minecraft:sapling"); + public static ItemInfo DarkOakSapling = new ItemInfo(6, 5, "Dark Oak Sapling", "minecraft:sapling"); + public static ItemInfo Bedrock = new ItemInfo(7, 0, "Bedrock", "minecraft:bedrock"); + public static ItemInfo FlowingWater = new ItemInfo(8, 0, "Flowing Water", "minecraft:flowing_water"); + public static ItemInfo StillWater = new ItemInfo(9, 0, "Still Water", "minecraft:water"); + public static ItemInfo FlowingLava = new ItemInfo(10, 0, "Flowing Lava", "minecraft:flowing_lava"); + public static ItemInfo StillLava = new ItemInfo(11, 0, "Still Lava", "minecraft:lava"); + public static ItemInfo Sand = new ItemInfo(12, 0, "Sand", "minecraft:sand"); + public static ItemInfo RedSand = new ItemInfo(12, 1, "Red Sand", "minecraft:sand"); + public static ItemInfo Gravel = new ItemInfo(13, 0, "Gravel", "minecraft:gravel"); + public static ItemInfo GoldOre = new ItemInfo(14, 0, "Gold Ore", "minecraft:gold_ore"); + public static ItemInfo IronOre = new ItemInfo(15, 0, "Iron Ore", "minecraft:iron_ore"); + public static ItemInfo CoalOre = new ItemInfo(16, 0, "Coal Ore", "minecraft:coal_ore"); + public static ItemInfo OakWood = new ItemInfo(17, 0, "Oak Wood", "minecraft:log"); + public static ItemInfo SpruceWood = new ItemInfo(17, 1, "Spruce Wood", "minecraft:log"); + public static ItemInfo BirchWood = new ItemInfo(17, 2, "Birch Wood", "minecraft:log"); + public static ItemInfo JungleWood = new ItemInfo(17, 3, "Jungle Wood", "minecraft:log"); + public static ItemInfo OakLeaves = new ItemInfo(18, 0, "Oak Leaves", "minecraft:leaves"); + public static ItemInfo SpruceLeaves = new ItemInfo(18, 1, "Spruce Leaves", "minecraft:leaves"); + public static ItemInfo BirchLeaves = new ItemInfo(18, 2, "Birch Leaves", "minecraft:leaves"); + public static ItemInfo JungleLeaves = new ItemInfo(18, 3, "Jungle Leaves", "minecraft:leaves"); + public static ItemInfo Sponge = new ItemInfo(19, 0, "Sponge", "minecraft:sponge"); + public static ItemInfo WetSponge = new ItemInfo(19, 1, "Wet Sponge", "minecraft:sponge"); + public static ItemInfo Glass = new ItemInfo(20, 0, "Glass", "minecraft:glass"); + public static ItemInfo LapisLazuliOre = new ItemInfo(21, 0, "Lapis Lazuli Ore", "minecraft:lapis_ore"); + public static ItemInfo LapisLazuliBlock = new ItemInfo(22, 0, "Lapis Lazuli Block", "minecraft:lapis_block"); + public static ItemInfo Dispenser = new ItemInfo(23, 0, "Dispenser", "minecraft:dispenser"); + public static ItemInfo Sandstone = new ItemInfo(24, 0, "Sandstone", "minecraft:sandstone"); + public static ItemInfo ChiseledSandstone = new ItemInfo(24, 1, "Chiseled Sandstone", "minecraft:sandstone"); + public static ItemInfo SmoothSandstone = new ItemInfo(24, 2, "Smooth Sandstone", "minecraft:sandstone"); + public static ItemInfo NoteBlock = new ItemInfo(25, 0, "Note Block", "minecraft:noteblock"); + public static ItemInfo Bed = new ItemInfo(26, 0, "Bed", "minecraft:bed"); + public static ItemInfo PoweredRail = new ItemInfo(27, 0, "Powered Rail", "minecraft:golden_rail"); + public static ItemInfo DetectorRail = new ItemInfo(28, 0, "Detector Rail", "minecraft:detector_rail"); + public static ItemInfo StickyPiston = new ItemInfo(29, 0, "Sticky Piston", "minecraft:sticky_piston"); + public static ItemInfo Cobweb = new ItemInfo(30, 0, "Cobweb", "minecraft:web"); + public static ItemInfo DeadShrub = new ItemInfo(31, 0, "Dead Shrub", "minecraft:tallgrass"); + public static ItemInfo TallGrass = new ItemInfo(31, 1, "Grass", "minecraft:tallgrass"); + public static ItemInfo Fern = new ItemInfo(31, 2, "Fern", "minecraft:tallgrass"); + public static ItemInfo DeadBush = new ItemInfo(32, 0, "Dead Bush", "minecraft:deadbush"); + public static ItemInfo Piston = new ItemInfo(33, 0, "Piston", "minecraft:piston"); + public static ItemInfo PistonHead = new ItemInfo(34, 0, "Piston Head", "minecraft:piston_head"); + public static ItemInfo WhiteWool = new ItemInfo(35, 0, "White Wool", "minecraft:wool"); + public static ItemInfo OrangeWool = new ItemInfo(35, 1, "Orange Wool", "minecraft:wool"); + public static ItemInfo MagentaWool = new ItemInfo(35, 2, "Magenta Wool", "minecraft:wool"); + public static ItemInfo LightBlueWool = new ItemInfo(35, 3, "Light Blue Wool", "minecraft:wool"); + public static ItemInfo YellowWool = new ItemInfo(35, 4, "Yellow Wool", "minecraft:wool"); + public static ItemInfo LimeWool = new ItemInfo(35, 5, "Lime Wool", "minecraft:wool"); + public static ItemInfo PinkWool = new ItemInfo(35, 6, "Pink Wool", "minecraft:wool"); + public static ItemInfo GrayWool = new ItemInfo(35, 7, "Gray Wool", "minecraft:wool"); + public static ItemInfo LightGrayWool = new ItemInfo(35, 8, "Light Gray Wool", "minecraft:wool"); + public static ItemInfo CyanWool = new ItemInfo(35, 9, "Cyan Wool", "minecraft:wool"); + public static ItemInfo PurpleWool = new ItemInfo(35, 10, "Purple Wool", "minecraft:wool"); + public static ItemInfo BlueWool = new ItemInfo(35, 11, "Blue Wool", "minecraft:wool"); + public static ItemInfo BrownWool = new ItemInfo(35, 12, "Brown Wool", "minecraft:wool"); + public static ItemInfo GreenWool = new ItemInfo(35, 13, "Green Wool", "minecraft:wool"); + public static ItemInfo RedWool = new ItemInfo(35, 14, "Red Wool", "minecraft:wool"); + public static ItemInfo BlackWool = new ItemInfo(35, 15, "Black Wool", "minecraft:wool"); + public static ItemInfo Dandelion = new ItemInfo(37, 0, "Dandelion", "minecraft:yellow_flower"); + public static ItemInfo Poppy = new ItemInfo(38, 0, "Poppy", "minecraft:red_flower"); + public static ItemInfo BlueOrchid = new ItemInfo(38, 1, "Blue Orchid", "minecraft:red_flower"); + public static ItemInfo Allium = new ItemInfo(38, 2, "Allium", "minecraft:red_flower"); + public static ItemInfo AzureBluet = new ItemInfo(38, 3, "Azure Bluet", "minecraft:red_flower"); + public static ItemInfo RedTulip = new ItemInfo(38, 4, "Red Tulip", "minecraft:red_flower"); + public static ItemInfo OrangeTulip = new ItemInfo(38, 5, "Orange Tulip", "minecraft:red_flower"); + public static ItemInfo WhiteTulip = new ItemInfo(38, 6, "White Tulip", "minecraft:red_flower"); + public static ItemInfo PinkTulip = new ItemInfo(38, 7, "Pink Tulip", "minecraft:red_flower"); + public static ItemInfo OxeyeDaisy = new ItemInfo(38, 8, "Oxeye Daisy", "minecraft:red_flower"); + public static ItemInfo BrownMushroom = new ItemInfo(39, 0, "Brown Mushroom", "minecraft:brown_mushroom"); + public static ItemInfo RedMushroom = new ItemInfo(40, 0, "Red Mushroom", "minecraft:red_mushroom"); + public static ItemInfo GoldBlock = new ItemInfo(41, 0, "Gold Block", "minecraft:gold_block"); + public static ItemInfo IronBlock = new ItemInfo(42, 0, "Iron Block", "minecraft:iron_block"); + public static ItemInfo DoubleStoneSlab = new ItemInfo(43, 0, "Double Stone Slab", "minecraft:double_stone_slab"); + public static ItemInfo DoubleSandstoneSlab = new ItemInfo(43, 1, "Double Sandstone Slab", "minecraft:double_stone_slab"); + public static ItemInfo DoubleWoodenSlab = new ItemInfo(43, 2, "Double Wooden Slab", "minecraft:double_stone_slab"); + public static ItemInfo DoubleCobblestoneSlab = new ItemInfo(43, 3, "Double Cobblestone Slab", "minecraft:double_stone_slab"); + public static ItemInfo DoubleBrickSlab = new ItemInfo(43, 4, "Double Brick Slab", "minecraft:double_stone_slab"); + public static ItemInfo DoubleStoneBrickSlab = new ItemInfo(43, 5, "Double Stone Brick Slab", "minecraft:double_stone_slab"); + public static ItemInfo DoubleNetherBrickSlab = new ItemInfo(43, 6, "Double Nether Brick Slab", "minecraft:double_stone_slab"); + public static ItemInfo DoubleQuartzSlab = new ItemInfo(43, 7, "Double Quartz Slab", "minecraft:double_stone_slab"); + public static ItemInfo StoneSlab = new ItemInfo(44, 0, "Stone Slab", "minecraft:stone_slab"); + public static ItemInfo SandstoneSlab = new ItemInfo(44, 1, "Sandstone Slab", "minecraft:stone_slab"); + public static ItemInfo WoodenSlab = new ItemInfo(44, 2, "Wooden Slab", "minecraft:stone_slab"); + public static ItemInfo CobblestoneSlab = new ItemInfo(44, 3, "Cobblestone Slab", "minecraft:stone_slab"); + public static ItemInfo BrickSlab = new ItemInfo(44, 4, "Brick Slab", "minecraft:stone_slab"); + public static ItemInfo StoneBrickSlab = new ItemInfo(44, 5, "Stone Brick Slab", "minecraft:stone_slab"); + public static ItemInfo NetherBrickSlab = new ItemInfo(44, 6, "Nether Brick Slab", "minecraft:stone_slab"); + public static ItemInfo QuartzSlab = new ItemInfo(44, 7, "Quartz Slab", "minecraft:stone_slab"); + public static ItemInfo Bricks = new ItemInfo(45, 0, "Bricks", "minecraft:brick_block"); + public static ItemInfo Tnt = new ItemInfo(46, 0, "TNT", "minecraft:tnt"); + public static ItemInfo Bookshelf = new ItemInfo(47, 0, "Bookshelf", "minecraft:bookshelf"); + public static ItemInfo MossStone = new ItemInfo(48, 0, "Moss Stone", "minecraft:mossy_cobblestone"); + public static ItemInfo Obsidian = new ItemInfo(49, 0, "Obsidian", "minecraft:obsidian"); + public static ItemInfo Torch = new ItemInfo(50, 0, "Torch", "minecraft:torch"); + public static ItemInfo Fire = new ItemInfo(51, 0, "Fire", "minecraft:fire"); + public static ItemInfo MonsterSpawner = new ItemInfo(52, 0, "Monster Spawner", "minecraft:mob_spawner"); + public static ItemInfo OakWoodStairs = new ItemInfo(53, 0, "Oak Wood Stairs", "minecraft:oak_stairs"); + public static ItemInfo Chest = new ItemInfo(54, 0, "Chest", "minecraft:chest"); + public static ItemInfo RedstoneWire = new ItemInfo(55, 0, "Redstone Wire", "minecraft:redstone_wire"); + public static ItemInfo DiamondOre = new ItemInfo(56, 0, "Diamond Ore", "minecraft:diamond_ore"); + public static ItemInfo DiamondBlock = new ItemInfo(57, 0, "Diamond Block", "minecraft:diamond_block"); + public static ItemInfo CraftingTable = new ItemInfo(58, 0, "Crafting Table", "minecraft:crafting_table"); + public static ItemInfo WheatCrops = new ItemInfo(59, 0, "Wheat Crops", "minecraft:wheat"); + public static ItemInfo Farmland = new ItemInfo(60, 0, "Farmland", "minecraft:farmland"); + public static ItemInfo Furnace = new ItemInfo(61, 0, "Furnace", "minecraft:furnace"); + public static ItemInfo BurningFurnace = new ItemInfo(62, 0, "Burning Furnace", "minecraft:lit_furnace"); + public static ItemInfo StandingSignBlock = new ItemInfo(63, 0, "Standing Sign Block", "minecraft:standing_sign"); + public static ItemInfo OakDoorBlock = new ItemInfo(64, 0, "Oak Door Block", "minecraft:wooden_door"); + public static ItemInfo Ladder = new ItemInfo(65, 0, "Ladder", "minecraft:ladder"); + public static ItemInfo Rail = new ItemInfo(66, 0, "Rail", "minecraft:rail"); + public static ItemInfo CobblestoneStairs = new ItemInfo(67, 0, "Cobblestone Stairs", "minecraft:stone_stairs"); + public static ItemInfo WallMountedSignBlock = new ItemInfo(68, 0, "Wall-mounted Sign Block", "minecraft:wall_sign"); + public static ItemInfo Lever = new ItemInfo(69, 0, "Lever", "minecraft:lever"); + public static ItemInfo StonePressurePlate = new ItemInfo(70, 0, "Stone Pressure Plate", "minecraft:stone_pressure_plate"); + public static ItemInfo IronDoorBlock = new ItemInfo(71, 0, "Iron Door Block", "minecraft:iron_door"); + public static ItemInfo WoodenPressurePlate = new ItemInfo(72, 0, "Wooden Pressure Plate", "minecraft:wooden_pressure_plate"); + public static ItemInfo RedstoneOre = new ItemInfo(73, 0, "Redstone Ore", "minecraft:redstone_ore"); + public static ItemInfo GlowingRedstoneOre = new ItemInfo(74, 0, "Glowing Redstone Ore", "minecraft:lit_redstone_ore"); + public static ItemInfo RedstoneTorchOff = new ItemInfo(75, 0, "Redstone Torch (off)", "minecraft:unlit_redstone_torch"); + public static ItemInfo RedstoneTorchOn = new ItemInfo(76, 0, "Redstone Torch (on)", "minecraft:redstone_torch"); + public static ItemInfo StoneButton = new ItemInfo(77, 0, "Stone Button", "minecraft:stone_button"); + public static ItemInfo Snow = new ItemInfo(78, 0, "Snow", "minecraft:snow_layer"); + public static ItemInfo Ice = new ItemInfo(79, 0, "Ice", "minecraft:ice"); + public static ItemInfo SnowBlock = new ItemInfo(80, 0, "Snow Block", "minecraft:snow").SetStackSize(16); + public static ItemInfo Cactus = new ItemInfo(81, 0, "Cactus", "minecraft:cactus"); + public static ItemInfo Clay = new ItemInfo(82, 0, "Clay", "minecraft:clay"); + public static ItemInfo SugarCanes = new ItemInfo(83, 0, "Sugar Canes", "minecraft:reeds"); + public static ItemInfo Jukebox = new ItemInfo(84, 0, "Jukebox", "minecraft:jukebox"); + public static ItemInfo OakFence = new ItemInfo(85, 0, "Oak Fence", "minecraft:fence"); + public static ItemInfo Pumpkin = new ItemInfo(86, 0, "Pumpkin", "minecraft:pumpkin"); + public static ItemInfo Netherrack = new ItemInfo(87, 0, "Netherrack", "minecraft:netherrack"); + public static ItemInfo SoulSand = new ItemInfo(88, 0, "Soul Sand", "minecraft:soul_sand"); + public static ItemInfo Glowstone = new ItemInfo(89, 0, "Glowstone", "minecraft:glowstone"); + public static ItemInfo NetherPortal = new ItemInfo(90, 0, "Nether Portal", "minecraft:portal"); + public static ItemInfo JackOLantern = new ItemInfo(91, 0, "Jack o'Lantern", "minecraft:lit_pumpkin"); + public static ItemInfo CakeBlock = new ItemInfo(92, 0, "Cake Block", "minecraft:cake"); + public static ItemInfo RedstoneRepeaterBlockOff = new ItemInfo(93, 0, "Redstone Repeater Block (off)", "minecraft:unpowered_repeater"); + public static ItemInfo RedstoneRepeaterBlockOn = new ItemInfo(94, 0, "Redstone Repeater Block (on)", "minecraft:powered_repeater"); + public static ItemInfo WhiteStainedGlass = new ItemInfo(95, 0, "White Stained Glass", "minecraft:stained_glass"); + public static ItemInfo OrangeStainedGlass = new ItemInfo(95, 1, "Orange Stained Glass", "minecraft:stained_glass"); + public static ItemInfo MagentaStainedGlass = new ItemInfo(95, 2, "Magenta Stained Glass", "minecraft:stained_glass"); + public static ItemInfo LightBlueStainedGlass = new ItemInfo(95, 3, "Light Blue Stained Glass", "minecraft:stained_glass"); + public static ItemInfo YellowStainedGlass = new ItemInfo(95, 4, "Yellow Stained Glass", "minecraft:stained_glass"); + public static ItemInfo LimeStainedGlass = new ItemInfo(95, 5, "Lime Stained Glass", "minecraft:stained_glass"); + public static ItemInfo PinkStainedGlass = new ItemInfo(95, 6, "Pink Stained Glass", "minecraft:stained_glass"); + public static ItemInfo GrayStainedGlass = new ItemInfo(95, 7, "Gray Stained Glass", "minecraft:stained_glass"); + public static ItemInfo LightGrayStainedGlass = new ItemInfo(95, 8, "Light Gray Stained Glass", "minecraft:stained_glass"); + public static ItemInfo CyanStainedGlass = new ItemInfo(95, 9, "Cyan Stained Glass", "minecraft:stained_glass"); + public static ItemInfo PurpleStainedGlass = new ItemInfo(95, 10, "Purple Stained Glass", "minecraft:stained_glass"); + public static ItemInfo BlueStainedGlass = new ItemInfo(95, 11, "Blue Stained Glass", "minecraft:stained_glass"); + public static ItemInfo BrownStainedGlass = new ItemInfo(95, 12, "Brown Stained Glass", "minecraft:stained_glass"); + public static ItemInfo GreenStainedGlass = new ItemInfo(95, 13, "Green Stained Glass", "minecraft:stained_glass"); + public static ItemInfo RedStainedGlass = new ItemInfo(95, 14, "Red Stained Glass", "minecraft:stained_glass"); + public static ItemInfo BlackStainedGlass = new ItemInfo(95, 15, "Black Stained Glass", "minecraft:stained_glass"); + public static ItemInfo WoodenTrapdoor = new ItemInfo(96, 0, "Wooden Trapdoor", "minecraft:trapdoor"); + public static ItemInfo StoneMonsterEgg = new ItemInfo(97, 0, "Stone Monster Egg", "minecraft:monster_egg"); + public static ItemInfo CobblestoneMonsterEgg = new ItemInfo(97, 1, "Cobblestone Monster Egg", "minecraft:monster_egg"); + public static ItemInfo StoneBrickMonsterEgg = new ItemInfo(97, 2, "Stone Brick Monster Egg", "minecraft:monster_egg"); + public static ItemInfo MossyStoneBrickMonsterEgg = new ItemInfo(97, 3, "Mossy Stone Brick Monster Egg", "minecraft:monster_egg"); + public static ItemInfo CrackedStoneBrickMonsterEgg = new ItemInfo(97, 4, "Cracked Stone Brick Monster Egg", "minecraft:monster_egg"); + public static ItemInfo ChiseledStoneBrickMonsterEgg = new ItemInfo(97, 5, "Chiseled Stone Brick Monster Egg", "minecraft:monster_egg"); + public static ItemInfo StoneBricks = new ItemInfo(98, 0, "Stone Bricks", "minecraft:stonebrick"); + public static ItemInfo MossyStoneBricks = new ItemInfo(98, 1, "Mossy Stone Bricks", "minecraft:stonebrick"); + public static ItemInfo CrackedStoneBricks = new ItemInfo(98, 2, "Cracked Stone Bricks", "minecraft:stonebrick"); + public static ItemInfo ChiseledStoneBricks = new ItemInfo(98, 3, "Chiseled Stone Bricks", "minecraft:stonebrick"); + public static ItemInfo BrownMushroomBlock = new ItemInfo(99, 0, "Brown Mushroom Block", "minecraft:brown_mushroom_block"); + public static ItemInfo RedMushroomBlock = new ItemInfo(100, 0, "Red Mushroom Block", "minecraft:red_mushroom_block"); + public static ItemInfo IronBars = new ItemInfo(101, 0, "Iron Bars", "minecraft:iron_bars"); + public static ItemInfo GlassPane = new ItemInfo(102, 0, "Glass Pane", "minecraft:glass_pane"); + public static ItemInfo MelonBlock = new ItemInfo(103, 0, "Melon Block", "minecraft:melon_block"); + public static ItemInfo PumpkinStem = new ItemInfo(104, 0, "Pumpkin Stem", "minecraft:pumpkin_stem"); + public static ItemInfo MelonStem = new ItemInfo(105, 0, "Melon Stem", "minecraft:melon_stem"); + public static ItemInfo Vines = new ItemInfo(106, 0, "Vines", "minecraft:vine"); + public static ItemInfo OakFenceGate = new ItemInfo(107, 0, "Oak Fence Gate", "minecraft:fence_gate"); + public static ItemInfo BrickStairs = new ItemInfo(108, 0, "Brick Stairs", "minecraft:brick_stairs"); + public static ItemInfo StoneBrickStairs = new ItemInfo(109, 0, "Stone Brick Stairs", "minecraft:stone_brick_stairs"); + public static ItemInfo Mycelium = new ItemInfo(110, 0, "Mycelium", "minecraft:mycelium"); + public static ItemInfo LilyPad = new ItemInfo(111, 0, "Lily Pad", "minecraft:waterlily"); + public static ItemInfo NetherBrick = new ItemInfo(112, 0, "Nether Brick", "minecraft:nether_brick").SetStackSize(64); + public static ItemInfo NetherBrickFence = new ItemInfo(113, 0, "Nether Brick Fence", "minecraft:nether_brick_fence"); + public static ItemInfo NetherBrickStairs = new ItemInfo(114, 0, "Nether Brick Stairs", "minecraft:nether_brick_stairs"); + public static ItemInfo NetherWart = new ItemInfo(115, 0, "Nether Wart", "minecraft:nether_wart").SetStackSize(64); + public static ItemInfo EnchantmentTable = new ItemInfo(116, 0, "Enchantment Table", "minecraft:enchanting_table"); + public static ItemInfo BrewingStand = new ItemInfo(117, 0, "Brewing Stand", "minecraft:brewing_stand").SetStackSize(64); + public static ItemInfo Cauldron = new ItemInfo(118, 0, "Cauldron", "minecraft:cauldron"); + public static ItemInfo EndPortal = new ItemInfo(119, 0, "End Portal", "minecraft:end_portal"); + public static ItemInfo EndPortalFrame = new ItemInfo(120, 0, "End Portal Frame", "minecraft:end_portal_frame"); + public static ItemInfo EndStone = new ItemInfo(121, 0, "End Stone", "minecraft:end_stone"); + public static ItemInfo DragonEgg = new ItemInfo(122, 0, "Dragon Egg", "minecraft:dragon_egg"); + public static ItemInfo RedstoneLampInactive = new ItemInfo(123, 0, "Redstone Lamp (inactive)", "minecraft:redstone_lamp"); + public static ItemInfo RedstoneLampActive = new ItemInfo(124, 0, "Redstone Lamp (active)", "minecraft:lit_redstone_lamp"); + public static ItemInfo DoubleOakWoodSlab = new ItemInfo(125, 0, "Double Oak Wood Slab", "minecraft:double_wooden_slab"); + public static ItemInfo DoubleSpruceWoodSlab = new ItemInfo(125, 1, "Double Spruce Wood Slab", "minecraft:double_wooden_slab"); + public static ItemInfo DoubleBirchWoodSlab = new ItemInfo(125, 2, "Double Birch Wood Slab", "minecraft:double_wooden_slab"); + public static ItemInfo DoubleJungleWoodSlab = new ItemInfo(125, 3, "Double Jungle Wood Slab", "minecraft:double_wooden_slab"); + public static ItemInfo DoubleAcaciaWoodSlab = new ItemInfo(125, 4, "Double Acacia Wood Slab", "minecraft:double_wooden_slab"); + public static ItemInfo DoubleDarkOakWoodSlab = new ItemInfo(125, 5, "Double Dark Oak Wood Slab", "minecraft:double_wooden_slab"); + public static ItemInfo OakWoodSlab = new ItemInfo(126, 0, "Oak Wood Slab", "minecraft:wooden_slab"); + public static ItemInfo SpruceWoodSlab = new ItemInfo(126, 1, "Spruce Wood Slab", "minecraft:wooden_slab"); + public static ItemInfo BirchWoodSlab = new ItemInfo(126, 2, "Birch Wood Slab", "minecraft:wooden_slab"); + public static ItemInfo JungleWoodSlab = new ItemInfo(126, 3, "Jungle Wood Slab", "minecraft:wooden_slab"); + public static ItemInfo AcaciaWoodSlab = new ItemInfo(126, 4, "Acacia Wood Slab", "minecraft:wooden_slab"); + public static ItemInfo DarkOakWoodSlab = new ItemInfo(126, 5, "Dark Oak Wood Slab", "minecraft:wooden_slab"); + public static ItemInfo Cocoa = new ItemInfo(127, 0, "Cocoa", "minecraft:cocoa"); + public static ItemInfo SandstoneStairs = new ItemInfo(128, 0, "Sandstone Stairs", "minecraft:sandstone_stairs"); + public static ItemInfo EmeraldOre = new ItemInfo(129, 0, "Emerald Ore", "minecraft:emerald_ore"); + public static ItemInfo EnderChest = new ItemInfo(130, 0, "Ender Chest", "minecraft:ender_chest"); + public static ItemInfo TripwireHook = new ItemInfo(131, 0, "Tripwire Hook", "minecraft:tripwire_hook"); + public static ItemInfo Tripwire = new ItemInfo(132, 0, "Tripwire", "minecraft:tripwire_hook"); + public static ItemInfo EmeraldBlock = new ItemInfo(133, 0, "Emerald Block", "minecraft:emerald_block"); + public static ItemInfo SpruceWoodStairs = new ItemInfo(134, 0, "Spruce Wood Stairs", "minecraft:spruce_stairs"); + public static ItemInfo BirchWoodStairs = new ItemInfo(135, 0, "Birch Wood Stairs", "minecraft:birch_stairs"); + public static ItemInfo JungleWoodStairs = new ItemInfo(136, 0, "Jungle Wood Stairs", "minecraft:jungle_stairs"); + public static ItemInfo CommandBlock = new ItemInfo(137, 0, "Command Block", "minecraft:command_block"); + public static ItemInfo Beacon = new ItemInfo(138, 0, "Beacon", "minecraft:beacon"); + public static ItemInfo CobblestoneWall = new ItemInfo(139, 0, "Cobblestone Wall", "minecraft:cobblestone_wall"); + public static ItemInfo MossyCobblestoneWall = new ItemInfo(139, 1, "Mossy Cobblestone Wall", "minecraft:cobblestone_wall"); + public static ItemInfo FlowerPot = new ItemInfo(140, 0, "Flower Pot", "minecraft:flower_pot").SetStackSize(64); + public static ItemInfo Carrots = new ItemInfo(141, 0, "Carrots", "minecraft:carrots"); + public static ItemInfo Potatoes = new ItemInfo(142, 0, "Potatoes", "minecraft:potatoes"); + public static ItemInfo WoodenButton = new ItemInfo(143, 0, "Wooden Button", "minecraft:wooden_button"); + public static ItemInfo MobHead = new ItemInfo(144, 0, "Mob Head", "minecraft:skull"); + public static ItemInfo Anvil = new ItemInfo(145, 0, "Anvil", "minecraft:anvil"); + public static ItemInfo TrappedChest = new ItemInfo(146, 0, "Trapped Chest", "minecraft:trapped_chest"); + public static ItemInfo WeightedPressurePlateLight = new ItemInfo(147, 0, "Weighted Pressure Plate (light)", "minecraft:light_weighted_pressure_plate"); + public static ItemInfo WeightedPressurePlateHeavy = new ItemInfo(148, 0, "Weighted Pressure Plate (heavy)", "minecraft:heavy_weighted_pressure_plate"); + public static ItemInfo RedstoneComparatorInactive = new ItemInfo(149, 0, "Redstone Comparator (inactive)", "minecraft:unpowered_comparator"); + public static ItemInfo RedstoneComparatorActive = new ItemInfo(150, 0, "Redstone Comparator (active)", "minecraft:powered_comparator"); + public static ItemInfo DaylightSensor = new ItemInfo(151, 0, "Daylight Sensor", "minecraft:daylight_detector"); + public static ItemInfo RedstoneBlock = new ItemInfo(152, 0, "Redstone Block", "minecraft:redstone_block"); + public static ItemInfo NetherQuartzOre = new ItemInfo(153, 0, "Nether Quartz Ore", "minecraft:quartz_ore"); + public static ItemInfo Hopper = new ItemInfo(154, 0, "Hopper", "minecraft:hopper"); + public static ItemInfo QuartzBlock = new ItemInfo(155, 0, "Quartz Block", "minecraft:quartz_block"); + public static ItemInfo ChiseledQuartzBlock = new ItemInfo(155, 1, "Chiseled Quartz Block", "minecraft:quartz_block"); + public static ItemInfo PillarQuartzBlock = new ItemInfo(155, 2, "Pillar Quartz Block", "minecraft:quartz_block"); + public static ItemInfo QuartzStairs = new ItemInfo(156, 0, "Quartz Stairs", "minecraft:quartz_stairs"); + public static ItemInfo ActivatorRail = new ItemInfo(157, 0, "Activator Rail", "minecraft:activator_rail"); + public static ItemInfo Dropper = new ItemInfo(158, 0, "Dropper", "minecraft:dropper"); + public static ItemInfo WhiteHardenedClay = new ItemInfo(159, 0, "White Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo OrangeHardenedClay = new ItemInfo(159, 1, "Orange Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo MagentaHardenedClay = new ItemInfo(159, 2, "Magenta Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo LightBlueHardenedClay = new ItemInfo(159, 3, "Light Blue Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo YellowHardenedClay = new ItemInfo(159, 4, "Yellow Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo LimeHardenedClay = new ItemInfo(159, 5, "Lime Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo PinkHardenedClay = new ItemInfo(159, 6, "Pink Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo GrayHardenedClay = new ItemInfo(159, 7, "Gray Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo LightGrayHardenedClay = new ItemInfo(159, 8, "Light Gray Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo CyanHardenedClay = new ItemInfo(159, 9, "Cyan Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo PurpleHardenedClay = new ItemInfo(159, 10, "Purple Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo BlueHardenedClay = new ItemInfo(159, 11, "Blue Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo BrownHardenedClay = new ItemInfo(159, 12, "Brown Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo GreenHardenedClay = new ItemInfo(159, 13, "Green Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo RedHardenedClay = new ItemInfo(159, 14, "Red Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo BlackHardenedClay = new ItemInfo(159, 15, "Black Hardened Clay", "minecraft:stained_hardened_clay"); + public static ItemInfo WhiteStainedGlassPane = new ItemInfo(160, 0, "White Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo OrangeStainedGlassPane = new ItemInfo(160, 1, "Orange Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo MagentaStainedGlassPane = new ItemInfo(160, 2, "Magenta Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo LightBlueStainedGlassPane = new ItemInfo(160, 3, "Light Blue Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo YellowStainedGlassPane = new ItemInfo(160, 4, "Yellow Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo LimeStainedGlassPane = new ItemInfo(160, 5, "Lime Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo PinkStainedGlassPane = new ItemInfo(160, 6, "Pink Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo GrayStainedGlassPane = new ItemInfo(160, 7, "Gray Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo LightGrayStainedGlassPane = new ItemInfo(160, 8, "Light Gray Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo CyanStainedGlassPane = new ItemInfo(160, 9, "Cyan Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo PurpleStainedGlassPane = new ItemInfo(160, 10, "Purple Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo BlueStainedGlassPane = new ItemInfo(160, 11, "Blue Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo BrownStainedGlassPane = new ItemInfo(160, 12, "Brown Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo GreenStainedGlassPane = new ItemInfo(160, 13, "Green Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo RedStainedGlassPane = new ItemInfo(160, 14, "Red Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo BlackStainedGlassPane = new ItemInfo(160, 15, "Black Stained Glass Pane", "minecraft:stained_glass_pane"); + public static ItemInfo AcaciaLeaves = new ItemInfo(161, 0, "Acacia Leaves", "minecraft:leaves2"); + public static ItemInfo DarkOakLeaves = new ItemInfo(161, 1, "Dark Oak Leaves", "minecraft:leaves2"); + public static ItemInfo AcaciaWood = new ItemInfo(162, 0, "Acacia Wood", "minecraft:log2"); + public static ItemInfo DarkOakWood = new ItemInfo(162, 1, "Dark Oak Wood", "minecraft:log2"); + public static ItemInfo AcaciaWoodStairs = new ItemInfo(163, 0, "Acacia Wood Stairs", "minecraft:acacia_stairs"); + public static ItemInfo DarkOakWoodStairs = new ItemInfo(164, 0, "Dark Oak Wood Stairs", "minecraft:dark_oak_stairs"); + public static ItemInfo SlimeBlock = new ItemInfo(165, 0, "Slime Block", "minecraft:slime"); + public static ItemInfo Barrier = new ItemInfo(166, 0, "Barrier", "minecraft:barrier"); + public static ItemInfo IronTrapdoor = new ItemInfo(167, 0, "Iron Trapdoor", "minecraft:iron_trapdoor"); + public static ItemInfo Prismarine = new ItemInfo(168, 0, "Prismarine", "minecraft:prismarine"); + public static ItemInfo PrismarineBricks = new ItemInfo(168, 1, "Prismarine Bricks", "minecraft:prismarine"); + public static ItemInfo DarkPrismarine = new ItemInfo(168, 2, "Dark Prismarine", "minecraft:prismarine"); + public static ItemInfo SeaLantern = new ItemInfo(169, 0, "Sea Lantern", "minecraft:sea_lantern"); + public static ItemInfo HayBale = new ItemInfo(170, 0, "Hay Bale", "minecraft:hay_block"); + public static ItemInfo WhiteCarpet = new ItemInfo(171, 0, "White Carpet", "minecraft:carpet"); + public static ItemInfo OrangeCarpet = new ItemInfo(171, 1, "Orange Carpet", "minecraft:carpet"); + public static ItemInfo MagentaCarpet = new ItemInfo(171, 2, "Magenta Carpet", "minecraft:carpet"); + public static ItemInfo LightBlueCarpet = new ItemInfo(171, 3, "Light Blue Carpet", "minecraft:carpet"); + public static ItemInfo YellowCarpet = new ItemInfo(171, 4, "Yellow Carpet", "minecraft:carpet"); + public static ItemInfo LimeCarpet = new ItemInfo(171, 5, "Lime Carpet", "minecraft:carpet"); + public static ItemInfo PinkCarpet = new ItemInfo(171, 6, "Pink Carpet", "minecraft:carpet"); + public static ItemInfo GrayCarpet = new ItemInfo(171, 7, "Gray Carpet", "minecraft:carpet"); + public static ItemInfo LightGrayCarpet = new ItemInfo(171, 8, "Light Gray Carpet", "minecraft:carpet"); + public static ItemInfo CyanCarpet = new ItemInfo(171, 9, "Cyan Carpet", "minecraft:carpet"); + public static ItemInfo PurpleCarpet = new ItemInfo(171, 10, "Purple Carpet", "minecraft:carpet"); + public static ItemInfo BlueCarpet = new ItemInfo(171, 11, "Blue Carpet", "minecraft:carpet"); + public static ItemInfo BrownCarpet = new ItemInfo(171, 12, "Brown Carpet", "minecraft:carpet"); + public static ItemInfo GreenCarpet = new ItemInfo(171, 13, "Green Carpet", "minecraft:carpet"); + public static ItemInfo RedCarpet = new ItemInfo(171, 14, "Red Carpet", "minecraft:carpet"); + public static ItemInfo BlackCarpet = new ItemInfo(171, 15, "Black Carpet", "minecraft:carpet"); + public static ItemInfo HardenedClay = new ItemInfo(172, 0, "Hardened Clay", "minecraft:hardened_clay"); + public static ItemInfo BlockOfCoal = new ItemInfo(173, 0, "Block of Coal", "minecraft:coal_block"); + public static ItemInfo PackedIce = new ItemInfo(174, 0, "Packed Ice", "minecraft:packed_ice"); + public static ItemInfo Sunflower = new ItemInfo(175, 0, "Sunflower", "minecraft:double_plant"); + public static ItemInfo Lilac = new ItemInfo(175, 1, "Lilac", "minecraft:double_plant"); + public static ItemInfo DoubleTallgrass = new ItemInfo(175, 2, "Double Tallgrass", "minecraft:double_plant"); + public static ItemInfo LargeFern = new ItemInfo(175, 3, "Large Fern", "minecraft:double_plant"); + public static ItemInfo RoseBush = new ItemInfo(175, 4, "Rose Bush", "minecraft:double_plant"); + public static ItemInfo Peony = new ItemInfo(175, 5, "Peony", "minecraft:double_plant"); + public static ItemInfo FreeStandingBanner = new ItemInfo(176, 0, "Free-standing Banner", "minecraft:standing_banner"); + public static ItemInfo WallMountedBanner = new ItemInfo(177, 0, "Wall-mounted Banner", "minecraft:wall_banner"); + public static ItemInfo InvertedDaylightSensor = new ItemInfo(178, 0, "Inverted Daylight Sensor", "minecraft:daylight_detector_inverted"); + public static ItemInfo RedSandstone = new ItemInfo(179, 0, "Red Sandstone", "minecraft:red_sandstone"); + public static ItemInfo ChiseledRedSandstone = new ItemInfo(179, 1, "Chiseled Red Sandstone", "minecraft:red_sandstone"); + public static ItemInfo SmoothRedSandstone = new ItemInfo(179, 2, "Smooth Red Sandstone", "minecraft:red_sandstone"); + public static ItemInfo RedSandstoneStairs = new ItemInfo(180, 0, "Red Sandstone Stairs", "minecraft:red_sandstone_stairs"); + public static ItemInfo DoubleRedSandstoneSlab = new ItemInfo(181, 0, "Double Red Sandstone Slab", "minecraft:double_stone_slab2"); + public static ItemInfo RedSandstoneSlab = new ItemInfo(182, 0, "Red Sandstone Slab", "minecraft:stone_slab2"); + public static ItemInfo SpruceFenceGate = new ItemInfo(183, 0, "Spruce Fence Gate", "minecraft:spruce_fence_gate"); + public static ItemInfo BirchFenceGate = new ItemInfo(184, 0, "Birch Fence Gate", "minecraft:birch_fence_gate"); + public static ItemInfo JungleFenceGate = new ItemInfo(185, 0, "Jungle Fence Gate", "minecraft:jungle_fence_gate"); + public static ItemInfo DarkOakFenceGate = new ItemInfo(186, 0, "Dark Oak Fence Gate", "minecraft:dark_oak_fence_gate"); + public static ItemInfo AcaciaFenceGate = new ItemInfo(187, 0, "Acacia Fence Gate", "minecraft:acacia_fence_gate"); + public static ItemInfo SpruceFence = new ItemInfo(188, 0, "Spruce Fence", "minecraft:spruce_fence"); + public static ItemInfo BirchFence = new ItemInfo(189, 0, "Birch Fence", "minecraft:birch_fence"); + public static ItemInfo JungleFence = new ItemInfo(190, 0, "Jungle Fence", "minecraft:jungle_fence"); + public static ItemInfo DarkOakFence = new ItemInfo(191, 0, "Dark Oak Fence", "minecraft:dark_oak_fence"); + public static ItemInfo AcaciaFence = new ItemInfo(192, 0, "Acacia Fence", "minecraft:acacia_fence"); + public static ItemInfo SpruceDoorBlock = new ItemInfo(193, 0, "Spruce Door Block", "minecraft:spruce_door"); + public static ItemInfo BirchDoorBlock = new ItemInfo(194, 0, "Birch Door Block", "minecraft:birch_door"); + public static ItemInfo JungleDoorBlock = new ItemInfo(195, 0, "Jungle Door Block", "minecraft:jungle_door"); + public static ItemInfo AcaciaDoorBlock = new ItemInfo(196, 0, "Acacia Door Block", "minecraft:acacia_door"); + public static ItemInfo DarkOakDoorBlock = new ItemInfo(197, 0, "Dark Oak Door Block", "minecraft:dark_oak_door"); + public static ItemInfo EndRod = new ItemInfo(198, 0, "End Rod", "minecraft:end_rod"); + public static ItemInfo ChorusPlant = new ItemInfo(199, 0, "Chorus Plant", "minecraft:chorus_plant"); + public static ItemInfo ChorusFlower = new ItemInfo(200, 0, "Chorus Flower", "minecraft:chorus_flower"); + public static ItemInfo PurpurBlock = new ItemInfo(201, 0, "Purpur Block", "minecraft:purpur_block"); + public static ItemInfo PurpurPillar = new ItemInfo(202, 0, "Purpur Pillar", "minecraft:purpur_pillar"); + public static ItemInfo PurpurStairs = new ItemInfo(203, 0, "Purpur Stairs", "minecraft:purpur_stairs"); + public static ItemInfo PurpurDoubleSlab = new ItemInfo(204, 0, "Purpur Double Slab", "minecraft:purpur_double_slab"); + public static ItemInfo PurpurSlab = new ItemInfo(205, 0, "Purpur Slab", "minecraft:purpur_slab"); + public static ItemInfo EndStoneBricks = new ItemInfo(206, 0, "End Stone Bricks", "minecraft:end_bricks"); + public static ItemInfo BeetrootBlock = new ItemInfo(207, 0, "Beetroot Block", "minecraft:beetroots"); + public static ItemInfo GrassPath = new ItemInfo(208, 0, "Grass Path", "minecraft:grass_path"); + public static ItemInfo EndGateway = new ItemInfo(209, 0, "End Gateway", "minecraft:end_gateway"); + public static ItemInfo RepeatingCommandBlock = new ItemInfo(210, 0, "Repeating Command Block", "minecraft:repeating_command_block"); + public static ItemInfo ChainCommandBlock = new ItemInfo(211, 0, "Chain Command Block", "minecraft:chain_command_block"); + public static ItemInfo FrostedIce = new ItemInfo(212, 0, "Frosted Ice", "minecraft:frosted_ice"); + public static ItemInfo MagmaBlock = new ItemInfo(213, 0, "Magma Block", "minecraft:magma"); + public static ItemInfo NetherWartBlock = new ItemInfo(214, 0, "Nether Wart Block", "minecraft:nether_wart_block"); + public static ItemInfo RedNetherBrick = new ItemInfo(215, 0, "Red Nether Brick", "minecraft:red_nether_brick"); + public static ItemInfo BoneBlock = new ItemInfo(216, 0, "Bone Block", "minecraft:bone_block"); + public static ItemInfo StructureVoid = new ItemInfo(217, 0, "Structure Void", "minecraft:structure_void"); + public static ItemInfo Observer = new ItemInfo(218, 0, "Observer", "minecraft:observer"); + public static ItemInfo WhiteShulkerBox = new ItemInfo(219, 0, "White Shulker Box", "minecraft:white_shulker_box"); + public static ItemInfo OrangeShulkerBox = new ItemInfo(220, 0, "Orange Shulker Box", "minecraft:orange_shulker_box"); + public static ItemInfo MagentaShulkerBox = new ItemInfo(221, 0, "Magenta Shulker Box", "minecraft:magenta_shulker_box"); + public static ItemInfo LightBlueShulkerBox = new ItemInfo(222, 0, "Light Blue Shulker Box", "minecraft:light_blue_shulker_box"); + public static ItemInfo YellowShulkerBox = new ItemInfo(223, 0, "Yellow Shulker Box", "minecraft:yellow_shulker_box"); + public static ItemInfo LimeShulkerBox = new ItemInfo(224, 0, "Lime Shulker Box", "minecraft:lime_shulker_box"); + public static ItemInfo PinkShulkerBox = new ItemInfo(225, 0, "Pink Shulker Box", "minecraft:pink_shulker_box"); + public static ItemInfo GrayShulkerBox = new ItemInfo(226, 0, "Gray Shulker Box", "minecraft:gray_shulker_box"); + public static ItemInfo LightGrayShulkerBox = new ItemInfo(227, 0, "Light Gray Shulker Box", "minecraft:silver_shulker_box"); + public static ItemInfo CyanShulkerBox = new ItemInfo(228, 0, "Cyan Shulker Box", "minecraft:cyan_shulker_box"); + public static ItemInfo PurpleShulkerBox = new ItemInfo(229, 0, "Purple Shulker Box", "minecraft:purple_shulker_box"); + public static ItemInfo BlueShulkerBox = new ItemInfo(230, 0, "Blue Shulker Box", "minecraft:blue_shulker_box"); + public static ItemInfo BrownShulkerBox = new ItemInfo(231, 0, "Brown Shulker Box", "minecraft:brown_shulker_box"); + public static ItemInfo GreenShulkerBox = new ItemInfo(232, 0, "Green Shulker Box", "minecraft:green_shulker_box"); + public static ItemInfo RedShulkerBox = new ItemInfo(233, 0, "Red Shulker Box", "minecraft:red_shulker_box"); + public static ItemInfo BlackShulkerBox = new ItemInfo(234, 0, "Black Shulker Box", "minecraft:black_shulker_box"); + public static ItemInfo WhiteGlazedTerracotta = new ItemInfo(235, 0, "White Glazed Terracotta", "minecraft:white_glazed_terracotta"); + public static ItemInfo OrangeGlazedTerracotta = new ItemInfo(236, 0, "Orange Glazed Terracotta", "minecraft:orange_glazed_terracotta"); + public static ItemInfo MagentaGlazedTerracotta = new ItemInfo(237, 0, "Magenta Glazed Terracotta", "minecraft:magenta_glazed_terracotta"); + public static ItemInfo LightBlueGlazedTerracotta = new ItemInfo(238, 0, "Light Blue Glazed Terracotta", "minecraft:light_blue_glazed_terracotta"); + public static ItemInfo YellowGlazedTerracotta = new ItemInfo(239, 0, "Yellow Glazed Terracotta", "minecraft:yellow_glazed_terracotta"); + public static ItemInfo LimeGlazedTerracotta = new ItemInfo(240, 0, "Lime Glazed Terracotta", "minecraft:lime_glazed_terracotta"); + public static ItemInfo PinkGlazedTerracotta = new ItemInfo(241, 0, "Pink Glazed Terracotta", "minecraft:pink_glazed_terracotta"); + public static ItemInfo GrayGlazedTerracotta = new ItemInfo(242, 0, "Gray Glazed Terracotta", "minecraft:gray_glazed_terracotta"); + public static ItemInfo LightGrayGlazedTerracotta = new ItemInfo(243, 0, "Light Gray Glazed Terracotta", "minecraft:light_gray_glazed_terracotta"); + public static ItemInfo CyanGlazedTerracotta = new ItemInfo(244, 0, "Cyan Glazed Terracotta", "minecraft:cyan_glazed_terracotta"); + public static ItemInfo PurpleGlazedTerracotta = new ItemInfo(245, 0, "Purple Glazed Terracotta", "minecraft:purple_glazed_terracotta"); + public static ItemInfo BlueGlazedTerracotta = new ItemInfo(246, 0, "Blue Glazed Terracotta", "minecraft:blue_glazed_terracotta"); + public static ItemInfo BrownGlazedTerracotta = new ItemInfo(247, 0, "Brown Glazed Terracotta", "minecraft:brown_glazed_terracotta"); + public static ItemInfo GreenGlazedTerracotta = new ItemInfo(248, 0, "Green Glazed Terracotta", "minecraft:green_glazed_terracotta"); + public static ItemInfo RedGlazedTerracotta = new ItemInfo(249, 0, "Red Glazed Terracotta", "minecraft:red_glazed_terracotta"); + public static ItemInfo BlackGlazedTerracotta = new ItemInfo(250, 0, "Black Glazed Terracotta", "minecraft:black_glazed_terracotta"); + public static ItemInfo WhiteConcrete = new ItemInfo(251, 0, "White Concrete", "minecraft:concrete"); + public static ItemInfo OrangeConcrete = new ItemInfo(251, 1, "Orange Concrete", "minecraft:concrete"); + public static ItemInfo MagentaConcrete = new ItemInfo(251, 2, "Magenta Concrete", "minecraft:concrete"); + public static ItemInfo LightBlueConcrete = new ItemInfo(251, 3, "Light Blue Concrete", "minecraft:concrete"); + public static ItemInfo YellowConcrete = new ItemInfo(251, 4, "Yellow Concrete", "minecraft:concrete"); + public static ItemInfo LimeConcrete = new ItemInfo(251, 5, "Lime Concrete", "minecraft:concrete"); + public static ItemInfo PinkConcrete = new ItemInfo(251, 6, "Pink Concrete", "minecraft:concrete"); + public static ItemInfo GrayConcrete = new ItemInfo(251, 7, "Gray Concrete", "minecraft:concrete"); + public static ItemInfo LightGrayConcrete = new ItemInfo(251, 8, "Light Gray Concrete", "minecraft:concrete"); + public static ItemInfo CyanConcrete = new ItemInfo(251, 9, "Cyan Concrete", "minecraft:concrete"); + public static ItemInfo PurpleConcrete = new ItemInfo(251, 10, "Purple Concrete", "minecraft:concrete"); + public static ItemInfo BlueConcrete = new ItemInfo(251, 11, "Blue Concrete", "minecraft:concrete"); + public static ItemInfo BrownConcrete = new ItemInfo(251, 12, "Brown Concrete", "minecraft:concrete"); + public static ItemInfo GreenConcrete = new ItemInfo(251, 13, "Green Concrete", "minecraft:concrete"); + public static ItemInfo RedConcrete = new ItemInfo(251, 14, "Red Concrete", "minecraft:concrete"); + public static ItemInfo BlackConcrete = new ItemInfo(251, 15, "Black Concrete", "minecraft:concrete"); + public static ItemInfo WhiteConcretePowder = new ItemInfo(252, 0, "White Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo OrangeConcretePowder = new ItemInfo(252, 1, "Orange Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo MagentaConcretePowder = new ItemInfo(252, 2, "Magenta Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo LightBlueConcretePowder = new ItemInfo(252, 3, "Light Blue Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo YellowConcretePowder = new ItemInfo(252, 4, "Yellow Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo LimeConcretePowder = new ItemInfo(252, 5, "Lime Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo PinkConcretePowder = new ItemInfo(252, 6, "Pink Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo GrayConcretePowder = new ItemInfo(252, 7, "Gray Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo LightGrayConcretePowder = new ItemInfo(252, 8, "Light Gray Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo CyanConcretePowder = new ItemInfo(252, 9, "Cyan Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo PurpleConcretePowder = new ItemInfo(252, 10, "Purple Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo BlueConcretePowder = new ItemInfo(252, 11, "Blue Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo BrownConcretePowder = new ItemInfo(252, 12, "Brown Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo GreenConcretePowder = new ItemInfo(252, 13, "Green Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo RedConcretePowder = new ItemInfo(252, 14, "Red Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo BlackConcretePowder = new ItemInfo(252, 15, "Black Concrete Powder", "minecraft:concrete_powder"); + public static ItemInfo StructureBlock = new ItemInfo(255, 0, "Structure Block", "minecraft:structure_block"); + public static ItemInfo IronShovel = new ItemInfo(256, 0, "Iron Shovel", "minecraft:iron_shovel"); + public static ItemInfo IronPickaxe = new ItemInfo(257, 0, "Iron Pickaxe", "minecraft:iron_pickaxe"); + public static ItemInfo IronAxe = new ItemInfo(258, 0, "Iron Axe", "minecraft:iron_axe"); + public static ItemInfo FlintAndSteel = new ItemInfo(259, 0, "Flint and Steel", "minecraft:flint_and_steel"); + public static ItemInfo Apple = new ItemInfo(260, 0, "Apple", "minecraft:apple", stack: 64).SetStackSize(64); + public static ItemInfo Bow = new ItemInfo(261, 0, "Bow", "minecraft:bow"); + public static ItemInfo Arrow = new ItemInfo(262, 0, "Arrow", "minecraft:arrow").SetStackSize(64); + public static ItemInfo Coal = new ItemInfo(263, 0, "Coal", "minecraft:coal").SetStackSize(64); + public static ItemInfo Charcoal = new ItemInfo(263, 1, "Charcoal", "minecraft:coal"); + public static ItemInfo Diamond = new ItemInfo(264, 0, "Diamond", "minecraft:diamond").SetStackSize(64); + public static ItemInfo IronIngot = new ItemInfo(265, 0, "Iron Ingot", "minecraft:iron_ingot").SetStackSize(64); + public static ItemInfo GoldIngot = new ItemInfo(266, 0, "Gold Ingot", "minecraft:gold_ingot").SetStackSize(64); + public static ItemInfo IronSword = new ItemInfo(267, 0, "Iron Sword", "minecraft:iron_sword"); + public static ItemInfo WoodenSword = new ItemInfo(268, 0, "Wooden Sword", "minecraft:wooden_sword"); + public static ItemInfo WoodenShovel = new ItemInfo(269, 0, "Wooden Shovel", "minecraft:wooden_shovel"); + public static ItemInfo WoodenPickaxe = new ItemInfo(270, 0, "Wooden Pickaxe", "minecraft:wooden_pickaxe"); + public static ItemInfo WoodenAxe = new ItemInfo(271, 0, "Wooden Axe", "minecraft:wooden_axe"); + public static ItemInfo StoneSword = new ItemInfo(272, 0, "Stone Sword", "minecraft:stone_sword"); + public static ItemInfo StoneShovel = new ItemInfo(273, 0, "Stone Shovel", "minecraft:stone_shovel"); + public static ItemInfo StonePickaxe = new ItemInfo(274, 0, "Stone Pickaxe", "minecraft:stone_pickaxe"); + public static ItemInfo StoneAxe = new ItemInfo(275, 0, "Stone Axe", "minecraft:stone_axe"); + public static ItemInfo DiamondSword = new ItemInfo(276, 0, "Diamond Sword", "minecraft:diamond_sword"); + public static ItemInfo DiamondShovel = new ItemInfo(277, 0, "Diamond Shovel", "minecraft:diamond_shovel"); + public static ItemInfo DiamondPickaxe = new ItemInfo(278, 0, "Diamond Pickaxe", "minecraft:diamond_pickaxe"); + public static ItemInfo DiamondAxe = new ItemInfo(279, 0, "Diamond Axe", "minecraft:diamond_axe"); + public static ItemInfo Stick = new ItemInfo(280, 0, "Stick", "minecraft:stick").SetStackSize(64); + public static ItemInfo Bowl = new ItemInfo(281, 0, "Bowl", "minecraft:bowl").SetStackSize(64); + public static ItemInfo MushroomStew = new ItemInfo(282, 0, "Mushroom Stew", "minecraft:mushroom_stew"); + public static ItemInfo GoldenSword = new ItemInfo(283, 0, "Golden Sword", "minecraft:golden_sword"); + public static ItemInfo GoldenShovel = new ItemInfo(284, 0, "Golden Shovel", "minecraft:golden_shovel"); + public static ItemInfo GoldenPickaxe = new ItemInfo(285, 0, "Golden Pickaxe", "minecraft:golden_pickaxe"); + public static ItemInfo GoldenAxe = new ItemInfo(286, 0, "Golden Axe", "minecraft:golden_axe"); + public static ItemInfo String = new ItemInfo(287, 0, "String", "minecraft:string").SetStackSize(64); + public static ItemInfo Feather = new ItemInfo(288, 0, "Feather", "minecraft:feather").SetStackSize(64); + public static ItemInfo Gunpowder = new ItemInfo(289, 0, "Gunpowder", "minecraft:gunpowder").SetStackSize(64); + public static ItemInfo WoodenHoe = new ItemInfo(290, 0, "Wooden Hoe", "minecraft:wooden_hoe"); + public static ItemInfo StoneHoe = new ItemInfo(291, 0, "Stone Hoe", "minecraft:stone_hoe"); + public static ItemInfo IronHoe = new ItemInfo(292, 0, "Iron Hoe", "minecraft:iron_hoe"); + public static ItemInfo DiamondHoe = new ItemInfo(293, 0, "Diamond Hoe", "minecraft:diamond_hoe"); + public static ItemInfo GoldenHoe = new ItemInfo(294, 0, "Golden Hoe", "minecraft:golden_hoe"); + public static ItemInfo WheatSeeds = new ItemInfo(295, 0, "Wheat Seeds", "minecraft:wheat_seeds").SetStackSize(64); + public static ItemInfo Wheat = new ItemInfo(296, 0, "Wheat", "minecraft:wheat").SetStackSize(64); + public static ItemInfo Bread = new ItemInfo(297, 0, "Bread", "minecraft:bread").SetStackSize(64); + public static ItemInfo LeatherHelmet = new ItemInfo(298, 0, "Leather Helmet", "minecraft:leather_helmet"); + public static ItemInfo LeatherTunic = new ItemInfo(299, 0, "Leather Tunic", "minecraft:leather_chestplate"); + public static ItemInfo LeatherPants = new ItemInfo(300, 0, "Leather Pants", "minecraft:leather_leggings"); + public static ItemInfo LeatherBoots = new ItemInfo(301, 0, "Leather Boots", "minecraft:leather_boots"); + public static ItemInfo ChainmailHelmet = new ItemInfo(302, 0, "Chainmail Helmet", "minecraft:chainmail_helmet"); + public static ItemInfo ChainmailChestplate = new ItemInfo(303, 0, "Chainmail Chestplate", "minecraft:chainmail_chestplate"); + public static ItemInfo ChainmailLeggings = new ItemInfo(304, 0, "Chainmail Leggings", "minecraft:chainmail_leggings"); + public static ItemInfo ChainmailBoots = new ItemInfo(305, 0, "Chainmail Boots", "minecraft:chainmail_boots"); + public static ItemInfo IronHelmet = new ItemInfo(306, 0, "Iron Helmet", "minecraft:iron_helmet"); + public static ItemInfo IronChestplate = new ItemInfo(307, 0, "Iron Chestplate", "minecraft:iron_chestplate"); + public static ItemInfo IronLeggings = new ItemInfo(308, 0, "Iron Leggings", "minecraft:iron_leggings"); + public static ItemInfo IronBoots = new ItemInfo(309, 0, "Iron Boots", "minecraft:iron_boots"); + public static ItemInfo DiamondHelmet = new ItemInfo(310, 0, "Diamond Helmet", "minecraft:diamond_helmet"); + public static ItemInfo DiamondChestplate = new ItemInfo(311, 0, "Diamond Chestplate", "minecraft:diamond_chestplate"); + public static ItemInfo DiamondLeggings = new ItemInfo(312, 0, "Diamond Leggings", "minecraft:diamond_leggings"); + public static ItemInfo DiamondBoots = new ItemInfo(313, 0, "Diamond Boots", "minecraft:diamond_boots"); + public static ItemInfo GoldenHelmet = new ItemInfo(314, 0, "Golden Helmet", "minecraft:golden_helmet"); + public static ItemInfo GoldenChestplate = new ItemInfo(315, 0, "Golden Chestplate", "minecraft:golden_chestplate"); + public static ItemInfo GoldenLeggings = new ItemInfo(316, 0, "Golden Leggings", "minecraft:golden_leggings"); + public static ItemInfo GoldenBoots = new ItemInfo(317, 0, "Golden Boots", "minecraft:golden_boots"); + public static ItemInfo Flint = new ItemInfo(318, 0, "Flint", "minecraft:flint").SetStackSize(64); + public static ItemInfo RawPorkchop = new ItemInfo(319, 0, "Raw Porkchop", "minecraft:porkchop").SetStackSize(64); + public static ItemInfo CookedPorkchop = new ItemInfo(320, 0, "Cooked Porkchop", "minecraft:cooked_porkchop").SetStackSize(64); + public static ItemInfo Painting = new ItemInfo(321, 0, "Painting", "minecraft:painting").SetStackSize(64); + public static ItemInfo GoldenApple = new ItemInfo(322, 0, "Golden Apple", "minecraft:golden_apple").SetStackSize(64); + public static ItemInfo EnchantedGoldenApple = new ItemInfo(322, 1, "Enchanted Golden Apple", "minecraft:golden_apple"); + public static ItemInfo Sign = new ItemInfo(323, 0, "Sign", "minecraft:sign"); + public static ItemInfo OakDoor = new ItemInfo(324, 0, "Oak Door", "minecraft:wooden_door"); + public static ItemInfo Bucket = new ItemInfo(325, 0, "Bucket", "minecraft:bucket"); + public static ItemInfo WaterBucket = new ItemInfo(326, 0, "Water Bucket", "minecraft:water_bucket"); + public static ItemInfo LavaBucket = new ItemInfo(327, 0, "Lava Bucket", "minecraft:lava_bucket"); + public static ItemInfo Minecart = new ItemInfo(328, 0, "Minecart", "minecraft:minecart"); + public static ItemInfo Saddle = new ItemInfo(329, 0, "Saddle", "minecraft:saddle"); + public static ItemInfo IronDoor = new ItemInfo(330, 0, "Iron Door", "minecraft:iron_door"); + public static ItemInfo Redstone = new ItemInfo(331, 0, "Redstone", "minecraft:redstone"); + public static ItemInfo Snowball = new ItemInfo(332, 0, "Snowball", "minecraft:snowball"); + public static ItemInfo OakBoat = new ItemInfo(333, 0, "Oak Boat", "minecraft:boat"); + public static ItemInfo Leather = new ItemInfo(334, 0, "Leather", "minecraft:leather").SetStackSize(64); + public static ItemInfo MilkBucket = new ItemInfo(335, 0, "Milk Bucket", "minecraft:milk_bucket"); + public static ItemInfo ClayBrick = new ItemInfo(336, 0, "Brick", "minecraft:brick").SetStackSize(64); + public static ItemInfo ClayBall = new ItemInfo(337, 0, "Clay", "minecraft:clay_ball").SetStackSize(64); + public static ItemInfo Paper = new ItemInfo(339, 0, "Paper", "minecraft:paper"); + public static ItemInfo Book = new ItemInfo(340, 0, "Book", "minecraft:book").SetStackSize(64); + public static ItemInfo Slimeball = new ItemInfo(341, 0, "Slimeball", "minecraft:slime_ball").SetStackSize(64); + public static ItemInfo MinecartWithChest = new ItemInfo(342, 0, "Minecart with Chest", "minecraft:chest_minecart"); + public static ItemInfo MinecartWithFurnace = new ItemInfo(343, 0, "Minecart with Furnace", "minecraft:furnace_minecart"); + public static ItemInfo Egg = new ItemInfo(344, 0, "Egg", "minecraft:egg").SetStackSize(16); + public static ItemInfo Compass = new ItemInfo(345, 0, "Compass", "minecraft:compass"); + public static ItemInfo FishingRod = new ItemInfo(346, 0, "Fishing Rod", "minecraft:fishing_rod"); + public static ItemInfo Clock = new ItemInfo(347, 0, "Clock", "minecraft:clock"); + public static ItemInfo GlowstoneDust = new ItemInfo(348, 0, "Glowstone Dust", "minecraft:glowstone_dust").SetStackSize(64); + public static ItemInfo RawFish = new ItemInfo(349, 0, "Raw Fish", "minecraft:fish").SetStackSize(64); + public static ItemInfo RawSalmon = new ItemInfo(349, 1, "Raw Salmon", "minecraft:fish").SetStackSize(64); + public static ItemInfo Clownfish = new ItemInfo(349, 2, "Clownfish", "minecraft:fish").SetStackSize(64); + public static ItemInfo Pufferfish = new ItemInfo(349, 3, "Pufferfish", "minecraft:fish").SetStackSize(64); + public static ItemInfo CookedFish = new ItemInfo(350, 0, "Cooked Fish", "minecraft:cooked_fish").SetStackSize(64); + public static ItemInfo CookedSalmon = new ItemInfo(350, 1, "Cooked Salmon", "minecraft:cooked_fish").SetStackSize(64); + public static ItemInfo InkSack = new ItemInfo(351, 0, "Ink Sack", "minecraft:dye").SetStackSize(64); + public static ItemInfo RoseRed = new ItemInfo(351, 1, "Rose Red", "minecraft:dye").SetStackSize(64); + public static ItemInfo CactusGreen = new ItemInfo(351, 2, "Cactus Green", "minecraft:dye").SetStackSize(64); + public static ItemInfo CocoBeans = new ItemInfo(351, 3, "Coco Beans", "minecraft:dye").SetStackSize(64); + public static ItemInfo LapisLazuli = new ItemInfo(351, 4, "Lapis Lazuli", "minecraft:dye").SetStackSize(64); + public static ItemInfo PurpleDye = new ItemInfo(351, 5, "Purple Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo CyanDye = new ItemInfo(351, 6, "Cyan Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo LightGrayDye = new ItemInfo(351, 7, "Light Gray Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo GrayDye = new ItemInfo(351, 8, "Gray Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo PinkDye = new ItemInfo(351, 9, "Pink Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo LimeDye = new ItemInfo(351, 10, "Lime Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo DandelionYellow = new ItemInfo(351, 11, "Dandelion Yellow", "minecraft:dye").SetStackSize(64); + public static ItemInfo LightBlueDye = new ItemInfo(351, 12, "Light Blue Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo MagentaDye = new ItemInfo(351, 13, "Magenta Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo OrangeDye = new ItemInfo(351, 14, "Orange Dye", "minecraft:dye").SetStackSize(64); + public static ItemInfo BoneMeal = new ItemInfo(351, 15, "Bone Meal", "minecraft:dye").SetStackSize(64); + public static ItemInfo Bone = new ItemInfo(352, 0, "Bone", "minecraft:bone"); + public static ItemInfo Sugar = new ItemInfo(353, 0, "Sugar", "minecraft:sugar").SetStackSize(64); + public static ItemInfo Cake = new ItemInfo(354, 0, "Cake", "minecraft:cake"); + public static ItemInfo RedstoneRepeater = new ItemInfo(356, 0, "Redstone Repeater", "minecraft:repeater").SetStackSize(64); + public static ItemInfo Cookie = new ItemInfo(357, 0, "Cookie", "minecraft:cookie").SetStackSize(64); + public static ItemInfo Map = new ItemInfo(358, 0, "Map", "minecraft:filled_map"); + public static ItemInfo Shears = new ItemInfo(359, 0, "Shears", "minecraft:shears"); + public static ItemInfo Melon = new ItemInfo(360, 0, "Melon", "minecraft:melon"); + public static ItemInfo PumpkinSeeds = new ItemInfo(361, 0, "Pumpkin Seeds", "minecraft:pumpkin_seeds").SetStackSize(64); + public static ItemInfo MelonSeeds = new ItemInfo(362, 0, "Melon Seeds", "minecraft:melon_seeds").SetStackSize(64); + public static ItemInfo RawBeef = new ItemInfo(363, 0, "Raw Beef", "minecraft:beef").SetStackSize(64); + public static ItemInfo Steak = new ItemInfo(364, 0, "Steak", "minecraft:cooked_beef").SetStackSize(64); + public static ItemInfo RawChicken = new ItemInfo(365, 0, "Raw Chicken", "minecraft:chicken").SetStackSize(64); + public static ItemInfo CookedChicken = new ItemInfo(366, 0, "Cooked Chicken", "minecraft:cooked_chicken").SetStackSize(64); + public static ItemInfo RottenFlesh = new ItemInfo(367, 0, "Rotten Flesh", "minecraft:rotten_flesh").SetStackSize(64); + public static ItemInfo EnderPearl = new ItemInfo(368, 0, "Ender Pearl", "minecraft:ender_pearl").SetStackSize(64); + public static ItemInfo BlazeRod = new ItemInfo(369, 0, "Blaze Rod", "minecraft:blaze_rod").SetStackSize(64); + public static ItemInfo GhastTear = new ItemInfo(370, 0, "Ghast Tear", "minecraft:ghast_tear").SetStackSize(64); + public static ItemInfo GoldNugget = new ItemInfo(371, 0, "Gold Nugget", "minecraft:gold_nugget").SetStackSize(64); + public static ItemInfo Potion = new ItemInfo(373, 0, "Potion", "minecraft:potion"); + public static ItemInfo GlassBottle = new ItemInfo(374, 0, "Glass Bottle", "minecraft:glass_bottle"); + public static ItemInfo SpiderEye = new ItemInfo(375, 0, "Spider Eye", "minecraft:spider_eye").SetStackSize(64); + public static ItemInfo FermentedSpiderEye = new ItemInfo(376, 0, "Fermented Spider Eye", "minecraft:fermented_spider_eye").SetStackSize(64); + public static ItemInfo BlazePowder = new ItemInfo(377, 0, "Blaze Powder", "minecraft:blaze_powder").SetStackSize(64); + public static ItemInfo MagmaCream = new ItemInfo(378, 0, "Magma Cream", "minecraft:magma_cream").SetStackSize(64); + public static ItemInfo EyeOfEnder = new ItemInfo(381, 0, "Eye of Ender", "minecraft:ender_eye").SetStackSize(64); + public static ItemInfo GlisteringMelon = new ItemInfo(382, 0, "Glistering Melon", "minecraft:speckled_melon"); + public static ItemInfo SpawnElderGuardian = new ItemInfo(383, 4, "Spawn Elder Guardian", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnWitherSkeleton = new ItemInfo(383, 5, "Spawn Wither Skeleton", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnStray = new ItemInfo(383, 6, "Spawn Stray", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnHusk = new ItemInfo(383, 23, "Spawn Husk", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnZombieVillager = new ItemInfo(383, 27, "Spawn Zombie Villager", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnSkeletonHorse = new ItemInfo(383, 28, "Spawn Skeleton Horse", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnZombieHorse = new ItemInfo(383, 29, "Spawn Zombie Horse", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnDonkey = new ItemInfo(383, 31, "Spawn Donkey", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnMule = new ItemInfo(383, 32, "Spawn Mule", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnEvoker = new ItemInfo(383, 34, "Spawn Evoker", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnVex = new ItemInfo(383, 35, "Spawn Vex", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnVindicator = new ItemInfo(383, 36, "Spawn Vindicator", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnCreeper = new ItemInfo(383, 50, "Spawn Creeper", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnSkeleton = new ItemInfo(383, 51, "Spawn Skeleton", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnSpider = new ItemInfo(383, 52, "Spawn Spider", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnZombie = new ItemInfo(383, 54, "Spawn Zombie", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnSlime = new ItemInfo(383, 55, "Spawn Slime", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnGhast = new ItemInfo(383, 56, "Spawn Ghast", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnZombiePigman = new ItemInfo(383, 57, "Spawn Zombie Pigman", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnEnderman = new ItemInfo(383, 58, "Spawn Enderman", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnCaveSpider = new ItemInfo(383, 59, "Spawn Cave Spider", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnSilverfish = new ItemInfo(383, 60, "Spawn Silverfish", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnBlaze = new ItemInfo(383, 61, "Spawn Blaze", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnMagmaCube = new ItemInfo(383, 62, "Spawn Magma Cube", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnBat = new ItemInfo(383, 65, "Spawn Bat", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnWitch = new ItemInfo(383, 66, "Spawn Witch", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnEndermite = new ItemInfo(383, 67, "Spawn Endermite", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnGuardian = new ItemInfo(383, 68, "Spawn Guardian", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnShulker = new ItemInfo(383, 69, "Spawn Shulker", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnPig = new ItemInfo(383, 90, "Spawn Pig", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnSheep = new ItemInfo(383, 91, "Spawn Sheep", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnCow = new ItemInfo(383, 92, "Spawn Cow", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnChicken = new ItemInfo(383, 93, "Spawn Chicken", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnSquid = new ItemInfo(383, 94, "Spawn Squid", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnWolf = new ItemInfo(383, 95, "Spawn Wolf", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnMooshroom = new ItemInfo(383, 96, "Spawn Mooshroom", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnOcelot = new ItemInfo(383, 98, "Spawn Ocelot", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnHorse = new ItemInfo(383, 100, "Spawn Horse", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnRabbit = new ItemInfo(383, 101, "Spawn Rabbit", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnPolarBear = new ItemInfo(383, 102, "Spawn Polar Bear", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnLlama = new ItemInfo(383, 103, "Spawn Llama", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnParrot = new ItemInfo(383, 105, "Spawn Parrot", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo SpawnVillager = new ItemInfo(383, 120, "Spawn Villager", "minecraft:spawn_egg").SetStackSize(64); + public static ItemInfo BottleOEnchanting = new ItemInfo(384, 0, "Bottle o' Enchanting", "minecraft:experience_bottle").SetStackSize(64); + public static ItemInfo FireCharge = new ItemInfo(385, 0, "Fire Charge", "minecraft:fire_charge").SetStackSize(64); + public static ItemInfo BookAndQuill = new ItemInfo(386, 0, "Book and Quill", "minecraft:writable_book"); + public static ItemInfo WrittenBook = new ItemInfo(387, 0, "Written Book", "minecraft:written_book"); + public static ItemInfo Emerald = new ItemInfo(388, 0, "Emerald", "minecraft:emerald").SetStackSize(64); + public static ItemInfo ItemFrame = new ItemInfo(389, 0, "Item Frame", "minecraft:item_frame").SetStackSize(64); + public static ItemInfo Carrot = new ItemInfo(391, 0, "Carrot", "minecraft:carrot").SetStackSize(64); + public static ItemInfo Potato = new ItemInfo(392, 0, "Potato", "minecraft:potato").SetStackSize(64); + public static ItemInfo BakedPotato = new ItemInfo(393, 0, "Baked Potato", "minecraft:baked_potato").SetStackSize(64); + public static ItemInfo PoisonousPotato = new ItemInfo(394, 0, "Poisonous Potato", "minecraft:poisonous_potato").SetStackSize(64); + public static ItemInfo EmptyMap = new ItemInfo(395, 0, "Empty Map", "minecraft:map").SetStackSize(64); + public static ItemInfo GoldenCarrot = new ItemInfo(396, 0, "Golden Carrot", "minecraft:golden_carrot").SetStackSize(64); + public static ItemInfo MobHeadSkeleton = new ItemInfo(397, 0, "Mob Head (Skeleton)", "minecraft:skull").SetStackSize(64); + public static ItemInfo MobHeadWitherSkeleton = new ItemInfo(397, 1, "Mob Head (Wither Skeleton)", "minecraft:skull").SetStackSize(64); + public static ItemInfo MobHeadZombie = new ItemInfo(397, 2, "Mob Head (Zombie)", "minecraft:skull").SetStackSize(64); + public static ItemInfo MobHeadHuman = new ItemInfo(397, 3, "Mob Head (Human)", "minecraft:skull").SetStackSize(64); + public static ItemInfo MobHeadCreeper = new ItemInfo(397, 4, "Mob Head (Creeper)", "minecraft:skull").SetStackSize(64); + public static ItemInfo MobHeadDragon = new ItemInfo(397, 5, "Mob Head (Dragon)", "minecraft:skull").SetStackSize(64); + public static ItemInfo CarrotOnAStick = new ItemInfo(398, 0, "Carrot on a Stick", "minecraft:carrot_on_a_stick"); + public static ItemInfo NetherStar = new ItemInfo(399, 0, "Nether Star", "minecraft:nether_star").SetStackSize(64); + public static ItemInfo PumpkinPie = new ItemInfo(400, 0, "Pumpkin Pie", "minecraft:pumpkin_pie").SetStackSize(64); + public static ItemInfo FireworkRocket = new ItemInfo(401, 0, "Firework Rocket", "minecraft:fireworks"); + public static ItemInfo FireworkStar = new ItemInfo(402, 0, "Firework Star", "minecraft:firework_charge").SetStackSize(64); + public static ItemInfo EnchantedBook = new ItemInfo(403, 0, "Enchanted Book", "minecraft:enchanted_book"); + public static ItemInfo RedstoneComparator = new ItemInfo(404, 0, "Redstone Comparator", "minecraft:comparator").SetStackSize(64); + public static ItemInfo NetherQuartz = new ItemInfo(406, 0, "Nether Quartz", "minecraft:quartz").SetStackSize(64); + public static ItemInfo MinecartWithTnt = new ItemInfo(407, 0, "Minecart with TNT", "minecraft:tnt_minecart"); + public static ItemInfo MinecartWithHopper = new ItemInfo(408, 0, "Minecart with Hopper", "minecraft:hopper_minecart"); + public static ItemInfo PrismarineShard = new ItemInfo(409, 0, "Prismarine Shard", "minecraft:prismarine_shard"); + public static ItemInfo PrismarineCrystals = new ItemInfo(410, 0, "Prismarine Crystals", "minecraft:prismarine_crystals"); + public static ItemInfo RawRabbit = new ItemInfo(411, 0, "Raw Rabbit", "minecraft:rabbit"); + public static ItemInfo CookedRabbit = new ItemInfo(412, 0, "Cooked Rabbit", "minecraft:cooked_rabbit"); + public static ItemInfo RabbitStew = new ItemInfo(413, 0, "Rabbit Stew", "minecraft:rabbit_stew"); + public static ItemInfo RabbitSFoot = new ItemInfo(414, 0, "Rabbit's Foot", "minecraft:rabbit_foot"); + public static ItemInfo RabbitHide = new ItemInfo(415, 0, "Rabbit Hide", "minecraft:rabbit_hide"); + public static ItemInfo ArmorStand = new ItemInfo(416, 0, "Armor Stand", "minecraft:armor_stand"); + public static ItemInfo IronHorseArmor = new ItemInfo(417, 0, "Iron Horse Armor", "minecraft:iron_horse_armor"); + public static ItemInfo GoldenHorseArmor = new ItemInfo(418, 0, "Golden Horse Armor", "minecraft:golden_horse_armor"); + public static ItemInfo DiamondHorseArmor = new ItemInfo(419, 0, "Diamond Horse Armor", "minecraft:diamond_horse_armor"); + public static ItemInfo Lead = new ItemInfo(420, 0, "Lead", "minecraft:lead").SetStackSize(64); + public static ItemInfo NameTag = new ItemInfo(421, 0, "Name Tag", "minecraft:name_tag").SetStackSize(64); + public static ItemInfo MinecartWithCommandBlock = new ItemInfo(422, 0, "Minecart with Command Block", "minecraft:command_block_minecart"); + public static ItemInfo RawMutton = new ItemInfo(423, 0, "Raw Mutton", "minecraft:mutton"); + public static ItemInfo CookedMutton = new ItemInfo(424, 0, "Cooked Mutton", "minecraft:cooked_mutton"); + public static ItemInfo Banner = new ItemInfo(425, 0, "Banner", "minecraft:banner"); + public static ItemInfo EndCrystal = new ItemInfo(426, 0, "End Crystal", "minecraft:end_crystal"); + public static ItemInfo SpruceDoor = new ItemInfo(427, 0, "Spruce Door", "minecraft:spruce_door"); + public static ItemInfo BirchDoor = new ItemInfo(428, 0, "Birch Door", "minecraft:birch_door"); + public static ItemInfo JungleDoor = new ItemInfo(429, 0, "Jungle Door", "minecraft:jungle_door"); + public static ItemInfo AcaciaDoor = new ItemInfo(430, 0, "Acacia Door", "minecraft:acacia_door"); + public static ItemInfo DarkOakDoor = new ItemInfo(431, 0, "Dark Oak Door", "minecraft:dark_oak_door"); + public static ItemInfo ChorusFruit = new ItemInfo(432, 0, "Chorus Fruit", "minecraft:chorus_fruit"); + public static ItemInfo PoppedChorusFruit = new ItemInfo(433, 0, "Popped Chorus Fruit", "minecraft:popped_chorus_fruit"); + public static ItemInfo Beetroot = new ItemInfo(434, 0, "Beetroot", "minecraft:beetroot"); + public static ItemInfo BeetrootSeeds = new ItemInfo(435, 0, "Beetroot Seeds", "minecraft:beetroot_seeds").SetStackSize(64); + public static ItemInfo BeetrootSoup = new ItemInfo(436, 0, "Beetroot Soup", "minecraft:beetroot_soup"); + public static ItemInfo DragonSBreath = new ItemInfo(437, 0, "Dragon's Breath", "minecraft:dragon_breath"); + public static ItemInfo SplashPotion = new ItemInfo(438, 0, "Splash Potion", "minecraft:splash_potion"); + public static ItemInfo SpectralArrow = new ItemInfo(439, 0, "Spectral Arrow", "minecraft:spectral_arrow"); + public static ItemInfo TippedArrow = new ItemInfo(440, 0, "Tipped Arrow", "minecraft:tipped_arrow"); + public static ItemInfo LingeringPotion = new ItemInfo(441, 0, "Lingering Potion", "minecraft:lingering_potion"); + public static ItemInfo Shield = new ItemInfo(442, 0, "Shield", "minecraft:shield"); + public static ItemInfo Elytra = new ItemInfo(443, 0, "Elytra", "minecraft:elytra"); + public static ItemInfo SpruceBoat = new ItemInfo(444, 0, "Spruce Boat", "minecraft:spruce_boat"); + public static ItemInfo BirchBoat = new ItemInfo(445, 0, "Birch Boat", "minecraft:birch_boat"); + public static ItemInfo JungleBoat = new ItemInfo(446, 0, "Jungle Boat", "minecraft:jungle_boat"); + public static ItemInfo AcaciaBoat = new ItemInfo(447, 0, "Acacia Boat", "minecraft:acacia_boat"); + public static ItemInfo DarkOakBoat = new ItemInfo(448, 0, "Dark Oak Boat", "minecraft:dark_oak_boat"); + public static ItemInfo TotemOfUndying = new ItemInfo(449, 0, "Totem of Undying", "minecraft:totem_of_undying"); + public static ItemInfo ShulkerShell = new ItemInfo(450, 0, "Shulker Shell", "minecraft:shulker_shell"); + public static ItemInfo IronNugget = new ItemInfo(452, 0, "Iron Nugget", "minecraft:iron_nugget"); + public static ItemInfo KnowledgeBook = new ItemInfo(453, 0, "Knowledge Book", "minecraft:knowledge_book"); + public static ItemInfo Music13Disc = new ItemInfo(2256, 0, "13 Disc", "minecraft:record_13"); + public static ItemInfo MusicCatDisc = new ItemInfo(2257, 0, "Cat Disc", "minecraft:record_cat"); + public static ItemInfo MusicBlocksDisc = new ItemInfo(2258, 0, "Blocks Disc", "minecraft:record_blocks"); + public static ItemInfo MusicChirpDisc = new ItemInfo(2259, 0, "Chirp Disc", "minecraft:record_chirp"); + public static ItemInfo MusicFarDisc = new ItemInfo(2260, 0, "Far Disc", "minecraft:record_far"); + public static ItemInfo MusicMallDisc = new ItemInfo(2261, 0, "Mall Disc", "minecraft:record_mall"); + public static ItemInfo MusicMellohiDisc = new ItemInfo(2262, 0, "Mellohi Disc", "minecraft:record_mellohi"); + public static ItemInfo MusicStalDisc = new ItemInfo(2263, 0, "Stal Disc", "minecraft:record_stal"); + public static ItemInfo MusicStradDisc = new ItemInfo(2264, 0, "Strad Disc", "minecraft:record_strad"); + public static ItemInfo MusicWardDisc = new ItemInfo(2265, 0, "Ward Disc", "minecraft:record_ward"); + public static ItemInfo Music11Disc = new ItemInfo(2266, 0, "11 Disc", "minecraft:record_11"); + public static ItemInfo MusicWaitDisc = new ItemInfo(2267, 0, "Wait Disc", "minecraft:record_wait"); } } diff --git a/SubstrateCS/Source/Level.cs b/SubstrateCS/Source/Level.cs index 8faf5822..67c9199b 100644 --- a/SubstrateCS/Source/Level.cs +++ b/SubstrateCS/Source/Level.cs @@ -136,14 +136,14 @@ public class Level : INbtObject, ICopyable { new SchemaNodeCompound("Data") { - new SchemaNodeScaler("Time", TagType.TAG_LONG), + new SchemaNodeScaler("Time", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeScaler("LastPlayed", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), new SchemaNodeCompound("Player", Player.Schema, SchemaOptions.OPTIONAL), - new SchemaNodeScaler("SpawnX", TagType.TAG_INT), - new SchemaNodeScaler("SpawnY", TagType.TAG_INT), - new SchemaNodeScaler("SpawnZ", TagType.TAG_INT), - new SchemaNodeScaler("SizeOnDisk", TagType.TAG_LONG, SchemaOptions.CREATE_ON_MISSING), - new SchemaNodeScaler("RandomSeed", TagType.TAG_LONG), + new SchemaNodeScaler("SpawnX", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("SpawnY", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("SpawnZ", TagType.TAG_INT, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("SizeOnDisk", TagType.TAG_LONG, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("RandomSeed", TagType.TAG_LONG, SchemaOptions.OPTIONAL), new SchemaNodeScaler("version", TagType.TAG_INT, SchemaOptions.OPTIONAL), new SchemaNodeScaler("LevelName", TagType.TAG_STRING, SchemaOptions.OPTIONAL), new SchemaNodeScaler("generatorName", TagType.TAG_STRING, SchemaOptions.OPTIONAL), @@ -610,12 +610,31 @@ public virtual Level LoadTree (TagNode tree) _player = new Player().LoadTree(ctree["Player"]); } - _spawnX = ctree["SpawnX"].ToTagInt(); - _spawnY = ctree["SpawnY"].ToTagInt(); - _spawnZ = ctree["SpawnZ"].ToTagInt(); - - _sizeOnDisk = ctree["SizeOnDisk"].ToTagLong(); - _randomSeed = ctree["RandomSeed"].ToTagLong(); + if (ctree.ContainsKey("SpawnX")) + _spawnX = ctree["SpawnX"].ToTagInt(); + if (ctree.ContainsKey("SpawnY")) + _spawnY = ctree["SpawnY"].ToTagInt(); + if (ctree.ContainsKey("SpawnZ")) + _spawnZ = ctree["SpawnZ"].ToTagInt(); + + TagNode modernSpawn; + if (ctree.TryGetValue("spawn", out modernSpawn)) { + TagNodeCompound spawn = modernSpawn as TagNodeCompound; + TagNode positionNode; + if (spawn != null && spawn.TryGetValue("pos", out positionNode)) { + TagNodeIntArray position = positionNode as TagNodeIntArray; + if (position != null && position.Data.Length >= 3) { + _spawnX = position.Data[0]; + _spawnY = position.Data[1]; + _spawnZ = position.Data[2]; + } + } + } + + if (ctree.ContainsKey("SizeOnDisk")) + _sizeOnDisk = ctree["SizeOnDisk"].ToTagLong(); + if (ctree.ContainsKey("RandomSeed")) + _randomSeed = ctree["RandomSeed"].ToTagLong(); if (ctree.ContainsKey("version")) { _version = ctree["version"].ToTagInt(); diff --git a/SubstrateCS/Source/Nbt/NbtTree.cs b/SubstrateCS/Source/Nbt/NbtTree.cs index eff53ab6..c91fdea3 100644 --- a/SubstrateCS/Source/Nbt/NbtTree.cs +++ b/SubstrateCS/Source/Nbt/NbtTree.cs @@ -308,8 +308,11 @@ private TagNode ReadList () throw new NBTException(NBTException.MSG_READ_NEG); } - if (val.ValueType == TagType.TAG_END) - return new TagNodeList(TagType.TAG_BYTE); + if (val.ValueType == TagType.TAG_END) { + if (length != 0) + throw new NBTException(NBTException.MSG_READ_TYPE); + return val; + } for (int i = 0; i < length; i++) { val.Add(ReadValue(val.ValueType)); diff --git a/SubstrateCS/Source/Nbt/NbtVerifier.cs b/SubstrateCS/Source/Nbt/NbtVerifier.cs index 34067ef0..47326078 100644 --- a/SubstrateCS/Source/Nbt/NbtVerifier.cs +++ b/SubstrateCS/Source/Nbt/NbtVerifier.cs @@ -68,7 +68,7 @@ public SchemaNode Schema } /// - /// Constructs a new event argument set. + /// Constructs a event argument set. /// /// The expected name of a . public TagEventArgs (string tagName) @@ -158,225 +158,7 @@ private bool Verify (TagNode parent, TagNode tag, SchemaNode schema) return OnMissingTag(new TagEventArgs(schema.Name)); } - SchemaNodeScaler scaler = schema as SchemaNodeScaler; - if (scaler != null) { - return VerifyScaler(tag, scaler); - } - - SchemaNodeString str = schema as SchemaNodeString; - if (str != null) { - return VerifyString(tag, str); - } - - SchemaNodeArray array = schema as SchemaNodeArray; - if (array != null) { - return VerifyArray(tag, array); - } - - SchemaNodeIntArray intarray = schema as SchemaNodeIntArray; - if (intarray != null) { - return VerifyIntArray(tag, intarray); - } - - SchemaNodeLongArray longarray = schema as SchemaNodeLongArray; - if (longarray != null) { - return VerifyLongArray(tag, longarray); - } - - SchemaNodeShortArray shortarray = schema as SchemaNodeShortArray; - if (shortarray != null) { - return VerifyShortArray(tag, shortarray); - } - - SchemaNodeList list = schema as SchemaNodeList; - if (list != null) { - return VerifyList(tag, list); - } - - SchemaNodeCompound compound = schema as SchemaNodeCompound; - if (compound != null) { - return VerifyCompound(tag, compound); - } - - return OnInvalidTagType(new TagEventArgs(schema.Name, tag)); - } - - private bool VerifyScaler (TagNode tag, SchemaNodeScaler schema) - { - if (!tag.IsCastableTo(schema.Type)) { - if (!OnInvalidTagType(new TagEventArgs(schema.Name, tag))) { - return false; - } - } - - return true; - } - - private bool VerifyString (TagNode tag, SchemaNodeString schema) - { - TagNodeString stag = tag as TagNodeString; - if (stag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { - return false; - } - } - if (schema.Length > 0 && stag.Length > schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - if (schema.Value != null && stag.Data != schema.Value) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - - return true; - } - - - private bool VerifyArray (TagNode tag, SchemaNodeArray schema) - { - TagNodeByteArray atag = tag as TagNodeByteArray; - if (atag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { - return false; - } - } - if (schema.Length > 0 && atag.Length != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - - return true; - } - - private bool VerifyIntArray (TagNode tag, SchemaNodeIntArray schema) - { - TagNodeIntArray atag = tag as TagNodeIntArray; - if (atag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { - return false; - } - } - if (schema.Length > 0 && atag.Length != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - - return true; - } - - private bool VerifyLongArray (TagNode tag, SchemaNodeLongArray schema) - { - TagNodeLongArray atag = tag as TagNodeLongArray; - if (atag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { - return false; - } - } - if (schema.Length > 0 && atag.Length != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - - return true; - } - - private bool VerifyShortArray (TagNode tag, SchemaNodeShortArray schema) - { - TagNodeShortArray atag = tag as TagNodeShortArray; - if (atag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { - return false; - } - } - if (schema.Length > 0 && atag.Length != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - - return true; - } - - private bool VerifyList (TagNode tag, SchemaNodeList schema) - { - TagNodeList ltag = tag as TagNodeList; - if (ltag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { - return false; - } - } - if (ltag.Count > 0 && ltag.ValueType != schema.Type) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - if (schema.Length > 0 && ltag.Count != schema.Length) { - if (!OnInvalidTagValue(new TagEventArgs(schema, tag))) { - return false; - } - } - - // Patch up empty lists - //if (schema.Length == 0) { - // tag = new NBT_List(schema.Type); - //} - - bool pass = true; - - // If a subschema is set, test all items in list against it - - if (schema.SubSchema != null) { - foreach (TagNode v in ltag) { - pass = Verify(tag, v, schema.SubSchema) && pass; - } - } - - return pass; - } - - private bool VerifyCompound (TagNode tag, SchemaNodeCompound schema) - { - TagNodeCompound ctag = tag as TagNodeCompound; - if (ctag == null) { - if (!OnInvalidTagType(new TagEventArgs(schema, tag))) { - return false; - } - } - - bool pass = true; - - Dictionary _scratch = new Dictionary(); - - foreach (SchemaNode node in schema) { - TagNode value; - ctag.TryGetValue(node.Name, out value); - - if (value == null) { - if ((node.Options & SchemaOptions.CREATE_ON_MISSING) == SchemaOptions.CREATE_ON_MISSING) { - _scratch[node.Name] = node.BuildDefaultTree(); - continue; - } - else if ((node.Options & SchemaOptions.OPTIONAL) == SchemaOptions.OPTIONAL) { - continue; - } - } - - pass = Verify(tag, value, node) && pass; - } - - foreach (KeyValuePair item in _scratch) { - ctag[item.Key] = item.Value; - } - - _scratch.Clear(); - - return pass; + return schema.Verify(this, tag); } #region Event Handlers @@ -387,66 +169,66 @@ private bool VerifyCompound (TagNode tag, SchemaNodeCompound schema) /// Arguments for this event. /// Status indicating whether this event can be ignored. protected virtual bool OnMissingTag (TagEventArgs e) - { - if (MissingTag != null) { - foreach (VerifierEventHandler func in MissingTag.GetInvocationList()) { - TagEventCode code = func(e); - switch (code) { - case TagEventCode.FAIL: - return false; - case TagEventCode.PASS: - return true; + { + if (MissingTag != null) { + foreach (VerifierEventHandler func in MissingTag.GetInvocationList()) { + TagEventCode code = func(e); + switch (code) { + case TagEventCode.FAIL: + return false; + case TagEventCode.PASS: + return true; + } } } - } - return false; - } - - /// - /// Processes registered events for whenever an expected is of the wrong type and cannot be cast. - /// - /// Arguments for this event. - /// Status indicating whether this event can be ignored. - protected virtual bool OnInvalidTagType (TagEventArgs e) - { - if (InvalidTagType != null) { - foreach (VerifierEventHandler func in InvalidTagType.GetInvocationList()) { - TagEventCode code = func(e); - switch (code) { - case TagEventCode.FAIL: - return false; - case TagEventCode.PASS: - return true; + return false; + } + + /// + /// Processes registered events for whenever an expected is of the wrong type and cannot be cast. + /// + /// Arguments for this event. + /// Status indicating whether this event can be ignored. + public virtual bool OnInvalidTagType (TagEventArgs e) + { + if (InvalidTagType != null) { + foreach (VerifierEventHandler func in InvalidTagType.GetInvocationList()) { + TagEventCode code = func(e); + switch (code) { + case TagEventCode.FAIL: + return false; + case TagEventCode.PASS: + return true; + } } } - } - - return false; - } - /// - /// Processes registered events for whenever an expected has a value that violates the schema. - /// - /// Arguments for this event. - /// Status indicating whether this event can be ignored. - protected virtual bool OnInvalidTagValue (TagEventArgs e) - { - if (InvalidTagValue != null) { - foreach (VerifierEventHandler func in InvalidTagValue.GetInvocationList()) { - TagEventCode code = func(e); - switch (code) { - case TagEventCode.FAIL: - return false; - case TagEventCode.PASS: - return true; + return false; + } + + /// + /// Processes registered events for whenever an expected has a value that violates the schema. + /// + /// Arguments for this event. + /// Status indicating whether this event can be ignored. + public virtual bool OnInvalidTagValue (TagEventArgs e) + { + if (InvalidTagValue != null) { + foreach (VerifierEventHandler func in InvalidTagValue.GetInvocationList()) { + TagEventCode code = func(e); + switch (code) { + case TagEventCode.FAIL: + return false; + case TagEventCode.PASS: + return true; + } } } + + return false; } - return false; +#endregion } - - #endregion } -} diff --git a/SubstrateCS/Source/Nbt/SchemaNode.cs b/SubstrateCS/Source/Nbt/SchemaNode.cs index e8d34ce0..43cc7017 100644 --- a/SubstrateCS/Source/Nbt/SchemaNode.cs +++ b/SubstrateCS/Source/Nbt/SchemaNode.cs @@ -56,5 +56,9 @@ public virtual TagNode BuildDefaultTree () { return null; } + + public virtual bool Verify(NbtVerifier verifier, TagNode tag) { + return verifier.OnInvalidTagType(new TagEventArgs(Name, tag)); + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeArray.cs b/SubstrateCS/Source/Nbt/SchemaNodeArray.cs index 9d3f3544..01fce687 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeArray.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeArray.cs @@ -77,5 +77,22 @@ public override TagNode BuildDefaultTree () { return new TagNodeByteArray(new byte[_length]); } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + TagNodeByteArray atag = tag as TagNodeByteArray; + if (atag == null) { + if (!verifier.OnInvalidTagType(new TagEventArgs(this, tag))) { + return false; + } + } + if (Length > 0 && atag.Length != Length) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + + return true; + + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeCompound.cs b/SubstrateCS/Source/Nbt/SchemaNodeCompound.cs index a7670f9b..347450d2 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeCompound.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeCompound.cs @@ -215,5 +215,48 @@ public override TagNode BuildDefaultTree () return list; } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + TagNodeCompound ctag = tag as TagNodeCompound; + if (ctag == null) { + if (!verifier.OnInvalidTagType(new TagEventArgs(this, tag))) { + return false; + } + } + + bool pass = true; + + Dictionary _scratch = null; + + foreach (SchemaNode node in this) { + TagNode value; + ctag.TryGetValue(node.Name, out value); + + if (value == null) { + if ((node.Options & SchemaOptions.CREATE_ON_MISSING) == SchemaOptions.CREATE_ON_MISSING) { + if (_scratch == null) { + _scratch = new Dictionary(); + } + _scratch[node.Name] = node.BuildDefaultTree(); + continue; + } else if ((node.Options & SchemaOptions.OPTIONAL) == SchemaOptions.OPTIONAL) { + continue; + } + } + + if (!node.Verify(verifier, value)) + { + pass = false; + } + } + + if (_scratch != null) { + foreach (KeyValuePair item in _scratch) { + ctag[item.Key] = item.Value; + } + } + + return pass; + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs b/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs index 086b67fb..c81ea0ab 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeIntArray.cs @@ -79,5 +79,22 @@ public override TagNode BuildDefaultTree () { return new TagNodeIntArray(new int[_length]); } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + TagNodeIntArray atag = tag as TagNodeIntArray; + if (atag == null) { + if (!verifier.OnInvalidTagType(new TagEventArgs(this, tag))) { + return false; + } + } + if (Length > 0 && atag.Length != Length) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + + return true; + + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeList.cs b/SubstrateCS/Source/Nbt/SchemaNodeList.cs index d7bf6e2a..10dad639 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeList.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeList.cs @@ -168,5 +168,41 @@ public override TagNode BuildDefaultTree () return list; } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + TagNodeList ltag = tag as TagNodeList; + if (ltag == null) { + if (!verifier.OnInvalidTagType(new TagEventArgs(this, tag))) { + return false; + } + } + if (ltag.Count > 0 && ltag.ValueType != Type) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + if (Length > 0 && ltag.Count != Length) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + + // Patch up empty lists + //if (schema.Length == 0) { + // tag = new NBT_List(schema.Type); + //} + + bool pass = true; + + // If a subschema is set, test all items in list against it + + if (SubSchema != null) { + foreach (TagNode v in ltag) { + pass = SubSchema.Verify(verifier, v) && pass; + } + } + + return pass; + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs b/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs index 702bed1a..cb847f53 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeLongArray.cs @@ -79,5 +79,22 @@ public override TagNode BuildDefaultTree () { return new TagNodeLongArray(new long[_length]); } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + TagNodeLongArray atag = tag as TagNodeLongArray; + if (atag == null) { + if (!verifier.OnInvalidTagType(new TagEventArgs(this, tag))) { + return false; + } + } + if (Length > 0 && atag.Length != Length) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + + return true; + + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeScaler.cs b/SubstrateCS/Source/Nbt/SchemaNodeScaler.cs index b156c8d8..6449b9fa 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeScaler.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeScaler.cs @@ -71,5 +71,16 @@ public override TagNode BuildDefaultTree () return null; } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + if (!tag.IsCastableTo(Type)) { + if (!verifier.OnInvalidTagType(new TagEventArgs(Name, tag))) { + return false; + } + } + + return true; + + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeShortArray.cs b/SubstrateCS/Source/Nbt/SchemaNodeShortArray.cs index d6e1e8f1..5b562229 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeShortArray.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeShortArray.cs @@ -79,5 +79,22 @@ public override TagNode BuildDefaultTree () { return new TagNodeShortArray(new short[_length]); } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + TagNodeShortArray atag = tag as TagNodeShortArray; + if (atag == null) { + if (!verifier.OnInvalidTagType(new TagEventArgs(this, tag))) { + return false; + } + } + if (Length > 0 && atag.Length != Length) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + + return true; + + } } } diff --git a/SubstrateCS/Source/Nbt/SchemaNodeString.cs b/SubstrateCS/Source/Nbt/SchemaNodeString.cs index 54c1f9b2..a5f3f205 100644 --- a/SubstrateCS/Source/Nbt/SchemaNodeString.cs +++ b/SubstrateCS/Source/Nbt/SchemaNodeString.cs @@ -112,5 +112,26 @@ public override TagNode BuildDefaultTree () return new TagNodeString(); } + + public override bool Verify(NbtVerifier verifier, TagNode tag) { + TagNodeString stag = tag as TagNodeString; + if (stag == null) { + if (!verifier.OnInvalidTagType(new TagEventArgs(this, tag))) { + return false; + } + } + if (Length > 0 && stag.Length > Length) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + if (Value != null && stag.Data != Value) { + if (!verifier.OnInvalidTagValue(new TagEventArgs(this, tag))) { + return false; + } + } + + return true; + } } } diff --git a/SubstrateCS/Source/Nbt/TagNodeList.cs b/SubstrateCS/Source/Nbt/TagNodeList.cs index b227cb8a..86ce7a90 100644 --- a/SubstrateCS/Source/Nbt/TagNodeList.cs +++ b/SubstrateCS/Source/Nbt/TagNodeList.cs @@ -230,11 +230,14 @@ public TagNode this[int index] /// /// The subnode to add. /// Thrown when a subnode being added has the wrong tag type. - public void Add (TagNode item) - { - if (item.GetTagType() != _type) { - throw new ArgumentException("The tag type of item is invalid for this node"); - } + public void Add (TagNode item) + { + if (_type == TagType.TAG_END && _items.Count == 0) { + _type = item.GetTagType(); + } + if (item.GetTagType() != _type) { + throw new ArgumentException("The tag type of item is invalid for this node"); + } _items.Add(item); } @@ -313,4 +316,4 @@ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator () #endregion } -} \ No newline at end of file +} diff --git a/SubstrateCS/Source/NbtWorld.cs b/SubstrateCS/Source/NbtWorld.cs index bbb31004..bbef5a15 100644 --- a/SubstrateCS/Source/NbtWorld.cs +++ b/SubstrateCS/Source/NbtWorld.cs @@ -151,6 +151,10 @@ public static NbtWorld Open (string path) /// public abstract void Save (); + public virtual void SaveBlocks() { + Save(); + } + /// /// Raised when is called, used to find a concrete type that can open the world. /// diff --git a/SubstrateCS/Source/RegionChunkManager.cs b/SubstrateCS/Source/RegionChunkManager.cs index e3e8cca0..6ba9a975 100644 --- a/SubstrateCS/Source/RegionChunkManager.cs +++ b/SubstrateCS/Source/RegionChunkManager.cs @@ -14,8 +14,8 @@ public class RegionChunkManager : IChunkManager, IEnumerable private const int REGION_XLEN = 32; private const int REGION_ZLEN = 32; - private const int REGION_XLOG = 5; - private const int REGION_ZLOG = 5; + public const int REGION_XLOG = 5; + public const int REGION_ZLOG = 5; private const int REGION_XMASK = 0x1F; private const int REGION_ZMASK = 0x1F; diff --git a/SubstrateCS/Source/TileEntities/TileEntityBanner.cs b/SubstrateCS/Source/TileEntities/TileEntityBanner.cs new file mode 100644 index 00000000..d31c6fea --- /dev/null +++ b/SubstrateCS/Source/TileEntities/TileEntityBanner.cs @@ -0,0 +1,162 @@ +using Substrate.Nbt; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Substrate.TileEntities { + public class TileEntityBanner : TileEntity { + public static readonly SchemaNodeCompound BannerSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") { + new SchemaNodeString("id", TypeId), + new SchemaNodeScaler("CustomName", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("Base", TagType.TAG_INT), + new SchemaNodeList( + "Patterns", + TagType.TAG_COMPOUND, + new SchemaNodeCompound() { + new SchemaNodeScaler("Color", TagType.TAG_INT), + new SchemaNodeScaler("Pattern", TagType.TAG_STRING) + }, + SchemaOptions.OPTIONAL + ) + }); + + public BannerColor BaseColor { + get; + set; + } + + public TileEntityBanner() : base(TypeId) { + Patterns = new BannerPattern[0]; + } + + public TileEntityBanner(TileEntity te) : base(te) { + var teb = te as TileEntityBanner; + if (teb != null) { + CustomName = teb.CustomName; + Patterns = (BannerPattern[])teb.Patterns.Clone(); + BaseColor = teb.BaseColor; + } else { + Patterns = new BannerPattern[0]; + } + } + + public static string TypeId { + get { return "minecraft:banner"; } + } + + public string CustomName { + get; + set; + } + + public BannerPattern[] Patterns { + get; + set; + } + + public override TileEntity Copy() { + return new TileEntityBanner(this); + } + + #region INBTObject Members + + public override TileEntity LoadTree(TagNode tree) { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + TagNode node; + if (ctree.TryGetValue("CustomName", out node)) { + CustomName = node.ToTagString(); + } + BaseColor = (BannerColor)(int)ctree["Base"].ToTagInt(); + if (ctree.TryGetValue("Patterns", out node)) { + var items = node.ToTagList(); + List patterns = new List(); + foreach (var item in items) { + patterns.Add( + new BannerPattern( + (BannerColor)(int)(item.ToTagCompound()["Color"].ToTagInt()), + item.ToTagCompound()["Pattern"].ToTagString() + ) + ); + } + Patterns = patterns.ToArray(); + } else { + Patterns = new BannerPattern[0]; + } + + return this; + } + + public override TagNode BuildTree() { + TagNodeCompound tree = base.BuildTree() as TagNodeCompound; + if (CustomName != null) { + tree["CustomName"] = new TagNodeString(CustomName); + } + tree["Base"] = new TagNodeInt((int)BaseColor); + if (Patterns.Length != 0) { + tree["Patterns"] = new TagNodeList( + TagType.TAG_COMPOUND, + Patterns.Select(x => new TagNodeCompound() { + {"Color", new TagNodeInt((int)x.Color) }, + {"Pattern", new TagNodeString(x.Pattern) } + }).ToList() + ); + } + + return tree; + } + + public override bool ValidateTree(TagNode tree) { + return new NbtVerifier(tree, BannerSchema).Verify(); + } + + #endregion + } + + // TODO: https://minecraft.gamepedia.com/Banner/Patterns + public class BannerStyles { + public const string TopTriangle = "tt"; + public const string BottomTriangle = "bt"; + public const string MiddleCircle = "mc"; + public const string CurlyBorder = "cbo"; + public const string Border = "bo"; + public const string BottomStripe = "bs"; + public const string TopStripe = "ts"; + public const string tr = "tr"; + public const string MiddleRectangle = "mr"; + } + + + public struct BannerPattern { + public readonly BannerColor Color; + public readonly string Pattern; + + public BannerPattern(BannerColor color, string pattern) { + Color = color; + Pattern = pattern; + } + } + + public enum BannerColor { + Black, + Red, + Green, + Brown, + Blue, + Purple, + Cyan, + LightGray, + DaryGray, + Pink, + LightGreen, + Yellow, + LightBlue, + LightPurple, + Orange, + White + } +} diff --git a/SubstrateCS/Source/TileEntities/TileEntitySign.cs b/SubstrateCS/Source/TileEntities/TileEntitySign.cs index 1c0c72bf..bc90ab1c 100644 --- a/SubstrateCS/Source/TileEntities/TileEntitySign.cs +++ b/SubstrateCS/Source/TileEntities/TileEntitySign.cs @@ -11,15 +11,15 @@ public class TileEntitySign : TileEntity public static readonly SchemaNodeCompound SignSchema = TileEntity.Schema.MergeInto(new SchemaNodeCompound("") { new SchemaNodeString("id", TypeId), - new SchemaNodeScaler("Text1", TagType.TAG_STRING), - new SchemaNodeScaler("Text2", TagType.TAG_STRING), - new SchemaNodeScaler("Text3", TagType.TAG_STRING), - new SchemaNodeScaler("Text4", TagType.TAG_STRING), + new SchemaNodeScaler("Text1", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("Text2", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("Text3", TagType.TAG_STRING, SchemaOptions.OPTIONAL), + new SchemaNodeScaler("Text4", TagType.TAG_STRING, SchemaOptions.OPTIONAL), }); public static string TypeId { - get { return "Sign"; } + get { return "minecraft:sign"; } } private string _text1 = ""; @@ -30,30 +30,31 @@ public static string TypeId public string Text1 { get { return _text1; } - set { _text1 = value.Length > 14 ? value.Substring(0, 14) : value; } + set { _text1 = value; } } public string Text2 { get { return _text2; } - set { _text2 = value.Length > 14 ? value.Substring(0, 14) : value; } + set { _text2 = value; } } public string Text3 { get { return _text3; } - set { _text3 = value.Length > 14 ? value.Substring(0, 14) : value; } + set { _text3 = value; } } public string Text4 { get { return _text4; } - set { _text4 = value.Length > 14 ? value.Substring(0, 14) : value; } + set { _text4 = value; } } protected TileEntitySign (string id) : base(id) { + Text1 = Text2 = Text3 = Text4 = "{\"text\":\"\"}"; } public TileEntitySign () @@ -86,37 +87,229 @@ public override TileEntity Copy () #region INBTObject Members - public override TileEntity LoadTree (TagNode tree) - { - TagNodeCompound ctree = tree as TagNodeCompound; - if (ctree == null || base.LoadTree(tree) == null) { - return null; - } - - _text1 = ctree["Text1"].ToTagString(); - _text2 = ctree["Text2"].ToTagString(); - _text3 = ctree["Text3"].ToTagString(); - _text4 = ctree["Text4"].ToTagString(); - - return this; - } + public override TileEntity LoadTree (TagNode tree) + { + TagNodeCompound ctree = tree as TagNodeCompound; + if (ctree == null || base.LoadTree(tree) == null) { + return null; + } + + TagNode frontNode; + TagNodeCompound front; + TagNode messagesNode; + TagNodeList messages; + if (ctree.TryGetValue("front_text", out frontNode) + && (front = frontNode as TagNodeCompound) != null + && front.TryGetValue("messages", out messagesNode) + && (messages = messagesNode as TagNodeList) != null) { + _text1 = GetMessage(messages, 0); + _text2 = GetMessage(messages, 1); + _text3 = GetMessage(messages, 2); + _text4 = GetMessage(messages, 3); + } + else { + _text1 = GetLegacyText(ctree, "Text1"); + _text2 = GetLegacyText(ctree, "Text2"); + _text3 = GetLegacyText(ctree, "Text3"); + _text4 = GetLegacyText(ctree, "Text4"); + } + + return this; + } public override TagNode BuildTree () { TagNodeCompound tree = base.BuildTree() as TagNodeCompound; tree["Text1"] = new TagNodeString(_text1); - tree["Text2"] = new TagNodeString(_text2); - tree["Text3"] = new TagNodeString(_text3); - tree["Text4"] = new TagNodeString(_text4); - - return tree; - } - - public override bool ValidateTree (TagNode tree) - { - return new NbtVerifier(tree, SignSchema).Verify(); - } - - #endregion + tree["Text2"] = new TagNodeString(_text2); + tree["Text3"] = new TagNodeString(_text3); + tree["Text4"] = new TagNodeString(_text4); + tree["front_text"] = BuildTextCompound(tree, "front_text", + new string[] { _text1, _text2, _text3, _text4 }); + if (!tree.ContainsKey("back_text")) + tree["back_text"] = BuildTextCompound(tree, "back_text", + new string[] { EmptyText, EmptyText, EmptyText, EmptyText }); + if (!tree.ContainsKey("is_waxed")) + tree["is_waxed"] = new TagNodeByte(0); + if (!tree.ContainsKey("components")) + tree["components"] = new TagNodeCompound(); + if (!tree.ContainsKey("keepPacked")) + tree["keepPacked"] = new TagNodeByte(0); + + return tree; + } + + public override bool ValidateTree (TagNode tree) + { + TagNodeCompound compound = tree as TagNodeCompound; + if (compound == null || !base.ValidateTree(tree)) return false; + TagNode frontNode; + TagNode messagesNode; + TagNodeCompound front; + TagNodeList messages; + if (compound.TryGetValue("front_text", out frontNode) + && (front = frontNode as TagNodeCompound) != null + && front.TryGetValue("messages", out messagesNode) + && (messages = messagesNode as TagNodeList) != null) + return messages.Count >= 4 + && (messages.ValueType == TagType.TAG_STRING + || messages.ValueType == TagType.TAG_COMPOUND); + return HasString(compound, "Text1") && HasString(compound, "Text2") + && HasString(compound, "Text3") && HasString(compound, "Text4"); + } + + private const string EmptyText = "{\"text\":\"\"}"; + + private static string GetMessage(TagNodeList messages, int index) + { + if (index >= messages.Count) + return EmptyText; + + TagNodeString value = messages[index] as TagNodeString; + if (value != null) { + string data = value.Data; + if (String.IsNullOrEmpty(data)) + return EmptyText; + char first = data[0]; + return first == '{' || first == '[' || first == '"' + ? data + : "{\"text\":\"" + EscapeJson(data) + "\"}"; + } + + TagNodeCompound component = messages[index] as TagNodeCompound; + TagNode textNode; + TagNodeString text; + if (component != null + && component.TryGetValue("text", out textNode) + && (text = textNode as TagNodeString) != null) + return "{\"text\":\"" + EscapeJson(text.Data) + "\"}"; + + return EmptyText; + } + + private static string GetLegacyText(TagNodeCompound tree, string name) + { + TagNode node; + return tree.TryGetValue(name, out node) && node is TagNodeString + ? node.ToTagString().Data + : EmptyText; + } + + private static bool HasString(TagNodeCompound tree, string name) + { + TagNode node; + return tree.TryGetValue(name, out node) && node is TagNodeString; + } + + private static TagNodeCompound BuildTextCompound( + TagNodeCompound tree, string name, string[] values) + { + TagNode existingNode; + TagNodeCompound existing = tree.TryGetValue(name, out existingNode) + ? existingNode as TagNodeCompound + : null; + TagNodeCompound text = existing == null + ? new TagNodeCompound() + : existing.Copy() as TagNodeCompound; + // Minecraft 26.2 stores each sign line as a plain NBT string. + // Older releases stored a JSON text component in the same string. + // Keep accepting the public JSON form, but write its visible text + // using the native 26.2 representation. + TagNodeList messages = new TagNodeList(TagType.TAG_STRING); + foreach (string value in values) + messages.Add(new TagNodeString(GetJsonText(value))); + text["messages"] = messages; + if (text.ContainsKey("filtered_messages")) + text["filtered_messages"] = messages.Copy(); + if (!text.ContainsKey("color")) + text["color"] = new TagNodeString("black"); + if (!text.ContainsKey("has_glowing_text")) + text["has_glowing_text"] = new TagNodeByte(0); + return text; + } + + private static string GetJsonText(string value) + { + if (String.IsNullOrEmpty(value)) + return ""; + + string source = value.Trim(); + int name = source.IndexOf("\"text\"", StringComparison.Ordinal); + if (name < 0) + return UnquoteJson(source); + + int colon = source.IndexOf(':', name + 6); + if (colon < 0) + return source; + + int quote = colon + 1; + while (quote < source.Length && Char.IsWhiteSpace(source[quote])) + quote++; + if (quote >= source.Length || source[quote] != '"') + return source; + + return ReadJsonString(source, quote); + } + + private static string UnquoteJson(string value) + { + return value.Length >= 2 && value[0] == '"' + && value[value.Length - 1] == '"' + ? ReadJsonString(value, 0) + : value; + } + + private static string ReadJsonString(string source, int quote) + { + StringBuilder result = new StringBuilder(); + for (int i = quote + 1; i < source.Length; i++) { + char c = source[i]; + if (c == '"') + break; + if (c != '\\' || ++i >= source.Length) { + result.Append(c); + continue; + } + + c = source[i]; + switch (c) { + case '"': result.Append('"'); break; + case '\\': result.Append('\\'); break; + case '/': result.Append('/'); break; + case 'b': result.Append('\b'); break; + case 'f': result.Append('\f'); break; + case 'n': result.Append('\n'); break; + case 'r': result.Append('\r'); break; + case 't': result.Append('\t'); break; + case 'u': + if (i + 4 < source.Length) { + int code; + if (Int32.TryParse(source.Substring(i + 1, 4), + System.Globalization.NumberStyles.HexNumber, + System.Globalization.CultureInfo.InvariantCulture, + out code)) { + result.Append((char)code); + i += 4; + } + } + break; + default: result.Append(c); break; + } + } + return result.ToString(); + } + + private static string EscapeJson(string value) + { + if (value == null) + return ""; + return value.Replace("\\", "\\\\") + .Replace("\"", "\\\"") + .Replace("\r", "\\r") + .Replace("\n", "\\n") + .Replace("\t", "\\t"); + } + + #endregion } } diff --git a/SubstrateCS/Source/TileEntityFactory.cs b/SubstrateCS/Source/TileEntityFactory.cs index 6704c648..2946843a 100644 --- a/SubstrateCS/Source/TileEntityFactory.cs +++ b/SubstrateCS/Source/TileEntityFactory.cs @@ -125,6 +125,7 @@ static TileEntityFactory () _registry[TileEntityRecordPlayer.TypeId] = typeof(TileEntityRecordPlayer); _registry[TileEntitySign.TypeId] = typeof(TileEntitySign); _registry[TileEntityTrap.TypeId] = typeof(TileEntityTrap); + _registry[TileEntityBanner.TypeId] = typeof(TileEntityBanner); } } diff --git a/SubstrateCS/Source/TileTick.cs b/SubstrateCS/Source/TileTick.cs index 3d28943c..0210a9ed 100644 --- a/SubstrateCS/Source/TileTick.cs +++ b/SubstrateCS/Source/TileTick.cs @@ -13,14 +13,15 @@ public class TileTick : INbtObject, ICopyable { private static readonly SchemaNodeCompound _schema = new SchemaNodeCompound("") { - new SchemaNodeScaler("i", TagType.TAG_INT), new SchemaNodeScaler("t", TagType.TAG_INT), new SchemaNodeScaler("x", TagType.TAG_INT), new SchemaNodeScaler("y", TagType.TAG_INT), new SchemaNodeScaler("z", TagType.TAG_INT), + new SchemaNodeScaler("p", TagType.TAG_INT, SchemaOptions.OPTIONAL), }; private int _blockId; + private string _stringId; private int _ticks; private int _x; private int _y; @@ -42,6 +43,7 @@ public TileTick () public TileTick (TileTick tt) { _blockId = tt._blockId; + _stringId = tt._stringId; _ticks = tt._ticks; _x = tt._x; _y = tt._y; @@ -58,7 +60,18 @@ public TileTick (TileTick tt) public int ID { get { return _blockId; } - set { _blockId = value; } + set { + _blockId = value; + _stringId = null; + } + } + + /// + /// Gets the namespaced block identifier when the source used the string form. + /// + public string StringID + { + get { return _stringId; } } /// @@ -164,7 +177,28 @@ public TileTick LoadTree (TagNode tree) return null; } - _blockId = ctree["i"].ToTagInt(); + TagNode idNode; + if (!ctree.TryGetValue("i", out idNode)) { + return null; + } + + if (idNode.GetTagType() == TagType.TAG_STRING) { + _stringId = idNode.ToTagString().Data; + + ItemInfo info; + if (!ItemInfo.StrTable.TryGetValue(_stringId, out info)) { + return null; + } + _blockId = info.ID; + } + else if (idNode.IsCastableTo(TagType.TAG_INT)) { + _blockId = idNode.ToTagInt(); + _stringId = null; + } + else { + return null; + } + _ticks = ctree["t"].ToTagInt(); _x = ctree["x"].ToTagInt(); _y = ctree["y"].ToTagInt(); @@ -196,7 +230,9 @@ public TileTick LoadTreeSafe (TagNode tree) public TagNode BuildTree () { TagNodeCompound tree = new TagNodeCompound(); - tree["i"] = new TagNodeInt(_blockId); + tree["i"] = _stringId == null + ? (TagNode)new TagNodeInt(_blockId) + : new TagNodeString(_stringId); tree["t"] = new TagNodeInt(_ticks); tree["x"] = new TagNodeInt(_x); tree["y"] = new TagNodeInt(_y); @@ -216,6 +252,17 @@ public TagNode BuildTree () /// Status indicating whether the tree was valid against the internal schema. public bool ValidateTree (TagNode tree) { + TagNodeCompound ctree = tree as TagNodeCompound; + TagNode idNode; + if (ctree == null || !ctree.TryGetValue("i", out idNode)) { + return false; + } + + if (idNode.GetTagType() != TagType.TAG_STRING + && !idNode.IsCastableTo(TagType.TAG_INT)) { + return false; + } + return new NbtVerifier(tree, _schema).Verify(); } diff --git a/SubstrateCS/Substrate (NET4).csproj b/SubstrateCS/Substrate (NET4).csproj index f293012e..5c087d2a 100644 --- a/SubstrateCS/Substrate (NET4).csproj +++ b/SubstrateCS/Substrate (NET4).csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,7 +10,7 @@ Properties Substrate Substrate - v4.0 + v4.8 512 false @@ -19,7 +19,8 @@ 3.5 - Client + + publish\ true Disk @@ -44,6 +45,7 @@ prompt 4 bin\Debug\Substrate.XML + false pdbonly @@ -53,7 +55,16 @@ prompt 4 bin\Release\Substrate.XML + false + + + Substrate.Data.BlockRegistry-26.2.txt + + + Substrate.Data.LegacyBlockStates.txt + + @@ -61,7 +72,11 @@ + + + + @@ -84,6 +99,7 @@ + @@ -165,6 +181,7 @@ + @@ -211,6 +228,7 @@ + @@ -295,4 +313,4 @@ --> - \ No newline at end of file +