ANGEL Prim Drop SL Script
From SLIS Second Life Wiki
Add this code to the moving drawer
Be sure to change all the variables in the // ANGEL Connection block
string ApplicationName = "ANGEL PrimDrop";
string version = ".09";
// Sloodle - Copyright (C) 2008 Jeremy Kemp, et al
// Whitepaper: http://www.sloodle.com/whitepaper.pdf
////////////
//FUNCTION
// Accepts objects and reports their properties to a web script.
// Prototype for 3D Object assignment tool.
// REQUIRES API configured with new function SL_CHECK_AVATAR
// LICENSE - GNU General Public License 3
// This program comes with ABSOLUTELY NO WARRANTY; for details see
// http://www.sloodle.com/license
// This is free software, and you are welcome to redistribute it under certain conditions.
// BASED ON Bulletin Board by Apotheus Silverman
// VERSIONS
//.01 initial build from Sloodle Primdrop
//.06 cleaned and documented
//.07 made the UUID secret with instant message and Load URL dialog,
//.08 changed image on top to make ctrl-drag easier
//.09 added drawer movement, docs, ANGEL connection constants
////////////
////Constants
// ANGEL Connection
string URL="secondlife.angellearning.com"; //The server address
string SECTION="SEM1-ANG-Demo-testing-1"; //The class section
string ENTRY="86F124EF7871431A9C4C34B453EAC58D";//The assignment's ID
string ANGELID="199790f0-ee64-4e97-9d01-ac8d3c44709a"; //Used for API calls
string APIUSER="jkemp";//to access the API - DANGER - THIS SHOULD NOT BE HARDCODED
string APIPWD="angel123";//to access the API - DANGER - THIS SHOULD NOT BE HARDCODED
// Shelf movement
float movementToForeground = 0.35; //Change this to suit the size of your object
// Sounds
key ConnectedSound="c6cf7fc3-e07b-b4dc-1f55-785cf4b8c32a";// Metal Door - http://www.freesound.org/samplesViewSingle.php?id=26923
key ConnectingSound="ba74fb28-47d4-0270-c875-e12267d02dce";// Radio waves - http://www.freesound.org/samplesViewSingle.php?id=3176
key SubmittedSound="ba74fb28-47d4-0270-c875-e12267d02dce"; // Radio waves - http://www.freesound.org/samplesViewSingle.php?id=3176
key ErrorSound="4174f859-0d3d-c517-c424-72923dc21f65";// Guitar twang
key TimeoutSound="b3831ff2-a197-62df-34f7-a83be592c1da";// Crickets
// Colors
vector colorOpen=<0,128,0>; // Green - "Accepting objects"
vector colorClosed=<128,50,0>; // Yellow - "Waiting to be touched"
float Timeout = 45; //Reset if no object is given
// Variables
string SubmitObject; //Results of the API call for ITEM_RESPONSE_POST
string CheckAvatar; //Results of the API call for SL_CHECK_AVATAR
string Region; //Where is this box?
integer x;
integer y;
integer z;
key CurrentAgent;
integer ListenHandle;
string BulletinTitle;
string BulletinItem;
list InventoryBefore;
integer RezQuant;
string AviID;
string AviName;
// All inventory types
list InventoryTypes = [
INVENTORY_TEXTURE,
INVENTORY_SOUND,
INVENTORY_OBJECT,
INVENTORY_SCRIPT,
INVENTORY_LANDMARK,
INVENTORY_CLOTHING,
INVENTORY_NOTECARD,
INVENTORY_BODYPART
];
// Global functions
Identify() {// Identifies this application in public chat.
llSay(0, ApplicationName + " v" + version);
}
integer GetInventoryType(string inventory) { // Returns the type of inventory (an integer value) defined by the inventory argument.
if (llGetInventoryKey(inventory) == NULL_KEY) {
return(-1);
} else {
integer i;
for (i = 0; i < llGetListLength(InventoryTypes); i++) {
integer constant = llList2Integer(InventoryTypes, i);
integer j;
for (j = 0; j < llGetInventoryNumber(constant); j++) {
if(inventory == llGetInventoryName(constant, j)) {
return(constant);
}
}
}
}
return(-1);
}
list GetInventoryDirectory() {// Returns a list of inventory names
list myInventory;
integer j;
integer k;
for(j = 0; j < llGetListLength(InventoryTypes); j++) {
integer constant = llList2Integer(InventoryTypes, j);
for(k = 0; k < llGetInventoryNumber(constant); k++) {
myInventory += llGetInventoryName(constant, k);
}
}
return(myInventory);
}
string ListDiff(list list1, list list2) { // Returns the first item in list1 that does not exist in list2. If all items in list1 exist in list2, returns an empty string.
integer i;
for (i = 0; i < llGetListLength(list1); i++) {
if (llListFindList(list2, llList2List(list1, i, i)) == -1) {
return(llList2String(list1, i));
}
}
return("");
}
// States
default {
state_entry() { // Initialize
Identify();
llStopSound();
llPlaySound(ConnectingSound, 1.0);
state idle;
}
}
state idle {
state_entry() { // Clear global vars, change color and start listening
llAllowInventoryDrop(FALSE);
CurrentAgent = NULL_KEY;
InventoryBefore = [];
BulletinItem = "";
BulletinTitle = "";
llSetPrimitiveParams([PRIM_COLOR,ALL_SIDES,colorClosed,1]);
llListenRemove(ListenHandle);
ListenHandle = llListen(0, "", NULL_KEY, "");
}
touch_start(integer total_number) { // "I've been clicked!"
AviID = (string)llDetectedKey(0); //Get the UUID of the avatar touching
AviName = llKey2Name(llDetectedKey(0)); //Convert the UUID to a name
llSay(0,"Hello "+AviName+". This object is checking your unique Second Life ID against the ANGEL database.");
CheckAvatar = llHTTPRequest("http://"+URL+"/api/default.asp?APIACTION=SL_CHECK_AVATAR&APIUSER="+APIUSER+"&APIPWD="+APIPWD+"&AVATAR_UUID="+llEscapeURL(AviID),[HTTP_METHOD,"GET"],"");//Send off a request to the ANGEL server API with variables set above
}
http_response(key request_id, integer status, list metadata, string body)
{ //Interprets the returned messages from the ANGEL server in XML
if (request_id == CheckAvatar)
{
if (llSubStringIndex(llToUpper(body),"<SUCCESS>")==30)//ANGEL server acknowledges with XML and "<SUCCESS>" 30 characters in
{
llSay(0,"ANGEL recognizes you....");
llStopSound();
llPlaySound(ConnectedSound, 1.0);
ANGELID=llList2String(llParseString2List(body,["\""],[]),3);//Grabs the 3rd item which is the ID from the ANGEL user table
state bulletin;
} else
{
llStopSound();
llPlaySound(ErrorSound, 1.0);
llInstantMessage(AviID,"\nSelect and copy "+AviName+"'s secret code: \n-------\n"+AviID+"\n-------\nand click 'Go to page' in the blue pull-down message in the top right of your screen.");
llLoadURL(AviID, "Your avatar is not linked. Add the Angel Island component then copy the secret code", "http://"+URL);
state idle;
}
} else if (request_id == SubmitObject)
{
if (llSubStringIndex(llToUpper(body),"<SUCCESS>")==30)
{
llStopSound();
llPlaySound(SubmittedSound, 1.0);
llSay(0, "Success! You should see an entry in the dropbox resource.");
//Move the drawer back into the mailbox
vector fgpos = llGetPos();
vector bgpos = llGetPos() - (<movementToForeground, 0.0, 0.0> * llGetRot());
llSetPos(bgpos);
} else
{
llSay(0,"There is a problem...\n"+body);
llStopSound();
llPlaySound(ErrorSound, 1.0);
}
}
}
}
state bulletin {
state_entry() {
InventoryBefore = GetInventoryDirectory();
llSay(0, "CTRL-drag an object from Inventory.");
llSetPrimitiveParams([PRIM_COLOR,ALL_SIDES,colorOpen,1]);
//Move the drawer out from the mailbox
vector bgpos = llGetPos();
vector fgpos = llGetPos() + (<movementToForeground, 0.0, 0.0> * llGetRot());
llSetPos(fgpos);
llAllowInventoryDrop(TRUE);
llSetTimerEvent(Timeout);
llListenRemove(ListenHandle);
ListenHandle = llListen(0, "", NULL_KEY, "");
}
touch_start(integer total_number) { //touched while waiting for an object
llSay(0,"Already connected - Ctrl-Drag an object.");
llStopSound();
llPlaySound(ErrorSound, 1.0);
}
changed(integer change) { //Something was added
if ((change & CHANGED_INVENTORY) || (change & CHANGED_ALLOWED_DROP)) {
// Get new inventory list
list inventoryAfter = GetInventoryDirectory();
// Make sure something was added
if (llGetListLength(InventoryBefore) < llGetListLength(inventoryAfter))
// Figure out what was added
BulletinItem = ListDiff(inventoryAfter, InventoryBefore);
if (BulletinItem != "") { //It is named something
// Create new bulletin
llSay(0,"Sending the item "+BulletinItem+"...");
llSetTimerEvent(0);
//Gather data envelope to package this and send to ANGEL server
string obj_id = (string)llGetInventoryKey(BulletinItem);
string obj_name = BulletinItem;
string AviID = (string)CurrentAgent;
string AviName = llKey2Name(CurrentAgent);
string region = llGetRegionName();
vector Where = llGetPos();
integer x = (integer)Where.x;
integer y = (integer)Where.y;
integer z = (integer)Where.z;
string obj_type = (string)GetInventoryType(BulletinItem);
integer prim_count=llGetObjectPrimCount(llGetInventoryKey(BulletinItem));
string dropbox_name = llGetObjectName();
string dropbox_id = (string)llGetInventoryKey(dropbox_name);
SubmitObject = llHTTPRequest("http://"+URL+"/api/default.asp?APIACTION=ITEM_RESPONSE_POST&APIUSER="+APIUSER+"&APIPWD="+APIPWD+"&ENTRY="+ENTRY+"&SECTION="+SECTION+"&RESPONSE_SUBMITTER="+ANGELID+"&RESPONSE_TITLE="+llEscapeURL(obj_name)+"&RESPONSE_DATA="+llEscapeURL("Second Life object (ID=")+llEscapeURL(obj_id)+llEscapeURL(") stored in a box at: <a href=\"http://slurl.com/secondlife/")+llEscapeURL(region)+"/"+(string)x+"/"+(string)y+"/"+(string)z+"\">http://slurl.com/secondlife/"+llEscapeURL(region)+"/"+(string)x+"/"+(string)y+"/"+(string)z+"</a>",[HTTP_METHOD,"GET"],"");
state idle ;
}
}
}
// }
timer() {
llSetTimerEvent(0);
llSay(0, "TIMED OUT. Please start over.");
llStopSound();
llPlaySound(TimeoutSound, 1.0);
//Move the drawer back into the mailbox
vector fgpos = llGetPos();
vector bgpos = llGetPos() - (<movementToForeground, 0.0, 0.0> * llGetRot());
llSetPos(bgpos);
state idle;
}
}