Files
eqemu-server/tob/opcodes.md
T
dannuic 168995a5b5
Build / Linux (push) Has been cancelled
Build / Windows (push) Has been cancelled
Full Packet Review for Known Conversion (#5100)
2026-06-07 00:12:57 -07:00

172 KiB
Raw Blame History

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
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 vtable0x138 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->vtable0x27 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.