/* EQEmu: EQEmulator
Copyright (C) 2001-2026 EQEmu Development Team
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#pragma once
#include "common/emu_constants.h"
#include "common/textures.h"
#include "common/types.h"
#include "common/version.h"
#include "cereal/archives/binary.hpp"
#include "cereal/types/string.hpp"
#include "cereal/types/vector.hpp"
#include
#include
#include
#include
static const uint32 BUFF_COUNT = 42;
static const uint32 PET_BUFF_COUNT = 30;
static const uint32 MAX_MERC = 100;
static const uint32 MAX_MERC_GRADES = 10;
static const uint32 MAX_MERC_STANCES = 10;
static const uint32 BLOCKED_BUFF_COUNT = 20;
static const uint32 QUESTREWARD_COUNT = 8;
static const uint32 ADVANCED_LORE_LENGTH = 8192;
/*
** Compiler override to ensure
** byte aligned structures
*/
#pragma pack(push)
#pragma pack(1)
struct LoginInfo {
/*000*/ char login_info[64];
/*064*/ uint8 unknown064[124];
/*188*/ uint8 zoning; // 01 if zoning, 00 if not
/*189*/ uint8 unknown189[275];
/*488*/
};
struct EnterWorld_Struct {
/*000*/ char name[64];
/*064*/ uint32 tutorial; // 01 on "Enter Tutorial", 00 if not
/*068*/ uint32 return_home; // 01 on "Return Home", 00 if not
};
struct ExpansionInfo_Struct {
/*0000*/ uint32 Expansions;
};
/* Name Approval Struct */
/* Len: */
/* Opcode: 0x8B20*/
struct NameApproval
{
char name[64];
uint32 race;
uint32 class_;
uint32 deity;
};
/*
** Entity identification struct
** Size: 4 bytes
** OPCodes: OP_DeleteSpawn, OP_Assist
*/
struct EntityId_Struct
{
/*00*/ uint32 entity_id;
/*04*/
};
struct Duel_Struct
{
uint32 duel_initiator;
uint32 duel_target;
};
struct DuelResponse_Struct
{
uint32 target_id;
uint32 entity_id;
uint32 unknown;
};
//adventure stuff
enum AdventureObjective
{
Adventure_Random = 0,
Adventure_Assassinate = 1,
Adventure_Kill = 2,
Adventure_Collect = 3,
Adventure_Rescue = 4
};
typedef enum
{
LDoNTypeMechanical = 1,
LDoNTypeMagical = 2,
LDoNTypeCursed = 3,
} LDoNChestTypes;
struct LDoNTrapTemplate
{
uint32 id;
LDoNChestTypes type;
uint32 spell_id;
uint16 skill;
uint8 locked;
};
enum CrystalReclaimTypes
{
Ebon = 5,
Radiant = 4,
};
namespace ItemStackSizeConstraint {
constexpr int16 Minimum = 1;
constexpr int16 Maximum = 1000;
}
///////////////////////////////////////////////////////////////////////////////
// All clients translate the character select information to some degree
struct CharSelectEquip : EQ::textures::Texture_Struct, EQ::textures::Tint_Struct {};
// RoF2-based hybrid struct
struct CharacterSelectEntry_Struct
{
char Name[64];
uint8 Class;
uint32 Race;
uint8 Level;
uint8 ShroudClass;
uint32 ShroudRace;
uint16 Zone;
uint16 Instance;
uint8 Gender;
uint8 Face;
CharSelectEquip Equip[EQ::textures::materialCount];
uint8 Unknown15; // Seen FF
uint8 Unknown19; // Seen FF
uint32 DrakkinTattoo;
uint32 DrakkinDetails;
uint32 Deity;
uint32 PrimaryIDFile;
uint32 SecondaryIDFile;
uint8 HairColor;
uint8 BeardColor;
uint8 EyeColor1;
uint8 EyeColor2;
uint8 HairStyle;
uint8 Beard;
uint8 GoHome; // Seen 0 for new char and 1 for existing
uint8 Tutorial; // Seen 1 for new char or 0 for existing
uint32 DrakkinHeritage;
uint8 Unknown1; // Seen 0
uint8 Enabled; // Originally labeled as 'CharEnabled' - unknown purpose and setting
uint32 LastLogin;
uint8 Unknown2; // Seen 0
};
struct CharacterSelect_Struct
{
uint32 CharCount; //number of chars in this packet
uint32 TotalChars; //total number of chars allowed?
CharacterSelectEntry_Struct Entries[0];
};
/*
** Generic Spawn Struct
** Length: 257 Bytes
** Fields from old struct not yet found:
** float size;
** float walkspeed; // probably one of the ff 33 33 33 3f
** float runspeed; // probably one of the ff 33 33 33 3f
** uint8 traptype; // 65 is disarmable trap, 66 and 67 are invis triggers/traps
** uint8 npc_armor_graphic; // 0xFF=Player, 0=none, 1=leather, 2=chain, 3=steelplate
** uint8 npc_helm_graphic; // 0xFF=Player, 0=none, 1=leather, 2=chain, 3=steelplate
**
*/
/*
** Generic Spawn Struct
** Length: 383 Octets
** Used in:
** spawnZoneStruct
** dbSpawnStruct
** petStruct
** newSpawnStruct
*/
/*
showeq -> eqemu
sed -e 's/_t//g' -e 's/seto_0xFF/set_to_0xFF/g'
*/
struct Spawn_Struct {
/*0000*/ uint8 unknown0000;
/*0001*/ uint8 gm; // 0=no, 1=gm
/*0002*/ uint8 unknown0003;
/*0003*/ uint8 aaitle; // 0=none, 1=general, 2=archtype, 3=class
/*0004*/ uint8 unknown0004;
/*0005*/ uint8 anon; // 0=normal, 1=anon, 2=roleplay
/*0006*/ uint8 face; // Face id for players
/*0007*/ char name[64]; // Player's Name
/*0071*/ uint16 deity; // Player's Deity
/*0073*/ uint16 unknown0073;
/*0075*/ float size; // Model size
/*0079*/ uint32 unknown0079;
/*0083*/ uint8 NPC; // 0=player,1=npc,2=pc corpse,3=npc corpse,a
/*0084*/ uint8 invis; // Invis (0=not, 1=invis)
/*0085*/ uint8 haircolor; // Hair color
/*0086*/ uint8 curHp; // Current hp %%% wrong
/*0087*/ uint8 max_hp; // (name prolly wrong)takes on the value 100 for players, 100 or 110 for NPCs and 120 for PC corpses...
/*0088*/ uint8 findable; // 0=can't be found, 1=can be found
/*0089*/ uint8 unknown0089[5];
/*0094*/ signed deltaHeading:10; // change in heading
/*????*/ signed x:19; // x coord
/*????*/ signed padding0054:3; // ***Placeholder
/*0098*/ signed y:19; // y coord
/*????*/ signed animation:10; // animation
/*????*/ signed padding0058:3; // ***Placeholder
/*0102*/ signed z:19; // z coord
/*????*/ signed deltaY:13; // change in y
/*0106*/ signed deltaX:13; // change in x
/*????*/ unsigned heading:12; // heading
/*????*/ signed padding0066:7; // ***Placeholder
/*0110*/ signed deltaZ:13; // change in z
/*????*/ signed padding0070:19; // ***Placeholder
/*0114*/ uint8 eyecolor1; // Player's left eye color
/*0115*/ uint8 unknown0115[11]; // Was [24]
/*0126*/ uint8 StandState; // stand state for SoF+ 0x64 for normal animation
/*0127*/ uint32 drakkin_heritage; // Added for SoF
/*0131*/ uint32 drakkin_tattoo; // Added for SoF
/*0135*/ uint32 drakkin_details; // Added for SoF
/*0139*/ uint8 showhelm; // 0=no, 1=yes
/*0140*/ uint8 unknown0140[4];
/*0144*/ uint8 is_npc; // 0=no, 1=yes
/*0145*/ uint8 hairstyle; // Hair style
/*0146*/ uint8 beard; // Beard style (not totally, sure but maybe!)
/*0147*/ uint8 unknown0147[4];
/*0151*/ uint8 level; // Spawn Level
// None = 0, Open = 1, WeaponSheathed = 2, Aggressive = 4, ForcedAggressive = 8, InstrumentEquipped = 16, Stunned = 32, PrimaryWeaponEquipped = 64, SecondaryWeaponEquipped = 128
/*0152*/ uint32 PlayerState; // Controls animation stuff
/*0156*/ uint8 beardcolor; // Beard color
/*0157*/ char suffix[32]; // Player's suffix (of Veeshan, etc.)
/*0189*/ uint32 petOwnerId; // If this is a pet, the spawn id of owner
/*0193*/ uint8 guildrank; // 0=normal, 1=officer, 2=leader
/*0194*/ uint8 unknown0194[3];
/*0197*/ EQ::TextureProfile equipment;
/*0233*/ float runspeed; // Speed when running
/*0036*/ uint8 afk; // 0=no, 1=afk
/*0238*/ uint32 guildID; // Current guild
/*0242*/ char title[32]; // Title
/*0274*/ uint8 unknown0274; // non-zero prefixes name with '!'
/*0275*/ uint8 set_to_0xFF[8]; // ***Placeholder (all ff)
/*0283*/ uint8 helm; // Helm texture
/*0284*/ uint32 race; // Spawn race
/*0288*/ uint32 unknown0288;
/*0292*/ char lastName[32]; // Player's Lastname
/*0324*/ float walkspeed; // Speed when walking
/*0328*/ uint8 unknown0328;
/*0329*/ uint8 is_pet; // 0=no, 1=yes
/*0330*/ uint8 light; // Spawn's lightsource %%% wrong
/*0331*/ uint8 class_; // Player's class
/*0332*/ uint8 eyecolor2; // Left eye color
/*0333*/ uint8 flymode;
/*0334*/ uint8 gender; // Gender (0=male, 1=female)
/*0335*/ uint8 bodytype; // Bodytype
/*0336*/ uint8 unknown0336[3];
union
{
/*0339*/ uint8 equip_chest2; // Second place in packet for chest texture (usually 0xFF in live packets)
// Not sure why there are 2 of them, but it effects chest texture!
/*0339*/ uint8 mount_color; // drogmor: 0=white, 1=black, 2=green, 3=red
// horse: 0=brown, 1=white, 2=black, 3=tan
};
/*0340*/ uint32 spawnId; // Spawn Id
/*0344*/ float bounding_radius; // used in melee, overrides calc
/*0347*/ uint8 IsMercenary;
/*0348*/ EQ::TintProfile equipment_tint;
/*0384*/ uint8 lfg; // 0=off, 1=lfg on
/*0385*/
bool DestructibleObject; // Only used to flag as a destrible object
char DestructibleModel[64]; // Model of the Destructible Object - Required - Seen "DEST_TNT_G"
char DestructibleName2[64]; // Secondary name - Not Required - Seen "a_tent"
char DestructibleString[64]; // Unknown - Not Required - Seen "ZoneActor_01186"
uint32 DestructibleAppearance; // Damage Appearance
uint32 DestructibleUnk1;
uint32 DestructibleID1;
uint32 DestructibleID2;
uint32 DestructibleID3;
uint32 DestructibleID4;
uint32 DestructibleUnk2;
uint32 DestructibleUnk3;
uint32 DestructibleUnk4;
uint32 DestructibleUnk5;
uint32 DestructibleUnk6;
uint32 DestructibleUnk7;
uint8 DestructibleUnk8;
uint32 DestructibleUnk9;
bool targetable_with_hotkey;
bool show_name;
bool guild_show;
bool trader;
bool buyer;
bool untargetable;
uint32 npc_tint_id;
};
struct PlayerState_Struct {
/*00*/ uint32 spawn_id;
/*04*/ uint32 state;
};
/*
** New Spawn
** Length: 176 Bytes
** OpCode: 4921
*/
struct NewSpawn_Struct
{
struct Spawn_Struct spawn; // Spawn Information
};
struct ClientZoneEntry_Struct {
/*0000*/ uint32 unknown00;
/*0004*/ char char_name[64]; // Character Name
};
/*
** Server Zone Entry Struct
** OPCodes: OP_ServerZoneEntry
**
*/
struct ServerZoneEntry_Struct
{
struct NewSpawn_Struct player;
};
struct NewZone_Struct {
/*0000*/ char char_name[64]; // Character Name
/*0064*/ char zone_short_name[32]; // Zone Short Name
/*0096*/ char zone_long_name[278]; // Zone Long Name
/*0374*/ uint8 ztype; // Zone type (usually FF)
/*0375*/ uint8 fog_red[4]; // Zone fog (red)
/*0379*/ uint8 fog_green[4]; // Zone fog (green)
/*0383*/ uint8 fog_blue[4]; // Zone fog (blue)
/*0387*/ uint8 unknown323;
/*0388*/ float fog_minclip[4];
/*0404*/ float fog_maxclip[4];
/*0420*/ float gravity;
/*0424*/ uint8 time_type;
/*0425*/ uint8 rain_chance[4];
/*0429*/ uint8 rain_duration[4];
/*0433*/ uint8 snow_chance[4];
/*0437*/ uint8 snow_duration[4];
/*0441*/ uint8 unknown360[33];
/*0474*/ uint8 sky; // Sky Type
/*0475*/ uint8 unknown331[13]; // ***Placeholder
/*0488*/ float zone_exp_multiplier; // Experience Multiplier
/*0492*/ float safe_y; // Zone Safe Y
/*0496*/ float safe_x; // Zone Safe X
/*0500*/ float safe_z; // Zone Safe Z
/*0504*/ float max_z; // Guessed
/*0508*/ float underworld; // Underworld, min z (Not Sure?)
/*0512*/ float minclip; // Minimum View Distance
/*0516*/ float maxclip; // Maximum View DIstance
/*0520*/ uint8 unknown_end[84]; // ***Placeholder
/*0604*/ char zone_short_name2[68];
/*0672*/ char unknown672[12];
/*0684*/ uint16 zone_id;
/*0686*/ uint16 zone_instance;
/*0688*/ uint32 unknown688;
/*0692*/ uint8 unknown692[8];
// Titanium doesn't have a translator, but we can still safely add stuff under here without issues since client memcpy's only what it knows
// Just wastes some bandwidth sending to tit clients /shrug
/*0700*/ float fog_density;
/*0704*/ uint32 suspend_buffs;
/*0708*/ uint32 fast_regen_hp;
/*0712*/ uint32 fast_regen_mana;
/*0716*/ uint32 fast_regen_endurance;
/*0720*/ uint32 npc_aggro_max_dist;
/*0724*/ uint32 underworld_teleport_index; // > 0 teleports w/ zone point index, invalid succors, if this value is 0, it prevents you from running off edges that would end up underworld
/*0728*/ uint32 lava_damage; // Seen 50
/*0732*/ uint32 min_lava_damage; // Seen 10
/*0736*/ float safe_heading;
};
/*
** Memorize Spell Struct
** Length: 12 Bytes
**
*/
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 if memorizing a spell, set to 0 if scribing to book, 2 if un-memming
uint32 reduction; // lower reuse
};
/*
** Linked Spell Reuse Timer
** Length: 12
** Comes before the OP_Memorize
** Live (maybe TDS steam) has an extra DWORD after timer_id
*/
struct LinkedSpellReuseTimer_Struct {
uint32 timer_id; // Timer ID of the spell
uint32 end_time; // timestamp of when it will be ready
uint32 start_time; // timestamp of when it started
};
/*
** Make Charmed Pet
** Length: 12 Bytes
**
*/
struct Charm_Struct {
/*00*/ uint32 owner_id;
/*04*/ uint32 pet_id;
/*08*/ uint32 command; // 1: make pet, 0: release pet
/*12*/
};
struct InterruptCast_Struct
{
uint32 spawnid;
uint32 messageid;
char message[0];
};
struct DeleteSpell_Struct
{
/*000*/int16 spell_slot;
/*002*/uint8 unknowndss002[2];
/*004*/uint8 success;
/*005*/uint8 unknowndss006[3];
/*008*/
};
struct ManaChange_Struct
{
/*00*/ uint32 new_mana; // New Mana AMount
/*04*/ uint32 stamina;
/*08*/ uint32 spell_id;
/*12*/ uint8 keepcasting; // won't stop the cast. Change mana while casting?
/*13*/ uint8 padding[3]; // client doesn't read it, garbage data seems like
/*16*/ int32 slot; // -1 normal, otherwise clear ETA and GCD
};
struct SwapSpell_Struct
{
uint32 from_slot;
uint32 to_slot;
};
struct BeginCast_Struct
{
// len = 8
/*000*/ uint16 caster_id;
/*002*/ uint16 spell_id;
/*004*/ uint32 cast_time; // in miliseconds
};
struct CastSpell_Struct
{
uint32 slot;
uint32 spell_id;
uint32 inventoryslot; // slot for clicky item, 0xFFFF = normal cast
uint32 target_id;
uint32 cs_unknown1;
uint32 cs_unknown2;
float y_pos;
float x_pos;
float z_pos;
};
struct SpellEffect_Struct
{
/*000*/ uint32 EffectID;
/*004*/ uint32 EntityID;
/*008*/ uint32 EntityID2; // EntityID again
/*012*/ uint32 Duration; // In Milliseconds
/*016*/ uint32 FinishDelay; // In Milliseconds - delay for final part of spell effect
/*020*/ uint32 Unknown020; // Seen 3000
/*024*/ uint8 Unknown024; // Seen 1 for SoD
/*025*/ uint8 Unknown025; // Seen 1 for Live
/*026*/ uint16 Unknown026; // Seen 1157 and 1177 - varies per char
/*028*/
};
/*
** SpawnAppearance_Struct
** Changes client appearance for all other clients in zone
** Size: 8 bytes
** Used in: OP_SpawnAppearance
**
*/
struct SpawnAppearance_Struct
{
/*0000*/ uint16 spawn_id; // ID of the spawn
/*0002*/ uint16 type; // Values associated with the type
/*0004*/ uint32 parameter; // Type of data sent
/*0008*/
};
// this is used inside profile
struct SpellBuff_Struct
{
/*000*/ uint8 effect_type; // 0 = no buff, 2 = buff, 4 = inverse affects of buff
/*001*/ uint8 level;
/*002*/ uint8 bard_modifier;
/*003*/ uint8 unknown003; // MQ2 used to call this "damage shield" -- don't see client referencing it, so maybe server side DS type tracking? -- OSX client calls this "activated"
/*004*/ uint32 spellid;
/*008*/ int32 duration;
/*012*/ uint32 counters; // single book keeping value (counters, rune/vie)
/*016*/ uint32 player_id; // caster ID, pretty sure just zone ID
// extra stuff for newer packets
/*020*/ uint32 num_hits;
/*024*/ float y; // referenced by SPA 441
/*028*/ float x; // unsure if all buffs get them
/*032*/ float z; // as valid data
/*036*/
};
struct SpellBuffPacket_Struct {
/*000*/ uint32 entityid;
/*004*/ SpellBuff_Struct buff;
/*040*/ uint32 slotid;
/*044*/ uint32 bufffade;
/*048*/
};
// Underfoot & later struct.
struct BuffRemoveRequest_Struct
{
/*00*/ uint32 SlotID;
/*04*/ uint32 EntityID;
/*08*/
};
struct PetBuff_Struct {
/*000*/ uint32 petid;
/*004*/ uint32 spellid[PET_BUFF_COUNT];
/*124*/ int32 ticsremaining[PET_BUFF_COUNT];
/*244*/ uint32 buffcount;
};
struct BlockedBuffs_Struct
{
/*00*/ int32 SpellID[BLOCKED_BUFF_COUNT];
/*80*/ uint32 Count;
/*84*/ uint8 Pet;
/*85*/ uint8 Initialise;
/*86*/ uint16 Flags;
};
// same for adding
struct RemoveNimbusEffect_Struct
{
/*00*/ uint32 spawnid; // Spawn ID
/*04*/ int32 nimbus_effect; // Nimbus Effect Number
/*08*/
};
struct ItemNamePacket_Struct {
/*000*/ uint32 item_id;
/*004*/ uint32 unkown004;
/*008*/ char name[64];
/*072*/
};
// Length: 10
struct ItemProperties_Struct {
uint8 unknown01[2];
uint8 charges;
uint8 unknown02[13];
};
struct GMTrainee_Struct
{
/*000*/ uint32 npcid;
/*004*/ uint32 playerid;
/*008*/ uint32 skills[PACKET_SKILL_ARRAY_SIZE];
/*408*/ uint8 unknown408[40];
/*448*/
};
struct GMTrainEnd_Struct
{
/*000*/ uint32 npcid;
/*004*/ uint32 playerid;
/*008*/
};
struct GMSkillChange_Struct {
/*000*/ uint16 npcid;
/*002*/ uint8 unknown1[2]; // something like PC_ID, but not really. stays the same thru the session though
/*002*/ uint16 skillbank; // 0 if normal skills, 1 if languages
/*002*/ uint8 unknown2[2];
/*008*/ uint16 skill_id;
/*010*/ uint8 unknown3[2];
};
struct GMTrainSkillConfirm_Struct { // SoF only
/*000*/ uint32 SkillID;
/*004*/ uint32 Cost;
/*008*/ uint8 NewSkill; // Set to 1 for 'You have learned the basics' message.
/*009*/ char TrainerName[64];
/*073*/
};
struct ConsentResponse_Struct {
char grantname[64];
char ownername[64];
uint8 permission;
char zonename[32];
};
struct NameApproval_Struct {
char name[64];
uint32 race_id;
uint32 class_id;
};
/*
** Name Generator Struct
** Length: 72 bytes
** OpCode: 0x0290
*/
struct NameGeneration_Struct
{
/*0000*/ uint32 race;
/*0004*/ uint32 gender;
/*0008*/ char name[64];
/*0072*/
};
/*
** Character Creation struct
** Length: 140 Bytes
** OpCode: 0x0113
*/
struct CharCreate_Struct
{
/*0000*/ uint32 class_;
/*0004*/ uint32 haircolor; // Might be hairstyle
/*0008*/ uint32 beardcolor; // Might be beard
/*0012*/ uint32 beard; // Might be beardcolor
/*0016*/ uint32 gender;
/*0020*/ uint32 race;
/*0024*/ uint32 start_zone;
// 0 = odus
// 1 = qeynos
// 2 = halas
// 3 = rivervale
// 4 = freeport
// 5 = neriak
// 6 = gukta/grobb
// 7 = ogguk
// 8 = kaladim
// 9 = gfay
// 10 = felwithe
// 11 = akanon
// 12 = cabalis
// 13 = shar vahl
/*0028*/ uint32 hairstyle; // Might be haircolor
/*0032*/ uint32 deity;
/*0036*/ uint32 STR;
/*0040*/ uint32 STA;
/*0044*/ uint32 AGI;
/*0048*/ uint32 DEX;
/*0052*/ uint32 WIS;
/*0056*/ uint32 INT;
/*0060*/ uint32 CHA;
/*0064*/ uint32 face; // Could be unknown0076
/*0068*/ uint32 eyecolor1; //its possiable we could have these switched
/*0073*/ uint32 eyecolor2; //since setting one sets the other we really can't check
/*0076*/ uint32 drakkin_heritage; // added for SoF
/*0080*/ uint32 drakkin_tattoo; // added for SoF
/*0084*/ uint32 drakkin_details; // added for SoF
/*0088*/ uint32 tutorial;
};
/*
*Used in PlayerProfile
*/
struct AA_Array
{
uint32 AA;
uint32 value;
uint32 charges;
};
typedef struct
{
/*00*/ char Name[64];
/*64*/ uint32 Level;
/*68*/ uint32 Race;
/*72*/ uint32 Class;
/*76*/ uint32 Zone;
/*80*/ uint32 Time;
/*84*/ uint32 Points;
/*88*/
} PVPStatsEntry_Struct;
static const uint32 MAX_PP_DISCIPLINES = 100;
static const uint32 MAX_DISCIPLINE_TIMERS = 20;
struct Disciplines_Struct {
uint32 values[MAX_PP_DISCIPLINES];
};
static const uint32 TRIBUTE_NONE = 0xFFFFFFFF;
struct Tribute_Struct {
uint32 tribute;
uint32 tier;
};
// Bandolier item positions
enum
{
bandolierPrimary = 0,
bandolierSecondary,
bandolierRange,
bandolierAmmo
};
//len = 72
struct BandolierItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 320
struct Bandolier_Struct
{
char Name[32];
BandolierItem_Struct Items[EQ::profile::BANDOLIER_ITEM_COUNT];
};
//len = 72
struct PotionBeltItem_Struct
{
uint32 ID;
uint32 Icon;
char Name[64];
};
//len = 288
struct PotionBelt_Struct
{
PotionBeltItem_Struct Items[EQ::profile::POTION_BELT_SIZE];
};
struct MovePotionToBelt_Struct
{
uint32 Action;
uint32 SlotNumber;
uint32 ItemID;
};
static const uint32 MAX_GROUP_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_RAID_LEADERSHIP_AA_ARRAY = 16;
static const uint32 MAX_LEADERSHIP_AA_ARRAY = (MAX_GROUP_LEADERSHIP_AA_ARRAY+MAX_RAID_LEADERSHIP_AA_ARRAY);
struct GroupLeadershipAA_Struct {
union {
struct {
uint32 groupAAMarkNPC;
uint32 groupAANPCHealth;
uint32 groupAADelegateMainAssist;
uint32 groupAADelegateMarkNPC;
uint32 groupAA4;
uint32 groupAA5;
uint32 groupAAInspectBuffs;
uint32 groupAA7;
uint32 groupAASpellAwareness;
uint32 groupAAOffenseEnhancement;
uint32 groupAAManaEnhancement;
uint32 groupAAHealthEnhancement;
uint32 groupAAHealthRegeneration;
uint32 groupAAFindPathToPC;
uint32 groupAAHealthOfTargetsTarget;
uint32 groupAA15;
};
uint32 ranks[MAX_GROUP_LEADERSHIP_AA_ARRAY];
};
};
struct RaidLeadershipAA_Struct {
union {
struct {
uint32 raidAAMarkNPC;
uint32 raidAANPCHealth;
uint32 raidAADelegateMainAssist;
uint32 raidAADelegateMarkNPC;
uint32 raidAA4;
uint32 raidAA5;
uint32 raidAA6;
uint32 raidAASpellAwareness;
uint32 raidAAOffenseEnhancement;
uint32 raidAAManaEnhancement;
uint32 raidAAHealthEnhancement;
uint32 raidAAHealthRegeneration;
uint32 raidAAFindPathToPC;
uint32 raidAAHealthOfTargetsTarget;
uint32 raidAA14;
uint32 raidAA15;
};
uint32 ranks[MAX_RAID_LEADERSHIP_AA_ARRAY];
};
};
struct LeadershipAA_Struct {
union {
struct {
GroupLeadershipAA_Struct group;
RaidLeadershipAA_Struct raid;
};
uint32 ranks[MAX_LEADERSHIP_AA_ARRAY];
};
};
/**
* A bind point.
* Size: 20 Octets
*/
struct BindStruct {
/*000*/ uint32 zone_id;
/*004*/ float x;
/*008*/ float y;
/*012*/ float z;
/*016*/ float heading;
/*020*/ uint32 instance_id;
/*024*/
};
struct SuspendedMinion_Struct
{
/*000*/ uint16 SpellID;
/*002*/ uint32 HP;
/*006*/ uint32 Mana;
/*010*/ SpellBuff_Struct Buffs[BUFF_COUNT];
/*510*/ EQ::TextureMaterialProfile Items;
/*546*/ char Name[64];
/*610*/
};
/*
** Player Profile
**
** Length: 4308 bytes
** OpCode: 0x006a
*/
static const uint32 MAX_PP_LANGUAGE = 28;
static const uint32 MAX_PP_SKILL = PACKET_SKILL_ARRAY_SIZE; // 100 - actual skills buffer size
static const uint32 MAX_PP_INNATE_SKILL = 25;
static const uint32 MAX_PP_AA_ARRAY = 240;
static const uint32 MAX_GROUP_MEMBERS = 6;
static const uint32 MAX_RECAST_TYPES = 20;
/*
showeq -> eqemu
sed -e 's/_t//g' -e 's/MAX_AA/MAX_PP_AA_ARRAY/g' \
-e 's/MAX_SPELL_SLOTS/MAX_PP_MEMSPELL/g' \
-e 's/MAX_KNOWN_SKILLS/MAX_PP_SKILL/g' \
-e 's/MAXRIBUTES/MAX_PLAYER_TRIBUTES/g' \
-e 's/MAX_BUFFS/BUFF_COUNT/g' \
-e 's/MAX_KNOWN_LANGS/MAX_PP_LANGUAGE/g' \
-e 's/MAX_RECASTYPES/MAX_RECAST_TYPES/g' \
-e 's/spellBuff/SpellBuff_Struct/g' \
-e 's/lastName/last_name/g' \
-e 's/guildID/guildid/g' \
-e 's/itemint/item_tint/g' \
-e 's/MANA/mana/g' \
-e 's/curHp/cur_hp/g' \
-e 's/sSpellBook/spell_book/g' \
-e 's/sMemSpells/mem_spells/g' \
-e 's/uint32[ \t]*disciplines\[MAX_DISCIPLINES\]/Disciplines_Struct disciplines/g' \
-e 's/aa_unspent/aapoints/g' \
-e 's/aa_spent/aapoints_spent/g' \
-e 's/InlineItem[ \t]*potionBelt\[MAX_POTIONS_IN_BELT\]/PotionBelt_Struct potionbelt/g' \
-e 's/ldon_guk_points/ldon_points_guk/g' \
-e 's/ldon_mir_points/ldon_points_mir/g' \
-e 's/ldon_mmc_points/ldon_points_mmc/g' \
-e 's/ldon_ruj_points/ldon_points_ruj/g' \
-e 's/ldonak_points/ldon_points_tak/g' \
-e 's/ldon_avail_points/ldon_points_available/g' \
-e 's/tributeTime/tribute_time_remaining/g' \
-e 's/careerTribute/career_tribute_points/g' \
-e 's/currentTribute/tribute_points/g' \
-e 's/tributeActive/tribute_active/g' \
-e 's/TributeStruct/Tribute_Struct/g' \
-e 's/expGroupLeadAA/group_leadership_exp/g' \
-e 's/expRaidLeadAA/raid_leadership_exp/g' \
-e 's/groupLeadAAUnspent/group_leadership_points/g' \
-e 's/raidLeadAAUnspent/raid_leadership_points/g' \
-e 's/uint32[ \t]*leadershipAAs\[MAX_LEAD_AA\]/LeadershipAA_Struct leader_abilities/g' \
-e 's/BandolierStruct/Bandolier_Struct/g' \
-e 's/MAX_BANDOLIERS/MAX_PLAYER_BANDOLIER/g' \
-e 's/birthdayTime/birthday/g' \
-e 's/lastSaveTime/lastlogin/g' \
-e 's/zoneId/zone_id/g' \
-e 's/hunger/hunger_level/g' \
-e 's/thirst/thirst_level/g' \
-e 's/guildstatus/guildrank/g' \
-e 's/airRemaining/air_remaining/g' \
*/
struct PlayerProfile_Struct
{
// /*0000*/ uint32 checksum; // Checksum from CRC32::SetEQChecksum
/*0004*/ char name[64]; // Name of player sizes not right
/*0068*/ char last_name[32]; // Last name of player sizes not right
/*0100*/ uint32 gender; // Player Gender - 0 Male, 1 Female
/*0104*/ uint32 race; // Player race
/*0108*/ uint32 class_; // Player class
/*0112*/ uint32 unknown0112; //
/*0116*/ uint32 level; // Level of player (might be one byte)
/*0120*/ BindStruct binds[5]; // Bind points (primary is first, home city is fifth)
/*0220*/ uint32 deity; // deity
/*0224*/ uint32 guild_id;
/*0228*/ uint32 birthday; // characters bday
/*0232*/ uint32 lastlogin; // last login or zone time
/*0236*/ uint32 timePlayedMin; // in minutes
/*0240*/ uint8 pvp;
/*0241*/ uint8 level2; //no idea why this is here, but thats how it is on live
/*0242*/ uint8 anon; // 2=roleplay, 1=anon, 0=not anon
/*0243*/ uint8 gm;
/*0244*/ uint8 guildrank;
/*0245*/ uint8 guildbanker;
/*0246*/ uint8 unknown0246[6]; //
/*0252*/ uint32 intoxication;
/*0256*/ uint32 spellSlotRefresh[EQ::spells::SPELL_GEM_COUNT]; //in ms
/*0292*/ uint32 abilitySlotRefresh;
/*0296*/ uint8 haircolor; // Player hair color
/*0297*/ uint8 beardcolor; // Player beard color
/*0298*/ uint8 eyecolor1; // Player left eye color
/*0299*/ uint8 eyecolor2; // Player right eye color
/*0300*/ uint8 hairstyle; // Player hair style
/*0301*/ uint8 beard; // Beard type
/*0302*/ uint8 ability_time_seconds; //The following four spots are unknown right now.....
/*0303*/ uint8 ability_number; //ability used
/*0304*/ uint8 ability_time_minutes;
/*0305*/ uint8 ability_time_hours; //place holder
/*0306*/ uint8 unknown0306[6]; // @bp Spacer/Flag?
/*0312*/ EQ::TextureMaterialProfile item_material; // Item texture/material of worn/held items
/*0348*/ uint8 unknown0348[44];
/*0392*/ EQ::TintProfile item_tint;
/*0428*/ AA_Array aa_array[MAX_PP_AA_ARRAY];
/*2348*/ float unknown2384; //seen ~128, ~47
/*2352*/ char servername[32]; // length probably not right
/*2384*/ char title[32]; // length might be wrong
/*2416*/ char suffix[32]; // length might be wrong
/*2448*/ uint32 guildid2; //
/*2452*/ uint32 exp; // Current Experience
/*2456*/ uint32 unknown2492;
/*2460*/ uint32 points; // Unspent Practice points
/*2464*/ uint32 mana; // current mana
/*2468*/ uint32 cur_hp; // current hp
/*2472*/ uint32 unknown2508; // 0x05
/*2476*/ uint32 STR; // Strength
/*2480*/ uint32 STA; // Stamina
/*2484*/ uint32 CHA; // Charisma
/*2488*/ uint32 DEX; // Dexterity
/*2492*/ uint32 INT; // Intelligence
/*2496*/ uint32 AGI; // Agility
/*2500*/ uint32 WIS; // Wisdom
/*2504*/ uint8 face; // Player face
/*2505*/ uint8 unknown2541[47]; // ?
/*2552*/ uint8 languages[MAX_PP_LANGUAGE];
/*2580*/ uint8 unknown2616[4];
/*2584*/ uint32 spell_book[EQ::spells::SPELLBOOK_SIZE];
/*4504*/ uint8 unknown4540[128]; // Was [428] all 0xff
/*4632*/ uint32 mem_spells[EQ::spells::SPELL_GEM_COUNT];
/*4668*/ uint8 unknown4704[32]; //
/*4700*/ float y; // Player y position
/*4704*/ float x; // Player x position
/*4708*/ float z; // Player z position
/*4712*/ float heading; // Direction player is facing
/*4716*/ uint8 unknown4752[4]; //
/*4720*/ int32 platinum; // Platinum Pieces on player
/*4724*/ int32 gold; // Gold Pieces on player
/*4728*/ int32 silver; // Silver Pieces on player
/*4732*/ int32 copper; // Copper Pieces on player
/*4736*/ int32 platinum_bank; // Platinum Pieces in Bank
/*4740*/ int32 gold_bank; // Gold Pieces in Bank
/*4744*/ int32 silver_bank; // Silver Pieces in Bank
/*4748*/ int32 copper_bank; // Copper Pieces in Bank
/*4752*/ int32 platinum_cursor; // Platinum on cursor
/*4756*/ int32 gold_cursor; // Gold on cursor
/*4760*/ int32 silver_cursor; // Silver on cursor
/*4764*/ int32 copper_cursor; // Copper on cursor
/*4768*/ int32 platinum_shared; // Platinum shared between characters
/*4772*/ uint8 unknown4808[24];
/*4796*/ uint32 skills[MAX_PP_SKILL]; // [400] List of skills // 100 dword buffer
/*5196*/ uint32 InnateSkills[MAX_PP_INNATE_SKILL];
/*5296*/ uint8 unknown5132[84];
/*5380*/ uint32 pvp2; //
/*5384*/ uint32 unknown5420; //
/*5388*/ uint32 pvptype; //
/*5392*/ uint32 unknown5428; //
/*5396*/ uint32 ability_down; // Guessing
/*5400*/ uint8 unknown5436[8]; //
/*5408*/ uint32 autosplit; //not used right now
/*5412*/ uint8 unknown5448[8];
/*5420*/ uint32 zone_change_count; // Number of times user has zoned in their career (guessing)
/*5424*/ uint8 unknown5460[16]; //
/*5440*/ uint32 drakkin_heritage; //
/*5444*/ uint32 drakkin_tattoo; //
/*5448*/ uint32 drakkin_details; //
/*5452*/ uint32 expansions; // expansion setting, bit field of expansions avaliable
/*5456*/ int32 toxicity; //from drinking potions, seems to increase by 3 each time you drink
/*5460*/ char unknown5496[16]; //
/*5476*/ int32 hunger_level;
/*5480*/ int32 thirst_level;
/*5484*/ uint32 ability_up;
/*5488*/ char unknown5524[16];
/*5504*/ uint16 zone_id; // Current zone of the player
/*5506*/ uint16 zoneInstance; // Instance ID
/*5508*/ SpellBuff_Struct buffs[BUFF_COUNT]; // Buffs currently on the player
/*6008*/ char groupMembers[6][64];//
/*6392*/ char unknown6428[656];
/*7048*/ uint32 entityid;
/*7052*/ uint32 leadAAActive;
/*7056*/ uint32 unknown7092;
/*7060*/ int32 ldon_points_guk; //client uses these as signed
/*7064*/ int32 ldon_points_mir;
/*7068*/ int32 ldon_points_mmc;
/*7072*/ int32 ldon_points_ruj;
/*7076*/ int32 ldon_points_tak;
/*7080*/ int32 ldon_points_available;
/*7084*/ int32 ldon_wins_guk;
/*7088*/ int32 ldon_wins_mir;
/*7092*/ int32 ldon_wins_mmc;
/*7096*/ int32 ldon_wins_ruj;
/*7100*/ int32 ldon_wins_tak;
/*7104*/ int32 ldon_losses_guk;
/*7108*/ int32 ldon_losses_mir;
/*7112*/ int32 ldon_losses_mmc;
/*7116*/ int32 ldon_losses_ruj;
/*7120*/ int32 ldon_losses_tak;
/*7124*/ uint8 unknown7160[72];
/*7196*/ uint32 tribute_time_remaining; //in miliseconds
/*7200*/ uint32 showhelm;
/*7204*/ uint32 career_tribute_points;
/*7208*/ uint32 unknown7244;
/*7212*/ uint32 tribute_points;
/*7216*/ uint32 unknown7252;
/*7220*/ uint32 tribute_active; //1=active
/*7224*/ Tribute_Struct tributes[EQ::invtype::TRIBUTE_SIZE];
/*7264*/ Disciplines_Struct disciplines;
/*7664*/ uint32 recastTimers[MAX_RECAST_TYPES]; // Timers (GMT of last use)
/*7744*/ char unknown7780[160];
/*7904*/ uint32 endurance;
/*7908*/ uint32 group_leadership_exp; //0-1000
/*7912*/ uint32 raid_leadership_exp; //0-2000
/*7916*/ uint32 group_leadership_points;
/*7920*/ uint32 raid_leadership_points;
/*7924*/ LeadershipAA_Struct leader_abilities;
/*8052*/ uint8 unknown8088[132];
/*8184*/ uint32 air_remaining;
/*8188*/ uint32 PVPKills;
/*8192*/ uint32 PVPDeaths;
/*8196*/ uint32 PVPCurrentPoints;
/*8200*/ uint32 PVPCareerPoints;
/*8204*/ uint32 PVPBestKillStreak;
/*8208*/ uint32 PVPWorstDeathStreak;
/*8212*/ uint32 PVPCurrentKillStreak;
/*8216*/ PVPStatsEntry_Struct PVPLastKill;
/*8304*/ PVPStatsEntry_Struct PVPLastDeath;
/*8392*/ uint32 PVPNumberOfKillsInLast24Hours;
/*8396*/ PVPStatsEntry_Struct PVPRecentKills[50];
/*12796*/ uint32 aapoints_spent;
/*12800*/ uint32 expAA;
/*12804*/ uint32 aapoints; //avaliable, unspent
/*12808*/ uint8 unknown12844[36];
/*12844*/ Bandolier_Struct bandoliers[EQ::profile::BANDOLIERS_SIZE];
/*14124*/ uint8 unknown14160[4506];
/*18630*/ SuspendedMinion_Struct SuspendedMinion; // No longer in use
/*19240*/ uint32 timeentitledonaccount;
/*19244*/ PotionBelt_Struct potionbelt; //there should be 3 more of these
/*19532*/ uint8 unknown19568[8];
/*19540*/ uint32 currentRadCrystals; // Current count of radiant crystals
/*19544*/ uint32 careerRadCrystals; // Total count of radiant crystals ever
/*19548*/ uint32 currentEbonCrystals;// Current count of ebon crystals
/*19552*/ uint32 careerEbonCrystals; // Total count of ebon crystals ever
/*19556*/ uint8 groupAutoconsent; // 0=off, 1=on
/*19557*/ uint8 raidAutoconsent; // 0=off, 1=on
/*19558*/ uint8 guildAutoconsent; // 0=off, 1=on
/*19559*/ uint8 unknown19595[5]; // ***Placeholder (6/29/2005)
/*19564*/ uint32 RestTimer;
/*19568*/ uint32 char_id; // Found as part of bazaar revamp (5/15/2024)
// All player profile packets are translated and this overhead is ignored in out-bound packets
PlayerProfile_Struct() : m_player_profile_version(EQ::versions::MobVersion::Unknown) { }
EQ::versions::MobVersion PlayerProfileVersion() { return m_player_profile_version; }
void SetPlayerProfileVersion(EQ::versions::MobVersion mob_version) { m_player_profile_version = EQ::versions::ValidateMobVersion(mob_version); }
void SetPlayerProfileVersion(EQ::versions::ClientVersion client_version) { SetPlayerProfileVersion(EQ::versions::ConvertClientVersionToMobVersion(client_version)); }
private:
// No need for gm flag since pp already has one
// No need for lookup pointer since this struct is not tied to any one system
EQ::versions::MobVersion m_player_profile_version;
};
/*
** Client Target Struct
** Length: 2 Bytes
** OpCode: 6221
*/
struct ClientTarget_Struct {
/*000*/ uint32 new_target; // Target ID
};
/*
** Target Rejection Struct
** Length: 12 Bytes
** OpCode: OP_TargetReject
*/
struct TargetReject_Struct {
/*00*/ uint8 unknown00[12];
};
struct PetCommand_Struct {
/*000*/ uint32 command;
/*004*/ uint32 target;
};
struct PetCommandState_Struct {
/*00*/ uint32 button_id;
/*04*/ uint32 state;
};
/*
** Delete Spawn
** Length: 4 Bytes
** OpCode: OP_DeleteSpawn
*/
struct DeleteSpawn_Struct
{
/*00*/ uint32 spawn_id; // Spawn ID to delete
/*04*/ uint8 Decay; // 0 = vanish immediately, 1 = 'Decay' sparklies for corpses.
};
/*
** Channel Message received or sent
** Length: 144 Bytes + Variable Length + 1
** OpCode: OP_ChannelMessage
**
*/
struct ChannelMessage_Struct
{
/*000*/ char targetname[64]; // Tell recipient
/*064*/ char sender[64]; // The senders name (len might be wrong)
/*128*/ uint32 language; // Language
/*132*/ uint32 chan_num; // Channel
/*136*/ uint32 cm_unknown4[2]; // ***Placeholder
/*144*/ uint32 skill_in_language; // The players skill in this language? might be wrong
/*148*/ char message[0]; // Variable length message
};
/*
** Special Message
** Length: 4 Bytes + Variable Text Length + 1
** OpCode: OP_SpecialMesg
**
*/
/*
Theres something wrong with this... example live packet:
Server->Client: [ Opcode: OP_SpecialMesg (0x0fab) Size: 244 ]
0: 01 02 00 0A 00 00 00 09 - 05 00 00 42 61 72 73 74 | ...........Barst
16: 72 65 20 53 6F 6E 67 77 - 65 61 76 65 72 00 7C F9 | re Songweaver.|.
32: FF FF 84 FF FF FF 03 00 - 00 00 47 72 65 65 74 69 | ..........Greeti
*/
struct SpecialMesg_Struct
{
/*00*/ char header[3]; // 04 04 00 <-- for #emote style msg
/*03*/ uint32 msg_type; // Color of text (see MT_*** below)
/*07*/ uint32 target_spawn_id; // Who is it being said to?
/*11*/ char sayer[1]; // Who is the source of the info
/*12*/ uint8 unknown12[12];
/*24*/ char message[1]; // What is being said?
};
struct SpecialMesgHeader_Struct
{
/*00*/ char SpeakMode; // 2 shouts, 4 %1 %2, 3 %2, 5 tells group, 0 copy, default says
/*01*/ char JournalMode; // 1 and 2 go to journal
/*02*/ char language;
/*03*/ uint32 msg_type; // Color of text (see MT_*** below)
/*07*/ uint32 target_spawn_id; // Who is it being said to?
/*11*/ // speaker's name
/*xx*/ // unknown, location, client doesn't care
/*xx*/ // unknown
/*xx*/ // unknown
/*xx*/ // message
};
/*
** When somebody changes what they're wearing or give a pet a weapon (model changes)
** Length: 19 Bytes
*/
struct WearChange_Struct {
/*000*/ uint16 spawn_id;
/*002*/ uint32 material;
/*006*/ uint32 unknown06;
/*010*/ uint32 elite_material; // 1 for Drakkin Elite Material
/*014*/ uint32 hero_forge_model; // New to VoA
/*018*/ uint32 unknown18; // New to RoF
/*022*/ EQ::textures::Tint_Struct color;
/*026*/ uint8 wear_slot_id;
/*027*/
};
/*
** Type: Bind Wound Structure
** Length: 8 Bytes
*/
//Fixed for 7-14-04 patch
struct BindWound_Struct
{
/*002*/ uint16 to; // TargetID
/*004*/ uint16 unknown2; // ***Placeholder
/*006*/ uint16 type;
/*008*/ uint16 unknown6;
};
/*
** Type: Zone Change Request (before hand)
** Length: 88 bytes
** OpCode: a320
*/
struct ZoneChange_Struct {
/*000*/ char char_name[64]; // Character Name
/*064*/ uint16 zoneID;
/*066*/ uint16 instanceID;
/*068*/ float y;
/*072*/ float x;
/*076*/ float z;
/*080*/ uint32 zone_reason; //0x0A == death, I think
/*084*/ int32 success; // =0 client->server, =1 server->client, -X=specific error
/*088*/
};
// Whatever you send to the client in RequestClientZoneChange_Struct.type, the client will send back
// to the server in ZoneChange_Struct.zone_reason. My guess is this is a memo field of sorts.
// 27 January 2008
struct RequestClientZoneChange_Struct {
/*00*/ uint16 zone_id;
/*02*/ uint16 instance_id;
/*04*/ float y;
/*08*/ float x;
/*12*/ float z;
/*16*/ float heading;
/*20*/ uint32 type; //unknown... values
};
struct Animation_Struct {
/*00*/ uint16 spawnid;
/*02*/ uint8 speed;
/*03*/ uint8 action;
/*04*/
};
// this is what causes the caster to animate and the target to
// get the particle effects around them when a spell is cast
// also causes a buff icon
struct Action_Struct
{
/* 00 */ uint16 target; // id of target
/* 02 */ uint16 source; // id of caster
/* 04 */ uint16 level; // level of caster for spells, OSX dump says attack rating, guess spells use it for level
/* 06 */ uint32 instrument_mod; // OSX dump says base damage, spells use it for bard song (different from newer clients)
/* 10 */ float force;
/* 14 */ float hit_heading;
/* 18 */ float hit_pitch;
/* 22 */ uint8 type; // 231 (0xE7) for spells, skill
/* 23 */ uint16 unknown23; // OSX says min_damage
/* 25 */ uint16 unknown25; // OSX says tohit
/* 27 */ uint16 spell; // spell id being cast
/* 29 */ uint8 spell_level;
// this field seems to be some sort of success flag, if it's 4
/* 30 */ uint8 effect_flag; // if this is 4, a buff icon is made
// newer clients have some data for setting LaunchSpellData when effect_flag & 4
// /* 31 */ uint8 spell_gem;
// /* 32 */ uint32 inventory_slot;
// /* 36 */ uint32 item_cast_type;
};
// this is what prints the You have been struck. and the regular
// melee messages like You try to pierce, etc. It's basically the melee
// and spell damage message
struct CombatDamage_Struct
{
/* 00 */ uint16 target;
/* 02 */ uint16 source;
/* 04 */ uint8 type; //slashing, etc. 231 (0xE7) for spells, skill
/* 05 */ uint16 spellid;
/* 07 */ uint32 damage;
/* 11 */ float force;
/* 15 */ float hit_heading; // see above notes in Action_Struct
/* 19 */ float hit_pitch;
/* 23 */ uint32 special; // 2 = Rampage, 1 = Wild Rampage
};
/*
** Consider Struct
*/
struct Consider_Struct{
/*000*/ uint32 playerid; // PlayerID
/*004*/ uint32 targetid; // TargetID
/*008*/ uint32 faction; // Faction
/*0012*/ uint32 level; // Level
/*016*/ int32 cur_hp; // Current Hitpoints
/*020*/ int32 max_hp; // Maximum Hitpoints
/*024*/ uint8 pvpcon; // Pvp con flag 0/1
/*025*/ uint8 unknown3[3];
};
/*
** Spawn Death Blow
** Length: 32 Bytes
** OpCode: 0114
*/
struct Death_Struct
{
/*000*/ uint32 spawn_id;
/*004*/ uint32 killer_id;
/*008*/ uint32 corpseid; // was corpseid
/*012*/ uint32 bindzoneid;
/*016*/ uint32 spell_id;
/*020*/ uint32 attack_skill;
/*024*/ uint32 damage;
/*028*/ uint32 unknown028;
};
struct BecomeCorpse_Struct {
uint32 spawn_id;
float y;
float x;
float z;
};
/*
** Spawn position update
** Struct sent from server->client to update position of
** another spawn's position update in zone (whether NPC or PC)
**
*/
struct PlayerPositionUpdateServer_Struct
{
/*0000*/ uint16 spawn_id;
/*0002*/ uint16 vehicle_id;
/*0004*/ signed padding0004 : 12;
signed y_pos : 19; // y coord
unsigned padding : 1;
/*0008*/ signed delta_z : 13; // change in z
signed delta_x : 13; // change in x
signed padding0008 : 6;
/*0012*/ signed x_pos : 19; // x coord
unsigned heading : 12; // heading
signed padding0016 : 1;
/*0016*/ signed delta_heading : 10; // change in heading
signed z_pos : 19; // z coord
signed padding0020 : 3;
/*0020*/ signed animation : 10; // animation
signed delta_y : 13; // change in y
signed padding0024 : 9;
/*0024*/
};
/*
** Player position update
** Struct sent from client->server to update
** player position on server
**
*/
struct PlayerPositionUpdateClient_Struct
{
/*0000*/ uint16 sequence; // increments one each packet - Verified
/*0002*/ uint16 spawn_id; // Player's spawn id
/*0004*/ uint16 vehicle_id; // Player's vehicle spawn id
/*0006*/ uint8 unknown0004[4]; // ***Placeholder
/*0010*/ float delta_x; // Change in x
/*0014*/ unsigned heading : 12; // Directional heading
unsigned padding0040 : 20; // ***Placeholder
/*0018*/ float x_pos; // x coord (2nd loc value)
/*0022*/ float delta_z; // Change in z
/*0026*/ float z_pos; // z coord (3rd loc value)
/*0030*/ float y_pos; // y coord (1st loc value)
/*0034*/ unsigned animation : 10; // ***Placeholder
unsigned padding0024 : 22; // animation
/*0038*/ float delta_y; // Change in y
/*0042*/ signed delta_heading : 10; // change in heading
unsigned padding0041 : 22; // ***Placeholder
/*0046*/
};
struct SpawnPositionUpdate_Struct
{
/*0000*/ uint16 spawn_id;
/*0002*/ uint64 y_pos:19, z_pos:19, x_pos:19, padding002:7;
/*0010*/ unsigned heading:12;
/*0012*/ signed padding010:4;
};
/*
** Spawn HP Update
** Length: 10 Bytes
** OpCode: OP_HPUpdate
*/
struct SpawnHPUpdate_Struct
{
/*00*/ uint32 cur_hp; // Id of spawn to update
/*04*/ int32 max_hp; // Maximum hp of spawn
/*08*/ int16 spawn_id; // Current hp of spawn
/*10*/
};
struct ManaUpdate_Struct
{
/*00*/ uint32 cur_mana;
/*04*/ uint32 max_mana;
/*08*/ uint16 spawn_id;
/*10*/
};
struct EnduranceUpdate_Struct
{
/*00*/ uint32 cur_end;
/*04*/ uint32 max_end;
/*08*/ uint16 spawn_id;
/*10*/
};
struct SpawnHPUpdate_Struct2
{
/*00*/ int16 spawn_id;
/*02*/ uint8 hp; //HP Percentage
/*03*/
};
struct MobManaUpdate_Struct
{
/*00*/ uint16 spawn_id;
/*02*/ uint8 mana; //Mana Percentage
/*03*/
};
struct MobEnduranceUpdate_Struct
{
/*00*/ uint16 spawn_id;
/*02*/ uint8 endurance; //Endurance Percentage
/*03*/
};
// Is this even used?
struct MobHealth
{
/*0000*/ uint8 hp; //health percent
/*0001*/ uint16 id; //mobs id
};
/*
** Stamina
** Length: 8 Bytes
** OpCode: 5721
*/
struct Stamina_Struct {
/*00*/ uint32 food; // (low more hungry 127-0)
/*02*/ uint32 water; // (low more thirsty 127-0)
};
/*
** Level Update
** Length: 12 Bytes
*/
struct LevelUpdate_Struct
{
/*00*/ uint32 level; // New level
/*04*/ uint32 level_old; // Old level
/*08*/ uint32 exp; // Current Experience
};
/*
** Experience Update
** Length: 14 Bytes
** OpCode: 9921
*/
struct ExpUpdate_Struct
{
/*0000*/ uint32 exp; // Current experience ratio from 0 to 330
/*0004*/ uint32 aaxp; // @BP ??
};
/*
** Item Packet Struct - Works on a variety of opcodes
** Packet Types: See ItemPacketType enum
**
*/
enum ItemPacketType {
ItemPacketViewLink = 0x00,
ItemPacketMerchant = 0x64,
ItemPacketTradeView = 0x65,
ItemPacketLoot = 0x66,
ItemPacketTrade = 0x67,
ItemPacketCharInventory = 0x69,
ItemPacketLimbo = 0x6A,
ItemPacketWorldContainer = 0x6B,
ItemPacketTributeItem = 0x6C,
ItemPacketGuildTribute = 0x6D,
ItemPacketCharmUpdate = 0x6E, // noted as incorrect
ItemPacketRecovery = 0x71,
ItemPacketParcel = 0x73,
ItemPacketInvalid = 0xFF
};
enum MerchantWindowTabDisplay {
None = 0x00,
SellBuy = 0x01,
Recover = 0x02,
SellBuyRecover = 0x03,
Parcel = 0x04,
SellBuyParcel = 0x05,
RecoverParcel = 0x06,
SellBuyRecoverParcel = 0x07
};
//enum ItemPacketType
//{
// ItemPacketMerchant = /*100*/ 0x64, // Titanium+
// ItemPacketTradeView = /*101*/ 0x65,
// ItemPacketLoot = /*102*/ 0x66,
// ItemPacketTrade = /*103*/ 0x67,
// ItemPacketCharInventory = /*105*/ 0x69, // 105 looks like raw item packet (no appearance update) thru shared bank..110, possibly possessions with appearance update
// ItemPacketLimbo = /*106*/ 0x6A,
// ItemPacketWorldContainer = /*107*/ 0x6B,
// ItemPacketTributeItem = /*108*/ 0x6C,
// ItemPacketGuildTribute = /*109*/ 0x6D, // missing from EQEmu
// ItemPacket10 = /*110*/ 0x6E,
// ItemPacket11 = /*111*/ 0x6F, // UF+ (equipment slots only) (RoF+ checks '(WORD*)slot + 4 != -1' [(WORD*)]slot + 2 would be bag index - if used) (guess) (appearance (over-level) items?)
// ItemPacket12 = /*112*/ 0x70, // RoF+ (causes stat update) (could be TrophyTribute and GuildTrophyTribute together - two case methodology - is it checking for GuildID?)
// ItemPacketMerchantRecovery = /*113*/ 0x71,
// ItemPacket14 = /*115*/ 0x73, (real estate/moving crate?)
// ItemPacket__ = /*xxx*/ 0xXX // switch 'default' - all clients
//};
struct ItemPacket_Struct
{
/*00*/ ItemPacketType PacketType;
/*04*/ char SerializedItem[1];
/*xx*/
};
struct BulkItemPacket_Struct
{
/*00*/ char SerializedItem[0];
/*xx*/
};
struct Consume_Struct
{
/*0000*/ uint32 slot;
/*0004*/ uint32 auto_consumed; // 0xffffffff when auto eating e7030000 when right click
/*0008*/ uint8 c_unknown1[4];
/*0012*/ uint8 type; // 0x01=Food 0x02=Water
/*0013*/ uint8 unknown13[3];
};
struct DeleteItem_Struct {
/*0000*/ uint32 from_slot;
/*0004*/ uint32 to_slot;
/*0008*/ uint32 number_in_stack;
/*0012*/
};
struct MoveItem_Struct
{
/*0000*/ uint32 from_slot;
/*0004*/ uint32 to_slot;
/*0008*/ uint32 number_in_stack;
/*0012*/
};
// New for RoF2 - Size: 12
struct InventorySlot_Struct
{
/*000*/ int16 Type; // Worn and Normal inventory = 0, Bank = 1, Shared Bank = 2, Delete Item = -1
/*002*/ int16 Unknown02;
/*004*/ int16 Slot;
/*006*/ int16 SubIndex;
/*008*/ int16 AugIndex; // Guessing - Seen 0xffff
/*010*/ int16 Unknown01; // Normally 0 - Seen 13262 when deleting an item, but didn't match item ID
/*012*/
};
struct MultiMoveItemSub_Struct
{
/*0000*/ InventorySlot_Struct from_slot;
/*0012*/ InventorySlot_Struct to_slot;
/*0024*/ uint32 number_in_stack;
/*0028*/ uint8 unknown[8];
};
struct MultiMoveItem_Struct
{
/*0000*/ uint32 count;
/*0004*/ MultiMoveItemSub_Struct moves[0];
};
// both MoveItem_Struct/DeleteItem_Struct server structures will be changing to a structure-based slot format..this will
// be used for handling SoF/SoD/etc... time stamps sent using the MoveItem_Struct format. (nothing will be done with this
// info at the moment..but, it is forwarded on to the server for handling/future use)
struct ClientTimeStamp_Struct
{
/*0000*/ uint32 from_slot;
/*0004*/ uint32 to_slot;
/*0008*/ uint32 number_in_stack;
/*0012*/
};
//
// from_slot/to_slot
// -1 - destroy
// 0 - cursor
// 1 - inventory
// 2 - bank
// 3 - trade
// 4 - shared bank
//
// cointype
// 0 - copeer
// 1 - silver
// 2 - gold
// 3 - platinum
//
static const uint32 COINTYPE_PP = 3;
static const uint32 COINTYPE_GP = 2;
static const uint32 COINTYPE_SP = 1;
static const uint32 COINTYPE_CP = 0;
struct MoveCoin_Struct
{
int32 from_slot;
int32 to_slot;
uint32 cointype1;
uint32 cointype2;
int32 amount;
};
struct TradeCoin_Struct{
uint32 trader;
uint8 slot;
uint16 unknown5;
uint8 unknown7;
uint32 amount;
};
struct TradeMoneyUpdate_Struct{
uint32 trader;
uint32 type;
uint32 amount;
};
/*
** Surname struct
** Size: 100 bytes
*/
struct Surname_Struct
{
/*0000*/ char name[64];
/*0064*/ uint32 unknown0064;
/*0068*/ char lastname[32];
/*0100*/
};
struct GuildsListEntry_Struct {
char name[64];
};
static const uint32 MAX_NUMBER_GUILDS = 1500;
struct GuildsList_Struct {
uint8 head[64]; // First on guild list seems to be empty...
GuildsListEntry_Struct Guilds[MAX_NUMBER_GUILDS];
};
struct GuildsListMessagingEntry_Struct {
/*000*/ uint32 guild_id;
/*004*/ std::string guild_name;
template
void serialize(Archive& archive)
{
archive(
CEREAL_NVP(guild_id),
CEREAL_NVP(guild_name)
);
}
};
struct GuildsListMessaging_Struct {
/*000*/ char header[64];
/*064*/ uint32 no_of_guilds;
/*068*/ uint32 string_length;
/*072*/ std::vector guild_detail;
template
void serialize(Archive& archive)
{
archive(
CEREAL_NVP(header),
CEREAL_NVP(no_of_guilds),
CEREAL_NVP(string_length),
CEREAL_NVP(guild_detail)
);
}
};
struct GuildUpdate_Struct {
uint32 guildID;
GuildsListEntry_Struct entry;
};
struct GuildMemberAdd_Struct {
/*000*/ uint32 guild_id;
/*004*/ uint32 unknown04;
/*008*/ uint32 unknown08;
/*012*/ uint32 unknown12;
/*016*/ uint32 level;
/*020*/ uint32 class_;
/*024*/ uint32 rank_;
/*028*/ uint32 guild_show;
/*032*/ uint32 zone_id;
/*036*/ uint32 last_on;
/*040*/ char player_name[64];
};
struct GuildMemberLevel_Struct {
/*000*/ uint32 guild_id;
/*004*/ char player_name[64];
/*068*/ uint32 level;
};
struct GuildMemberRank_Struct {
/*000*/ uint32 guild_id;
/*004*/ uint32 rank_;
/*008*/ char player_name[64];
/*072*/ uint32 alt_banker; //Banker/Alt bit 00 - none 10 - Alt 11 - Alt and Banker 01 - Banker. Banker not functional for RoF2+
/*076*/ uint32 offline;
};
struct GuildMemberPublicNote_Struct {
/*000*/ uint32 guild_id;
/*004*/ char player_name[64];
/*068*/ char public_note[256]; //RoF2 256
};
struct GuildDelete_Struct {
/*000*/ uint32 guild_id;
};
struct GuildRenameGuild_Struct {
/*000*/ uint32 guild_id;
/*004*/ char new_guild_name[64];
};
struct GuildRenameMember_Struct {
/*000*/ uint32 guild_id;
/*004*/ char player_name[64];
/*068*/ char new_player_name[64];
};
struct GuildMemberDetails_Struct {
/*000*/ uint32 guild_id;
/*004*/ char player_name[64];
/*068*/ uint32 zone_id;
/*072*/ uint32 last_on;
/*076*/ uint32 offline_mode; //1 Offline
};
struct GuildMemberDelete_Struct {
/*000*/ uint32 guild_id;
/*004*/ char player_name[64];
};
/*
** Money Loot
** Length: 22 Bytes
** OpCode: 5020
*/
struct moneyOnCorpseStruct {
/*0000*/ uint8 response; // 0 = someone else is, 1 = OK, 2 = not at this time
/*0001*/ uint8 unknown1; // = 0x5a
/*0002*/ uint8 unknown2; // = 0x40
/*0003*/ uint8 unknown3; // = 0
/*0004*/ uint32 platinum; // Platinum Pieces
/*0008*/ uint32 gold; // Gold Pieces
/*0012*/ uint32 silver; // Silver Pieces
/*0016*/ uint32 copper; // Copper Pieces
};
//opcode = 0x5220
// size 292
struct LootingItem_Struct {
/*000*/ uint32 lootee;
/*002*/ uint32 looter;
/*004*/ uint16 slot_id;
/*006*/ uint8 unknown3[2];
/*008*/ int32 auto_loot;
};
struct GuildManageStatus_Struct{
uint32 guild_id;
uint32 oldrank;
uint32 newrank;
char name[64];
};
// Guild invite, remove
struct GuildJoin_Struct{
/*000*/ uint32 guild_id;
/*004*/ uint32 unknown04;
/*008*/ uint32 level;
/*012*/ uint32 class_;
/*016*/ uint32 rank;//0 member, 1 officer, 2 leader
/*020*/ uint32 zoneid;
/*024*/ uint32 unknown24;
/*028*/ char name[64];
/*092*/
};
struct GuildInviteAccept_Struct {
char inviter[64];
char new_member[64];
uint32 response;
uint32 guild_id;
};
struct GuildManageRemove_Struct {
uint32 guildeqid;
char member[64];
};
struct GuildCommand_Struct {
char othername[64];
char myname[64];
uint16 guildeqid;
uint8 unknown[2]; // for guildinvite all 0's, for remove 0=0x56, 2=0x02
uint32 officer;
};
struct OnLevelMessage_Struct
{
char Title[128];
char Text[4096];
uint32 Buttons;
uint32 Duration;
uint32 PopupID;
uint32 NegativeID;
uint32 SoundControls;
char ButtonName0[25];
char ButtonName1[25];
};
struct PopupResponse_Struct {
/*0000*/ uint32 unknown0000;
/*0004*/ uint32 popupid;
};
enum GuildInformationActions
{
GuildUpdateURL = 0,
GuildUpdateChannel = 1,
GuildUpdateRanks = 4,
GuildUpdatePermissions = 5
};
struct GuildManageBanker_Struct {
uint32 unknown0;
char myname[64];
char member[64];
uint32 enabled;
};
// Server -> Client
// Update a guild members rank and banker status
struct GuildSetRank_Struct
{
/*00*/ uint32 Unknown00;
/*04*/ uint32 Unknown04;
/*08*/ uint32 rank;
/*12*/ char member_name[64];
/*76*/ uint32 banker;
/*80*/
};
// Opcode OP_GMZoneRequest
// Size = 88 bytes
struct GMZoneRequest_Struct {
/*0000*/ char charname[64];
/*0064*/ uint32 zone_id;
/*0068*/ float x;
/*0072*/ float y;
/*0076*/ float z;
/*0080*/ float heading;
/*0084*/ uint32 success; // 0 if command failed, 1 if succeeded?
/*0088*/
// /*072*/ int8 success; // =0 client->server, =1 server->client, -X=specific error
// /*073*/ uint8 unknown0073[3]; // =0 ok, =ffffff error
};
struct GMSummon_Struct {
/* 0*/ char charname[64];
/* 30*/ char gmname[64];
/* 60*/ uint32 success;
/* 61*/ uint32 zoneID;
/*92*/ float y;
/*96*/ float x;
/*100*/ float z;
/*104*/ uint32 unknown2; // E0 E0 56 00
};
struct GMFind_Struct {
char charname[64];
char gmname[64];
uint32 success;
uint32 zoneID;
float x;
float y;
float z;
uint32 unknown2;
};
struct GMGoto_Struct { // x,y is swapped as compared to summon and makes sense as own packet
/* 0*/ char charname[64];
/* 64*/ char gmname[64];
/* 128*/uint32 success;
/* 132*/ uint32 zoneID;
/*136*/ int32 y;
/*140*/ int32 x;
/*144*/ int32 z;
/*148*/ uint32 unknown2; // E0 E0 56 00
};
struct GMLastName_Struct {
char name[64];
char gmname[64];
char lastname[64];
uint16 unknown[4]; // 0x00, 0x00
// 0x01, 0x00 = Update the clients
};
//Combat Abilities
struct CombatAbility_Struct {
uint32 m_target; //the ID of the target mob
uint32 m_atk;
uint32 m_skill;
};
// Disarm Struct incoming from Client [Size: 16]
struct Disarm_Struct
{
uint32 source;
uint32 target;
uint32 skill;
uint32 unknown;
};
//Instill Doubt
struct Instill_Doubt_Struct {
uint8 i_id;
uint8 ia_unknown;
uint8 ib_unknown;
uint8 ic_unknown;
uint8 i_atk;
uint8 id_unknown;
uint8 ie_unknown;
uint8 if_unknown;
uint8 i_type;
uint8 ig_unknown;
uint8 ih_unknown;
uint8 ii_unknown;
};
struct GiveItem_Struct {
uint16 to_entity;
int16 to_equipSlot;
uint16 from_entity;
int16 from_equipSlot;
};
struct RandomReq_Struct {
uint32 low;
uint32 high;
};
/* 9/23/03 reply to /random command */
struct RandomReply_Struct {
/* 00 */ uint32 low;
/* 04 */ uint32 high;
/* 08 */ uint32 result;
/* 12 */ char name[64];
/* 76 */
};
struct LFG_Struct {
/*
Wrong size on OP_LFG. Got: 80, Expected: 68
0: 00 00 00 00 01 00 00 00 - 00 00 00 00 64 00 00 00 | ............d...
16: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
32: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
48: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
64: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
Wrong size on OP_LFG. Got: 80, Expected: 68
0: 00 00 00 00 01 00 00 00 - 3F 00 00 00 41 00 00 00 | ........?...A...
16: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
32: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
48: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
64: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
Wrong size on OP_LFG. Got: 80, Expected: 68
0: 00 00 00 00 01 00 00 00 - 3F 00 00 00 41 00 00 00 | ........?...A...
16: 46 72 75 62 20 66 72 75 - 62 20 66 72 75 62 00 00 | Frub frub frub..
32: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
48: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
64: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00 | ................
*/
/*000*/ uint32 unknown000;
/*004*/ uint8 value; // 0x00 = off 0x01 = on
/*005*/ uint8 MatchFilter;
/*006*/ uint16 Unknown006;
/*008*/ uint32 FromLevel;
/*012*/ uint32 ToLevel;
/*016*/ char Comments[64];
};
struct LFGGetMatchesRequest_Struct {
/*000*/ uint32 Unknown000;
/*004*/ uint32 FromLevel;
/*008*/ uint32 ToLevel;
/*012*/ uint32 Classes;
};
enum { LFPOff = 0,
LFPOn = 1,
LFPMemberUpdate = 255 // Internal use, not sent by client
};
struct LFP_Struct {
/*000*/ uint32 Unknown000;
/*004*/ uint8 Action;
/*005*/ uint8 MatchFilter;
/*006*/ uint16 Unknown006;
/*008*/ uint32 FromLevel;
/*012*/ uint32 ToLevel;
/*016*/ uint32 Classes;
/*020*/ char Comments[64];
};
struct LFPGetMatchesRequest_Struct {
/*000*/ uint32 Unknown000;
/*004*/ uint32 FromLevel;
/*008*/ uint32 ToLevel;
};
/*
** LFG_Appearance_Struct
** Packet sent to clients to notify when someone in zone toggles LFG flag
** Size: 8 bytes
** Used in: OP_LFGAppearance
**
*/
struct LFG_Appearance_Struct
{
/*0000*/ uint32 spawn_id; // ID of the client
/*0004*/ uint8 lfg; // 1=LFG, 0=Not LFG
/*0005*/ char unknown0005[3]; //
/*0008*/
};
// EverQuest Time Information:
// 72 minutes per EQ Day
// 3 minutes per EQ Hour
// 6 seconds per EQ Tick (2 minutes EQ Time)
// 3 seconds per EQ Minute
struct TimeOfDay_Struct {
uint8 hour;
uint8 minute;
uint8 day;
uint8 month;
uint32 year;
};
// Darvik: shopkeeper structs
struct MerchantClick_Struct
{
/*000*/ uint32 npc_id; // Merchant NPC's entity id
/*004*/ uint32 player_id;
/*008*/ uint32 command; // 1=open, 0=cancel/close
/*012*/ float rate; // cost multiplier, dosent work anymore
/*016*/ int32 tab_display; // bitmask b000 none, b001 Purchase/Sell, b010 Recover, b100 Parcels
/*020*/ int32 unknown020; // Seen 2592000 from Server or -1 from Client
/*024*/
};
enum MerchantActions {
Close = 0,
Open = 1
};
struct Parcel_Struct
{
/*000*/ uint32 npc_id;
/*004*/ uint32 item_slot;
/*008*/ uint32 quantity;
/*012*/ uint32 money_flag;
/*016*/ char send_to[64];
/*080*/ char note[128];
/*208*/ uint32 unknown_208;
/*212*/ uint32 unknown_212;
/*216*/ uint32 unknown_216;
};
struct ParcelRetrieve_Struct
{
uint32 merchant_entity_id;
uint32 player_entity_id;
uint32 parcel_slot_id;
uint32 parcel_item_id;
};
struct ParcelMessaging_Struct {
ItemPacketType packet_type;
std::string serialized_item;
uint32 sent_time;
std::string player_name;
std::string note;
uint32 slot_id;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(packet_type),
CEREAL_NVP(serialized_item),
CEREAL_NVP(sent_time),
CEREAL_NVP(player_name),
CEREAL_NVP(note),
CEREAL_NVP(slot_id)
);
}
};
struct ParcelIcon_Struct {
uint32 status; //0 off 1 on 2 overlimit
};
enum ParcelIconActions {
IconOff = 0,
IconOn = 1,
Overlimit = 2
};
/*
Unknowns:
0 is e7 from 01 to // MAYBE SLOT IN PURCHASE
1 is 03
2 is 00
3 is 00
4 is ??
5 is ??
6 is 00 from a0 to
7 is 00 from 3f to */
/*
0 is F6 to 01
1 is CE CE
4A 4A
00 00
00 E0
00 CB
00 90
00 3F
*/
struct Merchant_Sell_Struct {
/*000*/ uint32 npcid; // Merchant NPC's entity id
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
uint32 unknown12;
/*016*/ uint32 quantity;
/*020*/ uint32 price;
};
struct Merchant_Purchase_Struct {
/*000*/ uint32 npcid; // Merchant NPC's entity id
/*004*/ uint32 itemslot; // Player's entity id
/*008*/ uint32 quantity;
/*012*/ uint32 price;
};
struct Merchant_DelItem_Struct{
/*000*/ uint32 npcid; // Merchant NPC's entity id
/*004*/ uint32 playerid; // Player's entity id
/*008*/ uint32 itemslot;
/*012*/ uint32 unknown012;
};
struct Adventure_Purchase_Struct {
/*000*/ uint32 Type; // 1 = LDoN, 2 = Discord, 4 = Norrath's Keepers, 5 = Dark Reign
/*000*/ uint32 npcid;
/*004*/ uint32 itemid;
/*008*/ uint32 variable;
};
struct Adventure_Sell_Struct {
/*000*/ uint32 unknown000; //0x01
/*004*/ uint32 npcid;
/*008*/ uint32 slot;
/*012*/ uint32 charges;
/*016*/ uint32 sell_price;
};
struct AdventurePoints_Update_Struct {
/*000*/ uint32 ldon_available_points; // Total available points
/*004*/ uint8 unknown004[36];
/*040*/ uint8 unknown040[16];
/*056*/ uint32 ldon_guk_points; // Earned Deepest Guk points
/*060*/ uint8 unknown060[16];
/*076*/ uint32 ldon_mirugal_points; // Earned Mirugal' Menagerie points
/*080*/ uint8 unknown080[16];
/*096*/ uint32 ldon_mistmoore_points; // Earned Mismoore Catacombs Points
/*100*/ uint8 unknown100[16];
/*116*/ uint32 ldon_rujarkian_points; // Earned Rujarkian Hills points
/*120*/ uint8 unknown120[16];
/*136*/ uint32 ldon_takish_points; // Earned Takish points
/*140*/
};
struct AdventureFinish_Struct{
/*000*/ uint32 win_lose;//Cofruben: 00 is a lose,01 is win.
/*004*/ uint32 points;
/*008*/
};
struct Weblink_Struct{
/*000*/ char weblink[1];
/*004*/
};
//OP_AdventureRequest
struct AdventureRequest_Struct{
/*000*/ uint32 risk;//1 normal,2 hard.
/*004*/ uint32 entity_id;
/*008*/ uint32 type;
/*012*/
};
struct AdventureRequestResponse_Struct{
/*0000*/ uint32 unknown000;
/*0004*/ char text[2048];
/*2052*/ uint32 timetoenter;
/*2056*/ uint32 timeleft;
/*2060*/ uint32 risk;
/*2064*/ float x;
/*2068*/ float y;
/*2072*/ float z;
/*2076*/ uint32 showcompass;
/*2080*/ uint32 unknown2080;
/*2084*/
};
struct AdventureCountUpdate_Struct
{
/*000*/ uint32 current;
/*004*/ uint32 total;
/*008*/
};
struct AdventureStatsColumn_Struct
{
/*000*/ uint32 total;
/*004*/ uint32 guk;
/*008*/ uint32 mir;
/*012*/ uint32 mmc;
/*016*/ uint32 ruj;
/*020*/ uint32 tak;
/*024*/
};
struct AdventureStats_Struct
{
/*000*/ AdventureStatsColumn_Struct success;
/*024*/ AdventureStatsColumn_Struct failure;
/*048*/ AdventureStatsColumn_Struct rank;
/*072*/ AdventureStatsColumn_Struct rank2;
/*096*/
};
//this is mostly right but something is off that causes the client to crash sometimes
//I don't really care enough about the feature to work on it anymore though.
struct AdventureLeaderboardEntry_Struct
{
/*000*/ char name[64];
/*064*/ uint32 success;
/*068*/ uint32 failure;
/*072*/
};
struct AdventureLeaderboardRequest_Struct
{
/*000*/ uint32 type;
/*004*/ uint32 theme;
/*008*/ uint32 risk;
/*012*/
};
struct AdventureLeaderboard_Struct
{
/*000*/ uint32 unknown000;
/*004*/ uint32 unknown004;
/*008*/ uint32 success;
/*012*/ uint32 failure;
/*016*/ uint32 our_rank;
/*020*/ AdventureLeaderboardEntry_Struct entries[100];
};
/*struct Item_Shop_Struct {
uint16 merchantid;
uint8 itemtype;
EQ::ItemData item;
uint8 iss_unknown001[6];
};*/
struct Illusion_Struct { //size: 256 - SoF
/*000*/ uint32 spawnid;
/*004*/ char charname[64]; //
/*068*/ uint16 race; //
/*070*/ char unknown006[2];
/*072*/ uint8 gender;
/*073*/ uint8 texture;
/*074*/ uint8 unknown008; //
/*075*/ uint8 unknown009; //
/*076*/ uint8 helmtexture; //
/*077*/ uint8 unknown010; //
/*078*/ uint8 unknown011; //
/*079*/ uint8 unknown012; //
/*080*/ uint32 face; //
/*084*/ uint8 hairstyle; //
/*085*/ uint8 haircolor; //
/*086*/ uint8 beard; //
/*087*/ uint8 beardcolor; //
/*088*/ float size; //
/*092*/ uint32 drakkin_heritage; //
/*096*/ uint32 drakkin_tattoo; //
/*100*/ uint32 drakkin_details; //
/*104*/ EQ::TintProfile armor_tint; //
/*140*/ uint8 eyecolor1; // Field Not Identified in any Illusion Struct
/*141*/ uint8 eyecolor2; // Field Not Identified in any Illusion Struct
/*142*/ uint8 unknown138[114]; //
/*256*/
};
struct Illusion_Struct_Old {
/*000*/ uint32 spawnid;
char charname[64];
/**/ uint16 race;
/**/ char unknown006[2];
/**/ uint8 gender;
/**/ uint8 texture;
/**/ uint8 helmtexture;
/**/ uint8 unknown011;
/**/ uint32 face;
/**/ char unknown020[88];
/**/
};
// OP_Sound - Size: 68
struct QuestReward_Struct
{
/*000*/ uint32 mob_id; // ID of mob awarding the client
/*004*/ uint32 target_id;
/*008*/ uint32 exp_reward;
/*012*/ uint32 faction;
/*016*/ int32 faction_mod;
/*020*/ uint32 copper; // Gives copper to the client
/*024*/ uint32 silver; // Gives silver to the client
/*028*/ uint32 gold; // Gives gold to the client
/*032*/ uint32 platinum; // Gives platinum to the client
/*036*/ int32 item_id[QUESTREWARD_COUNT]; // -1 for nothing
/*068*/
};
struct CashReward_Struct
{
/*000*/ uint32 copper;
/*004*/ uint32 silver;
/*008*/ uint32 gold;
/*012*/ uint32 platinum;
};
// Size: 8
struct Camera_Struct
{
uint32 duration; // Duration in ms
float intensity;
};
struct ZonePoint_Entry {
/*0000*/ uint32 iterator;
/*0004*/ float y;
/*0008*/ float x;
/*0012*/ float z;
/*0016*/ float heading;
/*0020*/ uint16 zoneid;
/*0022*/ uint16 zoneinstance; // LDoN instance
};
struct ZonePoints {
/*0000*/ uint32 count;
/*0004*/ struct ZonePoint_Entry zpe[0]; // Always add one extra to the end after all zonepoints
};
struct SkillUpdate_Struct {
/*00*/ uint32 skillId;
/*04*/ uint32 value;
/*08*/
};
struct ZoneUnavail_Struct {
//This actually varies, but...
char zonename[16];
int16 unknown[4];
};
enum { //Group action fields
groupActJoin = 0,
groupActLeave = 1,
groupActDisband = 6,
groupActUpdate = 7,
groupActMakeLeader = 8,
groupActInviteInitial = 9,
groupActAAUpdate = 10
};
struct GroupGeneric_Struct {
char name1[64];
char name2[64];
};
struct GroupCancel_Struct {
char name1[64];
char name2[64];
uint8 toggle;
};
struct GroupUpdate_Struct {
/*0000*/ uint32 action;
/*0004*/ char yourname[64];
/*0068*/ char membername[5][64];
/*0388*/ char leadersname[64];
};
struct GroupUpdate2_Struct {
/*0000*/ uint32 action;
/*0004*/ char yourname[64];
/*0068*/ char membername[5][64];
/*0388*/ char leadersname[64];
/*0452*/ GroupLeadershipAA_Struct leader_aas;
/*0580*/ uint8 unknown580[196];
/*0766*/ uint32 NPCMarkerID; // EntityID of player delegated MarkNPC ability
/*0780*/ uint8 unknown780[56];
/*0836*/
};
struct GroupJoin_Struct {
/*0000*/ uint32 action;
/*0004*/ char yourname[64];
/*0068*/ char membername[64];
/*0132*/ GroupLeadershipAA_Struct leader_aas;
/*0196*/ uint8 unknown196[196];
/*0392*/ uint32 NPCMarkerID; // EntityID of player delegated MarkNPC ability
/*0396*/ uint8 unknown396[56];
/*0452*/
};
// SoD+ Struct
struct GroupLeadershipAAUpdate_Struct
{
/*000*/ uint32 Unknown000; // GroupID or Leader EntityID ?
/*004*/ GroupLeadershipAA_Struct LeaderAAs;
/*068*/ uint32 Unknown068[49]; // Was 63
/*264*/ uint32 NPCMarkerID;
/*268*/ uint32 Unknown268[13];
/*320*/
};
struct GroupFollow_Struct { // SoF Follow Struct
/*0000*/ char name1[64]; // inviter
/*0064*/ char name2[64]; // invitee
/*0128*/ uint32 unknown0128;
/*0132*/
};
// this is generic struct
struct GroupLeaderChange_Struct
{
/*000*/ char Unknown000[64];
/*064*/ char LeaderName[64];
/*128*/ char Unknown128[20];
};
struct GroupMentor_Struct {
/*000*/ int percent;
/*004*/ char name[64];
/*068*/
};
struct FaceChange_Struct {
/*000*/ uint8 haircolor;
/*001*/ uint8 beardcolor;
/*002*/ uint8 eyecolor1; // the eyecolors always seem to be the same, maybe left and right eye?
/*003*/ uint8 eyecolor2;
/*004*/ uint8 hairstyle;
/*005*/ uint8 beard;
/*006*/ uint8 face;
/*007*/ uint8 unused_padding;
/*008*/ uint32 drakkin_heritage;
/*012*/ uint32 drakkin_tattoo;
/*016*/ uint32 drakkin_details;
/*020*/ uint32 entity_id;
/*024*/
//there are only 10 faces for barbs changing woad just
//increase the face value by ten so if there were 8 woad
//designs then there would be 80 barb faces
};
/*
** Trade request from one client to another
** Used to initiate a trade
** Size: 8 bytes
** Used in: OP_TradeRequest
*/
struct TradeRequest_Struct {
/*00*/ uint32 to_mob_id;
/*04*/ uint32 from_mob_id;
/*08*/
};
struct TradeAccept_Struct {
/*00*/ uint32 from_mob_id;
/*04*/ uint32 unknown4; //seems to be garbage
/*08*/
};
/*
** Cancel Trade struct
** Sent when a player cancels a trade
** Size: 8 bytes
** Used In: OP_CancelTrade
**
*/
struct CancelTrade_Struct {
/*00*/ uint32 fromid;
/*04*/ uint32 action;
/*08*/
};
struct TradeBusy_Struct {
/*00*/ uint32 to_mob_id;
/*04*/ uint32 from_mob_id;
/*08*/ uint8 type; // Seen 01
/*09*/ uint8 unknown09; // Seen EF (239)
/*10*/ uint8 unknown10; // Seen FF (255)
/*11*/ uint8 unknown11; // Seen FF (255)
/*12*/
};
struct PetitionUpdate_Struct {
uint32 petnumber; // Petition Number
uint32 color; // 0x00 = green, 0x01 = yellow, 0x02 = red
uint32 status;
time_t senttime; // 4 has to be 0x1F
char accountid[32];
char gmsenttoo[64];
int32 quetotal;
char charname[64];
};
struct Petition_Struct {
uint32 petnumber;
uint32 urgency;
char accountid[32];
char lastgm[32];
uint32 zone;
//char zone[32];
char charname[64];
uint32 charlevel;
uint32 charclass;
uint32 charrace;
uint32 unknown;
//time_t senttime; // Time?
uint32 checkouts;
uint32 unavail;
//uint8 unknown5[4];
time_t senttime;
uint32 unknown2;
char petitiontext[1024];
char gmtext[1024];
};
struct Who_All_Struct { // 76 length total
/*000*/ char whom[64];
/*064*/ uint32 wrace; // FF FF = no race
/*068*/ uint32 wclass; // FF FF = no class
/*072*/ uint32 lvllow; // FF FF = no numbers
/*076*/ uint32 lvlhigh; // FF FF = no numbers
/*080*/ uint32 gmlookup; // FF FF = not doing /who all gm
/*084*/ uint32 guildid;
/*088*/ uint8 unknown076[64];
/*152*/ uint32 type; // New for SoF. 0 = /who 3 = /who all
/*156*/
};
struct Stun_Struct { // 4 bytes total
uint32 duration; // Duration of stun
};
struct AugmentItem_Struct {
/*00*/ uint32 container_index;
/*04*/ int32 container_slot;
/*08*/ uint32 augment_index;
/*12*/ int32 augment_slot;
/*16*/ uint32 dest_inst_id; // The unique serial number for the item instance that is being augmented
/*20*/ int32 augment_action; // Guessed - 0 = augment, 1 = remove with distiller, 3 = delete aug
/*24*/
};
// OP_Emote
struct Emote_Struct {
/*0000*/ uint32 type; // 0 - custom, 0xffffffff - command (/dance, /flip, etc...)
/*0004*/ char message[1024];
/*1028*/
};
// Inspect
struct Inspect_Struct {
uint16 TargetID;
uint16 PlayerID;
};
//OP_InspectAnswer - Size: 1860
struct InspectResponse_Struct {
/*000*/ uint32 TargetID;
/*004*/ uint32 playerid;
/*008*/ char itemnames[23][64];
/*1480*/uint32 itemicons[23];
/*1572*/char text[288]; // Max number of chars in Inspect Window appears to be 254 // Msg struct property is 256 (254 + '\0' is my guess)
/*1860*/
};
//OP_InspectMessageUpdate - Size: 256 (SoF+ clients after self-inspect window is closed)
struct InspectMessage_Struct {
/*000*/ char text[256];
/*256*/
};
//OP_SetDataRate
struct SetDataRate_Struct {
float newdatarate;
};
//OP_SetServerFilter
struct SetServerFilter_Struct {
uint32 filters[29]; //see enum eqFilterType
};
//Op_SetServerFilterAck
struct SetServerFilterAck_Struct {
uint8 blank[8];
};
struct IncreaseStat_Struct{
/*0000*/ uint8 unknown0;
/*0001*/ uint8 str;
/*0002*/ uint8 sta;
/*0003*/ uint8 agi;
/*0004*/ uint8 dex;
/*0005*/ uint8 int_;
/*0006*/ uint8 wis;
/*0007*/ uint8 cha;
/*0008*/ uint8 fire;
/*0009*/ uint8 cold;
/*0010*/ uint8 magic;
/*0011*/ uint8 poison;
/*0012*/ uint8 disease;
/*0013*/ char unknown13[116];
/*0129*/ uint8 str2;
/*0130*/ uint8 sta2;
/*0131*/ uint8 agi2;
/*0132*/ uint8 dex2;
/*0133*/ uint8 int_2;
/*0134*/ uint8 wis2;
/*0135*/ uint8 cha2;
/*0136*/ uint8 fire2;
/*0137*/ uint8 cold2;
/*0138*/ uint8 magic2;
/*0139*/ uint8 poison2;
/*0140*/ uint8 disease2;
};
struct GMName_Struct {
char oldname[64];
char gmname[64];
char newname[64];
uint8 badname;
uint8 unknown[3];
};
struct GMDelCorpse_Struct {
char corpsename[64];
char gmname[64];
uint8 unknown;
};
struct GMKick_Struct {
char name[64];
char gmname[64];
uint8 unknown;
};
struct GMKill_Struct {
char name[64];
char gmname[64];
uint8 unknown;
};
struct GMEmoteZone_Struct {
char text[512];
};
// This is where the Text is sent to the client.
// Use ` as a newline character in the text.
// Variable length.
struct BookText_Struct {
uint8 window; // where to display the text (0xFF means new window)
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
int16 invslot; // Only used in SoF and later clients.
int32 target_id;
int8 can_cast;
int8 can_scribe;
char booktext[1]; // Variable Length
};
// This is the request to read a book.
// This is just a "text file" on the server
// or in our case, the 'name' column in our books table.
struct BookRequest_Struct {
uint8 window; // where to display the text (0xFF means new window)
uint8 type; //type: 0=scroll, 1=book, 2=item info.. prolly others.
int16 invslot; // Only used in Sof and later clients;
int32 target_id;
char txtfile[20];
};
// used by Scribe and CastSpell book buttons
struct BookButton_Struct
{
int16 invslot; // server slot
int32 target_id;
};
/*
** Object/Ground Spawn struct
** Used for Forges, Ovens, ground spawns, items dropped to ground, etc
** Size: 92 bytes
** OpCodes: OP_CreateObject
** Last Updated: Oct-17-2003
**
*/
struct Object_Struct {
/*00*/ uint32 linked_list_addr[2];// They are, get this, prev and next, ala linked list
/*08*/ float size; //
/*10*/ uint16 solid_type; //
/*12*/ uint32 drop_id; // Unique object id for zone
/*16*/ uint16 zone_id; // Redudant, but: Zone the object appears in
/*18*/ uint16 zone_instance; //
/*20*/ uint32 incline; //
/*24*/ uint32 unknown024; //
/*28*/ float tilt_x;
/*32*/ float tilt_y;
/*36*/ float heading; // heading
/*40*/ float z; // z coord
/*44*/ float x; // x coord
/*76*/ float y; // y coord
/*80*/ char object_name[32]; // Name of object, usually something like IT63_ACTORDEF
/*84*/ uint32 unknown076; //
/*88*/ uint32 object_type; // Type of object, not directly translated to OP_OpenObject
/*92*/ uint32 unknown084; //set to 0xFF
uint32 spawn_id; // Spawn Id of client interacting with object
};
// 01 = generic drop, 02 = armor, 19 = weapon
//[13:40] and 0xff seems to be indicative of the tradeskill/openable items that end up returning the old style item type in the OP_OpenObject
/*
** Click Object Struct
** Client clicking on zone object (forge, groundspawn, etc)
** Size: 8 bytes
** Last Updated: Oct-17-2003
**
*/
struct ClickObject_Struct {
/*00*/ uint32 drop_id;
/*04*/ uint32 player_id;
/*08*/
};
struct Shielding_Struct {
uint32 target_id;
};
/*
** Click Object Action Struct
** Response to client clicking on a World Container (ie, forge)
** also sent by the client when they close the container.
**
*/
struct ClickObjectAction_Struct {
/*00*/ uint32 player_id; // Entity Id of player who clicked object
/*04*/ uint32 drop_id; // Zone-specified unique object identifier
/*08*/ uint32 open; // 1=opening, 0=closing
/*12*/ uint32 type; // See object.h, "Object Types"
/*16*/ uint32 unknown16; // set to 0xA
/*20*/ uint32 icon; // Icon to display for tradeskill containers
/*24*/ uint32 unknown24; //
/*28*/ char object_name[64]; // Object name to display
/*92*/
};
/*
** This is different now, mostly unknown
**
*/
struct CloseContainer_Struct {
/*00*/ uint32 player_id; // Entity Id of player who clicked object
/*04*/ uint32 drop_id; // Zone-specified unique object identifier
/*08*/ uint32 open; // 1=opening, 0=closing
/*12*/ uint32 unknown12[12];
};
/*
** Generic Door Struct
** Length: 52 Octets
** Used in:
** cDoorSpawnsStruct(f721)
**
*/
struct Door_Struct
{
/*0000*/ char name[32]; // Filename of Door // Was 10char long before... added the 6 in the next unknown to it //changed both to 32
/*0032*/ float yPos; // y loc
/*0036*/ float xPos; // x loc
/*0040*/ float zPos; // z loc
/*0044*/ float heading;
/*0048*/ uint32 incline; // rotates the whole door
/*0052*/ uint16 size; // 100 is normal, smaller number = smaller model
/*0054*/ uint8 unknown0038[6];
/*0060*/ uint8 doorId; // door's id #
/*0061*/ uint8 opentype;
/*
* Open types:
* 66 = PORT1414 (Qeynos)
* 55 = BBBOARD (Qeynos)
* 100 = QEYLAMP (Qeynos)
* 56 = CHEST1 (Qeynos)
* 5 = DOOR1 (Qeynos)
*/
/*0062*/ uint8 state_at_spawn;
/*0063*/ uint8 invert_state; // if this is 1, the door is normally open
/*0064*/ uint32 door_param;
/*0068*/ uint8 unknown0052[12]; // mostly 0s, the last 3 bytes are something tho
/*0080*/
};
struct DoorSpawns_Struct {
struct Door_Struct doors[0];
};
/*
OP Code: Op_ClickDoor
Size: 16
*/
struct ClickDoor_Struct {
/*000*/ uint8 doorid;
/*001*/ uint8 unknown001; // This may be some type of action setting
/*002*/ uint8 unknown002; // This is sometimes set after a lever is closed
/*003*/ uint8 unknown003; // Seen 0
/*004*/ uint8 picklockskill;
/*005*/ uint8 unknown005[3];
/*008*/ uint32 item_id;
/*012*/ uint16 player_id;
/*014*/ uint8 unknown014[2];
/*016*/
};
struct MoveDoor_Struct {
uint8 doorid;
uint8 action;
};
struct BecomeNPC_Struct {
uint32 id;
int32 maxlevel;
};
struct Underworld_Struct {
float speed;
float y;
float x;
float z;
};
struct Resurrect_Struct {
/*000*/ uint32 unknown000;
/*004*/ uint16 zone_id;
/*006*/ uint16 instance_id;
/*008*/ float y;
/*012*/ float x;
/*016*/ float z;
/*020*/ uint32 unknown020;
/*024*/ char your_name[64];
/*088*/ uint32 unknown088;
/*092*/ char rezzer_name[64];
/*156*/ uint32 spellid;
/*160*/ char corpse_name[64];
/*224*/ uint32 action;
/* 228 */
};
struct Translocate_Struct {
/*000*/ uint32 ZoneID;
/*004*/ uint32 SpellID;
/*008*/ uint32 unknown008; //Heading ?
/*012*/ char Caster[64];
/*076*/ float y;
/*080*/ float x;
/*084*/ float z;
/*088*/ uint32 Complete;
};
struct PendingTranslocate_Struct
{
uint32 zone_id;
uint16 instance_id;
float heading;
float x;
float y;
float z;
uint32 spell_id;
};
struct Sacrifice_Struct {
/*000*/ uint32 CasterID;
/*004*/ uint32 TargetID;
/*008*/ uint32 Confirm;
};
struct SetRunMode_Struct {
uint8 mode;
uint8 unknown[3];
};
//EnvDamage is EnvDamage2 without a few bytes at the end.
struct EnvDamage2_Struct {
/*0000*/ uint32 id;
/*0004*/ uint16 unknown4;
/*0006*/ uint32 damage;
/*0010*/ uint8 unknown10[12];
/*0022*/ uint8 dmgtype; // FA = Lava, FB = Drowning, FC = Falling, FD = Trap
/*0023*/ uint8 unknown2[4];
/*0027*/ uint16 constant; //Always FFFF
/*0029*/ uint16 unknown29;
};
//Bazaar Stuff =D
//
enum {
BazaarTrader_StartTraderMode = 1,
BazaarTrader_EndTraderMode = 2,
BazaarTrader_UpdatePrice = 3,
BazaarTrader_EndTransaction = 4,
BazaarSearchResults = 7,
BazaarWelcome = 9,
BazaarBuyItem = 10,
BazaarTrader_ShowItems = 11,
BazaarSearchDone = 12,
BazaarTrader_CustomerBrowsing = 13,
BazaarInspectItem = 18,
BazaarSearchDone2 = 19,
BazaarTrader_StartTraderMode2 = 22
};
enum {
BazaarPriceChange_Fail = 0,
BazaarPriceChange_UpdatePrice = 1,
BazaarPriceChange_RemoveItem = 2,
BazaarPriceChange_AddItem = 3
};
struct BazaarWindowStart_Struct {
uint8 Action;
uint8 Unknown001;
uint16 Unknown002;
};
struct BazaarWelcome_Struct {
uint32 action;
uint32 traders;
uint32 items;
uint32 unknown_012;
uint32 unknown_016;
};
struct BazaarSearchCriteria_Struct {
/*000*/ uint32 action{0};
/*004*/ uint32 search_scope{0}; // 1 all traders 0 local traders
/*008*/ uint32 unknown_008{0};
/*012*/ uint32 unknown_012{0};
/*016*/ uint32 trader_id{0};
/*020*/ uint32 _class{0};
/*024*/ uint32 race{0};
/*028*/ uint32 item_stat{0};
/*032*/ uint32 slot{0};
/*036*/ uint32 type{0};
/*040*/ char item_name[64]{""};
/*104*/ uint32 min_cost{0};
/*108*/ uint32 max_cost{0};
/*112*/ uint32 min_level{1};
/*116*/ uint32 max_level{0};
/*120*/ uint32 max_results{0};
/*124*/ uint32 prestige{0};
/*128*/ uint32 augment{0};
/*132*/ uint32 trader_entity_id{0};
};
struct BazaarInspect_Struct {
uint32 action;
char player_name[64];
uint32 serial_number;
uint32 item_id;
uint32 trader_id;
};
struct NewBazaarInspect_Struct {
/*000*/ BazaarWindowStart_Struct Beginning;
/*004*/ char Name[64];
/*068*/ uint32 Unknown068;
/*072*/ uint32 Unknown072;
/*076*/ uint32 Unknown076;
/*080*/ int32 SerialNumber;
/*084*/ uint32 Unknown084;
};
struct BazaarReturnDone_Struct{
uint32 Type;
uint32 TraderID;
uint32 Unknown008;
uint32 Unknown012;
uint32 Unknown016;
};
struct BazaarDeliveryCost_Struct {
uint32 action;
uint16 voucher_delivery_cost;
float parcel_deliver_cost; //percentage of item cost
uint32 unknown_010;
};
struct BazaarSearchResults_Struct {
/*000*/ BazaarWindowStart_Struct Beginning;
/*004*/ uint32 NumItems;
/*008*/ uint32 SerialNumber;
/*012*/ uint32 SellerID;
/*016*/ uint32 Cost;
/*020*/ uint32 ItemStat;
/*024*/ char ItemName[64];
/*088*/
// New fields for SoD+, stripped off when encoding for older clients.
char SellerName[64];
uint32 ItemID;
uint32 ItemID2;
};
// Barter/Buyer
//
//
#define MAX_BUYER_COMPENSATION_ITEMS 10
enum BarterBuyerActions {
Barter_BuyerSearch = 0,
Barter_SellerSearch = 1,
Barter_BuyerModeOn = 2,
Barter_BuyerModeOff = 3,
Barter_BuyerItemStart = 4,
Barter_BuyerItemUpdate = 5,
Barter_BuyerItemRemove = 6,
Barter_SellItem = 7,
Barter_SellerTransactionComplete = 8,
Barter_BuyerTransactionComplete = 9,
Barter_BuyerInspectBegin = 10,
Barter_BuyerInspectEnd = 11,
Barter_BuyerAppearance = 12,
Barter_BuyerInspectWindow = 13,
Barter_BarterItemInspect = 14,
Barter_SellerBrowsing = 15,
Barter_BuyerSearchResults = 16,
Barter_Welcome = 17,
Barter_WelcomeMessageUpdate = 19,
Barter_Greeting = 20,
Barter_BuyerItemInspect = 21,
Barter_OpenBarterWindow = 23,
Barter_AddToBarterWindow = 26,
Barter_RemoveFromBarterWindow = 27,
Barter_RemoveFromMerchantWindow = 50, //Not a client item. Used for internal communications.
Barter_FailedTransaction = 51,
Barter_BuyerCouldNotBeFound = 52,
Barter_FailedBuyerChecks = 53,
Barter_SellerCouldNotBeFound = 54,
Barter_FailedSellerChecks = 55
};
enum BarterBuyerSubActions {
Barter_Success = 0,
Barter_Failure = 1,
Barter_DataOutOfDate = 4,
Barter_SellerDoesNotHaveItem = 6,
Barter_SameZone = 8
};
enum BuyerBarter {
Off = 0,
On = 1
};
struct BuyerRemoveItem_Struct {
uint32 action;
uint32 buy_slot_id;
};
struct BuyerRemoveItemFromMerchantWindow_Struct {
uint32 action;
uint32 unknown_004;
uint32 buy_slot_id;
uint32 unknown_012;
};
struct BuyerGeneric_Struct {
uint32 action;
char payload[];
};
struct BuyerMessaging_Struct {
uint32 action;
uint32 sub_action;
uint32 zone_id;
uint32 buyer_id;
uint32 buyer_entity_id;
char buyer_name[64];
uint32 buy_item_id;
uint32 buy_item_qty;
uint64 buy_item_cost;
uint32 buy_item_icon;
uint32 seller_entity_id;
char seller_name[64];
char item_name[64];
uint32 slot;
uint32 seller_quantity;
uint32 purchase_method; // 0 direct merchant, 1 via /barter window
};
struct BuyerAddBuyertoBarterWindow_Struct {
uint32 action;
uint32 zone_id;
uint32 buyer_id;
uint32 buyer_entity_id;
char buyer_name[64];
};
struct BuyerRemoveBuyerFromBarterWindow_Struct {
uint32 action;
uint32 buyer_id;
};
struct BuyerBrowsing_Struct {
uint32 action;
char char_name[64];
};
struct BuyerGreeting_Struct {
uint32 action;
uint32 buyer_id;
};
struct BuyerWelcomeMessageUpdate_Struct {
uint32 action;
char welcome_message[256];
};
struct BuyerLineTradeItems_Struct {
uint32 item_id;
uint32 item_quantity;
uint32 item_icon;
std::string item_name;
void operator*=(uint32 multiplier)
{
this->item_quantity *= multiplier;
}
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(item_id),
CEREAL_NVP(item_quantity),
CEREAL_NVP(item_icon),
CEREAL_NVP(item_name)
);
}
};
struct BuyerLineItems_Struct {
uint32 slot;
uint8 enabled;
uint32 item_id;
std::string item_name;
uint32 item_icon;
uint32 item_quantity;
uint8 item_toggle;
uint32 item_cost;
std::vector trade_items;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(slot),
CEREAL_NVP(enabled),
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(item_icon),
CEREAL_NVP(item_quantity),
CEREAL_NVP(item_toggle),
CEREAL_NVP(item_cost),
CEREAL_NVP(trade_items)
);
}
};
struct BuyerBuyLines_Struct {
uint32 action;
union {
uint32 no_items;
uint32 string_length;
};
std::vector buy_lines;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(action),
CEREAL_NVP(no_items),
CEREAL_NVP(buy_lines)
);
}
};
struct BuyerLineSellItem_Struct {
uint32 action;
uint32 sub_action;
uint32 error_code;
uint32 purchase_method; // 0 direct merchant, 1 via /barter window
uint32 buyer_entity_id;
uint32 buyer_id;
std::string buyer_name;
uint32 seller_entity_id;
std::string seller_name;
uint32 slot;
uint8 enabled;
uint32 item_id;
char item_name[64];
uint32 item_icon;
uint32 item_quantity;
uint8 item_toggle;
uint32 item_cost;
uint32 no_trade_items;
std::vector trade_items;
uint32 seller_quantity;
uint32 zone_id;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(action),
CEREAL_NVP(sub_action),
CEREAL_NVP(error_code),
CEREAL_NVP(purchase_method),
CEREAL_NVP(buyer_entity_id),
CEREAL_NVP(buyer_id),
CEREAL_NVP(buyer_name),
CEREAL_NVP(seller_entity_id),
CEREAL_NVP(seller_name),
CEREAL_NVP(slot),
CEREAL_NVP(enabled),
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(item_icon),
CEREAL_NVP(item_quantity),
CEREAL_NVP(item_toggle),
CEREAL_NVP(item_cost),
CEREAL_NVP(no_trade_items),
CEREAL_NVP(trade_items),
CEREAL_NVP(seller_quantity),
CEREAL_NVP(zone_id)
);
}
};
struct BuyerLineItemsSearch_Struct {
uint32 slot;
uint8 enabled;
uint32 item_id;
char item_name[64];
uint32 item_icon;
uint32 item_quantity;
uint8 item_toggle;
uint32 item_cost;
uint32 buyer_id;
uint32 buyer_entity_id;
uint32 buyer_zone_id;
uint32 buyer_zone_instance_id;
std::string buyer_name;
std::vector trade_items;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(slot),
CEREAL_NVP(enabled),
CEREAL_NVP(item_id),
CEREAL_NVP(item_name),
CEREAL_NVP(item_icon),
CEREAL_NVP(item_quantity),
CEREAL_NVP(item_toggle),
CEREAL_NVP(item_cost),
CEREAL_NVP(buyer_id),
CEREAL_NVP(buyer_entity_id),
CEREAL_NVP(buyer_zone_id),
CEREAL_NVP(buyer_zone_instance_id),
CEREAL_NVP(buyer_name),
CEREAL_NVP(trade_items)
);
}
};
struct BuyerLineSearch_Struct {
uint32 action;
uint32 no_items;
std::string search_string;
uint32 transaction_id;
std::vector buy_line;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(action),
CEREAL_NVP(no_items),
CEREAL_NVP(search_string),
CEREAL_NVP(transaction_id),
CEREAL_NVP(buy_line)
);
}
};
struct BuyerSetAppearance_Struct {
uint32 action;
uint32 entity_id;
uint32 status; // 0 off 1 on
char buyer_name[64];
};
struct BarterItemSearchLinkRequest_Struct {
uint32 action;
uint32 searcher_id;
uint32 unknown_008;
uint32 unknown_012;
uint32 item_id;
uint32 unknown_020;
};
struct BuyerInspectRequest_Struct {
uint32 action;
uint32 buyer_id;
uint32 approval;
};
struct BarterSearchRequest_Struct {
uint32 action;
char search_string[64];
uint32 transaction_id;
uint32 unknown_072;
uint32 buyer_id;
uint8 search_scope; //0 All Buyers, 1 Local Buyers
uint16 zone_id;
};
struct BuyerItemSearch_Struct {
uint32 action;
char search_string[64];
};
struct BuyerItemSearchResultEntry_Struct {
char item_name[64];
uint32 item_id;
uint32 item_icon;
uint32 unknown_072;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(item_name),
CEREAL_NVP(item_id),
CEREAL_NVP(item_icon),
CEREAL_NVP(unknown_072)
);
}
};
struct BuyerItemSearchResults_Struct {
uint32 action;
uint32 result_count;
std::vector results;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(action),
CEREAL_NVP(result_count),
CEREAL_NVP(results)
);
}
};
//old below here
struct BuyerItemSearchLinkRequest_Struct {
/*000*/ uint32 Action; // 0x00000015
/*004*/ uint32 ItemID;
/*008*/ uint32 Unknown008;
/*012*/ uint32 Unknown012;
};
struct ServerSideFilters_Struct {
uint8 clientattackfilters; // 0) No, 1) All (players) but self, 2) All (players) but group
uint8 npcattackfilters; // 0) No, 1) Ignore NPC misses (all), 2) Ignore NPC Misses + Attacks (all but self), 3) Ignores NPC Misses + Attacks (all but group)
uint8 clientcastfilters; // 0) No, 1) Ignore PC Casts (all), 2) Ignore PC Casts (not directed towards self)
uint8 npccastfilters; // 0) No, 1) Ignore NPC Casts (all), 2) Ignore NPC Casts (not directed towards self)
};
/*
** Client requesting item statistics
** Size: 48 bytes
** Used In: OP_ItemLinkClick
** Last Updated: 2/15/2009
**
*/
struct ItemViewRequest_Struct {
/*000*/ uint32 item_id;
/*004*/ uint32 augments[6];
/*024*/ uint32 link_hash;
/*028*/ uint32 unknown028;
/*032*/ char unknown032[12]; //probably includes loregroup & evolving info. see Client::MakeItemLink() in zone/inventory.cpp:469
/*044*/ uint16 icon;
/*046*/ char unknown046[2];
};
struct ItemAdvancedLoreText_Struct {
int32 item_id;
char item_name[64];
char advanced_lore[ADVANCED_LORE_LENGTH];
};
struct LDONItemViewRequest_Struct {
uint32 item_id;
uint8 unknown004[4];
char item_name[64];
};
/*
* Client to server packet
*/
struct PickPocket_Struct {
// Size 18
uint32 to;
uint32 from;
uint16 myskill;
uint8 type; // -1 you are being picked, 0 failed , 1 = plat, 2 = gold, 3 = silver, 4 = copper, 5 = item
uint8 unknown1; // 0 for response, unknown for input
uint32 coin;
uint8 lastsix[2];
};
/*
* Server to client packet
*/
enum {
PickPocketFailed = 0,
PickPocketPlatinum = 1,
PickPocketGold = 2,
PickPocketSilver = 3,
PickPocketCopper = 4,
PickPocketItem = 5
};
struct sPickPocket_Struct {
// Size 28 = coin/fail
uint32 to;
uint32 from;
uint32 myskill;
uint32 type;
uint32 coin;
char itemname[64];
};
struct LogServer_Struct {
// Op_Code OP_LOGSERVER
/*000*/ uint32 unknown000;
/*004*/ uint8 enable_pvp;
/*005*/ uint8 unknown005;
/*006*/ uint8 unknown006;
/*007*/ uint8 unknown007;
/*008*/ uint8 enable_FV;
/*009*/ uint8 unknown009;
/*010*/ uint8 unknown010;
/*011*/ uint8 unknown011;
/*012*/ uint32 unknown012; // htonl(1) on live
/*016*/ uint32 unknown016; // htonl(1) on live
/*020*/ uint8 unknown020[12];
/*032*/ char worldshortname[32];
/*064*/ uint8 unknown064[32];
/*096*/ char unknown096[16]; // 'pacman' on live
/*112*/ char unknown112[16]; // '64.37,148,36' on live
/*126*/ uint8 unknown128[48];
/*176*/ uint32 unknown176; // htonl(0x00002695)
/*180*/ char unknown180[80]; // 'eqdataexceptions@mail.station.sony.com' on live
/*260*/ uint8 enable_petition_wnd;
/*261*/ uint8 enablevoicemacros;
/*262*/ uint8 enablemail;
/*263*/ uint8 disable_tutorial_go_home; // This appears valid on Ti and RoF..other clients need verification
/*264*/
};
struct ApproveWorld_Struct {
// Size 544
// Op_Code OP_ApproveWorld
uint8 unknown544[544];
};
struct ClientError_Struct
{
/*00001*/ char type;
/*00001*/ char unknown0001[69];
/*00069*/ char character_name[64];
/*00134*/ char unknown134[192];
/*00133*/ char message[31994];
/*32136*/
};
struct Track_Struct {
uint32 entityid;
float distance;
// Fields for SoD and later
uint8 level;
uint8 is_npc;
char name[64];
uint8 is_pet;
uint8 is_merc;
};
struct Tracking_Struct {
Track_Struct Entrys[0];
};
struct TrackTarget_Struct
{
uint32 EntityID;
};
/*
** ZoneServerInfo_Struct
** Zone server information
** Size: 130 bytes
** Used In: OP_ZoneServerInfo
**
*/
struct ZoneServerInfo_Struct
{
/*0000*/ char ip[128];
/*0128*/ uint16 port;
};
struct WhoAllPlayer{
uint32 formatstring;
uint32 pidstring;
char* name;
uint32 rankstring;
char* guild;
uint32 unknown80[2];
uint32 zonestring;
uint32 zone;
uint32 class_;
uint32 level;
uint32 race;
char* account;
uint32 unknown100;
};
// The following four structs are the WhoAllPlayer struct above broken down
// for use in World ClientList::SendFriendsWho to accomodate the user of variable
// length strings within the struct above.
struct WhoAllPlayerPart1 {
uint32 FormatMSGID;
uint32 PIDMSGID;
char Name[1];;
};
struct WhoAllPlayerPart2 {
uint32 RankMSGID;
char Guild[1];
};
struct WhoAllPlayerPart3 {
uint32 Unknown80[2];
uint32 ZoneMSGID;
uint32 Zone;
uint32 Class_;
uint32 Level;
uint32 Race;
char Account[1];
};
struct WhoAllPlayerPart4 {
uint32 Unknown100;
};
struct WhoAllReturnStruct {
/*000*/ uint32 id;
/*004*/ uint32 playerineqstring;
/*008*/ char line[27];
/*035*/ uint8 unknown35; //0A
/*036*/ uint32 unknown36;//0s
/*040*/ uint32 playersinzonestring;
/*044*/ uint32 unknown44[2]; //0s
/*052*/ uint32 unknown52;//1
/*056*/ uint32 unknown56;//1
/*060*/ uint32 playercount;//1
struct WhoAllPlayer player[0];
};
struct Trader_Struct {
/*000*/ uint32 action;
/*004*/ uint32 unknown_004;
/*008*/ uint64 items[EQ::invtype::BAZAAR_SIZE];
/*648*/ uint32 item_cost[EQ::invtype::BAZAAR_SIZE];
};
struct ClickTrader_Struct {
/*000*/ uint32 action;
/*004*/ uint32 unknown_004;
/*008*/ int64 serial_number[EQ::invtype::BAZAAR_SIZE] {};
/*648*/ uint32 item_cost[EQ::invtype::BAZAAR_SIZE] {};
};
struct GetItems_Struct{
uint32 items[EQ::invtype::BAZAAR_SIZE];
int32 serial_number[EQ::invtype::BAZAAR_SIZE];
int32 charges[EQ::invtype::BAZAAR_SIZE];
};
struct BecomeTrader_Struct {
uint32 action;
uint16 zone_id;
uint16 zone_instance_id;
uint32 trader_id;
uint32 entity_id;
char trader_name[64];
};
struct TraderStatus_Struct{
uint32 Code;
uint32 Uknown04;
uint32 Uknown08;
};
struct Trader_ShowItems_Struct{
/*000*/ uint32 action;
/*004*/ uint32 entity_id;
/*008*/ uint32 Unknown08[3];
/*020*/
};
struct TraderBuy_Struct {
/*000*/ uint32 action;
/*004*/ uint32 method;
/*008*/ uint32 sub_action;
/*012*/ uint32 unknown_012;
/*016*/ uint32 trader_id;
/*020*/ char buyer_name[64];
/*084*/ char seller_name[64];
/*148*/ char unknown_148[32];
/*180*/ char item_name[64];
/*244*/ char serial_number[17];
/*261*/ char unknown_261[3];
/*264*/ uint32 item_id;
/*268*/ uint32 price;
/*272*/ uint32 already_sold;
/*276*/ uint32 unknown_276;
/*280*/ uint32 quantity;
/*284*/
};
struct TraderItemUpdate_Struct{
uint32 Unknown000;
uint32 TraderID;
uint8 FromSlot;
int ToSlot; //7?
uint16 Charges;
};
struct TraderPriceUpdate_Struct {
/*000*/ uint32 Action;
/*004*/ uint32 SubAction;
/*008*/ int32 SerialNumber;
/*012*/ uint32 Unknown012;
/*016*/ uint32 NewPrice;
/*020*/ uint32 Unknown016;
};
struct MoneyUpdate_Struct{
int32 platinum;
int32 gold;
int32 silver;
int32 copper;
};
struct TraderDelItem_Struct{
uint32 unknown_000;
uint32 trader_id;
uint32 item_id;
uint32 unknown_012;
};
struct TraderClick_Struct{
/*000*/ uint32 Code;
/*004*/ uint32 TraderID;
/*008*/ uint32 Unknown008;
/*012*/ uint32 Approval;
/*016*/
};
struct FormattedMessage_Struct{
uint32 unknown0; // 1 means from world server
uint32 string_id;
uint32 type;
char message[0];
};
struct SimpleMessage_Struct{
uint32 string_id;
uint32 color;
uint32 unknown8; // 1 means from world server
};
struct GuildMemberUpdate_Struct {
/*00*/ uint32 GuildID;
/*04*/ char MemberName[64];
/*68*/ uint16 ZoneID;
/*70*/ uint16 InstanceID; //speculated
/*72*/ uint32 LastSeen; //unix timestamp
/*76*/
};
struct GuildMemberLevelUpdate_Struct {
/*00*/ uint32 guild_id;
/*04*/ char member_name[64];
/*68*/ uint32 level; //not sure
};
struct Internal_GuildMemberEntry_Struct {
// char name[64]; //variable length
uint32 level; //network byte order
uint32 banker; //1=yes, 0=no, network byte order
uint32 class_; //network byte order
uint32 rank; //network byte order
uint32 time_last_on; //network byte order
uint32 tribute_enable; //network byte order
uint32 total_tribute; //total guild tribute donated, network byte order
uint32 last_tribute; //unix timestamp
// char public_note[1]; //variable length.
uint16 zoneinstance; //network byte order
uint16 zone_id; //network byte order
uint32 online;
};
struct Internal_GuildMembers_Struct { //just for display purposes, this is not actually used in the message encoding.
char player_name[64]; //variable length.
uint32 count; //network byte order
uint32 name_length; //total length of all of the char names, excluding terminators
uint32 note_length; //total length of all the public notes, excluding terminators
Internal_GuildMemberEntry_Struct member[0];
/*
* followed by a set of `count` null terminated name strings
* and then a set of `count` null terminated public note strings
*/
};
struct GuildMOTD_Struct{
/*0000*/ uint32 unknown0;
/*0004*/ char name[64];
/*0068*/ char setby_name[64];
/*0132*/ uint32 unknown132;
/*0136*/ char motd[512];
};
struct GuildUpdate_PublicNote{
uint32 unknown0;
char name[64];
char target[64];
char note[256];
};
struct GuildUpdateURLAndChannelStruct {
char text[512];
};
struct GuildUpdatePermissionsStruct {
uint32 rank; // the rank that is being changed
uint32 function_id; // the id of the guild function
uint32 value; // 1 is on, 0 is off
};
struct GuildUpdateRankNamesStruct {
uint32 rank; // the rank that is being updated
char rank_name[76]; // the rank name
};
struct GuildUpdateUCPStruct {
uint32 action; // 0 and 1 use url and channel payload. 5 uses permissions payload
char unknown[76];
union {
GuildUpdateURLAndChannelStruct url_channel;
GuildUpdatePermissionsStruct permissions;
GuildUpdateRankNamesStruct rank_name;
}payload;
};
struct GuildPermission_Struct
{
uint32 Action; // 5 = Update function permission
char Unknown0004[76]; // not used
uint32 rank; // the rank that is being changed
uint32 function_id; // the id of the guild function
uint32 value; // 1 is on, 0 is off
};
struct GuildUpdateURLAndChannel_Struct
{
/*0000*/ uint32 Action; // 0 = Update URL, 1 = Update Channel
/*0004*/ char Unknown0004[76];
/*0080*/ char Text[512]; // URL can be up to 512, SoD client caps the Channel at 128;
/*0592*/ char Unknown0592[3584];
/*4176*/
};
//Case 5 in Rain of Fear and higher clients for guild permissions.
//RankID is the internal guild rank. There are 8 in Rain of Fear as opposed to the 3 in Titanium.
//PermissionID is the type of permission. There are 32 total, with some unused. Live May 2014 sends and uses 26 of them. Varies through client version.
//Permission value is a char that is either 0 or 1. Enabled for that rank/disabled for that rank.
//The client sends this struct on changing a guild rank. The server sends each rank in 32 or less packets upon zonein if you are in a guild.
struct GuildUpdateRanks_Struct
{
/*0000*/ uint32 Action; // 0 = Update URL, 1 = Update Channel, 4 = Ranks 5 = Permissions
/*0004*/ uint32 Unknown0004; //Seen 00 00 00 00
/*0008*/ uint32 Unknown0008; //Seen 96 29 00 00
/*0008*/ char Unknown0012[64]; //Seen "CharacterName"
/*0076*/ uint32 GuildID; //Guild ID of "CharacterName"
/*0080*/ uint32 RankID;
/*0084*/ uint32 PermissionID;
/*0088*/ char PermissionVal;
/*0089*/ char Unknown0089[3]; //Seen 2c 01 00 ?
/*0092*/
};
struct GuildStatus_Struct
{
/*000*/ char Name[64];
/*064*/ uint8 Unknown064[72];
};
struct GuildDemoteStruct{
char name[64];
char target[64];
uint32 rank;
};
struct GuildRemoveStruct{
char target[64];
char name[64];
uint32 unknown128;
uint32 leaderstatus; //?
};
struct GuildMakeLeader_Struct{
char requestor[64];
char new_leader[64];
};
struct BugReport_Struct {
/*0000*/ uint32 category_id;
/*0004*/ char category_name[64];
/*0068*/ char reporter_name[64];
/*0132*/ char unused_0132[32];
/*0164*/ char ui_path[128];
/*0292*/ float pos_x;
/*0296*/ float pos_y;
/*0300*/ float pos_z;
/*0304*/ uint32 heading;
/*0308*/ uint32 unused_0308;
/*0312*/ uint32 time_played;
/*0316*/ char padding_0316[8];
/*0324*/ uint32 target_id;
/*0328*/ char padding_0328[140];
/*0468*/ uint32 unknown_0468; // seems to always be '0'
/*0472*/ char target_name[64];
/*0536*/ uint32 optional_info_mask;
// this looks like a butchered 8k buffer with 2 trailing dword fields
/*0540*/ char unused_0540[2052];
/*2592*/ char bug_report[2050];
/*4642*/ char system_info[4098];
/*8740*/
};
struct Make_Pet_Struct { //Simple struct for getting pet info
uint8 level;
uint8 class_;
uint16 race;
uint8 texture;
uint8 pettype;
float size;
uint8 type;
uint32 min_dmg;
uint32 max_dmg;
};
struct GroundSpawn {
float max_x = 0.0f;
float max_y = 0.0f;
float min_x = 0.0f;
float min_y = 0.0f;
float max_z = 0.0f;
float heading = 0.0f;
std::string name = std::string();
uint32 item_id = 0;
uint32 max_allowed = 1;
uint32 respawn_timer = 1;
bool fix_z = true;
};
struct GroundSpawns {
struct GroundSpawn spawn[50]; //Assigned max number to allow
};
//struct PetitionBug_Struct{
// uint32 petition_number;
// uint32 unknown4;
// char accountname[64];
// uint32 zoneid;
// char name[64];
// uint32 level;
// uint32 class_;
// uint32 race;
// uint32 unknown152[3];
// uint32 time;
// uint32 unknown168;
// char text[1028];
//};
struct ApproveZone_Struct {
char name[64];
uint32 zoneid;
uint32 approve;
};
struct ZoneInSendName_Struct {
uint32 unknown0;
char name[64];
char name2[64];
uint32 unknown132;
};
struct ZoneInSendName_Struct2 {
uint32 unknown0;
char name[64];
uint32 unknown68[145];
};
static const uint32 MAX_TRIBUTE_TIERS = 10;
struct StartTribute_Struct {
uint32 client_id;
uint32 tribute_master_id;
uint32 response;
};
struct TributeLevel_Struct {
uint32 level; //backwards byte order!
uint32 tribute_item_id; //backwards byte order!
uint32 cost; //backwards byte order!
};
struct TributeAbility_Struct {
uint32 tribute_id; //backwards byte order!
uint32 tier_count; //backwards byte order!
TributeLevel_Struct tiers[MAX_TRIBUTE_TIERS];
char name[0];
};
struct SelectTributeReq_Struct {
uint32 client_id; //? maybe action ID?
uint32 tribute_id;
uint32 unknown8; //seen E3 00 00 00
};
struct GuildTributeAbilityDetail_Struct {
uint32 tribute_id; //backwards byte order!
uint32 tier_count; //backwards byte order!
TributeLevel_Struct tiers[MAX_TRIBUTE_TIERS];
uint32 unknown132;
char name[0];
};
struct GuildTributeAbility_Struct {
uint32 guild_id;
GuildTributeAbilityDetail_Struct ability;
};
struct GuildTributeSelectReq_Struct {
uint32 tribute_id;
uint32 tier;
uint32 tribute_id2;
uint32 unknown12; //seen A7 01 00 00
};
struct GuildTributeSelectReply_Struct {
uint32 tribute_id;
uint32 tier;
uint32 tribute_id2;
char description;
};
struct GuildTributeModifyBenefits_Struct {
/*000*/uint32 command;
/*004*/uint32 data;
/*008*/char unknown8[12];
/*020*/uint32 tribute_master_id;
/*024*/uint32 tribute_id_1;
/*028*/uint32 tribute_id_2;
/*032*/uint32 tribute_id_1_tier;
/*036*/uint32 tribute_id_2_tier;
/*040*/char unknown[40];
};
struct GuildTributeOptInOutReq_Struct {
/*000*/uint32 guild_id;
/*004*/uint32 tribute_toggle;
/*008*/char player[64];
/*072*/uint32 command;
/*076*/uint32 tribute_master_id;
};
struct GuildTributeOptInOutReply_Struct {
/*000*/uint32 guild_id;
/*004*/char player_name[64];
/*068*/uint32 tribute_toggle;// 0 off 1 on
/*072*/uint32 tribute_trophy_toggle;// 0 off 1 on not yet implemented
/*076*/uint32 no_donations;
/*080*/uint32 time;
/*084*/uint32 command;
};
struct GuildTributeSaveActive_Struct {
/*000*/ uint32 command;
/*004*/ char unknown04[16];
/*020*/ uint32 master_tribute_id;
/*024*/ uint32 tribute_id_1;
/*028*/ uint32 tribute_id_2;
/*032*/ uint32 tribute_1_tier;
/*036*/ uint32 tribute_2_tier;
/*040*/ char unknown40[8];
};
struct GuildTributeFavorTimer_Struct {
/*000*/ uint32 guild_id;
/*004*/ uint32 guild_favor;
/*008*/ uint32 tribute_timer;
/*012*/ uint32 trophy_timer;
};
struct GuildTributeSendActive_Struct {
/*000*/ uint32 not_used;
/*004*/ uint32 guild_favor;
/*008*/ uint32 tribute_timer;
/*012*/ uint32 tribute_enabled;
/*016*/ char unknown16[8];
/*024*/ uint32 tribute_id_1;
/*028*/ uint32 tribute_id_2;
/*032*/ uint32 tribute_id_1_tier;
/*036*/ uint32 tribute_id_2_tier;
};
struct GuildTributeToggleReq_Struct {
/*000*/ uint32 command;
/*004*/ uint32 unknown4;
/*008*/ uint32 unknown8;
};
struct GuildTributeDonateItemRequest_Struct {
/*000*/ uint32 type;
/*004*/ uint16 slot;
/*006*/ uint16 sub_index;
/*008*/ uint16 aug_index;
/*010*/ uint16 unknown10;
/*012*/ uint32 quantity;
/*016*/ uint32 tribute_master_id;
/*020*/ uint32 unknown20;
/*024*/ uint32 guild_id;
/*028*/ uint32 unknown28;
/*032*/ uint32 unknown32;
};
struct GuildTributeDonateItemReply_Struct {
/*000*/ uint32 type;
/*004*/ uint16 slot;
/*006*/ uint16 sub_index;
/*008*/ uint16 aug_index;
/*010*/ uint16 unknown10;
/*012*/ uint32 quantity;
/*016*/ uint32 unknown20;
/*020*/ uint32 favor;
};
struct GuildTributeDonatePlatRequest_Struct {
/*000*/ uint32 quantity;
/*004*/ uint32 tribute_master_id;
/*008*/ uint32 unknown08;
/*012*/ uint32 guild_id;
/*016*/ uint32 unknown16;
};
struct GuildTributeDonatePlatReply_Struct {
/*000*/ uint32 quantity;
/*004*/ uint32 unknown4;
/*008*/ uint32 favor;
};
struct SelectTributeReply_Struct {
uint32 client_id; //echoed from request.
uint32 tribute_id;
char description[0];
};
struct TributeInfo_Struct {
uint32 active; //0 == inactive, 1 == active
uint32 tributes[EQ::invtype::TRIBUTE_SIZE]; //-1 == NONE
uint32 tiers[EQ::invtype::TRIBUTE_SIZE]; //all 00's
uint32 tribute_master_id;
};
struct TributeItem_Struct {
uint32 slot;
uint32 quantity;
uint32 tribute_master_id;
int32 tribute_points;
};
struct TributePoint_Struct {
int32 tribute_points;
uint32 unknown04;
int32 career_tribute_points;
uint32 unknown12;
};
struct TributeMoney_Struct {
uint32 platinum;
uint32 tribute_master_id;
int32 tribute_points;
};
struct Split_Struct
{
uint32 platinum;
uint32 gold;
uint32 silver;
uint32 copper;
};
/*
** New Combine Struct
** Client requesting to perform a tradeskill combine
** Size: 4 bytes
** Used In: OP_TradeSkillCombine
** Last Updated: Oct-15-2003
**
*/
struct NewCombine_Struct {
/*00*/ int16 container_slot;
/*02*/ int16 guildtribute_slot;
/*04*/
};
struct TradeSkillRecipeInspect_Struct {
uint32 recipe_id;
uint32 padding[17]; // unknown
};
//client requesting favorite recipies
struct TradeskillFavorites_Struct {
uint32 object_type;
uint32 some_id;
uint32 favorite_recipes[500];
};
//search request
struct RecipesSearch_Struct {
uint32 object_type; //same as in favorites
uint32 some_id; //same as in favorites
uint32 mintrivial;
uint32 maxtrivial;
char query[56];
uint32 unknown4; //is set to 00 03 00 00
uint32 unknown5; //is set to 4C DD 12 00
/*80*/
};
//one sent for each item, from server in reply to favorites or search
struct RecipeReply_Struct {
uint32 object_type;
uint32 some_id; //same as in favorites
uint32 component_count;
uint32 recipe_id;
uint32 trivial;
char recipe_name[64];
/*84*/
};
//received and sent back as an ACK with different reply_code
struct RecipeAutoCombine_Struct {
uint32 object_type;
uint32 some_id;
uint32 unknown1; //echoed in reply
uint32 recipe_id;
uint32 reply_code; // 93 64 e1 00 (junk) in request
// 00 00 00 00 in successful reply
// f5 ff ff ff in 'you dont have all the stuff' reply
};
// this is the "value#a" data
enum EParticlePoint {
eDefault,
eChest,
eHead,
eLeftHand,
eRigthHand,
eLeftFoot,
eRightFood,
eLeftEye,
eRightEye,
eMouth
};
struct LevelAppearance_Struct { //Sends a little graphic on level up
uint32 spawn_id;
uint32 parm1;
uint32 value1a;
uint32 value1b;
uint32 parm2;
uint32 value2a;
uint32 value2b;
uint32 parm3;
uint32 value3a;
uint32 value3b;
uint32 parm4;
uint32 value4a;
uint32 value4b;
uint32 parm5;
uint32 value5a;
uint32 value5b;
/*64*/
};
struct MerchantList {
uint32 id;
uint32 slot;
uint32 item;
int16 faction_required;
int8 level_required;
uint8 min_status;
uint8 max_status;
uint16 alt_currency_cost;
uint32 classes_required;
uint8 probability;
std::string bucket_name;
std::string bucket_value;
uint8 bucket_comparison;
};
struct TempMerchantList {
uint32 npcid;
uint32 slot;
uint32 item;
uint32 charges; //charges/quantity
uint32 origslot;
};
struct AltCurrencyDefinition_Struct {
uint32 id;
uint32 item_id;
};
struct NPC_Emote_Struct {
uint32 emoteid;
uint8 event_;
uint8 type;
char text[515];
};
struct FindPerson_Point {
float y;
float x;
float z;
};
struct FindPersonRequest_Struct {
uint32 npc_id;
FindPerson_Point client_pos;
};
//variable length packet of points
struct FindPersonResult_Struct {
FindPerson_Point dest;
FindPerson_Point path[0]; //last element must be the same as dest
};
struct MobRename_Struct {
/*000*/ char old_name[64];
/*064*/ char old_name_again[64]; //not sure what the difference is
/*128*/ char new_name[64];
/*192*/ uint32 unknown192; //set to 0
/*196*/ uint32 unknown196; //set to 1
/*200*/
};
struct PlayMP3_Struct {
char filename[0];
};
//this is for custom title display in the skill window
struct TitleEntry_Struct {
uint32 title_id;
char title[1];
char suffix[1];
};
struct Titles_Struct {
uint32 title_count;
TitleEntry_Struct titles[0];
};
//this is for title selection by the client
struct TitleListEntry_Struct {
uint32 unknown0; //title ID
char prefix[1]; //variable length, null terminated
char postfix[1]; //variable length, null terminated
};
struct TitleList_Struct {
uint32 title_count;
TitleListEntry_Struct titles[0]; //list of title structs
//uint32 unknown_ending; seen 0x7265, 0
};
struct SetTitle_Struct {
uint32 is_suffix; //guessed: 0 = prefix, 1 = suffix
uint32 title_id;
};
struct SetTitleReply_Struct {
uint32 is_suffix; //guessed: 0 = prefix, 1 = suffix
char title[32];
uint32 entity_id;
};
struct SharedTaskMemberList_Struct {
/*00*/ uint32 gopher_id;
/*04*/ uint32 unknown04;
/*08*/ uint32 member_count; //1 less than the number of members
///*12*/ char list_pointer[0];
char member_name[1]; //null terminated string
uint32 monster_mission; // class chosen
uint8 task_leader; //boolean flag
/* list is of the form:
uint8 task_leader //boolean flag
*/
};
struct SharedTaskQuit_Struct {
int32 field1;
int32 field2;
int32 field3;
};
struct SharedTaskAddPlayer_Struct {
int32 field1;
int32 field2;
char player_name[64];
};
struct SharedTaskMakeLeader_Struct {
int32 field1;
int32 field2;
char player_name[64];
};
struct SharedTaskRemovePlayer_Struct {
int32 field1;
int32 field2;
char player_name[64];
};
struct SharedTaskInvite_Struct {
int32_t unknown00; // probably the unique character id sent in some packets
int32_t invite_id; // invite id sent back in response
char task_name[64];
char inviter_name[64];
};
struct SharedTaskInviteResponse_Struct {
int32_t unknown00; // 0
int32_t invite_id; // same id sent in the invite, probably for server verification
int8_t accepted; // 0: declined 1: accepted
int8_t padding[3]; // padding garbage probably
};
struct SharedTaskAccept_Struct {
int32_t unknown00;
int32_t unknown04;
uint32_t npc_entity_id; // npc task giver entity id (sent in selection window)
uint32_t task_id;
float reward_multiplier; // added after titanium (sent in selection window)
};
#if 0
// Old struct not used by Task System implementation but left for reference
struct TaskDescription_Struct {
/*000*/ uint32 activity_count; //not right.
/*004*/ uint32 taskid;
/*008*/ uint8 unk;
/*009*/ uint32 id3;
/*013*/ uint32 unknown13;
/*017*/ char name[1]; //variable length, 0 terminated
/*018*/ uint32 unknown18;
/*022*/ uint32 unknown22;
/*026*/ char desc[1]; //variable length, 0 terminated
/*027*/ uint32 reward_count; //not sure
/*031*/ uint32 unknown31;
/*035*/ uint32 unknown35;
/*039*/ uint16 unknown39;
/*041*/ char reward_link[1]; //variable length, 0 terminated
/*042*/ uint32 unknown43; //maybe crystal count?
};
// Old structs not used by Task System implentation but left for reference
struct TaskActivity_Struct {
/*000*/ uint32 activity_count; //not right
/*004*/ uint32 id3;
/*008*/ uint32 taskid;
/*012*/ uint32 activity_id;
/*016*/ uint32 unknown016;
/*020*/ uint32 activity_type;
/*024*/ uint32 unknown024;
/*028*/ uint32 unknown28;
/*032*/ char mob_name[1]; //variable length, 0 terminated
/*033*/ char item_name[1]; //variable length, 0 terminated
/*034*/ uint32 goal_count;
/*038*/ uint32 unknown38; //0xFFFFFFFF
/*042*/ uint32 unknown42; //0xFFFFFFFF
/*046*/ uint32 unknown46; //saw 0x151,0x156
/*050*/ uint32 unknown50; //saw 0x404,0
/*054*/ char activity_name[1]; //variable length, 0 terminated... commonly empty
/*055*/ uint32 done_count;
/*059*/ uint32 unknown59; //=1 except on unknown and terminal activities?
/*063*/
};
struct TaskSelectorWindowHeader_Struct {
/*000*/ uint32 TaskCount; // Guessed - Seen 1
/*000*/ uint32 Unknown2; // Seen 2
/*000*/ uint32 TaskGiver; // Guessed - Seen 1517
/*000*/ TaskSelectorData_Struct Tasks[1];
};
struct TaskSelectorData_Struct {
/*000*/ uint32 TaskID; // Seen 208
/*000*/ float Unknown5; // Seen 1.0
/*000*/ uint32 Unknown6; // Seen 0
/*000*/ uint32 Unknown7; // Seen 0
/*000*/ char TaskName[1]; // Null Terminated
/*000*/ char TaskDescription[1]; // Null Terminated
/*000*/ uint8 Unknown10; // Possibly another Null Terminated String? Seen 0
/*000*/ uint32 ActivityCount; // Seen 5
/*000*/ TaskSelectorActivities_Struct Activities[1];
};
struct TaskSelectorActivities_Struct {
/*000*/ uint32 ActivityNumber; // Seen 0 to 4
/*000*/ uint32 ActivityType; // Guessed - 1 = Give? 2 = Kill? 3 = Loot? 5 = Speak?
/*000*/ uint32 Unknown14; // Seen 0
/*000*/ char Text1; // Seen 0
/*000*/ uint32 Text2Len; // Size of the following string
/*000*/ char Text2; // If the previous field is 0, this field is not send (item name?)
/*000*/ uint32 GoalCount; // Seen 1
/*000*/ uint32 NumString1Len; // Seen 2
/*000*/ char NumString1; // Seen "-1"
/*000*/ uint32 NumString2Len; // Seen 2
/*000*/ char NumString2; // Seen "-1"
/*000*/ char ZoneIDString; // Seen "188" tutoriala
/*000*/ char Text3[1]; // Null Terminated
/*000*/ char NumString3; // Null Terminated - Seen "1546"
};
struct TaskHistoryEntry_Struct {
uint32 task_id;
char name[1];
uint32 completed_time;
};
struct TaskHistory_Struct {
uint32 completed_count;
TaskHistoryEntry_Struct entries[0];
};
#endif
struct AcceptNewTask_Struct {
uint32 task_type; // type sent in selection window
uint32 task_id; //set to 0 for 'decline'
uint32 task_master_id; //entity ID
};
//was all 0's from client, server replied with same op, all 0's
struct CancelTask_Struct {
uint32 SequenceNumber;
uint32 type; // Only seen 0x00000002
};
#if 0
// old struct, not used by Task System implementation but left for reference.
struct AvaliableTask_Struct {
uint32 task_index; //no idea, seen 0x1
uint32 task_master_id; //entity ID
uint32 task_id;
uint32 unknown012;
uint32 activity_count; //not sure, seen 2
char desc[1]; //variable length, 0 terminated
uint32 reward_platinum;//not sure on these
uint32 reward_gold;
uint32 reward_silver;
uint32 reward_copper;
char some_name[1]; //variable length, 0 terminated
uint8 unknown1;
uint32 unknown2; //0xFFFFFFFF
uint32 unknown3; //0xFFFFFFFF
uint32 unknown4; //seen 0x16
uint8 unknown5;
};
#endif
// Many of the Task System packets contain variable length strings, as well as variable numbers
// of records, hence splitting them into multiple structs (header, middle, trailer) etc.
//
struct AvailableTaskHeader_Struct {
uint32 TaskCount;
uint32 unknown1;
uint32 TaskGiver;
};
struct AvailableTaskData1_Struct {
uint32 TaskID;
uint32 TimeLimit;
uint32 unknown2;
};
struct AvailableTaskData2_Struct {
uint32 unknown1,unknown2,unknown3,unknown4;
};
struct AvailableTaskTrailer_Struct {
uint32 ItemCount;
uint32 unknown1, unknown2;
uint32 StartZone;
};
struct TaskDescriptionHeader_Struct {
uint32 SequenceNumber; // The order the tasks appear in the journal. 0 for first task, 1 for second, etc.
uint32 TaskID;
uint8 open_window;
uint32 task_type;
uint32 reward_type; // if this != 4 says Ebon Crystals else Radiant Crystals
};
struct TaskDescriptionData1_Struct {
uint32 Duration;
uint32 dur_code; // if Duration == 0
uint32 StartTime;
};
struct TaskDescriptionData2_Struct {
uint8 has_rewards;
uint32 coin_reward;
uint32 xp_reward;
uint32 faction_reward;
};
struct TaskDescriptionTrailer_Struct {
//uint16 unknown1; // 0x0012
uint32 Points;
uint8 has_reward_selection; // uses newer reward selection window, not in all clients
};
struct TaskActivityHeader_Struct {
uint32 TaskSequenceNumber;
uint32 unknown2; // Seen 0x00000002
uint32 TaskID;
uint32 ActivityID;
uint32 unknown3;
uint32 ActivityType;
uint32 Optional;
uint32 unknown5;
};
struct TaskActivityData1_Struct {
uint32 GoalCount;
uint32 unknown1; // 0xffffffff
uint32 unknown2; // 0xffffffff
uint32 ZoneID; // seen 0x36
uint32 unknown3;
};
struct TaskActivityTrailer_Struct {
uint32 DoneCount;
uint32 unknown1; // Seen 1
};
// The Short_Struct is sent for tasks that are hidden and act as a placeholder
struct TaskActivityShort_Struct {
uint32 TaskSequenceNumber;
uint32 unknown2; // Seen 0x00000002
uint32 TaskID;
uint32 ActivityID;
uint32 unknown3;
uint32 ActivityType; // 0xffffffff for the short packet
uint32 unknown4;
};
struct TaskActivityComplete_Struct {
uint32 TaskIndex;
uint32 TaskType; // task, shared task, quest
uint32 TaskID; // must match
uint32 ActivityID;
uint32 task_completed; // Broadcasts "Task '%1' Completed" it not 0 and "Task '%1' Failed." if 0
uint32 stage_complete; // Broadcasts "Task Stage Completed"
};
#if 0
// This is a dupe of the CancelTask struct
struct TaskComplete_Struct {
uint32 unknown00; // 0x00000000
uint32 unknown04; // 0x00000002
};
#endif
struct TaskHistoryRequest_Struct {
uint32 TaskIndex; // This is the sequence the task was sent in the Completed Tasks packet.
};
struct TaskHistoryReplyHeader_Struct {
uint32 TaskID;
uint32 ActivityCount;
};
struct TaskHistoryReplyData1_Struct {
uint32 ActivityType;
};
struct TaskHistoryReplyData2_Struct {
uint32 GoalCount;
uint32 unknown04; // 0xffffffff
uint32 unknown08; // 0xffffffff
uint32 ZoneID;
uint32 unknown16;
};
enum { VoiceMacroTell = 1, VoiceMacroGroup = 2, VoiceMacroRaid = 3 };
struct VoiceMacroIn_Struct {
/*000*/ char Unknown000[64];
/*064*/ uint32 Type; // 1 = Tell, 2 = Group, 3 = Raid
/*068*/ char Target[64];
/*132*/ uint32 Unknown132; // Seems to be 0x0000000c always
/*136*/ uint32 MacroNumber;
};
struct VoiceMacroOut_Struct {
/*000*/ char From[64];
/*064*/ uint32 Type; // 1 = Tell, 2 = Group, 3 = Raid
/*068*/ uint32 Unknown068;
/*072*/ uint32 Voice;
/*076*/ uint32 MacroNumber;
/*080*/ char Unknown080[60];
};
struct BankerChange_Struct {
uint32 platinum;
uint32 gold;
uint32 silver;
uint32 copper;
uint32 platinum_bank;
uint32 gold_bank;
uint32 silver_bank;
uint32 copper_bank;
};
struct LeadershipExpUpdate_Struct {
/*0000*/ uint32 unknown0000; // All zeroes?
/*0004*/ uint32 group_leadership_exp; // Group leadership exp value
/*0008*/ uint32 group_leadership_points; // Unspent group points
/*0012*/ uint32 unknown0012; // Type?
/*0016*/ uint32 unknown0016; // All zeroes?
/*0020*/ uint32 raid_leadership_exp; // Raid leadership exp value
/*0024*/ uint32 raid_leadership_points; // Unspent raid points
/*0028*/ uint32 unknown0028;
};
struct UpdateLeadershipAA_Struct {
/*00*/ uint32 ability_id;
/*04*/ uint32 new_rank;
/*08*/ uint32 pointsleft;
/*12*/
};
enum
{
GroupLeadershipAbility_MarkNPC = 0,
RaidLeadershipAbility_MarkNPC = 16,
RaidLeadershipAbility_MainAssist = 19
};
struct DoGroupLeadershipAbility_Struct
{
/*000*/ uint32 Ability;
/*000*/ uint32 Parameter;
};
struct DelegateAbility_Struct
{
/*000*/ uint32 DelegateAbility;
/*004*/ uint32 MemberNumber;
/*008*/ uint32 Action;
/*012*/ uint32 Unknown012;
/*016*/ uint32 Unknown016;
/*020*/ uint32 EntityID;
/*024*/ uint32 Unknown024;
/*028*/ char Name[64];
};
struct GroupUpdateLeaderAA_Struct
{
/*000*/ char Unknown000[64];
/*064*/ GroupLeadershipAA_Struct LeaderAAs;
/*128*/ char unknown128[128];
};
struct MarkNPC_Struct
{
/*00*/ uint32 TargetID; // Target EntityID
/*04*/ uint32 Number; // Number to mark them with (1, 2 or 3)
// The following field is for SoD+
/*08**/ char Name[64];
};
struct InspectBuffs_Struct {
/*000*/ uint32 spell_id[BUFF_COUNT];
/*100*/ int32 tics_remaining[BUFF_COUNT];
};
struct RaidGeneral_Struct {
/*00*/ uint32 action; //=10
/*04*/ char player_name[64]; //should both be the player's name
/*68*/ uint32 unknown1;
/*72*/ char leader_name[64];
/*136*/ uint32 parameter;
};
struct RaidAddMember_Struct {
/*000*/ RaidGeneral_Struct raidGen; //param = (group num-1); 0xFFFFFFFF = no group
/*136*/ uint8 _class;
/*137*/ uint8 level;
/*138*/ uint8 isGroupLeader;
/*139*/ uint8 flags[5]; //no idea if these are needed...
};
struct RaidNote_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char note[64];
};
struct RaidMOTD_Struct {
/*000*/ RaidGeneral_Struct general;
/*140*/ char motd[1024];
};
struct RaidLeadershipUpdate_Struct {
/*000*/ uint32 action;
/*004*/ char player_name[64];
/*068*/ char leader_name[64];
/*132*/ GroupLeadershipAA_Struct group; //unneeded
/*196*/ RaidLeadershipAA_Struct raid;
/*260*/ char Unknown260[128]; //unverified
};
struct RaidAdd_Struct {
/*000*/ uint32 action; //=0
/*004*/ char player_name[64]; //should both be the player's name
/*068*/ char leader_name[64];
/*132*/ uint8 _class;
/*133*/ uint8 level;
/*134*/ uint8 has_group;
/*135*/ uint8 unknown135; //seems to be 0x42 or 0
};
struct RaidCreate_Struct {
/*00*/ uint32 action; //=8
/*04*/ char leader_name[64];
/*68*/ uint32 leader_id;
};
struct RaidMemberInfo_Struct {
/*00*/ uint8 group_number;
/*01*/ char member_name[1]; //dyanmic length, null terminated '\0'
/*00*/ uint8 unknown00;
/*01*/ uint8 _class;
/*02*/ uint8 level;
/*03*/ uint8 is_raid_leader;
/*04*/ uint8 is_group_leader;
/*05*/ uint8 main_tank; //not sure
/*06*/ uint8 unknown06[5]; //prolly more flags
};
struct RaidDetails_Struct {
/*000*/ uint32 action; //=6,20
/*004*/ char leader_name[64];
/*068*/ uint32 unknown68[4];
/*084*/ LeadershipAA_Struct abilities; //ranks in backwards byte order
/*128*/ uint8 unknown128[142];
/*354*/ uint32 leader_id;
};
struct RaidMembers_Struct {
/*000*/ RaidDetails_Struct details;
/*358*/ uint32 member_count; //including leader
/*362*/ RaidMemberInfo_Struct members[1];
/*...*/ RaidMemberInfo_Struct empty; //seem to have an extra member with a 0 length name on the end
};
struct DynamicWall_Struct {
/*00*/ char name[32];
/*32*/ float y;
/*36*/ float x;
/*40*/ float z;
/*44*/ uint32 something;
/*48*/ uint32 unknown48; //0
/*52*/ uint32 one_hundred; //0x64
/*56*/ uint32 unknown56; //0
/*60*/ uint32 something2;
/*64*/ int32 unknown64; //-1
/*68*/ uint32 unknown68; //0
/*72*/ uint32 unknown72; //0
/*76*/ uint32 unknown76; //0x100
/*80*/
};
// Bandolier actions
enum
{
bandolierCreate = 0,
bandolierRemove,
bandolierSet
};
struct BandolierCreate_Struct
{
/*00*/ uint32 Action; //0 for create
/*04*/ uint8 Number;
/*05*/ char Name[32];
/*37*/ uint16 Unknown37; //seen 0x93FD
/*39*/ uint8 Unknown39; //0
};
struct BandolierDelete_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct BandolierSet_Struct
{
/*00*/ uint32 Action;
/*04*/ uint8 Number;
/*05*/ uint8 Unknown05[35];
};
struct Arrow_Struct {
/*000*/ uint32 type; //unsure on name, seems to be 0x1, dosent matter
/*005*/ uint8 unknown004[12];
/*016*/ float src_y;
/*020*/ float src_x;
/*024*/ float src_z;
/*028*/ uint8 unknown028[12];
/*040*/ float velocity; //4 is normal, 20 is quite fast
/*044*/ float launch_angle; //0-450ish, not sure the units, 140ish is straight
/*048*/ float tilt; //on the order of 125
/*052*/ uint8 unknown052[8];
/*060*/ float arc;
/*064*/ uint8 unknown064[12];
/*076*/ uint32 source_id;
/*080*/ uint32 target_id; //entity ID
/*084*/ uint32 item_id; //1 to about 150ish
/*088*/ uint32 unknown088; //seen 125, dosent seem to change anything..
/*092*/ uint32 unknown092; //seen 16, dosent seem to change anything
/*096*/ uint8 unknown096[2];
/*098*/ uint8 skill;
/*099*/ uint8 item_type;
/*100*/ uint8 unknown100;
/*101*/ char model_name[16];
/*117*/ uint8 unknown117[19];
};
//made a bunch of trivial structs for stuff for opcode finder to use
struct Consent_Struct {
char name[1]; //always at least a null
};
enum { LDoNMerchant = 1, DiscordMerchant = 2, NorrathsKeepersMerchant = 4, DarkReignMerchant = 5 };
struct AdventureMerchant_Struct {
uint32 Type; // 1 = LDoN, 2 = Discord, 4 = Norrath's Keepers, 5 = Dark Reign
uint32 entity_id;
};
struct Save_Struct {
uint8 unknown00[192];
};
struct GMToggle_Struct {
uint8 unknown0[64];
uint32 toggle;
};
struct GroupInvite_Struct {
char invitee_name[64];
char inviter_name[64];
// uint8 unknown128[65];
};
struct ColoredText_Struct {
uint32 color;
char msg[1];
};
struct UseAA_Struct {
uint32 begin;
uint32 ability;
uint32 end;
};
//new AA stuff
//reference only
struct AARankInfo_Struct
{
uint32 id;
int32 upper_hotkey_sid;
int32 lower_hotkey_sid;
int32 title_sid;
int32 desc_sid;
int32 level_req;
int32 cost;
uint32 seq;
uint32 current_level;
uint32 type;
int32 spell;
int32 spell_type;
int32 spell_refresh;
int32 classes;
int32 max_level;
int32 prev_id;
int32 next_id;
int32 total_cost;
int32 expansion;
int32 category;
uint32 charges;
uint8 grant_only;
uint32 total_effects;
uint32 total_prereqs;
};
struct AARankPrereq_Struct
{
int32 aa_id;
int32 points;
};
struct AARankEffect_Struct
{
int32 effect_id;
int32 base_value;
int32 limit_value;
int32 slot;
};
//old AA stuff
struct AA_Ability {
/*00*/ uint32 skill_id;
/*04*/ uint32 base_value;
/*08*/ uint32 limit_value;
/*12*/ uint32 slot;
};
struct SendAA_Struct {
/* EMU additions for internal use */
char name[128];
int16 cost_inc;
uint32 sof_current_level;
uint32 sof_next_id;
uint8 level_inc;
/*0000*/ uint32 id;
/*0004*/ uint32 unknown004;
/*0008*/ uint32 hotkey_sid;
/*0012*/ uint32 hotkey_sid2;
/*0016*/ uint32 title_sid;
/*0020*/ uint32 desc_sid;
/*0024*/ uint32 class_type;
/*0028*/ uint32 cost;
/*0032*/ uint32 seq;
/*0036*/ uint32 current_level; //1s, MQ2 calls this AARankRequired
/*0040*/ uint32 prereq_skill; //is < 0, abs() is category #
/*0044*/ uint32 prereq_minpoints; //min points in the prereq
/*0048*/ uint32 type;
/*0052*/ uint32 spellid;
/*0056*/ uint32 spell_type;
/*0060*/ uint32 spell_refresh;
/*0064*/ uint16 classes;
/*0066*/ uint16 berserker; //seems to be 1 if its a berserker ability
/*0068*/ uint32 max_level;
/*0072*/ uint32 last_id;
/*0076*/ uint32 next_id;
/*0080*/ uint32 cost2;
/*0084*/ uint32 unknown80[2]; //0s
// Begin SoF Specific/Adjusted AA Fields
/*0088*/ uint32 aa_expansion;
/*0092*/ uint32 special_category;
/*0096*/ uint32 sof_type;
/*0100*/ uint32 sof_cost_inc;
/*0104*/ uint32 sof_max_level;
/*0108*/ uint32 sof_next_skill;
/*0112*/ uint32 clientver;
/*0016*/ uint32 account_time_required;
/*0120*/ uint32 total_abilities;
/*0124*/ AA_Ability abilities[0];
};
struct AA_Action {
/*00*/ uint32 action;
/*04*/ uint32 ability;
/*08*/ uint32 target_id;
/*12*/ uint32 exp_value;
};
struct AAExpUpdate_Struct {
/*00*/ uint32 unknown00; //seems to be a value from AA_Action.ability
/*04*/ uint32 aapoints_unspent;
/*08*/ uint8 aaxp_percent; //% of exp that goes to AAs
/*09*/ uint8 unknown09[3]; //live dosent always zero these, so they arnt part of aaxp_percent
};
struct AltAdvStats_Struct {
/*000*/ uint32 experience;
/*004*/ uint16 unspent;
/*006*/ uint16 unknown006;
/*008*/ uint8 percentage;
/*009*/ uint8 unknown009[3];
};
struct PlayerAA_Struct { // Is this still used?
AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct AATable_Struct {
/*00*/ int32 aa_spent; // Total AAs Spent
/*04*/ AA_Array aa_list[MAX_PP_AA_ARRAY];
};
struct Weather_Struct {
uint32 val1; //generall 0x000000FF
uint32 type; //0x31=rain, 0x02=snow(i think), 0 = normal
uint32 mode;
};
struct ZoneInUnknown_Struct {
uint32 val1;
uint32 val2;
uint32 val3;
};
struct MobHealth_Struct {
uint16 entity_id;
uint8 hp;
};
struct AnnoyingZoneUnknown_Struct {
uint32 entity_id;
uint32 value; //always 4
};
struct LoadSpellSet_Struct {
uint32 spell[EQ::spells::SPELL_GEM_COUNT]; // 0xFFFFFFFF if no action, slot number if to unmem starting at 0
uint32 unknown; //there seems to be an extra field in this packet...
};
// This is the structure for OP_ZonePlayerToBind opcode. Discovered on Feb 9 2007 by FNW from packet logs for titanium client
// This field "zone_name" is text the Titanium client will display on player death
// it appears to be a variable length, null-terminated string
// In logs it has "Bind Location" text which shows up on Titanium client as ....
// "Return to Bind Location, please wait..."
// This can be used to send zone name instead.. On 6.2 client, this is ignored.
struct ZonePlayerToBind_Struct {
/*000*/ uint16 bind_zone_id;
/*002*/ uint16 bind_instance_id;
/*004*/ float x;
/*008*/ float y;
/*012*/ float z;
/*016*/ float heading;
/*020*/ char zone_name[1];
};
typedef struct {
/*000*/ uint32 bind_number; // Number of this bind in the iteration
/*004*/ uint32 bind_zone_id; // ID of the zone for this bind point or resurect point
/*008*/ float x; // X loc for this bind point
/*012*/ float y; // Y loc for this bind point
/*016*/ float z; // Z loc for this bind point
/*020*/ float heading; // Heading for this bind point
/*024*/ char bind_zone_name[1]; // Or "Bind Location" or "Resurrect"
/*000*/ uint8 validity; // 0 = valid choice, 1 = not a valid choice at this time (resurrection)
} RespawnOptions_Struct;
struct RespawnWindow_Struct {
/*000*/ uint32 unknown000; // Seen 0
/*004*/ uint32 time_remaining; // Total time before respawn in milliseconds
/*008*/ uint32 unknown008; // Seen 0
/*012*/ uint32 total_binds; // Total Bind Point Options? - Seen 2
/*016*/ RespawnOptions_Struct bind_points;
// First bind point is "Bind Location" and the last one is "Ressurect"
};
/**
* Shroud spawn. For others shrouding, this has their spawnId and
* spawnStruct.
*
* Length: 586
* OpCode: OP_Shroud
*/
struct spawnShroudOther
{
/*0000*/ uint32 spawnId; // Spawn Id of the shrouded player
/*0004*/ Spawn_Struct spawn; // Updated spawn struct for the player
/*0586*/
};
struct ApplyPoison_Struct {
uint32 inventorySlot;
uint32 success;
};
struct ItemVerifyRequest_Struct {
/*000*/ int32 slot; // Slot being Right Clicked
/*004*/ uint32 target; // Target Entity ID
/*008*/
};
struct ItemVerifyReply_Struct {
/*000*/ int32 slot; // Slot being Right Clicked
/*004*/ uint32 spell; // Spell ID to cast if different than item effect
/*008*/ uint32 target; // Target Entity ID
/*012*/
};
struct ItemRecastDelay_Struct {
/*000*/ uint32 recast_delay; // in seconds
/*004*/ uint32 recast_type;
/*008*/ bool ignore_casting_requirement; //Ignores recast times allows items to be reset?
/*012*/
};
/**
* Shroud yourself. For yourself shrouding, this has your spawnId, spawnStruct,
* bits of your charProfileStruct (no checksum, then charProfile up till
* but not including name), and an itemPlayerPacket for only items on the player
* and not the bank.
*
* Length: Variable
* OpCode: OP_Shroud
*/
#if 0
struct spawnShroudSelf
{
/*00000*/ uint32 spawnId; // Spawn Id of you
/*00004*/ Spawn_Struct spawn; // Updated spawnStruct for you
//this is a sub-struct of PlayerProfile, which we havent broken out yet.
/*00586*/ playerProfileStruct profile; // Character profile for shrouded char
/*13522*/ uint8 items; // Items on the player
/*xxxxx*/
};
#endif
typedef struct {
char Name[64];
uint16 Class;
uint16 Level;
uint16 Zone;
uint16 GuildID;
} GroupLFPMemberEntry;
struct ControlBoat_Struct {
/*000*/ uint32 boatId; // entitylist id of the boat
/*004*/ bool TakeControl; // 01 if taking control, 00 if releasing it
/*007*/ char unknown[3]; // no idea what these last three bytes represent
};
struct AugmentInfo_Struct
{
/*000*/ uint32 itemid; // id of the solvent needed
/*004*/ uint32 window; // window to display the information in
/*008*/ char augment_info[64]; // the reply has the text here
/*072*/
};
struct ClearObject_Struct
{
/*000*/ uint8 Clear; // If this is not set to non-zero there is a random chance of a client crash.
/*001*/ uint8 Unknown001[7];
};
struct PVPStats_Struct
{
/*0000*/ uint32 Kills;
/*0004*/ uint32 Deaths;
/*0008*/ uint32 PVPPointsAvailable;
/*0012*/ uint32 TotalPVPPoints;
/*0016*/ uint32 BestKillStreak;
/*0020*/ uint32 WorstDeathStreak;
/*0024*/ uint32 CurrentKillStreak;
/*0028*/ uint32 Infamy;
/*0032*/ uint32 Vitality;
/*0036*/ PVPStatsEntry_Struct LastDeath;
/*0124*/ PVPStatsEntry_Struct LastKill;
/*0212*/ PVPStatsEntry_Struct KillsLast24Hours[50];
/*4612*/
};
typedef struct
{
/*000*/ char Name[64];
/*064*/ uint32 Kills;
/*068*/ uint32 Deaths;
/*072*/ uint32 TotalPoints;
/*076*/ uint32 Infamy;
/*080*/
} PVPLeaderBoardEntry_Struct;
enum { PVPSortByKills = 0, PVPSortByPoints, PVPSortByInfamy };
struct PVPLeaderBoardRequest_Struct
{
/*00*/ uint32 SortType;
/*04*/
};
struct PVPLeaderBoard_Struct
{
/*0000*/ uint32 Unknown0000;
/*0004*/ uint32 MyKills;
/*0008*/ uint32 MyTotalPoints;
/*0012*/ uint32 MyRank;
/*0016*/ uint32 MyDeaths;
/*0020*/ uint32 MyInfamy;
/*0024*/ PVPLeaderBoardEntry_Struct Entries[100];
/*8024*/
};
struct PVPLeaderBoardDetailsRequest_Struct
{
/*00*/ uint32 Unknown00;
/*04*/ char Name[64];
/*68*/
};
struct PVPLeaderBoardDetailsReply_Struct
{
/*000*/ char Name[64];
/*064*/ uint8 Unknown064[64];
/*128*/ uint32 Level;
/*132*/ uint32 Race;
/*136*/ uint32 Class;
/*140*/ uint32 GuildID;
/*144*/ uint32 TotalAA;
/*148*/ uint32 Unknown148;
/*152*/ uint32 Kills;
/*156*/ uint32 Deaths;
/*160*/ uint32 Infamy;
/*164*/ uint32 Points;
/*168*/
};
struct DisciplineTimer_Struct
{
/*00*/ uint32 TimerID;
/*04*/ uint32 Duration;
/*08*/ uint32 Unknown08;
};
struct InternalVeteranRewardItem
{
/*000*/ uint32 item_id;
/*004*/ uint32 charges;
/*008*/ char item_name[64];
};
struct InternalVeteranReward
{
/*000*/ uint32 claim_id;
/*004*/ uint32 number_available;
/*008*/ uint32 claim_count;
/*012*/ InternalVeteranRewardItem items[8];
};
struct VeteranClaim
{
/*000*/ char name[64]; //name + other data
/*064*/ uint32 claim_id;
/*068*/ uint32 unknown068;
/*072*/ uint32 action;
};
struct GMSearchCorpse_Struct
{
/*000*/ char Unknown000[64];
/*064*/ char Name[64];
/*128*/ uint32 Unknown128;
};
struct CrystalCountUpdate_Struct
{
/*000*/ uint32 CurrentRadiantCrystals;
/*004*/ uint32 CurrentEbonCrystals;
/*008*/ uint32 CareerRadiantCrystals;
/*012*/ uint32 CareerEbonCrystals;
};
struct BeggingResponse_Struct
{
/*00*/ uint32 Unknown00;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Unknown08;
/*12*/ uint32 Result; // 0 = Fail, 1 = Plat, 2 = Gold, 3 = Silver, 4 = Copper
/*16*/ uint32 Amount;
};
struct GuildBankAck_Struct
{
/*00*/ uint32 Action; // 10
/*04*/ uint32 Unknown04;
};
struct GuildBankDepositAck_Struct
{
/*00*/ uint32 Action; // 10
/*04*/ uint32 Unknown04;
/*08*/ uint32 Fail; //1 = Fail, 0 = Success
};
struct GuildBankPromote_Struct
{
/*00*/ uint32 Action; // 3
/*04*/ uint32 Unknown04;
/*08*/ uint32 Slot;
/*12*/ uint32 Slot2; // Always appears to be the same as Slot for Action code 3
};
struct GuildPromoteStruct {
/*000*/ char target[64];
/*064*/ char name[64];
/*128*/ uint32 rank;
/*132*/ uint32 myrank;
/*136*/
};
struct GuildBankPermissions_Struct
{
/*00*/ uint32 Action; // 6
/*04*/ uint32 Unknown04;
/*08*/ uint16 SlotID;
/*10*/ uint16 Unknown10; // Saw 1, probably indicating it is the main area rather than deposits
/*12*/ uint32 ItemID;
/*16*/ uint32 Permissions;
/*20*/ char MemberName[64];
};
struct GuildBankViewItem_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint16 SlotID; // 0 = Deposit area, 1 = Main area
/*10*/ uint16 Area;
/*12*/ uint32 Unknown12;
/*16*/ uint32 Unknown16;
};
struct GuildBankWithdrawItem_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint16 SlotID;
/*10*/ uint16 Area;
/*12*/ uint32 Unknown12;
/*16*/ uint32 Quantity;
/*20*/
};
struct GuildBankItemUpdate_Struct
{
void Init(
uint32 inAction,
uint32 inUnknown004,
uint16 inSlotID,
uint16 inArea,
uint16 inUnknown012,
uint32 inItemID,
uint32 inIcon,
uint32 inQuantity,
uint32 inPermissions,
uint32 inAllowMerge,
bool inUseable)
{
action = inAction;
unknown004 = inUnknown004;
slot_id = inSlotID;
area = inArea;
display = inUnknown012;
item_id = inItemID;
icon_id = inIcon;
quantity = inQuantity;
permissions = inPermissions;
allow_merge = inAllowMerge;
is_useable = inUseable;
item_name[0] = '\0';
donator[0] = '\0';
who_for[0] = '\0';
};
/*000*/ uint32 action;
/*004*/ uint32 unknown004;
/*008*/ uint16 slot_id;
/*010*/ uint16 area;
/*012*/ uint32 display;
/*016*/ uint32 item_id;
/*020*/ uint32 icon_id;
/*024*/ uint32 quantity;
/*028*/ uint32 permissions;
/*032*/ uint8 allow_merge;
/*033*/ uint8 is_useable; // Used in conjunction with the Public-if-useable permission.
/*034*/ char item_name[64];
/*098*/ char donator[64];
/*162*/ char who_for[64];
/*226*/ uint16 unknown226;
};
// newer clients (RoF+) send a list that contains 240 entries
// The packets don't actually use all 64 chars in the strings, but we'll just overallocate for these
struct GuildBankItemListEntry_Struct {
uint8 vaild;
uint32 permissions;
char whofor[64];
char donator[64];
uint32 item_id;
uint32 item_icon;
uint32 quantity;
uint8 allow_merge; // 1 here for non-full stacks
uint8 usable;
char item_name[64];
};
struct GuildBankClear_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/ uint32 DepositAreaCount;
/*12*/ uint32 MainAreaCount;
};
struct FindableNPC_Struct
{
/*000*/ uint32 Action; // 0 = Add, 1 = Remove
/*004*/ uint32 EntityID;
/*008*/ char Name[64];
/*072*/ char LastName[32];
/*104*/ uint32 Race;
/*108*/ uint8 Class;
/*109*/ uint8 Unknown109; // Observed 0x16
/*110*/ uint8 Unknown110; // Observed 0x06
/*111*/ uint8 Unknown111; // Observed 0x24
/*112*/
};
struct GroupRole_Struct
{
/*000*/ char Name1[64];
/*064*/ char Name2[64];
/*128*/ uint32 Unknown128;
/*132*/ uint32 Unknown132;
/*136*/ uint32 Unknown136;
/*140*/ uint32 RoleNumber;
/*144*/ uint8 Toggle;
/*145*/ uint8 Unknown145[3];
/*148*/
};
struct HideCorpse_Struct
{
/*00*/ uint32 Action;
/*04*/ uint32 Unknown04;
/*08*/
};
struct BuffIconEntry_Struct
{
uint32 buff_slot;
uint32 spell_id;
int32 tics_remaining;
uint32 num_hits;
char caster[64];
};
struct BuffIcon_Struct
{
uint32 entity_id;
uint8 all_buffs;
uint16 count;
uint8 type; // 0 = self buff window, 1 = self target window, 4 = group, 5 = PC, 7 = NPC
int32 tic_timer;
int32 name_lengths; // so ahh we kind of do these packets hacky, this is the total length of all the names to make creating the real packets in the translators easier
BuffIconEntry_Struct entries[0];
};
struct ExpeditionInvite_Struct
{
/*000*/ uint32 client_id; // unique character id
/*004*/ uint32 unknown004; // added after titanium
/*008*/ char inviter_name[64];
/*072*/ char expedition_name[128];
/*200*/ uint8 swapping; // 0: adding 1: swapping
/*201*/ char swap_name[64]; // if swapping, swap name being removed
/*265*/ uint8 padding[3];
/*268*/ uint16 dz_zone_id; // dz_id zone/instance pair, sent back in reply
/*270*/ uint16 dz_instance_id;
};
struct ExpeditionInviteResponse_Struct
{
/*000*/ uint32 unknown000;
/*004*/ uint32 unknown004; // added after titanium
/*008*/ uint16 dz_zone_id; // dz_id pair sent in invite
/*010*/ uint16 dz_instance_id;
/*012*/ uint8 accepted; // 0: declined 1: accepted
/*013*/ uint8 swapping; // 0: adding 1: swapping (sent in invite)
/*014*/ char swap_name[64]; // swap name sent in invite
/*078*/ uint8 unknown078; // padding garbage?
/*079*/ uint8 unknown079; // padding garbage?
};
struct DynamicZoneInfo_Struct
{
/*000*/ uint32 client_id;
/*004*/ uint32 unknown004; // added after titanium
/*008*/ uint32 assigned; // padded bool, 0: clear info, 1: fill window info
/*012*/ uint32 max_players;
/*016*/ char dz_name[128];
/*144*/ char leader_name[64];
//*208*/ uint32 dz_type; // only in newer clients, if not 1 (expedition type) window does not auto show when dz info assigned
};
struct DynamicZoneMemberEntry_Struct
{
/*000*/ char name[64]; // variable length, null terminated, max 0x40 (64)
/*064*/ uint8 online_status; // 0: unknown, 1: Online, 2: Offline, 3: In Dynamic Zone, 4: Link Dead
};
struct DynamicZoneMemberList_Struct
{
/*000*/ uint32 client_id;
/*004*/ uint32 member_count;
/*008*/ DynamicZoneMemberEntry_Struct members[0]; // variable length
};
struct DynamicZoneMemberListName_Struct
{
/*000*/ uint32 client_id;
/*004*/ uint32 unknown004;
/*008*/ uint32 add_name; // padded bool, 0: remove name, 1: add name with unknown status
/*012*/ char name[64];
};
struct ExpeditionLockoutTimerEntry_Struct
{
/*000*/ char expedition_name[128]; // variable length, null terminated, max 0x80 (128)
/*000*/ uint32 seconds_remaining;
/*000*/ int32 event_type; // seen -1 (0xffffffff) for replay timers and 1 for event timers
/*000*/ char event_name[256]; // variable length, null terminated, max 0x100 (256)
};
struct ExpeditionLockoutTimers_Struct
{
/*000*/ uint32 client_id;
/*004*/ uint32 count;
/*008*/ ExpeditionLockoutTimerEntry_Struct timers[0];
};
struct DynamicZoneLeaderName_Struct
{
/*000*/ uint32 client_id;
/*004*/ uint32 unknown004;
/*008*/ char leader_name[64];
};
struct ExpeditionCommand_Struct
{
/*000*/ uint32 unknown000;
/*004*/ uint32 unknown004;
/*008*/ char name[64];
};
struct ExpeditionCommandSwap_Struct
{
/*000*/ uint32 unknown000;
/*004*/ uint32 unknown004;
/*008*/ char add_player_name[64]; // swap to (player must confirm)
/*072*/ char rem_player_name[64]; // swap from
};
struct ExpeditionExpireWarning
{
/*008*/ uint32 minutes_remaining;
};
struct DynamicZoneCompassEntry_Struct
{
/*000*/ uint16 dz_zone_id; // target dz id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 dz_type; // 1: Expedition, 2: Tutorial (purple), 3: Task, 4: Mission, 5: Quest (green)
/*008*/ uint32 dz_switch_id;
/*012*/ float y;
/*016*/ float x;
/*020*/ float z;
};
struct DynamicZoneCompass_Struct
{
/*000*/ uint32 client_id;
/*000*/ uint32 count;
/*004*/ DynamicZoneCompassEntry_Struct entries[0];
};
struct DynamicZoneChooseZoneEntry_Struct
{
/*000*/ uint16 dz_zone_id; // dz_id pair
/*002*/ uint16 dz_instance_id;
/*004*/ uint32 unknown_id1; // seen 28 00 00 00 (40), sent back in reply
/*008*/ uint32 dz_type; // 1: Expedition, 2: Tutorial, 3: Task, 4: Mission, 5: Quest -- sent back in reply
/*012*/ uint32 unknown_id2; // possibly an id based on dz type, for expeditions this was same as dz_id (zone|instance) but task dz was different
/*016*/ char description[128]; // variable length, null terminated
/*144*/ char leader_name[64]; // variable length, null terminated
};
struct DynamicZoneChooseZone_Struct
{
/*000*/ uint32 client_id;
/*004*/ uint32 count;
/*008*/ DynamicZoneChooseZoneEntry_Struct choices[0];
};
struct DynamicZoneChooseZoneReply_Struct
{
/*000*/ uint32 unknown000; // ff ff ff ff
/*004*/ uint32 unknown004; // seen 69 00 00 00
/*008*/ uint32 unknown008; // ff ff ff ff
/*012*/ uint32 unknown_id1; // from choose zone entry message
/*016*/ uint16 dz_zone_id; // dz_id pair
/*018*/ uint16 dz_instance_id;
/*020*/ uint32 dz_type; // 1: Expedition, 2: Tutorial, 3: Task, 4: Mission, 5: Quest
/*024*/ uint32 unknown_id2; // from choose zone entry message
/*028*/ uint32 unknown028; // 00 00 00 00
/*032*/ uint32 unknown032; // always same as unknown044
/*036*/ uint32 unknown036;
/*040*/ uint32 unknown040;
/*044*/ uint32 unknown044; // always same as unknown032
/*048*/ uint32 unknown048; // seen 01 00 00 00 and 02 00 00 00
};
struct KickPlayers_Struct
{
/*000*/ char char_name[64];
/*064*/ uint32 unknown064; // always 0
/*068*/ uint8 kick_expedition; // true if /kickplayers exp
/*069*/ uint8 kick_task; // true if /kickplayers task
/*070*/ uint8 padding[2];
};
struct CorpseDrag_Struct
{
/*000*/ char CorpseName[64];
/*064*/ char DraggerName[64];
/*128*/ uint8 Unknown128[24];
/*152*/
};
struct ChangeSize_Struct
{
/*00*/ uint32 EntityID;
/*04*/ float Size;
/*08*/ uint32 Unknown08; // Observed 0
/*12*/ float Unknown12; // Observed 1.0f
/*16*/
};
enum ChangeNameResponse : int {
Denied = 0, // 5167: "You have requested an invalid name or a Customer Service Representative has denied your name request. Please try another name."
Accepted = 1, // 5976: "Your request for a name change was successful."
Timeout = -1, // 5977: "Your request for a name change has timed out. Please try again later."
ServerError = -2, // 5978: "The server had an error while processing your name request. Please try again later."
RateLimited = -3, // 5979: "You must wait longer before submitting another name request. Please try again in a few minutes."
Ineligible = -4, // 5980: "Your character is not eligible for a name change."
Pending = -5 // 5193: "You already have a name change pending. Please wait until it is fully processed before attempting another name change."
};
struct AltChangeName_Struct {
/*00*/ char new_name[64];
/*40*/ char old_name[64];
/*80*/ int response_code;
};
struct ChangePetName_Struct {
/*00*/ char new_pet_name[64];
/*40*/ char pet_owner_name[64];
/*80*/ int response_code;
};
// New OpCode/Struct for SoD+
struct GroupMakeLeader_Struct
{
/*000*/ uint32 Unknown000;
/*004*/ char CurrentLeader[64];
/*068*/ char NewLeader[64];
/*132*/ char Unknown072[324];
/*456*/
};
//One packet i didn't include here is the alt currency merchant window.
//it works much like the adventure merchant window
//it is formated like: dbstringid|1|dbstringid|count
//ex for a blank crowns window you would send:
//999999|1|999999|0
//any items come after in much the same way adventure merchant items do except there is no theme included
//Server -> Client
//Populates the initial Alternate Currency Window
struct AltCurrencyPopulateEntry_Struct
{
/*000*/ uint32 currency_number; //corresponds to a dbstr id as well, the string matches what shows up in the "alternate currency" tab.
/*004*/ uint32 unknown00; //always 1
/*008*/ uint32 currency_number2; //always same as currency number
/*012*/ uint32 item_id; //appears to be the item id
/*016*/ uint32 item_icon; //actual icon
/*020*/ uint32 stack_size; //most are set to 1000, the stack size for the item; should match db i think or there will be problems.
};
struct AltCurrencyPopulate_Struct {
/*000*/ uint32 opcode; //8 for populate
/*004*/ uint32 count; //number of entries
/*008*/ AltCurrencyPopulateEntry_Struct entries[0];
};
//Server -> Client
//Updates the value of a specific Alternate Currency
struct AltCurrencyUpdate_Struct {
/*000*/ uint32 opcode; //7 for update
/*004*/ char name[64]; //name of client (who knows why just do it)
/*068*/ uint32 currency_number; //matches currency_number from populate entry
/*072*/ uint32 unknown072; //always 1
/*076*/ uint32 amount; //new amount
/*080*/ uint32 unknown080; //seen 0
/*084*/ uint32 unknown084; //seen 0
};
//Client -> Server
//When an item is selected while the alt currency merchant window is open
struct AltCurrencySelectItem_Struct {
/*000*/ uint32 merchant_entity_id;
/*004*/ uint32 slot_id;
/*008*/ uint32 unknown008;
/*012*/ uint32 unknown012;
/*016*/ uint32 unknown016;
/*020*/ uint32 unknown020;
/*024*/ uint32 unknown024;
/*028*/ uint32 unknown028;
/*032*/ uint32 unknown032;
/*036*/ uint32 unknown036;
/*040*/ uint32 unknown040;
/*044*/ uint32 unknown044;
/*048*/ uint32 unknown048;
/*052*/ uint32 unknown052;
/*056*/ uint32 unknown056;
/*060*/ uint32 unknown060;
/*064*/ uint32 unknown064;
/*068*/ uint32 unknown068;
/*072*/ uint32 unknown072;
/*076*/ uint32 unknown076;
};
//Server -> Client
//As setup it makes it so that item can't be sold to the merchant.
//eg: "I will give you no doubloons for a cloth cap."
//Probably also sends amounts somewhere
struct AltCurrencySelectItemReply_Struct {
/*000*/ uint32 unknown000;
/*004*/ uint8 unknown004; //0xff
/*005*/ uint8 unknown005; //0xff
/*006*/ uint16 unknown006; //0xffff
/*008*/ uint16 unknown008; //0xffff
/*010*/ char item_name[64];
/*074*/ uint16 unknown074;
/*076*/ uint32 cost;
/*080*/ uint32 unknown080;
/*084*/ uint32 unknown084;
};
//Client -> Server
//Requests purchase of a specific item from the vendor
struct AltCurrencyPurchaseItem_Struct {
/*000*/ uint32 merchant_entity_id;
/*004*/ uint32 item_id;
/*008*/ uint32 unknown008; //1
};
//Client -> Server
//Reclaims / Create currency button pushed.
struct AltCurrencyReclaim_Struct {
/*000*/ uint32 currency_id;
/*004*/ uint32 unknown004;
/*008*/ uint32 count;
/*012*/ uint32 reclaim_flag; //1 = this is reclaim
};
struct AltCurrencySellItem_Struct {
/*000*/ uint32 merchant_entity_id;
/*004*/ uint32 slot_id;
/*008*/ uint32 charges;
/*012*/ uint32 cost;
};
struct Untargetable_Struct {
/*000*/ uint32 id;
/*004*/ uint32 targetable_flag; //0 = not targetable, 1 or higher = targetable
/*008*/
};
struct CrystalReclaim_Struct {
/**/ uint32 type;
/**/ uint32 amount;
};
struct LFGuild_SearchPlayer_Struct
{
/*00*/ uint32 Command;
/*04*/ uint32 Unknown04;
/*08*/ uint32 FromLevel;
/*12*/ uint32 ToLevel;
/*16*/ uint32 MinAA;
/*20*/ uint32 TimeZone;
/*24*/ uint32 Classes;
};
struct LFGuild_SearchGuild_Struct
{
/*00*/ uint32 Command;
/*04*/ uint32 Unknown04;
/*08*/ uint32 Level;
/*12*/ uint32 AAPoints;
/*16*/ uint32 TimeZone;
/*20*/ uint32 Class;
/*24*/
};
struct LFGuild_PlayerToggle_Struct
{
/*000*/ uint32 Command;
/*004*/ uint8 Unknown004[68];
/*072*/ char Comment[256];
/*328*/ uint8 Unknown328[268];
/*596*/ uint32 TimeZone;
/*600*/ uint8 Toggle;
/*601*/ uint8 Unknown601[7];
/*608*/ uint32 TimePosted;
/*612*/ uint8 Unknown612[12];
/*624*/
};
struct LFGuild_GuildToggle_Struct
{
/*000*/ uint32 Command;
/*004*/ uint8 Unknown004[8];
/*012*/ char Comment[256];
/*268*/ uint8 Unknown268[256];
/*524*/ uint32 FromLevel;
/*528*/ uint32 ToLevel;
/*532*/ uint32 Classes;
/*536*/ uint32 AACount;
/*540*/ uint32 TimeZone;
/*544*/ uint8 Toggle;
/*545*/ uint8 Unknown545[3];
/*548*/ uint32 TimePosted;
/*552*/ char Name[64];
/*616*/
};
struct MaxCharacters_Struct
{
/*000*/ uint32 max_chars; // Seen 4 on Silver Account (4 characters max)
/*004*/ uint32 unknown004; // Seen 0
/*008*/ uint32 unknown008; // Seen 0
};
struct Membership_Struct
{
/*000*/ uint32 membership; // Seen 2 on Gold Account
/*004*/ uint32 races; // Seen ff ff 01 00
/*008*/ uint32 classes; // Seen ff ff 01 01
/*012*/ uint32 entrysize; // Seen 15 00 00 00
/*016*/ int32 entries[21]; //Varies. Seen ff ff ff ff, and 01 00 00 00
/*104*/ uint32 exit_url_length; // Length of the exit_url string (0 for none)
/*108*/ // char exit_url[0]; // URL that will open when EQ is exited
};
// Used by MercenaryListEntry_Struct
struct MercenaryStance_Struct {
/*0000*/ uint32 StanceIndex; // Index of this stance (sometimes reverse reverse order - 3, 2, 1, 0 for 4 stances etc)
/*0004*/ uint32 Stance; // From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};
struct Membership_Entry_Struct
{
/*000*/ uint32 purchase_id; // Seen 1, then increments 90287 to 90300
/*004*/ uint32 bitwise_entry; // Seen 16 to 65536 - Skips 4096
/*008*/
};
struct Membership_Setting_Struct
{
/*000*/ uint32 setting_index; // 0, 1, or 2
/*004*/ uint32 setting_id; // 0 to 21
/*008*/ int32 setting_value; // All can be 0, 1, or -1
/*012*/
};
struct Membership_Details_Struct
{
/*0000*/ uint32 membership_setting_count; // Seen 66
/*0016*/ Membership_Setting_Struct settings[66];
/*0012*/ uint32 race_entry_count; // Seen 15
/*1044*/ Membership_Entry_Struct membership_races[15];
/*0012*/ uint32 class_entry_count; // Seen 15
/*1044*/ Membership_Entry_Struct membership_classes[15];
/*1044*/ uint32 exit_url_length; // Length of the exit_url string (0 for none)
/*1048*/ //char exit_url[42]; // Upgrade to Silver or Gold Membership URL
/*1048*/ uint32 exit_url_length2; // Length of the exit_url2 string (0 for none)
/*0000*/ //char exit_url2[49]; // Upgrade to Gold Membership URL
};
struct ItemPreview_Struct
{
/*000*/ uint32 itemid;
/*004*/ uint32 unknown004[3];
/*016*/ uint32 slot;
/*020*/ uint32 unknown020;
/*024*/ uint16 slot2;
/*026*/ uint8 unknown026[54];
};
// Used by specific packets
struct MercenaryList_Struct {
/*0000*/ uint32 MercID; // ID unique to each type of mercenary (probably a DB id)
/*0004*/ uint32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ uint32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan
Type: Healer
Confidence: High
Proficiency: Apprentice, Tier V...
/*0012*/ uint32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ uint32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ uint32 Status; // Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ?
/*0024*/ uint32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0028*/ uint32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0032*/ uint32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0036*/ uint8 MercUnk01; // Unknown (always see 0)
/*0037*/ int32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0041*/ uint32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0045*/ uint32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0)
/*0049*/ uint32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0057*/ uint8 MercUnk04; // Seen 1
/*0058*/ char MercName[1]; // Null Terminated Mercenary Name (00 at merchants)
};
// Used by MercenaryMerchantList_Struct
struct MercenaryListEntry_Struct {
/*0000*/ uint32 MercID; // ID unique to each type of mercenary (probably a DB id)
/*0004*/ uint32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ uint32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan
Type: Healer
Confidence: High
Proficiency: Apprentice, Tier V...
/*0012*/ uint32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ uint32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ uint32 Status; // Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ?
/*0024*/ uint32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0028*/ uint32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0032*/ uint32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0036*/ uint8 MercUnk01; // Unknown (always see 0)
/*0037*/ int32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0041*/ uint32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0045*/ uint32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0)
/*0049*/ uint32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0057*/ uint8 MercUnk04; // Seen 1
/*0058*/ char MercName[1]; // Null Terminated Mercenary Name (00 at merchants)
/*0000*/ MercenaryStance_Struct Stances[MAX_MERC_STANCES]; // Count Varies, but hard set to 5 max for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
};
// [OPCode: 0x27ac OP_MercenaryDataResponse] On Live as of April 2 2012 [Server->Client]
// Opcode should be renamed to something like OP_MercenaryMerchantShopResponse since the Data Response packet is different
// Sent by the server when browsing the Mercenary Merchant
struct MercenaryMerchantList_Struct {
/*0000*/ uint32 MercTypeCount; // Number of Merc Types to follow
/*0004*/ uint32 MercGrades[MAX_MERC_GRADES]; // Count varies, but hard set to 3 max for now - From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0016*/ uint32 MercCount; // Number of MercenaryInfo_Struct to follow
/*0020*/ MercenaryListEntry_Struct Mercs[MAX_MERC]; // Data for individual mercenaries in the Merchant List
};
// [OPCode: 0x4dd9 OP_MercenaryDataRequest] On Live as of April 2 2012 [Client->Server]
// Opcode should be renamed to something like OP_MercenaryMerchantShopRequest since the Data Request packet is different
// Right clicking merchant - shop request
struct MercenaryMerchantShopRequest_Struct {
/*0000*/ uint32 MercMerchantID; // Entity ID of the Mercenary Merchant
/*0004*/
};
// Used by MercenaryDataUpdate_Struct
struct MercenaryData_Struct {
/*0000*/ uint32 MercID; // ID unique to each type of mercenary (probably a DB id) - (if 1, do not send MercenaryData_Struct - No merc hired)
/*0004*/ uint32 MercType; // From dbstr_us.txt - Apprentice (330000100), Journeyman (330000200), Master (330000300)
/*0008*/ uint32 MercSubType; // From dbstr_us.txt - 330020105^23^Race: Guktan
Type: Healer
Confidence: High
Proficiency: Apprentice, Tier V...
/*0012*/ uint32 PurchaseCost; // Purchase Cost (in gold)
/*0016*/ uint32 UpkeepCost; // Upkeep Cost (in gold)
/*0020*/ uint32 Status; // Required Account Status (Free = 0, Silver = 1, Gold = 2) at merchants - Seen 0 (suspended) or 1 (unsuspended) on hired mercs ?
/*0024*/ uint32 AltCurrencyCost; // Alternate Currency Purchase Cost? (all seen costs show N/A Bayle Mark) - Seen 0
/*0028*/ uint32 AltCurrencyUpkeep; // Alternate Currency Upkeep Cost? (all seen costs show 1 Bayle Mark) - Seen 1
/*0032*/ uint32 AltCurrencyType; // Alternate Currency Type? - 19^17^Bayle Mark^0 - Seen 19
/*0036*/ uint8 MercUnk01; // Unknown (always see 0)
/*0037*/ int32 TimeLeft; // Unknown (always see -1 at merchant) - Seen 900000 (15 minutes in ms for newly hired merc)
/*0041*/ uint32 MerchantSlot; // Merchant Slot? Increments, but not always by 1 - May be for Merc Window Options (Seen 5, 36, 1 for active mercs)?
/*0045*/ uint32 MercUnk02; // Unknown (normally see 1, but sometimes 2 or 0)
/*0049*/ uint32 StanceCount; // Iterations of MercenaryStance_Struct - Normally 2 to 4 seen
/*0053*/ int32 MercUnk03; // Unknown (always 0 at merchant) - Seen on active merc: 93 a4 03 77, b8 ed 2f 26, 88 d5 8b c3, and 93 a4 ad 77
/*0057*/ uint8 MercUnk04; // Seen 1
/*0058*/ char MercName[64]; // Null Terminated Mercenary Name (00 at merchants)
/*0000*/ MercenaryStance_Struct Stances[MAX_MERC_STANCES]; // Count Varies, but hard set to 2 for now - From dbstr_us.txt - 1^24^Passive^0, 2^24^Balanced^0, etc (1 to 9 as of April 2012)
/*0000*/ uint32 MercUnk05; // Seen 1 - Extra Merc Data field that differs from MercenaryListEntry_Struct
// MercUnk05 may be a field that is at the end of the packet only, even if multiple mercs are listed (haven't seen examples of multiple mercs owned at once)
};
// [OPCode: 0x6537] On Live as of April 2 2012 [Server->Client]
// Should be named OP_MercenaryDataResponse, but the current opcode using that name should be renamed first
// Size varies if mercenary is hired or if browsing Mercenary Merchant
// This may also be the response for Client->Server 0x0327 (size 0) packet On Live as of April 2 2012
struct MercenaryDataUpdate_Struct {
/*0000*/ int32 MercStatus; // Seen 0 with merc and -1 with no merc hired
/*0004*/ uint32 MercCount; // Seen 1 with 1 merc hired and 0 with no merc hired
/*0008*/ MercenaryData_Struct MercData[MAX_MERC]; // Data for individual mercenaries in the Merchant List
};
// [OPCode: 0x6537] On Live as of April 2 2012 [Server->Client]
// Size 12 and sent on Zone-In if no mercenary is currently hired and when merc is dismissed
// (Same packet as MercAssign_Struct?)
struct NoMercenaryHired_Struct {
/*0000*/ int32 MercStatus; // Seen -1 with no merc hired
/*0004*/ uint32 MercCount; // Seen 0 with no merc hired
/*0008*/ uint32 MercID; // Seen 1 when no merc is hired - ID unique to each type of mercenary
/*0012*/
};
// OP_MercenaryAssign (Same packet as NoMercenaryHired_Struct?)
struct MercenaryAssign_Struct {
/*0000*/ uint32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ uint32 MercUnk01; //
/*0008*/ uint32 MercUnk02; //
/*0012*/
};
// [OPCode: 0x495d OP_MercenaryTimer] On Live as of April 2 2012 [Server->Client] [Size: 20]
// Sent on Zone-In, or after Dismissing, Suspending, or Unsuspending Mercs
struct MercenaryStatus_Struct {
/*0000*/ uint32 MercEntityID; // Seen 0 (no merc spawned) or 615843841 and 22779137
/*0004*/ uint32 UpdateInterval; // Seen 900000 - Matches from 0x6537 packet (15 minutes in ms?)
/*0008*/ uint32 MercUnk01; // Seen 180000 - 3 minutes in milleseconds? Maybe next update interval?
/*0012*/ uint32 MercState; // Seen 5 (normal) or 1 (suspended)
/*0016*/ uint32 SuspendedTime; // Seen 0 (not suspended) or c9 c2 64 4f (suspended on Sat Mar 17 11:58:49 2012) - Unix Timestamp
/*0020*/
};
// [OPCode: 0x4c6c] On Live as of April 2 2012 [Client->Server] [Size: 8]
// Sent from the client when using the Mercenary Window
struct MercenaryCommand_Struct {
/*0000*/ uint32 MercCommand; // Seen 0 (zone in with no merc or suspended), 1 (dismiss merc), 5 (normal state), 36 (zone in with merc)
/*0004*/ int32 Option; // Seen -1 (zone in with no merc), 0 (setting to passive stance), 1 (normal or setting to balanced stance)
/*0008*/
};
// [OPCode: 0x1a79] On Live as of April 2 2012 [Client->Server] [Size: 1]
// Requesting to suspend or unsuspend merc
struct SuspendMercenary_Struct {
/*0000*/ uint8 SuspendMerc; // Seen 30 (48) for suspending or unsuspending
/*0001*/
};
// [OPCode: 0x2528] On Live as of April 2 2012 [Server->Client] [Size: 4]
// Response to suspend merc with timestamp
struct SuspendMercenaryResponse_Struct {
/*0000*/ uint32 SuspendTime; // Unix Timestamp - Seen a9 11 78 4f
/*0004*/
};
// [OPCode: 0x5e78 (OP_MercenaryHire?)] On Live as of April 2 2012
// Sent by client when requesting to view Mercenary info or Hire a Mercenary
struct MercenaryMerchantRequest_Struct {
/*0000*/ uint32 MercID; // Seen 399 and 400 for merc ID
/*0004*/ uint32 MercUnk01; // Seen 1
/*0008*/ uint32 MercMerchantID; // Entity ID for Mercenary Merchant
/*0012*/ uint32 MercUnk02; // Seen 65302016 (00 6e e4 03) - (probably actually individual uint8 fields), but seen as DWORD in Seeds client.
/*0016*/
};
// [OPCode: 0x5e78 (OP_MercenaryHire?)] On Live as of April 2 2012
/*
Valid response IDs:
0 - Hire me! (Assign Merc after sending this.)
1 - Insufficient money message.
2 - Mercenary-To-Hire does not exist in the server's DB.
3 - Mercenary failed to spawn. (this actually tells us the mercenary should spawn BEFORE recieving this packet.)
4 - Mercenaries not allowed in raids.
5 - You already have a mercenary request pending
6 - You must dismiss the mercenary before hiring a new one.
7 - You must dismiss your suspended one before hiring a new one.
8 - Group is full.
9 - Error creating mercenary
10 - Replacing mercenary(?!)
11 - Your mercenary has quit! You ran out of money to pay for your mercenary!
12 - Your mercenary waived an upkeep cost of %d plat, and %d gold and your mercenary upkeep cost timer has been reset to %s. <-- these values are for GM resets of mercenaries and are generated from the client's
mercenary info. NOT from the packet.
13 - Your mercenary is about to be quit due to insufficient funds! <--- Sent before the mercenary quits, unsure of time sent before.
14 - There is no mercenary liason nearby! <-- hacking attempt check if no mercenary merchant is in the zone!
15 - You are too far away from the liason! <-- Liason exists as type in the zone, but client is too far away. (position update happened)
16 - You do not meet the requirements for that mercenary! <-- For example, if a mercenary is 'unlocked' in some way, send this if they do not have the mercenary unlock.
*/
// Sent by Server in response to requesting to view Mercenary info or Hire a Mercenary
struct MercenaryMerchantResponse_Struct {
/*0000*/ uint32 ResponseType;
/*0004*/
};
//Found in client near a ref to the string:
//"Got a broadcast message for ... %s ...\n"
struct ClientMarqueeMessage_Struct {
uint32 type;
uint32 unk04; // no idea, didn't notice a change when altering it.
//According to asm the following are hard coded values: 2, 4, 5, 6, 7, 10, 12, 13, 14, 15, 16, 18, 20
//There is also a non-hardcoded fall through but to be honest i don't know enough about what it does yet
uint32 priority; //needs a better name but it does:
//opacity = (priority / 255) - floor(priority / 255)
//# of fade in/out blinks = (int)((priority - 1) / 255)
//so 510 would have 100% opacity and 1 extra blink at end
uint32 fade_in_time; //The fade in time, in ms
uint32 fade_out_time; //The fade out time, in ms
uint32 duration; //in ms
char msg[1]; //message plus null terminator
};
struct fling_struct {
/* 00 */ uint32 collision; // 0 collision is off, anything else it's on
/* 04 */ int32 travel_time; // ms -- UF we need to calc this, RoF+ -1 auto calcs
/* 08 */ uint8 unk3; // bool, set to 1 has something to do with z-axis or something weird things happen if the new Z is above or equal to yours
/* 09 */ uint8 disable_fall_damage; // 1 you take no fall damage, 0 you take fall damage
/* 10 */ uint8 padding[2];
/* 12 */ float speed_z;
/* 16 */ float new_y;
/* 20 */ float new_x;
/* 24 */ float new_z;
/* 28 */
};
// used when action == 0
struct AuraCreate_Struct {
/* 00 */ uint32 action; // 0 = add, 1 = delete, 2 = reset
/* 04 */ uint32 type; // unsure -- normal auras show 1 clicky (ex. Circle of Power) show 0
/* 08 */ char aura_name[64];
/* 72 */ uint32 entity_id;
/* 76 */ uint32 icon;
/* 80 */
};
// used when action == 1
struct AuraDestory_Struct {
/* 00 */ uint32 action; // 0 = add, 1 = delete, 2 = reset
/* 04 */ uint32 entity_id;
/* 08 */
};
// I think we can assume it's just action for 2, client doesn't seem to do anything with the rest of the data in that case
struct SayLinkBodyFrame_Struct {
/*000*/ char ActionID[1];
/*001*/ char ItemID[5];
/*006*/ char Augment1[5];
/*011*/ char Augment2[5];
/*016*/ char Augment3[5];
/*021*/ char Augment4[5];
/*026*/ char Augment5[5];
/*031*/ char Augment6[5];
/*036*/ char IsEvolving[1];
/*037*/ char EvolveGroup[4];
/*041*/ char EvolveLevel[2];
/*043*/ char OrnamentIcon[5];
/*048*/ char Hash[8];
/*056*/
};
struct Checksum_Struct {
uint64 checksum;
uint8 data[2048];
};
struct UpdateMovementEntry {
/* 00 */ float Y;
/* 04 */ float X;
/* 08 */ float Z;
/* 12 */ uint8 type;
/* 13 */ unsigned int timestamp;
/* 17 */
};
struct UnderWorld {
/* 00 */ int spawn_id;
/* 04 */ float y;
/* 08 */ float x;
/* 12 */ float z;
/* 16 */
};
enum BazaarTraderBarterActions {
TraderOff = 0,
TraderOn = 1,
PriceUpdate = 3,
EndTransaction = 4,
BazaarSearch = 7,
WelcomeMessage = 9,
BuyTraderItem = 10,
ListTraderItems = 11,
CustomerBrowsing = 13,
BazaarInspect = 18,
ItemMove = 19,
TraderAck2 = 22,
AddTraderToBazaarWindow = 24,
RemoveTraderFromBazaarWindow = 25,
FirstOpenSearch = 26,
ClickTrader = 28,
DeliveryCostUpdate = 29
};
enum BazaarPurchaseActions {
BazaarByVendor = 0,
BazaarByParcel = 1,
BazaarByDirectToInventory = 2,
BarterByVendor = 0,
BarterInBazaar = 1,
BarterOutsideBazaar = 2
};
enum BazaarPurchaseSubActions {
Success = 0,
Failed = 1,
DataOutDated = 3,
TooManyParcels = 5,
TransactionInProgress = 6,
InsufficientFunds = 7
};
enum BazaarSearchScopes {
Local_Scope = 0,
AllTraders_Scope = 1,
NonRoFBazaarSearchScope = 99
};
struct BazaarSearchResultsFromDB_Struct {
uint32 count;
uint32 trader_id;
uint32 item_id;
uint32 serial_number;
uint32 charges;
uint32 cost;
uint32 slot_id;
uint32 icon_id;
uint32 sum_charges;
uint32 trader_zone_id;
int32 trader_zone_instance_id;
uint32 trader_entity_id;
uint32 item_stat;
bool stackable;
std::string item_name;
std::string serial_number_RoF;
std::string trader_name;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(count),
CEREAL_NVP(trader_id),
CEREAL_NVP(item_id),
CEREAL_NVP(serial_number),
CEREAL_NVP(charges),
CEREAL_NVP(cost),
CEREAL_NVP(slot_id),
CEREAL_NVP(icon_id),
CEREAL_NVP(sum_charges),
CEREAL_NVP(trader_zone_id),
CEREAL_NVP(trader_zone_instance_id),
CEREAL_NVP(trader_entity_id),
CEREAL_NVP(item_stat),
CEREAL_NVP(stackable),
CEREAL_NVP(item_name),
CEREAL_NVP(serial_number_RoF),
CEREAL_NVP(trader_name)
);
}
};
struct BazaarSearchMessaging_Struct {
uint32 action;
char payload[];
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(action),
CEREAL_NVP(payload)
);
}
};
struct BuylineItemDetails_Struct {
uint64 item_cost;
uint32 item_quantity;
};
struct PickZoneEntry_Struct {
int16 zone_id;
int16 unknown;
int32 player_count;
int32 instance_id;
};
struct PickZoneWindow_Struct {
char padding000[64];
int64 session_id;
int8 option_count;
char padding073[23];
PickZoneEntry_Struct entries[10];
};
struct PickZone_Struct {
int64 session_id;
int32 selection_id;
};
struct EvolveItemToggle {
uint32 action;
uint32 unknown_004;
uint64 unique_id;
uint32 percentage;
uint32 activated;
};
struct EvolveXPWindowReceive {
uint32 action;
uint32 unknown_004;
uint64 item1_unique_id;
uint64 item2_unique_id;
};
struct EvolveItemMessaging {
uint32 action;
char serialized_data[];
};
struct EvolveXPWindowSend {
/*000*/ uint32 action;
/*004*/ uint64 item1_unique_id;
/*012*/ uint64 item2_unique_id;
/*020*/ uint32 compatibility;
/*024*/ uint32 max_transfer_level;
/*028*/ uint8 item1_present;
/*029*/ uint8 item2_present;
/*030*/ std::string serialize_item_1;
/*034*/ std::string serialize_item_2;
template
void serialize(Archive &archive)
{
archive(
CEREAL_NVP(action),
CEREAL_NVP(item1_unique_id),
CEREAL_NVP(item2_unique_id),
CEREAL_NVP(compatibility),
CEREAL_NVP(max_transfer_level),
CEREAL_NVP(item1_present),
CEREAL_NVP(item2_present),
CEREAL_NVP(serialize_item_1),
CEREAL_NVP(serialize_item_2)
);
}
};
struct EvolveTransfer {
uint32 item_from_id;
uint32 item_from_current_amount;
uint32 item_to_id;
uint32 item_to_current_amount;
uint32 compatibility;
uint32 max_transfer_level;
};
struct EvolveGetNextItem {
uint32 new_item_id;
uint64 new_current_amount;
uint64 from_current_amount;
uint32 max_transfer_level;
};
// Restore structure packing to default
#pragma pack(pop)