10 October 2011
This is a simple security orb to use in your home or on your land to automatically eject people who are not on a white list. It allows changing the distance, frequency of the scans and also setting a custom warning message via a dialog menu.
Morgan LeFay Worf Rozhenko
/////////////////////////////////////////////////////////////////////////// // Copyright (C) Wizardry and Steamworks 2011 - License: GNU GPLv3 // // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // // rights of fair usage, the disclaimer and warranty conditions. // /////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////// // CONFIGURATION // ////////////////////////////////////////////////////////// // // // All options are settable by touching the object. // // These are the defaults and also used internally for // // the security orb once it is reset. You may modify // // them. // ////////////////////////////////////////////////////////// // The default message a visitor will get if they are not // allowed to be on the parcel of land where the security // orb is currently placed. string EJECT_MESSAGE = "Hello, we are sorry but this land is private and you will be ejected unless you leave. Thank you!"; // The range in meters that the security orb will scan for // people to eject off your land parcel. integer RANGE = 20; // Kick after this number of seconds. integer KICK_SECONDS = 10; // Set a predefined scanning interval, by default it is // set to 4 seconds. integer SCAN_INTERVAL = 4; ////////////////////////////////////////////////////////// // // // END CONFIGURATION // ////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////// // INTERNALS // /////////////////////////////////////////////////////////////////////////// integer gItra = 0; list wList = []; list eList = []; key wQuery = NULL_KEY; integer comHandle; integer setHandle; default { state_entry() { wList = []; eList = []; gItra = 0; integer itra = llGetInventoryNumber(INVENTORY_NOTECARD)-1; do { if(llGetInventoryName(INVENTORY_NOTECARD, itra) == "Whitelist") jump found_notecard; } while(--itra>0); llSay(DEBUG_CHANNEL, "Failed to find Whitelist notecard in inventory. Please add a notecard Whitelist and configure the script."); return; @found_notecard; wQuery = llGetNotecardLine("Whitelist", gItra); llSetTimerEvent(1); } changed(integer change) { if(change & CHANGED_INVENTORY) llResetScript(); } timer() { if(!llGetListLength(eList)) { llSetTimerEvent(0); return; } integer itra; integer cTime = llGetUnixTime(); for(itra=0; itra<llGetListLength(eList); itra+=2) { if(cTime - llList2Integer(eList, itra+1) > KICK_SECONDS) { llEjectFromLand(llList2Key(eList, itra)); eList = llDeleteSubList((eList = []) + eList, itra, itra+1); } } llSetTimerEvent(1); } touch_start(integer num_detected) { if(llDetectedKey(0) != llGetCreator()) return; integer comChannel = ((integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; comHandle = llListen(comChannel, "", llGetCreator(), ""); llDialog(llGetCreator(), "Welcome to the security orb configuration, please select from the following options.\n", [ "Warning", "Scanning", "Range" ], comChannel); } listen(integer channel, string name, key id, string message) { if(channel == gItra) { llListenRemove(setHandle); EJECT_MESSAGE = message; llInstantMessage(llGetCreator(), "The eject message is now set to: " + EJECT_MESSAGE); return; } if(message == "Warning") { llListenRemove(comHandle); gItra = 1 + (integer)llFrand(100); llInstantMessage(llGetCreator(), "Please type the message trespassers will get before they are ejected on the channel " + (string)gItra + " for example, by typing: /" + (string)gItra + " Hello, we are sorry but this land is private and you will be ejected unless you leave. Thank you!"); setHandle = llListen(gItra, "", llGetCreator(), ""); return; } if(message == "Scanning") { llListenRemove(comHandle); integer comChannel = ((integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; comHandle = llListen(comChannel, "", llGetCreator(), ""); llDialog(llGetCreator(),"\nPlease select a scanning interval in seconds.\n",["2s","4s","8s", "16s", "32s", "64s"],comChannel); return; } if(message == "Range") { llListenRemove(comHandle); integer comChannel = ((integer)("0x"+llGetSubString((string)llGetKey(),-8,-1)) & 0x3FFFFFFF) ^ 0xBFFFFFFF; comHandle = llListen(comChannel, "", llGetCreator(), ""); llDialog(llGetCreator(),"\nPlease select a scanning range in meters.\n",["5","10","15","30","35","40","45","50","60","70","80","90"],comChannel); return; } if((integer)message%5 == 0) { llListenRemove(comHandle); RANGE = (integer)message; llSensorRemove(); llSensorRepeat("", NULL_KEY, AGENT, RANGE, TWO_PI, 4); return; } if((integer)message && !((integer)message & ((integer)message-1))) { llListenRemove(comHandle); SCAN_INTERVAL = (integer)message; llSensorRemove(); llSensorRepeat("", NULL_KEY, AGENT, RANGE, TWO_PI, SCAN_INTERVAL); return; } } sensor(integer num) { --num; do { if(~llListFindList(wList, (list)llDetectedName(num)) || llDetectedKey(num) == llGetCreator() || ~llListFindList(eList, (list)llDetectedKey(num))) jump continue; llDialog(llDetectedKey(num), EJECT_MESSAGE, [], (integer)llFrand(-500)-1); eList += llDetectedKey(num); eList += llGetUnixTime(); llSetTimerEvent(1); @continue; } while(--num>-1); } dataserver(key query_id, string data) { if(query_id != wQuery) return; if(data == EOF) { llSensorRepeat("", NULL_KEY, AGENT, RANGE, TWO_PI, SCAN_INTERVAL); return; } if(data == "") jump next_access; wList += (list) data; @next_access; wQuery = llGetNotecardLine("Whitelist", ++gItra); } }