diff --git a/examples/Objects/TaskInventory.ts b/examples/Objects/TaskInventory.ts new file mode 100644 index 0000000..9149adf --- /dev/null +++ b/examples/Objects/TaskInventory.ts @@ -0,0 +1,35 @@ +import { ExampleBot } from '../ExampleBot'; +import { GameObject, Utils } from '../../lib'; + +class TaskInventory extends ExampleBot +{ + async onConnected(): Promise + { + let attachments: GameObject[] = []; + while(!attachments.length) + { + await Utils.sleep(1000); + attachments = this.bot.currentRegion.objects.getObjectsByParent(this.bot.agent.localID); + } + console.log('Got ' + attachments.length + ' attachments'); + + for(const obj of attachments) + { + await obj.updateInventory(); + for(const task of obj.inventory) + { + console.log('Found task inventory item ' + task.name); + } + } + + console.log('Finished!'); + } +} + +new TaskInventory().run().then(() => +{ + +}).catch((err) => +{ + console.error(err); +}); diff --git a/lib/classes/Caps.ts b/lib/classes/Caps.ts index 951f44d..04c97c7 100644 --- a/lib/classes/Caps.ts +++ b/lib/classes/Caps.ts @@ -106,6 +106,7 @@ export class Caps req.push('RemoteParcelRequest'); req.push('RenderMaterials'); req.push('RequestTextureDownload'); + req.push('RequestTaskInventory'); req.push('ResourceCostSelected'); req.push('RetrieveNavMeshSrc'); req.push('SearchStatRequest'); diff --git a/lib/classes/Utils.ts b/lib/classes/Utils.ts index 0850dcd..c731083 100644 --- a/lib/classes/Utils.ts +++ b/lib/classes/Utils.ts @@ -331,6 +331,40 @@ export class Utils return 0; } } + static capInventoryTypeToAssetType(capInventoryType: string): AssetType + { + switch (capInventoryType) + { + case 'texture': + return AssetType.Texture; + case 'sound': + return AssetType.Sound; + case 'animation': + return AssetType.Animation; + case 'gesture': + return AssetType.Gesture; + case 'landmark': + return AssetType.Landmark; + case 'callcard': + return AssetType.CallingCard; + case 'script': + return AssetType.LSLText; + case 'wearable': + return AssetType.Bodypart; + case 'object': + return AssetType.Object; + case 'notecard': + return AssetType.Notecard; + case 'category': + return AssetType.Category; + case 'mesh': + return AssetType.Mesh; + + default: + return AssetType.Unknown + } + } + static HTTPAssetTypeToCapInventoryType(HTTPAssetType: string): String { diff --git a/lib/classes/public/GameObject.ts b/lib/classes/public/GameObject.ts index 57064bd..862158c 100644 --- a/lib/classes/public/GameObject.ts +++ b/lib/classes/public/GameObject.ts @@ -954,6 +954,94 @@ export class GameObject implements IGameObjectData return; } + try + { + const capURL = await this.region.caps.getCapability('RequestTaskInventory'); + const result = await this.region.caps.capsPerformXMLGet(capURL + '?task_id=' + this.FullID) as { + contents?: { + asset_id?: string, + created_at?: number, + desc?: string, + flags?: number, + inv_type?: string, + item_id?: string, + metadata?: Record, + name?: string, + parent_id?: string; + permissions?: { + base_mask?: number; + creator_id?: string; + everyone_mask?: number; + group_id?: string; + group_mask?: number; + is_owner_group?: boolean; + last_owner_id?: string; + next_owner_mask?: number; + owner_id?: string; + owner_mask?: number; + } + sale_info?: { + sale_price?: number; + sale_type?: string; + } + type?: string + }[] + }; + + if (result.contents) + { + this.inventory = []; + for(const item of result.contents) + { + const invItem = new InventoryItem(this, this.region.agent); + invItem.assetID = new UUID(item.asset_id); + invItem.created = new Date((item.created_at ?? 0) * 1000); + invItem.description = item.desc ?? ''; + invItem.flags = item.flags ?? 0; + invItem.inventoryType = Utils.HTTPAssetTypeToInventoryType(item.inv_type ?? ''); + invItem.itemID = new UUID(item.item_id); + invItem.name = item.name ?? ''; + invItem.parentID = new UUID(item.parent_id); + invItem.permissions = { + baseMask: item.permissions?.base_mask ?? 0, + creator: new UUID(item.permissions?.creator_id), + everyoneMask: item.permissions?.everyone_mask ?? 0, + group: new UUID(item.permissions?.group_id), + groupMask: item.permissions?.group_mask ?? 0, + groupOwned: item.permissions?.is_owner_group ?? false, + lastOwner: new UUID(item.permissions?.last_owner_id), + nextOwnerMask: item.permissions?.next_owner_mask ?? 0, + owner: new UUID(item.permissions?.owner_id), + ownerMask: item.permissions?.owner_mask ?? 0 + } + invItem.salePrice = item.sale_info?.sale_price ?? 0; + switch (item.sale_info?.sale_type) + { + case 'not': + invItem.saleType = 0; + break; + case 'orig': + invItem.saleType = 1; + break; + case 'copy': + invItem.saleType = 2; + break; + case 'cntn': + invItem.saleType = 3; + break; + } + invItem.type = Utils.capInventoryTypeToAssetType(item.inv_type ?? ''); + this.inventory.push(invItem); + } + return; + } + } + catch(e) + { + // ignore + } + + const req = new RequestTaskInventoryMessage(); req.AgentData = { AgentID: this.region.agent.agentID,