Example #1
0
        private string GetWoodBlock(BlockStateContainer record)
        {
            string type     = "oak";
            bool   stripped = false;
            string axis     = "y";

            foreach (var state in record.States)
            {
                switch (state.Name)
                {
                case "wood_type":
                    type = state.Value();
                    break;

                case "stripped_bit":
                    stripped = state.Value() == "1";
                    break;

                case "pillar_axis":
                    axis = state.Value();
                    break;
                }
            }

            string result = $"{type}_log";

            if (stripped)
            {
                result = "stripped_" + result;
            }

            return($"minecraft:{result}");
        }
Example #2
0
        }         // method

        public override BlockStateContainer GetState()
        {
            var record = new BlockStateContainer();

            record.Name = "minecraft:chalkboard";
            record.Id   = 230;
            return(record);
        }         // method
Example #3
0
        public static Block GetBlockById(int blockId, byte metadata)
        {
            int runtimeId = (int)GetRuntimeId(blockId, metadata);
            BlockStateContainer blockState = BlockPalette[runtimeId];
            Block block = GetBlockById(blockState.Id);

            block.SetState(blockState.States);
            return(block);
        }
Example #4
0
        private static BlockStateContainer GetBlockStateContainer(NbtTag tag)
        {
            var record = new BlockStateContainer();

            string name = tag["name"].StringValue;

            record.Name   = name;
            record.States = GetBlockStates(tag);

            return(record);
        }
Example #5
0
        public virtual BlockStateContainer GetGlobalState()
        {
            BlockStateContainer currentState = GetState();

            if (!BlockFactory.BlockStates.TryGetValue(currentState, out var blockstate))
            {
                Log.Warn($"Did not find block state for {this}, {currentState}");
                return(null);
            }

            return(blockstate);
        }
Example #6
0
        public int GetRuntimeId()
        {
            BlockStateContainer currentState = GetState();

            if (!BlockFactory.BlockStates.TryGetValue(currentState, out var blockstate))
            {
                Log.Warn($"Did not find block state for {this}, {currentState}");
                return(-1);
            }

            return(blockstate.RuntimeId);
        }
Example #7
0
		public void GetItemFromBlockStateTest()
		{
			// Picked block minecraft:cobblestone_wall from blockstate 3313
			int runtimeId = 3313;

			BlockStateContainer blocStateFromPick = BlockFactory.BlockPalette[runtimeId];
			var block = BlockFactory.GetBlockById(blocStateFromPick.Id) as CobblestoneWall;
			Assert.IsNotNull(block);
			block.SetState(blocStateFromPick.States);

			Item item = block.GetItem();
			Assert.AreEqual("minecraft:cobblestone_wall", item.Name);
			Assert.AreEqual(139, item.Id);
			Assert.AreEqual(12, item.Metadata);
		}
Example #8
0
        private string BlockStateToString(BlockStateContainer record)
        {
            StringBuilder sb = new StringBuilder();

            sb.Append($"{record.Name}[");

            foreach (var state in record.States)
            {
                sb.Append($"{state.Name}={state.Value()},");
            }

            sb.Append("]");

            return(sb.ToString());
        }
Example #9
0
        public void GetItemFromBlockStateTest()
        {
            // Picked block minecraft:chain from blockstate 917
            int runtimeId = 917;

            BlockStateContainer blocStateFromPick = BlockFactory.BlockPalette[runtimeId];
            var block = BlockFactory.GetBlockById(blocStateFromPick.Id) as Chain;

            Assert.IsNotNull(block);
            block.SetState(blocStateFromPick.States);

            Item item = block.GetItem();

            Assert.AreEqual("minecraft:chain", item.Name);
            Assert.AreEqual(758, item.Id);
            Assert.AreEqual(0, item.Metadata);
        }
Example #10
0
        public Block GetBlockObject(int bx, int @by, int bz)
        {
            if (_runtimeIds.Count == 0)
            {
                return(new Air());
            }

            int index     = _blocks[GetIndex(bx, by, bz)];
            int runtimeId = _runtimeIds[index];
            BlockStateContainer blockState = BlockFactory.BlockPalette[runtimeId];
            Block block = BlockFactory.GetBlockById(blockState.Id);

            block.SetState(blockState.States);
            block.Metadata = (byte)blockState.Data;              //TODO: REMOVE metadata. Not needed.

            return(block);
        }
