From fd9a6657fa47729897ee4301c9b86b56e505ff16 Mon Sep 17 00:00:00 2001 From: wdvxdr Date: Wed, 25 Aug 2021 16:16:08 +0800 Subject: [PATCH] drop dep jsoniter&reflect2. for smaller binary size. --- binary/jce/writer.go | 46 +++++++++++++++++++-------------------- binary/jce/writer_test.go | 45 +++++++++++++++++++++++++++++++++++++- client/client.go | 3 --- client/global.go | 1 + client/group_info.go | 1 + client/group_msg.go | 1 + client/http_api.go | 7 +++--- client/model_show.go | 21 +++++++++--------- client/notify.go | 1 + go.mod | 3 +-- go.sum | 17 ++++++--------- message/message.go | 4 +--- protocol/crypto/crypto.go | 4 ++-- 13 files changed, 95 insertions(+), 59 deletions(-) diff --git a/binary/jce/writer.go b/binary/jce/writer.go index 702f1eb1..f78038b9 100644 --- a/binary/jce/writer.go +++ b/binary/jce/writer.go @@ -6,9 +6,6 @@ import ( "reflect" "strconv" "sync" - "unsafe" - - "github.com/modern-go/reflect2" ) type JceWriter struct { @@ -204,29 +201,31 @@ func (w *JceWriter) WriteObject(i interface{}, tag int) { } } -type decoder []struct { - ty reflect2.Type - offset uintptr - id int +type decoder struct { + index int + id int } var decoderCache = sync.Map{} // WriteJceStructRaw 写入 Jce 结构体 -func (w *JceWriter) WriteJceStructRaw(s IJceStruct) { - var ( - ty2 = reflect2.TypeOf(s) - jceDec decoder - ) - dec, ok := decoderCache.Load(ty2) +func (w *JceWriter) WriteJceStructRaw(s interface{}) { + t := reflect.TypeOf(s) + reflect.ValueOf(s).Interface() + if t.Kind() != reflect.Ptr { + return + } + t = t.Elem() + v := reflect.ValueOf(s).Elem() + var jceDec []decoder + dec, ok := decoderCache.Load(t) if ok { // 从缓存中加载 - jceDec = dec.(decoder) + jceDec = dec.([]decoder) } else { // 初次反射 - jceDec = decoder{} - t := reflect2.TypeOf(s).(reflect2.PtrType).Elem().(reflect2.StructType) + jceDec = make([]decoder, 0, t.NumField()) for i := 0; i < t.NumField(); i++ { field := t.Field(i) - strId := field.Tag().Get("jceId") + strId := field.Tag.Get("jceId") if strId == "" { continue } @@ -234,16 +233,15 @@ func (w *JceWriter) WriteJceStructRaw(s IJceStruct) { if err != nil { continue } - jceDec = append(jceDec, struct { - ty reflect2.Type - offset uintptr - id int - }{ty: field.Type(), offset: field.Offset(), id: id}) + jceDec = append(jceDec, decoder{ + index: i, + id: id, + }) } - decoderCache.Store(ty2, jceDec) // 存入缓存 + decoderCache.Store(t, jceDec) // 存入缓存 } for _, dec := range jceDec { - obj := dec.ty.UnsafeIndirect(unsafe.Pointer(uintptr(reflect2.PtrOf(s)) + dec.offset)) // MAGIC! + obj := v.Field(dec.index).Interface() if obj != nil { w.WriteObject(obj, dec.id) } diff --git a/binary/jce/writer_test.go b/binary/jce/writer_test.go index bba1f1a8..1eafdd00 100644 --- a/binary/jce/writer_test.go +++ b/binary/jce/writer_test.go @@ -1,6 +1,10 @@ package jce -import "testing" +import ( + "testing" + + "github.com/stretchr/testify/assert" +) var globalBytes []byte @@ -14,3 +18,42 @@ func BenchmarkJceWriter_WriteMap(b *testing.B) { globalBytes = x b.SetBytes(int64(len(globalBytes))) } + +var reqPacket1 = &RequestPacket{ + IVersion: 1, + CPacketType: 114, + IMessageType: 514, + IRequestId: 1919, + SServantName: "田所", + SFuncName: "浩二", + SBuffer: []byte{1, 1, 4, 5, 1, 4, 1, 9, 1, 9, 8, 1, 0}, + ITimeout: 810, + Context: map[string]string{ + "114": "514", + "1919": "810", + }, + Status: map[string]string{ + "野兽": "前辈", + "田所": "浩二", + }, +} + +func BenchmarkJceWriter_WriteJceStructRaw(b *testing.B) { + var x = globalBytes + for i := 0; i < b.N; i++ { + w := NewJceWriter() + w.WriteJceStructRaw(reqPacket1) + x = w.Bytes() + } + globalBytes = x + b.SetBytes(int64(len(globalBytes))) +} + +func TestJceWriter_WriteJceStructRaw(t *testing.T) { + w := NewJceWriter() + w.WriteJceStructRaw(reqPacket1) + r := NewJceReader(w.Bytes()) + var reqPacket2 RequestPacket + reqPacket2.ReadFrom(r) + assert.Equal(t, reqPacket1, &reqPacket2) +} diff --git a/client/client.go b/client/client.go index 534c2cf3..e61008b1 100644 --- a/client/client.go +++ b/client/client.go @@ -11,7 +11,6 @@ import ( "sync/atomic" "time" - jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" "github.com/Mrs4s/MiraiGo/binary" @@ -23,8 +22,6 @@ import ( "github.com/Mrs4s/MiraiGo/utils" ) -var json = jsoniter.ConfigFastest - //go:generate go run github.com/a8m/syncmap -o "handler_map_gen.go" -pkg client -name HandlerMap "map[uint16]*handlerInfo" type QQClient struct { diff --git a/client/global.go b/client/global.go index 493c8e6b..66024e8b 100644 --- a/client/global.go +++ b/client/global.go @@ -3,6 +3,7 @@ package client import ( "crypto/md5" "encoding/hex" + "encoding/json" "fmt" "math/rand" "net" diff --git a/client/group_info.go b/client/group_info.go index 5a233a62..130b3822 100644 --- a/client/group_info.go +++ b/client/group_info.go @@ -1,6 +1,7 @@ package client import ( + "encoding/json" "fmt" "math/rand" "net/url" diff --git a/client/group_msg.go b/client/group_msg.go index bd9b4131..cb10a7e1 100644 --- a/client/group_msg.go +++ b/client/group_msg.go @@ -3,6 +3,7 @@ package client import ( "bytes" "encoding/base64" + "encoding/json" "fmt" "math" "math/rand" diff --git a/client/http_api.go b/client/http_api.go index 5aaa2d0e..69a71698 100644 --- a/client/http_api.go +++ b/client/http_api.go @@ -2,6 +2,7 @@ package client import ( "bytes" + "encoding/json" "fmt" "html" "io" @@ -124,8 +125,8 @@ func (c *QQClient) GetGroupHonorInfo(groupCode int64, honorType HonorType) (*Gro func (c *QQClient) GetTts(text string) ([]byte, error) { url := "https://textts.qq.com/cgi-bin/tts" - text, _ = json.MarshalToString(text) - data := fmt.Sprintf(`{"appid": "201908021016","sendUin": %v,"text": %v}`, c.Uin, text) + bt, _ := json.Marshal(text) + data := fmt.Sprintf(`{"appid": "201908021016","sendUin": %v,"text": %s}`, c.Uin, bt) rsp, err := utils.HttpPostBytesWithCookie(url, []byte(data), c.getCookies()) if err != nil { return nil, errors.Wrap(err, "failed to post to tts server") @@ -231,7 +232,7 @@ func (c *QQClient) uploadGroupNoticePic(img []byte) (*noticeImage, error) { return nil, errors.New(res.ErrorMessage) } ret := ¬iceImage{} - err = json.UnmarshalFromString(html.UnescapeString(res.ID), &ret) + err = json.Unmarshal([]byte(html.UnescapeString(res.ID)), &ret) if err != nil { return nil, errors.Wrap(err, "failed to unmarshal json") } diff --git a/client/model_show.go b/client/model_show.go index 898cd11d..450d1d02 100644 --- a/client/model_show.go +++ b/client/model_show.go @@ -1,12 +1,13 @@ package client import ( + "encoding/json" "fmt" "net/url" "strings" "time" - jsoniter "github.com/json-iterator/go" + "github.com/tidwall/gjson" "github.com/Mrs4s/MiraiGo/utils" ) @@ -78,16 +79,14 @@ func (c *QQClient) GetModelShow(modelName string) ([]*ModelVariant, error) { return nil, err } - items := jsoniter.Get(b, "13030", "data", "rsp", "vItemList") - size := items.Size() - variants := make([]*ModelVariant, size) - for i := 0; i < size; i++ { - item := items.Get(i) - variants[i] = &ModelVariant{ - ModelShow: item.Get("sModelShow").ToString(), - NeedPay: item.Get("bNeedPay").ToBool(), - } - } + variants := make([]*ModelVariant, 0) + gjson.ParseBytes(b).Get("13030.data.rsp.vItemList").ForEach(func(_, value gjson.Result) bool { + variants = append(variants, &ModelVariant{ + ModelShow: value.Get("sModelShow").String(), + NeedPay: value.Get("bNeedPay").Bool(), + }) + return true + }) return variants, nil } diff --git a/client/notify.go b/client/notify.go index d5d422da..634f88cb 100644 --- a/client/notify.go +++ b/client/notify.go @@ -1,6 +1,7 @@ package client import ( + "encoding/json" "fmt" "strconv" "strings" diff --git a/go.mod b/go.mod index 24ecc34e..abe5a380 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,9 @@ module github.com/Mrs4s/MiraiGo go 1.16 require ( - github.com/json-iterator/go v1.1.10 - github.com/modern-go/reflect2 v1.0.1 github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.3.0 + github.com/tidwall/gjson v1.8.1 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/protobuf v1.25.0 ) diff --git a/go.sum b/go.sum index d875a184..10ebeca1 100644 --- a/go.sum +++ b/go.sum @@ -2,9 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -23,14 +22,6 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -39,6 +30,12 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/tidwall/gjson v1.8.1 h1:8j5EE9Hrh3l9Od1OIEDAb7IpezNA20UdRngNAj5N0WU= +github.com/tidwall/gjson v1.8.1/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk= +github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE= +github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.1.0 h1:K3hMW5epkdAVwibsQEfR/7Zj0Qgt4DxtNumTq/VloO8= +github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/message/message.go b/message/message.go index ccc38bb9..52b26d75 100644 --- a/message/message.go +++ b/message/message.go @@ -1,12 +1,12 @@ package message import ( + "encoding/json" "reflect" "regexp" "strconv" "strings" - jsoniter "github.com/json-iterator/go" "google.golang.org/protobuf/proto" "github.com/Mrs4s/MiraiGo/binary" @@ -14,8 +14,6 @@ import ( "github.com/Mrs4s/MiraiGo/utils" ) -var json = jsoniter.ConfigFastest - type ( PrivateMessage struct { Id int32 diff --git a/protocol/crypto/crypto.go b/protocol/crypto/crypto.go index 7de323e2..54e3e0d0 100644 --- a/protocol/crypto/crypto.go +++ b/protocol/crypto/crypto.go @@ -5,11 +5,11 @@ import ( "crypto/md5" "crypto/rand" "encoding/hex" + "encoding/json" "net/http" "strconv" "github.com/Mrs4s/MiraiGo/binary" - jsoniter "github.com/json-iterator/go" ) type EncryptECDH struct { @@ -97,7 +97,7 @@ func (e *EncryptECDH) FetchPubKey(uin int64) { } defer resp.Body.Close() pubKey := pubKeyResp{} - err = jsoniter.NewDecoder(resp.Body).Decode(&pubKey) + err = json.NewDecoder(resp.Body).Decode(&pubKey) if err != nil { return }