Difference between revisions of "User:Opensource Obscure/FFHUD"

From Second Life Wiki
Jump to navigation Jump to search
m (templatizationingsx)
 
(28 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{LSL Header}}
{{User:Opensource_Obscure/Backlink}}


== FFHUD: a simple FriendFeed HUD ==
{{Help/Box|FFHUD|'''A SIMPLE FRIENDFEED HUD'''}}
'''v 0.6.1 by [[User:Opensource_Obscure|Opensource Obscure]] '''<br>


'''FFHUD updates your FriendFeed page.''' It usually publishes a post structured like this:
* An idea by '''[[User:Opensource_Obscure|Opensource Obscure]]'''
* Current release: '''0.7.3'''  
* Features:
** single, non-obtrusive button
** quick automatic or custom messages
** Friendfeed Rooms support
** Parcel Owner Profile Image support
<br/>


* LINK = SLURL of your location
== What does it do ==
* TITLE = region name + parcel name
 
* COMMENT = parcel description + your message (optional)
'''FFHUD lets you publish to the [http://friendfeed.com/ FriendFeed] microblogging service from inside Second Life.'''
* IMAGE = profile image of resident or group that owns the parcel (if available)
 
You send your posts by writing them in a private chat channel. Posts always include a SLURL link to your actual location. You can send a quick update that automatically includes the parcel description, or write a custom message. If available, the owner or owner-group profile image is also published, accordingly to their privacy settings.
 
FFHUD is an ideal way to participate on web social networks while you're enjoying Second Life. You can publish a quick review of an interesting place you just found in-world, or share with your friends your random thoughts from your home.
 
=== Automated Web Diary of your SL parcel ===
 
You could also use FFHUD to automatically report on a web page what's happening in Second Life. Use it together with sensors and scripted objects so that a new post is published to a dedicated Friendfeed group/room when actions occur, then [http://friendfeed.com/embed embed] that Friendfeed stream in your website.
 
* ''Example''. I'm currently using FFHUD to automatically transmit information from [http://slurl.com/secondlife/LOL my Second Life island, LOL], to http://friendfeed.com/lolsl - Many LSL sensors using FFHUD are placed near various places inside the region. They get triggered when visitors walk over them, or they start using devices and installations made by LOL builders.
 
== Setup==
 
* Put the script (see below) in a prim (you may also want to rename it).
* Edit the script and insert your FriendFeed account data. You may also specify a room.
* Wear the prim as an HUD. Resize and replace as needed.


== How it works ==
== How to use FFHUD ==


* edit script 1 and put your FriendFeed account data
Touch it once to '''get information about the parcel''' you're in (printed in private chat via llOwnerSay). Then:
* put script 1 in a prim (you may call the prim FFHUD)
* put script 2 in another prim (call it PARCEL INFO)
* link the prims
* wear the object as an HUD like this:
________ ______________
|      |            |
| FFHUD | PARCEL INFO |
|_______|_____________|


* touch FFHUD to get info about the parcel you're in and agents around (printed in chat via llOwnerSay)
* if you're not publishing a post, just wait until FFHUD resets itself before touching it again;
* touch PARCEL INFO to publish a post on FriendFeed that includes available info about the parcel (SLURL, name, description, owner/owner group profile image if available)
* touch it again within 20 seconds to '''publish a post''' on FriendFeed that includes '''available info about the parcel''': SLURL, description, owner profile image;
* say a message on channel 8 to publish a post on FriendFeed with parcel info + your message:
* or say a message on channel 8 within 20 seconds to '''publish a post''' that includes both parcel info and your message. Example:
  /8 This is my message
  /8 This is my message


