109 lines
5.7 KiB
Go
109 lines
5.7 KiB
Go
package routers
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
)
|
||
|
||
var _ = sync.Mutex{}
|
||
var _ = context.Background
|
||
|
||
//
|
||
// 改装店(Smokey Drift / ApplyCar)的购买链与外观回声 ——
|
||
// 2026-09-26 自上游 donor repair-shop.zip 移植(唯一参考源,没有混其它捐赠端)。
|
||
// <para>第一步(进场闭环)已经在 GameRouter.Teleport.cs / GameRouter.Vehicle.cs 落地;
|
||
// 这一步补的是「进店之后能干什么」:切换展示车、买件、买套件、清车位。</para>
|
||
// <para>⛑⛑ 三条 donor 用实机日志证明、不看代码绝对猜不出来的结论:</para>
|
||
// <list type="number">
|
||
// <item>纯数值件(引擎/刹车数值/传动/车身数值)不能进刷车包。它们在
|
||
// VehiclePartConfig 里没有 PartPath、只有 PartPerfID,混进 Parts 会让真车装配把槽位冲空
|
||
// ⇒ 全黑透明不可驾驶(81005006 + engine 9995002 复现)。但它们是唯一的数值通道
|
||
// (客户端本地不应用),所以 owned-fleet 列表里必须带、刷车包默认不带,用
|
||
// gameplay.repairShop.sendStatParts 做 A/B。</item>
|
||
// <item>Parts 里必须有车轮。只发买过的件 ⇒ 客户端 NPDVehicleSwitch 报
|
||
// 「未配置车轮数据」,车退化成 SwitchToNonPhysicalDriveModular(Burst data not init,透明不可开)。
|
||
// 所以服务端要按套件把 Suit[] + WheelModelA[] + WheelModelB[] + SuitPaint 全展开成底座,
|
||
// 再用买过的件按 PartTag 顶替。</item>
|
||
// <item>钱和库存一律不模拟。客户端在发请求前已经拿我们推下去的商品表自己校验过了,
|
||
// 服务端只要 ack ok;扣钱是另一条链(本次不做)。</item>
|
||
// </list>
|
||
//
|
||
// ----------------------------------------------------------------------------------
|
||
// 外观展开
|
||
// ----------------------------------------------------------------------------------
|
||
//
|
||
// 一辆车此刻的完整外观: = 套件底座 id, =
|
||
// 展开后的零件表。口径与客户端 ExpandForClient 一致(按 PartTag 顶替,没有就追加,
|
||
// ConfigId=0 表示移除)。
|
||
// 顺序:先按套件展开底座(Suit[] + WheelModelA[] + WheelModelB[] + SuitPaint),
|
||
// 再用买过的件按 PartTag 顶替。套件本身(type 18)由 SuitId 承载,不进 Parts。
|
||
//
|
||
func GameRouter_VehicleTuning_BuildAppearance(ctx context.Context, world any, configId uint32, parts []any, suit uint32, includeStatParts bool) any {
|
||
// Router implementation for GameRouter_VehicleTuning_BuildAppearance
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 购买后重推 SyncAllUnlockedVehicles(64871623):改装面板靠这份列表判断
|
||
// 「哪些类目已解锁」,不重推的话第二次购买就点不动了(donor 2026-09-23 21:19)。
|
||
// 与 PublishVehicleOwnership 的区别:那个有「只推一次」的闸门,这个是每次都推。
|
||
// owned-fleet 里带纯数值件(见类注释第 1 条)。
|
||
//
|
||
func GameRouter_VehicleTuning_PushTunedFleetAsync(ctx context.Context, session *GameSession, reason string) any {
|
||
// Router implementation for GameRouter_VehicleTuning_PushTunedFleetAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
// ----------------------------------------------------------------------------------
|
||
// 购买链
|
||
// ----------------------------------------------------------------------------------
|
||
// 63699253 — 改装面板开面板时要的完整商品表(返回体,不是 notify)。
|
||
func GameRouter_VehicleTuning_AskNpcShopCommodityInfo(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_VehicleTuning_AskNpcShopCommodityInfo
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 63497070 — 店里换展示车。返回新车实体的 uid(0 = 失败),客户端随后 possession 它。
|
||
// 落点 = 该店的 Interior(地下工位),不是「玩家旁边」:donor 踩过「spawn 到
|
||
// 玩家右手边 5.5m」导致车卡在墙里。返回之后补一发 SyncTeleportVehicle 把车钉在工位上
|
||
// ——客户端自己的 parking-waypoint 查询在没有 spoon graph 时返回 0,会把它摆在玩家看的地方。
|
||
//
|
||
func GameRouter_VehicleTuning_AskVehicleShopSpawnVehicle(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_VehicleTuning_AskVehicleShopSpawnVehicle
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 63613647 — 客户端把停在那的预览车收掉了。只记日志(车是客户端本地预览)。
|
||
func GameRouter_VehicleTuning_AskVehicleShopDestroyParking(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_VehicleTuning_AskVehicleShopDestroyParking
|
||
var zero any; return zero
|
||
}
|
||
|
||
// 63970007 — 改装面板单件购买。不扣钱不查库存,直接 ok。
|
||
func GameRouter_VehicleTuning_AskBuyCommodity(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_VehicleTuning_AskBuyCommodity
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 63701165 — 改装购买(NewCarStoreMgr 的「应用」)。{shopid, vehicleid,
|
||
// commodityiddict{商品id:数量}, removedparttypes[]}。
|
||
// 这是唯一真正改变服务端状态的一步:把买到的件按车记进 WorldEntryState,
|
||
// BuildAppearance 会在后续刷车 / owned-fleet 里把它们回声出去。
|
||
//
|
||
func GameRouter_VehicleTuning_AskBuyModifyParts(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_VehicleTuning_AskBuyModifyParts
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 63614427 — 4S / 商店整单购买。Smokey Drift 不走这条(它用 AskBuyModifyParts),
|
||
// 但客户端会发,不注册就会挂在 await 上,所以照样 ack ok 并记日志。
|
||
//
|
||
func GameRouter_VehicleTuning_AskBuyCommodities(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_VehicleTuning_AskBuyCommodities
|
||
var zero any; return zero
|
||
}
|
||
|