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/pkg/protocol/methods/truck_order_methods4229938.go

104 lines
6.4 KiB
Go
Raw Permalink 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 methods
//
// Cat Express / 蓝猫物流 wire contracts for client build 4229938 (internal name: UberSim).
// Why this file exists: the panels exist and look finished, but every list they render is a server
// reply — AskGetTruckJobOrders supplies the take-order list, AskGetFinishedOrderWraps
// the completed list — and none of those had a handler, so the app opened onto an empty board.
// Source of truth. The IL2CPP dump declares these types as EMPTY classes
// (ux_game_all.dump.cs:24562 ClientTruckOrderView, :34846 TruckJobOrderWrap — hard
// rule 22), so every field order below comes from the client's own writer in
// lua/LuaGen/AutoGen/RPCSerializeAuto.lua:
// ClientTruckOrderView :2523 · TruckJobOrderWrap :10473
// TruckJobOrderInfo :10433 · TruckJobOrderAccept :10428
// TruckJobOrderResult :10456 · TruckNpcInfo :10483
// TruckPosInfo :10490 · CargoInfo :1571
// DeliveryGadgetInfo :3272 · UXVector3 :11429
// ClientFinishedTruckOrderView :2273
// Field order IS the wire layout — do not reorder (UxSerializer writes by MetadataToken).
// Framing (from BowlingWireContracts.cs §0, re-derived here line by line):
// complex -> 0x00 when null, else 0xFF + fields (Base.WriteComplex)
// struct -> never any marker (Base.WriteStruct / Inline = true)
// list -> 0x00 when null, else 0xFF + Int32 count (Base.WriteList, 4 bytes FLAT)
// list7 -> 0x00 when null, else 0xFF + varint(count + 1) (Base.WriteList7Bit)
// dict7 -> same as list7, then key, value pairs
// ⛑⛑ WriteList and WriteList7Bit are NOT interchangeable and this type family mixes
// both — see the Count = UxCountEncoding.Int32 notes on each list below. Writing the
// wrong one shifts everything after it by three bytes and the client silently drops the reply.
//
// Three floats, never marked. Used for both positions and euler rotations.
//
// One drop-off fixture = Auto.WriteDeliveryGadgetInfo (RPCSerializeAuto.lua:3272). Complex.
//
//
// Pickup / delivery point = Auto.WriteTruckPosInfo (RPCSerializeAuto.lua:10490).
// ⛑ DeliveryGadgetInfoList goes through Base.WriteList (flat Int32 count), not the
// 7-bit variant — it is the one list in this family that is NOT varint-counted.
//
// Consignee identity = Auto.WriteTruckNpcInfo (RPCSerializeAuto.lua:10483).
// One physical parcel = Auto.WriteCargoInfo (RPCSerializeAuto.lua:1571).
//
// The authored body of one order = Auto.WriteTruckJobOrderInfo (RPCSerializeAuto.lua:10433).
// Everything cosmetic (cargo name, area name, disaster stars, tag icons, NPC portrait) is looked up
// client-side from CargoId / OrderType / SpecialOrderId, so the server only publishes identifiers
// and the numbers that go into payment.
//
// Set once the player takes the row = Auto.WriteTruckJobOrderAccept (:10428).
// Filled on settlement = Auto.WriteTruckJobOrderResult (:10456).
//
// One row of the take-order list = Auto.WriteTruckJobOrderWrap (RPCSerializeAuto.lua:10473).
// AcceptInfo / ResultInfo are the ONLY nullable complexes here
// (WriteComplex(..., true)), which is exactly how a row tells "takeable" from "taken".
//
//
// Reply body of AskGetTruckJobOrders(63386469) and AskRefreshTruckOrder(63071191) —
// Auto.WriteClientTruckOrderView (RPCSerializeAuto.lua:2523). The whole take-order board.
// ⛑ Reply framing: this type is declared complex (no Inline), matching every other INVOKE reply in
// this repo (Bubble / Extraction / Tuite's TuiteTimelineData). If the client logs
// deserialize failed for these two methods, flip delivery.replyFraming to "struct" in
// private-server.json — no rebuild needed.
//
//
// Reply body of AskGetFinishedOrderWraps — Auto.WriteClientFinishedTruckOrderView
// (RPCSerializeAuto.lua:2273). The three counters headline the completed-log page.
//
//
// Reply body of AskAcceptTruckJobOrder(63110537) — the callback is
// (errorId, TruckJobOrderWrap, ulong npcInstanceId), so this is the two-part tuple the RPC
// layer unpacks: complex row first, raw u64 second (no marker on a primitive).
// ⛑⛑ Inline, not complex. 2026-09-25 修正:这曾写成 [UxContract],于是顶层多出
// 一个 0xFF。多值回包的顶层是没有标记的 —— RPCDeserializeAuto.lua:10160 直接
// ReadComplex(286) 再 ReadUInt64,标记由每个值自己发。多出来的那一字节会让
// 客户端把 OrderWrap 的标记当成 OrderInfo 的标记、把 OrderInfo 的标记当成 StartPos 的标记,
// 整包左移一字节 ⇒ 回调拿到的是一坨垃圾(现象正是"点了接单没反应")。
// 对照:单值回包(ClientTruckOrderView / TruckJobOrderWrap)顶层要那个 0xFF,
// 因为客户端第一个读的就是 ReadComplex。
//
//
// Reply body of AskQueryTruckPosInfo(63763434) — RPCDeserializeAuto.lua:12187 reads
// ReadList7Bit(Auto.Reader[641]) twice, so again no top-level marker: Inline.
// The client only looks at [1] of each list (DeliveryTaskManager.lua:1870), so one
// entry per queried id in the same order as the request is all that is required.
//
//
// Push body of SyncAcceptTruckJobOrder(64910164) — RPCDeserializeAuto.lua:4732:
// (u32 id, complex TruckJobOrderWrap, u64 deliveryAgentId, u64 deliveryGadgetId), no top marker.
// ⛑ This — not the accept reply — is what actually moves the UI: the reply callback at
// DeliveryHomepagePanelStore.lua:809 inspects errorId and nothing else, and the
// store only clears its own canInteract latch in
// OnAcceptTruckJobOrder, which is bound to
// ON_ACCEPT_TRUCK_JOB_ORDER — the message GameToClientImpl.SyncAcceptTruckJobOrder
// (:1761) raises. So without this push the board stays frozen after a tap that the server logged
// as accepted.
//
//
// Inline twin of ClientTruckOrderView — identical fields, no leading marker.
// ⛑ Why a copy instead of a base class: UxSerializer serialises every public field including
// inherited ones and orders them by MetadataToken, so sharing one declaration would quietly make
// both framings emit the same bytes. The duplication is the cheap part; a mismatched reply
// framing costs a rebuild round-trip per guess.
// Selected at runtime by gameplay.deliveryReplyFraming ("complex" | "struct"). Nothing else
// consults it — a wrong guess shows up as the client dropping the callback, never as an exception.
//
// Inline twin of ClientFinishedTruckOrderView for the same reason.