1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

export gzip writer & inline UniPacket

This commit is contained in:
wdvxdr 2021-04-16 16:15:14 +08:00
parent 5b44879005
commit f2de387430
No known key found for this signature in database
GPG Key ID: 55FF1414A69CEBA6
6 changed files with 68 additions and 45 deletions

View File

@ -32,30 +32,25 @@ func PutBuffer(w *Writer) {
} }
} }
type gzipWriter struct {
w *gzip.Writer
buf *bytes.Buffer
}
var gzipPool = sync.Pool{ var gzipPool = sync.Pool{
New: func() interface{} { New: func() interface{} {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
w := gzip.NewWriter(buf) w := gzip.NewWriter(buf)
return &gzipWriter{ return &GzipWriter{
w: w, w: w,
buf: buf, buf: buf,
} }
}, },
} }
func acquireGzipWriter() *gzipWriter { func AcquireGzipWriter() *GzipWriter {
ret := gzipPool.Get().(*gzipWriter) ret := gzipPool.Get().(*GzipWriter)
ret.buf.Reset() ret.buf.Reset()
ret.w.Reset(ret.buf) ret.w.Reset(ret.buf)
return ret return ret
} }
func releaseGzipWriter(w *gzipWriter) { func ReleaseGzipWriter(w *GzipWriter) {
// See https://golang.org/issue/23199 // See https://golang.org/issue/23199
const maxSize = 1 << 16 const maxSize = 1 << 16
if w.buf.Cap() < maxSize { if w.buf.Cap() < maxSize {

View File

@ -117,10 +117,8 @@ func (r *Reader) Len() int {
} }
func (tlv TlvMap) Exists(key uint16) bool { func (tlv TlvMap) Exists(key uint16) bool {
if _, ok := tlv[key]; ok { _, ok := tlv[key]
return true return ok
}
return false
} }
// --- Network reader --- // --- Network reader ---
@ -144,13 +142,13 @@ func (r *NetworkReader) ReadByte() (byte, error) {
func (r *NetworkReader) ReadBytes(len int) ([]byte, error) { func (r *NetworkReader) ReadBytes(len int) ([]byte, error) {
buf := make([]byte, len) buf := make([]byte, len)
_, err := io.ReadFull(r.conn, buf) _, err := io.ReadFull(r.conn, buf)
//for i := 0; i < len; i++ { // for i := 0; i < len; i++ {
// b, err := r.ReadByte() // b, err := r.ReadByte()
// if err != nil { // if err != nil {
// return nil, err // return nil, err
// } // }
// buf[i] = b // buf[i] = b
//} // }
return buf, err return buf, err
} }

View File

@ -12,6 +12,23 @@ import (
"github.com/Mrs4s/MiraiGo/utils" "github.com/Mrs4s/MiraiGo/utils"
) )
type GzipWriter struct {
w *gzip.Writer
buf *bytes.Buffer
}
func (w *GzipWriter) Write(p []byte) (int, error) {
return w.w.Write(p)
}
func (w *GzipWriter) Close() error {
return w.w.Close()
}
func (w *GzipWriter) Bytes() []byte {
return w.buf.Bytes()
}
func ZlibUncompress(src []byte) []byte { func ZlibUncompress(src []byte) []byte {
b := bytes.NewReader(src) b := bytes.NewReader(src)
var out bytes.Buffer var out bytes.Buffer
@ -31,11 +48,11 @@ func ZlibCompress(data []byte) []byte {
} }
func GZipCompress(data []byte) []byte { func GZipCompress(data []byte) []byte {
gw := acquireGzipWriter() gw := AcquireGzipWriter()
_, _ = gw.w.Write(data) _, _ = gw.Write(data)
_ = gw.w.Close() _ = gw.Close()
ret := append([]byte(nil), gw.buf.Bytes()...) ret := append([]byte(nil), gw.buf.Bytes()...)
releaseGzipWriter(gw) ReleaseGzipWriter(gw)
return ret return ret
} }

View File

@ -79,20 +79,24 @@ func (w *Writer) WriteIntLvPacket(offset int, f func(writer *Writer)) {
} }
func (w *Writer) WriteUniPacket(commandName string, sessionId, extraData, body []byte) { func (w *Writer) WriteUniPacket(commandName string, sessionId, extraData, body []byte) {
w.WriteIntLvPacket(4, func(w *Writer) { w1 := NewWriter()
w.WriteString(commandName) { // WriteIntLvPacket
w.WriteUInt32(8) w1.WriteString(commandName)
w.Write(sessionId) w1.WriteUInt32(8)
w1.Write(sessionId)
if len(extraData) == 0 { if len(extraData) == 0 {
w.WriteUInt32(0x04) w1.WriteUInt32(0x04)
} else { } else {
w.WriteUInt32(uint32(len(extraData) + 4)) w1.WriteUInt32(uint32(len(extraData) + 4))
w.Write(extraData) w1.Write(extraData)
} }
}) }
w.WriteIntLvPacket(4, func(w *Writer) { data := w1.Bytes()
w.Write(body) w.WriteUInt32(uint32(len(data) + 4))
}) w.Write(data)
PutBuffer(w1)
w.WriteUInt32(uint32(len(body) + 4)) // WriteIntLvPacket
w.Write(body)
} }
func (w *Writer) WriteBytesShort(data []byte) { func (w *Writer) WriteBytesShort(data []byte) {

View File

@ -27,15 +27,23 @@ func BuildLoginPacket(uin int64, bodyType byte, key, body, extraData []byte) []b
func BuildUniPacket(uin int64, seq uint16, commandName string, encryptType byte, sessionID, extraData, key, body []byte) []byte { func BuildUniPacket(uin int64, seq uint16, commandName string, encryptType byte, sessionID, extraData, key, body []byte) []byte {
return binary.NewWriterF(func(w *binary.Writer) { return binary.NewWriterF(func(w *binary.Writer) {
w.WriteIntLvPacket(4, func(w *binary.Writer) { w2 := binary.NewWriter()
w.WriteUInt32(0x0B) { // w.WriteIntLvPacket
w.WriteByte(encryptType) w2.WriteUInt32(0x0B)
w.WriteUInt32(uint32(seq)) w2.WriteByte(encryptType)
w.WriteByte(0) w2.WriteUInt32(uint32(seq))
w.WriteString(strconv.FormatInt(uin, 10)) w2.WriteByte(0)
w.EncryptAndWrite(key, binary.NewWriterF(func(w *binary.Writer) { w2.WriteString(strconv.FormatInt(uin, 10))
w.WriteUniPacket(commandName, sessionID, extraData, body)
})) // inline NewWriterF
}) w3 := binary.NewWriter()
w3.WriteUniPacket(commandName, sessionID, extraData, body)
w2.EncryptAndWrite(key, w3.Bytes())
binary.PutBuffer(w3)
}
data := w2.Bytes()
w.WriteUInt32(uint32(len(data) + 4))
w.Write(data)
binary.PutBuffer(w2)
}) })
} }

View File

@ -3,9 +3,10 @@ package packets
import ( import (
"strconv" "strconv"
"github.com/pkg/errors"
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/protocol/crypto" "github.com/Mrs4s/MiraiGo/protocol/crypto"
"github.com/pkg/errors"
) )
var ( var (