package catalogs import ( "encoding/json" "os" "path/filepath" "sync" ) var _ = json.RawMessage{} var _ = sync.Mutex{} var _ = os.ReadFile var _ = filepath.Join // // 一条电台「串词」内容(歌与歌之间播的 DJ 口播 / 广告 / 新闻 / 突发新闻)。 // ContentType 是 UX.Game.RadioContentType:1=Ad 2=News 3=Chat(DJ) // 4=Comment(DJ) 5=SpecialNews。3 和 4 在客户端 RadioPlayerManager.GetVoicesByContent // 里走同一张表 RadioContentDJs,所以 3/4 共用同一批 id。 // StartContentId / EndContentId 是「开场/收尾」两条 DJ 口播的 id // (突发新闻行自带 DJComeId / DJBackId,广告/新闻不用,填 0)。 // type RadioContentEntry4229938 struct { Id uint32 `json:"id"` ContentType uint32 `json:"contentType"` SoundId uint32 `json:"soundId"` Weight uint32 `json:"weight"` DJName uint32 `json:"dJName"` StartContentId uint32 `json:"startContentId"` EndContentId uint32 `json:"endContentId"` Content string `json:"content"` } // // 电台串词目录 —— 2026-09-27 新增,投影自 补丁和工具\DUMPS\ConfigDump_v3.zip 的 // RadioContentDJsConfig / RadioContentAdsConfig / RadioContentNewsConfig / // RadioContentSpecialNewsConfig(共 47 行:DJ 12 / 广告 2 / 新闻 2 / 突发 31)。 // 为什么需要它:AskGetVehicleRadioContent(67725622) 是 INVOKE,返回 // UX.Game.RadioRandomContent,客户端拿里面的 id 去查上面那四条表拿 SoundId。 // 在此之前服务端回的是全零 typed-default ⇒ 四条表全查不到(客户端日志四行 // 「GetVoicesByContent … 配表找不到」)⇒ 车上只有歌、没有串词。 // var ( RadioContentCatalog4229938_cacheLock sync.RWMutex RadioContentCatalog4229938_cached = false RadioContentCatalog4229938_entries []any ) // LoadRadioContentCatalog4229938 loads catalog records from client config directory func LoadRadioContentCatalog4229938(configDir string) ([]any, error) { RadioContentCatalog4229938_cacheLock.RLock() if RadioContentCatalog4229938_cached { defer RadioContentCatalog4229938_cacheLock.RUnlock() return RadioContentCatalog4229938_entries, nil } RadioContentCatalog4229938_cacheLock.RUnlock() RadioContentCatalog4229938_cacheLock.Lock() defer RadioContentCatalog4229938_cacheLock.Unlock() if RadioContentCatalog4229938_cached { return RadioContentCatalog4229938_entries, nil } filePath := filepath.Join(configDir, "RadioContentCatalog.json.json") data, err := os.ReadFile(filePath) if err != nil { return nil, err } var raw struct { Records []json.RawMessage `json:"records"` } if err := json.Unmarshal(data, &raw); err != nil { return nil, err } var result []any for _, item := range raw.Records { var m map[string]any if err := json.Unmarshal(item, &m); err == nil { result = append(result, m) } } RadioContentCatalog4229938_entries = result RadioContentCatalog4229938_cached = true return result, nil } // 某一类型的全部行(ContentType 见 RadioContentEntry4229938)。 func RadioContentCatalog4229938_ByType(contentType uint32) []RadioContentEntry4229938 { // Catalog helper RadioContentCatalog4229938_ByType return nil } // 权重为 0 时按官方静态表 RadioContentConfig 的默认值兜底(DJChat 50 / 其余 20)。 func RadioContentCatalog4229938_EffectiveWeight(e RadioContentEntry4229938) int32 { // Catalog helper RadioContentCatalog4229938_EffectiveWeight return 0 }