Skip to content
Merged
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
33 changes: 33 additions & 0 deletions datapacks/dataLib/data/datalib/dialog/input_prompt.json
Original file line number Diff line number Diff line change
@@ -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)}"
}
}
]
}
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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 ~
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
22 changes: 22 additions & 0 deletions datapacks/dataLib/data/datalib/function/input/dialog.mcfunction
Original file line number Diff line number Diff line change
@@ -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 <player> 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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
give @s minecraft:writable_book[minecraft:custom_data={dataLib:{input:1b}}] 1
Original file line number Diff line number Diff line change
@@ -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"]}]}
Original file line number Diff line number Diff line change
@@ -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

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"values": []
}
6 changes: 5 additions & 1 deletion datapacks/dataLib/data/datalib/tags/function/loop.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
{
"values": []
"values": [
"datalib:input/writable_book",
"datalib:input/command_block_minecart",
"datalib:core/internal/api/cmd/freeze/tick"
]
}