Jump to content

OpenSimulator Internals/Code Map/AttachmentsModule

From Open Simulator Technical Help
Revision as of 13:19, 7 July 2026 by Jwbshaw (talk | contribs) (first)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

OpenSimulator Internals/Code Map/AttachmentsModule

[edit]

Overview

[edit]
OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs

INonSharedRegionModule. Handles all attachment operations: rezzing attachments on login, attaching/detaching objects, saving attachment state to inventory, and transferring attachments between regions. One instance per region.

Registered as IAttachmentsModule. Can be disabled via [Attachments] Enabled=false.

Requires IInventoryAccessModule -- disables itself if unavailable.


Configuration

[edit]
[Attachments] section
Key Default Purpose
Enabled true Enable/disable the module
WearReplacesAll true When attaching to a point, remove all existing attachments at that point

Event Wiring

[edit]

SubscribeToClientEvents() hooks per client:

Event Handler
OnRezSingleAttachmentFromInv Client_OnRezSingleAttachmentFromInv()
OnRezMultipleAttachmentsFromInv Client_OnRezMultipleAttachmentsFromInv()
OnObjectAttach Client_OnObjectAttach()
OnObjectDetach Client_OnObjectDetach()
OnDetachAttachmentIntoInv Client_OnDetachAttachmentIntoInv()
OnObjectDrop Client_OnObjectDrop()

Scene events:

  • OnStartScript / OnStopScript -- sets HasGroupChanged on attachment SOGs when scripts start/stop.

RezAttachments()

[edit]

Called from ScenePresence.CompleteMovement() on real login (IsRealLogin true). Not called for teleports or crossings -- those carry attachments in AgentData.

  1. Returns immediately if sp.GetAttachmentsCount() > 0 (viewer already rezzed them).
  2. Fetches all attachment item UUIDs in a single batch: InventoryService.GetMultipleItems().
  3. For each attachment in sp.Appearance.GetAttachments():
    • Validates item exists and owner matches sp.UUID. If not: removes from appearance.
    • Calls RezSingleAttachmentFromInventoryInternal().
  4. For NPCs: uses AssetID directly, skips inventory item checks.
DB reads
  • inventoryitems -- SELECT batch by item UUID array

RezSingleAttachmentFromInventoryInternal()

[edit]

Core rez path for a single attachment.

  1. Calls IInventoryAccessModule.RezObject() -- fetches asset, deserialises SOG, adds to scene.
  2. Calls AttachObjectInternal() -- attaches SOG to avatar.
  3. If doc (saved script state) provided: LoadScriptState() before attach.
  4. If attach fails: removes SOG from scene and returns null.

AttachObjectInternal()

[edit]

Attaches a SOG already in the scene to an avatar.

  1. Rejects if any avatars are sitting on the object.
  2. Resolves attachment point: uses explicit point, or stored LastAttachPoint, or left hand as fallback.
  3. Rejects if > Constants.MaxAgentAttachments already attached.
  4. If not appending (WearReplacesAll): collects existing SOGs at same attach point for removal.
  5. Calls DetachSingleAttachmentToInv() for each displaced attachment.
  6. Calls UpdateUserInventoryWithAttachment() -- updates inventory item to reflect new attach point.
  7. Calls AttachToAgent() -- physically attaches SOG to avatar in scene.
  8. If resumeScripts: CreateScriptInstances() + ResumeScripts().
  9. Fires EventManager.TriggerOnAttach().

AttachToAgent()

[edit]

Low-level scene attachment.

  1. Calls m_scene.DeleteFromStorage() -- removes object from region storage.
  2. Removes physics actors from all parts.
  3. Sets so.AttachedAvatar, so.AttachmentPoint, so.IsAttachment = true.
  4. Calls sp.AddAttachment(so).
  5. For HUD attachments (HasPrivateAttachmentPoint): sends kill packets to all other clients.
  6. Schedules full update for the SOG.

DetachSingleAttachmentToInv()

[edit]

Detach and save to inventory.

  1. Calls PrepareScriptInstanceForSave() -- fires detach event, waits 30ms, snapshots script state. Must be done OUTSIDE AttachmentsSyncLock to avoid deadlock.
  2. Under AttachmentsSyncLock:
    • Calls sp.Appearance.DetachAttachment() -- updates appearance wearables.
    • Calls AvatarFactory.QueueAppearanceSave().
    • Calls sp.RemoveAttachment().
    • Calls UpdateDetachedObject().

UpdateDetachedObject():

  • Calls m_scene.DeleteSceneObject() -- removes from scene.
  • Clears attachment fields (AttachedAvatar, ParentLocalId, IsAttachment).
  • For local grid users (not HG visitors): calls UpdateKnownItem() -- serialises SOG to XML, updates asset and inventory item.
  • Calls so.RemoveScriptInstances() + so.Dispose().

UpdateKnownItem():

  • Serialises SOG to XML via SceneObjectSerializer.ToOriginalXmlFormat() including script state.
  • Recalculates permissions from current prim permissions.
  • Creates new asset via m_scene.CreateAsset().
  • Calls IInventoryAccessModule.UpdateInventoryItemAsset().
  • Sends SendInventoryItemCreateUpdate() to client.
DB writes (on detach)
  • assets -- INSERT: new serialised object asset
  • inventoryitems -- UPDATE: new assetID, permissions

DetachSingleAttachmentToGround()

[edit]

Drops attachment to world at position 2.5m in front of avatar.

  1. Removes from inventory (DeleteItems).
  2. Clears attachment fields, sets AbsolutePosition.
  3. Calls so.ApplyPhysics(), so.AttachToBackup().
  4. Sends SendRemoveInventoryItem() to client.
  5. Fires TriggerOnAttach(localId, UUID.Zero) -- signals scripts.
  6. Removes script permissions (take controls, camera).
  7. Resumes scripts, schedules updates.
DB writes
  • inventoryitems -- DELETE: removes item from user inventory

CopyAttachments() (for region transfer)

[edit]

CopyAttachments(IScenePresence, AgentData) -- called by ScenePresence.CopyTo() on departure:

  • Clones each attachment SOG for transfer.
  • Snapshots script state via GetStateSnapshot().
  • Stores clones and states in ad.AttachmentObjects / ad.AttachmentObjectStates.

CopyAttachments(AgentData, IScenePresence) -- called by ScenePresence.CopyFrom() on arrival:

  • Calls DeleteAttachmentsFromScene() to clear any existing attachments.
  • Calls m_scene.IncomingAttechments() [sic -- typo in source] to add transferred SOGs.
  • Note: typo IncomingAttechments() in Scene.cs line 2976 and AttachmentsModule.cs (Mantis pending).

DeRezAttachments()

[edit]

Called on avatar departure (not crossing -- crossing uses CopyAttachments).

  • For each attachment: PrepareScriptInstanceForSave() then UpdateDetachedObject().
  • For NPCs: UpdateDetachedObject() with empty script state.

Known Issues

[edit]
  • IncomingAttechments() typo in Scene.cs line 2976 and AttachmentsModule.cs (Mantis pending).
  • Comment in source notes that RegionCombiner module accesses SubscribeToClientEvents() and UnsubscribeFromClientEvents() directly, breaking module encapsulation. Marked as needing a fix.

See Also

[edit]