User:Kerik Rau/n2k.AppSpot
This service is designed to provide effortless name to key and the inverse conversions. It does so by utilizing web services that are readily available and acts as a proxy that strips things down to where they are easily usable within LSL (or any other application). It is hosted on Google's AppEngine, which means that it should easily scale with most demands placed on it.
The base url is http://n2k.AppSpot.com
Name 2 Key
example: http://n2k.AppSpot.com/n2k/Kerik%20Rau
The response will either be the key or an empty string.
Key 2 Name
example: http://n2k.appspot.com/k2n/cc62e3dd-a3e0-4556-9585-bfcbc7997f77
Note: Some keys will not resolve. This is due to world.secondlife.com/resident/ not returning the profile. See http://jira.secondlife.com/browse/WEB-952 for the status of this issue.
Data Validity
- You should always check to see if the response returned 200. App Engine will send out a temporarily unavailable at times until the application wakes up.
- For Name2Key you can validate their length. All avatars have a key length of 36.
- Key2Name will not always resolve, until LL modifies things upstream this will not change.
Example Script
<lsl> // // Example Query Script, tells the avatar that clicks it their // key and name based on reverse lookups. // // The service caches lookups in memcached, which means if you // click it a second time it should be a lot faster. // // Sometimes App Engine just craps out, so you should always // check for a status code of 200. If you are concerned with // data integrety you should verify the key length. // // // The Key2Name portion of the service is not fully functional, // currently LL plans on adding in web profiles for all avatars. // // see http://jira.secondlife.com/browse/WEB-952 //
// - Kerik
string gLookupUrl = "http://n2k.appspot.com";
key gKeyRequestID; key gNameRequestID;
integer gLocked = 0;
default {
touch_start(integer total_number) { if(gLocked == FALSE) { key avatar = llDetectedKey(0); gNameRequestID = llHTTPRequest( gLookupUrl + "/k2n/" + (string) avatar, [], "" ); gKeyRequestID = llHTTPRequest( gLookupUrl + "/n2k/" + llEscapeURL(llKey2Name(avatar)), [], "" ); llSetTimerEvent(15); gLocked == TRUE; } else llWhisper(0, "Please wait for my request to finish"); } http_response( key request_id, integer status, list metadata, string body ) { //it is best to check if the response was correct (ie status == 200), sometimes app engine //gets a little fidgety (particuarly when it hasn't been requested in awhile) if(status == 200) { if(request_id == gKeyRequestID) { integer length = llStringLength(body); if(length == 36) // a proper key is 36 characters long llWhisper(0, "Your key is \"" + body + "\""); //ideally the service will return an empty string if no key is found else if(length == 0) llWhisper(0, "No key was returned, this shouldn't happen!"); else llWhisper(0, "An invalid response was returned, this shouldn't happen!"); gKeyRequestID = NULL_KEY; } else if(request_id == gNameRequestID) { if(body == "") llWhisper(0, "No name was returned, this happens sometimes, particuarly on older avatars."); else llWhisper(0, "Your name is \"" + body + "\""); gNameRequestID = NULL_KEY; } } else llWhisper(0, "The request was invalid!"); //Release the lock when both requests are finished if(gNameRequestID == NULL_KEY && gKeyRequestID == NULL_KEY) { gLocked = FALSE; llSetTimerEvent(0); } } timer() { llWhisper(0, "The request timed out"); gLocked = FALSE; }
} </lsl>