1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 19:17:38 +08:00

Merge pull request #11 from LXY1226/Ptt

Ptt
This commit is contained in:
Mrs4s 2020-08-05 09:38:30 +08:00 committed by GitHub
commit 133151bd29
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 954 additions and 351 deletions

View File

@ -16,6 +16,7 @@ qq-android协议的golang实现 移植于mirai
#### 消息类型 #### 消息类型
- [x] 文本 - [x] 文本
- [x] 图片 - [x] 图片
- [ ] 语音
- [x] 表情 - [x] 表情
- [x] At - [x] At
- [x] 回复 - [x] 回复

View File

@ -385,12 +385,17 @@ func (c *QQClient) buildDeleteOnlinePushPacket(uin int64, seq uint16, delMsg []j
// MessageSvc.PbSendMsg // MessageSvc.PbSendMsg
func (c *QQClient) buildGroupSendingPacket(groupCode int64, r int32, forward bool, m *message.SendingMessage) (uint16, []byte) { func (c *QQClient) buildGroupSendingPacket(groupCode int64, r int32, forward bool, m *message.SendingMessage) (uint16, []byte) {
seq := c.nextSeq() seq := c.nextSeq()
if m.Ptt != nil {
m.Elements = []message.IMessageElement{}
}
req := &msg.SendMessageRequest{ req := &msg.SendMessageRequest{
RoutingHead: &msg.RoutingHead{Grp: &msg.Grp{GroupCode: groupCode}}, RoutingHead: &msg.RoutingHead{Grp: &msg.Grp{GroupCode: groupCode}},
ContentHead: &msg.ContentHead{PkgNum: 1}, ContentHead: &msg.ContentHead{PkgNum: 1},
MsgBody: &msg.MessageBody{ MsgBody: &msg.MessageBody{
RichText: &msg.RichText{ RichText: &msg.RichText{
Elems: message.ToProtoElems(m.Elements, true), Elems: message.ToProtoElems(m.Elements, true),
Ptt: m.Ptt,
}, },
}, },
MsgSeq: c.nextGroupSeq(), MsgSeq: c.nextGroupSeq(),
@ -476,7 +481,7 @@ func (c *QQClient) buildGroupImageStorePacket(groupCode int64, md5 []byte, size
req := &pb.D388ReqBody{ req := &pb.D388ReqBody{
NetType: 3, NetType: 3,
Subcmd: 1, Subcmd: 1,
MsgTryupImgReq: []*pb.TryUpImgReq{ MsgTryUpImgReq: []*pb.TryUpImgReq{
{ {
GroupCode: groupCode, GroupCode: groupCode,
SrcUin: c.Uin, SrcUin: c.Uin,
@ -546,6 +551,37 @@ func (c *QQClient) buildImageUploadPacket(data, updKey []byte, commandId int32,
return return
} }
// PttStore.GroupPttUp
func (c *QQClient) buildGroupPttStorePacket(groupCode int64, md5 []byte, size, voiceLength int32) (uint16, []byte) {
seq := c.nextSeq()
req := &pb.D388ReqBody{
NetType: 3,
Subcmd: 3,
MsgTryUpPttReq: []*pb.TryUpPttReq{
{
GroupCode: groupCode,
SrcUin: c.Uin,
FileMd5: md5,
FileSize: int64(size),
FileName: md5,
SrcTerm: 5,
PlatformType: 9,
BuType: 4,
InnerIp: 0,
BuildVer: "6.5.5.663",
VoiceLength: voiceLength,
Codec: 0,
VoiceType: 1,
BoolNewUpChan: true,
},
},
Extension: EmptyBytes,
}
payload, _ := proto.Marshal(req)
packet := packets.BuildUniPacket(c.Uin, seq, "PttStore.GroupPttUp", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
return seq, packet
}
// ProfileService.Pb.ReqSystemMsgNew.Group // ProfileService.Pb.ReqSystemMsgNew.Group
func (c *QQClient) buildSystemMsgNewGroupPacket() (uint16, []byte) { func (c *QQClient) buildSystemMsgNewGroupPacket() (uint16, []byte) {
seq := c.nextSeq() seq := c.nextSeq()

View File

@ -18,7 +18,6 @@ import (
"math" "math"
"math/rand" "math/rand"
"net" "net"
"strconv"
"sync" "sync"
"sync/atomic" "sync/atomic"
"time" "time"
@ -118,6 +117,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
"friendlist.GetTroopListReqV2": decodeGroupListResponse, "friendlist.GetTroopListReqV2": decodeGroupListResponse,
"friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse, "friendlist.GetTroopMemberListReq": decodeGroupMemberListResponse,
"ImgStore.GroupPicUp": decodeGroupImageStoreResponse, "ImgStore.GroupPicUp": decodeGroupImageStoreResponse,
"PttStore.GroupPttUp": decodeGroupPttStoreResponse,
"LongConn.OffPicUp": decodeOffPicUpResponse, "LongConn.OffPicUp": decodeOffPicUpResponse,
"ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket, "ProfileService.Pb.ReqSystemMsgNew.Group": decodeSystemMsgGroupPacket,
"ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket, "ProfileService.Pb.ReqSystemMsgNew.Friend": decodeSystemMsgFriendPacket,
@ -148,7 +148,7 @@ func (c *QQClient) Login() (*LoginResponse, error) {
return nil, err return nil, err
} }
c.Online = true c.Online = true
go c.loop() go c.netLoop()
seq, packet := c.buildLoginPacket() seq, packet := c.buildLoginPacket()
rsp, err := c.sendAndWait(seq, packet) rsp, err := c.sendAndWait(seq, packet)
if err != nil { if err != nil {
@ -201,8 +201,7 @@ func (c *QQClient) GetFriendList() (*FriendListResponse, error) {
list := rsp.(FriendListResponse) list := rsp.(FriendListResponse)
r.TotalCount = list.TotalCount r.TotalCount = list.TotalCount
r.List = append(r.List, list.List...) r.List = append(r.List, list.List...)
curFriendCount += len(list.List) if int32(len(r.List)) >= r.TotalCount {
if int32(curFriendCount) >= r.TotalCount {
break break
} }
} }
@ -352,8 +351,7 @@ func (c *QQClient) sendGroupLongOrForwardMessage(groupCode int64, isLong bool, m
}, },
}) })
for i, ip := range rsp.Uint32UpIp { for i, ip := range rsp.Uint32UpIp {
updServer := binary.UInt32ToIPV4Address(uint32(ip)) err := c.highwayUploadImage(uint32(ip), int(rsp.Uint32UpPort[i]), rsp.MsgSig, body, 27)
err := c.highwayUploadImage(updServer+":"+strconv.FormatInt(int64(rsp.Uint32UpPort[i]), 10), rsp.MsgSig, body, 27)
if err == nil { if err == nil {
if !isLong { if !isLong {
var pv string var pv string
@ -395,17 +393,18 @@ func (c *QQClient) UploadGroupImage(groupCode int64, img []byte) (*message.Group
return nil, errors.New(rsp.Message) return nil, errors.New(rsp.Message)
} }
if rsp.IsExists { if rsp.IsExists {
return message.NewGroupImage(binary.CalculateImageResourceId(h[:]), h[:]), nil goto ok
} }
for i, ip := range rsp.UploadIp { for i, ip := range rsp.UploadIp {
updServer := binary.UInt32ToIPV4Address(uint32(ip)) err := c.highwayUploadImage(uint32(ip), int(rsp.UploadPort[i]), rsp.UploadKey, img, 2)
err := c.highwayUploadImage(updServer+":"+strconv.FormatInt(int64(rsp.UploadPort[i]), 10), rsp.UploadKey, img, 2)
if err != nil { if err != nil {
continue continue
} }
return message.NewGroupImage(binary.CalculateImageResourceId(h[:]), h[:]), nil goto ok
} }
return nil, errors.New("upload failed") return nil, errors.New("upload failed")
ok:
return message.NewGroupImage(binary.CalculateImageResourceId(h[:]), h[:]), nil
} }
func (c *QQClient) UploadPrivateImage(target int64, img []byte) (*message.FriendImageElement, error) { func (c *QQClient) UploadPrivateImage(target int64, img []byte) (*message.FriendImageElement, error) {
@ -430,6 +429,42 @@ func (c *QQClient) uploadPrivateImage(target int64, img []byte, count int) (*mes
return e, nil return e, nil
} }
func (c *QQClient) UploadGroupPtt(groupCode int64, voice []byte, voiceLength int32) (*message.GroupPtt, error) {
h := md5.Sum(voice)
seq, pkt := c.buildGroupPttStorePacket(groupCode, h[:], int32(len(voice)), voiceLength)
r, err := c.sendAndWait(seq, pkt)
if err != nil {
return nil, err
}
rsp := r.(pttUploadResponse)
if rsp.ResultCode != 0 {
return nil, errors.New(rsp.Message)
}
if rsp.IsExists {
goto ok
}
for i, ip := range rsp.UploadIp {
err := c.uploadGroupPtt(ip, rsp.UploadPort[i], rsp.UploadKey, rsp.FileKey, voice, h[:], 2)
if err != nil {
continue
}
goto ok
}
return nil, errors.New("upload failed")
ok:
return &message.GroupPtt{
Ptt: msg.Ptt{
FileType: 4,
SrcUin: c.Uin,
FileMd5: h[:],
FileName: hex.EncodeToString(h[:]) + ".amr",
FileSize: int32(len(voice)),
GroupFileKey: rsp.FileKey,
BoolValid: true,
PbReserve: []byte{8, 0, 40, 0, 56, 0},
}}, nil
}
func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*message.GroupImageElement, error) { func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*message.GroupImageElement, error) {
r, err := c.sendAndWait(c.buildGroupImageStorePacket(groupCode, hash, size)) r, err := c.sendAndWait(c.buildGroupImageStorePacket(groupCode, hash, size))
if err != nil { if err != nil {
@ -718,7 +753,7 @@ func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
} }
} }
func (c *QQClient) loop() { func (c *QQClient) netLoop() {
reader := binary.NewNetworkReader(c.Conn) reader := binary.NewNetworkReader(c.Conn)
retry := 0 retry := 0
for c.Online { for c.Online {

View File

@ -388,7 +388,7 @@ func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (inter
if err != nil { if err != nil {
return nil, err return nil, err
} }
rsp := pkt.MsgTryupImgRsp[0] rsp := pkt.MsgTryUpImgRsp[0]
if rsp.Result != 0 { if rsp.Result != 0 {
return imageUploadResponse{ return imageUploadResponse{
ResultCode: rsp.Result, ResultCode: rsp.Result,
@ -405,6 +405,30 @@ func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (inter
}, nil }, nil
} }
func decodeGroupPttStoreResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
pkt := pb.D388RespBody{}
err := proto.Unmarshal(payload, &pkt)
if err != nil {
return nil, err
}
rsp := pkt.MsgTryUpPttRsp[0]
if rsp.Result != 0 {
return pttUploadResponse{
ResultCode: rsp.Result,
Message: rsp.FailMsg,
}, nil
}
if rsp.BoolFileExit {
return imageUploadResponse{IsExists: true}, nil
}
return pttUploadResponse{
UploadKey: rsp.UpUkey,
UploadIp: rsp.Uint32UpIp,
UploadPort: rsp.Uint32UpPort,
FileKey: rsp.FileKey,
}, nil
}
func decodeOffPicUpResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) { func decodeOffPicUpResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
rsp := cmd0x352.RspBody{} rsp := cmd0x352.RspBody{}
if err := proto.Unmarshal(payload, &rsp); err != nil { if err := proto.Unmarshal(payload, &rsp); err != nil {

View File

@ -167,6 +167,19 @@ type (
UploadPort []int32 UploadPort []int32
} }
pttUploadResponse struct {
ResultCode int32
Message string
IsExists bool
ResourceId string
UploadKey []byte
UploadIp []int32
UploadPort []int32
FileKey []byte
}
groupMessageReceiptEvent struct { groupMessageReceiptEvent struct {
Rand int32 Rand int32
Seq int32 Seq int32

View File

@ -2,16 +2,25 @@ package client
import ( import (
"crypto/md5" "crypto/md5"
binary2 "encoding/binary"
"encoding/hex"
"errors" "errors"
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/client/pb" "github.com/Mrs4s/MiraiGo/client/pb"
"github.com/Mrs4s/MiraiGo/utils"
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"net" "net"
"strconv"
"time" "time"
) )
func (c *QQClient) highwayUploadImage(ser string, updKey, img []byte, cmdId int32) error { func (c *QQClient) highwayUploadImage(ip uint32, port int, updKey, img []byte, cmdId int32) error {
conn, err := net.DialTimeout("tcp", ser, time.Second*5) addr := net.TCPAddr{
IP: make([]byte, 4),
Port: port,
}
binary2.LittleEndian.PutUint32(addr.IP, ip)
conn, err := net.DialTCP("tcp", nil, &addr)
if err != nil { if err != nil {
return err return err
} }
@ -36,8 +45,8 @@ func (c *QQClient) highwayUploadImage(ser string, updKey, img []byte, cmdId int3
_, _ = r.ReadBytes(4) _, _ = r.ReadBytes(4)
payload, _ := r.ReadBytes(int(hl)) payload, _ := r.ReadBytes(int(hl))
_ = conn.Close() _ = conn.Close()
rsp := pb.RspDataHighwayHead{} rsp := new(pb.RspDataHighwayHead)
if err = proto.Unmarshal(payload, &rsp); err != nil { if err = proto.Unmarshal(payload, rsp); err != nil {
return err return err
} }
if rsp.ErrorCode != 0 { if rsp.ErrorCode != 0 {
@ -45,3 +54,29 @@ func (c *QQClient) highwayUploadImage(ser string, updKey, img []byte, cmdId int3
} }
return nil return nil
} }
// 只是为了写的跟上面一样长(bushi当然也应该是最快的玩法
func (c *QQClient) uploadGroupPtt(ip, port int32, updKey, fileKey, data, md5 []byte, codec int64) error {
url := make([]byte, 512)[:0]
url = append(url, "http://"...)
url = append(url, binary.UInt32ToIPV4Address(uint32(ip))...)
url = append(url, ':')
url = strconv.AppendInt(url, int64(port), 10)
url = append(url, "/?ver=4679&ukey="...)
p := len(url)
url = url[:p+len(updKey)*2]
hex.Encode(url[p:], updKey)
url = append(url, "&filekey="...)
p = len(url)
url = url[:p+len(fileKey)*2]
hex.Encode(url[p:], fileKey)
url = append(url, "&filesize="...)
url = strconv.AppendInt(url, int64(len(data)), 10)
url = append(url, "&bmd5="...)
p = len(url)
url = url[:p+32]
hex.Encode(url[p:], md5)
url = append(url, "&mType=pttDu&voice_encodec=1"...)
_, err := utils.HttpPostBytes(string(url), data)
return err
}

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.11.4 // protoc v3.12.3
// source: cmd0x352.proto // source: cmd0x352.proto
package cmd0x352 package cmd0x352

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,8 @@ message D50ReqBody {
message D388ReqBody { message D388ReqBody {
int32 netType = 1; int32 netType = 1;
int32 subcmd = 2; int32 subcmd = 2;
repeated TryUpImgReq msgTryupImgReq = 3; repeated TryUpImgReq msgTryUpImgReq = 3;
repeated TryUpPttReq msgTryUpPttReq = 5;
int32 commandId = 7; int32 commandId = 7;
bytes extension = 1001; bytes extension = 1001;
} }
@ -49,7 +50,8 @@ message D388ReqBody {
message D388RespBody { message D388RespBody {
int32 clientIp = 1; int32 clientIp = 1;
int32 subCmd = 2; int32 subCmd = 2;
repeated TryUpImgResp msgTryupImgRsp = 3; repeated TryUpImgResp msgTryUpImgRsp = 3;
repeated TryUpPttResp msgTryUpPttRsp = 5;
} }
message ReqDataHighwayHead { message ReqDataHighwayHead {
@ -136,6 +138,44 @@ message TryUpImgResp {
int64 fid = 9; int64 fid = 9;
} }
message TryUpPttReq {
int64 groupCode = 1;
int64 srcUin = 2;
int64 fileId = 3;
bytes fileMd5 = 4;
int64 fileSize = 5;
bytes fileName = 6;
int32 srcTerm = 7;
int32 platformType = 8;
int32 buType = 9;
string buildVer = 10;
int32 innerIp = 11;
int32 voiceLength = 12;
bool boolNewUpChan = 13;
int32 codec = 14;
int32 voiceType = 15;
int32 buId = 16;
}
message TryUpPttResp {
int64 fileId = 1;
int32 result = 2;
string failMsg = 3;
bool boolFileExit = 4;
repeated int32 uint32UpIp = 5;
repeated int32 uint32UpPort = 6;
bytes upUkey = 7;
// int64 fileid = 8; //
int64 upOffset = 9;
int64 blockSize = 10;
bytes fileKey = 11;
int32 channelType = 12;
// List<IPv6Info>? msgUpIp6 = 26;
// bytes clientIp6 = 27;
}
message ImgInfo { message ImgInfo {
bytes fileMd5 = 1; bytes fileMd5 = 1;
int32 fileType = 2; int32 fileType = 2;

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.11.4 // protoc v3.12.3
// source: longmsg.proto // source: longmsg.proto
package longmsg package longmsg

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.11.4 // protoc v3.12.3
// source: msg.proto // source: msg.proto
package msg package msg
@ -2020,7 +2020,7 @@ type Ptt struct {
SrcUin int64 `protobuf:"varint,2,opt,name=srcUin,proto3" json:"srcUin,omitempty"` SrcUin int64 `protobuf:"varint,2,opt,name=srcUin,proto3" json:"srcUin,omitempty"`
FileUuid []byte `protobuf:"bytes,3,opt,name=fileUuid,proto3" json:"fileUuid,omitempty"` FileUuid []byte `protobuf:"bytes,3,opt,name=fileUuid,proto3" json:"fileUuid,omitempty"`
FileMd5 []byte `protobuf:"bytes,4,opt,name=fileMd5,proto3" json:"fileMd5,omitempty"` FileMd5 []byte `protobuf:"bytes,4,opt,name=fileMd5,proto3" json:"fileMd5,omitempty"`
FileName []byte `protobuf:"bytes,5,opt,name=fileName,proto3" json:"fileName,omitempty"` FileName string `protobuf:"bytes,5,opt,name=fileName,proto3" json:"fileName,omitempty"`
FileSize int32 `protobuf:"varint,6,opt,name=fileSize,proto3" json:"fileSize,omitempty"` FileSize int32 `protobuf:"varint,6,opt,name=fileSize,proto3" json:"fileSize,omitempty"`
Reserve []byte `protobuf:"bytes,7,opt,name=reserve,proto3" json:"reserve,omitempty"` Reserve []byte `protobuf:"bytes,7,opt,name=reserve,proto3" json:"reserve,omitempty"`
FileId int32 `protobuf:"varint,8,opt,name=fileId,proto3" json:"fileId,omitempty"` FileId int32 `protobuf:"varint,8,opt,name=fileId,proto3" json:"fileId,omitempty"`
@ -2102,11 +2102,11 @@ func (x *Ptt) GetFileMd5() []byte {
return nil return nil
} }
func (x *Ptt) GetFileName() []byte { func (x *Ptt) GetFileName() string {
if x != nil { if x != nil {
return x.FileName return x.FileName
} }
return nil return ""
} }
func (x *Ptt) GetFileSize() int32 { func (x *Ptt) GetFileSize() int32 {
@ -5711,7 +5711,7 @@ var file_msg_proto_rawDesc = []byte{
0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x75, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x55, 0x75, 0x69,
0x64, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, 0x18, 0x04, 0x20, 0x01, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, 0x18, 0x04, 0x20, 0x01,
0x28, 0x0c, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x28, 0x0c, 0x52, 0x07, 0x66, 0x69, 0x6c, 0x65, 0x4d, 0x64, 0x35, 0x12, 0x1a, 0x0a, 0x08, 0x66,
0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66,
0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x6c, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53,
0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x53,
0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18, 0x07, 0x69, 0x7a, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x18, 0x07,

View File

@ -265,7 +265,7 @@ message Ptt {
int64 srcUin = 2; int64 srcUin = 2;
bytes fileUuid = 3; bytes fileUuid = 3;
bytes fileMd5 = 4; bytes fileMd5 = 4;
bytes fileName = 5; string fileName = 5;
int32 fileSize = 6; int32 fileSize = 6;
bytes reserve = 7; bytes reserve = 7;
int32 fileId = 8; int32 fileId = 8;

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.11.4 // protoc v3.12.3
// source: objmsg.proto // source: objmsg.proto
package msg package msg

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.11.4 // protoc v3.12.3
// source: multimsg.proto // source: multimsg.proto
package multimsg package multimsg

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.11.4 // protoc v3.12.3
// source: oidb.proto // source: oidb.proto
package oidb package oidb

View File

@ -1,7 +1,7 @@
// Code generated by protoc-gen-go. DO NOT EDIT. // Code generated by protoc-gen-go. DO NOT EDIT.
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.11.4 // protoc v3.12.3
// source: structmsg.proto // source: structmsg.proto
package structmsg package structmsg

2
go.mod
View File

@ -3,6 +3,6 @@ module github.com/Mrs4s/MiraiGo
go 1.14 go 1.14
require ( require (
github.com/golang/protobuf v1.4.1 github.com/golang/protobuf v1.4.2
google.golang.org/protobuf v1.25.0 google.golang.org/protobuf v1.25.0
) )

21
go.sum
View File

@ -7,7 +7,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
@ -22,52 +21,36 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/ishbir/elliptic v0.0.0-20150227224012-7fa75501baae h1:p4rT8RR3B5Q6rXTG5v0Tns45zn4wJucqQKF5hzrjtgU=
github.com/ishbir/elliptic v0.0.0-20150227224012-7fa75501baae/go.mod h1:JPqapJUq3G3ojsWKJHZNsUK2OJmarnOxFN9afp3/Ovo=
github.com/jhump/protoreflect v1.6.1 h1:4/2yi5LyDPP7nN+Hiird1SAJ6YoxUm13/oxHGRnbPd8=
github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= 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= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=

View File

@ -2,6 +2,7 @@ package message
import ( import (
"fmt" "fmt"
"github.com/Mrs4s/MiraiGo/client/pb/msg"
"strconv" "strconv"
"strings" "strings"
) )
@ -67,6 +68,10 @@ type ForwardElement struct {
ResId string ResId string
} }
type GroupPtt struct {
Ptt msg.Ptt
}
func NewText(s string) *TextElement { func NewText(s string) *TextElement {
return &TextElement{Content: s} return &TextElement{Content: s}
} }

View File

@ -2,7 +2,6 @@ package message
import ( import (
"crypto/md5" "crypto/md5"
"encoding/hex"
"github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/binary"
"github.com/Mrs4s/MiraiGo/client/pb/msg" "github.com/Mrs4s/MiraiGo/client/pb/msg"
"github.com/Mrs4s/MiraiGo/utils" "github.com/Mrs4s/MiraiGo/utils"
@ -45,6 +44,7 @@ type (
SendingMessage struct { SendingMessage struct {
Elements []IMessageElement Elements []IMessageElement
Ptt *msg.Ptt
} }
ForwardMessage struct { ForwardMessage struct {
@ -80,7 +80,8 @@ const (
Reply Reply
Service Service
Forward Forward
File File // Voice?
Voice
) )
func (s *Sender) IsAnonymous() bool { func (s *Sender) IsAnonymous() bool {
@ -200,6 +201,9 @@ func (s *Sender) DisplayName() string {
} }
func ToProtoElems(elems []IMessageElement, generalFlags bool) (r []*msg.Elem) { func ToProtoElems(elems []IMessageElement, generalFlags bool) (r []*msg.Elem) {
if len(elems) == 0 {
return nil
}
for _, elem := range elems { for _, elem := range elems {
if reply, ok := elem.(*ReplyElement); ok { if reply, ok := elem.(*ReplyElement); ok {
r = append(r, &msg.Elem{ r = append(r, &msg.Elem{
@ -330,10 +334,15 @@ func ToProtoElems(elems []IMessageElement, generalFlags bool) (r []*msg.Elem) {
}) })
break L break L
} }
d, _ := hex.DecodeString("08097800C80100F00100F80100900200C80200980300A00320B00300C00300D00300E803008A04020803900480808010B80400C00400") //d, _ := hex.DecodeString("08097800C80100F00100F80100900200C80200980300A00320B00300C00300D00300E803008A04020803900480808010B80400C00400")
r = append(r, &msg.Elem{ r = append(r, &msg.Elem{
GeneralFlags: &msg.GeneralFlags{ GeneralFlags: &msg.GeneralFlags{
PbReserve: d, PbReserve: []byte{
0x08, 0x09, 0x78, 0x00, 0xC8, 0x01, 0x00, 0xF0, 0x01, 0x00, 0xF8, 0x01, 0x00, 0x90, 0x02, 0x00,
0xC8, 0x02, 0x00, 0x98, 0x03, 0x00, 0xA0, 0x03, 0x20, 0xB0, 0x03, 0x00, 0xC0, 0x03, 0x00, 0xD0,
0x03, 0x00, 0xE8, 0x03, 0x00, 0x8A, 0x04, 0x02, 0x08, 0x03, 0x90, 0x04, 0x80, 0x80, 0x80, 0x10,
0xB8, 0x04, 0x00, 0xC0, 0x04, 0x00,
},
}, },
}) })
break L break L

View File

@ -33,3 +33,29 @@ func HttpGetBytes(url string) ([]byte, error) {
} }
return body, nil return body, nil
} }
func HttpPostBytes(url string, data []byte) ([]byte, error) {
req, err := http.NewRequest("POST", url, bytes.NewReader(data))
if err != nil {
return nil, err
}
req.Header["User-Agent"] = []string{"QQ/8.2.0.1296 CFNetwork/1126"}
req.Header["Net-Type"] = []string{"Wifi"}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if strings.Contains(resp.Header.Get("Content-Encoding"), "gzip") {
buffer := bytes.NewBuffer(body)
r, _ := gzip.NewReader(buffer)
defer r.Close()
unCom, err := ioutil.ReadAll(r)
return unCom, err
}
return body, nil
}