FFHUD has the Friendfeed favicon as fixed texture. PARCEL INFO texture changes (after touch) when a profile image is available for the parcel owners. Profile images are shown on the PARCEL INFO prim by using llSetTexture; the UUID is retrieved using the Second Life Search. The image web address (not the image itself) is sent to FriendFeed, that then retrieves and hosts a copy of the image.
Do you need help? Feel free to contact me (Opensource Obscure) in-world, through this wiki or [http://friendfeed.com/oobscure on FriendFeed].


== Notes ==
== Notes ==


''This code is probably horrible and flawed.''
'''FFHUD builds your posts this way:'''
* LINK = SLURL of your location
* TITLE = parcel name
* COMMENT = parcel description (if available) OR your message
* IMAGE = profile image of resident or group that owns the parcel
* ROOM = according to your settings
 
FFHUD shows the FriendFeed logo by default. After you touch it once, it will display the parcel owner profile image, if available. It's the same picture that will be published in your post. Profile images are shown by using [[llSetTexture]]; the UUID is retrieved using the Second Life Search; the image web address (not the image itself) is sent to FriendFeed, that then retrieves and hosts a copy of the image.


''Use of this script may be a violation of [[Project:Terms_of_Service|ToS]] - help to clearify this [[User_talk:Opensource_Obscure/FFHUD|is welcome]]'' :)
'''If you're on FriendFeed, join the Second Life room!''' <br>
'''http://friendfeed.com/rooms/secondlife'''


I am not a real developer. I cut, paste and tweak code from other sources. I think I used snippets by: Ordinal Malaprop, Cory Ondrejka, MarcoDuff Palen, Jana Kamachi and others.
Feel free to use this room for testing: <br>
http://friendfeed.com/rooms/ffhud


== script 1/2: FFHUD ==
== Script ==


