package methods // // 房产自带家具的「家具机关(furniture gadget)」契约 —— 2026-10-01 新增。 // 背景:AskLoadHouseData(63109556) 下发的家具树只带 // FurnitureId + 世界坐标 + PlacedInstanceId,GadgetInstanceId 恒 0。 // 客户端把家具模型建出来之后,会再问一次服务端要机关实例 id —— // LX6/Manager/House/HouseGadgetManager.lua:CreateGadgetsForFurnitures: // // gClientToGameDelegate:AskCreateHouseFurnitureGadgets(houseId, floor, ulongList).Callback = // function (err, mapping) // ... mapping.placedID2GadgetInstanceID ... // self.placedId2GadgetIdMap[numPlacedId] = numGadgetId // gFurnitureUtils:TrySetGadgetInstanceId(furnitureGo, numGadgetId) // end // // 在此之前服务端没有这两个 handler,兜底表一律回空 ⇒ placedId2GadgetIdMap 恒空 // ⇒ 椅子坐不了、衣柜开不了、电视点不亮(用户 2026-10-01 实测:「沙发椅子已经生成了的没法交互」)。 // 线格式(逐条取自客户端自己的生成代码,不是推测): // // C2S 请求:LuaGen/AutoGen/ClientToGameDelegate.lua:4434 // AskCreateHouseFurnitureGadgets_Serializer = // WriteUInt32(houseid) + WriteUInt32(floor) + WriteList7Bit(placedgadgets, WriteUInt64); // 同文件 :5692 的 AskDestoryHouseFurnitureGadgets_Serializer 同构 // (第三参叫 placedfurnitures)。 // 列表计数编码:Int7(biased,线上写 count+1)。 // RPCSerializeBase.lua 的 WriteList7Bit 写 Write7BitEncodedInt(num), // 该 UX 版方法就是 biased 写法;RPCDeserializeBase.lua 的 ReadList7Bit 读 // ReadInt7Bit。实测请求字节:绿屿 33 件 ⇒ FF 22(0x22=34)、观澜 6 件 ⇒ FF 07、 // 旧物仓 3 件 ⇒ FF 04、素光 1 件 ⇒ FF 02、空 ⇒ FF 01。 // UxSerializer 里对应 UxCountEncoding.Int7(writer.Int7 = value+1)。 // S2C 应答:LuaGen/AutoGen/RPCDeserializeAuto.lua 的 // midToReturnMessageReader[63581446] = Base.ReadStruct(reader, Auto.Reader[631]), // 而 Auto.Reader[631] 只有一个字段: // placedID2GadgetInstanceID = Base.ReadDict7Bit(ReadUInt64 → ReadUInt64)。 // ⚠️ 应答外壳是 Struct 不是 Complex:客户端用的是 Base.ReadStruct // (RPCDeserializeBase.lua:109,直接读字段、不读 0xFF 对象标记) // ⇒ 服务端这边必须写 [UxContract(Inline = true)],否则会多写一个 0xFF 把整包顶掉。 // 权威兜底表 DefaultReturnCatalog4229938.cs:624 给的空应答正好是 2 字节 FF 01 // = 「dict 的 0xFF 标记 + Int7 计数 0(偏置后 1)」,没有第三层对象标记 —— 与 Inline 吻合。 // 参数外壳:args 一律 [UxContract(Inline = true)] —— 生成代码是「裸着按顺序写各参数」, // 没有外层对象标记。 // AskDestoryHouseFurnitureGadgets(63759452) 的应答是 void: // midToReturnMessageReader[63759452] 是空函数 ⇒ 回空 body(ReturnEmptyOkAsync)。 // // ⛔ placedId 的 32 位截断坑:客户端发上来的 placedId 是 // (houseId * 100000 + nodeId) & 0xFFFFFFFF —— 高 4 字节恒为 0。 // 实测绿屿第一件 93 8A 38 C5 00 00 00 00 = 0xC5388A93,而 // 0xC5388A93 - (11200003*100000 mod 2^32) = 14003(= 模板节点号)。 // ⇒ 返回映射的键必须原样回显收到的 u64,不能拿服务端自己算的 64 位值当键。 // // // AskCreateHouseFurnitureGadgets(63581446) 的入参。 // ClientToGameDelegate.lua:4434:u32 houseid + u32 floor + List7Bit<u64> placedgadgets。 // // // AskCreateHouseFurnitureGadgets(63581446) 的应答。 // Auto.Reader[631]:唯一字段 placedID2GadgetInstanceID = ReadDict7Bit(u64 → u64)。 // 键 = 客户端请求里的那个 placedId(原样回显,见上文 32 位截断坑); // 值 = 该家具机关的 gadget 实例 id(客户端用 ConvertServerUidToNumber 转 number, // 0 视为无效,会被 HouseGadgetManager 直接跳过)。 // // // AskDestoryHouseFurnitureGadgets(63759452) 的入参(官方拼写就是 Destory)。 // ClientToGameDelegate.lua:5692:u32 houseid + u32 floor + List7Bit<u64> placedfurnitures。 //