<?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%2FConnector_Architecture%2FSimulation_Connector</id>
	<title>OpenSimulator Internals/Connector Architecture/Simulation Connector - 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%2FConnector_Architecture%2FSimulation_Connector"/>
	<link rel="alternate" type="text/html" href="http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Connector_Architecture/Simulation_Connector&amp;action=history"/>
	<updated>2026-08-04T15:31:29Z</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/Connector_Architecture/Simulation_Connector&amp;diff=78&amp;oldid=prev</id>
		<title>Jwbshaw: first</title>
		<link rel="alternate" type="text/html" href="http://osimdev.org/wiki/index.php?title=OpenSimulator_Internals/Connector_Architecture/Simulation_Connector&amp;diff=78&amp;oldid=prev"/>
		<updated>2026-07-07T12:23:08Z</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/Connector Architecture/Simulation Connector =&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
SimulationServiceConnector is the remote connector for ISimulationService. It handles inter-simulator communication: creating and updating agents during teleport and region crossing, and transferring objects between regions. Unlike the other connectors, it talks directly to region simulators, not to ROBUST.&lt;br /&gt;
&lt;br /&gt;
Source file:&lt;br /&gt;
&lt;br /&gt;
 OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Initialisation ===&lt;br /&gt;
&lt;br /&gt;
No config file reading. No service URI -- the destination URI comes from GridRegion.ServerURI on each call.&lt;br /&gt;
&lt;br /&gt;
Two constructors:&lt;br /&gt;
* Default (no args)&lt;br /&gt;
* IConfigSource -- no-op, config argument unused&lt;br /&gt;
&lt;br /&gt;
GetScene() and GetInnerService() always return null.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Transport ===&lt;br /&gt;
&lt;br /&gt;
Unlike all other connectors, SimulationServiceConnector does not use SynchronousRestFormsRequester. It uses WebUtil methods with OSDMap (LLSD) payloads:&lt;br /&gt;
&lt;br /&gt;
* WebUtil.PostToServiceCompressed() -- compressed POST, used for CreateAgent first attempt&lt;br /&gt;
* WebUtil.PostToService() -- uncompressed POST, used as fallback&lt;br /&gt;
* WebUtil.PutToServiceCompressed() / PutToService() -- PUT, used for UpdateAgent&lt;br /&gt;
* WebUtil.ServiceOSDRequest() -- used for QueryAccess (QUERYACCESS method), ReleaseAgent and CloseAgent (DELETE)&lt;br /&gt;
&lt;br /&gt;
URL pattern: destination.ServerURI + &amp;quot;agent/&amp;quot; + agentID + &amp;quot;/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
AgentPath() and ObjectPath() are virtual -- subclasses can override the path segments.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Agent Methods ===&lt;br /&gt;
&lt;br /&gt;
==== CreateAgent() ====&lt;br /&gt;
&lt;br /&gt;
 public bool CreateAgent(GridRegion source, GridRegion destination, AgentCircuitData aCircuit, uint flags, EntityTransferContext ctx, out string reason)&lt;br /&gt;
&lt;br /&gt;
# Packs AgentCircuitData via aCircuit.PackAgentCircuitData(ctx)&lt;br /&gt;
# Adds context, source region info, destination region info, and teleport flags via PackData()&lt;br /&gt;
# Attempts compressed POST first (WebUtil.PostToServiceCompressed)&lt;br /&gt;
# On success: reads _Result map for actual success/reason&lt;br /&gt;
# On failure: falls back to uncompressed POST (WebUtil.PostToService) with warning that destination should be updated&lt;br /&gt;
# Returns false with reason on all failure paths&lt;br /&gt;
&lt;br /&gt;
====  UpdateAgent(destination, AgentData, ctx) ====&lt;br /&gt;
&lt;br /&gt;
Full agent data update (region crossing). Timeout 200 seconds.&lt;br /&gt;
&lt;br /&gt;
==== UpdateAgent(destination, AgentPosition) ====&lt;br /&gt;
&lt;br /&gt;
Position-only update. Called frequently during avatar movement.&lt;br /&gt;
&lt;br /&gt;
Deduplication via m_updateAgentQueue dictionary keyed by URI:&lt;br /&gt;
* First thread for a URI becomes the worker; subsequent threads update the map and return&lt;br /&gt;
* Worker loops, sending the most recent position until no new update arrives&lt;br /&gt;
* On send failure: blacklists the destination URI for 120 seconds via _failedSims ExpiringCache&lt;br /&gt;
* Blacklisted destinations return false immediately without attempting contact&lt;br /&gt;
&lt;br /&gt;
Private UpdateAgent(destination, IAgentData, ctx, timeout) handles the actual PUT:&lt;br /&gt;
* Uses PutToServiceCompressed&lt;br /&gt;
* If OutboundVersion &amp;gt;= 0.3: returns immediately on success&lt;br /&gt;
* If OutboundVersion &amp;lt; 0.2: falls back to uncompressed PutToService on failure&lt;br /&gt;
&lt;br /&gt;
==== QueryAccess() ====&lt;br /&gt;
&lt;br /&gt;
 public bool QueryAccess(GridRegion destination, UUID agentID, string agentHomeURI, bool viaTeleport, Vector3 position, List&amp;lt;UUID&amp;gt; featuresAvailable, EntityTransferContext ctx, out string reason)&lt;br /&gt;
