1
0
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:
wdvxdr 2023-02-14 23:23:09 +08:00
parent 3ff1fee1b6
commit cfd7d92d1f
6 changed files with 131 additions and 121 deletions

View File

@ -137,9 +137,8 @@ func (c *QQClient) buildDeviceLockLoginPacket() (uint16, []byte) {
}
func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (uint16, []byte) {
version := c.transport.Version
watch := auth.AndroidWatch.Version()
c.transport.Version = watch
c.transport.Version = &watch
seq := c.nextSeq()
req := oicq.Message{
Command: 0x0812,
@ -173,13 +172,13 @@ func (c *QQClient) buildQRCodeFetchRequestPacket(size, margin, ecLevel uint32) (
Body: c.oicq.Marshal(&req),
}
payload := c.transport.PackPacket(&r)
c.transport.Version = version
c.transport.Version = &c.version
return seq, payload
}
func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []byte) {
version := c.transport.Version
c.transport.Version = auth.AndroidWatch.Version()
watch := auth.AndroidWatch.Version()
c.transport.Version = &watch
seq := c.nextSeq()
req := oicq.Message{
Command: 0x0812,
@ -209,7 +208,7 @@ func (c *QQClient) buildQRCodeResultQueryRequestPacket(sig []byte) (uint16, []by
Body: c.oicq.Marshal(&req),
}
payload := c.transport.PackPacket(&r)
c.transport.Version = version
c.transport.Version = &c.version
return seq, payload
}

View File

@ -4,7 +4,6 @@ import (
"crypto/md5"
"fmt"
"math/rand"
"net"
"net/netip"
"sort"
"strconv"
@ -62,6 +61,7 @@ type QQClient struct {
// internal state
handlers syncx.Map[uint16, *handlerInfo]
waiters syncx.Map[string, func(any, error)]
initServerOnce sync.Once
servers []netip.AddrPort
currServerIndex int
retryTimes int
@ -197,15 +197,12 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
onlinePushCache: utils.NewCache[unit](time.Second * 15),
alive: true,
highwaySession: new(highway.Session),
version: new(auth.AppVersion),
device: new(auth.Device),
}
cli.transport = &network.Transport{
Sig: cli.sig,
Version: cli.version,
Device: cli.device,
Version: &cli.version,
Device: &cli.device,
}
cli.oicq = oicq.NewCodec(cli.Uin)
{ // init atomic values
@ -217,62 +214,18 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
}
cli.highwaySession.Uin = strconv.FormatInt(cli.Uin, 10)
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.UnexpectedDisconnect(cli.unexpectedDisconnect)
return cli
}
func (c *QQClient) Device() *DeviceInfo {
return c.device
}
func (c *QQClient) UseDevice(info *auth.Device) {
*c.version = *info.Protocol.Version()
*c.device = *info
c.version = info.Protocol.Version()
c.device = info
c.highwaySession.AppID = int32(c.version.AppId)
c.sig.Ksid = []byte(fmt.Sprintf("|%s|A8.2.7.27f6ea96", info.IMEI))
}

View File

@ -31,15 +31,20 @@ type (
Version = auth.OSVersion
)
var SystemDeviceInfo = &DeviceInfo{
Display: []byte("MIRAI.123456.001"),
var EmptyBytes = make([]byte, 0)
func GenRandomDevice() *DeviceInfo {
r := make([]byte, 16)
crand.Read(r)
const numberRange = "0123456789"
var device = &DeviceInfo{
Product: []byte("mirai"),
Device: []byte("mirai"),
Board: []byte("mirai"),
Brand: []byte("mamoe"),
Model: []byte("mirai"),
Bootloader: []byte("unknown"),
FingerPrint: []byte("mamoe/mirai/mirai:10/MIRAI.200122.001/1234567:user/release-keys"),
BootId: []byte("cb886ae2-00b6-4d68-a230-787f111d12c7"),
ProcVersion: []byte("Linux version 3.0.31-cb886ae2 (android-build@xxx.xxx.xxx.xxx.com)"),
BaseBand: EmptyBytes,
@ -61,36 +66,22 @@ var SystemDeviceInfo = &DeviceInfo{
CodeName: []byte("REL"),
SDK: 29,
},
}
}
var EmptyBytes = make([]byte, 0)
func init() {
r := make([]byte, 16)
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")
device.BootId = binary.GenUUID(r)
device.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.GenNewGuid()
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()
device.IMSIMd5 = t[:]
device.IMEI = GenIMEI()
r = make([]byte, 8)
crand.Read(r)
hex.Encode(SystemDeviceInfo.AndroidId, r)
SystemDeviceInfo.GenNewGuid()
SystemDeviceInfo.GenNewTgtgtKey()
hex.Encode(device.AndroidId, r)
device.GenNewGuid()
device.GenNewTgtgtKey()
return device
}
func GenIMEI() string {
@ -114,13 +105,13 @@ func GenIMEI() string {
return final.String()
}
func getSSOAddress() ([]netip.AddrPort, error) {
protocol := SystemDeviceInfo.Protocol.Version()
func getSSOAddress(device *auth.Device) ([]netip.AddrPort, error) {
protocol := device.Protocol.Version()
key, _ := hex.DecodeString("F0441F5FF42DA58FDCF7949ABA62D411")
payload := jce.NewJceWriter(). // see ServerConfig.d
WriteInt64(0, 1).WriteInt64(0, 2).WriteByte(1, 3).
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, 11).WriteByte(0, 12).WriteInt64(0, 13).Bytes()
buf := &jce.RequestDataVersion3{

View File

@ -139,6 +139,14 @@ func (info *Device) ReadJson(d []byte) error {
default:
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.GenNewTgtgtKey()
return nil

View File

@ -10,8 +10,8 @@ import (
// Transport is a network transport.
type Transport struct {
Sig *auth.SigInfo
Version *auth.AppVersion
Device *auth.Device
Version **auth.AppVersion
Device **auth.Device
// connection
// conn *TCPClient
@ -21,8 +21,8 @@ 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.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 {
@ -36,7 +36,7 @@ func (t *Transport) packBody(req *Request, w *binary.Writer) {
w.WriteUInt32(uint32(len(t.Sig.OutPacketSessionID) + 4))
w.Write(t.Sig.OutPacketSessionID)
if req.Type == RequestTypeLogin {
w.WriteString(t.Device.IMEI)
w.WriteString((*t.Device).IMEI)
w.WriteUInt32(0x04)
w.WriteUInt16(uint16(len(t.Sig.Ksid)) + 2)

View File

@ -2,7 +2,9 @@ package client
import (
"net"
"net/netip"
"runtime/debug"
"sort"
"sync"
"time"
@ -86,8 +88,65 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
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 中的服务器
func (c *QQClient) connect() error {
// init qq servers
c.initServerOnce.Do(c.initServers)
addr := c.servers[c.currServerIndex].String()
c.info("connect to server: %v", addr)
err := c.TCP.Connect(addr)