/** * Centralized config for bundled GUI textures. Uses maps from generated localTextures. * Supports overrides via short paths (e.g. "gui/sprites/container/anvil/text_field_disabled.png"), * remote fallback toggle, and cache invalidation after overrides. * * Version prefix (e.g. "1.21.11/textures/") in bundled keys exists only for the texture * import generator — setOverride accepts short paths without it. */ import { bundledTextureMap, allTexturePaths, allContainerPaths, } from './generated/localTextures' import type { TextureConfig } from './context/TextureContext' import { clearTextureCache } from './cache/textureCache' const MC_ASSETS_REMOTE = 'https://raw.githubusercontent.com/zardoy/mc-assets/refs/heads/gh-pages' /** Normalize path to short form: "gui/..." (strip version prefix if present). */ function toShortPath(path: string): string { const m = path.match(/^\d[\d.]+\/textures\/(.+)$/) return m ? m[1] : path } /** Default version for building mc-assets URLs when path is short. */ const DEFAULT_VERSION = '1.21.11' export interface BundledTexturesConfigOptions { /** When true (default), unknown paths fall back to remote mc-assets URL. */ remoteFallback?: boolean /** Override the bundled texture map (e.g. for custom builds). */ bundledTextureMap?: Record } export interface BundledTexturesConfig extends Pick { /** * Override a texture. Pass short path (e.g. "gui/sprites/container/anvil/text_field_disabled.png") * and image URL. Version prefix is only for the import generator — not needed here. */ setOverride(path: string, image: string): void /** Remove all texture overrides. */ clearOverrides(): void /** Enable or disable remote fallback for unknown paths. */ setRemoteFallback(enabled: boolean): void /** * Invalidate cached textures so slots re-request them. Call after multiple setOverride * calls when you want UI to immediately reflect new overrides. */ resetRenderedSlots(): void } /** * Build a reverse map: shortPath -> bundled URL. */ function buildShortPathToBundled( bundled: Record, ): Map { const map = new Map() for (const [key, url] of Object.entries(bundled)) { if (!url) continue const short = toShortPath(key) if (!map.has(short)) map.set(short, url) } return map } /** * Create a bundled textures config with overrides and optional remote fallback. * Pass the returned config to . */ export function createBundledTexturesConfig( options?: BundledTexturesConfigOptions, ): BundledTexturesConfig { let remoteFallbackEnabled = options?.remoteFallback ?? true const overrides = new Map() const bundled = options?.bundledTextureMap ?? bundledTextureMap const shortToBundled = buildShortPathToBundled(bundled) function getGuiTextureUrl(path: string): string { const shortPath = toShortPath(path) const override = overrides.get(shortPath) if (override) return override const bundledUrl = bundled[path] ?? shortToBundled.get(shortPath) if (bundledUrl) return bundledUrl if ( remoteFallbackEnabled && path.endsWith('.png') && path.includes('/textures/') ) { return `${MC_ASSETS_REMOTE}/${path}` } if (remoteFallbackEnabled && shortPath.endsWith('.png')) { const versioned = `${DEFAULT_VERSION}/textures/${shortPath}` return `${MC_ASSETS_REMOTE}/${versioned}` } return path } return { getGuiTextureUrl, setOverride(path: string, image: string) { overrides.set(toShortPath(path), image) }, clearOverrides() { overrides.clear() }, setRemoteFallback(enabled: boolean) { remoteFallbackEnabled = enabled }, resetRenderedSlots() { clearTextureCache() }, } } /** Default config instance for . */ export const localBundledTexturesConfig = createBundledTexturesConfig() export { allTexturePaths, allContainerPaths }