Skip to content

Instantly share code, notes, and snippets.

@Talv
Created June 25, 2024 14:45
Show Gist options
  • Save Talv/b3612efe08db7d935eecf3405810d02e to your computer and use it in GitHub Desktop.
Save Talv/b3612efe08db7d935eecf3405810d02e to your computer and use it in GitHub Desktop.
sc2 webapi wtf portaits messed up

sc2 webapi wtf portaits messed up

What and where

Go to cache directory

cd "$HOME/.wine/drive_c/ProgramData/Blizzard Entertainment/Battle.net"

List files, uniq by extension, aggregate, sort to get a feeling what's stored here

fd --exclude='TMP' --exclude='Download' -t f -x bash -c 'filename="{/}" ; echo "${filename##*.}"' | sort -h | uniq -c | sort -h
    1 apps
    1 bsas
    1 index
    1 s1s
    1 s2sites
    2 d3s
    2 hero
    2 mtrz
    2 s2
    3 odin
    3 wows
    4 hss
    4 metr
    6 xml
    8 achv
    9 s2cs
   10 xp
   11 wmod
   16 s2hk
   28 pfty
   30 cata
   31 clfl
   54 s2ma
   73 wafl
  138 ldpt
  143 s2ql
  153 s2gs
  292 s2qh
  313 ldpl
  485 unlk
 2270 s2mi
 3355 s2mv
 8842 s2mh
23575 s2ml

Search what references 3d5fd8e83a8ecba8d8fc9e29804b95560e955288757783307aa7442e10ec10e5.wafl (.wafl are imagesheets).

❯ rg --count '3d5fd8e83a8ecba8d8fc9e29804b95560e955288757783307aa7442e10ec10e5'
Cache/4b/03/4b030e1275a3032ddcdb5d2e2e0a03822d2e6ac1665bf313be2536bd509347b8.ldpt:1
Cache/e5/1d/e51d65ceddf34c6b1565fccc80ef7f59ab3abc6836e8c4094dc4a71ee370ac9a.ldpt:1
Cache/b1/76/b176757c481534057213d37c36eea61682f3be66881446799d5a9e8082238b6e.ldpt:1
Cache/bc/27/bc274636b4bf50cabece550381471926e9b10ba3d0e343b94c3742c2a18873e8.ldpt:1
Cache/46/5b/465bb526bac9a075de0555e94f7da9bc5142a31d03ae265d452643fbf15e7768.ldpt:1
Cache/d9/3c/d93c4d86ee3c09063a7dbaef908d3af6b5c845bf84a0aa6c73cbca404bd3e809.ldpt:1
Cache/7f/df/7fdf6c235bdefcce8540c19ce56da2d9b85bf468985150298b4115f870386212.ldpt:1
Cache/7f/a8/7fa8aea42dc87adbf657db7485f9aabcec915adf3eeb7288cc585722564df90d.ldpt:1
Cache/f7/3f/f73ff6a6c389376b8d06738ffc59274428052c84137879b833dd51b022ab3a3f.ldpt:1
Cache/09/03/0903ee49f09cb12c24e68f9d7105dfc0788a10ba83ee8dd4d1fa1bdc8b9076c7.ldpt:1
Cache/35/c8/35c8b60236f720335df6f2cd8c68808bda229b5affb7b771b82861baf57aff2b.ldpt:1
Cache/ce/e9/cee92579d07844e053318432970f50c7440e7846fbc3fe8b597db7d74e025d2b.ldpt:1
Cache/d0/e4/d0e41ed50a551dc0ceaba34a74420cc0fd953a9ab4c1fa5e0dce02fc46a97652.ldpt:1
Cache/75/80/758072828bc6887effb4c22b5083b009ae3fa691646253eab078f6766f718885.ldpt:1
Cache/02/7a/027a0114963fbeddc94c62645c3a76f5ddbf4c898044126f1f080b7288efab22.ldpt:1
Cache/74/48/74487b58791c71fcef54f91d5369ecfae82e1633f5569be9ee506e51c4ed199d.ldpt:1
Cache/29/f9/29f911cc20eb848aa9a782cb4ebf69d623b9409402e804c7465f5f0bdd38d2c7.ldpt:1
Cache/87/b1/87b18daed048857b20b2925286c013880c054be75ecf24fd78e458164715ca1a.ldpt:1
Cache/8b/85/8b85e39d8043872da667d4f8fde68cc3fd3525660e988f6d3b46430d72e38b43.ldpt:1
Cache/ea/f3/eaf364697e7bc76505368f6f83d0b77c1f233251aa050af88d9b29416e41bf2b.ldpt:1
Cache/5e/6a/5e6a32b67ed4eb2633b8a5de9f90f3b87715313f1906e5c3a42a9b2e547196c4.ldpt:1
Cache/05/57/0557a9027944ddf5464039455582e8e43066649356b129425b702e37beb38cb8.ldpt:1
Cache/d6/a2/d6a2bf1d88c91f791592cda4677fd21bffdffaa2bd7724af105cf5bd56335c17.ldpt:1
Cache/47/fa/47fa94fe33e32729a3351da538fa2c40846a507cf2a21089d1696ccff60f5498.ldpt:1
Cache/ac/02/ac0257c31e657278167e73d23c9bf9676d82469b7e4702cc16a0f00f41288dd0.ldpt:1
Cache/63/20/6320cafb6fbfe496958df43cc30e5b799ace6db11f70a5f6c2d184d32d14d23d.ldpt:1
Cache/83/47/8347bdb45502b8ea84276de693201bf285a13a1ee61675a5ed4b27c5efb2c457.ldpt:1
Cache/3d/63/3d630e92e756ec4cea02b939ff0c80e6cbd83345e9b2c0af666697ec5890b731.ldpt:1
Cache/1f/f4/1ff48f82db5cb6013f651a018701434bab859b4a45f50d40104ffbf6502306e9.ldpt:1
Cache/fd/64/fd646e456427b2d4eccc67d032212f5fde6d35f05a7f4e4b94f4b2389143a63d.ldpt:1
Cache/5b/20/5b20e8a81bc3c86481ec38aeddbe8fc1fe3d846a7a4a55fbe490f791e5922b1d.ldpt:1
Cache/b0/56/b056f13abd70ed7c30e6d6dc37c22c68e0964b9165ce9c5e0a6ffc905ed77089.ldpt:1
Cache/f9/92/f9924f466908f223d96340a222e7be237436dded6b2f47708e34b9f65f6bf9f7.ldpt:1
Cache/6c/0d/6c0d61a20978736befedf9ee5f635adf6f2fabbac08e5541c3c44302c4ef29e0.ldpt:1

