Difference between revisions of "User:Opensource Obscure/FFHUD"
m (→Script) |
(→Script: I really dislike this whitespacing model) |
||
Line 48: | Line 48: | ||
* ...better code | * ...better code | ||
<lsl> | <lsl>// FFHUD 0.7 | ||
// FFHUD 0.7 | |||
// free for public use | // free for public use | ||
// A project started by Opensource Obscure | // A project started by Opensource Obscure | ||
Line 89: | Line 88: | ||
key texturedefault = "4760a44f-06f7-622e-7429-b01570a598b0"; | key texturedefault = "4760a44f-06f7-622e-7429-b01570a598b0"; | ||
//{ Combined Library - Copyright (C) 2004-2008, Strife Onizuka (cc-by 3.0) - "Jul 17 2008", "14:03:07" | |||
// | string str_replace(string src, string from, string to) | ||
string | {//replaces all occurrences of 'from' with 'to' in 'src'. | ||
integer len = llStringLength(from) - 1; | |||
integer | if(len >= 0) | ||
integer | { | ||
if ( | string buffer = src; | ||
integer b_pos = -1; | |||
integer to_len = llStringLength(to) - 1; | |||
@loop;//instead of a while loop, saves 5 bytes (and runs faster). | |||
integer to_pos = 1 + llSubStringIndex(buffer, from); | |||
if(to_pos) | |||
{ | |||
// b_pos += to_pos; | |||
// src = llInsertString(llDeleteSubString(src, b_pos, b_pos + len), b_pos, to); | |||
// b_pos += to_len; | |||
// buffer = llGetSubString(src, 1 + (b_pos), 0x40000000); | |||
buffer = llGetSubString(src = llInsertString(llDeleteSubString(src, b_pos += to_pos, b_pos + len), b_pos, to), 1 + (b_pos += to_len), 0x40000000); | |||
jump loop; | |||
} | |||
} | } | ||
return | return src; | ||
} | } | ||
//} | |||
// partially redundant (1) | // partially redundant (1) | ||
Line 120: | Line 129: | ||
list lstParcelDesc=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_DESC]); | list lstParcelDesc=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_DESC]); | ||
string a = (string)lstParcelDesc; | string a = (string)lstParcelDesc; | ||
if(a != | if(a != NULL_KEY) | ||
{ | { | ||
desc = llDumpList2String(llParseString2List(a,[" "],[]),"+") + "+-+"; | desc = llDumpList2String(llParseString2List(a,[" "],[]),"+") + "+-+"; | ||
Line 128: | Line 137: | ||
desc = ""; | desc = ""; | ||
} | } | ||
return | return str_replace(desc, "&", "and"); | ||
} | } | ||
Line 135: | Line 144: | ||
string parcelowner() | string parcelowner() | ||
{ | { | ||
return (string)llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_OWNER]); | |||
} | } | ||
Line 144: | Line 151: | ||
string parcelgroup() | string parcelgroup() | ||
{ | { | ||
return (string)lstParcelGroup=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_GROUP]); | |||
} | } | ||
Line 154: | Line 159: | ||
{ | { | ||
string simname = llDumpList2String(llParseString2List(llGetRegionName(),[" "],[]),"+"); | string simname = llDumpList2String(llParseString2List(llGetRegionName(),[" "],[]),"+"); | ||
vector detectedPos = llGetRootPosition(); | vector detectedPos = llGetRootPosition(); | ||
string sx = (string)llRound(detectedPos.x); | string sx = (string)llRound(detectedPos.x); | ||
string sy = (string)llRound(detectedPos.y); | string sy = (string)llRound(detectedPos.y); | ||
string sz = (string)llRound(detectedPos.z); | string sz = (string)llRound(detectedPos.z); | ||
return "http://slurl.com/secondlife/" + simname + "/" + sx + "/" + sy + "/" + sz; | |||
} | } | ||
Line 172: | Line 173: | ||
llOwnerSay("parcel desc = " + (string)llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_DESC])); | 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 = " | llOwnerSay("parcel group = " + "secondlife:///app/group/" + parcelgroup() + "/about"); | ||
} | } | ||
Line 240: | Line 241: | ||
if(request_id == request_ff) | if(request_id == request_ff) | ||
{ | { | ||
llOwnerSay(": Message sent."); | |||
} | } | ||
Line 263: | Line 264: | ||
changed(integer change) | changed(integer change) | ||
{ | { | ||
if (change & (CHANGED_TELEPORT|CHANGED_REGION)) | if (change & (CHANGED_TELEPORT | CHANGED_REGION)) | ||
{ | { | ||
llOwnerSay(": Location changed, restarting."); | llOwnerSay(": Location changed, restarting."); | ||
state default; | |||
} | } | ||
} | } | ||
timer() | |||
{ | |||
llOwnerSay(": Time over."); | llOwnerSay(": Time over."); | ||
state default; | state default; | ||
} | |||
touch_start(integer total_number) | touch_start(integer total_number) | ||
Line 284: | Line 282: | ||
state default; | state default; | ||
} | } | ||
listen(integer channel, string name, key id, string message) | listen(integer channel, string name, key id, string message) | ||
Line 291: | Line 288: | ||
state default; | state default; | ||
} | } | ||
// redundant (2) | // redundant (2) | ||
Line 298: | Line 294: | ||
if(request_id == request_ff) | if(request_id == request_ff) | ||
{ | { | ||
llOwnerSay(": Message sent."); | |||
} | } | ||
else if(request_id == request_texture) | else if(request_id == request_texture) | ||
{ | { | ||
textureuuid = (key)llGetSubString(body,llSubStringIndex(body, code1)+llStringLength(code1),llSubStringIndex(body,code2)-3); | textureuuid = (key)llGetSubString(body, llSubStringIndex(body, code1) + llStringLength(code1), llSubStringIndex(body,code2) - 3); | ||
llSetTexture(textureuuid, ALL_SIDES); | llSetTexture(textureuuid, ALL_SIDES); | ||
} | } | ||
} | } | ||
}</lsl> | |||
} | |||
</lsl> |
Revision as of 11:21, 17 July 2008
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
FFHUD: a simple FriendFeed HUD
Current release: 0.7
One-button, Custom messages, Rooms and Profile Image support.
FFHUD lets you post to FriendFeed. 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.
If you're on FriendFeed, you may want to join this room:
http://friendfeed.com/rooms/secondlife
Setup
- Edit the script and put your FriendFeed account data. You may also specify a room.
- Put the script in a prim (you may also want to rename it)
- Wear the prim as an HUD
How to use FFHUD
- Touch it once to get information about parcel you're in (printed in private chat via llOwnerSay)
- Touch it again within 20 seconds to publish a post on FriendFeed... (that includes available info about the parcel: SLURL, description, owner/owner-group profile image)
- ...or say a message on channel 8 within 20 seconds to publish a post (that includes same parcel info than above + your message) - Example:
/8 This is my message
Notes
Feel free to use this room for testing:
http://friendfeed.com/rooms/ffhud
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 favicon image by default; it changes (after the first touch) if a profile image is available for the parcel owners. 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.
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.
To do:
- add switch to turn off/on image support
- enriched SLURL as in Ordinal Malaprop's TwitterBox
- ...better code
<lsl>// FFHUD 0.7 // 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="";
// 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";
//{ Combined Library - Copyright (C) 2004-2008, Strife Onizuka (cc-by 3.0) - "Jul 17 2008", "14:03:07" string str_replace(string src, string from, string to) {//replaces all occurrences of 'from' with 'to' in 'src'.
integer len = llStringLength(from) - 1; if(len >= 0) { string buffer = src; integer b_pos = -1; integer to_len = llStringLength(to) - 1; @loop;//instead of a while loop, saves 5 bytes (and runs faster). integer to_pos = 1 + llSubStringIndex(buffer, from); if(to_pos) {
// b_pos += to_pos; // src = llInsertString(llDeleteSubString(src, b_pos, b_pos + len), b_pos, to); // b_pos += to_len; // buffer = llGetSubString(src, 1 + (b_pos), 0x40000000);
buffer = llGetSubString(src = llInsertString(llDeleteSubString(src, b_pos += to_pos, b_pos + len), b_pos, to), 1 + (b_pos += to_len), 0x40000000); jump loop; } } return src;
} //}
// 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 != NULL_KEY) { desc = llDumpList2String(llParseString2List(a,[" "],[]),"+") + "+-+"; } else { desc = ""; } return str_replace(desc, "&", "and");
}
// partially redundant (1)
string parcelowner()
{
return (string)llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_OWNER]);
}
// partially redundant (1)
string parcelgroup()
{
return (string)lstParcelGroup=llGetParcelDetails(llGetPos(),[PARCEL_DETAILS_GROUP]);
}
// this comes from Cory Ondrejka I think
string slurl()
{
string simname = llDumpList2String(llParseString2List(llGetRegionName(),[" "],[]),"+"); vector detectedPos = llGetRootPosition(); string sx = (string)llRound(detectedPos.x); string sy = (string)llRound(detectedPos.y); string sz = (string)llRound(detectedPos.z); return "http://slurl.com/secondlife/" + simname + "/" + sx + "/" + sy + "/" + sz;
}
// 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); 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>