Files
node-metaverse/lib/classes/Utils.ts
Casper Warden 4740b07e11 - Add LLWearable parsing
- Remove ExtraParams, TextureAnim, ParticleSystem binary data from GameObjects, instead encode on the fly when needed
- Add XML object decoding (WIP)
- Move FlexibleData, LightDate, LightImageData, MeshData, SculptData inside ExtraParams class
-
2018-11-05 11:45:04 +00:00

217 lines
6.4 KiB
TypeScript

import * as Long from 'long';
import {GlobalPosition, HTTPAssets} from '..';
export class Utils
{
static StringToBuffer(str: string): Buffer
{
return Buffer.from(str + '\0', 'utf8');
}
static BufferToStringSimple(buf: Buffer, startPos?: number): string
{
if (buf.length === 0)
{
return '';
}
if (buf[buf.length - 1] === 0)
{
return buf.slice(0, buf.length - 1).toString('utf8');
}
else
{
return buf.toString('utf8');
}
}
static Clamp(value: number, min: number, max: number)
{
value = (value > max) ? max : value;
value = (value < min) ? min : value;
return value;
}
static JSONStringify(obj: object, space: number)
{
const cache: any[] = [];
return JSON.stringify(obj, function (key, value)
{
if (typeof value === 'object' && value !== null)
{
if (cache.indexOf(value) !== -1)
{
try
{
return JSON.parse(JSON.stringify(value));
}
catch (error)
{
return 'Circular Reference';
}
}
cache.push(value);
}
return value;
}, space);
}
static BufferToString(buf: Buffer, startPos?: number):
{
readLength: number,
result: string
}
{
if (buf.length === 0)
{
return {
readLength: 0,
result: ''
};
}
if (startPos === undefined)
{
startPos = 0;
}
let foundNull = -1;
for (let x = startPos; x <= buf.length; x++)
{
if (buf[x] === 0)
{
foundNull = x;
break;
}
}
if (foundNull === -1)
{
console.error('BufferToString: Null terminator not found after ' + (buf.length - startPos) + ' bytes. Buffer length: ' + buf.length + ', startPos: ' + startPos);
foundNull = buf.length - 1;
}
return {
readLength: (foundNull - startPos) + 1,
result: buf.slice(startPos, foundNull).toString('utf8')
}
}
static RegionCoordinatesToHandle(regionX: number, regionY: number): GlobalPosition
{
const realRegionX = Math.floor(regionX / 256) * 256;
const realRegionY = Math.floor(regionY / 256) * 256;
const localX = regionX - realRegionX;
const localY = regionY - realRegionY;
const handle = new Long(realRegionY, realRegionX);
return {
'regionHandle': handle,
'regionX': realRegionX / 256,
'regionY': realRegionY / 256,
'localX': localX,
'localY': localY
};
}
static HTTPAssetTypeToInventoryType(HTTPAssetType: string)
{
switch (HTTPAssetType)
{
case HTTPAssets.ASSET_TEXTURE:
return 'texture';
case HTTPAssets.ASSET_SOUND:
return 'sound';
case HTTPAssets.ASSET_ANIMATION:
return 'animation';
case HTTPAssets.ASSET_GESTURE:
return 'gesture';
case HTTPAssets.ASSET_LANDMARK:
return 'landmark';
case HTTPAssets.ASSET_CALLINGCARD:
return 'callcard';
case HTTPAssets.ASSET_SCRIPT:
return 'script';
case HTTPAssets.ASSET_CLOTHING:
return 'wearable';
case HTTPAssets.ASSET_OBJECT:
return 'object';
case HTTPAssets.ASSET_NOTECARD:
return 'notecard';
case HTTPAssets.ASSET_CATEGORY:
return 'category';
case HTTPAssets.ASSET_LSL_TEXT:
return 'script';
case HTTPAssets.ASSET_LSL_BYTECODE:
return 'script';
case HTTPAssets.ASSET_BODYPART:
return 'wearable';
case HTTPAssets.ASSET_MESH:
return 'mesh';
default:
return '';
}
}
static FloatToByte(val: number, lower: number, upper: number)
{
val = Utils.Clamp(val, lower, upper);
val -= lower;
val /= (upper - lower);
return Math.round(val * 255);
}
static ByteToFloat(byte: number, lower: number, upper: number)
{
const ONE_OVER_BYTEMAX: number = 1.0 / 255;
let fval: number = byte * ONE_OVER_BYTEMAX;
const delta: number = (upper - lower);
fval *= delta;
fval += lower;
const error: number = delta * ONE_OVER_BYTEMAX;
if (Math.abs(fval) < error)
{
fval = 0.0;
}
return fval;
}
static UInt16ToFloat(val: number, lower: number, upper: number)
{
const ONE_OVER_U16_MAX = 1.0 / 65535;
let fval = val * ONE_OVER_U16_MAX;
const delta = upper - lower;
fval *= delta;
fval += lower;
const maxError = delta * ONE_OVER_U16_MAX;
if (Math.abs(fval) < maxError)
{
fval = 0.0;
}
return fval;
}
static Base64EncodeString(str: string): string
{
const buff = new Buffer(str, 'utf8');
return buff.toString('base64');
}
static Base64DecodeString(str: string): string
{
const buff = new Buffer(str, 'base64');
return buff.toString('utf8');
}
static HexToLong(hex: string)
{
while (hex.length < 16)
{
hex = '0' + hex;
}
return new Long(parseInt(hex.substr(8), 16), parseInt(hex.substr(0, 8), 16));
}
static ReadRotationFloat(buf: Buffer, pos: number): number
{
return ((buf[pos] | (buf[pos + 1] << 8)) / 32768.0) * (2 * Math.PI);
}
static ReadGlowFloat(buf: Buffer, pos: number): number
{
return buf[pos] / 255;
}
static ReadOffsetFloat(buf: Buffer, pos: number): number
{
const offset = buf.readInt16LE(pos);
return offset / 32767.0;
}
}