From e19991882c54d1c6357557985a2774d188bf9075 Mon Sep 17 00:00:00 2001 From: Legends11 Date: Tue, 28 Jul 2026 09:51:00 +0000 Subject: [PATCH 1/2] Update datapacks/dataLib with latest datapack contents --- .../data/datalib/dialog/input_prompt.json | 33 +++++++++++++ .../input/_private/book_capture.mcfunction | 19 +++++++ .../input/_private/cbm_align_tp.mcfunction | 16 ++++++ .../input/_private/cbm_capture.mcfunction | 35 +++++++++++++ .../input/_private/cbm_process.mcfunction | 16 ++++++ .../input/_private/dialog_capture.mcfunction | 18 +++++++ .../input/command_block_minecart.mcfunction | 49 +++++++++++++++++++ .../datalib/function/input/dialog.mcfunction | 22 +++++++++ .../function/input/summon_cbm.mcfunction | 3 ++ .../function/input/writable_book.mcfunction | 33 +++++++++++++ .../datalib/tags/function/events/on_tick.json | 5 -- .../input/command_block_minecart.json | 3 ++ .../datalib/tags/function/input/dialog.json | 3 ++ .../tags/function/input/writable_book.json | 3 ++ .../data/datalib/tags/function/loop.json | 6 ++- 15 files changed, 258 insertions(+), 6 deletions(-) create mode 100644 datapacks/dataLib/data/datalib/dialog/input_prompt.json create mode 100644 datapacks/dataLib/data/datalib/function/input/_private/book_capture.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/_private/cbm_align_tp.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/_private/cbm_capture.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/_private/cbm_process.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/_private/dialog_capture.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/command_block_minecart.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/dialog.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/summon_cbm.mcfunction create mode 100644 datapacks/dataLib/data/datalib/function/input/writable_book.mcfunction delete mode 100644 datapacks/dataLib/data/datalib/tags/function/events/on_tick.json create mode 100644 datapacks/dataLib/data/datalib/tags/function/input/command_block_minecart.json create mode 100644 datapacks/dataLib/data/datalib/tags/function/input/dialog.json create mode 100644 datapacks/dataLib/data/datalib/tags/function/input/writable_book.json diff --git a/datapacks/dataLib/data/datalib/dialog/input_prompt.json b/datapacks/dataLib/data/datalib/dialog/input_prompt.json new file mode 100644 index 00000000..589c629e --- /dev/null +++ b/datapacks/dataLib/data/datalib/dialog/input_prompt.json @@ -0,0 +1,33 @@ +{ + "type": "minecraft:multi_action", + "title": { + "text": "dataLib Input" + }, + "body": { + "type": "minecraft:plain_message", + "contents": "Enter your input below." + }, + "inputs": [ + { + "type": "minecraft:text", + "key": "dl_input_text", + "label": "Input", + "label_visible": false, + "max_length": 2000 + } + ], + "can_close_with_escape": true, + "after_action": "close", + "pause": false, + "actions": [ + { + "label": { + "text": "Submit" + }, + "action": { + "type": "minecraft:dynamic/run_command", + "template": "/function datalib:input/_private/dialog_capture {value:$(dl_input_text)}" + } + } + ] +} diff --git a/datapacks/dataLib/data/datalib/function/input/_private/book_capture.mcfunction b/datapacks/dataLib/data/datalib/function/input/_private/book_capture.mcfunction new file mode 100644 index 00000000..744a66ed --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/_private/book_capture.mcfunction @@ -0,0 +1,19 @@ +# ====================================================================================== +# datalib:input/_private/book_capture [INTERNAL — do not call directly] +# ====================================================================================== +# +# Runs with @s bound to a single player holding the marked written_book. +# Extracts SelectedItem.components."minecraft:writable_book_content".pages[0].raw +# into datalib:input storage. Read-only capture, no execution. +# ====================================================================================== + +data modify storage datalib:input book.player set from entity @s UUID +data modify storage datalib:input book.raw set from entity @s SelectedItem.components."minecraft:writable_book_content".pages[0].raw + +# Same "raw, unvalidated, unexecuted" contract as command_block_minecart capture. +data modify storage datalib:input book.executed set value 0b +execute if data storage datalib:input book{executed:0b} run function #datalib:input/writable_book + +# Clear the custom_data marker so the same book cannot be resubmitted every +# tick while the player keeps holding it — this is a one-shot capture. +data remove entity @s SelectedItem.components."minecraft:custom_data".dataLib.input diff --git a/datapacks/dataLib/data/datalib/function/input/_private/cbm_align_tp.mcfunction b/datapacks/dataLib/data/datalib/function/input/_private/cbm_align_tp.mcfunction new file mode 100644 index 00000000..c1ee080f --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/_private/cbm_align_tp.mcfunction @@ -0,0 +1,16 @@ +# ====================================================================================== +# datalib:input/_private/cbm_align_tp [INTERNAL — call explicitly, not auto-ticked] +# ====================================================================================== +# +# Legends11's tested pattern: teleports the executing player to the nearest +# entity tagged 'datalib_input' along their eye-line, avoiding a manual +# rail + redstone_block setup and skipping the "right-click to open" step. +# +# NOT added to #datalib:events/on_tick automatically — this runs 'as @a', +# which is a different cost/behavior profile than the capture functions +# above (it moves players every tick if left running unconditionally). +# Hook this into whatever trigger Legends11 intends (a specific tag, +# a command, an advancement) — not assumed here. +# ====================================================================================== + +execute as @e[type=minecraft:command_block_minecart,tag=datalib_input] as @a at @s anchored eyes align y positioned ^ ^ ^0.0 run tp @e[sort=nearest,limit=1,tag=datalib_input] ~ ~-0.23 ~ diff --git a/datapacks/dataLib/data/datalib/function/input/_private/cbm_capture.mcfunction b/datapacks/dataLib/data/datalib/function/input/_private/cbm_capture.mcfunction new file mode 100644 index 00000000..18bcd5aa --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/_private/cbm_capture.mcfunction @@ -0,0 +1,35 @@ +# ====================================================================================== +# datalib:input/_private/cbm_capture [INTERNAL — do not call directly] +# ====================================================================================== +# +# Only reached when cbm_process confirmed Command is non-empty. Runs with +# @s still bound to that minecart. +# +# TOCTOU note: snapshot into datalib:input BEFORE clearing Command, so a +# later tick mutating the entity's NBT cannot change what we already +# captured this tick. +# +# Entity handling matches TunnelScript: Command is cleared back to "" so +# the minecart is reusable and is NOT killed. This also matches the +# 'tunnelscript_input' tag Legends11 uses elsewhere (cbm_align_tp), which +# assumes the tagged minecart persists in the world. +# ====================================================================================== + +# Snapshot raw command string as-is — no interpretation, no execution. +data modify storage datalib:input cbm.command set from storage datalib:input _cbm.current + +data modify storage datalib:input cbm.source_uuid set from entity @s UUID +data modify storage datalib:input cbm.pos set from entity @s Pos + +# "raw, unvalidated, unexecuted" — downstream (separate execution pack) +# must run this through datalib:core/security/sanitize and +# datalib:debug/tools/utils/input_check before ever treating it as +# runnable, and running it there stays optional, never mandatory. +data modify storage datalib:input cbm.executed set value 0b +execute if data storage datalib:input cbm{executed:0b} run function #datalib:input/command_block_minecart + +# Clear Command so this same value isn't recaptured next tick — the +# minecart itself is kept alive, not killed. +data modify entity @s Command set value "" + +data remove storage datalib:input _cbm diff --git a/datapacks/dataLib/data/datalib/function/input/_private/cbm_process.mcfunction b/datapacks/dataLib/data/datalib/function/input/_private/cbm_process.mcfunction new file mode 100644 index 00000000..8e79dec7 --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/_private/cbm_process.mcfunction @@ -0,0 +1,16 @@ +# ====================================================================================== +# datalib:input/_private/cbm_process [INTERNAL — do not call directly] +# ====================================================================================== +# +# Runs with @s bound to a single tagged command_block_minecart. Reads its +# Command NBT into scratch storage, then only proceeds to capture if the +# value is a REAL non-empty string — matching TunnelScript's +# 'execute unless data storage tunnelscript:minecart {current:""}' check, +# not just a path-existence check. +# ====================================================================================== + +data modify storage datalib:input _cbm.current set from entity @s Command + +# Compare the actual VALUE to "" — a compound match, not a path-existence +# check. This is the fix for the false-positive-on-empty-Command bug. +execute unless data storage datalib:input {_cbm:{current:""}} run function datalib:input/_private/cbm_capture diff --git a/datapacks/dataLib/data/datalib/function/input/_private/dialog_capture.mcfunction b/datapacks/dataLib/data/datalib/function/input/_private/dialog_capture.mcfunction new file mode 100644 index 00000000..2855e85a --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/_private/dialog_capture.mcfunction @@ -0,0 +1,18 @@ +# ====================================================================================== +# datalib:input/_private/dialog_capture [INTERNAL — do not call directly] +# ====================================================================================== +# +# Called by the dialog system itself via its "run_command" action template +# (dialog-native substitution, NOT a datapack $$(cmd) macro chain). Receives +# the submitted text as $(value) and stores it — read-only capture, no +# execution of the submitted text as a command. +# +# NOTE: this file uses '$' line-macro syntax because it is invoked as a +# macro function (the dialog template calls it with a {value:...} NBT +# compound). This is NOT the $$(cmd) EXECUTION macro pattern Legends11 +# asked to avoid — no field here is ever run as a command, only stored. +# ====================================================================================== + +data modify storage datalib:input dialog.raw set value "$(value)" +data modify storage datalib:input dialog.executed set value 0b +execute if data storage datalib:input dialog{executed:0b} run function #datalib:input/dialog \ No newline at end of file diff --git a/datapacks/dataLib/data/datalib/function/input/command_block_minecart.mcfunction b/datapacks/dataLib/data/datalib/function/input/command_block_minecart.mcfunction new file mode 100644 index 00000000..a7849bf9 --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/command_block_minecart.mcfunction @@ -0,0 +1,49 @@ +# ====================================================================================== +# datalib:input/command_block_minecart +# ====================================================================================== +# +# TRIGGERED BY: #datalib:input/command_block_minecart function tag +# +# PURPOSE: +# Reads the Command NBT off any command_block_minecart tagged 'datalib_input', +# dropped into the world via +# 'summon minecraft:command_block_minecart ~ ~ ~ {Tags:["datalib_input"]}'. +# CAPTURE ONLY — never executes the string itself. +# +# REWRITTEN based on Legends11's reference implementation (TunnelScript-1.20.1: +# tunnelscript_core:internal/minecart_scan + minecart_process + minecart_capture). +# Bugs fixed vs. the previous version: +# +# BUG 1 — wrong emptiness check. Previous version used +# 'execute unless data entity @s Command run return 0' +# which only checks whether the Command PATH exists, not whether its VALUE +# is empty. A minecart with Command:"" (path present, value empty) passed +# this check and was treated as real input — false positive capture. Fixed +# by comparing the actual value, matching TunnelScript's +# 'execute unless data storage tunnelscript:minecart {current:""}'. +# +# BUG 2 — killed the entity instead of clearing it. TunnelScript never +# kills the minecart: it resets Command back to "" and keeps the entity +# alive for reuse (this also matches the 'tunnelscript_input' tag used +# elsewhere by Legends11 for the align/tp helper, which assumes the +# minecart persists rather than being destroyed each capture). Fixed to +# clear Command instead of killing @s. +# +# BUG 3 — 'limit=1,sort=nearest' silently ignored every other tagged +# minecart in the world. TunnelScript scans ALL tagged minecarts every +# tick with a plain 'as @e[...]', no limit. Fixed to match. +# +# SECURITY NOTE (unchanged): whoever can summon this entity with a real +# Command value already has raw command-execution ability. This function +# transports that string into the datapack, it does not create the +# privilege — the real permission boundary is who can spawn a marked +# minecart at all. +# ====================================================================================== + +# Fast exit — nothing tagged, nothing to scan this tick. +execute unless entity @e[type=minecraft:command_block_minecart,tag=datalib_input] run return 0 + +execute as @e[type=minecraft:command_block_minecart,tag=datalib_input] run function datalib:input/_private/cbm_process +function datalib:input/_private/cbm_align_tp + +return 1 diff --git a/datapacks/dataLib/data/datalib/function/input/dialog.mcfunction b/datapacks/dataLib/data/datalib/function/input/dialog.mcfunction new file mode 100644 index 00000000..c1f05724 --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/dialog.mcfunction @@ -0,0 +1,22 @@ +# ====================================================================================== +# datalib:input/dialog +# ====================================================================================== +# +# TRIGGERED BY: #datalib:input/dialog function tag +# +# PURPOSE: +# Opens datalib:input_prompt dialog for @s (must be run 'as' a player, +# e.g. 'execute as run function datalib:input/dialog', or bound +# to a right-click/other trigger by the caller). Submitted text lands in +# datalib:input_prompt's action, which macro-calls +# datalib:input/_private/dialog_capture — capture only, no execution. +# +# ASSUMPTION FLAGGED — CONFIRM WITH LEGENDS11: +# This function assumes the caller decides WHEN to open the dialog +# (e.g. right-click on an item, a command, an advancement). It is NOT +# wired to any automatic trigger itself — I did not invent one since +# none was specified. +# ====================================================================================== + +execute if entity @s[type=minecraft:player] run dialog show @s datalib:input_prompt +execute unless entity @s[type=minecraft:player] run return fail diff --git a/datapacks/dataLib/data/datalib/function/input/summon_cbm.mcfunction b/datapacks/dataLib/data/datalib/function/input/summon_cbm.mcfunction new file mode 100644 index 00000000..085781e6 --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/summon_cbm.mcfunction @@ -0,0 +1,3 @@ +kill @e[type=minecraft:minecart,tag=datalib_input,sort=nearest,limit=1,distance=..2] +kill @e[type=minecraft:interaction,tag=datalib_input,sort=nearest,limit=1,distance=..2] +execute as @s at @s run summon minecraft:interaction ~ ~ ~ {width:1.0f,height:1.0f,Tags:["datalib_input"],Passengers:[{id:"minecraft:command_block_minecart",Tags:["datalib_input"]}]} \ No newline at end of file diff --git a/datapacks/dataLib/data/datalib/function/input/writable_book.mcfunction b/datapacks/dataLib/data/datalib/function/input/writable_book.mcfunction new file mode 100644 index 00000000..84990cd7 --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/writable_book.mcfunction @@ -0,0 +1,33 @@ +# ====================================================================================== +# datalib:input/writable_book +# ====================================================================================== +# +# TRIGGERED BY: #datalib:input/writable_book function tag +# +# PURPOSE: +# Detect a player holding a written_book marked with +# custom_data={dataLib:{input:1b}} (given via +# 'give @s minecraft:written_book[minecraft:custom_data={dataLib:{input:1b}}]'), +# and extract the raw text of page[0] from +# SelectedItem.components."minecraft:writable_book_content".pages[0].raw +# into datalib:input storage. Input capture ONLY — no execution here. +# +# WHY THIS ONLY CHECKS THE MAINHAND SELECTED ITEM: +# 'SelectedItem' reflects the player's currently held mainhand item at +# entity-data-read time. If the marked book is not currently selected, +# this tick simply finds nothing — this is intentional, not a bug: we +# don't want to scan a player's whole inventory every tick for cost +# reasons, and forcing "hold it to submit" is a reasonable UX contract. +# +# NO MACRO, NO EXECUTION: +# This function contains no $$(...) macro syntax. It only reads and +# stores text. Whether the captured text is ever treated as a command +# is entirely up to a separate, opt-in execution pack — never mandatory. +# ====================================================================================== + +# Fast exit — skip entirely if no player is holding the marked book +execute unless entity @a[nbt={SelectedItem:{components:{"minecraft:custom_data":{dataLib:{input:1b}}}}}] run return 0 + +execute as @a[nbt={SelectedItem:{components:{"minecraft:custom_data":{dataLib:{input:1b}}}}}] run function datalib:input/_private/book_capture + +return 1 diff --git a/datapacks/dataLib/data/datalib/tags/function/events/on_tick.json b/datapacks/dataLib/data/datalib/tags/function/events/on_tick.json deleted file mode 100644 index ba9d3f46..00000000 --- a/datapacks/dataLib/data/datalib/tags/function/events/on_tick.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "values": [ - "datalib:core/internal/api/cmd/freeze/tick" - ] -} diff --git a/datapacks/dataLib/data/datalib/tags/function/input/command_block_minecart.json b/datapacks/dataLib/data/datalib/tags/function/input/command_block_minecart.json new file mode 100644 index 00000000..86dde3df --- /dev/null +++ b/datapacks/dataLib/data/datalib/tags/function/input/command_block_minecart.json @@ -0,0 +1,3 @@ +{ + "values": [] +} diff --git a/datapacks/dataLib/data/datalib/tags/function/input/dialog.json b/datapacks/dataLib/data/datalib/tags/function/input/dialog.json new file mode 100644 index 00000000..86dde3df --- /dev/null +++ b/datapacks/dataLib/data/datalib/tags/function/input/dialog.json @@ -0,0 +1,3 @@ +{ + "values": [] +} diff --git a/datapacks/dataLib/data/datalib/tags/function/input/writable_book.json b/datapacks/dataLib/data/datalib/tags/function/input/writable_book.json new file mode 100644 index 00000000..86dde3df --- /dev/null +++ b/datapacks/dataLib/data/datalib/tags/function/input/writable_book.json @@ -0,0 +1,3 @@ +{ + "values": [] +} diff --git a/datapacks/dataLib/data/datalib/tags/function/loop.json b/datapacks/dataLib/data/datalib/tags/function/loop.json index 86dde3df..7dda8660 100644 --- a/datapacks/dataLib/data/datalib/tags/function/loop.json +++ b/datapacks/dataLib/data/datalib/tags/function/loop.json @@ -1,3 +1,7 @@ { - "values": [] + "values": [ + "datalib:input/writable_book", + "datalib:input/command_block_minecart", + "datalib:core/internal/api/cmd/freeze/tick" + ] } From 633fe18092f07ad0034ff367df679c99181c890c Mon Sep 17 00:00:00 2001 From: IronCrest <234182831+IronCrest-sudo@users.noreply.github.com> Date: Tue, 28 Jul 2026 12:55:32 +0300 Subject: [PATCH 2/2] Create give_writable_book.mcfunction --- .../data/datalib/function/input/give_writable_book.mcfunction | 1 + 1 file changed, 1 insertion(+) create mode 100644 datapacks/dataLib/data/datalib/function/input/give_writable_book.mcfunction diff --git a/datapacks/dataLib/data/datalib/function/input/give_writable_book.mcfunction b/datapacks/dataLib/data/datalib/function/input/give_writable_book.mcfunction new file mode 100644 index 00000000..c12fdfa8 --- /dev/null +++ b/datapacks/dataLib/data/datalib/function/input/give_writable_book.mcfunction @@ -0,0 +1 @@ +give @s minecraft:writable_book[minecraft:custom_data={dataLib:{input:1b}}] 1