Filling out charProfileStruct
Unknowns in charProfileStruct make me sad. 4k unknowns in charProfileStruct really make me sad! I've done my best to fill in knowns in charProfileStruct when I've had time and I wanted to ask some help. I know a lot of you would help seq out if you could. Well here's your chance!
My current charProfileStruct is the following. I know this isn't what is in cvs and I haven't put out a patch with this in it. Don't cut and paste this into your everquest.h because it won't compile (since I've taken out aapoints because it didn't fit and was way off). When I put out a patch again, it will have this in it. It doesn't really make seq any better so don't worry about it! This is just in order to better understand the EQ net stream.
Code:
struct charProfileStruct
{
/*0000*/ uint32_t checksum; //
/*0004*/ char name[64]; // Name of player
/*0068*/ char lastName[32]; // Last name of player
/*0100*/ uint32_t gender; // Player Gender - 0 Male, 1 Female
/*0104*/ uint32_t race; // Player race
/*0108*/ uint32_t class_; // Player class
/*0112*/ uint32_t unknown0112; // *** Placeholder
/*0116*/ uint32_t level; // Level of player (might be one byte)
/*0120*/ uint32_t bind_zone_id[5]; // Bind info (zone, x, y, z, heading)
/*0140*/ float bind_x[5]; // 0 is normal bind
/*0160*/ float bind_y[5]; // 5 is some weird point in newbie zone
/*0180*/ float bind_z[5]; // (which is secondary bind for wiz/dru?)
/*0200*/ float bind_heading[5]; // Unused slots show newbie bind
/*0220*/ uint32_t deity; // deity
/*0224*/ int32_t guildID; // guildID
/*0228*/ uint32_t birthdayTime; // character birthday
/*0232*/ uint32_t lastSaveTime; // character last save time
/*0236*/ uint32_t timePlayedMin; // time character played
/*0240*/ uint8_t pvp; // 1=pvp, 0=not pvp
/*0241*/ uint8_t level1; // Level of Player
/*0242*/ uint8_t anon; // 2=roleplay, 1=anon, 0=not anon
/*0243*/ uint8_t gm; // 0=no, 1=yes
/*0244*/ int8_t guildstatus; // 0=member, 1=officer, 2=guildleader
/*0245*/ uint8_t unknown0245[55]; // *** Placeholder
/*0300*/ uint8_t haircolor; // Player hair color
/*0301*/ uint8_t beardcolor; // Player beard color
/*0302*/ uint8_t eyecolor1; // Player left eye color
/*0303*/ uint8_t eyecolor2; // Player right eye color
/*0304*/ uint8_t hairstyle; // Player hair style
/*0305*/ uint8_t beard; // Player beard type
/*0306*/ uint8_t unknown0302[6]; // *** Placeholder
/*0312*/ uint32_t item_material[9]; // Item texture/material of worn items
/*0348*/ uint8_t unknown0348[48]; // *** Placeholder
/*0396*/ Color_Struct item_tint[9]; // RR GG BB 00
/*0432*/ AA_Array aa_array[MAX_AA]; // AAs
/*1392*/ char servername[32]; // server the char was created on
/*1424*/ uint8_t unknown1452[68]; // *** Placeholder
/*1492*/ uint32_t exp; // Current Experience
/*1496*/ uint32_t unknown1496; // *** Placeholder
/*1500*/ uint32_t points; // Unspent Practice points
/*1504*/ uint32_t MANA; // Current MANA
/*1508*/ uint32_t curHp; // Current HP without +HP equipment
/*1512*/ uint32_t unknown1512; // 0x05
/*1516*/ uint32_t STR; // Strength
/*1520*/ uint32_t STA; // Stamina
/*1524*/ uint32_t CHA; // Charisma
/*1528*/ uint32_t DEX; // Dexterity
/*1532*/ uint32_t INT; // Intelligence
/*1536*/ uint32_t AGI; // Agility
/*1540*/ uint32_t WIS; // Wisdom
/*1544*/ uint8_t face; // Player face
/*1545*/ uint8_t unknown1545[47]; // *** Placeholder
/*1592*/ uint8_t languages[25]; // List of languages (MAX_KNOWN_LANGS)
/*1617*/ uint8_t unknown1617[7]; // All 0x00 (language buffer?)
/*1624*/ int32_t sSpellBook[400]; // List of the Spells in spellbook
/*3224*/ uint8_t unknown3224[448]; // all 0xff after last spell
/*3672*/ int32_t sMemSpells[9]; // List of spells memorized
/*3708*/ uint8_t unknown3708[32]; // *** Placeholder
/*3740*/ float x; // Players x position
/*3744*/ float y; // Players y position
/*3748*/ float z; // Players z position
/*3752*/ float heading; // Players heading
/*3756*/ uint8_t unknown3756[4]; // *** Placeholder
/*3760*/ uint32_t platinum; // Platinum Pieces on player
/*3764*/ uint32_t gold; // Gold Pieces on player
/*3768*/ uint32_t silver; // Silver Pieces on player
/*3772*/ uint32_t copper; // Copper Pieces on player
/*3776*/ uint32_t platinum_bank; // Platinum Pieces in Bank
/*3780*/ uint32_t gold_bank; // Gold Pieces in Bank
/*3784*/ uint32_t silver_bank; // Silver Pieces in Bank
/*3788*/ uint32_t copper_bank; // Copper Pieces in Bank
/*3792*/ uint32_t platinum_cursor; // Platinum Pieces on cursor
/*3796*/ uint32_t gold_cursor; // Gold Pieces on cursor
/*3800*/ uint32_t silver_cursor; // Silver Pieces on cursor
/*3804*/ uint32_t copper_cursor; // Copper Pieces on cursor
/*3808*/ uint32_t platinum_shared; // Shared platinum pieces
/*3812*/ uint8_t unknown3812[20]; // Unknown - all zero
/*3832*/ uint32_t skills[75]; // List of skills (MAX_KNOWN_SKILLS)
/*4132*/ uint8_t unknown4132[348]; // *** Placeholder
/*4480*/ uint32_t expAA; // Current AA experience
/*4484*/ uint8_t unknown4484[4]; // *** Placeholder
/*4488*/ uint32_t expansions; // Bitmask for expansions
/*4492*/ uint8_t unknown4492[20]; // *** Placeholder
/*4512*/ uint32_t hunger; // Food (ticks till next eat)
/*4516*/ uint32_t thirst; // Drink (ticks till next drink)
/*4520*/ uint8_t unknown4520[20]; // *** Placeholder
/*4540*/ uint16_t zoneId; // see zones.h
/*4542*/ uint16_t zoneInstance; // Instance id
/*4544*/ spellBuff buffs[MAX_BUFFS]; // Buffs currently on the player
/*4944*/ char groupMembers[MAX_GROUP_MEMBERS][64];// all the members in group, including self
/*5328*/ uint8_t unknown5328[668]; // *** Placeholder
/*5996*/ uint32_t ldon_guk_points; // Earned GUK points
/*6000*/ uint32_t ldon_mir_points; // Earned MIR points
/*6004*/ uint32_t ldon_mmc_points; // Earned MMC points
/*6008*/ uint32_t ldon_ruj_points; // Earned RUJ points
/*6012*/ uint32_t ldon_tak_points; // Earned TAK points
/*6016*/ uint32_t ldon_avail_points; // Available LDON points
/*6020*/ uint8_t unknown6020[112]; // *** Placeholder
/*6132*/ uint32_t tributeTime; // Time remaining on tribute (millisecs)
/*6136*/ uint32_t unknown6136; // *** Placeholder
/*6140*/ uint32_t careerTribute; // Total favor points for this char
/*6144*/ uint32_t unknown6144; // *** Placeholder
/*6148*/ uint32_t currentTribute; // Current tribute points
/*6152*/ uint32_t unknown6152; // *** Placeholder
/*6156*/ uint32_t tributeActive; // 0 = off, 1=on
/*6160*/ TributeStruct tributes[MAX_TRIBUTES]; // Current tribute loadout
/*6200*/ uint32_t disciplines[MAX_DISCIPLINES]; // Known disciplines
/*6400*/ uint8_t unknown6400[440]; // *** Placeholder
/*6840*/ uint32_t endurance; // Current endurance
/*6844*/ uint8_t unknown6844[276]; // *** Placeholder
/*7120*/ uint32_t airRemaining; // Air supply (seconds)
/*7124*/ uint8_t unknown7124[4608]; // *** Placeholder
/*11732*/ uint32_t aa_spent; // Number of spent AA points
/*11736*/ uint32_t unknown11736; // *** Placeholder
/*11740*/ uint32_t aa_unspent; // Unspent AA points
/*11744*/ uint8_t unknown11744[36]; // *** Placeholder
/*11780*/ BandolierStruct bandoliers[MAX_BANDOLIERS]; // bandolier contents
/*13060*/ uint8_t unknown13060[5120]; // *** Placeholder
/*18180*/ InlineItem potionBelt[MAX_POTIONS_IN_BELT]; // potion belt
/*18468*/ uint8_t unknown18468[28]; // *** Placeholder
}; /* 18496 */
Additions to this over current cvs are mostly thanks to help from eqemu and then I spent time and verified them and made sure they aligned properly against live servers. You'll see that bandolier is in there and potion belt, hunger, thirst, personal tribute, etc. Some stuff that wasn't there before. But you'll also see that there are still a lot of unknowns!
What do I want with you? I'd like help two ways.
The first is just brainstorming. What kinds of things do you think need to be in there that aren't? You all play EQ (or did at one point). What is there that the client knows that might be missing in charProfileStruct? I know not all of you know how the EQ net stream works, so don't feel silly saying something that might be dumb. A lot of stuff is in other packets, even though it might make sense that it would be in charProfileStruct (which comes with OP_PlayerProfile).
For example, we spent a bit of time last week tracking down where percentage of experience you have assigned to AA is. It used to be in charProfileStruct, but it no longer is. It's sent in an OP_AAUpdate now. Or we spent some time figuring out where the origin point for you character is stored (it isn't, the server sends it to you when you use the origin AA). I don't expect you to track stuff down, I just want a nice list of things that people think might be in there to aid in figuring this stuff out.
For example, things that I think might be in there, but I haven't had the time or the means to determine:
- Pet info (buffs, name, items, etc.) since pets zone with you now
- Pocketed pet info from the AA that lets you store pets
- Spell cooldown (for example, how long will Divine Intervention be greyed out), maybe in the 32 bytes after memmed spells?
- Skill cooldown (for example, how long will LoH be greyed), maybe in the unknown after skills?
- Disc cooldown (for example, how long until weaponshield is usable again), maybe in the unknown after discs?
- AA cooldown (though this may be in separate opcodes, the AA stuff seems like its a mess over the wire)
- Title (apprentiece baker, etc.), though this used to be there after servername, it was removed. I wouldn't be surprised if the list of available titles comes across separately, but an id is sent in charProfileStruct somewhere
- Group Leader exp (total this point to set the bar)
- Group Leader AA information (current points and max points)
- Which Group Lead AAs you have
- Whether Leader AA is on/off
- Raid Leader exp (total this point to set the bar)
- Raid Leader AA information (current points and max points)
- Which Raid Lead AAs you have
- DoN radiant and ebon shards
- Wizard/Druid secondary bind point
I'm sure there's stuff I'm missing too. Any ideas you might have are very welcome.
Some of that I can verify myself, but some of that I can't. For example, I don't have a pet class, let alone one with pocket pet AA. I don't have a wizard or druid with secondary bind AA. This brings me to the second way you can help out.
If you have a character who can test some of this stuff out, you can send me logs and I can use them to figure out things. For example, if you're a druid with secondary bind, you can log a zone, set your bind point, then zone again. I can use this to figure out if secondary bind is in charProfileStruct and where.
All you'd need to do this is:
1) tcpdump -i eth0 -s0 -w secondbind.log 'udp && host 192.168.1.52' (of course replace eth0 with your ethernet device, secondbind.log with whatever you want to call the log, and replace 192.168.1.52 with the ip of your eq machine). You must do this as root.
2) Do your test (zone, set your secondary bind, zone again)
3) Control-C the tcpdump to stop it
4) Zip up the log please with gzip secondbind.log
5) Email the log to seqdump at gmail.com
6) In the email, include what you did (in this case, that you zoned into PoT, set your secondary bind point to be right outside the Plane of Air in PoT, then zoned back into PoK)
Right now, the two biggest things I'd like to see are pocketed pets (with buffs and items if you can) and secondary bind points. There may be more things I'll be interested in at some point, but those are the big two.
Please only send me a log if you trust me with it. If you send me a log, I will know what server you are on and what your player name is. That is important information. If you don't feel comfortable sending this to me, DON'T DO IT. I will not give anyone your log. I won't use the information from the log for anything, other than to improve our understanding of the EQ net stream. Also, please do not include you logging into EQ in your log. I don't want your password at all. Log into EQ, then start the tcpdump, then zone.
Re: Filling out charProfileStruct
Yeah, ok, so Radiant and Ebon shards were obvious once I actually looked for them. So sue me!
Re: Filling out charProfileStruct
Heh. I had spent some time and corrected some of the structure about 6 months ago (additional unknowns have been added since then). I fixed what I could but there was a lot left to do (and now even more). I never could figure out the AA though.
I only have one char with a pet but dont have suspend minion aa so no go from me on that. I also only have one char with AA so I dont have a lot to compare to.
I'll also look at the structure again and see what I can figure out when I get some time. Im also going to have to try to remember how I did it back then.
Oh yea, I renewed my account again a week ago.
Re: Filling out charProfileStruct
I'm browsing from a windoze box durring class, so I don't have any of the source in front of me, but could
/*5328*/ uint8_t unknown5328[668]; // *** Placeholder
be raid members? How many uint8_t is a character, enough that 668 could hold 72 raid members information. Wouldn't even have to hold that much, since HP and pet info isn't available on the raid window. Just raid and group leader flags, looter flag, name, along note strings and raid motd string now.
Or am I way out in left field, and raid members are stored at 4944 in that large array?
Re: Filling out charProfileStruct
It looks like the raid comes along with an OP_RaidJoin on zoning, so it's outside of charProfileStruct. Good idea though. I had to check an old dump I had to see how it worked, but turns out not to be in charProfileStruct.
uint8_t = char = 1 byte. Character names are 64 characters.
Re: Filling out charProfileStruct
edit: okay, needs to read the discovered codes closer.
Re: Filling out charProfileStruct
AA is already known in there (expAA is exp points in this point, aa_spent = total AA you've spent, aa_unspent = unspent points you have, aa_array is the AA you have).
Re: Filling out charProfileStruct
Quote:
Originally Posted by purple
AA is already known in there (expAA is exp points in this point, aa_spent = total AA you've spent, aa_unspent = unspent points you have, aa_array is the AA you have).
Yes there is AA stuff in there, but from what I remember it doesn't match up correctly.
Re: Filling out charProfileStruct
I fixed it. It should line up ok in 5.0.0.19 against live.
Re: Filling out charProfileStruct
So far from my original list with the help of eqemu people, I've gotten the following placed into charProfileStruct:
- Spell cooldown (for example, how long will Divine Intervention be greyed out)
- Group Leader exp (total this point to set the bar)
- Group Leader AA information (current points)
- Which Group Lead AAs you have
- Raid Leader exp (total this point to set the bar)
- Raid Leader AA information (current points)
- Which Raid Lead AAs you have
- DoN radiant and ebon shards
I'm pretty sure normal pet info is not in charProfileStruct also:
- Pet info (buffs, name, items, etc.) since pets zone with you now
So that leaves to be verified from my original list:
- Pocketed pet info from the AA that lets you store pets
- Skill cooldown (for example, how long will LoH be greyed), maybe in the unknown after skills?
- Disc cooldown (for example, how long until weaponshield is usable again), maybe in the unknown after discs?
- AA cooldown (though this may be in separate opcodes, the AA stuff seems like its a mess over the wire)
- Title (apprentiece baker, etc.), though this used to be there after servername, it was removed. I wouldn't be surprised if the list of available titles comes across separately, but an id is sent in charProfileStruct somewhere
- Whether Leader AA is on/off
- Wizard/Druid secondary bind point
Moving right along!
Re: Filling out charProfileStruct
Nice work. Unfortuantely I cant help on most of them.
I will see if I can find the pet info though.
Re: Filling out charProfileStruct
Anyone have any idea what OP 0900 is? It seems to echo the data that is being sent to the client.
Pets seem to be coming up as the new spawn op code. fff9 Edit: After looking at this, it seems pets are treated as NPCs. I have not found a structure for them except for when you cast a buff on them.
Tribue item list seem to be op 123e
Title List (all titles like master tinkerer or master jeweler are in this op code) seem to be 642c I dont know where it is yet of when you assign one to yourself.
Petition structure seems to be on op 186e
Edit:
It looks like op 0e4a is when you cast a new spell on a pet. Possibly the display of the buff in the pet window.
Re: Filling out charProfileStruct
A while back, someone gave me a perl script to format out the player structure so it is a bit more readable. I updated it so it works with live code.
structvis.pl
Code:
#!/usr/bin/perl -w
use strict;
my $charProfile = << 'END'
/*
** Player Profile
** Length: 18496 Octets
** OpCode: CharProfileCode
*/
struct charProfileStruct
{
/*0000*/ uint32_t checksum; //
/*0004*/ char name[64]; // Name of player
/*0068*/ char lastName[32]; // Last name of player
/*0100*/ uint32_t gender; // Player Gender - 0 Male, 1 Female
/*0104*/ uint32_t race; // Player race
/*0108*/ uint32_t class_; // Player class
/*0112*/ uint32_t unknown0112; // *** Placeholder
/*0116*/ uint32_t level; // Level of player (might be one byte)
/*0120*/ uint32_t bind_zone_id[5]; // Bind info (zone, x, y, z, heading)
/*0140*/ float bind_x[5]; // 0 is normal bind
/*0160*/ float bind_y[5]; // 5 is some weird point in newbie zone
/*0180*/ float bind_z[5]; // (which is secondary bind for wiz/dru?)
/*0200*/ float bind_heading[5]; // Unused slots show newbie bind
/*0220*/ uint32_t deity; // deity
/*0224*/ int32_t guildID; // guildID
/*0228*/ uint32_t birthdayTime; // character birthday
/*0232*/ uint32_t lastSaveTime; // character last save time
/*0236*/ uint32_t timePlayedMin; // time character played
/*0240*/ uint8_t pvp; // 1=pvp, 0=not pvp
/*0241*/ uint8_t level1; // Level of Player
/*0242*/ uint8_t anon; // 2=roleplay, 1=anon, 0=not anon
/*0243*/ uint8_t gm; // 0=no, 1=yes
/*0244*/ int8_t guildstatus; // 0=member, 1=officer, 2=guildleader
/*0245*/ uint8_t unknown0245[55]; // *** Placeholder
/*0300*/ uint8_t haircolor; // Player hair color
/*0301*/ uint8_t beardcolor; // Player beard color
/*0302*/ uint8_t eyecolor1; // Player left eye color
/*0303*/ uint8_t eyecolor2; // Player right eye color
/*0304*/ uint8_t hairstyle; // Player hair style
/*0305*/ uint8_t beard; // Player beard type
/*0306*/ uint8_t unknown0302[6]; // *** Placeholder
/*0312*/ uint32_t item_material[9]; // Item texture/material of worn items
/*0348*/ uint8_t unknown0348[48]; // *** Placeholder
/*0396*/ Color_Struct item_tint[9]; // RR GG BB 00
/*0432*/ AA_Array aa_array[MAX_AA]; // AAs
/*1392*/ char servername[32]; // server the char was created on
/*1424*/ uint8_t unknown1452[68]; // *** Placeholder
/*1492*/ uint32_t exp; // Current Experience
/*1496*/ uint32_t unknown1496; // *** Placeholder
/*1500*/ uint32_t points; // Unspent Practice points
/*1504*/ uint32_t MANA; // Current MANA
/*1508*/ uint32_t curHp; // Current HP without +HP equipment
/*1512*/ uint32_t unknown1512; // 0x05
/*1516*/ uint32_t STR; // Strength
/*1520*/ uint32_t STA; // Stamina
/*1524*/ uint32_t CHA; // Charisma
/*1528*/ uint32_t DEX; // Dexterity
/*1532*/ uint32_t INT; // Intelligence
/*1536*/ uint32_t AGI; // Agility
/*1540*/ uint32_t WIS; // Wisdom
/*1544*/ uint8_t face; // Player face
/*1545*/ uint8_t unknown1545[47]; // *** Placeholder
/*1592*/ uint8_t languages[25]; // List of languages (MAX_KNOWN_LANGS)
/*1617*/ uint8_t unknown1617[7]; // All 0x00 (language buffer?)
/*1624*/ int32_t sSpellBook[400]; // List of the Spells in spellbook
/*3224*/ uint8_t unknown3224[448]; // all 0xff after last spell
/*3672*/ int32_t sMemSpells[9]; // List of spells memorized
/*3708*/ uint8_t unknown3708[32]; // *** Placeholder
/*3740*/ float x; // Players x position
/*3744*/ float y; // Players y position
/*3748*/ float z; // Players z position
/*3752*/ float heading; // Players heading
/*3756*/ uint8_t unknown3756[4]; // *** Placeholder
/*3760*/ uint32_t platinum; // Platinum Pieces on player
/*3764*/ uint32_t gold; // Gold Pieces on player
/*3768*/ uint32_t silver; // Silver Pieces on player
/*3772*/ uint32_t copper; // Copper Pieces on player
/*3776*/ uint32_t platinum_bank; // Platinum Pieces in Bank
/*3780*/ uint32_t gold_bank; // Gold Pieces in Bank
/*3784*/ uint32_t silver_bank; // Silver Pieces in Bank
/*3788*/ uint32_t copper_bank; // Copper Pieces in Bank
/*3792*/ uint32_t platinum_cursor; // Platinum Pieces on cursor
/*3796*/ uint32_t gold_cursor; // Gold Pieces on cursor
/*3800*/ uint32_t silver_cursor; // Silver Pieces on cursor
/*3804*/ uint32_t copper_cursor; // Copper Pieces on cursor
/*3808*/ uint32_t platinum_shared; // Shared platinum pieces
/*3812*/ uint8_t unknown3812[20]; // Unknown - all zero
/*3832*/ uint32_t skills[75]; // List of skills (MAX_KNOWN_SKILLS)
/*4132*/ uint8_t unknown4132[348]; // *** Placeholder
/*4480*/ uint32_t expAA; // Current AA experience
/*4484*/ uint8_t unknown4484[4]; // *** Placeholder
/*4488*/ uint32_t expansions; // Bitmask for expansions
/*4492*/ uint8_t unknown4492[20]; // *** Placeholder
/*4512*/ uint32_t hunger; // Food (ticks till next eat)
/*4516*/ uint32_t thirst; // Drink (ticks till next drink)
/*4520*/ uint8_t unknown4520[20]; // *** Placeholder
/*4540*/ uint16_t zoneId; // see zones.h
/*4542*/ uint16_t zoneInstance; // Instance id
/*4544*/ spellBuff buffs[MAX_BUFFS]; // Buffs currently on the player
/*4944*/ char groupMembers[MAX_GROUP_MEMBERS][64];// all the members in group, including self
/*5328*/ uint8_t unknown5328[668]; // *** Placeholder
/*5996*/ uint32_t ldon_guk_points; // Earned GUK points
/*6000*/ uint32_t ldon_mir_points; // Earned MIR points
/*6004*/ uint32_t ldon_mmc_points; // Earned MMC points
/*6008*/ uint32_t ldon_ruj_points; // Earned RUJ points
/*6012*/ uint32_t ldon_tak_points; // Earned TAK points
/*6016*/ uint32_t ldon_avail_points; // Available LDON points
/*6020*/ uint8_t unknown6020[112]; // *** Placeholder
/*6132*/ uint32_t tributeTime; // Time remaining on tribute (millisecs)
/*6136*/ uint32_t unknown6136; // *** Placeholder
/*6140*/ uint32_t careerTribute; // Total favor points for this char
/*6144*/ uint32_t unknown6144; // *** Placeholder
/*6148*/ uint32_t currentTribute; // Current tribute points
/*6152*/ uint32_t unknown6152; // *** Placeholder
/*6156*/ uint32_t tributeActive; // 0 = off, 1=on
/*6160*/ TributeStruct tributes[MAX_TRIBUTES]; // Current tribute loadout
/*6200*/ uint32_t disciplines[MAX_DISCIPLINES]; // Known disciplines
/*6400*/ uint8_t unknown6400[440]; // *** Placeholder
/*6840*/ uint32_t endurance; // Current endurance
/*6844*/ uint8_t unknown6844[276]; // *** Placeholder
/*7120*/ uint32_t airRemaining; // Air supply (seconds)
/*7124*/ uint8_t unknown7124[4608]; // *** Placeholder
/*11732*/ uint32_t aa_spent; // Number of spent AA points
/*11736*/ uint32_t unknown11736; // *** Placeholder
/*11740*/ uint32_t aa_unspent; // Unspent AA points
/*11744*/ uint8_t unknown11744[36]; // *** Placeholder
/*11780*/ BandolierStruct bandoliers[MAX_BANDOLIERS]; // bandolier contents
/*13060*/ uint8_t unknown13060[5120]; // *** Placeholder
/*18180*/ InlineItem potionBelt[MAX_POTIONS_IN_BELT]; // potion belt
/*18468*/ uint8_t unknown18468[8]; // *** Placeholder
/*18476*/ uint32_t currentRadCrystals; // Current count of radiant crystals
/*18480*/ uint32_t careerRadCrystals; // Total count of radiant crystals ever
/*18484*/ uint32_t currentEbonCrystals;// Current count of ebon crystals
/*18488*/ uint32_t careerEbonCrystals; // Total count of ebon crystals ever
/*18492*/ uint32_t unknown18492; // *** Placeholder
}; /* 18496 */
END
;
# load struct
my @struct = ();
while ($charProfile =~ /^(.*)$/mcg) {
my $line = $1;
if ($line =~ /^.*\s(\S+)\s+(\S+)\;/) {
my $type = $1;
my $name = $2;
push(@struct, { 'name' => $name, 'type' => $type } );
}
}
# load data
my @data = ();
open(PACKET, "./packet.txt");
while (my $line = <PACKET>) {
if ($line =~ /^\d+ \| ([0-9a-f ]+?) \|/) {
$line = $1;
while ($line =~ /([0-9a-f]{2})/mcg) {
push(@data, hex($1));
}
}
}
close(PACKET);
print "Loaded ". ($#data + 1) ." bytes.\n";
# fill in struct
my $offset = 0;
foreach my $i (0..$#struct) {
my $type = $struct[$i]{'type'};
my $name = $struct[$i]{'name'};
my $alen = 0;
my $size = 0;
if ($name =~ /(\S+)\[([0-9]+)\]/) {
$name = $1;
$alen = $2 - 1;
}
if ($alen > 0) {
printf("%04d: %s\t%s[%d]: ", $offset, $type, $name, $alen + 1);
} else {
printf("%04d: %s\t%s: ", $offset, $type, $name);
}
if ($type eq "uint8_t") {
$size = 1;
foreach my $j (0..$alen) {
print unpack("C", pack("C", $data[$offset + $j * $size])) ." ";
}
} elsif ($type eq "uint16_t") {
$size = 2;
foreach my $j (0..$alen) {
print unpack("S", pack("CC", $data[$offset + $j * $size], $data[$offset + 1 + $j * $size])) ." ";
}
} elsif ($type eq "uint32_t") {
if ($name eq "disciplines[MAX_DISCIPLINES]") {
$alen = 50 - 1;
$size = 4;
} else {
$size = 4;
foreach my $j (0..$alen) {
print unpack("L", pack("CCCC", $data[$offset + $j * $size], $data[$offset + 1 + $j * $size],
$data[$offset + 2 + $j * $size], $data[$offset + 3 + $j * $size])) ." ";
}
}
} elsif ($type eq "int8_t") {
$size = 1;
foreach my $j (0..$alen) {
print unpack("c", pack("C", $data[$offset + $j * $size])) ." ";
}
} elsif ($type eq "int16_t") {
$size = 2;
foreach my $j (0..$alen) {
print unpack("s", pack("CC", $data[$offset + $j * $size], $data[$offset + 1 + $j * $size])) ." ";
}
} elsif ($type eq "int32_t") {
$size = 4;
foreach my $j (0..$alen) {
print unpack("l", pack("CCCC", $data[$offset + $j * $size], $data[$offset + 1 + $j * $size],
$data[$offset + 2 + $j * $size], $data[$offset + 3 + $j * $size])) ." ";
}
} elsif ($type eq "float") {
$size = 4;
foreach my $j (0..$alen) {
my $num = pack("CCCC", $data[$offset + 0], $data[$offset + 1],
$data[$offset + 2], $data[$offset + 3]);
print unpack("f", $num) ." ";
}
} elsif ($type eq "char") {
if ($name eq "groupMembers[MAX_GROUP_MEMBERS]") {
$alen = 6 - 1;
$size = 64;
} else {
foreach my $j (0..$alen) {
if ($data[$offset + $j] > 0x1f && $data[$offset + $j] < 0x80) {
printf("%c", $data[$offset+$j]);
} else {
print ".";
}
}
$size = 1;
}
} elsif ($type eq "Color_Struct") {
# B R G A
$size = 4;
} elsif ($type eq "AA_Array") {
# AA value
$alen = 120 - 1;
$size = 8;
} elsif ($type eq "spellBuff") {
# slotid level effect spellid padding duration unknown
$alen = 25 - 1;
$size = 16;
} elsif ($name eq "groupMembers") {
# Group members
$alen = 6 - 1;
$size = 64;
} elsif ($type eq "TributeStruct") {
# Group Members
$alen = 5 - 1;
$size = 8;
} elsif ($type eq "BandolierStruct") {
# Bandolier Structure
$alen = 4 - 1;
$size = 320;
} elsif ($type eq "InlineItem") {
# Potion Belt
$alen = 4 - 1;
$size = 72;
} else {
die "Unknown type: $type\n";
}
print "\n";
$offset += ($size * ($alen + 1));
}
printf("%04d: END\n", $offset);
I had to do some updating to it, but I'm not a perl programmer. It works but isn't done right.
How to use it:
Go to Network
Then to OpCode Monitor
OpCode Monitoring and click on it.
It will open a window asking what to monitor. Put in this 2fee:PlayerProfile:3:1 and hit ok.
Then in the OpCode Monitor menu check Log Monitored OpCode Matches and then go into Log Filename... in the same menu and specify a name for the file.
Log into everquest do something you want to find and zone and camp.
You will now have 2 Player Profiles in the file you named. You will be splitting the file and remove the extra text until you get down to the first part of the profile (down to the 000 part) copy the text between the 000 and the last line of the profile structure (currently 18480) and paste it into a new file. Do the same thing for the bottom profile. Now we get to run it through the script.
cp the first file to packet.txt and then type (make sure you can execute your perl script!) ./structvis.pl > filenametosaveto.txt
It will read the packet.txt and output it to the file you named. Now do it again for the other profile structure you did. Copy it to packet.txt, run structvis.pl and save it to a different file name. Now you can open both and compare the changes. It just makes reading it a little easier.
Re: Filling out charProfileStruct
0900 is a net opcode. Do you have raw turned on and maybe are just being confused by the raw vs decoded packets in the log file? The 0900 will come out as the raw then the appropriate decoded application level packet will come out as decoded.
Re: Filling out charProfileStruct
structvis.pl sounds like one of Ksmith's scripts.