This repository has been archived on 2026-10-31. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Ananta-ps/internal/gameserver/routers/game_router_bowling_pin_gadget.go
T

75 lines
5.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package routers
import (
"context"
"sync"
)
var _ = sync.Mutex{}
var _ = context.Background
//
// ★ 诊断实验(2026-09-24 深夜):把 10 个球瓶改走**健身房器材那条路**推。
// 起因(客户端日志给出的硬证据):
// [error] ,scene item,910000000015, hold not found,
// BowlingGameManager.lua:670 in 'getItemsFromIdList'
// BowlingGameManager.lua:680 in 'InitSceneItems'
// ⇒ 客户端确实收到了我们推的 id(910000000001..15,见 BowlingZoneInfo 的两个 id 列表),
// 但 `SceneItemMgr.Instance:GetSceneItemHold(id)` 查不到 hold,
// 于是 `sceneItemPinList` 为空 → `Rent(101)` 报 "pool[101] is nil" →
// `BowlingPinSetter.CreatePin` 直接 return → 官方那套带模型的球瓶根本没被建出来。
// 我们走的 `DestructibleInfo` 只造出「物理 + 音效」的实体,不产生 hold、不产生渲染。
// 而本项目里**唯一被实测证明能生成"看得见"的物体**的通道是 gadget:
// `GameRouter.GymEquipment.cs` → GadgetEntityInfo(Pack.PathId 直接给资源 id)
// → `GadgetGridAOIIncrease` → `SyncGadgetAOIAddAndRemove`(68169646)
// 健身房器材就是这么生成出来的,肉眼可见。
// 所以本实验:同样用 gadget AOI 把东西推到球瓶位置,看客户端认不认。
// 配置(config/bowling_wire.json):
// "pinAsGadget": 1 打开本实验(0 = 关)
// "gadgetProbePathId": N 对照组的 pathId,默认 79300636 = MiniGameMachine_Bowling
// (GadgetConfig 里保龄球机器,写 0 = 不放对照组)
// 一次测试能读出三件事:
// ① 对照机器的 gadget 现身了?→ 说明「服务端推 gadget + AOI 通道」在球馆里也成立
// ② 10 个球瓶位置现出物体了?→ 说明客户端能把 `pinPathId` 当资源 id 解析出来 ⇒ 收工
// ③ 都不现 → gadget 通道认不得场景物 id,得转客户端侧(frida)方案
// ⚠ 本实验**不动**原来的 DestructibleInfo 推送(物理/计分/音效照旧),
// 只是在同一位置上再叠一层"看得见"的 gadget。两者互不干扰。
// ★★ 2026-09-24 A 方案移植说明(本文件与 PrivateServer修改 版的差异)
// 本仓库(DRMK-PS_09_HyNB-v1.7)里,机关那一族类型在 `...Methods.GameScene` 命名空间下,
// 且 `GadgetEntityInfo.Position/Facing` 的类型是 `Auto.UXVector3`:
// GadgetEntityInfo → Methods.GameScene(本仓库,下方用 SceneMethods. 限定)
// PackedGadgetInfo → Methods.GameScene(= 我们那边的 GadgetPackInfo,**字段顺序前 13 项完全一致**,
// 本仓库末位多出 extractionItemContainerId / isStatic 两个字段,
// 默认 0 即可,与 v1.7 自己的机关推送同形)
// 字段名对照(我们 → 本仓库):Jnc/Jnb/Jna → posX/posY/posZ;EulerX/Y/Z → eulerX/eulerY/eulerZ;
// IScale → iScale;UniqueId → uniqueId;PathId → pathId。
// ⚠ iScale 保持 100:这是**机关族**的正确取值(本仓库 PackedGadgetInfo.iScale 的注释写明
// "Uniform scale in percent (100 = authored size)",且 GameRouter.Gadget.cs / GymEquipment.cs
// 的默认参数就是 100)。我们那条「iScale 必须写 0」的教训针对的是**另一个**结构
// `SceneItemPlaceInfoData +0x3C`,两者不要混。
// ★★★ 第二处、也是**唯一改变语义**的一处:68169646 的顶层 args 换成本仓库既有的
// `SceneMethods.SyncGadgetAOIAddAndRemoveArgs4229938`(6 字段),不再用我们那边的
// `GymGadgetContracts.GadgetGridAOIIncrease`(7 字段)。理由是**证据打架时选宿主仓**:
// (a) 我们那边的 7 字段版本,来源是 Drmk.Proxy 的 proxy/rpc_schema.json 读端 schema
// `433`(已实测抽取,字段 = addInfos / indexList / addUniqueIds / removeIds /
// activeIds / inactiveIds / reason(ReadByte)),但本项目自己的
// `Drmk.RpcTypes\Client4229938\BowlingWireContracts.cs:271-276` 的注释把同一个
// DTO 判为 "uncalled rpc_schema-era gym DTO"(把 Destructible 与 Gadget 两族混用)。
// (b) 本仓库对 68169646 的既有写法就是 6 字段(GameRouter.Gadget.cs:257、Blackout.cs:335),
// 且 GameRouter.Gadget.cs:33-38 自述这条通道 "which one the client honours … is still
// unknown" —— 也就是说**本仓也从未验证过它**。
// (c) 本文件是**诊断旁路**,默认关闭(`_pinAsGadget = 0`),不参与保龄球主功能。
// 保龄球能不能玩,取决于服务端推球瓶实体(GameRouter.GameGround.cs + 本仓
// BowlingWireContracts.cs 的 DestructibleGridAOIIncrease,schema 396)**以及客户端
// BF1 补丁(AnantaBowlingLoader.exe)**,与本文件无关。
// ⇒ 结论:既然两种形状都未在本仓验证过,就**不引入第三种形状、不搬入被判可疑的 DTO**,
// 直接用宿主仓既有类型,保持本仓内部完全同形。若日后要试 7 字段形状,请回
// `PrivateServer修改\Drmk.Server\Drmk.RpcTypes\Client4229938\GymGadgetContracts.cs`
// 整体搬入,本文件只需把 payload 类型与字段名换回大驼峰即可。
//
func GameRouter_BowlingPinGadget_PushBowlingPinGadgetsAsync(ctx context.Context, conn any, session any, playerPos Vec3) any {
// Router implementation for GameRouter_BowlingPinGadget_PushBowlingPinGadgetsAsync
var zero any; return zero
}