Change everything

This commit is contained in:
Bill 2021-12-22 03:45:09 -05:00
parent 342fa7f122
commit 73fe879160
245 changed files with 6480 additions and 2162 deletions

2
.gitignore vendored
View File

@ -50,6 +50,8 @@ Thumbs.db
*.zip
*.as
*.bin
.env
assets/
# Nitro
/src/configuration.json

4679
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"description": "",
"main": "index.js",
"scripts": {
"start": "ts-node-transpile-only src/Main.ts",
"start": "node dist/Main.js",
"start:dev": "ts-node-dev --respawn --transpile-only src/Main.ts"
},
"author": "",
@ -20,8 +20,10 @@
"node-fetch": "^2.6.1",
"node-gzip": "^1.1.2",
"ora": "^5.3.0",
"pako": "^2.0.4",
"png-stream": "^1.0.5",
"reflect-metadata": "^0.1.13",
"shelljs": "^0.8.4",
"stream-to-array": "^2.3.0",
"tsyringe": "^4.4.0",
"xml2js": "^0.4.23"
@ -30,6 +32,9 @@
"@types/bytebuffer": "^5.0.42",
"@types/node": "^14.14.28",
"@types/node-fetch": "^2.5.8",
"@types/pako": "^1.0.2",
"@types/shelljs": "^0.8.10",
"@types/stream-to-array": "^2.3.0",
"@types/xml2js": "^0.4.8",
"@typescript-eslint/eslint-plugin": "^4.15.1",
"@typescript-eslint/parser": "^4.15.1",

View File

@ -10,14 +10,11 @@ import { FigureDataConverter } from './converters/FigureDataConverter';
import { FigureMapConverter } from './converters/FigureMapConverter';
import { FurnitureConverter } from './converters/FurnitureConverter';
import { FurnitureDataConverter } from './converters/FurnitureDataConverter';
import { OldAssetConverter } from './converters/OldAssetConverter';
import { PetConverter } from './converters/PetConverter';
import { ProductDataConverter } from './converters/ProductDataConverter';
(async () =>
{
checkNodeVersion();
const config = container.resolve(Configuration);
await config.init();
@ -31,26 +28,15 @@ import { ProductDataConverter } from './converters/ProductDataConverter';
FurnitureConverter,
FigureConverter,
EffectConverter,
PetConverter,
OldAssetConverter
PetConverter
];
const [ arg1, arg2, ...rest ] = process.argv;
for(const converterClass of converters)
{
const converter = (container.resolve<any>(converterClass) as IConverter);
await converter.convertAsync(rest);
await converter.convertAsync();
}
})();
function checkNodeVersion()
{
const version = process.version.replace('v', '');
const major = version.split('.')[0];
if(parseInt(major) < 14)
{
throw new Error('Invalid node version: ' + version + ' please use >= 14');
}
}
process.kill(process.pid, 'SIGTERM');
})();

View File

