package catalogs import ( "encoding/json" "os" "path/filepath" "sync" ) var _ = json.RawMessage{} var _ = sync.Mutex{} var _ = os.ReadFile var _ = filepath.Join // One row of WorldStateIndoorSectorConfig — a hand-authored interior chunk. type IndoorSector4229938 struct { Id uint32 `json:"id"` SectorName string `json:"sectorName"` BelongingIndoorId uint32 `json:"belongingIndoorId"` DefaultActive bool `json:"defaultActive"` } // // Reads Configs/WorldStateIndoorSectorConfig.json — the table that tells which // sector ids belong to which IndoorId. // // // ★★★ 2026-09-27 取证结论(推翻了此前「扇区 Id == IndoorId」的假设): // · 客户端 LT.ConfigGen.WorldStateIndoorSectorConfig(lua ClientConfig.lua // 池号 1556,dict.count = 44)字段为 // Id / SectorName / BelongingIndoorId / DefaultActive / StartVersion / EndVersion / TagList; // · Id 是 17600002 … 17600109 这种大号,BelongingIndoorId 才是 // IndoorConfig.Id(3 / 15 / 76 / 150 …)—— 两者是两个字段, // 扇区 Id ≠ IndoorId(dump.cs 28005 的字段偏移也印证:Id@0x10、BelongingIndoorId@0x20)。 // · 交叉验证:44 条里 42 条的 BelongingIndoorId 能在本仓 IndoorConfig.json // 里对上同名场馆 —— arcadehall↔1UP、tvstation02/03/05↔Saturn Entertainment、 // shannon/newshannon ×9↔ACD Nova Branch、acidsewer↔Underground Lab、 // gallery_01..04↔Eve Gallery Lobby/Exhibition/Secret Room、robhotel_01..07↔Spiko Hotel … // ⇒ 映射真实,BelongingIndoorId == IndoorConfig.Id 已被双向证实。 // · 另 2 条落空:17600006(indoor 22 = 玩家 penthouse 车库)IndoorConfig 里没有; // 17600037(indoor 0)无归属。 // ⛔ 覆盖范围要看清:全表只有 44 个扇区、约 25 个场馆,且全是剧情/副本类室内 // (街机厅、银行、Live House、电视台、地下实验室、画廊、Shannon 分部…)。 // 普通店铺(麦当劳 IndoorId 61 等)在这张表里一条都没有 —— 它们走 PCG // (BuildingIndoorController → PCGIndoorProxy,无外部触发点), // 服务端推扇区对它们无效。别把这通道当成「所有室内都能出」。 // ⛔ 一个 IndoorId 可以有多个扇区(Spiko Hotel = 7 个,ACD Nova Branch = 9 个), // 所以查询接口返回 列表,不是单值。 // var ( IndoorSectorCatalog4229938_cacheLock sync.RWMutex IndoorSectorCatalog4229938_cached = false IndoorSectorCatalog4229938_entries []any ) // LoadIndoorSectorCatalog4229938 loads catalog records from client config directory func LoadIndoorSectorCatalog4229938(configDir string) ([]any, error) { IndoorSectorCatalog4229938_cacheLock.RLock() if IndoorSectorCatalog4229938_cached { defer IndoorSectorCatalog4229938_cacheLock.RUnlock() return IndoorSectorCatalog4229938_entries, nil } IndoorSectorCatalog4229938_cacheLock.RUnlock() IndoorSectorCatalog4229938_cacheLock.Lock() defer IndoorSectorCatalog4229938_cacheLock.Unlock() if IndoorSectorCatalog4229938_cached { return IndoorSectorCatalog4229938_entries, nil } filePath := filepath.Join(configDir, "IndoorSectorCatalog.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) } } IndoorSectorCatalog4229938_entries = result IndoorSectorCatalog4229938_cached = true return result, nil } // Sectors belonging to one IndoorConfig.Id; empty when the venue has none. func IndoorSectorCatalog4229938_SectorsFor(indoorId uint32) []IndoorSector4229938 { // Catalog helper IndoorSectorCatalog4229938_SectorsFor return nil } // Does this venue have any hand-authored sector at all? func IndoorSectorCatalog4229938_HasSectors(indoorId uint32) bool { // Catalog helper IndoorSectorCatalog4229938_HasSectors return false } func IndoorSectorCatalog4229938_LoadTriple() any { // Catalog helper IndoorSectorCatalog4229938_LoadTriple var zero any; return zero } func IndoorSectorCatalog4229938_TryRead(node any, row *IndoorSector4229938) bool { // Catalog helper IndoorSectorCatalog4229938_TryRead return false } func IndoorSectorCatalog4229938_U32(source any, name string) uint32 { // Catalog helper IndoorSectorCatalog4229938_U32 return 0 } func IndoorSectorCatalog4229938_Str(source any, name string) string { // Catalog helper IndoorSectorCatalog4229938_Str return "" }