package catalogs import ( "encoding/json" "os" "path/filepath" "sync" ) var _ = json.RawMessage{} var _ = sync.Mutex{} var _ = os.ReadFile var _ = filepath.Join // One slice of an NPC's day, as NpcScheduleInfo carries it. type NpcScheduleSlice4229938 struct { ActivityId uint32 `json:"activityId"` StartDaySecond int32 `json:"startDaySecond"` EndDaySecond int32 `json:"endDaySecond"` RaidId uint32 `json:"raidId"` } // One NPC's five daily slices, keyed by AgentTag. type NpcDailySchedule4229938 struct { AgentTag uint32 `json:"agentTag"` Slices []NpcScheduleSlice4229938 `json:"slices"` } // // Reads Configs/NpcDailySchedule.json — a projection of the client's own // LifeScheduleTimetableConfig (four HHMM boundaries per AgentTag) crossed with // AgentDataSetsActivityConfig (what that AgentTag can actually be seen doing), built by // _gen_npc_schedule.py. // This is what fills the 日程 tab of the 趴卜 NPC home page: // BubbleFriendHomePanelStore.RefreshContent -> NpcDaliyManager:GetTodayScheduleList reads // NpcTimeTableLists[agentType], which is fed either by SyncFavorNpcTimeTableInfos(64219939) or, // as here, straight from the login frame's PlayerClientInfoMinor.FavorNpcDailyScheduleInfos. // GetTodayScheduleList keeps only the slices whose ActivityId is non-zero, and OnRenderActivity // resolves the id through ActivityConfig — a wrong id merely logs // "[C_NpcDaliyManager] 错误的ActivityId", so the table can be regenerated freely. // A missing or malformed file leaves the catalogue empty and LoadError explains why. // var ( NpcScheduleCatalog4229938_cacheLock sync.RWMutex NpcScheduleCatalog4229938_cached = false NpcScheduleCatalog4229938_entries []any ) // LoadNpcScheduleCatalog4229938 loads catalog records from client config directory func LoadNpcScheduleCatalog4229938(configDir string) ([]any, error) { NpcScheduleCatalog4229938_cacheLock.RLock() if NpcScheduleCatalog4229938_cached { defer NpcScheduleCatalog4229938_cacheLock.RUnlock() return NpcScheduleCatalog4229938_entries, nil } NpcScheduleCatalog4229938_cacheLock.RUnlock() NpcScheduleCatalog4229938_cacheLock.Lock() defer NpcScheduleCatalog4229938_cacheLock.Unlock() if NpcScheduleCatalog4229938_cached { return NpcScheduleCatalog4229938_entries, nil } filePath := filepath.Join(configDir, "NpcScheduleCatalog.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) } } NpcScheduleCatalog4229938_entries = result NpcScheduleCatalog4229938_cached = true return result, nil } // // The five slices of one AgentTag, or empty when that tag has no timetable at all. // Used by NpcActivityCatalog4229938.CurrentFor to turn "now" into an activity id. // Only 75 rows exist, so a scan beats maintaining a second index. // func NpcScheduleCatalog4229938_For(agentTag uint32) []NpcScheduleSlice4229938 { // Catalog helper NpcScheduleCatalog4229938_For return nil }