diff --git a/src/Main.ts b/src/Main.ts index 7e90e00..aac495c 100644 --- a/src/Main.ts +++ b/src/Main.ts @@ -1,29 +1,20 @@ import 'reflect-metadata'; import { container } from 'tsyringe'; -import { BundleProvider } from './common/bundle/BundleProvider'; import { Configuration } from './common/config/Configuration'; +import { FigureConverter } from './converters/figure/FigureConverter'; import { FurnitureConverter } from './converters/furniture/FurnitureConverter'; import { PetConverter } from './converters/pet/PetConverter'; -import { Mapper } from './mapping/mappers/asset/Mapper'; (async () => { const config = container.resolve(Configuration); await config.init(); - const prohibitedSizes = (config.getValue('prohibited.sizes') || '').split(','); - const prohibitedSizesAsset = []; - - for(const prohibitedSize of prohibitedSizes) prohibitedSizesAsset.push('_' + prohibitedSize + '_'); - - Mapper.PROHIBITED_SIZES = prohibitedSizes; - BundleProvider.PROHIBITED_SIZES = prohibitedSizesAsset; - - // if(config.getBoolean('convert.figure')) - // { - // const figureConverter = container.resolve(FigureConverter); - // await figureConverter.convertAsync(); - // } + if(config.getBoolean('convert.figure')) + { + const figureConverter = container.resolve(FigureConverter); + await figureConverter.convertAsync(); + } if(config.getBoolean('convert.furniture')) { diff --git a/src/common/bundle/BundleProvider.ts b/src/common/bundle/BundleProvider.ts index 92c6b33..c61e58c 100644 --- a/src/common/bundle/BundleProvider.ts +++ b/src/common/bundle/BundleProvider.ts @@ -1,19 +1,14 @@ import { packAsync } from 'free-tex-packer-core'; import { singleton } from 'tsyringe'; import { HabboAssetSWF } from '../../swf/HabboAssetSWF'; -import { Configuration } from '../config/Configuration'; +import { ImageBundle } from './ImageBundle'; import { SpriteBundle } from './SpriteBundle'; @singleton() export class BundleProvider { - public static PROHIBITED_SIZES: string[] = []; - public static imageSource: Map = new Map(); - constructor(private readonly _configuration: Configuration) - {} - public async generateSpriteSheet(habboAssetSWF: HabboAssetSWF): Promise { const tagList = habboAssetSWF.symbolTags(); @@ -26,7 +21,7 @@ export class BundleProvider tags.push(...tag.tags); } - const images: { path: string, contents: Buffer }[] = []; + const imageBundle = new ImageBundle(); const imageTags = habboAssetSWF.imageTags(); @@ -40,105 +35,62 @@ export class BundleProvider if(names[i] == imageTag.className) continue; - let isProhibited = false; + if(imageTag.className.startsWith('sh_')) continue; - for(const size of BundleProvider.PROHIBITED_SIZES) - { - if(imageTag.className.indexOf(size) >= 0) - { - isProhibited = true; - - break; - } - } - - if(isProhibited) continue; + if(imageTag.className.indexOf('_32_') >= 0) continue; BundleProvider.imageSource.set(names[i].substring(habboAssetSWF.getDocumentClass().length + 1), imageTag.className.substring(habboAssetSWF.getDocumentClass().length + 1)); - - images.push({ - path: imageTag.className, - contents: imageTag.imgData - }); } } - let isProhibited = false; + if(imageTag.className.startsWith('sh_')) continue; - for(const size of BundleProvider.PROHIBITED_SIZES) - { - if(imageTag.className.indexOf(size) >= 0) - { - isProhibited = true; + if(imageTag.className.indexOf('_32_') >= 0) continue; - break; - } - } - - if(isProhibited) continue; - - images.push({ - path: imageTag.className, - contents: imageTag.imgData - }); + imageBundle.addImage(imageTag.className, imageTag.imgData); } - if(!images.length) return null; + if(!imageBundle.images.length) return null; - return await this.packImages(habboAssetSWF.getDocumentClass(), images); + return await this.packImages(habboAssetSWF.getDocumentClass(), imageBundle); } - async packImages(documentClass: string, images: { path: string, contents: Buffer }[]): Promise + async packImages(documentClass: string, imageBundle: ImageBundle): Promise { - try + const files = await packAsync(imageBundle.images, { + textureName: documentClass, + width: 3072, + height: 2048, + fixedSize: false, + allowRotation: true, + detectIdentical: true, + allowTrim: true, + //@ts-ignore + exporter: 'Pixi' + }); + + const bundle = new SpriteBundle(); + + for(const item of files) { - const files = await packAsync(images, { - textureName: documentClass, - width: 3072, - height: 2048, - fixedSize: false, - allowRotation: true, - detectIdentical: true, - allowTrim: true, - //@ts-ignore - exporter: 'Pixi' - }); - - const bundle = new SpriteBundle(); - - for(const item of files) + if(item.name.endsWith('.json')) { - if(item.name.endsWith('.json')) - { - bundle.spritesheet = JSON.parse(item.buffer.toString('utf8')); + bundle.spritesheet = JSON.parse(item.buffer.toString('utf8')); - delete bundle.spritesheet.meta.app; - delete bundle.spritesheet.meta.version; - } - else - { - bundle.imageData = { - name: item.name, - buffer: item.buffer - }; - } + delete bundle.spritesheet.meta.app; + delete bundle.spritesheet.meta.version; } - - if(!bundle.spritesheet) throw new Error('Failed to parse SpriteSheet. ' + images[0].path); - - if((bundle.spritesheet !== undefined) && (bundle.imageData !== undefined)) + else { - bundle.spritesheet.meta.image = bundle.imageData.name; + bundle.imageData = { + name: item.name, + buffer: item.buffer + }; } - - return bundle; } - catch (error) - { - console.error('Image Packing Error', error); - } + if((bundle.spritesheet !== undefined) && (bundle.imageData !== undefined)) bundle.spritesheet.meta.image = bundle.imageData.name; - return null; + return bundle; } } diff --git a/src/common/bundle/ImageBundle.ts b/src/common/bundle/ImageBundle.ts new file mode 100644 index 0000000..b31afca --- /dev/null +++ b/src/common/bundle/ImageBundle.ts @@ -0,0 +1,23 @@ +export class ImageBundle +{ + private _images: { path: string, contents: Buffer }[] = []; + + public dispose(): void + { + this._images = null; + } + + public addImage(path: string, contents: Buffer): void + { + if(!path || !contents) return; + + for(const image of this._images) if(image.path === path) return; + + this._images.push({ path, contents }); + } + + public get images(): { path: string, contents: Buffer }[] + { + return this._images; + } +} diff --git a/src/common/bundle/SpriteBundle.ts b/src/common/bundle/SpriteBundle.ts index f9be598..f058f60 100644 --- a/src/common/bundle/SpriteBundle.ts +++ b/src/common/bundle/SpriteBundle.ts @@ -3,7 +3,7 @@ import { ISpritesheetData } from '../../mapping/json'; export class SpriteBundle { private _spritesheet: ISpritesheetData; - private _imageData: { name: string, buffer: Buffer}; + private _imageData: { name: string, buffer: Buffer }; public get spritesheet(): ISpritesheetData { diff --git a/src/common/converters/SWFConverter.ts b/src/common/converters/SWFConverter.ts index 0bdb296..b2b0ec6 100644 --- a/src/common/converters/SWFConverter.ts +++ b/src/common/converters/SWFConverter.ts @@ -38,6 +38,24 @@ export class SWFConverter return tag; } + protected static async getManifestXML(habboAssetSWF: HabboAssetSWF): Promise + { + const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'manifest', false); + + if(!binaryData) return null; + + return await parseStringPromise(binaryData.binaryData); + } + + protected static async getIndexXML(habboAssetSWF: HabboAssetSWF): Promise + { + const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'index', false); + + if(!binaryData) return null; + + return await parseStringPromise(binaryData.binaryData); + } + protected static async getAssetsXML(habboAssetSWF: HabboAssetSWF): Promise { const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'assets', true); @@ -56,15 +74,6 @@ export class SWFConverter return await parseStringPromise(binaryData.binaryData); } - protected static async getIndexXML(habboAssetSWF: HabboAssetSWF): Promise - { - const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'index', false); - - if(!binaryData) return null; - - return await parseStringPromise(binaryData.binaryData); - } - protected static async getVisualizationXML(habboAssetSWF: HabboAssetSWF): Promise { const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'visualization', true); diff --git a/src/config.json.example b/src/config.json.example index b306408..1e3023e 100644 --- a/src/config.json.example +++ b/src/config.json.example @@ -14,6 +14,5 @@ "convert.furniture": "1", "convert.figure": "0", "convert.effect": "0", - "convert.pet": "1", - "prohibited.sizes": "32,sh" + "convert.pet": "1" } diff --git a/src/converters/figure/FigureConverter.ts b/src/converters/figure/FigureConverter.ts new file mode 100644 index 0000000..e5b3404 --- /dev/null +++ b/src/converters/figure/FigureConverter.ts @@ -0,0 +1,73 @@ +import * as ora from 'ora'; +import { singleton } from 'tsyringe'; +import { BundleProvider } from '../../common/bundle/BundleProvider'; +import { Configuration } from '../../common/config/Configuration'; +import { SWFConverter } from '../../common/converters/SWFConverter'; +import { IAssetData } from '../../mapping/json'; +import { ManifestMapper } from '../../mapping/mappers'; +import { HabboAssetSWF } from '../../swf/HabboAssetSWF'; +import File from '../../utils/File'; +import Logger from '../../utils/Logger'; +import { FigureDownloader } from './FigureDownloader'; + +@singleton() +export class FigureConverter extends SWFConverter +{ + constructor( + private readonly _figureDownloader: FigureDownloader, + private readonly _configuration: Configuration, + private readonly _bundleProvider: BundleProvider, + private readonly _logger: Logger) + { + super(); + } + + public async convertAsync(): Promise + { + const now = Date.now(); + + const spinner = ora('Preparing Figure').start(); + + const outputFolder = new File(this._configuration.getValue('output.folder.figure')); + + if(!outputFolder.isDirectory()) outputFolder.mkdirs(); + + try + { + await this._figureDownloader.download(async (habboAssetSwf: HabboAssetSWF, className: string) => + { + spinner.text = 'Parsing Figure: ' + habboAssetSwf.getDocumentClass(); + + spinner.render(); + + const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf); + const assetData = await this.mapXML2JSON(habboAssetSwf, className); + + await this.fromHabboAsset(habboAssetSwf, outputFolder.path, assetData.type, assetData, spriteBundle); + }); + + spinner.succeed(`Figures finished in ${ Date.now() - now }ms`); + } + + catch (error) + { + spinner.fail('Figures failed: ' + error.message); + } + } + + private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise + { + if(!habboAssetSWF) return null; + + const assetData: IAssetData = {}; + + assetData.name = assetType; + assetData.type = FigureDownloader.FIGURE_TYPES.get(assetType); + + const manifestXML = await FigureConverter.getManifestXML(habboAssetSWF); + + if(manifestXML) ManifestMapper.mapXML(manifestXML, assetData); + + return assetData; + } +} diff --git a/src/converters/figure/FigureDownloader.ts b/src/converters/figure/FigureDownloader.ts new file mode 100644 index 0000000..85a2a82 --- /dev/null +++ b/src/converters/figure/FigureDownloader.ts @@ -0,0 +1,79 @@ +import { singleton } from 'tsyringe'; +import { Configuration } from '../../common/config/Configuration'; +import { IFigureMap } from '../../mapping/json'; +import { HabboAssetSWF } from '../../swf/HabboAssetSWF'; +import { FileUtilities } from '../../utils/FileUtilities'; + +@singleton() +export class FigureDownloader +{ + public static FIGURE_TYPES: Map = new Map(); + + constructor(private readonly _configuration: Configuration) + {} + + public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise): Promise + { + const figureMap = await this.parseFigureMap(); + const classNames: string[] = []; + + if(figureMap.libraries !== undefined) + { + for(const library of figureMap.libraries) + { + const className = library.id.split('*')[0]; + + if(className === 'hh_human_fx' || className === 'hh_pets') continue; + + if(classNames.indexOf(className) >= 0) continue; + + classNames.push(className); + + try + { + FigureDownloader.FIGURE_TYPES.set(className, library.parts[0].type); + + await this.extractFigure(className, callback); + } + + catch (error) + { + console.log(); + console.error(`Error parsing ${ className }: ` + error.message); + } + } + } + } + + public async parseFigureMap(): Promise + { + const url = this._configuration.getValue('figuremap.url'); + + if(!url || !url.length) return null; + + const content = await FileUtilities.readFileAsString(url); + + if(!content || !content.length) return null; + + return (JSON.parse(content) as IFigureMap); + } + + public async extractFigure(className: string, callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise): Promise + { + let url = this._configuration.getValue('dynamic.download.url.figure'); + + if(!url || !url.length) return; + + url = url.replace('%className%', className); + + const buffer = await FileUtilities.readFileAsBuffer(url); + + if(!buffer) return; + + const newHabboAssetSWF = new HabboAssetSWF(buffer); + + await newHabboAssetSWF.setupAsync(); + + await callback(newHabboAssetSWF, className); + } +} diff --git a/src/converters/furniture/FurnitureConverter.ts b/src/converters/furniture/FurnitureConverter.ts index 77cb64e..1264ed6 100644 --- a/src/converters/furniture/FurnitureConverter.ts +++ b/src/converters/furniture/FurnitureConverter.ts @@ -40,8 +40,8 @@ export class FurnitureConverter extends SWFConverter spinner.render(); - const assetData = await this.mapXML2JSON(habboAssetSwf, 'furniture'); const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf); + const assetData = await this.mapXML2JSON(habboAssetSwf, 'furniture'); await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'furniture', assetData, spriteBundle); }); diff --git a/src/converters/furniture/FurnitureDownloader.ts b/src/converters/furniture/FurnitureDownloader.ts index b0e700b..0c289e3 100644 --- a/src/converters/furniture/FurnitureDownloader.ts +++ b/src/converters/furniture/FurnitureDownloader.ts @@ -39,7 +39,7 @@ export class FurnitureDownloader catch (error) { console.log(); - console.error(error.message); + console.error(error); } } } @@ -66,7 +66,7 @@ export class FurnitureDownloader catch (error) { console.log(); - console.error(`Error parsing ${ className }: ` + error.message); + console.error(error); } } } diff --git a/src/converters/pet/PetConverter.ts b/src/converters/pet/PetConverter.ts index 7443bcb..fa63461 100644 --- a/src/converters/pet/PetConverter.ts +++ b/src/converters/pet/PetConverter.ts @@ -40,8 +40,8 @@ export class PetConverter extends SWFConverter spinner.render(); - const assetData = await this.mapXML2JSON(habboAssetSwf, 'pet'); const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf); + const assetData = await this.mapXML2JSON(habboAssetSwf, 'pet'); await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'pet', assetData, spriteBundle); }); diff --git a/src/mapping/mappers/asset/AssetMapper.ts b/src/mapping/mappers/asset/AssetMapper.ts index 183cb62..efec607 100644 --- a/src/mapping/mappers/asset/AssetMapper.ts +++ b/src/mapping/mappers/asset/AssetMapper.ts @@ -9,31 +9,37 @@ export class AssetMapper extends Mapper { if(!assets || !output) return; - AssetMapper.mapAssetsXML(new AssetsXML(assets), output); + AssetMapper.mapAssetsXML(new AssetsXML(assets.assets), output); } private static mapAssetsXML(xml: AssetsXML, output: IAssetData): void { - if(!xml) return; + if(!xml || !output) return; if(xml.assets !== undefined) { - output.assets = {}; + if(xml.assets.length) + { + output.assets = {}; - AssetMapper.mapAssetsAssetXML(xml.assets, output.assets); + AssetMapper.mapAssetsAssetXML(xml.assets, output.assets); + } } if(xml.palettes !== undefined) { - output.palettes = {}; + if(xml.palettes.length) + { + output.palettes = {}; - AssetMapper.mapAssetsPaletteXML(xml.palettes, output.palettes); + AssetMapper.mapAssetsPaletteXML(xml.palettes, output.palettes); + } } } private static mapAssetsAssetXML(xml: AssetXML[], output: { [index: string]: IAsset }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const assetXML of xml) { @@ -41,51 +47,35 @@ export class AssetMapper extends Mapper if(assetXML.name !== undefined) { - let isProhibited = false; + if(assetXML.name.startsWith('sh_')) continue; - for(const size of AssetMapper.PROHIBITED_SIZES) + if(assetXML.name.indexOf('_32_') >= 0) continue; + + if(assetXML.source !== undefined) { - if(assetXML.name.indexOf(('_' + size + '_')) >= 0) - { - isProhibited = true; + asset.source = assetXML.source; - break; - } + if(BundleProvider.imageSource.has(assetXML.source)) asset.source = BundleProvider.imageSource.get(assetXML.source) as string; } - if(isProhibited) continue; - } - - if(assetXML.source !== undefined) - { - asset.source = assetXML.source; - - if(BundleProvider.imageSource.has(assetXML.source)) + if(assetXML.name !== undefined) { - asset.source = BundleProvider.imageSource.get(assetXML.source) as string; + if(BundleProvider.imageSource.has(assetXML.name)) asset.source = BundleProvider.imageSource.get(assetXML.name) as string; } + + if(assetXML.x !== undefined) asset.x = assetXML.x; + if(assetXML.y !== undefined) asset.y = assetXML.y; + if(assetXML.flipH !== undefined) asset.flipH = assetXML.flipH; + if(assetXML.flipV !== undefined) asset.flipV = assetXML.flipV; + + output[assetXML.name] = asset; } - - if(assetXML.name !== undefined) - { - if(BundleProvider.imageSource.has(assetXML.name)) - { - asset.source = BundleProvider.imageSource.get(assetXML.name) as string; - } - } - - if(assetXML.x !== undefined) asset.x = assetXML.x; - if(assetXML.y !== undefined) asset.y = assetXML.y; - if(assetXML.flipH !== undefined) asset.flipH = assetXML.flipH; - if(assetXML.flipV !== undefined) asset.flipV = assetXML.flipV; - - output[assetXML.name] = asset; } } private static mapAssetsPaletteXML(xml: PaletteXML[], output: { [index: string]: IAssetPalette }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const paletteXML of xml) { diff --git a/src/mapping/mappers/asset/IndexMapper.ts b/src/mapping/mappers/asset/IndexMapper.ts index e8714ff..f1ad011 100644 --- a/src/mapping/mappers/asset/IndexMapper.ts +++ b/src/mapping/mappers/asset/IndexMapper.ts @@ -13,7 +13,7 @@ export class IndexMapper extends Mapper private static mapIndexXML(indexXML: IndexXML, output: IAssetData): void { - if(!indexXML) return; + if(!indexXML || !output) return; if(indexXML.type !== undefined) output.name = indexXML.type; if(indexXML.logic !== undefined) output.logicType = indexXML.logic; diff --git a/src/mapping/mappers/asset/LogicMapper.ts b/src/mapping/mappers/asset/LogicMapper.ts index b0fffba..8d5e980 100644 --- a/src/mapping/mappers/asset/LogicMapper.ts +++ b/src/mapping/mappers/asset/LogicMapper.ts @@ -13,7 +13,7 @@ export class LogicMapper extends Mapper private static mapLogicXML(xml: LogicXML, output: IAssetData): void { - if(!xml) return; + if(!xml || !output) return; if(xml.model !== undefined) { diff --git a/src/mapping/mappers/asset/ManifestMapper.ts b/src/mapping/mappers/asset/ManifestMapper.ts new file mode 100644 index 0000000..176b86a --- /dev/null +++ b/src/mapping/mappers/asset/ManifestMapper.ts @@ -0,0 +1,72 @@ +import { BundleProvider } from '../../../common/bundle/BundleProvider'; +import { IAsset, IAssetData } from '../../json'; +import { ManifestLibraryAssetParamXML, ManifestLibraryAssetXML, ManifestLibraryXML, ManifestXML } from '../../xml'; +import { Mapper } from './Mapper'; + +export class ManifestMapper extends Mapper +{ + public static mapXML(manifest: any, output: IAssetData): void + { + if(!manifest || !output) return; + + ManifestMapper.mapManifestXML(new ManifestXML(manifest.manifest), output); + } + + private static mapManifestXML(xml: ManifestXML, output: IAssetData): void + { + if(!xml || !output) return; + + if(xml.library !== undefined) ManifestMapper.mapManifestLibraryXML(xml.library, output); + } + + private static mapManifestLibraryXML(xml: ManifestLibraryXML, output: IAssetData): void + { + if(!xml || !output) return; + + if(xml.assets !== undefined) + { + if(xml.assets.length) + { + output.assets = {}; + + ManifestMapper.mapManifestLibraryAssetXML(xml.assets, output.assets); + } + } + } + + private static mapManifestLibraryAssetXML(xml: ManifestLibraryAssetXML[], output: { [index: string]: IAsset }): void + { + if(!xml || !xml.length || !output) return; + + for(const libraryAssetXML of xml) + { + const asset: IAsset = {}; + + if(libraryAssetXML.name !== undefined) + { + if(libraryAssetXML.name.startsWith('sh_')) continue; + + if(libraryAssetXML.name.indexOf('_32_') >= 0) continue; + + if(libraryAssetXML.param !== undefined) ManifestMapper.mapManifestLibraryAssetParamXML(libraryAssetXML.param, asset); + + if(BundleProvider.imageSource.has(libraryAssetXML.name)) asset.source = BundleProvider.imageSource.get(libraryAssetXML.name); + + output[libraryAssetXML.name] = asset; + } + } + } + + private static mapManifestLibraryAssetParamXML(xml: ManifestLibraryAssetParamXML, output: IAsset): void + { + if(!xml || !output) return; + + if(xml.value !== undefined) + { + const split = xml.value.split(','); + + output.x = parseInt(split[0]); + output.y = parseInt(split[1]); + } + } +} diff --git a/src/mapping/mappers/asset/Mapper.ts b/src/mapping/mappers/asset/Mapper.ts index b926e61..0647200 100644 --- a/src/mapping/mappers/asset/Mapper.ts +++ b/src/mapping/mappers/asset/Mapper.ts @@ -1,4 +1,2 @@ export class Mapper -{ - public static PROHIBITED_SIZES: string[] = []; -} +{} diff --git a/src/mapping/mappers/asset/VisualizationMapper.ts b/src/mapping/mappers/asset/VisualizationMapper.ts index 3af607c..7e0c958 100644 --- a/src/mapping/mappers/asset/VisualizationMapper.ts +++ b/src/mapping/mappers/asset/VisualizationMapper.ts @@ -13,37 +13,28 @@ export class VisualizationMapper extends Mapper private static mapVisualizationXML(xml: VisualizationXML, output: IAssetData): void { - if(!xml) return; + if(!xml || !output) return; if(xml.visualizations !== undefined) { - output.visualizations = []; + if(xml.visualizations.length) + { + output.visualizations = []; - VisualizationMapper.mapVisualizationDataXML(xml.visualizations, output.visualizations); + VisualizationMapper.mapVisualizationDataXML(xml.visualizations, output.visualizations); + } } } private static mapVisualizationDataXML(xml: VisualizationDataXML[], output: IAssetVisualizationData[]): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const visualizationDataXML of xml) { if(visualizationDataXML.size !== undefined) { - let isProhibited = false; - - for(const size of VisualizationMapper.PROHIBITED_SIZES) - { - if(visualizationDataXML.size === parseInt(size)) - { - isProhibited = true; - - break; - } - } - - if(isProhibited) continue; + if([ 32 ].indexOf(visualizationDataXML.size) >= 0) continue; } const visualizationData: IAssetVisualizationData = {}; @@ -118,7 +109,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationLayerXML(xml: LayerXML[], output: { [index: string]: IAssetVisualizationLayer }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const layerXML of xml) { @@ -138,7 +129,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationDirectionXML(xml: VisualDirectionXML[], output: { [index: string]: IAssetVisualizationDirection }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const directionXML of xml) { @@ -160,7 +151,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationColorXML(xml: ColorXML[], output: { [index: string]: IAssetColor }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const colorXML of xml) { @@ -182,7 +173,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationColorLayerXML(xml: ColorLayerXML[], output: { [index: string]: IAssetColorLayer }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const colorLayerXML of xml) { @@ -196,7 +187,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationAnimationXML(xml: AnimationXML[], output: { [index: string]: IAssetAnimation }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const animationXML of xml) { @@ -222,7 +213,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationAnimationLayerXML(xml: AnimationLayerXML[], output: { [index: string]: IAssetAnimationLayer }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const animationLayerXML of xml) { @@ -248,7 +239,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationFrameSequenceXML(xml: FrameSequenceXML[], output: { [index: string]: IAssetAnimationSequence }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; let i = 0; @@ -277,7 +268,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationFrameSequenceFrameXML(xml: FrameXML[], output: { [index: string]: IAssetAnimationSequenceFrame }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; let i = 0; @@ -311,7 +302,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationFrameSequenceFrameOffsetXML(xml: FrameOffsetXML[], output: { [index: string]: IAssetAnimationSequenceFrameOffset }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; const i = 0; @@ -329,7 +320,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationPostureXML(xml: PostureXML[], output: { [index: string]: IAssetPosture }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const postureXML of xml) { @@ -344,7 +335,7 @@ export class VisualizationMapper extends Mapper private static mapVisualizationGestureXML(xml: GestureXML[], output: { [index: string]: IAssetGesture }): void { - if(!xml || !xml.length) return; + if(!xml || !xml.length || !output) return; for(const gestureXML of xml) { diff --git a/src/mapping/mappers/asset/index.ts b/src/mapping/mappers/asset/index.ts index 51ff329..f7d84ef 100644 --- a/src/mapping/mappers/asset/index.ts +++ b/src/mapping/mappers/asset/index.ts @@ -1,4 +1,5 @@ export * from './AssetMapper'; export * from './IndexMapper'; export * from './LogicMapper'; +export * from './ManifestMapper'; export * from './VisualizationMapper'; diff --git a/src/mapping/xml/asset/assets/AssetsXML.ts b/src/mapping/xml/asset/assets/AssetsXML.ts index b5831b5..94c3599 100644 --- a/src/mapping/xml/asset/assets/AssetsXML.ts +++ b/src/mapping/xml/asset/assets/AssetsXML.ts @@ -8,17 +8,23 @@ export class AssetsXML constructor(xml: any) { - if(xml.assets !== undefined) + if(xml.asset !== undefined) { - this._assets = []; + if(Array.isArray(xml.asset)) + { + this._assets = []; - if(xml.assets.asset !== undefined) for(const asset of xml.assets.asset) this._assets.push(new AssetXML(asset)); + for(const asset of xml.asset) this._assets.push(new AssetXML(asset)); + } + } - if(xml.assets.palette !== undefined) + if(xml.palette !== undefined) + { + if(Array.isArray(xml.palette)) { this._palettes = []; - for(const palette of xml.assets.palette) this._palettes.push(new PaletteXML(palette)); + for(const palette of xml.palette) this._palettes.push(new PaletteXML(palette)); } } } diff --git a/src/mapping/xml/asset/index.ts b/src/mapping/xml/asset/index.ts index 7b54e38..719f115 100644 --- a/src/mapping/xml/asset/index.ts +++ b/src/mapping/xml/asset/index.ts @@ -2,4 +2,5 @@ export * from './assets'; export * from './index'; export * from './IndexXML'; export * from './logic'; +export * from './manifest'; export * from './visualization'; diff --git a/src/mapping/xml/asset/logic/model/ModelXML.ts b/src/mapping/xml/asset/logic/model/ModelXML.ts index 26bff00..467e9d2 100644 --- a/src/mapping/xml/asset/logic/model/ModelXML.ts +++ b/src/mapping/xml/asset/logic/model/ModelXML.ts @@ -15,10 +15,10 @@ export class ModelXML if(xml.directions !== undefined) { - this._directions = []; - if(Array.isArray(xml.directions)) { + this._directions = []; + for(const directionParent of xml.directions) { if(Array.isArray(directionParent.direction)) for(const direction of directionParent.direction) this._directions.push(new ModelDirectionXML(direction.$)); diff --git a/src/mapping/xml/asset/manifest/ManifestLibraryAssetParamXML.ts b/src/mapping/xml/asset/manifest/ManifestLibraryAssetParamXML.ts new file mode 100644 index 0000000..b04a0d9 --- /dev/null +++ b/src/mapping/xml/asset/manifest/ManifestLibraryAssetParamXML.ts @@ -0,0 +1,19 @@ +export class ManifestLibraryAssetParamXML +{ + private readonly _value: string; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + this._value = attributes.value; + } + } + + public get value(): string + { + return this._value; + } +} diff --git a/src/mapping/xml/asset/manifest/ManifestLibraryAssetXML.ts b/src/mapping/xml/asset/manifest/ManifestLibraryAssetXML.ts new file mode 100644 index 0000000..bd1b362 --- /dev/null +++ b/src/mapping/xml/asset/manifest/ManifestLibraryAssetXML.ts @@ -0,0 +1,34 @@ +import { ManifestLibraryAssetParamXML } from './ManifestLibraryAssetParamXML'; + +export class ManifestLibraryAssetXML +{ + private readonly _name: string; + private readonly _mimeType: string; + private readonly _param: ManifestLibraryAssetParamXML; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + if(attributes.name !== undefined) this._name = attributes.name; + if(attributes.mimeType !== undefined) this._mimeType = attributes.mimeType; + } + + if(xml.param !== undefined) + { + if(xml.param[0] !== undefined) this._param = new ManifestLibraryAssetParamXML(xml.param[0]); + } + } + + public get name(): string + { + return this._name; + } + + public get param(): ManifestLibraryAssetParamXML + { + return this._param; + } +} diff --git a/src/mapping/xml/asset/manifest/ManifestLibraryXML.ts b/src/mapping/xml/asset/manifest/ManifestLibraryXML.ts new file mode 100644 index 0000000..5eb5dbb --- /dev/null +++ b/src/mapping/xml/asset/manifest/ManifestLibraryXML.ts @@ -0,0 +1,40 @@ +import { ManifestLibraryAssetXML } from './ManifestLibraryAssetXML'; + +export class ManifestLibraryXML +{ + private readonly _name: string; + private readonly _version: string; + private readonly _assets: ManifestLibraryAssetXML[]; + + constructor(xml: any) + { + const attributes = xml.$; + + if(attributes !== undefined) + { + if(attributes.name !== undefined) this._name = attributes.name; + if(attributes.version !== undefined) this._version = attributes.version; + } + + if(xml.assets !== undefined) + { + if(Array.isArray(xml.assets)) + { + this._assets = []; + + for(const assetPartParent of xml.assets) + { + if(Array.isArray(assetPartParent.asset)) + { + for(const asset of assetPartParent.asset) this._assets.push(new ManifestLibraryAssetXML(asset)); + } + } + } + } + } + + public get assets(): ManifestLibraryAssetXML[] + { + return this._assets; + } +} diff --git a/src/mapping/xml/asset/manifest/ManifestXML.ts b/src/mapping/xml/asset/manifest/ManifestXML.ts new file mode 100644 index 0000000..c8910ce --- /dev/null +++ b/src/mapping/xml/asset/manifest/ManifestXML.ts @@ -0,0 +1,19 @@ +import { ManifestLibraryXML } from './ManifestLibraryXML'; + +export class ManifestXML +{ + private readonly _library: ManifestLibraryXML; + + constructor(xml: any) + { + if(xml.library !== undefined) + { + if(xml.library[0] !== undefined) this._library = new ManifestLibraryXML(xml.library[0]); + } + } + + public get library(): ManifestLibraryXML + { + return this._library; + } +} diff --git a/src/mapping/xml/asset/manifest/index.ts b/src/mapping/xml/asset/manifest/index.ts new file mode 100644 index 0000000..4cf3aee --- /dev/null +++ b/src/mapping/xml/asset/manifest/index.ts @@ -0,0 +1,4 @@ +export * from './ManifestLibraryAssetParamXML'; +export * from './ManifestLibraryAssetXML'; +export * from './ManifestLibraryXML'; +export * from './ManifestXML'; diff --git a/src/mapping/xml/asset/visualization/VisualDirectionXML.ts b/src/mapping/xml/asset/visualization/VisualDirectionXML.ts index 974009d..634c662 100644 --- a/src/mapping/xml/asset/visualization/VisualDirectionXML.ts +++ b/src/mapping/xml/asset/visualization/VisualDirectionXML.ts @@ -16,9 +16,12 @@ export class VisualDirectionXML if(xml.layer !== undefined) { - this._layers = []; + if(Array.isArray(xml.layer)) + { + this._layers = []; - for(const layer of xml.layer) this._layers.push(new LayerXML(layer)); + for(const layer of xml.layer) this._layers.push(new LayerXML(layer)); + } } } diff --git a/src/mapping/xml/asset/visualization/VisualizationDataXML.ts b/src/mapping/xml/asset/visualization/VisualizationDataXML.ts index 2948d48..4d6cc36 100644 --- a/src/mapping/xml/asset/visualization/VisualizationDataXML.ts +++ b/src/mapping/xml/asset/visualization/VisualizationDataXML.ts @@ -31,78 +31,96 @@ export class VisualizationDataXML if(xml.layers !== undefined) { - this._layers = []; - - for(const layerParent of xml.layers) + if(Array.isArray(xml.layers)) { - if(Array.isArray(layerParent.layer)) + this._layers = []; + + for(const layerParent of xml.layers) { - for(const layer of layerParent.layer) this._layers.push(new LayerXML(layer)); + if(Array.isArray(layerParent.layer)) + { + for(const layer of layerParent.layer) this._layers.push(new LayerXML(layer)); + } } } } if(xml.directions !== undefined) { - this._directions = []; - - for(const directionParent of xml.directions) + if(Array.isArray(xml.directions)) { - if(Array.isArray(directionParent.direction)) + this._directions = []; + + for(const directionParent of xml.directions) { - for(const direction of directionParent.direction) this._directions.push(new VisualDirectionXML(direction)); + if(Array.isArray(directionParent.direction)) + { + for(const direction of directionParent.direction) this._directions.push(new VisualDirectionXML(direction)); + } } } } if(xml.colors !== undefined) { - this._colors = []; - - for(const colorParent of xml.colors) + if(Array.isArray(xml.colors)) { - if(Array.isArray(colorParent.color)) + this._colors = []; + + for(const colorParent of xml.colors) { - for(const color of colorParent.color) this._colors.push(new ColorXML(color)); + if(Array.isArray(colorParent.color)) + { + for(const color of colorParent.color) this._colors.push(new ColorXML(color)); + } } } } if(xml.animations !== undefined) { - this._animations = []; - - for(const animationParent of xml.animations) + if(Array.isArray(xml.animations)) { - if(Array.isArray(animationParent.animation)) + this._animations = []; + + for(const animationParent of xml.animations) { - for(const animation of animationParent.animation) this._animations.push(new AnimationXML(animation)); + if(Array.isArray(animationParent.animation)) + { + for(const animation of animationParent.animation) this._animations.push(new AnimationXML(animation)); + } } } } - if((xml.postures !== undefined) && xml.postures.length) + if(xml.postures !== undefined) { - this._postures = []; - - for(const postureParent of xml.postures) + if(Array.isArray(xml.postures)) { - if(Array.isArray(postureParent.posture)) + this._postures = []; + + for(const postureParent of xml.postures) { - for(const posture of postureParent.posture) this._postures.push(new PostureXML(posture)); + if(Array.isArray(postureParent.posture)) + { + for(const posture of postureParent.posture) this._postures.push(new PostureXML(posture)); + } } } } if(xml.gestures !== undefined) { - this._gestures = []; - - for(const gestureParent of xml.gestures) + if(Array.isArray(xml.gestures)) { - if(Array.isArray(gestureParent.gesture)) + this._gestures = []; + + for(const gestureParent of xml.gestures) { - for(const gesture of gestureParent.gesture) this._gestures.push(new GestureXML(gesture)); + if(Array.isArray(gestureParent.gesture)) + { + for(const gesture of gestureParent.gesture) this._gestures.push(new GestureXML(gesture)); + } } } } diff --git a/src/mapping/xml/asset/visualization/VisualizationXML.ts b/src/mapping/xml/asset/visualization/VisualizationXML.ts index e5b8d57..d4a4120 100644 --- a/src/mapping/xml/asset/visualization/VisualizationXML.ts +++ b/src/mapping/xml/asset/visualization/VisualizationXML.ts @@ -16,11 +16,18 @@ export class VisualizationXML if(xml.graphics !== undefined) { - this._visualizations = []; - if(Array.isArray(xml.graphics)) { - for(const graphic of xml.graphics) for(const visualization of graphic.visualization) this._visualizations.push(new VisualizationDataXML(visualization)); + this._visualizations = []; + + for(const graphic of xml.graphics) + { + if(Array.isArray(graphic.visualization)) + { + for(const visualization of graphic.visualization) this._visualizations.push(new VisualizationDataXML(visualization)); + + } + } } } } diff --git a/src/mapping/xml/asset/visualization/animation/AnimationLayerXML.ts b/src/mapping/xml/asset/visualization/animation/AnimationLayerXML.ts index 1f8607a..2870832 100644 --- a/src/mapping/xml/asset/visualization/animation/AnimationLayerXML.ts +++ b/src/mapping/xml/asset/visualization/animation/AnimationLayerXML.ts @@ -25,9 +25,12 @@ export class AnimationLayerXML if(xml.frameSequence !== undefined) { - this._frameSequences = []; + if(Array.isArray(xml.frameSequence)) + { + this._frameSequences = []; - for(const frameSequence of xml.frameSequence) this._frameSequences.push(new FrameSequenceXML(frameSequence)); + for(const frameSequence of xml.frameSequence) this._frameSequences.push(new FrameSequenceXML(frameSequence)); + } } } diff --git a/src/mapping/xml/asset/visualization/animation/AnimationXML.ts b/src/mapping/xml/asset/visualization/animation/AnimationXML.ts index c6fd5b4..16df2f9 100644 --- a/src/mapping/xml/asset/visualization/animation/AnimationXML.ts +++ b/src/mapping/xml/asset/visualization/animation/AnimationXML.ts @@ -22,9 +22,12 @@ export class AnimationXML if(xml.animationLayer !== undefined) { - this._layers = []; + if(Array.isArray(xml.animationLayer)) + { + this._layers = []; - for(const animationLayer of xml.animationLayer) this._layers.push(new AnimationLayerXML(animationLayer)); + for(const animationLayer of xml.animationLayer) this._layers.push(new AnimationLayerXML(animationLayer)); + } } } diff --git a/src/mapping/xml/asset/visualization/animation/FrameSequenceXML.ts b/src/mapping/xml/asset/visualization/animation/FrameSequenceXML.ts index 52abe03..3c4b9d6 100644 --- a/src/mapping/xml/asset/visualization/animation/FrameSequenceXML.ts +++ b/src/mapping/xml/asset/visualization/animation/FrameSequenceXML.ts @@ -19,9 +19,12 @@ export class FrameSequenceXML if(xml.frame !== undefined) { - this._frames = []; + if(Array.isArray(xml.frame)) + { + this._frames = []; - for(const frame of xml.frame) this._frames.push(new FrameXML(frame)); + for(const frame of xml.frame) this._frames.push(new FrameXML(frame)); + } } } diff --git a/src/mapping/xml/asset/visualization/animation/FrameXML.ts b/src/mapping/xml/asset/visualization/animation/FrameXML.ts index e4fd747..962c5f3 100644 --- a/src/mapping/xml/asset/visualization/animation/FrameXML.ts +++ b/src/mapping/xml/asset/visualization/animation/FrameXML.ts @@ -25,9 +25,18 @@ export class FrameXML if(xml.offsets !== undefined) { - this._offsets = []; + if(Array.isArray(xml.offsets)) + { + this._offsets = []; - for(const offsetParent of xml.offsets) for(const offset of offsetParent.offset) this._offsets.push(new FrameOffsetXML(offset)); + for(const offsetParent of xml.offsets) + { + if(Array.isArray(offsetParent.offset)) + { + for(const offset of offsetParent.offset) this._offsets.push(new FrameOffsetXML(offset)); + } + } + } } }