This script:
This code works but may be horrible and flawed. Feel free to [[User_talk:Opensource_Obscure/FFHUD|suggest me how to improve it]]. I am not a real developer and I lack some programming basis, so any feedback can help me. I usually make the LSL scripts I need by reading around, cutting, pasting and tweaking code from other sources. To write FFHUD I used snippets by [[User:Ordinal Malaprop]], [[User:Cory Linden]], [http://www.marcoduff.com/ MarcoDuff Palen], [[User:Jana Kamachi]] and others. Thanks to Tayra Dagostino. [[User:Strife Onizuka]] [https://wiki.secondlife.com/w/index.php?title=User%3AOpensource_Obscure%2FFFHUD&diff=78978&oldid=78929 improved] this script, however its changes are missing from the current version and will be merged back as soon as possible.
* accepts touch event
* listens on channel 8 for your message
* sends a linkedmessage to script 2 (upon touch event or message on channel 8)
* receives texture uuid from script 2 via linkedmessage
* sends http request to friendfeed (after the linkedmessage from script 2)


<lsl>
To do:
* multiple rooms support
* add switch to turn off/on image support
* enriched SLURL as in [http://ordinalmalaprop.com/twitter/ Ordinal Malaprop's TwitterBox]
* parcel pics support (needs https://jira.secondlife.com/browse/SVC-1638 fix)
* ...better code = a real developer should rewrite it from scratch :D


// your FriendFeed username are here: https://friendfeed.com/account/api
<lsl>// FFHUD 0.7.3
string user=""; // your FriendFeed username
// free for public use
string ffkey=""; // your FriendFeed key
// A project started by Opensource Obscure
   
//
 
// Look for your username and FriendFeed key here: https://friendfeed.com/account/api
string user=""; // your FriendFeed username  
string ffkey=""; // your FriendFeed key  
 
// You can send messages to a FriendFeed room:
//  "" -----------> default setting - you won't share messages to any room
// "ffhud" ------> a test room you can freely use
//  "secondlife" -> an unofficial SL room - http://friendfeed.com/rooms/secondlife
// Change accordingly the line below:
string room="ffhud";
 
 
// after 1st click you have a few seconds to write and send
// your text message before FFHUD comes back to default state.
// you can change the timing below:
float listentime = 20.0;
 
 
 
///////////////////////////////////////////////////
// you don't need to modify anything below
 
 
string desc;
integer listen_handle;
string baseurl="@friendfeed.com/api/share";
string baseurl="@friendfeed.com/api/share";
string text;
key request_ff;
string url;
key request_texture;
string message;
string ownerurl =  "http://world.secondlife.com/resident/";
string desc;
string groupurl =  "http://world.secondlife.com/group/";
key texturedefault = "632f82da-7be7-9c7a-f254-3fc41a36ae12";
string code1 = "<img alt=\"profile image\" src=\"http://secondlife.com/app/image/";
string code2 = "\" class=\"parcelimg\" />";
azzera()
key textureuuid = "";
{
key texturedefault = "4760a44f-06f7-622e-7429-b01570a598b0";
    llSetTexture(texturedefault, ALL_SIDES);     
 
    text="";
 
    url="";
// let's substitute '&' character with 'and'
    message="";
    desc = "";
}
string strReplace(string source, string pattern, string replace) {
string strReplace(string source, string pattern, string replace) {
     while (llSubStringIndex(source, pattern) > -1) {
     while (llSubStringIndex(source, pattern) > -1) {
Line 80: Line 124:
     return source;
     return source;
}
}
string regionname()
{
    string region=llDumpList2String(llParseString2List(llGetRegionName(),[" "],[]),"+"); 
    return region;
}
string parcelname()
{
    list lstParcelName=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_NAME]);               
    string a = (string)lstParcelName;
    string name = llDumpList2String(llParseString2List(a,[" "],[]),"+");
    name = strReplace(name,"&","and");
    return name;
}
string parceldesc()
{
    list lstParcelDesc=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_DESC]);               
    string a = (string)lstParcelDesc;
    if(a != "00000000-0000-0000-0000-000000000000")
    {
        desc = llDumpList2String(llParseString2List(a,[" "],[]),"+");       
    }
    else
    {
        desc = "";
    }
    desc = strReplace(desc,"&","and");
    return desc; 
}
string slurl()
{
    string simname = llDumpList2String(llParseString2List(llGetRegionName(),[" "],[]),"+");
    string regionname = simname;
    vector detectedPos = llGetRootPosition();       
    string sx = (string)llRound(detectedPos.x);
    string sy = (string)llRound(detectedPos.y);
    string sz = (string)llRound(detectedPos.z);
    string url = "http://slurl.com/secondlife/"; 
    url += simname;
    url += "/" + sx + "/" + sy + "/" + sz ;
    return url; 
}
default
{
    state_entry()
    { 
        azzera();
        llListen(8, "", llGetOwner(), "");         
    }
    touch_start(integer total_number)
    {
        azzera();
        llMessageLinked(2, 1, "", NULL_KEY);       
    }
    listen(integer channel, string name, key id, string message)
    {
        azzera();
        llMessageLinked(2, 1, "", NULL_KEY);
        text = "+-+MY MESSAGE:+" + message;
        text = strReplace(text,"&","and");
    }
    link_message(integer sender_num, integer num, string str, key id)   
    {
        string imageurl = "http://secondlife.com/app/image/" + (string)id + "/2";       
        text = llDumpList2String(llParseString2List(text,[" "],[]),"+");
        string post =
        "http://" +
        user +
        ":" +
        ffkey +
        baseurl +
        "?title=" +
        regionname() +
        "+-+" +
        parcelname() +
        "&link=" +
        llEscapeURL(slurl()) +
        "&comment=" +
        "PARCEL+INFO:+" +
        parceldesc() +   
        text +
        "&image0_url=" +
        llEscapeURL(imageurl);
        llHTTPRequest(post, [HTTP_METHOD,"POST"], "");       
    }
    http_response(key request_id, integer status, list metadata, string body)
    {
        {
          llOwnerSay("Message sent to http://friendfeed.com/" + user);
        }
    }   


}


 
// partially redundant (1)
</lsl>
 
 
== script 2/2: PARCEL INFO ==
 
This script:
* accepts touch event
* gives info via chat about the parcel you're in:
** name
** description
** resident or group that owns it
** how many people are around you right now, their names and a link you can click to directly open their profile
*** this scan uses a default radius of 96 meters; change scanradius in the 1st line of script as needed
* receives linkedmessages from script 1
* retrieves from web the profile image texture UUID for resident or group that owns the parcel you're in
* sends texture UUID to script 1
 
<lsl>
 
float scanradius = 96.0;
string ownerurl =  "http://world.secondlife.com/resident/";
string groupurl =  "http://world.secondlife.com/group/";
string code1 = "<img alt=\"profile image\" src=\"http://secondlife.com/app/image/";
string code2 = "\" class=\"parcelimg\" />";
key texturedefault = "19920f4f-d667-ab18-7234-af4623b52065";
key textureuuid = "";
string desc;
integer check;
string parcelname()
string parcelname()
{
{
Line 223: Line 135:
}
}
   
   
   
 
// partially redundant (1)
// we use this after 2nd touch if no message is provided by the user  
string parceldesc()
string parceldesc()
{
{
Line 236: Line 150:
         desc = "";
         desc = "";
     }  
     }  
     return desc;   
     return strReplace(desc, "&", "and");   
}
}
   
   
 
