The game bundle switched back to obfuscator.io's base64 string-array
encoding: items are now `{'type':0x0,'name':af(0x..),...}` with a rotated,
base64-encoded string table and a decoder `function b(c,d){c=c-OFF;const
e=a();...}`. The old `_build_string_decoder` entry regex didn't match this
shape and silently fell back to the identity decoder, so every item array
still contained undecoded `af(0x..)` calls, hex numbers and arithmetic and
failed to parse -> "Missing official item arrays: boots, chestplates, ...".
- Detect the new decoder shape and reimplement the base64 string decoder
(custom-alphabet base64 -> utf-8), with startup table rotation replicated
from the decoded parseInt checksum; derive the rotation alias from the
checksum expression (the local `ad`), not the global `af`.
- `_parse_object_array`: evaluate hex numbers, arithmetic and JS booleans via
a restricted ast evaluator; transform JS->Python on the still-encoded text
so string decoding can't be corrupted.
Dr…
Game Info: mob/armor art, live Rival render, spawn counts, revamped gallery UI
- Bake 28 mob + 96 armor models to PNG and load the images instead of 3D (image-config.json + SM_IMG_VER cache-bust); images stored via Git LFS
- The Rival (daily Asgard boss): rendered live in-browser with its real skin (whole body), face, armor, sword & shield via the game's setRivalBossSkin loadout, framed with tuned orientation, labeled "The Rival (username)". Hourly server-side Colyseus join (rival_lookup.js) + /rival-info endpoint; falls back to "?" when no live data.
- Mob detail stats: add spawn-count bar
- Gallery controls: large icon category tiles with item counts + custom styled sort dropdown (native select kept as source of truth)
- Catalog: carry speed / enemyBodyRadius / attackDistance so mob stats are available
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix gear type->name resolution for exact HP/power (0 deviation)
Armor slots (helmet/shoe) were resolved with a legacy +1 offset plus a
Solarflare override that both types 20 and 21 mapped to. Against the
current catalog (25 armor tiers: ...Stormborn(20), Solarflare(21),
Graveborn(22), Mourner's(23), Eternal(24)) this resolved sub-max armor
one tier too strong, so the displayed/computed maxHealth over-counted.
- Resolve all armor purely via the direct catalog type->name map
(armor arrays keep None at type 0, so type == index; no offset).
- Add SWORD_TYPE_NAMES/SHIELD_TYPE_NAMES + _sm_gear_type_name so
swords/shields also resolve by direct type map (offset=-1 only as a
no-catalog fallback); wire inventory/storage/clan-chest lookups too.
- Drop the stale _SM_ARMOUR_TYPE_OVERRIDES/OFFSETS/DIRECT_MIN_TYPE.
Verified live against 480 accounts (getPlayerInfo): 474 exact vs the
server's maxHealth (0 deviation), incl. 259/260 accounts below level
1000; 0 over-counts remain. The 6 non-matching accounts all have MORE
HP than their gear+level allows (HP…
sync_game_catalog.py now extracts ores from config image assets (raw <Name>Ore.png
+ smelted <Name>.png), so a newly added ore propagates automatically. Adds the
new Gold ore + images and an 'ores' section to the catalog. No combat impact.