Creative Commons License Machine/Kiosk Script
The kiosk is actually just a general purpose state machine engine. The particular state machine that is used for the Creative Commons LIcense Machine is in the Creative Commons License Machine/Kiosk Program.
<lsl> key gBlankTexture = "5748decc-f629-461c-9a36-a35a221fe21f"; // well known
float gTimeOut = 60.0;
integer gUserListener = 0;
integer gLicenseChannel = 0; integer gLicenseListener = 0;
string gNode; list gPath;
// path of nodes, including current node at the end
key gUser = NULL_KEY;
// user we are interacting with
list gParams;
// user parameters, stride two: [ <key>, <value> ... ]
string gAltTrigger; key gArgID; string gArgMessage;
clearUse()
{
gNode = ""; gPath = [ ]; gUser = NULL_KEY; gParams = [ ]; clearNode();
}
clearNode() {
gTimeOut = 30.0;
}
cmdGo(string node) {
gNode = node; gPath += [ node ]; llMessageLinked(LINK_THIS, 200, node, NULL_KEY); clearNode(); runAnyAction("init", "", NULL_KEY, ""); llSetTimerEvent(gTimeOut); if (gUserListener) { llListenRemove(gUserListener); } gUserListener = llListen(0, "", gUser, "");
}
cmdReset() {
clearUse(); cmdGo("start");
}
cmdBack() {
integer n = llGetListLength(gPath); if (n >= 2) { string node = llList2String(gPath, -2); gPath = llDeleteSubList(gPath, -2, -1); cmdGo(node); } else { cmdReset(); }
}
cmdUser(key id)
{
gUser = id;
}
cmdAnyone() {
gUser = NULL_KEY;
}
cmdTimeOut(float t) {
gTimeOut = t;
}
cmdImage(string inv) {
llSetTexture(inv, 0);
}
cmdSay(string text) {
llSay(0, text);
}
cmdMovie() { }
cmdGive(string inv) {
llGiveInventory(gUser, inv);
}
cmdWebsite() {
llLoadURL(gUser, "View the Creative Commons web site.", "http://creativecommons.org/");
}
cmdSet(string param, string value)
{
integer i = llListFindList(gParams, [ param ]); if (i < 0) { gParams += [ param, value ]; } else { gParams = llListReplaceList(gParams, [ value ], i + 1, i + 1); }
}
cmdSetUser(string param) {
cmdSet(param, llKey2Name(gUser));
}
cmdSetNow(string param) {
cmdSet(param, llGetSubString(llGetDate(), 0, 3));
}
string getParam(string param) {
integer i = llListFindList(gParams, [ param ]); if (i < 0) return ""; return llList2String(gParams, i + 1);
}
cmdReport(string param, string prompt) {
string value = getParam(param); if (value == "") return; llSay(0, prompt + value);
}
cmdLicenseImage() {
string commercialUse = getParam("commercial-use"); string modifications = getParam("modifications"); string license = "by"; if (commercialUse == "no") { license += "-nc"; } if (modifications == "no") { license += "-nd"; } if (modifications == "share") { license += "-sa"; } string imageName = "lic-" + license; cmdImage(imageName); cmdSet("image-key", llGetInventoryKey(imageName));
}
cmdLicenseRez() {
gLicenseChannel = 10000000 + (integer)llFrand(10000000.0); gLicenseListener = llListen(gLicenseChannel, "", NULL_KEY, ""); rotation r = llEuler2Rot(<0, -45, 0> * DEG_TO_RAD) * llGetRot(); llRezObject("badge", llGetPos() + <-0.358, 0.0, 0.523> * r, ZERO_VECTOR, r, gLicenseChannel);
}
finishLicense() {
llListenRemove(gLicenseListener); integer n = llGetListLength(gParams); integer i; for (i = 0; i < n; i += 2) { string param = llList2String(gParams, i); string value = llList2String(gParams, i + 1); llSay(gLicenseChannel, param + ":" + value); } rotation r = llEuler2Rot(<0, -45, 0> * DEG_TO_RAD) * llGetRot(); vector p = llGetPos() + <-0.358, 0.0, 0.761> * r; llSay(gLicenseChannel, "done " + (string)p);
}
cmdLicenseDie() {
if (gLicenseChannel != 0) { llSay(gLicenseChannel, "die"); gLicenseChannel = 0; }
}
executeStatement(string statement)
{
integer sep = llSubStringIndex(statement, "|"); string tail = ""; if (sep >= 1) { tail = llGetSubString(statement, sep + 1, -1); statement = llGetSubString(statement, 0, sep - 1); } list parts = llParseString2List(statement, [ " " ], [ ]); if (tail != "") { parts += [ tail ]; } string cmd = llList2String(parts, 0); string arg1 = llList2String(parts, 1); string arg2 = llList2String(parts, 2); if (arg2 == "*") { arg2 = gArgMessage; } if (cmd == "back") { cmdBack(); } else if (cmd == "go") { cmdGo(arg1); } else if (cmd == "reset") { cmdReset(); } else if (cmd == "user") { cmdUser(gArgID); } else if (cmd == "anyone") { cmdAnyone(); } else if (cmd == "timeout") { cmdTimeOut((float)arg1); } else if (cmd == "image") { cmdImage(arg1); } else if (cmd == "say") { cmdSay(arg1); } else if (cmd == "movie") { cmdMovie(); } else if (cmd == "give") { cmdGive(arg1); } else if (cmd == "website") { cmdWebsite(); } else if (cmd == "set") { cmdSet(arg1, arg2); } else if (cmd == "setUser") { cmdSetUser(arg1); } else if (cmd == "setNow") { cmdSetNow(arg1); } else if (cmd == "report") { cmdReport(arg1, arg2); } else if (cmd == "licenseImage") { cmdLicenseImage(); } else if (cmd == "licenseRez") { cmdLicenseRez(); } else if (cmd == "licenseDie") { cmdLicenseDie(); } else { llOwnerSay("Unknown command: " + cmd); }
}
executeBlock(string block) {
list statements = llParseString2List(block, [ " ; ", " ;", "; ", ";" ], [ ]); integer n = llGetListLength(statements); integer i; for (i = 0; i < n; ++i) { executeStatement(llList2String(statements, i)); }
}
runAnyAction(string trigger, string altTrigger, key id, string message) {
gAltTrigger = altTrigger; gArgID = id; gArgMessage = message; llMessageLinked(LINK_THIS, 300, trigger, NULL_KEY);
}
default
{
state_entry() { llSetTexture(gBlankTexture, 0); llOwnerSay("Touch to start up."); } touch_start(integer n) { if (llDetectedKey(0) == llGetOwner()) { state readProgram; } else { llSay(0, "This kiosk is under construction."); } }
}
state readProgram {
state_entry() { llSetTexture(gBlankTexture, 0); llMessageLinked(LINK_THIS, 100, "", NULL_KEY); } state_exit() { llOwnerSay("main memory: " + (string)llGetFreeMemory()); }
link_message(integer sender, integer num, string str, key id) { if (num == 101) { state run; } } touch_start(integer n) { } on_rez(integer n) { llResetScript(); }
}
state run {
state_entry() { cmdReset(); } state_exit() { llSetTimerEvent(0.0); } touch_start(integer n) { key id = llDetectedKey(0); if (gUser != NULL_KEY && gUser != id) { return; } runAnyAction("touch", "", id, ""); llSetTimerEvent(gTimeOut); } listen(integer ch, string who, key id, string message) { if (ch != 0 && ch == gLicenseChannel) { finishLicense(); return; } string trigger = "\"" + llToLower(message) + "\""; runAnyAction(trigger, "listen", id, message); llSetTimerEvent(gTimeOut); }
changed(integer what) { if (what & CHANGED_INVENTORY) { state readProgram; } } link_message(integer sender, integer num, string str, key id) { if (num == 301) { executeBlock(str); } else if (num == 399) { if (gAltTrigger != "") { llMessageLinked(LINK_THIS, 300, gAltTrigger, NULL_KEY); gAltTrigger = ""; } } }
timer() { cmdReset(); } on_rez(integer n) { llResetScript(); }
} </lsl>