diff --git a/MinecraftClient/ClassicConsoleBackend.cs b/MinecraftClient/ClassicConsoleBackend.cs
index 02712459..c771d273 100644
--- a/MinecraftClient/ClassicConsoleBackend.cs
+++ b/MinecraftClient/ClassicConsoleBackend.cs
@@ -1,12 +1,81 @@
using System;
+using System.Text.RegularExpressions;
namespace MinecraftClient
{
///
/// Console backend wrapping the ConsoleInteractive library (existing behavior).
///
- public class ClassicConsoleBackend : IConsoleBackend
+ public partial class ClassicConsoleBackend : IConsoleBackend
{
+ private static readonly (byte R, byte G, byte B, char Code)[] McStandardColors =
+ [
+ (0, 0, 0, '0'), // black
+ (0, 0, 170, '1'), // dark_blue
+ (0, 170, 0, '2'), // dark_green
+ (0, 170, 170, '3'), // dark_aqua
+ (170, 0, 0, '4'), // dark_red
+ (170, 0, 170, '5'), // dark_purple
+ (255, 170, 0, '6'), // gold
+ (170, 170, 170, '7'), // gray
+ (85, 85, 85, '8'), // dark_gray
+ (85, 85, 255, '9'), // blue
+ (85, 255, 85, 'a'), // green
+ (85, 255, 255, 'b'), // aqua
+ (255, 85, 85, 'c'), // red
+ (255, 85, 255, 'd'), // light_purple
+ (255, 255, 85, 'e'), // yellow
+ (255, 255, 255, 'f'), // white
+ ];
+
+ [GeneratedRegex("§#([0-9a-fA-F]{6})")]
+ private static partial Regex HexColorRegex();
+
+ private static char NearestMcColor(byte r, byte g, byte b)
+ {
+ int bestIdx = 0;
+ long bestDist = long.MaxValue;
+
+ for (int i = 0; i < McStandardColors.Length; i++)
+ {
+ var (sr, sg, sb, _) = McStandardColors[i];
+ long dr = r - sr;
+ long dg = g - sg;
+ long db = b - sb;
+ long dist = dr * dr + dg * dg + db * db;
+ if (dist < bestDist)
+ {
+ bestDist = dist;
+ bestIdx = i;
+ }
+ }
+
+ return McStandardColors[bestIdx].Code;
+ }
+
+ private static string ResolveHexColors(string text)
+ {
+ if (string.IsNullOrEmpty(text) || !text.Contains("§#", StringComparison.Ordinal))
+ return text;
+
+ return HexColorRegex().Replace(text, match =>
+ {
+ ReadOnlySpan hex = match.Groups[1].ValueSpan;
+ byte r = (byte)((HexVal(hex[0]) << 4) | HexVal(hex[1]));
+ byte g = (byte)((HexVal(hex[2]) << 4) | HexVal(hex[3]));
+ byte b = (byte)((HexVal(hex[4]) << 4) | HexVal(hex[5]));
+ return $"§{NearestMcColor(r, g, b)}";
+ });
+ }
+
+ private static int HexVal(char c) => c switch
+ {
+ >= '0' and <= '9' => c - '0',
+ >= 'a' and <= 'f' => c - 'a' + 10,
+ >= 'A' and <= 'F' => c - 'A' + 10,
+ _ => 0
+ };
+
public event EventHandler? MessageReceived;
public event EventHandler? OnInputChange;
@@ -28,7 +97,7 @@ namespace MinecraftClient
public void WriteLineFormatted(string text)
{
- ConsoleInteractive.ConsoleWriter.WriteLineFormatted(text);
+ ConsoleInteractive.ConsoleWriter.WriteLineFormatted(ResolveHexColors(text));
}
public void BeginReadThread()
diff --git a/MinecraftClient/Commands/Dialog.cs b/MinecraftClient/Commands/Dialog.cs
index 682b468a..826fa592 100644
--- a/MinecraftClient/Commands/Dialog.cs
+++ b/MinecraftClient/Commands/Dialog.cs
@@ -53,9 +53,11 @@ public class Dialog : Command
{
var handler = CmdResult.currentHandler!;
var current = handler.Dialogs.Current;
- return current is null
- ? r.SetAndReturn(CmdResult.Status.Fail, Translations.dialog_none)
- : r.SetAndReturn(CmdResult.Status.Done, DialogFormatter.Render(current));
+ if (current is null)
+ return r.SetAndReturn(CmdResult.Status.Fail, Translations.dialog_none);
+
+ ConsoleIO.WriteLineFormatted(DialogFormatter.Render(current), acceptnewlines: true);
+ return r.SetAndReturn(CmdResult.Status.Done);
}
private static int Open(CmdResult r)
diff --git a/MinecraftClient/Dialogs/DialogFormatter.cs b/MinecraftClient/Dialogs/DialogFormatter.cs
index d7fe9ffa..c24fca44 100644
--- a/MinecraftClient/Dialogs/DialogFormatter.cs
+++ b/MinecraftClient/Dialogs/DialogFormatter.cs
@@ -11,17 +11,21 @@ public static class DialogFormatter
if (!string.IsNullOrWhiteSpace(definition.ExternalTitle))
return definition.ExternalTitle!;
- return string.IsNullOrWhiteSpace(definition.Title) ? definition.Type : definition.Title;
+ return string.IsNullOrWhiteSpace(definition.Title) ? DisplayType(definition.Type) : definition.Title;
}
+ private const int BoxWidth = 50;
+
public static string Render(DialogInstance instance)
{
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, DisplayType(instance.Definition.Type)));
+ string border = new('-', BoxWidth);
+ builder.AppendLine(border);
+ builder.AppendLine(" " + string.Format(Translations.dialog_render_header, instance.Revision, instance.Phase, instance.Definition.DisplayTitle()));
+ builder.AppendLine(border);
foreach (var body in instance.Definition.Body.Where(static body => !string.IsNullOrWhiteSpace(body.Text)))
- builder.AppendLine(string.Format(Translations.dialog_render_body, body.Text));
+ builder.AppendLine(body.Text);
if (instance.Definition.Inputs.Count > 0)
{
@@ -30,7 +34,7 @@ public static class DialogFormatter
{
instance.Values.TryGetValue(input.Key, out var value);
value ??= input.InitialValue;
- builder.AppendLine(string.Format(Translations.dialog_render_input, input.Key, input.Kind, input.Label, value, DescribeInput(input)));
+ builder.AppendLine(string.Format(Translations.dialog_render_input, input.Key, DescribeKind(input.Kind), input.Label, value, DescribeInput(input)));
}
}
@@ -41,9 +45,7 @@ public static class DialogFormatter
builder.AppendLine(string.Format(Translations.dialog_render_action, action.Index, action.Label, DescribeAction(action.Action)));
}
- if (instance.Definition.CancelAction is not null || instance.Definition.CanCloseWithEscape)
- builder.AppendLine(Translations.dialog_render_cancel_hint);
-
+ builder.Append(border);
return builder.ToString();
}
@@ -60,6 +62,18 @@ public static class DialogFormatter
};
}
+ private static string DescribeKind(DialogInputKind kind)
+ {
+ return kind switch
+ {
+ DialogInputKind.Text => Translations.dialog_input_kind_text,
+ DialogInputKind.Boolean => Translations.dialog_input_kind_boolean,
+ DialogInputKind.SingleOption => Translations.dialog_input_kind_options,
+ DialogInputKind.NumberRange => Translations.dialog_input_kind_number,
+ _ => Translations.dialog_input_kind_unknown
+ };
+ }
+
private static string DescribeInput(DialogInput input)
{
return input.Kind switch
diff --git a/MinecraftClient/Dialogs/DialogManager.cs b/MinecraftClient/Dialogs/DialogManager.cs
index ca34b281..40876b61 100644
--- a/MinecraftClient/Dialogs/DialogManager.cs
+++ b/MinecraftClient/Dialogs/DialogManager.cs
@@ -72,7 +72,7 @@ public sealed class DialogManager
_current = instance;
}
- _client.Log.Info(string.Format(Translations.dialog_received, instance.Definition.DisplayTitle()));
+ _client.Log.Info("§e" + string.Format(Translations.dialog_received, instance.Definition.DisplayTitle()));
DialogShown?.Invoke(instance);
return instance;
}
diff --git a/MinecraftClient/Protocol/Dialogs/DialogNbtParser.cs b/MinecraftClient/Protocol/Dialogs/DialogNbtParser.cs
index cfed430f..2636b5be 100644
--- a/MinecraftClient/Protocol/Dialogs/DialogNbtParser.cs
+++ b/MinecraftClient/Protocol/Dialogs/DialogNbtParser.cs
@@ -79,9 +79,6 @@ public sealed class DialogNbtParser
var body = ParseBody(GetValue(nbt, "body"));
var inputs = ParseInputs(GetValue(nbt, "inputs"));
- if (string.IsNullOrWhiteSpace(title))
- title = type;
-
return new DialogCommon(title, externalTitle, canCloseWithEscape, pause, afterAction, body, inputs);
}
diff --git a/MinecraftClient/Resources/Translations/Translations.Designer.cs b/MinecraftClient/Resources/Translations/Translations.Designer.cs
index fcc8bcad..c2803581 100644
--- a/MinecraftClient/Resources/Translations/Translations.Designer.cs
+++ b/MinecraftClient/Resources/Translations/Translations.Designer.cs
@@ -8101,5 +8101,25 @@ namespace MinecraftClient {
get { return ResourceManager.GetString("dialog.type.unknown", resourceCulture); }
}
+ internal static string dialog_input_kind_text {
+ get { return ResourceManager.GetString("dialog.input_kind.text", resourceCulture); }
+ }
+
+ internal static string dialog_input_kind_boolean {
+ get { return ResourceManager.GetString("dialog.input_kind.boolean", resourceCulture); }
+ }
+
+ internal static string dialog_input_kind_options {
+ get { return ResourceManager.GetString("dialog.input_kind.options", resourceCulture); }
+ }
+
+ internal static string dialog_input_kind_number {
+ get { return ResourceManager.GetString("dialog.input_kind.number", resourceCulture); }
+ }
+
+ internal static string dialog_input_kind_unknown {
+ get { return ResourceManager.GetString("dialog.input_kind.unknown", resourceCulture); }
+ }
+
}
}
diff --git a/MinecraftClient/Resources/Translations/Translations.resx b/MinecraftClient/Resources/Translations/Translations.resx
index 90c2f04a..34ce6a62 100644
--- a/MinecraftClient/Resources/Translations/Translations.resx
+++ b/MinecraftClient/Resources/Translations/Translations.resx
@@ -2834,7 +2834,7 @@ see item details.
View and interact with the current server custom dialog.
- Server showed custom dialog: {0}. Use dialog show.
+ Server showed custom dialog: {0}. Use /dialog show.
Server cleared the custom dialog.
@@ -2993,13 +2993,13 @@ see item details.
[{0}] {1} ({2})
- Use dialog cancel to close or run the cancel action.
+ Use /dialog cancel to close or run the cancel action.
max {0} chars
- true={0}, false={1}
+ Yes={0}, No={1}
options: {0}
@@ -3041,7 +3041,7 @@ see item details.
Confirmation
- Multi-action
+ Multi Action
Dialog list
@@ -3052,4 +3052,19 @@ see item details.
Unknown
+
+ Text
+
+
+ Check box
+
+
+ Options
+
+
+ Number
+
+
+ Unknown
+
diff --git a/MinecraftClient/Tui/DialogTuiHost.cs b/MinecraftClient/Tui/DialogTuiHost.cs
index f926b35e..8b0708a7 100644
--- a/MinecraftClient/Tui/DialogTuiHost.cs
+++ b/MinecraftClient/Tui/DialogTuiHost.cs
@@ -59,20 +59,27 @@ public static class DialogTuiHost
internal sealed class DialogView : Border, IOverlayCloseHandler
{
+ private static readonly Color AccentColor = Color.FromRgb(80, 180, 255);
+ private static readonly Color BorderColor = Color.FromRgb(70, 70, 70);
+ private static readonly Color SectionBg = Color.FromRgb(20, 20, 20);
+ private static readonly Color InputBg = Color.FromRgb(35, 35, 35);
+
private readonly McClient _handler;
private readonly DialogInstance _instance;
private readonly TextBlock _status;
private readonly Dictionary _inputControls = new(StringComparer.Ordinal);
+ private readonly StackPanel _inputsPanel;
+ private readonly WrapPanel _buttonsPanel;
public DialogView(McClient handler, DialogInstance instance)
{
_handler = handler;
_instance = instance;
- BorderBrush = Brushes.White;
+ BorderBrush = new SolidColorBrush(BorderColor);
BorderThickness = new Thickness(1);
- Background = Brushes.Black;
- Padding = new Thickness(1);
+ Background = new SolidColorBrush(Color.FromRgb(12, 12, 12));
+ Padding = new Thickness(2);
HorizontalAlignment = HorizontalAlignment.Stretch;
VerticalAlignment = VerticalAlignment.Stretch;
Focusable = true;
@@ -81,14 +88,18 @@ internal sealed class DialogView : Border, IOverlayCloseHandler
{
Foreground = Brushes.Gray,
TextWrapping = TextWrapping.Wrap,
- Margin = new Thickness(1, 0)
+ Margin = new Thickness(0, 1, 0, 0)
};
+ _inputsPanel = new StackPanel { Spacing = 0, Margin = new Thickness(0) };
+ _buttonsPanel = new WrapPanel { Orientation = Orientation.Horizontal };
+
Child = BuildContent();
AttachedToVisualTree += (_, _) =>
{
AddHandler(KeyDownEvent, OnTunnelKeyDown, RoutingStrategies.Tunnel, handledEventsToo: true);
+ FocusFirstInput();
Focus();
};
DetachedFromVisualTree += (_, _) => RemoveHandler(KeyDownEvent, OnTunnelKeyDown);
@@ -112,75 +123,97 @@ internal sealed class DialogView : Border, IOverlayCloseHandler
private Control BuildContent()
{
- var main = new StackPanel
+ var root = new DockPanel { Margin = new Thickness(0) };
+
+ var scroll = new ScrollViewer
{
- Spacing = 1,
- Margin = new Thickness(1)
+ HorizontalScrollBarVisibility = Avalonia.Controls.Primitives.ScrollBarVisibility.Disabled,
+ VerticalScrollBarVisibility = Avalonia.Controls.Primitives.ScrollBarVisibility.Auto
};
- main.Children.Add(new TextBlock
+ var main = new StackPanel { Spacing = 0, Margin = new Thickness(0) };
+
+ // Title
+ main.Children.Add(McColorParser.CreateColoredTextBlock(_instance.Definition.DisplayTitle()));
+
+ // Separator
+ main.Children.Add(new Border
{
- Text = _instance.Definition.DisplayTitle(),
- Foreground = Brushes.Yellow,
- FontWeight = FontWeight.Bold,
- TextWrapping = TextWrapping.Wrap
+ Height = 1,
+ Background = new SolidColorBrush(BorderColor),
+ Margin = new Thickness(0, 1, 0, 1)
});
+ // Body
foreach (var body in _instance.Definition.Body)
{
if (string.IsNullOrWhiteSpace(body.Text))
continue;
+ main.Children.Add(McColorParser.CreateColoredTextBlock(body.Text));
+ }
+ // Build action buttons
+ EnsureActionButtons();
+
+ // Inputs
+ foreach (var input in _instance.Definition.Inputs)
+ main.Children.Add(BuildInput(input));
+
+ // Action buttons
+ if (_buttonsPanel.Children.Count > 0)
+ main.Children.Add(_buttonsPanel);
+
+ // Cancel hint
+ if (_instance.Definition.CancelAction is not null || _instance.Definition.CanCloseWithEscape)
+ {
main.Children.Add(new TextBlock
{
- Text = body.Text,
- Foreground = Brushes.White,
+ Text = Translations.dialog_render_cancel_hint,
+ Foreground = new SolidColorBrush(Color.FromRgb(120, 120, 120)),
TextWrapping = TextWrapping.Wrap
});
}
- foreach (var input in _instance.Definition.Inputs)
- main.Children.Add(BuildInput(input));
+ main.Children.Add(_status);
+ scroll.Content = main;
+ root.Children.Add(scroll);
- var buttons = new WrapPanel
- {
- Orientation = Orientation.Horizontal
- };
+ return root;
+ }
+
+ private void EnsureActionButtons()
+ {
+ if (_buttonsPanel.Children.Count > 0)
+ return;
foreach (var action in _instance.Definition.Actions)
{
- var button = new Button
+ var btn = new Button
{
- Content = action.Label,
- Margin = new Thickness(0, 0, 1, 1),
- MinWidth = Math.Max(8, Math.Min(action.Label.Length + 4, 32))
+ Content = McColorParser.CreateColoredTextBlock(action.Label),
+ Padding = new Thickness(1),
+ BorderThickness = new Thickness(1),
+ BorderBrush = new SolidColorBrush(Color.FromRgb(60, 60, 60)),
+ Background = new SolidColorBrush(Color.FromRgb(40, 40, 40)),
+ Margin = new Thickness(0, 0, 1, 1)
};
- button.Click += (_, _) => Click(action.Index);
- buttons.Children.Add(button);
+ btn.Click += (_, _) => Click(action.Index);
+ _buttonsPanel.Children.Add(btn);
}
if (_instance.Definition.CancelAction is not null || _instance.Definition.CanCloseWithEscape)
{
var cancel = new Button
{
- Content = Translations.tui_dialog_cancel,
- Margin = new Thickness(0, 0, 1, 1)
+ Content = McColorParser.CreateColoredTextBlock(Translations.tui_dialog_cancel),
+ Padding = new Thickness(1),
+ BorderThickness = new Thickness(1),
+ BorderBrush = new SolidColorBrush(Color.FromRgb(80, 40, 40)),
+ Background = new SolidColorBrush(Color.FromRgb(50, 25, 25))
};
cancel.Click += (_, _) => TryCloseByUser();
- buttons.Children.Add(cancel);
+ _buttonsPanel.Children.Add(cancel);
}
-
- if (buttons.Children.Count > 0)
- main.Children.Add(buttons);
-
- main.Children.Add(_status);
-
- return new ScrollViewer
- {
- Content = main,
- HorizontalScrollBarVisibility = Avalonia.Controls.Primitives.ScrollBarVisibility.Disabled,
- VerticalScrollBarVisibility = Avalonia.Controls.Primitives.ScrollBarVisibility.Auto
- };
}
private Control BuildInput(DialogInput input)
@@ -188,84 +221,125 @@ internal sealed class DialogView : Border, IOverlayCloseHandler
_instance.Values.TryGetValue(input.Key, out var value);
value ??= input.InitialValue;
- var panel = new StackPanel
- {
- Spacing = 0,
- Margin = new Thickness(0, 1)
- };
+ var panel = new StackPanel { Spacing = 0, Margin = new Thickness(0) };
if (input.LabelVisible && !string.IsNullOrWhiteSpace(input.Label))
- {
- panel.Children.Add(new TextBlock
- {
- Text = input.Label,
- Foreground = Brushes.LightGray,
- TextWrapping = TextWrapping.Wrap
- });
- }
+ panel.Children.Add(McColorParser.CreateColoredTextBlock(input.Label));
- Control control = input.Kind switch
+ Control inner = input.Kind switch
{
- DialogInputKind.Boolean => BuildBooleanInput(value),
+ DialogInputKind.Boolean => BuildBooleanInput(value, input),
DialogInputKind.SingleOption => BuildOptionInput(input, value),
DialogInputKind.NumberRange => BuildNumberInput(input, value),
_ => BuildTextInput(input, value)
};
- _inputControls[input.Key] = control;
- panel.Children.Add(control);
+ _inputControls[input.Key] = inner;
+
+ if (input.Kind == DialogInputKind.Boolean)
+ {
+ panel.Children.Add(inner);
+ }
+ else
+ {
+ panel.Children.Add(new Border
+ {
+ Background = new SolidColorBrush(InputBg),
+ BorderBrush = new SolidColorBrush(Color.FromRgb(55, 55, 55)),
+ BorderThickness = new Thickness(1),
+ Padding = new Thickness(1),
+ Child = inner
+ });
+ }
+
return panel;
}
- private static Control BuildTextInput(DialogInput input, string value)
+ private Control BuildTextInput(DialogInput input, string value)
{
- return new TextBox
+ var tb = new TextBox
{
Text = value,
AcceptsReturn = input.Multiline,
- TextWrapping = TextWrapping.Wrap,
+ TextWrapping = input.Multiline ? TextWrapping.Wrap : TextWrapping.NoWrap,
MaxLength = input.MaxLength,
Foreground = Brushes.White,
- Background = Brushes.Black,
- BorderBrush = Brushes.Gray
+ Background = new SolidColorBrush(InputBg),
+ BorderThickness = new Thickness(0),
+ Padding = new Thickness(0)
};
+
+ return tb;
}
- private static Control BuildBooleanInput(string value)
+ private Control BuildBooleanInput(string value, DialogInput input)
{
return new CheckBox
{
IsChecked = value.Equals("true", StringComparison.OrdinalIgnoreCase),
- Foreground = Brushes.White
+ Foreground = Brushes.White,
+ Padding = new Thickness(0)
};
}
- private static Control BuildOptionInput(DialogInput input, string value)
+ private Control BuildOptionInput(DialogInput input, string value)
{
var combo = new ComboBox
{
ItemsSource = input.Options ?? [],
- Foreground = Brushes.White
+ Foreground = Brushes.White,
+ Background = new SolidColorBrush(InputBg),
+ BorderThickness = new Thickness(0),
+ Padding = new Thickness(1, 0)
};
- combo.SelectionBoxItemTemplate = null;
+
combo.SelectedItem = input.Options?.FirstOrDefault(option => option.Id.Equals(value, StringComparison.Ordinal))
?? input.Options?.FirstOrDefault();
+
return combo;
}
- private static Control BuildNumberInput(DialogInput input, string value)
+ private Control BuildNumberInput(DialogInput input, string value)
{
+ double numValue = double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var parsed)
+ ? parsed
+ : input.InitialNumber ?? input.Start;
+
+ double min = Math.Min(input.Start, input.End);
+ double max = Math.Max(input.Start, input.End);
+
+ var panel = new DockPanel { LastChildFill = true };
+
var slider = new Slider
{
- Minimum = Math.Min(input.Start, input.End),
- Maximum = Math.Max(input.Start, input.End),
- Value = double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var number)
- ? number
- : input.InitialNumber ?? input.Start,
+ Minimum = min,
+ Maximum = max,
+ Value = numValue,
TickFrequency = input.Step ?? 1,
- IsSnapToTickEnabled = input.Step is not null
+ IsSnapToTickEnabled = input.Step is not null,
+ Foreground = new SolidColorBrush(AccentColor)
};
- return slider;
+
+ var label = new TextBlock
+ {
+ Text = numValue.ToString(CultureInfo.InvariantCulture),
+ Foreground = Brushes.White,
+ VerticalAlignment = VerticalAlignment.Center,
+ Margin = new Thickness(2, 0, 0, 0),
+ MinWidth = 16
+ };
+
+ slider.PropertyChanged += (_, e) =>
+ {
+ if (e.Property == Slider.ValueProperty)
+ label.Text = ((float)slider.Value).ToString(CultureInfo.InvariantCulture);
+ };
+
+ DockPanel.SetDock(label, Dock.Right);
+ panel.Children.Add(slider);
+ panel.Children.Add(label);
+
+ return panel;
}
private void Click(int index)
@@ -306,6 +380,20 @@ internal sealed class DialogView : Border, IOverlayCloseHandler
return true;
}
+ private void FocusFirstInput()
+ {
+ var first = _inputControls.Values.FirstOrDefault();
+ if (first is TextBox tb)
+ {
+ tb.Focus();
+ tb.SelectAll();
+ }
+ else
+ {
+ first?.Focus();
+ }
+ }
+
private void CloseIfInactive()
{
var current = _handler.Dialogs.Current;
@@ -326,11 +414,22 @@ internal sealed class DialogView : Border, IOverlayCloseHandler
private void OnTunnelKeyDown(object? sender, KeyEventArgs e)
{
- if (e.Key != Key.Escape)
+ if (e.Key == Key.Escape)
+ {
+ TryCloseByUser();
+ e.Handled = true;
return;
+ }
- TryCloseByUser();
- e.Handled = true;
+ if (e.Key == Key.Enter)
+ {
+ var focused = TopLevel.GetTopLevel(this)?.FocusManager?.GetFocusedElement();
+ if (focused is TextBox && _instance.Definition.Actions.Count > 0)
+ {
+ Click(_instance.Definition.Actions[0].Index);
+ e.Handled = true;
+ }
+ }
}
private static string NumberToString(float value)
diff --git a/tools/run-dialog-test.sh b/tools/run-dialog-test.sh
index 12aad1b1..134fe31f 100755
--- a/tools/run-dialog-test.sh
+++ b/tools/run-dialog-test.sh
@@ -151,14 +151,14 @@ 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 render" "Dialog #1" 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 "confirmation render" "Dialog #1" 10
assert_log "yes button" "Yes (close)" 3
assert_log "no button" "No (close)" 3
@@ -166,7 +166,7 @@ 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 render" "Dialog #1" 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
@@ -175,7 +175,7 @@ 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 render" "Dialog #1" 10
assert_log "dialog_list sub 1" "Sub One (show dialog)" 3
assert_log "dialog_list sub 2" "Sub Two (show dialog)" 3
@@ -183,7 +183,7 @@ 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
+assert_log "server_links render" "Dialog #1" 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 "^$"