You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
导入回归收口:封面失败状态改由 React state 驱动(重复搜索同一张卡不再永久隐藏后来可加载的封面);刷新 toast 移出导入 try(导入成功后不再误报红色错误);路径在任何抓取前先拒绝 ./.. 段;NSFW 门控再加一层标签匹配,按路径直接导入也无法绕过。(be09116)
Changelog
Added
Character Market: a new top-level Market section (Characters tab) — search the open character-tavern catalog and add a card to your deck in one click. The backend is a thin, on-demand proxy to its public JSON API (the hub runs on your own machine — no hosted relay); import maps a foreign V2/V3 ST card onto our card shape and writes it into the deck. Import is tolerant of what a foreign card lacks — no aspiration → omitted, no theme color → a deterministic per-card color (never a primary-less theme, which used to crash the deck), {{char}}/{{user}} macros left intact, the lorebook (character_book) passed through to the embedded world; NSFW is gated and a failure surfaces a real error, never a blank. (8d8ef67)
The cover follows the card on import: importing a market card now actually carries its image into the deck — the web client fetches the cover bytes after import and uploads them (card.asset_save keyvisual + avatar) for a local, offline-safe copy (wins when present); if that's CORS-blocked, the stored cover URL still renders browser-side via the card-face <img>. The cover follows the card whenever you could see it in the market. (31270f8)
Fixes
Graceful card covers: character-tavern's image CDN hotlink-protects non-browser fetches (HTTP 403), so the hub can't download covers server-side — the grid thumbnails are browser-loaded <img> that degrade to a clean monogram on error, so the market never looks broken; the cover URL is preserved on the imported card for browser-side display. The server-side attach stays best-effort (browser-like headers + real image-format detection) and now logs WHY it skipped instead of failing silently. (38e27c1)
URL-encode card paths: a card path can contain spaces / unicode (e.g. bmboster/Yae Miko), which we passed unencoded into URLs (urllib would choke) — now each path segment is percent-encoded while the raw path stays as the stored identity. (9963d1f)
Import regressions closed: cover-load failure is now driven by React state (re-searching the same card no longer leaves a now-loadable cover hidden forever); the refresh toast moved out of the import try (no red error after a successful import); paths reject ./.. segments before any fetch; the NSFW gate is backed by a tag match so a direct import-by-path can't slip past the search-side exclude. (be09116)