@ -1,104 +0,0 @@
import { packAsync } from 'free-tex-packer-core';
import { HabboAssetSWF } from '../../swf/HabboAssetSWF';
import { ImageBundle } from './ImageBundle';
import { SpriteBundle } from './SpriteBundle';
export class BundleProvider
{
public static imageSource: Map<string, string> = new Map();
public static async generateSpriteSheet(habboAssetSWF: HabboAssetSWF, convertCase: boolean = false): Promise<SpriteBundle>
{
const tagList = habboAssetSWF.symbolTags();
const names: string[] = [];
const tags: number[] = [];
let documentClass = habboAssetSWF.getDocumentClass();
if(convertCase) documentClass = (documentClass.replace(/(?:^|\.?)([A-Z])/g, (x,y) => ('_' + y.toLowerCase().replace(/^_/, ''))));
for(const tag of tagList)
{
names.push(...tag.names);
tags.push(...tag.tags);
}
const imageBundle = new ImageBundle();
const imageTags = habboAssetSWF.imageTags();
for(const imageTag of imageTags)
{
if(tags.includes(imageTag.characterID))
{
for(let i = 0; i < tags.length; i++)
{
if(tags[i] != imageTag.characterID) continue;
if(names[i] == imageTag.className) continue;
if(imageTag.className.startsWith('sh_')) continue;
if(imageTag.className.indexOf('_32_') >= 0) continue;
BundleProvider.imageSource.set(names[i].substring(documentClass.length + 1), imageTag.className.substring(documentClass.length + 1));
}
}
if(imageTag.className.startsWith('sh_')) continue;
if(imageTag.className.indexOf('_32_') >= 0) continue;
let className = imageTag.className;
if(convertCase) className = ((className.replace(/(?:^|\.?)([A-Z])/g, (x,y) => ('_' + y.toLowerCase().replace(/^_/, '')))).substring(1));
imageBundle.addImage(className, imageTag.imgData);
}
if(!imageBundle.images.length) return null;
return await this.packImages(documentClass, imageBundle, convertCase);
}
private static async packImages(documentClass: string, imageBundle: ImageBundle, convertCase: boolean = false): Promise<SpriteBundle>
{
const files = await packAsync(imageBundle.images, {
textureName: (convertCase ? documentClass.substring(1) : documentClass),
width: 10240,
height: 4320,
fixedSize: false,
allowRotation: false,
detectIdentical: true,
allowTrim: true,
//@ts-ignore
exporter: 'Pixi'
});
const bundle = new SpriteBundle();
for(const item of files)
{
if(item.name.endsWith('.json'))
{
bundle.spritesheet = JSON.parse(item.buffer.toString('utf8'));
delete bundle.spritesheet.meta.app;
delete bundle.spritesheet.meta.version;
}
else
{
bundle.imageData = {
name: item.name,
buffer: item.buffer
};
if(convertCase) bundle.imageData.name = (documentClass.replace(/(?:^|\.?)([A-Z])/g, (x,y) => ('_' + y.toLowerCase().replace(/^_/, '')))).substring(1);
}
}
if((bundle.spritesheet !== undefined) && (bundle.imageData !== undefined)) bundle.spritesheet.meta.image = bundle.imageData.name;
return bundle;
}
}

View File

@ -0,0 +1,75 @@
import ByteBuffer from 'bytebuffer';
import { Data, deflate, inflate } from 'pako';
import { BinaryReader } from '../utils';
export class NitroBundle
{
private readonly _files: Map<string, Buffer>;
constructor()
{
this._files = new Map<string, Buffer>();
}
public static from(buffer: ArrayBuffer): NitroBundle
{
const nitroBundle = new NitroBundle();
const binaryReader = new BinaryReader(buffer);
let fileCount = binaryReader.readShort();
while(fileCount > 0)
{
const fileNameLength = binaryReader.readShort();
const fileName = binaryReader.readBytes(fileNameLength).toString();
const fileLength = binaryReader.readInt();
const buffer = binaryReader.readBytes(fileLength);
const decompressed = inflate((buffer.toArrayBuffer() as Data));
nitroBundle.addFile(fileName, Buffer.from(decompressed.buffer));
fileCount--;
}
return nitroBundle;
}
public addFile(name: string, data: Buffer): void
{
this._files.set(name, data);
}
public async toBufferAsync(): Promise<Buffer>
{
const buffer = new ByteBuffer();
buffer.writeUint16(this._files.size);
for(const file of this._files.entries())
{
const fileName = file[0];
const fileBuffer = file[1];
buffer.writeUint16(fileName.length);
buffer.writeString(fileName);
const compressed = deflate(fileBuffer);
buffer.writeUint32(compressed.length);
buffer.append(compressed);
}
buffer.flip();
return buffer.toBuffer();
}
public get files(): Map<string, Buffer>
{
return this._files;
}
public get totalFiles(): number
{
return this._files.size;
}
}

View File