Example #11
0
        public void GetDoorItemFromBlockStateTest()
        {
            // Picked block minecraft:dark_oak_door from blockstate 4003. Expected block to be in slot 9
            // Picked block minecraft:dark_oak_door from blockstate 3991. Expected block to be in slot 9
            int runtimeId = 3991;

            BlockStateContainer blocStateFromPick = BlockFactory.BlockPalette[runtimeId];
            var block = BlockFactory.GetBlockById(blocStateFromPick.Id) as DarkOakDoor;

            Assert.IsNotNull(block);
            block.SetState(blocStateFromPick.States);

            ItemBlock item = block.GetItem() as ItemBlock;

            Assert.IsNotNull(item, "Found no item");
            Assert.IsNotNull(item.Block);
            Assert.AreEqual("minecraft:dark_oak_door", item.Name);
            Assert.AreEqual(431, item.Id);
            Assert.AreEqual(0, item.Metadata);
        }
Example #12
0
		public BlockPalette ReadAlternateBlockPalette()
		{
			var  result = new BlockPalette();
			uint count  = ReadUnsignedVarInt();
			
			//Log.Info($"Block count startgame: {count}");
			for (int runtimeId = 0; runtimeId < count; runtimeId++)
			{
				var record = new BlockStateContainer();
				record.RuntimeId = runtimeId;
				record.Id = record.RuntimeId;
				record.Name = ReadString();
				record.States = new List<IBlockState>();
				
				
				var nbt     = NetworkUtils.ReadNewNbt(_reader);
				var rootTag = nbt.NbtFile.RootTag;

				if (rootTag is NbtList nbtList)
				{
					foreach (NbtTag tag in nbtList)
					{
						var s = tag["states"];

						if (s is NbtCompound compound)
						{
							foreach (NbtTag stateTag in compound)
							{
								IBlockState state = null;

								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte() {Name = stateTag.Name, Value = stateTag.ByteValue};

										break;

									case NbtTagType.Int:
										state = new BlockStateInt() {Name = stateTag.Name, Value = stateTag.IntValue};

										break;

									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name, Value = stateTag.StringValue
										};

										break;

									default:
										throw new ArgumentOutOfRangeException();
								}

								record.States.Add(state);
							}
						}
						else if (s is NbtList list)
						{
							foreach (NbtTag stateTag in list)
							{
								IBlockState state = null;

								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte() {Name = stateTag.Name, Value = stateTag.ByteValue};

										break;

									case NbtTagType.Int:
										state = new BlockStateInt() {Name = stateTag.Name, Value = stateTag.IntValue};

										break;

									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name, Value = stateTag.StringValue
										};

										break;

									default:
										throw new ArgumentOutOfRangeException();
								}

								record.States.Add(state);
							}
						}

						result.Add(record);
					}
				}
				else if (rootTag is NbtCompound c)
				{
					foreach (NbtTag tag in c)
					{
						var s = tag["states"];

						if (s is NbtCompound compound)
						{
							foreach (NbtTag stateTag in compound)
							{
								IBlockState state = null;
								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte()
										{
											Name = stateTag.Name,
											Value = stateTag.ByteValue
										};
										break;
									case NbtTagType.Int:
										state = new BlockStateInt()
										{
											Name = stateTag.Name,
											Value = stateTag.IntValue
										};
										break;
									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name,
											Value = stateTag.StringValue
										};
										break;
									default:
										throw new ArgumentOutOfRangeException();
								}
								record.States.Add(state);
							}
						}
						else if (s is NbtList list)
						{
							foreach (NbtTag stateTag in list)
							{
								IBlockState state = null;
								switch (stateTag.TagType)
								{
									case NbtTagType.Byte:
										state = new BlockStateByte()
										{
											Name = stateTag.Name,
											Value = stateTag.ByteValue
										};
										break;
									case NbtTagType.Int:
										state = new BlockStateInt()
										{
											Name = stateTag.Name,
											Value = stateTag.IntValue
										};
										break;
									case NbtTagType.String:
										state = new BlockStateString()
										{
											Name = stateTag.Name,
											Value = stateTag.StringValue
										};
										break;
									default:
										throw new ArgumentOutOfRangeException();
								}
								record.States.Add(state);
							}
						}

						result.Add(record);
					}
				}
			}
			return result;
		}
