mirror of
https://github.com/Mrs4s/MiraiGo.git
synced 2025-05-04 11:07:40 +08:00
client: remove SystemDeviceInfo [break]
This commit is contained in:
parent
3ff1fee1b6
commit
cfd7d92d1f
@ -137,9 +137,8 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (uint16, []byte) {
|
func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (uint16, []byte) {
|
||||||
version := c.transport.Version
|
|
||||||
watch := auth.AndroidWatch.Version()
|
watch := auth.AndroidWatch.Version()
|
||||||
c.transport.Version = watch
|
c.transport.Version = &watch
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
req := oicq.Message{
|
req := oicq.Message{
|
||||||
Command: 0x0812,
|
Command: 0x0812,
|
||||||
@ -173,13 +172,13 @@ func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (
|
|||||||
Body: c.oicq.Marshal(&req),
|
Body: c.oicq.Marshal(&req),
|
||||||
}
|
}
|
||||||
payload := c.transport.PackPacket(&r)
|
payload := c.transport.PackPacket(&r)
|
||||||
c.transport.Version = version
|
c.transport.Version = &c.version
|
||||||
return seq, payload
|
return seq, payload
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
|
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
|
||||||
version := c.transport.Version
|
watch := auth.AndroidWatch.Version()
|
||||||
c.transport.Version = auth.AndroidWatch.Version()
|
c.transport.Version = &watch
|
||||||
seq := c.nextSeq()
|
seq := c.nextSeq()
|
||||||
req := oicq.Message{
|
req := oicq.Message{
|
||||||
Command: 0x0812,
|
Command: 0x0812,
|
||||||
@ -209,7 +208,7 @@ func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []by
|
|||||||
Body: c.oicq.Marshal(&req),
|
Body: c.oicq.Marshal(&req),
|
||||||
}
|
}
|
||||||
payload := c.transport.PackPacket(&r)
|
payload := c.transport.PackPacket(&r)
|
||||||
c.transport.Version = version
|
c.transport.Version = &c.version
|
||||||
return seq, payload
|
return seq, payload
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"net"
|
|
||||||
"net/netip"
|
"net/netip"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -62,6 +61,7 @@ type QQClient struct {
|
|||||||
// internal state
|
// internal state
|
||||||
handlers syncx.Map[uint16, *handlerInfo]
|
handlers syncx.Map[uint16, *handlerInfo]
|
||||||
waiters syncx.Map[string, func(any, error)]
|
waiters syncx.Map[string, func(any, error)]
|
||||||
|
initServerOnce sync.Once
|
||||||
servers []netip.AddrPort
|
servers []netip.AddrPort
|
||||||
currServerIndex int
|
currServerIndex int
|
||||||
retryTimes int
|
retryTimes int
|
||||||
@ -197,15 +197,12 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
|||||||
onlinePushCache: utils.NewCache[unit](time.Second * 15),
|
onlinePushCache: utils.NewCache[unit](time.Second * 15),
|
||||||
alive: true,
|
alive: true,
|
||||||
highwaySession: new(highway.Session),
|
highwaySession: new(highway.Session),
|
||||||
|
|
||||||
version: new(auth.AppVersion),
|
|
||||||
device: new(auth.Device),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cli.transport = &network.Transport{
|
cli.transport = &network.Transport{
|
||||||
Sig: cli.sig,
|
Sig: cli.sig,
|
||||||
Version: cli.version,
|
Version: &cli.version,
|
||||||
Device: cli.device,
|
Device: &cli.device,
|
||||||
}
|
}
|
||||||
cli.oicq = oicq.NewCodec(cli.Uin)
|
cli.oicq = oicq.NewCodec(cli.Uin)
|
||||||
{ // init atomic values
|
{ // init atomic values
|
||||||
@ -217,62 +214,18 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
|
|||||||
}
|
}
|
||||||
cli.highwaySession.Uin = strconv.FormatInt(cli.Uin, 10)
|
cli.highwaySession.Uin = strconv.FormatInt(cli.Uin, 10)
|
||||||
cli.GuildService = &GuildService{c: cli}
|
cli.GuildService = &GuildService{c: cli}
|
||||||
cli.UseDevice(SystemDeviceInfo)
|
|
||||||
sso, err := getSSOAddress()
|
|
||||||
if err == nil && len(sso) > 0 {
|
|
||||||
cli.servers = append(sso, cli.servers...)
|
|
||||||
}
|
|
||||||
adds, err := net.LookupIP("msfwifi.3g.qq.com") // host servers
|
|
||||||
if err == nil && len(adds) > 0 {
|
|
||||||
var hostAddrs []netip.AddrPort
|
|
||||||
for _, addr := range adds {
|
|
||||||
ip, ok := netip.AddrFromSlice(addr.To4())
|
|
||||||
if ok {
|
|
||||||
hostAddrs = append(hostAddrs, netip.AddrPortFrom(ip, 8080))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cli.servers = append(hostAddrs, cli.servers...)
|
|
||||||
}
|
|
||||||
if len(cli.servers) == 0 {
|
|
||||||
cli.servers = []netip.AddrPort{ // default servers
|
|
||||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{42, 81, 172, 81}), 80),
|
|
||||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{114, 221, 148, 59}), 14000),
|
|
||||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{42, 81, 172, 147}), 443),
|
|
||||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{125, 94, 60, 146}), 80),
|
|
||||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{114, 221, 144, 215}), 80),
|
|
||||||
netip.AddrPortFrom(netip.AddrFrom4([4]byte{42, 81, 172, 22}), 80),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pings := make([]int64, len(cli.servers))
|
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
wg.Add(len(cli.servers))
|
|
||||||
// println(len(cli.servers))
|
|
||||||
for i := range cli.servers {
|
|
||||||
go func(index int) {
|
|
||||||
defer wg.Done()
|
|
||||||
p, err := qualityTest(cli.servers[index].String())
|
|
||||||
if err != nil {
|
|
||||||
pings[index] = 9999
|
|
||||||
return
|
|
||||||
}
|
|
||||||
pings[index] = p
|
|
||||||
}(i)
|
|
||||||
}
|
|
||||||
wg.Wait()
|
|
||||||
sort.Slice(cli.servers, func(i, j int) bool {
|
|
||||||
return pings[i] < pings[j]
|
|
||||||
})
|
|
||||||
if len(cli.servers) > 3 {
|
|
||||||
cli.servers = cli.servers[0 : len(cli.servers)/2] // 保留ping值中位数以上的server
|
|
||||||
}
|
|
||||||
cli.TCP.PlannedDisconnect(cli.plannedDisconnect)
|
cli.TCP.PlannedDisconnect(cli.plannedDisconnect)
|
||||||
cli.TCP.UnexpectedDisconnect(cli.unexpectedDisconnect)
|
cli.TCP.UnexpectedDisconnect(cli.unexpectedDisconnect)
|
||||||
return cli
|
return cli
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) Device() *DeviceInfo {
|
||||||
|
return c.device
|
||||||
|
}
|
||||||
|
|
||||||
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.device = *info
|
c.device = info
|
||||||
c.highwaySession.AppID = int32(c.version.AppId)
|
c.highwaySession.AppID = int32(c.version.AppId)
|
||||||
c.sig.Ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI))
|
c.sig.Ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI))
|
||||||
}
|
}
|
||||||
|
@ -31,15 +31,20 @@ type (
|
|||||||
Version = auth.OSVersion
|
Version = auth.OSVersion
|
||||||
)
|
)
|
||||||
|
|
||||||
var SystemDeviceInfo = &DeviceInfo{
|
var EmptyBytes = make([]byte, 0)
|
||||||
Display: []byte("MIRAI.123456.001"),
|
|
||||||
|
func GenRandomDevice() *DeviceInfo {
|
||||||
|
r := make([]byte, 16)
|
||||||
|
crand.Read(r)
|
||||||
|
const numberRange = "0123456789"
|
||||||
|
|
||||||
|
var device = &DeviceInfo{
|
||||||
Product: []byte("mirai"),
|
Product: []byte("mirai"),
|
||||||
Device: []byte("mirai"),
|
Device: []byte("mirai"),
|
||||||
Board: []byte("mirai"),
|
Board: []byte("mirai"),
|
||||||
Brand: []byte("mamoe"),
|
Brand: []byte("mamoe"),
|
||||||
Model: []byte("mirai"),
|
Model: []byte("mirai"),
|
||||||
Bootloader: []byte("unknown"),
|
Bootloader: []byte("unknown"),
|
||||||
FingerPrint: []byte("mamoe/mirai/mirai:10/MIRAI.200122.001/1234567:user/release-keys"),
|
|
||||||
BootId: []byte("cb886ae2-00b6-4d68-a230-787f111d12c7"),
|
BootId: []byte("cb886ae2-00b6-4d68-a230-787f111d12c7"),
|
||||||
ProcVersion: []byte("Linux version 3.0.31-cb886ae2 (android-build@xxx.xxx.xxx.xxx.com)"),
|
ProcVersion: []byte("Linux version 3.0.31-cb886ae2 (android-build@xxx.xxx.xxx.xxx.com)"),
|
||||||
BaseBand: EmptyBytes,
|
BaseBand: EmptyBytes,
|
||||||
@ -63,34 +68,20 @@ var SystemDeviceInfo = &DeviceInfo{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var EmptyBytes = make([]byte, 0)
|
device.Display = []byte("MIRAI." + utils.RandomStringRange(6, numberRange) + ".001")
|
||||||
|
device.FingerPrint = []byte("mamoe/mirai/mirai:10/MIRAI.200122.001/" + utils.RandomStringRange(7, numberRange) + ":user/release-keys")
|
||||||
func init() {
|
device.BootId = binary.GenUUID(r)
|
||||||
r := make([]byte, 16)
|
device.ProcVersion = []byte("Linux version 3.0.31-" + utils.RandomString(8) + " (android-build@xxx.xxx.xxx.xxx.com)")
|
||||||
crand.Read(r)
|
crand.Read(r)
|
||||||
t := md5.Sum(r)
|
t := md5.Sum(r)
|
||||||
SystemDeviceInfo.IMSIMd5 = t[:]
|
device.IMSIMd5 = t[:]
|
||||||
SystemDeviceInfo.GenNewGuid()
|
device.IMEI = GenIMEI()
|
||||||
SystemDeviceInfo.GenNewTgtgtKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenRandomDevice() {
|
|
||||||
r := make([]byte, 16)
|
|
||||||
crand.Read(r)
|
|
||||||
const numberRange = "0123456789"
|
|
||||||
SystemDeviceInfo.Display = []byte("MIRAI." + utils.RandomStringRange(6, numberRange) + ".001")
|
|
||||||
SystemDeviceInfo.FingerPrint = []byte("mamoe/mirai/mirai:10/MIRAI.200122.001/" + utils.RandomStringRange(7, numberRange) + ":user/release-keys")
|
|
||||||
SystemDeviceInfo.BootId = binary.GenUUID(r)
|
|
||||||
SystemDeviceInfo.ProcVersion = []byte("Linux version 3.0.31-" + utils.RandomString(8) + " (android-build@xxx.xxx.xxx.xxx.com)")
|
|
||||||
crand.Read(r)
|
|
||||||
t := md5.Sum(r)
|
|
||||||
SystemDeviceInfo.IMSIMd5 = t[:]
|
|
||||||
SystemDeviceInfo.IMEI = GenIMEI()
|
|
||||||
r = make([]byte, 8)
|
r = make([]byte, 8)
|
||||||
crand.Read(r)
|
crand.Read(r)
|
||||||
hex.Encode(SystemDeviceInfo.AndroidId, r)
|
hex.Encode(device.AndroidId, r)
|
||||||
SystemDeviceInfo.GenNewGuid()
|
device.GenNewGuid()
|
||||||
SystemDeviceInfo.GenNewTgtgtKey()
|
device.GenNewTgtgtKey()
|
||||||
|
return device
|
||||||
}
|
}
|
||||||
|
|
||||||
func GenIMEI() string {
|
func GenIMEI() string {
|
||||||
@ -114,13 +105,13 @@ func GenIMEI() string {
|
|||||||
return final.String()
|
return final.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getSSOAddress() ([]netip.AddrPort, error) {
|
func getSSOAddress(device *auth.Device) ([]netip.AddrPort, error) {
|
||||||
protocol := SystemDeviceInfo.Protocol.Version()
|
protocol := device.Protocol.Version()
|
||||||
key, _ := hex.DecodeString("F0441F5FF42DA58FDCF7949ABA62D411")
|
key, _ := hex.DecodeString("F0441F5FF42DA58FDCF7949ABA62D411")
|
||||||
payload := jce.NewJceWriter(). // see ServerConfig.d
|
payload := jce.NewJceWriter(). // see ServerConfig.d
|
||||||
WriteInt64(0, 1).WriteInt64(0, 2).WriteByte(1, 3).
|
WriteInt64(0, 1).WriteInt64(0, 2).WriteByte(1, 3).
|
||||||
WriteString("00000", 4).WriteInt32(100, 5).
|
WriteString("00000", 4).WriteInt32(100, 5).
|
||||||
WriteInt32(int32(protocol.AppId), 6).WriteString(SystemDeviceInfo.IMEI, 7).
|
WriteInt32(int32(protocol.AppId), 6).WriteString(device.IMEI, 7).
|
||||||
WriteInt64(0, 8).WriteInt64(0, 9).WriteInt64(0, 10).
|
WriteInt64(0, 8).WriteInt64(0, 9).WriteInt64(0, 10).
|
||||||
WriteInt64(0, 11).WriteByte(0, 12).WriteInt64(0, 13).Bytes()
|
WriteInt64(0, 11).WriteByte(0, 12).WriteInt64(0, 13).Bytes()
|
||||||
buf := &jce.RequestDataVersion3{
|
buf := &jce.RequestDataVersion3{
|
||||||
|
@ -139,6 +139,14 @@ func (info *Device) ReadJson(d []byte) error {
|
|||||||
default:
|
default:
|
||||||
info.Protocol = IPad
|
info.Protocol = IPad
|
||||||
}
|
}
|
||||||
|
|
||||||
|
v := new(OSVersion)
|
||||||
|
v.SDK = f.Version.Sdk
|
||||||
|
v.Release = []byte(f.Version.Release)
|
||||||
|
v.CodeName = []byte(f.Version.Codename)
|
||||||
|
v.Incremental = []byte(f.Version.Incremental)
|
||||||
|
info.Version = v
|
||||||
|
|
||||||
info.GenNewGuid()
|
info.GenNewGuid()
|
||||||
info.GenNewTgtgtKey()
|
info.GenNewTgtgtKey()
|
||||||
return nil
|
return nil
|
||||||
|
@ -10,8 +10,8 @@ import (
|
|||||||
// Transport is a network transport.
|
// Transport is a network transport.
|
||||||
type Transport struct {
|
type Transport struct {
|
||||||
Sig *auth.SigInfo
|
Sig *auth.SigInfo
|
||||||
Version *auth.AppVersion
|
Version **auth.AppVersion
|
||||||
Device *auth.Device
|
Device **auth.Device
|
||||||
|
|
||||||
// connection
|
// connection
|
||||||
// conn *TCPClient
|
// conn *TCPClient
|
||||||
@ -21,8 +21,8 @@ func (t *Transport) packBody(req *Request, w *binary.Writer) {
|
|||||||
pos := w.FillUInt32()
|
pos := w.FillUInt32()
|
||||||
if req.Type == RequestTypeLogin {
|
if req.Type == RequestTypeLogin {
|
||||||
w.WriteUInt32(uint32(req.SequenceID))
|
w.WriteUInt32(uint32(req.SequenceID))
|
||||||
w.WriteUInt32(t.Version.AppId)
|
w.WriteUInt32((*t.Version).AppId)
|
||||||
w.WriteUInt32(t.Version.SubAppId)
|
w.WriteUInt32((*t.Version).SubAppId)
|
||||||
w.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
w.Write([]byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00})
|
||||||
tgt := t.Sig.TGT
|
tgt := t.Sig.TGT
|
||||||
if len(tgt) == 0 || len(tgt) == 4 {
|
if len(tgt) == 0 || len(tgt) == 4 {
|
||||||
@ -36,7 +36,7 @@ func (t *Transport) packBody(req *Request, w *binary.Writer) {
|
|||||||
w.WriteUInt32(uint32(len(t.Sig.OutPacketSessionID) + 4))
|
w.WriteUInt32(uint32(len(t.Sig.OutPacketSessionID) + 4))
|
||||||
w.Write(t.Sig.OutPacketSessionID)
|
w.Write(t.Sig.OutPacketSessionID)
|
||||||
if req.Type == RequestTypeLogin {
|
if req.Type == RequestTypeLogin {
|
||||||
w.WriteString(t.Device.IMEI)
|
w.WriteString((*t.Device).IMEI)
|
||||||
w.WriteUInt32(0x04)
|
w.WriteUInt32(0x04)
|
||||||
|
|
||||||
w.WriteUInt16(uint16(len(t.Sig.Ksid)) + 2)
|
w.WriteUInt16(uint16(len(t.Sig.Ksid)) + 2)
|
||||||
|
@ -2,7 +2,9 @@ package client
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -86,8 +88,65 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
|
|||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *QQClient) initServers() {
|
||||||
|
if c.device == nil {
|
||||||
|
// must have device. Use c.UseDevice to set it!
|
||||||
|
panic("client device is nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
sso, err := getSSOAddress(c.device)
|
||||||
|
if err == nil && len(sso) > 0 {
|
||||||
|
c.servers = append(sso, c.servers...)
|
||||||
|
}
|
||||||
|
adds, err := net.LookupIP("msfwifi.3g.qq.com") // host servers
|
||||||
|
if err == nil && len(adds) > 0 {
|
||||||
|
var hostAddrs []netip.AddrPort
|
||||||
|
for _, addr := range adds {
|
||||||
|
ip, ok := netip.AddrFromSlice(addr.To4())
|
||||||
|
if ok {
|
||||||
|
hostAddrs = append(hostAddrs, netip.AddrPortFrom(ip, 8080))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c.servers = append(hostAddrs, c.servers...)
|
||||||
|
}
|
||||||
|
if len(c.servers) == 0 {
|
||||||
|
c.servers = []netip.AddrPort{ // default servers
|
||||||
|
netip.AddrPortFrom(netip.AddrFrom4([4]byte{42, 81, 172, 81}), 80),
|
||||||
|
netip.AddrPortFrom(netip.AddrFrom4([4]byte{114, 221, 148, 59}), 14000),
|
||||||
|
netip.AddrPortFrom(netip.AddrFrom4([4]byte{42, 81, 172, 147}), 443),
|
||||||
|
netip.AddrPortFrom(netip.AddrFrom4([4]byte{125, 94, 60, 146}), 80),
|
||||||
|
netip.AddrPortFrom(netip.AddrFrom4([4]byte{114, 221, 144, 215}), 80),
|
||||||
|
netip.AddrPortFrom(netip.AddrFrom4([4]byte{42, 81, 172, 22}), 80),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pings := make([]int64, len(c.servers))
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
wg.Add(len(c.servers))
|
||||||
|
for i := range c.servers {
|
||||||
|
go func(index int) {
|
||||||
|
defer wg.Done()
|
||||||
|
p, err := qualityTest(c.servers[index].String())
|
||||||
|
if err != nil {
|
||||||
|
pings[index] = 9999
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pings[index] = p
|
||||||
|
}(i)
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
sort.Slice(c.servers, func(i, j int) bool {
|
||||||
|
return pings[i] < pings[j]
|
||||||
|
})
|
||||||
|
if len(c.servers) > 3 {
|
||||||
|
c.servers = c.servers[0 : len(c.servers)/2] // 保留ping值中位数以上的server
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// connect 连接到 QQClient.servers 中的服务器
|
// connect 连接到 QQClient.servers 中的服务器
|
||||||
func (c *QQClient) connect() error {
|
func (c *QQClient) connect() error {
|
||||||
|
// init qq servers
|
||||||
|
c.initServerOnce.Do(c.initServers)
|
||||||
|
|
||||||
addr := c.servers[c.currServerIndex].String()
|
addr := c.servers[c.currServerIndex].String()
|
||||||
c.info("connect to server: %v", addr)
|
c.info("connect to server: %v", addr)
|
||||||
err := c.TCP.Connect(addr)
|
err := c.TCP.Connect(addr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user