@ -1,4 +1,4 @@
import { ISpritesheetData } from '../../mapping/json';
import { ISpritesheetData } from '../mapping';
export class SpriteBundle
{

View File

@ -0,0 +1,3 @@
export * from './ImageBundle';
export * from './NitroBundle';
export * from './SpriteBundle';

View File

@ -1,6 +1,6 @@
import { singleton } from 'tsyringe';
import * as configuration from '../../configuration.json';
import { FileUtilities } from '../../utils/FileUtilities';
import { FileUtilities } from '../utils';
@singleton()
export class Configuration
@ -101,6 +101,7 @@ export class Configuration
public interpolate(value: string, regex: RegExp = null): string
{
if(!value || (typeof value === 'object')) return value;
if(!regex) regex = new RegExp(/\${(.*?)}/g);
const pieces = value.match(regex);

View File

@ -0,0 +1 @@
export * from './Configuration';

View File

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

View File

@ -0,0 +1,7 @@
export class ConverterResult
{
public static OK: number = 1;
public static BAD_ARGS: number = 2;
public static FILE_EXISTS: number = 3;
public static INVALID_SWF: number = 4;
}

View File

@ -1,7 +0,0 @@
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(args?: string[]): Promise<void>;
convertAsync(): Promise<void>;
}

View File

@ -0,0 +1,2 @@
export * from './ConverterResult';
export * from './IConverter';

40
src/common/index.ts Normal file
View File

@ -0,0 +1,40 @@
export * from './bundle';
export * from './config';
export * from './converters';
export * from './mapping';
export * from './mapping/json';
export * from './mapping/json/asset';
export * from './mapping/json/asset/animation';
export * from './mapping/json/asset/logic';
export * from './mapping/json/asset/logic/model';
export * from './mapping/json/asset/logic/particlesystem';
export * from './mapping/json/asset/spritesheet';
export * from './mapping/json/asset/visualization';
export * from './mapping/json/asset/visualization/animation';
export * from './mapping/json/asset/visualization/color';
export * from './mapping/json/asset/visualization/gestures';
export * from './mapping/json/asset/visualization/postures';
export * from './mapping/json/effectmap';
export * from './mapping/json/externaltexts';
export * from './mapping/json/figuredata';
export * from './mapping/json/figuremap';
export * from './mapping/json/furnituredata';
export * from './mapping/json/productdata';
export * from './mapping/mappers';
export * from './mapping/mappers/asset';
export * from './mapping/xml';
export * from './mapping/xml/asset';
export * from './mapping/xml/asset/animation';
export * from './mapping/xml/asset/assets';
export * from './mapping/xml/asset/logic';
export * from './mapping/xml/asset/logic/model';
export * from './mapping/xml/asset/logic/particlesystem';
export * from './mapping/xml/asset/manifest';
export * from './mapping/xml/asset/visualization';
export * from './mapping/xml/asset/visualization/animation';
export * from './mapping/xml/asset/visualization/color';
export * from './mapping/xml/effectmap';
export * from './mapping/xml/figuredata';
export * from './mapping/xml/figuremap';
export * from './mapping/xml/furnituredata';
export * from './utils';

View File

@ -0,0 +1,35 @@
export * from './json';
export * from './json/asset';
export * from './json/asset/animation';
export * from './json/asset/logic';
export * from './json/asset/logic/model';
export * from './json/asset/logic/particlesystem';
export * from './json/asset/spritesheet';
export * from './json/asset/visualization';
export * from './json/asset/visualization/animation';
export * from './json/asset/visualization/color';
export * from './json/asset/visualization/gestures';
export * from './json/asset/visualization/postures';
export * from './json/effectmap';
export * from './json/externaltexts';
export * from './json/figuredata';
export * from './json/figuremap';
export * from './json/furnituredata';
export * from './json/productdata';
export * from './mappers';
export * from './mappers/asset';
export * from './xml';
export * from './xml/asset';
export * from './xml/asset/animation';
export * from './xml/asset/assets';
export * from './xml/asset/logic';
export * from './xml/asset/logic/model';
export * from './xml/asset/logic/particlesystem';
export * from './xml/asset/manifest';
export * from './xml/asset/visualization';
export * from './xml/asset/visualization/animation';
export * from './xml/asset/visualization/color';
export * from './xml/effectmap';
export * from './xml/figuredata';
export * from './xml/figuremap';
export * from './xml/furnituredata';

View File

@ -3,4 +3,5 @@ export interface IAssetDimension
x: number;
y: number;
z?: number;
centerZ?: number;
}

