This commit is contained in:
Bill 2022-12-15 13:51:10 -05:00
parent def234e058
commit a67b9daaaa
182 changed files with 2835 additions and 4179 deletions

View File

@ -1,16 +0,0 @@
# Editor configuration, see https://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.ts]
quote_type = single
[*.md]
max_line_length = off
trim_trailing_whitespace = false

135
.eslintrc.json Normal file
View File

@ -0,0 +1,135 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
"indent": [
"error",
4,
{
"SwitchCase": 1
}
],
"no-multi-spaces": [
"error"
],
"no-trailing-spaces": [
"error",
{
"skipBlankLines": false,
"ignoreComments": true
}
],
"linebreak-style": [
"off"
],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
],
"brace-style": [
"error",
"allman"
],
"object-curly-spacing": [
"error",
"always"
],
"keyword-spacing": [
"error",
{
"overrides":
{
"if":
{
"after": false
},
"for":
{
"after": false
},
"while":
{
"after": false
},
"switch":
{
"after": false
}
}
}
],
"@typescript-eslint/no-explicit-any": [
"off"
],
"@typescript-eslint/explicit-module-boundary-types": [
"off",
{
"allowedNames": [
"getMessageArray"
]
}
],
"@typescript-eslint/ban-ts-comment": [
"off"
],
"@typescript-eslint/no-empty-function": [
"error",
{
"allow": [
"functions",
"arrowFunctions",
"generatorFunctions",
"methods",
"generatorMethods",
"constructors"
]
}
],
"@typescript-eslint/no-unused-vars": [
"off"
],
"@typescript-eslint/no-inferrable-types": [
"error",
{
"ignoreParameters": true,
"ignoreProperties": true
}
],
"@typescript-eslint/ban-types": [
"error",
{
"types":
{
"String": true,
"Boolean": true,
"Number": true,
"Symbol": true,
"{}": false,
"Object": false,
"object": false,
"Function": false
},
"extendDefaults": true
}
]
}
}

22
.vscode/settings.json vendored
View File

@ -4,13 +4,27 @@
"typescript.preferences.quoteStyle": "single", "typescript.preferences.quoteStyle": "single",
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": true, "typescript.format.placeOpenBraceOnNewLineForControlBlocks": true,
"typescript.format.placeOpenBraceOnNewLineForFunctions": true, "typescript.format.placeOpenBraceOnNewLineForFunctions": true,
"editor.wordWrap": "on",
"editor.codeActionsOnSave": { "editor.codeActionsOnSave": {
"source.fixAll": true, "source.fixAll.eslint": true,
"source.organizeImports": true, "source.fixAll.sortJSON": false,
"source.organizeImports": true
}, },
"emmet.showExpandedAbbreviation": "never", "editor.formatOnSave": false,
"git.ignoreLimitWarning": true, "git.ignoreLimitWarning": true,
"files.eol": "\n", "files.eol": "\n",
"files.insertFinalNewline": true, "files.insertFinalNewline": true,
"files.trimFinalNewlines": true "files.trimFinalNewlines": true,
"emmet.showExpandedAbbreviation": "never",
"eslint.format.enable": true,
"eslint.validate": [
"javascript",
"typescript"
],
"eslint.workingDirectories": [
{
"pattern": "./src/*"
}
],
"javascript.format.enable": false
} }

View File

@ -1,2 +0,0 @@
require('dotenv').config();
require('./src/main');

3208
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -5,24 +5,26 @@
"main": "index.ts", "main": "index.ts",
"dependencies": { "dependencies": {
"bytebuffer": "^5.0.1", "bytebuffer": "^5.0.1",
"canvas": "^2.8.0", "canvas": "^2.10.2",
"chalk": "^4.1.2", "cli-color": "^2.0.3",
"dotenv": "^10.0.0", "dotenv": "^16.0.3",
"express": "^4.17.1", "express": "^4.18.2",
"gifencoder": "^2.0.1", "gifencoder": "^2.0.1",
"node-fetch": "^2.6.1", "node-fetch": "^2.0.0",
"pako": "^2.0.4" "pako": "^2.1.0"
}, },
"devDependencies": { "devDependencies": {
"@types/bytebuffer": "^5.0.42", "@types/bytebuffer": "^5.0.44",
"@types/chalk": "^2.2.0", "@types/cli-color": "^2.0.2",
"@types/express": "^4.17.13", "@types/express": "^4.17.15",
"@types/gifencoder": "^2.0.1", "@types/gifencoder": "^2.0.1",
"@types/node": "^14.17.12", "@types/node": "^18.11.15",
"@types/node-fetch": "^2.5.12", "@types/pako": "^2.0.0",
"@types/pako": "^1.0.2", "@typescript-eslint/eslint-plugin": "^5.46.1",
"ts-node-dev": "^1.1.8", "@typescript-eslint/parser": "^5.46.1",
"typescript": "^4.4.2" "eslint": "^8.29.0",
"ts-node-dev": "^2.0.0",
"typescript": "^4.9.4"
}, },
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",

View File

