mirror of
https://github.com/billsonnn/nitro-converter.git
synced 2024-11-26 17:30:52 +01:00
JPEG Magic + node version check
This commit is contained in:
parent
96825fb963
commit
cd5f4a093c
3894
package-lock.json
generated
3894
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
11
src/Main.ts
11
src/Main.ts
@ -11,6 +11,7 @@ import { ProductDataConverter } from './converters/productdata/ProductDataConver
|
||||
|
||||
(async () =>
|
||||
{
|
||||
checkNodeVersion();
|
||||
const config = container.resolve(Configuration);
|
||||
await config.init();
|
||||
|
||||
@ -30,3 +31,13 @@ import { ProductDataConverter } from './converters/productdata/ProductDataConver
|
||||
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');
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
{
|
||||
"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",
|
||||
"external.texts.url": "${external.texts.txt}",
|
||||
"convert.productdata": "1",
|
||||
"convert.externaltexts": "1",
|
||||
"convert.figure": "1",
|
||||
"convert.effect": "1",
|
||||
"convert.furniture": "1",
|
||||
"convert.pet": "1"
|
||||
}
|
@ -1,31 +1,27 @@
|
||||
import CustomIterator from '../utils/CustomIterator';
|
||||
import { readImagesDefineBitsLossless, readImagesJPEG, readSwfAsync } from '../utils/SwfReader';
|
||||
import { CharacterTag } from './tags/CharacterTag';
|
||||
import { DefineBinaryDataTag } from './tags/DefineBinaryDataTag';
|
||||
import { ImageTag } from './tags/ImageTag';
|
||||
import { ITag } from './tags/ITag';
|
||||
import { SymbolClassTag } from './tags/SymbolClassTag';
|
||||
import {readImagesDefineBitsLossless, readImagesJPEG3or4, readSwfAsync} from '../utils/SwfReader';
|
||||
import {CharacterTag} from './tags/CharacterTag';
|
||||
import {DefineBinaryDataTag} from './tags/DefineBinaryDataTag';
|
||||
import {ImageTag} from './tags/ImageTag';
|
||||
import {ITag} from './tags/ITag';
|
||||
import {SymbolClassTag} from './tags/SymbolClassTag';
|
||||
import {writeFileSync} from "fs";
|
||||
|
||||
export class HabboAssetSWF
|
||||
{
|
||||
export class HabboAssetSWF {
|
||||
private readonly _tags: Array<ITag>;
|
||||
private _documentClass: string | null = null;
|
||||
|
||||
constructor(
|
||||
private readonly _data: string | Buffer
|
||||
)
|
||||
{
|
||||
) {
|
||||
this._tags = new Array<ITag>();
|
||||
}
|
||||
|
||||
async setupAsync()
|
||||
{
|
||||
async setupAsync() {
|
||||
const swf = await readSwfAsync(this._data);
|
||||
for(const tag of swf.tags)
|
||||
{
|
||||
for (const tag of swf.tags) {
|
||||
|
||||
switch(tag.header.code)
|
||||
{
|
||||
switch (tag.header.code) {
|
||||
case 76:
|
||||
this._tags.push(new SymbolClassTag(tag.symbols));
|
||||
break;
|
||||
@ -37,39 +33,57 @@ export class HabboAssetSWF
|
||||
console.log(tag);
|
||||
break;
|
||||
|
||||
case 21:
|
||||
console.log(tag);
|
||||
case 21: {
|
||||
const jpeg3 = await readImagesJPEG3or4(21, tag);
|
||||
this._tags.push(new ImageTag({
|
||||
code: 21,
|
||||
characterID: jpeg3.characterId,
|
||||
imgType: 'jpeg',
|
||||
imgData: jpeg3.imageData,
|
||||
bitmapWidth: jpeg3.bitmapWidth,
|
||||
bitmapHeight: jpeg3.bitmapHeight
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
case 35: {
|
||||
const jpegTag = await readImagesJPEG(35, tag);
|
||||
const jpeg3 = await readImagesJPEG3or4(35, tag);
|
||||
this._tags.push(new ImageTag({
|
||||
code: jpegTag.code,
|
||||
characterID: jpegTag.characterId,
|
||||
imgType: jpegTag.imgType,
|
||||
imgData: jpegTag.imgData,
|
||||
bitmapWidth: jpegTag.bitmapWidth,
|
||||
bitmapHeight: jpegTag.bitmapHeight
|
||||
code: jpeg3.code,
|
||||
characterID: jpeg3.characterId,
|
||||
imgType: jpeg3.imgType,
|
||||
imgData: jpeg3.imgData,
|
||||
bitmapWidth: jpeg3.bitmapWidth,
|
||||
bitmapHeight: jpeg3.bitmapHeight
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
case 36: {
|
||||
const pngTag: any = await readImagesDefineBitsLossless(tag);
|
||||
const pngTagLossLess2: any = await readImagesDefineBitsLossless(tag);
|
||||
this._tags.push(new ImageTag({
|
||||
code: pngTag.code,
|
||||
characterID: pngTag.characterId,
|
||||
imgType: pngTag.imgType,
|
||||
imgData: pngTag.imgData,
|
||||
bitmapWidth: pngTag.bitmapWidth,
|
||||
bitmapHeight: pngTag.bitmapHeight
|
||||
code: pngTagLossLess2.code,
|
||||
characterID: pngTagLossLess2.characterId,
|
||||
imgType: pngTagLossLess2.imgType,
|
||||
imgData: pngTagLossLess2.imgData,
|
||||
bitmapWidth: pngTagLossLess2.bitmapWidth,
|
||||
bitmapHeight: pngTagLossLess2.bitmapHeight
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
case 20:
|
||||
console.log(tag);
|
||||
case 20: {
|
||||
const pngTagLossless: any = await readImagesDefineBitsLossless(tag);
|
||||
this._tags.push(new ImageTag({
|
||||
code: pngTagLossless.code,
|
||||
characterID: pngTagLossless.characterId,
|
||||
imgType: pngTagLossless.imgType,
|
||||
imgData: pngTagLossless.imgData,
|
||||
bitmapWidth: pngTagLossless.bitmapWidth,
|
||||
bitmapHeight: pngTagLossless.bitmapHeight
|
||||
}));
|
||||
break;
|
||||
}
|
||||
|
||||
case 90:
|
||||
console.log(tag);
|
||||
@ -84,47 +98,37 @@ export class HabboAssetSWF
|
||||
this.assignClassesToSymbols();
|
||||
}
|
||||
|
||||
public imageTags(): Array<ImageTag>
|
||||
{
|
||||
public imageTags(): Array<ImageTag> {
|
||||
return this._tags.filter((tag: ITag) => tag instanceof ImageTag).map(x => x as ImageTag);
|
||||
}
|
||||
|
||||
public symbolTags(): Array<SymbolClassTag>
|
||||
{
|
||||
public symbolTags(): Array<SymbolClassTag> {
|
||||
return this._tags.filter((tag: ITag) => tag instanceof SymbolClassTag).map(x => x as SymbolClassTag);
|
||||
}
|
||||
|
||||
private binaryTags(): Array<DefineBinaryDataTag>
|
||||
{
|
||||
private binaryTags(): Array<DefineBinaryDataTag> {
|
||||
return this._tags.filter((tag: ITag) => tag instanceof DefineBinaryDataTag).map(x => x as DefineBinaryDataTag);
|
||||
}
|
||||
|
||||
private assignClassesToSymbols()
|
||||
{
|
||||
private assignClassesToSymbols() {
|
||||
const classes: Map<number, string> = new Map();
|
||||
|
||||
let iterator: CustomIterator<ITag> = new CustomIterator(this._tags);
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
let t: ITag;
|
||||
|
||||
do
|
||||
{
|
||||
if(!iterator.hasNext())
|
||||
{
|
||||
do {
|
||||
if (!iterator.hasNext()) {
|
||||
iterator = new CustomIterator(this._tags);
|
||||
|
||||
while(iterator.hasNext())
|
||||
{
|
||||
while (iterator.hasNext()) {
|
||||
t = iterator.next();
|
||||
if(t instanceof CharacterTag)
|
||||
{
|
||||
if (t instanceof CharacterTag) {
|
||||
const ct = t as CharacterTag;
|
||||
|
||||
if(classes.has(ct.characterId))
|
||||
{
|
||||
if (classes.has(ct.characterId)) {
|
||||
// @ts-ignore
|
||||
ct.className = classes.get(ct.characterId);
|
||||
}
|
||||
@ -135,46 +139,37 @@ export class HabboAssetSWF
|
||||
}
|
||||
|
||||
t = iterator.next();
|
||||
} while(!(t instanceof SymbolClassTag));
|
||||
} while (!(t instanceof SymbolClassTag));
|
||||
|
||||
const sct = t as SymbolClassTag;
|
||||
|
||||
for(let i = 0; i < sct.tags.length; ++i)
|
||||
{
|
||||
if(!classes.has(sct.tags[i]) && !Array.from(classes.values()).includes(sct.names[i]))
|
||||
{
|
||||
for (let i = 0; i < sct.tags.length; ++i) {
|
||||
if (!classes.has(sct.tags[i]) && !Array.from(classes.values()).includes(sct.names[i])) {
|
||||
classes.set(sct.tags[i], sct.names[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public getBinaryTagByName(name: string): DefineBinaryDataTag | null
|
||||
{
|
||||
public getBinaryTagByName(name: string): DefineBinaryDataTag | null {
|
||||
const streamTag = this.binaryTags()
|
||||
.filter(tag => tag.className === name)[0];
|
||||
|
||||
if(streamTag === undefined) return null;
|
||||
if (streamTag === undefined) return null;
|
||||
|
||||
return streamTag;
|
||||
}
|
||||
|
||||
public getFullClassName(type: string, documentNameTwice: boolean): string
|
||||
{
|
||||
public getFullClassName(type: string, documentNameTwice: boolean): string {
|
||||
return this.getFullClassNameSnake(type, documentNameTwice, false);
|
||||
}
|
||||
|
||||
public getFullClassNameSnake(type: string, documentNameTwice: boolean, snakeCase: boolean): string
|
||||
{
|
||||
public getFullClassNameSnake(type: string, documentNameTwice: boolean, snakeCase: boolean): string {
|
||||
let result: string = this.getDocumentClass() + '_';
|
||||
if(documentNameTwice)
|
||||
{
|
||||
if(snakeCase)
|
||||
{
|
||||
if (documentNameTwice) {
|
||||
if (snakeCase) {
|
||||
//result += CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, this.swf.getDocumentClass()) + "_";
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
result += this.getDocumentClass() + '_';
|
||||
}
|
||||
}
|
||||
@ -182,32 +177,26 @@ export class HabboAssetSWF
|
||||
return result + type;
|
||||
}
|
||||
|
||||
public getDocumentClass(): string
|
||||
{
|
||||
if(this._documentClass !== null) return this._documentClass;
|
||||
public getDocumentClass(): string {
|
||||
if (this._documentClass !== null) return this._documentClass;
|
||||
|
||||
const iterator: CustomIterator<ITag> = new CustomIterator(this._tags);
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while(true)
|
||||
{
|
||||
while (true) {
|
||||
let t: ITag;
|
||||
do
|
||||
{
|
||||
if(!iterator.hasNext())
|
||||
{
|
||||
do {
|
||||
if (!iterator.hasNext()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
t = iterator.next();
|
||||
} while(!(t instanceof SymbolClassTag));
|
||||
} while (!(t instanceof SymbolClassTag));
|
||||
|
||||
const sc = t as SymbolClassTag;
|
||||
|
||||
for(let i = 0; i < sc.tags.length; ++i)
|
||||
{
|
||||
if(sc.tags[i] == 0)
|
||||
{
|
||||
for (let i = 0; i < sc.tags.length; ++i) {
|
||||
if (sc.tags[i] == 0) {
|
||||
this._documentClass = sc.names[i];
|
||||
return this._documentClass;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import {writeFileSync} from "fs";
|
||||
|
||||
const SWFReader = require('@gizeta/swf-reader');
|
||||
|
||||
const _encoder = require('png-stream/encoder');
|
||||
@ -98,14 +100,17 @@ export function readSwfAsync(data: string | Buffer): Promise<any>
|
||||
|
||||
const pngMagic = Buffer.from('0x89 0x50 0x4E 0x47 0x0D 0x0A 0x1A 0x0A'.split(' ').map(Number));
|
||||
const gifMagic = Buffer.from('0x47 0x49 0x46 0x38 0x39 0x61'.split(' ').map(Number));
|
||||
const jpegMagic = Buffer.from('0xFF 0xD8'.split(' ').map(Number));
|
||||
const recognizeHeader = function recognizeHeader(buffer: Buffer)
|
||||
{
|
||||
if(pngMagic.equals(buffer.slice(0, pngMagic.length))) return 'png';
|
||||
if(gifMagic.equals(buffer.slice(0, gifMagic.length))) return 'gif';
|
||||
return 'jpeg';
|
||||
if(jpegMagic.equals(buffer.slice(0, jpegMagic.length))) return 'jpeg';
|
||||
|
||||
throw new Error('unknown format: ' + buffer.slice(0, 8));
|
||||
};
|
||||
|
||||
export async function readImagesJPEG(code: number, tagData: any): Promise<any>
|
||||
export async function readImagesJPEG3or4(code: number, tagData: any): Promise<any>
|
||||
{
|
||||
const characterId = tagData.characterId,
|
||||
imageData = tagData.imageData;
|
||||
@ -141,7 +146,7 @@ export async function readImagesJPEG(code: number, tagData: any): Promise<any>
|
||||
other two zlib.unzip call happens at sites that an empty uncompressed Buffer
|
||||
does not make sense. So I think the current fix is good enough.
|
||||
*/
|
||||
if(bitmapAlphaData.length > 0)
|
||||
if(bitmapAlphaData && bitmapAlphaData.length > 0)
|
||||
{
|
||||
return reject(new Error(err));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user