From 19481ab95ecd6956880a0ea61f7c8a8d9de8ad6f Mon Sep 17 00:00:00 2001 From: Tnze Date: Fri, 17 Dec 2021 01:05:32 +0800 Subject: [PATCH] ClickEvent and HoverEvent support of /chat package --- chat/chatMsg.go | 50 +++++++++++++++++++++++-------------- chat/clickevent.go | 61 ++++++++++++++++++++++++++++++++++++++++++++++ chat/hoverevent.go | 34 ++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 chat/clickevent.go create mode 100644 chat/hoverevent.go diff --git a/chat/chatMsg.go b/chat/chatMsg.go index 6956c68..22a83f3 100644 --- a/chat/chatMsg.go +++ b/chat/chatMsg.go @@ -1,11 +1,13 @@ // Package chat implements Minecraft's chat message encoding system. // -// The type Message is the Minecraft chat message. Can be encode as JSON +// The type Message is the Minecraft chat message. Can be encoded as JSON // or net/packet.Field . // // It's very recommended that use SetLanguage before using Message.String or Message.ClearString, // or the `github.com/Tnze/go-mc/data/en-us` will be used. // Note: The package of data/lang/... will SetLanguage on theirs init() so you don't need to call by your self. +// +// Some of these docs is copied from https://wiki.vg/Chat. package chat import ( @@ -20,32 +22,44 @@ import ( ) // Message is a message sent by other -type Message jsonChat - -type jsonChat struct { +type Message struct { Text string `json:"text,omitempty"` - Bold bool `json:"bold,omitempty"` //粗体 - Italic bool `json:"italic,omitempty"` //斜体 - UnderLined bool `json:"underlined,omitempty"` //下划线 - StrikeThrough bool `json:"strikethrough,omitempty"` //删除线 - Obfuscated bool `json:"obfuscated,omitempty"` //随机 - Color string `json:"color,omitempty"` + Bold bool `json:"bold,omitempty"` //粗体 + Italic bool `json:"italic,omitempty"` //斜体 + UnderLined bool `json:"underlined,omitempty"` //下划线 + StrikeThrough bool `json:"strikethrough,omitempty"` //删除线 + Obfuscated bool `json:"obfuscated,omitempty"` //随机 + // Font of the message, could be one of minecraft:uniform, minecraft:alt or minecraft:default + // This option is only valid on 1.16+, otherwise the property is ignored. + Font string `json:"font,omitempty"` //字体 + Color string `json:"color,omitempty"` //颜色 + + // Insertion contains text to insert. Only used for messages in chat. + // When shift is held, clicking the component inserts the given text + // into the chat box at the cursor (potentially replacing selected text). + Insertion string `json:"insertion,omitempty"` + ClickEvent *ClickEvent `json:"clickEvent,omitempty"` + HoverEvent *HoverEvent `json:"hoverEvent,omitempty"` Translate string `json:"translate,omitempty"` - With []json.RawMessage `json:"with,omitempty"` // How can go handle an JSON array with Object and String? + With []json.RawMessage `json:"with,omitempty"` Extra []Message `json:"extra,omitempty"` } +type jsonMsg Message + //UnmarshalJSON decode json to Message -func (m *Message) UnmarshalJSON(jsonMsg []byte) (err error) { - if len(jsonMsg) == 0 { +func (m *Message) UnmarshalJSON(raw []byte) (err error) { + if len(raw) == 0 { return io.EOF } - if jsonMsg[0] == '"' { - err = json.Unmarshal(jsonMsg, &m.Text) //Unmarshal as jsonString + // The right way to distinguish JSON String and Object + // is to look up the first character. + if raw[0] == '"' { + err = json.Unmarshal(raw, &m.Text) // Unmarshal as jsonString } else { - err = json.Unmarshal(jsonMsg, (*jsonChat)(m)) //Unmarshal as jsonChat + err = json.Unmarshal(raw, (*jsonMsg)(m)) // Unmarshal as jsonMsg } return } @@ -142,7 +156,7 @@ var colors = map[string]string{ } // translateMap is the translation table. -// By default it's en-us. +// By default, it's en-us. var translateMap = en_us.Map // SetLanguage set the translate map to this map. @@ -182,7 +196,7 @@ func (m Message) ClearString() string { // String return the message string with escape sequence for ansi color. // To convert Translated Message to string, you must set -// On windows, you may want print this string using github.com/matte/go-colorable. +// On Windows, you may want print this string using github.com/matte/go-colorable. func (m Message) String() string { var msg, format strings.Builder if m.Bold { diff --git a/chat/clickevent.go b/chat/clickevent.go new file mode 100644 index 0000000..b0246c5 --- /dev/null +++ b/chat/clickevent.go @@ -0,0 +1,61 @@ +package chat + +import "strconv" + +// ClickEvent defines an event that occurs when this component is clicked. +type ClickEvent struct { + Action string `json:"action"` + Value string `json:"value"` +} + +// OpenURL create a ClickEvent opens the given URL in the default web browser. +// Ignored if the player has opted to disable links in chat; +// may open a GUI prompting the user if the setting for that is enabled. +// The link's protocol must be set and must be http or https, for security reasons. +func OpenURL(url string) *ClickEvent { + return &ClickEvent{ + Action: "open_url", + Value: url, + } +} + +// RunCommand create a ClickEvent runs the given command. Not required to be a command - +// clicking this only causes the client to send the given content as a chat message, +// so if not prefixed with /, they will say the given text instead. +// If used in a book GUI, the GUI is closed after clicking. +func RunCommand(cmd string) *ClickEvent { + return &ClickEvent{ + Action: "run_command", + Value: cmd, + } +} + +// SuggestCommand create a ClickEvent replaces the content of the chat box with the given text - +// usually a command, but it is not required to be a command +// (commands should be prefixed with /). +// This is only usable for messages in chat. +func SuggestCommand(cmd string) *ClickEvent { + return &ClickEvent{ + Action: "suggest_command", + Value: cmd, + } +} + +// ChangePage create a ClickEvent usable within written books. +// Changes the page of the book to the given page, starting at 1. +// For instance, "value":1 switches the book to the first page. +// If the page is less than one or beyond the number of pages in the book, the event is ignored. +func ChangePage(page int) *ClickEvent { + return &ClickEvent{ + Action: "change_page", + Value: strconv.Itoa(page), + } +} + +// CopyToClipboard create a ClickEvent copies the given text to the client's clipboard when clicked. +func CopyToClipboard(text string) *ClickEvent { + return &ClickEvent{ + Action: "copy_to_clipboard", + Value: text, + } +} diff --git a/chat/hoverevent.go b/chat/hoverevent.go new file mode 100644 index 0000000..698fa48 --- /dev/null +++ b/chat/hoverevent.go @@ -0,0 +1,34 @@ +package chat + +// HoverEvent defines an event that occurs when this component hovered over. +type HoverEvent struct { + Action string `json:"action"` + Value Message `json:"value"` +} + +// ShowText show the text to display. +func ShowText(text Message) *HoverEvent { + return &HoverEvent{ + Action: "show_text", + Value: text, + } +} + +// ShowItem show the item to display. +// Item is encoded as the S-NBT format, nbt.StringifiedMessage could help. +// See: https://wiki.vg/Chat#:~:text=show_item,in%20red%20instead. +func ShowItem(item string) *HoverEvent { + return &HoverEvent{ + Action: "show_item", + Value: Text(item), + } +} + +// ShowEntity show an entity describing by the S-NBT, nbt.StringifiedMessage could help. +// See: https://wiki.vg/Chat#:~:text=show_entity,given%20entity%20loaded. +func ShowEntity(entity string) *HoverEvent { + return &HoverEvent{ + Action: "show_entity", + Value: Text(entity), + } +}