@ -1,76 +0,0 @@
import * as express from 'express';
import { INitroCore, NitroManager } from '../core';
import { AvatarRenderManager, IAvatarRenderManager } from './avatar';
import { IApplication } from './IApplication';
import { HttpRouter } from './router/HttpRouter';
export class Application extends NitroManager implements IApplication
{
private static INSTANCE: IApplication = null;
private _core: INitroCore;
private _avatar: IAvatarRenderManager;
constructor(core: INitroCore)
{
super();
Application.INSTANCE = this;
this._core = core;
this._avatar = new AvatarRenderManager(core.asset);
}
protected async onInit(): Promise<void>
{
if(this._core) await this._core.init();
if(this._avatar) await this._avatar.init();
this.setupRouter();
this.logger.log(`Initialized`);
}
protected async onDispose(): Promise<void>
{
if(this._avatar) await this._avatar.dispose();
if(this._core) await this._core.dispose();
}
public getConfiguration<T>(key: string, value: T = null): T
{
return this._core.configuration.getValue<T>(key, value);
}
private setupRouter(): void
{
const router = express();
router.use('/', HttpRouter);
const host = (process.env.API_HOST as string);
const port = parseInt(process.env.API_PORT);
router.listen(port, host, () =>
{
this.logger.log(`Server Started ${ host }:${ port }`);
});
}
public get core(): INitroCore
{
return this._core;
}
public get avatar(): IAvatarRenderManager
{
return this._avatar;
}
public static get instance(): IApplication
{
return this.INSTANCE;
}
}

View File

@ -1,9 +0,0 @@
import { INitroCore, INitroManager } from '../core';
import { IAvatarRenderManager } from './avatar';
export interface IApplication extends INitroManager
{
getConfiguration<T>(key: string, value?: T): T;
core: INitroCore;
avatar: IAvatarRenderManager;
}

View File

@ -1,18 +0,0 @@
import { AssetAliasCollection } from './alias';
import { AvatarFigureContainer } from './AvatarFigureContainer';
import { AvatarImage } from './AvatarImage';
import { AvatarStructure } from './AvatarStructure';
import { EffectAssetDownloadManager } from './EffectAssetDownloadManager';
export class PlaceHolderAvatarImage extends AvatarImage
{
constructor(k: AvatarStructure, _arg_2: AssetAliasCollection, _arg_3: AvatarFigureContainer, _arg_4: string, _arg_5: EffectAssetDownloadManager)
{
super(k, _arg_2, _arg_3, _arg_4, _arg_5);
}
public isPlaceholder(): boolean
{
return true;
}
}

View File

@ -1,3 +0,0 @@
export * from './Application';
export * from './avatar';
export * from './IApplication';

View File

@ -1,6 +0,0 @@
import { Router } from 'express';
import { HabboImagingRouter } from './habbo-imaging';
export const HttpRouter = Router();
HttpRouter.use('/', HabboImagingRouter);

View File

@ -1,6 +0,0 @@
import { Router } from 'express';
import { HabboImagingRouterGet } from './handlers';
export const HabboImagingRouter = Router();
HabboImagingRouter.get('/', HabboImagingRouterGet);

View File

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

View File

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

View File

