Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

Locking Door w/Access List

Knotter Thor
Registered User
Join date: 21 Jun 2008
Posts: 21
08-06-2008 04:04
I'm looking for a way to lock my doors with an access list of people who are allowed to open/close them, I can't seem to find any. Maybe it's just what I'm searching, but I don't can't find something good.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
08-06-2008 14:14
Here's one. Features:

* Walks you the owner through configuration.
* Retains relative offsets (position and rotation) after linking/unlinking.
* Owner double-clicks to reset (requires re-configuring).
* Name-based access list notecard (re-reads automatically on change/replace).
* Static in-script list of names always allowed despite notecard existence and contents.

EDIT: Oh. Because this is a basic script with a dirt-simple user interface, it does NOT do the following:

* Open for avatars not in the current sim.
* Have an all-open unlocked state where anyone can open/close it.
* Modify the door prim in any way other than position and rotation (no hollowing, scaling, etc.).

It might be a good practice in scripting to change some of those.

CODE

//// Constants

// A double-click resets the object and forces it to restart configuration
float DOUBLE_CLICK_TIMEOUT = 0.3;

// Set to "" if an access notecard will not be used
string ACCESS_NOTECARD = "AccessList";

// Set to 0.0 if the door shouldn't close on its own
float CLOSE_DELAY = 3.0;

// Add names here and/or to the notecard identified by ACCESS_NOTECARD
list AUTH_USERS = [];


//// Variables

vector closedPos = ZERO_VECTOR;
rotation closedRot = ZERO_ROTATION;
vector openPosOffset = ZERO_VECTOR;
rotation openRotOffset = ZERO_ROTATION;

list authorizedUserNames = AUTH_USERS;

integer nextNoteLine = -1;
key noteLineRequest = NULL_KEY;

integer openConfigured = FALSE;
integer closeConfigured = FALSE;

integer waitingForDoubleClick = FALSE;

integer currentlyOpen = FALSE;


//// Functions

printHelp()
{
if (!closeConfigured)
{
llOwnerSay("Please place door in closed position, then touch.");
} else if (!openConfigured)
{
llOwnerSay("Please place door in open position, then touch.");
} else
{
llOwnerSay("Reading authorization list....");
}
}

initializeNotecardRead()
{
if (ACCESS_NOTECARD != "" &&
llGetInventoryType(ACCESS_NOTECARD) == INVENTORY_NOTECARD)
{
nextNoteLine = 0;
noteLineRequest = llGetNotecardLine(ACCESS_NOTECARD, nextNoteLine);
}
}

touchConfig()
{
if (!closeConfigured)
{
closedPos = llGetLocalPos();
closedRot = llGetLocalRot();
closeConfigured = TRUE;
openConfigured = FALSE;
currentlyOpen = FALSE;

llOwnerSay("Closed position configured.");
} else if (!openConfigured)
{
openPosOffset = (llGetLocalPos()-closedPos)/closedRot;
openRotOffset = llGetLocalRot()/closedRot;
openConfigured = TRUE;
currentlyOpen = TRUE;

llOwnerSay("Open position configured.");
}
}

integer configComplete()
{
return openConfigured && closeConfigured && (nextNoteLine < 0);
}

integer authorized(key user)
{
if (user == llGetOwner())
{
return TRUE;
}

string userName = llKey2Name(user);
return llListFindList(authorizedUserNames, [ userName ]) >= 0;
}

open()
{
if (currentlyOpen)
{
return;
}

rotation currRot = llGetLocalRot();
vector pos = llGetLocalPos()+openPosOffset*currRot;
rotation rot = openRotOffset*currRot;
if (llGetLinkNumber() > 1)
{
rot /= llGetRootRotation();
}
llSetPrimitiveParams([ PRIM_POSITION, pos, PRIM_ROTATION, rot ]);

currentlyOpen = TRUE;

llSetTimerEvent(CLOSE_DELAY);
}

close()
{
if (!currentlyOpen)
{
return;
}

llSetTimerEvent(0.0);

rotation rot = (ZERO_ROTATION/openRotOffset)*llGetLocalRot();
vector pos = llGetLocalPos()-openPosOffset*rot;
if (llGetLinkNumber() > 1)
{
rot /= llGetRootRotation();
}
llSetPrimitiveParams([ PRIM_POSITION, pos, PRIM_ROTATION, rot ]);

currentlyOpen = FALSE;
}

toggleOpenState()
{
if (currentlyOpen)
{
close();
} else
{
open();
}
}


//// States

default
{
state_entry()
{
initializeNotecardRead();

if (configComplete())
{
state operating;
} else
{
printHelp();
}
}

on_rez(integer startParam)
{
printHelp();
}

changed(integer changes)
{
if (changes & CHANGED_OWNER)
{
printHelp();
}

if (changes & CHANGED_INVENTORY)
{
authorizedUserNames = AUTH_USERS;
initializeNotecardRead();

if (configComplete())
{
state operating;
}
}
}

touch_start(integer nDetected)
{
key owner = llGetOwner();
integer i;
for (i = 0; i < nDetected; ++i)
{
if (llDetectedKey(i) == owner)
{
float time = llGetTime();
if (waitingForDoubleClick)
{
llResetScript();
} else
{
waitingForDoubleClick = TRUE;
llSetTimerEvent(DOUBLE_CLICK_TIMEOUT);
}

return;
}
}
}

timer()
{
llSetTimerEvent(0.0);

if (waitingForDoubleClick)
{
waitingForDoubleClick = FALSE;

touchConfig();
if (configComplete())
{
state operating;
} else
{
printHelp();
}
}
}

dataserver(key request, string data)
{
if (request != noteLineRequest)
{
return;
}
noteLineRequest = NULL_KEY;

if (data == EOF)
{
llOwnerSay("Authorization list loaded.");

nextNoteLine = -1;
if (configComplete())
{
state operating;
} else
{
return;
}
}

string name;

integer commentStart = llSubStringIndex(data, "#");
if (commentStart > 0)
{
name = llGetSubString(data, 0, commentStart-1);
} else if (commentStart == 0)
{
name = "";
} else
{
name = data;
}
name = llStringTrim(name, STRING_TRIM);

if (name != "")
{
authorizedUserNames =
(authorizedUserNames=[])+authorizedUserNames+
[ name ];
}

++nextNoteLine;
noteLineRequest = llGetNotecardLine(ACCESS_NOTECARD, nextNoteLine);
}
}

state operating
{
state_entry()
{
llOwnerSay("Door configured.");
}

changed(integer changes)
{
if (changes & CHANGED_INVENTORY)
{
state default;
}
}

touch_start(integer nDetected)
{
key owner = llGetOwner();
integer nToggles = 0;

integer i;
for (i = 0; i < nDetected; ++i)
{
key id = llDetectedKey(i);

if (waitingForDoubleClick)
{
if (id == owner)
{
llResetScript();
}
} else if (id == owner)
{
waitingForDoubleClick = TRUE;
llSetTimerEvent(DOUBLE_CLICK_TIMEOUT);
return;
} else if (authorized(id))
{
++nToggles;
}
}

if (nToggles%2 != 0)
{
toggleOpenState();
}
}

timer()
{
llSetTimerEvent(0.0);

if (waitingForDoubleClick)
{
waitingForDoubleClick = FALSE;
toggleOpenState();
} else
{
close();
}
}
}