@xmcl/resourcepack
Version:
A Minecraft resource pack parser
8 lines (7 loc) • 22.3 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../index.ts", "../resourceManager.ts", "../resourcePack.ts", "../modelLoader.ts"],
"sourcesContent": ["/**\n * The resource pack module to read Minecraft resource pack just like Minecraft in-game.\n *\n * You can open the ResourcePack by {@link ResourcePack.open} and get resource by {@link ResourcePack.get}.\n *\n * Or you can just load resource pack metadata by {@link readPackMetaAndIcon}.\n *\n * @packageDocumentation\n * @module @xmcl/resourcepack\n */\n\nimport { FileSystem, resolveFileSystem } from '@xmcl/system'\nimport { PackMeta } from './format'\n\nexport * from './resourceManager'\nexport * from './resourcePack'\nexport * from './modelLoader'\nexport * from './format'\n\n/**\n * Read the resource pack metadata from zip file or directory.\n *\n * If you have already read the data of the zip file, you can pass it as the second parameter. The second parameter will be ignored on reading directory.\n *\n * @param resourcePack The absolute path of the resource pack file, or a buffer, or a opened resource pack.\n */\nexport async function readPackMeta(resourcePack: string | Uint8Array | FileSystem): Promise<PackMeta.Pack> {\n const system = await resolveFileSystem(resourcePack)\n try {\n if (!await system.existsFile('pack.mcmeta')) {\n throw new Error('Illegal Resourcepack: Cannot find pack.mcmeta!')\n }\n const metadata = JSON.parse((await system.readFile('pack.mcmeta', 'utf-8')).replace(/^\\uFEFF/, ''))\n if (!metadata.pack) {\n throw new Error(\"Illegal Resourcepack: pack.mcmeta doesn't contain the pack metadata!\")\n }\n return metadata.pack\n } finally {\n if (system !== resourcePack) system.close()\n }\n}\n\n/**\n * Read the resource pack icon png binary.\n * @param resourcePack The absolute path of the resource pack file, or a buffer, or a opened resource pack.\n */\nexport async function readIcon(resourcePack: string | Uint8Array | FileSystem): Promise<Uint8Array> {\n const system = await resolveFileSystem(resourcePack)\n try {\n return system.readFile('pack.png')\n } finally {\n if (system !== resourcePack) system.close()\n }\n}\n\n/**\n * Read both metadata and icon\n *\n * @see {@link readIcon}\n * @see {@link readPackMeta}\n */\nexport async function readPackMetaAndIcon(resourcePack: string | Uint8Array | FileSystem) {\n const system = await resolveFileSystem(resourcePack)\n\n try {\n return {\n metadata: await readPackMeta(system),\n icon: await readIcon(system).catch(() => undefined),\n }\n } finally {\n if (system !== resourcePack) system.close()\n }\n}\n", "import { PackMeta } from './format'\nimport { ResourcePack, Resource, ResourceLocation } from './resourcePack'\n\nexport interface ResourcePackWrapper {\n source: ResourcePack\n info: PackMeta.Pack\n domains: string[]\n}\n\nexport interface ResourceLoader {\n /**\n * Get the resource in that location. This will walk through current resource source list to load the resource.\n * @param location The resource location\n */\n get(location: ResourceLocation): Promise<Resource | undefined>\n}\n\n/**\n * The resource manager just like Minecraft. Design to be able to use in both nodejs and browser environment.\n */\nexport class ResourceManager<T extends ResourcePackWrapper = ResourcePackWrapper> implements ResourceLoader {\n constructor(\n /**\n * The list order is just like the order in options.txt. The last element is the highest priority one.\n * The resource will load from the last one to the first one.\n */\n public list: Array<ResourcePackWrapper> = []) { }\n\n get allResourcePacks() { return this.list.map((l) => l.info) }\n\n /**\n * Add a new resource source as the first priority of the resource list.\n */\n async addResourcePack(resourcePack: ResourcePack) {\n let info\n try {\n info = await resourcePack.info()\n } catch {\n info = { pack_format: -1, description: '' }\n }\n const domains = await resourcePack.domains()\n const wrapper = { info, source: resourcePack, domains }\n\n this.list.push(wrapper)\n\n return wrapper\n }\n\n remove(index: number) {\n return this.list.splice(index, 1)[0]\n }\n\n /**\n * Clear all resource packs in this manager\n */\n clear() {\n return this.list.splice(0, this.list.length)\n }\n\n /**\n * Swap the resource source priority.\n */\n swap(first: number, second: number) {\n if (first >= this.list.length || first < 0 || second >= this.list.length || second < 0) {\n throw new Error('Illegal index')\n }\n\n const fir = this.list[first]\n this.list[first] = this.list[second]\n this.list[second] = fir\n }\n\n /**\n * Get the resource in that location. This will walk through current resource source list to load the resource.\n * @param location The resource location\n */\n async get(location: ResourceLocation): Promise<Resource | undefined> {\n for (let i = this.list.length - 1; i >= 0; i--) {\n const src = this.list[i]\n const resource = await src.source.get(location)\n if (resource) { return resource }\n }\n return undefined\n }\n}\n", "/**\n * The resource pack module to read Minecraft resource pack just like Minecraft in-game.\n *\n * You can open the ResourcePack by {@link ResourcePack.open} and get resource by {@link ResourcePack.get}.\n *\n * Or you can just load resource pack metadata by {@link readPackMetaAndIcon}.\n *\n * @packageDocumentation\n */\n\nimport { FileSystem, resolveFileSystem } from '@xmcl/system'\nimport { PackMeta } from './format'\n\n/**\n * The Minecraft used object to map the game resource location.\n */\nexport class ResourceLocation {\n static deconstruct(path:string, appendPath = '') {\n const splitPath = path.split(':')\n\n const domain = (splitPath.length > 1 && splitPath[0]) ? splitPath[0] : 'minecraft'\n let resourcePath = splitPath.length > 1 ? splitPath[1] : splitPath[0]\n\n if (appendPath.length > 0) {\n if (appendPath.charAt(appendPath.length - 1) !== '/') {\n appendPath = appendPath + '/'\n }\n if (!resourcePath.startsWith(appendPath)) {\n resourcePath = appendPath + resourcePath\n }\n }\n\n return new ResourceLocation(domain, resourcePath)\n }\n\n /**\n * build from texture path\n */\n static ofTexturePath(location: string|ResourceLocation) {\n if (typeof location === 'string') { location = ResourceLocation.deconstruct(location) }\n return new ResourceLocation(location.domain, `textures/${location.path}.png`)\n }\n\n /**\n * build from model path\n */\n static ofBlockModelPath(location: string|ResourceLocation) {\n location = ResourceLocation.deconstruct(location.toString(), 'block/')\n return new ResourceLocation(location.domain, `models/${location.path}.json`)\n }\n\n static ofItemModelPath(location: string|ResourceLocation) {\n location = ResourceLocation.deconstruct(location.toString(), 'item/')\n return new ResourceLocation(location.domain, `models/${location.path}.json`)\n }\n\n static ofModelPath(location: string|ResourceLocation) {\n if (typeof location === 'string') { location = ResourceLocation.deconstruct(location) }\n return new ResourceLocation(location.domain, `models/${location.path}.json`)\n }\n\n /**\n * build from block state path\n */\n static ofBlockStatePath(location: string|ResourceLocation) {\n if (typeof location === 'string') { location = ResourceLocation.deconstruct(location) }\n return new ResourceLocation(location.domain, `blockstates/${location.path}.json`)\n }\n\n /**\n * from absoluted path\n */\n static fromPath(location: string|ResourceLocation) {\n return ResourceLocation.deconstruct(location.toString())\n }\n\n static getAssetsPath(location: string|ResourceLocation) {\n if (typeof location === 'string') { location = ResourceLocation.deconstruct(location) }\n return `assets/${location.domain}/${location.path}`\n }\n\n constructor(\n readonly domain: string,\n readonly path: string) { }\n\n toString() { return `${this.domain}:${this.path}` }\n}\n\n/**\n * The resource in the resource pack on a `ResourceLocation`\n * @see {@link ResourceLocation}\n */\nexport interface Resource {\n /**\n * The absolute location of the resource\n */\n readonly location: ResourceLocation\n /**\n * The real resource url which is used for reading the content of it.\n */\n readonly url: string\n /**\n * Read the resource content\n */\n read(): Promise<Uint8Array>\n read(encoding: undefined): Promise<Uint8Array>\n read(encoding: 'utf-8' | 'base64'): Promise<string>\n read(encoding?: 'utf-8' | 'base64'): Promise<Uint8Array | string>\n /**\n * Read the metadata of the resource\n */\n readMetadata(): Promise<PackMeta>\n}\n\n/**\n * The Minecraft resource pack. Providing the loading resource from `ResourceLocation` function.\n * It's a wrap of `FileSystem` which provides cross node/browser accssing.\n *\n * @see {@link ResourceLocation}\n * @see {@link FileSystem}\n */\nexport class ResourcePack {\n constructor(readonly fs: FileSystem) { }\n /**\n * Load the resource content\n * @param location The resource location\n * @param type The output type of the resource\n */\n async load(location: ResourceLocation, type?: 'utf-8' | 'base64'): Promise<Uint8Array | string | undefined> {\n const p = this.getPath(location)\n if (await this.fs.existsFile(p)) {\n return this.fs.readFile(p, type)\n }\n return undefined\n }\n\n /**\n * Load the resource metadata which is localted at <resource-path>.mcmeta\n */\n async loadMetadata(location: ResourceLocation) {\n const p = this.getPath(location)\n const name = p.substring(0, p.lastIndexOf('.'))\n const metafileName = name + '.mcmeta'\n return await this.fs.existsFile(metafileName) ? JSON.parse((await this.fs.readFile(metafileName, 'utf-8')).replace(/^\\uFEFF/, '')) : {}\n }\n\n /**\n * Get the url of the resource location.\n * Please notice that this is depended on `FileSystem` implementation of the `getUrl`.\n *\n * @returns The absolute url like `file://` or `http://` depending on underlaying `FileSystem`.\n * @see {@link FileSystem}\n */\n getUrl(location: ResourceLocation) {\n const p = this.getPath(location)\n return this.fs.getUrl(p)\n }\n\n /**\n * Get the resource on the resource location.\n *\n * It can be undefined if there is no resource at that location.\n * @param location THe resource location\n */\n async get(location: ResourceLocation): Promise<Resource | undefined> {\n if (await this.has(location)) {\n return {\n location,\n url: this.getUrl(location),\n read: ((encoding: any) => this.load(location, encoding)) as any,\n readMetadata: () => this.loadMetadata(location),\n }\n }\n }\n\n /**\n * Does the resource pack has the resource\n */\n has(location: ResourceLocation): Promise<boolean> {\n return this.fs.existsFile(this.getPath(location))\n }\n\n /**\n * The owned domain. You can think about the modids.\n */\n async domains(): Promise<string[]> {\n const files = await this.fs.listFiles('assets')\n const result: string[] = []\n for (const f of files) {\n if (await this.fs.isDirectory('assets/' + f)) {\n result.push(f)\n }\n }\n return result\n }\n\n /**\n * The pack info, just like resource pack\n */\n async info(): Promise<PackMeta.Pack> {\n const { pack } = await this.fs.readFile('pack.mcmeta', 'utf-8').then(\n (s) => JSON.parse(s.replace(/^\\uFEFF/, '')),\n () => { throw new Error('Illegal Resourcepack: Cannot find pack.mcmeta!') })\n if (!pack) {\n throw new Error(\"Illegal Resourcepack: pack.mcmeta doesn't contain the pack metadata!\")\n }\n return pack\n }\n\n /**\n * The icon of the resource pack\n */\n icon(): Promise<Uint8Array> {\n return this.fs.readFile('pack.png')\n }\n\n private getPath(location: ResourceLocation) {\n return `assets/${location.domain}/${location.path}`\n }\n\n static async open(resourcePack: string | Uint8Array | FileSystem): Promise<ResourcePack> {\n return new ResourcePack(await resolveFileSystem(resourcePack))\n }\n}\n", "import { Resource, ResourceLocation } from './resourcePack'\nimport { ResourceLoader } from './resourceManager'\nimport { BlockModel } from './format'\n\n/**\n * The model loader load the resource\n */\nexport class ModelLoader {\n static findRealTexturePath(model: BlockModel.Resolved, variantKey: string) {\n let texturePath = model.textures[variantKey] as string\n while (texturePath.startsWith('#')) {\n const next = model.textures[texturePath.substring(1, texturePath.length)]\n if (!next) { return undefined }\n texturePath = next\n }\n return texturePath\n }\n\n /**\n * All required texture raw resources\n */\n readonly textures: Record<string, Resource> = {}\n /**\n * All the resolved model\n */\n readonly models: Record<string, BlockModel.Resolved> = {}\n\n /**\n * @param loader The resource loader\n */\n constructor(readonly loader: ResourceLoader) { }\n\n /**\n * Load a model by search its parent. It will throw an error if the model is not found.\n */\n async loadModel(modelPath: string, folder = 'block'): Promise<BlockModel.Resolved> {\n const path = ResourceLocation.deconstruct(modelPath, folder)\n const resourceLocation = ResourceLocation.ofModelPath(path)\n\n const cacheName = resourceLocation.toString()\n\n if (this.models[cacheName] !== undefined) {\n return this.models[cacheName]\n }\n\n const resource = await this.loader.get(resourceLocation)\n if (!resource) { throw new Error(`Model ${modelPath} (${resourceLocation}) not found`) }\n const baseModel = JSON.parse(await resource.read('utf-8')) as BlockModel\n\n if (!baseModel.textures) { baseModel.textures = {} }\n\n if (baseModel.parent) {\n const parentModel = await this.loadModel(baseModel.parent, '')\n if (!parentModel) { throw new Error(`Missing parent model ${baseModel.parent} for ${resource.location}`) }\n if (!baseModel.elements) { baseModel.elements = parentModel.elements }\n if (!baseModel.ambientocclusion) { baseModel.ambientocclusion = parentModel.ambientocclusion }\n if (!baseModel.display) { baseModel.display = parentModel.display }\n if (!baseModel.overrides) { baseModel.overrides = parentModel.overrides }\n\n if (parentModel.textures) { Object.assign(baseModel.textures, parentModel.textures) }\n }\n\n baseModel.ambientocclusion = baseModel.ambientocclusion || false\n baseModel.overrides = baseModel.overrides || []\n\n delete baseModel.parent\n\n const model: BlockModel.Resolved = baseModel as any\n\n const reg = this.textures\n for (const variant of Object.keys(model.textures)) {\n const texPath = ModelLoader.findRealTexturePath(model, variant)\n if (texPath) {\n const load = await this.loader.get(ResourceLocation.ofTexturePath(texPath))\n if (load) {\n reg[texPath] = load\n }\n }\n }\n\n this.models[cacheName] = model\n return model\n }\n}\n"],
"mappings": "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",
"names": ["resolveFileSystem", "resolveFileSystem"]
}