From a70e0f20de405cafd8df617180694ec6d7b8a9a0 Mon Sep 17 00:00:00 2001 From: fumiama Date: Tue, 23 Nov 2021 16:21:06 +0800 Subject: [PATCH] perf: add 0 alloc func OpenWriterF --- binary/writer.go | 11 +++++++++- binary/writer_test.go | 48 +++++++++++++++++++++++++++++++++++++++++++ client/builders.go | 42 ++++++++++++++++++++++++------------- client/global.go | 9 +++++--- 4 files changed, 92 insertions(+), 18 deletions(-) diff --git a/binary/writer.go b/binary/writer.go index 1441d95f..de7d55f5 100644 --- a/binary/writer.go +++ b/binary/writer.go @@ -19,6 +19,14 @@ func NewWriterF(f func(writer *Writer)) []byte { return b } +// OpenWriterF must call func close +func OpenWriterF(f func(writer *Writer)) (b []byte, close func()) { + w := SelectWriter() + w.WriteByte(0) + f(w) + return w.Bytes(), func() { PutWriter(w) } +} + func (w *Writer) Write(b []byte) { (*bytes.Buffer)(w).Write(b) } @@ -73,9 +81,10 @@ func (w *Writer) EncryptAndWrite(key []byte, data []byte) { } func (w *Writer) WriteIntLvPacket(offset int, f func(writer *Writer)) { - data := NewWriterF(f) + data, close := OpenWriterF(f) w.WriteUInt32(uint32(len(data) + offset)) w.Write(data) + close() } func (w *Writer) WriteUniPacket(commandName string, sessionId, extraData, body []byte) { diff --git a/binary/writer_test.go b/binary/writer_test.go index 578095c2..6128e223 100644 --- a/binary/writer_test.go +++ b/binary/writer_test.go @@ -49,3 +49,51 @@ func BenchmarkNewWriterF128_5(b *testing.B) { } }) } + +func BenchmarkOpenWriterF128(b *testing.B) { + test := make([]byte, 128) + rand.Read(test) + b.StartTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, close := OpenWriterF(func(w *Writer) { + w.Write(test) + }) + close() + } + }) +} + +func BenchmarkOpenWriterF128_3(b *testing.B) { + test := make([]byte, 128) + rand.Read(test) + b.StartTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, close := OpenWriterF(func(w *Writer) { + w.Write(test) + w.Write(test) + w.Write(test) + }) + close() + } + }) +} + +func BenchmarkOpenWriterF128_5(b *testing.B) { + test := make([]byte, 128) + rand.Read(test) + b.StartTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, close := OpenWriterF(func(w *Writer) { + w.Write(test) + w.Write(test) + w.Write(test) + w.Write(test) + w.Write(test) + }) + close() + } + }) +} diff --git a/client/builders.go b/client/builders.go index a98df673..49e6ea90 100644 --- a/client/builders.go +++ b/client/builders.go @@ -169,10 +169,12 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by w.Write(tlv.T18(16, uint32(c.Uin))) w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress)) - w.Write(binary.NewWriterF(func(w *binary.Writer) { + wb, cl := binary.OpenWriterF(func(w *binary.Writer) { w.WriteUInt16(0x106) w.WriteBytesShort(t106) - })) + }) + w.Write(wb) + cl() // w.Write(tlv.T106(uint32(c.Uin), 0, c.version.AppId, c.version.SSOVersion, c.PasswordMd5, true, c.deviceInfo.Guid, c.deviceInfo.TgtgtKey, 0)) w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap)) w.Write(tlv.T100(c.version.SSOVersion, c.version.SubAppId, c.version.MainSigMap)) @@ -194,10 +196,12 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by w.Write(tlv.T145(c.deviceInfo.Guid)) w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign)) - w.Write(binary.NewWriterF(func(w *binary.Writer) { + wb, cl = binary.OpenWriterF(func(w *binary.Writer) { w.WriteUInt16(0x16A) w.WriteBytesShort(t16a) - })) + }) + w.Write(wb) + cl() w.Write(tlv.T154(seq)) w.Write(tlv.T141(c.deviceInfo.SimInfo, c.deviceInfo.APN)) w.Write(tlv.T8(2052)) @@ -219,10 +223,12 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by w.Write(tlv.T516()) w.Write(tlv.T521(8)) // w.Write(tlv.T525(tlv.T536([]byte{0x01, 0x00}))) - w.Write(binary.NewWriterF(func(w *binary.Writer) { + wb, cl = binary.OpenWriterF(func(w *binary.Writer) { w.WriteUInt16(0x318) w.WriteBytesShort(t318) - })) + }) + w.Write(wb) + cl() }) sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, []byte{}, c.OutGoingPacketSessionId, req, c.ksid) packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, []byte{}) @@ -306,10 +312,12 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) { w.Write(tlv.T18(16, uint32(c.Uin))) w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress)) - w.Write(binary.NewWriterF(func(w *binary.Writer) { + wb, cl := binary.OpenWriterF(func(w *binary.Writer) { w.WriteUInt16(0x106) w.WriteBytesShort(c.sigInfo.encryptedA1) - })) + }) + w.Write(wb) + cl() w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap)) w.Write(tlv.T100(c.version.SSOVersion, 2, c.version.MainSigMap)) w.Write(tlv.T107(0)) @@ -989,13 +997,15 @@ func (c *QQClient) buildGroupKickPacket(groupCode, memberUin int64, kickMsg stri // OidbSvc.0x570_8 func (c *QQClient) buildGroupMutePacket(groupCode, memberUin int64, time uint32) (uint16, []byte) { seq := c.nextSeq() - payload := c.packOIDBPackage(1392, 8, binary.NewWriterF(func(w *binary.Writer) { + b, cl := binary.OpenWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(groupCode)) w.WriteByte(32) w.WriteUInt16(1) w.WriteUInt32(uint32(memberUin)) w.WriteUInt32(time) - })) + }) + payload := c.packOIDBPackage(1392, 8, b) + cl() packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0x570_8", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload) return seq, packet } @@ -1029,7 +1039,7 @@ func (c *QQClient) buildFriendPokePacket(target int64) (uint16, []byte) { // OidbSvc.0x55c_1 func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool) (uint16, []byte) { seq := c.nextSeq() - payload := c.packOIDBPackage(1372, 1, binary.NewWriterF(func(w *binary.Writer) { + b, cl := binary.OpenWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(groupCode)) w.WriteUInt32(uint32(member)) w.WriteByte(func() byte { @@ -1038,7 +1048,9 @@ func (c *QQClient) buildGroupAdminSetPacket(groupCode, member int64, flag bool) } return 0 }()) - })) + }) + payload := c.packOIDBPackage(1372, 1, b) + cl() packet := packets.BuildUniPacket(c.Uin, seq, "OidbSvc.0x55c_1", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload) return seq, packet } @@ -1049,10 +1061,12 @@ func (c *QQClient) buildQuitGroupPacket(groupCode int64) (uint16, []byte) { jw := jce.NewJceWriter() jw.WriteInt32(2, 0) jw.WriteInt64(c.Uin, 1) - jw.WriteBytes(binary.NewWriterF(func(w *binary.Writer) { + b, cl := binary.OpenWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(c.Uin)) w.WriteUInt32(uint32(groupCode)) - }), 2) + }) + jw.WriteBytes(b, 2) + cl() buf := &jce.RequestDataVersion3{Map: map[string][]byte{"GroupMngReq": packUniRequestData(jw.Bytes())}} pkt := &jce.RequestPacket{ IVersion: 3, diff --git a/client/global.go b/client/global.go index 56d24df8..a239f61f 100644 --- a/client/global.go +++ b/client/global.go @@ -459,12 +459,15 @@ func getSSOAddress() ([]*net.TCPAddr, error) { SFuncName: "HttpServerListReq", SBuffer: buf.ToBytes(), } - tea := binary.NewTeaCipher(key) - rsp, err := utils.HttpPostBytes("https://configsvr.msf.3g.qq.com/configsvr/serverlist.jsp", tea.Encrypt(binary.NewWriterF(func(w *binary.Writer) { + b, cl := binary.OpenWriterF(func(w *binary.Writer) { w.WriteIntLvPacket(0, func(w *binary.Writer) { w.Write(pkt.ToBytes()) }) - }))) + }) + tea := binary.NewTeaCipher(key) + encpkt := tea.Encrypt(b) + cl() + rsp, err := utils.HttpPostBytes("https://configsvr.msf.3g.qq.com/configsvr/serverlist.jsp", encpkt) if err != nil { return nil, errors.Wrap(err, "unable to fetch server list") }