// partially redundant (1)
string parcelowner()
string parcelowner()
{
{
Line 247: Line 162:
}
}
   
   
 
// partially redundant (1)
string parcelgroup()
string parcelgroup()
{
{
Line 256: Line 172:




texture()
// this comes from Cory Ondrejka I think
string slurl()
{
{
        string a = parcelgroup();
    string simname = llDumpList2String(llParseString2List(llGetRegionName(),[" "],[]),"+");
        if(a == "00000000-0000-0000-0000-000000000000")
    string regionname = simname;
        {
    vector detectedPos = llGetRootPosition();       
            llHTTPRequest( ownerurl + parcelowner(),[HTTP_METHOD,"GET"],"");              
    string sx = (string)llRound(detectedPos.x);
        } 
    string sy = (string)llRound(detectedPos.y);
        else
    string sz = (string)llRound(detectedPos.z);
        {
    string url = "http://slurl.com/secondlife/"; 
            llHTTPRequest( groupurl + parcelgroup(),[HTTP_METHOD,"GET"],"");          
    url += simname;
        }
    url += "/" + sx + "/" + sy + "/" + sz ;  
}  
    return url; 
}
   
   
// partially redundant (1)
infoparcel()
infoparcel()
{
{
     llOwnerSay("parcel name =" + parcelname());
     llOwnerSay("parcel name = " + (string)llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_NAME]));
     llOwnerSay("parcel desc =" + parceldesc());
     llOwnerSay("parcel desc = " + (string)llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_DESC]));
     llOwnerSay("parcel owner = " + "secondlife:///app/agent/" + parcelowner() + "/about");   
     llOwnerSay("parcel owner = " + "secondlife:///app/agent/" + parcelowner() + "/about");   
     llOwnerSay("parcel group = "  + "secondlife:///app/group/" + parcelgroup() + "/about");
     llOwnerSay("parcel group = "  + "secondlife:///app/group/" + parcelgroup() + "/about");
    llSensor("", NULL_KEY, AGENT, scanradius, PI);
}
}
   
 
 
texture()
{
    if (parcelgroup() == parcelowner()) // group-owned land
    {
        request_texture = llHTTPRequest(groupurl + parcelgroup(),[HTTP_METHOD,"GET"],"");           
    }  
    else // group may be set, but land is not group-owned
        // single residents have pictures more often than group so we choose them
    {
        request_texture = llHTTPRequest(ownerurl + parcelowner(),[HTTP_METHOD,"GET"],"");             
    }
}
 
 
string prepara(string messaggio)
{
    string imageurl = "http://secondlife.com/app/image/" + (string)textureuuid + "/2";     
    messaggio = llDumpList2String(llParseString2List(messaggio,[" "],[]),"+");
    string post =
    "http://" +
    user +
    ":" +
    ffkey +
    baseurl +
    "?title=" +
    parcelname() +
    "&link=" +
    llEscapeURL(slurl()) +
    "&comment=" +     
    messaggio +
    "&room=" +
    room +
    "&image0_url=" +
    llEscapeURL(imageurl) +
    "&via=ffhud";
    return post;
}
 
 
default
default
{
{
     state_entry()
     on_rez(integer start_param)
     {
     {
         llSetTexture(texturedefault, ALL_SIDES);      
         llOwnerSay(": Ready. Touch once to get parcel info - Touch twice to update your FriendFeed page.");        
     }
     }
   
     link_message(integer sender_num, integer num, string str, key id)  
     state_entry()
     {
     {
         check = TRUE;
         llSetTexture(texturedefault, ALL_SIDES);        
         texture();      
         llSetTimerEvent(0.0);              
     }
     }
 
   
   
     touch_start(integer total_number)
     touch_start(integer total_number)
     {
     {    
        check = FALSE;
         infoparcel();
         infoparcel();
         texture();
         texture();
        state pronto;       
     }
     }
 
    // redundant (2)
     http_response(key req,integer stat, list met, string body)
     http_response(key request_id, integer status, list metadata, string body)
     {  
     {
         textureuuid = (key)llGetSubString(body,llSubStringIndex(body, code1)+llStringLength(code1),llSubStringIndex(body,code2)-3);  
    if(request_id == request_ff)
        {
        llOwnerSay(": Message sent.");
        }
   
    else if(request_id == request_texture)
        {
         textureuuid = (key)llGetSubString(body,llSubStringIndex(body, code1)+llStringLength(code1),llSubStringIndex(body,code2)-3);
         llSetTexture(textureuuid, ALL_SIDES);
         llSetTexture(textureuuid, ALL_SIDES);
        if (check == TRUE)
        {
            llMessageLinked(1, 2, "", textureuuid);   
         }
         }
    }                               
}
       
state pronto
{
    state_entry()
    {
        llSetTimerEvent(listentime);       
        llOwnerSay(": Say your message on channel 8 within 20 seconds, or touch again to send a quick post.");       
        listen_handle = llListen(8, "", llGetOwner(), "");               
     }
     }
   
    changed(integer change)
     sensor(integer total_number)
    {
     if (change & (CHANGED_TELEPORT|CHANGED_REGION))
     {
     {
         llOwnerSay((string)total_number + " avatar" + " in " + (string)scanradius+ " meters");
         llOwnerSay(": Location changed, restarting.");          
        integer i;
        state default;
        for (i = 0; i < total_number; i++)
    }
        {
            llOwnerSay(llDetectedName(i) + " > secondlife:///app/agent/" + (string)llDetectedKey(i) + "/about");            
        }
     }
     }
     no_sensor()
 
      
   
  timer()
  {
        llOwnerSay(": Time over.");       
        state default;
  }
 
                   
    touch_start(integer total_number)
    {
        request_ff = llHTTPRequest(prepara(parceldesc()), [HTTP_METHOD,"POST"], "");
        state default;       
    }
   
   
    listen(integer channel, string name, key id, string message)
     {
     {
         llOwnerSay("nobody here right now (radius=" + (string)scanradius + " meters)");
         request_ff = llHTTPRequest(prepara(message), [HTTP_METHOD,"POST"], "");  
        state default;       
     }
     }
   
 
    // redundant (2)
    http_response(key request_id, integer status, list metadata, string body)
    {
    if(request_id == request_ff)
        {
        llOwnerSay(": Message sent.");
        }
   
    else if(request_id == request_texture)
        {
        textureuuid = (key)llGetSubString(body,llSubStringIndex(body, code1)+llStringLength(code1),llSubStringIndex(body,code2)-3);
        llSetTexture(textureuuid, ALL_SIDES);
        }
    }                                                                   
 
       
}
}


