| Section Leader Gold |
 |
 |
Joined: Fri Sep 20, 2002 2:38 am Location: ٩(͡๏̯͡๏)۶0x3CC4E7C0 CHATSUBO
|
Packet 0x9c Breakdown by Herzog_Zwei ------------------------------------
Packet 0x9c general layout: --------------------------- Bit(0:7) Packet message (0x9c) Bit(8:15) Action bit(16:23) Item type bit(24:31) Valid data size in bytes (0x16-0xFF?) bit(32:63) Item ID: bit(64:95) Flags bit(96:105) Unknown bit(106:108) Position type bit(109:125) X-position bit(126:141) Y-position bit(142:173) Itemcode bit(174:176) Unknown bit(177:183) Magic level (?) bit(184:187) Item quality bit(188:190) Item design (For rings/amus) bit(191:199) Unknown bit(200:+) Prefix/suffix/modifiers/quantities etc...
Item type: ---------- 0x00 Helm 0x01 Armor 0x05 Weapon 0x07 Shield 0x10 Most other items
Item quality: ------------- 0x0 Most other items 0x1 Damaged/cracked 0x2 normal 0x3 superior 0x4 magic 0x5 set 0x6 rare 0x7 unique 0x09 Gem
Action: ------- 0x00 New item ID on ground 0x01 Pick up to cursor 0x02 Drop from cursor to ground 0x03 Old item ID on ground 0x04 Place in backpack 0x0E Place in belt
Flags: ------ bit(64) Sockets are full (1=yes/0=no) Bit(6 Item identified (1=yes/0=no) Bit(69) Item is ethereal (1=yes/0=no) Bit(75) Item has sockets (1=yes/0=no) Bit(77) Item just generated (1=yes/0=no) Bit(80) Item is an ear (1=yes/0=no) If yes, see structure for ear! Bit(87) Item is magic or higher (0=yes/1=no)
Unknown origin: --------------------------------------------- Detailed 9C Item info WARNING: Some of this information could be wrong. In particular, there are several of the values that I have taken from other sources and not checked myself. I have tried not to include too much information that I have not yet verified.
* PACKET MESSAGE ID -- byte: 00, bits: 000-007 9C for item packets, 9D for items char is wearing note that the structure below reflects 9C packets only! 9D packets have 5 extra bytes inserted at byte 10!
* ORIGIN -- byte: 01, bits: 008-015 for 9C packets 00 = new item on ground 01 = pick up to cursor 02 = drop from cursor to ground 03 = old item on ground 04 = inventory (including stash) 0B = store 0C = removed from store (e.g., when you buy an item) 0E = belt
* PACKET LENGTH -- byte: 02, bits: 016-023 number of bytes in the packet
* ITEM CATEGORY -- byte: 03, bits: 024-031 00 = helm 01 = armor 05 = weapon (including xbows) 06 = bow (excluding xbows) 07 = shield 10 = misc
* ITEM ID -- bytes: 04-07, bits: 032-063 unique ID within a game (not persisted!) these IDs are assigned sequentially within a game
* FLAGS -- bytes: 08-11, bits: 064-095 not sure what all of these are... special includes quest items (e.g., Mephisto's Soulstone), but also seems to include potions in belt... isSocketed = (flags & 0x00080000) > 0 isEtheral = (flags & 0x00004000) > 0 isSpecial = (flags & 0x0000FF00) == 0x0000C000
* UNKNOWN??? -- bytes: 12-13, bits: 096-111
* X/Y ITEM POSITION -- byte: 14, bits: 112-119 this can be the position in the inventory, stash, store, etc
* ITEM LOCATION -- byte: 15, bits: 124-127 (low nybble) if in store (ORIGIN = 0B) 02 = armor tab 04 = weap1 tab 06 = weap2 tab 08 = misc tab if in inventory/stash (ORIGIN = 04) 00 = belt 02 = inventory 08 = Horadric Cube 0A = stash
* ITEM CODE -- bytes: 15-18, bits 120-147 (24 bits total) this code is a 3 character alpha-numeric code (stored as ASCII) this code can be found in the "code" column of following MPQ files: "Weapons.txt", "Armor.txt", and "Misc.txt"
* UNKNOWN??? -- bytes: 18-19, bits: 148-159
* FLAGS2 -- bytes: 20-21, bits: 160-171 not sure what all of these are...
isMagic = (flags2 & 0x000F) == 0x0001; isJwlChrm = (flags2 & 0xF000) == 0x2000; (jewels, charms) isInferior = (flags2 & 0xF000) == 0x4000; (*** see special encoding below) isNormal = (flags2 & 0xF000) == 0x8000; isSuperior = (flags2 & 0xF000) == 0xC000; (*** see special encoding below)
isUnique = (flags2 & 0xF000) == 0xE001; isRare = (flags2 & 0xF001) == 0xA001; isMisc = (flags2 & 0xF001) == 0xA000; (includes items like keys, arrows, etc)
!!! WARNING: From here on out, the location of bits in the packet !!! can vary (e.g., inferior will add 3 bits for the quality identifier). !!! Hence all parsing must be done relative to where we last left off. !!! This parsing starts at byte 21, bit 4 (high nybble of byte 21).
* INFERIOR ITEM -- 3 bits these 3 bits are only present if the item is inferior (see isInferior FLAGS2) 00 = crude 01 = cracked 02 = damaged 03 = low quality
==================================================
================== ARMORS --------------------------------------------------------------------
I have not looked closely at armors since I have been focusing on weapons, but there is a 10 bit offset before the DURABILITY, even for normal armors. Not sure what this is right now.
==================================================
================== NORMAL ITEM --------------------------------------------------------------------
* DURABILITY MAX -- 8 bits
* DURABILITY CURRENT - 8 bits
* NUMBER OF SOCKETS -- 4 bits these 4 bits are only present if the item is socketed (see isSocketed FLAGS)
==================================================
================== SUPERIOR ITEM --------------------------------------------------------------------
* SUPERIOR TYPE -- 3 bits 00 = AR 01 = Max Dmg 02 = AC 03 = AR + Max Dmg 04 = Durability 05 = Durability + AR 06 = Durability + Max Dmg 07 = Durability + AC
* DURABILITY MAX -- 8 bits
* DURABILITY CURRENT - 8 bits
* NUMBER OF SOCKETS -- 4 bits these 4 bits are only present if the item is socketed (see isSocketed FLAGS)
* SUPERIOR PARAMS -- ??? bits the superior parameters are then encoded have not looked at these closely yet the values for AR (10 bits) + Max Dmg (7 bits) are not offset, but Durability (7 bits) looks like it is offset by 20d
==================================================
================== MAGIC ITEM --------------------------------------------------------------------
* MAGIC PREFIX -- 11 bits this prefix is an ID that comes from the "MagicPrefix.txt" MPQ file this id is not actually in the MPQ itself, but is the row number (which is calculated including the blank lines)
* MAGIC SUFFIX -- 11 bits this prefix is an ID that comes from the "MagicSuffix.txt" MPQ file this id is not actually in the MPQ itself, but is the row number (which is calculated including the blank lines)
* DURABILITY MAX -- 8 bits
* DURABILITY CURRENT - 8 bits
* ITEM MODS -- (varies) see next section
==================================================
================== ITEM MODS --------------------------------------------------------------------
Ok, here is where things get tricky! There are 2 different encoding schemes for the mods themselves (and the "NEw" scheme has a wrinkle in it as well).
To determine which encoding scheme is used, you must look at the affix information in the MPQ file. The two things that seem to matter are the "version" column (0, 1, or 100) and the number of stats that a given mod has (e.g., "of Frost" has 3 stats: cold-min, cold-max, and cold-len).
There is another MPQ table that comes into play as well, the "ItemStatCost.txt" file. This file is important because it contains the number of bits that a stat parameter takes (saveBits), and its offset (saveAdd) from 0 (since not all stats are 0-based; e.g., STATS_ITEM_UNDEADDAMAGE_PERCENT is offset by 20).
The Affix tables and ItemStatCost tables can be correlated using the "Properties.txt" MPQ file. This file contains a "code" that is found in the Affix tables (mod1code, mod2code, mod3code). This code jas a corresponding "ModFuncOffset" that comes from the ItemStatCost table. WARNING: The "ModFuncOffsets" that do not start with "STATS_" must be prefixed with this string in order to find a match!
* PREFIX RULES - Always use the "NEW" encoding scheme (see below).
* SUFFIX RULES - If the version is 0 or 1, *and* the affix mod has more than 1 parameter use the "OLD" encoding scheme (see below). - Otherwise, use the "NEW" encoding scheme (see below).
I have no idea why suffix parsing would be different, but I had to use this technique in order to properly parse suffix mods with 3 parameters (e.g., of Frost). Note that the Sharp prefix mod has 2 parameters and parses differently. Originally, I thought that these two affixes would have different versions but they did not; both had a version of 1. So perhaps my determination for how to parse the affix is ill founed.
==================================================
================== "OLD" ITEM MODS --------------------------------------------------------------------
"OLD" item mods have an stat id that can be completely ignored. They have 0-3 parameters. This number is determined by the affix (from the mod codes in the MPQ file).
* STAT ID -- 9 bits this is the STAT ID from the "ItemStatCost.txt" MPQ file WARNING: there is only 1 stat id even though there can be multiple mods! Furthermore, this stat id is ignored since we already know the stats from the prefix/suffix mod codes!
* PARAMETER value -- (optional and number of bits varies) the number of bits that make up the parameter value is determined by the "saveBits" column of the stat note that this value may be offset by the "saveAdd" column WARNING: that stat id corresponding to this stat must be looked up from the mod code pf the affix since only the first parameter has a stat id! Yes this is really stupid, but don't blame me!
==================================================
================== "NEW" ITEM MODS --------------------------------------------------------------------
"NEW" item mods have 0 or 1 parameter associated with each stat.
* STAT ID -- 9 bits this is the STAT ID from the "ItemStatCost.txt" MPQ file
* PARAMETER value -- (optional and number of bits varies) the number of bits that make up the parameter value is determined by the "saveBits" column of the stat note that this value may be offset by the "saveAdd" column
* 2nd PARAMETER value -- (optional, but ignored if present) some stats have 2 parameter values! in such a case, the stat will have its "Target Stat" (from the "ItemStatCost.txt" MPQ file) be other than "-1". This value corresponds to the stat id of the second parameter. This second parameter looks like it can be ignored (at least for the purposes of determining the mods of an item). E.g., the "Jagged" maps to STATS_ITEM_MAXDAMAGE_PERCENT. This stat has a "Target Stat" of 22 (STATS_MAXDAMAGE). In this case, both the first and second parameter are identical.
* = seems to be true but not 100% sure
Items are usually encoded along the lines of: origin, id, [player info,] flags, location, item code, item info (sockets, quality, image, etc), item quality data, runeword data, personalization data, more item info (defense, durability, sockets, etc), mods.
The exceptions to the scheme seems to be: 1) Gambled items should stop decoding after reading the item code 2) Ears are decoded differently and is already known
After reading the item code, for items with the misc bit not set in the flags: 1) Read in 3 bits. If it is socketed, that is the total number of sockets 2) Read in 7 bits (unknown) 3) Read in 4 bits for the item quality 4) Read in 1 bit. This tells you if the item has an image. 4a) If it has an image, read in 4 bits for the image number. 4b) If it does not have an image, read in 1 bit. This tells you if it has class specific data. If it does, read in 11 bits to get that info.
The above should get you synced up to read in data about the quality.
The 2nd section on item info is decodes as such: 1) If it comes from the armor file, read in 10 bits and subtract 10 to get the base defense. 2) If the item does not come from the misc item file (*), read in 8 bits for the base durability. If this is 0, it is indestructible. If it is not 0, read in 8 bits to get the current durability. Bows and throwing items have durability and WILL break if durability becomes 0 (try it out with ethereal javelins if you want). 3) If it is socketed, read 4 bits for the number of used sockets 4) If it is a set item, read in 5 bits to get the number of set bonuses associated with the set. 5) If it is stackable (from mpq file (*)): 5a) If it is useable (from mpq file) (*), read in 5 bits (I didn't check the value to find out what it might be) 5b) Read in 9 bits to get the quantity
4 and 5 might be reversed, but I don't think there are any set stackable items to test it with. This should get you synced up to start reading in the mods.
Mods are decoded along the lines of: 1) Read stat 1a) If stat is 0x1ff, go to 3. If not, read info related to stat 2) Go to 1. 3) If it is a set, repeat from 1 for the count indicated in the set bonuses field
That should get you to the end of the packet with less than 8 bits left in the packet.
Special stats: STATS_ITEM_MAXDAMAGE_PERCENT (and probably STATS_ITEM_MINDAMAGE_PERCENT): encoded in 2 pairs of length "SaveBits". Probably for left/ right hand, primary/secondary weapon or something along those lines
Replenish stats: rate is given as 1 per 100/value seconds
Cold/poison duration: duration is given as value * 0.04 (*) seconds
Posion damage: rate is given as value / 10.25 (*) damage per second
STATS_FIREMINDAM, STATS_LIGHTMINDAM, STATS_MAGICMINDAM, STATS_COLDMINDAM, STATS_COLDMAXDAM, STATS_POISONMINDAM, STATS_POISONMAXDAM: require reading looping back to 1a using stat + 1 as the current stat. I'm guessing this was done to save 9 bits each stat.
Per level: ((level * value) >> PerLevelShift) - SaveAdd (better done with floats instead of integers so use division instead of shifts)
By time: "max value" : "min value" : "best time" (x : 10 : 2). Max/min values subtracted by 0x100. Times: 0 = daytime, 1 = dusk, 2 = nighttime, 3 = dawn. Best time = max value, worst time = min value, others = average of max + min
+Skill tab: encoded as "# of skills" : "skill tab" (x : 5) (x = remaining bits, calculated as SaveBits - used up bits (in this case, 5))
+Skill: encoded as "# of skills" : "skill" (x : 9)
+Skill on attack/striking/struck: "% chance" : "skill level" : "skill" (x : 5 : 9)
+Charges: "total charges" : "current charges" : "skill level" : "skill" (x : 8 : 5 : 9)
_________________ [23:04] <~Cthanukah> DM is my khaleesi. || [01:28:49] <~Cthanukah> They put their dicks in butts
DM, the DECEPTION - Lies within a lie within a lie. “Just a second-rate Snarg living in a third-rate Blizzhackers.”  
Last edited by Dark_Mage- on Sun Mar 30, 2008 10:19 pm, edited 2 times in total.
|
|