Improve LLLindenText parsing
This commit is contained in:
@@ -71,7 +71,7 @@ export class InventoryItem
|
||||
groupOwned: false
|
||||
};
|
||||
|
||||
static fromAsset(lineObj: { lines: string[], lineNum: number }, container?: GameObject | InventoryFolder, agent?: Agent): InventoryItem
|
||||
static fromEmbeddedAsset(lineObj: { lines: string[], lineNum: number, pos: number }, container?: GameObject | InventoryFolder, agent?: Agent): InventoryItem
|
||||
{
|
||||
const item: InventoryItem = new InventoryItem(container, agent);
|
||||
let contMetadata = false;
|
||||
@@ -79,7 +79,7 @@ export class InventoryItem
|
||||
let contDesc = false;
|
||||
while (lineObj.lineNum < lineObj.lines.length)
|
||||
{
|
||||
let line = lineObj.lines[lineObj.lineNum++];
|
||||
let line = Utils.getNotecardLine(lineObj);
|
||||
|
||||
if (contMetadata)
|
||||
{
|
||||
@@ -162,7 +162,7 @@ export class InventoryItem
|
||||
{
|
||||
while (lineObj.lineNum < lineObj.lines.length)
|
||||
{
|
||||
result = Utils.parseLine(lineObj.lines[lineObj.lineNum++]);
|
||||
result = Utils.parseLine(Utils.getNotecardLine(lineObj));
|
||||
if (result.key !== null)
|
||||
{
|
||||
if (result.key === '{')
|
||||
@@ -229,7 +229,7 @@ export class InventoryItem
|
||||
{
|
||||
while (lineObj.lineNum < lineObj.lines.length)
|
||||
{
|
||||
result = Utils.parseLine(lineObj.lines[lineObj.lineNum++]);
|
||||
result = Utils.parseLine(Utils.getNotecardLine(lineObj));
|
||||
if (result.key !== null)
|
||||
{
|
||||
if (result.key === '{')
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,5 @@
|
||||
import { InventoryItem } from './InventoryItem';
|
||||
import { Utils } from './Utils';
|
||||
|
||||
export class LLLindenText
|
||||
{
|
||||
@@ -6,14 +7,14 @@ export class LLLindenText
|
||||
|
||||
private lineObj: {
|
||||
lines: string[],
|
||||
lineNum: number
|
||||
lineNum: number,
|
||||
pos: number
|
||||
} = {
|
||||
lines: [],
|
||||
lineNum: 0
|
||||
lineNum: 0,
|
||||
pos: 0
|
||||
};
|
||||
|
||||
private pos = 0;
|
||||
|
||||
body = '';
|
||||
embeddedItems: { [key: number]: InventoryItem } = {};
|
||||
|
||||
@@ -23,9 +24,9 @@ export class LLLindenText
|
||||
{
|
||||
const initial = data.toString('ascii');
|
||||
this.lineObj.lines = initial.split('\n');
|
||||
this.pos = 0;
|
||||
this.lineObj.pos = 0;
|
||||
|
||||
let line = this.getLine();
|
||||
let line = Utils.getNotecardLine(this.lineObj);
|
||||
if (!line.startsWith('Linden text version'))
|
||||
{
|
||||
throw new Error('Invalid Linden Text header');
|
||||
@@ -40,28 +41,28 @@ export class LLLindenText
|
||||
const v2 = data.toString('utf-8');
|
||||
this.lineObj.lines = v2.replace(/\r\n/g, '\n').split('\n');
|
||||
}
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (line !== '{')
|
||||
{
|
||||
throw new Error('Error parsing Linden Text file');
|
||||
}
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (line.startsWith('LLEmbeddedItems'))
|
||||
{
|
||||
this.parseEmbeddedItems();
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
}
|
||||
if (!line.startsWith('Text length'))
|
||||
{
|
||||
throw new Error('Error parsing Linden Text file: ' + line);
|
||||
}
|
||||
const textLength = parseInt(this.getLastToken(line), 10);
|
||||
this.body = data.slice(this.pos, this.pos + textLength).toString();
|
||||
const remainingBuffer = data.slice(this.pos + textLength).toString('ascii');
|
||||
this.body = data.slice(this.lineObj.pos, this.lineObj.pos + textLength).toString();
|
||||
const remainingBuffer = data.slice(this.lineObj.pos + textLength).toString('ascii');
|
||||
this.lineObj.lines = remainingBuffer.split('\n');
|
||||
this.lineObj.lineNum = 0;
|
||||
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (line !== '}')
|
||||
{
|
||||
throw new Error('Error parsing Linden Text file');
|
||||
@@ -93,17 +94,17 @@ export class LLLindenText
|
||||
{
|
||||
return Buffer.from(lines.join('\n') + '\n', 'ascii');
|
||||
}
|
||||
return Buffer.from(lines.join('\n') + '\n', 'utf-8');
|
||||
return Buffer.from(lines.join('\n') + '\n\0', 'utf-8');
|
||||
}
|
||||
|
||||
private parseEmbeddedItems(): void
|
||||
{
|
||||
let line = this.getLine();
|
||||
let line = Utils.getNotecardLine(this.lineObj);
|
||||
if (line !== '{')
|
||||
{
|
||||
throw new Error('Invalid LLEmbeddedItems format (no opening brace)');
|
||||
}
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (!line.startsWith('count'))
|
||||
{
|
||||
throw new Error('Invalid LLEmbeddedItems format (no count)');
|
||||
@@ -111,31 +112,31 @@ export class LLLindenText
|
||||
const itemCount = parseInt(this.getLastToken(line), 10);
|
||||
for (let x = 0; x < itemCount; x++)
|
||||
{
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (line !== '{')
|
||||
{
|
||||
throw new Error('Invalid LLEmbeddedItems format (no item opening brace)');
|
||||
}
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (!line.startsWith('ext char index'))
|
||||
{
|
||||
throw new Error('Invalid LLEmbeddedItems format (no ext char index)');
|
||||
}
|
||||
const index = parseInt(this.getLastToken(line), 10);
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (!line.startsWith('inv_item'))
|
||||
{
|
||||
throw new Error('Invalid LLEmbeddedItems format (no inv_item)');
|
||||
}
|
||||
const item = InventoryItem.fromAsset(this.lineObj);
|
||||
const item = InventoryItem.fromEmbeddedAsset(this.lineObj);
|
||||
this.embeddedItems[index] = item;
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (line !== '}')
|
||||
{
|
||||
throw new Error('Invalid LLEmbeddedItems format (no closing brace)');
|
||||
}
|
||||
}
|
||||
line = this.getLine();
|
||||
line = Utils.getNotecardLine(this.lineObj);
|
||||
if (line !== '}')
|
||||
{
|
||||
throw new Error('Error parsing Linden Text file');
|
||||
@@ -154,12 +155,4 @@ export class LLLindenText
|
||||
return input.substr(index + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private getLine(): string
|
||||
{
|
||||
const line = this.lineObj.lines[this.lineObj.lineNum++];
|
||||
this.pos += Buffer.byteLength(line) + 1;
|
||||
return line.replace(/\r/, '').trim().replace(/[\t ]+/g, ' ');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -978,4 +978,15 @@ export class Utils
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static getNotecardLine(lineObj: {
|
||||
lines: string[],
|
||||
lineNum: number,
|
||||
pos: number
|
||||
}): string
|
||||
{
|
||||
const line = lineObj.lines[lineObj.lineNum++];
|
||||
lineObj.pos += Buffer.byteLength(line) + 1;
|
||||
return line.replace(/\r/, '').trim().replace(/[\t ]+/g, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -990,11 +990,12 @@ export class GameObject implements IGameObjectData
|
||||
const str = file.toString('utf-8');
|
||||
const lineObj = {
|
||||
lines: str.replace(/\r\n/g, '\n').split('\n'),
|
||||
lineNum: 0
|
||||
lineNum: 0,
|
||||
pos: 0
|
||||
};
|
||||
while (lineObj.lineNum < lineObj.lines.length)
|
||||
{
|
||||
const line = lineObj.lines[lineObj.lineNum++];
|
||||
const line = Utils.getNotecardLine(lineObj);
|
||||
const result = Utils.parseLine(line);
|
||||
if (result.key !== null)
|
||||
{
|
||||
@@ -1047,7 +1048,7 @@ export class GameObject implements IGameObjectData
|
||||
*/
|
||||
break;
|
||||
case 'inv_item':
|
||||
this.inventory.push(InventoryItem.fromAsset(lineObj, this, this.region.agent));
|
||||
this.inventory.push(InventoryItem.fromEmbeddedAsset(lineObj, this, this.region.agent));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@caspertech/node-metaverse",
|
||||
"version": "0.6.19",
|
||||
"version": "0.6.22",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@caspertech/node-metaverse",
|
||||
"version": "0.6.19",
|
||||
"version": "0.6.22",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@caspertech/llsd": "^1.0.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@caspertech/node-metaverse",
|
||||
"version": "0.6.21",
|
||||
"version": "0.6.22",
|
||||
"description": "A node.js interface for Second Life.",
|
||||
"main": "dist/lib/index.js",
|
||||
"types": "dist/lib/index.d.ts",
|
||||
|
||||
Reference in New Issue
Block a user