Item and block name/ID in pm5
Description
Implement StringToBlockParser (including NBT), reversible StringToBlockParser and reversible StringToItemParser
Justification
In PM5, you only can use StringToItemParser->parse()->getBlock() to parse string to a block. Some blocks will lose the state (or meta?) such as lit_redstone_lamp and stair (https://discord.com/channels/373199722573201408/546255162222706696/1004707998486245488). If a plugin get the block name from config.yml to setBlock(), you may not be able to set the block you want. Also for world edit plugin, you may need to use this command //set VanillaBlocks::REDSTONE_LAMP()->setPowered(true). Therefore, StringToBlockParser should be implemented to parse the block with block state and NBT.
You can easily to make a table using ID and meta for a block/item name translation plugin in PM3 and PM4, but using state ID is not suitable in PM5. It is for runtime and cannot save into .ini file. Block->getName() and Item->getVanillaName() are not including the state. I think no one want to make a table for each block like BlockObjectToBlockStateSerializer and BlockStateToBlockObjectDeserializer. For world edit plugin, displaying the block/item type name with state instead of state ID for //set and /give is needed in runtime. It is for human to remember and it should keep unchange after MCBE updates. It would be useful if reversible StringToBlockParser and reversible StringToItemParser or Block/Item->getVanillaTypeNameWithState() are implemented.
Alternative methods
I've previously considered the idea of reversible StringToTParser and I don't think its use case is that compelling - it's only really useful for generating user-editable config files. You can build your own reverse StringToItemParser using the following code:
class ItemToStringEmitter{
/**
* @var string[]
* @phpstan-var array<int, string>
*/
private array $entries = [];
public function add(Item $item, string $string) : void{
$this->entries[$item->getTypeId()] = $string;
}
public function emit(Item $item) : ?string{
return $this->entries[$item->getTypeId()] ?? null;
}
}
$emitter = new ItemToStringEmitter();
foreach(StringToItemParser::getInstance()->getKnownAliases() as $alias){
if(is_int($alias)){
continue;
}
$item = StringToItemParser::getInstance()->parse((string) $alias);
$emitter->add($item, (string) $alias);
}
var_dump($emitter->emit(VanillaItems::DIAMOND_SWORD()));
I do recognize that this isn't perfect, since items with multiple aliases may return any one of their aliases, but it's perfectly working code.
The blockstates issue is significantly more complex and likely won't see a resolution in 5.0.
Reverse-mapping items to names has been implemented as of b0c6e8d8e0beb08d9010370b77ae0d9a855d32a9.
Umm why am not able replace tree leaves into Sand I did this command //replace 18 sand i did this command but than also it's shows only 0 has been replaced why?