more endpoints

This commit is contained in:
Devin Zuczek
2026-07-05 19:23:06 -04:00
parent 8f61adff1b
commit 7cf380a401
14 changed files with 179 additions and 33 deletions
+26
View File
@@ -11,6 +11,7 @@ import weeklyChallenge from '../static/weekly-challenge.json'
import { getAvatar, setAvatar } from './avatar-db'
import { validateAndGetAccountId } from './jwt'
import type { Avatar } from './avatar-db'
import type { Context } from 'hono'
import type { App } from './context'
@@ -43,6 +44,21 @@ function unauthorized(c: Context<App>) {
return c.body(null, 401)
}
/**
* Project a stored avatar into the public render subset returned by
* `GET /api/avatar/v2/:id` — the fields needed to draw another player's avatar
* (the full blob also holds `OutfitSelectionsV2`/`CustomAvatarItems`, which this
* view omits).
*/
function toAvatarV2Dto(avatar: Avatar) {
return {
OutfitSelections: avatar.OutfitSelections,
FaceFeatures: avatar.FaceFeatures,
SkinColor: avatar.SkinColor,
HairColor: avatar.HairColor,
}
}
/** RecNet currency types (the `CurrencyType` enum the client uses). */
const CurrencyType = {
Invalid: 0,
@@ -153,6 +169,16 @@ const app = new Hono<App>()
return c.json([])
})
// A player's avatar by account id, projected to the public render subset (used
// to draw other players' avatars). No auth — like the accounts `/account/:id`
// lookup. Falls back to the default outfit when the player hasn't saved one.
// Registered after the static `/api/avatar/v2/*` routes so `:id` can't shadow them.
.get('/api/avatar/v2/:id', async (c) => {
const accountId = Number.parseInt(c.req.param('id'), 10)
if (Number.isNaN(accountId)) return c.body(null, 400)
return c.json(toAvatarV2Dto((await getAvatar(c.env.DB, accountId)) ?? defaultAvatar))
})
// Unlocked equipment. Returns "[]" with no auth.
.get('/api/equipment/v2/getUnlocked', (c) => c.json([]))