merged from gramsrv upstream

This commit is contained in:
onysd 2026-09-01 12:06:31 +03:00
parent 79c64ee916
commit 21a0856587
651 changed files with 54774 additions and 4590 deletions

View file

@ -13,7 +13,7 @@ import (
//
// 字段值取 Telegram 常见默认TDesktop 联调阶段按客户端实际需要微调
// (记录于 docs/compatibility-matrix.md
func BuildConfig(dc int, ip string, port int, now time.Time, publicBaseURL string) *tg.Config {
func BuildConfig(dc int, ip string, port int, now time.Time, publicBaseURL, updateBaseURL string) *tg.Config {
// TELESRV_ADVERTISE_IP is validated during config loading. Parse again here
// only to derive the wire ipv6 flag and to render IPv4-mapped addresses in
// their canonical form. Keeping the advertised route in help.getConfig is a
@ -65,13 +65,10 @@ func BuildConfig(dc int, ip string, port int, now time.Time, publicBaseURL strin
MessageLengthMax: 4096,
WebfileDCID: dc,
}
config.SetReactionsDefault(&tg.ReactionEmoji{Emoticon: DefaultReactionEmoticon})
// The GIF picker's trending/search panel reads this from help.getConfig's
// typed Config (gifs_list_widget.cpp: session().serverConfig().gifSearchUsername)
// -- NOT from help.getAppConfig's loose JSON blob, which is a separate RPC/
// response entirely. Must match the built-in @gif system bot's username
// (domain.GifBotUser().Username), whose inline results are served
// synchronously in-process (see rpc.ServiceBotInlineResults).
config.SetGifSearchUsername("gif")
config.SetReactionsDefault(&tg.ReactionEmoji{Emoticon: DefaultReactionEmoticon})
if updateBaseURL != "" {
config.SetAutoupdateURLPrefix(links.NormalizeBaseURL(updateBaseURL))
}
return config
}

View file

@ -8,7 +8,7 @@ import (
)
func TestBuildConfigIncludesDefaultReaction(t *testing.T) {
config := BuildConfig(2, "127.0.0.1", 2398, time.Unix(1, 0), "https://telesrv.net")
config := BuildConfig(2, "127.0.0.1", 2398, time.Unix(1, 0), "https://telesrv.net", "https://updates.example.test/root/")
reaction, ok := config.GetReactionsDefault()
if !ok {
t.Fatal("reactions_default is absent")
@ -17,6 +17,9 @@ func TestBuildConfigIncludesDefaultReaction(t *testing.T) {
if !ok || emoji.Emoticon != DefaultReactionEmoticon {
t.Fatalf("reactions_default = %#v, want %q emoji", reaction, DefaultReactionEmoticon)
}
if got, ok := config.GetAutoupdateURLPrefix(); !ok || got != "https://updates.example.test/root" {
t.Fatalf("autoupdate_url_prefix = %q, %v", got, ok)
}
}
func TestBuildConfigAdvertisesCanonicalPrimaryDC(t *testing.T) {
@ -32,7 +35,7 @@ func TestBuildConfigAdvertisesCanonicalPrimaryDC(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
config := BuildConfig(2, tt.ip, 2398, time.Unix(1, 0), "https://telesrv.net")
config := BuildConfig(2, tt.ip, 2398, time.Unix(1, 0), "https://telesrv.net", "")
if len(config.DCOptions) != 1 {
t.Fatalf("len(DCOptions) = %d, want 1", len(config.DCOptions))
}

View file

@ -4,11 +4,12 @@ import (
"github.com/iamxvbaba/td/tg"
compatandroid "telesrv/internal/compat/android"
"telesrv/internal/domain"
"telesrv/internal/seed/catalog"
)
const (
appConfigHash = 18 // app config 内容变更时必须递增,否则缓存端只会收到 notModified。
appConfigHash = 19 // app config 内容变更时必须递增,否则缓存端只会收到 notModified。
countriesListHash = 1
timezonesListHash = 1
)
@ -53,6 +54,7 @@ func readMarkAppConfig(mapboxToken string) *tg.JSONObject {
{Key: "boosts_channel_level_max", Value: &tg.JSONNumber{Value: 100}},
// TDesktop 富文本编辑入口:官方默认缺省 disabled显式 enabled 才显示/允许进入编辑器。
{Key: "rich_message_posting", Value: &tg.JSONString{Value: "enabled"}},
{Key: "ephemeral_welcome_messages_max", Value: &tg.JSONNumber{Value: float64(domain.MaxWelcomeMessagesPerPeer)}},
// dialog_filters_enabled=trueTDesktop 据此(或已有文件夹)才显示 Settings→Folders 入口。
{Key: "dialog_filters_enabled", Value: &tg.JSONBool{Value: true}},
{Key: "chatlist_update_period", Value: &tg.JSONNumber{Value: 3600}},

View file

@ -5,6 +5,7 @@ import (
"github.com/iamxvbaba/td/tg"
"telesrv/internal/branding"
"telesrv/internal/seed/appearance"
"telesrv/internal/seed/catalog"
)
@ -348,7 +349,7 @@ func StickerSet(req *tg.MessagesGetStickerSetRequest) tg.MessagesStickerSetClass
if req != nil && req.Hash == emptyStickerSetHash {
return &tg.MessagesStickerSetNotModified{}
}
title, shortName := "OwpenGram Empty Sticker Set", "owpengram_empty"
title, shortName := branding.ProductName+" Empty Sticker Set", "owpengram_empty"
if req != nil {
switch set := req.Stickerset.(type) {
case *tg.InputStickerSetAnimatedEmoji:

View file

@ -6,6 +6,7 @@ import (
"github.com/iamxvbaba/td/tg"
"telesrv/internal/domain"
"telesrv/internal/seed/appearance"
)
@ -79,6 +80,9 @@ func TestAppConfigIncludesStoryStealthPeriods(t *testing.T) {
if strings["rich_message_posting"] != "enabled" {
t.Fatalf("AppConfig[rich_message_posting] = %q, want enabled", strings["rich_message_posting"])
}
if values["ephemeral_welcome_messages_max"] != float64(domain.MaxWelcomeMessagesPerPeer) {
t.Fatalf("AppConfig[ephemeral_welcome_messages_max] = %v, want %d", values["ephemeral_welcome_messages_max"], domain.MaxWelcomeMessagesPerPeer)
}
if !boolSeen["stars_purchase_blocked"] || bools["stars_purchase_blocked"] ||
!boolSeen["giveaway_gifts_purchase_available"] || !bools["giveaway_gifts_purchase_available"] {
t.Fatalf("AppConfig purchase flags = stars_blocked:%v giveaway_available:%v", bools["stars_purchase_blocked"], bools["giveaway_gifts_purchase_available"])