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/task_methods.go
T

144 lines
8.4 KiB
Go
Raw Normal View History

package methods
// ============================================================================
// Task (quest) contracts for build 4229938.
//
// Why this file exists: the task panel reads its list from ONE dedicated S2C,
// SyncPlayerAllTask(64260853). It does not read the login payload at all —
// PlayerClientInfoAchievement.UnlockedQuestList is consumed only by the
// favourites / ambient-event code (verified by grepping the client Lua), so
// filling 4342 quest ids there leaves the panel empty. That was tried and it
// changed nothing in-game.
//
// Every shape below is transcribed from the client's OWN reader table
// (Drmk.Proxy/proxy/lua/RPCDeserializeAuto.lua), which is authoritative for the
// wire order. Reader indices are noted per type so a future change can be
// re-verified instead of guessed. Indices are build-specific — an earlier draft of
// this file quoted 334/335/503/1567 from a different client build and produced a
// stream that desynced the reader:
//
// midToReader[64260853] -> taskInfos, submitTaskList,
// currentTask, eventPanelInfo,
// loginGameServer (5 args, not 7)
// Auto.Reader[334] TaskViewData TaskId, CounterValues, Counters,
// State(byte), ActiveFunctionValue,
// ActiveFunctionIds, RecoverResource,
// SpoonViewInfo
// Auto.Reader[1567] TaskViewCounter Index, Value, ConfigValue, Parent, Child
// Auto.Reader[1164] IntList Value (Int32 count!)
// Auto.Reader[503] TaskSpoonViewInfo (unused while null)
// Auto.Reader[335] TaskEventPanelInfo EventsInfo, SubmitEventList,
// SubmitReplayEventList, EventViewInfoList
// <-- FOUR fields on 4229938
// Auto.Reader[1563] EventInfo (unused while EventsInfo is empty)
// Auto.Reader[1043] EventViewInfo (unused while EventViewInfoList is empty)
// Auto.Reader[438] TaskStateData State(byte), Reason(byte), FailTextId,
// CanSkip
//
// Reader indices are build-specific and MUST be re-read from
// Drmk.Proxy/proxy/lua/RPCDeserializeAuto.lua (or lua.zip) rather than copied from
// another branch. An earlier draft of this file quoted 293/294 from a different
// client build: 293 is a colouring-slot struct and 294 has three fields, so that
// draft dropped SubmitReplayEventList and desynced everything after eventPanelInfo.
//
// Framing, from lua/LX6/Service/RPCDeserializeBase.lua: ReadList7Bit/ReadDict7Bit read
// one byte and return nil only when it is 0x00, then read a biased 7-bit count;
// ReadComplex does the same and emits NO inner object marker. UxSerializer therefore
// writes 0xFF as the "present" marker (any non-zero byte works) followed by UxWriter.Int7.
//
// Enums are 1 byte on the wire (Reader[334].State = ReadByte), so every enum below is
// declared `: byte`. UxSerializer writes Enum.GetUnderlyingType, so a plain `enum`
// (int) would emit four bytes and shift every following field.
//
// TaskState comes from the IL2CPP dump (enum UX.Game.TaskState, TypeDefIndex
// 32201): NotAccept=0, Accepted=1, Submited=3, Aborted=4. Note there is no 2.
// ============================================================================
// UX.Game.TaskState — one byte on the wire (Reader[334].State is ReadByte).
type TaskState4229938 byte
const (
TaskState4229938_NotAccept TaskState4229938 = 0
TaskState4229938_Accepted TaskState4229938 = 1
TaskState4229938_Submited TaskState4229938 = 3
TaskState4229938_Aborted TaskState4229938 = 4
)
// Auto.Reader[1567] — a task counter node. `Child` is the same type, so the
// recursive field references this class.
// Auto.Reader[503] — which spoon/raid this task is authored in.
// Auto.Reader[1164] — value list behind PlayerTaskInfo.ActiveFunctionIds.
// Uses an Int32 count, not a 7-bit one.
// Auto.Reader[334] — one row of the task panel.
// Auto.Reader[1563] — an ambient/story event row.
// FinishedChoiceLs is the Int32-counted list.
// Auto.Reader[1043] — event view metadata.
// Auto.Reader[335] — bundled event state carried alongside the task list.
// Exactly FOUR fields on 4229938. SubmitReplayEventList is easy to lose because some
// client builds omit it; dropping it here pushes EventViewInfoList into
// loginGameServer and strands a trailing byte, which desyncs the whole packet.
//
// SyncPlayerAllTask(64260853) — the ONLY thing that populates the task panel.
// Wire shape (midToReader[64260853], export option LuaAndCSharp, so both the Lua
// impl and the native side see it):
// taskInfos List&lt;PlayerTaskInfo&gt; (7-bit count, complex items)
// submitTaskList List&lt;uint&gt; (7-bit count)
// currentTask uint
// eventPanelInfo EventPanelInfo (complex)
// loginGameServer bool
// Flat argument list, so this wrapper is Inline: a 0xFF marker before taskInfos
// would be read as the list's own framing and corrupt the count.
//
//
// SyncPlayerAllTaskDebug(64423039) — the CSharpOnly twin of SyncPlayerAllTask, and the ONLY
// way to get task rows into the native task manager.
// Why this exists: SyncPlayerAllTask(64260853) is LuaAndCSharp and the client ships a Lua impl
// (GameToClientImpl.SyncPlayerAllTask). Per the dispatcher rule, a LuaAndCSharp method with an
// impl reports handled=true and native never sees the packet — and that impl only reads
// `currentTask`, it never touches `taskInfos`. So the list we publish there is discarded.
// This one is CSharpOnly with no Lua impl, so native reads it. Field order straight from the
// IL2CPP dump (UXRPCMethodArgs64423039): taskInfos / submitTaskList / submitEventList /
// versionControlInfo. TaskViewData (dump TypeDefIndex 32303) has exactly the eight fields of
// PlayerTaskInfo4229938, so that DTO is reused as-is.
//
// UX.Game.ChangeSingleTaskReason — one byte on the wire (Reader[438].Reason).
// From the IL2CPP dump, TypeDefIndex 32311.
type ChangeSingleTaskReason4229938 byte
const (
ChangeSingleTaskReason4229938_Accept ChangeSingleTaskReason4229938 = 0
ChangeSingleTaskReason4229938_TaskCounterAdd ChangeSingleTaskReason4229938 = 1
ChangeSingleTaskReason4229938_TaskCounterDesChange ChangeSingleTaskReason4229938 = 2
ChangeSingleTaskReason4229938_GpsChange ChangeSingleTaskReason4229938 = 3
ChangeSingleTaskReason4229938_Submit ChangeSingleTaskReason4229938 = 4
ChangeSingleTaskReason4229938_Abort ChangeSingleTaskReason4229938 = 5
ChangeSingleTaskReason4229938_Fail ChangeSingleTaskReason4229938 = 6
ChangeSingleTaskReason4229938_ClearSubmit ChangeSingleTaskReason4229938 = 7
)
// Auto.Reader[438] / UX.Game.TaskStateData (TypeDefIndex 32305) — why a single task
// changed. Note the dump declares these enums as `int`, but the generated client reader reads
// bytes, so both are declared `: byte` here.
//
// SyncTaskTitleGuideUnlock(64841491) — unlocks one task title (a panel tab / chapter group).
// Wire shape from the IL2CPP dump (UXRPCMethodArgs64841491): `ushort taskTitleId`,
// `bool unlock`. The client's Lua impl calls
// gMapSystem.taskUtils:SetTaskTitleGuide(taskTitleId, unlocked), so this is what reveals
// the story/side/chapter tabs. Ids come from TaskTitleConfig.json (21 rows on this build:
// 1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,19,21,23,24,25,99).
// taskTitleId is a ushort — writing it as uint would shift `unlock` out of position.
//
//
// SyncPlayerSingleTask(64917604) — per-task incremental channel, and CSharpOnly with no Lua
// impl, so native's task manager reads it. This is the channel the real server uses when a
// task changes state after login.
// Wire shape from the dump (UXRPCMethodArgs64917604): `uint taskId`, `TaskViewData taskInfo`,
// `TaskSpoonViewInfo spoonViewInfo`, `TaskStateData stateData`. Flat argument list, so this
// wrapper is Inline; each of the three class arguments carries its own Complex marker.
//
//
// SyncCurrentTask(64450155) — S2C「把这条任务设为当前追踪任务」(GPS 布点)。
// 2026-10-03 随赛车移植:赛车接受任务时必须回这一条,否则客户端不知道该追踪哪条。
// 线格式取自客户端 reader:`byte type, uint taskId, uint eventId, bool firstTime, byte reason`
// —— flat argument list,Inline。
// Type 0 = CurrentTaskType.Primary;Reason 2 = ChangeCurrentTaskReason.Client。
//