2021-02-17 06:14:07 +01:00
|
|
|
import { wrap } from 'bytebuffer';
|
|
|
|
import { parseStringPromise } from 'xml2js';
|
2021-12-22 09:45:09 +01:00
|
|
|
import { AnimationMapper, AssetMapper, IAssetData, IndexMapper, LogicMapper, ManifestMapper, NitroBundle, SpriteBundle, VisualizationMapper } from '../common';
|
|
|
|
import { HabboAssetSWF } from './HabboAssetSWF';
|
|
|
|
import { DefineBinaryDataTag } from './tags';
|
|
|
|
|
|
|
|
export class SWFUtilities
|
2021-02-17 06:14:07 +01:00
|
|
|
{
|
2021-08-19 10:02:25 +02:00
|
|
|
private static removeComments(data: string): string
|
|
|
|
{
|
|
|
|
return data.replace(/<!--.*?-->/sg, '');
|
|
|
|
}
|
|
|
|
|
|
|
|
public static createNitroBundle(className: string, assetData: IAssetData, spriteBundle: SpriteBundle): NitroBundle
|
2021-02-18 01:10:33 +01:00
|
|
|
{
|
|
|
|
if(spriteBundle && (spriteBundle.spritesheet !== undefined)) assetData.spritesheet = spriteBundle.spritesheet;
|
|
|
|
|
|
|
|
const nitroBundle = new NitroBundle();
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
nitroBundle.addFile((className + '.json'), Buffer.from(JSON.stringify(assetData)));
|
2021-02-18 01:10:33 +01:00
|
|
|
|
|
|
|
if(spriteBundle && (spriteBundle.imageData !== undefined)) nitroBundle.addFile(spriteBundle.imageData.name, spriteBundle.imageData.buffer);
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
return nitroBundle;
|
2021-02-18 01:10:33 +01:00
|
|
|
}
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static getBinaryData(habboAssetSWF: HabboAssetSWF, type: string, documentNameTwice: boolean, snakeCase: boolean = false): DefineBinaryDataTag
|
2021-02-17 06:14:07 +01:00
|
|
|
{
|
2021-08-19 10:02:25 +02:00
|
|
|
let binaryName = habboAssetSWF.getFullClassName(type, documentNameTwice, snakeCase);
|
2021-02-17 06:14:07 +01:00
|
|
|
let tag = habboAssetSWF.getBinaryTagByName(binaryName);
|
|
|
|
|
|
|
|
if(!tag)
|
|
|
|
{
|
|
|
|
binaryName = habboAssetSWF.getFullClassNameSnake(type, documentNameTwice, true);
|
|
|
|
tag = habboAssetSWF.getBinaryTagByName(binaryName);
|
|
|
|
}
|
|
|
|
|
|
|
|
return tag;
|
|
|
|
}
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static async getManifestXML(habboAssetSWF: HabboAssetSWF, snakeCase: boolean = false): Promise<any>
|
2021-02-17 06:14:07 +01:00
|
|
|
{
|
2021-12-22 09:45:09 +01:00
|
|
|
const binaryData = SWFUtilities.getBinaryData(habboAssetSWF, 'manifest', false, snakeCase);
|
2021-02-17 06:14:07 +01:00
|
|
|
|
|
|
|
if(!binaryData) return null;
|
2021-02-17 06:30:41 +01:00
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
return await parseStringPromise(this.removeComments(binaryData.binaryData));
|
2021-02-17 06:14:07 +01:00
|
|
|
}
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static async getIndexXML(habboAssetSWF: HabboAssetSWF, snakeCase: boolean = false): Promise<any>
|
2021-02-17 06:14:07 +01:00
|
|
|
{
|
2021-12-22 09:45:09 +01:00
|
|
|
const binaryData = SWFUtilities.getBinaryData(habboAssetSWF, 'index', false, snakeCase);
|
2021-02-17 06:14:07 +01:00
|
|
|
|
|
|
|
if(!binaryData) return null;
|
2021-02-17 06:30:41 +01:00
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
return await parseStringPromise(this.removeComments(binaryData.binaryData));
|
2021-02-17 06:14:07 +01:00
|
|
|
}
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static async getAssetsXML(habboAssetSWF: HabboAssetSWF, snakeCase: boolean = false): Promise<any>
|
2021-02-17 06:14:07 +01:00
|
|
|
{
|
2021-12-22 09:45:09 +01:00
|
|
|
const binaryData = SWFUtilities.getBinaryData(habboAssetSWF, 'assets', true, snakeCase);
|
2021-02-18 07:03:08 +01:00
|
|
|
|
|
|
|
if(!binaryData) return null;
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
return await parseStringPromise(this.removeComments(binaryData.binaryData));
|
2021-02-18 07:03:08 +01:00
|
|
|
}
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static async getLogicXML(habboAssetSWF: HabboAssetSWF, snakeCase: boolean = false): Promise<any>
|
2021-02-18 07:03:08 +01:00
|
|
|
{
|
2021-12-22 09:45:09 +01:00
|
|
|
const binaryData = SWFUtilities.getBinaryData(habboAssetSWF, 'logic', true, snakeCase);
|
2021-02-17 06:14:07 +01:00
|
|
|
|
|
|
|
if(!binaryData) return null;
|
2021-02-17 06:30:41 +01:00
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
return await parseStringPromise(this.removeComments(binaryData.binaryData));
|
2021-02-17 06:14:07 +01:00
|
|
|
}
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static async getVisualizationXML(habboAssetSWF: HabboAssetSWF, snakeCase: boolean = false): Promise<any>
|
2021-02-17 06:14:07 +01:00
|
|
|
{
|
2021-12-22 09:45:09 +01:00
|
|
|
const binaryData = SWFUtilities.getBinaryData(habboAssetSWF, 'visualization', true, snakeCase);
|
2021-02-17 06:14:07 +01:00
|
|
|
|
|
|
|
if(!binaryData) return null;
|
2021-02-17 06:30:41 +01:00
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
return await parseStringPromise(this.removeComments(binaryData.binaryData));
|
2021-02-20 05:10:06 +01:00
|
|
|
}
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static async getAnimationXML(habboAssetSWF: HabboAssetSWF, snakeCase: boolean = false): Promise<any>
|
2021-02-20 05:10:06 +01:00
|
|
|
{
|
2021-12-22 09:45:09 +01:00
|
|
|
const binaryData = SWFUtilities.getBinaryData(habboAssetSWF, 'animation', false, snakeCase);
|
2021-02-20 05:10:06 +01:00
|
|
|
|
|
|
|
if(!binaryData) return null;
|
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
return await parseStringPromise(this.removeComments(binaryData.binaryData));
|
2021-02-17 06:14:07 +01:00
|
|
|
}
|
2021-02-18 01:10:33 +01:00
|
|
|
|
2021-08-19 10:02:25 +02:00
|
|
|
public static getPalette(habboAssetSWF: HabboAssetSWF, paletteName: string): [ number, number, number ][]
|
2021-02-18 01:10:33 +01:00
|
|
|
{
|
2021-12-22 09:45:09 +01:00
|
|
|
const binaryData = SWFUtilities.getBinaryData(habboAssetSWF, paletteName, false);
|
2021-02-18 01:10:33 +01:00
|
|
|
|
|
|
|
if(!binaryData || !binaryData.binaryDataBuffer) return null;
|
|
|
|
|
|
|
|
const byteBuffer = wrap(binaryData.binaryDataBuffer);
|
|
|
|
|
|
|
|
const paletteColors: [ number, number, number ][] = [];
|
|
|
|
|
|
|
|
let R = 0;
|
|
|
|
let G = 0;
|
|
|
|
let B = 0;
|
|
|
|
let counter = 1;
|
|
|
|
|
|
|
|
while((binaryData.binaryDataBuffer.length - byteBuffer.offset) > 0)
|
|
|
|
{
|
|
|
|
if(counter == 1) R = byteBuffer.readUint8();
|
|
|
|
|
|
|
|
else if(counter == 2) G = byteBuffer.readUint8();
|
|
|
|
|
|
|
|
else if(counter == 3)
|
|
|
|
{
|
|
|
|
B = byteBuffer.readUint8();
|
|
|
|
|
|
|
|
paletteColors.push([ R, G, B ]);
|
|
|
|
|
|
|
|
counter = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
counter++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return paletteColors;
|
|
|
|
}
|
2021-08-19 10:02:25 +02:00
|
|
|
|
|
|
|
public static async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string, snakeCase: boolean = false): Promise<IAssetData>
|
|
|
|
{
|
|
|
|
if(!habboAssetSWF) return null;
|
|
|
|
|
|
|
|
const output: IAssetData = {};
|
|
|
|
|
2022-01-18 16:17:38 +01:00
|
|
|
if(assetType) output.type = assetType;
|
2021-08-19 10:02:25 +02:00
|
|
|
|
|
|
|
const indexXML = await this.getIndexXML(habboAssetSWF, snakeCase);
|
|
|
|
|
|
|
|
if(indexXML) IndexMapper.mapXML(indexXML, output);
|
|
|
|
|
|
|
|
const manifestXML = await this.getManifestXML(habboAssetSWF, snakeCase);
|
|
|
|
|
|
|
|
if(manifestXML) ManifestMapper.mapXML(manifestXML, output);
|
|
|
|
|
|
|
|
const assetXML = await this.getAssetsXML(habboAssetSWF, snakeCase);
|
|
|
|
|
|
|
|
if(assetXML)
|
|
|
|
{
|
|
|
|
AssetMapper.mapXML(assetXML, output);
|
|
|
|
|
|
|
|
if(output.palettes !== undefined)
|
|
|
|
{
|
|
|
|
for(const paletteId in output.palettes)
|
|
|
|
{
|
|
|
|
const palette = output.palettes[paletteId];
|
|
|
|
|
|
|
|
const paletteColors = this.getPalette(habboAssetSWF, palette.source);
|
|
|
|
|
|
|
|
if(!paletteColors)
|
|
|
|
{
|
|
|
|
delete output.palettes[paletteId];
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const rgbs: [ number, number, number ][] = [];
|
|
|
|
|
|
|
|
for(const rgb of paletteColors) rgbs.push([ rgb[0], rgb[1], rgb[2] ]);
|
|
|
|
|
|
|
|
palette.rgb = rgbs;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const animationXML = await this.getAnimationXML(habboAssetSWF, snakeCase);
|
|
|
|
|
|
|
|
if(animationXML) AnimationMapper.mapXML(animationXML, output);
|
|
|
|
|
|
|
|
const logicXML = await this.getLogicXML(habboAssetSWF, snakeCase);
|
|
|
|
|
|
|
|
if(logicXML) LogicMapper.mapXML(logicXML, output);
|
|
|
|
|
|
|
|
const visualizationXML = await this.getVisualizationXML(habboAssetSWF, snakeCase);
|
|
|
|
|
|
|
|
if(visualizationXML) VisualizationMapper.mapXML(visualizationXML, output);
|
|
|
|
|
|
|
|
return output;
|
|
|
|
}
|
2021-02-17 06:14:07 +01:00
|
|
|
}
|