owpengram-server/internal/rpc/langpack.go
A 1292540350 feat: sync langpack and auth updates
Sync telesrv commits 49f9bab and 04d9563 into the public mirror. Exclude private docs and runtime key material per sync rules.
2026-07-18 00:07:41 +08:00

152 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package rpc
import (
"context"
"strings"
"github.com/iamxvbaba/td/tg"
"github.com/iamxvbaba/td/tlprofile"
)
// registerLangpack 注册 langpack.* RPC handler。
//
// 老客户端DrKLO发的是不带 lang_pack 参数的旧构造器,已由 gotdgen client overlay 入站升级为 canonical
// 形态并把 lang_pack 置空;故这里 lang_pack 为空时回退到按 client 信息派生langPackFromClient
// 与历史 handleLegacyLangpack* 的行为一致。
func (r *Router) registerLangpack(d *tlprofile.Dispatcher) {
registerRPC[*tg.LangpackGetLanguagesRequest](d, tlprofile.SemanticMethodLangpackGetLanguages, func(ctx context.Context, layerRequest *tg.LangpackGetLanguagesRequest) (any, error) {
langPack := layerRequest.
LangPack
languages, err := r.langpackLanguages(ctx, langPack)
if err != nil {
return nil, internalErr()
}
return languages, nil
})
registerRPC[*tg.LangpackGetLanguageRequest](d, tlprofile.SemanticMethodLangpackGetLanguage, func(ctx context.Context, req *tg.LangpackGetLanguageRequest) (any, error) {
if req == nil {
return nil, inputConstructorInvalidErr()
}
lang, err := r.langpackLanguage(ctx, req.LangPack, req.LangCode)
if err != nil {
return nil, err
}
return &lang, nil
})
registerRPC[*tg.LangpackGetLangPackRequest](d, tlprofile.SemanticMethodLangpackGetLangPack, func(ctx context.Context, req *tg.LangpackGetLangPackRequest) (any, error) {
langPack := langPackOrClient(ctx, req.LangPack)
_ = langPack
if r.deps.LangPack == nil {
return &tg.LangPackDifference{LangCode: req.LangCode}, nil
}
pack, err := r.deps.LangPack.GetLangPack(ctx, langPack, req.LangCode)
if err != nil {
return nil, internalErr()
}
return tgLangPackDifference(pack), nil
})
registerRPC[*tg.LangpackGetDifferenceRequest](d, tlprofile.SemanticMethodLangpackGetDifference, func(ctx context.Context, req *tg.LangpackGetDifferenceRequest) (any, error) {
if r.deps.LangPack == nil {
return &tg.LangPackDifference{LangCode: req.LangCode, FromVersion: req.FromVersion}, nil
}
pack, err := r.deps.LangPack.GetDifference(ctx, langPackOrClient(ctx, req.LangPack), req.LangCode, req.FromVersion)
if err != nil {
return nil, internalErr()
}
return tgLangPackDifference(pack), nil
})
registerRPC[*tg.LangpackGetStringsRequest](d, tlprofile.SemanticMethodLangpackGetStrings, func(ctx context.Context, req *tg.LangpackGetStringsRequest) (any, error) {
if r.deps.LangPack == nil {
return []tg.LangPackStringClass{}, nil
}
pack, err := r.deps.LangPack.GetStrings(ctx, langPackOrClient(ctx, req.LangPack), req.LangCode, req.Keys)
if err != nil {
return nil, internalErr()
}
return tgLangPackStrings(pack.Strings), nil
})
}
// langPackOrClient 返回请求里的 lang_pack为空老客户端经生成 overlay 升级而来)时按 client 派生。
func langPackOrClient(ctx context.Context, langPack string) string {
if langPack != "" {
return langPack
}
return langPackFromClient(ctx)
}
func (r *Router) langpackLanguage(ctx context.Context, langPack, langCode string) (tg.LangPackLanguage, error) {
if langCode == "" {
if info, ok := ClientInfoFrom(ctx); ok && info.LangCode != "" {
langCode = info.LangCode
} else {
langCode = "en"
}
}
langCode = normalizeLangpackCode(langCode)
languages, err := r.langpackLanguages(ctx, langPack)
if err != nil {
return tg.LangPackLanguage{}, internalErr()
}
for _, lang := range languages {
if strings.ToLower(lang.LangCode) == langCode {
return lang, nil
}
}
return tg.LangPackLanguage{}, langCodeNotSupportedErr()
}
func (r *Router) langpackLanguages(ctx context.Context, langPack string) ([]tg.LangPackLanguage, error) {
if langPack == "" {
langPack = langPackFromClient(ctx)
}
langPack = strings.ToLower(langPack)
if r.deps.LangPack == nil {
return []tg.LangPackLanguage{}, nil
}
languages, err := r.deps.LangPack.ListLanguages(ctx, langPack)
if err != nil {
return nil, err
}
return tgLangPackLanguages(languages), nil
}
func langPackFromClient(ctx context.Context) string {
info, ok := ClientInfoFrom(ctx)
if !ok {
return "tdesktop"
}
if info.LangPack != "" {
return info.LangPack
}
switch info.ClientType() {
case ClientTypeAndroid:
return string(ClientTypeAndroid)
case ClientTypeTDesktop:
return string(ClientTypeTDesktop)
case ClientTypeIOS:
return string(ClientTypeIOS)
case ClientTypeMacOS:
return string(ClientTypeMacOS)
case ClientTypeTWeb:
return "webk"
case ClientTypeTelegramTT:
return "weba"
}
client := strings.ToLower(info.DeviceModel + " " + info.SystemVersion + " " + info.AppVersion)
if strings.Contains(client, "android") {
return "android"
}
return "tdesktop"
}
func normalizeLangpackCode(langCode string) string {
code := strings.ToLower(strings.TrimSpace(langCode))
if code == "" {
return "en"
}
code = strings.ReplaceAll(code, "_", "-")
return strings.TrimSuffix(code, "-raw")
}