Example #13
0
        private void HandleMcpeUpdateBlock(BedrockTraceHandler caller, McpeUpdateBlock message)
        {
            //if (message.OrderingIndex <= lastNumber) return;
            //lastNumber = message.OrderingIndex;

            if (message.storage != 0)
            {
                return;
            }
            if (message.blockPriority != 3)
            {
                return;
            }

            if (!_runningBlockMetadataDiscovery)
            {
                _resetEventUpdateBlock.Set();
                return;
            }

            int runtimeId = (int)message.blockRuntimeId;
            int bid       = message.coordinates.X / 2;
            int meta      = (message.coordinates.Y - 100) / 2;

            //TODO: Fix for doors and beds. They get 2 updates.
            BlockStateContainer blockstate = caller.Client.BlockPalette[runtimeId];

            if (message.coordinates.X % 2 != 0 || message.coordinates.Y % 2 != 0)
            {
                Log.Warn($"Update block outside of grid {message.coordinates}, {caller.Client.BlockPalette[runtimeId]}");

                if (blockstate.Name.EndsWith("_door"))
                {
                    if (blockstate.States.First(s => s.Name.Equals("upper_block_bit") && ((BlockStateInt)s).Value == 1) != null)
                    {
                        blockstate.Data = (short)meta;
                    }
                }
                else if (blockstate.Name.Equals("minecraft:bed"))
                {
                    if (blockstate.States.First(s => s.Name.Equals("head_piece_bit") && ((BlockStateInt)s).Value == 0) != null)
                    {
                        blockstate.Data = (short)meta;
                    }
                }

                return;
            }

            if (blockstate.Id == 0)
            {
                return;
            }

            if (blockstate.Data == -1)
            {
                lock (_lastUpdatedBlockstate)
                {
                    try
                    {
                        if (bid != blockstate.Id)
                        {
                            Log.Warn($"Wrong id. Expected {blockstate.Id}, got {bid}");
                        }
                        else
                        {
                            blockstate.Data = (short)meta;

                            Log.Debug($"Correct id. Expected {blockstate.Id}, and got {bid}");
                        }

                        Log.Debug($"Block update {bid}, {meta}, with blockstate\n{blockstate}");
                    }
                    finally
                    {
                        Log.Warn($"Got {blockstate.Id}, {meta} storage {message.storage}, {message.blockPriority}");
                        _lastUpdatedBlockstate = blockstate;
                        _resetEventUpdateBlock.Set();
                    }
                }
            }
            else
            {
                Log.Warn($"Blockstate {runtimeId} {blockstate.Id}, {meta} already had meta set to {blockstate.Data}");
            }
        }
Example #14
0
 private ChunkSection(BlockStateContainer blockContainer, BiomeContainer biomeContainer, int?yBase)
 {
     BlockStateContainer = blockContainer;
     BiomeContainer      = biomeContainer;
     YBase = yBase;
 }
Example #15
0
 public ChunkSection Clone()
 {
     return(new ChunkSection(BlockStateContainer.Clone(), BiomeContainer.Clone(), YBase));
 }
Example #16
0
 public virtual void SetState(BlockStateContainer blockstate)
 {
     SetState(blockstate.States);
 }
Example #17
0
 public R12ToCurrentBlockMapEntry(string id, short meta, BlockStateContainer state)
 {
     StringId = id;
     Meta     = meta;
     State    = state;
 }
