Add planet & particle systems to furni

This commit is contained in:
Bill 2021-08-11 23:07:23 -04:00
parent b5ee74ae95
commit e681a316a1
36 changed files with 723 additions and 61 deletions

View File

@ -27,11 +27,13 @@ import { ProductDataConverter } from './converters/productdata/ProductDataConver
FigureDataConverter
];
const [ arg1, arg2, ...rest ] = process.argv;
for(const converterClass of converters)
{
const converter = (container.resolve<any>(converterClass) as IConverter);
await converter.convertAsync();
await converter.convertAsync(rest);
}
})();

View File

@ -2,7 +2,7 @@ import { IConverter } from './IConverter';
export class Converter implements IConverter
{
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
return;
}

View File

@ -0,0 +1,7 @@
export class ConverterType
{
public static EFFECT_CONVERTER: string = 'effect';
public static FIGURE_CONVERTER: string = 'figure';
public static FURNITURE_CONVERTER: string = 'furni';
public static PET_CONVERTER: string = 'pet';
}

View File

@ -1,4 +1,4 @@
export interface IConverter
{
convertAsync(): Promise<void>;
convertAsync(args?: string[]): Promise<void>;
}

View File

@ -20,7 +20,7 @@ export class CatalogConverter extends SWFConverter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
if(!this._configuration.getBoolean('convert.catalog')) return;

View File

@ -22,7 +22,7 @@ export class EffectConverter extends SWFConverter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
if(!this._configuration.getBoolean('convert.effect')) return;

View File

