Jump to content

OpenSimulator Internals/Walkthroughs/Avatar Acquires Inventory

From Open Simulator Technical Help

OpenSimulator Internals/Walkthroughs/Avatar Acquires Inventory

[edit]

Overview

[edit]

Traces what happens in code, connectors, and database when an avatar acquires an object into inventory. Covers three cases:

  1. Taking a copyable object from the world (Take Copy).
  2. Taking a no-copy object from the world (Take / derez).
  3. Buying an object from another avatar or vendor (buy object).

Avatar-to-avatar direct inventory transfer (Give Inventory) is a separate flow not covered here.


Case 1: Take Copy (copyable object)

[edit]

Avatar right-clicks an object they have copy permission on and selects Take Copy.

1. Client Sends DeRezObject

[edit]
OpenSim/Region/Framework/Scenes/Scene.cs -- DeRezObjects()
  1. Viewer sends DeRezObject packet with action = TakeCopy.
  2. Scene.DeRezObjects() fires.
  3. Permission check: CanTakeObject() for the SOG.
  4. If passing: calls IInventoryAccessModule.CopyToInventory(DeRezAction.TakeCopy, folderID, objlist, remoteClient, false).
  5. Object remains in scene -- Take Copy does not delete it.

2. Object Serialised to Asset

[edit]
BasicInventoryAccessModule -- CopyBundleToInventory()
  1. Suspends keyframe motion.
  2. Records current world position/rotation.
  3. Serialises SOG to XML via SceneObjectSerializer.ToOriginalXmlFormat() (single object) or CoalescedSceneObjectsSerializer (multiple selected).
  4. Restores position.
  5. Calls CreateItemForObject(TakeCopy):
    • Destination folder: Object folder (FolderType.Object).
    • Owner: remoteClient.AgentId.
  6. Calls AddPermissions() -- same-owner path: copies current perms, preserves folded bits, applies NextOwnerMask to NextPermissions.
  7. Creates asset: UUID.Random(), AssetType.Object, stores via AssetService.Store().
  8. Calls Scene.AddInventoryItem() → InventoryService.AddItem().
  9. Sends SendInventoryItemCreateUpdate() to client.
DB writes
  • assets -- INSERT: serialised object XML
  • inventoryitems -- INSERT: new item in Object folder

3. HG Asset Post (HG users only)

[edit]
HGInventoryAccessModule -- ExportAsset()

If avatar is a foreign HG user and OutboundPermission=true:

  • m_assMapper.Post(assetID, agentID, foreignAssetServer) -- HTTP POST to push asset to foreign grid.

Case 2: Take (no-copy object, or owner taking back own object)

[edit]

Avatar takes a no-copy object, or picks up their own placed object.

1. Client Sends DeRezObject

[edit]
  1. Viewer sends DeRezObject packet with action = Take.
  2. Same permission check path.
  3. Calls IInventoryAccessModule.CopyToInventory(DeRezAction.Take, folderID, objlist, remoteClient, false).

2. Object Serialised (same as Take Copy)

[edit]

CopyBundleToInventory() with Take:

  • Destination folder: original FromFolderID if owner taking back own item and folder still valid; otherwise Object folder.
  • Asset created and stored, inventory item inserted.

3. Object Removed from Scene

[edit]

DoPostRezWhenFromItem():

  • If item is no-copy (CurrentPermissions & Copy == 0): InventoryService.DeleteItems() removes item from inventory first (item was previously there for the no-copy object).

Scene.DeRezObjects() also:

  • Calls DeleteSceneObject() -- removes SOG from scene graph, removes from SimulationDataService (prims table).
DB writes
  • assets -- INSERT: serialised object XML
  • inventoryitems -- INSERT: new item (or UPDATE if SaveToExisting)
  • inventoryitems -- DELETE: original no-copy item if applicable
  • prims/primshapes -- DELETE: object removed from region storage

Case 3: Buy Object

[edit]

Avatar buys an object set for sale (right-click → Buy).

1. Client Sends ObjectBuy

[edit]
OpenSim/Region/Framework/Scenes/Scene.cs -- ProcessObjectBuy() (via IBuySellModule)
  1. Viewer sends ObjectBuy packet with price.
  2. IBuySellModule.BuyObject() called.
  3. Checks sale type and price.
  4. If sale type is Copy: calls IInventoryAccessModule.CopyToInventory(DeRezAction.TakeCopy) -- same as Take Copy path above. Object stays in scene.
  5. If sale type is Original: calls IInventoryAccessModule.CopyToInventory(DeRezAction.Take). Object leaves scene.
  6. If sale type is Contents: copies contents of the object's inventory to buyer's inventory, not the object itself (separate path via task inventory).

Money transfer (if price > 0):

  • IBuySellModule calls IMoneyModule.ObjectBuy() -- money transfer between accounts. This is grid-specific; base OpenSim has no money module by default.
DB writes (object sale)
  • Same as Take or Take Copy depending on sale type.

Permissions Applied on Acquire

[edit]

AddPermissions() is the key method. Two paths:

New owner (buyer or taker who is not the original owner) and PropagatePermissions=true:

  • effectivePerms = intersection of all parts' CurrentAndFoldedNextPermissions().
  • Applies PermissionsUtil.ApplyNoModFoldedPermissions().
  • basePerms = effectivePerms & RootPart.NextOwnerMask.
  • Fixes and folds: PermissionsUtil.FixAndFoldPermissions().
  • Sets ObjectSlamPerm flag -- permissions applied again on rez.

Same owner (taking back own object):

  • effectivePerms = intersection of current perms.
  • NextPermissions = RootPart.NextOwnerMask & effectivePerms.
  • No slam flag.

Summary: DB Tables Touched

[edit]
Table Operation Case
assets INSERT All cases: new serialised object asset
inventoryitems INSERT All cases: new inventory item
inventoryitems DELETE No-copy Take: removes existing item
prims/primshapes/primitems DELETE Take (no-copy) or Take (own object): removes from region

HG Suitcase Note

[edit]

When a local user is abroad (HG), ProcessInventoryForHypergriding() has renamed their non-suitcase folders to "(Unavailable)". Items they acquire while abroad go into My Suitcase (the only accessible folder). On return home, ProcessInventoryForComingHome() restores the full inventory view.

Foreign users acquiring objects: ExportAsset() posts the asset to their home grid's asset server if OutboundPermission=true.


See Also

[edit]