Example #18
0
        public override void HandleMcpeStartGame(McpeStartGame message)
        {
            Client.EntityId        = message.runtimeEntityId;
            Client.NetworkEntityId = message.entityIdSelf;
            Client.SpawnPoint      = message.spawn;
            Client.CurrentLocation = new PlayerLocation(Client.SpawnPoint, message.rotation.X, message.rotation.X, message.rotation.Y);

            BlockPalette blockPalette = message.blockPalette;

            Client.BlockPalette = blockPalette;

            Log.Warn($"Got position from startgame packet: {Client.CurrentLocation}");

            var settings = new JsonSerializerSettings
            {
                PreserveReferencesHandling = PreserveReferencesHandling.Arrays,
                TypeNameHandling           = TypeNameHandling.Auto,
                Formatting           = Formatting.Indented,
                DefaultValueHandling = DefaultValueHandling.Include
            };

            var fileNameItemstates = Path.GetTempPath() + "itemstates_" + Guid.NewGuid() + ".json";

            File.WriteAllText(fileNameItemstates, JsonConvert.SerializeObject(message.itemstates, settings));

            string fileName = Path.GetTempPath() + "MissingBlocks_" + Guid.NewGuid() + ".txt";

            using (FileStream file = File.OpenWrite(fileName))
            {
                var writer = new IndentedTextWriter(new StreamWriter(file));

                Log.Warn($"Directory:\n{Path.GetTempPath()}");
                Log.Warn($"Filename:\n{fileName}");

                writer.WriteLine($"namespace MiNET.Blocks");
                writer.WriteLine($"{{");
                writer.Indent++;

                var blocks = new List <(int, string)>();

                foreach (IGrouping <string, BlockStateContainer> blockstateGrouping in blockPalette.OrderBy(record => record.Name).ThenBy(record => record.Data).ThenBy(record => record.RuntimeId).GroupBy(record => record.Name))
                {
                    BlockStateContainer currentBlockState = blockstateGrouping.First();
                    Log.Debug($"{currentBlockState.Name}, Id={currentBlockState.Id}");
                    BlockStateContainer defaultBlockState = BlockFactory.GetBlockById(currentBlockState.Id, 0)?.GetGlobalState();
                    if (defaultBlockState == null)
                    {
                        defaultBlockState = blockstateGrouping.FirstOrDefault(bs => bs.Data == 0);
                    }

                    Log.Debug($"{currentBlockState.RuntimeId}, {currentBlockState.Name}, {currentBlockState.Data}");
                    Block blockById     = BlockFactory.GetBlockById(currentBlockState.Id);
                    bool  existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated;
                    int   id            = existingBlock ? currentBlockState.Id : -1;

                    string blockClassName = CodeName(currentBlockState.Name.Replace("minecraft:", ""), true);

                    blocks.Add((blockById.Id, blockClassName));
                    writer.WriteLineNoTabs($"");

                    writer.WriteLine($"public partial class {blockClassName} // {blockById.Id} typeof={blockById.GetType().Name}");
                    writer.WriteLine($"{{");
                    writer.Indent++;

                    writer.WriteLine($"public override string Name => \"{currentBlockState.Name}\";");
                    writer.WriteLineNoTabs("");

                    var bits = new List <BlockStateByte>();
                    foreach (var state in blockstateGrouping.First().States)
                    {
                        var q = blockstateGrouping.SelectMany(c => c.States);

                        // If this is on base, skip this property. We need this to implement common functionality.
                        Type baseType     = blockById.GetType().BaseType;
                        bool propOverride = baseType != null &&
                                            ("Block" != baseType.Name &&
                                             baseType.GetProperty(CodeName(state.Name, true)) != null);

                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                        {
                            var  values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateByte)d).Value).Distinct().OrderBy(s => s).ToList();
                            byte defaultVal = ((BlockStateByte)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0;
                            if (values.Min() == 0 && values.Max() == 1)
                            {
                                bits.Add(blockStateByte);
                                writer.Write($"[StateBit] ");
                                writer.WriteLine($"public{(propOverride ? " override" : "")} bool {CodeName(state.Name, true)} {{ get; set; }} = {(defaultVal == 1 ? "true" : "false")};");
                            }
                            else
                            {
                                writer.Write($"[StateRange({values.Min()}, {values.Max()})] ");
                                writer.WriteLine($"public{(propOverride ? " override" : "")} byte {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};");
                            }
                            break;
                        }

                        case BlockStateInt blockStateInt:
                        {
                            var values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateInt)d).Value).Distinct().OrderBy(s => s).ToList();
                            int defaultVal = ((BlockStateInt)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? 0;
                            writer.Write($"[StateRange({values.Min()}, {values.Max()})] ");
                            writer.WriteLine($"public{(propOverride ? " override" : "")} int {CodeName(state.Name, true)} {{ get; set; }} = {defaultVal};");
                            break;
                        }

                        case BlockStateString blockStateString:
                        {
                            var    values     = q.Where(s => s.Name == state.Name).Select(d => ((BlockStateString)d).Value).Distinct().ToList();
                            string defaultVal = ((BlockStateString)defaultBlockState?.States.First(s => s.Name == state.Name))?.Value ?? "";
                            if (values.Count > 1)
                            {
                                writer.WriteLine($"[StateEnum({string.Join(',', values.Select(v => $"\"{v}\""))})]");
                            }
                            writer.WriteLine($"public{(propOverride ? " override" : "")} string {CodeName(state.Name, true)} {{ get; set; }} = \"{defaultVal}\";");
                            break;
                        }

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                    }

                    // Constructor

                    //if (id == -1 || blockById.IsGenerated)
                    //{
                    //	writer.WriteLine($"");

                    //	writer.WriteLine($"public {blockClassName}() : base({currentBlockState.Id})");
                    //	writer.WriteLine($"{{");
                    //	writer.Indent++;
                    //	writer.WriteLine($"IsGenerated = true;");
                    //	writer.WriteLine($"SetGenerated();");
                    //	writer.Indent--;
                    //	writer.WriteLine($"}}");
                    //}

                    writer.WriteLineNoTabs($"");
                    writer.WriteLine($"public override void SetState(List<IBlockState> states)");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"foreach (var state in states)");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"switch(state)");
                    writer.WriteLine($"{{");
                    writer.Indent++;

                    foreach (var state in blockstateGrouping.First().States)
                    {
                        writer.WriteLine($"case {state.GetType().Name} s when s.Name == \"{state.Name}\":");
                        writer.Indent++;
                        writer.WriteLine($"{CodeName(state.Name, true)} = {(bits.Contains(state) ? "Convert.ToBoolean(s.Value)" : "s.Value")};");
                        writer.WriteLine($"break;");
                        writer.Indent--;
                    }

                    writer.Indent--;
                    writer.WriteLine($"}} // switch");
                    writer.Indent--;
                    writer.WriteLine($"}} // foreach");
                    writer.Indent--;
                    writer.WriteLine($"}} // method");

                    writer.WriteLineNoTabs($"");
                    writer.WriteLine($"public override BlockStateContainer GetState()");
                    writer.WriteLine($"{{");
                    writer.Indent++;
                    writer.WriteLine($"var record = new BlockStateContainer();");
                    writer.WriteLine($"record.Name = \"{blockstateGrouping.First().Name}\";");
                    writer.WriteLine($"record.Id = {blockstateGrouping.First().Id};");
                    foreach (var state in blockstateGrouping.First().States)
                    {
                        string propName = CodeName(state.Name, true);
                        writer.WriteLine($"record.States.Add(new {state.GetType().Name} {{Name = \"{state.Name}\", Value = {(bits.Contains(state) ? $"Convert.ToByte({propName})" : propName)}}});");
                    }
                    writer.WriteLine($"return record;");
                    writer.Indent--;
                    writer.WriteLine($"}} // method");
                    writer.Indent--;
                    writer.WriteLine($"}} // class");
                }

                writer.WriteLine();

                foreach (var block in blocks.OrderBy(tuple => tuple.Item1))
                {
                    int clazzId = block.Item1;

                    Block blockById     = BlockFactory.GetBlockById(clazzId);
                    bool  existingBlock = blockById.GetType() != typeof(Block) && !blockById.IsGenerated;
                    if (existingBlock)
                    {
                        continue;
                    }

                    string clazzName = block.Item2;
                    string baseClazz = clazzName.EndsWith("Stairs") ? "BlockStairs" : "Block";
                    baseClazz = clazzName.EndsWith("Slab") && !clazzName.EndsWith("DoubleSlab")? "SlabBase" : baseClazz;
                    writer.WriteLine($"public partial class {clazzName} : {baseClazz} {{ " +
                                     $"public {clazzName}() : base({clazzId}) {{ IsGenerated = true; }} " +
                                     $"}}");
                }

                writer.Indent--;
                writer.WriteLine($"}}");                 // namespace

                //foreach (var block in blocks.OrderBy(tuple => tuple.Item1))
                //{
                //	// 495 => new StrippedCrimsonStem(),
                //	writer.WriteLine($"\t\t\t\t{block.Item1} => new {block.Item2}(),");
                //}

                writer.Flush();
            }

            LogGamerules(message.gamerules);

            Client.LevelInfo.LevelName = "Default";
            Client.LevelInfo.Version   = 19133;
            Client.LevelInfo.GameType  = message.gamemode;

            //ClientUtils.SaveLevel(_level);

            {
                var packet = McpeRequestChunkRadius.CreateObject();
                Client.ChunkRadius = 5;
                packet.chunkRadius = Client.ChunkRadius;

                Client.SendPacket(packet);
            }
        }