@ -21,7 +21,7 @@ export class EffectMapConverter extends Converter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
return new Promise((resolve, reject) =>
{

View File

@ -19,7 +19,7 @@ export class ExternalTextsConverter extends Converter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
if(!this._configuration.getBoolean('convert.externaltexts')) return;

View File

@ -22,7 +22,7 @@ export class FigureConverter extends SWFConverter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
if(!this._configuration.getBoolean('convert.figure')) return;

View File

@ -21,7 +21,7 @@ export class FigureDataConverter extends Converter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
if(!this._configuration.getBoolean('convert.figuredata')) return;

View File

@ -21,7 +21,7 @@ export class FigureMapConverter extends Converter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
return new Promise((resolve, reject) =>
{

View File

@ -38,7 +38,7 @@ export class FurnitureConverter extends SWFConverter
{
await this._furniDownloader.download(directory, async (habboAssetSwf: HabboAssetSWF) =>
{
spinner.text = (`Parsing Furniture: ${ habboAssetSwf.getDocumentClass() } (${ this._furniDownloader.totalFinished } / ${ this._furniDownloader.totalItems })`);
spinner.text = (`Parsing Furniture: ${ habboAssetSwf.getDocumentClass() } (${ (this._furniDownloader.totalFinished + 1) } / ${ this._furniDownloader.totalItems })`);
spinner.render();

View File

@ -121,7 +121,7 @@ export class FurnitureDownloader
if(!url || !url.length) return;
url = url.replace('%revision%', revision.toString());
//url = url.replace('%revision%', revision.toString());
url = url.replace('%className%', className);
const logDownloads = this._configuration.getBoolean('misc.log_download_urls');

View File

@ -23,7 +23,7 @@ export class FurnitureDataConverter extends Converter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
return new Promise((resolve, reject) =>
{

View File

@ -22,7 +22,7 @@ export class PetConverter extends SWFConverter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
if(!this._configuration.getBoolean('convert.pet')) return;

View File

@ -19,7 +19,7 @@ export class ProductDataConverter extends Converter
super();
}
public async convertAsync(): Promise<void>
public async convertAsync(args: string[] = []): Promise<void>
{
if(!this._configuration.getBoolean('convert.productdata')) return;

View File

@ -3,7 +3,9 @@ import { IAsset } from './IAsset';
import { IAssetAlias } from './IAssetAlias';
import { IAssetDimension } from './IAssetDimension';
import { IAssetPalette } from './IAssetPalette';
import { IPlanetSystem } from './IPlanetSystem';
import { ISoundSample } from './ISoundSample';
import { IParticleSystem } from './particlesystem';
import { ISpritesheetData } from './spritesheet';
import { IAssetVisualizationData } from './visualization';
@ -16,6 +18,8 @@ export interface IAssetData {
credits?: string;
soundSample?: ISoundSample;
action?: { link?: string, startState?: number };
planetSystems?: IPlanetSystem[];
particleSystems?: IParticleSystem[];
spritesheet?: ISpritesheetData;
dimensions?: IAssetDimension;
directions?: number[];

View File

@ -0,0 +1,11 @@
export interface IPlanetSystem
{
id?: number;
name?: string;
parent?: string;
radius?: number;
arcSpeed?: number;
arcOffset?: number;
blend?: number;
height?: number;
}

View File

@ -4,5 +4,6 @@ export * from './IAssetAlias';
export * from './IAssetData';
export * from './IAssetDimension';
export * from './IAssetPalette';
export * from './IPlanetSystem';
export * from './spritesheet';
export * from './visualization';

View File

@ -0,0 +1,11 @@
import { IParticleSystemEmitter } from './IParticleSystemEmitter';
export interface IParticleSystem
{
size?: number;
canvasId?: number;
offsetY?: number;
blend?: number;
bgColor?: string;
emitters?: IParticleSystemEmitter[];
}

View File

@ -0,0 +1,15 @@
import { IParticleSystemParticle } from './IParticleSystemParticle';
import { IParticleSystemSimulation } from './IParticleSystemSimulation';
export interface IParticleSystemEmitter
{
id?: number;
name?: string;
spriteId?: number;
maxNumParticles?: number;
particlesPerFrame?: number;
burstPulse?: number;
fuseTime?: number;
simulation?: IParticleSystemSimulation;
particles?: IParticleSystemParticle[];
}

View File

@ -0,0 +1,7 @@
export interface IParticleSystemParticle
{
isEmitter?: boolean;
lifeTime?: number;
fade?: boolean;
frames?: string[];
}

View File

@ -0,0 +1,9 @@
export interface IParticleSystemSimulation
{
force?: number;
direction?: number;
gravity?: number;
airFriction?: number;
shape?: string;
energy?: number;
}

View File

@ -0,0 +1,4 @@
export * from './IParticleSystem';
export * from './IParticleSystemEmitter';
export * from './IParticleSystemParticle';
export * from './IParticleSystemSimulation';

View File

@ -1,5 +1,6 @@
import { IAssetData } from '../../json';
import { LogicXML } from '../../xml';
import { IAssetData, IPlanetSystem } from '../../json';
import { IParticleSystem, IParticleSystemEmitter, IParticleSystemParticle, IParticleSystemSimulation } from '../../json/asset/particlesystem';
import { LogicXML, ParticleSystemEmitterXML, ParticleSystemObjectXML, ParticleSystemParticleXML, ParticleSystemSimulationXML, PlanetSystemObjectXML } from '../../xml';
import { Mapper } from './Mapper';
export class LogicMapper extends Mapper
@ -71,5 +72,147 @@ export class LogicMapper extends Mapper
noPitch: xml.soundSample.noPitch
};
}
if(xml.planetSystem !== undefined)
{
if(!output.planetSystems)
{
output.planetSystems = [];
}
if(xml.planetSystem.objects !== undefined) LogicMapper.mapPlanetSystemXML(xml.planetSystem.objects, output.planetSystems);
}
if(xml.particleSystem !== undefined)
{
if(!output.particleSystems)
{
output.particleSystems = [];
}
if(xml.particleSystem.objects !== undefined) LogicMapper.mapParticleSystemXML(xml.particleSystem.objects, output.particleSystems);
}
}
private static mapPlanetSystemXML(xml: PlanetSystemObjectXML[], output: IPlanetSystem[]): void
{
if(!xml || !xml.length || !output) return;
for(const planetSystemObjectXML of xml)
{
const planetObject: IPlanetSystem = {};
if(planetSystemObjectXML.id !== undefined) planetObject.id = planetSystemObjectXML.id;
if(planetSystemObjectXML.name !== undefined) planetObject.name = planetSystemObjectXML.name;
if(planetSystemObjectXML.parent !== undefined) planetObject.parent = planetSystemObjectXML.parent;
if(planetSystemObjectXML.radius !== undefined) planetObject.radius = planetSystemObjectXML.radius;
if(planetSystemObjectXML.arcSpeed !== undefined) planetObject.arcSpeed = planetSystemObjectXML.arcSpeed;
if(planetSystemObjectXML.arcOffset !== undefined) planetObject.arcOffset = planetSystemObjectXML.arcOffset;
if(planetSystemObjectXML.blend !== undefined) planetObject.blend = planetSystemObjectXML.blend;
if(planetSystemObjectXML.height !== undefined) planetObject.height = planetSystemObjectXML.height;
output.push(planetObject);
}
}
private static mapParticleSystemXML(xml: ParticleSystemObjectXML[], output: IParticleSystem[]): void
{
if(!xml || !xml.length || !output) return;
for(const particleSystemXML of xml)
{
const particleObject: IParticleSystem = {};
if(particleSystemXML.size !== undefined) particleObject.size = particleSystemXML.size;
if(particleSystemXML.canvasId !== undefined) particleObject.canvasId = particleSystemXML.canvasId;
if(particleSystemXML.offsetY !== undefined) particleObject.offsetY = particleSystemXML.offsetY;
if(particleSystemXML.blend !== undefined) particleObject.blend = particleSystemXML.blend;
if(particleSystemXML.bgColor !== undefined) particleObject.bgColor = particleSystemXML.bgColor;
if(particleSystemXML.emitters !== undefined)
{
if(particleSystemXML.emitters.length)
{
particleObject.emitters = [];
LogicMapper.mapParticleSystemEmitterXML(particleSystemXML.emitters, particleObject.emitters);
}
}
output.push(particleObject);
}
}
private static mapParticleSystemEmitterXML(xml: ParticleSystemEmitterXML[], output: IParticleSystemEmitter[]): void
{
if(!xml || !xml.length || !output) return;
for(const particleSystemEmitterXML of xml)
{
const particleEmitter: IParticleSystemEmitter = {};
if(particleSystemEmitterXML.id !== undefined) particleEmitter.id = particleSystemEmitterXML.id;
if(particleSystemEmitterXML.name !== undefined) particleEmitter.name = particleSystemEmitterXML.name;
if(particleSystemEmitterXML.spriteId !== undefined) particleEmitter.spriteId = particleSystemEmitterXML.spriteId;
if(particleSystemEmitterXML.maxNumParticles !== undefined) particleEmitter.maxNumParticles = particleSystemEmitterXML.maxNumParticles;
if(particleSystemEmitterXML.particlesPerFrame !== undefined) particleEmitter.particlesPerFrame = particleSystemEmitterXML.particlesPerFrame;
if(particleSystemEmitterXML.burstPulse !== undefined) particleEmitter.burstPulse = particleSystemEmitterXML.burstPulse;
if(particleSystemEmitterXML.fuseTime !== undefined) particleEmitter.fuseTime = particleSystemEmitterXML.fuseTime;
if(particleSystemEmitterXML.simulation !== undefined)
{
particleEmitter.simulation = {};
LogicMapper.mapParticleSystemSimulationXML(particleSystemEmitterXML.simulation, particleEmitter.simulation);
}
if(particleSystemEmitterXML.particles !== undefined)
{
if(particleSystemEmitterXML.particles.length)
{
particleEmitter.particles = [];
LogicMapper.mapParticleSystemParticleXML(particleSystemEmitterXML.particles, particleEmitter.particles);
}
}
output.push(particleEmitter);
}
}
private static mapParticleSystemSimulationXML(xml: ParticleSystemSimulationXML, output: IParticleSystemSimulation): void
{
if(!xml || !output) return;
if(xml.force !== undefined) output.force = xml.force;
if(xml.direction !== undefined) output.direction = xml.direction;
if(xml.gravity !== undefined) output.gravity = xml.gravity;
if(xml.airFriction !== undefined) output.airFriction = xml.airFriction;
if(xml.shape !== undefined) output.shape = xml.shape;
if(xml.energy !== undefined) output.energy = xml.energy;
}
private static mapParticleSystemParticleXML(xml: ParticleSystemParticleXML[], output: IParticleSystemParticle[]): void
{
if(!xml || !xml.length || !output) return;
for(const particleSystemParticleXML of xml)
{
const particle: IParticleSystemParticle = {};
if(particleSystemParticleXML.isEmitter !== undefined) particle.isEmitter = particleSystemParticleXML.isEmitter;
if(particleSystemParticleXML.lifeTime !== undefined) particle.lifeTime = particleSystemParticleXML.lifeTime;
if(particleSystemParticleXML.fade !== undefined) particle.fade = particleSystemParticleXML.fade;
if(particleSystemParticleXML.frames !== undefined)
{
if(particleSystemParticleXML.frames.length)
{
particle.frames = particleSystemParticleXML.frames;
}
}
output.push(particle);
}
}
}

View File

@ -2,7 +2,9 @@ import { ActionXML } from './ActionXML';
import { CreditsXML } from './CreditsXML';
import { MaskXML } from './MaskXML';
import { ModelXML } from './model/ModelXML';
import {SoundSampleXML} from "./SoundSampleXML";
import { ParticleSystemXML } from './ParticleSystemXML';
import { PlanetSystemXML } from './PlanetSystemXML';
import { SoundSampleXML } from './SoundSampleXML';
export class LogicXML
{
@ -12,6 +14,8 @@ export class LogicXML
private readonly _mask: MaskXML;
private readonly _credits: CreditsXML;
private readonly _soundSample: SoundSampleXML;
private readonly _planetSystem: PlanetSystemXML;
private readonly _particleSystem: ParticleSystemXML;
constructor(xml: any)
{
@ -46,6 +50,16 @@ export class LogicXML
{
if(xml.sound[0] !== undefined) this._soundSample = new SoundSampleXML(xml.sound[0].sample);
}
if(xml.planetsystem !== undefined)
{
if(xml.planetsystem[0] !== undefined) this._planetSystem = new PlanetSystemXML(xml.planetsystem[0]);
}
if(xml.particlesystems !== undefined)
{
if(xml.particlesystems[0] !== undefined) this._particleSystem = new ParticleSystemXML(xml.particlesystems[0]);
}
}
public get type(): string
@ -58,23 +72,33 @@ export class LogicXML
return this._model;
}
public get action(): ActionXML | undefined
public get action(): ActionXML
{
return this._action;
}
public get mask(): MaskXML | undefined
public get mask(): MaskXML
{
return this._mask;
}
public get credits(): CreditsXML | undefined
public get credits(): CreditsXML
{
return this._credits;
}
public get soundSample(): SoundSampleXML | undefined
public get soundSample(): SoundSampleXML
{
return this._soundSample;
}
public get planetSystem(): PlanetSystemXML
{
return this._planetSystem;
}
public get particleSystem(): ParticleSystemXML
{
return this._particleSystem;
}
}

View File

@ -0,0 +1,91 @@
import { ParticleSystemParticleXML } from './ParticleSystemParticleXML';
import { ParticleSystemSimulationXML } from './ParticleSystemSimulationXML';
export class ParticleSystemEmitterXML
{
private _id: number;
private _name: string;
private _spriteId: number;
private _maxNumParticles: number;
private _particlesPerFrame: number;
private _burstPulse: number = 1;
private _fuseTime: number;
private _simulation: ParticleSystemSimulationXML;
private _particles: ParticleSystemParticleXML[];
constructor(xml: any)
{
const attributes = xml.$;
if(attributes !== undefined)
{
if(attributes.id !== undefined) this._id = parseInt(attributes.id);
if(attributes.name !== undefined) this._name = attributes.name;
if(attributes.sprite_id !== undefined) this._spriteId = parseInt(attributes.sprite_id);
if(attributes.max_num_particles !== undefined) this._maxNumParticles = parseInt(attributes.max_num_particles);
if(attributes.particles_per_frame !== undefined) this._particlesPerFrame = parseInt(attributes.particles_per_frame);
if(attributes.burst_pulse !== undefined) this._burstPulse = parseInt(attributes.burst_pulse);
if(attributes.fuse_time !== undefined) this._fuseTime = parseInt(attributes.fuse_time);
}
if(xml.simulation !== undefined)
{
if(xml.simulation[0] !== undefined) this._simulation = new ParticleSystemSimulationXML(xml.simulation[0]);
}
if((xml.particles !== undefined) && (xml.particles[0] !== undefined))
{
if(Array.isArray(xml.particles[0].particle))
{
this._particles = [];
for(const particle of xml.particles[0].particle) this._particles.push(new ParticleSystemParticleXML(particle));
}
}
}
public get id(): number
{
return this._id;
}
public get name(): string
{
return this._name;
}
public get spriteId(): number
{
return this._spriteId;
}
public get maxNumParticles(): number
{
return this._maxNumParticles;
}
public get particlesPerFrame(): number
{
return this._particlesPerFrame;
}
public get burstPulse(): number
{
return this._burstPulse;
}
public get fuseTime(): number
{
return this._fuseTime;
}
public get simulation(): ParticleSystemSimulationXML
{
return this._simulation;
}
public get particles(): ParticleSystemParticleXML[]
{
return this._particles;
}
}

View File

@ -0,0 +1,65 @@
import { ParticleSystemEmitterXML } from './ParticleSystemEmitterXML';
export class ParticleSystemObjectXML
{
private readonly _size: number;
private readonly _canvasId: number;
private readonly _offsetY: number;
private readonly _blend: number;
private readonly _bgColor: string;
private readonly _emitters: ParticleSystemEmitterXML[];
constructor(xml: any)
{
const attributes = xml.$;
if(attributes !== undefined)
{
if(attributes.size !== undefined) this._size = parseInt(attributes.size);
if(attributes.canvas_id !== undefined) this._canvasId = parseInt(attributes.canvas_id);
if(attributes.offset_y !== undefined) this._offsetY = parseFloat(attributes.offset_y);
if(attributes.blend !== undefined) this._blend = parseFloat(attributes.blend);
if(attributes.bgcolor !== undefined) this._bgColor = attributes.bgcolor;
}
if(xml.emitter !== undefined)
{
if(Array.isArray(xml.emitter))
{
this._emitters = [];
for(const emitter of xml.emitter) this._emitters.push(new ParticleSystemEmitterXML(emitter));
}
}
}
public get size(): number
{
return this._size;
}
public get canvasId(): number
{
return this._canvasId;
}
public get offsetY(): number
{
return this._offsetY;
}
public get blend(): number
{
return this._blend;
}
public get bgColor(): string
{
return this._bgColor;
}
public get emitters(): ParticleSystemEmitterXML[]
{
return this._emitters;
}
}

View File

@ -0,0 +1,50 @@
export class ParticleSystemParticleXML
{
private readonly _isEmitter: boolean;
private readonly _lifeTime: number;
private readonly _fade: boolean;
private readonly _frames: string[];
constructor(xml: any)
{
const attributes = xml.$;
if(attributes !== undefined)
{
if(attributes.is_emitter !== undefined) this._isEmitter = (attributes.is_emitter === 'true');
if(attributes.lifetime !== undefined) this._lifeTime = parseInt(attributes.lifetime);
if(attributes.fade !== undefined) this._fade = (attributes.fade === 'true');
}
if(xml.frame !== undefined)
{
if(Array.isArray(xml.frame))
{
this._frames = [];
for(const frame of xml.frame) this._frames.push(frame.$.name);
}
}
}
public get isEmitter(): boolean
{
return this._isEmitter;
}
public get lifeTime(): number
{
return this._lifeTime;
}
public get fade(): boolean
{
return this._fade;
}
public get frames(): string[]
{
return this._frames;
}
}

View File

@ -0,0 +1,55 @@
export class ParticleSystemSimulationXML
{
private _force: number;
private _direction: number;
private _gravity: number;
private _airFriction: number;
private _shape: string;
private _energy: number;
constructor(xml: any)
{
const attributes = xml.$;
if(attributes !== undefined)
{
if(attributes.force !== undefined) this._force = parseFloat(attributes.force);
if(attributes.direction !== undefined) this._direction = parseFloat(attributes.direction);
if(attributes.gravity !== undefined) this._gravity = parseFloat(attributes.gravity);
if(attributes.airfriction !== undefined) this._airFriction = parseFloat(attributes.airfriction);
if(attributes.shape !== undefined) this._shape = attributes.shape;
if(attributes.energy !== undefined) this._energy = parseFloat(attributes.energy);
}
}
public get force(): number
{
return this._force;
}
public get direction(): number
{
return this._direction;
}
public get gravity(): number
{
return this._gravity;
}
public get airFriction(): number
{
return this._airFriction;
}
public get shape(): string
{
return this._shape;
}
public get energy(): number
{
return this._energy;
}
}

View File

@ -0,0 +1,24 @@
import { ParticleSystemObjectXML } from './ParticleSystemObjectXML';
export class ParticleSystemXML
{
private readonly _objects: ParticleSystemObjectXML[];
constructor(xml: any)
{
if(xml.particlesystem !== undefined)
{
if(Array.isArray(xml.particlesystem))
{
this._objects = [];
for(const object of xml.particlesystem) this._objects.push(new ParticleSystemObjectXML(object));
}
}
}
public get objects(): ParticleSystemObjectXML[]
{
return this._objects;
}
}

View File

@ -0,0 +1,68 @@
export class PlanetSystemObjectXML
{
private readonly _id: number;
private readonly _name: string;
private readonly _parent: string;
private readonly _radius: number;
private readonly _arcSpeed: number;
private readonly _arcOffset: number;
private readonly _blend: number;
private readonly _height: number;
constructor(xml: any)
{
const attributes = xml.$;
if(attributes !== undefined)
{
if(attributes.id !== undefined) this._id = parseInt(attributes.id);
if(attributes.name !== undefined) this._name = attributes.name;
if(attributes.parent !== undefined) this._parent = attributes.parent;
if(attributes.radius !== undefined) this._radius = parseFloat(attributes.radius);
if(attributes.arcspeed !== undefined) this._arcSpeed = parseFloat(attributes.arcspeed);
if(attributes.arcoffset !== undefined) this._arcOffset = parseFloat(attributes.arcoffset);
if(attributes.blend !== undefined) this._blend = parseFloat(attributes.blend);
if(attributes.height !== undefined) this._height = parseFloat(attributes.height);
}
}
public get id(): number
{
return this._id;
}
public get name(): string
{
return this._name;
}
public get parent(): string
{
return this._parent;
}
public get radius(): number
{
return this._radius;
}
public get arcSpeed(): number
{
return this._arcSpeed;
}
public get arcOffset(): number
{
return this._arcOffset;
}
public get blend(): number
{
return this._blend;
}
public get height(): number
{
return this._height;
}
}

View File

@ -0,0 +1,24 @@
import { PlanetSystemObjectXML } from './PlanetSystemObjectXML';
export class PlanetSystemXML
{
private readonly _objects: PlanetSystemObjectXML[];
constructor(xml: any)
{
if(xml.object !== undefined)
{
if(Array.isArray(xml.object))
{
this._objects = [];
for(const object of xml.object) this._objects.push(new PlanetSystemObjectXML(object));
}
}
}
public get objects(): PlanetSystemObjectXML[]
{
return this._objects;
}
}

View File

@ -3,4 +3,11 @@ export * from './CreditsXML';
export * from './LogicXML';
export * from './MaskXML';
export * from './model';
export * from './ParticleSystemEmitterXML';
export * from './ParticleSystemObjectXML';
export * from './ParticleSystemParticleXML';
export * from './ParticleSystemSimulationXML';
export * from './ParticleSystemXML';
export * from './PlanetSystemObjectXML';
export * from './PlanetSystemXML';
export * from './SoundSampleXML';

View File

@ -51,6 +51,16 @@ export class ManifestLibraryXML
}
}
public get name(): string
{
return this._name;
}
public get version(): string
{
return this._version;
}
public get assets(): ManifestLibraryAssetXML[]
{
return this._assets;

View File

@ -1,26 +1,31 @@
import CustomIterator from '../utils/CustomIterator';
import {readImagesDefineBitsLossless, readImagesJPEG3or4, readSwfAsync} from '../utils/SwfReader';
import {CharacterTag} from './tags/CharacterTag';
import {DefineBinaryDataTag} from './tags/DefineBinaryDataTag';
import {ImageTag} from './tags/ImageTag';
import {ITag} from './tags/ITag';
import {SymbolClassTag} from './tags/SymbolClassTag';
import { readImagesDefineBitsLossless, readImagesJPEG3or4, readSwfAsync } from '../utils/SwfReader';
import { CharacterTag } from './tags/CharacterTag';
import { DefineBinaryDataTag } from './tags/DefineBinaryDataTag';
import { ImageTag } from './tags/ImageTag';
import { ITag } from './tags/ITag';
import { SymbolClassTag } from './tags/SymbolClassTag';
export class HabboAssetSWF {
export class HabboAssetSWF
{
private readonly _tags: Array<ITag>;
private _documentClass: string | null = null;
constructor(
private readonly _data: string | Buffer
) {
)
{
this._tags = new Array<ITag>();
}
async setupAsync() {
async setupAsync()
{
const swf = await readSwfAsync(this._data);
for (const tag of swf.tags) {
for(const tag of swf.tags)
{
switch (tag.header.code) {
switch(tag.header.code)
{
case 76:
this._tags.push(new SymbolClassTag(tag.symbols));
break;
@ -97,37 +102,47 @@ export class HabboAssetSWF {
this.assignClassesToSymbols();
}
public imageTags(): Array<ImageTag> {
public imageTags(): Array<ImageTag>
{
return this._tags.filter((tag: ITag) => tag instanceof ImageTag).map(x => x as ImageTag);
}
public symbolTags(): Array<SymbolClassTag> {
public symbolTags(): Array<SymbolClassTag>
{
return this._tags.filter((tag: ITag) => tag instanceof SymbolClassTag).map(x => x as SymbolClassTag);
}
private binaryTags(): Array<DefineBinaryDataTag> {
private binaryTags(): Array<DefineBinaryDataTag>
{
return this._tags.filter((tag: ITag) => tag instanceof DefineBinaryDataTag).map(x => x as DefineBinaryDataTag);
}
private assignClassesToSymbols() {
private assignClassesToSymbols()
{
const classes: Map<number, string> = new Map();
let iterator: CustomIterator<ITag> = new CustomIterator(this._tags);
// eslint-disable-next-line no-constant-condition
while (true) {
while(true)
{
let t: ITag;
do {
if (!iterator.hasNext()) {
do
{
if(!iterator.hasNext())
{
iterator = new CustomIterator(this._tags);
while (iterator.hasNext()) {
while(iterator.hasNext())
{
t = iterator.next();
if (t instanceof CharacterTag) {
if(t instanceof CharacterTag)
{
const ct = t as CharacterTag;
if (classes.has(ct.characterId)) {
if(classes.has(ct.characterId))
{
// @ts-ignore
ct.className = classes.get(ct.characterId);
}
@ -138,37 +153,46 @@ export class HabboAssetSWF {
}
t = iterator.next();
} while (!(t instanceof SymbolClassTag));
} while(!(t instanceof SymbolClassTag));
const sct = t as SymbolClassTag;
for (let i = 0; i < sct.tags.length; ++i) {
if (!classes.has(sct.tags[i]) && !Array.from(classes.values()).includes(sct.names[i])) {
for(let i = 0; i < sct.tags.length; ++i)
{
if(!classes.has(sct.tags[i]) && !Array.from(classes.values()).includes(sct.names[i]))
{
classes.set(sct.tags[i], sct.names[i]);
}
}
}
}
public getBinaryTagByName(name: string): DefineBinaryDataTag | null {
public getBinaryTagByName(name: string): DefineBinaryDataTag | null
{
const streamTag = this.binaryTags()
.filter(tag => tag.className === name)[0];
if (streamTag === undefined) return null;
if(streamTag === undefined) return null;
return streamTag;
}
public getFullClassName(type: string, documentNameTwice: boolean): string {
public getFullClassName(type: string, documentNameTwice: boolean): string
{
return this.getFullClassNameSnake(type, documentNameTwice, false);
}
public getFullClassNameSnake(type: string, documentNameTwice: boolean, snakeCase: boolean): string {
public getFullClassNameSnake(type: string, documentNameTwice: boolean, snakeCase: boolean): string
{
let result: string = this.getDocumentClass() + '_';
if (documentNameTwice) {
if (snakeCase) {
if(documentNameTwice)
{
if(snakeCase)
{
//result += CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, this.swf.getDocumentClass()) + "_";
} else {
}
else
{
result += this.getDocumentClass() + '_';
}
}
@ -176,26 +200,32 @@ export class HabboAssetSWF {
return result + type;
}
public getDocumentClass(): string {
if (this._documentClass !== null) return this._documentClass;
public getDocumentClass(): string
{
if(this._documentClass !== null) return this._documentClass;
const iterator: CustomIterator<ITag> = new CustomIterator(this._tags);
// eslint-disable-next-line no-constant-condition
while (true) {
while(true)
{
let t: ITag;
do {
if (!iterator.hasNext()) {
do
{
if(!iterator.hasNext())
{
return '';
}
t = iterator.next();
} while (!(t instanceof SymbolClassTag));
} while(!(t instanceof SymbolClassTag));
const sc = t as SymbolClassTag;
for (let i = 0; i < sc.tags.length; ++i) {
if (sc.tags[i] == 0) {
for(let i = 0; i < sc.tags.length; ++i)
{
if(sc.tags[i] == 0)
{
this._documentClass = sc.names[i];
return this._documentClass;
}