@ -1,4 +1,4 @@
import { IAssetManager } from '../../core'; import { AssetManager } from '../core';
export class AvatarAssetDownloadLibrary export class AvatarAssetDownloadLibrary
{ {
@ -10,15 +10,13 @@ export class AvatarAssetDownloadLibrary
private _libraryName: string; private _libraryName: string;
private _revision: string; private _revision: string;
private _downloadUrl: string; private _downloadUrl: string;
private _assets: IAssetManager;
constructor(id: string, revision: string, assets: IAssetManager, assetUrl: string) constructor(id: string, revision: string, assetUrl: string)
{ {
this._state = AvatarAssetDownloadLibrary.NOT_LOADED; this._state = AvatarAssetDownloadLibrary.NOT_LOADED;
this._libraryName = id; this._libraryName = id;
this._revision = revision; this._revision = revision;
this._downloadUrl = assetUrl; this._downloadUrl = assetUrl;
this._assets = assets;
this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName); this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName);
this._downloadUrl = this._downloadUrl.replace(/%revision%/gi, this._revision); this._downloadUrl = this._downloadUrl.replace(/%revision%/gi, this._revision);
@ -30,7 +28,7 @@ export class AvatarAssetDownloadLibrary
{ {
if(this._state === AvatarAssetDownloadLibrary.LOADED) return true; if(this._state === AvatarAssetDownloadLibrary.LOADED) return true;
const asset = this._assets.getCollection(this._libraryName); const asset = AssetManager.getCollection(this._libraryName);
if(asset) if(asset)
{ {
@ -44,13 +42,13 @@ export class AvatarAssetDownloadLibrary
public async downloadAsset(): Promise<boolean> public async downloadAsset(): Promise<boolean>
{ {
if(!this._assets || (this._state === AvatarAssetDownloadLibrary.LOADING)) return false; if(this._state === AvatarAssetDownloadLibrary.LOADING) return false;
if(this.checkIfAssetLoaded()) return false; if(this.checkIfAssetLoaded()) return false;
this._state = AvatarAssetDownloadLibrary.LOADING; this._state = AvatarAssetDownloadLibrary.LOADING;
if(!await this._assets.downloadAsset(this._downloadUrl)) return false; if(!await AssetManager.downloadAsset(this._downloadUrl)) return false;
this._state = AvatarAssetDownloadLibrary.LOADED; this._state = AvatarAssetDownloadLibrary.LOADED;

View File

@ -1,33 +1,28 @@
import { AdvancedMap, FileUtilities, IAssetManager } from '../../core'; import { AdvancedMap, ConfigurationManager, FileUtilities } from '../core';
import { Application } from '../Application';
import { AvatarAssetDownloadLibrary } from './AvatarAssetDownloadLibrary'; import { AvatarAssetDownloadLibrary } from './AvatarAssetDownloadLibrary';
import { AvatarStructure } from './AvatarStructure'; import { AvatarStructure } from './AvatarStructure';
import { IAvatarFigureContainer } from './IAvatarFigureContainer'; import { IAvatarFigureContainer } from './IAvatarFigureContainer';
export class AvatarAssetDownloadManager export class AvatarAssetDownloadManager
{ {
private _assets: IAssetManager;
private _structure: AvatarStructure; private _structure: AvatarStructure;
private _missingMandatoryLibs: string[]; private _missingMandatoryLibs: string[] = [];
private _figureMap: AdvancedMap<string, AvatarAssetDownloadLibrary[]>; private _figureMap: AdvancedMap<string, AvatarAssetDownloadLibrary[]> = new AdvancedMap();
private _libraryNames: string[]; private _libraryNames: string[] = [];
constructor(assets: IAssetManager, structure: AvatarStructure) constructor(structure: AvatarStructure)
{ {
this._assets = assets;
this._structure = structure; this._structure = structure;
this._missingMandatoryLibs = Application.instance.getConfiguration<string[]>('avatar.mandatory.libraries'); this._missingMandatoryLibs = ConfigurationManager.getValue<string[]>('avatar.mandatory.libraries');
this._figureMap = new AdvancedMap();
this._libraryNames = [];
} }
public async loadFigureMap(): Promise<void> public async loadFigureMap(): Promise<void>
{ {
const url = (process.env.AVATAR_FIGUREMAP_URL as string); const url = (process.env.AVATAR_FIGUREMAP_URL as string);
if(!url || !url.length) return Promise.reject('invalid_figuremap_url'); if(!url || !url.length) throw new Error('invalid_figuremap_url');
const data = await FileUtilities.readFileAsString(url); const data = await FileUtilities.readFileAsString(url);
const json = JSON.parse(data); const json = JSON.parse(data);
@ -56,7 +51,7 @@ export class AvatarAssetDownloadManager
this._libraryNames.push(id); this._libraryNames.push(id);
const downloadLibrary = new AvatarAssetDownloadLibrary(id, revision, this._assets, url); const downloadLibrary = new AvatarAssetDownloadLibrary(id, revision, url);
for(const part of library.parts) for(const part of library.parts)
{ {

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../core'; import { AdvancedMap } from '../core';
import { IAvatarFigureContainer } from './IAvatarFigureContainer'; import { IAvatarFigureContainer } from './IAvatarFigureContainer';
export class AvatarFigureContainer implements IAvatarFigureContainer export class AvatarFigureContainer implements IAvatarFigureContainer

View File

@ -1,5 +1,5 @@
import { Canvas } from 'canvas'; import { Canvas } from 'canvas';
import { CanvasUtilities, IGraphicAsset } from '../../core'; import { CanvasUtilities, IGraphicAsset } from '../core';
import { ActiveActionData, IActionDefinition, IActiveActionData } from './actions'; import { ActiveActionData, IActionDefinition, IActiveActionData } from './actions';
import { AssetAliasCollection } from './alias'; import { AssetAliasCollection } from './alias';
import { IAnimationLayerData, IAvatarDataContainer, ISpriteDataContainer } from './animation'; import { IAnimationLayerData, IAvatarDataContainer, ISpriteDataContainer } from './animation';
@ -306,6 +306,8 @@ export class AvatarImage implements IAvatarImage
const set = bodyParts[partCount]; const set = bodyParts[partCount];
const part = this._cache.getImageContainer(set, this._frameCounter); const part = this._cache.getImageContainer(set, this._frameCounter);
console.log(part);
if(part) if(part)
{ {
const partCacheContainer = part.image; const partCacheContainer = part.image;
@ -614,7 +616,7 @@ export class AvatarImage implements IAvatarImage
{ {
if(!this._sortedActions == null) return; if(!this._sortedActions == null) return;
const _local_3: number = 0; const _local_3 = 0;
const _local_4: string[] = []; const _local_4: string[] = [];
for(const k of this._sortedActions) _local_4.push(k.actionType); for(const k of this._sortedActions) _local_4.push(k.actionType);

View File

@ -1,5 +1,5 @@
import { Canvas } from 'canvas'; import { Canvas } from 'canvas';
import { Point } from '../../core'; import { Point } from '../core';
export class AvatarImageBodyPartContainer export class AvatarImageBodyPartContainer
{ {

View File

@ -1,6 +1,5 @@
import { IActionDefinition } from './actions/IActionDefinition'; import { IActionDefinition } from './actions';
import { AvatarAnimationFrame } from './structure/animation/AvatarAnimationFrame'; import { AvatarAnimationFrame, IPartColor } from './structure';
import { IPartColor } from './structure/figure/IPartColor';
export class AvatarImagePartContainer export class AvatarImagePartContainer
{ {

View File

@ -1,5 +1,4 @@
import { FileUtilities, IAssetManager, IGraphicAsset, NitroManager } from '../../core'; import { ConfigurationManager, FileUtilities, IGraphicAsset } from '../core';
import { Application } from '../Application';
import { AssetAliasCollection } from './alias'; import { AssetAliasCollection } from './alias';
import { AvatarAssetDownloadManager } from './AvatarAssetDownloadManager'; import { AvatarAssetDownloadManager } from './AvatarAssetDownloadManager';
import { AvatarFigureContainer } from './AvatarFigureContainer'; import { AvatarFigureContainer } from './AvatarFigureContainer';
@ -15,53 +14,50 @@ import { IAvatarRenderManager } from './IAvatarRenderManager';
import { IFigureData } from './interfaces'; import { IFigureData } from './interfaces';
import { IFigurePartSet, IStructureData } from './structure'; import { IFigurePartSet, IStructureData } from './structure';
export class AvatarRenderManager extends NitroManager implements IAvatarRenderManager export class AvatarRenderManager implements IAvatarRenderManager
{ {
private static INSTANCE: AvatarRenderManager = null;
public static DEFAULT_FIGURE: string = 'hd-99999-99999'; public static DEFAULT_FIGURE: string = 'hd-99999-99999';
private _aliasCollection: AssetAliasCollection; private _aliasCollection: AssetAliasCollection = null;
private _assets: IAssetManager; private _structure: AvatarStructure = null;
private _structure: AvatarStructure; private _avatarAssetDownloadManager: AvatarAssetDownloadManager = null;
private _avatarAssetDownloadManager: AvatarAssetDownloadManager; private _effectAssetDownloadManager: EffectAssetDownloadManager = null;
private _effectAssetDownloadManager: EffectAssetDownloadManager;
private _placeHolderFigure: AvatarFigureContainer;
constructor(assets: IAssetManager) public static async init(): Promise<void>
{ {
super(); if(!AvatarRenderManager.INSTANCE) AvatarRenderManager.INSTANCE = new AvatarRenderManager();
this._assets = assets; await AvatarRenderManager.instance.init();
this._structure = null;
this._avatarAssetDownloadManager = null;
this._effectAssetDownloadManager = null;
this._placeHolderFigure = null;
} }
public async onInit(): Promise<void> public async init(): Promise<void>
{ {
this._structure = new AvatarStructure(this); this._structure = new AvatarStructure(this);
this._structure.initGeometry(HabboAvatarGeometry.geometry); this._structure.initGeometry(HabboAvatarGeometry.geometry);
this._structure.initPartSets(HabboAvatarPartSets.partSets); this._structure.initPartSets(HabboAvatarPartSets.partSets);
this._structure.initAnimation(HabboAvatarAnimations.animations); this._structure.initAnimation(HabboAvatarAnimations.animations);
await this.loadActions(); await this.loadActions();
await this.loadFigureData(); await this.loadFigureData();
this._aliasCollection = new AssetAliasCollection(this, this._assets); this._aliasCollection = new AssetAliasCollection(this);
this._aliasCollection.init(); this._aliasCollection.init();
if(!this._avatarAssetDownloadManager) if(!this._avatarAssetDownloadManager)
{ {
this._avatarAssetDownloadManager = new AvatarAssetDownloadManager(this._assets, this._structure); this._avatarAssetDownloadManager = new AvatarAssetDownloadManager(this._structure);
await this._avatarAssetDownloadManager.loadFigureMap(); await this._avatarAssetDownloadManager.loadFigureMap();
} }
if(!this._effectAssetDownloadManager) if(!this._effectAssetDownloadManager)
{ {
this._effectAssetDownloadManager = new EffectAssetDownloadManager(this._assets, this._structure); this._effectAssetDownloadManager = new EffectAssetDownloadManager(this._structure);
await this._effectAssetDownloadManager.loadEffectMap(); await this._effectAssetDownloadManager.loadEffectMap();
} }
@ -70,23 +66,23 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
private async loadActions(): Promise<void> private async loadActions(): Promise<void>
{ {
this._structure.initActions({ this._structure.initActions({
"actions": [ 'actions': [
{ {
"id": "Default", 'id': 'Default',
"state": "std", 'state': 'std',
"precedence": 1000, 'precedence': 1000,
"main": true, 'main': true,
"isDefault": true, 'isDefault': true,
"geometryType": "vertical", 'geometryType': 'vertical',
"activePartSet": "figure", 'activePartSet': 'figure',
"assetPartDefinition": "std" 'assetPartDefinition': 'std'
} }
] ]
}); });
const url = (process.env.AVATAR_ACTIONS_URL as string); const url = (process.env.AVATAR_ACTIONS_URL as string);
if(!url || !url.length) return Promise.reject('invalid_actions_url'); if(!url || !url.length) throw new Error(`Invalid avatar actions url: ${ url }`);
const data = await FileUtilities.readFileAsString(url); const data = await FileUtilities.readFileAsString(url);
@ -95,13 +91,13 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
private async loadFigureData(): Promise<void> private async loadFigureData(): Promise<void>
{ {
const defaultFigureData = Application.instance.getConfiguration<IFigureData>('avatar.default.figuredata'); const defaultFigureData = ConfigurationManager.getValue<IFigureData>('avatar.default.figuredata');
if(this._structure) this._structure.initFigureData(defaultFigureData); if(this._structure) this._structure.initFigureData(defaultFigureData);
const url = (process.env.AVATAR_FIGUREDATA_URL as string); const url = (process.env.AVATAR_FIGUREDATA_URL as string);
if(!url || !url.length) return Promise.reject('invalid_figuredata_url'); if(!url || !url.length) throw new Error('invalid_figuredata_url');
const data = await FileUtilities.readFileAsString(url); const data = await FileUtilities.readFileAsString(url);
@ -120,6 +116,13 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
return this._avatarAssetDownloadManager.isAvatarFigureContainerReady(container); return this._avatarAssetDownloadManager.isAvatarFigureContainerReady(container);
} }
public async downloadAvatarFigure(container: IAvatarFigureContainer): Promise<void>
{
if(!this._avatarAssetDownloadManager) return;
await this._avatarAssetDownloadManager.downloadAvatarFigure(container);
}
public async createAvatarImage(figure: string, size: string, gender: string): Promise<IAvatarImage> public async createAvatarImage(figure: string, size: string, gender: string): Promise<IAvatarImage>
{ {
if(!this._structure || !this._avatarAssetDownloadManager) return null; if(!this._structure || !this._avatarAssetDownloadManager) return null;
@ -128,23 +131,14 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
if(gender) this.validateAvatarFigure(figureContainer, gender); if(gender) this.validateAvatarFigure(figureContainer, gender);
if(!this._avatarAssetDownloadManager.isAvatarFigureContainerReady(figureContainer)) if(!this.isFigureContainerReady(figureContainer))
{ {
await this._avatarAssetDownloadManager.downloadAvatarFigure(figureContainer); await this.downloadAvatarFigure(figureContainer);
} }
if(!this._placeHolderFigure) this._placeHolderFigure = new AvatarFigureContainer(AvatarRenderManager.DEFAULT_FIGURE);
return new AvatarImage(this._structure, this._aliasCollection, figureContainer, size, this._effectAssetDownloadManager); return new AvatarImage(this._structure, this._aliasCollection, figureContainer, size, this._effectAssetDownloadManager);
} }
public async downloadAvatarFigure(container: IAvatarFigureContainer): Promise<void>
{
if(!this._avatarAssetDownloadManager) return;
await this._avatarAssetDownloadManager.downloadAvatarFigure(container);
}
private validateAvatarFigure(container: AvatarFigureContainer, gender: string): boolean private validateAvatarFigure(container: AvatarFigureContainer, gender: string): boolean
{ {
let isValid = false; let isValid = false;
@ -289,11 +283,6 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
return this._aliasCollection.getAsset(name); return this._aliasCollection.getAsset(name);
} }
public get assets(): IAssetManager
{
return this._assets;
}
public get structure(): AvatarStructure public get structure(): AvatarStructure
{ {
return this._structure; return this._structure;
@ -315,4 +304,9 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
{ {
return this._effectAssetDownloadManager; return this._effectAssetDownloadManager;
} }
public static get instance(): AvatarRenderManager
{
return AvatarRenderManager.INSTANCE;
}
} }

View File

@ -1,4 +1,4 @@
import { AdvancedMap, IAssetAnimation, IAssetManager, Point } from '../../core'; import { AdvancedMap, AssetManager, IAssetAnimation, Point } from '../core';
import { ActionDefinition, AvatarActionManager, IActionDefinition, IActiveActionData } from './actions'; import { ActionDefinition, AvatarActionManager, IActionDefinition, IActiveActionData } from './actions';
import { Animation, AnimationManager, AvatarAnimationLayerData } from './animation'; import { Animation, AnimationManager, AvatarAnimationLayerData } from './animation';
import { AvatarImagePartContainer } from './AvatarImagePartContainer'; import { AvatarImagePartContainer } from './AvatarImagePartContainer';
@ -104,13 +104,13 @@ export class AvatarStructure
this._figureData.injectJSON(data); this._figureData.injectJSON(data);
} }
public registerAnimations(k: IAssetManager, _arg_2: string = 'fx', _arg_3: number = 200): void public registerAnimations(name: string = 'fx', _arg_3: number = 200): void
{ {
let index = 0; let index = 0;
while(index < _arg_3) while(index < _arg_3)
{ {
const collection = k.getCollection((_arg_2 + index)); const collection = AssetManager.getCollection((name + index));
if(collection) if(collection)
{ {

View File

@ -1,4 +1,4 @@
import { IAssetAnimation, IAssetManager } from '../../core'; import { AssetManager, IAssetAnimation } from '../core';
export class EffectAssetDownloadLibrary export class EffectAssetDownloadLibrary
{ {
@ -10,16 +10,14 @@ export class EffectAssetDownloadLibrary
private _libraryName: string; private _libraryName: string;
private _revision: string; private _revision: string;
private _downloadUrl: string; private _downloadUrl: string;
private _assets: IAssetManager;
private _animation: { [index: string]: IAssetAnimation }; private _animation: { [index: string]: IAssetAnimation };
constructor(id: string, revision: string, assets: IAssetManager, assetUrl: string) constructor(id: string, revision: string, assetUrl: string)
{ {
this._state = EffectAssetDownloadLibrary.NOT_LOADED; this._state = EffectAssetDownloadLibrary.NOT_LOADED;
this._libraryName = id; this._libraryName = id;
this._revision = revision; this._revision = revision;
this._downloadUrl = assetUrl; this._downloadUrl = assetUrl;
this._assets = assets;
this._animation = null; this._animation = null;
this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName); this._downloadUrl = this._downloadUrl.replace(/%libname%/gi, this._libraryName);
@ -32,7 +30,7 @@ export class EffectAssetDownloadLibrary
{ {
if(this._state === EffectAssetDownloadLibrary.LOADED) return true; if(this._state === EffectAssetDownloadLibrary.LOADED) return true;
const asset = this._assets.getCollection(this._libraryName); const asset = AssetManager.getCollection(this._libraryName);
if(asset) if(asset)
{ {
@ -46,15 +44,15 @@ export class EffectAssetDownloadLibrary
public async downloadAsset(): Promise<boolean> public async downloadAsset(): Promise<boolean>
{ {
if(!this._assets || (this._state === EffectAssetDownloadLibrary.LOADING)) return; if(this._state === EffectAssetDownloadLibrary.LOADING) return;
if(this.checkIfAssetLoaded()) return true; if(this.checkIfAssetLoaded()) return true;
this._state = EffectAssetDownloadLibrary.LOADING; this._state = EffectAssetDownloadLibrary.LOADING;
if(!await this._assets.downloadAsset(this._downloadUrl)) return false; if(!await AssetManager.downloadAsset(this._downloadUrl)) return false;
const collection = this._assets.getCollection(this._libraryName); const collection = AssetManager.getCollection(this._libraryName);
if(collection) this._animation = collection.data.animations; if(collection) this._animation = collection.data.animations;

View File

@ -1,32 +1,27 @@
import { AdvancedMap, FileUtilities, IAssetManager } from '../../core'; import { AdvancedMap, ConfigurationManager, FileUtilities } from '../core';
import { Application } from '../Application';
import { AvatarStructure } from './AvatarStructure'; import { AvatarStructure } from './AvatarStructure';
import { EffectAssetDownloadLibrary } from './EffectAssetDownloadLibrary'; import { EffectAssetDownloadLibrary } from './EffectAssetDownloadLibrary';
export class EffectAssetDownloadManager export class EffectAssetDownloadManager
{ {
private _assets: IAssetManager;
private _structure: AvatarStructure; private _structure: AvatarStructure;
private _missingMandatoryLibs: string[]; private _missingMandatoryLibs: string[] = [];
private _effectMap: AdvancedMap<string, EffectAssetDownloadLibrary[]>; private _effectMap: AdvancedMap<string, EffectAssetDownloadLibrary[]> = new AdvancedMap();
private _libraryNames: string[]; private _libraryNames: string[] = [];
constructor(assets: IAssetManager, structure: AvatarStructure) constructor(structure: AvatarStructure)
{ {
this._assets = assets;
this._structure = structure; this._structure = structure;
this._missingMandatoryLibs = Application.instance.getConfiguration<string[]>('avatar.mandatory.effect.libraries'); this._missingMandatoryLibs = ConfigurationManager.getValue<string[]>('avatar.mandatory.effect.libraries');
this._effectMap = new AdvancedMap();
this._libraryNames = [];
} }
public async loadEffectMap(): Promise<void> public async loadEffectMap(): Promise<void>
{ {
const url = (process.env.AVATAR_EFFECTMAP_URL as string); const url = (process.env.AVATAR_EFFECTMAP_URL as string);
if(!url || !url.length) return Promise.reject('invalid_effectmap_url'); if(!url || !url.length) throw new Error('invalid_effectmap_url');
const data = await FileUtilities.readFileAsString(url); const data = await FileUtilities.readFileAsString(url);
const json = JSON.parse(data); const json = JSON.parse(data);
@ -56,7 +51,7 @@ export class EffectAssetDownloadManager
this._libraryNames.push(lib); this._libraryNames.push(lib);
const downloadLibrary = new EffectAssetDownloadLibrary(lib, revision, this._assets, url); const downloadLibrary = new EffectAssetDownloadLibrary(lib, revision, url);
let existing = this._effectMap.getValue(id); let existing = this._effectMap.getValue(id);

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../core'; import { AdvancedMap } from '../core';
export class FigureDataContainer export class FigureDataContainer
{ {

View File

@ -1,11 +1,11 @@
import { Canvas } from 'canvas'; import { Canvas } from 'canvas';
import { IDisposable, IGraphicAsset } from '../../core'; import { IGraphicAsset } from '../core';
import { IActiveActionData } from './actions'; import { IActiveActionData } from './actions';
import { IAnimationLayerData, IAvatarDataContainer, ISpriteDataContainer } from './animation'; import { IAnimationLayerData, IAvatarDataContainer, ISpriteDataContainer } from './animation';
import { IAvatarFigureContainer } from './IAvatarFigureContainer'; import { IAvatarFigureContainer } from './IAvatarFigureContainer';
import { IPartColor } from './structure'; import { IPartColor } from './structure';
export interface IAvatarImage extends IDisposable export interface IAvatarImage
{ {
setDirection(_arg_1: string, _arg_2: number): void; setDirection(_arg_1: string, _arg_2: number): void;
setDirectionAngle(_arg_1: string, _arg_2: number): void; setDirectionAngle(_arg_1: string, _arg_2: number): void;

View File

@ -1,4 +1,4 @@
import { IAssetManager, IGraphicAsset, INitroManager } from '../../core'; import { IGraphicAsset } from '../core';
import { AvatarAssetDownloadManager } from './AvatarAssetDownloadManager'; import { AvatarAssetDownloadManager } from './AvatarAssetDownloadManager';
import { AvatarStructure } from './AvatarStructure'; import { AvatarStructure } from './AvatarStructure';
import { EffectAssetDownloadManager } from './EffectAssetDownloadManager'; import { EffectAssetDownloadManager } from './EffectAssetDownloadManager';
@ -6,8 +6,9 @@ import { IAvatarFigureContainer } from './IAvatarFigureContainer';
import { IAvatarImage } from './IAvatarImage'; import { IAvatarImage } from './IAvatarImage';
import { IStructureData } from './structure/IStructureData'; import { IStructureData } from './structure/IStructureData';
export interface IAvatarRenderManager extends INitroManager export interface IAvatarRenderManager
{ {
init: () => Promise<void>;
createFigureContainer(figure: string): IAvatarFigureContainer; createFigureContainer(figure: string): IAvatarFigureContainer;
isFigureContainerReady(container: IAvatarFigureContainer): boolean; isFigureContainerReady(container: IAvatarFigureContainer): boolean;
createAvatarImage(figure: string, size: string, gender: string): Promise<IAvatarImage>; createAvatarImage(figure: string, size: string, gender: string): Promise<IAvatarImage>;
@ -17,7 +18,6 @@ export interface IAvatarRenderManager extends INitroManager
getFigureStringWithFigureIds(k: string, _arg_2: string, _arg_3: number[]): string; getFigureStringWithFigureIds(k: string, _arg_2: string, _arg_3: number[]): string;
getMandatoryAvatarPartSetIds(k: string, _arg_2: number): string[]; getMandatoryAvatarPartSetIds(k: string, _arg_2: number): string[];
getAssetByName(name: string): IGraphicAsset; getAssetByName(name: string): IGraphicAsset;
assets: IAssetManager;
structure: AvatarStructure; structure: AvatarStructure;
structureData: IStructureData; structureData: IStructureData;
downloadManager: AvatarAssetDownloadManager; downloadManager: AvatarAssetDownloadManager;

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { ActionType } from './ActionType'; import { ActionType } from './ActionType';
import { IActionDefinition } from './IActionDefinition'; import { IActionDefinition } from './IActionDefinition';

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { ActionDefinition } from './ActionDefinition'; import { ActionDefinition } from './ActionDefinition';
import { IActiveActionData } from './IActiveActionData'; import { IActiveActionData } from './IActiveActionData';

View File

@ -1,4 +1,4 @@
import { IAssetAlias } from '../../../core'; import { IAssetAlias } from '../../core';
export class AssetAlias export class AssetAlias
{ {

View File

@ -1,25 +1,22 @@
import { AdvancedMap, IAssetManager, IGraphicAsset } from '../../../core'; import { AdvancedMap, AssetManager, IGraphicAsset } from '../../core';
import { AvatarRenderManager } from '../AvatarRenderManager'; import { AvatarRenderManager } from '../AvatarRenderManager';
import { AssetAlias } from './AssetAlias'; import { AssetAlias } from './AssetAlias';
export class AssetAliasCollection export class AssetAliasCollection
{ {
private _assets: IAssetManager;
private _aliases: AdvancedMap<string, AssetAlias>; private _aliases: AdvancedMap<string, AssetAlias>;
private _avatarRenderManager: AvatarRenderManager; private _avatarRenderManager: AvatarRenderManager;
private _missingAssetNames: string[]; private _missingAssetNames: string[];
constructor(renderManager: AvatarRenderManager, assetManager: IAssetManager) constructor(renderManager: AvatarRenderManager)
{ {
this._avatarRenderManager = renderManager; this._avatarRenderManager = renderManager;
this._aliases = new AdvancedMap(); this._aliases = new AdvancedMap();
this._assets = assetManager;
this._missingAssetNames = []; this._missingAssetNames = [];
} }
public dispose(): void public dispose(): void
{ {
this._assets = null;
this._aliases = null; this._aliases = null;
} }
@ -30,7 +27,7 @@ export class AssetAliasCollection
public init(): void public init(): void
{ {
for(const collection of this._assets.collections.getValues()) for(const collection of AssetManager.collections.getValues())
{ {
if(!collection) continue; if(!collection) continue;
@ -76,11 +73,9 @@ export class AssetAliasCollection
public getAsset(name: string): IGraphicAsset public getAsset(name: string): IGraphicAsset
{ {
if(!this._assets) return null;
name = this.getAssetName(name); name = this.getAssetName(name);
const asset = this._assets.getAsset(name); const asset = AssetManager.getAsset(name);
if(!asset) return null; if(!asset) return null;

View File

@ -1,4 +1,4 @@
import { IAssetAnimationAdd } from '../../../core'; import { IAssetAnimationAdd } from '../../core';
export class AddDataContainer export class AddDataContainer
{ {

View File

@ -1,4 +1,4 @@
import { AdvancedMap, IAssetAnimation, IAssetAnimationFrame } from '../../../core'; import { AdvancedMap, IAssetAnimation, IAssetAnimationFrame } from '../../core';
import { AvatarStructure } from '../AvatarStructure'; import { AvatarStructure } from '../AvatarStructure';
import { AddDataContainer } from './AddDataContainer'; import { AddDataContainer } from './AddDataContainer';
import { AvatarAnimationLayerData } from './AvatarAnimationLayerData'; import { AvatarAnimationLayerData } from './AvatarAnimationLayerData';

View File

@ -1,4 +1,4 @@
import { AdvancedMap, IAssetAnimation } from '../../../core'; import { AdvancedMap, IAssetAnimation } from '../../core';
import { AvatarStructure } from '../AvatarStructure'; import { AvatarStructure } from '../AvatarStructure';
import { Animation } from './Animation'; import { Animation } from './Animation';
import { IAnimation } from './IAnimation'; import { IAnimation } from './IAnimation';

View File

@ -1,4 +1,4 @@
import { AdvancedMap, IAssetAnimationFramePart } from '../../../core'; import { AdvancedMap, IAssetAnimationFramePart } from '../../core';
import { ActiveActionData, IActionDefinition, IActiveActionData } from '../actions'; import { ActiveActionData, IActionDefinition, IActiveActionData } from '../actions';
import { IAnimationLayerData } from './IAnimationLayerData'; import { IAnimationLayerData } from './IAnimationLayerData';

View File

@ -1,4 +1,4 @@
import { AdvancedMap, IAssetAnimationAvatar } from '../../../core'; import { AdvancedMap, IAssetAnimationAvatar } from '../../core';
import { IAvatarDataContainer } from './IAvatarDataContainer'; import { IAvatarDataContainer } from './IAvatarDataContainer';
export class AvatarDataContainer implements IAvatarDataContainer export class AvatarDataContainer implements IAvatarDataContainer

View File

@ -1,4 +1,4 @@
import { IAssetAnimationDirection } from '../../../core'; import { IAssetAnimationDirection } from '../../core';
export class DirectionDataContainer export class DirectionDataContainer
{ {

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { IAnimation } from './IAnimation'; import { IAnimation } from './IAnimation';
import { IAnimationLayerData } from './IAnimationLayerData'; import { IAnimationLayerData } from './IAnimationLayerData';

View File

@ -1,4 +1,4 @@
import { IAssetAnimationSprite } from '../../../core'; import { IAssetAnimationSprite } from '../../core';
import { IAnimation } from './IAnimation'; import { IAnimation } from './IAnimation';
import { ISpriteDataContainer } from './ISpriteDataContainer'; import { ISpriteDataContainer } from './ISpriteDataContainer';
@ -16,6 +16,7 @@ export class SpriteDataContainer implements ISpriteDataContainer
constructor(animation: IAnimation, sprite: IAssetAnimationSprite) constructor(animation: IAnimation, sprite: IAssetAnimationSprite)
{ {
console.log(sprite);
this._animation = animation; this._animation = animation;
this._id = sprite.id; this._id = sprite.id;
this._ink = sprite.ink; this._ink = sprite.ink;

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { AvatarImageDirectionCache } from './AvatarImageDirectionCache'; import { AvatarImageDirectionCache } from './AvatarImageDirectionCache';
export class AvatarImageActionCache export class AvatarImageActionCache

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { IActiveActionData } from '../actions'; import { IActiveActionData } from '../actions';
import { AvatarImageActionCache } from './AvatarImageActionCache'; import { AvatarImageActionCache } from './AvatarImageActionCache';

View File

@ -1,4 +1,4 @@
import { AdvancedMap, CanvasUtilities, Point, Rectangle } from '../../../core'; import { AdvancedMap, CanvasUtilities, Point, Rectangle } from '../../core';
import { IActiveActionData } from '../actions'; import { IActiveActionData } from '../actions';
import { AssetAliasCollection } from '../alias'; import { AssetAliasCollection } from '../alias';
import { AvatarAnimationLayerData } from '../animation'; import { AvatarAnimationLayerData } from '../animation';

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { AvatarImageBodyPartContainer } from '../AvatarImageBodyPartContainer'; import { AvatarImageBodyPartContainer } from '../AvatarImageBodyPartContainer';
import { AvatarImagePartContainer } from '../AvatarImagePartContainer'; import { AvatarImagePartContainer } from '../AvatarImagePartContainer';

View File

@ -1,5 +1,5 @@
import { Canvas } from 'canvas'; import { Canvas } from 'canvas';
import { Point, Rectangle } from '../../../core'; import { Point, Rectangle } from '../../core';
export class CompleteImageData export class CompleteImageData
{ {

View File

@ -1,4 +1,4 @@
import { Point, Rectangle, Texture } from '../../../core'; import { Point, Rectangle, Texture } from '../../core';
export class ImageData export class ImageData
{ {

View File

@ -12,17 +12,17 @@ export const HabboAvatarGeometry = {
'geometries': [ 'geometries': [
{ {
'id': 'vertical', 'id': 'vertical',
'width': 64, 'width': 90,
'height': 110, 'height': 130,
'dx': 0, 'dx': 0,
'dy': 6 'dy': 0
}, },
{ {
'id': 'sitting', 'id': 'sitting',
'width': 64, 'width': 90,
'height': 110, 'height': 130,
'dx': 0, 'dx': 0,
'dy': 6 'dy': 0
}, },
{ {
'id': 'horizontal', 'id': 'horizontal',

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { IAvatarImage } from '../IAvatarImage'; import { IAvatarImage } from '../IAvatarImage';
import { AvatarCanvas } from '../structure'; import { AvatarCanvas } from '../structure';
import { AvatarSet } from './AvatarSet'; import { AvatarSet } from './AvatarSet';

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
export class AvatarSet export class AvatarSet
{ {

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { IAvatarImage } from '../IAvatarImage'; import { IAvatarImage } from '../IAvatarImage';
import { GeometryItem } from './GeometryItem'; import { GeometryItem } from './GeometryItem';
import { Matrix4x4 } from './Matrix4x4'; import { Matrix4x4 } from './Matrix4x4';

View File

@ -20,5 +20,8 @@ export * from './IAvatarFigureContainer';
export * from './IAvatarImage'; export * from './IAvatarImage';
export * from './IAvatarRenderManager'; export * from './IAvatarRenderManager';
export * from './interfaces'; export * from './interfaces';
export * from './PlaceHolderAvatarImage'; export * from './interfaces/figuredata';
export * from './structure'; export * from './structure';
export * from './structure/animation';
export * from './structure/figure';
export * from './structure/parts';

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { IActionDefinition } from '../actions'; import { IActionDefinition } from '../actions';
import { AnimationAction } from './animation'; import { AnimationAction } from './animation';
import { IFigureSetData } from './IFigureSetData'; import { IFigureSetData } from './IFigureSetData';

View File

@ -1,4 +1,4 @@
import { Point } from '../../../core'; import { Point } from '../../core';
import { AvatarScaleType } from '../enum'; import { AvatarScaleType } from '../enum';
export class AvatarCanvas export class AvatarCanvas

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { IFigureData } from '../interfaces'; import { IFigureData } from '../interfaces';
import { IFigurePartSet, IPalette, ISetType, Palette, SetType } from './figure'; import { IFigurePartSet, IPalette, ISetType, Palette, SetType } from './figure';
import { IFigureSetData } from './IFigureSetData'; import { IFigureSetData } from './IFigureSetData';

View File

@ -1,4 +1,4 @@
import { AdvancedMap } from '../../../core'; import { AdvancedMap } from '../../core';
import { ActionDefinition, IActionDefinition } from '../actions'; import { ActionDefinition, IActionDefinition } from '../actions';
import { IFigureSetData } from './IFigureSetData'; import { IFigureSetData } from './IFigureSetData';
import { ActivePartSet, PartDefinition } from './parts'; import { ActivePartSet, PartDefinition } from './parts';

View File

@ -1,4 +1,4 @@
import { AdvancedMap, Point } from '../../../../core'; import { AdvancedMap, Point } from '../../../core';
import { AnimationActionPart } from './AnimationActionPart'; import { AnimationActionPart } from './AnimationActionPart';
export class AnimationAction export class AnimationAction

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