127 lines
4.5 KiB
Go
127 lines
4.5 KiB
Go
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 ""
|
||
}
|
||
|