diff --git a/client/c2c_processor.go b/client/c2c_processor.go index f71d2b71..08504880 100644 --- a/client/c2c_processor.go +++ b/client/c2c_processor.go @@ -83,7 +83,7 @@ func (c *QQClient) commMsgProcessor(pMsg *msg.Message, info *network.IncomingPac c.Debug("c2c msg %v already exists in cache. skip.", pMsg.Head.GetMsgUid()) return } - c.msgSvcCache.Add(strKey, "", time.Hour) + c.msgSvcCache.Add(strKey, unit{}, time.Hour) if c.lastC2CMsgTime > int64(pMsg.Head.GetMsgTime()) && (c.lastC2CMsgTime-int64(pMsg.Head.GetMsgTime())) > 60*10 { c.Debug("c2c msg filtered by time. lastMsgTime: %v msgTime: %v", c.lastC2CMsgTime, pMsg.Head.GetMsgTime()) return diff --git a/client/client.go b/client/client.go index 12a8ce33..0ddc358d 100644 --- a/client/client.go +++ b/client/client.go @@ -77,12 +77,12 @@ type QQClient struct { // fileStorageInfo *jce.FileStoragePushFSSvcList // message state - msgSvcCache *utils.Cache + msgSvcCache *utils.Cache[unit] lastC2CMsgTime int64 - transCache *utils.Cache + transCache *utils.Cache[unit] groupSysMsgCache *GroupSystemMessages msgBuilders sync.Map - onlinePushCache *utils.Cache + onlinePushCache *utils.Cache[unit] heartbeatEnabled bool requestPacketRequestID atomic.Int32 groupSeq atomic.Int32 @@ -164,9 +164,9 @@ func NewClientMd5(uin int64, passwordMd5 [16]byte) *QQClient { sig: &auth.SigInfo{ OutPacketSessionID: []byte{0x02, 0xB0, 0x5B, 0x8B}, }, - msgSvcCache: utils.NewCache(time.Second * 15), - transCache: utils.NewCache(time.Second * 15), - onlinePushCache: utils.NewCache(time.Second * 15), + 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), diff --git a/client/decoders.go b/client/decoders.go index 736014f5..35a17919 100644 --- a/client/decoders.go +++ b/client/decoders.go @@ -646,7 +646,7 @@ func decodeOnlinePushTransPacket(c *QQClient, _ *network.IncomingPacketInfo, pay if _, ok := c.transCache.Get(idStr); ok { return nil, nil } - c.transCache.Add(idStr, "", time.Second*15) + c.transCache.Add(idStr, unit{}, time.Second*15) if info.GetMsgType() == 34 { data.ReadInt32() data.ReadByte() diff --git a/client/entities.go b/client/entities.go index adf22a15..d2351b56 100644 --- a/client/entities.go +++ b/client/entities.go @@ -296,6 +296,9 @@ type ( SigSession []byte SessionKey []byte } + + // unit is an alias for struct{}, like `()` in rust + unit = struct{} ) const ( diff --git a/client/online_push.go b/client/online_push.go index 5a913b92..64723ca0 100644 --- a/client/online_push.go +++ b/client/online_push.go @@ -37,7 +37,7 @@ func decodeOnlinePushReqPacket(c *QQClient, info *network.IncomingPacketInfo, pa if _, ok := c.onlinePushCache.Get(k); ok { continue } - c.onlinePushCache.Add(k, "", time.Second*30) + c.onlinePushCache.Add(k, unit{}, time.Second*30) // 0x2dc if m.MsgType == 732 { r := binary.NewReader(m.VMsg) diff --git a/go.mod b/go.mod index 3ca942d0..6e26ead4 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/Mrs4s/MiraiGo -go 1.17 +go 1.18 require ( github.com/RomiChan/protobuf v0.0.0-20220227114948-643565fff248 diff --git a/utils/ttl.go b/utils/ttl.go index 1b589960..2d27e79e 100644 --- a/utils/ttl.go +++ b/utils/ttl.go @@ -7,26 +7,26 @@ import ( // https://github.com/Konstantin8105/SimpleTTL // entry - typical element of cache -type entry struct { +type entry[T any] struct { expiry time.Time - value interface{} + value T } // Cache - simple implementation of cache // More information: https://en.wikipedia.org/wiki/Time_to_live -type Cache struct { +type Cache[T any] struct { lock sync.RWMutex - cache map[string]*entry + cache map[string]*entry[T] } // NewCache - initialization of new cache. // For avoid mistake - minimal time to live is 1 minute. // For simplification, - key is string and cache haven`t stop method -func NewCache(interval time.Duration) *Cache { +func NewCache[T any](interval time.Duration) *Cache[T] { if interval < time.Second { interval = time.Second } - cache := &Cache{cache: make(map[string]*entry)} + cache := &Cache[T]{cache: make(map[string]*entry[T])} go func() { ticker := time.NewTicker(interval) for { @@ -47,7 +47,7 @@ func NewCache(interval time.Duration) *Cache { } // Count - return amount element of TTL map. -func (cache *Cache) Count() int { +func (cache *Cache[_]) Count() int { cache.lock.RLock() defer cache.lock.RUnlock() @@ -55,7 +55,7 @@ func (cache *Cache) Count() int { } // Get - return value from cache -func (cache *Cache) Get(key string) (interface{}, bool) { +func (cache *Cache[_]) Get(key string) (interface{}, bool) { cache.lock.RLock() defer cache.lock.RUnlock() @@ -67,7 +67,7 @@ func (cache *Cache) Get(key string) (interface{}, bool) { return nil, false } -func (cache *Cache) GetAndUpdate(key string, ttl time.Duration) (interface{}, bool) { +func (cache *Cache[_]) GetAndUpdate(key string, ttl time.Duration) (interface{}, bool) { cache.lock.RLock() defer cache.lock.RUnlock() @@ -79,18 +79,18 @@ func (cache *Cache) GetAndUpdate(key string, ttl time.Duration) (interface{}, bo } // Add - add key/value in cache -func (cache *Cache) Add(key string, value interface{}, ttl time.Duration) { +func (cache *Cache[T]) Add(key string, value T, ttl time.Duration) { cache.lock.Lock() defer cache.lock.Unlock() - cache.cache[key] = &entry{ + cache.cache[key] = &entry[T]{ value: value, expiry: time.Now().Add(ttl), } } // GetKeys - return all keys of cache map -func (cache *Cache) GetKeys() []string { +func (cache *Cache[T]) GetKeys() []string { cache.lock.RLock() defer cache.lock.RUnlock()