&lt;br /&gt;
URL: destination.ServerURI + &amp;quot;agent/&amp;quot; + agentID + &amp;quot;/&amp;quot; + destination.RegionID + &amp;quot;/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Sends simulation service version negotiation fields:&lt;br /&gt;
* simulation_service_supported_min/max&lt;br /&gt;
* simulation_service_accepted_min/max&lt;br /&gt;
* my_version (legacy field, set to minimum for safety)&lt;br /&gt;
* features (List of UUID capabilities)&lt;br /&gt;
* context&lt;br /&gt;
&lt;br /&gt;
Response handling:&lt;br /&gt;
* Reads _Result map for success, reason, negotiated_inbound_version, negotiated_outbound_version&lt;br /&gt;
* Falls back to legacy &amp;quot;version&amp;quot; field (SIMULATION/N.N format) if negotiated fields absent&lt;br /&gt;
* Sets ctx.InboundVersion and ctx.OutboundVersion from response&lt;br /&gt;
* If MethodNotAllowed error received: logs it and returns true (legacy simulator compatibility)&lt;br /&gt;
* Sets ctx.WearablesCount based on OutboundVersion:&lt;br /&gt;
** &amp;lt; 0.5: LEGACY_VERSION_MAX_WEARABLES&lt;br /&gt;
** &amp;lt; 0.6: LEGACY_VERSION_MAX_WEARABLES + 1&lt;br /&gt;
** &amp;gt;= 0.6: -1 (send all)&lt;br /&gt;
* Clears featuresAvailable and repopulates from response&lt;br /&gt;
&lt;br /&gt;
Comment in source notes the _Result success/failure is the authoritative one, not the sibling result node -- legacy issue from 0.7.3.1 era labelled &amp;quot;nte4.8 crap&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==== ReleaseAgent() ====&lt;br /&gt;
&lt;br /&gt;
Sends DELETE to a provided URI (not constructed from destination). Always returns true regardless of result.&lt;br /&gt;
&lt;br /&gt;
==== CloseAgent() ====&lt;br /&gt;
&lt;br /&gt;
URL: destination.ServerURI + &amp;quot;agent/&amp;quot; + id + &amp;quot;/&amp;quot; + destination.RegionID + &amp;quot;/?auth=&amp;quot; + auth_code&lt;br /&gt;
&lt;br /&gt;
Sends DELETE. Always returns true regardless of result.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Object Methods ===&lt;br /&gt;
&lt;br /&gt;
==== CreateObject(destination, newPosition, sog, isLocalCall) ====&lt;br /&gt;
&lt;br /&gt;
URL: destination.ServerURI + &amp;quot;object/&amp;quot; + sog.UUID + &amp;quot;/&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Packs scene object as XML2 via sog.ToXml2(), extra state via ExtraToXmlString() and GetStateSnapshot(). Sends uncompressed POST. Returns false if result is null or success is false.&lt;br /&gt;
&lt;br /&gt;
==== CreateObject(destination, userID, itemID) ====&lt;br /&gt;
&lt;br /&gt;
Not implemented. Always returns false with a TODO comment.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
=== Notes ===&lt;br /&gt;
&lt;br /&gt;
* This connector talks to region simulators, not ROBUST. The destination URI comes from GridRegion.ServerURI per call.&lt;br /&gt;
* The compressed/uncompressed fallback in CreateAgent() exists for backward compatibility with older simulators. A warning is logged when the fallback is needed.&lt;br /&gt;
* UpdateAgent position deduplication means only the most recent position is ever sent -- intermediate positions are silently dropped. This is intentional.&lt;br /&gt;
* The 200-second timeout on full AgentData UpdateAgent is notably long -- comment &amp;quot;yes, 200 seconds&amp;quot; is in the source.&lt;br /&gt;
* ReleaseAgent and CloseAgent always return true -- callers cannot detect failure from return value.&lt;br /&gt;
* CreateObject by userID+itemID is explicitly unimplemented with a &amp;quot;TODO, not that urgent&amp;quot; comment.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[OpenSimulator Internals/Connector Architecture]]&lt;br /&gt;
* [[OpenSimulator Internals/Code Map/ROBUST/GatekeeperService]]&lt;br /&gt;
* [[OpenSimulator Internals/Code Map/Scene]]&lt;/div&gt;</summary>
		<author><name>Jwbshaw</name></author>
	</entry>
</feed>