minity-script / minity

Minity is a scripting language for Vanilla Minecraft
https://minity-script.github.io
GNU General Public License v3.0
23 stars 0 forks source link

SNBT/JSON encoding does not escape quotes properly #7

Open AgainPsychoX opened 2 years ago

AgainPsychoX commented 2 years ago

Code

namespace minecarts_nowadays

?furnace_minecart_name_text = "Minecart with Furnace"
?furnace_minecart_name_snbt = snbt {"text":"{?furnace_minecart_name_text}"}

function replace_drops #minecraft:tick {
    for @minecraft:furnace_minecart {
        /summon minecraft:chest_minecart ~ ~ ~ {CustomDisplayTile:1b,DisplayOffset:6,Tags:["furnace_minecart"],CustomName:"{?furnace_minecart_name_snbt}",DisplayState:{Name:"minecraft:furnace"}}
        /kill @s
    }
    for @item{Item:{id:"minecraft:minecart",Count:1b,tag:{display:{Name:"{?furnace_minecart_name_snbt}"}}}} {
        /kill @e[type=item,limit=1,sort=nearest,nbt={Item:{id:"minecraft:chest",Count:1b}}]
        /summon minecraft:item ~ ~ ~ {Item:{id:"minecraft:furnace_minecart",Count:1b}}
        /kill @s
    }
}

It compiles, but does not load/work properly, as generated mcfunctions are invalid.

Generated output

replace_drops.mcfunction

execute as @e[type=minecraft:furnace_minecart] at @s run function zzz_minity:minecarts_nowadays/_b_4
execute as @e[type=minecraft:item,nbt={Item:{id:"minecraft:minecart",Count:1b,tag:{display:{Name:"{text:"Minecart with Furnace"}"}}}}] at @s run function zzz_minity:minecarts_nowadays/_b_5

_b_$.mcfunction (body of first for statement)

summon minecraft:chest_minecart ~ ~ ~ {CustomDisplayTile:1b,DisplayOffset:6,Tags:["furnace_minecart"],CustomName:"{text:"Minecart with Furnace"}",DisplayState:{Name:"minecraft:furnace"}}
kill @s

Expected output

Example using escaping double quotes with slash:

execute as @e[type=minecraft:furnace_minecart] at @s run function zzz_minity:minecarts_nowadays/_b_4
execute as @e[type=minecraft:item,nbt={Item:{id:"minecraft:minecart",Count:1b,tag:{display:{Name:"{\"text\":\"Minecart with Furnace\"}"}}}}] at @s run function zzz_minity:minecarts_nowadays/_b_5

Example using encapsulating with single quote:

summon minecraft:chest_minecart ~ ~ ~ {CustomDisplayTile:1b,DisplayOffset:6,Tags:["furnace_minecart"],CustomName:'{"text":"Minecart with Furnace"}',DisplayState:{Name:"minecraft:furnace"}}
kill @s

It's expected the SNBT would be escaped, by slashes (" to \" in escaped string) or by encapsulating it in single quotes ('). Also, it won't work without key quotes while executing in Minecraft ("text": ... works, text: ... does not).


EDIT: Using SNBT was not valid here, but the issue with quotes is still a bug, both for SNBT and JSON.

_(CustomName requires JSON format)_

AgainPsychoX commented 2 years ago

Workarounds I tried but failed:

image

AgainPsychoX commented 2 years ago

Workaround is to use json:

?furnace_minecart_name_snbt = json {"text": "Minecart with Furnace"}

In raw commands, you need to use single quotes, like:

        /summon minecraft:chest_minecart ~ ~ ~ {CustomDisplayTile:1b,DisplayOffset:6,Tags:["furnace_minecart"],CustomName:'{?furnace_minecart_name_snbt}',DisplayState:{Name:"minecraft:furnace"}}

(if you use "{?furnace_minecart_name_snbt}" it will fail, because quotes will not be escaped.)

In raw selectors, you use double quotes (they will be escaped):

for @item{Item:{id:"minecraft:minecart",Count:1b,tag:{display:{Name:"{?furnace_minecart_name_snbt}"}}}} {
...

This is inconsistency, but at least it works.

BTW: Using double quotes causes warning in VSCode with Data-pack Helper Plus extension, since there is rule preferring single quote to encapsulate stuff, so I guess single quotes should be used to fix the bug.