1.19.2 chat support
This commit is contained in:
@ -1,5 +1,11 @@
|
||||
package chat
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
)
|
||||
|
||||
type Decoration struct {
|
||||
TranslationKey string `nbt:"translation_key"`
|
||||
Parameters []string `nbt:"parameters"`
|
||||
@ -49,3 +55,46 @@ func (t *Type) Decorate(content Message, d *Decoration) (msg Message) {
|
||||
Insertion: d.Style.Insertion,
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Type) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasTargetName pk.Boolean
|
||||
n1, err := (*pk.VarInt)(&t.ID).ReadFrom(r)
|
||||
if err != nil {
|
||||
return n1, err
|
||||
}
|
||||
n2, err := t.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 {
|
||||
t.TargetName = new(Message)
|
||||
n4, err := t.TargetName.ReadFrom(r)
|
||||
return n1 + n2 + n3 + n4, err
|
||||
}
|
||||
return n1 + n2 + n3, nil
|
||||
}
|
||||
|
||||
func (t *Type) WriteTo(w io.Writer) (n int64, err error) {
|
||||
hasTargetName := pk.Boolean(t.TargetName != nil)
|
||||
n1, err := (*pk.VarInt)(&t.ID).WriteTo(w)
|
||||
if err != nil {
|
||||
return n1, err
|
||||
}
|
||||
n2, err := t.SenderName.WriteTo(w)
|
||||
if err != nil {
|
||||
return n1 + n2, err
|
||||
}
|
||||
n3, err := hasTargetName.WriteTo(w)
|
||||
if err != nil {
|
||||
return n1 + n2 + n3, err
|
||||
}
|
||||
if hasTargetName {
|
||||
n4, err := t.TargetName.WriteTo(w)
|
||||
return n1 + n2 + n3 + n4, err
|
||||
}
|
||||
return n1 + n2 + n3, nil
|
||||
}
|
||||
|
@ -132,13 +132,13 @@ func (m *Message) UnmarshalJSON(raw []byte) (err error) {
|
||||
|
||||
// ReadFrom decode Message in a ChatMsg packet
|
||||
func (m *Message) ReadFrom(r io.Reader) (int64, error) {
|
||||
var Len pk.VarInt
|
||||
if n, err := Len.ReadFrom(r); err != nil {
|
||||
var code pk.String
|
||||
n, err := code.ReadFrom(r)
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
lr := &io.LimitedReader{R: r, N: int64(Len)}
|
||||
err := json.NewDecoder(lr).Decode(m)
|
||||
return int64(Len) - lr.N, err
|
||||
err = json.Unmarshal([]byte(code), m)
|
||||
return n, err
|
||||
}
|
||||
|
||||
// WriteTo encode Message into a ChatMsg packet
|
||||
|
216
chat/sign/sign.go
Normal file
216
chat/sign/sign.go
Normal file
@ -0,0 +1,216 @@
|
||||
package sign
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/Tnze/go-mc/chat"
|
||||
pk "github.com/Tnze/go-mc/net/packet"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
type MessageHeader struct {
|
||||
Signature []byte
|
||||
Sender uuid.UUID
|
||||
}
|
||||
|
||||
func (m *MessageHeader) WriteTo(w io.Writer) (n int64, err error) {
|
||||
hasSignature := pk.Boolean(len(m.Signature) > 0)
|
||||
n, err = hasSignature.WriteTo(w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if hasSignature {
|
||||
n2, err := pk.ByteArray(m.Signature).WriteTo(w)
|
||||
n += n2
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
n3, err := pk.UUID(m.Sender).WriteTo(w)
|
||||
return n + n3, err
|
||||
}
|
||||
|
||||
func (m *MessageHeader) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasSignature pk.Boolean
|
||||
n, err = hasSignature.ReadFrom(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if hasSignature {
|
||||
n2, err := (*pk.ByteArray)(&m.Signature).ReadFrom(r)
|
||||
n += n2
|
||||
if err != nil {
|
||||
return n, err
|
||||
}
|
||||
}
|
||||
n3, err := (*pk.UUID)(&m.Sender).ReadFrom(r)
|
||||
return n + n3, err
|
||||
}
|
||||
|
||||
type MessageBody struct {
|
||||
PlainMessage string
|
||||
Message *chat.Message
|
||||
Timestamp time.Time
|
||||
Salt int64
|
||||
History []HistoryMessage
|
||||
}
|
||||
|
||||
func (m *MessageBody) WriteTo(w io.Writer) (n int64, err error) {
|
||||
return pk.Tuple{
|
||||
pk.String(m.PlainMessage),
|
||||
pk.Boolean(m.Message != nil),
|
||||
pk.Opt{
|
||||
Has: m.Message != nil,
|
||||
Field: m.Message,
|
||||
},
|
||||
pk.Long(m.Timestamp.UnixMilli()),
|
||||
pk.Long(m.Salt),
|
||||
pk.Array(&m.History),
|
||||
}.WriteTo(w)
|
||||
}
|
||||
|
||||
func (m *MessageBody) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasContent pk.Boolean
|
||||
var timestamp pk.Long
|
||||
n, err = pk.Tuple{
|
||||
(*pk.String)(&m.PlainMessage),
|
||||
&hasContent,
|
||||
pk.Opt{
|
||||
Has: &hasContent,
|
||||
Field: func() pk.FieldDecoder {
|
||||
m.Message = new(chat.Message)
|
||||
return m.Message
|
||||
},
|
||||
},
|
||||
×tamp,
|
||||
(*pk.Long)(&m.Salt),
|
||||
pk.Array(&m.History),
|
||||
}.ReadFrom(r)
|
||||
m.Timestamp = time.UnixMilli(int64(timestamp))
|
||||
return
|
||||
}
|
||||
|
||||
type FilterMask struct {
|
||||
Type byte
|
||||
Mask pk.BitSet
|
||||
}
|
||||
|
||||
func (f *FilterMask) WriteTo(w io.Writer) (n int64, err error) {
|
||||
n, err = pk.VarInt(f.Type).WriteTo(w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if f.Type == 2 {
|
||||
var n1 int64
|
||||
n1, err = f.Mask.WriteTo(w)
|
||||
n += n1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (f *FilterMask) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var Type pk.VarInt
|
||||
if n, err = Type.ReadFrom(r); err != nil {
|
||||
return
|
||||
}
|
||||
f.Type = byte(Type)
|
||||
if f.Type == 2 {
|
||||
var n1 int64
|
||||
n1, err = f.Mask.ReadFrom(r)
|
||||
n += n1
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type PlayerMessage struct {
|
||||
MessageHeader
|
||||
MessageSignature []byte
|
||||
MessageBody
|
||||
UnsignedContent *chat.Message
|
||||
FilterMask
|
||||
}
|
||||
|
||||
func (msg *PlayerMessage) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
var hasUnsignedContent pk.Boolean
|
||||
return pk.Tuple{
|
||||
&msg.MessageHeader,
|
||||
(*pk.ByteArray)(&msg.MessageSignature),
|
||||
&msg.MessageBody,
|
||||
&hasUnsignedContent,
|
||||
pk.Opt{
|
||||
Has: &hasUnsignedContent,
|
||||
Field: func() pk.FieldDecoder {
|
||||
msg.UnsignedContent = new(chat.Message)
|
||||
return msg.UnsignedContent
|
||||
},
|
||||
},
|
||||
&msg.FilterMask,
|
||||
}.ReadFrom(r)
|
||||
}
|
||||
|
||||
func (msg *PlayerMessage) WriteTo(w io.Writer) (n int64, err error) {
|
||||
return pk.Tuple{
|
||||
&msg.MessageHeader,
|
||||
pk.ByteArray(msg.MessageSignature),
|
||||
&msg.MessageBody,
|
||||
pk.Boolean(msg.UnsignedContent != nil),
|
||||
pk.Opt{
|
||||
Has: msg.UnsignedContent != nil,
|
||||
Field: msg.UnsignedContent,
|
||||
},
|
||||
&msg.FilterMask,
|
||||
}.WriteTo(w)
|
||||
}
|
||||
|
||||
func genSalt() (salt int64) {
|
||||
err := binary.Read(rand.Reader, binary.BigEndian, &salt)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func Unsigned(id uuid.UUID, plain string, content *chat.Message) (msg PlayerMessage) {
|
||||
return PlayerMessage{
|
||||
MessageHeader: MessageHeader{
|
||||
Signature: nil,
|
||||
Sender: id,
|
||||
},
|
||||
MessageSignature: []byte{},
|
||||
MessageBody: MessageBody{
|
||||
PlainMessage: plain,
|
||||
Message: nil,
|
||||
Timestamp: time.Now(),
|
||||
Salt: genSalt(),
|
||||
History: nil,
|
||||
},
|
||||
UnsignedContent: nil,
|
||||
FilterMask: FilterMask{Type: 0},
|
||||
}
|
||||
}
|
||||
|
||||
type HistoryMessage struct {
|
||||
Sender uuid.UUID
|
||||
Signature []byte
|
||||
}
|
||||
|
||||
func (p *HistoryMessage) ReadFrom(r io.Reader) (n int64, err error) {
|
||||
n, err = (*pk.UUID)(&p.Sender).ReadFrom(r)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n2, err := (*pk.ByteArray)(&p.Signature).ReadFrom(r)
|
||||
return n + n2, err
|
||||
}
|
||||
|
||||
func (p *HistoryMessage) WriteTo(w io.Writer) (n int64, err error) {
|
||||
n, err = pk.UUID(p.Sender).WriteTo(w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n2, err := pk.ByteArray(p.Signature).WriteTo(w)
|
||||
return n + n2, err
|
||||
}
|
Reference in New Issue
Block a user