</lsl>
</lsl>

Latest revision as of 04:12, 22 April 2011

Go back to Opensource Obscure's userpage



FFHUD

A SIMPLE FRIENDFEED HUD

  • An idea by Opensource Obscure
  • Current release: 0.7.3
  • Features:
    • single, non-obtrusive button
    • quick automatic or custom messages
    • Friendfeed Rooms support
    • Parcel Owner Profile Image support


What does it do

FFHUD lets you publish to the FriendFeed microblogging service from inside Second Life.

You send your posts by writing them in a private chat channel. Posts always include a SLURL link to your actual location. You can send a quick update that automatically includes the parcel description, or write a custom message. If available, the owner or owner-group profile image is also published, accordingly to their privacy settings.

FFHUD is an ideal way to participate on web social networks while you're enjoying Second Life. You can publish a quick review of an interesting place you just found in-world, or share with your friends your random thoughts from your home.

Automated Web Diary of your SL parcel

You could also use FFHUD to automatically report on a web page what's happening in Second Life. Use it together with sensors and scripted objects so that a new post is published to a dedicated Friendfeed group/room when actions occur, then embed that Friendfeed stream in your website.

  • Example. I'm currently using FFHUD to automatically transmit information from my Second Life island, LOL, to http://friendfeed.com/lolsl - Many LSL sensors using FFHUD are placed near various places inside the region. They get triggered when visitors walk over them, or they start using devices and installations made by LOL builders.

Setup

  • Put the script (see below) in a prim (you may also want to rename it).
  • Edit the script and insert your FriendFeed account data. You may also specify a room.
  • Wear the prim as an HUD. Resize and replace as needed.

How to use FFHUD

Touch it once to get information about the parcel you're in (printed in private chat via llOwnerSay). Then:

  • if you're not publishing a post, just wait until FFHUD resets itself before touching it again;
  • touch it again within 20 seconds to publish a post on FriendFeed that includes available info about the parcel: SLURL, description, owner profile image;
  • or say a message on channel 8 within 20 seconds to publish a post that includes both parcel info and your message. Example:
