Initial open source release
This commit is contained in:
commit
74992e893f
377 changed files with 118084 additions and 0 deletions
148
internal/rpc/stickers.go
Normal file
148
internal/rpc/stickers.go
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
package rpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/gotd/td/tg"
|
||||
|
||||
"telesrv/internal/compat/tdesktop"
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
// 本文件把 reaction / sticker 资源 RPC 接到真实 seed 数据(documents / sticker_sets /
|
||||
// available_reactions);Files 服务缺失或资源未导入时回退到 tdesktop 兼容 stub。
|
||||
|
||||
func (r *Router) onMessagesGetAvailableReactions(ctx context.Context, hash int) (tg.MessagesAvailableReactionsClass, error) {
|
||||
if r.deps.Files == nil {
|
||||
return tdesktop.AvailableReactions(hash), nil
|
||||
}
|
||||
reactions, err := r.deps.Files.ListAvailableReactions(ctx)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if len(reactions) == 0 {
|
||||
return tdesktop.AvailableReactions(hash), nil
|
||||
}
|
||||
catalogHash := availableReactionsHash(reactions)
|
||||
if hash == catalogHash {
|
||||
return &tg.MessagesAvailableReactionsNotModified{}, nil
|
||||
}
|
||||
docs, err := r.deps.Files.GetDocuments(ctx, reactionDocumentIDs(reactions))
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
return tgAvailableReactions(reactions, documentsByID(docs), catalogHash), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetStickerSet(ctx context.Context, req *tg.MessagesGetStickerSetRequest) (tg.MessagesStickerSetClass, error) {
|
||||
if r.deps.Files == nil {
|
||||
return tdesktop.StickerSet(req), nil
|
||||
}
|
||||
ref, ok := stickerSetRefFromInput(req.Stickerset)
|
||||
if !ok {
|
||||
return tdesktop.StickerSet(req), nil
|
||||
}
|
||||
set, docs, found, err := r.deps.Files.ResolveStickerSet(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if !found {
|
||||
// 未 seed 的系统集 / 未知短名:回退兼容 stub,避免破坏客户端。
|
||||
return tdesktop.StickerSet(req), nil
|
||||
}
|
||||
if req.Hash != 0 && req.Hash == set.Hash {
|
||||
return &tg.MessagesStickerSetNotModified{}, nil
|
||||
}
|
||||
return tgMessagesStickerSet(set, docs), nil
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetAllStickers(ctx context.Context, hash int64) (tg.MessagesAllStickersClass, error) {
|
||||
return r.allStickersForKind(ctx, hash, domain.StickerSetKindStickers)
|
||||
}
|
||||
|
||||
func (r *Router) onMessagesGetEmojiStickers(ctx context.Context, hash int64) (tg.MessagesAllStickersClass, error) {
|
||||
return r.allStickersForKind(ctx, hash, domain.StickerSetKindEmoji)
|
||||
}
|
||||
|
||||
func (r *Router) allStickersForKind(ctx context.Context, hash int64, kind domain.StickerSetKind) (tg.MessagesAllStickersClass, error) {
|
||||
if r.deps.Files == nil {
|
||||
return messagesAllStickersEmpty(hash), nil
|
||||
}
|
||||
sets, err := r.deps.Files.ListStickerSets(ctx, kind)
|
||||
if err != nil {
|
||||
return nil, internalErr()
|
||||
}
|
||||
if len(sets) == 0 {
|
||||
return messagesAllStickersEmpty(hash), nil
|
||||
}
|
||||
catalogHash := stickerSetsCatalogHash(sets)
|
||||
if hash == catalogHash {
|
||||
return &tg.MessagesAllStickersNotModified{}, nil
|
||||
}
|
||||
return &tg.MessagesAllStickers{Hash: catalogHash, Sets: tgStickerSets(sets)}, nil
|
||||
}
|
||||
|
||||
func documentsByID(docs []domain.Document) map[int64]domain.Document {
|
||||
m := make(map[int64]domain.Document, len(docs))
|
||||
for _, d := range docs {
|
||||
m[d.ID] = d
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
// availableReactionsHash 用 reaction 的核心字段算稳定 hash(供 *NotModified 缓存判定)。
|
||||
func availableReactionsHash(reactions []domain.AvailableReaction) int {
|
||||
values := make([]int64, 0, len(reactions)*10)
|
||||
for _, r := range reactions {
|
||||
values = append(values,
|
||||
int64(len([]rune(r.Reaction))),
|
||||
boolHashValue(r.Inactive),
|
||||
boolHashValue(r.Premium),
|
||||
r.StaticIconID,
|
||||
r.AppearAnimationID,
|
||||
r.SelectAnimationID,
|
||||
r.ActivateAnimationID,
|
||||
r.EffectAnimationID,
|
||||
r.AroundAnimationID,
|
||||
r.CenterIconID,
|
||||
)
|
||||
}
|
||||
return int(tdesktopCountHash(values) & 0x7fffffff)
|
||||
}
|
||||
|
||||
func stickerSetsCatalogHash(sets []domain.StickerSet) int64 {
|
||||
values := make([]int64, 0, len(sets))
|
||||
for _, set := range sets {
|
||||
if set.ID == 0 {
|
||||
return 0
|
||||
}
|
||||
if set.Archived {
|
||||
continue
|
||||
}
|
||||
values = append(values, int64(set.Hash))
|
||||
}
|
||||
return int64(tdesktopCountHash(values))
|
||||
}
|
||||
|
||||
func boolHashValue(v bool) int64 {
|
||||
if v {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func tdesktopCountHash(values []int64) uint64 {
|
||||
var hash uint64
|
||||
for _, value := range values {
|
||||
hash = tdesktopHashUpdate(hash, value)
|
||||
}
|
||||
return hash
|
||||
}
|
||||
|
||||
func tdesktopHashUpdate(hash uint64, value int64) uint64 {
|
||||
hash ^= hash >> 21
|
||||
hash ^= hash << 35
|
||||
hash ^= hash >> 4
|
||||
hash += uint64(value)
|
||||
return hash
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue