Quantcast
Channel: An Engine Fit For My Proceeding - Scripting Examples
Viewing all articles
Browse latest Browse all 9

Mass distribution script

$
0
0
Code summary: 

Sends inventory contents to each named individual on a list, by trying to get their key from a series of databases. This would be so much easier if there was a name2key function. But there isn't.

To use this script: place it in a prim, along with some other items that you want to send to people, and a notecard called "Names" which has a list of avatar names to send items to, one per line without spaces before or after them. (Blank lines will be ignored; anything else, and the script will try to find the line as if it were a name, and fail, and tell you that it has failed.)

Then, touch to start sending. There will be a display of names left to check and estimated time remaining.

There is no way of determining whether an object has been successfully sent by script, or whether somebody was in busy mode (this is the usual culprit when people complain of not receiving an item - either that, or they did receive it but can't find it) or declined the item. My apologies.

// Mass distribution script // Ordinal Malaprop 2010-01-15 11:29 //..................................................................... // Sends inventory contents to each named individual on a list, by trying to get their key from a series of databases. This would be so much easier if there was a name2key function. But there isn't. // To use this script: place it in a prim, along with some other items that you want to send to people, and a notecard called "Names" which has a list of avatar names to send items to, one per line without spaces before or after them. (Blank lines will be ignored; anything else, and the script will try to find the line as if it were a name, and fail, and tell you that it has failed.) // Then, touch to start sending. There will be a display of names left to check and estimated time remaining. // There is no way of determining whether an object has been successfully sent by script, or whether somebody was in busy mode (this is the usual culprit when people complain of not receiving an item - either that, or they did receive it but can't find it) or declined the item. My apologies. // The original script can be found at http://ordinalmalaprop.com/engine/code/mass-distribution-script //--------------------------------------------------------------------- // LICENCE - Creative Commons "Attribution" 3.0 // http://creativecommons.org/licenses/by/3.0/ // Basically use it how you like, but if you do, please include a mention somewhere of me, and if possible a link to the original script. //--------------------------------------------------------------------- // Globals and constants // Configurable string NAME_NOTECARD = "Names"; // Change this if you want to call the notecard with your list of names on it something else. float TIMEOUT = 10.0; // There is no particular reason you would change this but you might wish to perhaps. integer TEST = FALSE; // change to TRUE to just run through the names in your notecard without sending anything // Not configurable - leave these alone key gQuery = NULL_KEY; string gAvName = ""; integer gLine = 0; integer gNumberOfLines = 0; list gItems = []; list gNotFound = []; integer gQuerySource = -1; //--------------------------------------------------------------------- // Functions // Looks for the next name on the list get_next_name() { llSetTimerEvent(TIMEOUT); if (gNumberOfLines == 0) { llSetText("Checking list size", <1.0, 1.0, 0.0>, 1.0); gQuery = llGetNumberOfNotecardLines(NAME_NOTECARD); } else { gQuery = llGetNotecardLine(NAME_NOTECARD, gLine++); update(); } } // Updates the prim display update() { integer line = gLine - 1; integer done = llRound(100 * line / gNumberOfLines); float x = (float)done / 100.0; llSetColor(, ALL_SIDES); llSetText((string)done + "% done (" + (string)line + "/" + (string)gNumberOfLines + ")\nRemaining time: " + time_left(line), <1.0, 1.0, 0.0>, 1.0); } string time_left(integer line) { if (gNumberOfLines == 0) return "unknown"; if (line == 0) { llResetTime(); return "unknown"; } float timePerLine = llGetTime() / line; return minutes_seconds(llRound(timePerLine * (float)(gNumberOfLines - line))); } string minutes_seconds(integer seconds) { if (seconds < 60) return (string)seconds + "s"; integer minutes = seconds / 60; seconds -= minutes * 60; string msg = (string)minutes + "m"; if (seconds > 0) msg += (string)seconds + "s"; return msg; } // This function sends queries to web databases to get keys from names. It moves through a series of different ones based on the current value of gQuerySource - if a query fails, it moves to the next one. I think that three different databases should eventually provide a reasonable result. Note that you can move the databases around according to your preference by cutting and pasting within the "if ... else" blocks. make_key_request(string name) { gAvName = name; llSetTimerEvent(TIMEOUT); gQuerySource++; string source = ""; if (gQuerySource == 0) { // modularsystems.sl name2key service source = "lawlinter.net"; gQuery = llHTTPRequest("http://lawlinter.net/secondlifeutility/name2key.php5?name=" + llEscapeURL(name), [HTTP_METHOD, "GET"], ""); } else if (gQuerySource == 1) { // visiontech - slow, but claims to be complete source = "VisionTech"; name = llDumpList2String(llParseString2List(name, [""], []), "_"); gQuery = llHTTPRequest("http://vision-tech.org/name2key/search.php?name=" + name, [HTTP_METHOD, "GET"], ""); } else if (gQuerySource == 2) { // w-hat source = "w-hat"; gQuery = llHTTPRequest("http://w-hat.com/name2key?terse=1&name=" + llEscapeURL(name), [HTTP_METHOD, "GET"], ""); } if (source == "") { // failed, try a new one llOwnerSay("All sources failed to find a key for '" + gAvName + "', moving on."); gQuerySource = -1; gNotFound = (gNotFound = []) + gNotFound + [gAvName]; get_next_name(); } else if (gQuerySource > 0) { llOwnerSay("Trying " + source + " database..."); } } // Gets all of the items to be sent, and sets text based on what they are list get_item_list() { integer f = llGetInventoryNumber(INVENTORY_ALL) - 1; list items = []; string thisScript = llGetScriptName(); while (f >= 0) { string name = llGetInventoryName(INVENTORY_ALL, f); if (name != ""&& name != thisScript && name != NAME_NOTECARD) { items = (items = []) + items + [name]; } f--; } if (llGetListLength(items) > 0) { string msg = "Sending:\n" + llDumpList2String(items, "\n"); if (TEST) msg = "[TEST] Not " + (msg = "") + msg; llSetText(msg, <0.0, 1.0, 0.0>, 1.0); } else { llSetText("No items found to send", <1.0, 0.0, 0.0>, 1.0); } return items; } // Sends the actual items to a particular avatar send_items(key id) { integer f = llGetListLength(gItems) - 1; llOwnerSay("Giving items..."); while (f >= 0) { string name = llList2String(gItems, f); if (TEST) llSleep(2.0); else llGiveInventory(id, name); f--; } llOwnerSay("Done."); } //--------------------------------------------------------------------- // Main // The default state is "not sending anything right at this moment". default { state_entry() { llSetText("", <0.0, 0.0, 0.0>, 1.0); llSetColor(<1.0, 1.0, 1.0>, ALL_SIDES); gItems = get_item_list(); llOwnerSay(llGetScriptName() + " ready, touch to start sending inventory."); } on_rez(integer p) { llResetScript(); } touch_start(integer n) { if (llGetListLength(gItems) == 0) { llOwnerSay("Nothing suitable in this item's inventory to give!"); } else if (llGetInventoryType(NAME_NOTECARD) == INVENTORY_NONE) { llOwnerSay("You need a notecard called '" + NAME_NOTECARD + "' in this item for it to send its contents to people."); } else { state sending; } } changed(integer change) { if (change & CHANGED_INVENTORY) llResetScript(); } } // In "sending" state, we are actually reading names, finding keys and sending things out. state sending { state_entry() { gNumberOfLines = 0; gLine = 0; gNotFound = []; gQuerySource = -1; llOwnerSay("Beginning send - take into inventory to stop this."); get_next_name(); } on_rez(integer p) { llResetScript(); } dataserver(key query, string data) { if (query != gQuery) return; if (data == EOF) { llOwnerSay("All notecard lines scanned."); state default; } else if (gNumberOfLines == 0) { gNumberOfLines = (integer)data; get_next_name(); } else if (data != "") { make_key_request(data); } else get_next_name(); } http_response(key query, integer status, list metadata, string data) { if (query != gQuery) return; llSetTimerEvent(0.0); key avKey = (key)data; if (llStringLength(data) == 36 && avKey != NULL_KEY) { llOwnerSay("Found key for '" + gAvName + "' : " + (string)avKey); gQuerySource = -1; send_items(avKey); } else { llOwnerSay("ERROR: Could not find avatar name '" + gAvName + "' in database."); make_key_request(gAvName); } get_next_name(); } timer() { llOwnerSay("ERROR: timed out looking for avatar name '" + gAvName + "'."); make_key_request(gAvName); } state_exit() { llOwnerSay("Names not found: " + llList2CSV(gNotFound)); float time = llGetTime(); llOwnerSay("Total time: " + minutes_seconds((integer)time) + " seconds (" + (string)(time / gNumberOfLines) + " seconds per line)."); } }

Viewing all articles
Browse latest Browse all 9

Trending Articles