Found and added task packets (#5101)
Build / Linux (push) Waiting to run
Build / Windows (push) Waiting to run

This commit is contained in:
dannuic
2026-06-17 22:22:09 -06:00
committed by GitHub
parent dc559710ed
commit 974dbcd6ff
38 changed files with 586 additions and 79 deletions
+23 -23
View File
@@ -11,7 +11,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th
|:----------------------------------|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------|
| `OP_AAAction` | 🟢 Verified | Client→Server only. 16-byte AA_Action struct (action/ability/target_id/exp_value) matches exactly across all 4 send sites. Passthrough correct. action=7 (set restore) and action=10 (shift-buy) unhandled by emu server by design. | |
| `OP_AAExpUpdate` | 🟢 Verified | Server→Client only. Handler: `msg_altexpup` @ `0x1402087b0`. Dispatched via `cmp [mem], 4C3h` @ `0x1401e4219` (memory-form, not switch table). Encoder correctly scales experience ×100000/330 and zero-extends unspent uint16→uint32. All 3 fields confirmed from raw ASM. | |
| `OP_AcceptNewTask` | 🟠 Missing | | |
| `OP_AcceptNewTask` | 🟢 Verified | Client→Server only. Sent from `CTaskSelectWnd::WndNotification` @ `0x1405100a0` (hton @ `0x1405101ec`). 12-byte payload: task_type\|task_id\|task_master_id matches `AcceptNewTask_Struct` exactly (size=0xE). Types 0 and 2 use this opcode; type 1 uses shared-task opcode 0x5274. Passthrough correct. | |
| `OP_AckPacket` | 🟢 Verified | Client→Server only. Sent from `CDisplay::SetViewActor` @ `0x1401a0b40` (hton @ `0x1401a0c9d`). 4-byte uint32 payload = spawn ID of newly viewed actor (0 if local player or no match). Server ignores payload on both zone and world paths. No encoder/decoder needed. Also used as `signature.ignore_eq_opcode` in zone-in detection. | |
| `OP_Action` | 🟢 Verified | Server→Client only. Dispatched via `cmp [mem], 7D28h` @ `0x1401f4245`. Inline case block: constructs CUnSerializeBuffer, calls MissileHitInfo::Deserialize @ `0x1402024C0`. Encoder correct: spell/effect_flag widened, instrument_mod→float, effective_casting_level/unknown1/damage hardcoded to 0 (intentional). Field offsets confirmed from case block and init function. | |
| `OP_Action2` | 🔴 Not-Set | | |
@@ -55,7 +55,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th
| `OP_AutoAttack` | 🟢 Verified | C→S only. No struct, no decoder needed. Client sends bAutoAttack as uint32 (0/1) in 4-byte payload from DoPassageOfTime@0x1400EC3BD; server reads pBuffer[0]. Passthrough correct. | |
| `OP_AutoAttack2` | 🟢 Verified | C→S only. Client sends uint32 auto-attack state (0/1) from DoPassageOfTime when bAutoAttack changes. Send @ 0x1400ec45f. No encoder/decoder needed; opcode_dispatch.h IN(uint32) correct. Handler stub. | |
| `OP_AutoFire` | 🟢 Verified | C→S only. No S→C handler (IDA showed fallback case). Client sends 6-byte packet (2B opcode + 4B uint32 payload) from DoPassageOfTime @ 0x1400ec65a. No encoder/decoder needed; passthrough correct. | |
| `OP_AvaliableTask` | 🟠 Missing | | |
| `OP_AvailableTask` | 🟢 Verified | Same wire value as `OP_SharedTaskAddPlayer` (0x195C in TOB, 0x36E8 in RoF2). C→S only. EQEMu has no handler under this name; all handling is via `OP_SharedTaskAddPlayer`. No encoder/decoder needed. | |
| `OP_Bandolier` | 🟠 Missing | | |
| `OP_BankerChange` | 🟢 Verified | Inline case block @ 0x1401e6d98. Bank fields (0x100x1C) confirmed correct under passthrough; SetBankPlatinum/Gold/Silver/Copper called at matching offsets. No encoder needed. C→S: header-only click. | |
| `OP_Barter` | 🟠 Missing | | |
@@ -77,7 +77,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th
| `OP_CameraEffect` | 🟢 Verified | S→C only. Passthrough — Camera_Struct (8B: +0 uint32 duration, +4 float intensity). Inline case 0x1401e8431 reads directly, calls CCameraShakeManager::AddShake @ 0x140537F10. | |
| `OP_Camp` | 🟢 Verified | Bidirectional, no encoder/decoder. C→S: empty (size 0) from `CEverQuest::Camp` @ `0x140267240`. S→C: 1 byte @ case `0x1401f9cc7` (cmp-dispatch); byte=0 starts countdown, byte≠0 cancels camp with AA warning. | |
| `OP_CancelSneakHide` | 🟢 Verified | S→C only. Zero-byte signal, no struct/encoder/decoder. Handler `CEverQuest::CancelSneakHide` @ `0x1402678e0` (cmp-dispatch @ `0x1401e8c86`). Client responds with OP_Hide (0x4F10) + OP_SpawnAppearance. | |
| `OP_CancelTask` | 🟠 Missing | | |
| `OP_CancelTask` | 🟢 Verified | Bidirectional. C→S: DialogResponse@CTaskWnd (0x140513c0a, edx=0x254B). S→C: sub_140182B30@0x140182b30 -> ClearTask. Passthrough; struct unchanged. | |
| `OP_CancelTrade` | 🟢 Verified | sub_140209C70 @ 0x140209c70 (cmp-dispatch). C→S field names inverted: fromid=trade target SpawnID, action=local SpawnID. No change needed. | |
| `OP_CashReward` | 🟢 Verified | Passthrough. `sub_140209DB0` @ `0x140209DB0` (Pattern A). 4×uint32 matches `CashReward_Struct`. | |
| `OP_CastSpell` | 🟢 Verified | C→S only (client ignores S→C). Send: `CharacterZoneClient::CastSpell` @ `0x1400d5350`, hton @ `0x1400d7e09`. Fixed decoder: `inventoryslot` now uses `TOBToServerSlot(TOBCastingInventorySlotToInventorySlot(eq->inventory_slot))`. | |
@@ -107,7 +107,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th
| `OP_ColoredText` | 🟢 Verified | Passthrough; sub_140205060 @ 0x140205060; color @ +0x00, msg @ +0x04; newline-split, calls DisplayChatText | |
| `OP_CombatAbility` | 🟢 Verified | C→S only passthrough. Client sends CombatAbility_Struct (m_target/m_atk/m_skill, 12 bytes) unchanged. S→C hits HWM fallback — server never sends this. Send @ sub_140246750 (0x140246750). | |
| `OP_Command` | 🔴 Not-Set | | |
| `OP_CompletedTasks` | 🟠 Missing | | |
| `OP_CompletedTasks` | 🟢 Verified | Handler `sub_140182B30` case 29766 @ `0x1401e7845`. ENCODE added: per-entry `completed_time` zero-extended uint32→uint64 (`mov rax,[rdx+1]` reads QWORD; `add rdx,9`). No struct. S→C only. | |
| `OP_ConfirmDelete` | 🟢 Verified | C→S only. Client sends 2-byte spawn_id from ProcessUpdateStats @ 0x140200010 when spawn not found locally. Server handler is a stub (returns immediately). Passthrough correct, no decoder needed. | |
| `OP_Consent` | 🟢 Verified | C→S only. Client sends null-terminated player name from sub_140221550 @ 0x140221550 (/consent cmd). No real S→C handler (fallback case). Passthrough correct, struct matches wire format. | |
| `OP_ConsentDeny` | 🟢 Verified | C→S only. `/deny` cmd. Send fn `sub_1402217E0` @ `0x1402217E0`. Passthrough — `Consent_Struct{char name[1]}` matches wire format. Not found in HandleWorldMessage (no S→C handler). | |
@@ -514,19 +514,19 @@ Below is a status list for the 450 opcodes we currently use on the server for th
| `OP_SetStartCity` | 🟠 Missing | | |
| `OP_SetTitle` | 🟠 Missing | | |
| `OP_SetTitleReply` | 🟠 Missing | | |
| `OP_SharedTaskMemberList` | 🟠 Missing | | |
| `OP_SharedTaskAddPlayer` | 🟠 Missing | | |
| `OP_SharedTaskRemovePlayer` | 🟠 Missing | | |
| `OP_SharedTaskMakeLeader` | 🟠 Missing | | |
| `OP_SharedTaskMemberList` | 🟢 Verified | TOB: 0x5CCC → cmp-dispatch @ 0x1401f3e48 → sub_140182B30 case 0x5CCC → builds 80-byte linked list, calls CTaskWnd::RefreshSharedTaskPlayerList. Passthrough. RoF2: 0x1E7D. | |
| `OP_SharedTaskAddPlayer` | 🟢 Verified | TOB: 0x195C. C→S send at sub_14022E840 (/taskaddplayer cmd, 0x14022E840) and CTaskWnd::WndNotification. 72-byte SharedTaskAddPlayer_Struct passthrough. field1/field2 always 0. RoF2: 0x36E8. | |
| `OP_SharedTaskRemovePlayer` | 🟢 Verified | TOB: 0x39C8. C→S send at sub_14022ECC0 (0x14022ECC0, /taskremoveplayer cmd) and CTaskWnd::WndNotification (0x1405166E0, GUI). 72-byte SharedTaskRemovePlayer_Struct passthrough. RoF2: 0x4865. | |
| `OP_SharedTaskMakeLeader` | 🟢 Verified | TOB: 0x5ECA. C→S send at sub_14022EF10 (0x14022EF10, /taskmakeleader cmd) and CTaskWnd::WndNotification (0x1405166E0, GUI). 72-byte SharedTaskMakeLeader_Struct passthrough. field1/field2 always 0. RoF2: 0x37F2. | |
| `OP_SharedTaskMemberInvite` | 🔴 Not-Set | | |
| `OP_SharedTaskInvite` | 🟠 Missing | | |
| `OP_SharedTaskInviteResponse` | 🟠 Missing | | |
| `OP_SharedTaskAcceptNew` | 🟠 Missing | | |
| `OP_SharedTaskMemberChange` | 🟠 Missing | | |
| `OP_SharedTaskPlayerList` | 🟠 Missing | | |
| `OP_SharedTaskSelectWindow` | 🟠 Missing | | |
| `OP_SharedTaskQuit` | 🟠 Missing | | |
| `OP_TaskTimers` | 🟠 Missing | | |
| `OP_SharedTaskInvite` | 🟢 Verified | TOB: 0x31EA → cmp-dispatch @ 0x1401f36dc → sub_140182B30 case 12778. Stores invite_id, shows popup dialog (token 8934). Passthrough. RoF2: 0x3444. | |
| `OP_SharedTaskInviteResponse` | 🟢 Verified | TOB: 0x3159. C→S send in CTaskManager::DialogResponse (0x140182400) when dialog_id==0x31EA. 12-byte SharedTaskInviteResponse_Struct passthrough: {0, invite_id, accepted, pad[3]}. RoF2: 0x7582. | |
| `OP_SharedTaskAcceptNew` | 🟢 Verified | Client→Server. Sent from CTaskSelectWnd::WndNotification @ 0x1405100a0 (TOB 0x5274). 106-byte packet; first 20 bytes map to SharedTaskAccept_Struct correctly. No encoder/decoder. Passthrough correct. | |
| `OP_SharedTaskMemberChange` | 🟢 Verified | TOB: 0x7DCA → cmp-dispatch @ 0x1401f41c6 → sub_140182B30 case 32202 → sub_140183830: checks byte[8] flag, displays token 8549/8550. Passthrough. RoF2: 0x0119. | |
| `OP_SharedTaskPlayerList` | 🟢 Verified | C→S passthrough only. Send fn `sub_14022EE50` @ `0x14022EE50` sends opcode `0x01AB` + 8 zero bytes (10 bytes total). Server ignores payload; no encoder/decoder needed. | |
| `OP_SharedTaskSelectWindow` | 🟢 Verified | TOB: 0x233D → cmp-dispatch @ 0x1401F34C3 → direct call sub_14050F970(CTaskSelectWnd) + vtable+0x1C0 show. S→C. RoF2: 0x48A2. ENCODE_FORWARD(OP_TaskSelectWindow): same handler, same dropped fields. | |
| `OP_SharedTaskQuit` | 🟢 Verified | C→S passthrough only. Send fn `sub_14022F150` @ `0x14022F150` sends opcode `0x455A` + 14-byte payload (ignored by server). Server calls `CancelTask`. No encoder/decoder needed. | |
| `OP_TaskTimers` | 🟢 Verified | C→S passthrough only. Send fn `sub_14022F0A0` @ `0x14022F0A0` sends opcode `0x0975`, 2-byte packet (opcode only). Server calls `GetTaskState()->ListTaskTimers`. No encoder/decoder needed. | |
| `OP_Shielding` | 🟠 Missing | | |
| `OP_ShopDelItem` | 🟢 Verified | Passthrough. Handler `sub_14020FA30`@`0x14020FA30``sub_140476CF0`@`0x140476CF0`. Client reads no payload fields; packet arrival triggers merchant window refresh only. Dispatched via cmp/jz sub-base. | |
| `OP_ShopEnd` | 🟢 Verified | Passthrough. S→C: inline case at 0x1401f6ff5; no body read, calls g_pMerchantWnd vtable[0x138](true) to close window. C→S: AboutToHide sends 8B (NPC spawn_id+player spawn_id); server uses INr (raw). | |
@@ -562,13 +562,13 @@ Below is a status list for the 450 opcodes we currently use on the server for th
| `OP_TargetHoTT` | 🟠 Missing | | |
| `OP_TargetMouse` | 🟢 Verified | Passthrough. C→S only. Sends `uint32 new_target` (spawn_id from `[g_pTargetPlayer+0x168]`, 0 to un-target). 3 send sites: DoPassageOfTime, CTargetWnd ctor, CTargetWnd::Init. Matches `ClientTarget_Struct`. | |
| `OP_TargetReject` | 🔴 Not-Set | | |
| `OP_TaskActivity` | 🟠 Missing | | |
| `OP_TaskActivityComplete` | 🟠 Missing | | |
| `OP_TaskDescription` | 🟠 Missing | | |
| `OP_TaskHistoryReply` | 🟠 Missing | | |
| `OP_TaskHistoryRequest` | 🟠 Missing | | |
| `OP_TaskRequestTimer` | 🟠 Missing | | |
| `OP_TaskSelectWindow` | 🟠 Missing | | |
| `OP_TaskActivity` | 🟢 Verified | TOB: 0x0B85 → sub_140182B30 case 2949 → CTaskManager::UpdateTaskElement. ENCODE added: strips WriteInt32(0) req_type, converts zones to length-prefixed, adds empty string for new TOB field. | |
| `OP_TaskActivityComplete` | 🟢 Verified | 0x131A → sub_140182B30 case 4890 @ 0x1401e7845. S→C only. Passthrough correct; struct unchanged (6×uint32=24B). Broadcasts task complete/fail text or stage-complete string. | |
| `OP_TaskDescription` | 🟢 Verified | 0x7F50 @ CTaskManager::UpdateTask(0x140184600); no dur_code; all strings length-prefixed; was crashing client with null-terminated WriteString | |
| `OP_TaskHistoryReply` | 🟢 Verified | TOB=0x50A3. S→C. Handler: sub_1401841E0 @ 0x1401841E0 via sub_140182B30 case 0x50A3. TOB wire format differs from RoF2: 5 null-term strings + 5 uint32s per activity (vs. RoF2 length-prefixed item_list + zone strings). ENCODE rewritten; uint32 field order (wire[3-6]) and extra strings (wire[8/11]) need live testing. | |
| `OP_TaskHistoryRequest` | 🟢 Verified | TOB=0x27D5. C→S passthrough. Send @ 0x1405168B9 in CTaskWnd::WndNotification. Wire: uint32 CurSel (6-byte packet). CTaskManager::GetQuestHistoryEntry present in TOB; feature not removed. No DECODE needed. | |
| `OP_TaskRequestTimer` | 🟢 Verified | 0x2C99 @ sub_140182B30 case 11417; two-level dispatch via CTaskManager; stores ms cooldown as abs deadline on LocalPC; passthrough only | |
| `OP_TaskSelectWindow` | 🟢 Verified | TOB: 0x0B2B → sub_140182B30 case 2859 → sub_14050F970(CTaskSelectWnd) + vtable+448 show. S→C. RoF2: 0x705B. ENCODE: drop duration_code per-task, drop request_type per-element. | |
| `OP_Taunt` | 🟢 Verified | C→S passthrough. Client sends target spawn_id (uint32 at [g_pTargetPlayer+0x168]) matching ClientTarget_Struct. Send @ sub_140102DF0 (0x140102DF0). Pre-send: range/LOS/inanimate checks. | |
| `OP_TestBuff` | 🟠 Missing | | |
| `OP_TGB` | 🟠 Missing | | |