/8 This is my message

Do you need help? Feel free to contact me (Opensource Obscure) in-world, through this wiki or on FriendFeed.

Notes

FFHUD builds your posts this way:

  • LINK = SLURL of your location
  • TITLE = parcel name
  • COMMENT = parcel description (if available) OR your message
  • IMAGE = profile image of resident or group that owns the parcel
  • ROOM = according to your settings

FFHUD shows the FriendFeed logo by default. After you touch it once, it will display the parcel owner profile image, if available. It's the same picture that will be published in your post. Profile images are shown by using llSetTexture; the UUID is retrieved using the Second Life Search; the image web address (not the image itself) is sent to FriendFeed, that then retrieves and hosts a copy of the image.

If you're on FriendFeed, join the Second Life room!
http://friendfeed.com/rooms/secondlife

Feel free to use this room for testing:
http://friendfeed.com/rooms/ffhud

Script

This code works but may be horrible and flawed. Feel free to suggest me how to improve it. I am not a real developer and I lack some programming basis, so any feedback can help me. I usually make the LSL scripts I need by reading around, cutting, pasting and tweaking code from other sources. To write FFHUD I used snippets by User:Ordinal Malaprop, User:Cory Linden, MarcoDuff Palen, User:Jana Kamachi and others. Thanks to Tayra Dagostino. User:Strife Onizuka improved this script, however its changes are missing from the current version and will be merged back as soon as possible.

To do:

<lsl>// FFHUD 0.7.3 // free for public use // A project started by Opensource Obscure //

// Look for your username and FriendFeed key here: https://friendfeed.com/account/api string user=""; // your FriendFeed username string ffkey=""; // your FriendFeed key

// You can send messages to a FriendFeed room: // "" -----------> default setting - you won't share messages to any room // "ffhud" ------> a test room you can freely use // "secondlife" -> an unofficial SL room - http://friendfeed.com/rooms/secondlife // Change accordingly the line below: string room="ffhud";


// after 1st click you have a few seconds to write and send // your text message before FFHUD comes back to default state. // you can change the timing below: float listentime = 20.0;


/////////////////////////////////////////////////// // you don't need to modify anything below


string desc; integer listen_handle; string baseurl="@friendfeed.com/api/share"; key request_ff; key request_texture; string ownerurl = "http://world.secondlife.com/resident/"; string groupurl = "http://world.secondlife.com/group/"; string code1 = "<img alt=\"profile image\" src=\"http://secondlife.com/app/image/"; string code2 = "\" class=\"parcelimg\" />"; key textureuuid = ""; key texturedefault = "4760a44f-06f7-622e-7429-b01570a598b0";


// let's substitute '&' character with 'and' string strReplace(string source, string pattern, string replace) {

   while (llSubStringIndex(source, pattern) > -1) {
       integer len = llStringLength(pattern);
       integer pos = llSubStringIndex(source, pattern);
       if (llStringLength(source) == len) { source = replace; }
       else if (pos == 0) { source = replace+llGetSubString(source, pos+len, -1); }
       else if (pos == llStringLength(source)-len) { source = llGetSubString(source, 0, pos-1)+replace; }
       else { source = llGetSubString(source, 0, pos-1)+replace+llGetSubString(source, pos+len, -1); }
   }
   return source;

}


// partially redundant (1) string parcelname() {

   list lstParcelName=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_NAME]);                
   string a = (string)lstParcelName;
   string name = llDumpList2String(llParseString2List(a,[" "],[]),"+"); 
   return name; 

}


// partially redundant (1) // we use this after 2nd touch if no message is provided by the user string parceldesc() {

   list lstParcelDesc=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_DESC]);                
   string a = (string)lstParcelDesc;  
   if(a != "00000000-0000-0000-0000-000000000000")
   {
       desc = llDumpList2String(llParseString2List(a,[" "],[]),"+") + "+-+";                
   } 
   else
   {
       desc = "";
   } 
   return strReplace(desc, "&", "and");   

}


// partially redundant (1) string parcelowner() {

   list lstParcelOwner=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_OWNER]);                
   string uuid = (string)lstParcelOwner;    
   return uuid;    

}


// partially redundant (1) string parcelgroup() {

   list lstParcelGroup=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_GROUP]);              
   string uuid = (string)lstParcelGroup;
   return uuid;

}