Example #19
0
        public bool TryConvertBlockState(BlockStateContainer record, out BlockState result)
        {
            if (_convertedStates.TryGetValue((uint)record.RuntimeId, out var alreadyConverted))
            {
                result = alreadyConverted;
                return(true);
            }

            result = null;

            string searchName = record.Name;

            switch (record.Name)
            {
            case "minecraft:torch":
                if (record.States.Any(x => x.Name.Equals("torch_facing_direction") && x.Value() != "top"))
                {
                    searchName = "minecraft:wall_torch";
                }
                break;

            case "minecraft:unlit_redstone_torch":
            case "minecraft:redstone_torch":
                if (record.States.Any(x => x.Name.Equals("torch_facing_direction") && x.Value() != "top"))
                {
                    searchName = "minecraft:redstone_wall_torch";
                }
                break;

            case "minecraft:flowing_water":
                searchName = "minecraft:water";
                break;

            case "minecraft:wood":
                searchName = GetWoodBlock(record);
                break;

            case "minecraft:tallgrass":
                searchName = "minecraft:tall_grass";
                break;
            }

            string prefix = "";

            foreach (var state in record.States.ToArray())
            {
                switch (state.Name)
                {
                case "stone_type":
                    switch (state.Value())
                    {
                    case "granite":
                    case "diorite":
                    case "andesite":
                        searchName = $"minecraft:{state.Value()}";
                        break;

                    case "granite_smooth":
                    case "diorite_smooth":
                    case "andesite_smooth":
                        var split = state.Value().Split('_');
                        searchName = $"minecraft:polished_{split[0]}";
                        break;
                    }

                    break;

                case "old_log_type":
                {
                    searchName = $"minecraft:{state.Value()}_log";
                }
                break;

                case "old_leaf_type":
                    searchName = $"minecraft:{state.Value()}_leaves";
                    break;

                case "wood_type":
                    switch (record.Name.ToLower())
                    {
                    case "minecraft:fence":
                        searchName = $"minecraft:{state.Value()}_fence";
                        break;

                    case "minecraft:planks":
                        searchName = $"minecraft:{state.Value()}_planks";
                        break;

                    case "minecraft:wooden_slab":
                        searchName = $"minecraft:{state.Value()}_slab";
                        break;
                        //  case "minecraft:wood":
                        //      searchName = $"minecraft:{state.Value}_log";
                        //       break;
                    }

                    break;

                case "sapling_type":
                    //case "old_log_type":
                    // case "old_leaf_type":
                    searchName = $"minecraft:{state.Value()}_sapling";
                    //prefix = "_";
                    break;

                case "flower_type":
                    searchName = $"minecraft:{state.Value()}";
                    break;

                case "double_plant_type":

                    switch (state.Value())
                    {
                    case "grass":
                        searchName = "minecraft:tall_grass";
                        break;

                    case "sunflower":
                        searchName = "minecraft:sunflower";
                        break;

                    case "fern":
                        searchName = "minecraft:large_fern";
                        break;

                    case "rose":
                        searchName = "minecraft:rose_bush";
                        break;

                    case "paeonia":
                        searchName = "minecraft:peony";
                        break;
                    }

                    break;

                case "color":
                    switch (record.Name)
                    {
                    case "minecraft:carpet":
                        searchName = $"minecraft:{state.Value()}_carpet";
                        break;

                    case "minecraft:wool":
                        searchName = $"minecraft:{state.Value()}_wool";
                        break;

                    case "minecraft:stained_glass":
                        searchName = $"minecraft:{state.Value()}_stained_glass";
                        break;

                    case "minecraft:concrete":
                        searchName = $"minecraft:{state.Value()}_concrete";
                        break;

                    case "minecraft:stained_glass_pane":
                        searchName = $"minecraft:{state.Value()}_stained_glass_pane";
                        break;
                    }

                    record.States.Remove(state);
                    break;
                }
            }

            BlockState r;    // = BlockFactory.GetBlockState(record.Name);

            r = BlockFactory.GetBlockState(prefix + searchName);

            if (r == null || r.Name == "Unknown")
            {
                r = BlockFactory.GetBlockState(searchName);
            }

            if (r == null || r.Name == "Unknown")
            {
                var mapResult =
                    BlockFactory.RuntimeIdTable.FirstOrDefault(xx =>
                                                               xx.Name == searchName);

                if (mapResult != null && mapResult.Id >= 0)
                {
                    var reverseMap = MiNET.Worlds.AnvilWorldProvider.Convert.FirstOrDefault(map =>
                                                                                            map.Value.Item1 == mapResult.Id);

                    var id = mapResult.Id;
                    if (reverseMap.Value != null)
                    {
                        id = reverseMap.Key;
                    }

                    var res = BlockFactory.GetBlockStateID(
                        (int)id,
                        (byte)record.Data);

                    if (AnvilWorldProvider.BlockStateMapper.TryGetValue(
                            res,
                            out var res2))
                    {
                        r = BlockFactory.GetBlockState(res2);
                    }
                    else
                    {
                        Log.Info(
                            $"Did not find anvil statemap: {result.Name}");
                        r = BlockFactory.GetBlockState(mapResult.Name);
                    }
                }
            }

            if (r == null || r.Name == "Unknown")
            {
                Log.Warn($"Could not translate block: {record.Name}");
                return(false);
            }

            foreach (var state in record.States)
            {
                switch (state.Name)
                {
                case "direction":
                case "weirdo_direction":
                    if (r.Block is FenceGate)
                    {
                        switch (state.Value())
                        {
                        case "0":
                            r = r.WithProperty(facing, "north");
                            break;

                        case "1":
                            r = r.WithProperty(facing, "west");
                            break;

                        case "2":
                            r = r.WithProperty(facing, "south");
                            break;

                        case "3":
                            r = r.WithProperty(facing, "east");
                            break;
                        }
                    }
                    else
                    {
                        r = FixFacing(r, int.Parse(state.Value()));
                    }

                    break;

                case "upside_down_bit":
                    r = (r).WithProperty("half", state.Value() == "1" ? "top" : "bottom");
                    break;

                case "door_hinge_bit":
                    r = r.WithProperty("hinge", (state.Value() == "0") ? "left" : "right");
                    break;

                case "open_bit":
                    r = r.WithProperty("open", (state.Value() == "1") ? "true" : "false");
                    break;

                case "upper_block_bit":
                    r = r.WithProperty("half", (state.Value() == "1") ? "upper" : "lower");
                    break;

                case "torch_facing_direction":
                    string facingValue = state.Value();
                    switch (facingValue)
                    {
                    case "north":
                        facingValue = "south";
                        break;

                    case "east":
                        facingValue = "west";
                        break;

                    case "south":
                        facingValue = "north";
                        break;

                    case "west":
                        facingValue = "east";
                        break;
                    }
                    r = r.WithProperty("facing", facingValue);
                    break;

                case "liquid_depth":
                    r = r.WithProperty("level", state.Value());
                    break;

                case "height":
                    r = r.WithProperty("layers", state.Value());
                    break;

                case "growth":
                    r = r.WithProperty("age", state.Value());
                    break;

                case "button_pressed_bit":
                    r = r.WithProperty("powered", state.Value() == "1" ? "true" : "false");
                    break;

                case "facing_direction":
                    switch (int.Parse(state.Value()))
                    {
                    case 0:
                    case 4:
                        r = r.WithProperty(facing, "west");
                        break;

                    case 1:
                    case 5:
                        r = r.WithProperty(facing, "east");
                        break;

                    case 6:
                    case 2:
                        r = r.WithProperty(facing, "north");
                        break;

                    case 7:
                    case 3:
                        r = r.WithProperty(facing, "south");
                        break;
                    }
                    break;

                case "head_piece_bit":
                    r = r.WithProperty("part", state.Value() == "1" ? "head" : "foot");
                    break;

                case "pillar_axis":
                    r = r.WithProperty("axis", state.Value());
                    break;

                case "top_slot_bit":
                    r = r.WithProperty("type", state.Value() == "1" ? "top" : "bottom", true);
                    break;

                case "moisturized_amount":
                    r = r.WithProperty("moisture", state.Value());
                    break;

                case "age":
                    r = r.WithProperty("age", state.Value());
                    break;

                default:
                    //	        Log.Info($"Unknown property for {record.Name}: {state.Name} - {state.Value()}");
                    //	r = r.WithProperty(state.Name, state.Value());
                    break;
                }
            }

            if (record.Name.Equals("minecraft:unlit_redstone_torch"))
            {
                r = r.WithProperty("lit", "false");
            }

            result = r;

            return(true);
        }
