OpenSimulator Internals/Walkthroughs/Avatar Logs Out
OpenSimulator Internals/Walkthroughs/Avatar Logs Out
[edit]Overview
[edit]Traces what happens in code, connectors, and database when an avatar logs out normally. Covers both viewer-initiated logout and region-initiated close.
This does not cover region crossing or teleport departure -- see OpenSimulator Internals/Walkthroughs/Avatar Transfer Between Regions.
1. Logout Initiated
[edit]Viewer-initiated
[edit]OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
- Avatar clicks Logout in viewer.
- Viewer sends LogoutRequest UDP packet.
- LLClientView.HandleLogout() fires. Sets IsLoggingOut = true on the client.
- Calls Scene.CloseAgent(agentID, force=false).
Region-initiated (admin kick or simulator shutdown)
[edit]- Console command or admin API calls Scene.CloseAgent(agentID, force=true).
- Or: LLClientView.OnConnectionClosed fires when viewer connection drops; EntityTransferModule.OnConnectionClosed() sets transfer state to Aborting if in transit.
2. Scene.CloseAgent()
[edit]OpenSim/Region/Framework/Scenes/Scene.cs -- CloseAgent()
Under m_removeClientLock:
- Gets ScenePresence. If null or IsDeleted: removes from clientManager, authenticateHandler, capsModule directly and returns.
- Checks LifecycleState -- must be Running or PreRemove to proceed.
- Checks DoNotCloseAfterTeleport -- if true (another region renewed the child connection), resets flag and returns false without closing.
- Sets sp.LifecycleState = Removing.
Then outside the lock:
- Calls sp.ControllingClient.Close(force, force) -- this triggers RemoveClient() via the client stack.
- For NPCs: calls UserManagementModule.RemoveUser().
3. RemoveClient()
[edit]OpenSim/Region/Framework/Scenes/Scene.cs -- RemoveClient()
Under m_removeClientPrivLock:
- Gets AgentCircuitData -- if null, aborts.
- Gets ScenePresence -- if null, removes circuit and returns.
- If child agent and closeChildAgents: sends SendShutdownConnectionNotice() to viewer.
- If avatar is sitting: calls avatar.StandUp().
- Calls m_sceneGraph.removeUserCount(!isChildAgent).
- If root agent and closeChildAgents:
- Gets KnownRegionHandles (all known neighbour regions).
- Calls m_sceneGridService.SendCloseChildAgentConnections() -- async HTTP DELETE to each neighbour simulator's agent endpoint.
- Fires EventManager.TriggerClientClosed().
- Fires EventManager.TriggerOnRemovePresence().
- If root agent:
- Calls AttachmentsModule.DeRezAttachments() -- saves all attachments to inventory (see step 4).
- Calls ForEachClient() sending SendKillObject for this avatar's LocalId to all connected clients.
- Calls AgentTransactionsModule.RemoveAgentAssetTransactions() if present.
Finally (in finally block, always runs):
- m_authenticateHandler.RemoveCircuit(acd).
- m_sceneGraph.RemoveScenePresence(agentID).
- m_clientManager.Remove(agentID).
- m_capsModule.RemoveCaps(agentID, circuitcode).
- avatar.Dispose().
Note: PresenceService.LogoutAgent() and GridUserService.LoggedOut() are NOT called from RemoveClient(). These are called from LLClientView.Close() or from the login service cleanup path. See step 5.
4. Attachments Saved
[edit]OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs -- DeRezAttachments()
For each attachment SOG:
- Calls PrepareScriptInstanceForSave() -- fires detach script event, waits 30ms, snapshots script state XML. Must run outside AttachmentsSyncLock.
- Calls UpdateDetachedObject():
- Calls m_scene.DeleteSceneObject() -- removes from scene.
- Clears attachment fields (AttachedAvatar, ParentLocalId, IsAttachment).
- For local grid users only (not HG visitors): calls UpdateKnownItem() -- serialises SOG to XML, creates new asset, updates inventory item assetID and permissions.
- Calls so.RemoveScriptInstances() + so.Dispose().
- Calls sp.ClearAttachments().
HG visitors: UpdateKnownItem() skipped. Their attachments are not saved to the foreign grid. When they log back in on their home grid, attachments reload from home grid state.
- DB writes
- assets -- INSERT: updated serialised object XML per attachment (local users only)
- inventoryitems -- UPDATE: new assetID per attachment (local users only)
5. Presence and GridUser Updated
[edit]OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs -- Close() OpenSim/Services/Connectors/Presence/PresenceServicesConnector.cs OpenSim/Services/Connectors/GridUser/GridUserServicesConnector.cs
On client close (called from CloseAgent step 2):
- PresenceService.LogoutAgent(sessionID) called -- HTTP POST to ROBUST PresenceService.
- ROBUST sets presence Online=0, clears RegionID for this session.
- GridUserService.LoggedOut(agentID, sessionID, regionID, position, lookAt) called -- HTTP POST to ROBUST GridUserService.
- ROBUST updates griduser: LastRegionID, LastPosition, LastLookAt, Logout timestamp.
- DB writes
- presence -- UPDATE: Online=0, RegionID cleared
- griduser -- UPDATE: LastPosition, LastLookAt, LastRegionID, Logout timestamp
6. Child Agents Closed
[edit]Called asynchronously from RemoveClient() step 3 via m_sceneGridService.SendCloseChildAgentConnections().
For each neighbour handle in KnownRegionHandles:
- HTTP DELETE to neighbour simulator's agent endpoint (SimulationService).
- Neighbour simulator receives request, validates auth token (SessionID).
- Calls Scene.CloseAgent() on the child ScenePresence.
- Child path: no attachment save, no presence update, just removes from scene graph.
7. Appearance Save (if queued)
[edit]If an appearance save was queued via AvatarFactoryModule and the 5-second delay has not yet elapsed:
- AvatarFactoryModule timer fires SaveAppearance().
- Calls AvatarService.SetAppearance() -- writes final appearance to ROBUST.
Whether this completes before or after the logout depends on timing. A logout immediately after an outfit change may race with or skip the final save.
- DB writes (conditional)
- avatarappearance -- UPDATE: final wearable list, textures, visual params
Shutdown vs Normal Logout
[edit]Scene.Close() (simulator shutdown):
- Fires EventManager.TriggerSceneShuttingDown().
- Calls GridService.DeregisterRegion() -- removes region from regions table. Sets RegionOnline=0.
- Sends Kick message to all root avatars via ControllingClient.Kick().
- Sends SendShutdownConnectionNotice() to all.
- Sleeps 500ms for messages to deliver.
- Calls CloseAgent() for every ScenePresence.
- Calls Backup(true) -- forces persistence of all changed scene objects.
- Closes SceneGraph and disposes PhysicsScene.
- DB writes (on shutdown)
- regions -- UPDATE: RegionOnline=0 (via GridService.DeregisterRegion())
- prims/primshapes/primitems -- UPDATE: all changed objects persisted via Backup(true)
- presence/griduser -- UPDATE: as per normal logout for each agent
Summary: DB Tables Touched
[edit]| Table | Operation | Step |
|---|---|---|
| assets | INSERT | Attachment object assets saved (step 4, local users) |
| inventoryitems | UPDATE | Attachment inventory items updated (step 4, local users) |
| presence | UPDATE | Online=0, session cleared (step 5) |
| griduser | UPDATE | LastPosition, Logout timestamp (step 5) |
| avatarappearance | UPDATE | Final appearance if save queued (step 7, conditional) |
| regions | UPDATE | RegionOnline=0 on shutdown only |
| prims/primshapes | UPDATE | Changed objects on shutdown only |
Simultaneous Logout During Teleport
[edit]If the client sends LogoutRequest while a teleport is in progress:
- EntityTransferModule.OnConnectionClosed() fires.
- If agent is in transit: sets transfer state to Aborting.
- The in-progress teleport path checks Aborting state at each stage and aborts.
- Source region calls CleanupFailedInterRegionTeleport() -- calls SimulationService.CloseAgent() on destination to remove the half-created agent there.
See Also
[edit]- OpenSimulator Internals/Walkthroughs
- OpenSimulator Internals/Code Map/EntityTransferModule
- OpenSimulator Internals/Code Map/Scene
- OpenSimulator Internals/Code Map/ScenePresence
- OpenSimulator Internals/Code Map/AttachmentsModule
- OpenSimulator Internals/Code Map/ROBUST/PresenceService
- OpenSimulator Internals/Connector Architecture/Presence Connector
- OpenSimulator Internals/Walkthroughs/Avatar Rez In Region
- OpenSimulator Internals/Walkthroughs/Avatar Transfer Between Regions