Name2Key in LSL

From Second Life Wiki
Revision as of 16:14, 19 January 2009 by Sensei Schism (talk | contribs)
Jump to navigation Jump to search

Still missing Name2Key functions in your code ? Still relying on external databases that are not always up to date with latests SL subscribers ?

Well now you can solve this by yourself, within your LSL script ! All you have to do is to rely on LL Search engine !

I put a kind of "library" and a sample of usage for your convenience

Library: <lsl> integer SERVICE_NAME2KEY = 19790; integer SERVICE_NAME2KEY_RET=19791; key ONE_KEY = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF";

integer gCurrentRequest=0; key gReqId=NULL_KEY; string gToSearch="";

ReturnService(integer Status, string message) { key Key;

if (Status) Key=ONE_KEY; else Key=NULL_KEY;

llMessageLinked(LINK_THIS, gCurrentRequest+1, message, Key);

gCurrentRequest=0; gReqId=NULL_KEY; gToSearch=""; }

SvcName2Key(string message) {

   if (gCurrentRequest) {
       ReturnService(FALSE, "BUSY");
   }
   list Args=llParseString2List(message, [" "], []);
   
   string FirstName = llList2String(Args, 0);
   string LastName = llList2String(Args, 1);
   
   gCurrentRequest=SERVICE_NAME2KEY;
   
   string url="http://66.196.80.202/babelfish/translate_url_content?.intl=us&lp=fr_en&trurl=http%3A%2F%2Fsearch.secondlife.com%2Fclient_search.php%3Fs%3DResident%26q%3D"+FirstName+"%2520"+LastName;
   gToSearch="secondlife:///app/agent/";
   
   gReqId=llHTTPRequest(url, [HTTP_METHOD,"GET"], "");

}

default { link_message(integer sender_number, integer number, string message, key id) { if (number==SERVICE_NAME2KEY) { SvcName2Key(message); } }

http_response(key request_id, integer status, list metadata, string body) { if (request_id==gReqId) { integer Pos1=llSubStringIndex(body, gToSearch); integer Pos2=0; string Ret=""; if (Pos1!=-1) { body=llGetSubString(body, Pos1+llStringLength(gToSearch), -1); if (gCurrentRequest==SERVICE_NAME2KEY) { Pos2=llStringLength((string)NULL_KEY); string Dat=llGetSubString(body, 0, Pos2-1); if (llStringLength((string)((key)Dat))==llStringLength(NULL_KEY)) { // Success ! Ret=llGetSubString(body, 0, Pos2-1); ReturnService(TRUE, Ret); } else ReturnService(FALSE, "UNKNOWN"); } else ReturnService(FALSE, "UNKNOWN SERVICE"); } else ReturnService(FALSE, "UNKNOWN"); }

} } </lsl>

Usage sample: <lsl> integer SERVICE_NAME2KEY = 19790; integer SERVICE_NAME2KEY_RET=19791; key ONE_KEY = "FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF";

MyName2Key(string message) { llMessageLinked(LINK_THIS, SERVICE_NAME2KEY, message, NULL_KEY); }

default { touch_start(integer total_number) { llOwnerSay("Searching key for avatar named Secret2 Linden"); MyName2Key("Secret2 Linden"); }

link_message(integer sender_number, integer number, string message, key id) { if (number==SERVICE_NAME2KEY_RET) { if (id==ONE_KEY) llOwnerSay("Found ! Key is: "+message); else llOwnerSay("Error: "+message); } } } </lsl>

Hope this helps ! Maeva Anatine

EDIT : Looks like the Lindens have either broken or blocked this function. It works from my browser, however from LSL I get an error page containing this message "Access control configuration prevents your request from being allowed at this time. Please contact your service provider if you feel this is incorrect." - Darling Brody.

EDIT : Yes you're right Darling. It seems they've blocked this acces from within the world... I still wonder why, especially as there are some workarounds to this... Anyway I discovered there is a JIRA issue for this. Please vote for the unblock ! https://jira.secondlife.com/browse/SVC-3122 - Mae

EDIT : OK after having read this article from LL: http://wiki.secondlife.com/wiki/SearchAPI, it seems proxy usage is allowed. So I modified the upper code in order to go through a proxy machine and it works again :) - Mae

EDIT: After reviewing this (and it not working for me for some reason) I rewrote this to allow different proxies by a simple configuration. This now uses Google instead of bablefish. It now can handle multiple requests at once. Replies have changed slightly, as the found key is returned in the "key" field instead of the message field. In addition, failure of any kind results in a NULL_KEY being returned, and status information is returned in the message field.

<lsl> integer SERVICE_NAME2KEY = 19790; integer SERVICE_NAME2KEY_RET = 19791;

string proxy = "http://www.google.com/gwt/n?_gwt_noimg=1&u="; string search = "http://search.secondlife.com/client_search.php?s=People&q="; string result = "http%3A%2F%2Fworld.secondlife.com%2Fresident%2F"; string notfound = "There were no matches for ";

list requests;

default {

   on_rez(integer i) { llResetScript(); }
   state_entry()
   {
       requests = [];
   }
       
   link_message(integer s, integer n, string m, key i)
   {
       if (n == SERVICE_NAME2KEY) {
           if(llListFindList(requests,[m]) == -1) {
               string url = proxy+llEscapeURL(search+m);
               key id = llHTTPRequest(url, [], "");
               requests += [(string)id,m];
           }
       }
   }

   http_response(key request_id, integer status, list metadata, string body)
   {
       integer p = llListFindList(requests,[(string)request_id]);
       if (p != -1) {
           string n = llList2String(requests,p+1);
           integer f = llSubStringIndex(body,result);
           if(f == -1) {
               f = llSubStringIndex(body,notfound);
               if(f == -1)
                   llMessageLinked(LINK_SET,SERVICE_NAME2KEY_RET,"Error with lookup!",NULL_KEY);
               else
                   llMessageLinked(LINK_SET,SERVICE_NAME2KEY_RET,n+" not found.",NULL_KEY);
           } else {
               f += llStringLength(result);
               string a = llGetSubString(body,f,f+35);
           
               llMessageLinked(LINK_SET,SERVICE_NAME2KEY_RET,n,(key)a);
           }
           requests = llDeleteSubList(requests,p,p+1);
       }
   }    

} </lsl>

Example use (listens on channel /1 and looks up anything send in that channel): <lsl> integer SERVICE_NAME2KEY = 19790; integer SERVICE_NAME2KEY_RET = 19791;

default {

   on_rez(integer i) { llResetScript(); }
   
   state_entry()
   {
       llListen(1, "", "", "");
   }
   listen(integer c, string n, key i, string m)
   {
       llSay(0,"Requesting key for "+m);
       llMessageLinked(LINK_THIS, SERVICE_NAME2KEY, m, "");
   }
   link_message(integer f, integer n, string s, key i)
   {
       if(n == SERVICE_NAME2KEY_RET) {
           if(i == NULL_KEY)
               llSay(0,"Lookup failed.  Returned: "+s);
           else
               llSay(0,s+": "+(string)i);
       }
   }

} </lsl>