Capabilities
In order for open metaverse servers to serve custom content without having
to alter the spec, servers have created a system called
Capabilities.
These capabilities are used for a large portion of server-client
communication.
The flow is relatively simple.
1.
Retrieve capability seed URL from login response
2.
Send capability request LLSD-XML to the received URL3.
Parse the response containing the capability URLs from the server4.
Retrieve non-spec data from the capability URL using get requestsEndpoints
Over the years, endpoints have been created and fallen out of use. Currently, most documentation lists several unused endpoints. The endpoints listed here are used by the project and are known to work.| ViewerAsset | Enables the viewer to retrieve assets from the asset server |
| FetchInventoryDescendents2 | Enable the viewer to retrieve the inventory of the current user. |
Initialization
Once a session is established, capabilitities should be enabled.Here, immediately after login, the session initialization code requests capabilities to be enabled based on the enabled features the viewer compiled with.
new_capability_request() generates the LLSD-XML that will be sent to the server to enable the listed endpoints. The resulting XML will look like this for example.
<?xml version="1.0" encoding="UTF-8"?>
<llsd>
<array>
<string>ViewerAsset</string>
<string>FetchLibDescendents2</string>
<string>FetchInventoryDescendents2</string>
</array>
</llsd>
LLSD-XML is a custom xml format used by secondlife and open metaverse applications. Docs for it can be found here.
The CapabilityRequest is then sent to the mailbox to enable.1.
The Seed Capability URL is retrieved from the LoginResponse object and saved in the session.
2.
The requested capabilities are serialized into LLSD-XML for transport
3.
The capability request LLSD-XML is sent to the seed capability URL using a Post, with the body being the LLSD-XML content
4
The requested URLs are returned in the response. These URLs will be used for making requests.
5
The resulting URLs are handled by the mailbox and stored in the global session, to be used later for making requests.
<llsd>
<map>
<key>FetchLibDescendents2</key>
<string>http://172.20.20.20:9000/491d7ad3-ecbf-497c-90e6-abcaba76277c</string>
<key>FetchInventoryDescendents2</key>
<string>http://172.20.20.20:9000/c2afbf94-99da-46d3-b046-8bea0df7a845</string>
<key>ViewerAsset</key>
<string>http://172.20.20.20:9000/8a578194-bd25-43a5-83e5-6b16bf34291d</string>
</map>
</llsd>
Making Requests
Now that we have the capability URLs, we can begin making requests to them.For example, this is the rquest to retrieve a folder from the inventory endpoint.
Post: http://172.20.20.20:9000/371320f6-7694-4e9c-bbb9-19e56f1e1027
Header: "Content-Type", "application/llsd+xml
<?xml version="1.0" encoding="UTF-8"?>
<llsd>
<map>
<key>folders</key>
<array>
<map>
<key>fetch_folders</key>
<boolean>true</boolean>
<key>fetch_items</key>
<boolean>true</boolean>
<key>folder_id</key>
<uuid>5b70e16b-4e8c-e463-f9b5-16e28f1b7213</uuid>
<key>sort_order</key>
<integer>0</integer>
<key>owner_id</key>
<uuid>fb2e5541-66ba-4019-a5de-e8b9286b0914</uuid>
</map>
</array>
</map>
</llsd>
Endpoint Response Deserialization
Not every endpoint will return the same data type, and the same endpoint may even return a different data type depending on what data is being requested from it.For example, the ViewerAsset endpoint can return three different data types, if the requested object is a SceneObject, an Item, or an Mesh. These docs will make an effort to point out which data type an endpoint returns, based on which input it receives.