Legacy accounts can carry a malformed stored look — the old register default
`hr-100-.hd-180-1...` has an empty colour slot — which the imager rejects with
400 "Invalid figure format", so the avatar renders broken everywhere the look
appears. Normalise the figure in the shared URL builder (`getAvatarUrl`, used by
every avatar on the site): an unrenderable look becomes `DEFAULT_AVATAR_FIGURE`
while the proxy route keeps rejecting malformed input with 400.
The rule set and default now live in one client-safe module
(`src/lib/avatar-figure.ts`), shared by the URL builder and the server parser.
A fallback render drops the requested effect and is only a degraded
stand-in, so writing it to the 30 day disk cache kept serving the worse
image long after the local renderer recovered. Cache primary renders only
and let the next request pick up the real render.
Effect renders need a little over 4s, which the 4s primary timeout cut off,
so every avatar with the default effect fell through to an unreachable
public fallback and rendered as a placeholder. Raise the primary budget
above the observed render cost and shorten the fallback budget.
Also stop the proxy from stamping no-store over the avatar and media
responses, so browsers keep the long-lived Cache-Control the route already
sends, and recreate the imaging cache directories with the container user
on every deploy, since root ownership made those cache writes fail
silently.
- Update imager to use epicnabbo.nl by default with effect=14 and img_format=apng
- Add figure string converter (old Habbo format -> epicnabbo.nl short format)
- Update avatarImageUrl to auto-convert figure strings
- Update online-users-widget to use new avatarImageUrl
- Add tests for imager and figure conversion
Add 22 test files covering imager, soundtracks, browser-headers, source-keys (figure/pet/effect), effect-source, plus catalog-translations, catalog-layouts, client-translation-files, translations-utils, and various admin/services/helpers modules. Total test count increases by 120+.
- Change default public imager URL from habbo.com to /imaging
- /imaging and /api/imaging/avatar now proxy from upstream (habbo.com) instead of redirecting
- Add resolveUpstreamBase() to separate public URL from upstream URL
- Update admin settings default and description