mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 19:17:38 +08:00
client: pack packet by transport
This commit is contained in:
parent
3e2b57eab5
commit
d2dc2e472d
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/binary/jce"
|
"github.com/Mrs4s/MiraiGo/binary/jce"
|
||||||
"github.com/Mrs4s/MiraiGo/client/internal/auth"
|
"github.com/Mrs4s/MiraiGo/client/internal/auth"
|
||||||
"github.com/Mrs4s/MiraiGo/client/internal/codec"
|
"github.com/Mrs4s/MiraiGo/client/internal/codec"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/internal/network"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb"
|
"github.com/Mrs4s/MiraiGo/client/pb"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
|
"github.com/Mrs4s/MiraiGo/client/pb/cmd0x352"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
@ -90,9 +91,16 @@ func (c *QQClient) buildLoginPacket() (uint16, []byte) {
|
|||||||
w.Write(tlv.T521(0))
|
w.Write(tlv.T521(0))
|
||||||
w.Write(tlv.T525(tlv.T536([]byte{0x01, 0x00})))
|
w.Write(tlv.T525(tlv.T536([]byte{0x01, 0x00})))
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
|
func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
|
||||||
@ -102,13 +110,19 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
|
|||||||
w.WriteUInt16(4)
|
w.WriteUInt16(4)
|
||||||
|
|
||||||
w.Write(tlv.T8(2052))
|
w.Write(tlv.T8(2052))
|
||||||
w.Write(tlv.T104(c.t104))
|
w.Write(tlv.T104(c.sig.T104))
|
||||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
w.Write(tlv.T401(c.g))
|
w.Write(tlv.T401(c.sig.G))
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
req2 := network.Request{
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
Type: network.RequestTypeLogin,
|
||||||
return seq, packet
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) {
|
func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) {
|
||||||
@ -133,13 +147,21 @@ func (c *QQClient) buildQRCodeFetchRequestPacket() (uint16, []byte) {
|
|||||||
w.Write(tlv.T35(8))
|
w.Write(tlv.T35(8))
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, watch.AppId, c.version.SubAppId, "wtlogin.trans_emp", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(0, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: 0,
|
||||||
|
CommandName: "wtlogin.trans_emp",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
|
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
|
||||||
watch := auth.AndroidWatch.Version()
|
version := c.transport.Version
|
||||||
|
c.transport.Version = auth.AndroidWatch.Version()
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
|
req := c.buildOicqRequestPacket(0, 0x0812, binary.NewWriterF(func(w *binary.Writer) {
|
||||||
w.WriteHex(`0000620000001000000072000000`) // trans header
|
w.WriteHex(`0000620000001000000072000000`) // trans header
|
||||||
@ -156,9 +178,18 @@ func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []by
|
|||||||
w.WriteUInt16(0) // const
|
w.WriteUInt16(0) // const
|
||||||
}))
|
}))
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, watch.AppId, c.version.SubAppId, "wtlogin.trans_emp", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(0, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: 0,
|
||||||
|
CommandName: "wtlogin.trans_emp",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
payload := c.transport.PackPacket(&req2)
|
||||||
|
c.transport.Version = version
|
||||||
|
return seq, payload
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []byte) {
|
func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []byte) {
|
||||||
@ -230,9 +261,16 @@ func (c *QQClient) buildQRCodeLoginPacket(t106, t16a, t318 []byte) (uint16, []by
|
|||||||
w.Write(wb)
|
w.Write(wb)
|
||||||
cl()
|
cl()
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byte) {
|
func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byte) {
|
||||||
@ -243,12 +281,19 @@ func (c *QQClient) buildCaptchaPacket(result string, sign []byte) (uint16, []byt
|
|||||||
|
|
||||||
w.Write(tlv.T2(result, sign))
|
w.Write(tlv.T2(result, sign))
|
||||||
w.Write(tlv.T8(2052))
|
w.Write(tlv.T8(2052))
|
||||||
w.Write(tlv.T104(c.t104))
|
w.Write(tlv.T104(c.sig.T104))
|
||||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) {
|
func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) {
|
||||||
@ -258,15 +303,22 @@ func (c *QQClient) buildSMSRequestPacket() (uint16, []byte) {
|
|||||||
w.WriteUInt16(6)
|
w.WriteUInt16(6)
|
||||||
|
|
||||||
w.Write(tlv.T8(2052))
|
w.Write(tlv.T8(2052))
|
||||||
w.Write(tlv.T104(c.t104))
|
w.Write(tlv.T104(c.sig.T104))
|
||||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
w.Write(tlv.T174(c.t174))
|
w.Write(tlv.T174(c.sig.T174))
|
||||||
w.Write(tlv.T17A(9))
|
w.Write(tlv.T17A(9))
|
||||||
w.Write(tlv.T197())
|
w.Write(tlv.T197())
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) {
|
func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) {
|
||||||
@ -276,16 +328,23 @@ func (c *QQClient) buildSMSCodeSubmitPacket(code string) (uint16, []byte) {
|
|||||||
w.WriteUInt16(7)
|
w.WriteUInt16(7)
|
||||||
|
|
||||||
w.Write(tlv.T8(2052))
|
w.Write(tlv.T8(2052))
|
||||||
w.Write(tlv.T104(c.t104))
|
w.Write(tlv.T104(c.sig.T104))
|
||||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
w.Write(tlv.T174(c.t174))
|
w.Write(tlv.T174(c.sig.T174))
|
||||||
w.Write(tlv.T17C(code))
|
w.Write(tlv.T17C(code))
|
||||||
w.Write(tlv.T401(c.g))
|
w.Write(tlv.T401(c.sig.G))
|
||||||
w.Write(tlv.T198())
|
w.Write(tlv.T198())
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) {
|
func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) {
|
||||||
@ -296,12 +355,19 @@ func (c *QQClient) buildTicketSubmitPacket(ticket string) (uint16, []byte) {
|
|||||||
|
|
||||||
w.Write(tlv.T193(ticket))
|
w.Write(tlv.T193(ticket))
|
||||||
w.Write(tlv.T8(2052))
|
w.Write(tlv.T8(2052))
|
||||||
w.Write(tlv.T104(c.t104))
|
w.Write(tlv.T104(c.sig.T104))
|
||||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.login", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
||||||
@ -314,14 +380,14 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
|||||||
w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress))
|
w.Write(tlv.T1(uint32(c.Uin), c.deviceInfo.IpAddress))
|
||||||
wb, cl := binary.OpenWriterF(func(bw *binary.Writer) {
|
wb, cl := binary.OpenWriterF(func(bw *binary.Writer) {
|
||||||
bw.WriteUInt16(0x106)
|
bw.WriteUInt16(0x106)
|
||||||
bw.WriteBytesShort(c.sigInfo.EncryptedA1)
|
bw.WriteBytesShort(c.sig.EncryptedA1)
|
||||||
})
|
})
|
||||||
w.Write(wb)
|
w.Write(wb)
|
||||||
cl()
|
cl()
|
||||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
w.Write(tlv.T100(c.version.SSOVersion, 2, c.version.MainSigMap))
|
w.Write(tlv.T100(c.version.SSOVersion, 2, c.version.MainSigMap))
|
||||||
w.Write(tlv.T107(0))
|
w.Write(tlv.T107(0))
|
||||||
w.Write(tlv.T108(c.ksid))
|
w.Write(tlv.T108(c.sig.Ksid))
|
||||||
w.Write(tlv.T144(
|
w.Write(tlv.T144(
|
||||||
c.deviceInfo.AndroidId,
|
c.deviceInfo.AndroidId,
|
||||||
c.deviceInfo.GenDeviceInfoData(),
|
c.deviceInfo.GenDeviceInfoData(),
|
||||||
@ -337,7 +403,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
|||||||
))
|
))
|
||||||
w.Write(tlv.T142(c.version.ApkId))
|
w.Write(tlv.T142(c.version.ApkId))
|
||||||
w.Write(tlv.T145(c.deviceInfo.Guid))
|
w.Write(tlv.T145(c.deviceInfo.Guid))
|
||||||
w.Write(tlv.T16A(c.sigInfo.SrmToken))
|
w.Write(tlv.T16A(c.sig.SrmToken))
|
||||||
w.Write(tlv.T154(seq))
|
w.Write(tlv.T154(seq))
|
||||||
w.Write(tlv.T141(c.deviceInfo.SimInfo, c.deviceInfo.APN))
|
w.Write(tlv.T141(c.deviceInfo.SimInfo, c.deviceInfo.APN))
|
||||||
w.Write(tlv.T8(2052))
|
w.Write(tlv.T8(2052))
|
||||||
@ -348,7 +414,7 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
|||||||
}))
|
}))
|
||||||
w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign))
|
w.Write(tlv.T147(16, []byte(c.version.SortVersionName), c.version.ApkSign))
|
||||||
w.Write(tlv.T177(c.version.BuildTime, c.version.SdkVersion))
|
w.Write(tlv.T177(c.version.BuildTime, c.version.SdkVersion))
|
||||||
w.Write(tlv.T400(c.g, c.Uin, c.deviceInfo.Guid, c.dpwd, 1, 16, c.randSeed))
|
w.Write(tlv.T400(c.sig.G, c.Uin, c.deviceInfo.Guid, c.sig.Dpwd, 1, 16, c.sig.RandSeed))
|
||||||
w.Write(tlv.T187(c.deviceInfo.MacAddress))
|
w.Write(tlv.T187(c.deviceInfo.MacAddress))
|
||||||
w.Write(tlv.T188(c.deviceInfo.AndroidId))
|
w.Write(tlv.T188(c.deviceInfo.AndroidId))
|
||||||
w.Write(tlv.T194(c.deviceInfo.IMSIMd5))
|
w.Write(tlv.T194(c.deviceInfo.IMSIMd5))
|
||||||
@ -363,23 +429,20 @@ func (c *QQClient) buildRequestTgtgtNopicsigPacket() (uint16, []byte) {
|
|||||||
oicq := codec.OICQ{
|
oicq := codec.OICQ{
|
||||||
Uin: uint32(c.Uin),
|
Uin: uint32(c.Uin),
|
||||||
Command: 0x810,
|
Command: 0x810,
|
||||||
EncryptMethod: crypto.NewEncryptSession(c.sigInfo.T133),
|
EncryptMethod: crypto.NewEncryptSession(c.sig.T133),
|
||||||
Key: c.sigInfo.WtSessionTicketKey,
|
Key: c.sig.WtSessionTicketKey,
|
||||||
Body: req,
|
Body: req,
|
||||||
}
|
}
|
||||||
|
|
||||||
uni := codec.Uni{
|
nreq := network.Request{
|
||||||
|
Type: network.RequestTypeSimple,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
Uin: c.Uin,
|
Uin: c.Uin,
|
||||||
Seq: seq,
|
SequenceID: int32(seq),
|
||||||
CommandName: "wtlogin.exchange_emp",
|
CommandName: "wtlogin.exchange_emp",
|
||||||
EncryptType: 2,
|
|
||||||
SessionID: c.OutGoingPacketSessionId,
|
|
||||||
ExtraData: EmptyBytes,
|
|
||||||
Key: make([]byte, 16),
|
|
||||||
Body: oicq.Encode(),
|
Body: oicq.Encode(),
|
||||||
}
|
}
|
||||||
|
return seq, c.transport.PackPacket(&nreq)
|
||||||
return seq, uni.Encode()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byte) {
|
func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byte) {
|
||||||
@ -389,10 +452,10 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
|
|||||||
w.WriteUInt16(17)
|
w.WriteUInt16(17)
|
||||||
|
|
||||||
w.Write(tlv.T100(c.version.SSOVersion, 100, mainSigMap))
|
w.Write(tlv.T100(c.version.SSOVersion, 100, mainSigMap))
|
||||||
w.Write(tlv.T10A(c.sigInfo.TGT))
|
w.Write(tlv.T10A(c.sig.TGT))
|
||||||
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
w.Write(tlv.T116(c.version.MiscBitmap, c.version.SubSigmap))
|
||||||
w.Write(tlv.T108(c.ksid))
|
w.Write(tlv.T108(c.sig.Ksid))
|
||||||
h := md5.Sum(c.sigInfo.D2Key)
|
h := md5.Sum(c.sig.D2Key)
|
||||||
w.Write(tlv.T144(
|
w.Write(tlv.T144(
|
||||||
c.deviceInfo.AndroidId,
|
c.deviceInfo.AndroidId,
|
||||||
c.deviceInfo.GenDeviceInfoData(),
|
c.deviceInfo.GenDeviceInfoData(),
|
||||||
@ -406,7 +469,7 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
|
|||||||
c.deviceInfo.Brand,
|
c.deviceInfo.Brand,
|
||||||
h[:],
|
h[:],
|
||||||
))
|
))
|
||||||
w.Write(tlv.T143(c.sigInfo.D2))
|
w.Write(tlv.T143(c.sig.D2))
|
||||||
w.Write(tlv.T142(c.version.ApkId))
|
w.Write(tlv.T142(c.version.ApkId))
|
||||||
w.Write(tlv.T154(seq))
|
w.Write(tlv.T154(seq))
|
||||||
w.Write(tlv.T18(16, uint32(c.Uin)))
|
w.Write(tlv.T18(16, uint32(c.Uin)))
|
||||||
@ -424,9 +487,16 @@ func (c *QQClient) buildRequestChangeSigPacket(mainSigMap uint32) (uint16, []byt
|
|||||||
}))
|
}))
|
||||||
// w.Write(tlv.T202(c.deviceInfo.WifiBSSID, c.deviceInfo.WifiSSID))
|
// w.Write(tlv.T202(c.deviceInfo.WifiBSSID, c.deviceInfo.WifiSSID))
|
||||||
}))
|
}))
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "wtlogin.exchange_emp", c.deviceInfo.IMEI, c.sigInfo.TGT, c.OutGoingPacketSessionId, req, c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 2, make([]byte, 16), sso, EmptyBytes)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeEmptyKey,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.exchange_emp",
|
||||||
|
Body: req,
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
// StatSvc.register
|
// StatSvc.register
|
||||||
@ -472,9 +542,16 @@ func (c *QQClient) buildClientRegisterPacket() (uint16, []byte) {
|
|||||||
Context: make(map[string]string),
|
Context: make(map[string]string),
|
||||||
Status: make(map[string]string),
|
Status: make(map[string]string),
|
||||||
}
|
}
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "StatSvc.register", c.deviceInfo.IMEI, c.sigInfo.TGT, c.OutGoingPacketSessionId, pkt.ToBytes(), c.ksid)
|
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 1, c.sigInfo.D2Key, sso, c.sigInfo.D2)
|
req2 := network.Request{
|
||||||
return seq, packet
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeD2Key,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "StatSvc.register",
|
||||||
|
Body: pkt.ToBytes(),
|
||||||
|
}
|
||||||
|
return seq, c.transport.PackPacket(&req2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildStatusSetPacket(status, extStatus int32) (uint16, []byte) {
|
func (c *QQClient) buildStatusSetPacket(status, extStatus int32) (uint16, []byte) {
|
||||||
@ -766,7 +843,7 @@ func (c *QQClient) buildGroupMemberInfoRequestPacket(groupCode, uin int64) (uint
|
|||||||
|
|
||||||
// MessageSvc.PbGetMsg
|
// MessageSvc.PbGetMsg
|
||||||
func (c *QQClient) buildGetMessageRequestPacket(flag msg.SyncFlag, msgTime int64) (uint16, []byte) {
|
func (c *QQClient) buildGetMessageRequestPacket(flag msg.SyncFlag, msgTime int64) (uint16, []byte) {
|
||||||
cook := c.syncCookie
|
cook := c.sig.SyncCookie
|
||||||
if cook == nil {
|
if cook == nil {
|
||||||
cook, _ = proto.Marshal(&msg.SyncCookie{
|
cook, _ = proto.Marshal(&msg.SyncCookie{
|
||||||
Time: &msgTime,
|
Time: &msgTime,
|
||||||
@ -1075,7 +1152,7 @@ func (c *QQClient) buildAppInfoRequestPacket(id string) (uint16, []byte) {
|
|||||||
TraceId: proto.String(fmt.Sprintf("%v_%v_%v", c.Uin, time.Now().Format("0102150405"), rand.Int63())),
|
TraceId: proto.String(fmt.Sprintf("%v_%v_%v", c.Uin, time.Now().Format("0102150405"), rand.Int63())),
|
||||||
}
|
}
|
||||||
payload, _ := proto.Marshal(body)
|
payload, _ := proto.Marshal(body)
|
||||||
packet := packets.BuildUniPacket(c.Uin, seq, "LightAppSvc.mini_app_info.GetAppInfoById", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
packet := packets.BuildUniPacket(c.Uin, seq, "LightAppSvc.mini_app_info.GetAppInfoById", 1, c.SessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||||
return seq, packet
|
return seq, packet
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -40,8 +40,8 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *network.IncomingPacketInfo) {
|
func (c *QQClient) c2cMessageSyncProcessor(rsp *msg.GetMessageResponse, info *network.IncomingPacketInfo) {
|
||||||
c.syncCookie = rsp.SyncCookie
|
c.sig.SyncCookie = rsp.SyncCookie
|
||||||
c.pubAccountCookie = rsp.PubAccountCookie
|
c.sig.PubAccountCookie = rsp.PubAccountCookie
|
||||||
// c.msgCtrlBuf = rsp.MsgCtrlBuf
|
// c.msgCtrlBuf = rsp.MsgCtrlBuf
|
||||||
if rsp.UinPairMsgs == nil {
|
if rsp.UinPairMsgs == nil {
|
||||||
return
|
return
|
||||||
|
@ -20,7 +20,6 @@ import (
|
|||||||
"github.com/Mrs4s/MiraiGo/client/internal/network"
|
"github.com/Mrs4s/MiraiGo/client/internal/network"
|
||||||
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
"github.com/Mrs4s/MiraiGo/client/pb/msg"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/crypto"
|
"github.com/Mrs4s/MiraiGo/internal/crypto"
|
||||||
"github.com/Mrs4s/MiraiGo/internal/packets"
|
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,11 +48,13 @@ type QQClient struct {
|
|||||||
|
|
||||||
// protocol public field
|
// protocol public field
|
||||||
SequenceId atomic.Int32
|
SequenceId atomic.Int32
|
||||||
OutGoingPacketSessionId []byte
|
SessionId []byte
|
||||||
RandomKey []byte
|
RandomKey []byte
|
||||||
TCP *network.TCPListener // todo: combine other protocol state into one struct
|
TCP *network.TCPListener // todo: combine other protocol state into one struct
|
||||||
ConnectTime time.Time
|
ConnectTime time.Time
|
||||||
|
|
||||||
|
transport *network.Transport
|
||||||
|
|
||||||
// internal state
|
// internal state
|
||||||
handlers HandlerMap
|
handlers HandlerMap
|
||||||
waiters sync.Map
|
waiters sync.Map
|
||||||
@ -65,29 +66,10 @@ type QQClient struct {
|
|||||||
alive bool
|
alive bool
|
||||||
ecdh *crypto.EncryptECDH
|
ecdh *crypto.EncryptECDH
|
||||||
|
|
||||||
// tlv cache
|
|
||||||
t104 []byte
|
|
||||||
t174 []byte
|
|
||||||
g []byte
|
|
||||||
t402 []byte
|
|
||||||
randSeed []byte // t403
|
|
||||||
// rollbackSig []byte
|
|
||||||
// t149 []byte
|
|
||||||
// t150 []byte
|
|
||||||
// t528 []byte
|
|
||||||
// t530 []byte
|
|
||||||
|
|
||||||
// sync info
|
|
||||||
syncCookie []byte
|
|
||||||
pubAccountCookie []byte
|
|
||||||
ksid []byte
|
|
||||||
// msgCtrlBuf []byte
|
|
||||||
|
|
||||||
// session info
|
// session info
|
||||||
qwebSeq atomic.Int64
|
qwebSeq atomic.Int64
|
||||||
sigInfo *auth.SigInfo
|
sig *auth.SigInfo
|
||||||
highwaySession *highway.Session
|
highwaySession *highway.Session
|
||||||
dpwd []byte
|
|
||||||
// pwdFlag bool
|
// pwdFlag bool
|
||||||
// timeDiff int64
|
// timeDiff int64
|
||||||
|
|
||||||
@ -180,9 +162,10 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
|||||||
PasswordMd5: passwordMd5,
|
PasswordMd5: passwordMd5,
|
||||||
AllowSlider: true,
|
AllowSlider: true,
|
||||||
RandomKey: make([]byte, 16),
|
RandomKey: make([]byte, 16),
|
||||||
OutGoingPacketSessionId: []byte{0x02, 0xB0, 0x5B, 0x8B},
|
|
||||||
TCP: &network.TCPListener{},
|
TCP: &network.TCPListener{},
|
||||||
sigInfo: &auth.SigInfo{},
|
sig: &auth.SigInfo{
|
||||||
|
OutPacketSessionID: []byte{0x02, 0xB0, 0x5B, 0x8B},
|
||||||
|
},
|
||||||
eventHandlers: &eventHandlers{},
|
eventHandlers: &eventHandlers{},
|
||||||
msgSvcCache: utils.NewCache(time.Second * 15),
|
msgSvcCache: utils.NewCache(time.Second * 15),
|
||||||
transCache: utils.NewCache(time.Second * 15),
|
transCache: utils.NewCache(time.Second * 15),
|
||||||
@ -191,7 +174,17 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
|||||||
alive: true,
|
alive: true,
|
||||||
ecdh: crypto.NewEcdh(),
|
ecdh: crypto.NewEcdh(),
|
||||||
highwaySession: new(highway.Session),
|
highwaySession: new(highway.Session),
|
||||||
|
|
||||||
|
version: new(auth.AppVersion),
|
||||||
|
deviceInfo: new(auth.Device),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cli.transport = &network.Transport{
|
||||||
|
Sig: cli.sig,
|
||||||
|
Version: cli.version,
|
||||||
|
Device: cli.deviceInfo,
|
||||||
|
}
|
||||||
|
|
||||||
{ // init atomic values
|
{ // init atomic values
|
||||||
cli.SequenceId.Store(0x3635)
|
cli.SequenceId.Store(0x3635)
|
||||||
cli.requestPacketRequestID.Store(1921334513)
|
cli.requestPacketRequestID.Store(1921334513)
|
||||||
@ -256,10 +249,10 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) UseDevice(info *auth.Device) {
|
func (c *QQClient) UseDevice(info *auth.Device) {
|
||||||
c.version = info.Protocol.Version()
|
*c.version = *info.Protocol.Version()
|
||||||
|
*c.deviceInfo = *info
|
||||||
c.highwaySession.AppID = int32(c.version.AppId)
|
c.highwaySession.AppID = int32(c.version.AppId)
|
||||||
c.ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI))
|
c.sig.Ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI))
|
||||||
c.deviceInfo = info
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) Release() {
|
func (c *QQClient) Release() {
|
||||||
@ -301,14 +294,14 @@ func (c *QQClient) TokenLogin(token []byte) error {
|
|||||||
{
|
{
|
||||||
r := binary.NewReader(token)
|
r := binary.NewReader(token)
|
||||||
c.Uin = r.ReadInt64()
|
c.Uin = r.ReadInt64()
|
||||||
c.sigInfo.D2 = r.ReadBytesShort()
|
c.sig.D2 = r.ReadBytesShort()
|
||||||
c.sigInfo.D2Key = r.ReadBytesShort()
|
c.sig.D2Key = r.ReadBytesShort()
|
||||||
c.sigInfo.TGT = r.ReadBytesShort()
|
c.sig.TGT = r.ReadBytesShort()
|
||||||
c.sigInfo.SrmToken = r.ReadBytesShort()
|
c.sig.SrmToken = r.ReadBytesShort()
|
||||||
c.sigInfo.T133 = r.ReadBytesShort()
|
c.sig.T133 = r.ReadBytesShort()
|
||||||
c.sigInfo.EncryptedA1 = r.ReadBytesShort()
|
c.sig.EncryptedA1 = r.ReadBytesShort()
|
||||||
c.sigInfo.WtSessionTicketKey = r.ReadBytesShort()
|
c.sig.WtSessionTicketKey = r.ReadBytesShort()
|
||||||
c.OutGoingPacketSessionId = r.ReadBytesShort()
|
c.sig.OutPacketSessionID = r.ReadBytesShort()
|
||||||
// SystemDeviceInfo.TgtgtKey = r.ReadBytesShort()
|
// SystemDeviceInfo.TgtgtKey = r.ReadBytesShort()
|
||||||
c.deviceInfo.TgtgtKey = r.ReadBytesShort()
|
c.deviceInfo.TgtgtKey = r.ReadBytesShort()
|
||||||
}
|
}
|
||||||
@ -406,7 +399,7 @@ func (c *QQClient) RequestSMS() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) init(tokenLogin bool) error {
|
func (c *QQClient) init(tokenLogin bool) error {
|
||||||
if len(c.g) == 0 {
|
if len(c.sig.G) == 0 {
|
||||||
c.Warning("device lock is disable. http api may fail.")
|
c.Warning("device lock is disable. http api may fail.")
|
||||||
}
|
}
|
||||||
c.highwaySession.Uin = strconv.FormatInt(c.Uin, 10)
|
c.highwaySession.Uin = strconv.FormatInt(c.Uin, 10)
|
||||||
@ -449,14 +442,14 @@ func (c *QQClient) init(tokenLogin bool) error {
|
|||||||
func (c *QQClient) GenToken() []byte {
|
func (c *QQClient) GenToken() []byte {
|
||||||
return binary.NewWriterF(func(w *binary.Writer) {
|
return binary.NewWriterF(func(w *binary.Writer) {
|
||||||
w.WriteUInt64(uint64(c.Uin))
|
w.WriteUInt64(uint64(c.Uin))
|
||||||
w.WriteBytesShort(c.sigInfo.D2)
|
w.WriteBytesShort(c.sig.D2)
|
||||||
w.WriteBytesShort(c.sigInfo.D2Key)
|
w.WriteBytesShort(c.sig.D2Key)
|
||||||
w.WriteBytesShort(c.sigInfo.TGT)
|
w.WriteBytesShort(c.sig.TGT)
|
||||||
w.WriteBytesShort(c.sigInfo.SrmToken)
|
w.WriteBytesShort(c.sig.SrmToken)
|
||||||
w.WriteBytesShort(c.sigInfo.T133)
|
w.WriteBytesShort(c.sig.T133)
|
||||||
w.WriteBytesShort(c.sigInfo.EncryptedA1)
|
w.WriteBytesShort(c.sig.EncryptedA1)
|
||||||
w.WriteBytesShort(c.sigInfo.WtSessionTicketKey)
|
w.WriteBytesShort(c.sig.WtSessionTicketKey)
|
||||||
w.WriteBytesShort(c.OutGoingPacketSessionId)
|
w.WriteBytesShort(c.sig.OutPacketSessionID)
|
||||||
w.WriteBytesShort(c.deviceInfo.TgtgtKey)
|
w.WriteBytesShort(c.deviceInfo.TgtgtKey)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -681,11 +674,11 @@ func (c *QQClient) SolveFriendRequest(req *NewFriendRequest, accept bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) getSKey() string {
|
func (c *QQClient) getSKey() string {
|
||||||
if c.sigInfo.SKeyExpiredTime < time.Now().Unix() && len(c.g) > 0 {
|
if c.sig.SKeyExpiredTime < time.Now().Unix() && len(c.sig.G) > 0 {
|
||||||
c.Debug("skey expired. refresh...")
|
c.Debug("skey expired. refresh...")
|
||||||
_, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket())
|
_, _ = c.sendAndWait(c.buildRequestTgtgtNopicsigPacket())
|
||||||
}
|
}
|
||||||
return string(c.sigInfo.SKey)
|
return string(c.sig.SKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) getCookies() string {
|
func (c *QQClient) getCookies() string {
|
||||||
@ -695,7 +688,7 @@ func (c *QQClient) getCookies() string {
|
|||||||
func (c *QQClient) getCookiesWithDomain(domain string) string {
|
func (c *QQClient) getCookiesWithDomain(domain string) string {
|
||||||
cookie := c.getCookies()
|
cookie := c.getCookies()
|
||||||
|
|
||||||
if psKey, ok := c.sigInfo.PsKeyMap[domain]; ok {
|
if psKey, ok := c.sig.PsKeyMap[domain]; ok {
|
||||||
return fmt.Sprintf("%s p_uin=o%d; p_skey=%s;", cookie, c.Uin, psKey)
|
return fmt.Sprintf("%s p_uin=o%d; p_skey=%s;", cookie, c.Uin, psKey)
|
||||||
} else {
|
} else {
|
||||||
return cookie
|
return cookie
|
||||||
@ -800,8 +793,15 @@ func (c *QQClient) doHeartbeat() {
|
|||||||
for c.Online.Load() {
|
for c.Online.Load() {
|
||||||
time.Sleep(time.Second * 30)
|
time.Sleep(time.Second * 30)
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
sso := packets.BuildSsoPacket(seq, c.version.AppId, c.version.SubAppId, "Heartbeat.Alive", c.deviceInfo.IMEI, EmptyBytes, c.OutGoingPacketSessionId, EmptyBytes, c.ksid)
|
req := network.Request{
|
||||||
packet := packets.BuildLoginPacket(c.Uin, 0, EmptyBytes, sso, EmptyBytes)
|
Type: network.RequestTypeLogin,
|
||||||
|
EncryptType: network.EncryptTypeNoEncrypt,
|
||||||
|
SequenceID: int32(seq),
|
||||||
|
Uin: c.Uin,
|
||||||
|
CommandName: "wtlogin.login",
|
||||||
|
Body: EmptyBytes,
|
||||||
|
}
|
||||||
|
packet := c.transport.PackPacket(&req)
|
||||||
_, err := c.sendAndWait(seq, packet)
|
_, err := c.sendAndWait(seq, packet)
|
||||||
if errors.Is(err, network.ErrConnectionClosed) {
|
if errors.Is(err, network.ErrConnectionClosed) {
|
||||||
continue
|
continue
|
||||||
|
@ -39,10 +39,10 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
|||||||
reader.ReadUInt16()
|
reader.ReadUInt16()
|
||||||
m := reader.ReadTlvMap(2)
|
m := reader.ReadTlvMap(2)
|
||||||
if m.Exists(0x402) {
|
if m.Exists(0x402) {
|
||||||
c.dpwd = []byte(utils.RandomString(16))
|
c.sig.Dpwd = []byte(utils.RandomString(16))
|
||||||
c.t402 = m[0x402]
|
c.sig.T402 = m[0x402]
|
||||||
h := md5.Sum(append(append(c.deviceInfo.Guid, c.dpwd...), c.t402...))
|
h := md5.Sum(append(append(c.deviceInfo.Guid, c.sig.Dpwd...), c.sig.T402...))
|
||||||
c.g = h[:]
|
c.sig.G = h[:]
|
||||||
}
|
}
|
||||||
if t == 0 { // login success
|
if t == 0 { // login success
|
||||||
// if t150, ok := m[0x150]; ok {
|
// if t150, ok := m[0x150]; ok {
|
||||||
@ -52,7 +52,7 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
|||||||
c.decodeT161(t161)
|
c.decodeT161(t161)
|
||||||
}
|
}
|
||||||
if m.Exists(0x403) {
|
if m.Exists(0x403) {
|
||||||
c.randSeed = m[0x403]
|
c.sig.RandSeed = m[0x403]
|
||||||
}
|
}
|
||||||
c.decodeT119(m[0x119], c.deviceInfo.TgtgtKey)
|
c.decodeT119(m[0x119], c.deviceInfo.TgtgtKey)
|
||||||
return LoginResponse{
|
return LoginResponse{
|
||||||
@ -60,7 +60,7 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
if t == 2 {
|
if t == 2 {
|
||||||
c.t104 = m[0x104]
|
c.sig.T104 = m[0x104]
|
||||||
if m.Exists(0x192) {
|
if m.Exists(0x192) {
|
||||||
return LoginResponse{
|
return LoginResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
@ -97,9 +97,9 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
|||||||
|
|
||||||
if t == 160 || t == 239 {
|
if t == 160 || t == 239 {
|
||||||
if t174, ok := m[0x174]; ok { // 短信验证
|
if t174, ok := m[0x174]; ok { // 短信验证
|
||||||
c.t104 = m[0x104]
|
c.sig.T104 = m[0x104]
|
||||||
c.t174 = t174
|
c.sig.T174 = t174
|
||||||
c.randSeed = m[0x403]
|
c.sig.RandSeed = m[0x403]
|
||||||
phone := func() string {
|
phone := func() string {
|
||||||
r := binary.NewReader(m[0x178])
|
r := binary.NewReader(m[0x178])
|
||||||
return r.ReadStringLimit(int(r.ReadInt32()))
|
return r.ReadStringLimit(int(r.ReadInt32()))
|
||||||
@ -122,7 +122,7 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
if _, ok := m[0x17b]; ok { // 二次验证
|
if _, ok := m[0x17b]; ok { // 二次验证
|
||||||
c.t104 = m[0x104]
|
c.sig.T104 = m[0x104]
|
||||||
return LoginResponse{
|
return LoginResponse{
|
||||||
Success: false,
|
Success: false,
|
||||||
Error: SMSNeededError,
|
Error: SMSNeededError,
|
||||||
@ -146,8 +146,8 @@ func decodeLoginResponse(c *QQClient, _ *network.IncomingPacketInfo, payload []b
|
|||||||
}
|
}
|
||||||
|
|
||||||
if t == 204 {
|
if t == 204 {
|
||||||
c.t104 = m[0x104]
|
c.sig.T104 = m[0x104]
|
||||||
c.randSeed = m[0x403]
|
c.sig.RandSeed = m[0x403]
|
||||||
return c.sendAndWait(c.buildDeviceLockLoginPacket())
|
return c.sendAndWait(c.buildDeviceLockLoginPacket())
|
||||||
} // drive lock
|
} // drive lock
|
||||||
|
|
||||||
@ -210,7 +210,7 @@ func decodeExchangeEmpResponse(c *QQClient, _ *network.IncomingPacketInfo, paylo
|
|||||||
c.decodeT119R(m[0x119])
|
c.decodeT119R(m[0x119])
|
||||||
}
|
}
|
||||||
if cmd == 11 {
|
if cmd == 11 {
|
||||||
h := md5.Sum(c.sigInfo.D2Key)
|
h := md5.Sum(c.sig.D2Key)
|
||||||
c.decodeT119(m[0x119], h[:])
|
c.decodeT119(m[0x119], h[:])
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
|
@ -663,7 +663,7 @@ func (s *GuildService) fetchChannelListState(guildId uint64, channels []*Channel
|
|||||||
2: ids,
|
2: ids,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
packet := packets.BuildUniPacket(s.c.Uin, seq, "OidbSvcTrpcTcp.0x1008_1", 1, s.c.OutGoingPacketSessionId, []byte{}, s.c.sigInfo.d2Key, payload)
|
packet := packets.BuildUniPacket(s.c.Uin, seq, "OidbSvcTrpcTcp.0x1008_1", 1, s.c.SessionId, []byte{}, s.c.sigInfo.d2Key, payload)
|
||||||
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
|
rsp, err := s.c.sendAndWaitDynamic(seq, packet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -127,4 +127,26 @@ type SigInfo struct {
|
|||||||
|
|
||||||
PsKeyMap map[string][]byte
|
PsKeyMap map[string][]byte
|
||||||
Pt4TokenMap map[string][]byte
|
Pt4TokenMap map[string][]byte
|
||||||
|
|
||||||
|
// Others
|
||||||
|
OutPacketSessionID []byte
|
||||||
|
Dpwd []byte
|
||||||
|
|
||||||
|
// tlv cache
|
||||||
|
T104 []byte
|
||||||
|
T174 []byte
|
||||||
|
G []byte
|
||||||
|
T402 []byte
|
||||||
|
RandSeed []byte // t403
|
||||||
|
// rollbackSig []byte
|
||||||
|
// t149 []byte
|
||||||
|
// t150 []byte
|
||||||
|
// t528 []byte
|
||||||
|
// t530 []byte
|
||||||
|
|
||||||
|
// sync info
|
||||||
|
SyncCookie []byte
|
||||||
|
PubAccountCookie []byte
|
||||||
|
Ksid []byte
|
||||||
|
// msgCtrlBuf []byte
|
||||||
}
|
}
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
package codec
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Uni struct {
|
|
||||||
Uin int64
|
|
||||||
Seq uint16
|
|
||||||
CommandName string
|
|
||||||
EncryptType byte
|
|
||||||
SessionID []byte
|
|
||||||
ExtraData []byte
|
|
||||||
Key []byte
|
|
||||||
Body []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
func (u *Uni) Encode() []byte {
|
|
||||||
return binary.NewWriterF(func(w *binary.Writer) {
|
|
||||||
w2 := binary.SelectWriter()
|
|
||||||
{ // w.WriteIntLvPacket
|
|
||||||
w2.WriteUInt32(0x0B)
|
|
||||||
w2.WriteByte(u.EncryptType)
|
|
||||||
w2.WriteUInt32(uint32(u.Seq))
|
|
||||||
w2.WriteByte(0)
|
|
||||||
w2.WriteString(strconv.FormatInt(u.Uin, 10))
|
|
||||||
|
|
||||||
// inline NewWriterF
|
|
||||||
w3 := binary.SelectWriter()
|
|
||||||
w3.WriteUniPacket(u.CommandName, u.SessionID, u.ExtraData, u.Body)
|
|
||||||
w2.EncryptAndWrite(u.Key, w3.Bytes())
|
|
||||||
binary.PutWriter(w3)
|
|
||||||
}
|
|
||||||
data := w2.Bytes()
|
|
||||||
w.WriteUInt32(uint32(len(data) + 4))
|
|
||||||
w.Write(data)
|
|
||||||
binary.PutWriter(w2)
|
|
||||||
})
|
|
||||||
}
|
|
@ -22,6 +22,6 @@ type Request struct {
|
|||||||
EncryptType EncryptType
|
EncryptType EncryptType
|
||||||
SequenceID int32
|
SequenceID int32
|
||||||
Uin int64
|
Uin int64
|
||||||
Method string
|
CommandName string
|
||||||
Body []byte
|
Body []byte
|
||||||
}
|
}
|
||||||
|
@ -11,95 +11,96 @@ import (
|
|||||||
// Transport is a network transport.
|
// Transport is a network transport.
|
||||||
type Transport struct {
|
type Transport struct {
|
||||||
sessionMu sync.Mutex
|
sessionMu sync.Mutex
|
||||||
// todo: combine session fields to a struct
|
Sig *auth.SigInfo
|
||||||
tgt []byte
|
Version *auth.AppVersion
|
||||||
d2key []byte
|
Device *auth.Device
|
||||||
sessionID []byte
|
|
||||||
ksid []byte
|
|
||||||
|
|
||||||
version *auth.AppVersion
|
|
||||||
device *auth.Device
|
|
||||||
|
|
||||||
// connection
|
// connection
|
||||||
conn *TCPListener
|
// conn *TCPListener
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) packBody(req *Request, w *binary.Writer) {
|
func (t *Transport) packBody(req *Request) []byte {
|
||||||
|
w := binary.SelectWriter()
|
||||||
|
defer binary.PutWriter(w)
|
||||||
w.WriteIntLvPacket(4, func(writer *binary.Writer) {
|
w.WriteIntLvPacket(4, func(writer *binary.Writer) {
|
||||||
if req.Type == RequestTypeLogin {
|
if req.Type == RequestTypeLogin {
|
||||||
writer.WriteUInt32(uint32(req.SequenceID))
|
writer.WriteUInt32(uint32(req.SequenceID))
|
||||||
writer.WriteUInt32(t.version.AppId)
|
writer.WriteUInt32(t.Version.AppId)
|
||||||
writer.WriteUInt32(t.version.SubAppId)
|
writer.WriteUInt32(t.Version.SubAppId)
|
||||||
writer.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
writer.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
||||||
if len(t.tgt) == 0 || len(t.tgt) == 4 {
|
tgt := t.Sig.TGT
|
||||||
|
if len(tgt) == 0 || len(tgt) == 4 {
|
||||||
writer.WriteUInt32(0x04)
|
writer.WriteUInt32(0x04)
|
||||||
} else {
|
} else {
|
||||||
writer.WriteUInt32(uint32(len(t.tgt) + 4))
|
writer.WriteUInt32(uint32(len(tgt) + 4))
|
||||||
writer.Write(t.tgt)
|
writer.Write(tgt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
writer.WriteString(req.CommandName)
|
||||||
writer.WriteString(req.Method)
|
writer.WriteIntLvPacket(4, func(w *binary.Writer) {
|
||||||
writer.WriteUInt32(uint32(len(t.sessionID) + 4))
|
w.Write(t.Sig.OutPacketSessionID)
|
||||||
w.Write(t.sessionID)
|
})
|
||||||
|
// writer.WriteUInt32(uint32(len(t.Sig.OutPacketSessionID) + 4))
|
||||||
|
// w.Write(t.Sig.OutPacketSessionID)
|
||||||
if req.Type == RequestTypeLogin {
|
if req.Type == RequestTypeLogin {
|
||||||
writer.WriteString(t.device.IMEI)
|
writer.WriteString(t.Device.IMEI)
|
||||||
writer.WriteUInt32(0x04)
|
writer.WriteUInt32(0x04)
|
||||||
{
|
{
|
||||||
writer.WriteUInt16(uint16(len(t.ksid)) + 2)
|
writer.WriteUInt16(uint16(len(t.Sig.Ksid)) + 2)
|
||||||
writer.Write(t.ksid)
|
writer.Write(t.Sig.Ksid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
writer.WriteUInt32(0x04)
|
writer.WriteUInt32(0x04)
|
||||||
})
|
})
|
||||||
|
|
||||||
w.WriteUInt32(uint32(len(req.Body) + 4))
|
w.WriteIntLvPacket(4, func(w *binary.Writer) {
|
||||||
w.Write(req.Body)
|
w.Write(req.Body)
|
||||||
|
})
|
||||||
|
// w.WriteUInt32(uint32(len(req.Body) + 4))
|
||||||
|
// w.Write(req.Body)
|
||||||
|
return append([]byte(nil), w.Bytes()...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
body := t.packBody(req)
|
||||||
|
// encrypt body
|
||||||
|
switch req.EncryptType {
|
||||||
|
case EncryptTypeD2Key:
|
||||||
|
body = binary.NewTeaCipher(t.Sig.D2Key).Encrypt(body)
|
||||||
|
case EncryptTypeEmptyKey:
|
||||||
|
body = binary.NewTeaCipher(emptyKey).Encrypt(body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) Send(req *Request) error {
|
|
||||||
// todo: return response
|
|
||||||
head := binary.NewWriterF(func(w *binary.Writer) {
|
head := binary.NewWriterF(func(w *binary.Writer) {
|
||||||
w.WriteUInt32(uint32(req.Type))
|
w.WriteUInt32(uint32(req.Type))
|
||||||
w.WriteUInt32(uint32(req.EncryptType))
|
w.WriteByte(byte(req.EncryptType))
|
||||||
switch req.Type {
|
switch req.Type {
|
||||||
case RequestTypeLogin:
|
case RequestTypeLogin:
|
||||||
switch req.EncryptType {
|
switch req.EncryptType {
|
||||||
case EncryptTypeD2Key:
|
case EncryptTypeD2Key:
|
||||||
w.WriteUInt32(uint32(len(t.d2key) + 4))
|
w.WriteUInt32(uint32(len(t.Sig.D2) + 4))
|
||||||
w.Write(t.d2key)
|
w.Write(t.Sig.D2)
|
||||||
default:
|
default:
|
||||||
w.WriteUInt32(4)
|
w.WriteUInt32(4)
|
||||||
}
|
}
|
||||||
case RequestTypeSimple:
|
case RequestTypeSimple:
|
||||||
w.WriteUInt32(uint32(req.SequenceID))
|
w.WriteUInt32(uint32(req.SequenceID))
|
||||||
}
|
}
|
||||||
|
w.WriteByte(0x00)
|
||||||
w.WriteString(strconv.FormatInt(req.Uin, 10))
|
w.WriteString(strconv.FormatInt(req.Uin, 10))
|
||||||
})
|
})
|
||||||
|
|
||||||
w := binary.SelectWriter()
|
w := binary.SelectWriter()
|
||||||
defer binary.PutWriter(w)
|
defer binary.PutWriter(w)
|
||||||
t.packBody(req, w)
|
w.WriteUInt32(uint32(len(head)+len(body)) + 4)
|
||||||
body := w.Bytes()
|
w.Write(head)
|
||||||
|
w.Write(body)
|
||||||
// encrypt body
|
return append([]byte(nil), w.Bytes()...) // copy
|
||||||
switch req.EncryptType {
|
|
||||||
case EncryptTypeD2Key:
|
|
||||||
body = binary.NewTeaCipher(t.d2key).Encrypt(body)
|
|
||||||
case EncryptTypeEmptyKey:
|
|
||||||
body = binary.NewTeaCipher(emptyKey).Encrypt(body)
|
|
||||||
}
|
|
||||||
|
|
||||||
w2 := binary.SelectWriter()
|
|
||||||
defer binary.PutWriter(w2)
|
|
||||||
w2.WriteUInt32(uint32(len(head) + len(body) + 4))
|
|
||||||
w2.Write(head)
|
|
||||||
w2.Write(body)
|
|
||||||
err := t.conn.Write(w2.Bytes())
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Transport) parse(head []byte) *Request {
|
func (t *Transport) parse(head []byte) *Request {
|
||||||
@ -119,7 +120,7 @@ func (t *Transport) parse(head []byte) *Request {
|
|||||||
case EncryptTypeNoEncrypt:
|
case EncryptTypeNoEncrypt:
|
||||||
req.Body = body
|
req.Body = body
|
||||||
case EncryptTypeD2Key:
|
case EncryptTypeD2Key:
|
||||||
req.Body = binary.NewTeaCipher(t.d2key).Decrypt(body)
|
req.Body = binary.NewTeaCipher(t.Sig.D2Key).Decrypt(body)
|
||||||
case EncryptTypeEmptyKey:
|
case EncryptTypeEmptyKey:
|
||||||
req.Body = binary.NewTeaCipher(emptyKey).Decrypt(body)
|
req.Body = binary.NewTeaCipher(emptyKey).Decrypt(body)
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ type (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (c *QQClient) getGtk(domain string) int {
|
func (c *QQClient) getGtk(domain string) int {
|
||||||
if psKey, ok := c.sigInfo.PsKeyMap[domain]; ok {
|
if psKey, ok := c.sig.PsKeyMap[domain]; ok {
|
||||||
accu := 5381
|
accu := 5381
|
||||||
for _, b := range psKey {
|
for _, b := range psKey {
|
||||||
accu = accu + (accu << 5) + int(b)
|
accu = accu + (accu << 5) + int(b)
|
||||||
|
@ -291,7 +291,7 @@ func (c *QQClient) netLoop() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
data, _ := c.TCP.ReadBytes(int(l) - 4)
|
data, _ := c.TCP.ReadBytes(int(l) - 4)
|
||||||
pkt, err := packets.ParseIncomingPacket(data, c.sigInfo.D2Key)
|
pkt, err := packets.ParseIncomingPacket(data, c.sig.D2Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error("parse incoming packet error: %v", err)
|
c.Error("parse incoming packet error: %v", err)
|
||||||
if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) {
|
if errors.Is(err, packets.ErrSessionExpired) || errors.Is(err, packets.ErrPacketDropped) {
|
||||||
@ -306,7 +306,7 @@ func (c *QQClient) netLoop() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if pkt.Flag2 == 2 {
|
if pkt.Flag2 == 2 {
|
||||||
pkt.Payload, err = pkt.DecryptPayload(c.ecdh.InitialShareKey, c.RandomKey, c.sigInfo.WtSessionTicketKey)
|
pkt.Payload, err = pkt.DecryptPayload(c.ecdh.InitialShareKey, c.RandomKey, c.sig.WtSessionTicketKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error("decrypt payload error: %v", err)
|
c.Error("decrypt payload error: %v", err)
|
||||||
if errors.Is(err, packets.ErrUnknownFlag) {
|
if errors.Is(err, packets.ErrUnknownFlag) {
|
||||||
|
@ -2,6 +2,7 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/Mrs4s/MiraiGo/client/internal/codec"
|
"github.com/Mrs4s/MiraiGo/client/internal/codec"
|
||||||
|
"github.com/Mrs4s/MiraiGo/client/internal/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:noinline
|
//go:noinline
|
||||||
@ -19,30 +20,26 @@ func (c *QQClient) buildOicqRequestPacket(uin int64, command uint16, body []byte
|
|||||||
//go:noinline
|
//go:noinline
|
||||||
func (c *QQClient) uniPacket(command string, body []byte) (uint16, []byte) {
|
func (c *QQClient) uniPacket(command string, body []byte) (uint16, []byte) {
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
req := codec.Uni{
|
req := network.Request{
|
||||||
|
Type: network.RequestTypeSimple,
|
||||||
|
EncryptType: network.EncryptTypeD2Key,
|
||||||
Uin: c.Uin,
|
Uin: c.Uin,
|
||||||
Seq: seq,
|
SequenceID: int32(seq),
|
||||||
CommandName: command,
|
CommandName: command,
|
||||||
EncryptType: 1,
|
|
||||||
SessionID: c.OutGoingPacketSessionId,
|
|
||||||
ExtraData: EmptyBytes,
|
|
||||||
Key: c.sigInfo.D2Key,
|
|
||||||
Body: body,
|
Body: body,
|
||||||
}
|
}
|
||||||
return seq, req.Encode()
|
return seq, c.transport.PackPacket(&req)
|
||||||
}
|
}
|
||||||
|
|
||||||
//go:noinline
|
//go:noinline
|
||||||
func (c *QQClient) uniPacketWithSeq(seq uint16, command string, body []byte) []byte {
|
func (c *QQClient) uniPacketWithSeq(seq uint16, command string, body []byte) []byte {
|
||||||
req := codec.Uni{
|
req := network.Request{
|
||||||
|
Type: network.RequestTypeSimple,
|
||||||
|
EncryptType: network.EncryptTypeD2Key,
|
||||||
Uin: c.Uin,
|
Uin: c.Uin,
|
||||||
Seq: seq,
|
SequenceID: int32(seq),
|
||||||
CommandName: command,
|
CommandName: command,
|
||||||
EncryptType: 1,
|
|
||||||
SessionID: c.OutGoingPacketSessionId,
|
|
||||||
ExtraData: EmptyBytes,
|
|
||||||
Key: c.sigInfo.D2Key,
|
|
||||||
Body: body,
|
Body: body,
|
||||||
}
|
}
|
||||||
return req.Encode()
|
return c.transport.PackPacket(&req)
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ func (c *QQClient) buildGetOneDayRoamMsgRequest(target, lastMsgTime, random int6
|
|||||||
ReadCnt: &count,
|
ReadCnt: &count,
|
||||||
}
|
}
|
||||||
payload, _ := proto.Marshal(req)
|
payload, _ := proto.Marshal(req)
|
||||||
packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbGetOneDayRoamMsg", 1, c.OutGoingPacketSessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
packet := packets.BuildUniPacket(c.Uin, seq, "MessageSvc.PbGetOneDayRoamMsg", 1, c.SessionId, EmptyBytes, c.sigInfo.d2Key, payload)
|
||||||
return seq, packet
|
return seq, packet
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
@ -157,11 +157,11 @@ func (c *QQClient) buildGetOfflineMsgRequestPacket() (uint16, []byte) {
|
|||||||
Channel: 4,
|
Channel: 4,
|
||||||
Inst: 1,
|
Inst: 1,
|
||||||
ChannelEx: 1,
|
ChannelEx: 1,
|
||||||
SyncCookie: c.syncCookie,
|
SyncCookie: c.sig.SyncCookie,
|
||||||
SyncFlag: 0, // START
|
SyncFlag: 0, // START
|
||||||
RambleFlag: 0,
|
RambleFlag: 0,
|
||||||
GeneralAbi: 1,
|
GeneralAbi: 1,
|
||||||
PubAccountCookie: c.pubAccountCookie,
|
PubAccountCookie: c.sig.PubAccountCookie,
|
||||||
},
|
},
|
||||||
GroupMsg: &jce.SvcReqPullGroupMsgSeq{
|
GroupMsg: &jce.SvcReqPullGroupMsgSeq{
|
||||||
VerifyType: 0,
|
VerifyType: 0,
|
||||||
@ -172,7 +172,7 @@ func (c *QQClient) buildGetOfflineMsgRequestPacket() (uint16, []byte) {
|
|||||||
flag := msg.SyncFlag_START
|
flag := msg.SyncFlag_START
|
||||||
msgReq, _ := proto.Marshal(&msg.GetMessageRequest{
|
msgReq, _ := proto.Marshal(&msg.GetMessageRequest{
|
||||||
SyncFlag: &flag,
|
SyncFlag: &flag,
|
||||||
SyncCookie: c.syncCookie,
|
SyncCookie: c.sig.SyncCookie,
|
||||||
RambleFlag: proto.Int32(0),
|
RambleFlag: proto.Int32(0),
|
||||||
ContextFlag: proto.Int32(1),
|
ContextFlag: proto.Int32(1),
|
||||||
OnlineSyncFlag: proto.Int32(0),
|
OnlineSyncFlag: proto.Int32(0),
|
||||||
@ -224,11 +224,11 @@ func (c *QQClient) buildSyncMsgRequestPacket() (uint16, []byte) {
|
|||||||
Channel: 4,
|
Channel: 4,
|
||||||
Inst: 1,
|
Inst: 1,
|
||||||
ChannelEx: 1,
|
ChannelEx: 1,
|
||||||
SyncCookie: c.syncCookie,
|
SyncCookie: c.sig.SyncCookie,
|
||||||
SyncFlag: 0, // START
|
SyncFlag: 0, // START
|
||||||
RambleFlag: 0,
|
RambleFlag: 0,
|
||||||
GeneralAbi: 1,
|
GeneralAbi: 1,
|
||||||
PubAccountCookie: c.pubAccountCookie,
|
PubAccountCookie: c.sig.PubAccountCookie,
|
||||||
},
|
},
|
||||||
GroupMask: 2,
|
GroupMask: 2,
|
||||||
EndSeq: int64(rand.Uint32()),
|
EndSeq: int64(rand.Uint32()),
|
||||||
@ -237,7 +237,7 @@ func (c *QQClient) buildSyncMsgRequestPacket() (uint16, []byte) {
|
|||||||
flag := msg.SyncFlag_START
|
flag := msg.SyncFlag_START
|
||||||
msgReq := &msg.GetMessageRequest{
|
msgReq := &msg.GetMessageRequest{
|
||||||
SyncFlag: &flag,
|
SyncFlag: &flag,
|
||||||
SyncCookie: c.syncCookie,
|
SyncCookie: c.sig.SyncCookie,
|
||||||
RambleFlag: proto.Int32(0),
|
RambleFlag: proto.Int32(0),
|
||||||
ContextFlag: proto.Int32(1),
|
ContextFlag: proto.Int32(1),
|
||||||
OnlineSyncFlag: proto.Int32(0),
|
OnlineSyncFlag: proto.Int32(0),
|
||||||
@ -248,7 +248,7 @@ func (c *QQClient) buildSyncMsgRequestPacket() (uint16, []byte) {
|
|||||||
offMsg, _ := proto.Marshal(msgReq)
|
offMsg, _ := proto.Marshal(msgReq)
|
||||||
msgReq.MsgReqType = proto.Int32(2)
|
msgReq.MsgReqType = proto.Int32(2)
|
||||||
msgReq.SyncCookie = nil
|
msgReq.SyncCookie = nil
|
||||||
msgReq.PubaccountCookie = c.pubAccountCookie
|
msgReq.PubaccountCookie = c.sig.PubAccountCookie
|
||||||
pubMsg, _ := proto.Marshal(msgReq)
|
pubMsg, _ := proto.Marshal(msgReq)
|
||||||
buf := &jce.RequestDataVersion3{Map: map[string][]byte{
|
buf := &jce.RequestDataVersion3{Map: map[string][]byte{
|
||||||
"req_PbOffMsg": jce.NewJceWriter().WriteBytes(append([]byte{0, 0, 0, 0}, offMsg...), 0).Bytes(),
|
"req_PbOffMsg": jce.NewJceWriter().WriteBytes(append([]byte{0, 0, 0, 0}, offMsg...), 0).Bytes(),
|
||||||
@ -280,7 +280,7 @@ func (c *QQClient) buildPrivateMsgReadedPacket(uin, time int64) (uint16, []byte)
|
|||||||
PeerUin: proto.Uint64(uint64(uin)),
|
PeerUin: proto.Uint64(uint64(uin)),
|
||||||
LastReadTime: proto.Uint32(uint32(time)),
|
LastReadTime: proto.Uint32(uint32(time)),
|
||||||
},
|
},
|
||||||
}, SyncCookie: c.syncCookie}})
|
}, SyncCookie: c.sig.SyncCookie}})
|
||||||
return c.uniPacket("PbMessageSvc.PbMsgReadedReport", req)
|
return c.uniPacket("PbMessageSvc.PbMsgReadedReport", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/client/internal/auth"
|
|
||||||
"github.com/Mrs4s/MiraiGo/utils"
|
"github.com/Mrs4s/MiraiGo/utils"
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
"github.com/Mrs4s/MiraiGo/binary"
|
||||||
@ -44,7 +43,7 @@ func (c *QQClient) decodeT119(data, ek []byte) {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
if t108, ok := m[0x108]; ok {
|
if t108, ok := m[0x108]; ok {
|
||||||
c.ksid = t108
|
c.sig.Ksid = t108
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -91,29 +90,28 @@ func (c *QQClient) decodeT119(data, ek []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we don't use `c.sigInfo = &auth.SigInfo{...}` here,
|
// we don't use `c.sigInfo = &auth.SigInfo{...}` here,
|
||||||
// because we need spread `SigInfo` to other places
|
// because we need keep other fields in `c.sigInfo`
|
||||||
*c.sigInfo = auth.SigInfo{
|
s := c.sig
|
||||||
LoginBitmap: 0,
|
s.LoginBitmap = 0
|
||||||
SrmToken: utils.Select(m[0x16a], c.sigInfo.SrmToken),
|
s.SrmToken = utils.Select(m[0x16a], s.SrmToken)
|
||||||
T133: utils.Select(m[0x133], c.sigInfo.T133),
|
s.T133 = utils.Select(m[0x133], s.T133)
|
||||||
EncryptedA1: utils.Select(m[0x106], c.sigInfo.EncryptedA1),
|
s.EncryptedA1 = utils.Select(m[0x106], s.EncryptedA1)
|
||||||
TGT: m[0x10a],
|
s.TGT = m[0x10a]
|
||||||
TGTKey: m[0x10d],
|
s.TGTKey = m[0x10d]
|
||||||
UserStKey: m[0x10e],
|
s.UserStKey = m[0x10e]
|
||||||
UserStWebSig: m[0x103],
|
s.UserStWebSig = m[0x103]
|
||||||
SKey: m[0x120],
|
s.SKey = m[0x120]
|
||||||
SKeyExpiredTime: time.Now().Unix() + 21600,
|
s.SKeyExpiredTime = time.Now().Unix() + 21600
|
||||||
D2: m[0x143],
|
s.D2 = m[0x143]
|
||||||
D2Key: m[0x305],
|
s.D2Key = m[0x305]
|
||||||
WtSessionTicketKey: utils.Select(m[0x134], c.sigInfo.WtSessionTicketKey),
|
s.WtSessionTicketKey = utils.Select(m[0x134], s.WtSessionTicketKey)
|
||||||
DeviceToken: m[0x322],
|
s.DeviceToken = m[0x322]
|
||||||
|
|
||||||
PsKeyMap: psKeyMap,
|
s.PsKeyMap = psKeyMap
|
||||||
Pt4TokenMap: pt4TokenMap,
|
s.Pt4TokenMap = pt4TokenMap
|
||||||
}
|
|
||||||
if len(c.PasswordMd5[:]) > 0 {
|
if len(c.PasswordMd5[:]) > 0 {
|
||||||
key := md5.Sum(append(append(c.PasswordMd5[:], []byte{0x00, 0x00, 0x00, 0x00}...), binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(c.Uin)) })...))
|
key := md5.Sum(append(append(c.PasswordMd5[:], []byte{0x00, 0x00, 0x00, 0x00}...), binary.NewWriterF(func(w *binary.Writer) { w.WriteUInt32(uint32(c.Uin)) })...))
|
||||||
decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sigInfo.EncryptedA1)
|
decrypted := binary.NewTeaCipher(key[:]).Decrypt(c.sig.EncryptedA1)
|
||||||
if len(decrypted) > 51+16 {
|
if len(decrypted) > 51+16 {
|
||||||
dr := binary.NewReader(decrypted)
|
dr := binary.NewReader(decrypted)
|
||||||
dr.ReadBytes(51)
|
dr.ReadBytes(51)
|
||||||
@ -132,9 +130,9 @@ func (c *QQClient) decodeT119R(data []byte) {
|
|||||||
reader.ReadBytes(2)
|
reader.ReadBytes(2)
|
||||||
m := reader.ReadTlvMap(2)
|
m := reader.ReadTlvMap(2)
|
||||||
if t120, ok := m[0x120]; ok {
|
if t120, ok := m[0x120]; ok {
|
||||||
c.sigInfo.SKey = t120
|
c.sig.SKey = t120
|
||||||
c.sigInfo.SKeyExpiredTime = time.Now().Unix() + 21600
|
c.sig.SKeyExpiredTime = time.Now().Unix() + 21600
|
||||||
c.Debug("skey updated: %v", c.sigInfo.SKey)
|
c.Debug("skey updated: %v", c.sig.SKey)
|
||||||
}
|
}
|
||||||
if t11a, ok := m[0x11a]; ok {
|
if t11a, ok := m[0x11a]; ok {
|
||||||
c.Nickname, c.Age, c.Gender = readT11A(t11a)
|
c.Nickname, c.Age, c.Gender = readT11A(t11a)
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
package packets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/Mrs4s/MiraiGo/binary"
|
|
||||||
)
|
|
||||||
|
|
||||||
func BuildLoginPacket(uin int64, bodyType byte, key, body, extraData []byte) []byte {
|
|
||||||
return binary.NewWriterF(func(w *binary.Writer) {
|
|
||||||
w.WriteIntLvPacket(4, func(w *binary.Writer) {
|
|
||||||
w.WriteUInt32(0x00_00_00_0A)
|
|
||||||
w.WriteByte(bodyType)
|
|
||||||
w.WriteIntLvPacket(4, func(w *binary.Writer) {
|
|
||||||
w.Write(extraData)
|
|
||||||
})
|
|
||||||
w.WriteByte(0x00)
|
|
||||||
w.WriteString(strconv.FormatInt(uin, 10))
|
|
||||||
if len(key) == 0 {
|
|
||||||
w.Write(body)
|
|
||||||
} else {
|
|
||||||
w.EncryptAndWrite(key, body)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
@ -46,38 +46,6 @@ func BuildCode2DRequestPacket(seq uint32, j uint64, cmd uint16, bodyFunc func(wr
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func BuildSsoPacket(seq uint16, appID, subAppID uint32, commandName, imei string, extData, outPacketSessionId, body, ksid []byte) []byte {
|
|
||||||
return binary.NewWriterF(func(p *binary.Writer) {
|
|
||||||
p.WriteIntLvPacket(4, func(writer *binary.Writer) {
|
|
||||||
writer.WriteUInt32(uint32(seq))
|
|
||||||
writer.WriteUInt32(appID)
|
|
||||||
writer.WriteUInt32(subAppID)
|
|
||||||
writer.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
|
||||||
if len(extData) == 0 || len(extData) == 4 {
|
|
||||||
writer.WriteUInt32(0x04)
|
|
||||||
} else {
|
|
||||||
writer.WriteUInt32(uint32(len(extData) + 4))
|
|
||||||
writer.Write(extData)
|
|
||||||
}
|
|
||||||
writer.WriteString(commandName)
|
|
||||||
writer.WriteIntLvPacket(4, func(w *binary.Writer) {
|
|
||||||
w.Write(outPacketSessionId)
|
|
||||||
})
|
|
||||||
writer.WriteString(imei)
|
|
||||||
writer.WriteUInt32(0x04)
|
|
||||||
{
|
|
||||||
writer.WriteUInt16(uint16(len(ksid)) + 2)
|
|
||||||
writer.Write(ksid)
|
|
||||||
}
|
|
||||||
writer.WriteUInt32(0x04)
|
|
||||||
})
|
|
||||||
|
|
||||||
p.WriteIntLvPacket(4, func(writer *binary.Writer) {
|
|
||||||
writer.Write(body)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ParseIncomingPacket(payload, d2key []byte) (*IncomingPacket, error) {
|
func ParseIncomingPacket(payload, d2key []byte) (*IncomingPacket, error) {
|
||||||
if len(payload) < 6 {
|
if len(payload) < 6 {
|
||||||
return nil, errors.WithStack(ErrInvalidPayload)
|
return nil, errors.WithStack(ErrInvalidPayload)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user