Security Orb

From Second Life Wiki
Jump to: navigation, search

Created by Kira Komarov.

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

  • Create a notecard called Whitelist and add all the avatar names you wish to allow on the land parcel where the security orb will be placed. For example, to allow Kira Komarov and Worf Rozhenko access to the parcel, create a notecard called Whitelist containing:
Kira Komarov
Worf Rozhenko
  • Add this notecard to a primitive and deed the primitive to the group that owns the land (if the land is not owned by a group, create a group and deed it).
  • Copy the script below and add it to the primitive you previously made which contains the notecard and is deeded to the group that owns the land.
  • [Optional] You can modify settings via a menu by touching the primitive this script resides in. Alternatively, you can make these settings permanent by editing the script manually and changing them in the "Configuration" section.

Limitations

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

Code

//////////////////////////////////////////////////////////
// [K] Kira Komarov - 2011, License: GPLv3              //
// Please see: http://www.gnu.org/licenses/gpl.html     //
// for legal details, rights of fair usage and          //
// 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()
    {
        integer itra;
        for(itra=0, wList=[], eList=[], gitra=0; itra<llGetInventoryNumber(INVENTORY_NOTECARD); ++itra) {
            if(llGetInventoryName(INVENTORY_NOTECARD, itra) == "Whitelist")
                jump found_list;
        }
        return;
@found_list;
        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_detected) {
        integer itra;
        for(itra=0; itra<num_detected; ++itra) {
            if(~llListFindList(wList, (list)llDetectedName(itra)) || llDetectedKey(itra) == llGetCreator() || ~llListFindList(eList, (list)llDetectedKey(itra))) jump continue;
            llDialog(llDetectedKey(itra), EJECT_MESSAGE, [], (integer)llFrand(-500)-1);
            eList += llDetectedKey(itra);
            eList += llGetUnixTime();
            llSetTimerEvent(1);
@continue;
        }
    }
 
    dataserver(key query_id, string data) {
        if(query_id == wQuery) {
            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);
        }
    }
}