/**
 * The resource pack module to read Minecraft resource pack just like Minecraft in-game.
 *
 * You can open the ResourcePack by  ResourcePack . open and get resource by  ResourcePack . get .
 *
 * Or you can just load resource pack metadata by  readPackMetaAndIcon .
 *
 *  packageDocumentation import { FileSystem , resolveFileSystem } from "@xmcl/system" ; import { PackMeta } from "./format" ; /**
 * The Minecraft used object to map the game resource location.
 */ export class ResourceLocation { /**
     * build from texture path
     */ static ofTexturePath ( path ) { const idx = path . indexOf ( ":" ) ; if ( idx === - 1 ) { return new ResourceLocation ( "minecraft" , `textures/${ path }.png` ) ; } if ( idx === 0 ) { return new ResourceLocation ( "minecraft" , `textures/${ path . substring ( 1 , path . length ) }.png` ) ; } return new ResourceLocation ( path . substring ( 0 , idx ) , `textures/${ path . substring ( idx + 1 , path . length ) }.png` ) ; } static ofBlockModelPath ( path ) { const splited = path . split ( ":" ) ; const domain = ( splited . length > 1 && splited [ 0 ] ) ? splited [ 0 ] : "minecraft" ; let blockPath = splited . length > 1 ? splited [ 1 ] : splited [ 0 ] ; if ( ! blockPath . startsWith ( "block/" ) ) { blockPath = `block/${ blockPath }` ; } return new ResourceLocation ( domain , `models/${ blockPath }.json` ) ; } /**
     * build from model path
     */ static ofModelPath ( path ) { const idx = path . indexOf ( ":" ) ; if ( idx === - 1 ) { return new ResourceLocation ( "minecraft" , `models/${ path }.json` ) ; } if ( idx === 0 ) { return new ResourceLocation ( "minecraft" , `models/${ path . substring ( 1 , path . length ) }.json` ) ; } return new ResourceLocation ( path . substring ( 0 , idx ) , `models/${ path . substring ( idx + 1 , path . length ) }.json` ) ; } /**
     * from absoluted path
     */ static fromPath ( path ) { const idx = path . indexOf ( ":" ) ; if ( idx === - 1 ) { return new ResourceLocation ( "minecraft" , path ) ; } if ( idx === 0 ) { return new ResourceLocation ( "minecraft" , path . substring ( 1 , path . length ) ) ; } return new ResourceLocation ( path . substring ( 0 , idx ) , path . substring ( idx + 1 , path . length ) ) ; } static getAssetsPath ( location ) { return `assets/${ location . domain }/${ location . path }` ; } constructor ( readonly domain , readonly path ) { } toString ( ) { return `${ this . domain }:${ this . path }` ; } } see ResourceLocation export interface Resource { /**
     * The absolute location of the resource
     */ readonly location : ResourceLocation ; /**
     * The real resource url which is used for reading the content of it.
     */ readonly url : string ; /**
     * Read the resource content
     */ read ( ) : Promise < Uint8Array > ; read ( encoding ) : Promise < Uint8Array > ; read ( encoding ) : Promise < string > ; read ( encoding ? ) : Promise < Uint8Array | string > ; /**
     * Read the metadata of the resource
     */ readMetadata ( ) : Promise < PackMeta > ; } see ResourceLocation see FileSystem export class ResourcePack { constructor ( readonly fs ) { } param location param type async load ( location , type ? ) { const p = this . getPath ( location ) ; if ( await this . fs . existsFile ( p ) ) { return this . fs . readFile ( p , type ) ; } return undefined ; } /**
     * Load the resource metadata which is localted at <resource-path>.mcmeta
     */ async loadMetadata ( location ) { const p = this . getPath ( location ) ; const name = p . substring ( 0 , p . lastIndexOf ( "." ) ) ; const metafileName = name + ".mcmeta" ; return await this . fs . existsFile ( metafileName ) ? JSON . parse ( ( await this . fs . readFile ( metafileName , "utf-8" ) ) . replace ( /^\uFEFF/ , "" ) ) : { } ; } returns see FileSystem getUrl ( location ) { const p = this . getPath ( location ) ; return this . fs . getUrl ( p ) ; } param location async get ( location ) { if ( await this . has ( location ) ) { return { location , url : this . getUrl ( location ) , read : ( ( encoding ) => this . load ( location , encoding ) ) as any , readMetadata : ( ) => this . loadMetadata ( location ) , } ; } } /**
     * Does the resource pack has the resource
     */ has ( location ) { return this . fs . existsFile ( this . getPath ( location ) ) ; } /**
     * The owned domain. You can think about the modids.
     */ async domains ( ) { const files = await this . fs . listFiles ( "assets" ) ; const result = [ ] ; for ( const f of files ) { if ( await this . fs . isDirectory ( "assets/" + f ) ) { result . push ( f ) ; } } return result ; } /**
     * The pack info, just like resource pack
     */ async info ( ) { let { pack } = await this . fs . readFile ( "pack.mcmeta" , "utf-8" ) . then ( ( s ) => JSON . parse ( s . replace ( /^\uFEFF/ , "" ) ) , ( ) => { throw new Error ( "Illegal Resourcepack: Cannot find pack.mcmeta!" ) ; } ) ; if ( ! pack ) { throw new Error ( "Illegal Resourcepack: pack.mcmeta doesn't contain the pack metadata!" ) ; } return pack ; } /**
     * The icon of the resource pack
     */ icon ( ) { return this . fs . readFile ( "pack.png" ) ; } private getPath ( location ) { return `assets/${ location . domain }/${ location . path }` ; } static async open ( resourcePack ) { return new ResourcePack ( await resolveFileSystem ( resourcePack ) ) ; } }