mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
Merge
merge
This commit is contained in:
commit
ebdcad5168
@ -6,6 +6,8 @@ qq-android协议的golang实现 移植于mirai
|
||||
|
||||
建议基于 [go-cqhttp](https://github.com/Mrs4s/go-cqhttp) 使用框架开发。
|
||||
|
||||
同时提供不基于 CQHTTP 的原生框架 [MiraiGo-Template](https://github.com/Logiase/MiraiGo-Template) 进行开发。
|
||||
|
||||
# 已完成功能/开发计划
|
||||
#### 登录
|
||||
- [x] 账号密码登录
|
||||
|
@ -40,9 +40,9 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) {
|
||||
|
||||
w.Write(tlv.T18(16, uint32(c.Uin)))
|
||||
w.Write(tlv.T1(uint32(c.Uin), SystemDeviceInfo.IpAddress))
|
||||
w.Write(tlv.T106(uint32(c.Uin), 0, uint32(SystemDeviceInfo.Protocol), c.PasswordMd5, true, SystemDeviceInfo.Guid, SystemDeviceInfo.TgtgtKey))
|
||||
w.Write(tlv.T106(uint32(c.Uin), 0, uint32(SystemDeviceInfo.Protocol), c.PasswordMd5, true, SystemDeviceInfo.Guid, SystemDeviceInfo.TgtgtKey, 0))
|
||||
w.Write(tlv.T116(184024956, 0x10400))
|
||||
w.Write(tlv.T100(uint32(SystemDeviceInfo.Protocol)))
|
||||
w.Write(tlv.T100(uint32(SystemDeviceInfo.Protocol), 34869472))
|
||||
w.Write(tlv.T107(0))
|
||||
w.Write(tlv.T142("com.tencent.mobileqq"))
|
||||
w.Write(tlv.T144(
|
||||
@ -127,6 +127,54 @@ func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byt
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
req := packets.BuildOicqRequestPacket(c.Uin, 0x0810, crypto.NewEncryptSession(c.sigInfo.t133), c.sigInfo.wtSessionTicketKey, func(w *binary.Writer) {
|
||||
w.WriteUInt16(15)
|
||||
w.WriteUInt16(21)
|
||||
|
||||
w.Write(tlv.T18(16, uint32(c.Uin)))
|
||||
w.Write(tlv.T1(uint32(c.Uin), SystemDeviceInfo.IpAddress))
|
||||
w.Write(tlv.T106(uint32(c.Uin), 0, uint32(SystemDeviceInfo.Protocol), c.PasswordMd5, true, SystemDeviceInfo.Guid, SystemDeviceInfo.TgtgtKey, 1))
|
||||
w.Write(tlv.T116(150470524, 66560))
|
||||
w.Write(tlv.T100(2, 34869472))
|
||||
w.Write(tlv.T107(0))
|
||||
w.Write(tlv.T144(
|
||||
SystemDeviceInfo.AndroidId,
|
||||
SystemDeviceInfo.GenDeviceInfoData(),
|
||||
SystemDeviceInfo.OSType,
|
||||
SystemDeviceInfo.Version.Release,
|
||||
SystemDeviceInfo.SimInfo,
|
||||
SystemDeviceInfo.APN,
|
||||
false, true, false, tlv.GuidFlag(),
|
||||
SystemDeviceInfo.Model,
|
||||
SystemDeviceInfo.Guid,
|
||||
SystemDeviceInfo.Brand,
|
||||
SystemDeviceInfo.TgtgtKey,
|
||||
))
|
||||
w.Write(tlv.T142("com.tencent.mobileqq"))
|
||||
w.Write(tlv.T145(SystemDeviceInfo.Guid))
|
||||
w.Write(tlv.T16A(c.sigInfo.srmToken))
|
||||
w.Write(tlv.T154(seq))
|
||||
w.Write(tlv.T141(SystemDeviceInfo.SimInfo, SystemDeviceInfo.APN))
|
||||
w.Write(tlv.T8(2052))
|
||||
w.Write(tlv.T511([]string{
|
||||
"tenpay.com", "openmobile.qq.com", "docs.qq.com", "connect.qq.com",
|
||||
"qzone.qq.com", "vip.qq.com", "qun.qq.com", "game.qq.com", "qqweb.qq.com",
|
||||
"office.qq.com", "ti.qq.com", "mail.qq.com", "qzone.com", "mma.qq.com",
|
||||
}))
|
||||
w.Write(tlv.T147(16, []byte("8.2.7"), []byte{0xA6, 0xB7, 0x45, 0xBF, 0x24, 0xA2, 0xC2, 0x77, 0x52, 0x77, 0x16, 0xF6, 0xF3, 0x6E, 0xB6, 0x8D}))
|
||||
w.Write(tlv.T177())
|
||||
w.Write(tlv.T187(SystemDeviceInfo.MacAddress))
|
||||
w.Write(tlv.T188(SystemDeviceInfo.AndroidId))
|
||||
w.Write(tlv.T194(SystemDeviceInfo.IMSIMd5))
|
||||
w.Write(tlv.T202(SystemDeviceInfo.WifiBSSID, SystemDeviceInfo.WifiSSID))
|
||||
w.Write(tlv.T516())
|
||||
})
|
||||
packet := packets.BuildUniPacket(c.Uin, seq, "wtlogin.exchange_emp", 2, c.OutGoingPacketSessionId, []byte{}, make([]byte, 16), req)
|
||||
return seq, packet
|
||||
}
|
||||
|
||||
// StatSvc.register
|
||||
func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
|
||||
seq := c.nextSeq()
|
||||
|
@ -94,6 +94,7 @@ type loginSigInfo struct {
|
||||
userStKey []byte
|
||||
userStWebSig []byte
|
||||
sKey []byte
|
||||
sKeyExpiredTime int64
|
||||
d2 []byte
|
||||
d2Key []byte
|
||||
wtSessionTicketKey []byte
|
||||
@ -121,6 +122,7 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
||||
OutGoingPacketSessionId: []byte{0x02, 0xB0, 0x5B, 0x8B},
|
||||
decoders: map[string]func(*QQClient, uint16, []byte) (interface{}, error){
|
||||
"wtlogin.login": decodeLoginResponse,
|
||||
"wtlogin.exchange_emp": decodeExchangeEmpResponse,
|
||||
"StatSvc.register": decodeClientRegisterResponse,
|
||||
"StatSvc.ReqMSFOffline": decodeMSFOfflinePacket,
|
||||
"StatSvc.GetDevLoginInfo": decodeDevListResponse,
|
||||
@ -849,6 +851,10 @@ func (c *QQClient) SolveFriendRequest(req *NewFriendRequest, accept bool) {
|
||||
}
|
||||
|
||||
func (c *QQClient) getCookies() string {
|
||||
if c.sigInfo.sKeyExpiredTime < time.Now().Unix() {
|
||||
c.Debug("skey expired. refresh...")
|
||||
_, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket())
|
||||
}
|
||||
return fmt.Sprintf("uin=o%d; skey=%s;", c.Uin, c.sigInfo.sKey)
|
||||
}
|
||||
|
||||
|
@ -127,6 +127,23 @@ func decodeClientRegisterResponse(_ *QQClient, _ uint16, payload []byte) (interf
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// wtlogin.exchange_emp
|
||||
func decodeExchangeEmpResponse(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||
reader := binary.NewReader(payload)
|
||||
cmd := reader.ReadUInt16()
|
||||
t := reader.ReadByte()
|
||||
reader.ReadUInt16()
|
||||
m := reader.ReadTlvMap(2)
|
||||
if t != 0 {
|
||||
c.Error("exchange_emp error: %v", t)
|
||||
return nil, nil
|
||||
}
|
||||
if cmd == 15 { // TODO: 免密登录
|
||||
c.decodeT119(m[0x119])
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ConfigPushSvc.PushReq
|
||||
func decodePushReqPacket(c *QQClient, _ uint16, payload []byte) (interface{}, error) {
|
||||
request := &jce.RequestPacket{}
|
||||
|
@ -23,7 +23,18 @@ func (c *QQClient) decodeT119(data []byte) {
|
||||
reader := binary.NewReader(tea.Decrypt(data))
|
||||
reader.ReadBytes(2)
|
||||
m := reader.ReadTlvMap(2)
|
||||
|
||||
if len(c.sigInfo.sKey) > 0 { // refresh
|
||||
if t120, ok := m[0x120]; ok {
|
||||
c.sigInfo.sKey = t120
|
||||
c.sigInfo.sKeyExpiredTime = time.Now().Unix() + 43200 // 86400 / 2
|
||||
c.Debug("skey updated: %v", c.sigInfo.sKey)
|
||||
}
|
||||
if t11a, ok := m[0x11a]; ok {
|
||||
c.Nickname, c.Age, c.Gender = readT11A(t11a)
|
||||
c.Debug("account info updated: " + c.Nickname)
|
||||
}
|
||||
return
|
||||
}
|
||||
if t130, ok := m[0x130]; ok {
|
||||
c.decodeT130(t130)
|
||||
}
|
||||
@ -79,6 +90,10 @@ func (c *QQClient) decodeT119(data []byte) {
|
||||
//a1, noPicSig = readT531(t531)
|
||||
}
|
||||
|
||||
if _, ok := m[0x138]; ok {
|
||||
//readT138(t138) // chg time
|
||||
}
|
||||
|
||||
c.sigInfo = &loginSigInfo{
|
||||
loginBitmap: 0,
|
||||
srmToken: m[0x16a],
|
||||
@ -88,6 +103,7 @@ func (c *QQClient) decodeT119(data []byte) {
|
||||
userStKey: m[0x10e],
|
||||
userStWebSig: m[0x103],
|
||||
sKey: m[0x120],
|
||||
sKeyExpiredTime: time.Now().Unix() + 43200, // 86400 / 2
|
||||
d2: m[0x143],
|
||||
d2Key: m[0x305],
|
||||
wtSessionTicketKey: m[0x134],
|
||||
|
@ -4,7 +4,7 @@ import (
|
||||
"github.com/Mrs4s/MiraiGo/binary"
|
||||
)
|
||||
|
||||
func T100(protocol uint32) []byte {
|
||||
func T100(protocol, mainSigMap uint32) []byte {
|
||||
return binary.NewWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt16(0x100)
|
||||
w.WriteTlv(binary.NewWriterF(func(w *binary.Writer) {
|
||||
@ -13,7 +13,7 @@ func T100(protocol uint32) []byte {
|
||||
w.WriteUInt32(16)
|
||||
w.WriteUInt32(protocol)
|
||||
w.WriteUInt32(0) // App client version
|
||||
w.WriteUInt32(34869472)
|
||||
w.WriteUInt32(mainSigMap) // 34869472
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func T106(uin, salt, protocol uint32, passwordMd5 [16]byte, guidAvailable bool, guid, tgtgtKey []byte) []byte {
|
||||
func T106(uin, salt, protocol uint32, passwordMd5 [16]byte, guidAvailable bool, guid, tgtgtKey []byte, wtf uint32) []byte {
|
||||
return binary.NewWriterF(func(w *binary.Writer) {
|
||||
w.WriteUInt16(0x106)
|
||||
body := binary.NewWriterF(func(w *binary.Writer) {
|
||||
@ -27,7 +27,7 @@ func T106(uin, salt, protocol uint32, passwordMd5 [16]byte, guidAvailable bool,
|
||||
w.WriteByte(0x01)
|
||||
w.Write(passwordMd5[:])
|
||||
w.Write(tgtgtKey)
|
||||
w.WriteUInt32(0)
|
||||
w.WriteUInt32(wtf)
|
||||
w.WriteBool(guidAvailable)
|
||||
if len(guid) == 0 {
|
||||
for i := 0; i < 4; i++ {
|
||||
|
Loading…
x
Reference in New Issue
Block a user