<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://osimdev.org/wiki/index.php?action=history&amp;feed=atom&amp;title=OpenSimulator_Internals%2FCode_Map%2FInventoryAccessModule</id>
	<title>OpenSimulator Internals/Code Map/InventoryAccessModule - Revision history</title>
	<link rel="self" type="application/atom+xml" href="http://osimdev.org/wiki/index.php?action=history&amp;feed=atom&amp;title=OpenSimulator_Internals%2FCode_Map%2FInventoryAccessModule"/>
	<link rel="alternate" type="text/html" href="http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Code_Map/InventoryAccessModule&amp;action=history"/>
	<updated>2026-08-04T15:27:52Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Code_Map/InventoryAccessModule&amp;diff=95&amp;oldid=prev</id>
		<title>Jwbshaw: first</title>
		<link rel="alternate" type="text/html" href="http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Code_Map/InventoryAccessModule&amp;diff=95&amp;oldid=prev"/>
		<updated>2026-07-07T13:21:52Z</updated>

		<summary type="html">&lt;p&gt;first&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= OpenSimulator Internals/Code Map/InventoryAccessModule =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
 OpenSim/Region/CoreModules/Framework/InventoryAccess/BasicInventoryAccessModule.cs&lt;br /&gt;
 OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs&lt;br /&gt;
&lt;br /&gt;
Two modules, one extends the other. BasicInventoryAccessModule handles all local inventory operations. HGInventoryAccessModule extends it for HyperGrid asset mirroring and suitcase management.&lt;br /&gt;
&lt;br /&gt;
Registered as IInventoryAccessModule. Selected via [Modules] InventoryAccessModule = BasicInventoryAccessModule or HGInventoryAccessModule.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== BasicInventoryAccessModule ==&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
&lt;br /&gt;
 [Inventory] section&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Default !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| CoalesceMultipleObjectsToInventory || true || Group multiple selected objects into one coalesced inventory item&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Event Wiring ===&lt;br /&gt;
