Table of Contents

ChangeLog

10 October 2011

  • Fixed instant kick bug for Ivory Bouscario as well as several other fixes.

About

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.

Setup

Morgan LeFay
Worf Rozhenko

Limitations

  1. Only the person who created this script is permitted to access the menus.

Code

security_orb.lsl
///////////////////////////////////////////////////////////////////////////
//  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);
    }
}