View File

@ -1,6 +1,6 @@
import { IEffectMap, IEffectMapLibrary } from '../json';
import { EffectMapEffectXML, EffectMapXML } from '../xml';
import { Mapper } from './asset/Mapper';
import { Mapper } from './asset';
export class EffectMapMapper extends Mapper
{

View File

@ -1,18 +1,6 @@
import { IFigureDataHiddenLayer } from '../json';
import { IFigureDataPalette } from '../json/figuredata/IFigureDataPalette';
import { IFigureDataSet } from '../json/figuredata/IFigureDataSet';
import { FigureDataHiddenLayerXML } from '../xml';
import { FigureDataColorXML } from '../xml/figuredata/FigureDataColorXML';
import { FigureDataPaletteXML } from '../xml/figuredata/FigureDataPaletteXML';
import { FigureDataXML } from '../xml/figuredata/FigureDataXML';
import { IFigureData } from './../json/figuredata/IFigureData';
import { IFigureDataColor } from './../json/figuredata/IFigureDataColor';
import { IFigureDataPart } from './../json/figuredata/IFigureDataPart';
import { IFigureDataSetType } from './../json/figuredata/IFigureDataSetType';
import { FigureDataPartXML } from './../xml/figuredata/FigureDataPartXML';
import { FigureDataSetTypeXML } from './../xml/figuredata/FigureDataSetTypeXML';
import { FigureDataSetXML } from './../xml/figuredata/FigureDataSetXML';
import { Mapper } from './asset/Mapper';
import { IFigureData, IFigureDataColor, IFigureDataHiddenLayer, IFigureDataPalette, IFigureDataPart, IFigureDataSet, IFigureDataSetType } from '../json';
import { FigureDataColorXML, FigureDataHiddenLayerXML, FigureDataPaletteXML, FigureDataPartXML, FigureDataSetTypeXML, FigureDataSetXML, FigureDataXML } from '../xml';
import { Mapper } from './asset';
export class FigureDataMapper extends Mapper
{

View File

@ -1,6 +1,6 @@
import { IFigureMap, IFigureMapLibrary, IFigureMapLibraryPart } from '../json';
import { FigureLibraryPartXML, FigureLibraryXML, FigureMapXML } from '../xml';
import { Mapper } from './asset/Mapper';
import { Mapper } from './asset';
export class FigureMapMapper extends Mapper
{

View File

@ -1,6 +1,6 @@
import { IFurnitureData, IFurnitureType } from '../json';
import { FurnitureDataXML, FurnitureTypeXML } from '../xml';
import { Mapper } from './asset/Mapper';
import { Mapper } from './asset';
export class FurnitureDataMapper extends Mapper
{

View File

@ -1,4 +1,4 @@
import { BundleProvider } from '../../../common/bundle/BundleProvider';
import { IMAGE_SOURCES } from '../../../../swf';
import { IAsset, IAssetData, IAssetPalette } from '../../json';
import { AssetsXML, AssetXML, PaletteXML } from '../../xml';
import { Mapper } from './Mapper';
@ -55,12 +55,12 @@ export class AssetMapper extends Mapper
{
asset.source = assetXML.source;
if(BundleProvider.imageSource.has(assetXML.source)) asset.source = BundleProvider.imageSource.get(assetXML.source) as string;
if(IMAGE_SOURCES.has(assetXML.source)) asset.source = IMAGE_SOURCES.get(assetXML.source) as string;
}
if(assetXML.name !== undefined)
{
if(BundleProvider.imageSource.has(assetXML.name)) asset.source = BundleProvider.imageSource.get(assetXML.name) as string;
if(IMAGE_SOURCES.has(assetXML.name)) asset.source = IMAGE_SOURCES.get(assetXML.name) as string;
}
if(assetXML.x !== undefined) asset.x = assetXML.x;

Some files were not shown because too many files have changed in this diff Show More