2020-01-06 12:10:40 +00:00
|
|
|
import { UUID } from './UUID';
|
2025-01-17 23:37:54 +00:00
|
|
|
import type { WearableType } from '../enums/WearableType';
|
|
|
|
|
import type { SaleType } from '../enums/SaleType';
|
2020-11-19 16:51:14 +00:00
|
|
|
import { SaleTypeLL } from '../enums/SaleTypeLL';
|
|
|
|
|
import { Utils } from './Utils';
|
2018-11-05 11:45:04 +00:00
|
|
|
|
|
|
|
|
export class LLWearable
|
|
|
|
|
{
|
2025-01-17 23:37:54 +00:00
|
|
|
public name: string;
|
|
|
|
|
public type: WearableType;
|
|
|
|
|
public parameters: Record<number, number> = {};
|
|
|
|
|
public textures: Record<number, UUID> = {};
|
|
|
|
|
public permission: {
|
2018-11-05 11:45:04 +00:00
|
|
|
baseMask: number,
|
|
|
|
|
ownerMask: number,
|
|
|
|
|
groupMask: number,
|
|
|
|
|
everyoneMask: number,
|
|
|
|
|
nextOwnerMask: number,
|
|
|
|
|
creatorID: UUID,
|
|
|
|
|
ownerID: UUID,
|
|
|
|
|
lastOwnerID: UUID,
|
|
|
|
|
groupID: UUID
|
|
|
|
|
} = {
|
|
|
|
|
baseMask: 0,
|
|
|
|
|
ownerMask: 0,
|
|
|
|
|
groupMask: 0,
|
|
|
|
|
everyoneMask: 0,
|
|
|
|
|
nextOwnerMask: 0,
|
|
|
|
|
creatorID: UUID.zero(),
|
|
|
|
|
ownerID: UUID.zero(),
|
|
|
|
|
lastOwnerID: UUID.zero(),
|
|
|
|
|
groupID: UUID.zero()
|
|
|
|
|
};
|
2025-01-17 23:37:54 +00:00
|
|
|
public saleType: SaleType;
|
|
|
|
|
public salePrice: number;
|
|
|
|
|
|
|
|
|
|
public constructor(data?: string)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
if (data !== undefined)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const lines: string[] = data.replace(/\r\n/g, '\n').split('\n');
|
|
|
|
|
for (let index = 0; index < lines.length; index++)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
if (index === 0)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const header = lines[index].split(' ');
|
|
|
|
|
if (header[0] !== 'LLWearable')
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
else if (index === 1)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
this.name = lines[index];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const parsedLine = Utils.parseLine(lines[index]);
|
|
|
|
|
if (parsedLine.key !== null)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
switch (parsedLine.key)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
case 'base_mask':
|
|
|
|
|
this.permission.baseMask = parseInt(parsedLine.value, 16);
|
|
|
|
|
break;
|
|
|
|
|
case 'owner_mask':
|
|
|
|
|
this.permission.ownerMask = parseInt(parsedLine.value, 16);
|
|
|
|
|
break;
|
|
|
|
|
case 'group_mask':
|
|
|
|
|
this.permission.groupMask = parseInt(parsedLine.value, 16);
|
|
|
|
|
break;
|
|
|
|
|
case 'everyone_mask':
|
|
|
|
|
this.permission.everyoneMask = parseInt(parsedLine.value, 16);
|
|
|
|
|
break;
|
|
|
|
|
case 'next_owner_mask':
|
|
|
|
|
this.permission.nextOwnerMask = parseInt(parsedLine.value, 16);
|
|
|
|
|
break;
|
|
|
|
|
case 'creator_id':
|
|
|
|
|
this.permission.creatorID = new UUID(parsedLine.value);
|
|
|
|
|
break;
|
|
|
|
|
case 'owner_id':
|
|
|
|
|
this.permission.ownerID = new UUID(parsedLine.value);
|
|
|
|
|
break;
|
|
|
|
|
case 'last_owner_id':
|
|
|
|
|
this.permission.lastOwnerID = new UUID(parsedLine.value);
|
|
|
|
|
break;
|
|
|
|
|
case 'group_id':
|
|
|
|
|
this.permission.groupID = new UUID(parsedLine.value);
|
|
|
|
|
break;
|
|
|
|
|
case 'sale_type':
|
|
|
|
|
switch (parsedLine.value.trim().toLowerCase())
|
|
|
|
|
{
|
|
|
|
|
case 'not':
|
|
|
|
|
this.saleType = 0;
|
|
|
|
|
break;
|
|
|
|
|
case 'orig':
|
|
|
|
|
this.saleType = 1;
|
|
|
|
|
break;
|
|
|
|
|
case 'copy':
|
|
|
|
|
this.saleType = 2;
|
|
|
|
|
break;
|
|
|
|
|
case 'cntn':
|
|
|
|
|
this.saleType = 3;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
console.log('Unrecognised saleType: ' + parsedLine.value.trim().toLowerCase());
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'sale_price':
|
|
|
|
|
this.salePrice = parseInt(parsedLine.value, 10);
|
|
|
|
|
break;
|
|
|
|
|
case 'type':
|
|
|
|
|
this.type = parseInt(parsedLine.value, 10);
|
|
|
|
|
break;
|
|
|
|
|
case 'parameters':
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const num = parseInt(parsedLine.value, 10);
|
|
|
|
|
const max = index + num;
|
|
|
|
|
for (index; index < max; index++)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const paramLine = Utils.parseLine(lines[index + 1]);
|
|
|
|
|
if (paramLine.key !== null)
|
|
|
|
|
{
|
|
|
|
|
this.parameters[parseInt(paramLine.key, 10)] = parseFloat(paramLine.value.replace('-.', '-0.'));
|
|
|
|
|
}
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
break;
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
case 'textures':
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const num = parseInt(parsedLine.value, 10);
|
|
|
|
|
const max = index + num;
|
|
|
|
|
for (index; index < max; index++)
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2025-01-17 23:37:54 +00:00
|
|
|
if (lines[index + 1] === undefined)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
const texLine = Utils.parseLine(lines[index + 1]);
|
|
|
|
|
if (texLine.key !== null)
|
|
|
|
|
{
|
|
|
|
|
this.textures[parseInt(texLine.key, 10)] = new UUID(texLine.value);
|
|
|
|
|
}
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
break;
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
case 'permissions':
|
|
|
|
|
case 'sale_info':
|
|
|
|
|
case '{':
|
|
|
|
|
case '}':
|
|
|
|
|
// ignore
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-17 23:37:54 +00:00
|
|
|
public toAsset(): string
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const lines: string[] = [
|
|
|
|
|
'LLWearable version 22'
|
|
|
|
|
];
|
|
|
|
|
lines.push(this.name);
|
|
|
|
|
lines.push('');
|
|
|
|
|
lines.push('\tpermissions 0');
|
|
|
|
|
lines.push('\t{');
|
|
|
|
|
lines.push('\t\tbase_mask\t' + Utils.numberToFixedHex(this.permission.baseMask));
|
|
|
|
|
lines.push('\t\towner_mask\t' + Utils.numberToFixedHex(this.permission.ownerMask));
|
|
|
|
|
lines.push('\t\tgroup_mask\t' + Utils.numberToFixedHex(this.permission.groupMask));
|
|
|
|
|
lines.push('\t\teveryone_mask\t' + Utils.numberToFixedHex(this.permission.everyoneMask));
|
|
|
|
|
lines.push('\t\tnext_owner_mask\t' + Utils.numberToFixedHex(this.permission.nextOwnerMask));
|
|
|
|
|
lines.push('\t\tcreator_id\t' + this.permission.creatorID.toString());
|
|
|
|
|
lines.push('\t\towner_id\t' + this.permission.ownerID.toString());
|
|
|
|
|
lines.push('\t\tlast_owner_id\t' + this.permission.lastOwnerID.toString());
|
|
|
|
|
lines.push('\t\tgroup_id\t' + this.permission.groupID.toString());
|
|
|
|
|
lines.push('\t}');
|
|
|
|
|
lines.push('\tsale_info\t0');
|
|
|
|
|
lines.push('\t{');
|
|
|
|
|
lines.push('\t\tsale_type\t' + SaleTypeLL[this.saleType]);
|
|
|
|
|
lines.push('\t\tsale_price\t' + this.salePrice);
|
|
|
|
|
lines.push('\t}');
|
|
|
|
|
lines.push('type ' + this.type);
|
|
|
|
|
lines.push('parameters ' + Object.keys(this.parameters).length);
|
|
|
|
|
for (const num of Object.keys(this.parameters))
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const val = this.parameters[parseInt(num, 10)];
|
|
|
|
|
lines.push(num + (' ' + String(val).replace('-0.', '-.')).replace(' 0.', ' .'));
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
lines.push('textures ' + Object.keys(this.textures).length);
|
|
|
|
|
for (const num of Object.keys(this.textures))
|
2018-11-05 11:45:04 +00:00
|
|
|
{
|
2020-11-19 16:51:14 +00:00
|
|
|
const val = this.textures[parseInt(num, 10)];
|
2025-01-17 23:37:54 +00:00
|
|
|
lines.push(num + ' ' + val.toString());
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
2020-11-19 16:51:14 +00:00
|
|
|
return lines.join('\n') + '\n';
|
2018-11-05 11:45:04 +00:00
|
|
|
}
|
|
|
|
|
}
|