From f29d87aced50d38ed7f65901c4b636f35f5a1836 Mon Sep 17 00:00:00 2001 From: dannuic Date: Thu, 16 Apr 2026 15:59:54 -0600 Subject: [PATCH 01/12] Validated up to OP_WorldObjectsSent --- common/patches/tob.cpp | 63 +- common/patches/tob_structs.h | 34 +- common/ruletypes.h | 2 +- tob/opcodes.md | 1256 +++++++++++++++++----------------- 4 files changed, 680 insertions(+), 675 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 90529b045..64ef78c77 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "world/sof_char_create_data.h" @@ -217,19 +218,22 @@ namespace TOB ENCODE(OP_BlockedBuffs) { - ENCODE_LENGTH_EXACT(BlockedBuffs_Struct); - SETUP_DIRECT_ENCODE(BlockedBuffs_Struct, structs::BlockedBuffs_Struct); + // Blocked buffs are a major change. They are stored in a resizable array in TOB, so this sends size, then + // spells, then the final two bools -- see 0x140202750 + SETUP_VAR_ENCODE(BlockedBuffs_Struct); - for (uint32 i = 0; i < BLOCKED_BUFF_COUNT; ++i) - eq->SpellID[i] = emu->SpellID[i]; + // size is uint32 + count * int32 + uint8 + uint8 + uint32 sz = 6 + emu->Count * 4; + __packet->size = sz; + __packet->pBuffer = new unsigned char[sz]; + memset(__packet->pBuffer, 0, sz); - for (uint32 i = BLOCKED_BUFF_COUNT; i < structs::BLOCKED_BUFF_COUNT; ++i) - eq->SpellID[i] = -1; + __packet->WriteUInt32(emu->Count); + for (int i = 0; i < emu->Count; i++) + __packet->WriteSInt32(emu->SpellID[i]); - OUT(Count); - OUT(Pet); - OUT(Initialise); - OUT(Flags); + __packet->WriteUInt8(emu->Pet); + __packet->WriteUInt8(emu->Initialise); FINISH_ENCODE(); } @@ -981,6 +985,7 @@ namespace TOB ENCODE(OP_NewSpawn) { ENCODE_FORWARD(OP_ZoneSpawns); } ENCODE(OP_NewZone) { + // zoneHeader EQApplicationPacket* in = *p; *p = nullptr; @@ -2903,7 +2908,7 @@ namespace TOB buf.WriteString(new_message); - auto outapp = new EQApplicationPacket(OP_SpecialMesg, buf); + auto outapp = new EQApplicationPacket(OP_SpecialMesg, std::move(buf)); dest->FastQueuePacket(&outapp, ack_req); delete in; @@ -2934,14 +2939,14 @@ namespace TOB return; } - auto outapp = new EQApplicationPacket(OP_ChangeSize, sizeof(ChangeSize_Struct)); + auto outapp = new EQApplicationPacket(OP_ChangeSize, sizeof(structs::ChangeSize_Struct)); - ChangeSize_Struct* css = (ChangeSize_Struct*)outapp->pBuffer; + structs::ChangeSize_Struct* css = (structs::ChangeSize_Struct*)outapp->pBuffer; css->EntityID = sas->spawn_id; css->Size = (float)sas->parameter; - css->Unknown08 = 0; - css->Unknown12 = 1.0f; + css->CameraOffset = 0; + css->AnimationSpeedRelated = 1.0f; dest->FastQueuePacket(&outapp, ack_req); delete in; @@ -3574,18 +3579,28 @@ namespace TOB DECODE(OP_BlockedBuffs) { - DECODE_LENGTH_EXACT(structs::BlockedBuffs_Struct); - SETUP_DIRECT_DECODE(BlockedBuffs_Struct, structs::BlockedBuffs_Struct); + uint32 count = __packet->ReadUInt32(); + std::vector blocked_spell_ids; + blocked_spell_ids.reserve(count); + for (int i = 0; i < count; ++i) + blocked_spell_ids.push_back(static_cast(__packet->ReadUInt32())); - for (uint32 i = 0; i < BLOCKED_BUFF_COUNT; ++i) - emu->SpellID[i] = eq->SpellID[i]; + bool pet = __packet->ReadUInt8() == 1; + bool init = __packet->ReadUInt8() == 1; - IN(Count); - IN(Pet); - IN(Initialise); - IN(Flags); + __packet->SetReadPosition(0); // reset the packet read to pass it along - FINISH_DIRECT_DECODE(); + __packet->size = sizeof(BlockedBuffs_Struct); + __packet->pBuffer = new unsigned char[__packet->size]{}; + BlockedBuffs_Struct* emu = (BlockedBuffs_Struct*)__packet->pBuffer; + + memset(emu->SpellID, -1, sizeof(emu->SpellID)); + for (int i = 0; i < count; ++i) + emu->SpellID[i] = blocked_spell_ids[i]; + + emu->Count = count; + emu->Pet = pet; + emu->Initialise = init; } DECODE(OP_CastSpell) diff --git a/common/patches/tob_structs.h b/common/patches/tob_structs.h index 5f9803f3c..928e758e6 100644 --- a/common/patches/tob_structs.h +++ b/common/patches/tob_structs.h @@ -12,7 +12,7 @@ namespace TOB { static const uint32 MAX_PP_UNKNOWN_ABILITIES = 25; static const uint32 MAX_RECAST_TYPES = 25; static const uint32 MAX_ITEM_RECAST_TYPES = 100; - static const uint32 BLOCKED_BUFF_COUNT = 40; + static const uint32 BLOCKED_BUFF_COUNT = 60; // this might not be needed? static const uint32 BUFF_COUNT = 62; static const uint32 MAX_PP_LANGUAGE = 32; #pragma pack(1) @@ -274,7 +274,6 @@ namespace TOB { Unknown39, Unknown40, Unknown41, - Unknown42, Birthdate, EncounterLock }; @@ -288,6 +287,15 @@ namespace TOB { /*0024*/ }; + struct ChangeSize_Struct + { + /*00*/ uint32 EntityID; + /*04*/ float Size; + /*08*/ float CameraOffset; + /*12*/ float AnimationSpeedRelated; + /*16*/ + }; + struct Spawn_Struct_Bitfields { union { @@ -400,14 +408,14 @@ namespace TOB { /*056*/ float X; /*060*/ float Z; /*064*/ float Heading; - /*068*/ float DoorAngle; //not sure if this is actually a float; it might be a uint32 like DefaultDoorAngle + /*068*/ float DoorAngle; /*072*/ uint32 ScaleFactor; //rof2's size /*076*/ uint32 Unknown76; //client doesn't seem to read this /*080*/ uint8 Id; //doorid /*081*/ uint8 Type; //opentype /*082*/ uint8 State; //state_at_spawn /*083*/ uint8 DefaultState; //invert_state - /*084*/ int32 Param; //door_param + /*084*/ int32 Param; //door_param (spell id?) /*088*/ uint32 AdventureDoorId; /*092*/ uint32 DynDoorID; /*096*/ uint32 RealEstateDoorID; @@ -549,15 +557,6 @@ namespace TOB { /*024*/ }; - struct ChangeSize_Struct - { - /*00*/ uint32 EntityID; - /*04*/ float Size; - /*08*/ uint32 Unknown08; // Observed 0 - /*12*/ float Unknown12; // Observed 1.0f - /*16*/ - }; - struct SpawnHPUpdate_Struct { /*00*/ int16 spawn_id; @@ -837,15 +836,6 @@ namespace TOB { /*009*/ uint8 unknown009[3]; }; - struct BlockedBuffs_Struct - { - /*000*/ int32 SpellID[BLOCKED_BUFF_COUNT]; - /*120*/ uint32 Count; - /*124*/ uint8 Pet; - /*125*/ uint8 Initialise; - /*126*/ uint16 Flags; - }; - struct ZonePlayerToBind_Struct { //Same structure as the binds in PlayerProfile_Struct //Assembly calls the same function diff --git a/common/ruletypes.h b/common/ruletypes.h index fad7e2a96..131355c2c 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -349,7 +349,7 @@ RULE_STRING(World, MOTD, "", "Server MOTD sent on login, change from empty to ha RULE_STRING(World, Rules, "", "Server Rules, change from empty to have this be used instead of variables table 'rules' value, lines are pipe (|) separated, example: A|B|C") RULE_BOOL(World, EnableAutoLogin, false, "Enables or disables auto login of characters, allowing people to log characters in directly from loginserver to ingame") RULE_BOOL(World, EnablePVPRegions, true, "Enables or disables PVP Regions automatically setting your PVP flag") -RULE_STRING(World, SupportedClients, "RoF2", "Comma-delimited list of clients to restrict to. Supported values are Titanium | SoF | SoD | UF | RoF | RoF2. Example: Titanium,RoF2") +RULE_STRING(World, SupportedClients, "RoF2,TOB", "Comma-delimited list of clients to restrict to. Supported values are Titanium | SoF | SoD | UF | RoF | RoF2 | TOB. Example: Titanium,RoF2,TOB") RULE_STRING(World, CustomFilesKey, "", "Enable if the server requires custom files and sends a key to validate. Empty string to disable. Example: eqcustom_v1") RULE_STRING(World, CustomFilesUrl, "github.com/knervous/eqnexus/releases", "URL to display at character select if client is missing custom files") RULE_INT(World, CustomFilesAdminLevel, 20, "Admin level at which custom file key is not required when CustomFilesKey is specified") diff --git a/tob/opcodes.md b/tob/opcodes.md index 5337728e6..d21ad856f 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -6,631 +6,631 @@ Below is a status list for the 450 opcodes we currently use on the server for th ### World/Zone Opcode Implementation Status -| Opcode | Status | Notes | Working On | -|:----------------------------------|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------| -| `OP_AAAction` | 🟡 Unverified | | | -| `OP_AAExpUpdate` | 🟡 Unverified | | | -| `OP_AcceptNewTask` | 🔴 Not-Set | | | -| `OP_AckPacket` | 🟢 Verified | | | -| `OP_Action` | 🟡 Unverified | | | -| `OP_Action2` | 🔴 Not-Set | | | -| `OP_AddNimbusEffect` | 🟡 Unverified | | | -| `OP_AdventureData` | 🔴 Not-Set | | | -| `OP_AdventureDetails` | 🔴 Not-Set | | | -| `OP_AdventureFinish` | 🔴 Not-Set | | | -| `OP_AdventureInfo` | 🔴 Not-Set | | | -| `OP_AdventureInfoRequest` | 🔴 Not-Set | | | -| `OP_AdventureLeaderboardReply` | 🔴 Not-Set | | | -| `OP_AdventureLeaderboardRequest` | 🔴 Not-Set | | | -| `OP_AdventureMerchantPurchase` | 🔴 Not-Set | | | -| `OP_AdventureMerchantRequest` | 🔴 Not-Set | | | -| `OP_AdventureMerchantResponse` | 🔴 Not-Set | | | -| `OP_AdventureMerchantSell` | 🔴 Not-Set | | | -| `OP_AdventurePointsUpdate` | 🔴 Not-Set | | | -| `OP_AdventureRequest` | 🔴 Not-Set | | | -| `OP_AdventureStatsReply` | 🔴 Not-Set | | | -| `OP_AdventureStatsRequest` | 🔴 Not-Set | | | -| `OP_AdventureUpdate` | 🔴 Not-Set | | | -| `OP_AggroMeterLockTarget` | 🔴 Not-Set | | | -| `OP_AggroMeterTargetInfo` | 🔴 Not-Set | | | -| `OP_AggroMeterUpdate` | 🔴 Not-Set | | | -| `OP_AltCurrency` | 🔴 Not-Set | | | -| `OP_AltCurrencyMerchantReply` | 🔴 Not-Set | | | -| `OP_AltCurrencyMerchantRequest` | 🔴 Not-Set | | | -| `OP_AltCurrencyPurchase` | 🔴 Not-Set | | | -| `OP_AltCurrencyReclaim` | 🔴 Not-Set | | | -| `OP_AltCurrencySell` | 🔴 Not-Set | | | -| `OP_AltCurrencySellSelection` | 🔴 Not-Set | | | -| `OP_Animation` | 🟡 Unverified | | | -| `OP_AnnoyingZoneUnknown` | 🔴 Not-Set | | | -| `OP_ApplyPoison` | 🟡 Unverified | | | -| `OP_ApproveName` | 🟡 Unverified | This takes multiple parameters from the client, and it can take multiple integer values from the server | | -| `OP_ApproveWorld` | 🔴 Not-Set | | | -| `OP_ApproveZone` | 🔴 Not-Set | | | -| `OP_Assist` | 🟡 Unverified | | | -| `OP_AssistGroup` | 🟡 Unverified | | | -| `OP_AugmentInfo` | 🟡 Unverified | | | -| `OP_AugmentItem` | 🟡 Unverified | | | -| `OP_AutoAttack` | 🟡 Unverified | | | -| `OP_AutoAttack2` | 🟡 Unverified | | | -| `OP_AutoFire` | 🟡 Unverified | | | -| `OP_Bandolier` | 🔴 Not-Set | | | -| `OP_BankerChange` | 🟡 Unverified | | | -| `OP_Barter` | 🔴 Not-Set | | | -| `OP_Bazaar` | 🔴 Not-Set | | | -| `OP_BazaarInspect` | 🔴 Not-Set | | | -| `OP_BazaarSearch` | 🔴 Not-Set | | | -| `OP_BecomeCorpse` | 🔴 Not-Set | | | -| `OP_BecomeTrader` | 🔴 Not-Set | | | -| `OP_Begging` | 🟡 Unverified | | | -| `OP_BeginCast` | 🟡 Unverified | | | -| `OP_Bind_Wound` | 🟡 Unverified | | | -| `OP_BlockedBuffs` | 🟡 Unverified | | | -| `OP_BoardBoat` | 🟡 Unverified | | | -| `OP_BookButton` | 🟡 Unverified | | | -| `OP_Buff` | 🟡 Unverified | | | -| `OP_BuffCreate` | 🟡 Unverified | | | -| `OP_BuffRemoveRequest` | 🟡 Unverified | | | -| `OP_Bug` | 🟡 Unverified | | | -| `OP_BuyerItems` | 🔴 Not-Set | | | -| `OP_CameraEffect` | 🟡 Unverified | | | -| `OP_Camp` | 🟡 Unverified | | | -| `OP_CancelSneakHide` | 🟡 Unverified | | | -| `OP_CancelTask` | 🔴 Not-Set | | | -| `OP_CancelTrade` | 🟡 Unverified | | | -| `OP_CashReward` | 🟡 Unverified | | | -| `OP_CastSpell` | 🟡 Unverified | | | -| `OP_ChangeSize` | 🟡 Unverified | | | -| `OP_ChannelMessage` | 🟡 Unverified | | | -| `OP_ChangePetName` | 🔴 Not-Set | | | -| `OP_CharacterCreate` | 🟢 Verified | Sends heroic type, can be used for something? | | -| `OP_CharacterCreateRequest` | 🟢 Verified | | | -| `OP_CharInventory` | 🟡 Unverified | | | -| `OP_Charm` | 🟡 Unverified | | | -| `OP_ChatMessage` | 🔴 Not-Set | | | -| `OP_ClearAA` | 🟡 Unverified | | | -| `OP_ClearBlockedBuffs` | 🟡 Unverified | | | -| `OP_ClearLeadershipAbilities` | 🔴 Not-Set | | | -| `OP_ClearNPCMarks` | 🔴 Not-Set | | | -| `OP_ClearObject` | 🟡 Unverified | | | -| `OP_ClearSurname` | 🔴 Not-Set | | | -| `OP_ClickDoor` | 🟡 Unverified | | | -| `OP_ClickObject` | 🟡 Unverified | | | -| `OP_ClickObjectAction` | 🟡 Unverified | | | -| `OP_ClientError` | 🔴 Not-Set | | | -| `OP_ClientReady` | 🟡 Unverified | | | -| `OP_ClientTimeStamp` | 🔴 Not-Set | | | -| `OP_ClientUpdate` | 🟡 Unverified | | | -| `OP_CloseContainer` | 🔴 Not-Set | | | -| `OP_CloseTributeMaster` | 🔴 Not-Set | | | -| `OP_ColoredText` | 🟡 Unverified | | | -| `OP_CombatAbility` | 🟡 Unverified | | | -| `OP_Command` | 🔴 Not-Set | | | -| `OP_CompletedTasks` | 🔴 Not-Set | | | -| `OP_ConfirmDelete` | 🟡 Unverified | | | -| `OP_Consent` | 🟡 Unverified | | | -| `OP_ConsentDeny` | 🟡 Unverified | | | -| `OP_ConsentResponse` | 🟡 Unverified | | | -| `OP_Consider` | 🟡 Unverified | | | -| `OP_ConsiderCorpse` | 🟡 Unverified | | | -| `OP_Consume` | 🟡 Unverified | | | -| `OP_ControlBoat` | 🟡 Unverified | | | -| `OP_CorpseDrag` | 🟡 Unverified | | | -| `OP_CorpseDrop` | 🟡 Unverified | | | -| `OP_CrashDump` | 🔴 Not-Set | | | -| `OP_CrystalCountUpdate` | 🔴 Not-Set | | | -| `OP_CrystalCreate` | 🔴 Not-Set | | | -| `OP_CrystalReclaim` | 🔴 Not-Set | | | -| `OP_CustomTitles` | 🔴 Not-Set | | | -| `OP_Damage` | 🟡 Unverified | | | -| `OP_Death` | 🟡 Unverified | | | -| `OP_DelegateAbility` | 🔴 Not-Set | | | -| `OP_DeleteCharacter` | 🟢 Verified | | | -| `OP_DeleteCharge` | 🟡 Unverified | | | -| `OP_DeleteItem` | 🟡 Unverified | | | -| `OP_DeletePetition` | 🔴 Not-Set | | | -| `OP_DeleteSpawn` | 🟡 Unverified | | | -| `OP_DeleteSpell` | 🟡 Unverified | | | -| `OP_DenyResponse` | 🟡 Unverified | | | -| `OP_Disarm` | 🟡 Unverified | | | -| `OP_DisarmTraps` | 🟡 Unverified | | | -| `OP_DisciplineTimer` | 🟡 Unverified | | | -| `OP_DisciplineUpdate` | 🟡 Unverified | | | -| `OP_DiscordMerchantInventory` | 🔴 Not-Set | | | -| `OP_DoGroupLeadershipAbility` | 🔴 Not-Set | | | -| `OP_DuelDecline` | 🔴 Not-Set | | | -| `OP_DuelAccept` | 🔴 Not-Set | | | -| `OP_DumpName` | 🔴 Not-Set | | | -| `OP_Dye` | 🔴 Not-Set | | | -| `OP_DynamicWall` | 🔴 Not-Set | | | -| `OP_DzAddPlayer` | 🔴 Not-Set | | | -| `OP_DzChooseZone` | 🔴 Not-Set | | | -| `OP_DzChooseZoneReply` | 🔴 Not-Set | | | -| `OP_DzCompass` | 🔴 Not-Set | | | -| `OP_DzExpeditionEndsWarning` | 🔴 Not-Set | | | -| `OP_DzExpeditionInfo` | 🔴 Not-Set | | | -| `OP_DzExpeditionInvite` | 🔴 Not-Set | | | -| `OP_DzExpeditionInviteResponse` | 🔴 Not-Set | | | -| `OP_DzExpeditionLockoutTimers` | 🔴 Not-Set | | | -| `OP_DzListTimers` | 🔴 Not-Set | | | -| `OP_DzMakeLeader` | 🔴 Not-Set | | | -| `OP_DzMemberList` | 🔴 Not-Set | | | -| `OP_DzMemberListName` | 🔴 Not-Set | | | -| `OP_DzMemberListStatus` | 🔴 Not-Set | | | -| `OP_DzPlayerList` | 🔴 Not-Set | | | -| `OP_DzQuit` | 🔴 Not-Set | | | -| `OP_DzRemovePlayer` | 🔴 Not-Set | | | -| `OP_DzSetLeaderName` | 🔴 Not-Set | | | -| `OP_DzSwapPlayer` | 🔴 Not-Set | | | -| `OP_Emote` | 🔴 Not-Set | | | -| `OP_EndLootRequest` | 🟡 Unverified | | | -| `OP_EnduranceUpdate` | 🔴 Not-Set | | | -| `OP_EnterChat` | 🔴 Not-Set | | | -| `OP_EnterWorld` | 🟢 Verified | | | -| `OP_EnvDamage` | 🟡 Unverified | | | -| `OP_EvolveItem` | 🔴 Not-Set | | | -| `OP_ExpansionInfo` | 🟢 Verified | Updated from u32 to u64 and works now | | -| `OP_ExpUpdate` | 🟡 Unverified | | | -| `OP_FaceChange` | 🔴 Not-Set | | | -| `OP_Feedback` | 🔴 Not-Set | | | -| `OP_FeignDeath` | 🟡 Unverified | | | -| `OP_FellowshipUpdate` | 🔴 Not-Set | | | -| `OP_FindPersonReply` | 🔴 Not-Set | | | -| `OP_FindPersonRequest` | 🔴 Not-Set | | | -| `OP_FinishTrade` | 🟡 Unverified | | | -| `OP_FinishWindow` | 🟡 Unverified | | | -| `OP_FinishWindow2` | 🟡 Unverified | | | -| `OP_Fishing` | 🟡 Unverified | | | -| `OP_Fling` | 🟡 Unverified | | | -| `OP_FloatListThing` | 🟢 Verified | Movement History. Sent from client, but emu doesn't use it so setting it as varified. Reference is 0x1402FFAD0 | | -| `OP_Forage` | 🟡 Unverified | | | -| `OP_ForceFindPerson` | 🔴 Not-Set | | | -| `OP_FormattedMessage` | 🟡 Unverified | | | -| `OP_FriendsWho` | 🟡 Unverified | | | -| `OP_GetGuildMOTD` | 🔴 Not-Set | | | -| `OP_GetGuildMOTDReply` | 🔴 Not-Set | | | -| `OP_GetGuildsList` | 🔴 Not-Set | | | -| `OP_GiveMoney` | 🔴 Not-Set | | | -| `OP_GMApproval` | 🔴 Not-Set | | | -| `OP_GMBecomeNPC` | 🔴 Not-Set | | | -| `OP_GMDelCorpse` | 🔴 Not-Set | | | -| `OP_GMEmoteZone` | 🔴 Not-Set | | | -| `OP_GMEndTraining` | 🟡 Unverified | | | -| `OP_GMEndTrainingResponse` | 🔴 Not-Set | | | -| `OP_GMFind` | 🔴 Not-Set | | | -| `OP_GMGoto` | 🔴 Not-Set | | | -| `OP_GMHideMe` | 🔴 Not-Set | | | -| `OP_GMKick` | 🔴 Not-Set | | | -| `OP_GMKill` | 🔴 Not-Set | | | -| `OP_GMLastName` | 🔴 Not-Set | | | -| `OP_GMNameChange` | 🔴 Not-Set | | | -| `OP_GMSearchCorpse` | 🔴 Not-Set | | | -| `OP_GMServers` | 🔴 Not-Set | | | -| `OP_GMSummon` | 🔴 Not-Set | | | -| `OP_GMToggle` | 🔴 Not-Set | | | -| `OP_GMTraining` | 🟡 Unverified | | | -| `OP_GMTrainSkill` | 🟡 Unverified | | | -| `OP_GMTrainSkillConfirm` | 🟡 Unverified | | | -| `OP_GMZoneRequest` | 🔴 Not-Set | | | -| `OP_GMZoneRequest2` | 🔴 Not-Set | | | -| `OP_GroundSpawn` | 🟡 Unverified | | | -| `OP_GroupAcknowledge` | 🔴 Not-Set | | | -| `OP_GroupCancelInvite` | 🔴 Not-Set | | | -| `OP_GroupDelete` | 🔴 Not-Set | | | -| `OP_GroupDisband` | 🟡 Unverified | | | -| `OP_GroupDisbandOther` | 🔴 Not-Set | | | -| `OP_GroupDisbandYou` | 🔴 Not-Set | | | -| `OP_GroupFollow` | 🔴 Not-Set | | | -| `OP_GroupFollow2` | 🔴 Not-Set | | | -| `OP_GroupInvite` | 🟡 Unverified | | | -| `OP_GroupInvite2` | 🔴 Not-Set | | | -| `OP_GroupLeaderChange` | 🔴 Not-Set | | | -| `OP_GroupLeadershipAAUpdate` | 🔴 Not-Set | | | -| `OP_GroupMakeLeader` | 🔴 Not-Set | | | -| `OP_GroupMentor` | 🔴 Not-Set | | | -| `OP_GroupRoles` | 🔴 Not-Set | | | -| `OP_GroupUpdate` | 🔴 Not-Set | | | -| `OP_GroupUpdateB` | 🔴 Not-Set | | | -| `OP_GroupUpdateLeaderAA` | 🔴 Not-Set | | | -| `OP_GuildBank` | 🔴 Not-Set | | | -| `OP_GuildBankItemList` | 🔴 Not-Set | | | -| `OP_GuildCreate` | 🔴 Not-Set | | | -| `OP_GuildDelete` | 🔴 Not-Set | | | -| `OP_GuildDeleteGuild` | 🔴 Not-Set | | | -| `OP_GuildDemote` | 🔴 Not-Set | | | -| `OP_GuildInvite` | 🔴 Not-Set | | | -| `OP_GuildInviteAccept` | 🔴 Not-Set | | | -| `OP_GuildLeader` | 🔴 Not-Set | | | -| `OP_GuildManageAdd` | 🔴 Not-Set | | | -| `OP_GuildManageBanker` | 🔴 Not-Set | | | -| `OP_GuildManageRemove` | 🔴 Not-Set | | | -| `OP_GuildManageStatus` | 🔴 Not-Set | | | -| `OP_GuildMemberLevelUpdate` | 🔴 Not-Set | | | -| `OP_GuildMemberList` | 🔴 Not-Set | | | -| `OP_GuildMemberUpdate` | 🔴 Not-Set | | | -| `OP_GuildMemberLevel` | 🔴 Not-Set | | | -| `OP_GuildMemberRankAltBanker` | 🔴 Not-Set | | | -| `OP_GuildMemberPublicNote` | 🔴 Not-Set | | | -| `OP_GuildMemberAdd` | 🔴 Not-Set | | | -| `OP_GuildMemberRename` | 🔴 Not-Set | | | -| `OP_GuildMemberDelete` | 🔴 Not-Set | | | -| `OP_GuildMemberDetails` | 🔴 Not-Set | | | -| `OP_GuildRenameGuild` | 🔴 Not-Set | | | -| `OP_GuildMOTD` | 🔴 Not-Set | | | -| `OP_GuildPeace` | 🔴 Not-Set | | | -| `OP_GuildPromote` | 🔴 Not-Set | | | -| `OP_GuildPublicNote` | 🔴 Not-Set | | | -| `OP_GuildRemove` | 🔴 Not-Set | | | -| `OP_GuildSelectTribute` | 🔴 Not-Set | | | -| `OP_GuildModifyBenefits` | 🔴 Not-Set | | | -| `OP_GuildTributeToggleReq` | 🔴 Not-Set | | | -| `OP_GuildTributeToggleReply` | 🔴 Not-Set | | | -| `OP_GuildOptInOut` | 🔴 Not-Set | | | -| `OP_GuildSaveActiveTributes` | 🔴 Not-Set | | | -| `OP_GuildSendActiveTributes` | 🔴 Not-Set | | | -| `OP_GuildTributeFavorAndTimer` | 🔴 Not-Set | | | -| `OP_GuildsList` | 🔴 Not-Set | | | -| `OP_GuildStatus` | 🔴 Not-Set | | | -| `OP_GuildTributeInfo` | 🔴 Not-Set | | | -| `OP_GuildUpdate` | 🔴 Not-Set | | | -| `OP_GuildTributeDonateItem` | 🔴 Not-Set | | | -| `OP_GuildTributeDonatePlat` | 🔴 Not-Set | | | -| `OP_GuildWar` | 🔴 Not-Set | | | -| `OP_Heartbeat` | 🔴 Not-Set | | | -| `OP_Hide` | 🟡 Unverified | | | -| `OP_HideCorpse` | 🟡 Unverified | | | -| `OP_HPUpdate` | 🟡 Unverified | | | -| `OP_Illusion` | 🟡 Unverified | | | -| `OP_IncreaseStats` | 🟡 Unverified | | | -| `OP_InitialHPUpdate` | 🔴 Not-Set | | | -| `OP_InitialMobHealth` | 🔴 Not-Set | | | -| `OP_InspectAnswer` | 🔴 Not-Set | | | -| `OP_InspectBuffs` | 🔴 Not-Set | | | -| `OP_InspectMessageUpdate` | 🔴 Not-Set | | | -| `OP_InspectRequest` | 🔴 Not-Set | | | -| `OP_InstillDoubt` | 🟡 Unverified | | | -| `OP_InterruptCast` | 🟡 Unverified | | | -| `OP_InvokeChangePetName` | 🔴 Not-Set | | | -| `OP_InvokeChangePetNameImmediate` | 🔴 Not-Set | | | -| `OP_InvokeNameChangeImmediate` | 🔴 Not-Set | | | -| `OP_InvokeNameChangeLazy` | 🔴 Not-Set | | | -| `OP_ItemLinkClick` | 🔴 Not-Set | | | -| `OP_ItemLinkResponse` | 🔴 Not-Set | | | -| `OP_ItemLinkText` | 🔴 Not-Set | | | -| `OP_ItemName` | 🔴 Not-Set | | | -| `OP_ItemPacket` | 🟡 Unverified | | | -| `OP_ItemPreview` | 🔴 Not-Set | | | -| `OP_ItemPreviewRequest` | 🔴 Not-Set | | | -| `OP_ItemRecastDelay` | 🟡 Unverified | | | -| `OP_ItemVerifyReply` | 🟡 Unverified | | | -| `OP_ItemVerifyRequest` | 🟡 Unverified | | | -| `OP_ItemViewUnknown` | 🔴 Not-Set | | | -| `OP_Jump` | 🟡 Unverified | | | -| `OP_KeyRing` | 🔴 Not-Set | | | -| `OP_KickPlayers` | 🟡 Unverified | | | -| `OP_KnowledgeBase` | 🔴 Not-Set | | | -| `OP_LDoNButton` | 🔴 Not-Set | | | -| `OP_LDoNDisarmTraps` | 🔴 Not-Set | | | -| `OP_LDoNInspect` | 🔴 Not-Set | | | -| `OP_LDoNOpen` | 🟡 Unverified | | | -| `OP_LDoNPickLock` | 🟡 Unverified | | | -| `OP_LDoNSenseTraps` | 🟡 Unverified | | | -| `OP_LeadershipExpToggle` | 🔴 Not-Set | | | -| `OP_LeadershipExpUpdate` | 🔴 Not-Set | | | -| `OP_LeaveAdventure` | 🔴 Not-Set | | | -| `OP_LeaveBoat` | 🟡 Unverified | | | -| `OP_LevelAppearance` | 🟡 Unverified | | | -| `OP_LevelUpdate` | 🟢 Verified | | | -| `OP_LFGAppearance` | 🔴 Not-Set | | | -| `OP_LFGCommand` | 🔴 Not-Set | | | -| `OP_LFGGetMatchesRequest` | 🔴 Not-Set | | | -| `OP_LFGGetMatchesResponse` | 🔴 Not-Set | | | -| `OP_LFGResponse` | 🔴 Not-Set | | | -| `OP_LFGuild` | 🔴 Not-Set | | | -| `OP_LFPCommand` | 🔴 Not-Set | | | -| `OP_LFPGetMatchesRequest` | 🔴 Not-Set | | | -| `OP_LFPGetMatchesResponse` | 🔴 Not-Set | | | -| `OP_LinkedReuse` | 🟡 Unverified | | | -| `OP_LoadSpellSet` | 🔴 Not-Set | | | -| `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` | 🟡 Unverified | | | -| `OP_LogoutReply` | 🔴 Not-Set | | | -| `OP_LogServer` | 🟢 Verified | Mostly unused values | | -| `OP_LootComplete` | 🟡 Unverified | | | -| `OP_LootItem` | 🟡 Unverified | | | -| `OP_LootRequest` | 🟡 Unverified | | | -| `OP_ManaChange` | 🟡 Unverified | | | -| `OP_ManaUpdate` | 🔴 Not-Set | | | -| `OP_MarkNPC` | 🔴 Not-Set | | | -| `OP_MarkRaidNPC` | 🔴 Not-Set | | | -| `OP_Marquee` | 🟡 Unverified | | | -| `OP_MemorizeSpell` | 🟡 Unverified | | | -| `OP_Mend` | 🟡 Unverified | | | -| `OP_MendHPUpdate` | 🔴 Not-Set | | | -| `OP_MercenaryAssign` | 🔴 Not-Set | | | -| `OP_MercenaryCommand` | 🔴 Not-Set | | | -| `OP_MercenaryDataRequest` | 🔴 Not-Set | | | -| `OP_MercenaryDataResponse` | 🔴 Not-Set | | | -| `OP_MercenaryDataUpdate` | 🔴 Not-Set | | | -| `OP_MercenaryDataUpdateRequest` | 🔴 Not-Set | | | -| `OP_MercenaryDismiss` | 🔴 Not-Set | | | -| `OP_MercenaryHire` | 🔴 Not-Set | | | -| `OP_MercenarySuspendRequest` | 🔴 Not-Set | | | -| `OP_MercenarySuspendResponse` | 🔴 Not-Set | | | -| `OP_MercenaryTimer` | 🔴 Not-Set | | | -| `OP_MercenaryTimerRequest` | 🔴 Not-Set | | | -| `OP_MercenaryUnknown1` | 🔴 Not-Set | | | -| `OP_MercenaryUnsuspendResponse` | 🔴 Not-Set | | | -| `OP_MerchantBulkItems` | 🔴 Not-Set | | | -| `OP_MobEnduranceUpdate` | 🔴 Not-Set | | | -| `OP_MobHealth` | 🟡 Unverified | | | -| `OP_MobManaUpdate` | 🔴 Not-Set | | | -| `OP_MobRename` | 🔴 Not-Set | | | -| `OP_MobUpdate` | 🔴 Not-Set | | | -| `OP_MoneyOnCorpse` | 🟡 Unverified | | | -| `OP_MoneyUpdate` | 🟡 Unverified | | | -| `OP_MOTD` | 🟢 Verified | | | -| `OP_MoveCoin` | 🟡 Unverified | | | -| `OP_MoveDoor` | 🟡 Unverified | | | -| `OP_MoveItem` | 🟡 Unverified | | | -| `OP_MoveMultipleItems` | 🟡 Unverified | | | -| `OP_MoveLogDisregard` | 🔴 Not-Set | | | -| `OP_MoveLogRequest` | 🔴 Not-Set | | | -| `OP_MultiLineMsg` | 🔴 Not-Set | | | -| `OP_NewSpawn` | 🟢 Verified | Deprecated in the client, already handled in emu | | -| `OP_NewTitlesAvailable` | 🔴 Not-Set | | | -| `OP_NewZone` | 🟢 Verified | | | -| `OP_NPCMoveUpdate` | 🔴 Not-Set | | | -| `OP_OnLevelMessage` | 🟡 Unverified | | | -| `OP_OpenContainer` | 🟡 Unverified | | | -| `OP_OpenDiscordMerchant` | 🔴 Not-Set | | | -| `OP_OpenGuildTributeMaster` | 🔴 Not-Set | | | -| `OP_OpenInventory` | 🔴 Not-Set | | | -| `OP_OpenTributeMaster` | 🔴 Not-Set | | | -| `OP_PDeletePetition` | 🔴 Not-Set | | | -| `OP_PetBuffWindow` | 🔴 Not-Set | | | -| `OP_PetCommands` | 🔴 Not-Set | | | -| `OP_PetCommandState` | 🔴 Not-Set | | | -| `OP_PetHoTT` | 🔴 Not-Set | | | -| `OP_Petition` | 🔴 Not-Set | | | -| `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` | 🟡 Unverified | | | -| `OP_PickZone` | 🔴 Not-Set | | | -| `OP_PickZoneWindow` | 🔴 Not-Set | | | -| `OP_PlayerProfile` | 🟢 Verified | | | -| `OP_PlayerStateAdd` | 🟡 Unverified | | | -| `OP_PlayerStateRemove` | 🟡 Unverified | | | -| `OP_PlayEverquestRequest` | 🔴 Not-Set | | | -| `OP_PlayEverquestResponse` | 🔴 Not-Set | | | -| `OP_PlayMP3` | 🟡 Unverified | | | -| `OP_Poll` | 🔴 Not-Set | | | -| `OP_PollResponse` | 🔴 Not-Set | | | -| `OP_PopupResponse` | 🟡 Unverified | | | -| `OP_PostEnterWorld` | 🟢 Verified | | | -| `OP_PotionBelt` | 🔴 Not-Set | | | -| `OP_PreLogoutReply` | 🔴 Not-Set | | | -| `OP_PurchaseLeadershipAA` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardDetailsReply` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardDetailsRequest` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardReply` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardRequest` | 🔴 Not-Set | | | -| `OP_PVPStats` | 🔴 Not-Set | | | -| `OP_QueryResponseThing` | 🔴 Not-Set | | | -| `OP_QueryUCSServerStatus` | 🟡 Unverified | | | -| `OP_RaidDelegateAbility` | 🔴 Not-Set | | | -| `OP_RaidClearNPCMarks` | 🔴 Not-Set | | | -| `OP_RaidInvite` | 🔴 Not-Set | | | -| `OP_RaidJoin` | 🔴 Not-Set | | | -| `OP_RaidUpdate` | 🔴 Not-Set | | | -| `OP_RandomNameGenerator` | 🟢 Verified | The client no longer sends this packet (random name generation is done entirely in the client). The client will still accept this packet to set name (emu doesn't do this, but it's always been supported) | | -| `OP_RandomReply` | 🟡 Unverified | | | -| `OP_RandomReq` | 🟡 Unverified | | | -| `OP_ReadBook` | 🟡 Unverified | | | -| `OP_RecipeAutoCombine` | 🟡 Unverified | | | -| `OP_RecipeDetails` | 🟡 Unverified | | | -| `OP_RecipeReply` | 🟡 Unverified | | | -| `OP_RecipesFavorite` | 🟡 Unverified | | | -| `OP_RecipesSearch` | 🟡 Unverified | | | -| `OP_ReclaimCrystals` | 🔴 Not-Set | | | -| `OP_ReloadUI` | 🔴 Not-Set | | | -| `OP_RemoveAllDoors` | 🟡 Unverified | | | -| `OP_RemoveBlockedBuffs` | 🟡 Unverified | | | -| `OP_RemoveNimbusEffect` | 🟡 Unverified | | | -| `OP_RemoveTrap` | 🔴 Not-Set | | | -| `OP_Report` | 🟡 Unverified | | | -| `OP_ReqClientSpawn` | 🟢 Verified | | | -| `OP_ReqNewZone` | 🟢 Verified | Client does not send this (in LS or TOB), but it does receive it. emu does not send it | | -| `OP_RequestClientZoneChange` | 🟢 Verified | parity with RoF2, there's a string that gets passed to teleport at the end that's not known | | -| `OP_RequestDuel` | 🔴 Not-Set | | | -| `OP_RequestGuildTributes` | 🔴 Not-Set | | | -| `OP_RequestKnowledgeBase` | 🔴 Not-Set | | | -| `OP_RequestTitles` | 🔴 Not-Set | | | -| `OP_RespawnWindow` | 🟡 Unverified | | | -| `OP_RespondAA` | 🟡 Unverified | | | -| `OP_RestState` | 🟡 Unverified | | | -| `OP_Rewind` | 🟡 Unverified | | | -| `OP_RezzAnswer` | 🔴 Not-Set | | | -| `OP_RezzComplete` | 🔴 Not-Set | | | -| `OP_RezzRequest` | 🔴 Not-Set | | | -| `OP_Sacrifice` | 🟡 Unverified | | | -| `OP_SafeFallSuccess` | 🟡 Unverified | | | -| `OP_SafePoint` | 🔴 Not-Set | | | -| `OP_Save` | 🟡 Unverified | | | -| `OP_SaveOnZoneReq` | 🟡 Unverified | | | -| `OP_SelectTribute` | 🔴 Not-Set | | | -| `OP_SendAAStats` | 🟡 Unverified | | | -| `OP_SendAATable` | 🟡 Unverified | | | -| `OP_SendCharInfo` | 🟢 Verified | | | -| `OP_SendExpZonein` | 🟡 Unverified | | | -| `OP_SendFindableNPCs` | 🔴 Not-Set | | | -| `OP_SendGuildTributes` | 🔴 Not-Set | | | -| `OP_SendLoginInfo` | 🟢 Verified | | | -| `OP_SendMaxCharacters` | 🟢 Verified | | | -| `OP_SendMembership` | 🟢 Verified | | | -| `OP_SendMembershipDetails` | 🟢 Verified | The struct is correct, will need reversing for actual option keys/values | | -| `OP_SendSystemStats` | 🔴 Not-Set | | | -| `OP_SendTitleList` | 🔴 Not-Set | | | -| `OP_SendTributes` | 🔴 Not-Set | | | -| `OP_SendZonepoints` | 🟡 Unverified | | | -| `OP_SenseHeading` | 🟡 Unverified | | | -| `OP_SenseTraps` | 🟡 Unverified | | | -| `OP_ServerListRequest` | 🔴 Not-Set | | | -| `OP_ServerListResponse` | 🔴 Not-Set | | | -| `OP_SessionReady` | 🔴 Not-Set | | | -| `OP_SetChatServer` | 🔴 Not-Set | | | -| `OP_SetChatServer2` | 🟢 Verified | | | -| `OP_SetFace` | 🔴 Not-Set | | | -| `OP_SetGroupTarget` | 🔴 Not-Set | | | -| `OP_SetGuildMOTD` | 🔴 Not-Set | | | -| `OP_SetGuildRank` | 🔴 Not-Set | | | -| `OP_SetRunMode` | 🟡 Unverified | | | -| `OP_SetServerFilter` | 🟡 Unverified | | | -| `OP_SetStartCity` | 🔴 Not-Set | | | -| `OP_SetTitle` | 🔴 Not-Set | | | -| `OP_SetTitleReply` | 🔴 Not-Set | | | -| `OP_SharedTaskMemberList` | 🔴 Not-Set | | | -| `OP_SharedTaskAddPlayer` | 🔴 Not-Set | | | -| `OP_SharedTaskRemovePlayer` | 🔴 Not-Set | | | -| `OP_SharedTaskMakeLeader` | 🔴 Not-Set | | | -| `OP_SharedTaskMemberInvite` | 🔴 Not-Set | | | -| `OP_SharedTaskInvite` | 🔴 Not-Set | | | -| `OP_SharedTaskInviteResponse` | 🔴 Not-Set | | | -| `OP_SharedTaskAcceptNew` | 🔴 Not-Set | | | -| `OP_SharedTaskMemberChange` | 🔴 Not-Set | | | -| `OP_SharedTaskPlayerList` | 🔴 Not-Set | | | -| `OP_SharedTaskSelectWindow` | 🔴 Not-Set | | | -| `OP_SharedTaskQuit` | 🔴 Not-Set | | | -| `OP_TaskTimers` | 🔴 Not-Set | | | -| `OP_Shielding` | 🔴 Not-Set | | | -| `OP_ShopDelItem` | 🟡 Unverified | | | -| `OP_ShopEnd` | 🟡 Unverified | | | -| `OP_ShopEndConfirm` | 🟡 Unverified | | | -| `OP_ShopItem` | 🔴 Not-Set | | | -| `OP_ShopPlayerBuy` | 🟡 Unverified | | | -| `OP_ShopPlayerSell` | 🟡 Unverified | | | -| `OP_ShopSendParcel` | 🟡 Unverified | | | -| `OP_ShopDeleteParcel` | 🟡 Unverified | | | -| `OP_ShopRespondParcel` | 🔴 Not-Set | | | -| `OP_ShopRetrieveParcel` | 🟡 Unverified | | | -| `OP_ShopParcelIcon` | 🟡 Unverified | | | -| `OP_ShopRequest` | 🟡 Unverified | | | -| `OP_SimpleMessage` | 🟡 Unverified | | | -| `OP_SkillUpdate` | 🟡 Unverified | | | -| `OP_Sneak` | 🟡 Unverified | | | -| `OP_Some3ByteHPUpdate` | 🔴 Not-Set | | | -| `OP_Some6ByteHPUpdate` | 🔴 Not-Set | | | -| `OP_SomeItemPacketMaybe` | 🔴 Not-Set | | | -| `OP_Sound` | 🟡 Unverified | | | -| `OP_SpawnAppearance` | 🟡 Unverified | | | -| `OP_SpawnDoor` | 🟡 Unverified | | | -| `OP_SpawnPositionUpdate` | 🔴 Not-Set | | | -| `OP_SpecialMesg` | 🟡 Unverified | | | -| `OP_SpellEffect` | 🟡 Unverified | | | -| `OP_Split` | 🟡 Unverified | | | -| `OP_Stamina` | 🟢 Verified | These values are 0-32k instead of 0-127 | | -| `OP_Stun` | 🟡 Unverified | | | -| `OP_Surname` | 🔴 Not-Set | | | -| `OP_SwapSpell` | 🟡 Unverified | | | -| `OP_SystemFingerprint` | 🔴 Not-Set | | | -| `OP_TargetBuffs` | 🔴 Not-Set | | | -| `OP_TargetCommand` | 🟡 Unverified | | | -| `OP_TargetHoTT` | 🔴 Not-Set | | | -| `OP_TargetMouse` | 🟡 Unverified | | | -| `OP_TargetReject` | 🔴 Not-Set | | | -| `OP_TaskActivity` | 🔴 Not-Set | | | -| `OP_TaskActivityComplete` | 🔴 Not-Set | | | -| `OP_TaskDescription` | 🔴 Not-Set | | | -| `OP_TaskHistoryReply` | 🔴 Not-Set | | | -| `OP_TaskHistoryRequest` | 🔴 Not-Set | | | -| `OP_TaskRequestTimer` | 🔴 Not-Set | | | -| `OP_TaskSelectWindow` | 🔴 Not-Set | | | -| `OP_Taunt` | 🟡 Unverified | | | -| `OP_TestBuff` | 🔴 Not-Set | | | -| `OP_TGB` | 🔴 Not-Set | | | -| `OP_TimeOfDay` | 🟢 Verified | | | -| `OP_Track` | 🟡 Unverified | | | -| `OP_TrackTarget` | 🟡 Unverified | | | -| `OP_TrackUnknown` | 🟡 Unverified | | | -| `OP_TradeAcceptClick` | 🟡 Unverified | | | -| `OP_TradeBusy` | 🟡 Unverified | | | -| `OP_TradeCoins` | 🟡 Unverified | | | -| `OP_TradeMoneyUpdate` | 🟡 Unverified | | | -| `OP_Trader` | 🔴 Not-Set | | | -| `OP_TraderBulkSend` | 🔴 Not-Set | | | -| `OP_TraderBuy` | 🔴 Not-Set | | | -| `OP_TraderDelItem` | 🔴 Not-Set | | | -| `OP_TradeRequest` | 🟡 Unverified | | | -| `OP_TradeRequestAck` | 🟡 Unverified | | | -| `OP_TraderItemUpdate` | 🔴 Not-Set | | | -| `OP_TraderShop` | 🔴 Not-Set | | | -| `OP_TradeSkillCombine` | 🟡 Unverified | | | -| `OP_TradeSkillRecipeInspect` | 🔴 Not-Set | | | -| `OP_Translocate` | 🟡 Unverified | | | -| `OP_TributeInfo` | 🔴 Not-Set | | | -| `OP_TributeItem` | 🔴 Not-Set | | | -| `OP_TributeMoney` | 🔴 Not-Set | | | -| `OP_TributeNPC` | 🔴 Not-Set | | | -| `OP_TributePointUpdate` | 🔴 Not-Set | | | -| `OP_TributeTimer` | 🔴 Not-Set | | | -| `OP_TributeToggle` | 🔴 Not-Set | | | -| `OP_TributeUpdate` | 🔴 Not-Set | | | -| `OP_Untargetable` | 🟡 Unverified | | | -| `OP_UpdateAA` | 🟡 Unverified | | | -| `OP_UpdateAura` | 🔴 Not-Set | | | -| `OP_UpdateLeadershipAA` | 🔴 Not-Set | | | -| `OP_VetClaimReply` | 🔴 Not-Set | | | -| `OP_VetClaimRequest` | 🔴 Not-Set | | | -| `OP_VetRewardsAvaliable` | 🔴 Not-Set | | | -| `OP_VoiceMacroIn` | 🟡 Unverified | | | -| `OP_VoiceMacroOut` | 🟡 Unverified | | | -| `OP_WeaponEquip1` | 🔴 Not-Set | | | -| `OP_WearChange` | 🟡 Unverified | | | -| `OP_Weather` | 🟡 Unverified | | | -| `OP_Weblink` | 🟡 Unverified | | | -| `OP_WhoAllRequest` | 🟡 Unverified | | | -| `OP_WhoAllResponse` | 🟡 Unverified | | | -| `OP_World_Client_CRC1` | 🟢 Verified | | | -| `OP_World_Client_CRC2` | 🟢 Verified | | | -| `OP_World_Client_CRC3` | 🟢 Verified | | | -| `OP_WorldClientReady` | 🟢 Verified | | | -| `OP_WorldComplete` | 🟢 Verified | | | -| `OP_WorldLogout` | 🔴 Not-Set | | | -| `OP_WorldObjectsSent` | 🟡 Unverified | | | -| `OP_WorldUnknown001` | 🟢 Verified | SetServerTime. emu doesn't currently send it so setting it to verified, but the reference is 0x140292550 | | -| `OP_XTargetAutoAddHaters` | 🔴 Not-Set | | | -| `OP_XTargetOpen` | 🔴 Not-Set | | | -| `OP_XTargetOpenResponse` | 🔴 Not-Set | | | -| `OP_XTargetRequest` | 🔴 Not-Set | | | -| `OP_XTargetResponse` | 🔴 Not-Set | | | -| `OP_YellForHelp` | 🟡 Unverified | | | -| `OP_ZoneChange` | 🟢 Verified | | | -| `OP_ZoneComplete` | 🔴 Not-Set | | | -| `OP_ZoneEntry` | 🟢 Verified | unknown fields in C->S struct are various CRCs, emu doesn't use them | | -| `OP_ZoneGuildList` | 🔴 Not-Set | | | -| `OP_ZoneInUnknown` | 🔴 Not-Set | | | -| `OP_ZonePlayerToBind` | 🟡 Unverified | | | -| `OP_ZoneServerInfo` | 🟢 Verified | | | -| `OP_ZoneServerReady` | 🔴 Not-Set | | | -| `OP_ZoneSpawns` | 🟢 Verified | This is deprecated in the client (and emu never sends it directly) | | -| `OP_ZoneUnavail` | 🟢 Verified | The client discards all content of this packet | | -| `OP_ResetAA` | 🟡 Unverified | | | -| `OP_UnderWorld` | 🟡 Unverified | | | +| Opcode | Status | Notes | Working On | +|:----------------------------------|:---------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------| +| `OP_AAAction` | 🟡 Unverified | | | +| `OP_AAExpUpdate` | 🟡 Unverified | | | +| `OP_AcceptNewTask` | 🔴 Not-Set | | | +| `OP_AckPacket` | 🟢 Verified | | | +| `OP_Action` | 🟡 Unverified | | | +| `OP_Action2` | 🔴 Not-Set | | | +| `OP_AddNimbusEffect` | 🟡 Unverified | | | +| `OP_AdventureData` | 🔴 Not-Set | | | +| `OP_AdventureDetails` | 🔴 Not-Set | | | +| `OP_AdventureFinish` | 🔴 Not-Set | | | +| `OP_AdventureInfo` | 🔴 Not-Set | | | +| `OP_AdventureInfoRequest` | 🔴 Not-Set | | | +| `OP_AdventureLeaderboardReply` | 🔴 Not-Set | | | +| `OP_AdventureLeaderboardRequest` | 🔴 Not-Set | | | +| `OP_AdventureMerchantPurchase` | 🔴 Not-Set | | | +| `OP_AdventureMerchantRequest` | 🔴 Not-Set | | | +| `OP_AdventureMerchantResponse` | 🔴 Not-Set | | | +| `OP_AdventureMerchantSell` | 🔴 Not-Set | | | +| `OP_AdventurePointsUpdate` | 🔴 Not-Set | | | +| `OP_AdventureRequest` | 🔴 Not-Set | | | +| `OP_AdventureStatsReply` | 🔴 Not-Set | | | +| `OP_AdventureStatsRequest` | 🔴 Not-Set | | | +| `OP_AdventureUpdate` | 🔴 Not-Set | | | +| `OP_AggroMeterLockTarget` | 🔴 Not-Set | | | +| `OP_AggroMeterTargetInfo` | 🔴 Not-Set | | | +| `OP_AggroMeterUpdate` | 🔴 Not-Set | | | +| `OP_AltCurrency` | 🔴 Not-Set | | | +| `OP_AltCurrencyMerchantReply` | 🔴 Not-Set | | | +| `OP_AltCurrencyMerchantRequest` | 🔴 Not-Set | | | +| `OP_AltCurrencyPurchase` | 🔴 Not-Set | | | +| `OP_AltCurrencyReclaim` | 🔴 Not-Set | | | +| `OP_AltCurrencySell` | 🔴 Not-Set | | | +| `OP_AltCurrencySellSelection` | 🔴 Not-Set | | | +| `OP_Animation` | 🟡 Unverified | | | +| `OP_AnnoyingZoneUnknown` | 🔴 Not-Set | | | +| `OP_ApplyPoison` | 🟡 Unverified | | | +| `OP_ApproveName` | 🟡 Unverified | This takes multiple parameters from the client, and it can take multiple integer values from the server | | +| `OP_ApproveWorld` | 🔴 Not-Set | | | +| `OP_ApproveZone` | 🔴 Not-Set | | | +| `OP_Assist` | 🟡 Unverified | | | +| `OP_AssistGroup` | 🟡 Unverified | | | +| `OP_AugmentInfo` | 🟡 Unverified | | | +| `OP_AugmentItem` | 🟡 Unverified | | | +| `OP_AutoAttack` | 🟡 Unverified | | | +| `OP_AutoAttack2` | 🟡 Unverified | | | +| `OP_AutoFire` | 🟡 Unverified | | | +| `OP_Bandolier` | 🔴 Not-Set | | | +| `OP_BankerChange` | 🟡 Unverified | | | +| `OP_Barter` | 🔴 Not-Set | | | +| `OP_Bazaar` | 🔴 Not-Set | | | +| `OP_BazaarInspect` | 🔴 Not-Set | | | +| `OP_BazaarSearch` | 🔴 Not-Set | | | +| `OP_BecomeCorpse` | 🔴 Not-Set | | | +| `OP_BecomeTrader` | 🔴 Not-Set | | | +| `OP_Begging` | 🟡 Unverified | | | +| `OP_BeginCast` | 🟡 Unverified | | | +| `OP_Bind_Wound` | 🟡 Unverified | | | +| `OP_BlockedBuffs` | 🟢 Verified | | | +| `OP_BoardBoat` | 🟡 Unverified | | | +| `OP_BookButton` | 🟡 Unverified | | | +| `OP_Buff` | 🟡 Unverified | | | +| `OP_BuffCreate` | 🟡 Unverified | | | +| `OP_BuffRemoveRequest` | 🟡 Unverified | | | +| `OP_Bug` | 🟡 Unverified | | | +| `OP_BuyerItems` | 🔴 Not-Set | | | +| `OP_CameraEffect` | 🟡 Unverified | | | +| `OP_Camp` | 🟡 Unverified | | | +| `OP_CancelSneakHide` | 🟡 Unverified | | | +| `OP_CancelTask` | 🔴 Not-Set | | | +| `OP_CancelTrade` | 🟡 Unverified | | | +| `OP_CashReward` | 🟡 Unverified | | | +| `OP_CastSpell` | 🟡 Unverified | | | +| `OP_ChangeSize` | 🟢 Verified | | | +| `OP_ChannelMessage` | 🟡 Unverified | | | +| `OP_ChangePetName` | 🔴 Not-Set | | | +| `OP_CharacterCreate` | 🟢 Verified | Sends heroic type, can be used for something? | | +| `OP_CharacterCreateRequest` | 🟢 Verified | | | +| `OP_CharInventory` | 🟡 Unverified | | | +| `OP_Charm` | 🟡 Unverified | | | +| `OP_ChatMessage` | 🔴 Not-Set | | | +| `OP_ClearAA` | 🟡 Unverified | | | +| `OP_ClearBlockedBuffs` | 🟢 Verified | | | +| `OP_ClearLeadershipAbilities` | 🔴 Not-Set | | | +| `OP_ClearNPCMarks` | 🔴 Not-Set | | | +| `OP_ClearObject` | 🟡 Unverified | | | +| `OP_ClearSurname` | 🔴 Not-Set | | | +| `OP_ClickDoor` | 🟡 Unverified | | | +| `OP_ClickObject` | 🟡 Unverified | | | +| `OP_ClickObjectAction` | 🟡 Unverified | | | +| `OP_ClientError` | 🔴 Not-Set | | | +| `OP_ClientReady` | 🟡 Unverified | | | +| `OP_ClientTimeStamp` | 🔴 Not-Set | | | +| `OP_ClientUpdate` | 🟡 Unverified | | | +| `OP_CloseContainer` | 🔴 Not-Set | | | +| `OP_CloseTributeMaster` | 🔴 Not-Set | | | +| `OP_ColoredText` | 🟡 Unverified | | | +| `OP_CombatAbility` | 🟡 Unverified | | | +| `OP_Command` | 🔴 Not-Set | | | +| `OP_CompletedTasks` | 🔴 Not-Set | | | +| `OP_ConfirmDelete` | 🟡 Unverified | | | +| `OP_Consent` | 🟡 Unverified | | | +| `OP_ConsentDeny` | 🟡 Unverified | | | +| `OP_ConsentResponse` | 🟡 Unverified | | | +| `OP_Consider` | 🟡 Unverified | | | +| `OP_ConsiderCorpse` | 🟡 Unverified | | | +| `OP_Consume` | 🟡 Unverified | | | +| `OP_ControlBoat` | 🟡 Unverified | | | +| `OP_CorpseDrag` | 🟡 Unverified | | | +| `OP_CorpseDrop` | 🟡 Unverified | | | +| `OP_CrashDump` | 🔴 Not-Set | | | +| `OP_CrystalCountUpdate` | 🔴 Not-Set | | | +| `OP_CrystalCreate` | 🔴 Not-Set | | | +| `OP_CrystalReclaim` | 🔴 Not-Set | | | +| `OP_CustomTitles` | 🔴 Not-Set | | | +| `OP_Damage` | 🟡 Unverified | | | +| `OP_Death` | 🟡 Unverified | | | +| `OP_DelegateAbility` | 🔴 Not-Set | | | +| `OP_DeleteCharacter` | 🟢 Verified | | | +| `OP_DeleteCharge` | 🟡 Unverified | | | +| `OP_DeleteItem` | 🟡 Unverified | | | +| `OP_DeletePetition` | 🔴 Not-Set | | | +| `OP_DeleteSpawn` | 🟡 Unverified | | | +| `OP_DeleteSpell` | 🟡 Unverified | | | +| `OP_DenyResponse` | 🟡 Unverified | | | +| `OP_Disarm` | 🟡 Unverified | | | +| `OP_DisarmTraps` | 🟡 Unverified | | | +| `OP_DisciplineTimer` | 🟡 Unverified | | | +| `OP_DisciplineUpdate` | 🟡 Unverified | | | +| `OP_DiscordMerchantInventory` | 🔴 Not-Set | | | +| `OP_DoGroupLeadershipAbility` | 🔴 Not-Set | | | +| `OP_DuelDecline` | 🔴 Not-Set | | | +| `OP_DuelAccept` | 🔴 Not-Set | | | +| `OP_DumpName` | 🔴 Not-Set | | | +| `OP_Dye` | 🔴 Not-Set | | | +| `OP_DynamicWall` | 🔴 Not-Set | | | +| `OP_DzAddPlayer` | 🔴 Not-Set | | | +| `OP_DzChooseZone` | 🔴 Not-Set | | | +| `OP_DzChooseZoneReply` | 🔴 Not-Set | | | +| `OP_DzCompass` | 🔴 Not-Set | | | +| `OP_DzExpeditionEndsWarning` | 🔴 Not-Set | | | +| `OP_DzExpeditionInfo` | 🔴 Not-Set | | | +| `OP_DzExpeditionInvite` | 🔴 Not-Set | | | +| `OP_DzExpeditionInviteResponse` | 🔴 Not-Set | | | +| `OP_DzExpeditionLockoutTimers` | 🔴 Not-Set | | | +| `OP_DzListTimers` | 🔴 Not-Set | | | +| `OP_DzMakeLeader` | 🔴 Not-Set | | | +| `OP_DzMemberList` | 🔴 Not-Set | | | +| `OP_DzMemberListName` | 🔴 Not-Set | | | +| `OP_DzMemberListStatus` | 🔴 Not-Set | | | +| `OP_DzPlayerList` | 🔴 Not-Set | | | +| `OP_DzQuit` | 🔴 Not-Set | | | +| `OP_DzRemovePlayer` | 🔴 Not-Set | | | +| `OP_DzSetLeaderName` | 🔴 Not-Set | | | +| `OP_DzSwapPlayer` | 🔴 Not-Set | | | +| `OP_Emote` | 🔴 Not-Set | | | +| `OP_EndLootRequest` | 🟡 Unverified | | | +| `OP_EnduranceUpdate` | 🔴 Not-Set | | | +| `OP_EnterChat` | 🔴 Not-Set | | | +| `OP_EnterWorld` | 🟢 Verified | | | +| `OP_EnvDamage` | 🟡 Unverified | | | +| `OP_EvolveItem` | 🔴 Not-Set | | | +| `OP_ExpansionInfo` | 🟢 Verified | Updated from u32 to u64 and works now | | +| `OP_ExpUpdate` | 🟡 Unverified | | | +| `OP_FaceChange` | 🔴 Not-Set | | | +| `OP_Feedback` | 🔴 Not-Set | | | +| `OP_FeignDeath` | 🟡 Unverified | | | +| `OP_FellowshipUpdate` | 🔴 Not-Set | | | +| `OP_FindPersonReply` | 🔴 Not-Set | | | +| `OP_FindPersonRequest` | 🔴 Not-Set | | | +| `OP_FinishTrade` | 🟡 Unverified | | | +| `OP_FinishWindow` | 🟡 Unverified | | | +| `OP_FinishWindow2` | 🟡 Unverified | | | +| `OP_Fishing` | 🟡 Unverified | | | +| `OP_Fling` | 🟡 Unverified | | | +| `OP_FloatListThing` | 🟢 Verified | Movement History. Sent from client, but emu doesn't use it so setting it as varified. Reference is 0x1402FFAD0 | | +| `OP_Forage` | 🟡 Unverified | | | +| `OP_ForceFindPerson` | 🔴 Not-Set | | | +| `OP_FormattedMessage` | 🟡 Unverified | | | +| `OP_FriendsWho` | 🟡 Unverified | | | +| `OP_GetGuildMOTD` | 🔴 Not-Set | | | +| `OP_GetGuildMOTDReply` | 🔴 Not-Set | | | +| `OP_GetGuildsList` | 🔴 Not-Set | | | +| `OP_GiveMoney` | 🔴 Not-Set | | | +| `OP_GMApproval` | 🔴 Not-Set | | | +| `OP_GMBecomeNPC` | 🔴 Not-Set | | | +| `OP_GMDelCorpse` | 🔴 Not-Set | | | +| `OP_GMEmoteZone` | 🔴 Not-Set | | | +| `OP_GMEndTraining` | 🟡 Unverified | | | +| `OP_GMEndTrainingResponse` | 🔴 Not-Set | | | +| `OP_GMFind` | 🔴 Not-Set | | | +| `OP_GMGoto` | 🔴 Not-Set | | | +| `OP_GMHideMe` | 🔴 Not-Set | | | +| `OP_GMKick` | 🔴 Not-Set | | | +| `OP_GMKill` | 🔴 Not-Set | | | +| `OP_GMLastName` | 🔴 Not-Set | | | +| `OP_GMNameChange` | 🔴 Not-Set | | | +| `OP_GMSearchCorpse` | 🔴 Not-Set | | | +| `OP_GMServers` | 🔴 Not-Set | | | +| `OP_GMSummon` | 🔴 Not-Set | | | +| `OP_GMToggle` | 🔴 Not-Set | | | +| `OP_GMTraining` | 🟡 Unverified | | | +| `OP_GMTrainSkill` | 🟡 Unverified | | | +| `OP_GMTrainSkillConfirm` | 🟡 Unverified | | | +| `OP_GMZoneRequest` | 🔴 Not-Set | | | +| `OP_GMZoneRequest2` | 🔴 Not-Set | | | +| `OP_GroundSpawn` | 🟢 Verified | | | +| `OP_GroupAcknowledge` | 🔴 Not-Set | | | +| `OP_GroupCancelInvite` | 🔴 Not-Set | | | +| `OP_GroupDelete` | 🔴 Not-Set | | | +| `OP_GroupDisband` | 🟡 Unverified | | | +| `OP_GroupDisbandOther` | 🔴 Not-Set | | | +| `OP_GroupDisbandYou` | 🔴 Not-Set | | | +| `OP_GroupFollow` | 🔴 Not-Set | | | +| `OP_GroupFollow2` | 🔴 Not-Set | | | +| `OP_GroupInvite` | 🟡 Unverified | | | +| `OP_GroupInvite2` | 🔴 Not-Set | | | +| `OP_GroupLeaderChange` | 🔴 Not-Set | | | +| `OP_GroupLeadershipAAUpdate` | 🔴 Not-Set | | | +| `OP_GroupMakeLeader` | 🔴 Not-Set | | | +| `OP_GroupMentor` | 🔴 Not-Set | | | +| `OP_GroupRoles` | 🔴 Not-Set | | | +| `OP_GroupUpdate` | 🔴 Not-Set | | | +| `OP_GroupUpdateB` | 🔴 Not-Set | | | +| `OP_GroupUpdateLeaderAA` | 🔴 Not-Set | | | +| `OP_GuildBank` | 🔴 Not-Set | | | +| `OP_GuildBankItemList` | 🔴 Not-Set | | | +| `OP_GuildCreate` | 🔴 Not-Set | | | +| `OP_GuildDelete` | 🔴 Not-Set | | | +| `OP_GuildDeleteGuild` | 🔴 Not-Set | | | +| `OP_GuildDemote` | 🔴 Not-Set | | | +| `OP_GuildInvite` | 🔴 Not-Set | | | +| `OP_GuildInviteAccept` | 🔴 Not-Set | | | +| `OP_GuildLeader` | 🔴 Not-Set | | | +| `OP_GuildManageAdd` | 🔴 Not-Set | | | +| `OP_GuildManageBanker` | 🔴 Not-Set | | | +| `OP_GuildManageRemove` | 🔴 Not-Set | | | +| `OP_GuildManageStatus` | 🔴 Not-Set | | | +| `OP_GuildMemberLevelUpdate` | 🔴 Not-Set | | | +| `OP_GuildMemberList` | 🔴 Not-Set | | | +| `OP_GuildMemberUpdate` | 🔴 Not-Set | | | +| `OP_GuildMemberLevel` | 🔴 Not-Set | | | +| `OP_GuildMemberRankAltBanker` | 🔴 Not-Set | | | +| `OP_GuildMemberPublicNote` | 🔴 Not-Set | | | +| `OP_GuildMemberAdd` | 🔴 Not-Set | | | +| `OP_GuildMemberRename` | 🔴 Not-Set | | | +| `OP_GuildMemberDelete` | 🔴 Not-Set | | | +| `OP_GuildMemberDetails` | 🔴 Not-Set | | | +| `OP_GuildRenameGuild` | 🔴 Not-Set | | | +| `OP_GuildMOTD` | 🔴 Not-Set | | | +| `OP_GuildPeace` | 🔴 Not-Set | | | +| `OP_GuildPromote` | 🔴 Not-Set | | | +| `OP_GuildPublicNote` | 🔴 Not-Set | | | +| `OP_GuildRemove` | 🔴 Not-Set | | | +| `OP_GuildSelectTribute` | 🔴 Not-Set | | | +| `OP_GuildModifyBenefits` | 🔴 Not-Set | | | +| `OP_GuildTributeToggleReq` | 🔴 Not-Set | | | +| `OP_GuildTributeToggleReply` | 🔴 Not-Set | | | +| `OP_GuildOptInOut` | 🔴 Not-Set | | | +| `OP_GuildSaveActiveTributes` | 🔴 Not-Set | | | +| `OP_GuildSendActiveTributes` | 🔴 Not-Set | | | +| `OP_GuildTributeFavorAndTimer` | 🔴 Not-Set | | | +| `OP_GuildsList` | 🔴 Not-Set | | | +| `OP_GuildStatus` | 🔴 Not-Set | | | +| `OP_GuildTributeInfo` | 🔴 Not-Set | | | +| `OP_GuildUpdate` | 🔴 Not-Set | | | +| `OP_GuildTributeDonateItem` | 🔴 Not-Set | | | +| `OP_GuildTributeDonatePlat` | 🔴 Not-Set | | | +| `OP_GuildWar` | 🔴 Not-Set | | | +| `OP_Heartbeat` | 🔴 Not-Set | | | +| `OP_Hide` | 🟡 Unverified | | | +| `OP_HideCorpse` | 🟡 Unverified | | | +| `OP_HPUpdate` | 🟡 Unverified | | | +| `OP_Illusion` | 🟡 Unverified | | | +| `OP_IncreaseStats` | 🟡 Unverified | | | +| `OP_InitialHPUpdate` | 🔴 Not-Set | | | +| `OP_InitialMobHealth` | 🔴 Not-Set | | | +| `OP_InspectAnswer` | 🔴 Not-Set | | | +| `OP_InspectBuffs` | 🔴 Not-Set | | | +| `OP_InspectMessageUpdate` | 🔴 Not-Set | | | +| `OP_InspectRequest` | 🔴 Not-Set | | | +| `OP_InstillDoubt` | 🟡 Unverified | | | +| `OP_InterruptCast` | 🟡 Unverified | | | +| `OP_InvokeChangePetName` | 🔴 Not-Set | | | +| `OP_InvokeChangePetNameImmediate` | 🔴 Not-Set | | | +| `OP_InvokeNameChangeImmediate` | 🔴 Not-Set | | | +| `OP_InvokeNameChangeLazy` | 🔴 Not-Set | | | +| `OP_ItemLinkClick` | 🔴 Not-Set | | | +| `OP_ItemLinkResponse` | 🔴 Not-Set | | | +| `OP_ItemLinkText` | 🔴 Not-Set | | | +| `OP_ItemName` | 🔴 Not-Set | | | +| `OP_ItemPacket` | 🟡 Unverified | | | +| `OP_ItemPreview` | 🔴 Not-Set | | | +| `OP_ItemPreviewRequest` | 🔴 Not-Set | | | +| `OP_ItemRecastDelay` | 🟡 Unverified | | | +| `OP_ItemVerifyReply` | 🟡 Unverified | | | +| `OP_ItemVerifyRequest` | 🟡 Unverified | | | +| `OP_ItemViewUnknown` | 🔴 Not-Set | | | +| `OP_Jump` | 🟡 Unverified | | | +| `OP_KeyRing` | 🔴 Not-Set | | | +| `OP_KickPlayers` | 🟡 Unverified | | | +| `OP_KnowledgeBase` | 🔴 Not-Set | | | +| `OP_LDoNButton` | 🔴 Not-Set | | | +| `OP_LDoNDisarmTraps` | 🔴 Not-Set | | | +| `OP_LDoNInspect` | 🔴 Not-Set | | | +| `OP_LDoNOpen` | 🟡 Unverified | | | +| `OP_LDoNPickLock` | 🟡 Unverified | | | +| `OP_LDoNSenseTraps` | 🟡 Unverified | | | +| `OP_LeadershipExpToggle` | 🔴 Not-Set | | | +| `OP_LeadershipExpUpdate` | 🔴 Not-Set | | | +| `OP_LeaveAdventure` | 🔴 Not-Set | | | +| `OP_LeaveBoat` | 🟡 Unverified | | | +| `OP_LevelAppearance` | 🟡 Unverified | | | +| `OP_LevelUpdate` | 🟢 Verified | | | +| `OP_LFGAppearance` | 🔴 Not-Set | | | +| `OP_LFGCommand` | 🔴 Not-Set | | | +| `OP_LFGGetMatchesRequest` | 🔴 Not-Set | | | +| `OP_LFGGetMatchesResponse` | 🔴 Not-Set | | | +| `OP_LFGResponse` | 🔴 Not-Set | | | +| `OP_LFGuild` | 🔴 Not-Set | | | +| `OP_LFPCommand` | 🔴 Not-Set | | | +| `OP_LFPGetMatchesRequest` | 🔴 Not-Set | | | +| `OP_LFPGetMatchesResponse` | 🔴 Not-Set | | | +| `OP_LinkedReuse` | 🟡 Unverified | | | +| `OP_LoadSpellSet` | 🔴 Not-Set | | | +| `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` | 🟡 Unverified | | | +| `OP_LogoutReply` | 🔴 Not-Set | | | +| `OP_LogServer` | 🟢 Verified | Mostly unused values | | +| `OP_LootComplete` | 🟡 Unverified | | | +| `OP_LootItem` | 🟡 Unverified | | | +| `OP_LootRequest` | 🟡 Unverified | | | +| `OP_ManaChange` | 🟡 Unverified | | | +| `OP_ManaUpdate` | 🔴 Not-Set | | | +| `OP_MarkNPC` | 🔴 Not-Set | | | +| `OP_MarkRaidNPC` | 🔴 Not-Set | | | +| `OP_Marquee` | 🟡 Unverified | | | +| `OP_MemorizeSpell` | 🟡 Unverified | | | +| `OP_Mend` | 🟡 Unverified | | | +| `OP_MendHPUpdate` | 🔴 Not-Set | | | +| `OP_MercenaryAssign` | 🔴 Not-Set | | | +| `OP_MercenaryCommand` | 🔴 Not-Set | | | +| `OP_MercenaryDataRequest` | 🔴 Not-Set | | | +| `OP_MercenaryDataResponse` | 🔴 Not-Set | | | +| `OP_MercenaryDataUpdate` | 🔴 Not-Set | | | +| `OP_MercenaryDataUpdateRequest` | 🔴 Not-Set | | | +| `OP_MercenaryDismiss` | 🔴 Not-Set | | | +| `OP_MercenaryHire` | 🔴 Not-Set | | | +| `OP_MercenarySuspendRequest` | 🔴 Not-Set | | | +| `OP_MercenarySuspendResponse` | 🔴 Not-Set | | | +| `OP_MercenaryTimer` | 🔴 Not-Set | | | +| `OP_MercenaryTimerRequest` | 🔴 Not-Set | | | +| `OP_MercenaryUnknown1` | 🔴 Not-Set | | | +| `OP_MercenaryUnsuspendResponse` | 🔴 Not-Set | | | +| `OP_MerchantBulkItems` | 🔴 Not-Set | | | +| `OP_MobEnduranceUpdate` | 🔴 Not-Set | | | +| `OP_MobHealth` | 🟡 Unverified | | | +| `OP_MobManaUpdate` | 🔴 Not-Set | | | +| `OP_MobRename` | 🔴 Not-Set | | | +| `OP_MobUpdate` | 🔴 Not-Set | | | +| `OP_MoneyOnCorpse` | 🟡 Unverified | | | +| `OP_MoneyUpdate` | 🟡 Unverified | | | +| `OP_MOTD` | 🟢 Verified | | | +| `OP_MoveCoin` | 🟡 Unverified | | | +| `OP_MoveDoor` | 🟡 Unverified | | | +| `OP_MoveItem` | 🟡 Unverified | | | +| `OP_MoveMultipleItems` | 🟡 Unverified | | | +| `OP_MoveLogDisregard` | 🔴 Not-Set | | | +| `OP_MoveLogRequest` | 🔴 Not-Set | | | +| `OP_MultiLineMsg` | 🔴 Not-Set | | | +| `OP_NewSpawn` | 🟢 Verified | Deprecated in the client, already handled in emu | | +| `OP_NewTitlesAvailable` | 🔴 Not-Set | | | +| `OP_NewZone` | 🟢 Verified | | | +| `OP_NPCMoveUpdate` | 🔴 Not-Set | | | +| `OP_OnLevelMessage` | 🟡 Unverified | | | +| `OP_OpenContainer` | 🟡 Unverified | | | +| `OP_OpenDiscordMerchant` | 🔴 Not-Set | | | +| `OP_OpenGuildTributeMaster` | 🔴 Not-Set | | | +| `OP_OpenInventory` | 🔴 Not-Set | | | +| `OP_OpenTributeMaster` | 🔴 Not-Set | | | +| `OP_PDeletePetition` | 🔴 Not-Set | | | +| `OP_PetBuffWindow` | 🔴 Not-Set | | | +| `OP_PetCommands` | 🔴 Not-Set | | | +| `OP_PetCommandState` | 🔴 Not-Set | | | +| `OP_PetHoTT` | 🔴 Not-Set | | | +| `OP_Petition` | 🔴 Not-Set | | | +| `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` | 🟡 Unverified | | | +| `OP_PickZone` | 🔴 Not-Set | | | +| `OP_PickZoneWindow` | 🔴 Not-Set | | | +| `OP_PlayerProfile` | 🟢 Verified | | | +| `OP_PlayerStateAdd` | 🟡 Unverified | | | +| `OP_PlayerStateRemove` | 🟡 Unverified | | | +| `OP_PlayEverquestRequest` | 🔴 Not-Set | | | +| `OP_PlayEverquestResponse` | 🔴 Not-Set | | | +| `OP_PlayMP3` | 🟡 Unverified | | | +| `OP_Poll` | 🔴 Not-Set | | | +| `OP_PollResponse` | 🔴 Not-Set | | | +| `OP_PopupResponse` | 🟡 Unverified | | | +| `OP_PostEnterWorld` | 🟢 Verified | | | +| `OP_PotionBelt` | 🔴 Not-Set | | | +| `OP_PreLogoutReply` | 🔴 Not-Set | | | +| `OP_PurchaseLeadershipAA` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardDetailsReply` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardDetailsRequest` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardReply` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardRequest` | 🔴 Not-Set | | | +| `OP_PVPStats` | 🔴 Not-Set | | | +| `OP_QueryResponseThing` | 🔴 Not-Set | | | +| `OP_QueryUCSServerStatus` | 🟡 Unverified | | | +| `OP_RaidDelegateAbility` | 🔴 Not-Set | | | +| `OP_RaidClearNPCMarks` | 🔴 Not-Set | | | +| `OP_RaidInvite` | 🔴 Not-Set | | | +| `OP_RaidJoin` | 🔴 Not-Set | | | +| `OP_RaidUpdate` | 🔴 Not-Set | | | +| `OP_RandomNameGenerator` | 🟢 Verified | The client no longer sends this packet (random name generation is done entirely in the client). The client will still accept this packet to set name (emu doesn't do this, but it's always been supported) | | +| `OP_RandomReply` | 🟡 Unverified | | | +| `OP_RandomReq` | 🟡 Unverified | | | +| `OP_ReadBook` | 🟡 Unverified | | | +| `OP_RecipeAutoCombine` | 🟡 Unverified | | | +| `OP_RecipeDetails` | 🟡 Unverified | | | +| `OP_RecipeReply` | 🟡 Unverified | | | +| `OP_RecipesFavorite` | 🟡 Unverified | | | +| `OP_RecipesSearch` | 🟡 Unverified | | | +| `OP_ReclaimCrystals` | 🔴 Not-Set | | | +| `OP_ReloadUI` | 🔴 Not-Set | | | +| `OP_RemoveAllDoors` | 🟡 Unverified | | | +| `OP_RemoveBlockedBuffs` | 🟢 Verified | | | +| `OP_RemoveNimbusEffect` | 🟡 Unverified | | | +| `OP_RemoveTrap` | 🔴 Not-Set | | | +| `OP_Report` | 🟡 Unverified | | | +| `OP_ReqClientSpawn` | 🟢 Verified | | | +| `OP_ReqNewZone` | 🟢 Verified | Client does not send this (in LS or TOB), but it does receive it. emu does not send it | | +| `OP_RequestClientZoneChange` | 🟢 Verified | parity with RoF2, there's a string that gets passed to teleport at the end that's not known | | +| `OP_RequestDuel` | 🔴 Not-Set | | | +| `OP_RequestGuildTributes` | 🔴 Not-Set | | | +| `OP_RequestKnowledgeBase` | 🔴 Not-Set | | | +| `OP_RequestTitles` | 🔴 Not-Set | | | +| `OP_RespawnWindow` | 🟡 Unverified | | | +| `OP_RespondAA` | 🟡 Unverified | | | +| `OP_RestState` | 🟡 Unverified | | | +| `OP_Rewind` | 🟡 Unverified | | | +| `OP_RezzAnswer` | 🔴 Not-Set | | | +| `OP_RezzComplete` | 🔴 Not-Set | | | +| `OP_RezzRequest` | 🔴 Not-Set | | | +| `OP_Sacrifice` | 🟡 Unverified | | | +| `OP_SafeFallSuccess` | 🟡 Unverified | | | +| `OP_SafePoint` | 🔴 Not-Set | | | +| `OP_Save` | 🟡 Unverified | | | +| `OP_SaveOnZoneReq` | 🟡 Unverified | | | +| `OP_SelectTribute` | 🔴 Not-Set | | | +| `OP_SendAAStats` | 🟡 Unverified | | | +| `OP_SendAATable` | 🟡 Unverified | | | +| `OP_SendCharInfo` | 🟢 Verified | | | +| `OP_SendExpZonein` | 🟡 Unverified | | | +| `OP_SendFindableNPCs` | 🔴 Not-Set | | | +| `OP_SendGuildTributes` | 🔴 Not-Set | | | +| `OP_SendLoginInfo` | 🟢 Verified | | | +| `OP_SendMaxCharacters` | 🟢 Verified | | | +| `OP_SendMembership` | 🟢 Verified | | | +| `OP_SendMembershipDetails` | 🟢 Verified | The struct is correct, will need reversing for actual option keys/values | | +| `OP_SendSystemStats` | 🔴 Not-Set | | | +| `OP_SendTitleList` | 🔴 Not-Set | | | +| `OP_SendTributes` | 🔴 Not-Set | | | +| `OP_SendZonepoints` | 🟢 Verified | | | +| `OP_SenseHeading` | 🟡 Unverified | | | +| `OP_SenseTraps` | 🟡 Unverified | | | +| `OP_ServerListRequest` | 🔴 Not-Set | | | +| `OP_ServerListResponse` | 🔴 Not-Set | | | +| `OP_SessionReady` | 🔴 Not-Set | | | +| `OP_SetChatServer` | 🔴 Not-Set | | | +| `OP_SetChatServer2` | 🟢 Verified | | | +| `OP_SetFace` | 🔴 Not-Set | | | +| `OP_SetGroupTarget` | 🔴 Not-Set | | | +| `OP_SetGuildMOTD` | 🔴 Not-Set | | | +| `OP_SetGuildRank` | 🔴 Not-Set | | | +| `OP_SetRunMode` | 🟡 Unverified | | | +| `OP_SetServerFilter` | 🟡 Unverified | | | +| `OP_SetStartCity` | 🔴 Not-Set | | | +| `OP_SetTitle` | 🔴 Not-Set | | | +| `OP_SetTitleReply` | 🔴 Not-Set | | | +| `OP_SharedTaskMemberList` | 🔴 Not-Set | | | +| `OP_SharedTaskAddPlayer` | 🔴 Not-Set | | | +| `OP_SharedTaskRemovePlayer` | 🔴 Not-Set | | | +| `OP_SharedTaskMakeLeader` | 🔴 Not-Set | | | +| `OP_SharedTaskMemberInvite` | 🔴 Not-Set | | | +| `OP_SharedTaskInvite` | 🔴 Not-Set | | | +| `OP_SharedTaskInviteResponse` | 🔴 Not-Set | | | +| `OP_SharedTaskAcceptNew` | 🔴 Not-Set | | | +| `OP_SharedTaskMemberChange` | 🔴 Not-Set | | | +| `OP_SharedTaskPlayerList` | 🔴 Not-Set | | | +| `OP_SharedTaskSelectWindow` | 🔴 Not-Set | | | +| `OP_SharedTaskQuit` | 🔴 Not-Set | | | +| `OP_TaskTimers` | 🔴 Not-Set | | | +| `OP_Shielding` | 🔴 Not-Set | | | +| `OP_ShopDelItem` | 🟡 Unverified | | | +| `OP_ShopEnd` | 🟡 Unverified | | | +| `OP_ShopEndConfirm` | 🟡 Unverified | | | +| `OP_ShopItem` | 🔴 Not-Set | | | +| `OP_ShopPlayerBuy` | 🟡 Unverified | | | +| `OP_ShopPlayerSell` | 🟡 Unverified | | | +| `OP_ShopSendParcel` | 🟡 Unverified | | | +| `OP_ShopDeleteParcel` | 🟡 Unverified | | | +| `OP_ShopRespondParcel` | 🔴 Not-Set | | | +| `OP_ShopRetrieveParcel` | 🟡 Unverified | | | +| `OP_ShopParcelIcon` | 🟡 Unverified | | | +| `OP_ShopRequest` | 🟡 Unverified | | | +| `OP_SimpleMessage` | 🟡 Unverified | | | +| `OP_SkillUpdate` | 🟡 Unverified | | | +| `OP_Sneak` | 🟡 Unverified | | | +| `OP_Some3ByteHPUpdate` | 🔴 Not-Set | | | +| `OP_Some6ByteHPUpdate` | 🔴 Not-Set | | | +| `OP_SomeItemPacketMaybe` | 🔴 Not-Set | | | +| `OP_Sound` | 🟡 Unverified | | | +| `OP_SpawnAppearance` | 🟢 Verified | | | +| `OP_SpawnDoor` | 🟢 Verified | | | +| `OP_SpawnPositionUpdate` | 🔴 Not-Set | | | +| `OP_SpecialMesg` | 🟡 Unverified | | | +| `OP_SpellEffect` | 🟡 Unverified | | | +| `OP_Split` | 🟡 Unverified | | | +| `OP_Stamina` | 🟢 Verified | These values are 0-32k instead of 0-127 | | +| `OP_Stun` | 🟡 Unverified | | | +| `OP_Surname` | 🔴 Not-Set | | | +| `OP_SwapSpell` | 🟡 Unverified | | | +| `OP_SystemFingerprint` | 🔴 Not-Set | | | +| `OP_TargetBuffs` | 🔴 Not-Set | | | +| `OP_TargetCommand` | 🟡 Unverified | | | +| `OP_TargetHoTT` | 🔴 Not-Set | | | +| `OP_TargetMouse` | 🟡 Unverified | | | +| `OP_TargetReject` | 🔴 Not-Set | | | +| `OP_TaskActivity` | 🔴 Not-Set | | | +| `OP_TaskActivityComplete` | 🔴 Not-Set | | | +| `OP_TaskDescription` | 🔴 Not-Set | | | +| `OP_TaskHistoryReply` | 🔴 Not-Set | | | +| `OP_TaskHistoryRequest` | 🔴 Not-Set | | | +| `OP_TaskRequestTimer` | 🔴 Not-Set | | | +| `OP_TaskSelectWindow` | 🔴 Not-Set | | | +| `OP_Taunt` | 🟡 Unverified | | | +| `OP_TestBuff` | 🔴 Not-Set | | | +| `OP_TGB` | 🔴 Not-Set | | | +| `OP_TimeOfDay` | 🟢 Verified | | | +| `OP_Track` | 🟡 Unverified | | | +| `OP_TrackTarget` | 🟡 Unverified | | | +| `OP_TrackUnknown` | 🟡 Unverified | | | +| `OP_TradeAcceptClick` | 🟡 Unverified | | | +| `OP_TradeBusy` | 🟡 Unverified | | | +| `OP_TradeCoins` | 🟡 Unverified | | | +| `OP_TradeMoneyUpdate` | 🟡 Unverified | | | +| `OP_Trader` | 🔴 Not-Set | | | +| `OP_TraderBulkSend` | 🔴 Not-Set | | | +| `OP_TraderBuy` | 🔴 Not-Set | | | +| `OP_TraderDelItem` | 🔴 Not-Set | | | +| `OP_TradeRequest` | 🟡 Unverified | | | +| `OP_TradeRequestAck` | 🟡 Unverified | | | +| `OP_TraderItemUpdate` | 🔴 Not-Set | | | +| `OP_TraderShop` | 🔴 Not-Set | | | +| `OP_TradeSkillCombine` | 🟡 Unverified | | | +| `OP_TradeSkillRecipeInspect` | 🔴 Not-Set | | | +| `OP_Translocate` | 🟡 Unverified | | | +| `OP_TributeInfo` | 🔴 Not-Set | | | +| `OP_TributeItem` | 🔴 Not-Set | | | +| `OP_TributeMoney` | 🔴 Not-Set | | | +| `OP_TributeNPC` | 🔴 Not-Set | | | +| `OP_TributePointUpdate` | 🔴 Not-Set | | | +| `OP_TributeTimer` | 🔴 Not-Set | | | +| `OP_TributeToggle` | 🔴 Not-Set | | | +| `OP_TributeUpdate` | 🔴 Not-Set | | | +| `OP_Untargetable` | 🟡 Unverified | | | +| `OP_UpdateAA` | 🟡 Unverified | | | +| `OP_UpdateAura` | 🔴 Not-Set | | | +| `OP_UpdateLeadershipAA` | 🔴 Not-Set | | | +| `OP_VetClaimReply` | 🔴 Not-Set | | | +| `OP_VetClaimRequest` | 🔴 Not-Set | | | +| `OP_VetRewardsAvaliable` | 🔴 Not-Set | | | +| `OP_VoiceMacroIn` | 🟡 Unverified | | | +| `OP_VoiceMacroOut` | 🟡 Unverified | | | +| `OP_WeaponEquip1` | 🔴 Not-Set | | | +| `OP_WearChange` | 🟡 Unverified | | | +| `OP_Weather` | 🟢 Verified | | | +| `OP_Weblink` | 🟡 Unverified | | | +| `OP_WhoAllRequest` | 🟡 Unverified | | | +| `OP_WhoAllResponse` | 🟡 Unverified | | | +| `OP_World_Client_CRC1` | 🟢 Verified | | | +| `OP_World_Client_CRC2` | 🟢 Verified | | | +| `OP_World_Client_CRC3` | 🟢 Verified | | | +| `OP_WorldClientReady` | 🟢 Verified | | | +| `OP_WorldComplete` | 🟢 Verified | | | +| `OP_WorldLogout` | 🔴 Not-Set | | | +| `OP_WorldObjectsSent` | 🟢 Verified | | | +| `OP_WorldUnknown001` | 🟢 Verified | SetServerTime. emu doesn't currently send it so setting it to verified, but the reference is 0x140292550 | | +| `OP_XTargetAutoAddHaters` | 🔴 Not-Set | | | +| `OP_XTargetOpen` | 🔴 Not-Set | | | +| `OP_XTargetOpenResponse` | 🔴 Not-Set | | | +| `OP_XTargetRequest` | 🔴 Not-Set | | | +| `OP_XTargetResponse` | 🔴 Not-Set | | | +| `OP_YellForHelp` | 🟡 Unverified | | | +| `OP_ZoneChange` | 🟢 Verified | | | +| `OP_ZoneComplete` | 🔴 Not-Set | | | +| `OP_ZoneEntry` | 🟢 Verified | unknown fields in C->S struct are various CRCs, emu doesn't use them | | +| `OP_ZoneGuildList` | 🔴 Not-Set | | | +| `OP_ZoneInUnknown` | 🔴 Not-Set | | | +| `OP_ZonePlayerToBind` | 🟡 Unverified | | | +| `OP_ZoneServerInfo` | 🟢 Verified | | | +| `OP_ZoneServerReady` | 🔴 Not-Set | | | +| `OP_ZoneSpawns` | 🟢 Verified | This is deprecated in the client (and emu never sends it directly) | | +| `OP_ZoneUnavail` | 🟢 Verified | The client discards all content of this packet | | +| `OP_ResetAA` | 🟡 Unverified | | | +| `OP_UnderWorld` | 🟡 Unverified | | | From 36ea94625589db7315ce85f921b702a1cbe8c243 Mon Sep 17 00:00:00 2001 From: dannuic Date: Thu, 16 Apr 2026 16:28:08 -0600 Subject: [PATCH 02/12] Attempt to fix opcodes formatting --- common/patches/tob.cpp | 2 +- tob/opcodes.md | 1256 ++++++++++++++++++++-------------------- 2 files changed, 629 insertions(+), 629 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 64ef78c77..cc18ae534 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -2391,7 +2391,7 @@ namespace TOB s32 Desc; */ - buffer.WriteUInt32(emu->id); + buffer.WriteUInt32(emu->id); // Index buffer.WriteUInt8(1); buffer.WriteInt32(emu->upper_hotkey_sid); buffer.WriteInt32(emu->lower_hotkey_sid); diff --git a/tob/opcodes.md b/tob/opcodes.md index d21ad856f..73567da2a 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -6,631 +6,631 @@ Below is a status list for the 450 opcodes we currently use on the server for th ### World/Zone Opcode Implementation Status -| Opcode | Status | Notes | Working On | -|:----------------------------------|:---------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------| -| `OP_AAAction` | 🟡 Unverified | | | -| `OP_AAExpUpdate` | 🟡 Unverified | | | -| `OP_AcceptNewTask` | 🔴 Not-Set | | | -| `OP_AckPacket` | 🟢 Verified | | | -| `OP_Action` | 🟡 Unverified | | | -| `OP_Action2` | 🔴 Not-Set | | | -| `OP_AddNimbusEffect` | 🟡 Unverified | | | -| `OP_AdventureData` | 🔴 Not-Set | | | -| `OP_AdventureDetails` | 🔴 Not-Set | | | -| `OP_AdventureFinish` | 🔴 Not-Set | | | -| `OP_AdventureInfo` | 🔴 Not-Set | | | -| `OP_AdventureInfoRequest` | 🔴 Not-Set | | | -| `OP_AdventureLeaderboardReply` | 🔴 Not-Set | | | -| `OP_AdventureLeaderboardRequest` | 🔴 Not-Set | | | -| `OP_AdventureMerchantPurchase` | 🔴 Not-Set | | | -| `OP_AdventureMerchantRequest` | 🔴 Not-Set | | | -| `OP_AdventureMerchantResponse` | 🔴 Not-Set | | | -| `OP_AdventureMerchantSell` | 🔴 Not-Set | | | -| `OP_AdventurePointsUpdate` | 🔴 Not-Set | | | -| `OP_AdventureRequest` | 🔴 Not-Set | | | -| `OP_AdventureStatsReply` | 🔴 Not-Set | | | -| `OP_AdventureStatsRequest` | 🔴 Not-Set | | | -| `OP_AdventureUpdate` | 🔴 Not-Set | | | -| `OP_AggroMeterLockTarget` | 🔴 Not-Set | | | -| `OP_AggroMeterTargetInfo` | 🔴 Not-Set | | | -| `OP_AggroMeterUpdate` | 🔴 Not-Set | | | -| `OP_AltCurrency` | 🔴 Not-Set | | | -| `OP_AltCurrencyMerchantReply` | 🔴 Not-Set | | | -| `OP_AltCurrencyMerchantRequest` | 🔴 Not-Set | | | -| `OP_AltCurrencyPurchase` | 🔴 Not-Set | | | -| `OP_AltCurrencyReclaim` | 🔴 Not-Set | | | -| `OP_AltCurrencySell` | 🔴 Not-Set | | | -| `OP_AltCurrencySellSelection` | 🔴 Not-Set | | | -| `OP_Animation` | 🟡 Unverified | | | -| `OP_AnnoyingZoneUnknown` | 🔴 Not-Set | | | -| `OP_ApplyPoison` | 🟡 Unverified | | | -| `OP_ApproveName` | 🟡 Unverified | This takes multiple parameters from the client, and it can take multiple integer values from the server | | -| `OP_ApproveWorld` | 🔴 Not-Set | | | -| `OP_ApproveZone` | 🔴 Not-Set | | | -| `OP_Assist` | 🟡 Unverified | | | -| `OP_AssistGroup` | 🟡 Unverified | | | -| `OP_AugmentInfo` | 🟡 Unverified | | | -| `OP_AugmentItem` | 🟡 Unverified | | | -| `OP_AutoAttack` | 🟡 Unverified | | | -| `OP_AutoAttack2` | 🟡 Unverified | | | -| `OP_AutoFire` | 🟡 Unverified | | | -| `OP_Bandolier` | 🔴 Not-Set | | | -| `OP_BankerChange` | 🟡 Unverified | | | -| `OP_Barter` | 🔴 Not-Set | | | -| `OP_Bazaar` | 🔴 Not-Set | | | -| `OP_BazaarInspect` | 🔴 Not-Set | | | -| `OP_BazaarSearch` | 🔴 Not-Set | | | -| `OP_BecomeCorpse` | 🔴 Not-Set | | | -| `OP_BecomeTrader` | 🔴 Not-Set | | | -| `OP_Begging` | 🟡 Unverified | | | -| `OP_BeginCast` | 🟡 Unverified | | | -| `OP_Bind_Wound` | 🟡 Unverified | | | -| `OP_BlockedBuffs` | 🟢 Verified | | | -| `OP_BoardBoat` | 🟡 Unverified | | | -| `OP_BookButton` | 🟡 Unverified | | | -| `OP_Buff` | 🟡 Unverified | | | -| `OP_BuffCreate` | 🟡 Unverified | | | -| `OP_BuffRemoveRequest` | 🟡 Unverified | | | -| `OP_Bug` | 🟡 Unverified | | | -| `OP_BuyerItems` | 🔴 Not-Set | | | -| `OP_CameraEffect` | 🟡 Unverified | | | -| `OP_Camp` | 🟡 Unverified | | | -| `OP_CancelSneakHide` | 🟡 Unverified | | | -| `OP_CancelTask` | 🔴 Not-Set | | | -| `OP_CancelTrade` | 🟡 Unverified | | | -| `OP_CashReward` | 🟡 Unverified | | | -| `OP_CastSpell` | 🟡 Unverified | | | -| `OP_ChangeSize` | 🟢 Verified | | | -| `OP_ChannelMessage` | 🟡 Unverified | | | -| `OP_ChangePetName` | 🔴 Not-Set | | | -| `OP_CharacterCreate` | 🟢 Verified | Sends heroic type, can be used for something? | | -| `OP_CharacterCreateRequest` | 🟢 Verified | | | -| `OP_CharInventory` | 🟡 Unverified | | | -| `OP_Charm` | 🟡 Unverified | | | -| `OP_ChatMessage` | 🔴 Not-Set | | | -| `OP_ClearAA` | 🟡 Unverified | | | -| `OP_ClearBlockedBuffs` | 🟢 Verified | | | -| `OP_ClearLeadershipAbilities` | 🔴 Not-Set | | | -| `OP_ClearNPCMarks` | 🔴 Not-Set | | | -| `OP_ClearObject` | 🟡 Unverified | | | -| `OP_ClearSurname` | 🔴 Not-Set | | | -| `OP_ClickDoor` | 🟡 Unverified | | | -| `OP_ClickObject` | 🟡 Unverified | | | -| `OP_ClickObjectAction` | 🟡 Unverified | | | -| `OP_ClientError` | 🔴 Not-Set | | | -| `OP_ClientReady` | 🟡 Unverified | | | -| `OP_ClientTimeStamp` | 🔴 Not-Set | | | -| `OP_ClientUpdate` | 🟡 Unverified | | | -| `OP_CloseContainer` | 🔴 Not-Set | | | -| `OP_CloseTributeMaster` | 🔴 Not-Set | | | -| `OP_ColoredText` | 🟡 Unverified | | | -| `OP_CombatAbility` | 🟡 Unverified | | | -| `OP_Command` | 🔴 Not-Set | | | -| `OP_CompletedTasks` | 🔴 Not-Set | | | -| `OP_ConfirmDelete` | 🟡 Unverified | | | -| `OP_Consent` | 🟡 Unverified | | | -| `OP_ConsentDeny` | 🟡 Unverified | | | -| `OP_ConsentResponse` | 🟡 Unverified | | | -| `OP_Consider` | 🟡 Unverified | | | -| `OP_ConsiderCorpse` | 🟡 Unverified | | | -| `OP_Consume` | 🟡 Unverified | | | -| `OP_ControlBoat` | 🟡 Unverified | | | -| `OP_CorpseDrag` | 🟡 Unverified | | | -| `OP_CorpseDrop` | 🟡 Unverified | | | -| `OP_CrashDump` | 🔴 Not-Set | | | -| `OP_CrystalCountUpdate` | 🔴 Not-Set | | | -| `OP_CrystalCreate` | 🔴 Not-Set | | | -| `OP_CrystalReclaim` | 🔴 Not-Set | | | -| `OP_CustomTitles` | 🔴 Not-Set | | | -| `OP_Damage` | 🟡 Unverified | | | -| `OP_Death` | 🟡 Unverified | | | -| `OP_DelegateAbility` | 🔴 Not-Set | | | -| `OP_DeleteCharacter` | 🟢 Verified | | | -| `OP_DeleteCharge` | 🟡 Unverified | | | -| `OP_DeleteItem` | 🟡 Unverified | | | -| `OP_DeletePetition` | 🔴 Not-Set | | | -| `OP_DeleteSpawn` | 🟡 Unverified | | | -| `OP_DeleteSpell` | 🟡 Unverified | | | -| `OP_DenyResponse` | 🟡 Unverified | | | -| `OP_Disarm` | 🟡 Unverified | | | -| `OP_DisarmTraps` | 🟡 Unverified | | | -| `OP_DisciplineTimer` | 🟡 Unverified | | | -| `OP_DisciplineUpdate` | 🟡 Unverified | | | -| `OP_DiscordMerchantInventory` | 🔴 Not-Set | | | -| `OP_DoGroupLeadershipAbility` | 🔴 Not-Set | | | -| `OP_DuelDecline` | 🔴 Not-Set | | | -| `OP_DuelAccept` | 🔴 Not-Set | | | -| `OP_DumpName` | 🔴 Not-Set | | | -| `OP_Dye` | 🔴 Not-Set | | | -| `OP_DynamicWall` | 🔴 Not-Set | | | -| `OP_DzAddPlayer` | 🔴 Not-Set | | | -| `OP_DzChooseZone` | 🔴 Not-Set | | | -| `OP_DzChooseZoneReply` | 🔴 Not-Set | | | -| `OP_DzCompass` | 🔴 Not-Set | | | -| `OP_DzExpeditionEndsWarning` | 🔴 Not-Set | | | -| `OP_DzExpeditionInfo` | 🔴 Not-Set | | | -| `OP_DzExpeditionInvite` | 🔴 Not-Set | | | -| `OP_DzExpeditionInviteResponse` | 🔴 Not-Set | | | -| `OP_DzExpeditionLockoutTimers` | 🔴 Not-Set | | | -| `OP_DzListTimers` | 🔴 Not-Set | | | -| `OP_DzMakeLeader` | 🔴 Not-Set | | | -| `OP_DzMemberList` | 🔴 Not-Set | | | -| `OP_DzMemberListName` | 🔴 Not-Set | | | -| `OP_DzMemberListStatus` | 🔴 Not-Set | | | -| `OP_DzPlayerList` | 🔴 Not-Set | | | -| `OP_DzQuit` | 🔴 Not-Set | | | -| `OP_DzRemovePlayer` | 🔴 Not-Set | | | -| `OP_DzSetLeaderName` | 🔴 Not-Set | | | -| `OP_DzSwapPlayer` | 🔴 Not-Set | | | -| `OP_Emote` | 🔴 Not-Set | | | -| `OP_EndLootRequest` | 🟡 Unverified | | | -| `OP_EnduranceUpdate` | 🔴 Not-Set | | | -| `OP_EnterChat` | 🔴 Not-Set | | | -| `OP_EnterWorld` | 🟢 Verified | | | -| `OP_EnvDamage` | 🟡 Unverified | | | -| `OP_EvolveItem` | 🔴 Not-Set | | | -| `OP_ExpansionInfo` | 🟢 Verified | Updated from u32 to u64 and works now | | -| `OP_ExpUpdate` | 🟡 Unverified | | | -| `OP_FaceChange` | 🔴 Not-Set | | | -| `OP_Feedback` | 🔴 Not-Set | | | -| `OP_FeignDeath` | 🟡 Unverified | | | -| `OP_FellowshipUpdate` | 🔴 Not-Set | | | -| `OP_FindPersonReply` | 🔴 Not-Set | | | -| `OP_FindPersonRequest` | 🔴 Not-Set | | | -| `OP_FinishTrade` | 🟡 Unverified | | | -| `OP_FinishWindow` | 🟡 Unverified | | | -| `OP_FinishWindow2` | 🟡 Unverified | | | -| `OP_Fishing` | 🟡 Unverified | | | -| `OP_Fling` | 🟡 Unverified | | | -| `OP_FloatListThing` | 🟢 Verified | Movement History. Sent from client, but emu doesn't use it so setting it as varified. Reference is 0x1402FFAD0 | | -| `OP_Forage` | 🟡 Unverified | | | -| `OP_ForceFindPerson` | 🔴 Not-Set | | | -| `OP_FormattedMessage` | 🟡 Unverified | | | -| `OP_FriendsWho` | 🟡 Unverified | | | -| `OP_GetGuildMOTD` | 🔴 Not-Set | | | -| `OP_GetGuildMOTDReply` | 🔴 Not-Set | | | -| `OP_GetGuildsList` | 🔴 Not-Set | | | -| `OP_GiveMoney` | 🔴 Not-Set | | | -| `OP_GMApproval` | 🔴 Not-Set | | | -| `OP_GMBecomeNPC` | 🔴 Not-Set | | | -| `OP_GMDelCorpse` | 🔴 Not-Set | | | -| `OP_GMEmoteZone` | 🔴 Not-Set | | | -| `OP_GMEndTraining` | 🟡 Unverified | | | -| `OP_GMEndTrainingResponse` | 🔴 Not-Set | | | -| `OP_GMFind` | 🔴 Not-Set | | | -| `OP_GMGoto` | 🔴 Not-Set | | | -| `OP_GMHideMe` | 🔴 Not-Set | | | -| `OP_GMKick` | 🔴 Not-Set | | | -| `OP_GMKill` | 🔴 Not-Set | | | -| `OP_GMLastName` | 🔴 Not-Set | | | -| `OP_GMNameChange` | 🔴 Not-Set | | | -| `OP_GMSearchCorpse` | 🔴 Not-Set | | | -| `OP_GMServers` | 🔴 Not-Set | | | -| `OP_GMSummon` | 🔴 Not-Set | | | -| `OP_GMToggle` | 🔴 Not-Set | | | -| `OP_GMTraining` | 🟡 Unverified | | | -| `OP_GMTrainSkill` | 🟡 Unverified | | | -| `OP_GMTrainSkillConfirm` | 🟡 Unverified | | | -| `OP_GMZoneRequest` | 🔴 Not-Set | | | -| `OP_GMZoneRequest2` | 🔴 Not-Set | | | -| `OP_GroundSpawn` | 🟢 Verified | | | -| `OP_GroupAcknowledge` | 🔴 Not-Set | | | -| `OP_GroupCancelInvite` | 🔴 Not-Set | | | -| `OP_GroupDelete` | 🔴 Not-Set | | | -| `OP_GroupDisband` | 🟡 Unverified | | | -| `OP_GroupDisbandOther` | 🔴 Not-Set | | | -| `OP_GroupDisbandYou` | 🔴 Not-Set | | | -| `OP_GroupFollow` | 🔴 Not-Set | | | -| `OP_GroupFollow2` | 🔴 Not-Set | | | -| `OP_GroupInvite` | 🟡 Unverified | | | -| `OP_GroupInvite2` | 🔴 Not-Set | | | -| `OP_GroupLeaderChange` | 🔴 Not-Set | | | -| `OP_GroupLeadershipAAUpdate` | 🔴 Not-Set | | | -| `OP_GroupMakeLeader` | 🔴 Not-Set | | | -| `OP_GroupMentor` | 🔴 Not-Set | | | -| `OP_GroupRoles` | 🔴 Not-Set | | | -| `OP_GroupUpdate` | 🔴 Not-Set | | | -| `OP_GroupUpdateB` | 🔴 Not-Set | | | -| `OP_GroupUpdateLeaderAA` | 🔴 Not-Set | | | -| `OP_GuildBank` | 🔴 Not-Set | | | -| `OP_GuildBankItemList` | 🔴 Not-Set | | | -| `OP_GuildCreate` | 🔴 Not-Set | | | -| `OP_GuildDelete` | 🔴 Not-Set | | | -| `OP_GuildDeleteGuild` | 🔴 Not-Set | | | -| `OP_GuildDemote` | 🔴 Not-Set | | | -| `OP_GuildInvite` | 🔴 Not-Set | | | -| `OP_GuildInviteAccept` | 🔴 Not-Set | | | -| `OP_GuildLeader` | 🔴 Not-Set | | | -| `OP_GuildManageAdd` | 🔴 Not-Set | | | -| `OP_GuildManageBanker` | 🔴 Not-Set | | | -| `OP_GuildManageRemove` | 🔴 Not-Set | | | -| `OP_GuildManageStatus` | 🔴 Not-Set | | | -| `OP_GuildMemberLevelUpdate` | 🔴 Not-Set | | | -| `OP_GuildMemberList` | 🔴 Not-Set | | | -| `OP_GuildMemberUpdate` | 🔴 Not-Set | | | -| `OP_GuildMemberLevel` | 🔴 Not-Set | | | -| `OP_GuildMemberRankAltBanker` | 🔴 Not-Set | | | -| `OP_GuildMemberPublicNote` | 🔴 Not-Set | | | -| `OP_GuildMemberAdd` | 🔴 Not-Set | | | -| `OP_GuildMemberRename` | 🔴 Not-Set | | | -| `OP_GuildMemberDelete` | 🔴 Not-Set | | | -| `OP_GuildMemberDetails` | 🔴 Not-Set | | | -| `OP_GuildRenameGuild` | 🔴 Not-Set | | | -| `OP_GuildMOTD` | 🔴 Not-Set | | | -| `OP_GuildPeace` | 🔴 Not-Set | | | -| `OP_GuildPromote` | 🔴 Not-Set | | | -| `OP_GuildPublicNote` | 🔴 Not-Set | | | -| `OP_GuildRemove` | 🔴 Not-Set | | | -| `OP_GuildSelectTribute` | 🔴 Not-Set | | | -| `OP_GuildModifyBenefits` | 🔴 Not-Set | | | -| `OP_GuildTributeToggleReq` | 🔴 Not-Set | | | -| `OP_GuildTributeToggleReply` | 🔴 Not-Set | | | -| `OP_GuildOptInOut` | 🔴 Not-Set | | | -| `OP_GuildSaveActiveTributes` | 🔴 Not-Set | | | -| `OP_GuildSendActiveTributes` | 🔴 Not-Set | | | -| `OP_GuildTributeFavorAndTimer` | 🔴 Not-Set | | | -| `OP_GuildsList` | 🔴 Not-Set | | | -| `OP_GuildStatus` | 🔴 Not-Set | | | -| `OP_GuildTributeInfo` | 🔴 Not-Set | | | -| `OP_GuildUpdate` | 🔴 Not-Set | | | -| `OP_GuildTributeDonateItem` | 🔴 Not-Set | | | -| `OP_GuildTributeDonatePlat` | 🔴 Not-Set | | | -| `OP_GuildWar` | 🔴 Not-Set | | | -| `OP_Heartbeat` | 🔴 Not-Set | | | -| `OP_Hide` | 🟡 Unverified | | | -| `OP_HideCorpse` | 🟡 Unverified | | | -| `OP_HPUpdate` | 🟡 Unverified | | | -| `OP_Illusion` | 🟡 Unverified | | | -| `OP_IncreaseStats` | 🟡 Unverified | | | -| `OP_InitialHPUpdate` | 🔴 Not-Set | | | -| `OP_InitialMobHealth` | 🔴 Not-Set | | | -| `OP_InspectAnswer` | 🔴 Not-Set | | | -| `OP_InspectBuffs` | 🔴 Not-Set | | | -| `OP_InspectMessageUpdate` | 🔴 Not-Set | | | -| `OP_InspectRequest` | 🔴 Not-Set | | | -| `OP_InstillDoubt` | 🟡 Unverified | | | -| `OP_InterruptCast` | 🟡 Unverified | | | -| `OP_InvokeChangePetName` | 🔴 Not-Set | | | -| `OP_InvokeChangePetNameImmediate` | 🔴 Not-Set | | | -| `OP_InvokeNameChangeImmediate` | 🔴 Not-Set | | | -| `OP_InvokeNameChangeLazy` | 🔴 Not-Set | | | -| `OP_ItemLinkClick` | 🔴 Not-Set | | | -| `OP_ItemLinkResponse` | 🔴 Not-Set | | | -| `OP_ItemLinkText` | 🔴 Not-Set | | | -| `OP_ItemName` | 🔴 Not-Set | | | -| `OP_ItemPacket` | 🟡 Unverified | | | -| `OP_ItemPreview` | 🔴 Not-Set | | | -| `OP_ItemPreviewRequest` | 🔴 Not-Set | | | -| `OP_ItemRecastDelay` | 🟡 Unverified | | | -| `OP_ItemVerifyReply` | 🟡 Unverified | | | -| `OP_ItemVerifyRequest` | 🟡 Unverified | | | -| `OP_ItemViewUnknown` | 🔴 Not-Set | | | -| `OP_Jump` | 🟡 Unverified | | | -| `OP_KeyRing` | 🔴 Not-Set | | | -| `OP_KickPlayers` | 🟡 Unverified | | | -| `OP_KnowledgeBase` | 🔴 Not-Set | | | -| `OP_LDoNButton` | 🔴 Not-Set | | | -| `OP_LDoNDisarmTraps` | 🔴 Not-Set | | | -| `OP_LDoNInspect` | 🔴 Not-Set | | | -| `OP_LDoNOpen` | 🟡 Unverified | | | -| `OP_LDoNPickLock` | 🟡 Unverified | | | -| `OP_LDoNSenseTraps` | 🟡 Unverified | | | -| `OP_LeadershipExpToggle` | 🔴 Not-Set | | | -| `OP_LeadershipExpUpdate` | 🔴 Not-Set | | | -| `OP_LeaveAdventure` | 🔴 Not-Set | | | -| `OP_LeaveBoat` | 🟡 Unverified | | | -| `OP_LevelAppearance` | 🟡 Unverified | | | -| `OP_LevelUpdate` | 🟢 Verified | | | -| `OP_LFGAppearance` | 🔴 Not-Set | | | -| `OP_LFGCommand` | 🔴 Not-Set | | | -| `OP_LFGGetMatchesRequest` | 🔴 Not-Set | | | -| `OP_LFGGetMatchesResponse` | 🔴 Not-Set | | | -| `OP_LFGResponse` | 🔴 Not-Set | | | -| `OP_LFGuild` | 🔴 Not-Set | | | -| `OP_LFPCommand` | 🔴 Not-Set | | | -| `OP_LFPGetMatchesRequest` | 🔴 Not-Set | | | -| `OP_LFPGetMatchesResponse` | 🔴 Not-Set | | | -| `OP_LinkedReuse` | 🟡 Unverified | | | -| `OP_LoadSpellSet` | 🔴 Not-Set | | | -| `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` | 🟡 Unverified | | | -| `OP_LogoutReply` | 🔴 Not-Set | | | -| `OP_LogServer` | 🟢 Verified | Mostly unused values | | -| `OP_LootComplete` | 🟡 Unverified | | | -| `OP_LootItem` | 🟡 Unverified | | | -| `OP_LootRequest` | 🟡 Unverified | | | -| `OP_ManaChange` | 🟡 Unverified | | | -| `OP_ManaUpdate` | 🔴 Not-Set | | | -| `OP_MarkNPC` | 🔴 Not-Set | | | -| `OP_MarkRaidNPC` | 🔴 Not-Set | | | -| `OP_Marquee` | 🟡 Unverified | | | -| `OP_MemorizeSpell` | 🟡 Unverified | | | -| `OP_Mend` | 🟡 Unverified | | | -| `OP_MendHPUpdate` | 🔴 Not-Set | | | -| `OP_MercenaryAssign` | 🔴 Not-Set | | | -| `OP_MercenaryCommand` | 🔴 Not-Set | | | -| `OP_MercenaryDataRequest` | 🔴 Not-Set | | | -| `OP_MercenaryDataResponse` | 🔴 Not-Set | | | -| `OP_MercenaryDataUpdate` | 🔴 Not-Set | | | -| `OP_MercenaryDataUpdateRequest` | 🔴 Not-Set | | | -| `OP_MercenaryDismiss` | 🔴 Not-Set | | | -| `OP_MercenaryHire` | 🔴 Not-Set | | | -| `OP_MercenarySuspendRequest` | 🔴 Not-Set | | | -| `OP_MercenarySuspendResponse` | 🔴 Not-Set | | | -| `OP_MercenaryTimer` | 🔴 Not-Set | | | -| `OP_MercenaryTimerRequest` | 🔴 Not-Set | | | -| `OP_MercenaryUnknown1` | 🔴 Not-Set | | | -| `OP_MercenaryUnsuspendResponse` | 🔴 Not-Set | | | -| `OP_MerchantBulkItems` | 🔴 Not-Set | | | -| `OP_MobEnduranceUpdate` | 🔴 Not-Set | | | -| `OP_MobHealth` | 🟡 Unverified | | | -| `OP_MobManaUpdate` | 🔴 Not-Set | | | -| `OP_MobRename` | 🔴 Not-Set | | | -| `OP_MobUpdate` | 🔴 Not-Set | | | -| `OP_MoneyOnCorpse` | 🟡 Unverified | | | -| `OP_MoneyUpdate` | 🟡 Unverified | | | -| `OP_MOTD` | 🟢 Verified | | | -| `OP_MoveCoin` | 🟡 Unverified | | | -| `OP_MoveDoor` | 🟡 Unverified | | | -| `OP_MoveItem` | 🟡 Unverified | | | -| `OP_MoveMultipleItems` | 🟡 Unverified | | | -| `OP_MoveLogDisregard` | 🔴 Not-Set | | | -| `OP_MoveLogRequest` | 🔴 Not-Set | | | -| `OP_MultiLineMsg` | 🔴 Not-Set | | | -| `OP_NewSpawn` | 🟢 Verified | Deprecated in the client, already handled in emu | | -| `OP_NewTitlesAvailable` | 🔴 Not-Set | | | -| `OP_NewZone` | 🟢 Verified | | | -| `OP_NPCMoveUpdate` | 🔴 Not-Set | | | -| `OP_OnLevelMessage` | 🟡 Unverified | | | -| `OP_OpenContainer` | 🟡 Unverified | | | -| `OP_OpenDiscordMerchant` | 🔴 Not-Set | | | -| `OP_OpenGuildTributeMaster` | 🔴 Not-Set | | | -| `OP_OpenInventory` | 🔴 Not-Set | | | -| `OP_OpenTributeMaster` | 🔴 Not-Set | | | -| `OP_PDeletePetition` | 🔴 Not-Set | | | -| `OP_PetBuffWindow` | 🔴 Not-Set | | | -| `OP_PetCommands` | 🔴 Not-Set | | | -| `OP_PetCommandState` | 🔴 Not-Set | | | -| `OP_PetHoTT` | 🔴 Not-Set | | | -| `OP_Petition` | 🔴 Not-Set | | | -| `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` | 🟡 Unverified | | | -| `OP_PickZone` | 🔴 Not-Set | | | -| `OP_PickZoneWindow` | 🔴 Not-Set | | | -| `OP_PlayerProfile` | 🟢 Verified | | | -| `OP_PlayerStateAdd` | 🟡 Unverified | | | -| `OP_PlayerStateRemove` | 🟡 Unverified | | | -| `OP_PlayEverquestRequest` | 🔴 Not-Set | | | -| `OP_PlayEverquestResponse` | 🔴 Not-Set | | | -| `OP_PlayMP3` | 🟡 Unverified | | | -| `OP_Poll` | 🔴 Not-Set | | | -| `OP_PollResponse` | 🔴 Not-Set | | | -| `OP_PopupResponse` | 🟡 Unverified | | | -| `OP_PostEnterWorld` | 🟢 Verified | | | -| `OP_PotionBelt` | 🔴 Not-Set | | | -| `OP_PreLogoutReply` | 🔴 Not-Set | | | -| `OP_PurchaseLeadershipAA` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardDetailsReply` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardDetailsRequest` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardReply` | 🔴 Not-Set | | | -| `OP_PVPLeaderBoardRequest` | 🔴 Not-Set | | | -| `OP_PVPStats` | 🔴 Not-Set | | | -| `OP_QueryResponseThing` | 🔴 Not-Set | | | -| `OP_QueryUCSServerStatus` | 🟡 Unverified | | | -| `OP_RaidDelegateAbility` | 🔴 Not-Set | | | -| `OP_RaidClearNPCMarks` | 🔴 Not-Set | | | -| `OP_RaidInvite` | 🔴 Not-Set | | | -| `OP_RaidJoin` | 🔴 Not-Set | | | -| `OP_RaidUpdate` | 🔴 Not-Set | | | -| `OP_RandomNameGenerator` | 🟢 Verified | The client no longer sends this packet (random name generation is done entirely in the client). The client will still accept this packet to set name (emu doesn't do this, but it's always been supported) | | -| `OP_RandomReply` | 🟡 Unverified | | | -| `OP_RandomReq` | 🟡 Unverified | | | -| `OP_ReadBook` | 🟡 Unverified | | | -| `OP_RecipeAutoCombine` | 🟡 Unverified | | | -| `OP_RecipeDetails` | 🟡 Unverified | | | -| `OP_RecipeReply` | 🟡 Unverified | | | -| `OP_RecipesFavorite` | 🟡 Unverified | | | -| `OP_RecipesSearch` | 🟡 Unverified | | | -| `OP_ReclaimCrystals` | 🔴 Not-Set | | | -| `OP_ReloadUI` | 🔴 Not-Set | | | -| `OP_RemoveAllDoors` | 🟡 Unverified | | | -| `OP_RemoveBlockedBuffs` | 🟢 Verified | | | -| `OP_RemoveNimbusEffect` | 🟡 Unverified | | | -| `OP_RemoveTrap` | 🔴 Not-Set | | | -| `OP_Report` | 🟡 Unverified | | | -| `OP_ReqClientSpawn` | 🟢 Verified | | | -| `OP_ReqNewZone` | 🟢 Verified | Client does not send this (in LS or TOB), but it does receive it. emu does not send it | | -| `OP_RequestClientZoneChange` | 🟢 Verified | parity with RoF2, there's a string that gets passed to teleport at the end that's not known | | -| `OP_RequestDuel` | 🔴 Not-Set | | | -| `OP_RequestGuildTributes` | 🔴 Not-Set | | | -| `OP_RequestKnowledgeBase` | 🔴 Not-Set | | | -| `OP_RequestTitles` | 🔴 Not-Set | | | -| `OP_RespawnWindow` | 🟡 Unverified | | | -| `OP_RespondAA` | 🟡 Unverified | | | -| `OP_RestState` | 🟡 Unverified | | | -| `OP_Rewind` | 🟡 Unverified | | | -| `OP_RezzAnswer` | 🔴 Not-Set | | | -| `OP_RezzComplete` | 🔴 Not-Set | | | -| `OP_RezzRequest` | 🔴 Not-Set | | | -| `OP_Sacrifice` | 🟡 Unverified | | | -| `OP_SafeFallSuccess` | 🟡 Unverified | | | -| `OP_SafePoint` | 🔴 Not-Set | | | -| `OP_Save` | 🟡 Unverified | | | -| `OP_SaveOnZoneReq` | 🟡 Unverified | | | -| `OP_SelectTribute` | 🔴 Not-Set | | | -| `OP_SendAAStats` | 🟡 Unverified | | | -| `OP_SendAATable` | 🟡 Unverified | | | -| `OP_SendCharInfo` | 🟢 Verified | | | -| `OP_SendExpZonein` | 🟡 Unverified | | | -| `OP_SendFindableNPCs` | 🔴 Not-Set | | | -| `OP_SendGuildTributes` | 🔴 Not-Set | | | -| `OP_SendLoginInfo` | 🟢 Verified | | | -| `OP_SendMaxCharacters` | 🟢 Verified | | | -| `OP_SendMembership` | 🟢 Verified | | | -| `OP_SendMembershipDetails` | 🟢 Verified | The struct is correct, will need reversing for actual option keys/values | | -| `OP_SendSystemStats` | 🔴 Not-Set | | | -| `OP_SendTitleList` | 🔴 Not-Set | | | -| `OP_SendTributes` | 🔴 Not-Set | | | -| `OP_SendZonepoints` | 🟢 Verified | | | -| `OP_SenseHeading` | 🟡 Unverified | | | -| `OP_SenseTraps` | 🟡 Unverified | | | -| `OP_ServerListRequest` | 🔴 Not-Set | | | -| `OP_ServerListResponse` | 🔴 Not-Set | | | -| `OP_SessionReady` | 🔴 Not-Set | | | -| `OP_SetChatServer` | 🔴 Not-Set | | | -| `OP_SetChatServer2` | 🟢 Verified | | | -| `OP_SetFace` | 🔴 Not-Set | | | -| `OP_SetGroupTarget` | 🔴 Not-Set | | | -| `OP_SetGuildMOTD` | 🔴 Not-Set | | | -| `OP_SetGuildRank` | 🔴 Not-Set | | | -| `OP_SetRunMode` | 🟡 Unverified | | | -| `OP_SetServerFilter` | 🟡 Unverified | | | -| `OP_SetStartCity` | 🔴 Not-Set | | | -| `OP_SetTitle` | 🔴 Not-Set | | | -| `OP_SetTitleReply` | 🔴 Not-Set | | | -| `OP_SharedTaskMemberList` | 🔴 Not-Set | | | -| `OP_SharedTaskAddPlayer` | 🔴 Not-Set | | | -| `OP_SharedTaskRemovePlayer` | 🔴 Not-Set | | | -| `OP_SharedTaskMakeLeader` | 🔴 Not-Set | | | -| `OP_SharedTaskMemberInvite` | 🔴 Not-Set | | | -| `OP_SharedTaskInvite` | 🔴 Not-Set | | | -| `OP_SharedTaskInviteResponse` | 🔴 Not-Set | | | -| `OP_SharedTaskAcceptNew` | 🔴 Not-Set | | | -| `OP_SharedTaskMemberChange` | 🔴 Not-Set | | | -| `OP_SharedTaskPlayerList` | 🔴 Not-Set | | | -| `OP_SharedTaskSelectWindow` | 🔴 Not-Set | | | -| `OP_SharedTaskQuit` | 🔴 Not-Set | | | -| `OP_TaskTimers` | 🔴 Not-Set | | | -| `OP_Shielding` | 🔴 Not-Set | | | -| `OP_ShopDelItem` | 🟡 Unverified | | | -| `OP_ShopEnd` | 🟡 Unverified | | | -| `OP_ShopEndConfirm` | 🟡 Unverified | | | -| `OP_ShopItem` | 🔴 Not-Set | | | -| `OP_ShopPlayerBuy` | 🟡 Unverified | | | -| `OP_ShopPlayerSell` | 🟡 Unverified | | | -| `OP_ShopSendParcel` | 🟡 Unverified | | | -| `OP_ShopDeleteParcel` | 🟡 Unverified | | | -| `OP_ShopRespondParcel` | 🔴 Not-Set | | | -| `OP_ShopRetrieveParcel` | 🟡 Unverified | | | -| `OP_ShopParcelIcon` | 🟡 Unverified | | | -| `OP_ShopRequest` | 🟡 Unverified | | | -| `OP_SimpleMessage` | 🟡 Unverified | | | -| `OP_SkillUpdate` | 🟡 Unverified | | | -| `OP_Sneak` | 🟡 Unverified | | | -| `OP_Some3ByteHPUpdate` | 🔴 Not-Set | | | -| `OP_Some6ByteHPUpdate` | 🔴 Not-Set | | | -| `OP_SomeItemPacketMaybe` | 🔴 Not-Set | | | -| `OP_Sound` | 🟡 Unverified | | | -| `OP_SpawnAppearance` | 🟢 Verified | | | -| `OP_SpawnDoor` | 🟢 Verified | | | -| `OP_SpawnPositionUpdate` | 🔴 Not-Set | | | -| `OP_SpecialMesg` | 🟡 Unverified | | | -| `OP_SpellEffect` | 🟡 Unverified | | | -| `OP_Split` | 🟡 Unverified | | | -| `OP_Stamina` | 🟢 Verified | These values are 0-32k instead of 0-127 | | -| `OP_Stun` | 🟡 Unverified | | | -| `OP_Surname` | 🔴 Not-Set | | | -| `OP_SwapSpell` | 🟡 Unverified | | | -| `OP_SystemFingerprint` | 🔴 Not-Set | | | -| `OP_TargetBuffs` | 🔴 Not-Set | | | -| `OP_TargetCommand` | 🟡 Unverified | | | -| `OP_TargetHoTT` | 🔴 Not-Set | | | -| `OP_TargetMouse` | 🟡 Unverified | | | -| `OP_TargetReject` | 🔴 Not-Set | | | -| `OP_TaskActivity` | 🔴 Not-Set | | | -| `OP_TaskActivityComplete` | 🔴 Not-Set | | | -| `OP_TaskDescription` | 🔴 Not-Set | | | -| `OP_TaskHistoryReply` | 🔴 Not-Set | | | -| `OP_TaskHistoryRequest` | 🔴 Not-Set | | | -| `OP_TaskRequestTimer` | 🔴 Not-Set | | | -| `OP_TaskSelectWindow` | 🔴 Not-Set | | | -| `OP_Taunt` | 🟡 Unverified | | | -| `OP_TestBuff` | 🔴 Not-Set | | | -| `OP_TGB` | 🔴 Not-Set | | | -| `OP_TimeOfDay` | 🟢 Verified | | | -| `OP_Track` | 🟡 Unverified | | | -| `OP_TrackTarget` | 🟡 Unverified | | | -| `OP_TrackUnknown` | 🟡 Unverified | | | -| `OP_TradeAcceptClick` | 🟡 Unverified | | | -| `OP_TradeBusy` | 🟡 Unverified | | | -| `OP_TradeCoins` | 🟡 Unverified | | | -| `OP_TradeMoneyUpdate` | 🟡 Unverified | | | -| `OP_Trader` | 🔴 Not-Set | | | -| `OP_TraderBulkSend` | 🔴 Not-Set | | | -| `OP_TraderBuy` | 🔴 Not-Set | | | -| `OP_TraderDelItem` | 🔴 Not-Set | | | -| `OP_TradeRequest` | 🟡 Unverified | | | -| `OP_TradeRequestAck` | 🟡 Unverified | | | -| `OP_TraderItemUpdate` | 🔴 Not-Set | | | -| `OP_TraderShop` | 🔴 Not-Set | | | -| `OP_TradeSkillCombine` | 🟡 Unverified | | | -| `OP_TradeSkillRecipeInspect` | 🔴 Not-Set | | | -| `OP_Translocate` | 🟡 Unverified | | | -| `OP_TributeInfo` | 🔴 Not-Set | | | -| `OP_TributeItem` | 🔴 Not-Set | | | -| `OP_TributeMoney` | 🔴 Not-Set | | | -| `OP_TributeNPC` | 🔴 Not-Set | | | -| `OP_TributePointUpdate` | 🔴 Not-Set | | | -| `OP_TributeTimer` | 🔴 Not-Set | | | -| `OP_TributeToggle` | 🔴 Not-Set | | | -| `OP_TributeUpdate` | 🔴 Not-Set | | | -| `OP_Untargetable` | 🟡 Unverified | | | -| `OP_UpdateAA` | 🟡 Unverified | | | -| `OP_UpdateAura` | 🔴 Not-Set | | | -| `OP_UpdateLeadershipAA` | 🔴 Not-Set | | | -| `OP_VetClaimReply` | 🔴 Not-Set | | | -| `OP_VetClaimRequest` | 🔴 Not-Set | | | -| `OP_VetRewardsAvaliable` | 🔴 Not-Set | | | -| `OP_VoiceMacroIn` | 🟡 Unverified | | | -| `OP_VoiceMacroOut` | 🟡 Unverified | | | -| `OP_WeaponEquip1` | 🔴 Not-Set | | | -| `OP_WearChange` | 🟡 Unverified | | | -| `OP_Weather` | 🟢 Verified | | | -| `OP_Weblink` | 🟡 Unverified | | | -| `OP_WhoAllRequest` | 🟡 Unverified | | | -| `OP_WhoAllResponse` | 🟡 Unverified | | | -| `OP_World_Client_CRC1` | 🟢 Verified | | | -| `OP_World_Client_CRC2` | 🟢 Verified | | | -| `OP_World_Client_CRC3` | 🟢 Verified | | | -| `OP_WorldClientReady` | 🟢 Verified | | | -| `OP_WorldComplete` | 🟢 Verified | | | -| `OP_WorldLogout` | 🔴 Not-Set | | | -| `OP_WorldObjectsSent` | 🟢 Verified | | | -| `OP_WorldUnknown001` | 🟢 Verified | SetServerTime. emu doesn't currently send it so setting it to verified, but the reference is 0x140292550 | | -| `OP_XTargetAutoAddHaters` | 🔴 Not-Set | | | -| `OP_XTargetOpen` | 🔴 Not-Set | | | -| `OP_XTargetOpenResponse` | 🔴 Not-Set | | | -| `OP_XTargetRequest` | 🔴 Not-Set | | | -| `OP_XTargetResponse` | 🔴 Not-Set | | | -| `OP_YellForHelp` | 🟡 Unverified | | | -| `OP_ZoneChange` | 🟢 Verified | | | -| `OP_ZoneComplete` | 🔴 Not-Set | | | -| `OP_ZoneEntry` | 🟢 Verified | unknown fields in C->S struct are various CRCs, emu doesn't use them | | -| `OP_ZoneGuildList` | 🔴 Not-Set | | | -| `OP_ZoneInUnknown` | 🔴 Not-Set | | | -| `OP_ZonePlayerToBind` | 🟡 Unverified | | | -| `OP_ZoneServerInfo` | 🟢 Verified | | | -| `OP_ZoneServerReady` | 🔴 Not-Set | | | -| `OP_ZoneSpawns` | 🟢 Verified | This is deprecated in the client (and emu never sends it directly) | | -| `OP_ZoneUnavail` | 🟢 Verified | The client discards all content of this packet | | -| `OP_ResetAA` | 🟡 Unverified | | | -| `OP_UnderWorld` | 🟡 Unverified | | | +| Opcode | Status | Notes | Working On | +|:----------------------------------|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------| +| `OP_AAAction` | 🟡 Unverified | | | +| `OP_AAExpUpdate` | 🟡 Unverified | | | +| `OP_AcceptNewTask` | 🔴 Not-Set | | | +| `OP_AckPacket` | 🟢 Verified | | | +| `OP_Action` | 🟡 Unverified | | | +| `OP_Action2` | 🔴 Not-Set | | | +| `OP_AddNimbusEffect` | 🟡 Unverified | | | +| `OP_AdventureData` | 🔴 Not-Set | | | +| `OP_AdventureDetails` | 🔴 Not-Set | | | +| `OP_AdventureFinish` | 🔴 Not-Set | | | +| `OP_AdventureInfo` | 🔴 Not-Set | | | +| `OP_AdventureInfoRequest` | 🔴 Not-Set | | | +| `OP_AdventureLeaderboardReply` | 🔴 Not-Set | | | +| `OP_AdventureLeaderboardRequest` | 🔴 Not-Set | | | +| `OP_AdventureMerchantPurchase` | 🔴 Not-Set | | | +| `OP_AdventureMerchantRequest` | 🔴 Not-Set | | | +| `OP_AdventureMerchantResponse` | 🔴 Not-Set | | | +| `OP_AdventureMerchantSell` | 🔴 Not-Set | | | +| `OP_AdventurePointsUpdate` | 🔴 Not-Set | | | +| `OP_AdventureRequest` | 🔴 Not-Set | | | +| `OP_AdventureStatsReply` | 🔴 Not-Set | | | +| `OP_AdventureStatsRequest` | 🔴 Not-Set | | | +| `OP_AdventureUpdate` | 🔴 Not-Set | | | +| `OP_AggroMeterLockTarget` | 🔴 Not-Set | | | +| `OP_AggroMeterTargetInfo` | 🔴 Not-Set | | | +| `OP_AggroMeterUpdate` | 🔴 Not-Set | | | +| `OP_AltCurrency` | 🔴 Not-Set | | | +| `OP_AltCurrencyMerchantReply` | 🔴 Not-Set | | | +| `OP_AltCurrencyMerchantRequest` | 🔴 Not-Set | | | +| `OP_AltCurrencyPurchase` | 🔴 Not-Set | | | +| `OP_AltCurrencyReclaim` | 🔴 Not-Set | | | +| `OP_AltCurrencySell` | 🔴 Not-Set | | | +| `OP_AltCurrencySellSelection` | 🔴 Not-Set | | | +| `OP_Animation` | 🟡 Unverified | | | +| `OP_AnnoyingZoneUnknown` | 🔴 Not-Set | | | +| `OP_ApplyPoison` | 🟡 Unverified | | | +| `OP_ApproveName` | 🟡 Unverified | This takes multiple parameters from the client, and it can take multiple integer values from the server | | +| `OP_ApproveWorld` | 🔴 Not-Set | | | +| `OP_ApproveZone` | 🔴 Not-Set | | | +| `OP_Assist` | 🟡 Unverified | | | +| `OP_AssistGroup` | 🟡 Unverified | | | +| `OP_AugmentInfo` | 🟡 Unverified | | | +| `OP_AugmentItem` | 🟡 Unverified | | | +| `OP_AutoAttack` | 🟡 Unverified | | | +| `OP_AutoAttack2` | 🟡 Unverified | | | +| `OP_AutoFire` | 🟡 Unverified | | | +| `OP_Bandolier` | 🔴 Not-Set | | | +| `OP_BankerChange` | 🟡 Unverified | | | +| `OP_Barter` | 🔴 Not-Set | | | +| `OP_Bazaar` | 🔴 Not-Set | | | +| `OP_BazaarInspect` | 🔴 Not-Set | | | +| `OP_BazaarSearch` | 🔴 Not-Set | | | +| `OP_BecomeCorpse` | 🔴 Not-Set | | | +| `OP_BecomeTrader` | 🔴 Not-Set | | | +| `OP_Begging` | 🟡 Unverified | | | +| `OP_BeginCast` | 🟡 Unverified | | | +| `OP_Bind_Wound` | 🟡 Unverified | | | +| `OP_BlockedBuffs` | 🟢 Verified | | | +| `OP_BoardBoat` | 🟡 Unverified | | | +| `OP_BookButton` | 🟡 Unverified | | | +| `OP_Buff` | 🟡 Unverified | | | +| `OP_BuffCreate` | 🟡 Unverified | | | +| `OP_BuffRemoveRequest` | 🟡 Unverified | | | +| `OP_Bug` | 🟡 Unverified | | | +| `OP_BuyerItems` | 🔴 Not-Set | | | +| `OP_CameraEffect` | 🟡 Unverified | | | +| `OP_Camp` | 🟡 Unverified | | | +| `OP_CancelSneakHide` | 🟡 Unverified | | | +| `OP_CancelTask` | 🔴 Not-Set | | | +| `OP_CancelTrade` | 🟡 Unverified | | | +| `OP_CashReward` | 🟡 Unverified | | | +| `OP_CastSpell` | 🟡 Unverified | | | +| `OP_ChangeSize` | 🟢 Verified | | | +| `OP_ChannelMessage` | 🟡 Unverified | | | +| `OP_ChangePetName` | 🔴 Not-Set | | | +| `OP_CharacterCreate` | 🟢 Verified | Sends heroic type, can be used for something? | | +| `OP_CharacterCreateRequest` | 🟢 Verified | | | +| `OP_CharInventory` | 🟡 Unverified | | | +| `OP_Charm` | 🟡 Unverified | | | +| `OP_ChatMessage` | 🔴 Not-Set | | | +| `OP_ClearAA` | 🟢 Verified | | | +| `OP_ClearBlockedBuffs` | 🟢 Verified | | | +| `OP_ClearLeadershipAbilities` | 🔴 Not-Set | | | +| `OP_ClearNPCMarks` | 🔴 Not-Set | | | +| `OP_ClearObject` | 🟡 Unverified | | | +| `OP_ClearSurname` | 🔴 Not-Set | | | +| `OP_ClickDoor` | 🟡 Unverified | | | +| `OP_ClickObject` | 🟡 Unverified | | | +| `OP_ClickObjectAction` | 🟡 Unverified | | | +| `OP_ClientError` | 🔴 Not-Set | | | +| `OP_ClientReady` | 🟡 Unverified | | | +| `OP_ClientTimeStamp` | 🔴 Not-Set | | | +| `OP_ClientUpdate` | 🟡 Unverified | | | +| `OP_CloseContainer` | 🔴 Not-Set | | | +| `OP_CloseTributeMaster` | 🔴 Not-Set | | | +| `OP_ColoredText` | 🟡 Unverified | | | +| `OP_CombatAbility` | 🟡 Unverified | | | +| `OP_Command` | 🔴 Not-Set | | | +| `OP_CompletedTasks` | 🔴 Not-Set | | | +| `OP_ConfirmDelete` | 🟡 Unverified | | | +| `OP_Consent` | 🟡 Unverified | | | +| `OP_ConsentDeny` | 🟡 Unverified | | | +| `OP_ConsentResponse` | 🟡 Unverified | | | +| `OP_Consider` | 🟡 Unverified | | | +| `OP_ConsiderCorpse` | 🟡 Unverified | | | +| `OP_Consume` | 🟡 Unverified | | | +| `OP_ControlBoat` | 🟡 Unverified | | | +| `OP_CorpseDrag` | 🟡 Unverified | | | +| `OP_CorpseDrop` | 🟡 Unverified | | | +| `OP_CrashDump` | 🔴 Not-Set | | | +| `OP_CrystalCountUpdate` | 🔴 Not-Set | | | +| `OP_CrystalCreate` | 🔴 Not-Set | | | +| `OP_CrystalReclaim` | 🔴 Not-Set | | | +| `OP_CustomTitles` | 🔴 Not-Set | | | +| `OP_Damage` | 🟡 Unverified | | | +| `OP_Death` | 🟡 Unverified | | | +| `OP_DelegateAbility` | 🔴 Not-Set | | | +| `OP_DeleteCharacter` | 🟢 Verified | | | +| `OP_DeleteCharge` | 🟡 Unverified | | | +| `OP_DeleteItem` | 🟡 Unverified | | | +| `OP_DeletePetition` | 🔴 Not-Set | | | +| `OP_DeleteSpawn` | 🟡 Unverified | | | +| `OP_DeleteSpell` | 🟡 Unverified | | | +| `OP_DenyResponse` | 🟡 Unverified | | | +| `OP_Disarm` | 🟡 Unverified | | | +| `OP_DisarmTraps` | 🟡 Unverified | | | +| `OP_DisciplineTimer` | 🟡 Unverified | | | +| `OP_DisciplineUpdate` | 🟡 Unverified | | | +| `OP_DiscordMerchantInventory` | 🔴 Not-Set | | | +| `OP_DoGroupLeadershipAbility` | 🔴 Not-Set | | | +| `OP_DuelDecline` | 🔴 Not-Set | | | +| `OP_DuelAccept` | 🔴 Not-Set | | | +| `OP_DumpName` | 🔴 Not-Set | | | +| `OP_Dye` | 🔴 Not-Set | | | +| `OP_DynamicWall` | 🔴 Not-Set | | | +| `OP_DzAddPlayer` | 🔴 Not-Set | | | +| `OP_DzChooseZone` | 🔴 Not-Set | | | +| `OP_DzChooseZoneReply` | 🔴 Not-Set | | | +| `OP_DzCompass` | 🔴 Not-Set | | | +| `OP_DzExpeditionEndsWarning` | 🔴 Not-Set | | | +| `OP_DzExpeditionInfo` | 🔴 Not-Set | | | +| `OP_DzExpeditionInvite` | 🔴 Not-Set | | | +| `OP_DzExpeditionInviteResponse` | 🔴 Not-Set | | | +| `OP_DzExpeditionLockoutTimers` | 🔴 Not-Set | | | +| `OP_DzListTimers` | 🔴 Not-Set | | | +| `OP_DzMakeLeader` | 🔴 Not-Set | | | +| `OP_DzMemberList` | 🔴 Not-Set | | | +| `OP_DzMemberListName` | 🔴 Not-Set | | | +| `OP_DzMemberListStatus` | 🔴 Not-Set | | | +| `OP_DzPlayerList` | 🔴 Not-Set | | | +| `OP_DzQuit` | 🔴 Not-Set | | | +| `OP_DzRemovePlayer` | 🔴 Not-Set | | | +| `OP_DzSetLeaderName` | 🔴 Not-Set | | | +| `OP_DzSwapPlayer` | 🔴 Not-Set | | | +| `OP_Emote` | 🔴 Not-Set | | | +| `OP_EndLootRequest` | 🟡 Unverified | | | +| `OP_EnduranceUpdate` | 🔴 Not-Set | | | +| `OP_EnterChat` | 🔴 Not-Set | | | +| `OP_EnterWorld` | 🟢 Verified | | | +| `OP_EnvDamage` | 🟡 Unverified | | | +| `OP_EvolveItem` | 🔴 Not-Set | | | +| `OP_ExpansionInfo` | 🟢 Verified | Updated from u32 to u64 and works now | | +| `OP_ExpUpdate` | 🟡 Unverified | | | +| `OP_FaceChange` | 🔴 Not-Set | | | +| `OP_Feedback` | 🔴 Not-Set | | | +| `OP_FeignDeath` | 🟡 Unverified | | | +| `OP_FellowshipUpdate` | 🔴 Not-Set | | | +| `OP_FindPersonReply` | 🔴 Not-Set | | | +| `OP_FindPersonRequest` | 🔴 Not-Set | | | +| `OP_FinishTrade` | 🟡 Unverified | | | +| `OP_FinishWindow` | 🟡 Unverified | | | +| `OP_FinishWindow2` | 🟡 Unverified | | | +| `OP_Fishing` | 🟡 Unverified | | | +| `OP_Fling` | 🟡 Unverified | | | +| `OP_FloatListThing` | 🟢 Verified | Movement History. Sent from client, but emu doesn't use it so setting it as varified. Reference is 0x1402FFAD0 | | +| `OP_Forage` | 🟡 Unverified | | | +| `OP_ForceFindPerson` | 🔴 Not-Set | | | +| `OP_FormattedMessage` | 🟡 Unverified | | | +| `OP_FriendsWho` | 🟡 Unverified | | | +| `OP_GetGuildMOTD` | 🔴 Not-Set | | | +| `OP_GetGuildMOTDReply` | 🔴 Not-Set | | | +| `OP_GetGuildsList` | 🔴 Not-Set | | | +| `OP_GiveMoney` | 🔴 Not-Set | | | +| `OP_GMApproval` | 🔴 Not-Set | | | +| `OP_GMBecomeNPC` | 🔴 Not-Set | | | +| `OP_GMDelCorpse` | 🔴 Not-Set | | | +| `OP_GMEmoteZone` | 🔴 Not-Set | | | +| `OP_GMEndTraining` | 🟡 Unverified | | | +| `OP_GMEndTrainingResponse` | 🔴 Not-Set | | | +| `OP_GMFind` | 🔴 Not-Set | | | +| `OP_GMGoto` | 🔴 Not-Set | | | +| `OP_GMHideMe` | 🔴 Not-Set | | | +| `OP_GMKick` | 🔴 Not-Set | | | +| `OP_GMKill` | 🔴 Not-Set | | | +| `OP_GMLastName` | 🔴 Not-Set | | | +| `OP_GMNameChange` | 🔴 Not-Set | | | +| `OP_GMSearchCorpse` | 🔴 Not-Set | | | +| `OP_GMServers` | 🔴 Not-Set | | | +| `OP_GMSummon` | 🔴 Not-Set | | | +| `OP_GMToggle` | 🔴 Not-Set | | | +| `OP_GMTraining` | 🟡 Unverified | | | +| `OP_GMTrainSkill` | 🟡 Unverified | | | +| `OP_GMTrainSkillConfirm` | 🟡 Unverified | | | +| `OP_GMZoneRequest` | 🔴 Not-Set | | | +| `OP_GMZoneRequest2` | 🔴 Not-Set | | | +| `OP_GroundSpawn` | 🟢 Verified | | | +| `OP_GroupAcknowledge` | 🔴 Not-Set | | | +| `OP_GroupCancelInvite` | 🔴 Not-Set | | | +| `OP_GroupDelete` | 🔴 Not-Set | | | +| `OP_GroupDisband` | 🟡 Unverified | | | +| `OP_GroupDisbandOther` | 🔴 Not-Set | | | +| `OP_GroupDisbandYou` | 🔴 Not-Set | | | +| `OP_GroupFollow` | 🔴 Not-Set | | | +| `OP_GroupFollow2` | 🔴 Not-Set | | | +| `OP_GroupInvite` | 🟡 Unverified | | | +| `OP_GroupInvite2` | 🔴 Not-Set | | | +| `OP_GroupLeaderChange` | 🔴 Not-Set | | | +| `OP_GroupLeadershipAAUpdate` | 🔴 Not-Set | | | +| `OP_GroupMakeLeader` | 🔴 Not-Set | | | +| `OP_GroupMentor` | 🔴 Not-Set | | | +| `OP_GroupRoles` | 🔴 Not-Set | | | +| `OP_GroupUpdate` | 🔴 Not-Set | | | +| `OP_GroupUpdateB` | 🔴 Not-Set | | | +| `OP_GroupUpdateLeaderAA` | 🔴 Not-Set | | | +| `OP_GuildBank` | 🔴 Not-Set | | | +| `OP_GuildBankItemList` | 🔴 Not-Set | | | +| `OP_GuildCreate` | 🔴 Not-Set | | | +| `OP_GuildDelete` | 🔴 Not-Set | | | +| `OP_GuildDeleteGuild` | 🔴 Not-Set | | | +| `OP_GuildDemote` | 🔴 Not-Set | | | +| `OP_GuildInvite` | 🔴 Not-Set | | | +| `OP_GuildInviteAccept` | 🔴 Not-Set | | | +| `OP_GuildLeader` | 🔴 Not-Set | | | +| `OP_GuildManageAdd` | 🔴 Not-Set | | | +| `OP_GuildManageBanker` | 🔴 Not-Set | | | +| `OP_GuildManageRemove` | 🔴 Not-Set | | | +| `OP_GuildManageStatus` | 🔴 Not-Set | | | +| `OP_GuildMemberLevelUpdate` | 🔴 Not-Set | | | +| `OP_GuildMemberList` | 🔴 Not-Set | | | +| `OP_GuildMemberUpdate` | 🔴 Not-Set | | | +| `OP_GuildMemberLevel` | 🔴 Not-Set | | | +| `OP_GuildMemberRankAltBanker` | 🔴 Not-Set | | | +| `OP_GuildMemberPublicNote` | 🔴 Not-Set | | | +| `OP_GuildMemberAdd` | 🔴 Not-Set | | | +| `OP_GuildMemberRename` | 🔴 Not-Set | | | +| `OP_GuildMemberDelete` | 🔴 Not-Set | | | +| `OP_GuildMemberDetails` | 🔴 Not-Set | | | +| `OP_GuildRenameGuild` | 🔴 Not-Set | | | +| `OP_GuildMOTD` | 🔴 Not-Set | | | +| `OP_GuildPeace` | 🔴 Not-Set | | | +| `OP_GuildPromote` | 🔴 Not-Set | | | +| `OP_GuildPublicNote` | 🔴 Not-Set | | | +| `OP_GuildRemove` | 🔴 Not-Set | | | +| `OP_GuildSelectTribute` | 🔴 Not-Set | | | +| `OP_GuildModifyBenefits` | 🔴 Not-Set | | | +| `OP_GuildTributeToggleReq` | 🔴 Not-Set | | | +| `OP_GuildTributeToggleReply` | 🔴 Not-Set | | | +| `OP_GuildOptInOut` | 🔴 Not-Set | | | +| `OP_GuildSaveActiveTributes` | 🔴 Not-Set | | | +| `OP_GuildSendActiveTributes` | 🔴 Not-Set | | | +| `OP_GuildTributeFavorAndTimer` | 🔴 Not-Set | | | +| `OP_GuildsList` | 🔴 Not-Set | | | +| `OP_GuildStatus` | 🔴 Not-Set | | | +| `OP_GuildTributeInfo` | 🔴 Not-Set | | | +| `OP_GuildUpdate` | 🔴 Not-Set | | | +| `OP_GuildTributeDonateItem` | 🔴 Not-Set | | | +| `OP_GuildTributeDonatePlat` | 🔴 Not-Set | | | +| `OP_GuildWar` | 🔴 Not-Set | | | +| `OP_Heartbeat` | 🔴 Not-Set | | | +| `OP_Hide` | 🟡 Unverified | | | +| `OP_HideCorpse` | 🟡 Unverified | | | +| `OP_HPUpdate` | 🟡 Unverified | | | +| `OP_Illusion` | 🟡 Unverified | | | +| `OP_IncreaseStats` | 🟡 Unverified | | | +| `OP_InitialHPUpdate` | 🔴 Not-Set | | | +| `OP_InitialMobHealth` | 🔴 Not-Set | | | +| `OP_InspectAnswer` | 🔴 Not-Set | | | +| `OP_InspectBuffs` | 🔴 Not-Set | | | +| `OP_InspectMessageUpdate` | 🔴 Not-Set | | | +| `OP_InspectRequest` | 🔴 Not-Set | | | +| `OP_InstillDoubt` | 🟡 Unverified | | | +| `OP_InterruptCast` | 🟡 Unverified | | | +| `OP_InvokeChangePetName` | 🔴 Not-Set | | | +| `OP_InvokeChangePetNameImmediate` | 🔴 Not-Set | | | +| `OP_InvokeNameChangeImmediate` | 🔴 Not-Set | | | +| `OP_InvokeNameChangeLazy` | 🔴 Not-Set | | | +| `OP_ItemLinkClick` | 🔴 Not-Set | | | +| `OP_ItemLinkResponse` | 🔴 Not-Set | | | +| `OP_ItemLinkText` | 🔴 Not-Set | | | +| `OP_ItemName` | 🔴 Not-Set | | | +| `OP_ItemPacket` | 🟡 Unverified | | | +| `OP_ItemPreview` | 🔴 Not-Set | | | +| `OP_ItemPreviewRequest` | 🔴 Not-Set | | | +| `OP_ItemRecastDelay` | 🟡 Unverified | | | +| `OP_ItemVerifyReply` | 🟡 Unverified | | | +| `OP_ItemVerifyRequest` | 🟡 Unverified | | | +| `OP_ItemViewUnknown` | 🔴 Not-Set | | | +| `OP_Jump` | 🟡 Unverified | | | +| `OP_KeyRing` | 🔴 Not-Set | | | +| `OP_KickPlayers` | 🟡 Unverified | | | +| `OP_KnowledgeBase` | 🔴 Not-Set | | | +| `OP_LDoNButton` | 🔴 Not-Set | | | +| `OP_LDoNDisarmTraps` | 🔴 Not-Set | | | +| `OP_LDoNInspect` | 🔴 Not-Set | | | +| `OP_LDoNOpen` | 🟡 Unverified | | | +| `OP_LDoNPickLock` | 🟡 Unverified | | | +| `OP_LDoNSenseTraps` | 🟡 Unverified | | | +| `OP_LeadershipExpToggle` | 🔴 Not-Set | | | +| `OP_LeadershipExpUpdate` | 🔴 Not-Set | | | +| `OP_LeaveAdventure` | 🔴 Not-Set | | | +| `OP_LeaveBoat` | 🟡 Unverified | | | +| `OP_LevelAppearance` | 🟡 Unverified | | | +| `OP_LevelUpdate` | 🟢 Verified | | | +| `OP_LFGAppearance` | 🔴 Not-Set | | | +| `OP_LFGCommand` | 🔴 Not-Set | | | +| `OP_LFGGetMatchesRequest` | 🔴 Not-Set | | | +| `OP_LFGGetMatchesResponse` | 🔴 Not-Set | | | +| `OP_LFGResponse` | 🔴 Not-Set | | | +| `OP_LFGuild` | 🔴 Not-Set | | | +| `OP_LFPCommand` | 🔴 Not-Set | | | +| `OP_LFPGetMatchesRequest` | 🔴 Not-Set | | | +| `OP_LFPGetMatchesResponse` | 🔴 Not-Set | | | +| `OP_LinkedReuse` | 🟡 Unverified | | | +| `OP_LoadSpellSet` | 🔴 Not-Set | | | +| `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` | 🟡 Unverified | | | +| `OP_LogoutReply` | 🔴 Not-Set | | | +| `OP_LogServer` | 🟢 Verified | Mostly unused values | | +| `OP_LootComplete` | 🟡 Unverified | | | +| `OP_LootItem` | 🟡 Unverified | | | +| `OP_LootRequest` | 🟡 Unverified | | | +| `OP_ManaChange` | 🟡 Unverified | | | +| `OP_ManaUpdate` | 🔴 Not-Set | | | +| `OP_MarkNPC` | 🔴 Not-Set | | | +| `OP_MarkRaidNPC` | 🔴 Not-Set | | | +| `OP_Marquee` | 🟡 Unverified | | | +| `OP_MemorizeSpell` | 🟡 Unverified | | | +| `OP_Mend` | 🟡 Unverified | | | +| `OP_MendHPUpdate` | 🔴 Not-Set | | | +| `OP_MercenaryAssign` | 🔴 Not-Set | | | +| `OP_MercenaryCommand` | 🔴 Not-Set | | | +| `OP_MercenaryDataRequest` | 🔴 Not-Set | | | +| `OP_MercenaryDataResponse` | 🔴 Not-Set | | | +| `OP_MercenaryDataUpdate` | 🔴 Not-Set | | | +| `OP_MercenaryDataUpdateRequest` | 🔴 Not-Set | | | +| `OP_MercenaryDismiss` | 🔴 Not-Set | | | +| `OP_MercenaryHire` | 🔴 Not-Set | | | +| `OP_MercenarySuspendRequest` | 🔴 Not-Set | | | +| `OP_MercenarySuspendResponse` | 🔴 Not-Set | | | +| `OP_MercenaryTimer` | 🔴 Not-Set | | | +| `OP_MercenaryTimerRequest` | 🔴 Not-Set | | | +| `OP_MercenaryUnknown1` | 🔴 Not-Set | | | +| `OP_MercenaryUnsuspendResponse` | 🔴 Not-Set | | | +| `OP_MerchantBulkItems` | 🔴 Not-Set | | | +| `OP_MobEnduranceUpdate` | 🔴 Not-Set | | | +| `OP_MobHealth` | 🟡 Unverified | | | +| `OP_MobManaUpdate` | 🔴 Not-Set | | | +| `OP_MobRename` | 🔴 Not-Set | | | +| `OP_MobUpdate` | 🔴 Not-Set | | | +| `OP_MoneyOnCorpse` | 🟡 Unverified | | | +| `OP_MoneyUpdate` | 🟡 Unverified | | | +| `OP_MOTD` | 🟢 Verified | | | +| `OP_MoveCoin` | 🟡 Unverified | | | +| `OP_MoveDoor` | 🟡 Unverified | | | +| `OP_MoveItem` | 🟡 Unverified | | | +| `OP_MoveMultipleItems` | 🟡 Unverified | | | +| `OP_MoveLogDisregard` | 🔴 Not-Set | | | +| `OP_MoveLogRequest` | 🔴 Not-Set | | | +| `OP_MultiLineMsg` | 🔴 Not-Set | | | +| `OP_NewSpawn` | 🟢 Verified | Deprecated in the client, already handled in emu | | +| `OP_NewTitlesAvailable` | 🔴 Not-Set | | | +| `OP_NewZone` | 🟢 Verified | | | +| `OP_NPCMoveUpdate` | 🔴 Not-Set | | | +| `OP_OnLevelMessage` | 🟡 Unverified | | | +| `OP_OpenContainer` | 🟡 Unverified | | | +| `OP_OpenDiscordMerchant` | 🔴 Not-Set | | | +| `OP_OpenGuildTributeMaster` | 🔴 Not-Set | | | +| `OP_OpenInventory` | 🔴 Not-Set | | | +| `OP_OpenTributeMaster` | 🔴 Not-Set | | | +| `OP_PDeletePetition` | 🔴 Not-Set | | | +| `OP_PetBuffWindow` | 🔴 Not-Set | | | +| `OP_PetCommands` | 🔴 Not-Set | | | +| `OP_PetCommandState` | 🔴 Not-Set | | | +| `OP_PetHoTT` | 🔴 Not-Set | | | +| `OP_Petition` | 🔴 Not-Set | | | +| `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` | 🟡 Unverified | | | +| `OP_PickZone` | 🔴 Not-Set | | | +| `OP_PickZoneWindow` | 🔴 Not-Set | | | +| `OP_PlayerProfile` | 🟢 Verified | | | +| `OP_PlayerStateAdd` | 🟡 Unverified | | | +| `OP_PlayerStateRemove` | 🟡 Unverified | | | +| `OP_PlayEverquestRequest` | 🔴 Not-Set | | | +| `OP_PlayEverquestResponse` | 🔴 Not-Set | | | +| `OP_PlayMP3` | 🟡 Unverified | | | +| `OP_Poll` | 🔴 Not-Set | | | +| `OP_PollResponse` | 🔴 Not-Set | | | +| `OP_PopupResponse` | 🟡 Unverified | | | +| `OP_PostEnterWorld` | 🟢 Verified | | | +| `OP_PotionBelt` | 🔴 Not-Set | | | +| `OP_PreLogoutReply` | 🔴 Not-Set | | | +| `OP_PurchaseLeadershipAA` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardDetailsReply` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardDetailsRequest` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardReply` | 🔴 Not-Set | | | +| `OP_PVPLeaderBoardRequest` | 🔴 Not-Set | | | +| `OP_PVPStats` | 🔴 Not-Set | | | +| `OP_QueryResponseThing` | 🔴 Not-Set | | | +| `OP_QueryUCSServerStatus` | 🟡 Unverified | | | +| `OP_RaidDelegateAbility` | 🔴 Not-Set | | | +| `OP_RaidClearNPCMarks` | 🔴 Not-Set | | | +| `OP_RaidInvite` | 🔴 Not-Set | | | +| `OP_RaidJoin` | 🔴 Not-Set | | | +| `OP_RaidUpdate` | 🔴 Not-Set | | | +| `OP_RandomNameGenerator` | 🟢 Verified | The client no longer sends this packet (random name generation is done entirely in the client). The client will still accept this packet to set name (emu doesn't do this, but it's always been supported) | | +| `OP_RandomReply` | 🟡 Unverified | | | +| `OP_RandomReq` | 🟡 Unverified | | | +| `OP_ReadBook` | 🟡 Unverified | | | +| `OP_RecipeAutoCombine` | 🟡 Unverified | | | +| `OP_RecipeDetails` | 🟡 Unverified | | | +| `OP_RecipeReply` | 🟡 Unverified | | | +| `OP_RecipesFavorite` | 🟡 Unverified | | | +| `OP_RecipesSearch` | 🟡 Unverified | | | +| `OP_ReclaimCrystals` | 🔴 Not-Set | | | +| `OP_ReloadUI` | 🔴 Not-Set | | | +| `OP_RemoveAllDoors` | 🟡 Unverified | | | +| `OP_RemoveBlockedBuffs` | 🟢 Verified | | | +| `OP_RemoveNimbusEffect` | 🟡 Unverified | | | +| `OP_RemoveTrap` | 🔴 Not-Set | | | +| `OP_Report` | 🟡 Unverified | | | +| `OP_ReqClientSpawn` | 🟢 Verified | | | +| `OP_ReqNewZone` | 🟢 Verified | Client does not send this (in LS or TOB), but it does receive it. emu does not send it | | +| `OP_RequestClientZoneChange` | 🟢 Verified | parity with RoF2, there's a string that gets passed to teleport at the end that's not known | | +| `OP_RequestDuel` | 🔴 Not-Set | | | +| `OP_RequestGuildTributes` | 🔴 Not-Set | | | +| `OP_RequestKnowledgeBase` | 🔴 Not-Set | | | +| `OP_RequestTitles` | 🔴 Not-Set | | | +| `OP_RespawnWindow` | 🟡 Unverified | | | +| `OP_RespondAA` | 🟡 Unverified | | | +| `OP_RestState` | 🟡 Unverified | | | +| `OP_Rewind` | 🟡 Unverified | | | +| `OP_RezzAnswer` | 🔴 Not-Set | | | +| `OP_RezzComplete` | 🔴 Not-Set | | | +| `OP_RezzRequest` | 🔴 Not-Set | | | +| `OP_Sacrifice` | 🟡 Unverified | | | +| `OP_SafeFallSuccess` | 🟡 Unverified | | | +| `OP_SafePoint` | 🔴 Not-Set | | | +| `OP_Save` | 🟡 Unverified | | | +| `OP_SaveOnZoneReq` | 🟡 Unverified | | | +| `OP_SelectTribute` | 🔴 Not-Set | | | +| `OP_SendAAStats` | 🟡 Unverified | | | +| `OP_SendAATable` | 🟢 Verified | | | +| `OP_SendCharInfo` | 🟢 Verified | | | +| `OP_SendExpZonein` | 🟢 Verified | | | +| `OP_SendFindableNPCs` | 🔴 Not-Set | | | +| `OP_SendGuildTributes` | 🔴 Not-Set | | | +| `OP_SendLoginInfo` | 🟢 Verified | | | +| `OP_SendMaxCharacters` | 🟢 Verified | | | +| `OP_SendMembership` | 🟢 Verified | | | +| `OP_SendMembershipDetails` | 🟢 Verified | The struct is correct, will need reversing for actual option keys/values | | +| `OP_SendSystemStats` | 🔴 Not-Set | | | +| `OP_SendTitleList` | 🔴 Not-Set | | | +| `OP_SendTributes` | 🔴 Not-Set | | | +| `OP_SendZonepoints` | 🟢 Verified | | | +| `OP_SenseHeading` | 🟡 Unverified | | | +| `OP_SenseTraps` | 🟡 Unverified | | | +| `OP_ServerListRequest` | 🔴 Not-Set | | | +| `OP_ServerListResponse` | 🔴 Not-Set | | | +| `OP_SessionReady` | 🔴 Not-Set | | | +| `OP_SetChatServer` | 🔴 Not-Set | | | +| `OP_SetChatServer2` | 🟢 Verified | | | +| `OP_SetFace` | 🔴 Not-Set | | | +| `OP_SetGroupTarget` | 🔴 Not-Set | | | +| `OP_SetGuildMOTD` | 🔴 Not-Set | | | +| `OP_SetGuildRank` | 🔴 Not-Set | | | +| `OP_SetRunMode` | 🟡 Unverified | | | +| `OP_SetServerFilter` | 🟡 Unverified | | | +| `OP_SetStartCity` | 🔴 Not-Set | | | +| `OP_SetTitle` | 🔴 Not-Set | | | +| `OP_SetTitleReply` | 🔴 Not-Set | | | +| `OP_SharedTaskMemberList` | 🔴 Not-Set | | | +| `OP_SharedTaskAddPlayer` | 🔴 Not-Set | | | +| `OP_SharedTaskRemovePlayer` | 🔴 Not-Set | | | +| `OP_SharedTaskMakeLeader` | 🔴 Not-Set | | | +| `OP_SharedTaskMemberInvite` | 🔴 Not-Set | | | +| `OP_SharedTaskInvite` | 🔴 Not-Set | | | +| `OP_SharedTaskInviteResponse` | 🔴 Not-Set | | | +| `OP_SharedTaskAcceptNew` | 🔴 Not-Set | | | +| `OP_SharedTaskMemberChange` | 🔴 Not-Set | | | +| `OP_SharedTaskPlayerList` | 🔴 Not-Set | | | +| `OP_SharedTaskSelectWindow` | 🔴 Not-Set | | | +| `OP_SharedTaskQuit` | 🔴 Not-Set | | | +| `OP_TaskTimers` | 🔴 Not-Set | | | +| `OP_Shielding` | 🔴 Not-Set | | | +| `OP_ShopDelItem` | 🟡 Unverified | | | +| `OP_ShopEnd` | 🟡 Unverified | | | +| `OP_ShopEndConfirm` | 🟡 Unverified | | | +| `OP_ShopItem` | 🔴 Not-Set | | | +| `OP_ShopPlayerBuy` | 🟡 Unverified | | | +| `OP_ShopPlayerSell` | 🟡 Unverified | | | +| `OP_ShopSendParcel` | 🟡 Unverified | | | +| `OP_ShopDeleteParcel` | 🟡 Unverified | | | +| `OP_ShopRespondParcel` | 🔴 Not-Set | | | +| `OP_ShopRetrieveParcel` | 🟡 Unverified | | | +| `OP_ShopParcelIcon` | 🟡 Unverified | | | +| `OP_ShopRequest` | 🟡 Unverified | | | +| `OP_SimpleMessage` | 🟡 Unverified | | | +| `OP_SkillUpdate` | 🟡 Unverified | | | +| `OP_Sneak` | 🟡 Unverified | | | +| `OP_Some3ByteHPUpdate` | 🔴 Not-Set | | | +| `OP_Some6ByteHPUpdate` | 🔴 Not-Set | | | +| `OP_SomeItemPacketMaybe` | 🔴 Not-Set | | | +| `OP_Sound` | 🟡 Unverified | | | +| `OP_SpawnAppearance` | 🟢 Verified | | | +| `OP_SpawnDoor` | 🟢 Verified | | | +| `OP_SpawnPositionUpdate` | 🔴 Not-Set | | | +| `OP_SpecialMesg` | 🟡 Unverified | | | +| `OP_SpellEffect` | 🟡 Unverified | | | +| `OP_Split` | 🟡 Unverified | | | +| `OP_Stamina` | 🟢 Verified | These values are 0-32k instead of 0-127 | | +| `OP_Stun` | 🟡 Unverified | | | +| `OP_Surname` | 🔴 Not-Set | | | +| `OP_SwapSpell` | 🟡 Unverified | | | +| `OP_SystemFingerprint` | 🔴 Not-Set | | | +| `OP_TargetBuffs` | 🔴 Not-Set | | | +| `OP_TargetCommand` | 🟡 Unverified | | | +| `OP_TargetHoTT` | 🔴 Not-Set | | | +| `OP_TargetMouse` | 🟡 Unverified | | | +| `OP_TargetReject` | 🔴 Not-Set | | | +| `OP_TaskActivity` | 🔴 Not-Set | | | +| `OP_TaskActivityComplete` | 🔴 Not-Set | | | +| `OP_TaskDescription` | 🔴 Not-Set | | | +| `OP_TaskHistoryReply` | 🔴 Not-Set | | | +| `OP_TaskHistoryRequest` | 🔴 Not-Set | | | +| `OP_TaskRequestTimer` | 🔴 Not-Set | | | +| `OP_TaskSelectWindow` | 🔴 Not-Set | | | +| `OP_Taunt` | 🟡 Unverified | | | +| `OP_TestBuff` | 🔴 Not-Set | | | +| `OP_TGB` | 🔴 Not-Set | | | +| `OP_TimeOfDay` | 🟢 Verified | | | +| `OP_Track` | 🟡 Unverified | | | +| `OP_TrackTarget` | 🟡 Unverified | | | +| `OP_TrackUnknown` | 🟡 Unverified | | | +| `OP_TradeAcceptClick` | 🟡 Unverified | | | +| `OP_TradeBusy` | 🟡 Unverified | | | +| `OP_TradeCoins` | 🟡 Unverified | | | +| `OP_TradeMoneyUpdate` | 🟡 Unverified | | | +| `OP_Trader` | 🔴 Not-Set | | | +| `OP_TraderBulkSend` | 🔴 Not-Set | | | +| `OP_TraderBuy` | 🔴 Not-Set | | | +| `OP_TraderDelItem` | 🔴 Not-Set | | | +| `OP_TradeRequest` | 🟡 Unverified | | | +| `OP_TradeRequestAck` | 🟡 Unverified | | | +| `OP_TraderItemUpdate` | 🔴 Not-Set | | | +| `OP_TraderShop` | 🔴 Not-Set | | | +| `OP_TradeSkillCombine` | 🟡 Unverified | | | +| `OP_TradeSkillRecipeInspect` | 🔴 Not-Set | | | +| `OP_Translocate` | 🟡 Unverified | | | +| `OP_TributeInfo` | 🔴 Not-Set | | | +| `OP_TributeItem` | 🔴 Not-Set | | | +| `OP_TributeMoney` | 🔴 Not-Set | | | +| `OP_TributeNPC` | 🔴 Not-Set | | | +| `OP_TributePointUpdate` | 🔴 Not-Set | | | +| `OP_TributeTimer` | 🔴 Not-Set | | | +| `OP_TributeToggle` | 🔴 Not-Set | | | +| `OP_TributeUpdate` | 🔴 Not-Set | | | +| `OP_Untargetable` | 🟡 Unverified | | | +| `OP_UpdateAA` | 🟡 Unverified | | | +| `OP_UpdateAura` | 🔴 Not-Set | | | +| `OP_UpdateLeadershipAA` | 🔴 Not-Set | | | +| `OP_VetClaimReply` | 🔴 Not-Set | | | +| `OP_VetClaimRequest` | 🔴 Not-Set | | | +| `OP_VetRewardsAvaliable` | 🔴 Not-Set | | | +| `OP_VoiceMacroIn` | 🟡 Unverified | | | +| `OP_VoiceMacroOut` | 🟡 Unverified | | | +| `OP_WeaponEquip1` | 🔴 Not-Set | | | +| `OP_WearChange` | 🟡 Unverified | | | +| `OP_Weather` | 🟢 Verified | | | +| `OP_Weblink` | 🟡 Unverified | | | +| `OP_WhoAllRequest` | 🟡 Unverified | | | +| `OP_WhoAllResponse` | 🟡 Unverified | | | +| `OP_World_Client_CRC1` | 🟢 Verified | | | +| `OP_World_Client_CRC2` | 🟢 Verified | | | +| `OP_World_Client_CRC3` | 🟢 Verified | | | +| `OP_WorldClientReady` | 🟢 Verified | | | +| `OP_WorldComplete` | 🟢 Verified | | | +| `OP_WorldLogout` | 🔴 Not-Set | | | +| `OP_WorldObjectsSent` | 🟢 Verified | | | +| `OP_WorldUnknown001` | 🟢 Verified | SetServerTime. emu doesn't currently send it so setting it to verified, but the reference is 0x140292550 | | +| `OP_XTargetAutoAddHaters` | 🔴 Not-Set | | | +| `OP_XTargetOpen` | 🔴 Not-Set | | | +| `OP_XTargetOpenResponse` | 🔴 Not-Set | | | +| `OP_XTargetRequest` | 🔴 Not-Set | | | +| `OP_XTargetResponse` | 🔴 Not-Set | | | +| `OP_YellForHelp` | 🟡 Unverified | | | +| `OP_ZoneChange` | 🟢 Verified | | | +| `OP_ZoneComplete` | 🔴 Not-Set | | | +| `OP_ZoneEntry` | 🟢 Verified | unknown fields in C->S struct are various CRCs, emu doesn't use them | | +| `OP_ZoneGuildList` | 🔴 Not-Set | | | +| `OP_ZoneInUnknown` | 🔴 Not-Set | | | +| `OP_ZonePlayerToBind` | 🟡 Unverified | | | +| `OP_ZoneServerInfo` | 🟢 Verified | | | +| `OP_ZoneServerReady` | 🔴 Not-Set | | | +| `OP_ZoneSpawns` | 🟢 Verified | This is deprecated in the client (and emu never sends it directly) | | +| `OP_ZoneUnavail` | 🟢 Verified | The client discards all content of this packet | | +| `OP_ResetAA` | 🟡 Unverified | | | +| `OP_UnderWorld` | 🟡 Unverified | | | From fe4146050f6dde1da635a9fc4856424f25b9cf2c Mon Sep 17 00:00:00 2001 From: dannuic Date: Thu, 16 Apr 2026 16:51:41 -0600 Subject: [PATCH 03/12] Validated up to OP_UpdateAA --- common/patches/tob.cpp | 3 +-- common/patches/tob_structs.h | 3 +-- tob/opcodes.md | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index cc18ae534..9c7cdd7f3 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -2337,12 +2337,11 @@ namespace TOB eq->aapoints_assigned[4] = 0; eq->aapoints_assigned[5] = 0; - for (uint32 i = 0; i < MAX_PP_AA_ARRAY; ++i) + for (uint32 i = 0; i < structs::MAX_PP_AA_ARRAY; ++i) { eq->aa_list[i].AA = emu->aa_list[i].AA; eq->aa_list[i].value = emu->aa_list[i].value; eq->aa_list[i].charges = emu->aa_list[i].charges; - eq->aa_list[i].bUnknown0x0c = false; } FINISH_ENCODE(); diff --git a/common/patches/tob_structs.h b/common/patches/tob_structs.h index 928e758e6..ba065542d 100644 --- a/common/patches/tob_structs.h +++ b/common/patches/tob_structs.h @@ -818,9 +818,8 @@ namespace TOB { struct AA_Array { uint32 AA; - uint32 value; + uint32 value; // points spent uint32 charges; // expendable charges - bool bUnknown0x0c; // added test winter 2024; removed sometime in summer 2024 }; struct AATable_Struct { diff --git a/tob/opcodes.md b/tob/opcodes.md index 73567da2a..320e466dc 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -465,7 +465,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_RequestKnowledgeBase` | 🔴 Not-Set | | | | `OP_RequestTitles` | 🔴 Not-Set | | | | `OP_RespawnWindow` | 🟡 Unverified | | | -| `OP_RespondAA` | 🟡 Unverified | | | +| `OP_RespondAA` | 🟢 Verified | | | | `OP_RestState` | 🟡 Unverified | | | | `OP_Rewind` | 🟡 Unverified | | | | `OP_RezzAnswer` | 🔴 Not-Set | | | @@ -594,7 +594,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_TributeToggle` | 🔴 Not-Set | | | | `OP_TributeUpdate` | 🔴 Not-Set | | | | `OP_Untargetable` | 🟡 Unverified | | | -| `OP_UpdateAA` | 🟡 Unverified | | | +| `OP_UpdateAA` | 🟢 Verified | | | | `OP_UpdateAura` | 🔴 Not-Set | | | | `OP_UpdateLeadershipAA` | 🔴 Not-Set | | | | `OP_VetClaimReply` | 🔴 Not-Set | | | From a8e3ab41e10865938b07b0fbc10ce2c254ba5799 Mon Sep 17 00:00:00 2001 From: dannuic Date: Thu, 16 Apr 2026 17:13:17 -0600 Subject: [PATCH 04/12] Validated up to OP_ExpUpdate --- common/patches/tob.cpp | 14 ++++++++++++++ common/patches/tob_ops.h | 1 + common/patches/tob_structs.h | 6 +++--- tob/opcodes.md | 6 +++--- utils/patches/patch_TOB.conf | 2 +- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 9c7cdd7f3..93e9a66f2 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -145,6 +145,20 @@ namespace TOB #include "ss_define.h" // ENCODE methods + ENCODE(OP_AAExpUpdate) { + ENCODE_LENGTH_EXACT(AltAdvStats_Struct); + SETUP_DIRECT_ENCODE(AltAdvStats_Struct, structs::AltAdvStats_Struct); + + //later we should change the underlying server to use this more accurate value + //and encode the 330 in the other patches + eq->experience = emu->experience * 100000 / 330; + + OUT(unspent); + OUT(percentage); + + FINISH_ENCODE(); + } + ENCODE(OP_Action) { ENCODE_LENGTH_EXACT(Action_Struct); SETUP_DIRECT_ENCODE(Action_Struct, structs::MissileHitInfo); diff --git a/common/patches/tob_ops.h b/common/patches/tob_ops.h index afaf305c3..9e8b8e07b 100644 --- a/common/patches/tob_ops.h +++ b/common/patches/tob_ops.h @@ -1,4 +1,5 @@ //list of packets we need to encode on the way out: +E(OP_AAExpUpdate) E(OP_Action) E(OP_Animation) E(OP_ApplyPoison) diff --git a/common/patches/tob_structs.h b/common/patches/tob_structs.h index ba065542d..64642c78b 100644 --- a/common/patches/tob_structs.h +++ b/common/patches/tob_structs.h @@ -503,8 +503,8 @@ namespace TOB { struct ExpUpdate_Struct { - /*000*/ uint64 exp; //This is exp % / 1000 now; eg 69250 = 69.25% - /*008*/ uint64 unknown; //unclear, I didn't see the client actually read this value but i might have missed it + /*000*/ uint64 exp; // This is exp % / 1000 now; eg 69250 = 69.25% + /*008*/ uint64 unknown; // if this is the value "2", it opens up the tip window }; struct DeleteSpawn_Struct @@ -832,7 +832,7 @@ namespace TOB { /*000*/ uint32 experience; /*004*/ uint32 unspent; /*008*/ uint8 percentage; - /*009*/ uint8 unknown009[3]; + /*009*/ uint8 padding[3]; }; struct ZonePlayerToBind_Struct { diff --git a/tob/opcodes.md b/tob/opcodes.md index 320e466dc..8a11d5107 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -9,7 +9,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | Opcode | Status | Notes | Working On | |:----------------------------------|:--------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:-----------| | `OP_AAAction` | 🟡 Unverified | | | -| `OP_AAExpUpdate` | 🟡 Unverified | | | +| `OP_AAExpUpdate` | 🟢 Verified | | | | `OP_AcceptNewTask` | 🔴 Not-Set | | | | `OP_AckPacket` | 🟢 Verified | | | | `OP_Action` | 🟡 Unverified | | | @@ -170,7 +170,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_EnvDamage` | 🟡 Unverified | | | | `OP_EvolveItem` | 🔴 Not-Set | | | | `OP_ExpansionInfo` | 🟢 Verified | Updated from u32 to u64 and works now | | -| `OP_ExpUpdate` | 🟡 Unverified | | | +| `OP_ExpUpdate` | 🟢 Verified | | | | `OP_FaceChange` | 🔴 Not-Set | | | | `OP_Feedback` | 🔴 Not-Set | | | | `OP_FeignDeath` | 🟡 Unverified | | | @@ -182,7 +182,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_FinishWindow2` | 🟡 Unverified | | | | `OP_Fishing` | 🟡 Unverified | | | | `OP_Fling` | 🟡 Unverified | | | -| `OP_FloatListThing` | 🟢 Verified | Movement History. Sent from client, but emu doesn't use it so setting it as varified. Reference is 0x1402FFAD0 | | +| `OP_FloatListThing` | 🟢 Verified | Movement History. Sent from client, but emu doesn't use it so setting it as verified. Reference is 0x1402FFAD0 | | | `OP_Forage` | 🟡 Unverified | | | | `OP_ForceFindPerson` | 🔴 Not-Set | | | | `OP_FormattedMessage` | 🟡 Unverified | | | diff --git a/utils/patches/patch_TOB.conf b/utils/patches/patch_TOB.conf index 3102e24a3..c718d5de4 100644 --- a/utils/patches/patch_TOB.conf +++ b/utils/patches/patch_TOB.conf @@ -93,7 +93,7 @@ OP_ClearAA=0x6093 OP_ClearLeadershipAbilities=0x0000 #removed; leadership abilities are baked in and always on OP_RespondAA=0x4449 OP_UpdateAA=0x1655 -OP_SendAAStats=0x7416 #i'll be honest i think this was removed at some point but this is the op at the spot in the list +OP_SendAAStats=0x7416 # Removed in TOB OP_AAExpUpdate=0x04c3 #need to look into whether this has changed; exp did OP_ExpUpdate=0x0e55 OP_HPUpdate=0x2723 From 6a7baf8f1c9c445c6c5116912b578baccc11f3c9 Mon Sep 17 00:00:00 2001 From: dannuic Date: Fri, 17 Apr 2026 11:56:46 -0600 Subject: [PATCH 05/12] Validated through OP_SetServerFilter --- common/patches/tob.cpp | 56 +++++++++++++++++------------------- common/patches/tob_structs.h | 6 ++-- tob/opcodes.md | 16 +++++------ utils/patches/patch_TOB.conf | 2 +- 4 files changed, 39 insertions(+), 41 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 93e9a66f2..c0ea35bda 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -3845,7 +3845,7 @@ namespace TOB int r; for (r = 0; r < 29; r++) { - // Size 68 in TOB + // Size 69 in TOB IN(filters[r]); } @@ -4149,7 +4149,7 @@ namespace TOB //s32 Variation; //s32 NewArmorId; //s32 NewArmorType; - buffer.WriteUInt32(item->Material); + buffer.WriteUInt32(item->Material); // this isn't labeled well, material is material *type* buffer.WriteUInt32(0); //unsupported atm buffer.WriteUInt32(item->EliteMaterial); buffer.WriteUInt32(item->HerosForgeModel); @@ -4267,9 +4267,20 @@ namespace TOB //u8 SpellDataSkillMask[78]; for (int j = 0; j < 78; ++j) { - buffer.WriteUInt8(0); //unsure what this is exactly + buffer.WriteUInt8(0); // TODO: collection of ints for bitfield for each skill required to use. reads 19 ints byte by byte in the client, leave like this for further investigation } + + /* There are a static 7 spell data entries on an item: + Clicky + Proc + Worn + Focus + Scroll + Focus2 + Blessing + */ + /* SpellData: s32 SpellId; u8 RequiredLevel; @@ -4678,55 +4689,42 @@ namespace TOB //ItemDefinition Item; SerializeItemDefinition(buffer, item); - //u32 RealEstateArrayCount; - // buffer.WriteInt32(0); - //s32 RealEstateArray[RealEstateArrayCount]; - - //bool bRealEstateItemPlaceable; - // buffer.WriteInt8(0); - //u32 SubContentSize; - uint32 subitem_count = 0; - int16 SubSlotNumber = EQ::invbag::SLOT_INVALID; if (slot_id_in <= EQ::invslot::GENERAL_END && slot_id_in >= EQ::invslot::GENERAL_BEGIN) - SubSlotNumber = EQ::invbag::GENERAL_BAGS_BEGIN + ((slot_id_in - EQ::invslot::GENERAL_BEGIN) * EQ::invbag::SLOT_COUNT); + SubSlotNumber = EQ::invbag::GENERAL_BAGS_BEGIN + (slot_id_in - EQ::invslot::GENERAL_BEGIN) * EQ::invbag::SLOT_COUNT; else if (slot_id_in == EQ::invslot::slotCursor) SubSlotNumber = EQ::invbag::CURSOR_BAG_BEGIN; else if (slot_id_in <= EQ::invslot::BANK_END && slot_id_in >= EQ::invslot::BANK_BEGIN) - SubSlotNumber = EQ::invbag::BANK_BAGS_BEGIN + ((slot_id_in - EQ::invslot::BANK_BEGIN) * EQ::invbag::SLOT_COUNT); + SubSlotNumber = EQ::invbag::BANK_BAGS_BEGIN + (slot_id_in - EQ::invslot::BANK_BEGIN) * EQ::invbag::SLOT_COUNT; else if (slot_id_in <= EQ::invslot::SHARED_BANK_END && slot_id_in >= EQ::invslot::SHARED_BANK_BEGIN) - SubSlotNumber = EQ::invbag::SHARED_BANK_BAGS_BEGIN + ((slot_id_in - EQ::invslot::SHARED_BANK_BEGIN) * EQ::invbag::SLOT_COUNT); + SubSlotNumber = EQ::invbag::SHARED_BANK_BAGS_BEGIN + (slot_id_in - EQ::invslot::SHARED_BANK_BEGIN) * EQ::invbag::SLOT_COUNT; else SubSlotNumber = slot_id_in; // not sure if this is the best way to handle this..leaving for now if (SubSlotNumber != EQ::invbag::SLOT_INVALID) { + std::vector> subitems; for (uint32 index = EQ::invbag::SLOT_BEGIN; index <= EQ::invbag::SLOT_END; ++index) { EQ::ItemInstance* sub = inst->GetItem(index); - if (!sub) - continue; - - ++subitem_count; + if (sub != nullptr) + subitems.emplace_back(index, sub); } - buffer.WriteUInt32(subitem_count); - - for (uint32 index = EQ::invbag::SLOT_BEGIN; index <= EQ::invbag::SLOT_END; ++index) { - EQ::ItemInstance* sub = inst->GetItem(index); - if (!sub) - continue; + buffer.WriteUInt32(subitems.size()); + // This must be guaranteed to have subitem_count members, where the index is the correct index. The client doesn't loop through all slots here + for (const auto& [index, subitem] : subitems) { buffer.WriteUInt32(index); - - SerializeItem(buffer, sub, SubSlotNumber, (depth + 1), packet_type); + SerializeItem(buffer, subitem, SubSlotNumber, depth + 1, packet_type); } - } + } else + buffer.WriteUInt32(0); // no subitems, client needs to know that //bool bCollected; buffer.WriteInt8(0); //unsupported atm //u64 DontKnow; - buffer.WriteUInt64(0); //unsupported atm + buffer.WriteInt64(0); //unsupported atm //s32 Luck; buffer.WriteInt32(0); //unsupported atm } diff --git a/common/patches/tob_structs.h b/common/patches/tob_structs.h index 64642c78b..c92d271ca 100644 --- a/common/patches/tob_structs.h +++ b/common/patches/tob_structs.h @@ -516,7 +516,7 @@ namespace TOB { //OP_SetServerFilter struct SetServerFilter_Struct { - uint32 filters[68]; + uint32 filters[69]; }; // Was new to RoF2, doesn't look changed @@ -748,10 +748,10 @@ namespace TOB { struct ManaChange_Struct { uint32 new_mana; - uint32 stamina; + uint32 stamina; // endurance uint32 spell_id; uint32 keepcasting; - int32 slot; + int32 slot; // gem slot }; //This is what we call OP_Action diff --git a/tob/opcodes.md b/tob/opcodes.md index 8a11d5107..67cdf20a9 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -85,7 +85,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_ChangePetName` | 🔴 Not-Set | | | | `OP_CharacterCreate` | 🟢 Verified | Sends heroic type, can be used for something? | | | `OP_CharacterCreateRequest` | 🟢 Verified | | | -| `OP_CharInventory` | 🟡 Unverified | | | +| `OP_CharInventory` | 🟢 Verified | | | | `OP_Charm` | 🟡 Unverified | | | | `OP_ChatMessage` | 🔴 Not-Set | | | | `OP_ClearAA` | 🟢 Verified | | | @@ -98,9 +98,9 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_ClickObject` | 🟡 Unverified | | | | `OP_ClickObjectAction` | 🟡 Unverified | | | | `OP_ClientError` | 🔴 Not-Set | | | -| `OP_ClientReady` | 🟡 Unverified | | | +| `OP_ClientReady` | 🟢 Verified | | | | `OP_ClientTimeStamp` | 🔴 Not-Set | | | -| `OP_ClientUpdate` | 🟡 Unverified | | | +| `OP_ClientUpdate` | 🟢 Verified | | | | `OP_CloseContainer` | 🔴 Not-Set | | | | `OP_CloseTributeMaster` | 🔴 Not-Set | | | | `OP_ColoredText` | 🟡 Unverified | | | @@ -279,7 +279,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_Heartbeat` | 🔴 Not-Set | | | | `OP_Hide` | 🟡 Unverified | | | | `OP_HideCorpse` | 🟡 Unverified | | | -| `OP_HPUpdate` | 🟡 Unverified | | | +| `OP_HPUpdate` | 🟢 Verified | | | | `OP_Illusion` | 🟡 Unverified | | | | `OP_IncreaseStats` | 🟡 Unverified | | | | `OP_InitialHPUpdate` | 🔴 Not-Set | | | @@ -346,7 +346,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_LootComplete` | 🟡 Unverified | | | | `OP_LootItem` | 🟡 Unverified | | | | `OP_LootRequest` | 🟡 Unverified | | | -| `OP_ManaChange` | 🟡 Unverified | | | +| `OP_ManaChange` | 🟢 Verified | | | | `OP_ManaUpdate` | 🔴 Not-Set | | | | `OP_MarkNPC` | 🔴 Not-Set | | | | `OP_MarkRaidNPC` | 🔴 Not-Set | | | @@ -503,7 +503,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_SetGuildMOTD` | 🔴 Not-Set | | | | `OP_SetGuildRank` | 🔴 Not-Set | | | | `OP_SetRunMode` | 🟡 Unverified | | | -| `OP_SetServerFilter` | 🟡 Unverified | | | +| `OP_SetServerFilter` | 🟢 Verified | | | | `OP_SetStartCity` | 🔴 Not-Set | | | | `OP_SetTitle` | 🔴 Not-Set | | | | `OP_SetTitleReply` | 🔴 Not-Set | | | @@ -543,7 +543,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_SpawnAppearance` | 🟢 Verified | | | | `OP_SpawnDoor` | 🟢 Verified | | | | `OP_SpawnPositionUpdate` | 🔴 Not-Set | | | -| `OP_SpecialMesg` | 🟡 Unverified | | | +| `OP_SpecialMesg` | 🟢 Verified | | | | `OP_SpellEffect` | 🟡 Unverified | | | | `OP_Split` | 🟡 Unverified | | | | `OP_Stamina` | 🟢 Verified | These values are 0-32k instead of 0-127 | | @@ -603,7 +603,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_VoiceMacroIn` | 🟡 Unverified | | | | `OP_VoiceMacroOut` | 🟡 Unverified | | | | `OP_WeaponEquip1` | 🔴 Not-Set | | | -| `OP_WearChange` | 🟡 Unverified | | | +| `OP_WearChange` | 🟢 Verified | | | | `OP_Weather` | 🟢 Verified | | | | `OP_Weblink` | 🟡 Unverified | | | | `OP_WhoAllRequest` | 🟡 Unverified | | | diff --git a/utils/patches/patch_TOB.conf b/utils/patches/patch_TOB.conf index c718d5de4..de96f6841 100644 --- a/utils/patches/patch_TOB.conf +++ b/utils/patches/patch_TOB.conf @@ -222,7 +222,7 @@ OP_KeyRing=0x0000 OP_WhoAllRequest=0x3328 OP_WhoAllResponse=0x4dfd OP_FriendsWho=0x3547 -OP_ConfirmDelete=0x14a8 +OP_ConfirmDelete=0x14a8 # This is sent fromt the client after a movement update (with just spawn ID as the content) OP_Logout=0x46f8 OP_Rewind=0x898a OP_TargetCommand=0x46bf From 2da6d3f37c02f6c50d6b1336c55811644b720901 Mon Sep 17 00:00:00 2001 From: dannuic Date: Fri, 17 Apr 2026 14:57:35 -0600 Subject: [PATCH 06/12] Fixed item index mapping --- common/patches/tob.cpp | 35 +++++++++++++++++------------------ common/patches/tob_limits.h | 4 ++-- common/patches/tob_structs.h | 3 +-- tob/opcodes.md | 2 +- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index c0ea35bda..159ec2643 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -471,7 +471,7 @@ namespace TOB int item_count = in->size / sizeof(EQ::InternalSerializedItem_Struct); if (!item_count || (in->size % sizeof(EQ::InternalSerializedItem_Struct)) != 0) { - Log(Logs::General, Logs::Netcode, "[STRUCTS] Wrong size on outbound %s: Got %d, expected multiple of %d", + LogNetcode("[STRUCTS] Wrong size on outbound {}: Got {}, expected multiple of {}", opcodes->EmuToName(in->GetOpcode()), in->size, sizeof(EQ::InternalSerializedItem_Struct)); delete in; @@ -2324,7 +2324,6 @@ namespace TOB eq->container_slot = ServerToTOBSlot(emu->unknown1); structs::InventorySlot_Struct TOBSlot; TOBSlot.Type = 8; // Observed - TOBSlot.Padding1 = 0; TOBSlot.Slot = 0xffff; TOBSlot.SubIndex = 0xffff; TOBSlot.AugIndex = 0xffff; @@ -5045,8 +5044,8 @@ namespace TOB TOBSlot.Slot = server_slot - EQ::invslot::WORLD_BEGIN; } - Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to TOB Slot [%i, %i, %i, %i]", - server_slot, TOBSlot.Type, TOBSlot.Slot, TOBSlot.SubIndex, TOBSlot.AugIndex); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert Server Slot {} to TOB Slot [{}, {}, {}, {}]", + server_slot, TOBSlot.Type, TOBSlot.Slot, TOBSlot.SubIndex, TOBSlot.AugIndex).c_str()); return TOBSlot; } @@ -5062,8 +5061,8 @@ namespace TOB if (TOBSlot.Slot != invslot::SLOT_INVALID) TOBSlot.Type = invtype::typeCorpse; - Log(Logs::Detail, Logs::Netcode, "Convert Server Corpse Slot %i to TOB Corpse Slot [%i, %i, %i, %i]", - server_corpse_slot, TOBSlot.Type, TOBSlot.Slot, TOBSlot.SubIndex, TOBSlot.AugIndex); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert Server Corpse Slot {} to TOB Corpse Slot [{}, {}, {}, {}]", + server_corpse_slot, TOBSlot.Type, TOBSlot.Slot, TOBSlot.SubIndex, TOBSlot.AugIndex).c_str()); return TOBSlot; } @@ -5103,8 +5102,8 @@ namespace TOB } } - Log(Logs::Detail, Logs::Netcode, "Convert Server Slot %i to TOB Typeless Slot [%i, %i, %i] (implied type: %i)", - server_slot, TOBSlot.Slot, TOBSlot.SubIndex, TOBSlot.AugIndex, server_type); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert Server Slot {} to TOB Typeless Slot [{}, {}, {}] (implied type: {})", + server_slot, TOBSlot.Slot, TOBSlot.SubIndex, TOBSlot.AugIndex, server_type).c_str()); return TOBSlot; } @@ -5112,8 +5111,8 @@ namespace TOB static inline uint32 TOBToServerSlot(structs::InventorySlot_Struct tob_slot) { if (tob_slot.AugIndex < invaug::SOCKET_INVALID || tob_slot.AugIndex >= invaug::SOCKET_COUNT) { - Log(Logs::Detail, Logs::Netcode, "Convert TOB Slot [%i, %i, %i, %i] to Server Slot %i", - tob_slot.Type, tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, EQ::invslot::SLOT_INVALID); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert TOB Slot [{}, {}, {}, {}] to Server Slot {}", + tob_slot.Type, tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, EQ::invslot::SLOT_INVALID).c_str()); return EQ::invslot::SLOT_INVALID; } @@ -5235,8 +5234,8 @@ namespace TOB } } - Log(Logs::Detail, Logs::Netcode, "Convert TOB Slot [%i, %i, %i, %i] to Server Slot %i", - tob_slot.Type, tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, server_slot); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert TOB Slot [{}, {}, {}, {}] to Server Slot {}", + tob_slot.Type, tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, server_slot).c_str()); return server_slot; } @@ -5253,8 +5252,8 @@ namespace TOB ServerSlot = TOBToServerCorpseMainSlot(tob_corpse_slot.Slot); } - Log(Logs::Detail, Logs::Netcode, "Convert TOB Slot [%i, %i, %i, %i] to Server Slot %i", - tob_corpse_slot.Type, tob_corpse_slot.Slot, tob_corpse_slot.SubIndex, tob_corpse_slot.AugIndex, ServerSlot); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert TOB Slot [{}, {}, {}, {}] to Server Slot {}", + tob_corpse_slot.Type, tob_corpse_slot.Slot, tob_corpse_slot.SubIndex, tob_corpse_slot.AugIndex, ServerSlot).c_str()); return ServerSlot; } @@ -5275,8 +5274,8 @@ namespace TOB static inline uint32 TOBToServerTypelessSlot(structs::TypelessInventorySlot_Struct tob_slot, int16 tob_type) { if (tob_slot.AugIndex < invaug::SOCKET_INVALID || tob_slot.AugIndex >= invaug::SOCKET_COUNT) { - Log(Logs::Detail, Logs::Netcode, "Convert TOB Typeless Slot [%i, %i, %i] (implied type: %i) to Server Slot %i", - tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, tob_type, EQ::invslot::SLOT_INVALID); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert TOB Typeless Slot [{}, {}, {}] (implied type: {}) to Server Slot {}", + tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, tob_type, EQ::invslot::SLOT_INVALID).c_str()); return EQ::invslot::SLOT_INVALID; } @@ -5389,8 +5388,8 @@ namespace TOB } } - Log(Logs::Detail, Logs::Netcode, "Convert TOB Typeless Slot [%i, %i, %i] (implied type: %i) to Server Slot %i", - tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, tob_type, ServerSlot); + Log(Logs::Detail, Logs::Netcode, fmt::format("Convert TOB Typeless Slot [{}, {}, {}] (implied type: {}) to Server Slot {}", + tob_slot.Slot, tob_slot.SubIndex, tob_slot.AugIndex, tob_type, ServerSlot).c_str()); return ServerSlot; } diff --git a/common/patches/tob_limits.h b/common/patches/tob_limits.h index 1288cf878..beb5e7b90 100644 --- a/common/patches/tob_limits.h +++ b/common/patches/tob_limits.h @@ -200,8 +200,8 @@ namespace TOB const int16 SLOT_INVALID = IINVALID; const int16 SLOT_BEGIN = INULL; - const int16 SLOT_END = 9; //254; - const int16 SLOT_COUNT = 10; //255; // server Size will be 255..unsure what actual client is (test) + const int16 SLOT_END = 199; + const int16 SLOT_COUNT = 200; // server Size will be 200..unsure what actual client is (test) const char* GetInvBagIndexName(int16 bag_index); diff --git a/common/patches/tob_structs.h b/common/patches/tob_structs.h index c92d271ca..b2211c7f0 100644 --- a/common/patches/tob_structs.h +++ b/common/patches/tob_structs.h @@ -523,8 +523,7 @@ namespace TOB { // The padding is because these structs are padded to the default 4 bytes struct InventorySlot_Struct { - /*000*/ int16 Type; - /*002*/ int16 Padding1; + /*000*/ int32 Type; /*004*/ int16 Slot; /*006*/ int16 SubIndex; /*008*/ int16 AugIndex; diff --git a/tob/opcodes.md b/tob/opcodes.md index 67cdf20a9..f8113c535 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -379,7 +379,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_MOTD` | 🟢 Verified | | | | `OP_MoveCoin` | 🟡 Unverified | | | | `OP_MoveDoor` | 🟡 Unverified | | | -| `OP_MoveItem` | 🟡 Unverified | | | +| `OP_MoveItem` | 🟢 Verified | | | | `OP_MoveMultipleItems` | 🟡 Unverified | | | | `OP_MoveLogDisregard` | 🔴 Not-Set | | | | `OP_MoveLogRequest` | 🔴 Not-Set | | | From ec5a9d0bd49673da1e47307c093ef7fd19284156 Mon Sep 17 00:00:00 2001 From: dannuic Date: Fri, 17 Apr 2026 18:07:39 -0600 Subject: [PATCH 07/12] Validated up to OP_MemorizeSpell (still needs testing in client) --- common/patches/tob.cpp | 34 ++++++++++++++++++++++++++++++++++ common/patches/tob_ops.h | 2 ++ common/patches/tob_structs.h | 9 ++++++++- tob/opcodes.md | 10 +++++----- zone/client_packet.cpp | 3 +++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 159ec2643..83a379b11 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -957,6 +957,23 @@ namespace TOB FINISH_ENCODE(); } + ENCODE(OP_MemorizeSpell) { + ENCODE_LENGTH_EXACT(MemorizeSpell_Struct); + SETUP_DIRECT_ENCODE(MemorizeSpell_Struct, structs::MemorizeSpell_Struct); + + // TODO: TOB has a "finish memming" value (2) here, might be needed to keep client spell gems in sync + if (emu->scribing == 2) + eq->scribing = 3; + else + OUT(scribing); + + OUT(slot); + OUT(spell_id); + OUT(reduction); + + FINISH_ENCODE(); + } + ENCODE(OP_MobHealth) { ENCODE_LENGTH_EXACT(SpawnHPUpdate_Struct2); SETUP_DIRECT_ENCODE(SpawnHPUpdate_Struct2, structs::MobHealth_Struct); @@ -3821,6 +3838,23 @@ namespace TOB DECODE_FORWARD(OP_GroupInvite); } + DECODE(OP_MemorizeSpell) { + DECODE_LENGTH_EXACT(structs::MemorizeSpell_Struct); + SETUP_DIRECT_DECODE(MemorizeSpell_Struct, structs::MemorizeSpell_Struct); + + // TODO: TOB has a "finish memming" value (2) here, might be needed to keep client spell gems in sync + if (emu->scribing == 3) + eq->scribing = 2; + else + IN(scribing); + + IN(slot); + IN(spell_id); + IN(reduction); + + FINISH_DIRECT_DECODE(); + } + DECODE(OP_MoveItem) { DECODE_LENGTH_EXACT(structs::MoveItem_Struct); diff --git a/common/patches/tob_ops.h b/common/patches/tob_ops.h index 9e8b8e07b..40a7c9adf 100644 --- a/common/patches/tob_ops.h +++ b/common/patches/tob_ops.h @@ -33,6 +33,7 @@ E(OP_Illusion) E(OP_ItemPacket) E(OP_LogServer) E(OP_ManaChange) +E(OP_MemorizeSpell) E(OP_MobHealth) E(OP_MoneyOnCorpse) E(OP_MoveItem) @@ -84,6 +85,7 @@ D(OP_GMTraining) D(OP_GroupDisband) D(OP_GroupInvite) D(OP_GroupInvite2) +D(OP_MemorizeSpell) D(OP_MoveItem) D(OP_RemoveBlockedBuffs) D(OP_SetServerFilter) diff --git a/common/patches/tob_structs.h b/common/patches/tob_structs.h index b2211c7f0..e003490ea 100644 --- a/common/patches/tob_structs.h +++ b/common/patches/tob_structs.h @@ -675,11 +675,18 @@ namespace TOB { /*000*/ uint32 spell_id; /*004*/ uint16 caster_id; /*006*/ uint32 cast_time; // in miliseconds - /*010*/ uint32 unknown0a; // I think this is caster effective level but im not sure. live always sends 0 + /*010*/ uint32 unknown0a; // I think this is caster effective level but im not sure. live always sends 0. The client uses this for the spell link /*014*/ uint8 unknown0e; // 0 will short circuit the cast, seen 1 from live usually, maybe related to interrupts or particles or something /*015*/ }; + struct MemorizeSpell_Struct { + uint32 slot; // Spot in the spell book/memorized slot + uint32 spell_id; // Spell id (200 or c8 is minor healing, etc) + uint32 scribing; // -1 refreshes book, 0 scribe to book, 2 end mem, 1 start mem, 3 unmem, 4 set activated item keyring -- client will send back 2 if a 0 operation updated a memorized spell of the same group + subgroup + uint32 reduction; // lower reuse (only used if scribing is 4) + }; + //I've observed 5 s16 that are all -1. //Clicky items don't even trigger this as far as i can tell so not sure what this is for now. //One of these could have changed to a s32 but im not sure. diff --git a/tob/opcodes.md b/tob/opcodes.md index f8113c535..3dbee363b 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -63,7 +63,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_BecomeCorpse` | 🔴 Not-Set | | | | `OP_BecomeTrader` | 🔴 Not-Set | | | | `OP_Begging` | 🟡 Unverified | | | -| `OP_BeginCast` | 🟡 Unverified | | | +| `OP_BeginCast` | 🟢 Verified | | | | `OP_Bind_Wound` | 🟡 Unverified | | | | `OP_BlockedBuffs` | 🟢 Verified | | | | `OP_BoardBoat` | 🟡 Unverified | | | @@ -103,14 +103,14 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_ClientUpdate` | 🟢 Verified | | | | `OP_CloseContainer` | 🔴 Not-Set | | | | `OP_CloseTributeMaster` | 🔴 Not-Set | | | -| `OP_ColoredText` | 🟡 Unverified | | | +| `OP_ColoredText` | 🟢 Verified | | | | `OP_CombatAbility` | 🟡 Unverified | | | | `OP_Command` | 🔴 Not-Set | | | | `OP_CompletedTasks` | 🔴 Not-Set | | | | `OP_ConfirmDelete` | 🟡 Unverified | | | | `OP_Consent` | 🟡 Unverified | | | | `OP_ConsentDeny` | 🟡 Unverified | | | -| `OP_ConsentResponse` | 🟡 Unverified | | | +| `OP_ConsentResponse` | 🟢 Verified | | | | `OP_Consider` | 🟡 Unverified | | | | `OP_ConsiderCorpse` | 🟡 Unverified | | | | `OP_Consume` | 🟡 Unverified | | | @@ -351,7 +351,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_MarkNPC` | 🔴 Not-Set | | | | `OP_MarkRaidNPC` | 🔴 Not-Set | | | | `OP_Marquee` | 🟡 Unverified | | | -| `OP_MemorizeSpell` | 🟡 Unverified | | | +| `OP_MemorizeSpell` | 🟢 Verified | | | | `OP_Mend` | 🟡 Unverified | | | | `OP_MendHPUpdate` | 🔴 Not-Set | | | | `OP_MercenaryAssign` | 🔴 Not-Set | | | @@ -435,7 +435,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_PVPLeaderBoardRequest` | 🔴 Not-Set | | | | `OP_PVPStats` | 🔴 Not-Set | | | | `OP_QueryResponseThing` | 🔴 Not-Set | | | -| `OP_QueryUCSServerStatus` | 🟡 Unverified | | | +| `OP_QueryUCSServerStatus` | 🟢 Verified | | | | `OP_RaidDelegateAbility` | 🔴 Not-Set | | | | `OP_RaidClearNPCMarks` | 🔴 Not-Set | | | | `OP_RaidInvite` | 🔴 Not-Set | | | diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index e568265c5..f1f241359 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -12239,6 +12239,9 @@ void Client::Handle_OP_QueryUCSServerStatus(const EQApplicationPacket *app) case EQ::versions::ClientVersion::RoF2: ConnectionType = EQ::versions::ucsRoF2Combined; break; + case EQ::versions::ClientVersion::TOB: + ConnectionType = EQ::versions::ucsTOBCombined; + break; default: ConnectionType = EQ::versions::ucsUnknown; break; From 3bb7f94713f1a9dac204d285b5767693fc80a08f Mon Sep 17 00:00:00 2001 From: dannuic Date: Fri, 17 Apr 2026 23:35:34 -0600 Subject: [PATCH 08/12] Fixed memorization for parity with RoF2 --- common/patches/tob.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 83a379b11..6522b2952 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -25,6 +25,7 @@ #include #include +#include "common/packet_dump.h" #include "world/sof_char_create_data.h" namespace TOB @@ -961,11 +962,13 @@ namespace TOB ENCODE_LENGTH_EXACT(MemorizeSpell_Struct); SETUP_DIRECT_ENCODE(MemorizeSpell_Struct, structs::MemorizeSpell_Struct); - // TODO: TOB has a "finish memming" value (2) here, might be needed to keep client spell gems in sync - if (emu->scribing == 2) + // in TOB, 2 is "finish memming" so that becomes 1 in emu and 3 is "unmem" which becomes 2 + if (emu->scribing == 1) + eq->scribing = 2; + else if (emu->scribing == 2) eq->scribing = 3; else - OUT(scribing); + OUT(scribing); // TODO: can handle 4 here (I assume it's just like 2 or 3 but can have a reduction component) OUT(slot); OUT(spell_id); @@ -3842,11 +3845,21 @@ namespace TOB DECODE_LENGTH_EXACT(structs::MemorizeSpell_Struct); SETUP_DIRECT_DECODE(MemorizeSpell_Struct, structs::MemorizeSpell_Struct); - // TODO: TOB has a "finish memming" value (2) here, might be needed to keep client spell gems in sync - if (emu->scribing == 3) - eq->scribing = 2; + // TOB sends status 1 here to let the server know that it's started memming, but doesn't want a response + if (eq->scribing == 1) { + // TODO: There should be a timer set here to detect short-mem cheats, and then checked when the 2 packet is sent + // The previous detection will still happen on scribing == 2, the new client just handles it better + __packet->SetOpcode(OP_Unknown); + return; + } + + // in TOB, 2 is "finish memming" so that becomes 1 in emu and 3 is "unmem" which becomes 2 + if (eq->scribing == 2) + emu->scribing = 1; + else if (eq->scribing == 3) + emu->scribing = 2; else - IN(scribing); + IN(scribing); // TODO: Handle 4 here (clicky keyring) IN(slot); IN(spell_id); From 08cdd8234dc9e60137a4d9368c73c7aea86fca22 Mon Sep 17 00:00:00 2001 From: dannuic Date: Sat, 18 Apr 2026 00:08:18 -0600 Subject: [PATCH 09/12] Validated to OP_CastSpell -- still causes a spell to unmem after cast --- common/patches/tob.cpp | 3 +++ tob/opcodes.md | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 6522b2952..4b2a3dd1d 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -352,6 +352,7 @@ namespace TOB ENCODE(OP_CastSpell) { + // I don't think the client handles this at all, it only sends the cast packet ENCODE_LENGTH_EXACT(CastSpell_Struct); SETUP_DIRECT_ENCODE(CastSpell_Struct, structs::CastSpell_Struct); @@ -363,6 +364,7 @@ namespace TOB //OUT(inventoryslot); OUT(target_id); + LogNetcode("S->C OP_CastSpell {}", DumpPacketToString(__packet)); FINISH_ENCODE(); } @@ -3648,6 +3650,7 @@ namespace TOB IN(y_pos); IN(x_pos); IN(z_pos); + LogNetcode("C->S OP_CastSpell {}", DumpPacketToString(__packet)); FINISH_DIRECT_DECODE(); } diff --git a/tob/opcodes.md b/tob/opcodes.md index 3dbee363b..7e451637a 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -330,7 +330,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_LFPCommand` | 🔴 Not-Set | | | | `OP_LFPGetMatchesRequest` | 🔴 Not-Set | | | | `OP_LFPGetMatchesResponse` | 🔴 Not-Set | | | -| `OP_LinkedReuse` | 🟡 Unverified | | | +| `OP_LinkedReuse` | 🟢 Verified | | | | `OP_LoadSpellSet` | 🔴 Not-Set | | | | `OP_LocInfo` | 🔴 Not-Set | | | | `OP_LockoutTimerInfo` | 🔴 Not-Set | | | @@ -549,7 +549,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_Stamina` | 🟢 Verified | These values are 0-32k instead of 0-127 | | | `OP_Stun` | 🟡 Unverified | | | | `OP_Surname` | 🔴 Not-Set | | | -| `OP_SwapSpell` | 🟡 Unverified | | | +| `OP_SwapSpell` | 🟢 Verified | | | | `OP_SystemFingerprint` | 🔴 Not-Set | | | | `OP_TargetBuffs` | 🔴 Not-Set | | | | `OP_TargetCommand` | 🟡 Unverified | | | From b8ee811ac6f21bd33f7eef100eff2dc88ad0e9a2 Mon Sep 17 00:00:00 2001 From: dannuic Date: Sat, 18 Apr 2026 06:53:37 -0600 Subject: [PATCH 10/12] Fixed unmemming spells on cast --- common/patches/tob.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 4b2a3dd1d..78c0c11c6 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -969,6 +969,8 @@ namespace TOB eq->scribing = 2; else if (emu->scribing == 2) eq->scribing = 3; + else if (emu->scribing == 3) + eq->scribing = 4; else OUT(scribing); // TODO: can handle 4 here (I assume it's just like 2 or 3 but can have a reduction component) @@ -3861,6 +3863,8 @@ namespace TOB emu->scribing = 1; else if (eq->scribing == 3) emu->scribing = 2; + else if (eq->scribing == 4) + emu->scribing = 3; else IN(scribing); // TODO: Handle 4 here (clicky keyring) From c5d089de681a3e6e0e9e628d11acfe95d72bfabb Mon Sep 17 00:00:00 2001 From: dannuic Date: Sat, 18 Apr 2026 12:08:54 -0600 Subject: [PATCH 11/12] Validated message and interrupt packets, needs refactor for full functionality --- common/patches/tob.cpp | 8 ++++---- common/patches/tob_structs.h | 7 +++++++ tob/opcodes.md | 8 ++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/common/patches/tob.cpp b/common/patches/tob.cpp index 78c0c11c6..a57195041 100644 --- a/common/patches/tob.cpp +++ b/common/patches/tob.cpp @@ -671,8 +671,8 @@ namespace TOB } SerializeBuffer buffer; - buffer.WriteUInt32(emu->unknown0); - buffer.WriteUInt8(0); // Observed + buffer.WriteUInt32(0); // This is a string written like the message arrays + buffer.WriteUInt8(emu->unknown0); buffer.WriteUInt32(emu->string_id); buffer.WriteUInt32(emu->type); @@ -972,7 +972,7 @@ namespace TOB else if (emu->scribing == 3) eq->scribing = 4; else - OUT(scribing); // TODO: can handle 4 here (I assume it's just like 2 or 3 but can have a reduction component) + OUT(scribing); OUT(slot); OUT(spell_id); @@ -3866,7 +3866,7 @@ namespace TOB else if (eq->scribing == 4) emu->scribing = 3; else - IN(scribing); // TODO: Handle 4 here (clicky keyring) + IN(scribing); IN(slot); IN(spell_id); diff --git a/common/patches/tob_structs.h b/common/patches/tob_structs.h index e003490ea..db3cd4ad7 100644 --- a/common/patches/tob_structs.h +++ b/common/patches/tob_structs.h @@ -713,6 +713,13 @@ namespace TOB { /*39*/ }; + struct InterruptCast_Struct + { + uint32 spawnid; + uint32 messageid; + char message[0]; + }; + struct EQAffectSlot_Struct { /*00*/ int32 slot; /*04*/ int32 padding; diff --git a/tob/opcodes.md b/tob/opcodes.md index 7e451637a..31d2b54d2 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -79,7 +79,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_CancelTask` | 🔴 Not-Set | | | | `OP_CancelTrade` | 🟡 Unverified | | | | `OP_CashReward` | 🟡 Unverified | | | -| `OP_CastSpell` | 🟡 Unverified | | | +| `OP_CastSpell` | 🟢 Verified | | | | `OP_ChangeSize` | 🟢 Verified | | | | `OP_ChannelMessage` | 🟡 Unverified | | | | `OP_ChangePetName` | 🔴 Not-Set | | | @@ -185,7 +185,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_FloatListThing` | 🟢 Verified | Movement History. Sent from client, but emu doesn't use it so setting it as verified. Reference is 0x1402FFAD0 | | | `OP_Forage` | 🟡 Unverified | | | | `OP_ForceFindPerson` | 🔴 Not-Set | | | -| `OP_FormattedMessage` | 🟡 Unverified | | | +| `OP_FormattedMessage` | 🟢 Verified | Some major work to do here -- the client now expects a spell link in the packet, will need to refactor the client work to decouple the stream from the internal representation | | | `OP_FriendsWho` | 🟡 Unverified | | | | `OP_GetGuildMOTD` | 🔴 Not-Set | | | | `OP_GetGuildMOTDReply` | 🔴 Not-Set | | | @@ -289,7 +289,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_InspectMessageUpdate` | 🔴 Not-Set | | | | `OP_InspectRequest` | 🔴 Not-Set | | | | `OP_InstillDoubt` | 🟡 Unverified | | | -| `OP_InterruptCast` | 🟡 Unverified | | | +| `OP_InterruptCast` | 🟢 Verified | Some major work to do here -- the client now expects a spell link in the packet, will need to refactor the client work to decouple the stream from the internal representation | | | `OP_InvokeChangePetName` | 🔴 Not-Set | | | | `OP_InvokeChangePetNameImmediate` | 🔴 Not-Set | | | | `OP_InvokeNameChangeImmediate` | 🔴 Not-Set | | | @@ -533,7 +533,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_ShopRetrieveParcel` | 🟡 Unverified | | | | `OP_ShopParcelIcon` | 🟡 Unverified | | | | `OP_ShopRequest` | 🟡 Unverified | | | -| `OP_SimpleMessage` | 🟡 Unverified | | | +| `OP_SimpleMessage` | 🟢 Verified | | | | `OP_SkillUpdate` | 🟡 Unverified | | | | `OP_Sneak` | 🟡 Unverified | | | | `OP_Some3ByteHPUpdate` | 🔴 Not-Set | | | From af06fb703cdeffc4ea50b4e6f7d7ec0541543a80 Mon Sep 17 00:00:00 2001 From: dannuic Date: Sat, 18 Apr 2026 12:37:56 -0600 Subject: [PATCH 12/12] confirmed consider --- tob/opcodes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tob/opcodes.md b/tob/opcodes.md index 31d2b54d2..62db50a03 100644 --- a/tob/opcodes.md +++ b/tob/opcodes.md @@ -111,7 +111,7 @@ Below is a status list for the 450 opcodes we currently use on the server for th | `OP_Consent` | 🟡 Unverified | | | | `OP_ConsentDeny` | 🟡 Unverified | | | | `OP_ConsentResponse` | 🟢 Verified | | | -| `OP_Consider` | 🟡 Unverified | | | +| `OP_Consider` | 🟢 Verified | | | | `OP_ConsiderCorpse` | 🟡 Unverified | | | | `OP_Consume` | 🟡 Unverified | | | | `OP_ControlBoat` | 🟡 Unverified | | |