mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Added Docs, Added Translations for Dialog Types
This commit is contained in:
parent
bd29c7fc5c
commit
2aa85cbb17
5 changed files with 408 additions and 1 deletions
|
|
@ -18,7 +18,7 @@ public static class DialogFormatter
|
|||
{
|
||||
StringBuilder builder = new();
|
||||
builder.AppendLine(string.Format(Translations.dialog_render_header, instance.Revision, instance.Phase, instance.Definition.DisplayTitle()));
|
||||
builder.AppendLine(string.Format(Translations.dialog_render_type, instance.Definition.Type));
|
||||
builder.AppendLine(string.Format(Translations.dialog_render_type, DisplayType(instance.Definition.Type)));
|
||||
|
||||
foreach (var body in instance.Definition.Body.Where(static body => !string.IsNullOrWhiteSpace(body.Text)))
|
||||
builder.AppendLine(string.Format(Translations.dialog_render_body, body.Text));
|
||||
|
|
@ -47,6 +47,19 @@ public static class DialogFormatter
|
|||
return builder.ToString();
|
||||
}
|
||||
|
||||
public static string DisplayType(string rawType)
|
||||
{
|
||||
return rawType switch
|
||||
{
|
||||
"minecraft:notice" => Translations.dialog_type_notice,
|
||||
"minecraft:confirmation" => Translations.dialog_type_confirmation,
|
||||
"minecraft:multi_action" => Translations.dialog_type_multi_action,
|
||||
"minecraft:dialog_list" => Translations.dialog_type_dialog_list,
|
||||
"minecraft:server_links" => Translations.dialog_type_server_links,
|
||||
_ => string.IsNullOrEmpty(rawType) ? Translations.dialog_type_unknown : rawType
|
||||
};
|
||||
}
|
||||
|
||||
private static string DescribeInput(DialogInput input)
|
||||
{
|
||||
return input.Kind switch
|
||||
|
|
|
|||
|
|
@ -8077,5 +8077,29 @@ namespace MinecraftClient {
|
|||
get { return ResourceManager.GetString("dialog.action_desc_unknown", resourceCulture); }
|
||||
}
|
||||
|
||||
internal static string dialog_type_notice {
|
||||
get { return ResourceManager.GetString("dialog.type.notice", resourceCulture); }
|
||||
}
|
||||
|
||||
internal static string dialog_type_confirmation {
|
||||
get { return ResourceManager.GetString("dialog.type.confirmation", resourceCulture); }
|
||||
}
|
||||
|
||||
internal static string dialog_type_multi_action {
|
||||
get { return ResourceManager.GetString("dialog.type.multi_action", resourceCulture); }
|
||||
}
|
||||
|
||||
internal static string dialog_type_dialog_list {
|
||||
get { return ResourceManager.GetString("dialog.type.dialog_list", resourceCulture); }
|
||||
}
|
||||
|
||||
internal static string dialog_type_server_links {
|
||||
get { return ResourceManager.GetString("dialog.type.server_links", resourceCulture); }
|
||||
}
|
||||
|
||||
internal static string dialog_type_unknown {
|
||||
get { return ResourceManager.GetString("dialog.type.unknown", resourceCulture); }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3034,4 +3034,22 @@ see item details.</value>
|
|||
<data name="dialog.action_desc_unknown" xml:space="preserve">
|
||||
<value>unknown</value>
|
||||
</data>
|
||||
<data name="dialog.type.notice" xml:space="preserve">
|
||||
<value>Notice</value>
|
||||
</data>
|
||||
<data name="dialog.type.confirmation" xml:space="preserve">
|
||||
<value>Confirmation</value>
|
||||
</data>
|
||||
<data name="dialog.type.multi_action" xml:space="preserve">
|
||||
<value>Multi-action</value>
|
||||
</data>
|
||||
<data name="dialog.type.dialog_list" xml:space="preserve">
|
||||
<value>Dialog list</value>
|
||||
</data>
|
||||
<data name="dialog.type.server_links" xml:space="preserve">
|
||||
<value>Server links</value>
|
||||
</data>
|
||||
<data name="dialog.type.unknown" xml:space="preserve">
|
||||
<value>Unknown</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
|||
|
|
@ -1647,6 +1647,120 @@ In scripts and remote control, no slash is needed to perform the command, eg. `q
|
|||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>dialog</code></summary>
|
||||
|
||||
- **Description:**
|
||||
|
||||
Browse and interact with dialogs sent by the server. Dialogs are popups with a title, body text, and buttons. TUI mode gives the best experience -- use `/dialog open` to view the dialog in a full-screen overlay.
|
||||
|
||||
When a server shows a dialog, MCC prints:
|
||||
|
||||
```
|
||||
[MCC] Server showed custom dialog: Server Notice. Use dialog show.
|
||||
```
|
||||
|
||||
Run `/dialog show` to see the full dialog. Buttons show up like this:
|
||||
|
||||
```
|
||||
Actions:
|
||||
[1] OK (close)
|
||||
[2] Visit (command)
|
||||
[3] Rules (show dialog)
|
||||
```
|
||||
|
||||
The text in parentheses tells you what the button does: `(close)` closes the dialog, `(command)` sends a chat command, `(show dialog)` opens another dialog.
|
||||
|
||||
- **Dialog types:**
|
||||
|
||||
Dialogs come in a few shapes. You might see these in the output of `/dialog show`:
|
||||
|
||||
**Notice** -- A popup with a title, optional body, and one button.
|
||||
|
||||
```
|
||||
Type: Notice
|
||||
|
||||
Welcome to the server!
|
||||
|
||||
Body: Read the rules before playing.
|
||||
|
||||
Actions:
|
||||
[1] OK (close)
|
||||
```
|
||||
|
||||
**Confirmation** -- A choice between two buttons.
|
||||
|
||||
```
|
||||
Type: Confirmation
|
||||
|
||||
Reset your progress?
|
||||
|
||||
Actions:
|
||||
[1] Yes (close)
|
||||
[2] No (close)
|
||||
```
|
||||
|
||||
**Multi-action** -- A grid of buttons.
|
||||
|
||||
```
|
||||
Type: Multi-action
|
||||
|
||||
Choose a destination
|
||||
|
||||
Actions:
|
||||
[1] Spawn (close)
|
||||
[2] Shop (close)
|
||||
[3] Arena (close)
|
||||
```
|
||||
|
||||
**Dialog list** -- A list of sub-dialogs. Clicking one opens another dialog.
|
||||
|
||||
```
|
||||
Type: Dialog list
|
||||
|
||||
Help Topics
|
||||
|
||||
Actions:
|
||||
[1] Rules (show dialog)
|
||||
[2] Commands (show dialog)
|
||||
```
|
||||
|
||||
**Server links** -- Shows the server's configured links as buttons. May be empty.
|
||||
|
||||
```
|
||||
Type: Server links
|
||||
|
||||
Server Links
|
||||
```
|
||||
|
||||
- **Usage:**
|
||||
|
||||
```
|
||||
/dialog
|
||||
/dialog show
|
||||
/dialog open
|
||||
/dialog click <index>
|
||||
/dialog click-label <label>
|
||||
/dialog set <input> <value>
|
||||
/dialog input <input> <value>
|
||||
/dialog cancel
|
||||
/dialog dismiss
|
||||
```
|
||||
|
||||
- **Examples:**
|
||||
|
||||
```
|
||||
/dialog show
|
||||
/dialog click 1
|
||||
/dialog click-label Teleport
|
||||
/dialog set name MyPlayer
|
||||
/dialog dismiss
|
||||
```
|
||||
|
||||
See what dialog is currently shown, click the first button, click a button by its text, fill in an input, or close the dialog.
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><code>debug</code></summary>
|
||||
|
||||
|
|
|
|||
238
tools/run-dialog-test.sh
Executable file
238
tools/run-dialog-test.sh
Executable file
|
|
@ -0,0 +1,238 @@
|
|||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
||||
source "$REPO_ROOT/tools/mcc-env.sh"
|
||||
source "$REPO_ROOT/.skills/mcc-integration-testing/scripts/common.sh"
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: tools/run-dialog-test.sh <mc-version>
|
||||
|
||||
Integration test for MCC dialog system against a real local server.
|
||||
Tests all 5 dialog types, button actions, cancel/dismiss, and body content.
|
||||
|
||||
Examples:
|
||||
tools/run-dialog-test.sh 26.1
|
||||
tools/run-dialog-test.sh 1.21.11
|
||||
EOF
|
||||
}
|
||||
|
||||
MC_VERSION="${1:-}"
|
||||
if [[ -z "$MC_VERSION" ]]; then
|
||||
usage >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
SESSION_NAME="dialog-test-${MC_VERSION//[^a-zA-Z0-9]/_}"
|
||||
TEST_ROOT="${TMPDIR:-/tmp}/mcc-dialog-test/${MC_VERSION//\//_}"
|
||||
CFG="$TEST_ROOT/custom.ini"
|
||||
MCC_LOG="$TEST_ROOT/mcc-output.log"
|
||||
INPUT_FILE="$TEST_ROOT/mcc_input.txt"
|
||||
SERVER_PORT="25565"
|
||||
PASS=0
|
||||
FAIL=0
|
||||
|
||||
cleanup() {
|
||||
tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
header() {
|
||||
echo ""
|
||||
echo "===== $* ====="
|
||||
}
|
||||
|
||||
# Strip ANSI escape codes for grep matching
|
||||
ansi_strip() {
|
||||
sed 's/\x1b\[[0-9;]*[a-zA-Z]//g'
|
||||
}
|
||||
|
||||
assert_log() {
|
||||
local label="$1"
|
||||
local pattern="$2"
|
||||
local timeout="${3:-5}"
|
||||
local elapsed=0
|
||||
while (( elapsed < timeout )); do
|
||||
if [[ -f "$MCC_LOG" ]] && ansi_strip < "$MCC_LOG" | grep -Fq "$pattern" 2>/dev/null; then
|
||||
echo " PASS: $label"
|
||||
PASS=$((PASS + 1))
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
((elapsed += 1))
|
||||
done
|
||||
echo " FAIL: $label (expected: '$pattern')"
|
||||
FAIL=$((FAIL + 1))
|
||||
}
|
||||
|
||||
wait_for_pattern() {
|
||||
local file="$1"
|
||||
local pattern="$2"
|
||||
local timeout="${3:-60}"
|
||||
local elapsed=0
|
||||
while (( elapsed < timeout )); do
|
||||
if [[ -f "$file" ]] && ansi_strip < "$file" | grep -Fq "$pattern" 2>/dev/null; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
((elapsed += 1))
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
write_input() {
|
||||
echo "$1" >> "$INPUT_FILE"
|
||||
sleep 1
|
||||
}
|
||||
|
||||
assert_dialog_shown() {
|
||||
assert_log "$1 received" "Server showed custom dialog: $2" 10
|
||||
}
|
||||
|
||||
# ---- Setup ----
|
||||
|
||||
mkdir -p "$TEST_ROOT"
|
||||
rm -f "$MCC_LOG" "$INPUT_FILE"
|
||||
|
||||
echo "[Dialog Test] Version: $MC_VERSION, Session: $SESSION_NAME"
|
||||
echo "[Dialog Test] Log: $MCC_LOG"
|
||||
|
||||
# Ensure server is running
|
||||
if ! server_running "$MC_VERSION"; then
|
||||
echo "[Setup] Starting server..."
|
||||
bash "$REPO_ROOT/tools/start-server.sh" "$MC_VERSION" 2>&1 | tail -1
|
||||
wait_for_server_ready "$MC_VERSION" 120
|
||||
fi
|
||||
|
||||
echo "[Setup] Server ready."
|
||||
|
||||
# Prepare temp config
|
||||
echo "[Setup] Preparing MCC config..."
|
||||
bash "$REPO_ROOT/.skills/mcc-integration-testing/scripts/prepare_offline_mcc_config.sh" \
|
||||
"$CFG" "$MC_VERSION" "MCCBot" >/dev/null
|
||||
|
||||
# Disable packet debug (fix in-place to avoid dup sections)
|
||||
sed_in_place \
|
||||
-e '/^\[Debug\]/,/^\s*$/d' \
|
||||
"$CFG"
|
||||
|
||||
cat >> "$CFG" <<TOML
|
||||
|
||||
[Debug]
|
||||
DebugMessages = false
|
||||
PacketDebugMessages = false
|
||||
TOML
|
||||
|
||||
# Launch MCC with MCC_FILE_INPUT=1 for maximum compatibility
|
||||
echo "ping" > "$INPUT_FILE"
|
||||
tmux kill-session -t "$SESSION_NAME" 2>/dev/null || true
|
||||
sleep 1
|
||||
|
||||
cd "$REPO_ROOT"
|
||||
# FileInputBot ignores config and uses MCC_INPUT_FILE env var only
|
||||
INPUT_FILE_ABS="$(realpath "$INPUT_FILE")"
|
||||
tmux new-session -d -s "$SESSION_NAME" \
|
||||
"bash -c 'export MCC_FILE_INPUT=1; export MCC_INPUT_FILE=\"$INPUT_FILE_ABS\"; exec dotnet run --no-build --project MinecraftClient -c Release -- \"$CFG\" \"MCCBot\" \"-\" \"localhost:$SERVER_PORT\"' > '$MCC_LOG' 2>&1"
|
||||
|
||||
echo "[Setup] Waiting for MCC to join..."
|
||||
if ! wait_for_pattern "$MCC_LOG" "Server was successfully joined" 90; then
|
||||
echo "ERROR: MCC did not join the server. Check $MCC_LOG"
|
||||
tail -10 "$MCC_LOG" | ansi_strip
|
||||
exit 1
|
||||
fi
|
||||
echo "[Setup] MCC joined."
|
||||
sleep 2
|
||||
|
||||
# ---- Tests ----
|
||||
|
||||
header "1. Notice Dialog"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:notice", title:{text:"Notice Title"}}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "notice dialog" "Notice Title"
|
||||
write_input "dialog show"
|
||||
assert_log "notice type" "Type: Notice" 10
|
||||
assert_log "notice OK button" "OK (close)" 3
|
||||
|
||||
header "2. Confirmation Dialog"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:confirmation", title:{text:"Confirm?"}, yes:{label:{text:"Yes"}}, no:{label:{text:"No"}}}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "confirmation" "Confirm?"
|
||||
write_input "dialog show"
|
||||
assert_log "confirmation type" "Type: Confirmation" 10
|
||||
assert_log "yes button" "Yes (close)" 3
|
||||
assert_log "no button" "No (close)" 3
|
||||
|
||||
header "3. Multi-Action Dialog"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:multi_action", title:{text:"Choose"}, actions:[{label:{text:"Alpha"}}, {label:{text:"Beta"}}, {label:{text:"Gamma"}}]}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "multi_action" "Choose"
|
||||
write_input "dialog show"
|
||||
assert_log "multi_action type" "Type: Multi-action" 10
|
||||
assert_log "multi_action button 1" "Alpha (close)" 3
|
||||
assert_log "multi_action button 2" "Beta (close)" 3
|
||||
assert_log "multi_action button 3" "Gamma (close)" 3
|
||||
|
||||
header "4. Dialog-List Dialog"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:dialog_list", title:{text:"List"}, dialogs:[{type:"minecraft:notice", title:{text:"Sub One"}}, {type:"minecraft:notice", title:{text:"Sub Two"}}]}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "dialog_list" "List"
|
||||
write_input "dialog show"
|
||||
assert_log "dialog_list type" "Type: Dialog list" 10
|
||||
assert_log "dialog_list sub 1" "Sub One (show dialog)" 3
|
||||
assert_log "dialog_list sub 2" "Sub Two (show dialog)" 3
|
||||
|
||||
header "5. Server-Links Dialog"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:server_links", title:{text:"Links"}}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "server_links" "Links"
|
||||
write_input "dialog show"
|
||||
assert_log "server_links type" "Type: Server links" 10
|
||||
|
||||
header "6. Body Content"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:notice", title:{text:"With Body"}, body:[{type:"minecraft:plain_message", contents:{text:"Hello from body"}}]}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "body dialog" "With Body"
|
||||
write_input "dialog show"
|
||||
assert_log "body content" "Hello from body" 10
|
||||
|
||||
header "7. Custom run_command Action"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:notice", title:{text:"Run Cmd"}, action:{label:{text:"/list"}, action:{type:"minecraft:run_command", command:"/list"}}}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "command action" "Run Cmd"
|
||||
write_input "dialog show"
|
||||
assert_log "command action button" "/list (command)" 10
|
||||
write_input "dialog click 1"
|
||||
assert_log "command executed" "There are " 10
|
||||
|
||||
header "8. show_dialog Action (nested)"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:notice", title:{text:"First"}, action:{label:{text:"Next"}, action:{type:"minecraft:show_dialog", dialog:{type:"minecraft:notice", title:{text:"Second"}}}}}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "first dialog" "First"
|
||||
write_input "dialog click 1"
|
||||
assert_dialog_shown "nested dialog" "Second"
|
||||
|
||||
header "9. Dialog Cancel"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:notice", title:{text:"Cancel Me"}}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "cancel test dialog" "Cancel Me"
|
||||
write_input "dialog cancel"
|
||||
assert_log "cancel closed dialog" "Dialog action closed locally" 10
|
||||
|
||||
header "10. Dialog Click-Label"
|
||||
mc-rcon 'dialog show MCCBot {type:"minecraft:multi_action", title:{text:"Label Test"}, actions:[{label:{text:"Pick Me"}}, {label:{text:"Leave Me"}}]}' 2>&1 | ansi_strip | grep -v "^$"
|
||||
assert_dialog_shown "click-label dialog" "Label Test"
|
||||
write_input "dialog click-label Pick Me"
|
||||
assert_log "click-label worked" "Dialog action closed locally" 10
|
||||
|
||||
# ---- Results ----
|
||||
|
||||
echo ""
|
||||
echo "=========================================="
|
||||
echo " Dialog Integration Test Results"
|
||||
echo "=========================================="
|
||||
echo " PASS: $PASS"
|
||||
echo " FAIL: $FAIL"
|
||||
echo "------------------------------------------"
|
||||
|
||||
if [[ $FAIL -gt 0 ]]; then
|
||||
echo "FAILURES DETECTED. Full log: $MCC_LOG"
|
||||
echo "Last 20 lines:"
|
||||
ansi_strip < "$MCC_LOG" | tail -20
|
||||
exit 1
|
||||
else
|
||||
echo "ALL TESTS PASSED."
|
||||
exit 0
|
||||
fi
|
||||
Loading…
Add table
Add a link
Reference in a new issue