github.com/LagrangeDev/LagrangeGo@v0.0.0-20240512064304-ad4a85e10cb4/client/richmedia.go (about) 1 package client 2 3 import ( 4 "bytes" 5 "encoding/hex" 6 "errors" 7 8 highway2 "github.com/LagrangeDev/LagrangeGo/client/internal/highway" 9 "github.com/LagrangeDev/LagrangeGo/client/packets/oidb" 10 message2 "github.com/LagrangeDev/LagrangeGo/client/packets/pb/message" 11 "github.com/LagrangeDev/LagrangeGo/client/packets/pb/service/highway" 12 oidb2 "github.com/LagrangeDev/LagrangeGo/client/packets/pb/service/oidb" 13 "github.com/LagrangeDev/LagrangeGo/internal/proto" 14 "github.com/LagrangeDev/LagrangeGo/message" 15 "github.com/LagrangeDev/LagrangeGo/utils/binary" 16 ) 17 18 func oidbIPv4ToNTHighwayIPv4(ipv4s []*oidb2.IPv4) []*highway.NTHighwayIPv4 { 19 hwipv4s := make([]*highway.NTHighwayIPv4, len(ipv4s)) 20 for i, ip := range ipv4s { 21 hwipv4s[i] = &highway.NTHighwayIPv4{ 22 Domain: &highway.NTHighwayDomain{ 23 IsEnable: true, 24 IP: binary.UInt32ToIPV4Address(ip.OutIP), 25 }, 26 Port: ip.OutPort, 27 } 28 } 29 return hwipv4s 30 } 31 32 func (c *QQClient) ImageUploadPrivate(targetUid string, element message.IMessageElement) (*message.FriendImageElement, error) { 33 image, ok := element.(*message.FriendImageElement) 34 if !ok { 35 return nil, errors.New("element type is not friend image") 36 } 37 req, err := oidb.BuildImageUploadReq(targetUid, image.Stream) 38 if err != nil { 39 return nil, err 40 } 41 resp, err := c.sendOidbPacketAndWait(req) 42 if err != nil { 43 return nil, err 44 } 45 uploadResp, err := oidb.ParseImageUploadResp(resp) 46 if err != nil { 47 return nil, err 48 } 49 ukey := uploadResp.Upload.UKey.Unwrap() 50 c.debugln("private image upload ukey:", ukey) 51 if ukey != "" { 52 index := uploadResp.Upload.MsgInfo.MsgInfoBody[0].Index 53 sha1hash, err := hex.DecodeString(index.Info.FileSha1) 54 if err != nil { 55 return nil, err 56 } 57 extend := &highway.NTV2RichMediaHighwayExt{ 58 FileUuid: index.FileUuid, 59 UKey: ukey, 60 Network: &highway.NTHighwayNetwork{ 61 IPv4S: oidbIPv4ToNTHighwayIPv4(uploadResp.Upload.IPv4S), 62 }, 63 MsgInfoBody: uploadResp.Upload.MsgInfo.MsgInfoBody, 64 BlockSize: uint32(highway2.BlockSize), 65 Hash: &highway.NTHighwayHash{ 66 FileSha1: [][]byte{sha1hash}, 67 }, 68 } 69 extStream, err := proto.Marshal(extend) 70 if err != nil { 71 return nil, err 72 } 73 md5hash, err := hex.DecodeString(index.Info.FileHash) 74 if err != nil { 75 return nil, err 76 } 77 err = c.highwayUpload(1003, 78 bytes.NewReader(image.Stream), uint64(len(image.Stream)), 79 md5hash, extStream, 80 ) 81 if err != nil { 82 return nil, err 83 } 84 } 85 image.MsgInfo = uploadResp.Upload.MsgInfo 86 compatImage := &message2.NotOnlineImage{} 87 err = proto.Unmarshal(uploadResp.Upload.CompatQMsg, compatImage) 88 if err != nil { 89 return nil, err 90 } 91 image.CompatImage = compatImage 92 return image, nil 93 } 94 95 func (c *QQClient) ImageUploadGroup(groupUin uint32, element message.IMessageElement) (*message.GroupImageElement, error) { 96 image, ok := element.(*message.GroupImageElement) 97 if !ok { 98 return nil, errors.New("element type is not group image") 99 } 100 req, err := oidb.BuildGroupImageUploadReq(groupUin, image.Stream) 101 if err != nil { 102 return nil, err 103 } 104 resp, err := c.sendOidbPacketAndWait(req) 105 if err != nil { 106 return nil, err 107 } 108 uploadResp, err := oidb.ParseGroupImageUploadResp(resp) 109 if err != nil { 110 return nil, err 111 } 112 ukey := uploadResp.Upload.UKey.Unwrap() 113 c.debugln("private image upload ukey:", ukey) 114 if ukey != "" { 115 index := uploadResp.Upload.MsgInfo.MsgInfoBody[0].Index 116 sha1hash, err := hex.DecodeString(index.Info.FileSha1) 117 if err != nil { 118 return nil, err 119 } 120 extend := &highway.NTV2RichMediaHighwayExt{ 121 FileUuid: index.FileUuid, 122 UKey: ukey, 123 Network: &highway.NTHighwayNetwork{ 124 IPv4S: oidbIPv4ToNTHighwayIPv4(uploadResp.Upload.IPv4S), 125 }, 126 MsgInfoBody: uploadResp.Upload.MsgInfo.MsgInfoBody, 127 BlockSize: uint32(highway2.BlockSize), 128 Hash: &highway.NTHighwayHash{ 129 FileSha1: [][]byte{sha1hash}, 130 }, 131 } 132 extStream, err := proto.Marshal(extend) 133 if err != nil { 134 return nil, err 135 } 136 md5hash, err := hex.DecodeString(index.Info.FileHash) 137 if err != nil { 138 return nil, err 139 } 140 err = c.highwayUpload(1004, 141 bytes.NewReader(image.Stream), uint64(len(image.Stream)), 142 md5hash, extStream, 143 ) 144 if err != nil { 145 return nil, err 146 } 147 } 148 image.MsgInfo = uploadResp.Upload.MsgInfo 149 image.CompatFace = uploadResp.Upload.CompatQMsg 150 return image, nil 151 }