启动器新增游戏设置页(频道开关+活动开关),窗口标题改名

- 服务端新增活动开关运行时配置与 GM 接口(GET/POST /dnf/gm/activity-switches),
  持久化到 Settings,接入月签到/周签到/PC房↔累计在线的实时下发
- 服务端新增频道开关 GM 接口(channel-switches),目录生成时过滤禁用频道
- channelcatalog/channelinfo 支持按禁用频道 ID 过滤目录与客户端脚本
- 启动器新增「游戏设置」页面:频道开关 Tab + 活动开关 Tab
- native.py/server.py 新增对应转发 API
- 窗口标题/页面 title/侧边栏「90轮回」统一改为「DNF90 灵狐小竹整合单机版」
This commit is contained in:
hanfuit committed 2026-11-04 20:08:50 +08:00
1 parent 977a4a1196
commit 0ced464168
15 files changed
+1022 -14

No files matched your search

+35 -2
View File
@@ -284,6 +284,16 @@ type Service struct {
gmFatigueMode string
gmBurningEnabled bool
gmGameplaySettingsAt time.Time
// gmActivitySwitches 是活动开关的运行时缓存(见 gm_activity_switches.go)。
gmActivitySwitchesMu sync.Mutex
gmActivitySwitchesReady bool
gmActivitySwitches map[string]bool
gmActivitySwitchesAt time.Time
// gmChannelSwitches 是频道开关(禁用频道 ID 集合)的运行时缓存(见 gm_channel_switches.go)。
gmChannelSwitchesMu sync.Mutex
gmChannelSwitchesReady bool
gmChannelSwitches map[int]bool
gmChannelSwitchesAt time.Time
automaticRobotAppearanceMu sync.Mutex
automaticRobotAvatarConfig *currentAvatarFittingRoomConfig
automaticRobotAvatarLoadErr error
@@ -1015,17 +1025,40 @@ func (s *Service) loadChannelAssets() (*channelcatalog.Catalog, []byte, error) {
if err != nil {
return nil, nil, fmt.Errorf("parse dnf channel info: %w", err)
}
catalog, err := channelcatalog.New(index, channelcatalog.Options{ServerID: s.channelServerID()})
disabled := s.loadDisabledChannelIDs()
catalog, err := channelcatalog.New(index, channelcatalog.Options{
ServerID: s.channelServerID(),
DisabledIDs: disabled,
})
if err != nil {
return nil, nil, err
}
script, err := s.buildChannelScript(raw)
script, err := s.buildChannelScriptFiltered(raw, disabled)
if err != nil {
return nil, nil, fmt.Errorf("build 90CN online channel script: %w", err)
}
return catalog, script, nil
}
// loadDisabledChannelIDs 读取已持久化的禁用频道集合。启动时 Settings 未就绪或读失败
// 时返回 nil(视为无禁用频道),不阻塞服务启动。
func (s *Service) loadDisabledChannelIDs() map[int]bool {
if s == nil {
return nil
}
repositories, ok := s.repositoryGroup()
if !ok || repositories.Settings == nil {
return nil
}
ctx, cancel := context.WithTimeout(context.Background(), createWriteTimeout)
defer cancel()
record, found, err := repositories.Settings.Load(ctx, gmChannelSwitchesScope)
if err != nil || !found {
return nil
}
return gmDisabledChannelIDsFromRecord(record, true)
}
func (s *Service) buildChannelScript(raw []byte) ([]byte, error) {
if s.channelTableStrict() {
return channelinfo.Build90CNOnlineScript(