Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions TheSkyBlessing/data/debug/functions/read_sign/.m.mcfunction
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#> debug:read_sign/.m
#
# 実行座標の看板に書かれた文字列を storage debug:read_sign Data 内に書き写します。
#
# 引数が必要なマクロ関数をコマンドブロックで実行する時にちょっと便利です。
# 例: function マクロ関数 with storage debug:read_sign Data
#
# @input args Path : [string] @ 1..4
# @output storage debug:read_sign Data
# @private
# @user

#> 書き写すstorage
# @within function debug:read_sign/**
# @user
#declare storage debug:read_sign

# リセット
data remove storage debug:read_sign Data

# 引数
$data modify storage debug:read_sign Path set value $(Path)
# 書き写し
execute if data storage debug:read_sign Path[0] run data modify storage debug:read_sign Args.Path set from storage debug:read_sign Path[0]
execute if data storage debug:read_sign Path[0] run data modify storage debug:read_sign Args.Line set value 0
execute if data storage debug:read_sign Path[0] run function debug:read_sign/core/.m with storage debug:read_sign Args
execute if data storage debug:read_sign Path[1] run data modify storage debug:read_sign Args.Path set from storage debug:read_sign Path[1]
execute if data storage debug:read_sign Path[1] run data modify storage debug:read_sign Args.Line set value 1
execute if data storage debug:read_sign Path[1] run function debug:read_sign/core/.m with storage debug:read_sign Args
execute if data storage debug:read_sign Path[2] run data modify storage debug:read_sign Args.Path set from storage debug:read_sign Path[2]
execute if data storage debug:read_sign Path[2] run data modify storage debug:read_sign Args.Line set value 2
execute if data storage debug:read_sign Path[2] run function debug:read_sign/core/.m with storage debug:read_sign Args
execute if data storage debug:read_sign Path[3] run data modify storage debug:read_sign Args.Path set from storage debug:read_sign Path[3]
execute if data storage debug:read_sign Path[3] run data modify storage debug:read_sign Args.Line set value 3
execute if data storage debug:read_sign Path[3] run function debug:read_sign/core/.m with storage debug:read_sign Args

# リセット
data remove storage debug:read_sign Path
data remove storage debug:read_sign Args
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#> debug:read_sign/core/.m
# @input args
# Path : string
# Line : (0 | 1 | 2 | 3)
# @within function debug:read_sign/.m

$data modify storage debug:read_sign Data.$(Path) set string block ~ ~ ~ front_text.messages[$(Line)] 1 -1

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看板の各行は front_text.messages に JSON の文字列として保存されるため、前後の1文字を除くだけでは JSON のエスケープが残ります。看板に " や \ を書くと、Data には \ が付いた文字列が入り、{A:"b"} は {A:\"b\"}、a\b は a\\b になります。

マクロ関数はこの値をそのまま展開します。" を含む値(ダブルクォートで囲んだ文字列や、それを含む compound)を、set value $(...) のように SNBT として展開する関数へ渡すと、展開後のコマンドを解釈できず、その関数は実行されません。debug:read_sign/.m の説明の「実行座標の看板に書かれた文字列を storage debug:read_sign Data 内に書き写します」とも合いません。

検証用サーバー(Minecraft 1.20.4、このPRの head 042d962)で確かめました。テスト用クライアントから看板の編集パケットを送って書いた行は、3 が "3"、{A:"b"} が "{A:\"b\"}" という JSON の文字列で保存されていました。debug:read_sign/.m で書き写すと、3、abc、あいう、{A:'b'} は書いたとおりでしたが、{A:"b"} は {A:\"b\"}、a\b は a\\b になりました。この値を debug:entity_storage/set.m に with storage debug:read_sign Data で渡すと、{A:'b'} は {A:"b"} として設定されましたが、{A:\"b\"} は Failed to instantiate function debug:entity_storage/set.m: ... Expected value at position 82 となり、何も設定されませんでした。関数は RCON から execute positioned で実行しており、コマンドブロックからは実行していません。

直すなら、messages[$(Line)] を切り出さずにマクロ引数へ移し、set value $(...) で展開する方法があります。JSON の文字列が SNBT の引用符付き文字列として読まれ、\" と \\ が元の文字に戻ります。検証用サーバーでも、set value $(Data) で展開する debug:entity_storage/set.m に messages の値をそのまま Data として渡すと、{A:"b"}、a\b、3、あいう の文字列が設定されることを確かめました。この形にしない場合は、" と \ を使えないことを IMP Doc に書いておくと、使う人が原因を探さずに済みます。

Loading