diff --git a/hippolyzer/lib/base/legacy_schema.py b/hippolyzer/lib/base/legacy_schema.py index 70696dc..41deb30 100644 --- a/hippolyzer/lib/base/legacy_schema.py +++ b/hippolyzer/lib/base/legacy_schema.py @@ -113,7 +113,7 @@ class SchemaUUID(SchemaFieldSerializer[UUID]): def schema_field(spec: Type[Union[SchemaBase, SchemaFieldSerializer]], *, default=dataclasses.MISSING, init=True, repr=True, hash=None, compare=True, llsd_name=None, llsd_only=False) -> dataclasses.Field: # noqa """Describe a field in the inventory schema and the shape of its value""" - return dataclasses.field( + return dataclasses.field( # noqa metadata={"spec": spec, "llsd_name": llsd_name, "llsd_only": llsd_only}, default=default, init=init, repr=repr, hash=hash, compare=compare, ) diff --git a/hippolyzer/lib/base/templates.py b/hippolyzer/lib/base/templates.py index a0b2e48..edc0567 100644 --- a/hippolyzer/lib/base/templates.py +++ b/hippolyzer/lib/base/templates.py @@ -135,6 +135,7 @@ class InventoryType(IntEnum): lower = self.name.lower() return { "callingcard": "callcard", + "none": "-1", }.get(lower, lower) diff --git a/hippolyzer/lib/client/inventory_manager.py b/hippolyzer/lib/client/inventory_manager.py index 8ecf1fb..3a6473a 100644 --- a/hippolyzer/lib/client/inventory_manager.py +++ b/hippolyzer/lib/client/inventory_manager.py @@ -1,11 +1,15 @@ +from __future__ import annotations + import gzip import logging +import secrets from pathlib import Path from typing import Union, List, Tuple, Set from hippolyzer.lib.base import llsd from hippolyzer.lib.base.datatypes import UUID from hippolyzer.lib.base.inventory import InventoryModel, InventoryCategory, InventoryItem +from hippolyzer.lib.base.message.message import Block from hippolyzer.lib.client.state import BaseClientSession @@ -30,7 +34,7 @@ class InventoryManager: # completion from the inventory cache. This matches indra's behavior. version=InventoryCategory.VERSION_NONE, type="category", - pref_type="-1", + pref_type=skel_cat.get("type_default", -1), owner_id=self._session.agent_id, )) @@ -108,3 +112,81 @@ class InventoryManager: else: LOG.warning(f"Unknown node type in inv cache: {node_llsd!r}") return categories, items + + +# Thankfully we have 9 billion different ways to represent inventory data. +def ais_item_to_inventory_data(ais_item: dict) -> Block: + return Block( + "InventoryData", + ItemID=ais_item["item_id"], + FolderID=ais_item["parent_id"], + CallbackID=0, + CreatorID=ais_item["permissions"]["creator_id"], + OwnerID=ais_item["permissions"]["owner_id"], + GroupID=ais_item["permissions"]["group_id"], + BaseMask=ais_item["permissions"]["base_mask"], + OwnerMask=ais_item["permissions"]["owner_mask"], + GroupMask=ais_item["permissions"]["group_mask"], + EveryoneMask=ais_item["permissions"]["everyone_mask"], + NextOwnerMask=ais_item["permissions"]["next_owner_mask"], + GroupOwned=0, + AssetID=ais_item["asset_id"], + Type=ais_item["type"], + InvType=ais_item["inv_type"], + Flags=ais_item["flags"], + SaleType=ais_item["sale_info"]["sale_type"], + SalePrice=ais_item["sale_info"]["sale_price"], + Name=ais_item["name"], + Description=ais_item["desc"], + CreationDate=ais_item["created_at"], + # Meaningless here + CRC=secrets.randbits(32), + ) + + +def inventory_data_to_ais_item(inventory_data: Block) -> dict: + return dict( + item_id=inventory_data["ItemID"], + parent_id=inventory_data["ParentID"], + permissions=dict( + creator_id=inventory_data["CreatorID"], + owner_id=inventory_data["OwnerID"], + group_id=inventory_data["GroupID"], + base_mask=inventory_data["BaseMask"], + owner_mask=inventory_data["OwnerMask"], + group_mask=inventory_data["GroupMask"], + everyone_mask=inventory_data["EveryoneMask"], + next_owner_mask=inventory_data["NextOwnerMask"], + ), + asset_id=inventory_data["AssetID"], + type=inventory_data["Type"], + inv_type=inventory_data["InvType"], + flags=inventory_data["Flags"], + sale_info=dict( + sale_type=inventory_data["SaleType"], + sale_price=inventory_data["SalePrice"], + ), + name=inventory_data["Name"], + description=inventory_data["Description"], + creation_at=inventory_data["CreationDate"], + ) + + +def ais_folder_to_inventory_data(ais_folder: dict) -> Block: + return Block( + "FolderData", + FolderID=ais_folder["cat_id"], + ParentID=ais_folder["parent_id"], + CallbackID=0, + Type=ais_folder["preferred_type"], + Name=ais_folder["name"], + ) + + +def inventory_data_to_ais_folder(inventory_data: Block) -> dict: + return dict( + cat_id=inventory_data["FolderID"], + parent_id=inventory_data["ParentID"], + preferred_type=inventory_data["Type"], + name=inventory_data["Name"], + ) diff --git a/hippolyzer/lib/proxy/addon_utils.py b/hippolyzer/lib/proxy/addon_utils.py index c3c7685..e7b7f4c 100644 --- a/hippolyzer/lib/proxy/addon_utils.py +++ b/hippolyzer/lib/proxy/addon_utils.py @@ -7,7 +7,6 @@ import copy import dataclasses import multiprocessing import pickle -import secrets import warnings from hippolyzer.lib.base.datatypes import UUID, Vector3 @@ -103,46 +102,6 @@ def send_chat(message: Union[bytes, str], channel=0, chat_type=ChatType.NORMAL, )) -def ais_item_to_inventory_data(ais_item: dict): - return Block( - "InventoryData", - ItemID=ais_item["item_id"], - FolderID=ais_item["parent_id"], - CallbackID=0, - CreatorID=ais_item["permissions"]["creator_id"], - OwnerID=ais_item["permissions"]["owner_id"], - GroupID=ais_item["permissions"]["group_id"], - BaseMask=ais_item["permissions"]["base_mask"], - OwnerMask=ais_item["permissions"]["owner_mask"], - GroupMask=ais_item["permissions"]["group_mask"], - EveryoneMask=ais_item["permissions"]["everyone_mask"], - NextOwnerMask=ais_item["permissions"]["next_owner_mask"], - GroupOwned=0, - AssetID=ais_item["asset_id"], - Type=ais_item["type"], - InvType=ais_item["inv_type"], - Flags=ais_item["flags"], - SaleType=ais_item["sale_info"]["sale_type"], - SalePrice=ais_item["sale_info"]["sale_price"], - Name=ais_item["name"], - Description=ais_item["desc"], - CreationDate=ais_item["created_at"], - # Meaningless here - CRC=secrets.randbits(32), - ) - - -def ais_folder_to_inventory_data(ais_folder: dict): - return Block( - "FolderData", - FolderID=ais_folder["cat_id"], - ParentID=ais_folder["parent_id"], - CallbackID=0, - Type=ais_folder["preferred_type"], - Name=ais_folder["name"], - ) - - class MetaBaseAddon(abc.ABCMeta): """ Metaclass for BaseAddon that prevents class member assignments from clobbering descriptors diff --git a/hippolyzer/lib/proxy/asset_uploader.py b/hippolyzer/lib/proxy/asset_uploader.py index 8f9bc22..a397533 100644 --- a/hippolyzer/lib/proxy/asset_uploader.py +++ b/hippolyzer/lib/proxy/asset_uploader.py @@ -2,7 +2,7 @@ from hippolyzer.lib.base.datatypes import UUID from hippolyzer.lib.base.message.message import Message, Block from hippolyzer.lib.base.network.transport import Direction from hippolyzer.lib.client.asset_uploader import AssetUploader -from hippolyzer.lib.proxy.addon_utils import ais_item_to_inventory_data +from hippolyzer.lib.client.inventory_manager import ais_item_to_inventory_data class ProxyAssetUploader(AssetUploader):