package catalogs import ( "encoding/json" "os" "path/filepath" "sync" ) var _ = json.RawMessage{} var _ = sync.Mutex{} var _ = os.ReadFile var _ = filepath.Join // // HouseBuildConfig 的一行 —— 「这栋房子的可装修体」。 // 为什么需要它:HouseConfig.BuildId(0/2/3/4/5)指向本表的 Id, // 本表的 IndoorId 才是「房子主体所在的 indoor」,而 // FurnitureTemplateIds 指向 HouseFurnitureTemplateCatalog4229938 // 里的**自带家具模板根节点**。整条链: // houseId → HouseConfig.BuildId → HouseBuildConfig.FurnitureTemplateIds → 家具树。 // 4 行全表(2026-09-30 核对 E:\ConfigDump\ConfigDump_v3\HouseBuildConfig.json): // // Id IndoorId Floors FurnitureTemplateIds 对应房子 // 2 301 1 [14001] 绿屿公馆(11200003) // 3 205 1 [10013] 旧物仓公寓(11200004) // 4 298 1 [14000] 观澜北岸(11200005) // 5 378 2 [13000] 素光小筑(11200006) // // ⛔ IndoorId 与 HouseConfig.GarageIndoorId **不是一回事**: // 绿屿公馆两处都写着 301(它的车库就在主体 indoor 里),其余三套 // IndoorId 是 205/298/378 而 GarageIndoorId 是 300/299/379。 // 车库这一轮不做,别拿 GarageIndoorId 当 IndoorId 用。 // // HouseBuildConfig.Id,也是客户端 HouseBuildConfig.GetConfig(buildId) 的键。 // IndoorConfig.Id —— 房子主体 indoor(301/205/298/378)。 // HouseBuildConfig.Floors,楼层数(1 或 2)。 // HouseBuildConfig.FurnitureTemplateIds,自带家具模板根 id。 type HouseBuildDefinition4229938 struct { BuildId uint32 `json:"buildId"` IndoorId uint32 `json:"indoorId"` Floors uint32 `json:"floors"` FurnitureTemplateIds []uint32 `json:"furnitureTemplateIds"` } // // HouseFurnitureTemplateConfig 的一个节点(递归树)。 // 形状:根节点 FurnitureId == 0(纯容器,对应线格式里的 // IndoorBuildInfo.Root),子节点才是真家具。Position/Rotation 是 // 绝对世界坐标(不是相对父节点的偏移)—— 绿屿公馆的模板叶子全在 // (2254..2294, 160.72, 1394..1404),正好是 HouseConfig.11200003.VisitorEntrance 附近。 // 深度:14001(绿屿公馆)是 3 层 —— 147 个叶子里有 9 个是挂在 // 桌子/柜子下面的小物件(盘子、台灯…),父节点本身也是真家具。其余三个模板都是 2 层。 // 所以必须递归,不能只取根的直接子节点。 // type HouseFurnitureTemplateNode4229938 struct { // HouseFurnitureTemplateConfig.Id(模板内部节点号,10013..14150 量级)。 NodeId uint32 `json:"nodeId"` // HouseFurnitureTemplateConfig.FurnitureId(HouseFurnitureConfig.Id)。0 = 纯容器。 FurnitureId uint32 `json:"furnitureId"` X float32 `json:"x"` Y float32 `json:"y"` Z float32 `json:"z"` RotationX float32 `json:"rotationX"` RotationY float32 `json:"rotationY"` RotationZ float32 `json:"rotationZ"` Children []HouseFurnitureTemplateNode4229938 `json:"children"` } // // Reads Configs/HouseBuildConfig.json(4 行)+ // Configs/HouseFurnitureTemplateConfig.json(322 行),并把模板树按 buildId 索引好。 // 消费点只有一个:GameRouter.House.cs 的 AskLoadHouseData(63109556) —— // 客户端进房子时会用 houseId 问服务端要 HouseBuildingClientData, // 我们拿本目录把「房子本来该有的家具」塞进 FloorBuildInfoDict, // 否则客户端拿到的是空表 ⇒ 毛坯房。 // ⛑ 两张表都带 Lazy 缓存 ⇒ 改了要重启服务端 // (和 NpcCatalog.json 一个规矩)。 // var ( HouseFurnitureTemplateCatalog4229938_cacheLock sync.RWMutex HouseFurnitureTemplateCatalog4229938_cached = false HouseFurnitureTemplateCatalog4229938_entries []any ) // LoadHouseFurnitureTemplateCatalog4229938 loads catalog records from client config directory func LoadHouseFurnitureTemplateCatalog4229938(configDir string) ([]any, error) { HouseFurnitureTemplateCatalog4229938_cacheLock.RLock() if HouseFurnitureTemplateCatalog4229938_cached { defer HouseFurnitureTemplateCatalog4229938_cacheLock.RUnlock() return HouseFurnitureTemplateCatalog4229938_entries, nil } HouseFurnitureTemplateCatalog4229938_cacheLock.RUnlock() HouseFurnitureTemplateCatalog4229938_cacheLock.Lock() defer HouseFurnitureTemplateCatalog4229938_cacheLock.Unlock() if HouseFurnitureTemplateCatalog4229938_cached { return HouseFurnitureTemplateCatalog4229938_entries, nil } filePath := filepath.Join(configDir, "HouseFurnitureTemplateCatalog.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) } } HouseFurnitureTemplateCatalog4229938_entries = result HouseFurnitureTemplateCatalog4229938_cached = true return result, nil } // HouseBuildConfig.Id → 定义。找不到就 false。 func HouseFurnitureTemplateCatalog4229938_TryGetBuild(buildId uint32, build HouseBuildDefinition4229938) bool { // Catalog helper HouseFurnitureTemplateCatalog4229938_TryGetBuild return false } // // 这套房子的「顶层家具」节点列表 —— 已经剥掉了模板自己的根容器 // (模板根的 FurnitureId == 0,和线格式里的 IndoorBuildInfo.Root 是同一个东西, // 所以它的**子节点**才是要挂到 Root.ChildrenDict 上的那一层)。 // 模板根万一是真家具(FurnitureId != 0)就把它自己当顶层,免得整棵树丢掉。 // func HouseFurnitureTemplateCatalog4229938_TopLevelNodes(buildId uint32) []HouseFurnitureTemplateNode4229938 { // Catalog helper HouseFurnitureTemplateCatalog4229938_TopLevelNodes return nil } // // 按 buildId + 模板节点号找节点 —— 2026-10-01 为「家具机关」新增。 // 谁需要它:客户端 AskCreateHouseFurnitureGadgets 只给 // placedId(= houseId*100000 + nodeId,且线上是 32 位截断形态), // 服务端要把它反解成「哪件家具、在哪」,唯一入口就是这张表。 // 详见 GameRouter.HouseFurnitureGadget.cs。 // 索引按 buildId 懒建并缓存(TopLevelNodes 已剥掉模板根容器, // 这里再从顶层递归收全部后代)。四套房各自的模板节点号互不重叠,但按 build 分开更稳。 // func HouseFurnitureTemplateCatalog4229938_TryGetNode(buildId uint32, nodeId uint32, node HouseFurnitureTemplateNode4229938) bool { // Catalog helper HouseFurnitureTemplateCatalog4229938_TryGetNode return false } func HouseFurnitureTemplateCatalog4229938_BuildIndex(buildId uint32) map[uint32]HouseFurnitureTemplateNode4229938 { // Catalog helper HouseFurnitureTemplateCatalog4229938_BuildIndex return nil } func HouseFurnitureTemplateCatalog4229938_Collect(index map[uint32]HouseFurnitureTemplateNode4229938, node HouseFurnitureTemplateNode4229938) { // Catalog helper HouseFurnitureTemplateCatalog4229938_Collect } // 树里一共有多少个「真家具」节点(FurnitureId != 0),只用于日志 / 诊断。 func HouseFurnitureTemplateCatalog4229938_CountFurniture(nodes []HouseFurnitureTemplateNode4229938) int32 { // Catalog helper HouseFurnitureTemplateCatalog4229938_CountFurniture return 0 } func HouseFurnitureTemplateCatalog4229938_LoadBuilds(path string, target map[uint32]HouseBuildDefinition4229938) *string { // Catalog helper HouseFurnitureTemplateCatalog4229938_LoadBuilds return nil } func HouseFurnitureTemplateCatalog4229938_LoadTemplates(path string, target map[uint32]HouseFurnitureTemplateNode4229938) *string { // Catalog helper HouseFurnitureTemplateCatalog4229938_LoadTemplates return nil } func HouseFurnitureTemplateCatalog4229938_U32(source any, name string) uint32 { // Catalog helper HouseFurnitureTemplateCatalog4229938_U32 return 0 } // 读 {"X":..,"Y":..,"Z":..} 这种嵌套对象里的一个 float。 func HouseFurnitureTemplateCatalog4229938_F32(source any, outer string, inner string) float32 { // Catalog helper HouseFurnitureTemplateCatalog4229938_F32 return 0 } type HouseFurnitureTemplateCatalog4229938_Snapshot struct { Builds map[uint32]HouseBuildDefinition4229938 `json:"builds"` Nodes map[uint32]HouseFurnitureTemplateNode4229938 `json:"nodes"` Error *string `json:"error"` }