Add figures

This commit is contained in:
Bill 2021-02-18 01:03:08 -05:00
parent adbcec6e80
commit 812d0ee74d
33 changed files with 585 additions and 238 deletions

View File

@ -1,29 +1,20 @@
import 'reflect-metadata'; import 'reflect-metadata';
import { container } from 'tsyringe'; import { container } from 'tsyringe';
import { BundleProvider } from './common/bundle/BundleProvider';
import { Configuration } from './common/config/Configuration'; import { Configuration } from './common/config/Configuration';
import { FigureConverter } from './converters/figure/FigureConverter';
import { FurnitureConverter } from './converters/furniture/FurnitureConverter'; import { FurnitureConverter } from './converters/furniture/FurnitureConverter';
import { PetConverter } from './converters/pet/PetConverter'; import { PetConverter } from './converters/pet/PetConverter';
import { Mapper } from './mapping/mappers/asset/Mapper';
(async () => (async () =>
{ {
const config = container.resolve(Configuration); const config = container.resolve(Configuration);
await config.init(); await config.init();
const prohibitedSizes = (config.getValue('prohibited.sizes') || '').split(','); if(config.getBoolean('convert.figure'))
const prohibitedSizesAsset = []; {
const figureConverter = container.resolve(FigureConverter);
for(const prohibitedSize of prohibitedSizes) prohibitedSizesAsset.push('_' + prohibitedSize + '_'); await figureConverter.convertAsync();
}
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.furniture')) if(config.getBoolean('convert.furniture'))
{ {

View File

@ -1,19 +1,14 @@
import { packAsync } from 'free-tex-packer-core'; import { packAsync } from 'free-tex-packer-core';
import { singleton } from 'tsyringe'; import { singleton } from 'tsyringe';
import { HabboAssetSWF } from '../../swf/HabboAssetSWF'; import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
import { Configuration } from '../config/Configuration'; import { ImageBundle } from './ImageBundle';
import { SpriteBundle } from './SpriteBundle'; import { SpriteBundle } from './SpriteBundle';
@singleton() @singleton()
export class BundleProvider export class BundleProvider
{ {
public static PROHIBITED_SIZES: string[] = [];
public static imageSource: Map<string, string> = new Map(); public static imageSource: Map<string, string> = new Map();
constructor(private readonly _configuration: Configuration)
{}
public async generateSpriteSheet(habboAssetSWF: HabboAssetSWF): Promise<SpriteBundle> public async generateSpriteSheet(habboAssetSWF: HabboAssetSWF): Promise<SpriteBundle>
{ {
const tagList = habboAssetSWF.symbolTags(); const tagList = habboAssetSWF.symbolTags();
@ -26,7 +21,7 @@ export class BundleProvider
tags.push(...tag.tags); tags.push(...tag.tags);
} }
const images: { path: string, contents: Buffer }[] = []; const imageBundle = new ImageBundle();
const imageTags = habboAssetSWF.imageTags(); const imageTags = habboAssetSWF.imageTags();
@ -40,105 +35,62 @@ export class BundleProvider
if(names[i] == imageTag.className) continue; 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('_32_') >= 0) continue;
{
if(imageTag.className.indexOf(size) >= 0)
{
isProhibited = true;
break;
}
}
if(isProhibited) continue;
BundleProvider.imageSource.set(names[i].substring(habboAssetSWF.getDocumentClass().length + 1), imageTag.className.substring(habboAssetSWF.getDocumentClass().length + 1)); 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('_32_') >= 0) continue;
{
if(imageTag.className.indexOf(size) >= 0)
{
isProhibited = true;
break; imageBundle.addImage(imageTag.className, imageTag.imgData);
}
}
if(isProhibited) continue;
images.push({
path: imageTag.className,
contents: 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<SpriteBundle> async packImages(documentClass: string, imageBundle: ImageBundle): Promise<SpriteBundle>
{ {
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, { if(item.name.endsWith('.json'))
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')) 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.app;
delete bundle.spritesheet.meta.version; delete bundle.spritesheet.meta.version;
}
else
{
bundle.imageData = {
name: item.name,
buffer: item.buffer
};
}
} }
else
if(!bundle.spritesheet) throw new Error('Failed to parse SpriteSheet. ' + images[0].path);
if((bundle.spritesheet !== undefined) && (bundle.imageData !== undefined))
{ {
bundle.spritesheet.meta.image = bundle.imageData.name; bundle.imageData = {
name: item.name,
buffer: item.buffer
};
} }
return bundle;
} }
catch (error) if((bundle.spritesheet !== undefined) && (bundle.imageData !== undefined)) bundle.spritesheet.meta.image = bundle.imageData.name;
{
console.error('Image Packing Error', error);
}
return null; return bundle;
} }
} }

View File

@ -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;
}
}

