diff --git a/lib/classes/ObjectResolver.ts b/lib/classes/ObjectResolver.ts index e0e89e6..f9a2857 100644 --- a/lib/classes/ObjectResolver.ts +++ b/lib/classes/ObjectResolver.ts @@ -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 + resolveObjects(objects: GameObject[], options: GetObjectsOptions): Promise { return new Promise((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); } diff --git a/lib/classes/commands/RegionCommands.ts b/lib/classes/commands/RegionCommands.ts index 1036c21..a6724e7 100644 --- a/lib/classes/commands/RegionCommands.ts +++ b/lib/classes/commands/RegionCommands.ts @@ -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 @@ -374,12 +384,12 @@ export class RegionCommands extends CommandsBase async resolveObject(object: GameObject, forceResolve = false, skipInventory = false): Promise { - 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 + async resolveObjects(objects: GameObject[], forceResolve = false, skipInventory = false, outputLog = false): Promise { - 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 @@ -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 + async getAllObjects(options: GetObjectsOptions): Promise { 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; } diff --git a/lib/classes/public/GameObject.ts b/lib/classes/public/GameObject.ts index ecfba36..329e020 100644 --- a/lib/classes/public/GameObject.ts +++ b/lib/classes/public/GameObject.ts @@ -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) diff --git a/package.json b/package.json index 1e00441..2b3f6a6 100644 --- a/package.json +++ b/package.json @@ -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",