User:Pixel Gausman/Interop Viewer
Open Grid Protocol implementation in Snowglobe
This page is only for describing the OGP implementation of the viewer, not general OGP protocol description.
Open Grid Protocol (OGP) currently includes a style of login and teleport that separates control of the agent into a separate domain named agent domain (also called agentd or agent service). This separate service handles moving an avatar from region to region, including between regions that are run by different entities. This is helpful to end users because they can maintain a consistent appearance and inventory as they move from region to region. They can also trust the agent service to maintain their inventory without having to "hand over the keys" to their inventory to every region they visit.
It is a protocol under development, and that's why we need it in Snowglobe. I've developed a patch for Snowglobe to
enable OGP. Protocols are best standardized with the experience of implementation, and I believe
OGP needs a publicly available implementation to experiment with. An open implementation
will help ground the design of protocols in the reality of working code that the community can work with.
Note: In the near future, IBM will open source an OGP implementation for the community to experiment with.
OGP protocols are not supported on the main Linden grid or the Linden test grid, which for now is a good thing. The protocol needs further development before Linden or anyone else should use it on a production level grid. OGP is new and distinct protocol from the current SL UDP and HTTP protocols, so it is the choice of the deployer to expose these interfaces or not. The specific HTTP caps for keeping inventory at the agent domain, manipulating the agent domain inventory, and resolving remote assets do not exist on the Linden Lab main grid or test grid, so no assets/inventory will cross the boundary between Second Life and OpenSim by using this viewer unless Linden enables it in their deployment.OpenSim grids that choose to expose the interfaces can experiment with distributed assets and with an inventory that is maintained by the agent domain.
Note: If appropriate, I intend to replace OGP references in the code and this wiki page to match the IETF working group name.
General information about OGP is at https://wiki.secondlife.com/wiki/User:Infinity_Linden/IETF_Drafts_and_Meetings until the IETF working group is officially formed. General information about IBM's open source OGP implementation is at TBD.
OGP History
The original OGP specs ware developed by Linden Lab with input from the Architecture Working Group (AWG). OGP's initial proof of concept implementation was a joint project between Linden Lab and IBM. IBM did a portion of that OGP viewer code with some help from Linden developers. The viewer code for that initial Proof of Concept is currently located in the OGP9 public svn branch. I ported the OGP9 branch to Snowglobe, gave the code some cleanup, and added some of the additional inventory caps we have been experimenting with. The additional caps are not supported in Linden's agent domain implementation, so no assets/inventory will cross the boundary between Second Life and OpenSim by using this viewer unless Linden adds additional interfaces to their agent domain.
When looking at the patch, gentle readers, please remember that it was originally proof of concept level code, and that the OGP drafts are a moving target.
Implementation
OGP viewer code affects small portions of the UI, adds some command line parameters, modifies the login and teleport sequences, and implements some additional agent domain caps involving inventory and assets.
UI
If --ogp is passed on the command line, the panel_login layout is modified. Last/Home/Region has no meaning in OGP, so that space in the panel is instead used for the regionuri_edit combo box. The user enters the region uri in this combo box. "Start Location:" is used in both instances, because from an end user point of view, a region uri is a starting location. The combo box is populated using URIs that are saved in a LLURLHistory named "region_uri", but only if the user's First/Last name is saved. This is because if I don't have a First/Last when building the login panel, it's impossible to pull/save *user* specific data (like the specific LLURLHistory for the user Pixel Gausman). The selected entry for the combo box is set to the command line parameter --regionuri ( gSavedSettings.getString("CmdLineRegionURI")), which is an additional way to specify the desired initial region.
Also enabled/disabled by the --ogp command line switch is the "Teleport Region..." selection in the new "Interop" submenu under the "Advanced" menu. This menu selection pops a floater that allows teleport via OGP, it also uses the LLURLHistory to store region uris. The floater can also be popped via Ctrl-Alt-Shift-R.
Command line parameters
- --ogp
- enables OGP mode. Viewer is either OGP or non OGP for the life of the session
- --regionuri <uri>
- allows you to pass in the name of the region you wish to login to.
- --agenturi <uri>
- allows you to specify the name of the agent domain you wish to use. This is passed to the authenticate call. If you do not specify one, it is still possible to request and get a seed cap on an agent domain from authenticate.
- --loginuri <uri>
- While not a new flag, it is needed when authenticating against any agent domain. Use it to point to whatever authentication authority your agent domain accepts.
- --set PurgeCacheOnNextStartup TRUE
- Also not a new flag, but simplified testing in the OGP viewer. Not needed in XLM-RPC Legacy mode. On the TODO list is to test with the viewer's caching in OGP mode.
Example:
If you are part of the OGP beta from Summer 08 (yay Gridnauts!), this would be the command line parameter to authenticate against vaak, where <regionuri> comes from http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions :
--ogp --set PurgeCacheOnNextStartup TRUE --regionuri <regionuri> --loginuri https://login1.aditi.lindenlab.com/cgi-bin/auth.cgi
Login sequence
The login sequence for Snowglobe is messier than what exists in OGP9 SVN. This is because OGP9 did not support XML-RPC style logins, and the removal of the XML-RPC path in OGP9 made the code simpler. We will need to maintain the XML-RPC path in Snowglobe, so the patch attempts to do that with minimal disturbance (and therefore risk) to the XML-RPC code path.
The login sequence is kicked off in idle_startup() in llstartup.cpp. The code loops continuously in idle_startup() as
it moves through the different stages of the login sequence. OGP and XML-RPC diverge states for AUTHENTICATE and XMLRPC_LEGACY,
and then share the code for STATE_LOGIN_PROCESS_RESPONSE. STATE_LOGIN_PROCESS_RESPONSE is exceptionally long, there are now separate
XLMRPC and OGP blocks in that state that cope with all the responses gathered through the stages of the login process.
Note that the login for OGP daisy chains together several HTTP POSTs, kicking off the next one in the responder of the previous one.
Some of the HTTP POSTs must be successful (for instance, rez_avatar/place must succeed to move to STATE_LOGIN_PROCESS_RESPONSE), but some need to be optional, and still proceed with
the login process if they fail (for instance, fetching agent/inventory needs to be optional)
After the overly complex STATE_LOGIN_PROCESS_RESPONSE section of the code, OGP and XMLRPC processing are essentially the same in STATE_WORLD_INIT and onward. The viewer still does its handshake with the region, and goes through its AgentMovementComplete processing. In our initial POC coding last year, we had experimented with getting rid of AgentMovementComplete messages, but were unsuccessful.
The login sequence is intended to work for agent domains that do not expose inventory and asset HTTP caps (like the one on vaak). It has been tested with vaak for login and teleport, despite vaak being slightly temperamental. Members of the Gridnauts group on Aditi should be able to test with vaak, but be warned that vaak has intermittent issues with login.
On logout, instead of sending a UDP message to the region, in OGP a rez_avatar/place request is sent with a null URI. The null URI signals to the agent domain that it should derez the agent from its current region.
One difference between this viewer and the OGP9 SVN branch is that this viewer does not include LLSD "legacy" login, only XMLRPC legacy and OGP.
Teleport sequence
The user invokes OGP teleport via Ctrl-Alt-Shift-R or 'Teleport Region...' in the World menu. This pops up an instance of LLFoaterTeleport, which has a combo box of the same region_uri LLURLHistory. LLFloaterTeleport's function in life is to make a rez_avatar/place request on the agent domain using the URI from the floater. The reponse is caught by LLPlaceAvatarTeleportResponder, and relevant values are plucked from its contents. Note that some of the values in the response to rez_avatar/place are *only* passed on login, and not passed in teleport.
After the response to rez_avatar/place is received from the agentd, the code for Teleport is very similar to XML-RPC Teleport.
Assets and Inventory
Inventory can now be managed by the agent domain, and fetched via HTTP using agent/inventory cap. Temporarily Inventory manipulation (CreateInventoryItem, etc.) still goes through UDP. The UDP calls in OpenSim are reflected to the agent domain via an HTTP interface for handling. This was done as a temporary measure until proper HTTP Inventory manipulation calls could be designed properly and done from the viewer.
Fetching of the inventory is done via the existing WebFetchInventoryDescendents HTTP cap code in the viewer, with the cap renamed to be agent/inventory for the agentd case. For the time being, the format of agent/inventory is the same as WebFetchInventoryDescendents. In cases where there is both an agent/inventory cap on the agent domain and a WebFetchInventoryDescendents cap on the region, the cap on the agent domain is used.
There is a new cap in agentd called agent/inventory-skeleton. Its responder, LLInventorySkeletonResponder, grabs the skeleton, and also makes a new (dangerous?) assumption. It assumes that content["Skeleton"][0]["folder_id"] is the inventory-root UUID. It makes sense, but it is a change compared to how things worked in legacy mode. In legacy XML-RPC authentication, the inventory-root UUID is passed back from authenticate, separate from the skeleton. Just like agent/inventory, the values passed back for agent/inventory-skeleton mimic the values received in an XML-RPC login.
The interfaces of agent/inventory and agent/inventory-skeleton will change as the design of agent domain moves forward.
Also, assets will eventually be distributed, meaning that a region on a grid might contain an asset that is not stored
on that grid. An agent's inventory might be made up of items scattered across the web.
This means some interesting protocol changes, while keeping an eye on performance.
Shortcomings, future needs, and dirty laundry
- Refactor Teleport
- The teleport code needs to be refactored into a new class when OGP support is added for:
- LLAgent::teleportViaLure - This function is invoked when one agent offers one or more other agents to teleport to her location. LLAgent::teleportViaLure() is called when the current agent has accepted a lure and desires to TP to a friend. Currently all the protocol gives me is a lure_id. I'd really like to get a region_uri, so a protocol change would be needed.
- LLAgent::teleportViaLandmark - Similar to teleportViaLure issue. I have a landmark_asset_id, and need a URI.
- LLAgent::teleportViaLocation - This is invoked from about a dozen different places in the viewer (for instance, when the user clicks on the map). A global position is passed in, which is then used to compute the regionhandle. With the regionhandle, the legacy teleportRequest() is called. The assumptions around the use of regionhandle need to be reworked in the viewer (and in the OGP protocol).
- regionhandles
- The viewer assumes that all regions it can get to are arranged in one contiguous XY grid. It's not its fault, when the viewer was written, there was only one grid. A region's regionhandle denotes its XY location in the one known grid, i.e. where it shows up on the map. When teleporting between two distinct grids, it is very possible that two regions report the same regionhandle. This makes the viewer very unhappy. The viewer uses the regionhandle to check that an XY location is a valid region that the viewer has a connection to, and to do location based things like determine neighboring regions. It's even checked when determining if you are flying. In the OGP beta, we worked around this issue by having all the OGP region owners register their regionhandles on a website. That allowed us to avoid the issue. Longer term, the issue needs to be resolved differently.
- STATE_LOGIN_PROCESS_RESPONSE
- This section of idle_startup() is rather brittle, and will be easy to break. Consider rewriting it, or separating XML-RPC and OGP into two different states instead of both of them using STATE_LOGIN_PROCESS_RESPONSE. I think the original OGP9 code used STATE_LOGIN_PROCESS_RESPONSE as a common state between legacy and OGP because OGP9 only dealt with LLSD login (and had chopped all the XML-RPC code.)
- makeNewOutfit() crashes when in OGP mode.
- In the original Proof of Concept, we chose to disable the UI button for Make New Outfit. It has been re-enabled, and needs to be fixed for both agent domains that support inventory, and ones that do not.
- PurgeCacheOnNextStartup flag
- This flag is only needed in OGP mode, we need to test the viewer without this flag and make sure viewer's internal caching mechanisms work with OGP. Careful definition of the testing scenarios need to be done, and it also needs to work with agent domains that do not support Inventory.
- LLPlaceAvatarTeleportResponder
- Rework how values are caught from the rez_avatar/place responder, and put into mResult. Currently I think we might wipe out some mResult values on teleport.
Snowglobe 1.3 thoughts. Consider implementing...
- refactor caps code for 'simple' caps - caps are sprinkled all over, and coded in different ways. it might be nice to have a common framework for them. would be used for caps that get invoked more than once, that we need to keep track of. Note: propose to leave http image fetch alone.
- enhance event queue code - OGP requires a more complex handling of events on the event queue
- Agent domain Library(ies?) - Allowing existing fetchlib caps code in the viewer to be used for a Library
- regionhandle rework - see above in dirty laundry section. this might also fix SVC-2941 .
- inventory UDP->caps
- remove secondlife.com and lindenlab.com assumptions in the viewer
- implement Mana Janus' gridinfo type functionality for managing URIs on different grids
- implement a SNOW-129 type feature to allow multiple user names/password to be stored
- pluggable authentication model - allow things like OpenID and LDAP to be used
Test Plan
Objectives
Exercise agent related capability in the areas of login, teleport in the viewer for both OGP and non-OGP logins, with a focus on non-OGP mode testing.
Procedures for non-OGP testing
Login
- Validate login failure in non-OGP mode
- Launch the viewer with no additional command line parameters
- Enter bogus First/Last/password, and in the Start Location, type 'Ahern'
- After attempted login, verify that the viewer displays one error dialog (and one only...) and comes back to the same login screen
- Validate login panel UI and Agni login
- Launch the viewer with no additional command line parameters
- Validate that the combobox next to Start Location has : home, last, and region as the choices, and it can be toggled on/off in Preferences floater on General tab
- Enter First/Last/password, and in the Start Location, type 'Ahern'
- Login to Agni
- Ensure that My Inventory in your Inventory folder is populated.
- Search for an item in your inventory (thus kicking off large inventory fetch)
- Move an Inventory item from Landmarks to Clothes
- Login to Aditi using Grids combobox
- Launch viewer to login panel. Ctrl-Shift-G toggle Grid Box if not already displayed.
- Select Aditi and click login
- Validate that agent rezzes with expected appearance and wearables, and Inventory Folder has contents you'd expect
- Validate that the AVs friends list is correct by clicking Contacts in the Communicate window
- After logout, validate that with default logcontrol.xml, there isn't extra OGP related messages going into the SecondLife.log
- Login to OpenSim using --loginuri. (Note: you can register for an osgrid AV at http://www.osgrid.org/ login instructions at http://www.osgrid.org/docs/instructions.htm)
- Create a Windoze shortcut with the additional command line options, or otherwise launch the viewer with the command line: -loginuri http://osgrid.org:8002 -loginpage http://osgrid.org/loginscreen.php -helperuri http://osgrid.org/
- Login to Agni by launching the viewer with a SLURL in firefox : http://slurl.com/secondlife/Ahern/128/10/50
- Validate that the landmark you moved into Clothes folder in Test 1 above is still in Clothes folder
With a new AV on OSgrid, you might (as of Sept 2) need to create Skin and create Hair and wear it to get your texture bakes to happen properly. To create Skin/Hair, open Inventory, then Create->BodyParts->Hair in the Inventory floater menu, then right click on the created hair item, and select Wear. Do the same for Skin.
Teleport
For each type of test, validate these things after the completion of a Teleport:
- The progress bar during teleport slowly fills up as a teleport progresses
- Your AV arrives and can navigate in the region ( try to walk in a circle)
- The objects in the surrounding region look appropriate (you shouldn't see a mixture of objects from the source and destination regions jumbled together),
- Your AV rezzes properly. Avatar appearance should be validated from both your viewer session, and with a second viewer session that has your AV in its camera view. This is because the viewer's caching can play tricks on you. So validate wearables, texture bakes, and attachments by observing your AV from a second viewer
- After TP is complete, a message in Local chat appears: "Teleport completed from http://slurl.com/secondlife/Morris/11/195/59" (change Morris to whatever your source region for the TP was)
- Teleport via Landmark
- Open Landmarks folder in My Inventory, double click on a landmark to open it, and click teleport.
- Teleport via Location
- Open the Map, double click in the region next to you, this should invoke a TP
- Open the Map, double click a region that is 3 regions away
- Teleport Via Lure
- Login as AV1 in Ahern on Agni
- Login as AV2 in IBM
- AV2 double clicks on AV1 in her friends list to bring up AV1's profile
- AV2 clicks "offer teleport" to AV1
- AV1 accepts the TP offer
- AV1 is teleported to IBM
- Teleport Home
- Ctrl-Alt-Shift-H should TP you to wherever your Home location is set
- Validate that Ctrl-Alt-Shift-L does *not* bring up the OGP Teleport floater, and that "Teleport Region..." in the World menu is disabled
Region Crossing
- Validate agent crossing between two touching regions
- Go to the edge of Ahern, http://slurl.com/secondlife/Ahern/10/10/50 and walk between the adjoining regions.
- Watch the Region name and XYZ location in the menu bar to validate that you crossed the region successfully.
- Make sure you can walk around the region, and make sure you don't lose Voice connection.
- Validate that your Inventory looks correct in the Clothing folder of My Inventory
Browser history
- OGP makes use of the LLURLHistory class, so test out that url history is properly saved for non-OGP usage
- Press PF1 to bring up in world browser
- enter www.ibm.com in the address bar and hit enter
- enter www.opensimulator.org in the address bar and hit enter
- Log out and back in, and Press PF1 again.
- Validate that ibm.com and opensimulator.org are in the history by using the arrow button in the combo box
Procedures for OGP testing
Login
If you are in gridnauts group, and vaak is in a good mood, these command line parameters should get you to vaak regions:
--ogp --set PurgeCacheOnNextStartup TRUE --regionuri <regionuri> --loginuri https://login1.aditi.lindenlab.com/cgi-bin/auth.cgi
where regionuri is one of the vaak regions at http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions
On the login panel, validate that --ogp *slightly* enlarges the combo box at the right of Start Location (vs the size of that box when running in non-OGP mode), and that the regionuri is in the box.
- Click Login
- With vaak you might need to try several times, or try different regions in the list, or request restart of the regions and the agentd.
- This should log you in, but you will not have an appearance or inventory maintained.
Teleport
- Only one OGP teleport mechanism is provided in the viewer, it is accessed via Ctrl-Alt-Shift-R or "Teleport Region..." in the World menu
- Authenticate with vaak following Login instructions
- Place one of the region seeds from http://wiki.secondlife.com/wiki/Open_Grid_Public_Beta/Public_Regions#Linden_Lab_OGP_Regions
- Click Teleport.
Note: The progress bar gives a less pleasing "fill up" in OGP mode, this is expected.
On vaak, verify that the Inventory floater has no items in My Inventory
Avatar Rezzing
The OGP testing assumes vaak use. Additional tests for Avatar appearance and Inventory will be added at a later date.
If it is a new Avatar on an agent domain that supports inventory, then you will be a gassy cloud until you create and wear Skin and Hair. To create Skin/Hair, open Inventory, then Create->BodyParts->Hair in the Inventory floater menu, then right click on the created hair item, and select Wear. Do the same for Skin.
On vaak, currently you have no inventory, so you will probably be gassy ruthie.
Future testing
- Region Crossing with OGP - currently not supported (or at least not in all agent domains)
- OGP and non-OGP regions intermingled on the same grid - try a mix of teleporting (Lure, Landmark, location) and region crossings between OGP and non-OGP regions.
- On an agent domain and OpenSim region that supports Inventory managed at the agent domain, Test these Scenarios:
- Validate that several levels of hierarchy in My Inventory can be created
- Validate Create/Wear body part and clothing item
- Validate uploading a texture and applying it to a prim that you rez in multiple regions
- Validate modifying a clothing item color and texture.
- Validate that icons and C-M-T for items in My Inventory survive relogin
- Validate PurgeCacheOnRestart FALSE works
- Validate that meaningful error messages are displayed in all rez_avatar/place failure cases. agentd is also guilty here
- Test Voice on Vaak - didnt this used to work???
Disclaimer
Anything resembling an opinion is my own, and not that of my employer, IBM. This is experimental code, meant to give the community a relevant viewer to use in interoperability work.