OpenSimulator Internals/Walkthroughs/Avatar Goes HG
OpenSimulator Internals/Walkthroughs/Avatar Goes HG
Overview
Traces what happens in code, connectors, and database when an avatar HyperGrid teleports from their home grid to a foreign grid, and when they return.
Assumes the home grid runs ROBUST + OpenSim with HGEntityTransferModule enabled.
Part 1: Departing the Home Grid
1. HG Destination Resolved
OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs -- GetFinalDestination() OpenSim/Services/Connectors/Hypergrid/GatekeeperServiceConnector.cs
- Avatar clicks a HG link or enters a HG URI (e.g. hg.example.com:8002:RegionName).
- GridService on source region looks up the destination -- finds a region with RegionFlags.Hyperlink set. This is a local stub entry, not a real region.
- GetFinalDestination() detects the Hyperlink flag.
- Calls GatekeeperServiceConnector.GetHyperlinkRegion() -- HTTP POST to the foreign grid's Gatekeeper service (hg.example.com:8002).
- Gatekeeper validates the request and returns a real GridRegion descriptor for the destination on the foreign grid.
- ValidateGenericConditions() checks appearance restrictions if RestrictAppearanceAbroad=true.
2. Pre-flight at Foreign Gatekeeper
EntityTransferModule -- DoTeleportInternal()
- SimulationService.QueryAccess() -- HTTP POST to destination simulator on foreign grid.
- Destination checks ban list, parcel access, agent limit.
- sp.Appearance.CanTeleport() -- checks outfit compatibility with destination protocol version.
3. Agent Created at Foreign Grid
HGEntityTransferModule -- CreateAgent() override
- Detects Hyperlink destination.
- Checks local user's UserLevel >= LevelHGTeleport. Refuses if insufficient.
- Gets HomeURI from agentCircuit.ServiceURLs.
- Creates UserAgentServiceConnector for home grid's UserAgent service.
- Calls UserAgentService.LoginAgentToGrid(source, agentCircuit, gatekeeperRegion, finalDestination, false) -- HTTP POST to home grid's UserAgent service.
- Home UserAgent service validates the request.
- Home UserAgent service calls foreign Gatekeeper.CreateAgent() -- HTTP POST to foreign gatekeeper.
- Foreign Gatekeeper validates, calls foreign destination simulator's NewUserConnection.
- Returns success.
- Sets logout = true -- this agent will be logged out of home grid.
- Fires TriggerTeleportStart.
4. Agent State Sent
Same as standard teleport (see OpenSimulator Internals/Walkthroughs/Avatar Transfer Between Regions steps 5-6):
- sp.IsChildAgent = true set on source.
- TeleportFinishEvent sent to viewer with foreign destination endpoint and caps URL.
- AgentData built via sp.CopyTo() -- includes appearance, attachments with script states.
- SimulationService.UpdateAgent() -- HTTP POST to foreign destination simulator.
- Foreign destination's IncomingUpdateChildAgent() → CopyFrom() fires.
- UpdateAgent() waits for avatar to become root at destination.
5. Source Grid Logs Out Agent
HGEntityTransferModule -- AgentHasMovedAway() override
Called after UpdateAgent() returns successfully:
- sp.HasMovedAway() -- sends kill packets for non-HUD attachments, handles parcel visibility.
- sp.MakeChildAgent() -- source becomes child.
- sp.closeAllChildAgents() -- closes all neighbour child agents (logout=true path).
- AgentHasMovedAway() fires:
- PresenceService.LogoutAgent(sessionID) -- marks agent offline on home grid.
- GridUserService.LoggedOut(userID, ...) -- updates home grid's griduser with last position.
- NeedsClosing() returns true for HG (always) -- CloseAgent() called on source after delay.
- DB writes (home grid)
- presence -- UPDATE: Online=0
- griduser -- UPDATE: LastPosition, Logout timestamp
6. Avatar Arrives at Foreign Grid
Foreign destination's CompleteMovement() fires when viewer sends CompleteMovementToRegion.
Standard arrival sequence (see OpenSimulator Internals/Walkthroughs/Avatar Rez In Region) with HG differences:
- TeleportFlags.ViaHGLogin is set -- baked texture validation skipped (AvatarFactory.ValidateBakedTextureCache() not called for HG).
- Attachments carried in AgentData. HandleIncomingAttachments() called.
- For HGLogin: HGEntityTransferModule.HandleIncomingAttachments() queues async asset fetch:
- HGUuidGatherer walks each attachment SOG, collects all referenced asset UUIDs.
- Fetches each asset from home grid's AssetServerURI (from AgentCircuitData.ServiceURLs).
- 30-second timeout per asset fetch. On timeout: cancels all pending jobs for this avatar.
- On completion: base.HandleIncomingAttachments() adds SOGs to scene.
- Foreign grid does NOT write to home grid's databases. Avatar's home presence/griduser records are already marked offline (step 5).
- DB writes (foreign grid)
- None for standard avatar data. Foreign grid may cache fetched assets locally.
Part 2: Returning Home
1. TeleportHome Initiated
HGEntityTransferModule -- TeleportHome()
- Avatar clicks "Teleport Home" or script calls llTeleportAgentHome().
- HGEntityTransferModule.TeleportHome() detects foreign user (IsLocalGridUser returns false).
- Gets HomeURI from AgentCircuitData.ServiceURLs.
- Creates UserAgentServiceConnector for home grid.
- Calls UserAgentService.GetHomeRegion(agentID) -- HTTP GET to home grid's UserAgent service.
- Home UserAgent reads griduser table for HomeRegionID, HomePosition, HomeLookAt.
- Returns GridRegion descriptor for home region.
- Constructs Gatekeeper GridRegion from HomeURI.
- Calls DoTeleport() with ViaHome flag.
2. Home Grid Re-entry
Same protocol as any HG teleport but in reverse -- foreign grid is now source, home grid is destination.
Home grid's Gatekeeper receives CreateAgent request. Home grid validates. Home grid's NewUserConnection() fires. Standard arrival sequence.
On home grid arrival:
- TeleportFlags.ViaHGLogin is set.
- Home grid does NOT call PresenceService.LoginAgent() again -- the session was already established on initial login. A new session is established via the Gatekeeper flow.
- Baked texture validation skipped.
- Appearance data arrived via AgentData -- if RestrictAppearanceAbroad was enforced, avatar may arrive in restricted appearance.
3. Foreign Grid Logs Out
HGEntityTransferModule -- AgentHasMovedAway() (foreign grid side) HGEntityTransferModule -- OnConnectionClosed()
- AgentHasMovedAway() with logout=true:
- PresenceService.LogoutAgent() on foreign grid (clears foreign presence record if any).
- GridUserService.LoggedOut() on foreign grid.
- OnConnectionClosed() fires when viewer disconnects from foreign grid:
- For foreign user: calls UserAgentServiceConnector(homeURI).LogoutAgent() -- HTTP POST to home grid's UserAgent service notifying of departure.
Part 3: HG Landmark Teleport
HGEntityTransferModule -- RequestTeleportLandmark()
- Landmark contains Gatekeeper URI + RegionID + position.
- If gatekeeper is local grid: falls back to normal landmark teleport.
- If foreign gatekeeper:
- DNS-resolves the gatekeeper host.
- Calls GatekeeperServiceConnector.GetHyperlinkRegion() -- resolves RegionID to GridRegion on foreign grid.
- Calls ValidateGenericConditions() (appearance check).
- Calls DoTeleport() -- standard HG teleport from here.
Client Verification
HGEntityTransferModule -- VerifyClient()
Called by Scene.CheckClient() on first HTTP contact from a foreign avatar's viewer.
- Gets HomeURI.
- Calls UserAgentServiceConnector(homeURI).VerifyClient(SessionID, token).
- Home grid's UserAgent service confirms the session is valid.
- Returns false → scene removes circuit and closes agent.
Summary: DB Tables Touched
| Table | Grid | Operation | Step |
|---|---|---|---|
| presence | Home | UPDATE: Online=0 | Source logs out (step 5) |
| griduser | Home | UPDATE: LastPosition, Logout | Source logs out (step 5) |
| assets | Foreign | INSERT: fetched attachment assets | Incoming asset fetch (step 6) |
| presence | Foreign | UPDATE: session cleanup | Return/logout (part 2 step 3) |
| griduser | Foreign | UPDATE: LastPosition | Return/logout (part 2 step 3) |
Key HG-specific Differences from Standard Teleport
| Aspect | Standard Teleport | HG Teleport |
|---|---|---|
| CreateAgent | SimulationService.CreateAgent() direct | UserAgentService.LoginAgentToGrid() via home grid |
| logout flag | false | true |
| Source logs out | No | Yes (PresenceService + GridUserService) |
| NeedsClosing | Only if OutViewRange | Always |
| Attachment fetch | Carried in AgentData | Async HGUuidGatherer from foreign AssetServer |
| Baked texture validation | Yes | No (ViaHGLogin) |
| OnConnectionClosed | Base handler | Also notifies home UserAgent service |
| TeleportHome | GridUserService.GetHomeRegion | UserAgentService.GetHomeRegion |
See Also
- OpenSimulator Internals/Walkthroughs
- OpenSimulator Internals/Code Map/HGEntityTransferModule
- OpenSimulator Internals/Code Map/EntityTransferModule
- OpenSimulator Internals/Code Map/ROBUST/GatekeeperService
- OpenSimulator Internals/Code Map/ROBUST/UserAgentService
- OpenSimulator Internals/Connector Architecture/Gatekeeper Connector
- OpenSimulator Internals/Connector Architecture/UserAgent Connector
- OpenSimulator Internals/Walkthroughs/Avatar Transfer Between Regions
- OpenSimulator Internals/Walkthroughs/Avatar Rez In Region