Skip to content

Commit

Permalink
Merge pull request #19 from Szzrain/feat/image-uploader
Browse files Browse the repository at this point in the history
  • Loading branch information
Redmomn authored Apr 21, 2024
2 parents a14e01e + b69ce04 commit 91e6c2e
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 16 deletions.
4 changes: 4 additions & 0 deletions client/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ type QQClient struct {

cache *cache.Cache

highwayUri map[uint32][]string
highwaySequence atomic.Uint32
sigSession []byte

GroupMessageEvent EventHandle[*message.GroupMessage]
PrivateMessageEvent EventHandle[*message.PrivateMessage]
TempMessageEvent EventHandle[*message.TempMessage]
Expand Down
29 changes: 13 additions & 16 deletions client/highway.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,8 @@ import (
"net/http"
"net/url"
"strconv"
"sync/atomic"
)

var highwayUri map[uint32][]string
var sequence atomic.Uint32

type UpBlock struct {
CommandId int
Uin uint
Expand All @@ -32,40 +28,41 @@ type UpBlock struct {
Timestamp uint64
}

func (c *QQClient) GetServiceServer() map[uint32][]string {
if highwayUri == nil {
highwayUri = make(map[uint32][]string)
func (c *QQClient) GetServiceServer() ([]byte, map[uint32][]string) {
if c.highwayUri == nil || c.sigSession == nil {
c.highwayUri = make(map[uint32][]string)
packet, err := highway2.BuildHighWayUrlReq(c.sig.Tgt)
if err != nil {
return nil
return nil, nil
}
payload, err := c.SendUniPacketAndAwait("HttpConn.0x6ff_501", packet.Data())
if err != nil {
networkLogger.Errorf("Failed to get highway server: %v", err)
return nil
return nil, nil
}
resp, err := highway2.ParseHighWayUrlReq(payload.Data)
if err != nil {
networkLogger.Errorf("Failed to parse highway server: %v", err)
return nil
return nil, nil
}
for _, info := range resp.HttpConn.ServerInfos {
servicetype := info.ServiceType
for _, addr := range info.ServerAddrs {
ip := make([]byte, 4)
binary2.LittleEndian.PutUint32(ip, addr.IP)
service := highwayUri[servicetype]
service := c.highwayUri[servicetype]
service = append(service, fmt.Sprintf("http://%d.%d.%d.%d:%d/cgi-bin/httpconn?htcmd=0x6FF0087&uin=%d", ip[0], ip[1], ip[2], ip[3], addr.Port, c.sig.Uin))
highwayUri[servicetype] = service
c.highwayUri[servicetype] = service
}
}
c.sigSession = resp.HttpConn.SigSession
}
return highwayUri
return c.sigSession, c.highwayUri
}

func (c *QQClient) UploadSrcByStreamAsync(commonId int, stream io.ReadSeeker, ticket []byte, md5 []byte, extendInfo []byte) bool {
// Get server URL
server := c.GetServiceServer()
_, server := c.GetServiceServer()
if server == nil {
return false
}
Expand Down Expand Up @@ -98,15 +95,15 @@ func (c *QQClient) UploadSrcByStreamAsync(commonId int, stream io.ReadSeeker, ti
reqBody := UpBlock{
CommandId: commonId,
Uin: uint(c.sig.Uin),
Sequence: uint(sequence.Load()),
Sequence: uint(c.highwaySequence.Load()),
FileSize: fileSize,
Offset: offset,
Ticket: ticket,
FileMd5: md5,
Block: buffer,
ExtendInfo: extendInfo,
}
sequence.Add(1)
c.highwaySequence.Add(1)
upBlocks = append(upBlocks, reqBody)
offset += uint64(payload)
// 4 is HighwayConcurrent
Expand Down
91 changes: 91 additions & 0 deletions client/imageUploader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package client

import (
"bytes"
"encoding/hex"
"errors"
"github.com/LagrangeDev/LagrangeGo/message"
"github.com/LagrangeDev/LagrangeGo/packets/oidb"
"github.com/LagrangeDev/LagrangeGo/packets/pb/service/highway"
oidb2 "github.com/LagrangeDev/LagrangeGo/packets/pb/service/oidb"
"github.com/LagrangeDev/LagrangeGo/utils/proto"
"io"
"net"
)

func ConvertIP(raw uint32) string {
ip := make(net.IP, 4)
ip[0] = byte(raw & 0xFF)
ip[1] = byte((raw >> 8) & 0xFF)
ip[2] = byte((raw >> 16) & 0xFF)
ip[3] = byte((raw >> 24) & 0xFF)
return string(ip)
}

func ConvertNTHighwayNetWork(ipv4s []*oidb2.IPv4) []*highway.NTHighwayIPv4 {
var IPv4s []*highway.NTHighwayIPv4
for _, ipv4 := range ipv4s {
IPv4s = append(IPv4s, &highway.NTHighwayIPv4{
Domain: &highway.NTHighwayDomain{
IsEnable: true,
IP: ConvertIP(ipv4.OutIP),
},
Port: ipv4.OutPort,
})
}
return IPv4s
}

func (c *QQClient) ImageUploadGroup(groupUin uint32, element message.IMessageElement) (*message.GroupImageElement, error) {
image, ok := element.(*message.GroupImageElement)
if !ok {
return nil, errors.New("element type is not group image")
}
req, err := oidb.BuildGroupImageUploadReq(groupUin, bytes.NewReader(image.Stream))
if err != nil {
return nil, err
}
resp, err := c.SendOidbPacketAndWait(req)
if err != nil {
return nil, err
}
uploadResp, err := oidb.ParseGroupImageUploadResp(resp.Data)
if err != nil {
return nil, err
}
ukey := uploadResp.Upload.UKey
if ukey.Unwrap() != "" {
index := uploadResp.Upload.MsgInfo.MsgInfoBody[0].Index
sha1hash, err := hex.DecodeString(index.Info.FileSha1)
if err != nil {
return nil, err
}
extend := &highway.NTV2RichMediaHighwayExt{
FileUuid: index.FileUuid,
UKey: ukey.Unwrap(),
Network: &highway.NTHighwayNetwork{
IPv4S: ConvertNTHighwayNetWork(uploadResp.Upload.IPv4S),
},
MsgInfoBody: uploadResp.Upload.MsgInfo.MsgInfoBody,
BlockSize: 1024 * 1024,
Hash: &highway.NTHighwayHash{
FileSha1: [][]byte{sha1hash},
},
}
extStream, err := proto.Marshal(extend)
if err != nil {
return nil, err
}
md5hash, err := hex.DecodeString(index.Info.FileHash)
if err != nil {
return nil, err
}
sigSession, _ := c.GetServiceServer()
if !c.UploadSrcByStreamAsync(1004, io.ReadSeeker(bytes.NewReader(image.Stream)), sigSession, md5hash, extStream) {
return nil, errors.New("upload failed")
}
}
image.MsgInfo = uploadResp.Upload.MsgInfo
image.CompatFace = uploadResp.Upload.CompatQMsg
return image, nil
}
9 changes: 9 additions & 0 deletions message/image.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package message

import (
"github.com/LagrangeDev/LagrangeGo/packets/pb/service/oidb"
)

type GroupImageElement struct {
ImageId string
FileId int64
Expand All @@ -13,6 +17,11 @@ type GroupImageElement struct {
// EffectID show pic effect id.
EffectID int32
Flash bool

// Send
MsgInfo *oidb.MsgInfo
Stream []byte
CompatFace []byte
}

type FriendImageElement struct {
Expand Down
1 change: 1 addition & 0 deletions sig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"Sequence":8901,"Tgtgt":"BCCgSr6jXSS152VX5gzPBg==","Tgt":"ZwhpAHI0+IXnOyM7aWaI3pDfv+bG6d5fcstsiv+vVf5rc0hLYe7gn+lQZqKthqxUSnzn7+yr+dFDaXXKAV3DBOGCObNyA7OZ","D2":"6Eh025S5eIYgXBjgjHNux4g3dGUlQ6Qyypk2OOTVScgd8s/tZp3Mn0ShgsGUP6ohRSIwqZ/xt2JhzoNPjfoLRdvv8hc4e9YVxGCdc5R6BqlIZCfzVMB1gA==","D2Key":"NCw0QlZTOz8ocyhhJGcrZQ==","Qrsig":"KR3P4aJXvxWdcLD4kqqlKUmYo0yuTKEt","ExchangeKey":"1koG+MOC7P4pmDUj6mSmdhFG5QY0Y3gvNdxJemI35OM=","KeySig":"fj/L9A1bgXBhqB4Iqr5J93WeI/lDA+7T0I/OlBRqUsUlHfcFkRpdtU17xRb3jCM39uKUOHHNagPdY0IN1wTPmXdB8usSCyOorDF9iIfgi74hKaKfRwxhIOzpkkjhx7TX5Vtkqk8H1OQ=","Cookies":"","UnusualSig":"","TempPwd":"xDR7IgZSkKRTCq8qu4x5wAWmnQHsEtl7mDNADqdJ5StFll5LLWumxfpFgh8s6CbZmIu4iHuRV2OTCrkWyehkZj7VMnJaP040VhRs890kNxOuekyKNhAt7XgCIT65TmI+zgNvFEC7WWfVYtYaxO559aU6QAug8YaUzjRU/u8n17jL991BWiyBRjJ7IQq6eGBuutCHHM2Q/nM=","Uid":"u_T0WhBZchiZhEUIbSxoocGA","CaptchaInfo":["","",""]}

0 comments on commit 91e6c2e

Please sign in to comment.