Add dotenv

This commit is contained in:
Bill 2021-12-14 00:32:52 -05:00
parent 16479bfbfc
commit def234e058
12 changed files with 1936 additions and 94 deletions

9
.env.new Normal file
View File

@ -0,0 +1,9 @@
API_HOST=localhost
API_PORT=3030
AVATAR_SAVE_PATH=C:/nitro-converted-assets
AVATAR_ACTIONS_URL=https://website.com/gamedata/HabboAvatarActions.json
AVATAR_FIGUREDATA_URL=https://website.com/gamedata/FigureData.json
AVATAR_FIGUREMAP_URL=https://website.com/gamedata/FigureMap.json
AVATAR_EFFECTMAP_URL=https://website.com/gamedata/EffectMap.json
AVATAR_ASSET_URL=https://website.com/bundled/figure/%libname%.nitro
AVATAR_ASSET_EFFECT_URL=https://website.com/bundled/effect/%libname%.nitro

1
.gitignore vendored
View File

@ -49,3 +49,4 @@ Thumbs.db
*.zip *.zip
*.as *.as
*.bin *.bin
.env

128
README.md
View File

@ -1,10 +1,10 @@
# Nitro Imager # Nitro Imager
This tool serves as a server-side habbo-imager using the same avatar generator from nitro-renderer. It will download & cache in memory ``.nitro`` assets. Rendered figures will also save to a local folder to prevent re-renders. You will use the same process as your nitro-client to update assets for the imager. This tool serves as a server-side habbo-imager using the same avatar generator from nitro-renderer. It will download & cache in memory `.nitro` assets. Rendered figures will also save to a local folder to prevent re-renders. You will use the same process as your nitro-client to update assets for the imager.
## Configuration ## Configuration
You must configure your urls in `config.json` First you should rename `.env.new to .env` then set your configuration. Additional options can be found in `config.json`
Your figuredata, figuremap, effectmap, & HabboAvatarActions can safely point to a remote URL without worrying about performance. Your figuredata, figuremap, effectmap, & HabboAvatarActions can safely point to a remote URL without worrying about performance.
@ -14,97 +14,103 @@ You must also set an absolute path to a location where rendered figures can save
## Running the server ## Running the server
**Make sure you run ``npm i`` before first use.** **Make sure you run `npm i` before first use.**
You must compile the server by running ``npm run build`` You must compile the server by running `npm run build`
To start the server you must run ``npm start`` To start the server you must run `npm start`
The server will run on the desired host & port as set in the config. You must setup a reverse proxy on your server to make the imager publicly accessible. The server will run on the desired host & port as set in the config. You must setup a reverse proxy on your server to make the imager publicly accessible.
NGINX Example NGINX Example
server { server {
listen 80; listen 80;
listen [::]:80; listen [::]:80;
listen 443; listen 443;
listen [::]:443; listen [::]:443;
server_name habbo-imaging.website.com; server_name habbo-imaging.website.com;
location / {
proxy_pass http://localhost:1338;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
location / {
proxy_pass http://localhost:1338;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
## URL paramaters ## URL paramaters
Their are a few different options you may pass as URL parameters to generate figures with different actions. All parameters are optional. Their are a few different options you may pass as URL parameters to generate figures with different actions. All parameters are optional.
| key | default | description | | key | default | description |
| ------ | ------ | ------ | | -------------- | ------- | ------------------------------------------------------------------- |
| figure | null | The figure string to be rendered | | figure | null | The figure string to be rendered |
| action | null | The actions to render, see actions below | | action | null | The actions to render, see actions below |
| gesture | std | The gesture to render, see gestures below | | gesture | std | The gesture to render, see gestures below |
| direction | 2 | The direction to render, from 0-7 | | direction | 2 | The direction to render, from 0-7 |
| head_direction | 2 | The head direction to render, from 0-7 | | head_direction | 2 | The head direction to render, from 0-7 |
| headonly | 0 | A value of ``0`` or ``1`` | | headonly | 0 | A value of `0` or `1` |
| dance | 0 | A dance id of 0-4 to render | | dance | 0 | A dance id of 0-4 to render |
| effect | 0 | An effect id to render | | effect | 0 | An effect id to render |
| size | n | The size to render, see sizes below | | size | n | The size to render, see sizes below |
| frame_num | 0 | The frame number to render | | frame_num | 0 | The frame number to render |
| img_format | png | A value of ``png`` or ``gif``. Gif will render all frames of the figure | | img_format | png | A value of `png` or `gif`. Gif will render all frames of the figure |
## Actions ## Actions
You may render multiple actions with a comma separater You may render multiple actions with a comma separater
Example: ``&action=wlk,wav,drk=1`` Example: `&action=wlk,wav,drk=1`
##### Posture ##### Posture
| key | description |
| ------ | ------ | | key | description |
| std | Renders the standing posture | | ------ | ---------------------------- |
| wlk,mv | Renders the walking posture | | std | Renders the standing posture |
| sit | Renders the sitting posture | | wlk,mv | Renders the walking posture |
| lay | Renders the laying posture | | sit | Renders the sitting posture |
| lay | Renders the laying posture |
##### Expression ##### Expression
| key | description |
| ------ | ------ | | key | description |
| wav,wave | Renders the waving expression | | -------- | ------------------------------- |
| blow | Renders the kissing expression | | wav,wave | Renders the waving expression |
| laugh | Renders the laughing expression | | blow | Renders the kissing expression |
| respect | Renders the respect expression | | laugh | Renders the laughing expression |
| respect | Renders the respect expression |
##### Carry / Drink ##### Carry / Drink
To hold a certain drink, use an equal separator with the hand item id. You can only render one of these options at a time To hold a certain drink, use an equal separator with the hand item id. You can only render one of these options at a time
| key | description | | key | description |
| ------ | ------ | | -------- | ------------------------ |
| crr,cri | Renders the carry action | | crr,cri | Renders the carry action |
| drk,usei | Renders the drink action | | drk,usei | Renders the drink action |
## Gestures ## Gestures
| key | description |
| ------ | ------ | | key | description |
| std | Renders the standard gesture | | --- | ------------------------------ |
| std | Renders the standard gesture |
| agr | Renders the aggravated gesture | | agr | Renders the aggravated gesture |
| sad | Renders the sad gesture | | sad | Renders the sad gesture |
| sml | Renders the smile gesture | | sml | Renders the smile gesture |
| srp | Renders the surprised gesture | | srp | Renders the surprised gesture |
## Sizes ## Sizes
| key | description |
| ------ | ------ | | key | description |
| s | Renders the small size (0.5) | | --- | ---------------------------- |
| n | Renders the normal size (1) | | s | Renders the small size (0.5) |
| l | Renders the large size (2) | | n | Renders the normal size (1) |
| l | Renders the large size (2) |
## Known Issues ## Known Issues
* GIFs are only able to render 1 bit alpha channels, therefore most effects will not correctly render due to using many different alpha values.
* The rendered canvas size may not match habbos imager exactly, we will hopefully have this addressed soon. - GIFs are only able to render 1 bit alpha channels, therefore most effects will not correctly render due to using many different alpha values.
- The rendered canvas size may not match habbos imager exactly, we will hopefully have this addressed soon.

View File

@ -1,15 +1,4 @@
{ {
"api.host": "localhost",
"api.port": 3030,
"asset.url": "ABSOLUTE_ASSET_URL_WITHOUT_SLASH",
"gamedata.url": "${asset.url}/gamedata",
"avatar.save.path": "ABSOLUTE_PATH/saved-figures",
"avatar.actions.url": "${gamedata.url}/HabboAvatarActions.json",
"avatar.figuredata.url": "${gamedata.url}/FigureData.json",
"avatar.figuremap.url": "${gamedata.url}/FigureMap.json",
"avatar.effectmap.url": "${gamedata.url}/EffectMap.json",
"avatar.asset.url": "${asset.url}/bundled/figure/%libname%.nitro",
"avatar.asset.effect.url": "${asset.url}/bundled/effect/%libname%.nitro",
"avatar.mandatory.libraries": [ "avatar.mandatory.libraries": [
"bd:1", "bd:1",
"li:0" "li:0"

View File

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

1841
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@
"bytebuffer": "^5.0.1", "bytebuffer": "^5.0.1",
"canvas": "^2.8.0", "canvas": "^2.8.0",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"dotenv": "^10.0.0",
"express": "^4.17.1", "express": "^4.17.1",
"gifencoder": "^2.0.1", "gifencoder": "^2.0.1",
"node-fetch": "^2.6.1", "node-fetch": "^2.6.1",

View File

@ -50,8 +50,8 @@ export class Application extends NitroManager implements IApplication
router.use('/', HttpRouter); router.use('/', HttpRouter);
const host = this.getConfiguration<string>('api.host'); const host = (process.env.API_HOST as string);
const port = this.getConfiguration<number>('api.port'); const port = parseInt(process.env.API_PORT);
router.listen(port, host, () => router.listen(port, host, () =>
{ {

View File

@ -25,7 +25,9 @@ export class AvatarAssetDownloadManager
public async loadFigureMap(): Promise<void> public async loadFigureMap(): Promise<void>
{ {
const url = Application.instance.getConfiguration<string>('avatar.figuremap.url'); const url = (process.env.AVATAR_FIGUREMAP_URL as string);
if(!url || !url.length) return Promise.reject('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);
@ -39,7 +41,9 @@ export class AvatarAssetDownloadManager
{ {
if(!data) return; if(!data) return;
const avatarAssetUrl = Application.instance.getConfiguration<string>('avatar.asset.url'); const url = (process.env.AVATAR_ASSET_URL as string);
if(!url || !url.length) return;
for(const library of data) for(const library of data)
{ {
@ -52,7 +56,7 @@ export class AvatarAssetDownloadManager
this._libraryNames.push(id); this._libraryNames.push(id);
const downloadLibrary = new AvatarAssetDownloadLibrary(id, revision, this._assets, avatarAssetUrl); const downloadLibrary = new AvatarAssetDownloadLibrary(id, revision, this._assets, url);
for(const part of library.parts) for(const part of library.parts)
{ {

View File

@ -84,7 +84,9 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
] ]
}); });
const url = Application.instance.getConfiguration<string>('avatar.actions.url'); const url = (process.env.AVATAR_ACTIONS_URL as string);
if(!url || !url.length) return Promise.reject('invalid_actions_url');
const data = await FileUtilities.readFileAsString(url); const data = await FileUtilities.readFileAsString(url);
@ -97,7 +99,9 @@ export class AvatarRenderManager extends NitroManager implements IAvatarRenderMa
if(this._structure) this._structure.initFigureData(defaultFigureData); if(this._structure) this._structure.initFigureData(defaultFigureData);
const url = Application.instance.getConfiguration<string>('avatar.figuredata.url'); const url = (process.env.AVATAR_FIGUREDATA_URL as string);
if(!url || !url.length) return Promise.reject('invalid_figuredata_url');
const data = await FileUtilities.readFileAsString(url); const data = await FileUtilities.readFileAsString(url);

View File

@ -24,7 +24,9 @@ export class EffectAssetDownloadManager
public async loadEffectMap(): Promise<void> public async loadEffectMap(): Promise<void>
{ {
const url = Application.instance.getConfiguration<string>('avatar.effectmap.url'); const url = (process.env.AVATAR_EFFECTMAP_URL as string);
if(!url || !url.length) return Promise.reject('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);
@ -38,7 +40,9 @@ export class EffectAssetDownloadManager
{ {
if(!data) return; if(!data) return;
const avatarEffectAssetUrl = Application.instance.getConfiguration<string>('avatar.asset.effect.url'); const url = (process.env.AVATAR_ASSET_EFFECT_URL as string);
if(!url || !url.length) return;
for(const effect of data) for(const effect of data)
{ {
@ -52,7 +56,7 @@ export class EffectAssetDownloadManager
this._libraryNames.push(lib); this._libraryNames.push(lib);
const downloadLibrary = new EffectAssetDownloadLibrary(lib, revision, this._assets, avatarEffectAssetUrl); const downloadLibrary = new EffectAssetDownloadLibrary(lib, revision, this._assets, url);
let existing = this._effectMap.getValue(id); let existing = this._effectMap.getValue(id);

View File

@ -14,7 +14,7 @@ export const HabboImagingRouterGet = async (request: Request<any, any, any, Requ
try try
{ {
const buildOptions = BuildFigureOptionsRequest(query); const buildOptions = BuildFigureOptionsRequest(query);
const saveDirectory = Application.instance.getConfiguration<string>('avatar.save.path'); const saveDirectory = (process.env.AVATAR_SAVE_PATH as string);
const directory = FileUtilities.getDirectory(saveDirectory); const directory = FileUtilities.getDirectory(saveDirectory);
const avatarString = BuildFigureOptionsStringRequest(buildOptions); const avatarString = BuildFigureOptionsStringRequest(buildOptions);
const saveFile = new File(`${ directory.path }/${ avatarString }.${ buildOptions.imageFormat }`); const saveFile = new File(`${ directory.path }/${ avatarString }.${ buildOptions.imageFormat }`);