|
| 1 | +export type ResolvedItemTexture = { |
| 2 | + texture: string; |
| 3 | + texture_pack?: string; |
| 4 | +}; |
| 5 | + |
| 6 | +const resolutionCache = new Map<string, Promise<ResolvedItemTexture>>(); |
| 7 | + |
| 8 | +function enabledPacksCookie(): string { |
| 9 | + if (typeof document === "undefined") return ""; |
| 10 | + const cookie = document.cookie |
| 11 | + .split(";") |
| 12 | + .map((part) => part.trim()) |
| 13 | + .find((part) => part.startsWith("enabledPacks=")); |
| 14 | + const value = cookie?.slice("enabledPacks=".length) ?? ""; |
| 15 | + try { |
| 16 | + return decodeURIComponent(value); |
| 17 | + } catch { |
| 18 | + return value; |
| 19 | + } |
| 20 | +} |
| 21 | + |
| 22 | +function resolverUrl(textureUrl: string, enabledPacks: string): string | null { |
| 23 | + const url = new URL(textureUrl, window.location.origin); |
| 24 | + const match = url.pathname.match(/^(.*\/api\/item\/)([^/]+)$/); |
| 25 | + if (!match) return null; |
| 26 | + url.pathname = `${match[1]}${match[2]}/resolve`; |
| 27 | + if (enabledPacks) url.searchParams.set("enabledPacks", enabledPacks); |
| 28 | + return url.toString(); |
| 29 | +} |
| 30 | + |
| 31 | +export function resolveItemTexture(textureUrl: string): Promise<ResolvedItemTexture> { |
| 32 | + const enabledPacks = enabledPacksCookie(); |
| 33 | + const cacheKey = `${textureUrl}|${enabledPacks}`; |
| 34 | + const cached = resolutionCache.get(cacheKey); |
| 35 | + if (cached) return cached; |
| 36 | + |
| 37 | + const url = resolverUrl(textureUrl, enabledPacks); |
| 38 | + if (!url) return Promise.resolve({ texture: textureUrl }); |
| 39 | + |
| 40 | + const resolution = fetch(url) |
| 41 | + .then(async (response) => { |
| 42 | + if (!response.ok) throw new Error(`Failed to resolve item texture: ${response.status}`); |
| 43 | + return (await response.json()) as ResolvedItemTexture; |
| 44 | + }) |
| 45 | + .catch(() => ({ texture: textureUrl })); |
| 46 | + |
| 47 | + resolutionCache.set(cacheKey, resolution); |
| 48 | + return resolution; |
| 49 | +} |
0 commit comments