mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
143 lines
3.6 KiB
Go
143 lines
3.6 KiB
Go
package network
|
|
|
|
import (
|
|
"strconv"
|
|
|
|
"github.com/Mrs4s/MiraiGo/binary"
|
|
"github.com/Mrs4s/MiraiGo/client/internal/auth"
|
|
"github.com/Mrs4s/MiraiGo/client/pb"
|
|
"github.com/Mrs4s/MiraiGo/internal/proto"
|
|
"github.com/Mrs4s/MiraiGo/wrapper"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Transport is a network transport.
|
|
type Transport struct {
|
|
Sig *auth.SigInfo
|
|
Version *auth.AppVersion
|
|
Device *auth.Device
|
|
|
|
// connection
|
|
// conn *TCPClient
|
|
}
|
|
|
|
func (t *Transport) packBody(req *Request, w *binary.Writer) {
|
|
pos := w.FillUInt32()
|
|
if req.Type == RequestTypeLogin {
|
|
w.WriteUInt32(uint32(req.SequenceID))
|
|
w.WriteUInt32(t.Version.AppId)
|
|
w.WriteUInt32(t.Version.SubAppId)
|
|
w.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
|
tgt := t.Sig.TGT
|
|
if len(tgt) == 0 || len(tgt) == 4 {
|
|
w.WriteUInt32(0x04)
|
|
} else {
|
|
w.WriteUInt32(uint32(len(tgt) + 4))
|
|
w.Write(tgt)
|
|
}
|
|
}
|
|
w.WriteString(req.CommandName)
|
|
w.WriteUInt32(uint32(len(t.Sig.OutPacketSessionID) + 4))
|
|
w.Write(t.Sig.OutPacketSessionID)
|
|
if req.Type == RequestTypeLogin {
|
|
w.WriteString((*t.Device).IMEI)
|
|
w.WriteUInt32(0x04)
|
|
|
|
w.WriteUInt16(uint16(len(t.Sig.Ksid)) + 2)
|
|
w.Write(t.Sig.Ksid)
|
|
|
|
secSign := t.PackSecSign(req)
|
|
w.WriteUInt32(uint32(len(secSign) + 4))
|
|
w.Write(secSign)
|
|
}
|
|
if wrapper.AllowSignSendMsg != nil && wrapper.AllowSignSendMsg() && req.CommandName == "MessageSvc.PbSendMsg" {
|
|
secSign := t.PackSecSign(req)
|
|
w.WriteUInt32(uint32(len(secSign) + 4))
|
|
w.Write(secSign)
|
|
}
|
|
|
|
w.WriteUInt32(0x04 + uint32(len(t.Device.QImei16)))
|
|
w.Write([]byte(t.Device.QImei16))
|
|
|
|
w.WriteUInt32At(pos, uint32(w.Len()-pos))
|
|
|
|
w.WriteUInt32(uint32(len(req.Body) + 4))
|
|
w.Write(req.Body)
|
|
}
|
|
|
|
func (t *Transport) PackSecSign(req *Request) []byte {
|
|
if wrapper.FekitGetSign == nil {
|
|
return []byte{}
|
|
}
|
|
sign, extra, token, err := wrapper.FekitGetSign(uint64(req.SequenceID), strconv.FormatInt(req.Uin, 10), req.CommandName, "V1_AND_SQ_8.9.50_3898_YYB_D", req.Body)
|
|
m := &pb.SSOReserveField{
|
|
Flag: 0,
|
|
Qimei: t.Device.QImei16,
|
|
NewconnFlag: 0,
|
|
Uid: strconv.FormatInt(req.Uin, 10),
|
|
Imsi: 0,
|
|
NetworkType: 1,
|
|
IpStackType: 1,
|
|
MessageType: 0,
|
|
SecInfo: &pb.SsoSecureInfo{
|
|
SecSig: sign,
|
|
SecDeviceToken: token,
|
|
SecExtra: extra,
|
|
},
|
|
SsoIpOrigin: 0,
|
|
}
|
|
data, err := proto.Marshal(m)
|
|
if err != nil {
|
|
panic(errors.Wrap(err, "failed to unmarshal protobuf SSOReserveField"))
|
|
}
|
|
return data
|
|
}
|
|
|
|
// PackPacket packs a packet.
|
|
func (t *Transport) PackPacket(req *Request) []byte {
|
|
// todo(wdvxdr): combine pack packet, send packet and return the response
|
|
if len(t.Sig.D2) == 0 {
|
|
req.EncryptType = EncryptTypeEmptyKey
|
|
}
|
|
|
|
w := binary.SelectWriter()
|
|
defer binary.PutWriter(w)
|
|
|
|
pos := w.FillUInt32()
|
|
// vvv w.Write(head) vvv
|
|
w.WriteUInt32(uint32(req.Type))
|
|
w.WriteByte(byte(req.EncryptType))
|
|
switch req.Type {
|
|
case RequestTypeLogin:
|
|
switch req.EncryptType {
|
|
case EncryptTypeD2Key:
|
|
w.WriteUInt32(uint32(len(t.Sig.D2) + 4))
|
|
w.Write(t.Sig.D2)
|
|
default:
|
|
w.WriteUInt32(4)
|
|
}
|
|
case RequestTypeSimple:
|
|
w.WriteUInt32(uint32(req.SequenceID))
|
|
}
|
|
w.WriteByte(0x00)
|
|
w.WriteString(strconv.FormatInt(req.Uin, 10))
|
|
// ^^^ w.Write(head) ^^^
|
|
|
|
w2 := binary.SelectWriter()
|
|
t.packBody(req, w2)
|
|
body := w2.Bytes()
|
|
// encrypt body
|
|
switch req.EncryptType {
|
|
case EncryptTypeD2Key:
|
|
body = binary.NewTeaCipher(t.Sig.D2Key).Encrypt(body)
|
|
case EncryptTypeEmptyKey:
|
|
emptyKey := make([]byte, 16)
|
|
body = binary.NewTeaCipher(emptyKey).Encrypt(body)
|
|
}
|
|
w.Write(body)
|
|
binary.PutWriter(w2)
|
|
|
|
w.WriteUInt32At(pos, uint32(w.Len()))
|
|
return append([]byte(nil), w.Bytes()...)
|
|
}
|