Add additional options for object management

This commit is contained in:
Casper Warden
2023-11-16 22:56:20 +00:00
parent be8ee8f0c5
commit 2bd009bf73
4 changed files with 53 additions and 27 deletions

View File

@@ -6,6 +6,7 @@ import { Subject, Subscription } from 'rxjs';
import { ObjectResolvedEvent } from '../events/ObjectResolvedEvent';
import * as LLSD from '@caspertech/llsd';
import { GetObjectsOptions } from './commands/RegionCommands';
export class ObjectResolver
{
@@ -23,7 +24,7 @@ export class ObjectResolver
}
resolveObjects(objects: GameObject[], forceResolve: boolean = false, skipInventory = false, log = false): Promise<GameObject[]>
resolveObjects(objects: GameObject[], options: GetObjectsOptions): Promise<GameObject[]>
{
return new Promise<GameObject[]>((resolve, reject) =>
{
@@ -32,7 +33,7 @@ export class ObjectResolver
reject(new Error('Region is going away'));
return;
}
if (log)
if (options.outputLog)
{
// console.log('[RESOLVER] Scanning ' + objects.length + ' objects, skipInventory: ' + skipInventory);
}
@@ -52,12 +53,12 @@ export class ObjectResolver
{
this.objectsInQueue[id] = {
object: objs[id],
skipInventory: skipInventory,
log
skipInventory: options.skipInventory === true,
log: options.outputLog === true
};
this.queue.push(id);
}
else if (this.objectsInQueue[id].skipInventory && !skipInventory)
else if (this.objectsInQueue[id].skipInventory && !options.skipInventory)
{
this.objectsInQueue[id].skipInventory = true
}
@@ -68,13 +69,13 @@ export class ObjectResolver
{
const id = parseInt(obj, 10);
const gameObject = objs[id];
if (log)
if (options.outputLog === true)
{
// console.log('ResolvedInventory: ' + gameObject.resolvedInventory + ', skip: ' + skipInventory);
}
if (forceResolve || gameObject.resolvedAt === undefined || gameObject.resolvedAt === 0 || (!skipInventory && !gameObject.resolvedInventory))
if (!options.onlyUnresolved || gameObject.resolvedAt === undefined || gameObject.resolvedAt === 0 || (!options.skipInventory && !gameObject.resolvedInventory))
{
if (forceResolve)
if (!options.onlyUnresolved)
{
gameObject.resolvedAt = 0;
gameObject.resolveAttempts = 0;
@@ -89,7 +90,7 @@ export class ObjectResolver
for (const id of skipped)
{
delete objs[id];
if (log)
if (options.outputLog === true)
{
// console.log('[RESOLVER] Skipping already resolved object. ' + amountLeft + ' objects remaining to resolve (' + this.queue.length + ' in queue)');
}
@@ -109,9 +110,9 @@ export class ObjectResolver
let done = false;
if (obj.resolvedAt !== undefined && obj.resolvedAt > 0)
{
if (skipInventory || obj.resolvedInventory)
if (options.skipInventory === true || obj.resolvedInventory)
{
if (log)
if (options.outputLog === true)
{
// console.log('[RESOLVER] Resolved an object. ' + amountLeft + ' objects remaining to resolve (' + this.queue.length + ' in queue)');
}
@@ -148,13 +149,13 @@ export class ObjectResolver
{
if (objs[obj.ID] !== undefined)
{
if (log)
if (options.outputLog === true)
{
// console.log('Got onObjectResolveRan for 1 object ...');
}
if (!checkObject(obj))
{
if (log)
if (options.outputLog === true)
{
// console.log(' .. Not resolved yet');
}
@@ -163,7 +164,7 @@ export class ObjectResolver
if (!checkObject(obj))
{
// Requeue
if (log)
if (options.outputLog)
{
// console.log(' .. ' + obj.ID + ' still not resolved yet, requeuing');
}
@@ -189,7 +190,7 @@ export class ObjectResolver
{
if (objs[obj.object.ID] !== undefined)
{
if (log)
if (options.outputLog)
{
// console.log('Got object resolved event for ' + obj.object.ID);
}

View File

@@ -36,6 +36,16 @@ import Timeout = NodeJS.Timeout;
import Timer = NodeJS.Timer;
export interface GetObjectsOptions
{
resolve?: boolean;
onlyUnresolved?: boolean;
skipInventory?: boolean;
outputLog?: boolean;
includeTempObjects?: boolean;
includeAvatars?: boolean;
}
export class RegionCommands extends CommandsBase
{
async getRegionHandle(regionID: UUID): Promise<Long>
@@ -374,12 +384,12 @@ export class RegionCommands extends CommandsBase
async resolveObject(object: GameObject, forceResolve = false, skipInventory = false): Promise<GameObject[]>
{
return this.currentRegion.resolver.resolveObjects([object], forceResolve, skipInventory);
return this.currentRegion.resolver.resolveObjects([object], { onlyUnresolved: !forceResolve, skipInventory });
}
async resolveObjects(objects: GameObject[], forceResolve = false, skipInventory = false, log = false): Promise<GameObject[]>
async resolveObjects(objects: GameObject[], forceResolve = false, skipInventory = false, outputLog = false): Promise<GameObject[]>
{
return this.currentRegion.resolver.resolveObjects(objects, forceResolve, skipInventory, log);
return this.currentRegion.resolver.resolveObjects(objects, { onlyUnresolved: !forceResolve, skipInventory, outputLog });
}
private waitForObjectByLocalID(localID: number, timeout: number): Promise<GameObject>
@@ -1513,7 +1523,7 @@ export class RegionCommands extends CommandsBase
}
if (resolve)
{
await this.currentRegion.resolver.resolveObjects([obj]);
await this.currentRegion.resolver.resolveObjects([obj], {});
}
return obj;
}
@@ -1538,7 +1548,7 @@ export class RegionCommands extends CommandsBase
}
if (resolve)
{
await this.currentRegion.resolver.resolveObjects([obj]);
await this.currentRegion.resolver.resolveObjects([obj], {});
}
return obj;
}
@@ -1552,7 +1562,7 @@ export class RegionCommands extends CommandsBase
}
else
{
objects = await this.getAllObjects(true);
objects = await this.getAllObjects({ resolve: true });
}
const idCheck: { [key: string]: boolean } = {};
const matches: GameObject[] = [];
@@ -1608,13 +1618,28 @@ export class RegionCommands extends CommandsBase
return this.currentRegion.getParcels();
}
async getAllObjects(resolve = false, onlyUnresolved = false, skipInventory = false, outputLog = false): Promise<GameObject[]>
async getAllObjects(options: GetObjectsOptions): Promise<GameObject[]>
{
const objs = await this.currentRegion.objects.getAllObjects();
if (resolve)
if (options.resolve)
{
const resolver = new ObjectResolver(this.currentRegion);
await resolver.resolveObjects(objs, !onlyUnresolved, skipInventory, outputLog);
const incl: GameObject[] = [];
for (const obj of objs)
{
if (!options.includeAvatars && obj.PCode === PCode.Avatar)
{
continue;
}
if (!options.includeTempObjects && (((obj.Flags ?? 0) & PrimFlags.Temporary) === PrimFlags.Temporary))
{
continue;
}
incl.push(obj);
}
await resolver.resolveObjects(incl, options);
}
return objs;
}
@@ -1624,7 +1649,7 @@ export class RegionCommands extends CommandsBase
const objs = await this.currentRegion.objects.getObjectsInArea(minX, maxX, minY, maxY, minZ, maxZ);
if (resolve)
{
await this.currentRegion.resolver.resolveObjects(objs);
await this.currentRegion.resolver.resolveObjects(objs, {});
}
return objs;
}

View File

@@ -1502,7 +1502,7 @@ export class GameObject implements IGameObjectData
{
if ((this.resolvedAt === undefined || this.resolvedAt === 0 || !this.resolvedInventory) && this.region?.resolver)
{
await this.region.resolver.resolveObjects([this], true, false, false);
await this.region.resolver.resolveObjects([this], { onlyUnresolved: false });
}
let root = xml;
if (rootNode)

View File

@@ -1,6 +1,6 @@
{
"name": "@caspertech/node-metaverse",
"version": "0.6.9",
"version": "0.6.10",
"description": "A node.js interface for Second Life.",
"main": "dist/lib/index.js",
"types": "dist/lib/index.d.ts",