diff --git a/binary/tea.go b/binary/tea.go index c4bf48e7..7d95bbc3 100644 --- a/binary/tea.go +++ b/binary/tea.go @@ -7,11 +7,6 @@ import ( type TEA [4]uint32 -// randuint32 returns a lock free uint32 value. -// -//go:linkname randuint32 runtime.fastrand -func randuint32() uint32 - // Encrypt tea 加密 // http://bbs.chinaunix.net/thread-583468-1-1.html // 感谢xichen大佬对TEA的解释 @@ -19,9 +14,6 @@ func (t TEA) Encrypt(src []byte) (dst []byte) { lens := len(src) fill := 10 - (lens+1)%8 dst = make([]byte, fill+lens+7) - binary.LittleEndian.PutUint32(dst, randuint32()) - binary.LittleEndian.PutUint32(dst[4:], randuint32()) - binary.LittleEndian.PutUint32(dst[8:], randuint32()) dst[0] = byte(fill-3) | 0xF8 // 存储pad长度 copy(dst[fill:], src) @@ -59,38 +51,38 @@ func (t *TEA) encode(n uint64) uint64 { v0, v1 := uint32(n>>32), uint32(n) t0, t1, t2, t3 := t[0], t[1], t[2], t[3] - v0 += (v1 + 0x9e3779b9) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x9e3779b9) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x3c6ef372) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x3c6ef372) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0xdaa66d2b) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0xdaa66d2b) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x78dde6e4) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x78dde6e4) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x1715609d) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x1715609d) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0xb54cda56) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0xb54cda56) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x5384540f) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x5384540f) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0xf1bbcdc8) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0xf1bbcdc8) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x8ff34781) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x8ff34781) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x2e2ac13a) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x2e2ac13a) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0xcc623af3) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0xcc623af3) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x6a99b4ac) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x6a99b4ac) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x08d12e65) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x08d12e65) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0xa708a81e) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0xa708a81e) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0x454021d7) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0x454021d7) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 += (v1 + 0xe3779b90) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 += (v0 + 0xe3779b90) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) + v0 += (v1 + 0x9e3779b9) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x9e3779b9) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x3c6ef372) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x3c6ef372) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0xdaa66d2b) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0xdaa66d2b) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x78dde6e4) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x78dde6e4) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x1715609d) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x1715609d) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0xb54cda56) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0xb54cda56) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x5384540f) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x5384540f) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0xf1bbcdc8) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0xf1bbcdc8) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x8ff34781) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x8ff34781) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x2e2ac13a) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x2e2ac13a) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0xcc623af3) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0xcc623af3) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x6a99b4ac) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x6a99b4ac) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x08d12e65) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x08d12e65) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0xa708a81e) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0xa708a81e) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0x454021d7) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0x454021d7) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 += (v1 + 0xe3779b90) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 += (v0 + 0xe3779b90) ^ (v0<<4 + t2) ^ (v0>>5 + t3) return uint64(v0)<<32 | uint64(v1) } @@ -102,38 +94,38 @@ func (t *TEA) decode(n uint64) uint64 { v0, v1 := uint32(n>>32), uint32(n) t0, t1, t2, t3 := t[0], t[1], t[2], t[3] - v1 -= (v0 + 0xe3779b90) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0xe3779b90) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x454021d7) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x454021d7) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0xa708a81e) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0xa708a81e) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x08d12e65) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x08d12e65) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x6a99b4ac) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x6a99b4ac) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0xcc623af3) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0xcc623af3) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x2e2ac13a) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x2e2ac13a) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x8ff34781) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x8ff34781) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0xf1bbcdc8) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0xf1bbcdc8) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x5384540f) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x5384540f) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0xb54cda56) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0xb54cda56) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x1715609d) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x1715609d) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x78dde6e4) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x78dde6e4) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0xdaa66d2b) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0xdaa66d2b) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x3c6ef372) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x3c6ef372) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) - v1 -= (v0 + 0x9e3779b9) ^ ((v0 << 4) + t2) ^ ((v0 >> 5) + t3) - v0 -= (v1 + 0x9e3779b9) ^ ((v1 << 4) + t0) ^ ((v1 >> 5) + t1) + v1 -= (v0 + 0xe3779b90) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0xe3779b90) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x454021d7) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x454021d7) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0xa708a81e) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0xa708a81e) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x08d12e65) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x08d12e65) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x6a99b4ac) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x6a99b4ac) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0xcc623af3) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0xcc623af3) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x2e2ac13a) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x2e2ac13a) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x8ff34781) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x8ff34781) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0xf1bbcdc8) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0xf1bbcdc8) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x5384540f) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x5384540f) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0xb54cda56) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0xb54cda56) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x1715609d) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x1715609d) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x78dde6e4) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x78dde6e4) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0xdaa66d2b) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0xdaa66d2b) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x3c6ef372) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x3c6ef372) ^ (v1<<4 + t0) ^ (v1>>5 + t1) + v1 -= (v0 + 0x9e3779b9) ^ (v0<<4 + t2) ^ (v0>>5 + t3) + v0 -= (v1 + 0x9e3779b9) ^ (v1<<4 + t0) ^ (v1>>5 + t1) return uint64(v0)<<32 | uint64(v1) } diff --git a/binary/utils.go b/binary/utils.go index 58fa592c..ffa5dbb7 100644 --- a/binary/utils.go +++ b/binary/utils.go @@ -98,27 +98,12 @@ func AppendUUID(dst []byte, uuid []byte) []byte { return dst } -func ToIPV4Address(arr []byte) string { - ip := (net.IP)(arr) - return ip.String() -} - func UInt32ToIPV4Address(i uint32) string { ip := net.IP{0, 0, 0, 0} binary2.LittleEndian.PutUint32(ip, i) return ip.String() } -func ToChunkedBytesF(b []byte, size int, f func([]byte)) { - r := NewReader(b) - for r.Len() >= size { - f(r.ReadBytes(size)) - } - if r.Len() > 0 { - f(r.ReadAvailable()) - } -} - func ToBytes(i any) []byte { return NewWriterF(func(w *Writer) { // TODO: more types diff --git a/internal/proto/dynamic.go b/internal/proto/dynamic.go index a00339de..1812e826 100644 --- a/internal/proto/dynamic.go +++ b/internal/proto/dynamic.go @@ -1,7 +1,6 @@ package proto import ( - "bytes" "encoding/binary" "math" ) @@ -9,11 +8,11 @@ import ( type DynamicMessage map[uint64]any type encoder struct { - bytes.Buffer + buf []byte } func (msg DynamicMessage) Encode() []byte { - en := &encoder{} + en := encoder{} //nolint:staticcheck for id, value := range msg { key := id << 3 @@ -48,9 +47,8 @@ func (msg DynamicMessage) Encode() []byte { en.u64(math.Float64bits(v)) case string: en.uvarint(key | 2) - b := []byte(v) - en.uvarint(uint64(len(b))) - _, _ = en.Write(b) + en.uvarint(uint64(len(v))) + en.buf = append(en.buf, v...) case []uint64: for i := 0; i < len(v); i++ { en.uvarint(key | 0) @@ -59,21 +57,21 @@ func (msg DynamicMessage) Encode() []byte { case []byte: en.uvarint(key | 2) en.uvarint(uint64(len(v))) - _, _ = en.Write(v) + en.buf = append(en.buf, v...) case DynamicMessage: en.uvarint(key | 2) b := v.Encode() en.uvarint(uint64(len(b))) - _, _ = en.Write(b) + en.buf = append(en.buf, b...) } } - return en.Bytes() + return en.buf } func (en *encoder) uvarint(v uint64) { var b [binary.MaxVarintLen64]byte n := binary.PutUvarint(b[:], v) - _, _ = en.Write(b[:n]) + en.buf = append(en.buf, b[:n]...) } func (en *encoder) svarint(v int64) { @@ -83,11 +81,11 @@ func (en *encoder) svarint(v int64) { func (en *encoder) u32(v uint32) { var b [4]byte binary.LittleEndian.PutUint32(b[:], v) - _, _ = en.Write(b[:]) + en.buf = append(en.buf, b[:]...) } func (en *encoder) u64(v uint64) { var b [8]byte binary.LittleEndian.PutUint64(b[:], v) - _, _ = en.Write(b[:]) + en.buf = append(en.buf, b[:]...) } diff --git a/message/message.go b/message/message.go index 2cb9673b..9708b758 100644 --- a/message/message.go +++ b/message/message.go @@ -2,6 +2,7 @@ package message import ( "encoding/json" + "fmt" "reflect" "strconv" "strings" @@ -444,7 +445,7 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement { } var url string if elem.CustomFace.GetOrigUrl() == "" { - url = "https://gchat.qpic.cn/gchatpic_new/0/0-0-" + strings.ReplaceAll(binary.CalculateImageResourceId(elem.CustomFace.Md5)[1:37], "-", "") + "/0?term=2" + url = fmt.Sprintf("https://gchat.qpic.cn/gchatpic_new/0/0-0-%X/0?term=2", elem.CustomFace.Md5) } else { url = "https://gchat.qpic.cn" + elem.CustomFace.GetOrigUrl() } @@ -460,24 +461,22 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement { }) continue } + bizType := UnknownBizType + if len(elem.CustomFace.PbReserve) != 0 { + attr := new(msg.ResvAttr) + if proto.Unmarshal(elem.CustomFace.PbReserve, attr) == nil { + bizType = ImageBizType(attr.GetImageBizType()) + } + } res = append(res, &GroupImageElement{ - FileId: int64(elem.CustomFace.GetFileId()), - ImageId: elem.CustomFace.GetFilePath(), - Size: elem.CustomFace.GetSize(), - Width: elem.CustomFace.GetWidth(), - Height: elem.CustomFace.GetHeight(), - Url: url, - ImageBizType: func() ImageBizType { - if len(elem.CustomFace.PbReserve) == 0 { - return UnknownBizType - } - attr := new(msg.ResvAttr) - if proto.Unmarshal(elem.CustomFace.PbReserve, attr) != nil { - return UnknownBizType - } - return ImageBizType(attr.GetImageBizType()) - }(), - Md5: elem.CustomFace.Md5, + FileId: int64(elem.CustomFace.GetFileId()), + ImageId: elem.CustomFace.GetFilePath(), + Size: elem.CustomFace.GetSize(), + Width: elem.CustomFace.GetWidth(), + Height: elem.CustomFace.GetHeight(), + Url: url, + ImageBizType: bizType, + Md5: elem.CustomFace.Md5, }) } if elem.MarketFace != nil { @@ -492,19 +491,17 @@ func ParseMessageElems(elems []*msg.Elem) []IMessageElement { MagicValue: utils.B2S(elem.MarketFace.Mobileparam), } if face.Name == "[骰子]" || face.Name == "[随机骰子]" { + _, v, _ := strings.Cut(face.MagicValue, "=") + t, _ := strconv.ParseInt(v, 10, 32) return []IMessageElement{ &DiceElement{ MarketFaceElement: face, - Value: func() int32 { - v := strings.SplitN(face.MagicValue, "=", 2)[1] - t, _ := strconv.ParseInt(v, 10, 32) - return int32(t) + 1 - }(), + Value: int32(t) + 1, }, } } if face.Name == "[猜拳]" { - v := strings.SplitN(face.MagicValue, "=", 2)[1] + _, v, _ := strings.Cut(face.MagicValue, "=") t, _ := strconv.ParseInt(v, 10, 32) return []IMessageElement{ &FingerGuessingElement{