1.19.2 chat support

This commit is contained in:
Tnze
2022-11-30 18:50:10 +08:00
parent 0b7ef620d9
commit 55d79f791a
13 changed files with 431 additions and 244 deletions

View File

@ -1,16 +1,16 @@
package msg
import (
"encoding/hex"
"fmt"
"io"
"time"
"github.com/Tnze/go-mc/chat/sign"
"github.com/Tnze/go-mc/bot"
"github.com/Tnze/go-mc/bot/basic"
"github.com/Tnze/go-mc/chat"
"github.com/Tnze/go-mc/data/packetid"
pk "github.com/Tnze/go-mc/net/packet"
"github.com/google/uuid"
)
type Manager struct {
@ -24,149 +24,40 @@ func New(c *bot.Client, p *basic.Player, events EventsHandler) *Manager {
}
func attachPlayerMsg(c *bot.Client, p *basic.Player, handler func(msg chat.Message) error) {
c.Events.AddListener(bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundPlayerChat,
F: func(packet pk.Packet) error {
var message PlayerMessage
if err := packet.Scan(&message); err != nil {
return err
}
var content chat.Message
if message.content.formatted != nil {
content = *message.content.formatted
} else {
content = chat.Text(message.content.plainMsg)
}
ct := p.WorldInfo.RegistryCodec.ChatType.FindByID(message.chatType.ID)
if ct == nil {
return fmt.Errorf("chat type %d not found", message.chatType.ID)
}
msg := (*chat.Type)(&message.chatType).Decorate(content, &ct.Chat)
return handler(msg)
c.Events.AddListener(
bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundPlayerChatHeader,
F: func(packet pk.Packet) error {
fmt.Println(packetid.ClientboundPacketID(packet.ID))
fmt.Println(hex.Dump(packet.Data))
return nil
},
},
})
}
bot.PacketHandler{
Priority: 64, ID: packetid.ClientboundPlayerChat,
F: func(packet pk.Packet) error {
var message sign.PlayerMessage
var chatType chat.Type
fmt.Println(packetid.ClientboundPacketID(packet.ID))
fmt.Println(hex.Dump(packet.Data))
if err := packet.Scan(&message, &chatType); err != nil {
return err
}
type PlayerMessage struct {
// SignedMessageHeader
signature []byte
sender uuid.UUID
// MessageSignature
msgSignature []byte
// SignedMessageBody
content msgContent
timestamp time.Time
salt int64
prevMessages []prevMsg
// Optional<Component>
unsignedContent *chat.Message
// FilterMask
filterType int32
filterSet pk.BitSet
// ChatType
chatType chatType
}
var content chat.Message
if message.MessageBody.Message != nil {
content = *message.MessageBody.Message
} else {
content = chat.Text(message.MessageBody.PlainMessage)
}
func (p *PlayerMessage) String() string {
return p.content.plainMsg
}
ct := p.WorldInfo.RegistryCodec.ChatType.FindByID(chatType.ID)
if ct == nil {
return fmt.Errorf("chat type %d not found", chatType.ID)
}
func (p *PlayerMessage) ReadFrom(r io.Reader) (n int64, err error) {
var hasMsgSign, hasUnsignedContent pk.Boolean
var timestamp pk.Long
var unsignedContent chat.Message
n, err = pk.Tuple{
&hasMsgSign,
pk.Opt{
Has: &hasMsgSign,
Field: (*pk.ByteArray)(&p.signature),
},
(*pk.UUID)(&p.sender),
(*pk.ByteArray)(&p.msgSignature),
&p.content,
&timestamp,
(*pk.Long)(&p.salt),
pk.Array(&p.prevMessages),
&hasUnsignedContent,
pk.Opt{
Has: &hasUnsignedContent,
Field: &unsignedContent,
},
(*pk.VarInt)(&p.filterType),
pk.Opt{
Has: func() bool { return p.filterType == 2 },
Field: &p.filterSet,
},
&p.chatType,
}.ReadFrom(r)
if err != nil {
return
}
p.timestamp = time.UnixMilli(int64(timestamp))
if hasUnsignedContent {
p.unsignedContent = &unsignedContent
}
return n, err
}
type msgContent struct {
plainMsg string
formatted *chat.Message
}
func (m *msgContent) ReadFrom(r io.Reader) (n int64, err error) {
var hasFormatted pk.Boolean
n1, err := (*pk.String)(&m.plainMsg).ReadFrom(r)
if err != nil {
return n1, err
}
n2, err := hasFormatted.ReadFrom(r)
if err != nil {
return n1 + n2, err
}
if hasFormatted {
m.formatted = new(chat.Message)
n3, err := m.formatted.ReadFrom(r)
return n1 + n2 + n3, err
}
return n1 + n2, err
}
type prevMsg struct {
sender uuid.UUID
signature []byte
}
func (p *prevMsg) ReadFrom(r io.Reader) (n int64, err error) {
return pk.Tuple{
(*pk.UUID)(&p.sender),
(*pk.ByteArray)(&p.signature),
}.ReadFrom(r)
}
type chatType chat.Type
func (c *chatType) ReadFrom(r io.Reader) (n int64, err error) {
var hasTargetName pk.Boolean
n1, err := (*pk.VarInt)(&c.ID).ReadFrom(r)
if err != nil {
return n1, err
}
n2, err := c.SenderName.ReadFrom(r)
if err != nil {
return n1 + n2, err
}
n3, err := hasTargetName.ReadFrom(r)
if err != nil {
return n1 + n2 + n3, err
}
if hasTargetName {
c.TargetName = new(chat.Message)
n4, err := c.TargetName.ReadFrom(r)
return n1 + n2 + n3 + n4, err
}
return n1 + n2 + n3, nil
msg := chatType.Decorate(content, &ct.Chat)
return handler(msg)
},
})
}