From 6eb5f35c75b4c30c76da69b44fe7559f6917f33a Mon Sep 17 00:00:00 2001 From: Tnze Date: Mon, 30 May 2022 11:25:56 +0800 Subject: [PATCH] A chat.Message can be deserialized from json array. --- chat/hoverevent.go | 25 ++++++++----------------- chat/message.go | 17 +++++++++++------ chat/message_test.go | 42 +++++++++++++++++++++++++++--------------- 3 files changed, 46 insertions(+), 38 deletions(-) diff --git a/chat/hoverevent.go b/chat/hoverevent.go index 87c7900..df7371d 100644 --- a/chat/hoverevent.go +++ b/chat/hoverevent.go @@ -1,9 +1,12 @@ package chat +import "encoding/json" + // HoverEvent defines an event that occurs when this component hovered over. type HoverEvent struct { - Action string `json:"action"` - Value []HoverSub `json:"value"` // The issue i found is the fact the json is different now, it wasnt parsing properly because Message was invalid, its a listed dict. + Action string `json:"action"` + Contents json.RawMessage `json:"contents"` // Didn't handled yet + Value Message `json:"value"` // Legacy } type HoverSub struct { @@ -12,7 +15,7 @@ type HoverSub struct { } // ShowText show the text to display. -func ShowText(text []HoverSub) *HoverEvent { +func ShowText(text Message) *HoverEvent { return &HoverEvent{ Action: "show_text", Value: text, @@ -23,29 +26,17 @@ func ShowText(text []HoverSub) *HoverEvent { // 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 { - T := Text(item) return &HoverEvent{ Action: "show_item", - Value: []HoverSub{ - { - Color: T.Color, - Text: T.Text, - }, - }, + 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 { - T := Text(entity) return &HoverEvent{ Action: "show_entity", - Value: []HoverSub{ - { - Color: T.Color, - Text: T.Color, - }, - }, + Value: Text(entity), } } diff --git a/chat/message.go b/chat/message.go index a2b15a6..fac3b6e 100644 --- a/chat/message.go +++ b/chat/message.go @@ -12,6 +12,7 @@ package chat import ( "encoding/json" + "errors" "fmt" "io" "regexp" @@ -106,12 +107,16 @@ func (m *Message) UnmarshalJSON(raw []byte) (err error) { } // 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(raw, (*jsonMsg)(m)) // Unmarshal as jsonMsg + switch raw[0] { + case '"': + return json.Unmarshal(raw, &m.Text) // Unmarshal as jsonString + case '{': + return json.Unmarshal(raw, (*jsonMsg)(m)) // Unmarshal as jsonMsg + case '[': + return json.Unmarshal(raw, &m.Extra) // Unmarshal as []Message + default: + return errors.New("unknown chat message type: '" + string(raw[0]) + "'") } - return } // ReadFrom decode Message in a ChatMsg packet @@ -299,7 +304,7 @@ func (m Message) String() string { return msg.String() } -var fmtPat = regexp.MustCompile("(?i)§[0-9A-FK-OR]") +var fmtPat = regexp.MustCompile(`(?i)§[\dA-FK-OR]`) // TransCtrlSeq will transform control sequences into ANSI code // or simply filter them. Depends on the second argument. diff --git a/chat/message_test.go b/chat/message_test.go index face916..a84b4f2 100644 --- a/chat/message_test.go +++ b/chat/message_test.go @@ -12,23 +12,11 @@ import ( pk "github.com/Tnze/go-mc/net/packet" ) -/* - "translation.test.none": "Hello, world!", - "translation.test.complex": "Prefix, %s %[2]s again %s and %[1]s lastly %s and also %[1]s again!" - "Prefix, str1str2 again str3 and str1 lastly str2 and also str1 again!" - "Prefix, str1str2 again str2 and str1 lastly str3 and also str1 again!" - "translation.test.escape": "%%s %%%s %%%%s %%%%%s", - "translation.test.invalid": "hi %", - "translation.test.invalid2": "hi % s", - "translation.test.args": "%s %s", - "translation.test.world": -*/ var jsons = []string{ `{"extra":[{"color":"green","text":"故我依然"},{"color":"white","text":"™ "},{"color":"gray","text":"Kun_QwQ"},{"color":"white","text":": 为什么想要用炼药锅灭火时总是跳不进去"}],"text":""}`, `{"translate":"chat.type.text","with":[{"insertion":"Xi_Xi_Mi","clickEvent":{"action":"suggest_command","value":"/tell Xi_Xi_Mi "},"hoverEvent":{"action":"show_entity","value":{"text":"{name:\"{\\\"text\\\":\\\"Xi_Xi_Mi\\\"}\",id:\"c1445a67-7551-4d7e-813d-65ef170ae51f\",type:\"minecraft:player\"}"}},"text":"Xi_Xi_Mi"},"好像是这个id。。"]}`, `{"translate":"translation.test.none"}`, - //`{"translate":"translation.test.complex","with":["str1","str2","str3"]}`, `{"translate":"translation.test.escape","with":["str1","str2"]}`, `{"translate":"translation.test.args","with":["str1","str2"]}`, `{"translate":"translation.test.world"}`, @@ -45,7 +33,6 @@ var texts = []string{ " 好像是这个id。。", "Hello, world!", - //"Prefix, str1str2 again str2 and str1 lastly str3 and also str1 again!", "%s %str1 %%s %%str2", "str1 str2", "world", @@ -62,7 +49,6 @@ var clearTexts = []string{ " 好像是这个id。。", "Hello, world!", - //"Prefix, str1str2 again str2 and str1 lastly str3 and also str1 again!", "%s %str1 %%s %%str2", "str1 str2", "world", @@ -92,7 +78,7 @@ func TestMessage_ClearString(t *testing.T) { chat.SetLanguage(en_us.Map) for i, v := range jsons { var cm chat.Message - err := cm.UnmarshalJSON([]byte(v)) + err := json.Unmarshal([]byte(v), &cm) if err != nil { t.Error(err) } @@ -161,6 +147,32 @@ func TestMessage_MarshalJSON_issue151(t *testing.T) { } } +func TestMessage_UnmarshalJSON_hoverEvent(t *testing.T) { + msg := `{ + "text": "Text0", + "extra": [ + { + "hoverEvent": {"action": "show_text","value": "la"}, + "text": "Text1" + }, + { + "hoverEvent": {"action": "show_text","value": {"text":"la","color":"red"}}, + "text": "Text2" + }, + { + "hoverEvent": {"action": "show_text","value": [{"color": "white","text": "Normal"}]}, + "text": "Text3" + } + ] + }` + var message chat.Message + err := json.Unmarshal([]byte(msg), &message) + if err != nil { + t.Fatal(err) + } + t.Log(message) +} + func ExampleTranslateMsg() { fmt.Println(chat.TranslateMsg("translation.test.none")) fmt.Println(chat.TranslateMsg(