337 lines
16 KiB
Go
337 lines
16 KiB
Go
package routers
|
||
|
||
import (
|
||
"context"
|
||
"sync"
|
||
)
|
||
|
||
var _ = sync.Mutex{}
|
||
var _ = context.Background
|
||
|
||
//
|
||
// Cat Express (蓝猫物流) — the courier app, board + take-or-drop half.
|
||
// Why this file exists: the app already opens (the icon is published with every other phone app and
|
||
// SystemUnlock 305 is unlocked), but every list inside it is a server reply. With no handler each
|
||
// request fell through to the generic typed default, so the board stayed empty and the row was
|
||
// never takeable — the whole "接单 -> 详情 -> 支援" loop had nothing to iterate over.
|
||
// Scope of this first pass — exactly what its client (*DeliveryHomepagePanelStore*) asks for:
|
||
// · take-order board with per-row accept countdown AskGetTruckJobOrders / AskRefreshTruckOrder
|
||
// · taking and dropping a row AskAcceptTruckJobOrder / AskObsoleteTruckJobOrder
|
||
// · the finished-log page AskGetFinishedOrderWraps
|
||
// · the account-level satisfaction average AskGetTruckSatisfactionAverage
|
||
// · the two support buttons rendered by RefreshCallFunctionListView
|
||
// – 叫车 already works: the panel calls the client-side AskSummonVehicle(67012447),
|
||
// which has had a server handler since before this file existed (GameRouter.Vehicle.cs:449),
|
||
// so all that is missing here is remembering the chosen vehicle
|
||
// (AskSetTruckJobDefaultVehicleId). UberSimOrderSupportConfig.CallCarCfg ships
|
||
// vehicleId [81003022, 81004024] and the panel falls back to that list, so calling a car
|
||
// also works before anything is chosen.
|
||
// – 无人机 (Drone) needs buff 52800661 on the player, otherwise the button is filtered out
|
||
// by RefreshCallFunctionListView. It is published by
|
||
// gameplay.deliverySupportBuffIds through CharacterCapabilities.
|
||
// Settlement (PreSettle / Settle / the score row in the finished list) is NOT implemented: it needs
|
||
// the cargo-integrity model and its drop table, and the board is worth shipping without it.
|
||
// ⛑ Every field below is transcribed from the client's own writer
|
||
// (RPCSerializeAuto.lua lines cited in TruckOrderMethods4229938.cs). Positions are all zero: the
|
||
// server has no authored pickup/delivery coordinates, and inventing ones would put the map pin in
|
||
// the wrong place — an honest zero is better than a wrong coordinate.
|
||
//
|
||
func GameRouter_Delivery_Board(ctx context.Context, session *GameSession) any {
|
||
// Router implementation for GameRouter_Delivery_Board
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Delivery_Finished(ctx context.Context, session *GameSession) []any {
|
||
// Router implementation for GameRouter_Delivery_Finished
|
||
return nil
|
||
}
|
||
|
||
func GameRouter_Delivery_NextTruckOrderId(ctx context.Context, ) uint32 {
|
||
// Router implementation for GameRouter_Delivery_NextTruckOrderId
|
||
return 0
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------------------
|
||
// Board
|
||
// -----------------------------------------------------------------------------------------
|
||
//
|
||
// AskGetTruckJobOrders(63386469) — no arguments, returns the whole take-order board.
|
||
// Called when the panel opens and again on every new in-game day
|
||
// (ON_DELIVERY_TRUNK_ORDER_NEW_DAY -> DeliveryHomepagePanelStore.OnTruckOrderNewDay).
|
||
//
|
||
func GameRouter_Delivery_AskGetTruckJobOrders(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskGetTruckJobOrders
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskRefreshTruckOrder(63071191) — no arguments, same body. Rubber-banded by the client with
|
||
// UberSimConfig.TakeOrderRefreshTime (15 s), so re-rolling (rather than appending) is the
|
||
// behaviour that matches the cooldown the panel shows.
|
||
//
|
||
func GameRouter_Delivery_AskRefreshTruckOrder(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskRefreshTruckOrder
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Delivery_ReturnBoardAsync(ctx context.Context, conn any, msg any, via string) any {
|
||
// Router implementation for GameRouter_Delivery_ReturnBoardAsync
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Delivery_NewView(ctx context.Context, session *GameSession) any {
|
||
// Router implementation for GameRouter_Delivery_NewView
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Delivery_ToInline(ctx context.Context, view any) any {
|
||
// Router implementation for GameRouter_Delivery_ToInline
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// Where a generated order's pickup sits. All zeros when deliverySpotsAtPlayer is off —
|
||
// the pre-2026-09-25 behaviour, kept as the rollback for the coordinate work.
|
||
//
|
||
func GameRouter_Delivery_SpotOrigin(ctx context.Context, rpcCtx *RpcContext, cfg any) any {
|
||
// Router implementation for GameRouter_Delivery_SpotOrigin
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// One row of the board. everything authorable comes from the UberSim tables so the client can
|
||
// resolve its own labels; only ids the server owns (UniqueId, times) are invented here.
|
||
//
|
||
func GameRouter_Delivery_BuildRow(ctx context.Context, index int32, ox float32, oy float32, oz float32, offset float32) any {
|
||
// Router implementation for GameRouter_Delivery_BuildRow
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Delivery_Pick(ctx context.Context, source []any) any {
|
||
// Router implementation for GameRouter_Delivery_Pick
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Delivery_Pick_2(ctx context.Context, source []any) uint32 {
|
||
// Router implementation for GameRouter_Delivery_Pick_2
|
||
return 0
|
||
}
|
||
|
||
func GameRouter_Delivery_TruckVehicle(ctx context.Context, session *GameSession) uint32 {
|
||
// Router implementation for GameRouter_Delivery_TruckVehicle
|
||
return 0
|
||
}
|
||
|
||
func GameRouter_Delivery_TruckFlag(ctx context.Context, session *GameSession, key string) bool {
|
||
// Router implementation for GameRouter_Delivery_TruckFlag
|
||
return true
|
||
}
|
||
|
||
func GameRouter_Delivery_SetTruckFlag(ctx context.Context, session *GameSession, key string, value bool) any {
|
||
// Router implementation for GameRouter_Delivery_SetTruckFlag
|
||
var zero any; return zero
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------------------
|
||
// Take / drop
|
||
// -----------------------------------------------------------------------------------------
|
||
//
|
||
// AskAcceptTruckJobOrder(63110537) — (uint id) -> (TruckJobOrderWrap, ulong npcInstanceId).
|
||
// The cap itself is client-side (DeliveryHomepagePanelStore.CheckCanTakeOrder:
|
||
// UberSimConfig.InitAcceptCount plus one per badge in AddAcceptBadgeList), and it counts
|
||
// rows whose AcceptInfo is set — so stamping AcceptInfo is what makes the cap move, which is
|
||
// also why the server must not silently accept past it (the client would then disagree with its
|
||
// own button state).
|
||
//
|
||
func GameRouter_Delivery_AskAcceptTruckJobOrder(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskAcceptTruckJobOrder
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskObsoleteTruckJobOrder(63756681) — (uint id), void. Drops the row off the board for the
|
||
// rest of the in-game day, which is what the panel does locally before awaiting the reply.
|
||
//
|
||
func GameRouter_Delivery_AskObsoleteTruckJobOrder(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskObsoleteTruckJobOrder
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskAutoAcceptTruckJobOrder(63913941) — (bool bAutoAccept), void. Persisted per session and
|
||
// echoed back in ClientTruckOrderView.AutoAccept so the toggle keeps its state.
|
||
//
|
||
func GameRouter_Delivery_AskAutoAcceptTruckJobOrder(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskAutoAcceptTruckJobOrder
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskSetTruckJobDefaultVehicleId(63784367) — (uint vehicleId), void.
|
||
// The argument comes from the vehicle list panel opened by 叫车's detail button
|
||
// (DeliveryTaskManager.CallOpenCallCar); it only has to be remembered and echoed, because
|
||
// the actual summon goes out as AskSummonVehicle from OnOrderSupportItemClick.
|
||
//
|
||
func GameRouter_Delivery_AskSetTruckJobDefaultVehicleId(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskSetTruckJobDefaultVehicleId
|
||
var zero any; return zero
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------------------
|
||
// Pickup / delivery points
|
||
// -----------------------------------------------------------------------------------------
|
||
//
|
||
// AskQueryTruckPosInfo(63763434) — (list7bit u32 pickupIds, list7bit u32 deliveryIds)
|
||
// -> (list7bit TruckPosInfo, list7bit TruckPosInfo).
|
||
// ⛑ Only caller: DeliveryTaskManager.SetSpoonCustomOrderData (:1870), the custom/spoon
|
||
// order path — not the normal take-order row. It caches per id and reads [1] of each
|
||
// list only, so one entry per queried id, in request order, is all the client consumes.
|
||
// The server has no authored world points (UberSimPickupConfig / UberSimDeliveryConfig carry
|
||
// names and tags only — no coordinates), so the spot is placed relative to the player's last
|
||
// reported position: pickup on the player, drop-off deliveryDropOffset away. That keeps
|
||
// the map pin somewhere reachable instead of at the world origin; flip
|
||
// gameplay.deliverySpotsAtPlayer to false to get the old all-zero behaviour back.
|
||
//
|
||
func GameRouter_Delivery_AskQueryTruckPosInfo(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskQueryTruckPosInfo
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// One TruckPosInfo. WpId stays 0 — it is a world-point id from a table the server does
|
||
// not have, and the client only feeds these straight into the order it is assembling.
|
||
//
|
||
func GameRouter_Delivery_Spot(ctx context.Context, configId uint32, raid uint32, x float32, y float32, z float32) any {
|
||
// Router implementation for GameRouter_Delivery_Spot
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// list7bit<u32> 解包(带游标,供一条请求里连读两个列表)。
|
||
// ⛑ 首字节是集合标记:0xFF = 非空(SerializeBase.WriteList7Bit 写
|
||
// SerializeObjectMarkCommon),0x00 = null。一个正常的项数 varint 不会以 0xFF 开头
|
||
// (那意味着 count ≥ 2^28),所以"见到 0xFF 就跳过"是无歧义的。
|
||
// 项数带 +1 偏置(UxWriter.Int7),与 GameRouter.Extraction.cs 的同名工具一致。
|
||
//
|
||
func GameRouter_Delivery_ReadU32List7BitAt(ctx context.Context, body []byte, pos int32) []any {
|
||
// Router implementation for GameRouter_Delivery_ReadU32List7BitAt
|
||
return nil
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------------------
|
||
// Log / summary / tutorial
|
||
// -----------------------------------------------------------------------------------------
|
||
//
|
||
// AskGetFinishedOrderWraps(63545189) — no arguments, returns the completed-log body
|
||
// (Auto.WriteClientFinishedTruckOrderView, RPCSerializeAuto.lua:2273).
|
||
// ⛑⛑ 每一行都必须带齐 AcceptInfo 和 ResultInfo,否则面板直接炸而不是显示"暂无":
|
||
// · DeliveryLogPhonePanelStore.GetTotalMoney 读 ResultInfo.DropMoney
|
||
// · RefreshOrderListView 读 ResultInfo.FinishTime 做排序
|
||
// · OnRenderItem 读 ResultInfo.CargoIntegrity / Evaluation 与
|
||
// AcceptInfo.AcceptTime 算耗时
|
||
// · 详情 RefreshOrderDetailView(:1264) 第一句就是
|
||
// if resultInfo ~= nil then return end(判定又是反的,详见规则 135)
|
||
// 列表内容来自两处:真实结算(AskSettleTruckOrder 挪进来的行)和
|
||
// gameplay.deliveryLogSeedCount 的历史补账。之所以要补账:客户端那条结算链
|
||
// (PreSettleTruckOrder:571 / FinishDeliveryOrder:705) 只被任务系统驱动,
|
||
// 面板上没有任何入口,所以在这条链接通之前,日志页只能由服务端预置内容。
|
||
// 回滚:把 deliveryLogSeedCount 置 0 就只剩真实结算的行。
|
||
//
|
||
func GameRouter_Delivery_AskGetFinishedOrderWraps(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskGetFinishedOrderWraps
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// 一条「已完成」的行:照搬看板行的生成方式,再补上收货时间 / 结算结果。
|
||
// 只是为了让几条补账行的时间各不相同(第 n 条是 n 小时前完成),
|
||
// 这样列表按 FinishTime 排序和「今日收入」那一栏才看得出前后关系。
|
||
//
|
||
func GameRouter_Delivery_FinishedRow(ctx context.Context, slot int32, ox float32, oy float32, oz float32, offset float32, cfg any, seedIndex int32) any {
|
||
// Router implementation for GameRouter_Delivery_FinishedRow
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskGetTruckSatisfactionAverage(63344040) — no arguments, returns a float.
|
||
// This one already reaches the server today: it shows up 16 times in unknown-methods.log while
|
||
// the app sat open, and a 0-byte INVOKE is exactly the shape that hangs the callback until it
|
||
// times out (hard rule 94). Serving it removes that stall even before anything else lands.
|
||
//
|
||
func GameRouter_Delivery_AskGetTruckSatisfactionAverage(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskGetTruckSatisfactionAverage
|
||
var zero any; return zero
|
||
}
|
||
|
||
// AskStartTruckOrderGuide(63637032) — no arguments, void. Tutorial latch.
|
||
func GameRouter_Delivery_AskStartTruckOrderGuide(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskStartTruckOrderGuide
|
||
var zero any; return zero
|
||
}
|
||
|
||
func GameRouter_Delivery_BodyU32(ctx context.Context, msg any) uint32 {
|
||
// Router implementation for GameRouter_Delivery_BodyU32
|
||
return 0
|
||
}
|
||
|
||
// -----------------------------------------------------------------------------------------
|
||
// Settle chain — 完成结算 / 满意度评分 / 送货日志
|
||
//
|
||
// 这段只为把面板的文字内容顶出来,不做玩法:没有真实的货物完好度计算、没有里程、
|
||
// 没有路线校验。行在 PreSettle 时被打上"已完成",Settle 时从看板移进已完成列表,
|
||
// 之后 AskGetFinishedOrderWraps 就能把它读回去。
|
||
// -----------------------------------------------------------------------------------------
|
||
//
|
||
// AskPreSettleTruckOrder(63818375) — (uint uniqueId, list TruckCargoSettleInfo) -> (TruckJobOrderWrap).
|
||
// 客户端 PreSettleTruckOrder:571 的回调是 (err, truckJobOrderWrap),命中成功分支
|
||
// 后把 info.result = truckJobOrderWrap 并 SetOrderComplete(info, true),
|
||
// 结算面板就是靠这个 wrap 渲染的。货物完好度清单我们收下但不读 —— 那需要真实路线的里程/颠簸。
|
||
//
|
||
func GameRouter_Delivery_AskPreSettleTruckOrder(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskPreSettleTruckOrder
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskSettleTruckOrder(63873513) — (uint uniqueId), void.
|
||
// 客户端 FinishDeliveryOrder:705 成功后关倒计时面板并推送 ON_GOOD_OPEN_INTEGRITY_PLANE,
|
||
// 也就是评分那段演出。这里把行从看板挪进已完成列表,好让「送货日志」读得到。
|
||
// ⛑⛑ 挪之前必须补 AcceptInfo + ResultInfo —— 日志面板在它们上面取字段,
|
||
// 留 null 会直接报错而不是显示空。详见 AskGetFinishedOrderWraps 的注释。
|
||
//
|
||
func GameRouter_Delivery_AskSettleTruckOrder(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskSettleTruckOrder
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskFinishJob(63333823) — () -> void. 职业侧的"结束今日工作",与订单无关,回空即可。
|
||
//
|
||
func GameRouter_Delivery_AskFinishJob(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskFinishJob
|
||
var zero any; return zero
|
||
}
|
||
|
||
//
|
||
// AskAddTruckOrderSpecialPointRewards(63076643) — (list uint orderIds, int pointId), void.
|
||
// 特殊点位的额外奖励领取,回空即可(奖励入账没接货币系统)。
|
||
//
|
||
func GameRouter_Delivery_AskAddTruckOrderSpecialPointRewards(ctx context.Context, conn any, msg any) any {
|
||
// Router implementation for GameRouter_Delivery_AskAddTruckOrderSpecialPointRewards
|
||
var zero any; return zero
|
||
}
|
||
|
||
// First bytes of a reply, so a framing mismatch can be told apart without a client log.
|
||
// ⛑ MUST stay generic: UxSerializer.Serialize dispatches on the STATIC type argument, so an
|
||
// object parameter makes every overload here report "System.Object is not a UX contract"
|
||
// even though the real reply serializes fine. That false alarm cost a debugging round already.
|
||
func GameRouter_Delivery_HeadHex(ctx context.Context, value any) string {
|
||
// Router implementation for GameRouter_Delivery_HeadHex
|
||
return ""
|
||
}
|
||
|
||
type TruckOrderBoard struct {
|
||
Orders []TruckJobOrderWrap `json:"orders"`
|
||
}
|
||
|