chore: refresh gramsrv public release

This commit is contained in:
A 2026-06-30 14:37:43 +08:00
parent 75cebe8dbf
commit 70b6820474
1274 changed files with 378751 additions and 59919 deletions

View file

@ -0,0 +1,286 @@
package rpc
import (
"context"
"github.com/gotd/td/bin"
"github.com/gotd/td/proto"
"sync"
)
type captureSessions struct {
mu sync.Mutex
sessionID int64
userID int64
userResolved bool
authKeyID [8]byte
authKeyResolved bool
receives bool
messageType proto.MessageType
message bin.Encoder
userMessage bin.Encoder // 最近一次 PushToUser* 的消息(与 message 区分:message 也被 PushToSession 覆盖)
pushUserIDs []int64
onlineUserIDs []int64
channelViewers map[int64][]int64
channelMembers map[int64][]int64
// channelViewersLimit 记录最近一次 OnlineChannelUserIDs 收到的 limit,验证 fan-out 封顶传参。
channelViewersLimit int
}
type captureSessionsSnapshot struct {
sessionID int64
userID int64
userResolved bool
authKeyID [8]byte
authKeyResolved bool
receives bool
messageType proto.MessageType
message bin.Encoder
}
func (s *captureSessions) snapshot() captureSessionsSnapshot {
s.mu.Lock()
defer s.mu.Unlock()
return captureSessionsSnapshot{
sessionID: s.sessionID,
userID: s.userID,
userResolved: s.userResolved,
authKeyID: s.authKeyID,
authKeyResolved: s.authKeyResolved,
receives: s.receives,
messageType: s.messageType,
message: s.message,
}
}
func (s *captureSessions) pushedUserIDs() []int64 {
s.mu.Lock()
defer s.mu.Unlock()
return append([]int64(nil), s.pushUserIDs...)
}
// lastUserPush 返回最近一次 PushToUser* 的消息,独立于 message(后者也会被
// pushOnlinePeerStatusesToCurrentSession 经 PushToSession 覆盖成对端状态)。
func (s *captureSessions) lastUserPush() bin.Encoder {
s.mu.Lock()
defer s.mu.Unlock()
return s.userMessage
}
func (s *captureSessions) clearMessages() {
s.mu.Lock()
defer s.mu.Unlock()
s.message = nil
s.userMessage = nil
s.pushUserIDs = nil
}
func (s *captureSessions) BindAuthKey(sessionID int64, authKeyID [8]byte) {
s.mu.Lock()
defer s.mu.Unlock()
if s.authKeyResolved && s.authKeyID != authKeyID {
s.userID = 0
s.userResolved = false
}
s.sessionID = sessionID
s.authKeyID = authKeyID
s.authKeyResolved = true
}
func (s *captureSessions) AuthKeyID(int64) ([8]byte, bool) {
s.mu.Lock()
defer s.mu.Unlock()
return s.authKeyID, s.authKeyResolved
}
func (s *captureSessions) BindUser(sessionID, userID int64) {
s.mu.Lock()
defer s.mu.Unlock()
s.sessionID = sessionID
s.userID = userID
s.userResolved = true
}
func (s *captureSessions) UserID(int64) (int64, bool) {
s.mu.Lock()
defer s.mu.Unlock()
return s.userID, s.userID != 0
}
func (s *captureSessions) UserIDResolved(int64) (int64, bool) {
s.mu.Lock()
defer s.mu.Unlock()
return s.userID, s.userResolved
}
func (s *captureSessions) UnbindAuthKey(authKeyID [8]byte) int {
s.mu.Lock()
defer s.mu.Unlock()
if s.authKeyID == authKeyID {
s.userID = 0
s.userResolved = true
return 1
}
return 0
}
func (s *captureSessions) SetReceivesUpdates(sessionID int64, receives bool) {
s.mu.Lock()
defer s.mu.Unlock()
s.sessionID = sessionID
s.receives = receives
}
func (s *captureSessions) PushToSession(_ context.Context, sessionID int64, t proto.MessageType, msg bin.Encoder) error {
s.mu.Lock()
defer s.mu.Unlock()
s.sessionID = sessionID
s.messageType = t
s.message = msg
return nil
}
func (s *captureSessions) PushToUserExceptSession(_ context.Context, userID, excludeSessionID int64, t proto.MessageType, msg bin.Encoder) (int, error) {
s.mu.Lock()
defer s.mu.Unlock()
s.userID = userID
s.sessionID = excludeSessionID
s.messageType = t
s.message = msg
s.userMessage = msg
s.pushUserIDs = append(s.pushUserIDs, userID)
return 1, nil
}
func (s *captureSessions) IsUserOnline(userID int64) bool {
s.mu.Lock()
defer s.mu.Unlock()
for _, id := range s.onlineUserIDs {
if id == userID {
return true
}
}
return false
}
func (s *captureSessions) OnlineUserIDsForCandidates(candidateUserIDs []int64, limit int) []int64 {
s.mu.Lock()
defer s.mu.Unlock()
online := make(map[int64]struct{}, len(s.onlineUserIDs))
for _, id := range s.onlineUserIDs {
online[id] = struct{}{}
}
out := make([]int64, 0, len(candidateUserIDs))
seen := map[int64]struct{}{}
for _, id := range candidateUserIDs {
if _, ok := seen[id]; ok {
continue
}
seen[id] = struct{}{}
if _, ok := online[id]; !ok {
continue
}
out = append(out, id)
if limit > 0 && len(out) >= limit {
break
}
}
return out
}
func (s *captureSessions) TrackChannelInterest(_ [8]byte, _ int64, userID int64, channelIDs []int64) {
s.mu.Lock()
defer s.mu.Unlock()
if s.channelViewers == nil {
s.channelViewers = make(map[int64][]int64)
}
for channelID, viewers := range s.channelViewers {
out := viewers[:0]
for _, viewerID := range viewers {
if viewerID != userID {
out = append(out, viewerID)
}
}
if len(out) == 0 {
delete(s.channelViewers, channelID)
continue
}
s.channelViewers[channelID] = out
}
for _, channelID := range channelIDs {
if channelID == 0 {
continue
}
s.channelViewers[channelID] = append(s.channelViewers[channelID], userID)
}
}
func (s *captureSessions) ClearChannelInterest(_ [8]byte, _ int64, userID int64) {
s.mu.Lock()
defer s.mu.Unlock()
for channelID, viewers := range s.channelViewers {
out := viewers[:0]
for _, viewerID := range viewers {
if viewerID != userID {
out = append(out, viewerID)
}
}
if len(out) == 0 {
delete(s.channelViewers, channelID)
continue
}
s.channelViewers[channelID] = out
}
}
func (s *captureSessions) OnlineChannelUserIDs(channelID int64, limit int) []int64 {
s.mu.Lock()
defer s.mu.Unlock()
s.channelViewersLimit = limit
return limitIDs(s.channelViewers[channelID], limit)
}
func (s *captureSessions) SetSessionChannelMemberships(_ [8]byte, _ int64, userID int64, channelIDs []int64) {
s.mu.Lock()
defer s.mu.Unlock()
if s.channelMembers == nil {
s.channelMembers = make(map[int64][]int64)
}
for _, channelID := range channelIDs {
if channelID == 0 {
continue
}
s.channelMembers[channelID] = append(s.channelMembers[channelID], userID)
}
}
func (s *captureSessions) AddUserChannelMembership(userID, channelID int64) {
s.mu.Lock()
defer s.mu.Unlock()
if s.channelMembers == nil {
s.channelMembers = make(map[int64][]int64)
}
s.channelMembers[channelID] = append(s.channelMembers[channelID], userID)
}
func (s *captureSessions) RemoveUserChannelMembership(userID, channelID int64) {
s.mu.Lock()
defer s.mu.Unlock()
members := s.channelMembers[channelID]
out := members[:0]
for _, id := range members {
if id != userID {
out = append(out, id)
}
}
if len(out) == 0 {
delete(s.channelMembers, channelID)
return
}
s.channelMembers[channelID] = out
}
func (s *captureSessions) OnlineChannelMemberUserIDs(channelID int64, limit int) []int64 {
s.mu.Lock()
defer s.mu.Unlock()
return limitIDs(s.channelMembers[channelID], limit)
}