View File

@ -3,7 +3,7 @@ import { ISpritesheetData } from '../../mapping/json';
export class SpriteBundle export class SpriteBundle
{ {
private _spritesheet: ISpritesheetData; private _spritesheet: ISpritesheetData;
private _imageData: { name: string, buffer: Buffer}; private _imageData: { name: string, buffer: Buffer };
public get spritesheet(): ISpritesheetData public get spritesheet(): ISpritesheetData
{ {

View File

@ -38,6 +38,24 @@ export class SWFConverter
return tag; return tag;
} }
protected static async getManifestXML(habboAssetSWF: HabboAssetSWF): Promise<any>
{
const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'manifest', false);
if(!binaryData) return null;
return await parseStringPromise(binaryData.binaryData);
}
protected static async getIndexXML(habboAssetSWF: HabboAssetSWF): Promise<any>
{
const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'index', false);
if(!binaryData) return null;
return await parseStringPromise(binaryData.binaryData);
}
protected static async getAssetsXML(habboAssetSWF: HabboAssetSWF): Promise<any> protected static async getAssetsXML(habboAssetSWF: HabboAssetSWF): Promise<any>
{ {
const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'assets', true); const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'assets', true);
@ -56,15 +74,6 @@ export class SWFConverter
return await parseStringPromise(binaryData.binaryData); return await parseStringPromise(binaryData.binaryData);
} }
protected static async getIndexXML(habboAssetSWF: HabboAssetSWF): Promise<any>
{
const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'index', false);
if(!binaryData) return null;
return await parseStringPromise(binaryData.binaryData);
}
protected static async getVisualizationXML(habboAssetSWF: HabboAssetSWF): Promise<any> protected static async getVisualizationXML(habboAssetSWF: HabboAssetSWF): Promise<any>
{ {
const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'visualization', true); const binaryData = SWFConverter.getBinaryData(habboAssetSWF, 'visualization', true);

View File

@ -14,6 +14,5 @@
"convert.furniture": "1", "convert.furniture": "1",
"convert.figure": "0", "convert.figure": "0",
"convert.effect": "0", "convert.effect": "0",
"convert.pet": "1", "convert.pet": "1"
"prohibited.sizes": "32,sh"
} }

View File

@ -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<void>
{
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<IAssetData>
{
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;
}
}

View File

@ -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<string, string> = new Map();
constructor(private readonly _configuration: Configuration)
{}
public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
{
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<IFigureMap>
{
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<void>): Promise<void>
{
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);
}
}

View File

@ -40,8 +40,8 @@ export class FurnitureConverter extends SWFConverter
spinner.render(); spinner.render();
const assetData = await this.mapXML2JSON(habboAssetSwf, 'furniture');
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf); const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
const assetData = await this.mapXML2JSON(habboAssetSwf, 'furniture');
await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'furniture', assetData, spriteBundle); await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'furniture', assetData, spriteBundle);
}); });

View File

@ -39,7 +39,7 @@ export class FurnitureDownloader
catch (error) catch (error)
{ {
console.log(); console.log();
console.error(error.message); console.error(error);
} }
} }
} }
@ -66,7 +66,7 @@ export class FurnitureDownloader
catch (error) catch (error)
{ {
console.log(); console.log();
console.error(`Error parsing ${ className }: ` + error.message); console.error(error);
} }
} }
} }

View File

@ -40,8 +40,8 @@ export class PetConverter extends SWFConverter
spinner.render(); spinner.render();
const assetData = await this.mapXML2JSON(habboAssetSwf, 'pet');
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf); const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
const assetData = await this.mapXML2JSON(habboAssetSwf, 'pet');
await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'pet', assetData, spriteBundle); await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'pet', assetData, spriteBundle);
}); });

View File