// this comes from Cory Ondrejka I think string slurl() {

   string simname = llDumpList2String(llParseString2List(llGetRegionName(),[" "],[]),"+");
   string regionname = simname;
   vector detectedPos = llGetRootPosition();        
   string sx = (string)llRound(detectedPos.x);
   string sy = (string)llRound(detectedPos.y);
   string sz = (string)llRound(detectedPos.z);
   string url = "http://slurl.com/secondlife/";  
   url += simname; 
   url += "/" + sx + "/" + sy + "/" + sz ; 
   return url;   

}


// partially redundant (1) infoparcel() {

   llOwnerSay("parcel name = " + (string)llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_NAME]));
   llOwnerSay("parcel desc = " + (string)llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_DESC]));
   llOwnerSay("parcel owner = " + "secondlife:///app/agent/" + parcelowner() + "/about");   
   llOwnerSay("parcel group = "  + "secondlife:///app/group/" + parcelgroup() + "/about");

}


texture() {

   if (parcelgroup() == parcelowner()) // group-owned land
   {
       request_texture = llHTTPRequest(groupurl + parcelgroup(),[HTTP_METHOD,"GET"],"");            
   }  
   else // group may be set, but land is not group-owned
       // single residents have pictures more often than group so we choose them
   { 
       request_texture = llHTTPRequest(ownerurl + parcelowner(),[HTTP_METHOD,"GET"],"");               
   }

}


string prepara(string messaggio) {

   string imageurl = "http://secondlife.com/app/image/" + (string)textureuuid + "/2";       
   messaggio = llDumpList2String(llParseString2List(messaggio,[" "],[]),"+");
   string post = 
   "http://" + 
   user + 
   ":" + 
   ffkey + 
   baseurl + 
   "?title=" + 
   parcelname() +
   "&link=" + 
   llEscapeURL(slurl()) + 
   "&comment=" +      
   messaggio +
   "&room=" +
   room +
   "&image0_url=" + 
   llEscapeURL(imageurl) +
   "&via=ffhud";
   return post;

}


default {

   on_rez(integer start_param)
   {
       llOwnerSay(": Ready. Touch once to get parcel info - Touch twice to update your FriendFeed page.");         
   }
   
   state_entry()
   {
       llSetTexture(texturedefault, ALL_SIDES);         
       llSetTimerEvent(0.0);                
   }
   
   
   touch_start(integer total_number)
   {      
       infoparcel();
       texture();
       state pronto;        
   }
   // redundant (2)
   http_response(key request_id, integer status, list metadata, string body)
   {
   if(request_id == request_ff) 
       {
        llOwnerSay(": Message sent.");
       }
   
   else if(request_id == request_texture)
       {
       textureuuid = (key)llGetSubString(body,llSubStringIndex(body, code1)+llStringLength(code1),llSubStringIndex(body,code2)-3);
       llSetTexture(textureuuid, ALL_SIDES);
       }
   }                                 

}


state pronto {

   state_entry()
   {
       llSetTimerEvent(listentime);        
       llOwnerSay(": Say your message on channel 8 within 20 seconds, or touch again to send a quick post.");        
       listen_handle = llListen(8, "", llGetOwner(), "");                
   }
   
   changed(integer change) 
   { 
   if (change & (CHANGED_TELEPORT|CHANGED_REGION))
   {
       llOwnerSay(": Location changed, restarting.");           
        state default;
   }
   }


  timer()
  {
       llOwnerSay(": Time over.");        
       state default;
  }


   touch_start(integer total_number)
   {
       request_ff = llHTTPRequest(prepara(parceldesc()), [HTTP_METHOD,"POST"], ""); 
       state default;        
   } 
   
   
   listen(integer channel, string name, key id, string message)
   {
       request_ff = llHTTPRequest(prepara(message), [HTTP_METHOD,"POST"], ""); 
       state default;        
   }
   
   // redundant (2)
   http_response(key request_id, integer status, list metadata, string body)
   {
   if(request_id == request_ff) 
       {
        llOwnerSay(": Message sent.");
       }
   
   else if(request_id == request_texture)
       {
       textureuuid = (key)llGetSubString(body,llSubStringIndex(body, code1)+llStringLength(code1),llSubStringIndex(body,code2)-3);
       llSetTexture(textureuuid, ALL_SIDES);
       }
   }                                                                     


}

</lsl>