Decoding build template link — Guild Wars 2 Forums

Decoding build template link

Not really api related

So I'm trying to decode a build template link, however I am stuck on parsing out the skill info and cannot understand how I should proceed...
The link I am decoding is the following (Stripped the link start and end):
Which is a chrono template with only the heal skills selected (It was generated from gw2skills)
DQcAAAAAAAAjD24BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
Which gives the following bytes
13 7 0 0 0 0 0 0 35 15 110 1 0 0 . . . 0
The interesting bytes are 35 15 110 1, which correspond to the terrestial heal followed by the underwater, which is when I generated the link, Signet of ether (skill ID from Api is 21750) but no matter how I reorder those two bytes I am unable to get that number. 35 = (bin 100011), 15 (bin 1111), and 21750 (bin 101010011110110)
So what am I doing wrong?
I have read on the wiki and this confuses me as well:
After that, there are 20 bytes of skill information. The IDs here are provided in little-endian format and refer to internal skill palette IDs. In order, each 16-bit value represents the following skills: (https://wiki.guildwars2.com/wiki/Chat_link_format)
It mentions internal skill palette ID:s, are those different from the ID I get from the api?, and if so, how do I convert the internal skill palette id into the actual skill ID?
Or do I have to manually map these somehow?

Using the following simple python code:
s = base64.decodebytes(b'DQcAAAAAAAAjD24BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=')
struct.unpack('BBBBBBBB', s[0:8]), struct.unpack('<HHHHHHHHHHHHHHHHHH', s[8:])
doc for python struct the '<' character says to unpack using little-endian. and H stands for unsigned short, which is last time I checked 16 bits
I get the following when I run
0 = {tuple} : (13, 7, 0, 0, 0, 0, 0, 0) # Template id, profession id, empty trait lines
1 = {tuple} : (3875, 366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), terrestial heal, aquatic heal, ... acording to wiki...
Am I missing something obvious? 3875 != 21750

return 0xdeadbeaf

Comments

  • By the looks of it, you've got further than I have. Couldn't get any blob identified after Profession/spec1
    There is a separate Skill ID Pallet which skills relate to API ids, looking at what the developer community has shows this for 3875/21750:
    Signet of the Ether 21750 3875
    This should b in the API soon.

  • Cool, I knew I was missing something.

    And in order to unpack the profession spec, like the wiki states, the bits after the profession is 3 pairs of two bytes for each traitline.

    My example string DQcBHRc7KC4jD24BkxIAAIcSgwGAAYEBvAG8AQAAAAAAAAAAAAAAAAAAAAA=
    So for an example the following string of bytes (Not doing the entire unpacking here)
    Gives the following byte array
    (13, 7, 1, 29, 23, 59, 40, 46, 35, ..., 0) # the two bytes (1, 29) is the bytes describing what specialization and the trait choises made for that specialization.
    the 1 is pretty simple (binary 0b000 0001) - the specialization id (in this case defined in the api as mesmer duelling)
    the 29 is a little bit more tricky. It has the following binary value (0b0001 1101) Each pair of two bits (first unused (00)) (trait choise3 (01)) (trait choise2 (11)) (trait choise1 (01))
    The bits are extracted like the following pseudo code. bitfield extraction magic.

    extractBit(byte: number, int:number_of_bits, int: position) -> byte
    return ((1 << number_of_bits ) - 1) & (number >> (position -1 ))

    This allows me to extract each pair of two bits into a new byte, so I can store them like a traitline choise.
    This value will always correspond to a value between 0 and 3. Where 0 is not selected, 1 is top, 3 is bottom) just like the wiki states
    to extract choise3, we need to pick the 4th position (this case 5) since we negate position by 1
    choise3 = extractBit(dataArray[4], 2, 5), where dataArray is the base64 string decoded into a byte array.

    To pack the extracted bytes back into one single byte, there is just some bitshifting required.
    return (choise3 << 4) + (choise2 << 2) + choise1

    Hope this helps :)

    return 0xdeadbeaf

  • skoda.4619skoda.4619 Member ✭✭
    edited November 5, 2019

    that shaman has already done it for you :)

  • Never had a problem decoding the link, it's the fact there is a pallete id and a different skill id, however I can now see that the wiki has been updated with those pallete id's but they are not available from an endpoint... bleh.
    I'd like something like the following
    https://api.guildwars2.com/v2/skills?palleteId=id, to get the actual skill id(s) since there is the possibility that multiple results are returned... but that would have been too easy...
    Guess I have to fetch that wiki page now...

    return 0xdeadbeaf

©2010–2018 ArenaNet, LLC. All rights reserved. Guild Wars, Guild Wars 2, Heart of Thorns, Guild Wars 2: Path of Fire, ArenaNet, NCSOFT, the Interlocking NC Logo, and all associated logos and designs are trademarks or registered trademarks of NCSOFT Corporation. All other trademarks are the property of their respective owners.