These seem to be json files.


Find a .ldpt from latest deployment / most recent

fd -e ldpt -t f -x stat -c '%y %s %n' {} | sort -h
... ___CUT__ ...
2021-11-26 02:23:10.232544073 +0100 203 ./Cache/c8/18/c818b7ca381230d1491ae207efe7e8258f77bbed43ee28d43d6294baddb1ebce.ldpt
2021-11-26 02:23:12.915852231 +0100 3201 ./Cache/33/14/331475223ca83586eb6d9deaec2c44c6be676c7b131362611cd8a0d410a093ef.ldpt
2021-11-26 02:23:14.049174928 +0100 2700 ./Cache/d9/3c/d93c4d86ee3c09063a7dbaef908d3af6b5c845bf84a0aa6c73cbca404bd3e809.ldpt
2021-11-26 02:23:14.209173426 +0100 5873 ./Cache/75/80/758072828bc6887effb4c22b5083b009ae3fa691646253eab078f6766f718885.ldpt
2023-07-15 03:13:14.461012814 +0200 3201 ./Cache/0a/5c/0a5c79eae5e9eb5ec69770c8e9154c8653e1800b24b89a110e7ab0a27f8ba924.ldpt
2023-07-15 03:13:14.554345295 +0200 5873 ./Cache/09/03/0903ee49f09cb12c24e68f9d7105dfc0788a10ba83ee8dd4d1fa1bdc8b9076c7.ldpt
2023-07-15 03:13:15.047674132 +0200 2867 ./Cache/7f/a8/7fa8aea42dc87adbf657db7485f9aabcec915adf3eeb7288cc585722564df90d.ldpt
2024-05-25 11:09:55.787072387 +0200 3201 ./Cache/38/a1/38a127f1567d768d8d8a1448d463b1ea3013147942d7bf4328f84fabf7c54dcf.ldpt
2024-05-25 11:09:55.853738713 +0200 2867 ./Cache/b1/76/b176757c481534057213d37c36eea61682f3be66881446799d5a9e8082238b6e.ldpt
2024-05-25 11:09:56.027071160 +0200 6040 ./Cache/05/57/0557a9027944ddf5464039455582e8e43066649356b129425b702e37beb38cb8.ldpt
2024-06-24 07:27:22.798818496 +0200 6040 ./Cache/87/b1/87b18daed048857b20b2925286c013880c054be75ecf24fd78e458164715ca1a.ldpt
2024-06-24 07:27:23.088815505 +0200 2867 ./Cache/d6/a2/d6a2bf1d88c91f791592cda4677fd21bffdffaa2bd7724af105cf5bd56335c17.ldpt
  • 2 or 3 ldpt in latest deployments
  • between 2021 and 2023 stuff incresed in size - more imagesheets were added to json?