Example #20
0
        static BlockFactory()
        {
            for (int i = 0; i < byte.MaxValue * 2; i++)
            {
                var block = GetBlockById(i);
                if (block != null)
                {
                    if (block.IsTransparent)
                    {
                        TransparentBlocks[block.Id] = 1;
                    }
                    if (block.LightLevel > 0)
                    {
                        LuminousBlocks[block.Id] = (byte)block.LightLevel;
                    }
                }
            }

            NameToId = BuildNameToId();

            for (int i = 0; i < LegacyToRuntimeId.Length; ++i)
            {
                LegacyToRuntimeId[i] = -1;
            }

            var assembly = Assembly.GetAssembly(typeof(Block));

            lock (lockObj)
            {
                Dictionary <string, int> idMapping;
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".block_id_map.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        idMapping = JsonConvert.DeserializeObject <Dictionary <string, int> >(reader.ReadToEnd());
                    }

                Dictionary <string, short> itemIdMapping;
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".item_id_map.json"))
                    using (var reader = new StreamReader(stream))
                    {
                        itemIdMapping = JsonConvert.DeserializeObject <Dictionary <string, short> >(reader.ReadToEnd());
                    }

                int runtimeId = 0;
                BlockPalette = new BlockPalette();
                using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".canonical_block_states.nbt"))
                {
                    var reader = new NbtFile();
                    reader.UseVarInt = true;
                    reader.AllowAlternativeRootTag = true;

                    do
                    {
                        reader.LoadFromStream(stream, NbtCompression.AutoDetect);
                        var record = new BlockStateContainer();

                        var    tag  = reader.RootTag;
                        string name = tag["name"].StringValue;
                        record.Name   = name;
                        record.States = new List <IBlockState>();

                        if (idMapping.TryGetValue(name, out var id))
                        {
                            record.Id = id;
                        }

                        var states = tag["states"];
                        if (states != null && states is NbtCompound compound)
                        {
                            foreach (var stateEntry in compound)
                            {
                                switch (stateEntry)
                                {
                                case NbtInt nbtInt:
                                    record.States.Add(new BlockStateInt()
                                    {
                                        Name  = nbtInt.Name,
                                        Value = nbtInt.Value
                                    });
                                    break;

                                case NbtByte nbtByte:
                                    record.States.Add(new BlockStateByte()
                                    {
                                        Name  = nbtByte.Name,
                                        Value = nbtByte.Value
                                    });
                                    break;

                                case NbtString nbtString:
                                    record.States.Add(new BlockStateString()
                                    {
                                        Name  = nbtString.Name,
                                        Value = nbtString.Value
                                    });
                                    break;
                                }
                            }
                        }

                        if (itemIdMapping.TryGetValue(name, out var itemId))
                        {
                            record.ItemInstance = new ItemPickInstance()
                            {
                                Id       = itemId,
                                WantNbt  = false,
                                Metadata = 0
                            };
                        }

                        record.RuntimeId = runtimeId++;
                        BlockPalette.Add(record);
                    } while (stream.Position < stream.Length);
                }

                /*using (var stream = assembly.GetManifestResourceStream(typeof(Block).Namespace + ".blockstates.json"))
                 * using (var reader = new StreamReader(stream))
                 * {
                 *      BlockPalette = BlockPalette.FromJson(reader.ReadToEnd());
                 * }*/

                foreach (var record in BlockPalette)
                {
                    var states = new List <NbtTag>();
                    foreach (IBlockState state in record.States)
                    {
                        NbtTag stateTag = null;
                        switch (state)
                        {
                        case BlockStateByte blockStateByte:
                            stateTag = new NbtByte(state.Name, blockStateByte.Value);
                            break;

                        case BlockStateInt blockStateInt:
                            stateTag = new NbtInt(state.Name, blockStateInt.Value);
                            break;

                        case BlockStateString blockStateString:
                            stateTag = new NbtString(state.Name, blockStateString.Value);
                            break;

                        default:
                            throw new ArgumentOutOfRangeException(nameof(state));
                        }
                        states.Add(stateTag);
                    }

                    var nbt = new NbtFile()
                    {
                        BigEndian = false,
                        UseVarInt = true,
                        RootTag   = new NbtCompound("states", states)
                    };

                    byte[] nbtBinary = nbt.SaveToBuffer(NbtCompression.None);

                    record.StatesCacheNbt = nbtBinary;
                }
            }
            int palletSize = BlockPalette.Count;

            for (int i = 0; i < palletSize; i++)
            {
                if (BlockPalette[i].Data > 15)
                {
                    continue;                                            // TODO: figure out why palette contains blocks with meta more than 15
                }
                if (BlockPalette[i].Data == -1)
                {
                    continue;                                             // These are blockstates that does not have a metadata mapping
                }
                LegacyToRuntimeId[(BlockPalette[i].Id << 4) | (byte)BlockPalette[i].Data] = i;
            }

            BlockStates = new HashSet <BlockStateContainer>(BlockPalette);
        }
