mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
Merge pull request #70 from wfjsw/features/stack-trace-on-panic-catch
better error support
This commit is contained in:
commit
b3233e604e
@ -5,13 +5,13 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"image"
|
"image"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
"net"
|
||||||
|
"runtime/debug"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -19,6 +19,8 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
@ -701,7 +703,7 @@ func (c *QQClient) uploadPrivateImage(target int64, img []byte, count int) (*mes
|
|||||||
count++
|
count++
|
||||||
h := md5.Sum(img)
|
h := md5.Sum(img)
|
||||||
e, err := c.QueryFriendImage(target, h[:], int32(len(img)))
|
e, err := c.QueryFriendImage(target, h[:], int32(len(img)))
|
||||||
if err == ErrNotExists {
|
if errors.Is(err, ErrNotExists) {
|
||||||
// use group highway upload and query again for image id.
|
// use group highway upload and query again for image id.
|
||||||
if _, err = c.UploadGroupImage(target, img); err != nil {
|
if _, err = c.UploadGroupImage(target, img); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -747,7 +749,7 @@ func (c *QQClient) QueryGroupImage(groupCode int64, hash []byte, size int32) (*m
|
|||||||
if rsp.IsExists {
|
if rsp.IsExists {
|
||||||
return message.NewGroupImage(binary.CalculateImageResourceId(hash), hash, rsp.FileId, size, rsp.Width, rsp.Height, 1000), nil
|
return message.NewGroupImage(binary.CalculateImageResourceId(hash), hash, rsp.FileId, size, rsp.Width, rsp.Height, 1000), nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("image not exists")
|
return nil, errors.New("image does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) QueryFriendImage(target int64, hash []byte, size int32) (*message.FriendImageElement, error) {
|
func (c *QQClient) QueryFriendImage(target int64, hash []byte, size int32) (*message.FriendImageElement, error) {
|
||||||
@ -763,7 +765,7 @@ func (c *QQClient) QueryFriendImage(target int64, hash []byte, size int32) (*mes
|
|||||||
return &message.FriendImageElement{
|
return &message.FriendImageElement{
|
||||||
ImageId: rsp.ResourceId,
|
ImageId: rsp.ResourceId,
|
||||||
Md5: hash,
|
Md5: hash,
|
||||||
}, ErrNotExists
|
}, errors.WithStack(ErrNotExists)
|
||||||
}
|
}
|
||||||
return &message.FriendImageElement{
|
return &message.FriendImageElement{
|
||||||
ImageId: rsp.ResourceId,
|
ImageId: rsp.ResourceId,
|
||||||
@ -820,7 +822,7 @@ func (c *QQClient) GetGroupMembers(group *GroupInfo) ([]*GroupMemberInfo, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if data == nil {
|
if data == nil {
|
||||||
return nil, errors.New("rsp is nil")
|
return nil, errors.New("group member list unavailable: rsp is nil")
|
||||||
}
|
}
|
||||||
rsp := data.(groupMemberListResponse)
|
rsp := data.(groupMemberListResponse)
|
||||||
nextUin = rsp.NextUin
|
nextUin = rsp.NextUin
|
||||||
@ -983,7 +985,7 @@ func (c *QQClient) connect() error {
|
|||||||
if err != nil || conn == nil {
|
if err != nil || conn == nil {
|
||||||
c.retryTimes++
|
c.retryTimes++
|
||||||
if c.retryTimes > len(c.servers) {
|
if c.retryTimes > len(c.servers) {
|
||||||
return errors.New("network error")
|
return errors.New("All servers are unreachable")
|
||||||
}
|
}
|
||||||
c.Error("connect server error: %v", err)
|
c.Error("connect server error: %v", err)
|
||||||
if err = c.connect(); err != nil {
|
if err = c.connect(); err != nil {
|
||||||
@ -1050,7 +1052,7 @@ func (c *QQClient) send(pkt []byte) error {
|
|||||||
} else {
|
} else {
|
||||||
c.stat.PacketSent++
|
c.stat.PacketSent++
|
||||||
}
|
}
|
||||||
return err
|
return errors.Wrap(err, "Packet failed to send")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
|
func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
|
||||||
@ -1058,12 +1060,12 @@ func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
|
|||||||
Response interface{}
|
Response interface{}
|
||||||
Error error
|
Error error
|
||||||
}
|
}
|
||||||
_, err := c.Conn.Write(pkt)
|
|
||||||
|
err := c.send(pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.stat.PacketLost++
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c.stat.PacketSent++
|
|
||||||
ch := make(chan T)
|
ch := make(chan T)
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
c.handlers.Store(seq, func(i interface{}, err error) {
|
c.handlers.Store(seq, func(i interface{}, err error) {
|
||||||
@ -1072,6 +1074,7 @@ func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
|
|||||||
Error: err,
|
Error: err,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
retry := 0
|
retry := 0
|
||||||
for true {
|
for true {
|
||||||
select {
|
select {
|
||||||
@ -1086,7 +1089,7 @@ func (c *QQClient) sendAndWait(seq uint16, pkt []byte) (interface{}, error) {
|
|||||||
c.handlers.Delete(seq)
|
c.handlers.Delete(seq)
|
||||||
//c.Error("packet timed out, seq: %v", seq)
|
//c.Error("packet timed out, seq: %v", seq)
|
||||||
//println("Packet Timed out")
|
//println("Packet Timed out")
|
||||||
return nil, errors.New("timeout")
|
return nil, errors.New("Packet timed out")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -1102,7 +1105,7 @@ func (c *QQClient) netLoop() {
|
|||||||
errCount := 0
|
errCount := 0
|
||||||
for c.NetLooping {
|
for c.NetLooping {
|
||||||
l, err := reader.ReadInt32()
|
l, err := reader.ReadInt32()
|
||||||
if err == io.EOF || err == io.ErrClosedPipe {
|
if errors.Is(err, io.EOF) || errors.Is(err, io.ErrClosedPipe) {
|
||||||
c.Error("connection dropped by server: %v", err)
|
c.Error("connection dropped by server: %v", err)
|
||||||
c.stat.DisconnectTimes++
|
c.stat.DisconnectTimes++
|
||||||
err = c.connect()
|
err = c.connect()
|
||||||
@ -1130,7 +1133,7 @@ func (c *QQClient) netLoop() {
|
|||||||
pkt, err := packets.ParseIncomingPacket(data, c.sigInfo.d2Key)
|
pkt, err := packets.ParseIncomingPacket(data, c.sigInfo.d2Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error("parse incoming packet error: %v", err)
|
c.Error("parse incoming packet error: %v", err)
|
||||||
if err == packets.ErrSessionExpired || err == packets.ErrPacketDropped {
|
if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
errCount++
|
errCount++
|
||||||
@ -1155,26 +1158,26 @@ func (c *QQClient) netLoop() {
|
|||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if pan := recover(); pan != nil {
|
if pan := recover(); pan != nil {
|
||||||
c.Error("panic on decoder %v : %v", pkt.CommandName, pan)
|
c.Error("panic on decoder %v : %v\n%s", pkt.CommandName, pan, debug.Stack())
|
||||||
//fmt.Println("panic on decoder:", pan)
|
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
decoder, ok := c.decoders[pkt.CommandName]
|
|
||||||
if !ok {
|
if decoder, ok := c.decoders[pkt.CommandName]; ok {
|
||||||
|
// found predefined decoder
|
||||||
|
rsp, err := decoder(c, pkt.SequenceId, payload)
|
||||||
|
if err != nil {
|
||||||
|
c.Debug("decode pkt %v error: %+v", pkt.CommandName, err)
|
||||||
|
}
|
||||||
if f, ok := c.handlers.Load(pkt.SequenceId); ok {
|
if f, ok := c.handlers.Load(pkt.SequenceId); ok {
|
||||||
c.handlers.Delete(pkt.SequenceId)
|
c.handlers.Delete(pkt.SequenceId)
|
||||||
f.(func(i interface{}, err error))(nil, nil)
|
f.(func(i interface{}, err error))(rsp, err)
|
||||||
}
|
}
|
||||||
return
|
} else if f, ok := c.handlers.Load(pkt.SequenceId); ok {
|
||||||
}
|
// does not need decoder
|
||||||
rsp, err := decoder(c, pkt.SequenceId, payload)
|
|
||||||
if err != nil {
|
|
||||||
c.Debug("decode pkt %v error: %v", pkt.CommandName, err)
|
|
||||||
//log.Println("decode", pkt.CommandName, "error:", err)
|
|
||||||
}
|
|
||||||
if f, ok := c.handlers.Load(pkt.SequenceId); ok {
|
|
||||||
c.handlers.Delete(pkt.SequenceId)
|
c.handlers.Delete(pkt.SequenceId)
|
||||||
f.(func(i interface{}, err error))(rsp, err)
|
f.(func(i interface{}, err error))(nil, nil)
|
||||||
|
} else {
|
||||||
|
c.Debug("\nUnhandled Command: %s\nSeq: %d\nData: %x\n", pkt.CommandName, pkt.SequenceId, payload)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/notify"
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/pttcenter"
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/qweb"
|
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -13,6 +9,11 @@ import (
|
|||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/notify"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/pttcenter"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb/qweb"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb"
|
"github.com/Mrs4s/MiraiGo/client/pb"
|
||||||
@ -161,7 +162,7 @@ func decodeLoginResponse(c *QQClient, _ uint16, payload []byte) (interface{}, er
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, errors.New(fmt.Sprintf("unknown login response: %v", t)) // ?
|
return nil, errors.Errorf("unknown login response: %v", t) // ?
|
||||||
}
|
}
|
||||||
|
|
||||||
// StatSvc.register
|
// StatSvc.register
|
||||||
@ -248,7 +249,7 @@ func decodeMessageSvcPacket(c *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
rsp := msg.GetMessageResponse{}
|
rsp := msg.GetMessageResponse{}
|
||||||
err := proto.Unmarshal(payload, &rsp)
|
err := proto.Unmarshal(payload, &rsp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.GetResult() != 0 {
|
if rsp.GetResult() != 0 {
|
||||||
return nil, errors.New("message svc result unsuccessful")
|
return nil, errors.New("message svc result unsuccessful")
|
||||||
@ -351,6 +352,7 @@ func decodeMessageSvcPacket(c *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
case 529:
|
case 529:
|
||||||
sub4 := msg.SubMsgType0X4Body{}
|
sub4 := msg.SubMsgType0X4Body{}
|
||||||
if err := proto.Unmarshal(message.Body.MsgContent, &sub4); err != nil {
|
if err := proto.Unmarshal(message.Body.MsgContent, &sub4); err != nil {
|
||||||
|
err = errors.Wrap(err, "unmarshal sub msg 0x4 error")
|
||||||
c.Error("unmarshal sub msg 0x4 error: %v", err)
|
c.Error("unmarshal sub msg 0x4 error: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -382,7 +384,7 @@ func decodeGroupMessagePacket(c *QQClient, _ uint16, payload []byte) (interface{
|
|||||||
pkt := msg.PushMessagePacket{}
|
pkt := msg.PushMessagePacket{}
|
||||||
err := proto.Unmarshal(payload, &pkt)
|
err := proto.Unmarshal(payload, &pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if pkt.Message.Head.GetFromUin() == c.Uin {
|
if pkt.Message.Head.GetFromUin() == c.Uin {
|
||||||
c.dispatchGroupMessageReceiptEvent(&groupMessageReceiptEvent{
|
c.dispatchGroupMessageReceiptEvent(&groupMessageReceiptEvent{
|
||||||
@ -416,7 +418,7 @@ func decodeGroupMessagePacket(c *QQClient, _ uint16, payload []byte) (interface{
|
|||||||
func decodeMsgSendResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeMsgSendResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
rsp := msg.SendMessageResponse{}
|
rsp := msg.SendMessageResponse{}
|
||||||
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.GetResult() != 0 {
|
if rsp.GetResult() != 0 {
|
||||||
c.Error("send msg error: %v %v", rsp.Result, rsp.ErrMsg)
|
c.Error("send msg error: %v %v", rsp.Result, rsp.ErrMsg)
|
||||||
@ -568,10 +570,10 @@ func decodeGroupMemberListResponse(_ *QQClient, _ uint16, payload []byte) (inter
|
|||||||
func decodeGroupMemberInfoResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeGroupMemberInfoResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
rsp := pb.GroupMemberRspBody{}
|
rsp := pb.GroupMemberRspBody{}
|
||||||
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.MemInfo.Nick == nil && rsp.MemInfo.Age == 0 {
|
if rsp.MemInfo.Nick == nil && rsp.MemInfo.Age == 0 {
|
||||||
return nil, ErrMemberNotFound
|
return nil, errors.WithStack(ErrMemberNotFound)
|
||||||
}
|
}
|
||||||
group := c.FindGroup(rsp.GroupCode)
|
group := c.FindGroup(rsp.GroupCode)
|
||||||
return &GroupMemberInfo{
|
return &GroupMemberInfo{
|
||||||
@ -602,7 +604,7 @@ func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (inter
|
|||||||
pkt := pb.D388RespBody{}
|
pkt := pb.D388RespBody{}
|
||||||
err := proto.Unmarshal(payload, &pkt)
|
err := proto.Unmarshal(payload, &pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
rsp := pkt.MsgTryUpImgRsp[0]
|
rsp := pkt.MsgTryUpImgRsp[0]
|
||||||
if rsp.Result != 0 {
|
if rsp.Result != 0 {
|
||||||
@ -629,7 +631,7 @@ func decodeGroupImageStoreResponse(_ *QQClient, _ uint16, payload []byte) (inter
|
|||||||
func decodeOffPicUpResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeOffPicUpResponse(_ *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 {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.FailMsg != "" {
|
if rsp.FailMsg != "" {
|
||||||
return imageUploadResponse{
|
return imageUploadResponse{
|
||||||
@ -740,7 +742,7 @@ func decodeOnlinePushReqPacket(c *QQClient, seq uint16, payload []byte) (interfa
|
|||||||
case 0x8A, 0x8B:
|
case 0x8A, 0x8B:
|
||||||
s8a := pb.Sub8A{}
|
s8a := pb.Sub8A{}
|
||||||
if err := proto.Unmarshal(probuf, &s8a); err != nil {
|
if err := proto.Unmarshal(probuf, &s8a); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
for _, m := range s8a.MsgInfo {
|
for _, m := range s8a.MsgInfo {
|
||||||
if m.ToUin == c.Uin {
|
if m.ToUin == c.Uin {
|
||||||
@ -754,7 +756,7 @@ func decodeOnlinePushReqPacket(c *QQClient, seq uint16, payload []byte) (interfa
|
|||||||
case 0xB3:
|
case 0xB3:
|
||||||
b3 := pb.SubB3{}
|
b3 := pb.SubB3{}
|
||||||
if err := proto.Unmarshal(probuf, &b3); err != nil {
|
if err := proto.Unmarshal(probuf, &b3); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
frd := &FriendInfo{
|
frd := &FriendInfo{
|
||||||
Uin: b3.MsgAddFrdNotify.Uin,
|
Uin: b3.MsgAddFrdNotify.Uin,
|
||||||
@ -765,7 +767,7 @@ func decodeOnlinePushReqPacket(c *QQClient, seq uint16, payload []byte) (interfa
|
|||||||
case 0xD4:
|
case 0xD4:
|
||||||
d4 := pb.SubD4{}
|
d4 := pb.SubD4{}
|
||||||
if err := proto.Unmarshal(probuf, &d4); err != nil {
|
if err := proto.Unmarshal(probuf, &d4); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
groupLeaveLock.Lock()
|
groupLeaveLock.Lock()
|
||||||
if g := c.FindGroup(d4.Uin); g != nil {
|
if g := c.FindGroup(d4.Uin); g != nil {
|
||||||
@ -795,7 +797,7 @@ func decodeOnlinePushReqPacket(c *QQClient, seq uint16, payload []byte) (interfa
|
|||||||
case 0x44:
|
case 0x44:
|
||||||
s44 := pb.Sub44{}
|
s44 := pb.Sub44{}
|
||||||
if err := proto.Unmarshal(probuf, &s44); err != nil {
|
if err := proto.Unmarshal(probuf, &s44); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if s44.GroupSyncMsg != nil {
|
if s44.GroupSyncMsg != nil {
|
||||||
func() {
|
func() {
|
||||||
@ -832,7 +834,7 @@ func decodeOnlinePushTransPacket(c *QQClient, _ uint16, payload []byte) (interfa
|
|||||||
info := msg.TransMsgInfo{}
|
info := msg.TransMsgInfo{}
|
||||||
err := proto.Unmarshal(payload, &info)
|
err := proto.Unmarshal(payload, &info)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
data := binary.NewReader(info.MsgData)
|
data := binary.NewReader(info.MsgData)
|
||||||
idStr := strconv.FormatInt(info.GetMsgUid(), 10)
|
idStr := strconv.FormatInt(info.GetMsgUid(), 10)
|
||||||
@ -938,7 +940,7 @@ func decodeOnlinePushTransPacket(c *QQClient, _ uint16, payload []byte) (interfa
|
|||||||
func decodeSystemMsgFriendPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeSystemMsgFriendPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
rsp := structmsg.RspSystemMsgNew{}
|
rsp := structmsg.RspSystemMsgNew{}
|
||||||
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if len(rsp.Friendmsgs) == 0 {
|
if len(rsp.Friendmsgs) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
@ -983,15 +985,15 @@ func decodeWordSegmentation(_ *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
pkg := oidb.OIDBSSOPkg{}
|
pkg := oidb.OIDBSSOPkg{}
|
||||||
rsp := &oidb.D79RspBody{}
|
rsp := &oidb.D79RspBody{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.Bodybuffer, rsp); err != nil {
|
if err := proto.Unmarshal(pkg.Bodybuffer, rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.Content != nil {
|
if rsp.Content != nil {
|
||||||
return rsp.Content.SliceContent, nil
|
return rsp.Content.SliceContent, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("no word receive")
|
return nil, errors.New("no word received")
|
||||||
}
|
}
|
||||||
|
|
||||||
// OidbSvc.0xe07_0
|
// OidbSvc.0xe07_0
|
||||||
@ -999,10 +1001,10 @@ func decodeImageOcrResponse(_ *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
pkg := oidb.OIDBSSOPkg{}
|
pkg := oidb.OIDBSSOPkg{}
|
||||||
rsp := oidb.DE07RspBody{}
|
rsp := oidb.DE07RspBody{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.Wording != "" {
|
if rsp.Wording != "" {
|
||||||
return nil, errors.New(rsp.Wording)
|
return nil, errors.New(rsp.Wording)
|
||||||
@ -1032,7 +1034,7 @@ func decodeImageOcrResponse(_ *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
func decodePttShortVideoDownResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodePttShortVideoDownResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
rsp := pttcenter.ShortVideoRspBody{}
|
rsp := pttcenter.ShortVideoRspBody{}
|
||||||
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.PttShortVideoDownloadRsp == nil || rsp.PttShortVideoDownloadRsp.DownloadAddr == nil {
|
if rsp.PttShortVideoDownloadRsp == nil || rsp.PttShortVideoDownloadRsp.DownloadAddr == nil {
|
||||||
return nil, errors.New("resp error")
|
return nil, errors.New("resp error")
|
||||||
@ -1045,13 +1047,13 @@ func decodeAppInfoResponse(_ *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
pkg := qweb.QWebRsp{}
|
pkg := qweb.QWebRsp{}
|
||||||
rsp := qweb.GetAppInfoByIdRsp{}
|
rsp := qweb.GetAppInfoByIdRsp{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if pkg.RetCode != 0 {
|
if pkg.RetCode != 0 {
|
||||||
return nil, errors.New(pkg.ErrMsg)
|
return nil, errors.New(pkg.ErrMsg)
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.BusiBuff, &rsp); err != nil {
|
if err := proto.Unmarshal(pkg.BusiBuff, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
return rsp.AppInfo, nil
|
return rsp.AppInfo, nil
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -2,8 +2,10 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
"runtime/debug"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
type eventHandlers struct {
|
type eventHandlers struct {
|
||||||
@ -383,7 +385,7 @@ func (c *QQClient) dispatchLogEvent(e *LogEvent) {
|
|||||||
func cover(f func()) {
|
func cover(f func()) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if pan := recover(); pan != nil {
|
if pan := recover(); pan != nil {
|
||||||
fmt.Println("event error:", pan)
|
fmt.Printf("event error: %v\n%s", pan, debug.Stack())
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
f()
|
f()
|
||||||
|
@ -5,6 +5,12 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/rand"
|
||||||
|
"net"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
devinfo "github.com/Mrs4s/MiraiGo/client/pb"
|
devinfo "github.com/Mrs4s/MiraiGo/client/pb"
|
||||||
@ -12,12 +18,8 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"math/rand"
|
|
||||||
"net"
|
|
||||||
"sort"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeviceInfo struct {
|
type DeviceInfo struct {
|
||||||
@ -232,7 +234,7 @@ func (info *DeviceInfo) ToJson() []byte {
|
|||||||
func (info *DeviceInfo) ReadJson(d []byte) error {
|
func (info *DeviceInfo) ReadJson(d []byte) error {
|
||||||
var f DeviceInfoFile
|
var f DeviceInfoFile
|
||||||
if err := json.Unmarshal(d, &f); err != nil {
|
if err := json.Unmarshal(d, &f); err != nil {
|
||||||
return err
|
return errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
info.Display = []byte(f.Display)
|
info.Display = []byte(f.Display)
|
||||||
if f.Product != "" {
|
if f.Product != "" {
|
||||||
@ -287,7 +289,7 @@ func (info *DeviceInfo) GenDeviceInfoData() []byte {
|
|||||||
}
|
}
|
||||||
data, err := proto.Marshal(m)
|
data, err := proto.Marshal(m)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(errors.Wrap(err, "failed to unmarshal protobuf message"))
|
||||||
}
|
}
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
@ -317,7 +319,7 @@ func getSSOAddress() ([]*net.TCPAddr, error) {
|
|||||||
})
|
})
|
||||||
})))
|
})))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "unable to fetch server list")
|
||||||
}
|
}
|
||||||
rspPkt := &jce.RequestPacket{}
|
rspPkt := &jce.RequestPacket{}
|
||||||
data := &jce.RequestDataVersion2{}
|
data := &jce.RequestDataVersion2{}
|
||||||
@ -344,7 +346,7 @@ func qualityTest(addr *net.TCPAddr) (int64, error) {
|
|||||||
start := time.Now()
|
start := time.Now()
|
||||||
conn, err := net.DialTimeout("tcp", addr.String(), time.Second*5)
|
conn, err := net.DialTimeout("tcp", addr.String(), time.Second*5)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, errors.Wrap(err, "failed to connect to server during quality test")
|
||||||
}
|
}
|
||||||
_ = conn.Close()
|
_ = conn.Close()
|
||||||
end := time.Now()
|
end := time.Now()
|
||||||
@ -418,7 +420,7 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage {
|
|||||||
c.Debug("sync group %v.", m.Head.GroupInfo.GroupCode)
|
c.Debug("sync group %v.", m.Head.GroupInfo.GroupCode)
|
||||||
info, err := c.GetGroupInfo(m.Head.GroupInfo.GetGroupCode())
|
info, err := c.GetGroupInfo(m.Head.GroupInfo.GetGroupCode())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error("error to sync group %v : %v", m.Head.GroupInfo.GroupCode, err)
|
c.Error("error to sync group %v : %+v", m.Head.GroupInfo.GroupCode, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
group = info
|
group = info
|
||||||
@ -427,7 +429,7 @@ func (c *QQClient) parseGroupMessage(m *msg.Message) *message.GroupMessage {
|
|||||||
if len(group.Members) == 0 {
|
if len(group.Members) == 0 {
|
||||||
mem, err := c.GetGroupMembers(group)
|
mem, err := c.GetGroupMembers(group)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error("error to sync group %v member : %v", m.Head.GroupInfo.GroupCode, err)
|
c.Error("error to sync group %v member : %+v", m.Head.GroupInfo.GroupCode, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
group.Members = mem
|
group.Members = mem
|
||||||
@ -590,16 +592,23 @@ func genLongTemplate(resId, brief string, ts int64) *message.SendingMessage {
|
|||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) Info(msg string, args ...interface{}) {
|
func (c *QQClient) Error(msg string, args ...interface{}) {
|
||||||
c.dispatchLogEvent(&LogEvent{
|
c.dispatchLogEvent(&LogEvent{
|
||||||
Type: "INFO",
|
Type: "ERROR",
|
||||||
Message: fmt.Sprintf(msg, args...),
|
Message: fmt.Sprintf(msg, args...),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) Error(msg string, args ...interface{}) {
|
func (c *QQClient) Warning(msg string, args ...interface{}) {
|
||||||
c.dispatchLogEvent(&LogEvent{
|
c.dispatchLogEvent(&LogEvent{
|
||||||
Type: "ERROR",
|
Type: "WARNING",
|
||||||
|
Message: fmt.Sprintf(msg, args...),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) Info(msg string, args ...interface{}) {
|
||||||
|
c.dispatchLogEvent(&LogEvent{
|
||||||
|
Type: "INFO",
|
||||||
Message: fmt.Sprintf(msg, args...),
|
Message: fmt.Sprintf(msg, args...),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -610,3 +619,10 @@ func (c *QQClient) Debug(msg string, args ...interface{}) {
|
|||||||
Message: fmt.Sprintf(msg, args...),
|
Message: fmt.Sprintf(msg, args...),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) Trace(msg string, args ...interface{}) {
|
||||||
|
c.dispatchLogEvent(&LogEvent{
|
||||||
|
Type: "TRACE",
|
||||||
|
Message: fmt.Sprintf(msg, args...),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -2,11 +2,13 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@ -48,7 +50,7 @@ type (
|
|||||||
func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err error) {
|
func (c *QQClient) GetGroupFileSystem(groupCode int64) (fs *GroupFileSystem, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if pan := recover(); pan != nil {
|
if pan := recover(); pan != nil {
|
||||||
c.Error("get group fs error: %v", pan)
|
c.Error("get group fs error: %v\n%s", pan, debug.Stack())
|
||||||
err = errors.New("fs error")
|
err = errors.New("fs error")
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
@ -264,10 +266,10 @@ func decodeOIDB6d81Response(c *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
pkg := oidb.OIDBSSOPkg{}
|
pkg := oidb.OIDBSSOPkg{}
|
||||||
rsp := oidb.D6D8RspBody{}
|
rsp := oidb.D6D8RspBody{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
return &rsp, nil
|
return &rsp, nil
|
||||||
}
|
}
|
||||||
@ -277,10 +279,10 @@ func decodeOIDB6d62Response(_ *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
pkg := oidb.OIDBSSOPkg{}
|
pkg := oidb.OIDBSSOPkg{}
|
||||||
rsp := oidb.D6D6RspBody{}
|
rsp := oidb.D6D6RspBody{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.DownloadFileRsp.DownloadUrl == nil {
|
if rsp.DownloadFileRsp.DownloadUrl == nil {
|
||||||
return nil, errors.New(rsp.DownloadFileRsp.ClientWording)
|
return nil, errors.New(rsp.DownloadFileRsp.ClientWording)
|
||||||
@ -294,10 +296,10 @@ func decodeOIDB6d63Response(_ *QQClient, _ uint16, payload []byte) (interface{},
|
|||||||
pkg := oidb.OIDBSSOPkg{}
|
pkg := oidb.OIDBSSOPkg{}
|
||||||
rsp := oidb.D6D6RspBody{}
|
rsp := oidb.D6D6RspBody{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.DeleteFileRsp == nil {
|
if rsp.DeleteFileRsp == nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -120,10 +120,10 @@ func decodeGroupInfoResponse(c *QQClient, _ uint16, payload []byte) (interface{}
|
|||||||
pkg := oidb.OIDBSSOPkg{}
|
pkg := oidb.OIDBSSOPkg{}
|
||||||
rsp := oidb.D88DRspBody{}
|
rsp := oidb.D88DRspBody{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if len(rsp.RspGroupInfo) == 0 {
|
if len(rsp.RspGroupInfo) == 0 {
|
||||||
return nil, errors.New(string(rsp.StrErrorInfo))
|
return nil, errors.New(string(rsp.StrErrorInfo))
|
||||||
|
@ -5,15 +5,16 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
binary2 "encoding/binary"
|
binary2 "encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb"
|
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
|
||||||
"google.golang.org/protobuf/proto"
|
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/pb"
|
||||||
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *QQClient) highwayUpload(ip uint32, port int, updKey, data []byte, cmdId int32) error {
|
func (c *QQClient) highwayUpload(ip uint32, port int, updKey, data []byte, cmdId int32) error {
|
||||||
@ -24,7 +25,7 @@ func (c *QQClient) highwayUpload(ip uint32, port int, updKey, data []byte, cmdId
|
|||||||
binary2.LittleEndian.PutUint32(addr.IP, ip)
|
binary2.LittleEndian.PutUint32(addr.IP, ip)
|
||||||
conn, err := net.DialTCP("tcp", nil, &addr)
|
conn, err := net.DialTCP("tcp", nil, &addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "failed to connect to highway server")
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
h := md5.Sum(data)
|
h := md5.Sum(data)
|
||||||
@ -33,11 +34,11 @@ func (c *QQClient) highwayUpload(ip uint32, port int, updKey, data []byte, cmdId
|
|||||||
for _, p := range pkt {
|
for _, p := range pkt {
|
||||||
_, err = conn.Write(p)
|
_, err = conn.Write(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "failed to write")
|
||||||
}
|
}
|
||||||
_, err = r.ReadByte()
|
_, err = r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "failed to read byte")
|
||||||
}
|
}
|
||||||
hl, _ := r.ReadInt32()
|
hl, _ := r.ReadInt32()
|
||||||
a2, _ := r.ReadInt32()
|
a2, _ := r.ReadInt32()
|
||||||
@ -46,7 +47,7 @@ func (c *QQClient) highwayUpload(ip uint32, port int, updKey, data []byte, cmdId
|
|||||||
r.ReadByte()
|
r.ReadByte()
|
||||||
rsp := new(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 errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if rsp.ErrorCode != 0 {
|
if rsp.ErrorCode != 0 {
|
||||||
return errors.New("upload failed")
|
return errors.New("upload failed")
|
||||||
@ -79,7 +80,7 @@ func (c *QQClient) uploadPtt(ip string, port int32, updKey, fileKey, data, md5 [
|
|||||||
hex.Encode(url[p:], md5)
|
hex.Encode(url[p:], md5)
|
||||||
url = append(url, "&mType=pttDu&voice_encodec=1"...)
|
url = append(url, "&mType=pttDu&voice_encodec=1"...)
|
||||||
_, err := utils.HttpPostBytes(string(url), data)
|
_, err := utils.HttpPostBytes(string(url), data)
|
||||||
return err
|
return errors.Wrap(err, "failed to upload ptt")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) uploadGroupHeadPortrait(groupCode int64, img []byte) error {
|
func (c *QQClient) uploadGroupHeadPortrait(groupCode int64, img []byte) error {
|
||||||
@ -95,7 +96,7 @@ func (c *QQClient) uploadGroupHeadPortrait(groupCode int64, img []byte) error {
|
|||||||
req.Header["Content-Type"] = []string{"multipart/form-data;boundary=****"}
|
req.Header["Content-Type"] = []string{"multipart/form-data;boundary=****"}
|
||||||
rsp, err := http.DefaultClient.Do(req)
|
rsp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return errors.Wrap(err, "failed to upload group head portrait")
|
||||||
}
|
}
|
||||||
rsp.Body.Close()
|
rsp.Body.Close()
|
||||||
return nil
|
return nil
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/longmsg"
|
"github.com/Mrs4s/MiraiGo/client/pb/longmsg"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/multimsg"
|
"github.com/Mrs4s/MiraiGo/client/pb/multimsg"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ func (c *QQClient) buildMultiApplyUpPacket(data, hash []byte, buType int32, grou
|
|||||||
func decodeMultiApplyUpResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeMultiApplyUpResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
body := multimsg.MultiRspBody{}
|
body := multimsg.MultiRspBody{}
|
||||||
if err := proto.Unmarshal(payload, &body); err != nil {
|
if err := proto.Unmarshal(payload, &body); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if len(body.MultimsgApplyupRsp) == 0 {
|
if len(body.MultimsgApplyupRsp) == 0 {
|
||||||
return nil, errors.New("rsp is empty")
|
return nil, errors.New("rsp is empty")
|
||||||
@ -52,7 +53,7 @@ func decodeMultiApplyUpResponse(_ *QQClient, _ uint16, payload []byte) (interfac
|
|||||||
case 193:
|
case 193:
|
||||||
return nil, errors.New("too large")
|
return nil, errors.New("too large")
|
||||||
}
|
}
|
||||||
return nil, errors.New("failed")
|
return nil, errors.Errorf("unexpected multimsg apply up response: %d", rsp.Result)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MultiMsg.ApplyDown
|
// MultiMsg.ApplyDown
|
||||||
@ -82,7 +83,7 @@ func (c *QQClient) buildMultiApplyDownPacket(resId string) (uint16, []byte) {
|
|||||||
func decodeMultiApplyDownResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
func decodeMultiApplyDownResponse(_ *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||||
body := multimsg.MultiRspBody{}
|
body := multimsg.MultiRspBody{}
|
||||||
if err := proto.Unmarshal(payload, &body); err != nil {
|
if err := proto.Unmarshal(payload, &body); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if len(body.MultimsgApplydownRsp) == 0 {
|
if len(body.MultimsgApplydownRsp) == 0 {
|
||||||
return nil, errors.New("not found")
|
return nil, errors.New("not found")
|
||||||
@ -96,7 +97,7 @@ func decodeMultiApplyDownResponse(_ *QQClient, _ uint16, payload []byte) (interf
|
|||||||
}()
|
}()
|
||||||
b, err := utils.HttpGetBytes(fmt.Sprintf("%s%s", prefix, string(rsp.ThumbDownPara)), "")
|
b, err := utils.HttpGetBytes(fmt.Sprintf("%s%s", prefix, string(rsp.ThumbDownPara)), "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to download by multi apply down")
|
||||||
}
|
}
|
||||||
if b[0] != 40 {
|
if b[0] != 40 {
|
||||||
return nil, errors.New("unexpected body data")
|
return nil, errors.New("unexpected body data")
|
||||||
@ -111,12 +112,12 @@ func decodeMultiApplyDownResponse(_ *QQClient, _ uint16, payload []byte) (interf
|
|||||||
data := tea.Decrypt(r.ReadBytes(int(i2)))
|
data := tea.Decrypt(r.ReadBytes(int(i2)))
|
||||||
lb := longmsg.LongRspBody{}
|
lb := longmsg.LongRspBody{}
|
||||||
if err = proto.Unmarshal(data, &lb); err != nil {
|
if err = proto.Unmarshal(data, &lb); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
uc := binary.GZipUncompress(lb.MsgDownRsp[0].MsgContent)
|
uc := binary.GZipUncompress(lb.MsgDownRsp[0].MsgContent)
|
||||||
mt := msg.PbMultiMsgTransmit{}
|
mt := msg.PbMultiMsgTransmit{}
|
||||||
if err = proto.Unmarshal(uc, &mt); err != nil {
|
if err = proto.Unmarshal(uc, &mt); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
return &mt, nil
|
return &mt, nil
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x346"
|
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x346"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ func decodeOfflineFileDownloadResponse(c *QQClient, _ uint16, payload []byte) (i
|
|||||||
rsp := cmd0x346.C346RspBody{}
|
rsp := cmd0x346.C346RspBody{}
|
||||||
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
||||||
c.Error("unmarshal cmd0x346 rsp body error: %v", err)
|
c.Error("unmarshal cmd0x346 rsp body error: %v", err)
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "unmarshal cmd0x346 rsp body error")
|
||||||
}
|
}
|
||||||
if rsp.ApplyDownloadRsp == nil {
|
if rsp.ApplyDownloadRsp == nil {
|
||||||
c.Error("decode apply download 1200 error: apply rsp is nil.")
|
c.Error("decode apply download 1200 error: apply rsp is nil.")
|
||||||
@ -41,7 +40,7 @@ func decodeOfflineFileDownloadResponse(c *QQClient, _ uint16, payload []byte) (i
|
|||||||
}
|
}
|
||||||
if rsp.ApplyDownloadRsp.RetCode != 0 {
|
if rsp.ApplyDownloadRsp.RetCode != 0 {
|
||||||
c.Error("decode apply download 1200 error: %v", rsp.ApplyDownloadRsp.RetCode)
|
c.Error("decode apply download 1200 error: %v", rsp.ApplyDownloadRsp.RetCode)
|
||||||
return nil, errors.New(fmt.Sprint(rsp.ApplyDownloadRsp.RetCode))
|
return nil, errors.Errorf("apply download rsp error: %d", rsp.ApplyDownloadRsp.RetCode)
|
||||||
}
|
}
|
||||||
return "http://" + rsp.ApplyDownloadRsp.DownloadInfo.DownloadDomain + rsp.ApplyDownloadRsp.DownloadInfo.DownloadUrl, nil
|
return "http://" + rsp.ApplyDownloadRsp.DownloadInfo.DownloadDomain + rsp.ApplyDownloadRsp.DownloadInfo.DownloadUrl, nil
|
||||||
}
|
}
|
||||||
|
@ -3,14 +3,14 @@ package client
|
|||||||
import (
|
import (
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"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/client/pb/cmd0x346"
|
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x346"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ func decodeGroupPttStoreResponse(_ *QQClient, _ uint16, payload []byte) (interfa
|
|||||||
pkt := pb.D388RespBody{}
|
pkt := pb.D388RespBody{}
|
||||||
err := proto.Unmarshal(payload, &pkt)
|
err := proto.Unmarshal(payload, &pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
rsp := pkt.MsgTryUpPttRsp[0]
|
rsp := pkt.MsgTryUpPttRsp[0]
|
||||||
if rsp.Result != 0 {
|
if rsp.Result != 0 {
|
||||||
@ -180,7 +180,7 @@ func decodePrivatePttStoreResponse(c *QQClient, _ uint16, payload []byte) (inter
|
|||||||
rsp := cmd0x346.C346RspBody{}
|
rsp := cmd0x346.C346RspBody{}
|
||||||
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
if err := proto.Unmarshal(payload, &rsp); err != nil {
|
||||||
c.Error("unmarshal cmd0x346 rsp body error: %v", err)
|
c.Error("unmarshal cmd0x346 rsp body error: %v", err)
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "unmarshal cmd0x346 rsp body error")
|
||||||
}
|
}
|
||||||
if rsp.ApplyUploadRsp == nil {
|
if rsp.ApplyUploadRsp == nil {
|
||||||
c.Error("decode apply upload 500 error: apply rsp is nil.")
|
c.Error("decode apply upload 500 error: apply rsp is nil.")
|
||||||
@ -188,7 +188,7 @@ func decodePrivatePttStoreResponse(c *QQClient, _ uint16, payload []byte) (inter
|
|||||||
}
|
}
|
||||||
if rsp.ApplyUploadRsp.RetCode != 0 {
|
if rsp.ApplyUploadRsp.RetCode != 0 {
|
||||||
c.Error("decode apply upload 500 error: %v", rsp.ApplyUploadRsp.RetCode)
|
c.Error("decode apply upload 500 error: %v", rsp.ApplyUploadRsp.RetCode)
|
||||||
return nil, errors.New(fmt.Sprint(rsp.ApplyUploadRsp.RetCode))
|
return nil, errors.Errorf("apply upload rsp error: %d", rsp.ApplyUploadRsp.RetCode)
|
||||||
}
|
}
|
||||||
if rsp.ApplyUploadRsp.BoolFileExist {
|
if rsp.ApplyUploadRsp.BoolFileExist {
|
||||||
return pttUploadResponse{IsExists: true}, nil
|
return pttUploadResponse{IsExists: true}, nil
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||||
"github.com/Mrs4s/MiraiGo/message"
|
"github.com/Mrs4s/MiraiGo/message"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
"github.com/pkg/errors"
|
||||||
"google.golang.org/protobuf/proto"
|
"google.golang.org/protobuf/proto"
|
||||||
"math/rand"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type RichClientInfo struct {
|
type RichClientInfo struct {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
"github.com/Mrs4s/MiraiGo/client/pb/oidb"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
"github.com/Mrs4s/MiraiGo/protocol/packets"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *QQClient) buildTranslatePacket(src, dst, text string) (uint16, []byte) {
|
func (c *QQClient) buildTranslatePacket(src, dst, text string) (uint16, []byte) {
|
||||||
@ -46,10 +46,10 @@ func decodeTranslateResponse(c *QQClient, _ uint16, payload []byte) (interface{}
|
|||||||
pkg := oidb.OIDBSSOPkg{}
|
pkg := oidb.OIDBSSOPkg{}
|
||||||
rsp := oidb.TranslateRspBody{}
|
rsp := oidb.TranslateRspBody{}
|
||||||
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
if err := proto.Unmarshal(payload, &pkg); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
if err := proto.Unmarshal(pkg.Bodybuffer, &rsp); err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
return rsp.BatchTranslateRsp, nil
|
return rsp.BatchTranslateRsp, nil
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/richmedia"
|
"github.com/Mrs4s/MiraiGo/client/pb/richmedia"
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *QQClient) GetTts(text string) ([]byte, error) {
|
func (c *QQClient) GetTts(text string) ([]byte, error) {
|
||||||
@ -14,7 +15,7 @@ func (c *QQClient) GetTts(text string) ([]byte, error) {
|
|||||||
data := fmt.Sprintf("{\"appid\": \"201908021016\",\"sendUin\": %v,\"text\": \"%v\"}", c.Uin, text)
|
data := fmt.Sprintf("{\"appid\": \"201908021016\",\"sendUin\": %v,\"text\": \"%v\"}", c.Uin, text)
|
||||||
rsp, err := utils.HttpPostBytesWithCookie(url, []byte(data), c.getCookies())
|
rsp, err := utils.HttpPostBytesWithCookie(url, []byte(data), c.getCookies())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to post to tts server")
|
||||||
}
|
}
|
||||||
ttsReader := binary.NewReader(rsp)
|
ttsReader := binary.NewReader(rsp)
|
||||||
ttsWriter := binary.NewWriter()
|
ttsWriter := binary.NewWriter()
|
||||||
@ -34,7 +35,7 @@ func (c *QQClient) GetTts(text string) ([]byte, error) {
|
|||||||
ttsRsp := &richmedia.TtsRspBody{}
|
ttsRsp := &richmedia.TtsRspBody{}
|
||||||
err := proto.Unmarshal(ttsReader.ReadBytes(length), ttsRsp)
|
err := proto.Unmarshal(ttsReader.ReadBytes(length), ttsRsp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, errors.Wrap(err, "failed to unmarshal protobuf message")
|
||||||
}
|
}
|
||||||
if ttsRsp.RetCode != 0 {
|
if ttsRsp.RetCode != 0 {
|
||||||
return nil, errors.New("can't convert text to voice")
|
return nil, errors.New("can't convert text to voice")
|
||||||
|
3
go.mod
3
go.mod
@ -4,6 +4,7 @@ go 1.14
|
|||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/golang/protobuf v1.4.3
|
github.com/golang/protobuf v1.4.3
|
||||||
github.com/tidwall/gjson v1.6.1
|
github.com/pkg/errors v0.9.1
|
||||||
|
github.com/tidwall/gjson v1.6.3
|
||||||
google.golang.org/protobuf v1.25.0
|
google.golang.org/protobuf v1.25.0
|
||||||
)
|
)
|
||||||
|
8
go.sum
8
go.sum
@ -15,8 +15,6 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W
|
|||||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||||
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
|
github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0=
|
||||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||||
github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
|
|
||||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
|
||||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||||
@ -25,9 +23,11 @@ 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.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 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/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
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/tidwall/gjson v1.6.1 h1:LRbvNuNuvAiISWg6gxLEFuCe72UKy5hDqhxW/8183ws=
|
github.com/tidwall/gjson v1.6.3 h1:aHoiiem0dr7GHkW001T1SMTJ7X5PvyekH5WX0whWGnI=
|
||||||
github.com/tidwall/gjson v1.6.1/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
|
github.com/tidwall/gjson v1.6.3/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
|
||||||
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
|
github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc=
|
||||||
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E=
|
||||||
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
|
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
package packets
|
package packets
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
"github.com/Mrs4s/MiraiGo/protocol/crypto"
|
"github.com/Mrs4s/MiraiGo/protocol/crypto"
|
||||||
"strconv"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var ErrUnknownFlag = errors.New("unknown flag")
|
var ErrUnknownFlag = errors.New("unknown flag")
|
||||||
@ -88,13 +89,13 @@ func BuildSsoPacket(seq uint16, appId uint32, commandName, imei string, extData,
|
|||||||
|
|
||||||
func ParseIncomingPacket(payload, d2key []byte) (*IncomingPacket, error) {
|
func ParseIncomingPacket(payload, d2key []byte) (*IncomingPacket, error) {
|
||||||
if len(payload) < 6 {
|
if len(payload) < 6 {
|
||||||
return nil, ErrInvalidPayload
|
return nil, errors.WithStack(ErrInvalidPayload)
|
||||||
}
|
}
|
||||||
reader := binary.NewReader(payload)
|
reader := binary.NewReader(payload)
|
||||||
flag1 := reader.ReadInt32()
|
flag1 := reader.ReadInt32()
|
||||||
flag2 := reader.ReadByte()
|
flag2 := reader.ReadByte()
|
||||||
if reader.ReadByte() != 0 { // flag3
|
if reader.ReadByte() != 0 { // flag3
|
||||||
return nil, ErrUnknownFlag
|
return nil, errors.WithStack(ErrUnknownFlag)
|
||||||
}
|
}
|
||||||
reader.ReadString() // uin string
|
reader.ReadString() // uin string
|
||||||
decrypted := func() (data []byte) {
|
decrypted := func() (data []byte) {
|
||||||
@ -111,10 +112,10 @@ func ParseIncomingPacket(payload, d2key []byte) (*IncomingPacket, error) {
|
|||||||
return nil
|
return nil
|
||||||
}()
|
}()
|
||||||
if len(decrypted) == 0 {
|
if len(decrypted) == 0 {
|
||||||
return nil, ErrDecryptFailed
|
return nil, errors.WithStack(ErrDecryptFailed)
|
||||||
}
|
}
|
||||||
if flag1 != 0x0A && flag1 != 0x0B {
|
if flag1 != 0x0A && flag1 != 0x0B {
|
||||||
return nil, ErrDecryptFailed
|
return nil, errors.WithStack(ErrDecryptFailed)
|
||||||
}
|
}
|
||||||
return parseSsoFrame(decrypted, flag2)
|
return parseSsoFrame(decrypted, flag2)
|
||||||
}
|
}
|
||||||
@ -122,13 +123,13 @@ func ParseIncomingPacket(payload, d2key []byte) (*IncomingPacket, error) {
|
|||||||
func parseSsoFrame(payload []byte, flag2 byte) (*IncomingPacket, error) {
|
func parseSsoFrame(payload []byte, flag2 byte) (*IncomingPacket, error) {
|
||||||
reader := binary.NewReader(payload)
|
reader := binary.NewReader(payload)
|
||||||
if reader.ReadInt32()-4 > int32(reader.Len()) {
|
if reader.ReadInt32()-4 > int32(reader.Len()) {
|
||||||
return nil, ErrPacketDropped
|
return nil, errors.WithStack(ErrPacketDropped)
|
||||||
}
|
}
|
||||||
seqId := reader.ReadInt32()
|
seqId := reader.ReadInt32()
|
||||||
retCode := reader.ReadInt32()
|
retCode := reader.ReadInt32()
|
||||||
if retCode != 0 {
|
if retCode != 0 {
|
||||||
if retCode == -10008 {
|
if retCode == -10008 {
|
||||||
return nil, ErrSessionExpired
|
return nil, errors.WithStack(ErrSessionExpired)
|
||||||
}
|
}
|
||||||
return nil, errors.New("return code unsuccessful: " + strconv.FormatInt(int64(retCode), 10))
|
return nil, errors.New("return code unsuccessful: " + strconv.FormatInt(int64(retCode), 10))
|
||||||
}
|
}
|
||||||
@ -208,5 +209,5 @@ func (pkt *IncomingPacket) DecryptPayload(random, sessionKey []byte) ([]byte, er
|
|||||||
if encryptType == 4 {
|
if encryptType == 4 {
|
||||||
panic("todo")
|
panic("todo")
|
||||||
}
|
}
|
||||||
return nil, ErrUnknownFlag
|
return nil, errors.WithStack(ErrUnknownFlag)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user