&lt;br /&gt;
OnNewClient() hooks per client:&lt;br /&gt;
* OnCreateNewInventoryItem → CreateNewInventoryItem()&lt;br /&gt;
&lt;br /&gt;
=== CreateNewInventoryItem() ===&lt;br /&gt;
&lt;br /&gt;
Called when avatar creates a new item directly in inventory (new script, notecard, landmark, etc.).&lt;br /&gt;
&lt;br /&gt;
# Checks CanCreateUserInventory permission.&lt;br /&gt;
# Resolves target folder by ID, or by type if folder not found.&lt;br /&gt;
# If transactionID set (asset upload in progress): delegates to IAgentAssetTransactions.HandleItemCreationFromTransaction().&lt;br /&gt;
# Otherwise creates inline based on asset type:&lt;br /&gt;
#* Landmark: generates landmark asset data (region_id, local_pos, region_handle), stores asset, creates inventory item.&lt;br /&gt;
#* LSLText: uses Constants.DefaultScriptID as asset.&lt;br /&gt;
#* Notecard: uses Constants.EmptyNotecardID.&lt;br /&gt;
#* Settings/Material: uses environment/material defaults.&lt;br /&gt;
#* Clothing/Bodypart: sets flags = subType.&lt;br /&gt;
# Calls Scene.CreateNewInventoryItem() -- writes to inventoryitems table via InventoryService.&lt;br /&gt;
&lt;br /&gt;
; DB writes:&lt;br /&gt;
* assets -- INSERT: new asset (landmark, notecard, etc.)&lt;br /&gt;
* inventoryitems -- INSERT: new inventory item&lt;br /&gt;
&lt;br /&gt;
=== CopyToInventory() ===&lt;br /&gt;
&lt;br /&gt;
Main path for taking objects from world to inventory (Take, TakeCopy, Delete, Return).&lt;br /&gt;
&lt;br /&gt;
# Groups SOGs by owner (for coalesced objects, only same-owner SOGs merge).&lt;br /&gt;
# For each bundle: calls CopyBundleToInventory().&lt;br /&gt;
&lt;br /&gt;
CopyBundleToInventory():&lt;br /&gt;
# Suspends keyframe motion on all SOGs.&lt;br /&gt;
# Records and stores positions/rotations (attachment stored pos used for attachments).&lt;br /&gt;
# Applies NextOwnerMask cleanup.&lt;br /&gt;
# Serialises: single SOG → SceneObjectSerializer.ToOriginalXmlFormat(); multiple → CoalescedSceneObjectsSerializer.ToXml().&lt;br /&gt;
# Restores positions.&lt;br /&gt;
# Calls CreateItemForObject() -- determines destination folder and creates InventoryItemBase shell.&lt;br /&gt;
# Calls AddPermissions() -- computes effective permissions from SOG current+folded perms; applies NextOwner if ownership changes.&lt;br /&gt;
# Creates asset: CreateAsset() → UUID.Random(), stores via AssetService.Store().&lt;br /&gt;
# If SaveToExistingUserInventoryItem: InventoryService.UpdateItem().&lt;br /&gt;
# Otherwise: Scene.AddInventoryItem() → InventoryService.AddItem(). Sends SendInventoryItemCreateUpdate() to client or owner&amp;#039;s client.&lt;br /&gt;
&lt;br /&gt;
; DB writes:&lt;br /&gt;
* assets -- INSERT: serialised object XML&lt;br /&gt;
* inventoryitems -- INSERT or UPDATE&lt;br /&gt;
&lt;br /&gt;
=== CreateItemForObject() ===&lt;br /&gt;
&lt;br /&gt;
Determines destination folder and owner:&lt;br /&gt;
&lt;br /&gt;
* Take / TakeCopy: remoteClient&amp;#039;s agent ID, Object folder (or original folder if owner taking back own item).&lt;br /&gt;
* Delete (own item): Trash folder.&lt;br /&gt;
* Delete (other&amp;#039;s item) / Return: Lost and Found folder of object owner.&lt;br /&gt;
* Group-owned: Last owner&amp;#039;s inventory.&lt;br /&gt;
&lt;br /&gt;
=== AddPermissions() ===&lt;br /&gt;
&lt;br /&gt;
* If new owner (remoteClient != object owner) and PropagatePermissions: applies NextOwnerMask, sets ObjectSlamPerm flag.&lt;br /&gt;
* If same owner: copies current perms preserving folded bits.&lt;br /&gt;
&lt;br /&gt;
=== RezObject() ===&lt;br /&gt;
&lt;br /&gt;
Rezzes an inventory item into the scene.&lt;br /&gt;
&lt;br /&gt;
# Gets InventoryItemBase from InventoryService.&lt;br /&gt;
# Gets asset from AssetService.&lt;br /&gt;
# Calls Scene.GetObjectsToRez() -- deserialises XML into List&amp;lt;SceneObjectGroup&amp;gt;.&lt;br /&gt;
# Calls Scene.GetNewRezLocation() -- raycasts to find rez position.&lt;br /&gt;
# Calls DoPreRezWhenFromItem():&lt;br /&gt;
#* Checks CanRezObject permission for each SOG.&lt;br /&gt;
#* Sets name/description from inventory item.&lt;br /&gt;
#* Applies ownership change and permission slam if new owner or Slam flag set.&lt;br /&gt;
#* Calls ApplyNextOwnerPermissions() if ownership changed.&lt;br /&gt;
#* Sets FromUserInventoryItemID if item is copyable.&lt;br /&gt;
# For each SOG: Scene.AddNewSceneObject(), CreateScriptInstances(), ResumeScripts().&lt;br /&gt;
# Calls DoPostRezWhenFromItem():&lt;br /&gt;
#* If item is no-copy: InventoryService.DeleteItems() -- removes item from inventory.&lt;br /&gt;
&lt;br /&gt;
; DB reads:&lt;br /&gt;
* inventoryitems -- SELECT by item UUID&lt;br /&gt;
* assets -- SELECT by asset UUID&lt;br /&gt;
&lt;br /&gt;
; DB writes (conditional):&lt;br /&gt;
* inventoryitems -- DELETE: if no-copy item consumed on rez&lt;br /&gt;
&lt;br /&gt;
=== CapsUpdateInventoryItemAsset() ===&lt;br /&gt;
&lt;br /&gt;
Called via capability when avatar edits a notecard, script, gesture, etc. in-world.&lt;br /&gt;
&lt;br /&gt;
# Gets item, checks ownership and permissions.&lt;br /&gt;
# Creates new asset from uploaded data.&lt;br /&gt;
# Calls AssetService.Store() + InventoryService.UpdateItem().&lt;br /&gt;
# Returns new asset UUID.&lt;br /&gt;
&lt;br /&gt;
; DB writes:&lt;br /&gt;
* assets -- INSERT: updated asset&lt;br /&gt;
* inventoryitems -- UPDATE: new assetID&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== HGInventoryAccessModule ==&lt;br /&gt;
&lt;br /&gt;
Extends BasicInventoryAccessModule. Active when HyperGrid is enabled.&lt;br /&gt;
&lt;br /&gt;
=== Additional Configuration ===&lt;br /&gt;
&lt;br /&gt;
 [HGInventoryAccessModule] section&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Key !! Default !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| OutboundPermission || true || Allow assets to be posted to foreign user&amp;#039;s asset server&lt;br /&gt;
|-&lt;br /&gt;
| RestrictInventoryAccessAbroad || true || Hide non-suitcase inventory when going HG&lt;br /&gt;
|-&lt;br /&gt;
| CheckSeparateAssets || false || Support grids where world and inventory use different asset servers&lt;br /&gt;
|-&lt;br /&gt;
| RegionHGAssetServerURI || (empty) || Local asset server URL when CheckSeparateAssets=true&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== HGAssetMapper ===&lt;br /&gt;
&lt;br /&gt;
Static singleton. Handles Get() and Post() -- HTTP calls to foreign asset servers to fetch or push assets.&lt;br /&gt;
&lt;br /&gt;
* Get(assetID, agentID, foreignAssetServerURL): fetches asset from foreign server if not in local cache.&lt;br /&gt;
* Post(assetID, agentID, foreignAssetServerURL): pushes local asset to foreign server (subject to OutboundPermission).&lt;br /&gt;
&lt;br /&gt;
=== IsForeignUser() ===&lt;br /&gt;
&lt;br /&gt;
Returns true if the user&amp;#039;s asset server differs from local. Gets AssetServerURI from AgentCircuitData.ServiceURLs or UserManagementModule. If CheckSeparateAssets=true, compares against m_LocalAssetsURL.&lt;br /&gt;
&lt;br /&gt;
=== RezObject() Override ===&lt;br /&gt;
&lt;br /&gt;
Before calling base.RezObject():&lt;br /&gt;
* If IsForeignUser: calls m_assMapper.Get(item.AssetID, agentID, foreignAssetServer) -- fetches object asset from foreign grid if not cached locally.&lt;br /&gt;
&lt;br /&gt;
=== ExportAsset() Override ===&lt;br /&gt;
&lt;br /&gt;
Called from CopyBundleToInventory() after asset is stored:&lt;br /&gt;
* If IsForeignUser and OutboundPermission: calls m_assMapper.Post() -- pushes newly created asset to foreign user&amp;#039;s asset server.&lt;br /&gt;
&lt;br /&gt;
=== Suitcase Management ===&lt;br /&gt;
&lt;br /&gt;
On TeleportStart (HG departure, local user):&lt;br /&gt;
* ProcessInventoryForHypergriding(): fetches root folder content, renames all non-Suitcase folders to &amp;quot;FolderName (Unavailable)&amp;quot;, sends BulkUpdateInventory to client. Avatar sees only My Suitcase contents while abroad.&lt;br /&gt;
&lt;br /&gt;
On TeleportFail (HG departure failed, local user):&lt;br /&gt;
* ProcessInventoryForComingHome(): fetches root folder, sends full inventory back without &amp;quot;(Unavailable)&amp;quot; suffix.&lt;br /&gt;
&lt;br /&gt;
On CompleteMovement (HG arrival, local user returning home):&lt;br /&gt;
* ProcessInventoryForComingHome(): same as TeleportFail -- restores full inventory view.&lt;br /&gt;
&lt;br /&gt;
ProcessInventoryForArriving() and ProcessInventoryForLeaving() are currently no-ops.&lt;br /&gt;
&lt;br /&gt;
=== GenerateLandmark() Override ===&lt;br /&gt;
&lt;br /&gt;
Appends &amp;quot;gatekeeper {URL}&amp;quot; line to landmark data so HG landmarks carry grid identity.&lt;br /&gt;
&lt;br /&gt;
=== Permissions ===&lt;br /&gt;
&lt;br /&gt;
CanTakeObject(): if OutboundPermission=false and user is foreign, only allow taking own objects.&lt;br /&gt;
OnTransferUserInventory(): if OutboundPermission=false, block inventory transfer to foreign users.&lt;br /&gt;
&lt;br /&gt;
=== PostInventoryAsset() ===&lt;br /&gt;
&lt;br /&gt;
Hooked to OnNewInventoryItemUploadComplete event. After any inventory asset upload:&lt;br /&gt;
* If IsForeignUser and OutboundPermission (or asset is a landmark): posts asset to foreign user&amp;#039;s asset server.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[OpenSimulator Internals/Code Map/Scene]]&lt;br /&gt;
* [[OpenSimulator Internals/Code Map/AttachmentsModule]]&lt;br /&gt;
* [[OpenSimulator Internals/Walkthroughs/Avatar Acquires Inventory]]&lt;br /&gt;
* [[OpenSimulator Internals/Walkthroughs/Avatar Rezzes Inventory]]&lt;br /&gt;
* [[OpenSimulator Internals/Walkthroughs/Avatar Removes From Inventory]]&lt;br /&gt;
* [[OpenSimulator Internals/Walkthroughs/Avatar Rezzes Box]]&lt;br /&gt;
* [[OpenSimulator Internals/Walkthroughs/Avatar Derezzes Object]]&lt;/div&gt;</summary>
		<author><name>Jwbshaw</name></author>
	</entry>
</feed>