TBF Security Cube

Written by Kitsune
// ~ NOTES ~

// Licence

// Restricted land access script by Arduenn Schwartzman
// Licenced according to the following Creative Commons terms:
// Attribution-NonCommercial-ShareAlike 3.0 Unported
// http://creativecommons.org/licenses/by-nc-sa/3.0/

// Version changes

// v0.1 - Created 3/6/2013 by Arduenn
// v0.2 - By Arduenn:
//        Reads guest list from notecard.
//        The names from the list are handled case-insensitive.
//        Tidied up the script comments.

// Caveats

// IMPORTANT! If an agent is not on the guest list
// and happens to sit on an object that is owned by that agent,
// the object will be ejected too. If that object happens to
// be 'No Copy', it will be gone forever! This is a dangerous
// toy. People may Abuse Report you if this is not set up
// properly. The original maker cannot be held liable for any
// damage suffered from using this security script.



// ~ ADVANCED SETTINGS ~

// Scanning boundaries

// 'BOUNDARY_LOW=<0,0,1000>;' and 'BOUNDARY_HIGH=<256,256,2000>;'
// means: Restrict access from 1000 to 2000 meter altitude.

vector BOUNDARY_LOW=<0,0,0>;

vector BOUNDARY_HIGH=<256,256,200>;

// Time between warning and ejection (seconds)

float EJECT_TIME=20;

// Warning message

string WARNING="\nWARNING\n\nYou have entered a restricted area. You will be ejected in 20 seconds.\n";

// Scanning type

// Use 'integer SCANNING_TYPE=AGENT_LIST_PARCEL;' to scan people in this parcel.
// Use 'integer SCANNING_TYPE=AGENT_LIST_PARCEL_OWNER;' to scan people in all
// parcels in this sim, owned by the owner of this device
// Use 'integer SCANNING_TYPE=AGENT_LIST_REGION;' to scan the entire region:

integer SCANNING_TYPE=AGENT_LIST_PARCEL;



// ~ GLOBAL VARIABLES ~

list GUEST_LIST;

list BAN_LIST;

list NAMES;

string FILE;

integer LINE;

key QUERY;



// ~ FUNCTIONS ~

// Fancy settings for the radar box-like prim included with this
// awesome security orb cube thing
uEffectsOff(){
    llTriggerSound("35a93da0-674d-125c-b62c-b89dccc02bbb",1);
    llOwnerSay("Check your guest list (see notecard inside) before turning on this device.");
    llOwnerSay("Click to turn on. Security is now turned OFF.");
    llSetLinkTextureAnim(LINK_SET,ROTATE,2,0,0,0,0,0);
    llSetLinkPrimitiveParamsFast(LINK_THIS,[
        PRIM_COLOR,2,<0,0,0>,0,
        PRIM_GLOW,2,0,
        PRIM_LINK_TARGET,LINK_THIS,
        PRIM_COLOR,1,<0,0,0>,1
    ]);
}

uEffectsOn(){
    llTriggerSound("35a93da0-674d-125c-b62c-b89dccc02bbb",1);
    llOwnerSay("Click to turn off. Security is now turned ON.");
    llSetLinkTextureAnim(LINK_THIS,ANIM_ON|SMOOTH|ROTATE|LOOP,2,1,1,0,2*PI,-2*PI);
    llSetLinkPrimitiveParamsFast(LINK_THIS,[
        PRIM_COLOR,2,<0,.5,0>,.5,
        PRIM_GLOW,2,.1,
        PRIM_LINK_TARGET,LINK_THIS,
        PRIM_COLOR,1,<0,1,0>,1
    ]);
}

uNotecard(){
    FILE=llGetInventoryName(INVENTORY_NOTECARD,0);
    QUERY=llGetNotecardLine(FILE,LINE);
}

uGuestList(string NAME){
    integer SIZE=llStringLength(NAME);
    if(SIZE>0){
        integer INDEX=llSubStringIndex(NAME,".");
        if(INDEX>=0){
            string FIRST=llGetSubString(NAME,0,INDEX-1);
            string LAST=llGetSubString(NAME,INDEX+1,SIZE-1);
            NAME=FIRST+" "+LAST;
        }
        INDEX=llSubStringIndex(NAME," ");
        if(INDEX<0)NAME+=" resident";
        GUEST_LIST+=[llToLower(NAME)];
    }
    LINE++;
    uNotecard();
}

list uBanList(){
    key KEY;
    vector P;
    list LIST;
    string NAME;
    list PARAMS;
    integer INDEX;
    vector L=BOUNDARY_LOW;
    vector H=BOUNDARY_HIGH;
    list KEYS=llGetAgentList(SCANNING_TYPE,[]);
    integer COUNT=llGetListLength(KEYS);
    for(INDEX=0;INDEXL.x&P.xL.y&P.yL.z&P.z=0){
            llEjectFromLand(KEY);
        }
    }
}



// ~ PROCEDURE ~

 default{
    state_entry(){
        llOwnerSay("Reading guest list ...");
        uNotecard();
    }
    dataserver(key Q,string NAME){
        if(Q==QUERY){
            if(NAME!=EOF){
                uGuestList(NAME);
            }else{
                llOwnerSay("Guest list read.");
                state off;
            }
        }
    }
    changed(integer C) {
        if (C&CHANGED_INVENTORY){
            llOwnerSay("Inventory changed. Resetting...");
            llResetScript();
        }
    }
}

state off{
    state_entry(){
        uEffectsOff();
    }
    touch_end(integer P){
        if(llDetectedKey(0)==llGetOwner()){
            uEffectsOn();
            state on;
        }
    }
    on_rez(integer P){
        llResetScript();
    }
    changed(integer C) {
        if (C&CHANGED_INVENTORY){
            llOwnerSay("Inventory changed. Resetting...");
            llResetScript();
        }
    }
}

state on{
    state_entry(){
        BAN_LIST=[];
        GUEST_LIST+=[llKey2Name(llGetOwner())];
        llSetTimerEvent(10);
    }
    touch_end(integer P){
        if(llDetectedKey(0)==llGetOwner())state off;
    }
    timer(){
        BAN_LIST=uBanList();
        integer COUNT=llGetListLength(BAN_LIST);
        if(COUNT>0){
            llSetTimerEvent(0);
            state eject;
        }
    }
    on_rez(integer P){
        llResetScript();
    }
    changed(integer C) {
        if (C&CHANGED_INVENTORY){
            llOwnerSay("Inventory changed. Resetting...");
            llResetScript();
        }
    }
}

state eject{
    state_entry(){
        uWarn();
        llSetTimerEvent(EJECT_TIME);
    }
    timer(){
        llSetTimerEvent(0);
        uEject();
        state on;
    }
    on_rez(integer P){
        llResetScript();
    }
    changed(integer C) {
        if (C&CHANGED_INVENTORY){
            llOwnerSay("Inventory changed. Resetting...");
            llResetScript();
        }
    }
}