1
0
mirror of https://github.com/Mrs4s/MiraiGo.git synced 2025-05-04 11:07:40 +08:00

client: use net/netip

netip包中的数据结构更省内存,而且不需要堆分配
This commit is contained in:
wdvxdr 2022-03-22 22:44:37 +08:00
parent 4314fdcb39
commit 665c6acf02
No known key found for this signature in database
GPG Key ID: 703F8C071DE7A1B6
7 changed files with 39 additions and 87 deletions

View File

@ -5,6 +5,7 @@ import (
"fmt"
"math/rand"
"net"
"net/netip"
"sort"
"strconv"
"sync"
@ -59,7 +60,7 @@ type QQClient struct {
// internal state
handlers syncx.Map[uint16, *handlerInfo]
waiters syncx.Map[string, func(any, error)]
servers []*net.TCPAddr
servers []netip.AddrPort
currServerIndex int
retryTimes int
version *auth.AppVersion
@ -196,7 +197,6 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
msgSvcCache: utils.NewCache[unit](time.Second * 15),
transCache: utils.NewCache[unit](time.Second * 15),
onlinePushCache: utils.NewCache[unit](time.Second * 15),
servers: []*net.TCPAddr{},
alive: true,
highwaySession: new(highway.Session),
@ -226,28 +226,29 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient {
}
adds, err := net.LookupIP("msfwifi.3g.qq.com") // host servers
if err == nil && len(adds) > 0 {
var hostAddrs []*net.TCPAddr
var hostAddrs []netip.AddrPort
for _, addr := range adds {
hostAddrs = append(hostAddrs, &net.TCPAddr{
IP: addr,
Port: 8080,
})
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 = []*net.TCPAddr{ // default servers
{IP: net.IP{42, 81, 172, 81}, Port: 80},
{IP: net.IP{114, 221, 148, 59}, Port: 14000},
{IP: net.IP{42, 81, 172, 147}, Port: 443},
{IP: net.IP{125, 94, 60, 146}, Port: 80},
{IP: net.IP{114, 221, 144, 215}, Port: 80},
{IP: net.IP{42, 81, 172, 22}, Port: 80},
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()
@ -783,7 +784,7 @@ func (c *QQClient) UpdateProfile(profile ProfileDetailUpdate) {
_, _ = c.sendAndWait(c.buildUpdateProfileDetailPacket(profile))
}
func (c *QQClient) SetCustomServer(servers []*net.TCPAddr) {
func (c *QQClient) SetCustomServer(servers []netip.AddrPort) {
c.servers = append(servers, c.servers...)
}

View File

@ -2,7 +2,7 @@ package client
import (
"crypto/md5"
"net"
"net/netip"
"strconv"
"strings"
"sync"
@ -312,16 +312,16 @@ func decodePushReqPacket(c *QQClient, _ *network.IncomingPacketInfo, payload []b
ssoPkt := jce.NewJceReader(jceBuf)
servers := ssoPkt.ReadSsoServerInfos(1)
if len(servers) > 0 {
var adds []*net.TCPAddr
var adds []netip.AddrPort
for _, s := range servers {
if strings.Contains(s.Server, "com") {
continue
}
c.debug("got new server addr: %v location: %v", s.Server, s.Location)
adds = append(adds, &net.TCPAddr{
IP: net.ParseIP(s.Server),
Port: int(s.Port),
})
addr, err := netip.ParseAddr(s.Server)
if err == nil {
adds = append(adds, netip.AddrPortFrom(addr, uint16(s.Port)))
}
}
f := true
for _, e := range c.eventHandlers.serverUpdatedHandlers {

View File

@ -6,6 +6,7 @@ import (
"fmt"
"math/rand"
"net"
"net/netip"
"sort"
"strconv"
"strings"
@ -114,7 +115,7 @@ func GenIMEI() string {
return final.String()
}
func getSSOAddress() ([]*net.TCPAddr, error) {
func getSSOAddress() ([]netip.AddrPort, error) {
protocol := SystemDeviceInfo.Protocol.Version()
key, _ := hex.DecodeString("F0441F5FF42DA58FDCF7949ABA62D411")
payload := jce.NewJceWriter(). // see ServerConfig.d
@ -150,15 +151,15 @@ func getSSOAddress() ([]*net.TCPAddr, error) {
data.ReadFrom(jce.NewJceReader(rspPkt.SBuffer))
reader := jce.NewJceReader(data.Map["HttpServerListRes"][1:])
servers := reader.ReadSsoServerInfos(2)
adds := make([]*net.TCPAddr, 0, len(servers))
adds := make([]netip.AddrPort, 0, len(servers))
for _, s := range servers {
if strings.Contains(s.Server, "com") {
continue
}
adds = append(adds, &net.TCPAddr{
IP: net.ParseIP(s.Server),
Port: int(s.Port),
})
ip, ok := netip.AddrFromSlice(net.ParseIP(s.Server))
if ok {
adds = append(adds, netip.AddrPortFrom(ip, uint16(s.Port)))
}
}
return adds, nil
}

View File

@ -34,9 +34,9 @@ func (t *TCPListener) UnexpectedDisconnect(f func(*TCPListener, error)) {
t.unexpectedDisconnect = f
}
func (t *TCPListener) Connect(addr *net.TCPAddr) error {
func (t *TCPListener) Connect(addr string) error {
t.Close()
conn, err := net.DialTCP("tcp", nil, addr)
conn, err := net.Dial("tcp", addr)
if err != nil {
return errors.Wrap(err, "dial tcp error")
}

View File

@ -40,11 +40,13 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
r := &ConnectionQualityInfo{}
wg := sync.WaitGroup{}
wg.Add(2)
currentServerAddr := c.servers[c.currServerIndex].String()
go func() {
defer wg.Done()
var err error
if r.ChatServerLatency, err = qualityTest(c.servers[c.currServerIndex].String()); err != nil {
if r.ChatServerLatency, err = qualityTest(currentServerAddr); err != nil {
c.error("test chat server latency error: %v", err)
r.ChatServerLatency = 9999
}
@ -67,7 +69,7 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
}()
go func() {
defer wg.Done()
res := utils.RunTCPPingLoop(c.servers[c.currServerIndex].String(), 10)
res := utils.RunTCPPingLoop(currentServerAddr, 10)
r.ChatServerPacketLoss = res.PacketsLoss
if c.highwaySession.AddrLength() > 0 {
res = utils.RunTCPPingLoop(c.highwaySession.SsoAddr[0].String(), 10)
@ -87,8 +89,9 @@ func (c *QQClient) ConnectionQualityTest() *ConnectionQualityInfo {
// connect 连接到 QQClient.servers 中的服务器
func (c *QQClient) connect() error {
c.info("connect to server: %v", c.servers[c.currServerIndex].String())
err := c.TCP.Connect(c.servers[c.currServerIndex])
addr := c.servers[c.currServerIndex].String()
c.info("connect to server: %v", addr)
err := c.TCP.Connect(addr)
c.currServerIndex++
if c.currServerIndex == len(c.servers) {
c.currServerIndex = 0

View File

@ -58,7 +58,7 @@ type (
content map[string]any
)
var globalBlockId int64 = 0
var globalBlockId int64
func genBlockId() string {
id := atomic.AddInt64(&globalBlockId, 1)

View File

@ -44,59 +44,6 @@ func MultiReadSeeker(r ...io.ReadSeeker) io.ReadSeeker {
}
}
type multiReadAt struct {
first io.ReadSeeker
second io.ReadSeeker
firstSize int64
secondSize int64
}
func (m *multiReadAt) ReadAt(p []byte, off int64) (n int, err error) {
if m.second == nil { // quick path
_, _ = m.first.Seek(off, io.SeekStart)
return m.first.Read(p)
}
if off < m.firstSize && off+int64(len(p)) < m.firstSize {
_, err = m.first.Seek(off, io.SeekStart)
if err != nil {
return
}
return m.first.Read(p)
} else if off < m.firstSize && off+int64(len(p)) >= m.firstSize {
_, _ = m.first.Seek(off, io.SeekStart)
_, _ = m.second.Seek(0, io.SeekStart)
n, err = m.first.Read(p[:m.firstSize-off])
if err != nil {
return
}
n2, err := m.second.Read(p[m.firstSize-off:])
return n + n2, err
}
_, err = m.second.Seek(off-m.firstSize, io.SeekStart)
if err != nil {
return
}
return m.second.Read(p)
}
func ReaderAtFrom2ReadSeeker(first, second io.ReadSeeker) io.ReaderAt {
firstSize, _ := first.Seek(0, io.SeekEnd)
if second == nil {
return &multiReadAt{
first: first,
firstSize: firstSize,
secondSize: 0,
}
}
secondSize, _ := second.Seek(0, io.SeekEnd)
return &multiReadAt{
first: first,
second: second,
firstSize: firstSize,
secondSize: secondSize,
}
}
// Select 如果A为nil 将会返回 B 否则返回A
// 对应 ?? 语法
func Select(a, b []byte) []byte {