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;
    }
}
Toolbox
LANGUAGES