@ -9,31 +9,37 @@ export class AssetMapper extends Mapper
{ {
if(!assets || !output) return; 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 private static mapAssetsXML(xml: AssetsXML, output: IAssetData): void
{ {
if(!xml) return; if(!xml || !output) return;
if(xml.assets !== undefined) 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) 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 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) for(const assetXML of xml)
{ {
@ -41,51 +47,35 @@ export class AssetMapper extends Mapper
if(assetXML.name !== undefined) 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) asset.source = assetXML.source;
{
isProhibited = true;
break; if(BundleProvider.imageSource.has(assetXML.source)) asset.source = BundleProvider.imageSource.get(assetXML.source) as string;
}
} }
if(isProhibited) continue; if(assetXML.name !== undefined)
}
if(assetXML.source !== undefined)
{
asset.source = assetXML.source;
if(BundleProvider.imageSource.has(assetXML.source))
{ {
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 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) for(const paletteXML of xml)
{ {

View File

@ -13,7 +13,7 @@ export class IndexMapper extends Mapper
private static mapIndexXML(indexXML: IndexXML, output: IAssetData): void 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.type !== undefined) output.name = indexXML.type;
if(indexXML.logic !== undefined) output.logicType = indexXML.logic; if(indexXML.logic !== undefined) output.logicType = indexXML.logic;

View File

@ -13,7 +13,7 @@ export class LogicMapper extends Mapper
private static mapLogicXML(xml: LogicXML, output: IAssetData): void private static mapLogicXML(xml: LogicXML, output: IAssetData): void
{ {
if(!xml) return; if(!xml || !output) return;
if(xml.model !== undefined) if(xml.model !== undefined)
{ {

View File

@ -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]);
}
}
}

View File

@ -1,4 +1,2 @@
export class Mapper export class Mapper
{ {}
public static PROHIBITED_SIZES: string[] = [];
}

View File

@ -13,37 +13,28 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationXML(xml: VisualizationXML, output: IAssetData): void private static mapVisualizationXML(xml: VisualizationXML, output: IAssetData): void
{ {
if(!xml) return; if(!xml || !output) return;
if(xml.visualizations !== undefined) 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 private static mapVisualizationDataXML(xml: VisualizationDataXML[], output: IAssetVisualizationData[]): void
{ {
if(!xml || !xml.length) return; if(!xml || !xml.length || !output) return;
for(const visualizationDataXML of xml) for(const visualizationDataXML of xml)
{ {
if(visualizationDataXML.size !== undefined) if(visualizationDataXML.size !== undefined)
{ {
let isProhibited = false; if([ 32 ].indexOf(visualizationDataXML.size) >= 0) continue;
for(const size of VisualizationMapper.PROHIBITED_SIZES)
{
if(visualizationDataXML.size === parseInt(size))
{
isProhibited = true;
break;
}
}
if(isProhibited) continue;
} }
const visualizationData: IAssetVisualizationData = {}; const visualizationData: IAssetVisualizationData = {};
@ -118,7 +109,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationLayerXML(xml: LayerXML[], output: { [index: string]: IAssetVisualizationLayer }): void 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) for(const layerXML of xml)
{ {
@ -138,7 +129,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationDirectionXML(xml: VisualDirectionXML[], output: { [index: string]: IAssetVisualizationDirection }): void 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) for(const directionXML of xml)
{ {
@ -160,7 +151,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationColorXML(xml: ColorXML[], output: { [index: string]: IAssetColor }): void 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) for(const colorXML of xml)
{ {
@ -182,7 +173,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationColorLayerXML(xml: ColorLayerXML[], output: { [index: string]: IAssetColorLayer }): void 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) for(const colorLayerXML of xml)
{ {
@ -196,7 +187,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationAnimationXML(xml: AnimationXML[], output: { [index: string]: IAssetAnimation }): void 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) for(const animationXML of xml)
{ {
@ -222,7 +213,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationAnimationLayerXML(xml: AnimationLayerXML[], output: { [index: string]: IAssetAnimationLayer }): void 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) for(const animationLayerXML of xml)
{ {
@ -248,7 +239,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationFrameSequenceXML(xml: FrameSequenceXML[], output: { [index: string]: IAssetAnimationSequence }): void private static mapVisualizationFrameSequenceXML(xml: FrameSequenceXML[], output: { [index: string]: IAssetAnimationSequence }): void
{ {
if(!xml || !xml.length) return; if(!xml || !xml.length || !output) return;
let i = 0; let i = 0;
@ -277,7 +268,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationFrameSequenceFrameXML(xml: FrameXML[], output: { [index: string]: IAssetAnimationSequenceFrame }): void private static mapVisualizationFrameSequenceFrameXML(xml: FrameXML[], output: { [index: string]: IAssetAnimationSequenceFrame }): void
{ {
if(!xml || !xml.length) return; if(!xml || !xml.length || !output) return;
let i = 0; let i = 0;
@ -311,7 +302,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationFrameSequenceFrameOffsetXML(xml: FrameOffsetXML[], output: { [index: string]: IAssetAnimationSequenceFrameOffset }): void private static mapVisualizationFrameSequenceFrameOffsetXML(xml: FrameOffsetXML[], output: { [index: string]: IAssetAnimationSequenceFrameOffset }): void
{ {
if(!xml || !xml.length) return; if(!xml || !xml.length || !output) return;
const i = 0; const i = 0;
@ -329,7 +320,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationPostureXML(xml: PostureXML[], output: { [index: string]: IAssetPosture }): void 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) for(const postureXML of xml)
{ {
@ -344,7 +335,7 @@ export class VisualizationMapper extends Mapper
private static mapVisualizationGestureXML(xml: GestureXML[], output: { [index: string]: IAssetGesture }): void 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) for(const gestureXML of xml)
{ {

View File

@ -1,4 +1,5 @@
export * from './AssetMapper'; export * from './AssetMapper';
export * from './IndexMapper'; export * from './IndexMapper';
export * from './LogicMapper'; export * from './LogicMapper';
export * from './ManifestMapper';
export * from './VisualizationMapper'; export * from './VisualizationMapper';

View File

@ -8,17 +8,23 @@ export class AssetsXML
constructor(xml: any) 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 = []; 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));
} }
} }
} }

View File

@ -2,4 +2,5 @@ export * from './assets';
export * from './index'; export * from './index';
export * from './IndexXML'; export * from './IndexXML';
export * from './logic'; export * from './logic';
export * from './manifest';
export * from './visualization'; export * from './visualization';

View File

@ -15,10 +15,10 @@ export class ModelXML
if(xml.directions !== undefined) if(xml.directions !== undefined)
{ {
this._directions = [];
if(Array.isArray(xml.directions)) if(Array.isArray(xml.directions))
{ {
this._directions = [];
for(const directionParent of xml.directions) for(const directionParent of xml.directions)
{ {
if(Array.isArray(directionParent.direction)) for(const direction of directionParent.direction) this._directions.push(new ModelDirectionXML(direction.$)); if(Array.isArray(directionParent.direction)) for(const direction of directionParent.direction) this._directions.push(new ModelDirectionXML(direction.$));

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,4 @@
export * from './ManifestLibraryAssetParamXML';
export * from './ManifestLibraryAssetXML';
export * from './ManifestLibraryXML';
export * from './ManifestXML';

View File

@ -16,9 +16,12 @@ export class VisualDirectionXML
if(xml.layer !== undefined) 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));
}
} }
} }

View File

@ -31,78 +31,96 @@ export class VisualizationDataXML
if(xml.layers !== undefined) if(xml.layers !== undefined)
{ {
this._layers = []; if(Array.isArray(xml.layers))
for(const layerParent of 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) if(xml.directions !== undefined)
{ {
this._directions = []; if(Array.isArray(xml.directions))
for(const directionParent of 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) if(xml.colors !== undefined)
{ {
this._colors = []; if(Array.isArray(xml.colors))
for(const colorParent of 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) if(xml.animations !== undefined)
{ {
this._animations = []; if(Array.isArray(xml.animations))
for(const animationParent of 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 = []; if(Array.isArray(xml.postures))
for(const postureParent of 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) if(xml.gestures !== undefined)
{ {
this._gestures = []; if(Array.isArray(xml.gestures))
for(const gestureParent of 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));
}
} }
} }
} }

View File

@ -16,11 +16,18 @@ export class VisualizationXML
if(xml.graphics !== undefined) if(xml.graphics !== undefined)
{ {
this._visualizations = [];
if(Array.isArray(xml.graphics)) 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));
}
}
} }
} }
} }

View File

@ -25,9 +25,12 @@ export class AnimationLayerXML
if(xml.frameSequence !== undefined) 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));
}
} }
} }

View File

@ -22,9 +22,12 @@ export class AnimationXML
if(xml.animationLayer !== undefined) 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));
}
} }
} }

View File

@ -19,9 +19,12 @@ export class FrameSequenceXML
if(xml.frame !== undefined) 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));
}
} }
} }

View File

@ -25,9 +25,18 @@ export class FrameXML
if(xml.offsets !== undefined) 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));
}
}
}
} }
} }