67 lines
4.2 KiB
Go
67 lines
4.2 KiB
Go
package methods
|
||
|
||
//
|
||
// 房产自带家具的「家具机关(furniture gadget)」契约 —— 2026-10-01 新增。
|
||
// <para>背景:AskLoadHouseData(63109556) 下发的家具树只带
|
||
// FurnitureId + 世界坐标 + PlacedInstanceId,GadgetInstanceId 恒 0。
|
||
// 客户端把家具模型建出来之后,会再问一次服务端要机关实例 id ——
|
||
// LX6/Manager/House/HouseGadgetManager.lua:CreateGadgetsForFurnitures:
|
||
// <code>
|
||
// gClientToGameDelegate:AskCreateHouseFurnitureGadgets(houseId, floor, ulongList).Callback =
|
||
// function (err, mapping)
|
||
// ... mapping.placedID2GadgetInstanceID ...
|
||
// self.placedId2GadgetIdMap[numPlacedId] = numGadgetId
|
||
// gFurnitureUtils:TrySetGadgetInstanceId(furnitureGo, numGadgetId)
|
||
// end
|
||
// </code>
|
||
// 在此之前服务端没有这两个 handler,兜底表一律回空 ⇒ placedId2GadgetIdMap 恒空
|
||
// ⇒ 椅子坐不了、衣柜开不了、电视点不亮(用户 2026-10-01 实测:「沙发椅子已经生成了的没法交互」)。</para>
|
||
// <para>线格式(逐条取自客户端自己的生成代码,不是推测):</para>
|
||
// <list type="bullet">
|
||
// <item>C2S 请求:LuaGen/AutoGen/ClientToGameDelegate.lua:4434
|
||
// AskCreateHouseFurnitureGadgets_Serializer =
|
||
// WriteUInt32(houseid) + WriteUInt32(floor) + WriteList7Bit(placedgadgets, WriteUInt64);
|
||
// 同文件 :5692 的 AskDestoryHouseFurnitureGadgets_Serializer 同构
|
||
// (第三参叫 placedfurnitures)。</item>
|
||
// <item>列表计数编码: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)。</item>
|
||
// <item>S2C 应答:LuaGen/AutoGen/RPCDeserializeAuto.lua 的
|
||
// midToReturnMessageReader[63581446] = Base.ReadStruct(reader, Auto.Reader[631]),
|
||
// 而 Auto.Reader[631] 只有一个字段:
|
||
// placedID2GadgetInstanceID = Base.ReadDict7Bit(ReadUInt64 → ReadUInt64)。</item>
|
||
// <item>⚠️ 应答外壳是 Struct 不是 Complex:客户端用的是 Base.ReadStruct
|
||
// (RPCDeserializeBase.lua:109,直接读字段、不读 0xFF 对象标记)
|
||
// ⇒ 服务端这边必须写 [UxContract(Inline = true)],否则会多写一个 0xFF 把整包顶掉。
|
||
// 权威兜底表 DefaultReturnCatalog4229938.cs:624 给的空应答正好是 2 字节 FF 01
|
||
// = 「dict 的 0xFF 标记 + Int7 计数 0(偏置后 1)」,没有第三层对象标记 —— 与 Inline 吻合。</item>
|
||
// <item>参数外壳:args 一律 [UxContract(Inline = true)] —— 生成代码是「裸着按顺序写各参数」,
|
||
// 没有外层对象标记。</item>
|
||
// <item>AskDestoryHouseFurnitureGadgets(63759452) 的应答是 void:
|
||
// midToReturnMessageReader[63759452] 是空函数 ⇒ 回空 body(ReturnEmptyOkAsync)。</item>
|
||
// </list>
|
||
// <para>⛔ 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 位值当键。</para>
|
||
//
|
||
//
|
||
// AskCreateHouseFurnitureGadgets(63581446) 的入参。
|
||
// ClientToGameDelegate.lua:4434:u32 houseid + u32 floor + List7Bit<u64> placedgadgets。
|
||
//
|
||
//
|
||
// AskCreateHouseFurnitureGadgets(63581446) 的应答。
|
||
// Auto.Reader[631]:唯一字段 placedID2GadgetInstanceID = ReadDict7Bit(u64 → u64)。
|
||
// <para>键 = 客户端请求里的那个 placedId(原样回显,见上文 32 位截断坑);
|
||
// 值 = 该家具机关的 gadget 实例 id(客户端用 ConvertServerUidToNumber 转 number,
|
||
// 0 视为无效,会被 HouseGadgetManager 直接跳过)。</para>
|
||
//
|
||
//
|
||
// AskDestoryHouseFurnitureGadgets(63759452) 的入参(官方拼写就是 Destory)。
|
||
// ClientToGameDelegate.lua:5692:u32 houseid + u32 floor + List7Bit<u64> placedfurnitures。
|
||
//
|