mirror of
https://github.com/billsonnn/nitro-converter.git
synced 2024-11-26 17:30:52 +01:00
Add more converters
This commit is contained in:
parent
c3f894b231
commit
c54fddd5ea
2
.gitignore
vendored
2
.gitignore
vendored
@ -41,7 +41,7 @@ yarn-error.log
|
|||||||
testem.log
|
testem.log
|
||||||
/typings
|
/typings
|
||||||
.git
|
.git
|
||||||
error.log
|
*.log
|
||||||
|
|
||||||
# System Files
|
# System Files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
40
src/Main.ts
40
src/Main.ts
@ -2,21 +2,55 @@ import 'reflect-metadata';
|
|||||||
import { container } from 'tsyringe';
|
import { container } from 'tsyringe';
|
||||||
import { Configuration } from './common/config/Configuration';
|
import { Configuration } from './common/config/Configuration';
|
||||||
import { EffectConverter } from './converters/effect/EffectConverter';
|
import { EffectConverter } from './converters/effect/EffectConverter';
|
||||||
|
import { EffectMapConverter } from './converters/effectmap/EffectMapConverter';
|
||||||
import { FigureConverter } from './converters/figure/FigureConverter';
|
import { FigureConverter } from './converters/figure/FigureConverter';
|
||||||
|
import { FigureMapConverter } from './converters/figuremap/FigureMapConverter';
|
||||||
import { FurnitureConverter } from './converters/furniture/FurnitureConverter';
|
import { FurnitureConverter } from './converters/furniture/FurnitureConverter';
|
||||||
|
import { FurnitureDataConverter } from './converters/furnituredata/FurnitureDataConverter';
|
||||||
import { PetConverter } from './converters/pet/PetConverter';
|
import { PetConverter } from './converters/pet/PetConverter';
|
||||||
|
import { ProductDataConverter } from './converters/productdata/ProductDataConverter';
|
||||||
|
|
||||||
(async () =>
|
(async () =>
|
||||||
{
|
{
|
||||||
const config = container.resolve(Configuration);
|
const config = container.resolve(Configuration);
|
||||||
await config.init();
|
await config.init();
|
||||||
|
|
||||||
|
if(config.getBoolean('convert.figuremap'))
|
||||||
|
{
|
||||||
|
const figureMapConverter = container.resolve(FigureMapConverter);
|
||||||
|
await figureMapConverter.convertAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config.getBoolean('convert.effectmap'))
|
||||||
|
{
|
||||||
|
const effectMapConverter = container.resolve(EffectMapConverter);
|
||||||
|
await effectMapConverter.convertAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config.getBoolean('convert.furnidata'))
|
||||||
|
{
|
||||||
|
const furniDataConverter = container.resolve(FurnitureDataConverter);
|
||||||
|
await furniDataConverter.convertAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(config.getBoolean('convert.productdata'))
|
||||||
|
{
|
||||||
|
const productDataConverter = container.resolve(ProductDataConverter);
|
||||||
|
await productDataConverter.convertAsync();
|
||||||
|
}
|
||||||
|
|
||||||
if(config.getBoolean('convert.figure'))
|
if(config.getBoolean('convert.figure'))
|
||||||
{
|
{
|
||||||
const figureConverter = container.resolve(FigureConverter);
|
const figureConverter = container.resolve(FigureConverter);
|
||||||
await figureConverter.convertAsync();
|
await figureConverter.convertAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(config.getBoolean('convert.effect'))
|
||||||
|
{
|
||||||
|
const effectConverter = container.resolve(EffectConverter);
|
||||||
|
await effectConverter.convertAsync();
|
||||||
|
}
|
||||||
|
|
||||||
if(config.getBoolean('convert.furniture'))
|
if(config.getBoolean('convert.furniture'))
|
||||||
{
|
{
|
||||||
const furnitureConverter = container.resolve(FurnitureConverter);
|
const furnitureConverter = container.resolve(FurnitureConverter);
|
||||||
@ -28,10 +62,4 @@ import { PetConverter } from './converters/pet/PetConverter';
|
|||||||
const petConverter = container.resolve(PetConverter);
|
const petConverter = container.resolve(PetConverter);
|
||||||
await petConverter.convertAsync();
|
await petConverter.convertAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(config.getBoolean('convert.effect'))
|
|
||||||
{
|
|
||||||
const effectConverter = container.resolve(EffectConverter);
|
|
||||||
await effectConverter.convertAsync();
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
@ -14,26 +14,22 @@ export class Configuration
|
|||||||
|
|
||||||
public async init(): Promise<void>
|
public async init(): Promise<void>
|
||||||
{
|
{
|
||||||
for(const key of Object.keys(configuration)) this._config.set(key, configuration[key]);
|
this.parseConfiguration(configuration);
|
||||||
|
|
||||||
|
await this.loadExternalVariables();
|
||||||
|
|
||||||
|
this.parseConfiguration(configuration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async loadExternalVariables(): Promise<void>
|
public async loadExternalVariables(): Promise<void>
|
||||||
{
|
{
|
||||||
const url = this.getValue('external_vars.url');
|
const url = this.getValue('external.variables.url');
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const content = await FileUtilities.readFileAsString(url);
|
const content = await FileUtilities.readFileAsString(url);
|
||||||
const config: string[] = content.split('\n');
|
|
||||||
|
|
||||||
for(const configEntry of config)
|
this.parseExternalVariables(content);
|
||||||
{
|
|
||||||
const configEntrySplit = configEntry.split('=');
|
|
||||||
const configKey = configEntrySplit[0];
|
|
||||||
const configValue = configEntrySplit[1];
|
|
||||||
|
|
||||||
this._config.set(configKey, configValue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (error)
|
catch (error)
|
||||||
@ -43,19 +39,106 @@ export class Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public getBoolean(key: string): boolean
|
private parseConfiguration(content: Object): boolean
|
||||||
{
|
{
|
||||||
return this._config.get(key) === '1';
|
if(!content) return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const regex = new RegExp(/\${(.*?)}/g);
|
||||||
|
|
||||||
|
for(const key of Object.keys(configuration))
|
||||||
|
{
|
||||||
|
if(this._config.get(key))
|
||||||
|
{
|
||||||
|
if(!configuration[key].length) continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getValue(key: string, value: string = ''): string
|
this._config.set(key, this.interpolate(configuration[key], regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (e)
|
||||||
{
|
{
|
||||||
if(this._config.has(key))
|
console.log();
|
||||||
|
console.error(e);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private parseExternalVariables(content: string): boolean
|
||||||
{
|
{
|
||||||
// @ts-ignore
|
if(!content || (content === '')) return false;
|
||||||
return this._config.get(key);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
const regex = new RegExp(/\${(.*?)}/g);
|
||||||
|
const lines: string[] = content.split('\n');
|
||||||
|
|
||||||
|
for(const line of lines)
|
||||||
|
{
|
||||||
|
const [ key, value ] = line.split('=');
|
||||||
|
|
||||||
|
if(key.startsWith('landing.view')) continue;
|
||||||
|
|
||||||
|
this._config.set(key, this.interpolate((value || ''), regex));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (e)
|
||||||
|
{
|
||||||
|
console.log();
|
||||||
|
console.error(e);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interpolate(value: string, regex: RegExp = null): string
|
||||||
|
{
|
||||||
|
if(!regex) regex = new RegExp(/\${(.*?)}/g);
|
||||||
|
|
||||||
|
const pieces = value.match(regex);
|
||||||
|
|
||||||
|
if(pieces && pieces.length)
|
||||||
|
{
|
||||||
|
for(const piece of pieces)
|
||||||
|
{
|
||||||
|
const existing = this._config.get(this.removeInterpolateKey(piece));
|
||||||
|
|
||||||
|
if(existing) (value = value.replace(piece, existing));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private removeInterpolateKey(value: string): string
|
||||||
|
{
|
||||||
|
return value.replace('${', '').replace('}', '');
|
||||||
|
}
|
||||||
|
|
||||||
|
public getValue(key: string, value: string = ''): string
|
||||||
|
{
|
||||||
|
if(this._config.has(key)) return this._config.get(key);
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public setValue(key: string, value: string): void
|
||||||
|
{
|
||||||
|
this._config.set(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getBoolean(key: string): boolean
|
||||||
|
{
|
||||||
|
const value = this.getValue(key);
|
||||||
|
|
||||||
|
return ((value === 'true') || (value === '1'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
4
src/common/converters/Converter.ts
Normal file
4
src/common/converters/Converter.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export class Converter
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -6,8 +6,9 @@ import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
|||||||
import { DefineBinaryDataTag } from '../../swf/tags/DefineBinaryDataTag';
|
import { DefineBinaryDataTag } from '../../swf/tags/DefineBinaryDataTag';
|
||||||
import { NitroBundle } from '../../utils/NitroBundle';
|
import { NitroBundle } from '../../utils/NitroBundle';
|
||||||
import { SpriteBundle } from '../bundle/SpriteBundle';
|
import { SpriteBundle } from '../bundle/SpriteBundle';
|
||||||
|
import { Converter } from './Converter';
|
||||||
|
|
||||||
export class SWFConverter
|
export class SWFConverter extends Converter
|
||||||
{
|
{
|
||||||
protected async fromHabboAsset(habboAssetSWF: HabboAssetSWF, outputFolder: string, type: string, assetData: IAssetData, spriteBundle: SpriteBundle): Promise<void>
|
protected async fromHabboAsset(habboAssetSWF: HabboAssetSWF, outputFolder: string, type: string, assetData: IAssetData, spriteBundle: SpriteBundle): Promise<void>
|
||||||
{
|
{
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
{
|
|
||||||
"output.folder.furniture": "/converted-assets/furniture/",
|
|
||||||
"output.folder.figure": "/converted-assets/figure/",
|
|
||||||
"output.folder.effect": "/converted-assets/effect/",
|
|
||||||
"output.folder.pet": "/converted-assets/pet/",
|
|
||||||
"furnidata.url": "/gamedata/json/furnidata",
|
|
||||||
"figuremap.url": "/gamedata/figuremap.xml",
|
|
||||||
"effectmap.url": "/gamedata/effectmap.xml",
|
|
||||||
"external_vars.url": "/gamedata/external_variables.txt",
|
|
||||||
"dynamic.download.url.furniture": "/dcr/hof_furni/%className%.swf",
|
|
||||||
"dynamic.download.url.figure": "/gordon/PRODUCTION/%className%.swf",
|
|
||||||
"dynamic.download.url.effect": "/gordon/PRODUCTION/%className%.swf",
|
|
||||||
"dynamic.download.url.pet": "/gordon/PRODUCTION/%className%.swf",
|
|
||||||
"convert.furniture": "1",
|
|
||||||
"convert.figure": "1",
|
|
||||||
"convert.effect": "1",
|
|
||||||
"convert.pet": "1"
|
|
||||||
}
|
|
22
src/configuration.json.example
Normal file
22
src/configuration.json.example
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"output.folder": "C:/nitro-converted-assets/",
|
||||||
|
"flash.client.url": "",
|
||||||
|
"furnidata.load.url": "",
|
||||||
|
"productdata.load.url": "",
|
||||||
|
"figuremap.load.url": "${flash.client.url}figuremap.xml",
|
||||||
|
"effectmap.load.url": "${flash.client.url}effectmap.xml",
|
||||||
|
"dynamic.download.pet.url": "${flash.client.url}%className%.swf",
|
||||||
|
"dynamic.download.figure.url": "${flash.client.url}%className%.swf",
|
||||||
|
"dynamic.download.effect.url": "${flash.client.url}%className%.swf",
|
||||||
|
"flash.dynamic.download.url": "",
|
||||||
|
"dynamic.download.furniture.url": "${flash.dynamic.download.url}%revision%/%className%.swf",
|
||||||
|
"external.variables.url": "https://www.habbo.com/gamedata/external_variables/1",
|
||||||
|
"convert.furnidata": "1",
|
||||||
|
"convert.productdata": "1",
|
||||||
|
"convert.figuremap": "1",
|
||||||
|
"convert.effectmap": "1",
|
||||||
|
"convert.figure": "1",
|
||||||
|
"convert.effect": "1",
|
||||||
|
"convert.furniture": "1",
|
||||||
|
"convert.pet": "1"
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { IAssetData } from '../../mapping/json';
|
|||||||
import { AnimationMapper, ManifestMapper } from '../../mapping/mappers';
|
import { AnimationMapper, ManifestMapper } from '../../mapping/mappers';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import File from '../../utils/File';
|
import File from '../../utils/File';
|
||||||
import Logger from '../../utils/Logger';
|
import { Logger } from '../../utils/Logger';
|
||||||
import { EffectDownloader } from './EffectDownloader';
|
import { EffectDownloader } from './EffectDownloader';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
@ -28,9 +28,7 @@ export class EffectConverter extends SWFConverter
|
|||||||
|
|
||||||
const spinner = ora('Preparing Effects').start();
|
const spinner = ora('Preparing Effects').start();
|
||||||
|
|
||||||
const outputFolder = new File(this._configuration.getValue('output.folder.effect'));
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
if(!outputFolder.isDirectory()) outputFolder.mkdirs();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -43,7 +41,7 @@ export class EffectConverter extends SWFConverter
|
|||||||
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
||||||
const assetData = await this.mapXML2JSON(habboAssetSwf, className);
|
const assetData = await this.mapXML2JSON(habboAssetSwf, className);
|
||||||
|
|
||||||
await this.fromHabboAsset(habboAssetSwf, outputFolder.path, assetData.type, assetData, spriteBundle);
|
await this.fromHabboAsset(habboAssetSwf, directory.path, assetData.type, assetData, spriteBundle);
|
||||||
});
|
});
|
||||||
|
|
||||||
spinner.succeed(`Effects finished in ${ Date.now() - now }ms`);
|
spinner.succeed(`Effects finished in ${ Date.now() - now }ms`);
|
||||||
@ -55,23 +53,36 @@ export class EffectConverter extends SWFConverter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + 'effect');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
return gameDataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
||||||
{
|
{
|
||||||
if(!habboAssetSWF) return null;
|
if(!habboAssetSWF) return null;
|
||||||
|
|
||||||
const assetData: IAssetData = {};
|
const output: IAssetData = {};
|
||||||
|
|
||||||
assetData.name = assetType;
|
output.name = assetType;
|
||||||
assetData.type = EffectDownloader.EFFECT_TYPES.get(assetType);
|
output.type = EffectDownloader.EFFECT_TYPES.get(assetType);
|
||||||
|
|
||||||
const manifestXML = await EffectConverter.getManifestXML(habboAssetSWF);
|
const manifestXML = await EffectConverter.getManifestXML(habboAssetSWF);
|
||||||
|
|
||||||
if(manifestXML) ManifestMapper.mapXML(manifestXML, assetData);
|
if(manifestXML) ManifestMapper.mapXML(manifestXML, output);
|
||||||
|
|
||||||
const animationXML = await EffectConverter.getAnimationXML(habboAssetSWF);
|
const animationXML = await EffectConverter.getAnimationXML(habboAssetSWF);
|
||||||
|
|
||||||
if(animationXML) AnimationMapper.mapXML(animationXML, assetData);
|
if(animationXML) AnimationMapper.mapXML(animationXML, output);
|
||||||
|
|
||||||
return assetData;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,16 @@ import { Configuration } from '../../common/config/Configuration';
|
|||||||
import { IEffectMap } from '../../mapping/json';
|
import { IEffectMap } from '../../mapping/json';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import { FileUtilities } from '../../utils/FileUtilities';
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
|
import { Logger } from '../../utils/Logger';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
export class EffectDownloader
|
export class EffectDownloader
|
||||||
{
|
{
|
||||||
public static EFFECT_TYPES: Map<string, string> = new Map();
|
public static EFFECT_TYPES: Map<string, string> = new Map();
|
||||||
|
|
||||||
constructor(private readonly _configuration: Configuration)
|
constructor(
|
||||||
|
private readonly _configuration: Configuration,
|
||||||
|
private readonly _logger: Logger)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
||||||
@ -38,6 +41,8 @@ export class EffectDownloader
|
|||||||
{
|
{
|
||||||
console.log();
|
console.log();
|
||||||
console.error(`Error parsing ${ className }: ` + error.message);
|
console.error(`Error parsing ${ className }: ` + error.message);
|
||||||
|
|
||||||
|
this._logger.logError(`Error parsing ${ className }: ` + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,7 +50,7 @@ export class EffectDownloader
|
|||||||
|
|
||||||
public async parseEffectMap(): Promise<IEffectMap>
|
public async parseEffectMap(): Promise<IEffectMap>
|
||||||
{
|
{
|
||||||
const url = this._configuration.getValue('effectmap.url');
|
const url = this._configuration.getValue('effectmap.load.url');
|
||||||
|
|
||||||
if(!url || !url.length) return null;
|
if(!url || !url.length) return null;
|
||||||
|
|
||||||
@ -58,7 +63,7 @@ export class EffectDownloader
|
|||||||
|
|
||||||
public async extractEffect(className: string, callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
public async extractEffect(className: string, callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
||||||
{
|
{
|
||||||
let url = this._configuration.getValue('dynamic.download.url.effect');
|
let url = this._configuration.getValue('dynamic.download.effect.url');
|
||||||
|
|
||||||
if(!url || !url.length) return;
|
if(!url || !url.length) return;
|
||||||
|
|
||||||
|
94
src/converters/effectmap/EffectMapConverter.ts
Normal file
94
src/converters/effectmap/EffectMapConverter.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { writeFile } from 'fs/promises';
|
||||||
|
import * as ora from 'ora';
|
||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { parseStringPromise } from 'xml2js';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { Converter } from '../../common/converters/Converter';
|
||||||
|
import { IEffectMap } from '../../mapping/json';
|
||||||
|
import { EffectMapMapper } from '../../mapping/mappers';
|
||||||
|
import File from '../../utils/File';
|
||||||
|
import { Logger } from '../../utils/Logger';
|
||||||
|
import { EffectMapDownloader } from './EffectMapDownloader';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class EffectMapConverter extends Converter
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private readonly _effectMapDownloader: EffectMapDownloader,
|
||||||
|
private readonly _configuration: Configuration,
|
||||||
|
private readonly _logger: Logger)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async convertAsync(): Promise<void>
|
||||||
|
{
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
const spinner = ora('Preparing EffectMap').start();
|
||||||
|
|
||||||
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this._effectMapDownloader.download(async (content: string) =>
|
||||||
|
{
|
||||||
|
spinner.text = 'Parsing EffectMap';
|
||||||
|
|
||||||
|
spinner.render();
|
||||||
|
|
||||||
|
let effectMapString = content;
|
||||||
|
|
||||||
|
if(!effectMapString.startsWith('{'))
|
||||||
|
{
|
||||||
|
const xml = await parseStringPromise(effectMapString);
|
||||||
|
|
||||||
|
const effectMap = await this.mapXML2JSON(xml);
|
||||||
|
|
||||||
|
effectMapString = JSON.stringify(effectMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = directory.path + '/EffectMap.json';
|
||||||
|
|
||||||
|
await writeFile(path, effectMapString, 'utf8');
|
||||||
|
|
||||||
|
this._configuration.setValue('effectmap.load.url', path);
|
||||||
|
});
|
||||||
|
|
||||||
|
spinner.succeed(`EffectMap finished in ${ Date.now() - now }ms`);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
spinner.fail('EffectMap failed: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + '/gamedata');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
const jsonFolder = new File(gameDataFolder.path + '/json');
|
||||||
|
|
||||||
|
if(!jsonFolder.isDirectory()) jsonFolder.mkdirs();
|
||||||
|
|
||||||
|
return jsonFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async mapXML2JSON(xml: any): Promise<IEffectMap>
|
||||||
|
{
|
||||||
|
if(!xml) return null;
|
||||||
|
|
||||||
|
const output: IEffectMap = {};
|
||||||
|
|
||||||
|
EffectMapMapper.mapXML(xml, output);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
32
src/converters/effectmap/EffectMapDownloader.ts
Normal file
32
src/converters/effectmap/EffectMapDownloader.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class EffectMapDownloader
|
||||||
|
{
|
||||||
|
constructor(private readonly _configuration: Configuration)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public async download(callback: (content: string) => Promise<void>): Promise<void>
|
||||||
|
{
|
||||||
|
const effectMap = await this.parseEffectMap();
|
||||||
|
|
||||||
|
if(!effectMap) throw new Error('invalid_effect_map');
|
||||||
|
|
||||||
|
callback(effectMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async parseEffectMap(): Promise<string>
|
||||||
|
{
|
||||||
|
const url = this._configuration.getValue('effectmap.load.url');
|
||||||
|
|
||||||
|
if(!url || !url.length) return null;
|
||||||
|
|
||||||
|
const content = await FileUtilities.readFileAsString(url);
|
||||||
|
|
||||||
|
if(!content || !content.length) return null;
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { IAssetData } from '../../mapping/json';
|
|||||||
import { ManifestMapper } from '../../mapping/mappers';
|
import { ManifestMapper } from '../../mapping/mappers';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import File from '../../utils/File';
|
import File from '../../utils/File';
|
||||||
import Logger from '../../utils/Logger';
|
import { Logger } from '../../utils/Logger';
|
||||||
import { FigureDownloader } from './FigureDownloader';
|
import { FigureDownloader } from './FigureDownloader';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
@ -28,9 +28,7 @@ export class FigureConverter extends SWFConverter
|
|||||||
|
|
||||||
const spinner = ora('Preparing Figure').start();
|
const spinner = ora('Preparing Figure').start();
|
||||||
|
|
||||||
const outputFolder = new File(this._configuration.getValue('output.folder.figure'));
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
if(!outputFolder.isDirectory()) outputFolder.mkdirs();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -43,7 +41,7 @@ export class FigureConverter extends SWFConverter
|
|||||||
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
||||||
const assetData = await this.mapXML2JSON(habboAssetSwf, className);
|
const assetData = await this.mapXML2JSON(habboAssetSwf, className);
|
||||||
|
|
||||||
await this.fromHabboAsset(habboAssetSwf, outputFolder.path, assetData.type, assetData, spriteBundle);
|
await this.fromHabboAsset(habboAssetSwf, directory.path, assetData.type, assetData, spriteBundle);
|
||||||
});
|
});
|
||||||
|
|
||||||
spinner.succeed(`Figures finished in ${ Date.now() - now }ms`);
|
spinner.succeed(`Figures finished in ${ Date.now() - now }ms`);
|
||||||
@ -55,19 +53,32 @@ export class FigureConverter extends SWFConverter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + 'figure');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
return gameDataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
||||||
{
|
{
|
||||||
if(!habboAssetSWF) return null;
|
if(!habboAssetSWF) return null;
|
||||||
|
|
||||||
const assetData: IAssetData = {};
|
const output: IAssetData = {};
|
||||||
|
|
||||||
assetData.name = assetType;
|
output.name = assetType;
|
||||||
assetData.type = FigureDownloader.FIGURE_TYPES.get(assetType);
|
output.type = FigureDownloader.FIGURE_TYPES.get(assetType);
|
||||||
|
|
||||||
const manifestXML = await FigureConverter.getManifestXML(habboAssetSWF);
|
const manifestXML = await FigureConverter.getManifestXML(habboAssetSWF);
|
||||||
|
|
||||||
if(manifestXML) ManifestMapper.mapXML(manifestXML, assetData);
|
if(manifestXML) ManifestMapper.mapXML(manifestXML, output);
|
||||||
|
|
||||||
return assetData;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,16 @@ import { Configuration } from '../../common/config/Configuration';
|
|||||||
import { IFigureMap } from '../../mapping/json';
|
import { IFigureMap } from '../../mapping/json';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import { FileUtilities } from '../../utils/FileUtilities';
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
|
import { Logger } from '../../utils/Logger';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
export class FigureDownloader
|
export class FigureDownloader
|
||||||
{
|
{
|
||||||
public static FIGURE_TYPES: Map<string, string> = new Map();
|
public static FIGURE_TYPES: Map<string, string> = new Map();
|
||||||
|
|
||||||
constructor(private readonly _configuration: Configuration)
|
constructor(
|
||||||
|
private readonly _configuration: Configuration,
|
||||||
|
private readonly _logger: Logger)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
||||||
@ -40,6 +43,8 @@ export class FigureDownloader
|
|||||||
{
|
{
|
||||||
console.log();
|
console.log();
|
||||||
console.error(`Error parsing ${ className }: ` + error.message);
|
console.error(`Error parsing ${ className }: ` + error.message);
|
||||||
|
|
||||||
|
this._logger.logError(`Error parsing ${ className }: ` + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -47,7 +52,7 @@ export class FigureDownloader
|
|||||||
|
|
||||||
public async parseFigureMap(): Promise<IFigureMap>
|
public async parseFigureMap(): Promise<IFigureMap>
|
||||||
{
|
{
|
||||||
const url = this._configuration.getValue('figuremap.url');
|
const url = this._configuration.getValue('figuremap.load.url');
|
||||||
|
|
||||||
if(!url || !url.length) return null;
|
if(!url || !url.length) return null;
|
||||||
|
|
||||||
@ -60,7 +65,7 @@ export class FigureDownloader
|
|||||||
|
|
||||||
public async extractFigure(className: string, callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
public async extractFigure(className: string, callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
||||||
{
|
{
|
||||||
let url = this._configuration.getValue('dynamic.download.url.figure');
|
let url = this._configuration.getValue('dynamic.download.figure.url');
|
||||||
|
|
||||||
if(!url || !url.length) return;
|
if(!url || !url.length) return;
|
||||||
|
|
||||||
|
94
src/converters/figuremap/FigureMapConverter.ts
Normal file
94
src/converters/figuremap/FigureMapConverter.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { writeFile } from 'fs/promises';
|
||||||
|
import * as ora from 'ora';
|
||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { parseStringPromise } from 'xml2js';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { Converter } from '../../common/converters/Converter';
|
||||||
|
import { IFigureMap } from '../../mapping/json';
|
||||||
|
import { FigureMapMapper } from '../../mapping/mappers';
|
||||||
|
import File from '../../utils/File';
|
||||||
|
import { Logger } from '../../utils/Logger';
|
||||||
|
import { FigureMapDownloader } from './FigureMapDownloader';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class FigureMapConverter extends Converter
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private readonly _figureMapDownloader: FigureMapDownloader,
|
||||||
|
private readonly _configuration: Configuration,
|
||||||
|
private readonly _logger: Logger)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async convertAsync(): Promise<void>
|
||||||
|
{
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
const spinner = ora('Preparing FigureMap').start();
|
||||||
|
|
||||||
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this._figureMapDownloader.download(async (content: string) =>
|
||||||
|
{
|
||||||
|
spinner.text = 'Parsing FigureMap';
|
||||||
|
|
||||||
|
spinner.render();
|
||||||
|
|
||||||
|
let figureMapString = content;
|
||||||
|
|
||||||
|
if(!figureMapString.startsWith('{'))
|
||||||
|
{
|
||||||
|
const xml = await parseStringPromise(figureMapString);
|
||||||
|
|
||||||
|
const figureMap = await this.mapXML2JSON(xml);
|
||||||
|
|
||||||
|
figureMapString = JSON.stringify(figureMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = directory.path + '/FigureMap.json';
|
||||||
|
|
||||||
|
await writeFile(path, figureMapString, 'utf8');
|
||||||
|
|
||||||
|
this._configuration.setValue('figuremap.load.url', path);
|
||||||
|
});
|
||||||
|
|
||||||
|
spinner.succeed(`FigureMap finished in ${ Date.now() - now }ms`);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
spinner.fail('FigureMap failed: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + '/gamedata');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
const jsonFolder = new File(gameDataFolder.path + '/json');
|
||||||
|
|
||||||
|
if(!jsonFolder.isDirectory()) jsonFolder.mkdirs();
|
||||||
|
|
||||||
|
return jsonFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async mapXML2JSON(xml: any): Promise<IFigureMap>
|
||||||
|
{
|
||||||
|
if(!xml) return null;
|
||||||
|
|
||||||
|
const output: IFigureMap = {};
|
||||||
|
|
||||||
|
FigureMapMapper.mapXML(xml, output);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
32
src/converters/figuremap/FigureMapDownloader.ts
Normal file
32
src/converters/figuremap/FigureMapDownloader.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class FigureMapDownloader
|
||||||
|
{
|
||||||
|
constructor(private readonly _configuration: Configuration)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public async download(callback: (content: string) => Promise<void>): Promise<void>
|
||||||
|
{
|
||||||
|
const figureMap = await this.parseFigureMap();
|
||||||
|
|
||||||
|
if(!figureMap) throw new Error('invalid_figure_map');
|
||||||
|
|
||||||
|
callback(figureMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async parseFigureMap(): Promise<string>
|
||||||
|
{
|
||||||
|
const url = this._configuration.getValue('figuremap.load.url');
|
||||||
|
|
||||||
|
if(!url || !url.length) return null;
|
||||||
|
|
||||||
|
const content = await FileUtilities.readFileAsString(url);
|
||||||
|
|
||||||
|
if(!content || !content.length) return null;
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { IAssetData } from '../../mapping/json';
|
|||||||
import { AssetMapper, IndexMapper, LogicMapper, VisualizationMapper } from '../../mapping/mappers';
|
import { AssetMapper, IndexMapper, LogicMapper, VisualizationMapper } from '../../mapping/mappers';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import File from '../../utils/File';
|
import File from '../../utils/File';
|
||||||
import Logger from '../../utils/Logger';
|
import { Logger } from '../../utils/Logger';
|
||||||
import { FurnitureDownloader } from './FurnitureDownloader';
|
import { FurnitureDownloader } from './FurnitureDownloader';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
@ -28,9 +28,7 @@ export class FurnitureConverter extends SWFConverter
|
|||||||
|
|
||||||
const spinner = ora('Preparing Furniture').start();
|
const spinner = ora('Preparing Furniture').start();
|
||||||
|
|
||||||
const outputFolder = new File(this._configuration.getValue('output.folder.furniture'));
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
if(!outputFolder.isDirectory()) outputFolder.mkdirs();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -43,7 +41,7 @@ export class FurnitureConverter extends SWFConverter
|
|||||||
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
||||||
const assetData = await this.mapXML2JSON(habboAssetSwf, 'furniture');
|
const assetData = await this.mapXML2JSON(habboAssetSwf, 'furniture');
|
||||||
|
|
||||||
await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'furniture', assetData, spriteBundle);
|
await this.fromHabboAsset(habboAssetSwf, directory.path, 'furniture', assetData, spriteBundle);
|
||||||
});
|
});
|
||||||
|
|
||||||
spinner.succeed(`Furniture finished in ${ Date.now() - now }ms`);
|
spinner.succeed(`Furniture finished in ${ Date.now() - now }ms`);
|
||||||
@ -55,30 +53,43 @@ export class FurnitureConverter extends SWFConverter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + 'furniture');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
return gameDataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
||||||
{
|
{
|
||||||
if(!habboAssetSWF) return null;
|
if(!habboAssetSWF) return null;
|
||||||
|
|
||||||
const assetData: IAssetData = {};
|
const output: IAssetData = {};
|
||||||
|
|
||||||
assetData.type = assetType;
|
output.type = assetType;
|
||||||
|
|
||||||
const indexXML = await FurnitureConverter.getIndexXML(habboAssetSWF);
|
const indexXML = await FurnitureConverter.getIndexXML(habboAssetSWF);
|
||||||
|
|
||||||
if(indexXML) IndexMapper.mapXML(indexXML, assetData);
|
if(indexXML) IndexMapper.mapXML(indexXML, output);
|
||||||
|
|
||||||
const assetXML = await FurnitureConverter.getAssetsXML(habboAssetSWF);
|
const assetXML = await FurnitureConverter.getAssetsXML(habboAssetSWF);
|
||||||
|
|
||||||
if(assetXML) AssetMapper.mapXML(assetXML, assetData);
|
if(assetXML) AssetMapper.mapXML(assetXML, output);
|
||||||
|
|
||||||
const logicXML = await FurnitureConverter.getLogicXML(habboAssetSWF);
|
const logicXML = await FurnitureConverter.getLogicXML(habboAssetSWF);
|
||||||
|
|
||||||
if(logicXML) LogicMapper.mapXML(logicXML, assetData);
|
if(logicXML) LogicMapper.mapXML(logicXML, output);
|
||||||
|
|
||||||
const visualizationXML = await FurnitureConverter.getVisualizationXML(habboAssetSWF);
|
const visualizationXML = await FurnitureConverter.getVisualizationXML(habboAssetSWF);
|
||||||
|
|
||||||
if(visualizationXML) VisualizationMapper.mapXML(visualizationXML, assetData);
|
if(visualizationXML) VisualizationMapper.mapXML(visualizationXML, output);
|
||||||
|
|
||||||
return assetData;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,14 @@ import { Configuration } from '../../common/config/Configuration';
|
|||||||
import { IFurnitureData } from '../../mapping/json';
|
import { IFurnitureData } from '../../mapping/json';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import { FileUtilities } from '../../utils/FileUtilities';
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
|
import { Logger } from '../../utils/Logger';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
export class FurnitureDownloader
|
export class FurnitureDownloader
|
||||||
{
|
{
|
||||||
constructor(private readonly _configuration: Configuration)
|
constructor(
|
||||||
|
private readonly _configuration: Configuration,
|
||||||
|
private readonly _logger: Logger)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
public async download(callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
||||||
@ -39,7 +42,7 @@ export class FurnitureDownloader
|
|||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
console.log();
|
console.log();
|
||||||
console.error(error);
|
console.error(`Error parsing ${ className }: ` + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,7 +69,9 @@ export class FurnitureDownloader
|
|||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
console.log();
|
console.log();
|
||||||
console.error(error);
|
console.error(`Error parsing ${ className }: ` + error.message);
|
||||||
|
|
||||||
|
this._logger.logError(`Error parsing ${ className }: ` + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,7 +80,7 @@ export class FurnitureDownloader
|
|||||||
|
|
||||||
public async parseFurniData(): Promise<IFurnitureData>
|
public async parseFurniData(): Promise<IFurnitureData>
|
||||||
{
|
{
|
||||||
const url = this._configuration.getValue('furnidata.url');
|
const url = this._configuration.getValue('furnidata.load.url');
|
||||||
|
|
||||||
if(!url || !url.length) return null;
|
if(!url || !url.length) return null;
|
||||||
|
|
||||||
@ -88,7 +93,7 @@ export class FurnitureDownloader
|
|||||||
|
|
||||||
public async extractFurniture(revision: number, className: string, callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
public async extractFurniture(revision: number, className: string, callback: (habboAssetSwf: HabboAssetSWF, className: string) => Promise<void>): Promise<void>
|
||||||
{
|
{
|
||||||
let url = this._configuration.getValue('dynamic.download.url.furniture');
|
let url = this._configuration.getValue('dynamic.download.furniture.url');
|
||||||
|
|
||||||
if(!url || !url.length) return;
|
if(!url || !url.length) return;
|
||||||
|
|
||||||
|
94
src/converters/furnituredata/FurnitureDataConverter.ts
Normal file
94
src/converters/furnituredata/FurnitureDataConverter.ts
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
import { writeFile } from 'fs/promises';
|
||||||
|
import * as ora from 'ora';
|
||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { parseStringPromise } from 'xml2js';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { Converter } from '../../common/converters/Converter';
|
||||||
|
import { IFurnitureData } from '../../mapping/json';
|
||||||
|
import { FurnitureDataMapper } from '../../mapping/mappers';
|
||||||
|
import File from '../../utils/File';
|
||||||
|
import { Logger } from '../../utils/Logger';
|
||||||
|
import { FurnitureDataDownloader } from './FurnitureDataDownloader';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class FurnitureDataConverter extends Converter
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private readonly _furnitureDataDownloader: FurnitureDataDownloader,
|
||||||
|
private readonly _configuration: Configuration,
|
||||||
|
private readonly _logger: Logger)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async convertAsync(): Promise<void>
|
||||||
|
{
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
const spinner = ora('Preparing FurnitureData').start();
|
||||||
|
|
||||||
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this._furnitureDataDownloader.download(async (content: string) =>
|
||||||
|
{
|
||||||
|
spinner.text = 'Parsing FurnitureData';
|
||||||
|
|
||||||
|
spinner.render();
|
||||||
|
|
||||||
|
let furnitureDataString = content;
|
||||||
|
|
||||||
|
if(!furnitureDataString.startsWith('{'))
|
||||||
|
{
|
||||||
|
const xml = await parseStringPromise(furnitureDataString);
|
||||||
|
|
||||||
|
const furnitureData = await this.mapXML2JSON(xml);
|
||||||
|
|
||||||
|
furnitureDataString = JSON.stringify(furnitureData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = directory.path + '/FurnitureData.json';
|
||||||
|
|
||||||
|
await writeFile(path, furnitureDataString, 'utf8');
|
||||||
|
|
||||||
|
this._configuration.setValue('furnidata.load.url', path);
|
||||||
|
});
|
||||||
|
|
||||||
|
spinner.succeed(`FurnitureData finished in ${ Date.now() - now }ms`);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
spinner.fail('FurnitureData failed: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + '/gamedata');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
const jsonFolder = new File(gameDataFolder.path + '/json');
|
||||||
|
|
||||||
|
if(!jsonFolder.isDirectory()) jsonFolder.mkdirs();
|
||||||
|
|
||||||
|
return jsonFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async mapXML2JSON(xml: any): Promise<IFurnitureData>
|
||||||
|
{
|
||||||
|
if(!xml) return null;
|
||||||
|
|
||||||
|
const output: IFurnitureData = {};
|
||||||
|
|
||||||
|
FurnitureDataMapper.mapXML(xml, output);
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
32
src/converters/furnituredata/FurnitureDataDownloader.ts
Normal file
32
src/converters/furnituredata/FurnitureDataDownloader.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class FurnitureDataDownloader
|
||||||
|
{
|
||||||
|
constructor(private readonly _configuration: Configuration)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public async download(callback: (content: string) => Promise<void>): Promise<void>
|
||||||
|
{
|
||||||
|
const furnitureData = await this.parseFurnitureData();
|
||||||
|
|
||||||
|
if(!furnitureData) throw new Error('invalid_furniture_data');
|
||||||
|
|
||||||
|
callback(furnitureData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async parseFurnitureData(): Promise<string>
|
||||||
|
{
|
||||||
|
const url = this._configuration.getValue('furnidata.load.url');
|
||||||
|
|
||||||
|
if(!url || !url.length) return null;
|
||||||
|
|
||||||
|
const content = await FileUtilities.readFileAsString(url);
|
||||||
|
|
||||||
|
if(!content || !content.length) return null;
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { IAssetData } from '../../mapping/json';
|
|||||||
import { AssetMapper, IndexMapper, LogicMapper, VisualizationMapper } from '../../mapping/mappers';
|
import { AssetMapper, IndexMapper, LogicMapper, VisualizationMapper } from '../../mapping/mappers';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import File from '../../utils/File';
|
import File from '../../utils/File';
|
||||||
import Logger from '../../utils/Logger';
|
import { Logger } from '../../utils/Logger';
|
||||||
import { PetDownloader } from './PetDownloader';
|
import { PetDownloader } from './PetDownloader';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
@ -28,9 +28,7 @@ export class PetConverter extends SWFConverter
|
|||||||
|
|
||||||
const spinner = ora('Preparing Pets').start();
|
const spinner = ora('Preparing Pets').start();
|
||||||
|
|
||||||
const outputFolder = new File(this._configuration.getValue('output.folder.pet'));
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
if(!outputFolder.isDirectory()) outputFolder.mkdirs();
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -43,7 +41,7 @@ export class PetConverter extends SWFConverter
|
|||||||
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
const spriteBundle = await this._bundleProvider.generateSpriteSheet(habboAssetSwf);
|
||||||
const assetData = await this.mapXML2JSON(habboAssetSwf, 'pet');
|
const assetData = await this.mapXML2JSON(habboAssetSwf, 'pet');
|
||||||
|
|
||||||
await this.fromHabboAsset(habboAssetSwf, outputFolder.path, 'pet', assetData, spriteBundle);
|
await this.fromHabboAsset(habboAssetSwf, directory.path, 'pet', assetData, spriteBundle);
|
||||||
});
|
});
|
||||||
|
|
||||||
spinner.succeed(`Pets finished in ${ Date.now() - now }ms`);
|
spinner.succeed(`Pets finished in ${ Date.now() - now }ms`);
|
||||||
@ -55,35 +53,48 @@ export class PetConverter extends SWFConverter
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + 'pet');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
return gameDataFolder;
|
||||||
|
}
|
||||||
|
|
||||||
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
private async mapXML2JSON(habboAssetSWF: HabboAssetSWF, assetType: string): Promise<IAssetData>
|
||||||
{
|
{
|
||||||
if(!habboAssetSWF) return null;
|
if(!habboAssetSWF) return null;
|
||||||
|
|
||||||
const assetData: IAssetData = {};
|
const output: IAssetData = {};
|
||||||
|
|
||||||
assetData.type = assetType;
|
output.type = assetType;
|
||||||
|
|
||||||
const indexXML = await PetConverter.getIndexXML(habboAssetSWF);
|
const indexXML = await PetConverter.getIndexXML(habboAssetSWF);
|
||||||
|
|
||||||
if(indexXML) IndexMapper.mapXML(indexXML, assetData);
|
if(indexXML) IndexMapper.mapXML(indexXML, output);
|
||||||
|
|
||||||
const assetXML = await PetConverter.getAssetsXML(habboAssetSWF);
|
const assetXML = await PetConverter.getAssetsXML(habboAssetSWF);
|
||||||
|
|
||||||
if(assetXML)
|
if(assetXML)
|
||||||
{
|
{
|
||||||
AssetMapper.mapXML(assetXML, assetData);
|
AssetMapper.mapXML(assetXML, output);
|
||||||
|
|
||||||
if(assetData.palettes !== undefined)
|
if(output.palettes !== undefined)
|
||||||
{
|
{
|
||||||
for(const paletteId in assetData.palettes)
|
for(const paletteId in output.palettes)
|
||||||
{
|
{
|
||||||
const palette = assetData.palettes[paletteId];
|
const palette = output.palettes[paletteId];
|
||||||
|
|
||||||
const paletteColors = PetConverter.getPalette(habboAssetSWF, palette.source);
|
const paletteColors = PetConverter.getPalette(habboAssetSWF, palette.source);
|
||||||
|
|
||||||
if(!paletteColors)
|
if(!paletteColors)
|
||||||
{
|
{
|
||||||
delete assetData.palettes[paletteId];
|
delete output.palettes[paletteId];
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -99,12 +110,12 @@ export class PetConverter extends SWFConverter
|
|||||||
|
|
||||||
const logicXML = await PetConverter.getLogicXML(habboAssetSWF);
|
const logicXML = await PetConverter.getLogicXML(habboAssetSWF);
|
||||||
|
|
||||||
if(logicXML) LogicMapper.mapXML(logicXML, assetData);
|
if(logicXML) LogicMapper.mapXML(logicXML, output);
|
||||||
|
|
||||||
const visualizationXML = await PetConverter.getVisualizationXML(habboAssetSWF);
|
const visualizationXML = await PetConverter.getVisualizationXML(habboAssetSWF);
|
||||||
|
|
||||||
if(visualizationXML) VisualizationMapper.mapXML(visualizationXML, assetData);
|
if(visualizationXML) VisualizationMapper.mapXML(visualizationXML, output);
|
||||||
|
|
||||||
return assetData;
|
return output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,13 @@ import { singleton } from 'tsyringe';
|
|||||||
import { Configuration } from '../../common/config/Configuration';
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
|
||||||
import { FileUtilities } from '../../utils/FileUtilities';
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
import Logger from '../../utils/Logger';
|
import { Logger } from '../../utils/Logger';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
export class PetDownloader
|
export class PetDownloader
|
||||||
{
|
{
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _config: Configuration,
|
private readonly _configuration: Configuration,
|
||||||
private readonly _logger: Logger)
|
private readonly _logger: Logger)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
@ -34,18 +34,18 @@ export class PetDownloader
|
|||||||
catch (error)
|
catch (error)
|
||||||
{
|
{
|
||||||
console.log();
|
console.log();
|
||||||
console.error(error);
|
console.error(`Error parsing ${ petType }: ` + error.message);
|
||||||
|
|
||||||
|
this._logger.logError(`Error parsing ${ petType }: ` + error.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async parsePetTypes(): Promise<string[]>
|
public async parsePetTypes(): Promise<string[]>
|
||||||
{
|
{
|
||||||
await this._config.loadExternalVariables();
|
|
||||||
|
|
||||||
const petTypes: string[] = [];
|
const petTypes: string[] = [];
|
||||||
|
|
||||||
const pets = this._config.getValue('pet.configuration');
|
const pets = this._configuration.getValue('pet.configuration');
|
||||||
|
|
||||||
if(pets)
|
if(pets)
|
||||||
{
|
{
|
||||||
@ -59,7 +59,7 @@ export class PetDownloader
|
|||||||
|
|
||||||
public async extractPet(className: string, callback: (habboAssetSwf: HabboAssetSWF) => Promise<void>): Promise<void>
|
public async extractPet(className: string, callback: (habboAssetSwf: HabboAssetSWF) => Promise<void>): Promise<void>
|
||||||
{
|
{
|
||||||
let url = this._config.getValue('dynamic.download.url.pet');
|
let url = this._configuration.getValue('dynamic.download.pet.url');
|
||||||
|
|
||||||
if(!url || !url.length) return;
|
if(!url || !url.length) return;
|
||||||
|
|
||||||
|
118
src/converters/productdata/ProductDataConverter.ts
Normal file
118
src/converters/productdata/ProductDataConverter.ts
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
import { writeFile } from 'fs/promises';
|
||||||
|
import * as ora from 'ora';
|
||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { Converter } from '../../common/converters/Converter';
|
||||||
|
import { IProductData } from '../../mapping/json';
|
||||||
|
import File from '../../utils/File';
|
||||||
|
import { Logger } from '../../utils/Logger';
|
||||||
|
import { ProductDataDownloader } from './ProductDataDownloader';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class ProductDataConverter extends Converter
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
private readonly _productDataDownloader: ProductDataDownloader,
|
||||||
|
private readonly _configuration: Configuration,
|
||||||
|
private readonly _logger: Logger)
|
||||||
|
{
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async convertAsync(): Promise<void>
|
||||||
|
{
|
||||||
|
const now = Date.now();
|
||||||
|
|
||||||
|
const spinner = ora('Preparing ProductData').start();
|
||||||
|
|
||||||
|
const directory = this.getDirectory();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await this._productDataDownloader.download(async (content: string) =>
|
||||||
|
{
|
||||||
|
spinner.text = 'Parsing FurnitureData';
|
||||||
|
|
||||||
|
spinner.render();
|
||||||
|
|
||||||
|
let productDataString = content;
|
||||||
|
|
||||||
|
if(!productDataString.startsWith('{'))
|
||||||
|
{
|
||||||
|
const productData = await this.mapText2JSON(productDataString);
|
||||||
|
|
||||||
|
productDataString = JSON.stringify(productData);
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = directory.path + '/ProductData.json';
|
||||||
|
|
||||||
|
await writeFile(path, productDataString, 'utf8');
|
||||||
|
});
|
||||||
|
|
||||||
|
spinner.succeed(`ProductData finished in ${ Date.now() - now }ms`);
|
||||||
|
}
|
||||||
|
|
||||||
|
catch (error)
|
||||||
|
{
|
||||||
|
spinner.fail('ProductData failed: ' + error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDirectory(): File
|
||||||
|
{
|
||||||
|
const baseFolder = new File(this._configuration.getValue('output.folder'));
|
||||||
|
|
||||||
|
if(!baseFolder.isDirectory()) baseFolder.mkdirs();
|
||||||
|
|
||||||
|
const gameDataFolder = new File(baseFolder.path + '/gamedata');
|
||||||
|
|
||||||
|
if(!gameDataFolder.isDirectory()) gameDataFolder.mkdirs();
|
||||||
|
|
||||||
|
const jsonFolder = new File(gameDataFolder.path + '/json');
|
||||||
|
|
||||||
|
if(!jsonFolder.isDirectory()) jsonFolder.mkdirs();
|
||||||
|
|
||||||
|
return jsonFolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async mapText2JSON(text: string): Promise<IProductData>
|
||||||
|
{
|
||||||
|
if(!text) return null;
|
||||||
|
|
||||||
|
const output: IProductData = {
|
||||||
|
productdata: {
|
||||||
|
product: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
text = text.replace(/"{1,}/g, '');
|
||||||
|
|
||||||
|
const parts = text.split(/\n\r{1,}|\n{1,}|\r{1,}/mg);
|
||||||
|
|
||||||
|
for(const part of parts)
|
||||||
|
{
|
||||||
|
const set = part.match(/\[+?((.)*?)\]/g);
|
||||||
|
|
||||||
|
if(set)
|
||||||
|
{
|
||||||
|
for(const entry of set)
|
||||||
|
{
|
||||||
|
let value = entry.replace(/\[{1,}/mg, '');
|
||||||
|
value = entry.replace(/\]{1,}/mg, '');
|
||||||
|
|
||||||
|
value = value.replace('[[', '');
|
||||||
|
value = value.replace('[', '');
|
||||||
|
|
||||||
|
const pieces = value.split(',');
|
||||||
|
const code = pieces.shift();
|
||||||
|
const name = pieces.shift();
|
||||||
|
const description = pieces.join(',');
|
||||||
|
|
||||||
|
output.productdata.product.push({ code, name, description });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
}
|
32
src/converters/productdata/ProductDataDownloader.ts
Normal file
32
src/converters/productdata/ProductDataDownloader.ts
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { singleton } from 'tsyringe';
|
||||||
|
import { Configuration } from '../../common/config/Configuration';
|
||||||
|
import { FileUtilities } from '../../utils/FileUtilities';
|
||||||
|
|
||||||
|
@singleton()
|
||||||
|
export class ProductDataDownloader
|
||||||
|
{
|
||||||
|
constructor(private readonly _configuration: Configuration)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public async download(callback: (content: string) => Promise<void>): Promise<void>
|
||||||
|
{
|
||||||
|
const productData = await this.parseProductData();
|
||||||
|
|
||||||
|
if(!productData) throw new Error('invalid_product_data');
|
||||||
|
|
||||||
|
callback(productData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async parseProductData(): Promise<string>
|
||||||
|
{
|
||||||
|
const url = this._configuration.getValue('productdata.load.url');
|
||||||
|
|
||||||
|
if(!url || !url.length) return null;
|
||||||
|
|
||||||
|
const content = await FileUtilities.readFileAsString(url);
|
||||||
|
|
||||||
|
if(!content || !content.length) return null;
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
@ -2,5 +2,5 @@ import { IEffectMapLibrary } from './IEffectMapLibrary';
|
|||||||
|
|
||||||
export interface IEffectMap
|
export interface IEffectMap
|
||||||
{
|
{
|
||||||
effects: IEffectMapLibrary[];
|
effects?: IEffectMapLibrary[];
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
export interface IEffectMapLibrary
|
export interface IEffectMapLibrary
|
||||||
{
|
{
|
||||||
id: string;
|
id?: string;
|
||||||
lib: string;
|
lib?: string;
|
||||||
type: string;
|
type?: string;
|
||||||
revision: number;
|
revision?: number;
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,5 @@ import { IFigureMapLibrary } from './IFigureMapLibrary';
|
|||||||
|
|
||||||
export interface IFigureMap
|
export interface IFigureMap
|
||||||
{
|
{
|
||||||
libraries: IFigureMapLibrary[];
|
libraries?: IFigureMapLibrary[];
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ import { IFigureMapLibraryPart } from './IFigureMapLibraryPart';
|
|||||||
|
|
||||||
export interface IFigureMapLibrary
|
export interface IFigureMapLibrary
|
||||||
{
|
{
|
||||||
id: string;
|
id?: string;
|
||||||
revision: number;
|
revision?: number;
|
||||||
parts: IFigureMapLibraryPart[];
|
parts?: IFigureMapLibraryPart[];
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
export interface IFigureMapLibraryPart
|
export interface IFigureMapLibraryPart
|
||||||
{
|
{
|
||||||
id: number;
|
id?: number;
|
||||||
type: string;
|
type?: string;
|
||||||
}
|
}
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
export interface IFurnitureType
|
|
||||||
{
|
|
||||||
id: number;
|
|
||||||
classname: string;
|
|
||||||
revision: number;
|
|
||||||
category: string;
|
|
||||||
defaultdir: number;
|
|
||||||
xdim: number;
|
|
||||||
ydim: number;
|
|
||||||
partcolors: { color: string[] };
|
|
||||||
name: string;
|
|
||||||
description: string;
|
|
||||||
adurl: string;
|
|
||||||
offerid: number;
|
|
||||||
buyout: boolean;
|
|
||||||
rentofferid: number;
|
|
||||||
rentbuyout: boolean;
|
|
||||||
bc: boolean;
|
|
||||||
excludeddynamic: boolean;
|
|
||||||
customparams: string;
|
|
||||||
specialtype: number;
|
|
||||||
canstandon: boolean;
|
|
||||||
cansiton: boolean;
|
|
||||||
canlayon: boolean;
|
|
||||||
furniline: string;
|
|
||||||
environment: string;
|
|
||||||
rare: boolean;
|
|
||||||
}
|
|
@ -2,10 +2,10 @@ import { IFurnitureType } from './IFurnitureType';
|
|||||||
|
|
||||||
export class IFurnitureData
|
export class IFurnitureData
|
||||||
{
|
{
|
||||||
roomitemtypes: {
|
roomitemtypes?: {
|
||||||
furnitype: IFurnitureType[]
|
furnitype: IFurnitureType[]
|
||||||
};
|
};
|
||||||
wallitemtypes: {
|
wallitemtypes?: {
|
||||||
furnitype: IFurnitureType[]
|
furnitype: IFurnitureType[]
|
||||||
};
|
};
|
||||||
}
|
}
|
28
src/mapping/json/furnituredata/IFurnitureType.ts
Normal file
28
src/mapping/json/furnituredata/IFurnitureType.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export interface IFurnitureType
|
||||||
|
{
|
||||||
|
id?: number;
|
||||||
|
classname?: string;
|
||||||
|
revision?: number;
|
||||||
|
category?: string;
|
||||||
|
defaultdir?: number;
|
||||||
|
xdim?: number;
|
||||||
|
ydim?: number;
|
||||||
|
partcolors?: { color: string[] };
|
||||||
|
name?: string;
|
||||||
|
description?: string;
|
||||||
|
adurl?: string;
|
||||||
|
offerid?: number;
|
||||||
|
buyout?: boolean;
|
||||||
|
rentofferid?: number;
|
||||||
|
rentbuyout?: boolean;
|
||||||
|
bc?: boolean;
|
||||||
|
excludeddynamic?: boolean;
|
||||||
|
customparams?: string;
|
||||||
|
specialtype?: number;
|
||||||
|
canstandon?: boolean;
|
||||||
|
cansiton?: boolean;
|
||||||
|
canlayon?: boolean;
|
||||||
|
furniline?: string;
|
||||||
|
environment?: string;
|
||||||
|
rare?: boolean;
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
export * from './asset';
|
export * from './asset';
|
||||||
export * from './effectmap';
|
export * from './effectmap';
|
||||||
export * from './figuremap';
|
export * from './figuremap';
|
||||||
export * from './furnidata';
|
export * from './furnituredata';
|
||||||
|
export * from './productdata';
|
||||||
|
8
src/mapping/json/productdata/IProductData.ts
Normal file
8
src/mapping/json/productdata/IProductData.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { IProductType } from './IProductType';
|
||||||
|
|
||||||
|
export interface IProductData
|
||||||
|
{
|
||||||
|
productdata?: {
|
||||||
|
product: IProductType[]
|
||||||
|
};
|
||||||
|
}
|
6
src/mapping/json/productdata/IProductType.ts
Normal file
6
src/mapping/json/productdata/IProductType.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
export interface IProductType
|
||||||
|
{
|
||||||
|
code: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
}
|
2
src/mapping/json/productdata/index.ts
Normal file
2
src/mapping/json/productdata/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './IProductData';
|
||||||
|
export * from './IProductType';
|
45
src/mapping/mappers/EffectMapMapper.ts
Normal file
45
src/mapping/mappers/EffectMapMapper.ts
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import { IEffectMap, IEffectMapLibrary } from '../json';
|
||||||
|
import { EffectMapEffectXML, EffectMapXML } from '../xml';
|
||||||
|
import { Mapper } from './asset/Mapper';
|
||||||
|
|
||||||
|
export class EffectMapMapper extends Mapper
|
||||||
|
{
|
||||||
|
public static mapXML(xml: any, output: IEffectMap): void
|
||||||
|
{
|
||||||
|
if(!xml || !output) return;
|
||||||
|
|
||||||
|
if(xml.map !== undefined) EffectMapMapper.mapEffectMapXML(new EffectMapXML(xml.map), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapEffectMapXML(xml: EffectMapXML, output: IEffectMap): void
|
||||||
|
{
|
||||||
|
if(!xml || !output) return;
|
||||||
|
|
||||||
|
if(xml.effects !== undefined)
|
||||||
|
{
|
||||||
|
if(xml.effects.length)
|
||||||
|
{
|
||||||
|
output.effects = [];
|
||||||
|
|
||||||
|
EffectMapMapper.mapEffectMapLibrariesXML(xml.effects, output.effects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapEffectMapLibrariesXML(xml: EffectMapEffectXML[], output: IEffectMapLibrary[]): void
|
||||||
|
{
|
||||||
|
if(!xml || !xml.length || !output) return;
|
||||||
|
|
||||||
|
for(const libraryXML of xml)
|
||||||
|
{
|
||||||
|
const library: IEffectMapLibrary = {};
|
||||||
|
|
||||||
|
if(libraryXML.id !== undefined) library.id = libraryXML.id;
|
||||||
|
if(libraryXML.lib !== undefined) library.lib = libraryXML.lib;
|
||||||
|
if(libraryXML.type !== undefined) library.type = libraryXML.type;
|
||||||
|
if(libraryXML.revision !== undefined) library.revision = libraryXML.revision;
|
||||||
|
|
||||||
|
output.push(library);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
src/mapping/mappers/FigureMapMapper.ts
Normal file
68
src/mapping/mappers/FigureMapMapper.ts
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import { IFigureMap, IFigureMapLibrary, IFigureMapLibraryPart } from '../json';
|
||||||
|
import { FigureLibraryPartXML, FigureLibraryXML, FigureMapXML } from '../xml';
|
||||||
|
import { Mapper } from './asset/Mapper';
|
||||||
|
|
||||||
|
export class FigureMapMapper extends Mapper
|
||||||
|
{
|
||||||
|
public static mapXML(xml: any, output: IFigureMap): void
|
||||||
|
{
|
||||||
|
if(!xml || !output) return;
|
||||||
|
|
||||||
|
if(xml.map !== undefined) FigureMapMapper.mapFigureMapXML(new FigureMapXML(xml.map), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapFigureMapXML(xml: FigureMapXML, output: IFigureMap): void
|
||||||
|
{
|
||||||
|
if(!xml || !output) return;
|
||||||
|
|
||||||
|
if(xml.libraries !== undefined)
|
||||||
|
{
|
||||||
|
if(xml.libraries.length)
|
||||||
|
{
|
||||||
|
output.libraries = [];
|
||||||
|
|
||||||
|
FigureMapMapper.mapFigureMapLibrariesXML(xml.libraries, output.libraries);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapFigureMapLibrariesXML(xml: FigureLibraryXML[], output: IFigureMapLibrary[]): void
|
||||||
|
{
|
||||||
|
if(!xml || !xml.length || !output) return;
|
||||||
|
|
||||||
|
for(const libraryXML of xml)
|
||||||
|
{
|
||||||
|
const library: IFigureMapLibrary = {};
|
||||||
|
|
||||||
|
if(libraryXML.id !== undefined) library.id = libraryXML.id;
|
||||||
|
if(libraryXML.revision !== undefined) library.revision = libraryXML.revision;
|
||||||
|
|
||||||
|
if(libraryXML.parts !== undefined)
|
||||||
|
{
|
||||||
|
if(libraryXML.parts.length)
|
||||||
|
{
|
||||||
|
library.parts = [];
|
||||||
|
|
||||||
|
FigureMapMapper.mapFigureMapLibraryPartsXML(libraryXML.parts, library.parts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push(library);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapFigureMapLibraryPartsXML(xml: FigureLibraryPartXML[], output: IFigureMapLibraryPart[]): void
|
||||||
|
{
|
||||||
|
if(!xml || !xml.length || !output) return;
|
||||||
|
|
||||||
|
for(const libraryPartXML of xml)
|
||||||
|
{
|
||||||
|
const libraryPart: IFigureMapLibraryPart = {};
|
||||||
|
|
||||||
|
if(libraryPartXML.id !== undefined) libraryPart.id = libraryPartXML.id;
|
||||||
|
if(libraryPartXML.type !== undefined) libraryPart.type = libraryPartXML.type;
|
||||||
|
|
||||||
|
output.push(libraryPart);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
src/mapping/mappers/FurnitureDataMapper.ts
Normal file
90
src/mapping/mappers/FurnitureDataMapper.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
import { IFurnitureData, IFurnitureType } from '../json';
|
||||||
|
import { FurnitureDataXML, FurnitureTypeXML } from '../xml';
|
||||||
|
import { Mapper } from './asset/Mapper';
|
||||||
|
|
||||||
|
export class FurnitureDataMapper extends Mapper
|
||||||
|
{
|
||||||
|
public static mapXML(xml: any, output: IFurnitureData): void
|
||||||
|
{
|
||||||
|
if(!xml || !output) return;
|
||||||
|
|
||||||
|
if(xml.furnidata !== undefined) FurnitureDataMapper.mapFurnitureDataXML(new FurnitureDataXML(xml.furnidata), output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapFurnitureDataXML(xml: FurnitureDataXML, output: IFurnitureData): void
|
||||||
|
{
|
||||||
|
if(!xml || !output) return;
|
||||||
|
|
||||||
|
if(xml.floorItems !== undefined)
|
||||||
|
{
|
||||||
|
if(xml.floorItems.length)
|
||||||
|
{
|
||||||
|
output.roomitemtypes = {
|
||||||
|
furnitype: []
|
||||||
|
};
|
||||||
|
|
||||||
|
FurnitureDataMapper.mapFurnitureTypesXML(xml.floorItems, output.roomitemtypes.furnitype, 'floor');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(xml.wallItems !== undefined)
|
||||||
|
{
|
||||||
|
if(xml.wallItems.length)
|
||||||
|
{
|
||||||
|
output.wallitemtypes = {
|
||||||
|
furnitype: []
|
||||||
|
};
|
||||||
|
|
||||||
|
FurnitureDataMapper.mapFurnitureTypesXML(xml.wallItems, output.wallitemtypes.furnitype, 'wall');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static mapFurnitureTypesXML(xml: FurnitureTypeXML[], output: IFurnitureType[], type: string): void
|
||||||
|
{
|
||||||
|
if(!xml || !xml.length || !output) return;
|
||||||
|
|
||||||
|
for(const typeXML of xml)
|
||||||
|
{
|
||||||
|
const furnitureType: IFurnitureType = {};
|
||||||
|
|
||||||
|
furnitureType.id = typeXML.id;
|
||||||
|
furnitureType.classname = typeXML.classname;
|
||||||
|
furnitureType.revision = typeXML.revision;
|
||||||
|
furnitureType.category = typeXML.category;
|
||||||
|
|
||||||
|
if(type === 'floor')
|
||||||
|
{
|
||||||
|
furnitureType.defaultdir = typeXML.defaultdir;
|
||||||
|
furnitureType.xdim = typeXML.xdim;
|
||||||
|
furnitureType.ydim = typeXML.ydim;
|
||||||
|
furnitureType.partcolors = typeXML.partcolors;
|
||||||
|
}
|
||||||
|
|
||||||
|
furnitureType.name = typeXML.name;
|
||||||
|
furnitureType.description = typeXML.description;
|
||||||
|
furnitureType.adurl = typeXML.adurl;
|
||||||
|
furnitureType.offerid = typeXML.offerid;
|
||||||
|
furnitureType.buyout = typeXML.buyout;
|
||||||
|
furnitureType.rentofferid = typeXML.rentofferid;
|
||||||
|
furnitureType.rentbuyout = typeXML.rentbuyout;
|
||||||
|
furnitureType.bc = typeXML.bc;
|
||||||
|
furnitureType.excludeddynamic = typeXML.excludeddynamic;
|
||||||
|
furnitureType.customparams = typeXML.customparams;
|
||||||
|
furnitureType.specialtype = typeXML.specialtype;
|
||||||
|
|
||||||
|
if(type === 'floor')
|
||||||
|
{
|
||||||
|
furnitureType.canstandon = typeXML.canstandon;
|
||||||
|
furnitureType.cansiton = typeXML.cansiton;
|
||||||
|
furnitureType.canlayon = typeXML.canlayon;
|
||||||
|
}
|
||||||
|
|
||||||
|
furnitureType.furniline = typeXML.furniline;
|
||||||
|
furnitureType.environment = typeXML.environment;
|
||||||
|
furnitureType.rare = typeXML.rare;
|
||||||
|
|
||||||
|
output.push(furnitureType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,4 @@
|
|||||||
export * from './asset';
|
export * from './asset';
|
||||||
|
export * from './EffectMapMapper';
|
||||||
|
export * from './FigureMapMapper';
|
||||||
|
export * from './FurnitureDataMapper';
|
||||||
|
@ -1,26 +0,0 @@
|
|||||||
export class EffectLibraryPartXML
|
|
||||||
{
|
|
||||||
private _id: number;
|
|
||||||
private _type: string;
|
|
||||||
|
|
||||||
constructor(xml: any)
|
|
||||||
{
|
|
||||||
const attributes = xml.$;
|
|
||||||
|
|
||||||
if(attributes)
|
|
||||||
{
|
|
||||||
if(attributes.id !== undefined) this._id = parseInt(attributes.id);
|
|
||||||
if(attributes.type !== undefined) this._type = attributes.type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public get id(): number
|
|
||||||
{
|
|
||||||
return this._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get type(): string
|
|
||||||
{
|
|
||||||
return this._type;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,46 +0,0 @@
|
|||||||
import { EffectLibraryPartXML } from './EffectLibraryPartXML';
|
|
||||||
|
|
||||||
export class EffectLibraryXML
|
|
||||||
{
|
|
||||||
private _id: string;
|
|
||||||
private _revision: number;
|
|
||||||
private _parts: EffectLibraryPartXML[];
|
|
||||||
|
|
||||||
constructor(xml: any)
|
|
||||||
{
|
|
||||||
const attributes = xml.$;
|
|
||||||
|
|
||||||
if(attributes)
|
|
||||||
{
|
|
||||||
if(attributes.id !== undefined) this._id = attributes.id;
|
|
||||||
if(attributes.revision !== undefined) this._revision = parseInt(attributes.revision);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(xml.part !== undefined)
|
|
||||||
{
|
|
||||||
this._parts = [];
|
|
||||||
|
|
||||||
for(const partId in xml.part)
|
|
||||||
{
|
|
||||||
const part = xml.part[partId];
|
|
||||||
|
|
||||||
this._parts.push(new EffectLibraryPartXML(part));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public get id(): string
|
|
||||||
{
|
|
||||||
return this._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get revision(): number
|
|
||||||
{
|
|
||||||
return this._revision;
|
|
||||||
}
|
|
||||||
|
|
||||||
public get parts(): EffectLibraryPartXML[]
|
|
||||||
{
|
|
||||||
return this._parts;
|
|
||||||
}
|
|
||||||
}
|
|
41
src/mapping/xml/effectmap/EffectMapEffectXML.ts
Normal file
41
src/mapping/xml/effectmap/EffectMapEffectXML.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
export class EffectMapEffectXML
|
||||||
|
{
|
||||||
|
private _id: string;
|
||||||
|
private _lib: string;
|
||||||
|
private _type: string;
|
||||||
|
private _revision: number;
|
||||||
|
|
||||||
|
constructor(xml: any)
|
||||||
|
{
|
||||||
|
const attributes = xml.$;
|
||||||
|
|
||||||
|
if(attributes)
|
||||||
|
{
|
||||||
|
if(attributes.id !== undefined) this._id = attributes.id;
|
||||||
|
if(attributes.lib !== undefined) this._lib = attributes.lib;
|
||||||
|
if(attributes.type !== undefined) this._type = attributes.type;
|
||||||
|
if(attributes.revision !== undefined) this._revision = parseInt(attributes.revision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public get id(): string
|
||||||
|
{
|
||||||
|
return this._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get lib(): string
|
||||||
|
{
|
||||||
|
return this._lib;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get type(): string
|
||||||
|
{
|
||||||
|
return this._type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get revision(): number
|
||||||
|
{
|
||||||
|
return this._revision;
|
||||||
|
}
|
||||||
|
}
|
@ -1,29 +1,24 @@
|
|||||||
import { EffectLibraryXML } from './EffectLibraryXML';
|
import { EffectMapEffectXML } from './EffectMapEffectXML';
|
||||||
|
|
||||||
export class EffectMapXML
|
export class EffectMapXML
|
||||||
{
|
{
|
||||||
private _librares: EffectLibraryXML[];
|
private _effect: EffectMapEffectXML[];
|
||||||
|
|
||||||
constructor(xml: any)
|
constructor(xml: any)
|
||||||
{
|
{
|
||||||
if(xml.map !== undefined)
|
if(xml.effect !== undefined)
|
||||||
{
|
{
|
||||||
if(xml.map.lib !== undefined)
|
if(Array.isArray(xml.effect))
|
||||||
{
|
{
|
||||||
this._librares = [];
|
this._effect = [];
|
||||||
|
|
||||||
for(const lib in xml.map.lib)
|
for(const library of xml.effect) this._effect.push(new EffectMapEffectXML(library));
|
||||||
{
|
|
||||||
const library = xml.map.lib[lib];
|
|
||||||
|
|
||||||
this._librares.push(new EffectLibraryXML(library));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get libraries(): EffectLibraryXML[]
|
public get effects(): EffectMapEffectXML[]
|
||||||
{
|
{
|
||||||
return this._librares;
|
return this._effect;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,2 @@
|
|||||||
export * from './EffectLibraryPartXML';
|
export * from './EffectMapEffectXML';
|
||||||
export * from './EffectLibraryXML';
|
|
||||||
export * from './EffectMapXML';
|
export * from './EffectMapXML';
|
||||||
|
@ -17,6 +17,8 @@ export class FigureLibraryXML
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(xml.part !== undefined)
|
if(xml.part !== undefined)
|
||||||
|
{
|
||||||
|
if(Array.isArray(xml.part))
|
||||||
{
|
{
|
||||||
this._parts = [];
|
this._parts = [];
|
||||||
|
|
||||||
@ -28,6 +30,7 @@ export class FigureLibraryXML
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public get id(): string
|
public get id(): string
|
||||||
{
|
{
|
||||||
|
@ -6,15 +6,15 @@ export class FigureMapXML
|
|||||||
|
|
||||||
constructor(xml: any)
|
constructor(xml: any)
|
||||||
{
|
{
|
||||||
if(xml.map !== undefined)
|
if(xml.lib !== undefined)
|
||||||
{
|
{
|
||||||
if(xml.map.lib !== undefined)
|
if(Array.isArray(xml.lib))
|
||||||
{
|
{
|
||||||
this._librares = [];
|
this._librares = [];
|
||||||
|
|
||||||
for(const lib in xml.map.lib)
|
for(const lib in xml.lib)
|
||||||
{
|
{
|
||||||
const library = xml.map.lib[lib];
|
const library = xml.lib[lib];
|
||||||
|
|
||||||
this._librares.push(new FigureLibraryXML(library));
|
this._librares.push(new FigureLibraryXML(library));
|
||||||
}
|
}
|
||||||
|
@ -13,13 +13,13 @@ export class FurnitureDataXML
|
|||||||
{
|
{
|
||||||
this._floorItems = [];
|
this._floorItems = [];
|
||||||
|
|
||||||
for(const roomitemtype in xml.roomitemtypes)
|
for(const roomitemtype of xml.roomitemtypes)
|
||||||
{
|
{
|
||||||
const furniTypes = xml.roomitemtypes[roomitemtype];
|
const furniTypes = roomitemtype.furnitype;
|
||||||
|
|
||||||
if(furniTypes !== undefined)
|
if(furniTypes !== undefined)
|
||||||
{
|
{
|
||||||
for(const furniType in furniTypes) this._floorItems.push(new FurnitureTypeXML('floor', furniType));
|
if(Array.isArray(furniTypes)) for(const furniType of furniTypes) this._floorItems.push(new FurnitureTypeXML('floor', furniType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,13 +28,13 @@ export class FurnitureDataXML
|
|||||||
{
|
{
|
||||||
this._wallItems = [];
|
this._wallItems = [];
|
||||||
|
|
||||||
for(const wallitemtype in xml.wallitemtypes)
|
for(const wallitemtype of xml.wallitemtypes)
|
||||||
{
|
{
|
||||||
const furniTypes = xml.wallitemtypes[wallitemtype];
|
const furniTypes = wallitemtype.furnitype;
|
||||||
|
|
||||||
if(furniTypes !== undefined)
|
if(furniTypes !== undefined)
|
||||||
{
|
{
|
||||||
for(const furniType in furniTypes) this._wallItems.push(new FurnitureTypeXML('wall', furniType));
|
if(Array.isArray(furniTypes)) for(const furniType in furniTypes) this._wallItems.push(new FurnitureTypeXML('wall', furniType));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
export * from './asset';
|
export * from './asset';
|
||||||
export * from './effectmap';
|
export * from './effectmap';
|
||||||
export * from './figuremap';
|
export * from './figuremap';
|
||||||
export * from './furnidata';
|
export * from './furnituredata';
|
||||||
|
@ -12,6 +12,8 @@ export class FileUtilities
|
|||||||
|
|
||||||
let content: Buffer = null;
|
let content: Buffer = null;
|
||||||
|
|
||||||
|
if(url.startsWith('//')) url = ('https:' + url);
|
||||||
|
|
||||||
if(url.startsWith('http'))
|
if(url.startsWith('http'))
|
||||||
{
|
{
|
||||||
const data = await fetch.default(url);
|
const data = await fetch.default(url);
|
||||||
@ -33,6 +35,8 @@ export class FileUtilities
|
|||||||
|
|
||||||
let content = null;
|
let content = null;
|
||||||
|
|
||||||
|
if(url.startsWith('//')) url = ('https:' + url);
|
||||||
|
|
||||||
if(url.startsWith('http'))
|
if(url.startsWith('http'))
|
||||||
{
|
{
|
||||||
const data = await fetch.default(url);
|
const data = await fetch.default(url);
|
||||||
|
@ -1,22 +1,19 @@
|
|||||||
import { createWriteStream, existsSync } from 'fs';
|
import { WriteStream } from 'fs';
|
||||||
import { appendFile } from 'fs/promises';
|
|
||||||
import { singleton } from 'tsyringe';
|
import { singleton } from 'tsyringe';
|
||||||
|
|
||||||
@singleton()
|
@singleton()
|
||||||
export default class Logger
|
export class Logger
|
||||||
{
|
{
|
||||||
|
private _fileName: string = `error-${ Date.now() }.log`;
|
||||||
|
private _writeStream: WriteStream = null;
|
||||||
|
|
||||||
constructor()
|
constructor()
|
||||||
{
|
{
|
||||||
if(!existsSync('error.log'))
|
|
||||||
{
|
|
||||||
const createStream = createWriteStream('error.log');
|
|
||||||
createStream.end();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public logErrorAsync(message: string): Promise<void>
|
public logError(message: string): void
|
||||||
{
|
{
|
||||||
return appendFile('error.log', message + '\n');
|
//
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user