Example #21
0
        public Block Next(BlockCoordinates position)
        {
            BlockDataEntry blockEntry = GetRandomBlock(_random, BlockList);

            Block block;

            if (blockEntry.HasMetadata)
            {
                block = BlockFactory.GetBlockById(blockEntry.Id, blockEntry.Metadata);
            }
            else
            {
                block = BlockFactory.GetBlockById(blockEntry.Id);
                if (blockEntry.HasBlockStates)
                {
                    BlockStateContainer currentStates = block.GetState();
                    foreach (BlockStateEntry stateEntry in blockEntry.BlockStates)
                    {
                        IBlockState state = currentStates.States.FirstOrDefault(s => s.Name == stateEntry.Name);
                        if (state == null)
                        {
                            continue;
                        }

                        switch (state)
                        {
                        case BlockStateByte s:
                        {
                            if (byte.TryParse(stateEntry.Value, out byte v))
                            {
                                s.Value = v;
                            }
                            break;
                        }

                        case BlockStateInt s:
                        {
                            if (int.TryParse(stateEntry.Value, out int v))
                            {
                                s.Value = v;
                            }
                            break;
                        }

                        case BlockStateString s:
                        {
                            s.Value = stateEntry.Value;
                            break;
                        }
                        }
                    }
                    block.SetState(currentStates);
                }
            }

            block ??= new Air();

            block.Coordinates = position;

            return(block);
        }