LDPT

Example

jq <Cache/d6/a2/d6a2bf1d88c91f791592cda4677fd21bffdffaa2bd7724af105cf5bd56335c17.ldpt
{
  "m_count": 17,
  "m_usage": 1818521716
}
{
  "m_cacheHandle": "7761666c00005553cdb695cabc67577f17f591100ab262cac351e64a33a81829eb432ea0d99c4a3e"
}
{
  "m_textureFileIndex": 0,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553d5f4e40be09f34aaaff966d363e6d86e4983585a388c803f38ceb34d6161b3f0"
}
{
  "m_textureFileIndex": 1,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553b13701d87ae44ee31c9285418923688b38c8249a0c0402e7be849896c2e53305"
}
{
  "m_textureFileIndex": 2,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c000055534a4361d0ffb2d07bf0bd59e85597680155763229867afe272f73f7404d7a4191"
}
{
  "m_textureFileIndex": 3,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c0000555394de73ac09f24609491cc0d52c3c1a01f2ea8a09c0e5159cea23e5fa468d952f"
}
{
  "m_textureFileIndex": 4,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553464d96700a080a9a0d623d0da03b74df51b387983df21d7576d9e30d5f212e42"
}
{
  "m_textureFileIndex": 5,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c0000555382977fb0a8462ae8f494cdada5f99690d546e9b1f1c2e187d6c1b82e01d9d9b7"
}
{
  "m_textureFileIndex": 6,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553f7ed305c934551870aa621eefbf2ef50d9d454e577268f9256082d5ff8c5ac3b"
}
{
  "m_textureFileIndex": 7,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553401c39a44296256b053531edd6ff30998a429627612911917512ee62c349f0c9"
}
{
  "m_textureFileIndex": 8,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c0000555376c951d0d76d3a619af373bd92f8944bb8f223651bebe62b8ccbb2f01e047bd3"
}
{
  "m_textureFileIndex": 9,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c000055533d5fd8e83a8ecba8d8fc9e29804b95560e955288757783307aa7442e10ec10e5"
}
{
  "m_textureFileIndex": 10,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553f7421051d9e39d912906ad58800f4e5f3ed415395edcb01c0cadf80f1b59cb5a"
}
{
  "m_textureFileIndex": 11,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553ea0e6924e5bc850e1ad5c40ea0769461610bd8d395919f3229dc88a209c6615a"
}
{
  "m_textureFileIndex": 12,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c0000555327afd2c4c5b34271db8e1fdb6e8c7df89bbd235f76f9ddaf86364a79dd90d2e9"
}
{
  "m_textureFileIndex": 13,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c0000555337ac3e2ac83dd3d91fa70027899fee965944a25c08a8da973d77dca1e390c705"
}
{
  "m_textureFileIndex": 14,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553fb38a55b94e364fdbc0c6a7311437fa4abc01e780b8f743adad02ae09b7211cc"
}
{
  "m_textureFileIndex": 15,
  "m_textureCols": 6,
  "m_textureRows": 6
}
{
  "m_cacheHandle": "7761666c00005553bfb1735c47fa70a300c35cd9e09db60986fc1881efdd183ee7466b1a99b46204"
}
{
  "m_textureFileIndex": 16,
  "m_textureCols": 6,
  "m_textureRows": 6
}

What is what

Obvious:

  • m_count 17 entries / imagesheets
  • m_textureFileIndex 0 based index

m_usage

"m_usage": 1818521716

hex(1818521716)
# '0x6c647074'

struct.unpack('4s', b'\x6c\x64\x70\x74')[0]
# b'ldpt'

m_cacheHandle:

"m_cacheHandle": "7761666c000055533d5fd8e83a8ecba8d8fc9e29804b95560e955288757783307aa7442e10ec10e5"

a = 0x7761666c # 4b magic
b = 0x00005553 # 4b magic
c = '3d5fd8e83a8ecba8d8fc9e29804b95560e955288757783307aa7442e10ec10e5' # 64b - sha256

# -- a
struct.unpack('4s', b'\x77\x61\x66\x6c')[0]
# b'wafl

# -- b
struct.unpack('4s', b'\x00\x00\x55\x53')[0]
# b'\x00\x00US

# -- c
# it's sha256(resourceContent)

static.starcraft2.com/starport broken

  • bda9a860-ca36-11ec-b5ea-4bed4e205979 current deployment of static images?
  • d0e7c831-18ab-4cd6-adc7-9d4a28f49ec7 previous?
❯ http -h 'https://static.starcraft2.com/starport/bda9a860-ca36-11ec-b5ea-4bed4e205979/portraits/9-152-grid.jpg' | rg -i last
Last-Modified: Mon, 02 May 2022 16:44:31 GMT
❯ http -b "https://us.api.blizzard.com/sc2/metadata/profile/1/1/258901" "Authorization:Bearer $BATTLE_TOKEN"
{
    "avatarUrl": "https://static.starcraft2.com/starport/bda9a860-ca36-11ec-b5ea-4bed4e205979/portraits/12-24.jpg",
    "name": "blizzmaps",
    "profileId": "258901",
    "profileUrl": "https://starcraft2.blizzard.com/profile/1/1/258901",
    "realmId": 1,
    "regionId": 1
}

Stuff broken:

crop from wafl

Retrieve and crop portraits from s2 depot basing on .ldpt spec.

./s2-ldpt-dl.sh d6a2bf1d88c91f791592cda4677fd21bffdffaa2bd7724af105cf5bd56335c17 ./outdir
#!/usr/bin/env bash
set -eu
function usage {
>&2 cat << EOF
USAGE:
$(basename "$0") <LDPT_HASH> [OUT_DIR]
DESCRIPTION:
retrieve and crop portraits from s2 depot basing on .ldpt spec
EOF
exit 99
}
if [ $# -lt 1 ]; then
usage;
fi
MY_TMPDIR=$(mktemp -d)
MY_OUT_DIR=${2:-$(mktemp --tmpdir="$PWD" -d)}
DEPOT_URL="https://us-s2-depot.classic.blizzard.com"
function cleanup {
rm -r "$MY_TMPDIR"
}
trap cleanup EXIT
if [ ! -d "$MY_OUT_DIR" ]; then
mkdir "$MY_OUT_DIR"
fi
LDPT_FILENAME="$MY_TMPDIR/$1.ldpt"
wget -q -O "$LDPT_FILENAME" "$DEPOT_URL/$1.ldpt"
LDPT_SHEET_COUNT=$(cat "$LDPT_FILENAME" | jq --slurp -r '.[0].m_count')
>&2 echo "found ${LDPT_SHEET_COUNT} entries in $(basename "$LDPT_FILENAME")"
for (( LDPT_INDEX = 0 ; LDPT_INDEX < LDPT_SHEET_COUNT; LDPT_INDEX++ )); do
# >&2 echo "-- $LDPT_INDEX"
LDPT_ENTRY_HANDLE=$(cat "$LDPT_FILENAME" | jq --slurp -r ".[$(($LDPT_INDEX * 2 + 1))].m_cacheHandle")
LDPT_ENTRY_INDEX=$(cat "$LDPT_FILENAME" | jq --slurp -r ".[$(($LDPT_INDEX * 2 + 2))].m_textureFileIndex")
LDPT_ENTRY_FILENAME="$MY_TMPDIR/${LDPT_ENTRY_HANDLE:16}.wafl"
>&2 echo "processing ${LDPT_ENTRY_INDEX}-${LDPT_ENTRY_HANDLE:16} .."
# dl wafl
wget -q -O "$LDPT_ENTRY_FILENAME" "$DEPOT_URL/${LDPT_ENTRY_HANDLE:16}.wafl"
# cut into pieces
magick "$LDPT_ENTRY_FILENAME" -crop 152x152 "$MY_OUT_DIR/$LDPT_ENTRY_INDEX.png"
done
>&2 echo "done: $MY_OUT_DIR"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment