diff --git a/client/client.go b/client/client.go index cff45e7e..b84416e0 100644 --- a/client/client.go +++ b/client/client.go @@ -58,13 +58,9 @@ type QQClient struct { oicq *oicq.Codec // internal state - waiters sync.Map - servers []*net.TCPAddr - currServerIndex int - retryTimes int - version *auth.AppVersion - deviceInfo *auth.Device - alive bool + waiters sync.Map + version *auth.AppVersion + deviceInfo *auth.Device // session info qwebSeq atomic.Int64 @@ -139,8 +135,6 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient { msgSvcCache: utils.NewCache(time.Second * 15), transCache: utils.NewCache(time.Second * 15), onlinePushCache: utils.NewCache(time.Second * 15), - servers: []*net.TCPAddr{}, - alive: true, highwaySession: new(highway.Session), pending: make(map[int32]*network.Call), @@ -166,27 +160,29 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient { cli.UseDevice(SystemDeviceInfo) sso, err := getSSOAddress() if err == nil && len(sso) > 0 { - cli.servers = append(sso, cli.servers...) + for _, addr := range sso { + cli.transport.AddServerAddr(addr) + } } adds, err := net.LookupIP("msfwifi.3g.qq.com") // host servers if err == nil && len(adds) > 0 { - var hostAddrs []*net.TCPAddr for _, addr := range adds { - hostAddrs = append(hostAddrs, &net.TCPAddr{ + cli.transport.AddServerAddr(&net.TCPAddr{ IP: addr, Port: 8080, }) } - cli.servers = append(hostAddrs, cli.servers...) } - if len(cli.servers) == 0 { - cli.servers = []*net.TCPAddr{ // default servers + if cli.transport.ServerCount() == 0 { + for _, addr := range []*net.TCPAddr{ // default servers {IP: net.IP{42, 81, 172, 22}, Port: 80}, {IP: net.IP{42, 81, 172, 81}, Port: 80}, {IP: net.IP{42, 81, 172, 147}, Port: 443}, {IP: net.IP{114, 221, 144, 215}, Port: 80}, {IP: net.IP{114, 221, 148, 59}, Port: 14000}, {IP: net.IP{125, 94, 60, 146}, Port: 80}, + } { + cli.transport.AddServerAddr(addr) } } /*pings := make([]int64, len(cli.servers)) @@ -227,7 +223,6 @@ func (c *QQClient) Release() { if c.Online.Load() { c.Disconnect() } - c.alive = false } // Login send login request @@ -831,7 +826,9 @@ func (g *GroupInfo) removeMember(uin int64) { } func (c *QQClient) SetCustomServer(servers []*net.TCPAddr) { - c.servers = append(servers, c.servers...) + for _, server := range servers { + c.transport.AddServerAddr(server) + } } func (c *QQClient) registerClient() error { diff --git a/client/internal/network/transport.go b/client/internal/network/transport.go index 2b700a20..8fa187bd 100644 --- a/client/internal/network/transport.go +++ b/client/internal/network/transport.go @@ -3,10 +3,12 @@ package network import ( goBinary "encoding/binary" "fmt" - "github.com/pkg/errors" "io" "net" "strconv" + "sync" + + "github.com/pkg/errors" "github.com/Mrs4s/MiraiGo/binary" "github.com/Mrs4s/MiraiGo/client/internal/auth" @@ -20,7 +22,28 @@ type Transport struct { Device *auth.Device // connection - conn TCPListener + connMu sync.Mutex + servers []*net.TCPAddr + curServerAddr *net.TCPAddr + conn TCPListener +} + +func (t *Transport) AddServerAddr(addr *net.TCPAddr) { + t.connMu.Lock() + defer t.connMu.Unlock() + t.servers = append(t.servers, addr) +} + +func (t *Transport) GetServerAddr() *net.TCPAddr { + t.connMu.Lock() + defer t.connMu.Unlock() + return t.curServerAddr +} + +func (t *Transport) ServerCount() int { + t.connMu.Lock() + defer t.connMu.Unlock() + return len(t.servers) } func (t *Transport) PlannedDisconnect(fun func(*TCPListener)) { @@ -31,8 +54,12 @@ func (t *Transport) UnexpectedDisconnect(fun func(*TCPListener, error)) { t.conn.UnexpectedDisconnect = fun } -func (t *Transport) ConnectFastest(servers []*net.TCPAddr) (chosen *net.TCPAddr, err error) { - return t.conn.ConnectFastest(servers) +func (t *Transport) ConnectFastest() (chosen *net.TCPAddr, err error) { + t.connMu.Lock() + defer t.connMu.Unlock() + chosen, err = t.conn.ConnectFastest(t.servers) + t.curServerAddr = chosen + return } func (t *Transport) Close() { diff --git a/client/network.go b/client/network.go index b784995c..447de6e0 100644 --- a/client/network.go +++ b/client/network.go @@ -44,7 +44,7 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo { defer wg.Done() var err error - if r.ChatServerLatency, err = qualityTest(c.servers[c.currServerIndex].String()); err != nil { + if r.ChatServerLatency, err = qualityTest(c.transport.GetServerAddr().String()); err != nil { c.Error("test chat server latency error: %v", err) r.ChatServerLatency = 9999 } @@ -67,7 +67,7 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo { }() go func() { defer wg.Done() - res := utils.RunTCPPingLoop(c.servers[c.currServerIndex].String(), 10) + res := utils.RunTCPPingLoop(c.transport.GetServerAddr().String(), 10) r.ChatServerPacketLoss = res.PacketsLoss if c.highwaySession.AddrLength() > 0 { res = utils.RunTCPPingLoop(c.highwaySession.SsoAddr[0].String(), 10) @@ -87,14 +87,13 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo { func (c *QQClient) connectFastest() error { c.Disconnect() - addr, err := c.transport.ConnectFastest(c.servers) + addr, err := c.transport.ConnectFastest() if err != nil { c.Disconnect() return err } c.Debug("connected to server: %v [fastest]", addr.String()) c.transport.NetLoop(c.pktProc, c.transport.ReadRequest) - c.retryTimes = 0 c.ConnectTime = time.Now() return nil }