### Status Below is a status list for the 450 opcodes we currently use on the server for the TOB client. Currently uses 3 status levels (let me know if we should do more): - πŸ”΄ Not-Set (Opcode not set in the patch file) - 🟠 Missing (Opcode is 0x0000 in TOB patch but has a known value in RoF2 β€” needs investigation) - 🟑 Unverified (Opcode set but structure hasn't been verified as completely working) - 🟒 Verified (Opcode set and structure is working) ### World/Zone Opcode Implementation Status | Opcode | Status | Notes | Working On | |:----------------------------------|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------| | `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_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 | | | | `OP_AddNimbusEffect` | 🟒 Verified | Serverβ†’Client only. Dispatched via `cmp @ 0x1401F3C89` β†’ case block `0x1401F8C36`. Case block extracts spawnid [+0] and nimbus_effect [+4] as dwords, calls `ActivateStateFlavorSpellParticleEffect` @ `0x1401E2060`. Wire layout matches `RemoveNimbusEffect_Struct` exactly. Passthrough correct. | | | `OP_AdventureData` | 🟠 Missing | | | | `OP_AdventureDetails` | 🟠 Missing | | | | `OP_AdventureFinish` | 🟠 Missing | | | | `OP_AdventureInfo` | 🟠 Missing | | | | `OP_AdventureInfoRequest` | 🟠 Missing | | | | `OP_AdventureLeaderboardReply` | 🟠 Missing | | | | `OP_AdventureLeaderboardRequest` | 🟠 Missing | | | | `OP_AdventureMerchantPurchase` | 🟠 Missing | | | | `OP_AdventureMerchantRequest` | 🟠 Missing | | | | `OP_AdventureMerchantResponse` | 🟠 Missing | | | | `OP_AdventureMerchantSell` | 🟠 Missing | | | | `OP_AdventurePointsUpdate` | 🟠 Missing | | | | `OP_AdventureRequest` | 🟠 Missing | | | | `OP_AdventureStatsReply` | 🟠 Missing | | | | `OP_AdventureStatsRequest` | 🟠 Missing | | | | `OP_AdventureUpdate` | 🟠 Missing | | | | `OP_AggroMeterLockTarget` | 🟠 Missing | | | | `OP_AggroMeterTargetInfo` | 🟠 Missing | | | | `OP_AggroMeterUpdate` | 🟠 Missing | | | | `OP_AltCurrency` | 🟠 Missing | | | | `OP_AltCurrencyMerchantReply` | 🟠 Missing | | | | `OP_AltCurrencyMerchantRequest` | 🟠 Missing | | | | `OP_AltCurrencyPurchase` | 🟠 Missing | | | | `OP_AltCurrencyReclaim` | 🟠 Missing | | | | `OP_AltCurrencySell` | 🟠 Missing | | | | `OP_AltCurrencySellSelection` | 🟠 Missing | | | | `OP_Animation` | 🟒 Verified | Inline case block @ `0x1401f7ab2` (cmp-dispatch). 4-byte struct verified field-by-field. Encoder/decoder correctly handle `action`/`speed` field-order swap between server and TOB structs. | | | `OP_AnnoyingZoneUnknown` | πŸ”΄ Not-Set | | | | `OP_ApplyPoison` | 🟒 Verified | Handler `msg_apply_poison` @ `0x140208810`. Fixed: struct changed from `TypelessInventorySlot_Struct` (8B) to `InventorySlot_Struct` (12B); slot fns updated to `ServerToTOBSlot`/`TOBToServerSlot`. | | | `OP_ApproveName` | 🟒 Verified | Bidirectional. Sβ†’C: 1-byte response code, `HandleNameApprovalResponse` @ `0x14039bff0` (26 cases). Cβ†’S: decoder maps name/race_id/class_id; deity_id+heroic_type dropped (TODO, enhancement only). | | | `OP_ApproveWorld` | 🟠 Missing | | | | `OP_ApproveZone` | πŸ”΄ Not-Set | | | | `OP_Assist` | 🟒 Verified | Inline case block @ 0x1401EF76D. Reads entity_id (dword +0), sets g_pTargetPlayer; triggers SetAutoAttack if attack_on_assist set. No encoder/decoder needed. | | | `OP_AssistGroup` | 🟒 Verified | Passthrough. EntityId_Struct (4B uint32 entity_id). Sβ†’C inline case @ 0x1401ef76d (Pattern B): lookup player, set target, optional auto-attack. Cβ†’S via do_assist() @ 0x140223710 (/assist group only). | | | `OP_AugmentInfo` | 🟒 Verified | Bidirectional. Encoder: itemid/window/augment_info[64] ok; TOB-extra unknown072 (+0x48) and unknown076 (+0x4C) not set. S->C inline @ 0x1401EFB0D. C->S CItemDisplayWnd::SetItem @ 0x1404314E0. | | | `OP_AugmentItem` | 🟒 Verified | Cβ†’S only. 4 send sites: InsertAugmentRequest, RemoveAugmentRequest, SwapAugmentRequest, DialogResponse. 40-byte TOB struct (InventorySlot_Struct slots) decoded correctly via TOBToServerSlot. | | | `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_Bandolier` | 🟠 Missing | | | | `OP_BankerChange` | 🟒 Verified | Inline case block @ 0x1401e6d98. Bank fields (0x10–0x1C) confirmed correct under passthrough; SetBankPlatinum/Gold/Silver/Copper called at matching offsets. No encoder needed. Cβ†’S: header-only click. | | | `OP_Barter` | 🟠 Missing | | | | `OP_Bazaar` | πŸ”΄ Not-Set | | | | `OP_BazaarInspect` | πŸ”΄ Not-Set | | | | `OP_BazaarSearch` | 🟠 Missing | | | | `OP_BecomeCorpse` | πŸ”΄ Not-Set | | | | `OP_BecomeTrader` | 🟠 Missing | | | | `OP_Begging` | 🟒 Verified | Encoder correct. Result cast uint32β†’uint8 (values 0–4). StringSize=0 and Lucky=0 hardcoded (no server struct fields). Handler sub_1402088C0 @ 0x1402088c0; cmp-dispatch at 0x1401f346a. No decoder (passthrough). | | | `OP_BeginCast` | 🟒 Verified | Handler: CEverQuest::StartCasting@0x140293100. Direct 15-byte memcpy into local struct. TOB struct reorders fields (spell_id int32 first) vs server. Encoder correctly maps all fields; unknown0e hardcoded 1 (matches live). | | | `OP_Bind_Wound` | 🟒 Verified | Passthrough via tob_ops.h. Client sends 8-byte BindWound_Struct (target field [r14+0x168] β†’ to+unknown2, type+unknown6 = 0). Sβ†’C handler @ 0x1401ef3f3 (ja-dispatch, inline Pattern B). Cβ†’S send @ 0x140101c99 in sub_140101A90. Struct matches server struct exactly. | | | `OP_BlockedBuffs` | 🟒 Verified | Bidirectional. Dynamic-length wire (uint32 count + int32[count] + uint8 Pet + uint8 Init). ENCODE/DECODE correct. Case block @ `0x1401f1dac`, Pattern D (inline CUnSerializeBuffer β†’ sub_140202750). 4 Cβ†’S send sites. | | | `OP_BoardBoat` | 🟒 Verified | C->S only. Passthrough. Client sends null-terminated boat name string (6-64 bytes). Send @ DoPassageOfTime 0x1400ebf30. Server reads pBuffer directly via memcpy. | | | `OP_BookButton` | 🟒 Verified | C->S only. Added DECODE + TOB struct (16-byte wire: +0 int16 invslot, +4 int16 unknown, +8 int32 target_id). Was broken (size mismatch 16 vs 6); scribing from book window now functional. | | | `OP_BuffDefinition` | 🟒 Verified | Bidirectional. Sβ†’C: EQAffectPacket_Struct (168B), inline case 0x1401e8994. Cβ†’S: added DECODE to tob.cpp/tob_ops.h mapping EQAffectPacket_Structβ†’SpellBuffPacket_Struct; fixes buff click-off size mismatch.| | | `OP_BuffRemoveRequest` | 🟒 Verified | Cβ†’S only. Two send sites: `RemoveBuffEffect` @ `0x1402ec560` (char buffs), `RemovePetEffect` @ `0x1402ec9c0` (pet buffs). Decoder correctly applies `TOBToServerBuffSlot` on SlotID; EntityID passthrough. | | | `OP_Bug` | 🟒 Verified | Cβ†’S passthrough: `sub_140391580` @ `0x140391580` sends exact `BugReport_Struct` (8740B); server size-checks before cast. Sβ†’C: case `0x1401f2d5e` (cmp/ja dispatch) reads one length-prefixed URL string via CUnSerializeBuffer; handler `sub_140391470` shows popup + LaunchWebPage; EQEmu never sends Sβ†’C so no encoder needed. | | | `OP_BuyerItems` | 🟠 Missing | | | | `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_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))`. | | | `OP_ChangeSize` | 🟒 Verified | Inline Pattern B @ `0x1401f20d4`; calls `ChangeHeight` @ `0x14030ffc0`; bidirectional β€” client sends via `/changesize` GM cmd (`sub_140234D90` @ `0x140234d90`); passthrough correct, layouts match. | | | `OP_ChannelMessage` | 🟒 Verified | Fixed decoder: `emu->sender` now uses `Sender` not `Target` (tob.cpp:3669). Encoder correct. Handler @ `0x1401f0875` (cmp-dispatch), UnSerialize @ `0x1406a6c70`. Pattern D (CommunicationManagerMessage). | | | `OP_ChangePetName` | πŸ”΄ Not-Set | | | | `OP_CharacterCreate` | 🟒 Verified | Cβ†’S only. Handler sub_14039B900 @ 0x14039b900 (738 bytes). TOB struct 168 bytes with 72-byte padding prefix. All 23 server fields verified correct. heroic_type at +0xa4 not in server struct (existing TODO). | | | `OP_CharacterCreateRequest` | 🟒 Verified | Bidirectional. Sβ†’C: handler `HandleStartingLocationResponse` @ `0x14039c5a0`, cmp/jz dispatch @ `0x1401e5987`. Encoder widens `ExpansionRequired` uint32β†’uint64. Cβ†’S: empty trigger, no decoder needed. | | | `OP_CharInventory` | 🟒 Verified | Handler: msgCompItems @ 0x1402051b0; shared with OP_BankItems; cmp-dispatch @ 0x1401e4679; client sends zero-byte ACK (no decoder needed) | | | `OP_Charm` | 🟒 Verified | Handler: sub_140217E40 @ 0x140217E40; cmp-dispatch @ 0x1401e4a43; TOB wire 13B (owner_id,pet_id,charmer_id[TOB-only +0x08 set to 0],command[uint8 at +0x0C]); encoder added; release(0) was ok, make-pet(1) was broken | | | `OP_ChatMessage` | πŸ”΄ Not-Set | | | | `OP_ClearAA` | 🟒 Verified | Zero-payload trigger; case @ 0x1401E83CD calls CAltAdvManager::Reset() (0x1401A9DF0) with no packet fields read. Passthrough correct, no struct. | | | `OP_ClearBlockedBuffs` | 🟒 Verified | Passthrough, no encode/decode. 1-byte packet: `uint8 pet`. Cβ†’S: `/blockspell clear`, hton@0x14023053a in sub_140230370. Sβ†’C: QueuePacket echo β†’ msg_blocked_spells_clear@0x140209a40 clears INI slots. | | | `OP_ClearLeadershipAbilities` | 🟠 Missing | | | | `OP_ClearNPCMarks` | 🟠 Missing | | | | `OP_ClearObject` | 🟒 Verified | Passthrough. Handler `msg_clear_world_con` @ `0x14020a520` (Pattern A). Server always sends Clear=1 β†’ ClearWorldContainerItems(). Struct wire-compatible. | | | `OP_ClearSurname` | 🟠 Missing | | | | `OP_ClickDoor` | 🟒 Verified | Cβ†’S only. Send @ EQSwitch::UseSwitch 0x140260da0. Added item_id and picklockskill decoding; doorid and player_id were already correct. TOB struct unknowns renamed to match server fields. | | | `OP_ClickObject` | 🟒 Verified | Bidirectional passthrough. Cβ†’S: LMouseUp @ 0x14027b4f0. Sβ†’C: inline Pattern B @ 0x1401f6e8e; body at loc_1401F6EAD reads drop_id(+0) as serial and player_id(+4) to gate pending-counter dec. | | | `OP_ClickObjectAction` | 🟒 Verified | Handler `msg_world_container` @ `0x1402197A0`. Added `OUT(unknown24)` (ItemNumber). Slots hardcoded to 10 by client; `unknown16=0` OK. Cβ†’S opcode-only, no payload (camp cmd + close container). | | | `OP_ClientError` | πŸ”΄ Not-Set | | | | `OP_ClientReady` | 🟒 Verified | Zero-length bidirectional. Sβ†’C @ `0x1401F46BC` (cmp-dispatch); sets ReadyEnterWorld=1. Cβ†’S zero-payload. | | | `OP_ClientTimeStamp` | πŸ”΄ Not-Set | | | | `OP_ClientUpdate` | 🟒 Verified | Bidirectional. Sβ†’C: `ProcessUpdateStats` @ `0x140200010` (Pattern A); spawn_id, vehicle_id, 9 position fields all correct. Cβ†’S: 4 send sites in DoMainLoop/DoTeleportB; decoder correct; pitch not forwarded (no server field). | | | `OP_CloseContainer` | πŸ”΄ Not-Set | | | | `OP_CloseTributeMaster` | πŸ”΄ Not-Set | | | | `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_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). | | | `OP_ConsentResponse` | 🟒 Verified | Passthrough Sβ†’C. Handler `sub_14020A550` @ `0x14020A550` (Pattern A). All 4 struct fields verified: grantname+0x00, ownername+0x40, permission+0x80, zonename+0x81. No encoder/decoder needed. | | | `OP_Consider` | 🟒 Verified | Bidirectional. Sβ†’C handler `CEverQuest::Consider` @ `0x1402687e0`; client reads only targetid (+4), ignores faction/level/HP β€” consider UI uses locally-cached player state. Cβ†’S send @ `0x14021faf0`; sends playerid+targetid only. Dead targets send OP_ConsiderCorpse from same fn. Encoder/decoder correct. | | | `OP_ConsiderCorpse` | 🟒 Verified | Cβ†’S only. `sub_14021FAF0` @ `0x14021faf0`; hton @ `0x14021fe60`. Sent when target spawn-type β‰₯ 2 (corpse). Decoder forwards to OP_Consider; reads playerid + targetid correctly. | | | `OP_Consume` | 🟒 Verified | Cβ†’S only. 4 send sites in DoDrinkEatPoison+sub_1402E1DD0. TOB wire: InventorySlot_Struct(12B)+unknown(-1)+type(0/1)+mode(0/1)=20B. Added DECODE: TOBToServerSlot, modeβ†’auto_consumed, type+1. | | | `OP_ControlBoat` | 🟒 Verified | Passthrough. Inline case block @ 0x1401f0384 (cmp-dispatch). Reads boatId [+0] uint32 + TakeControl [+4] bool. Cβ†’S: 3 send sites in ProcessControls + RightClickedOnPlayer. Struct matches exactly. | | | `OP_CorpseDrag` | 🟒 Verified | Cβ†’S only. Decoder reads two length-prefixed strings β†’ CorpseDrag_Struct. No real Sβ†’C handler (fallback at 0x1401f2dfb). No hton send site found; corpse drag may not be initiated by TOB client. | | | `OP_CorpseDrop` | 🟒 Verified | Cβ†’S only. Passthrough. Client sends null-terminated target name (g_pTargetPlayer+0xB4, max 64 chars) when releasing a dragged corpse. Send @ sub_140172C80 (0x140172C80). No struct in eq_packet_structs.h. | | | `OP_CrashDump` | πŸ”΄ Not-Set | | | | `OP_CrystalCountUpdate` | 🟠 Missing | | | | `OP_CrystalCreate` | 🟠 Missing | | | | `OP_CrystalReclaim` | 🟠 Missing | | | | `OP_CustomTitles` | 🟠 Missing | | | | `OP_Damage` | 🟒 Verified | handler `msg_successful_hit` @ `0x140216190`; TOB 48-byte struct (int64 damage at +0x08, type at +0x28) verified; decoder fixed (added `force` and `hit_pitch`) | | | `OP_Death` | 🟒 Verified | Handler: `CEverQuest::ReportDeath` @ `0x1402866c0` (Pattern A). Fixed: added `OUT(corpseid)` to encoder (client reads +0x08 for `ReportSuccessfulHit` on skill-231 kills). TOB struct is 40 bytes. | | | `OP_DelegateAbility` | 🟠 Missing | | | | `OP_DeleteCharacter` | 🟒 Verified | Cβ†’S only. No Sβ†’C handler. Client sends char[64] name + uint32 padding (always 0) from `sub_1400CF9A0`. World handler `HandleDeleteCharacterPacket` reads `app->pBuffer` as char* directly β€” no struct needed, passthrough correct. | | | `OP_DeleteCharge` | 🟒 Verified | ENCODE_FORWARD(OP_MoveItem). Client handler @ 0x1401eac01 (cmp-dispatch). Calls msg_move_spell_charge @ 0x1402102e0 β€” looks up item by from_slot, applies negative number_in_stack as charge delta. | | | `OP_DeleteItem` | 🟒 Verified | Handler `sub_140204D00` @ `0x140204D00`; cmp-dispatch Sβ†’C; client reads from_slot+number_in_stack; to_slot sent but not read Sβ†’C; Cβ†’S always sends to_slot=-1 (trash); encoder/decoder correct. | | | `OP_DeletePetition` | πŸ”΄ Not-Set | | | | `OP_DeleteSpawn` | 🟒 Verified | Struct correct (5 bytes). Byte 4 (Decay): 0=deferred decay animation path (sets field_133Ch=1 on corpse-type spawns), 1=immediate PrepForDestroyPlayer. Also gates duel-end logic. | | | `OP_DeleteSpell` | 🟒 Verified | Passthrough. Sβ†’C @ 0x1401f097e β†’ DeleteSpellFromBook @ 0x1404f26a0. Cβ†’S: DialogResponse @ 0x1404f27b0. | | | `OP_DenyResponse` | 🟒 Verified | Sβ†’C only. Handler sub_14020A550 @ 0x14020a550. Corpse drag consent response: char[64] requester (+0), char[64] owner (+0x40), bool granted (+0x80), zone name (+0x81). Client picks message by name match. | | | `OP_Disarm` | 🟒 Verified | Clientβ†’Server only. 16-byte struct (source/target/skill/unknown) matches Disarm_Struct exactly. No encoder/decoder needed; passthrough is correct. | | | `OP_DisarmTraps` | 🟒 Verified | Cβ†’S only. 2-byte opcode, no payload. Sent by `CharacterZoneClient::UseSkill` (skill 17) when target is a valid NPC. Passthrough β€” no struct, no decoder needed. hton @ `0x140101740`. | | | `OP_DisciplineTimer` | 🟒 Verified | Sβ†’C. Inline handler @ 0x1401f4b5d (cmp-dispatch secondary table). Calls SetMeleeSpellReuseTimer(TimerID,Duration,computed). Encoder sends 16-byte TOB struct with ServerTime for client latency-adjust calculation. | | | `OP_DisciplineUpdate` | 🟒 Verified | Sβ†’C. Encoder sends 1200-byte packet (300Γ—uint32); client at 0x1401e885b validates size via GetCombatAbilitySize()=1200, then rep movsb into CurrentProfile+0x4700. Server fills entries 0–99, zeros 100–299. | | | `OP_DiscordMerchantInventory` | πŸ”΄ Not-Set | | | | `OP_DoGroupLeadershipAbility` | 🟠 Missing | | | | `OP_DuelDecline` | 🟠 Missing | | | | `OP_DuelAccept` | 🟠 Missing | | | | `OP_DumpName` | πŸ”΄ Not-Set | | | | `OP_Dye` | 🟠 Missing | | | | `OP_DynamicWall` | πŸ”΄ Not-Set | | | | `OP_DzAddPlayer` | 🟠 Missing | | | | `OP_DzChooseZone` | 🟠 Missing | | | | `OP_DzChooseZoneReply` | 🟠 Missing | | | | `OP_DzCompass` | 🟠 Missing | | | | `OP_DzExpeditionEndsWarning` | 🟠 Missing | | | | `OP_DzExpeditionInfo` | 🟠 Missing | | | | `OP_DzExpeditionInvite` | 🟠 Missing | | | | `OP_DzExpeditionInviteResponse` | 🟠 Missing | | | | `OP_DzExpeditionLockoutTimers` | 🟠 Missing | | | | `OP_DzListTimers` | 🟠 Missing | | | | `OP_DzMakeLeader` | 🟠 Missing | | | | `OP_DzMemberList` | 🟠 Missing | | | | `OP_DzMemberListName` | 🟠 Missing | | | | `OP_DzMemberListStatus` | 🟠 Missing | | | | `OP_DzPlayerList` | 🟠 Missing | | | | `OP_DzQuit` | 🟠 Missing | | | | `OP_DzRemovePlayer` | 🟠 Missing | | | | `OP_DzSetLeaderName` | 🟠 Missing | | | | `OP_DzSwapPlayer` | 🟠 Missing | | | | `OP_Emote` | 🟠 Missing | | | | `OP_EndLootRequest` | 🟒 Verified | Bidirectional passthrough. Sβ†’C: client calls CLootWnd::EndLootingSession @ 0x1404426e0, no body read. Cβ†’S: 4-byte body = corpse entity ID (uint32); server reads low 2 bytes as uint16 spawn ID. | | | `OP_EnduranceUpdate` | 🟠 Missing | | | | `OP_EnterChat` | πŸ”΄ Not-Set | | | | `OP_EnterWorld` | 🟒 Verified | Cβ†’S only. Decoder copies name correctly but hardcodes tutorial=0, return_home=0. TOB sends zoneID (EverQuest_EnterZoneReason; -1=last zone) instead of flags. Enter Tutorial/Return Home buttons broken. | | | `OP_EnvDamage` | 🟒 Verified | Cβ†’S only. Send @ 0x1400E6012 (sub_1400E5DC0). TOB wire=58 bytes. Decoder added: entity_id=wire+0 (u16β†’u32), damage=wire+16 (i64β†’u32), dmgtype=wire+56. Needs in-game test (fall/drown/lava). | | | `OP_EvolveItem` | πŸ”΄ Not-Set | | | | `OP_ExpansionInfo` | 🟒 Verified | Handler `msg_expansions` @ 0x14020B970 (12 bytes). Pattern A. Client reads uint64 at offset 0x40; 64-byte Unknown000 prefix zeroed by alloc. OUT(Expansions) correct (u32β†’u64 zero-extend). | | | `OP_ExpUpdate` | 🟒 Verified | Handler sub_14020B980 @ 0x14020B980 (95 bytes); Pattern A; encoder converts exp 0–330β†’0–100000; unknown=0 (no tip window); aaxp intentionally omitted (handled via OP_AAExpUpdate). | | | `OP_FaceChange` | 🟠 Missing | | | | `OP_Feedback` | 🟠 Missing | | | | `OP_FeignDeath` | 🟒 Verified | Passthrough. No struct defined. Wire: spawn_id(4)+last_hitter(4)+fd(1). Inline case block @ 0x1401f55eb; Cβ†’S send in UseSkill::0x19 @ 0x140101388. fd always 0 from client; Sβ†’C checks nonzero for name-lookup. | | | `OP_FellowshipUpdate` | πŸ”΄ Not-Set | | | | `OP_FindPersonReply` | 🟠 Missing | | | | `OP_FindPersonRequest` | 🟠 Missing | | | | `OP_FinishTrade` | 🟒 Verified | Passthrough, zero-payload notification. Handler `msg_do_trade` @ `0x14020b4b0` reads no packet data; client finalises trade UI on receipt. No struct. | | | `OP_FinishWindow` | 🟒 Verified | Zero-payload Sβ†’C notification. Handler @ 0x1401f4ae1 (ja-dispatch; missed by validate_opcode.py). Calls DecItemPending() β€” decrements pending item window counter. No struct needed. | | | `OP_FinishWindow2` | 🟒 Verified | Zero-payload Sβ†’C signal, always paired with OP_FinishWindow in trade/object-close flows. No struct. Passthrough correct. TOB client has no handler β€” packet silently discarded on receipt (harmless). | | | `OP_Fishing` | 🟒 Verified | Cβ†’S only. Zero-payload cast signal (opcode only, no struct). Client validates pole/bait/land/level before sending. Send @ sub_140102510+0x140102510. Passthrough β€” no decoder needed. | | | `OP_Fling` | 🟒 Verified | Encoder added. TOB wire layout differs from server fling_struct β€” fields reordered + extra radius (+16, set 0.0f) and padding (+20). Handler sub_1403135C0 @ 0x1403135c0 (Pattern A). fall_damage bit semantics TBD (see packet_analysis/OP_Fling.md). | | | `OP_FloatListThing` | 🟒 Verified | Cβ†’S only. Movement History telemetry; EQEmu ignores it, no decoder needed. `PlayerClient::SendMovementHistory` @ `0x1402FFAD0` (0x1DF bytes). Throttled to 1000ms; payload via `CMovementHistory::BuildPacket`. | | | `OP_Forage` | 🟒 Verified | Cβ†’S only; zero-payload forage trigger (skill 27). hton @ 0x140101740 in UseSkill. No Sβ†’C handler in HWM. | | | `OP_ForceFindPerson` | πŸ”΄ Not-Set | | | | `OP_FormattedMessage` | 🟒 Verified | Handler: msgTokenTextParam @ 0x140207ce0 (Pattern D, inline CUnSerializeBuffer). No encoder needed β€” MessageComponent::Formatted() (tob.cpp:5795) builds the TOB wire format directly (uint32=0 + uint8 from_world + uint32 string_id + uint32 color + 9x WriteLengthString). Spell links handled via ServerToTOBConvertLinks before serialization. | | | `OP_FriendsWho` | 🟒 Verified | Cβ†’S only; sends comma-separated friends string (flag+'0'/'1' + buddy names). No Sβ†’C handler. Zone reads as raw char*. hton @ 0x1402992d9 in CEverQuest::Who (0x140298b70). Passthrough correct. | | | `OP_GetGuildMOTD` | 🟠 Missing | | | | `OP_GetGuildMOTDReply` | 🟠 Missing | | | | `OP_GetGuildsList` | πŸ”΄ Not-Set | | | | `OP_GiveMoney` | πŸ”΄ Not-Set | | | | `OP_GMApproval` | 🟠 Missing | | | | `OP_GMBecomeNPC` | 🟠 Missing | | | | `OP_GMDelCorpse` | 🟠 Missing | | | | `OP_GMEmoteWorld` | 🟠 Missing | | | | `OP_GMEmoteZone` | 🟠 Missing | | | | `OP_GMEndTraining` | 🟒 Verified | Cβ†’S only. Passthrough. CTrainWnd::AboutToHide @ 0x140529b30. Payload: npcid+playerid = GMTrainEnd_Struct exactly. | | | `OP_GMEndTrainingResponse` | πŸ”΄ Not-Set | | | | `OP_GMFind` | 🟠 Missing | | | | `OP_GMGoto` | 🟠 Missing | | | | `OP_GMHideMe` | 🟠 Missing | | | | `OP_GMKick` | 🟠 Missing | | | | `OP_GMKill` | 🟠 Missing | | | | `OP_GMLastName` | 🟠 Missing | | | | `OP_GMNameChange` | 🟠 Missing | | | | `OP_GMSearchCorpse` | 🟠 Missing | | | | `OP_GMServers` | 🟠 Missing | | | | `OP_GMSummon` | 🟠 Missing | | | | `OP_GMToggle` | 🟠 Missing | | | | `OP_GMTraining` | 🟒 Verified | Bidirectional. Sβ†’C handler `msg_req_guildmaster` @ `0x140212e20` (Pattern A). Reads npcid[+0], flag[+0x198], passes skills[+8] and languages[+0x199] to CTrainWnd::SetGMData. Encoder/decoder correct. | | | `OP_GMTrainSkill` | 🟒 Verified | Cβ†’S only. Send fn `sub_14052ADE0` @ `0x14052ade0`. Wire: uint32 npcid, skillbank, skill_id. Passthrough. | | | `OP_GMTrainSkillConfirm` | 🟒 Verified | Encoder maps all 4 fields correctly. Inline handler @ cmp-dispatch 0x1401f37b4β†’0x1401f98c5. SkillID≀99=normal skill, >99=language (GetLangDesc). Unknown073[3] trailing padding not read by client. | | | `OP_GMZoneRequest` | 🟠 Missing | | | | `OP_GMZoneRequest2` | 🟠 Missing | | | | `OP_GroundSpawn` | 🟒 Verified | Sβ†’C encoder verified. Pattern D: HWM inline alloc EQGroundItem, CSB in sub_14021EA40 @ 0x14021EA40. 13 wire fields match client reads. Cβ†’S is zero-byte signal (no decoder needed). | | | `OP_GroupAcknowledge` | 🟠 Missing | | | | `OP_GroupCancelInvite` | 🟠 Missing | | | | `OP_GroupDelete` | 🟠 Missing | | | | `OP_GroupDisband` | 🟒 Verified | Cβ†’S only; `CEverQuest::Disband` @ `0x14026c220`; decoder correctly copies name1/name2 from 154-byte TOB struct (26 extra bytes zeroed/ignored); no Sβ†’C handler. | | | `OP_GroupDisbandOther` | 🟠 Missing | | | | `OP_GroupDisbandYou` | 🟠 Missing | | | | `OP_GroupFollow` | 🟠 Missing | | | | `OP_GroupFollow2` | 🟠 Missing | | | | `OP_GroupInvite` | 🟒 Verified | Handler sub_14029A040@0x14029A040 (PatternA). Fixed GroupGeneric_Struct to 168B (was 154); added ENCODE using SETUP_DIRECT_ENCODE. Client reads GroupRequestId at offset 168 (1B past buf) β€” server has no equivalent field, reads 0. | | | `OP_GroupInvite2` | πŸ”΄ Not-Set | | | | `OP_GroupLeaderChange` | 🟠 Missing | | | | `OP_GroupLeadershipAAUpdate` | 🟠 Missing | | | | `OP_GroupMakeLeader` | 🟠 Missing | | | | `OP_GroupMentor` | 🟠 Missing | | | | `OP_GroupRoles` | 🟠 Missing | | | | `OP_GroupUpdate` | 🟠 Missing | | | | `OP_GroupUpdateB` | 🟠 Missing | | | | `OP_GroupUpdateLeaderAA` | πŸ”΄ Not-Set | | | | `OP_GuildBank` | 🟠 Missing | | | | `OP_GuildBankItemList` | 🟠 Missing | | | | `OP_GuildCreate` | 🟠 Missing | | | | `OP_GuildDelete` | 🟠 Missing | | | | `OP_GuildDeleteGuild` | 🟠 Missing | | | | `OP_GuildDemote` | 🟠 Missing | | | | `OP_GuildInvite` | 🟠 Missing | | | | `OP_GuildInviteAccept` | 🟠 Missing | | | | `OP_GuildLeader` | 🟠 Missing | | | | `OP_GuildManageAdd` | πŸ”΄ Not-Set | | | | `OP_GuildManageBanker` | 🟠 Missing | | | | `OP_GuildManageRemove` | πŸ”΄ Not-Set | | | | `OP_GuildManageStatus` | πŸ”΄ Not-Set | | | | `OP_GuildMemberLevelUpdate` | πŸ”΄ Not-Set | | | | `OP_GuildMemberList` | 🟠 Missing | | | | `OP_GuildMemberUpdate` | 🟠 Missing | | | | `OP_GuildMemberLevel` | 🟠 Missing | | | | `OP_GuildMemberRankAltBanker` | 🟠 Missing | | | | `OP_GuildMemberPublicNote` | 🟠 Missing | | | | `OP_GuildMemberAdd` | 🟠 Missing | | | | `OP_GuildMemberRename` | 🟠 Missing | | | | `OP_GuildMemberDelete` | 🟠 Missing | | | | `OP_GuildMemberDetails` | 🟠 Missing | | | | `OP_GuildRenameGuild` | 🟠 Missing | | | | `OP_GuildMOTD` | 🟠 Missing | | | | `OP_GuildPeace` | 🟠 Missing | | | | `OP_GuildPromote` | 🟠 Missing | | | | `OP_GuildPublicNote` | 🟠 Missing | | | | `OP_GuildRemove` | 🟠 Missing | | | | `OP_GuildSelectTribute` | 🟠 Missing | | | | `OP_GuildModifyBenefits` | 🟠 Missing | | | | `OP_GuildTributeToggleReq` | 🟠 Missing | | | | `OP_GuildTributeToggleReply` | 🟠 Missing | | | | `OP_GuildOpenGuildWindow` | 🟠 Missing | | | | `OP_GuildOptInOut` | 🟠 Missing | | | | `OP_GuildSaveActiveTributes` | 🟠 Missing | | | | `OP_GuildSendActiveTributes` | 🟠 Missing | | | | `OP_GuildTributeFavorAndTimer` | 🟠 Missing | | | | `OP_GuildsList` | 🟠 Missing | | | | `OP_GuildStatus` | 🟠 Missing | | | | `OP_GuildTributeInfo` | πŸ”΄ Not-Set | | | | `OP_GuildUpdate` | 🟠 Missing | | | | `OP_GuildTributeDonateItem` | 🟠 Missing | | | | `OP_GuildTributeDonatePlat` | 🟠 Missing | | | | `OP_GuildWar` | 🟠 Missing | | | | `OP_Heartbeat` | πŸ”΄ Not-Set | | | | `OP_Hide` | 🟒 Verified | Cβ†’S only. 4-byte payload: uint32 (1=movement check passed, requesting hide roll; 0=cancel). 3 send sites: sub_140102A50 @ 0x140102A50, CancelHide @ 0x140267670, CancelSneakHide @ 0x1402678E0. Fixed: data==0 returns early, data==1 falls through to full server hide roll. | | | `OP_HideCorpse` | 🟒 Verified | Cβ†’S only passthrough. Send sites: cmd@0x140222bf0, DoMainLoop, loadOptions, ALWAYS-mode@0x140441b70. | | | `OP_HPUpdate` | 🟒 Verified | Sβ†’C only. Cmp-dispatch @ 0x1401f3571 β†’ inline case block 0x1401f4448 (Pattern B). Reads spawn_id(+0,w), cur_hp(+2,q), max_hp(+0xA,q); calls ProcessHitpointMessage@0x1401fefd0. Encoder+struct match. | | | `OP_Illusion` | 🟒 Verified | Sβ†’C: msg_change_form@0x14020a080 (Pattern A); encoder maps all common fields; TOB-only fields (class_, armorProperties, armorTints) zero-init (correct for NPC illusions). Cβ†’S: /becomenpc sends 332-byte TOB struct; no decoder, server gets garbled data past charname β€” GM-only. | | | `OP_IncreaseStats` | 🟒 Verified | Handler sub_140208290 @ 0x140208290 (Pattern A). TOB wire: {uint32 spawn_id, uint32 stat_type 0–6, uint32 value}. Encoder added; spawn_id sourced from unknown13[0..1] stashed by Client::IncStats/SetStats (GetID()). Primary stats only; resists not handled by TOB client. | | | `OP_InitialHPUpdate` | πŸ”΄ Not-Set | | | | `OP_InitialMobHealth` | πŸ”΄ Not-Set | | | | `OP_InspectAnswer` | 🟠 Missing | | | | `OP_InspectBuffs` | 🟠 Missing | | | | `OP_InspectMessageUpdate` | 🟠 Missing | | | | `OP_InspectRequest` | 🟠 Missing | | | | `OP_InstillDoubt` | 🟠 Missing | Was duplicate of OP_Fishing (both 0x3cdb). Fixed: set to 0x0000. IDA confirms 0x3cdb is fishing only (sub_140102510); no Instill Doubt send site found in TOB binary. Real TOB opcode unknown. | | | `OP_InterruptCast` | 🟒 Verified | Sβ†’C passthrough. Handler sub_1401E27C0 @ 0x1401E27C0 (Pattern A). Reads spawnid+4, messageid+4, message[0]+8. messageid used for StringTable lookup + orderedStringExpansion. Struct matches exactly. | | | `OP_InvokeChangePetName` | πŸ”΄ Not-Set | | | | `OP_InvokeChangePetNameImmediate` | πŸ”΄ Not-Set | | | | `OP_InvokeNameChangeImmediate` | πŸ”΄ Not-Set | | | | `OP_InvokeNameChangeLazy` | πŸ”΄ Not-Set | | | | `OP_ItemAdvancedLoreText` | 🟠 Missing | | | | `OP_ItemLinkClick` | 🟠 Missing | | | | `OP_ItemLinkResponse` | 🟠 Missing | | | | `OP_ItemLinkText` | πŸ”΄ Not-Set | | | | `OP_ItemName` | πŸ”΄ Not-Set | | | | `OP_ItemPacket` | 🟒 Verified | Handler @ `0x1401f0bf3` (inline+CSB). Fixed: added `ItemPacketParcel` to `ServerToTOBItemPacketType` (srv 0x73β†’TOB 0x74) and corrected parcel `SerializeItem` to use `pms.slot_id`. Note: client discards note field. | | | `OP_ItemPreview` | 🟠 Missing | | | | `OP_ItemPreviewRequest` | πŸ”΄ Not-Set | | | | `OP_ItemRecastDelay` | 🟒 Verified | Handler @ `0x1401E8638` (inline, Pattern B). Encoder added: InventorySlot_Struct (zeroed, TODO server struct) + recast_delay (+0x0C) + recast_type (+0x10). SetCoreItemRecastTimer fires; per-item timer needs server slot. | | | `OP_ItemVerifyReply` | 🟒 Verified | Handler `0x1401e652c` (inline Pattern B). Encoder added: expands 12β†’20 bytes; adds unknown0 (+0x0C exit gate) and recast_time (+0x10 timestamp, zeroed). Autobook-scribe (spell==0x407) needs server-side recast_time. | | | `OP_ItemVerifyRequest` | 🟒 Verified | Cβ†’S only. TOB sends 16-byte packet (InventorySlot_Struct 12 bytes + target uint32). DECODE added using TOBToServerSlot; tob_structs.h entry added. Matches RoF2 layout with int32 Type instead of int16. | | | `OP_ItemViewUnknown` | 🟠 Missing | | | | `OP_Jump` | 🟒 Verified | Cβ†’S only; 0-byte payload, no struct. Client sends on jump; server deducts endurance (`Handle_OP_Jump`). Passthrough correct. Send @ `0x140272773` in `DoMainLoop`. | | | `OP_KeyRing` | 🟠 Missing | | | | `OP_KickPlayers` | 🟒 Verified | Cβ†’S only (no HWM handler). DialogResponse case 140. Sends full KickPlayers_Struct (72 bytes): char_name[64]+unknown064+kick_expedition+kick_task+padding. Passthrough correct, struct matches exactly. | | | `OP_KnowledgeBase` | πŸ”΄ Not-Set | | | | `OP_LDoNButton` | 🟠 Missing | | | | `OP_LDoNDisarmTraps` | πŸ”΄ Not-Set | | | | `OP_LDoNInspect` | πŸ”΄ Not-Set | | | | `OP_LDoNOpen` | 🟒 Verified | Cβ†’S only. Zero-payload packet (opcode only, no data body). Client sends from `do_open` @ `0x14022b160`; server handler reads no packet data β€” uses `GetTarget()`. No encoder/decoder needed. | | | `OP_LDoNPickLock` | 🟒 Verified | Cβ†’S only. Zero-payload packet (opcode only, no data body). Client sends from `UseSkill` @ `0x140100e60` (case 0x23, skill 35); server handler reads no packet data β€” uses `GetTarget()`. No encoder/decoder needed. | | | `OP_LDoNSenseTraps` | πŸ”΄ Not-Set | Not set in patch_TOB.conf; no server struct or encoder/decoder found. | | | `OP_LeadershipExpToggle` | 🟠 Missing | | | | `OP_LeadershipExpUpdate` | 🟠 Missing | | | | `OP_LeaveAdventure` | 🟠 Missing | | | | `OP_LeaveBoat` | 🟒 Verified | Cβ†’S only. Zero-payload signal packet (no struct). Client sends opcode-only header from DoPassageOfTime @ 0x1400edf50 to notify server of vehicle dismount. No encoder/decoder needed. | | | `OP_LevelAppearance` | 🟒 Verified | Passthrough. Case block @ 0x1401f61ff β†’ UpdateAnimVariation @ 0x1402ff3d0. 5 parm/slot/flag triplets; all offsets match LevelAppearance_Struct exactly. valueNb low-byte-only read is benign. | | | `OP_LevelUpdate` | 🟒 Verified | Passthrough. Handler sub_14020F110 @ 0x14020F110 (Pattern A). All 3 fields (level/level_old/exp) read correctly from wire offsets 0/4/8. No encoder/decoder needed. | | | `OP_LFGAppearance` | πŸ”΄ Not-Set | | | | `OP_LFGCommand` | 🟠 Missing | | | | `OP_LFGGetMatchesRequest` | 🟠 Missing | | | | `OP_LFGGetMatchesResponse` | 🟠 Missing | | | | `OP_LFGResponse` | πŸ”΄ Not-Set | | | | `OP_LFGuild` | 🟠 Missing | | | | `OP_LFPCommand` | 🟠 Missing | | | | `OP_LFPGetMatchesRequest` | 🟠 Missing | | | | `OP_LFPGetMatchesResponse` | 🟠 Missing | | | | `OP_LinkedReuse` | 🟒 Verified | Inline case @ 0x1401f4c23. Added encoder + TOB struct (16 bytes): extra DWORD at +0x04, end_time at +0x08, start_time at +0x0C. Server sent 12 bytes; client read past end β€” reuse timers were corrupted. | | | `OP_LoadSpellSet` | 🟠 Missing | | | | `OP_LocInfo` | πŸ”΄ Not-Set | | | | `OP_LockoutTimerInfo` | πŸ”΄ Not-Set | | | | `OP_Login` | πŸ”΄ Not-Set | | | | `OP_LoginAccepted` | πŸ”΄ Not-Set | | | | `OP_LoginComplete` | πŸ”΄ Not-Set | | | | `OP_LoginExpansionPacketData` | πŸ”΄ Not-Set | | | | `OP_LoginUnknown1` | πŸ”΄ Not-Set | | | | `OP_LoginUnknown2` | πŸ”΄ Not-Set | | | | `OP_Logout` | 🟒 Verified | Cβ†’S passthrough (empty, `INz`). Sβ†’C handler @ `0x1401ea526` reads 2 bools (bool[0]=cancel-camp/AA, bool[1]=exit-confirm) but EQEmu never sends Sβ†’C; uses `OP_LogoutReply` instead. | | | `OP_LogoutReply` | πŸ”΄ Not-Set | | | | `OP_LogServer` | 🟒 Verified | Inline case block @ 0x1401eda66, Pattern B; 1932-byte packet manually assembled; all 23 client-read fields correctly set; dead: worldshortname (+0x15), voicemacros (+0x5F4), tutorial (+0x5F8) | | | `OP_LootComplete` | 🟒 Verified | Sβ†’C only. Zero-payload signal; client calls CLootWnd::EndLootingSession @ 0x1404426e0. No struct, no encoder/decoder needed. Passthrough confirmed. | | | `OP_LootItem` | 🟒 Verified | Bidirectional. Cβ†’S decoder correct. Added Sβ†’C encoder: server 16-byteβ†’TOB 20-byte; slot_id via ServerToTOBCorpseMainSlot; unknown16 (quantity) set to 0 (no server-side quantity field). Handler: `CLootWnd::SlotLooted` @ 0x140443d40. | | | `OP_LootRequest` | 🟒 Verified | Cβ†’S only. Raw uint32 payload (corpse spawn ID at PlayerClient+0x168). No struct, no decoder needed. Server checks app->size == sizeof(uint32) and calls entity_list.GetID(). Passthrough confirmed. | | | `OP_ManaChange` | 🟒 Verified | Sβ†’C handler `msg_stop_casting` @ 0x140215f70 (Pattern A, 531 bytes). Updates mana+endurance, clears gem ETA, optionally stops cast. Encoder correct; keepcasting uint8β†’uint32 safe (client reads byte). Cβ†’S opcode-only (no payload). | | | `OP_ManaUpdate` | 🟠 Missing | | | | `OP_MarkNPC` | 🟠 Missing | | | | `OP_MarkRaidNPC` | 🟠 Missing | | | | `OP_Marquee` | 🟒 Verified | Passthrough Sβ†’C. Inline case 0x1401F00CD reads all 6 uint32 fields (+0x00–+0x14) + msg ptr (+0x18) directly; forwards to CBroadcast::BroadcastString @ 0x1400BCEA0. | | | `OP_MemorizeSpell` | 🟒 Verified | Bidir. Handler sub_14020ECB0 @ 0x14020ecb0 (Pattern A). Switch on scribing -1..4. Encoder/decoder correct; scribing=1 suppress intentional. 6 Cβ†’S send sites confirmed. | | | `OP_Mend` | 🟒 Verified | Cβ†’S only, no payload. UseSkill case 0x20 (Mend/skill 32) @ hton 0x140101740. No struct or decoder needed. | | | `OP_MendHPUpdate` | πŸ”΄ Not-Set | | | | `OP_MercenaryAssign` | πŸ”΄ Not-Set | | | | `OP_MercenaryCommand` | 🟠 Missing | | | | `OP_MercenaryDataRequest` | 🟠 Missing | | | | `OP_MercenaryDataResponse` | 🟠 Missing | | | | `OP_MercenaryDataUpdate` | 🟠 Missing | | | | `OP_MercenaryDataUpdateRequest` | 🟠 Missing | | | | `OP_MercenaryDismiss` | 🟠 Missing | | | | `OP_MercenaryHire` | 🟠 Missing | | | | `OP_MercenarySuspendRequest` | 🟠 Missing | | | | `OP_MercenarySuspendResponse` | 🟠 Missing | | | | `OP_MercenaryTimer` | 🟠 Missing | | | | `OP_MercenaryTimerRequest` | 🟠 Missing | | | | `OP_MercenaryUnknown1` | 🟠 Missing | | | | `OP_MercenaryUnsuspendResponse` | 🟠 Missing | | | | `OP_MerchantBulkItems` | πŸ”΄ Not-Set | | | | `OP_MobEnduranceUpdate` | 🟠 Missing | | | | `OP_MobHealth` | 🟒 Verified | Sβ†’C only. Handler via cmp-dispatch @ `0x1401f43ce` β†’ `ProcessHitpointMessage` @ `0x1401fefd0`. 6-byte packet: int16 spawn_id + uint32 hp%. Encoder correct; max hardcoded 100 at call site. | | | `OP_MobManaUpdate` | 🟠 Missing | | | | `OP_MobRename` | 🟠 Missing | | | | `OP_MobUpdate` | 🟠 Missing | | | | `OP_MoneyOnCorpse` | 🟒 Verified | Handler `sub_140443110` @ `0x140443110`. Pattern B inline; TOB struct (24 B) matches client reads. flags=0 hardcoded (no server field); type 0/1/2 map correctly from emu->response. | | | `OP_MoneyUpdate` | 🟒 Verified | Passthrough. Handler sub_140213940 @ 0x140213940 (Pattern A). All 4 fields (platinum/gold/silver/copper) read directly into LocalPC. Sβ†’C only. | | | `OP_MOTD` | 🟒 Verified | Passthrough. Raw null-terminated string (no struct). Handler sub_140219DA0 @ 0x140219DA0 stores MOTD in EverQuest_motd and calls display update if changed. Client never sends. | | | `OP_MoveCoin` | 🟒 Verified | Cβ†’S only. Passthrough (no encoder/decoder). 2 send sites: CEverQuest::MoveMoney @ 0x14027e000, PcZoneClient::DestroyHeldItemOrMoney @ 0x1402e6a10. No Sβ†’C handler in HWM. 20-byte struct matches. | | | `OP_MoveDoor` | 🟒 Verified | Passthrough. Inline Pattern B @ 0x1401ED4A9. Reads doorid (+0) to look up EQSwitch via sub_14025FE50, then action (+1) β†’ EQSwitch::ChangeState. Struct matches exactly. Sβ†’C only. | | | `OP_MoveItem` | 🟒 Verified | Bidirectional. Encoder/decoder use ServerToTOBSlot/TOBToServerSlot (uint32↔InventorySlot_Struct). Sβ†’C cmp-dispatch @ 0x1401EAE97; normal path calls sub_14020FAF0; invalid to_slot+Type3/4 destroys item via sub_140204D00. 12 Cβ†’S send sites. | | | `OP_MoveMultipleItems` | 🟒 Verified | Bidirectional. Passthrough. Sβ†’C handler sub_1402CD630 @ 0x1402cd630; reads count (+0) then 36-byte MultiMoveItemSub_Struct entries. Cβ†’S send in MultipleItemMoveManager::ProcessMove @ 0x1402cd830. | | | `OP_MoveLogDisregard` | πŸ”΄ Not-Set | | | | `OP_MoveLogRequest` | πŸ”΄ Not-Set | | | | `OP_MultiLineMsg` | πŸ”΄ Not-Set | | | | `OP_NewSpawn` | 🟒 Verified | Deprecated in TOB client β€” 0x053d handler @ 0x1401eedcc calls fdebug("Received deprecated...") only. Encoder forwards to OP_ZoneSpawns which sends OP_ZoneEntry (0x713d). No struct parsing by client. | | | `OP_NewTitlesAvailable` | 🟠 Missing | | | | `OP_NewZone` | 🟒 Verified | Handler: zoneHeader_Deserialize @ 0x140203d30, Pattern D. Fixed npc_aggro_max_dist (was hardcoded 600). All other fields correct. | | | `OP_NPCMoveUpdate` | 🟠 Missing | | | | `OP_OnLevelMessage` | 🟒 Verified | Handler `CServerTextWnd::HandleShowDialogMessage` @ `0x1404ed300`. Pattern D (Hybrid CUnSerializeBuffer). Encoder matches client reads. Fields 9–10 hardcoded 0 (no server struct equivalent); correct. | | | `OP_OpenContainer` | 🟒 Verified | Cβ†’S only. Server handler is empty no-op by design (all clients). Send @ 0x1403bad8d in CContainerMgr::OpenContainer. Sends 12-byte ItemGlobalIndex payload; server ignores contents. | | | `OP_OpenDiscordMerchant` | πŸ”΄ Not-Set | | | | `OP_OpenGuildTributeMaster` | 🟠 Missing | | | | `OP_OpenInventory` | πŸ”΄ Not-Set | | | | `OP_OpenTributeMaster` | 🟠 Missing | | | | `OP_PDeletePetition` | πŸ”΄ Not-Set | | | | `OP_PetCommands` | 🟠 Missing | | | | `OP_PetCommandState` | 🟠 Missing | | | | `OP_PetHoTT` | 🟠 Missing | | | | `OP_Petition` | 🟠 Missing | | | | `OP_PetitionBug` | πŸ”΄ Not-Set | | | | `OP_PetitionCheckIn` | πŸ”΄ Not-Set | | | | `OP_PetitionCheckout` | πŸ”΄ Not-Set | | | | `OP_PetitionCheckout2` | πŸ”΄ Not-Set | | | | `OP_PetitionDelete` | πŸ”΄ Not-Set | | | | `OP_PetitionQue` | πŸ”΄ Not-Set | | | | `OP_PetitionRefresh` | πŸ”΄ Not-Set | | | | `OP_PetitionResolve` | πŸ”΄ Not-Set | | | | `OP_PetitionSearch` | πŸ”΄ Not-Set | | | | `OP_PetitionSearchResults` | πŸ”΄ Not-Set | | | | `OP_PetitionSearchText` | πŸ”΄ Not-Set | | | | `OP_PetitionUnCheckout` | πŸ”΄ Not-Set | | | | `OP_PetitionUpdate` | πŸ”΄ Not-Set | | | | `OP_PickPocket` | 🟒 Verified | Sβ†’C encoder + Cβ†’S decoder via structs::PickPocket_Struct. Handler sub_140215B60@0x140215B60 (Pattern D). Wire: uint32 to/from/myskill, uint8 type, uint32 coin(unaligned@0xD), length-prefixed itemname, uint8 luckily. | | | `OP_PickZone` | πŸ”΄ Not-Set | | | | `OP_PickZoneWindow` | πŸ”΄ Not-Set | | | | `OP_PlayerProfile` | 🟒 Verified | Sβ†’C only. Case block `0x1401f124e` β†’ `sub_1402E01A0` @ `0x1402e01a0`. Decompresses, CRC32-verifies, calls `ClientNetPcData::UnSerialize()`. ~1040-line manual SerializeBuffer encoder. Buffs/armor hardcoded empty; coin written twice. | | | `OP_PlayerStateAdd` | 🟒 Verified | Passthrough. Sβ†’C handler sub_1401FE640 @ 0x1401FE640 (Pattern A): reads spawn_id+0x00 and state+0x04, ORs state into PlayerState. 5 Cβ†’S send sites in do_sheathe, do_aggressive, UpdateItemSlot. | | | `OP_PlayerStateRemove` | 🟒 Verified | Passthrough. Sβ†’C handler sub_1401FE670 @ 0x1401FE670 (Pattern A): reads spawn_id+0x00 and state+0x04, ANDs ~state into PlayerState. 5 Cβ†’S send sites in do_sheathe, do_aggressive, UpdateItemSlot. | | | `OP_PlayEverquestRequest` | πŸ”΄ Not-Set | | | | `OP_PlayEverquestResponse` | πŸ”΄ Not-Set | | | | `OP_PlayMP3` | 🟒 Verified | Passthrough. Inline case block @ 0x1401f7b7e (cmp-dispatch). Packet body = raw filename char*; passed directly to EqSoundManager::PlayScriptMp3. Volume sourced client-side from CLargeDialogWnd. | | | `OP_Poll` | πŸ”΄ Not-Set | | | | `OP_PollResponse` | πŸ”΄ Not-Set | | | | `OP_PopupResponse` | 🟒 Verified | Cβ†’S only. `SendDialogResponseToServer` @ `0x1404ed680`. Sends `EDialogResponse` enum + popup ID (8-byte payload). Wire layout = `PopupResponse_Struct` exactly. Passthrough correct, no decoder needed. | | | `OP_PostEnterWorld` | 🟒 Verified | Unused β€” marked `# unused` in patch conf; IDA confirms no Sβ†’C handler in HWM and no Cβ†’S hton send sites; no struct defined anywhere | | | `OP_PotionBelt` | 🟠 Missing | | | | `OP_PreLogoutReply` | πŸ”΄ Not-Set | | | | `OP_PurchaseLeadershipAA` | 🟠 Missing | | | | `OP_PVPLeaderBoardDetailsReply` | 🟠 Missing | | | | `OP_PVPLeaderBoardDetailsRequest` | 🟠 Missing | | | | `OP_PVPLeaderBoardReply` | 🟠 Missing | | | | `OP_PVPLeaderBoardRequest` | 🟠 Missing | | | | `OP_PVPStats` | 🟠 Missing | | | | `OP_QueryResponseThing` | πŸ”΄ Not-Set | | | | `OP_QueryUCSServerStatus` | 🟒 Verified | Cβ†’S only. Client polls every ~30s via AddPlayerTimer::Stop (0x14009de50). Server ignores payload; responds with OP_SetChatServer+OP_SetChatServer2. TOB handled (ucsTOBCombined). Passthrough, no struct. | | | `OP_RaidDelegateAbility` | 🟠 Missing | | | | `OP_RaidClearNPCMarks` | 🟠 Missing | | | | `OP_RaidInvite` | 🟠 Missing | | | | `OP_RaidJoin` | πŸ”΄ Not-Set | | | | `OP_RaidUpdate` | 🟠 Missing | | | | `OP_RandomNameGenerator` | 🟒 Verified | Sβ†’C only; no hton sends. Handler: CCharacterCreation::NameGenerated @ 0x14039cb30 (Pattern A, 128 bytes). Packet: 8-byte prefix (skipped) + null-terminated name; calls SetName() and enables Accept button. No server struct; emu never sends this opcode. | | | `OP_RandomReply` | 🟒 Verified | Passthrough. Inline HWM (0x1401F4C85/0x1401F4CD4). BeingIgnored gate on name[+0xC]; reads low[+0], high[+4], result[+8] via _ltoa; self vs other roll via strncmp. Struct matches exactly. | | | `OP_RandomReq` | 🟒 Verified | Cβ†’S only. No Sβ†’C handler. Passthrough. Client sends sorted low/high pair from /random cmd; matches RandomReq_Struct exactly. Send @ sub_1402266E0 (0x1402266E0). | | | `OP_ReadBook` | 🟒 Verified | Bidirectional. ENCODE+DECODE added. BookRequest_Struct in tob_structs.h. TOB wire: window(u32)+type(u32)+target_id(u32)+invslot(8B)+can_cast(1B)+txtfile[8194]. Handler: msg_note_text@0x140211740. | | | `OP_RecipeAutoCombine` | 🟒 Verified | Fixed Sβ†’C encoder: container_slot now serialized as 10B (no Padding2), eliminating 2-byte misalignment. Added Cβ†’S DECODE for 56B wire layout (HandleCombine). New RecipeAutoCombine_CS_Struct in tob_structs.h. | | | `OP_RecipeDetails` | 🟒 Verified | Bidirectional passthrough (no encoder/decoder). Sβ†’C: sub_140521980@0x140521980 (Pattern A, 422B). 10-slot big-endian format. Fixed: appended htonl(trivial) at end of SendTradeskillDetails packet (zone/tradeskills.cpp); client was reading 4 garbage bytes at recipe[+84]. | | | `OP_RecipeReply` | 🟒 Verified | Passthrough. Handler sub_14051F590@0x14051F590 (Pattern A). All 5 uint32 fields + recipe_name[64] read at correct offsets; matches RecipeReply_Struct exactly. | | | `OP_RecipesFavorite` | 🟒 Verified | Cβ†’S only. Passthrough. Client sends TradeskillFavorites_Struct (2008 B): object_type + some_id + favorite_recipes[500]. Sent by CTradeskillWnd::ShowFavorites @ 0x140522960. Server size-validates. | | | `OP_RecipesSearch` | 🟒 Verified | Cβ†’S only. Client sends 80-byte struct (object_type, some_id, mintrivial, maxtrivial, query[56], 2 unknowns). Send @ sub_14051FC10 (0x14051FC10). Passthrough; struct matches exactly. | | | `OP_ReclaimCrystals` | πŸ”΄ Not-Set | | | | `OP_RefreshBuffs` | 🟒 Verified | Sβ†’C. CBuffWindow::RefreshBuffs @ 0x14038fda0. mob_id & refresh_type skipped by client; tic_time, full_flag, count, per-buff fields, suspended all verified ok. | | | `OP_RefreshPetBuffs` | 🟒 Verified | Bidi. CPetInfoWnd::RefreshPetBuffs @ 0x1404a0ae0. hit_number skipped by pet window (harmless); mob_id/refresh_type skipped; Cβ†’S is 6-byte UI-reload request, no server decoder. | | | `OP_RefreshTargetBuffs` | 🟒 Verified | Sβ†’C. CTargetWnd::RefreshTargetBuffs @ 0x14050e510. Pattern D. Built by BuffComponent::RefreshBuffs; no ENCODE/DECODE. mob_id and hit_number sent but discarded by client. All fields verified ok. | | | `OP_ReloadUI` | πŸ”΄ Not-Set | | | | `OP_RemoveAllDoors` | 🟒 Verified | Zero-byte signal; case block @ `0x1401ED50E` calls `EqSwitchManager::DeleteAll` @ `0x14025FBD0`; no packet payload, no encoder/decoder needed. | | | `OP_RemoveBlockedBuffs` | 🟒 Verified | Bidirectional; encoder/decoder forward to `OP_BlockedBuffs`; wire = `uint32 Count + CountΓ—int32 SpellID + uint8 Pet + uint8 Initialise`; Sβ†’C case block @ `0x1401f1e47`, deserializer `sub_140202750`. | | | `OP_RemoveNimbusEffect` | 🟒 Verified | Passthrough. Case block 0x1401F8C65, handler sub_1401E2890 (24B); reads spawnid+0, nimbus_effect+4; calls CParticleSystemInterface vtbl[0x70]. | | | `OP_RemoveTrap` | 🟠 Missing | | | | `OP_Report` | 🟒 Verified | Cβ†’S only. Passthrough. Two send sites: `/report` cmd (sub_14021EE20 @ 0x14021ee20) sends `target|reporter|chatlog\0`; CMail::ReportInappropriateMail (0x1401680e0) sends mail body. BugReport_Struct does NOT match wire format. | | | `OP_ReqClientSpawn` | 🟒 Verified | Cβ†’S only. Zero-byte signal packet, no struct or decoder needed. Sent from DoMainLoop@0x14026e670 (hton@0x14026e992) during world init ("Requesting initialization data."). | | | `OP_ReqNewZone` | 🟒 Verified | Sβ†’C passthrough; emu never sends it, handler is dead. Inline case @ 0x1401e7ee6 via cmp-dispatch. Reads [Src+0xF4] (string-table ID, default 0x563) and [Src+0xF8] (class ID) from internal zone struct; displays zone-entry chat msg. Dead branch at loc_1401E804E (compiler artifact). | | | `OP_RequestClientZoneChange` | 🟒 Verified | handler @ 0x1401f7040 (inline Pattern B); cont. @ 0x1401f713a calls DoTeleportB; zone_id/instance_id/y/x/z/heading pass correctly; type hardcoded 0x0b (ignores server field); message string at pkt+29 sent as zeros; tob_structs.h unknown032 offset annotation wrong (should be /*029*/ not /*032*/) | | | `OP_RequestDuel` | 🟠 Missing | | | | `OP_RequestGuildTributes` | 🟠 Missing | | | | `OP_RequestKnowledgeBase` | πŸ”΄ Not-Set | | | | `OP_RequestTitles` | 🟠 Missing | | | | `OP_ResetAA` | 🟒 Verified | Cβ†’S only. Zero-payload signal packet; client sends opcode header only. Server handler reads no fields β€” opcode arrival triggers admin AA reset. Send fn sub_140174980 @ 0x140174980, hton @ 0x1401749a2. | | | `OP_RespawnWindow` | 🟒 Verified | Passthrough correct. Inline CUnSerializeBuffer handler @ `0x1401eb890`: reads selected_bind_id, time_remaining, ui_flag, total_binds, then loops reading bind_number+WorldLocation(20B)+name+validity. Client sends empty 0x5c ACK. | | | `OP_RespondAA` | 🟒 Verified | Handler sub_140217A60 @ 0x140217a60 (Pattern A). TOB adds aapoints_assigned[6] header; aa_list expanded to 300 entries vs server's 240. Fixed OOB read: loop now uses MAX_PP_AA_ARRAY (240); entries 240-299 zero-filled. | | | `OP_RestState` | 🟒 Verified | Passthrough. No struct. Variable-length: 1B (0x01=combat) or 5B (0x00+uint32 timer). Handler sub_1402DA8E0 @ 0x1402da8e0; manual CSB reads. Updates LocalPC+0x2E2C/28/20. Sβ†’C only. | | | `OP_Rewind` | 🟒 Verified | Cβ†’S only; zero-payload signal (no struct); send @ sub_1402326F0 (0x1402326F0); guard: bBeingFlung at [player+0x18F]; no Sβ†’C handler | | | `OP_RezzAnswer` | 🟠 Missing | | | | `OP_RezzComplete` | 🟠 Missing | | | | `OP_RezzRequest` | 🟠 Missing | | | | `OP_Sacrifice` | 🟒 Verified | Passthrough. Sβ†’C: handler sub_140214100 @ 0x140214100 (Pattern A) reads CasterID (+0x00) only; pops sacrifice confirm dialog (token 9054). Cβ†’S: zero-payload send from DialogResponse case 107 (user accepted). | | | `OP_SafeFallSuccess` | 🟒 Verified | Cβ†’S only. Zero-byte notification sent by TakeFallDamage @ 0x140100520 when SafeFall skill (0x27) reduces fall damage. No struct, no decoder needed β€” passthrough correct. | | | `OP_SafePoint` | πŸ”΄ Not-Set | | | | `OP_Save` | 🟒 Verified | Cβ†’S only. Passthrough β€” no encoder/decoder. `Save_Struct` is opaque (192 unknown bytes). Client sends 476-byte save blob via `CEverQuest::SavePC` @ `0x14028d640`. No Sβ†’C handler. | | | `OP_SaveOnZoneReq` | 🟒 Verified | Cβ†’S only. Zero-byte packet sent by sub_14028DF20 @ 0x14028DF20 when zoning. Server Handle_OP_SaveOnZoneReq β†’ Handle_OP_Save β†’ Save(); payload ignored entirely. No decoder needed. | | | `OP_SelectTribute` | 🟠 Missing | | | | `OP_SendAAStats` | 🟒 Verified | Removed in TOB β€” no Sβ†’C handler in HandleWorldMessage, no Cβ†’S send sites, no server struct. Value 0x7416 retained in patch conf as documentation only; server must not send this opcode to TOB clients. | | | `OP_SendAATable` | 🟒 Verified | Sβ†’C: msg_send_alt_data@0x140214200 β†’ UnPackNetBuffer@0x1401a80d0. Pattern A. Encoder verified field-by-field. Effects base/limit zero-extend int32β†’int64 (positive values only in practice). No decoder. | | | `OP_SendCharInfo` | 🟒 Verified | Handler: msg_send_characters@0x1402142a0, sub_140203150@0x140203150. Pattern D (inline CUnSerializeBuffer). Variable-length name, 9 equip slots, PreFTP=1 hardcoded to bypass FTP checks. No changes needed.| | | `OP_SendExpZonein` | 🟒 Verified | Bidirectional handshake; Sβ†’C inline @ `0x1401f4923` sets `EverQuest_ReceivedWorldObjects=1`; client echoes 0-byte Cβ†’S response. No struct, passthrough. | | | `OP_SendFindableNPCs` | 🟠 Missing | | | | `OP_SendGuildTributes` | 🟠 Missing | | | | `OP_SendLoginInfo` | 🟒 Verified | Cβ†’S only. Send @ `0x1402bfec8` in WorldAuthenticate (`0x1402bfb40`). No Sβ†’C handler. Passthrough β€” no encoder/decoder. sub_140246F50 packs login+passwd+empty as NUL-terminated strings; zoning=EverQuest_EnterZone; 0xCC hardcoded at offset 192. | | | `OP_SendMaxCharacters` | 🟒 Verified | Handler `msg_player_info_header` @ `0x140211ae0` (938B, Pattern A). All 16 client-read fields set by encoder; values hardcoded (server struct has no TOB-field equivalents). add_marketplace_chars/add_unknown both 0 so conditional 0x76C4 responses never triggered. | | | `OP_SendMembership` | 🟒 Verified | Sβ†’C only. FreeToPlayClient::UnSerialize @ 0x14067d6f0. Wire: uint8 membership, uint32 races/classes, uint32 entrysize, int32[33] entries. TOB struct packed; encoder correct; entries hardcoded to max. | | | `OP_SendMembershipDetails` | 🟒 Verified | Handler: FreeToPlay::UnSerialize @ 0x14067d540 (Pattern D). Encoder fully hardcoded β€” 96 settings (4 tiers Γ— 24 IDs), 17 race + 17 class entries, exit_url_length=0. Wire format matches client reads. | | | `OP_SendSystemStats` | πŸ”΄ Not-Set | | | | `OP_SendTitleList` | 🟠 Missing | | | | `OP_SendTributes` | 🟠 Missing | | | | `OP_SendZonepoints` | 🟒 Verified | Sβ†’C. Handler: msg_teleport_index @ 0x14029A9B0 (63B). Pattern A. XMM bulk copy, 32B/entry. TOB adds unknown024/028 (zeroed). Client cap: 127 entries. Encoder correct. | | | `OP_SenseHeading` | 🟒 Verified | Cβ†’S only. Client sends 0-byte packet when Sense Heading skill succeeds. No payload, no decoder needed. Send: `sub_140103050` @ `0x140103050`, hton @ `0x1401031a0`. No Sβ†’C handler. | | | `OP_SenseTraps` | 🟒 Verified | Cβ†’S only. Client sends 0-byte packet when Sense Traps skill (ID 62) is used. No payload, no decoder needed. Send: `UseSkill` @ `0x140100e60`, hton @ `0x140101740`. No Sβ†’C handler. | | | `OP_ServerListRequest` | πŸ”΄ Not-Set | | | | `OP_ServerListResponse` | πŸ”΄ Not-Set | | | | `OP_SessionReady` | πŸ”΄ Not-Set | | | | `OP_SetChatServer` | 🟠 Missing | | | | `OP_SetChatServer2` | 🟒 Verified | Sβ†’C only. Raw CSV text packet β€” no binary struct, no encoder/decoder. Handler sub_140208110 @ 0x140208110 parses 5 comma-sep fields; wire has 4 (3 commas), 5th absentβ†’always false. Calls UniversalChatProxyConnect. | | | `OP_SetFace` | 🟠 Missing | | | | `OP_SetGroupTarget` | 🟠 Missing | | | | `OP_SetGuildMOTD` | 🟠 Missing | | | | `OP_SetGuildRank` | 🟠 Missing | | | | `OP_SetRunMode` | 🟒 Verified | Cβ†’S only. Client sends when run mode changes in DoPassageOfTime @ 0x1400ec06f. uint32 payload (mode clamped 0/1) matches SetRunMode_Struct exactly. No Sβ†’C handler exists; no encoder/decoder needed. | | | `OP_SetServerFilter` | 🟒 Verified | Cβ†’S only; no Sβ†’C handler. Decoder copies filters[0..28] from 69-entry TOB packet (276 bytes); remaining 40 TOB-only filters correctly dropped. send_update_filters @ 0x1402a0b00. | | | `OP_SetStartCity` | 🟠 Missing | | | | `OP_SetTitle` | 🟠 Missing | | | | `OP_SetTitleReply` | 🟠 Missing | | | | `OP_SharedTaskMemberList` | 🟠 Missing | | | | `OP_SharedTaskAddPlayer` | 🟠 Missing | | | | `OP_SharedTaskRemovePlayer` | 🟠 Missing | | | | `OP_SharedTaskMakeLeader` | 🟠 Missing | | | | `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_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). | | | `OP_ShopEndConfirm` | 🟒 Verified | Passthrough. Inline case @ 0x1401F61A2; no packet fields read. Calls g_pMerchantWnd->vtable[0x27](1) to close merchant window. Client never sends. | | | `OP_ShopItem` | πŸ”΄ Not-Set | | | | `OP_ShopPlayerBuy` | 🟒 Verified | Sβ†’C: handler sub_1401E3E20@0x1401e3e20, encoder correct. Cβ†’S: fixed Merchant_Sell_Request_Struct from 20β†’24 bytes (added unknown20); client sends 24-byte payload, DECODE_LENGTH_EXACT was rejecting all | | | `OP_ShopPlayerSell` | 🟒 Verified | Bidirectional. Cβ†’S decoder correct. Fixed Sβ†’C encoder: removed npcid from Merchant_Purchase_Response_Struct (client sub_14047A3A0@0x14047A3A0 reads TypelessInventorySlot at byte 0 and quantity at [rsi+8]; npcid was offsetting both). | | | `OP_ShopSendParcel` | 🟒 Verified | Bidirectional. Cβ†’S: 224B RoF2 Parcel_Struct; inherited RoF2 decoder correct (TypelessInventorySlotβ†’item_slot, send_to, note). Sβ†’C: no encoder; server sends empty (success) or 220B item_slot=0xFFFF (cancel). Handler sub_14020FAB0@0x14020FAB0β†’sub_14047B380@0x14047B380; unconditional UpdateSlots covers all cases. | | | `OP_ShopDeleteParcel` | 🟒 Verified | Sβ†’C passthrough. Handler msg_merchant_mail_clearslot@0x14020fa40 reads [rcx+8] (parcel_slot_id+parcel_item_id as int64) β†’ CMerchantWnd::ClearMailSlot. ParcelRetrieve_Struct matches. | | | `OP_ShopRespondParcel` | πŸ”΄ Not-Set | | | | `OP_ShopRetrieveParcel` | 🟒 Verified | Passthrough. Sβ†’C empty ack (SendParcelRetrieveAck). Cβ†’S uses ParcelRetrieve_Struct (merchant+player entity id, parcel_slot_id, parcel_item_id). Handler @ client_packet.cpp:17225. | | | `OP_ShopParcelIcon` | 🟒 Verified | Passthrough Sβ†’C. ParcelIcon_Struct (uint32 status: 0=off,1=on,2=overlimit) matches client reads exactly. Inline case @ 0x1401f277f; drives show/hide+overlimit on CPlayerWnd (sub_140201A20/A40) and updates LocalPC (sub_140201690). | | | `OP_ShopRequest` | 🟒 Verified | Sβ†’C handler sub_1401E3E60 @ 0x1401E3E60 (cmp-dispatch). Fixed close case: OUT(npc_id) always; player_id=0 for close triggers client close path. Decoder correct (4-byte npc_id only). | | | `OP_SimpleMessage` | 🟒 Verified | Passthrough. Handler `msgTokenText` @ `0x140207BF0` (Pattern A). Reads `string_id`/`color`/`unknown8` as dwords at +0,+4,+8. String IDs 469/471/14261 also open CTipWnd. | | | `OP_SkillUpdate` | 🟒 Verified | Handler sub_140214AB0 @ 0x140214ab0 (676B). Pattern A. Handles skills 0-99 and languages 100-131. active=1 hardcoded correctly; server struct omits active by design. | | | `OP_Sneak` | 🟒 Verified | Cβ†’S only. Empty packet (size=0) sent to activate sneak. No struct or decoder needed. Send @ `sub_1401032A0` (0x1401032A0). Sβ†’C not handled by client. | | | `OP_Some3ByteHPUpdate` | πŸ”΄ Not-Set | | | | `OP_Some6ByteHPUpdate` | πŸ”΄ Not-Set | | | | `OP_SomeItemPacketMaybe` | 🟠 Missing | | | | `OP_Sound` | 🟒 Verified | Passthrough. Inline handler @ `0x1401e9799` (Pattern B). Reads mob_id (+0x00), copper/silver/gold/platinum (+0x14–0x20) at correct offsets; plays sound WavePlay(0x8D). Ignores target_id, exp, faction, items. | | | `OP_SpawnAppearance` | 🟒 Verified | Handler `msg_stat_change` @ `0x140215060` (cmp-dispatch @ `0x1401f3b90`). Fixed encoder: now sets both `eq->parameter` and `eq->lock_id` β€” half the TOBAppearance types (MaxHealth, HP, PVP, Sneak, Linkdead) read value from lock_id (offset +16). | | | `OP_SpawnDoor` | 🟒 Verified | Handler @ 0x1401ED624 (inline Pattern B); EQSwitch ctor @ 0x14025E990 reads 132-byte _EQClientSwitch array; all server fields correct; extra TOB-only fields (AdventureDoorId, DynDoorID, RealEstateDoorID, speeds, flags) sent as 0 | | | `OP_SpawnPositionUpdate` | πŸ”΄ Not-Set | | | | `OP_SpecialMesg` | 🟒 Verified | Inline @ `0x1401f6c6e` (Pattern B); encoder correct; link conversion applied to message | | | `OP_SpellEffect` | 🟒 Verified | Passthrough. Handler sub_1402C0BE0 @ 0x1402c0be0. All struct fields matched. Unknown025 (+0x19) is a gate flag (0 = skip); Unknown026 (+0x1A) not read by client. | | | `OP_Split` | 🟒 Verified | Passthrough. Bidirectional. Sβ†’C inline case @ 0x1401F1420 (Pattern B): reads platinum/gold/silver/copper at +0,+4,+8,+C; calls BuildMoneyText then displays chat. Cβ†’S: DoSplit @ 0x1402755E0. | | | `OP_Stamina` | 🟒 Verified | Passthrough. Handler: msg_fwater_update @ 0x14020bc30. Pattern A. food@+0, water@+4 (both uint32). Client clamps to [0,32000]; original 0-127 comment reflects older protocol range. | | | `OP_Stun` | 🟒 Verified | Sβ†’C only. Handler: `CharacterZoneClient::StunMe` @ `0x1401003C0` (Pattern A). Encoder correctly passes `duration`; `unknown004` sent as 0 (no server field); offsets +5/+6 hardcoded but not read by client. | | | `OP_Surname` | 🟠 Missing | | | | `OP_SwapSpell` | 🟒 Verified | Passthrough. Case block @ 0x1401eabca reads from_slot (+0) and to_slot (+4) inline β†’ CSpellBookWnd::SwapSpellBookSlots @ 0x1404f6170. Send: HandleRightClickOnSpell @ 0x1404f40e0. | | | `OP_SystemFingerprint` | πŸ”΄ Not-Set | | | | `OP_TargetCommand` | 🟒 Verified | Passthrough. Bidirectional 4-byte SpawnID. Sβ†’C inline case @ `0x1401ef810` sets `g_pTargetPlayer`. Cβ†’S send sites in AdvancedLootWnd, `/target` handler (`sub_140235E60`), and zero-byte un-target in HWM. | | | `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_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 | | | | `OP_TimeOfDay` | 🟒 Verified | Passthrough Sβ†’C; case 0x1401edc8b β†’ sub_1401E07F0; reads {hour,minute,day,month:uint8, year:uint32}; exact match with TimeOfDay_Struct. | | | `OP_Track` | 🟒 Verified | Added ENCODE: uint16 count + variable-length null-terminated names per entry (entityid, distance, level, is_npc, name, is_pet, is_merc). Identical to RoF2. Handler: sub_14051CF50 @ 0x14051CF50. | | | `OP_TrackTarget` | 🟒 Verified | Cβ†’S only. Passthrough. Client sends uint32 EntityID at +0x00 matching TrackTarget_Struct exactly. Two send sites: CTrackingWnd::NotifyServerOfTrackingTarget (0x14051cc10) and UpdateUsingSkill (0x14024a6d0). | | | `OP_TrackUnknown` | 🟒 Verified | Zero-length Cβ†’S companion to OP_Track (skill 53, Tracking). Server handler is a no-op; no struct payload. | | | `OP_TradeAcceptClick` | 🟒 Verified | Passthrough. Sβ†’C handler sub_140212A90 @ 0x140212a90 reads byte ptr [rcx+4] (flag from unknown4) to set trade-accepted state. Cβ†’S sends 8-byte struct from ClickedTradeButton/WndNotification. No issues. | | | `OP_TradeBusy` | 🟒 Verified | Passthrough. Sβ†’C handler sub_140212C30 @ 0x140212C30: reads from_mob_id (+4) and type byte (+8). Cβ†’S send @ 0x140213020: sends to/from mob IDs + type. Type encoding consistent; no translation needed. | | | `OP_TradeCoins` | 🟒 Verified | Passthrough. Sβ†’C only. Handler sub_140216740 @ 0x140216740. Reads slot (+4, byte, 0–3=copper/silver/gold/platinum) and amount (+8, dword). trader field ignored (client uses g_pTradeTarget). | | | `OP_TradeMoneyUpdate` | 🟒 Verified | Passthrough. Sβ†’C only. Handler sub_140216670 @ 0x140216670. Reads type (byte +4, 0–3=copper/silver/gold/platinum) and amount (dword +8), adds to LocalPC wallet. trader field (+0) unused by client. | | | `OP_Trader` | 🟠 Missing | | | | `OP_TraderBulkSend` | 🟠 Missing | | | | `OP_TraderBuy` | πŸ”΄ Not-Set | | | | `OP_TraderDelItem` | 🟠 Missing | | | | `OP_TradeRequest` | 🟒 Verified | Bidirectional passthrough. Sβ†’C handler `sub_140213020 @ 0x140213020` reads `from_mob_id` at [rbx+4]; opens trade window or sends `OP_TradeBusy` (0x43B8) with reason code. Cβ†’S send in `sub_140275D30`. | | | `OP_TradeRequestAck` | 🟒 Verified | Bidirectional passthrough. Sβ†’C handler `sub_140208C50 @ 0x140208C50` (cmp-dispatch); reads `from_mob_id` at [rcx+4] to open trade window. Cβ†’S send in `sub_140528740 @ 0x140528971`; 8-byte `TradeRequest_Struct` matches exactly. | | | `OP_TraderItemUpdate` | πŸ”΄ Not-Set | | | | `OP_TraderShop` | 🟠 Missing | | | | `OP_TradeSkillCombine` | 🟒 Verified | Fixed: TOB struct now 28 bytes (added unknown0x18 at +24). DECODE_LENGTH_EXACT now accepts client's 28-byte packet. container_slot and guildtribute_slot decoded correctly. Sβ†’C: 0-byte ack, client calls DecItemPending. | | | `OP_TradeSkillRecipeInspect` | πŸ”΄ Not-Set | | | | `OP_Translocate` | 🟒 Verified | Passthrough correct. Handler sub_140217410 @ 0x140217410. Pattern D (manual reads + GetString). All 8 struct fields read at correct offsets. Complete=1β†’immediate teleport; Complete=0β†’popup dialog (DialogResponse sends 0x0611 back). | | | `OP_TributeInfo` | 🟠 Missing | | | | `OP_TributeItem` | 🟠 Missing | | | | `OP_TributeMoney` | 🟠 Missing | | | | `OP_TributeNPC` | πŸ”΄ Not-Set | | | | `OP_TributePointUpdate` | 🟠 Missing | | | | `OP_TributeTimer` | 🟠 Missing | | | | `OP_TributeToggle` | 🟠 Missing | | | | `OP_TributeUpdate` | 🟠 Missing | | | | `OP_UnderWorld` | 🟒 Verified | Cβ†’S only. Client sends position (x,y,z floats) + uint32 at player+0x168 on underworld fall; 18-byte wire. After send, client auto-teleports via zoneHdr_fallThroughWorldTeleportId. No server decoder. | | | `OP_Untargetable` | 🟒 Verified | Passthrough. Inline case block @ 0x1401EF975. Reads id (uint32 +0) via GetPlayerByID, targetable_flag (byte ptr +4) via SetTargetable vtable. Clears g_pTargetPlayer if flag=0 and player is target. | | | `OP_UpdateAA` | 🟒 Verified | Cβ†’S only zero-payload trigger. Client sends during connect phase; server calls SendAlternateAdvancementPoints(). Send fn sub_1404EFE70 @ 0x1404efe70. No struct, no decoder needed. | | | `OP_UpdateAura` | 🟠 Missing | | | | `OP_UpdateLeadershipAA` | 🟠 Missing | | | | `OP_VetClaimReply` | 🟠 Missing | | | | `OP_VetClaimRequest` | 🟠 Missing | | | | `OP_VetRewardsAvaliable` | 🟠 Missing | | | | `OP_VoiceMacroIn` | 🟒 Verified | Cβ†’S only. 3 send sites: do_vtell/do_vraid/do_vgroup @ 0x140229950/CF0/A030. Wire format matches VoiceMacroIn_Struct exactly. Unknown132=Voice ID (GetMyVoice). Passthrough correct. | | | `OP_VoiceMacroOut` | 🟒 Verified | Passthrough. Handler: VoiceManager::HandleMessage @ 0x14033d570. Reads From[64], Type, Voice, MacroNumber; all match server struct. Unknown068 unused; Unknown080 passed to sub_140242E90 for Tell type. | | | `OP_WeaponEquip1` | 🟠 Missing | | | | `OP_WearChange` | 🟒 Verified | Inline Sβ†’C @ 0x1401f5f48. All 8 fields confirmed: spawn_id (+0), wear_slot_id (+4), armor_id..new_armor_type (+8..+24 via rep movsb), color (+28). Encoder/decoder correct. | | | `OP_Weather` | 🟒 Verified | Handler @ 0x1401ECE65, sub_14031BE00 @ 0x14031BE00. TOB wire is 16 bytes (4 uint32s); server struct 12 bytes. Client skips +0x08, reads mode at +0x0C. Added TOB struct + encoder to remap mode. | | | `OP_Weblink` | 🟒 Verified | Deprecated in TOB client β€” not implemented. No handler found in HandleWorldMessage or sub-base scan, no Cβ†’S send. Passthrough is a no-op. | | | `OP_WhoAllRequest` | 🟒 Verified | Cβ†’S only. TOB sends 176B (RoF2 sends 156B): guildid split into flag+id at 0x94/0x98, type moved to 0xA0. Decoder added; /who and /who all now functional. Trader/Buyer filters TODO (NaN sentinel unmapped). | | | `OP_WhoAllResponse` | 🟒 Verified | Handler @ sub_1402182A0 (0x1402182a0). TOB client expects extra uint32 (0xFFFFFFFF) between PIDMSGID and Name per player. Encoder added (mirrors RoF2): inserts extra field, sets PIDMSGID=0 (no surname). | | | `OP_World_Client_CRC1` | 🟒 Verified | Cβ†’S only. No struct/decoder. SendExeChecksum @ 0x14024aa10 sends 0x808-byte payload: crc32 + filesize + 256 sampled (offset, byte) pairs. World-server anti-cheat; EQEmu discards it. | | | `OP_World_Client_CRC2` | 🟒 Verified | Cβ†’S only. No struct/decoder. SendBaseDataChecksum @ 0x14024a7b0 sends 0x808-byte payload: crc32 + filesize of Resources\BaseData.txt + 256 sampled (DWORD-idx, DWORD-val) pairs. EQEmu discards it. | | | `OP_World_Client_CRC3` | 🟒 Verified | Cβ†’S only. No struct/decoder. SendSkillCapschecksum @ 0x14024ae10 sends 0x808-byte payload: crc32 + filesize of Resources\SkillCaps.txt + 256 sampled (DWORD-idx, DWORD-val) pairs. EQEmu discards it. | | | `OP_WorldClientReady` | 🟒 Verified | Cβ†’S only. Zero-payload notification sent from DoCharacterSelection @ 0x14026cec0 (hton @ 0x14026cf8d). No struct, no decoder needed. Passthrough correct. | | | `OP_WorldComplete` | 🟒 Verified | Cβ†’S only. 0-byte payload (opcode-only ACK). Client sends after receiving zone-connect data. Send @ 0x1401eeaaf in HandleWorldMessage. No Sβ†’C handler. No encoder/decoder needed. | | | `OP_WorldLogout` | πŸ”΄ Not-Set | | | | `OP_WorldObjectsSent` | 🟒 Verified | Empty packet both ways; handler @ `0x1401f47e4` checks g_world, acks with Cβ†’S empty send at `0x1401f4882`. | | | `OP_WorldUnknown001` | 🟒 Verified | SetServerTime (Sβ†’C). Handler `CEverQuest::SetServerTime` @ 0x140292550. Seeds CPacketScrambler with seeds at +0x00/+0x10; stores ServerTimeBase at +0x08. EQEmu doesn't use scrambler so packet never sent. | | | `OP_XTargetAutoAddHaters` | 🟠 Missing | | | | `OP_XTargetOpen` | 🟠 Missing | | | | `OP_XTargetOpenResponse` | 🟠 Missing | | | | `OP_XTargetRequest` | 🟠 Missing | | | | `OP_XTargetResponse` | 🟠 Missing | | | | `OP_YellForHelp` | 🟒 Verified | Passthrough. Sβ†’C: handler sub_140219A80 reads yeller spawn_id (+0) and target spawn_id (+4); server sends only 4 bytes so "with [target]" display is non-functional (server limitation, not TOB issue). | | | `OP_ZoneChange` | 🟒 Verified | Bidirectional (100-byte TOB struct). Sβ†’C via ServerStatusPacketHandler (not HWM). Encoder/decoder correct; 3 extra unknown fields (068/072/096) are 0-filled/ignored. success-=1 for negative codes. | | | `OP_ZoneComplete` | πŸ”΄ Not-Set | | | | `OP_ZoneEntry` | 🟒 Verified | Bidir. Sβ†’C: ENCODE_FORWARD(OP_ZoneSpawns); handler msgEQAddPlayer@0x140205610 (Pattern D). Cβ†’S: 92-byte; decoder extracts char_name only; unknown00/68-88 are crc32/SpellFileCRC/fingerprint, unused. | | | `OP_ZoneGuildList` | πŸ”΄ Not-Set | | | | `OP_ZoneInUnknown` | πŸ”΄ Not-Set | | | | `OP_ZonePlayerToBind` | 🟒 Verified | Inline CSB in HWM case @ 0x1401eb3bc. WorldLocation (20B: ZoneBoundID+Y+X+Z+Heading), zone_name string, then 3 ints (HP/End/mana β€” hardcoded 60/0/51). Extra WriteUInt32(41) not read by client; remove it | | | `OP_ZoneServerInfo` | 🟒 Verified | Sβ†’C only. Inline Pattern B @ `0x1401ee9cc`. `rep movsb ecx=0x82` copies 130 bytes; port read at offset 128. Struct matches exactly. Client acks with OP_WorldComplete (0x1223) to world server. | | | `OP_ZoneServerReady` | πŸ”΄ Not-Set | | | | `OP_ZoneSpawns` | 🟒 Verified | Deprecated in TOB client β€” case block @ 0x1401EEDDD calls fdebug only, no parsing. Encoder fans out each Spawn_Struct as individual OP_ZoneEntry (0x713D) packets. Client never receives this directly. | | | `OP_ZoneUnavail` | 🟒 Verified | Passthrough. Inline case @ 0x1401EE4CC: sets global ZoneUnavailable=1, clears PendingCharacterName[0]. Client reads no packet fields β€” opcode arrival is the entire signal. | |