Welcome to the Second Life Forums Archive

These forums are CLOSED. Please visit the new forums HERE

multiple notecards and a state change

Tobler Ballinger
Registered User
Join date: 6 May 2007
Posts: 14
10-08-2007 21:04
Hello,
I'm having problems with a security system script I'm writing and I was hoping someone could point me in the right direction. The script uses 3 different notecards, Owners, Admins, and Visitors. The owners and admins cards are designed to hold Agent UUID keys while the visitors card uses Avatar names. I'm using the default state to read in the notecards and calling a different state once the contents of all the cards is read.

Can someone possibly give me an idea what would be the most efficient method of determining when all three cards and read and triggering the state change once they are?


On a side note, what would be the best way to determine whether the data on the owners and admins card is in fact a valid Agent key?


any help with either of these issues would be greatly appreciated.

Thanks.
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
10-08-2007 23:59
I'll assume you have all the code to read the cards done... so heres a thought....

add some boolean globals to the top, all false, in your notecard (or just the reader code abusing EOF maybe?) have them set to true

at the end of each notecard read, test for all the globals to be true, if they are, poof, state change

EDIT: on further thought, why not walk each notecard read through a state of it's own, use EOF to or a counter to trigger next state?

as for testing the keys... you can test if it's a valid type like this

if (KeyHolder) KeyIsValid = TRUE;

but it won't tell you if it's a valid AGENT key
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
10-09-2007 01:22
You could either use llGetNumberOfNotecardLines () on the 3 notecards, or you could just look for EOF being returned in the dataserver event which will tell you that you've finished reading that notecard.
_____________________
Tobler Ballinger
Registered User
Join date: 6 May 2007
Posts: 14
10-09-2007 19:13
From: Void Singer


if (KeyHolder) KeyIsValid = TRUE;

but it won't tell you if it's a valid AGENT key



Cool. that does help. I already found a tip in the hacks section on lslwiki for determining if a key is an AGENT. I just needed to know how to make sure a string is a valid key. this will help make sure that at least items in my lists are in fact keys and not random input.
Jesse Barnett
500,000 scoville units
Join date: 21 May 2006
Posts: 4,160
10-09-2007 19:31
From: Tobler Ballinger
Cool. that does help. I already found a tip in the hacks section on lslwiki for determining if a key is an AGENT. I just needed to know how to make sure a string is a valid key. this will help make sure that at least items in my lists are in fact keys and not random input.

Did you see this entry in the script on the "types" wiki page"

if(llStringLength(var) == 36 &&
llGetListLength(llParseStringKeepNulls(var, ["-"], [])) == 5) return TYPE_KEY;


http://lslwiki.net/lslwiki/wakka.php?wakka=types
_____________________
I (who is a she not a he) reserve the right to exercise selective comprehension of the OP's question at anytime.
From: someone
I am still around, just no longer here. See you across the aisle. Hope LL burns in hell for archiving this forum
Tobler Ballinger
Registered User
Join date: 6 May 2007
Posts: 14
10-10-2007 06:28
From: Jesse Barnett
Did you see this entry in the script on the "types" wiki page"

if(llStringLength(var) == 36 &&
llGetListLength(llParseStringKeepNulls(var, ["-"], [])) == 5) return TYPE_KEY;


http://lslwiki.net/lslwiki/wakka.php?wakka=types



Actually no I didn't. The other method is a lot simpler but I can see how it can be fooled by passing it a regular string.



As for my original problem, I poked around a bit deeper on lslwiki and ended up finding a multi-notecard reader. DUH! I'll integrate that and the key validation and give it a go.

Thanks
Void Singer
Int vSelf = Sing(void);
Join date: 24 Sep 2005
Posts: 6,973
10-10-2007 10:11
heh my above example SHOULD HAVE included a typecast before the test... oops?
Tobler Ballinger
Registered User
Join date: 6 May 2007
Posts: 14
10-14-2007 08:12
Ok I've got the notecard reader working by modeling it after the code I found on lslwiki. now for the state change. I've added a simple state the just does an llSay(0,"Done reading notcards";); which I call from a function. The problem is I keep getting the following error when i try to compile/debug in LSLEditor.

'state(string)' is a 'method' but is used as a 'type'


See below for the code as I have it.


//
// Access Lists
list owners;
list admins;
list visitors;

//Notecards
string notecardname1 = "owners"; // System Owners
string notecardname2 = "admins"; // System Admins
string notecardname3 = "visitors"; // Authorized Visitors

// Variables used for reading notecards
string notecardname; // Notecard name
key notecardquery; // Notecard query
list templineslist; // Temp variable to hold notecard contents
integer notecardline; // Notecard line counter
integer templistlength; // Temp variable for length of templineslist



// Begin Custom Functions

// Start Notecard Reader
initialize(string _action) {
if (_action == "";) {
loadNoteCard(notecardname1);
} else if (_action = "finish";) {
integer end = llGetListLength(owners);
integer i;
for (i = 0; i< end; i++) {
llSay(0, llList2String(owners,i));
}
end = llGetListLength(admins);
for (i = 0; i< end; i++) {
llSay(0, llList2String(admins,i));
}
end = llGetListLength(visitors);
for (i = 0; i< end; i++) {
llSay(0, llList2String(visitors,i));
}
state start;
}
}

// Load the first line of the notecard
loadNoteCard( string _notecard ) {
templineslist = []; //clear the temp lines
notecardname = _notecard;
notecardline = 0;
notecardquery = llGetNotecardLine(notecardname, notecardline);

}

// Called when the end of a notecard is reached
notecardFinished(string _notecard){
integer i;
string templistline;

// Notecard 1
if (_notecard == notecardname1) {
templistlength = llGetListLength(owners);
// verify we only load keys into the owners list
for ( i = 0 ; i < templistlength; ++i ) {
templistline = llList2String(owners,i);
if ( GetType(templistline) == 4 ) {
owners += templistline;
}
}

// Load the next card
loadNoteCard(notecardname2);
} else if (_notecard == notecardname2) {
templistlength = llGetListLength(admins);
// verify we only load keys into the owners list
for ( i = 0 ; i < templistlength; ++i ) {
templistline = llList2String(admins,i);
if ( GetType(templistline) == 4 ) {
owners += templistline;
}
}

// Load the next card
loadNoteCard(notecardname3);
} else if (_notecard == notecardname3) {
templistlength = llGetListLength(visitors);
for ( i = 0 ; i < templistlength ; ++i ) {
templistline = llList2String(visitors,i);
if ( GetType(templistline) == 3 ) {
visitors += templistline;
}
}
initialize("finish";);
}
}

// Function to verify variable types
integer GetType(string var)
integer n = llGetListLength(llParseStringKeepNulls(var, ["1", "2", "3", "4"], [])) - 1;
n += llGetListLength(llParseStringKeepNulls(var, ["5", "6", "7", "8"], [])) - 1;
n += llGetListLength(llParseStringKeepNulls(var, ["9", "0", ".", "<"], [])) - 1;
n += llGetListLength(llParseStringKeepNulls(var, [">", " ", ",", "-"], [])) - 1;
if(n == llStringLength(var))
{
if(llSubStringIndex(var, "<";) != -1 || llSubStringIndex(var, ">";) != -1)
{
if(llGetListLength(llParseStringKeepNulls(var, [","], [])) == 3) {
return TYPE_VECTOR;
} else {
return TYPE_ROTATION;
}
} else {
if(llSubStringIndex(var, ".";) != -1) {
return TYPE_FLOAT;
} else {
return TYPE_INTEGER;
}
}
} else {
if(llStringLength(var) == 36 && llGetListLength(llParseStringKeepNulls(var, ["-"], [])) == 5) {
return TYPE_KEY;
} else {
return TYPE_STRING;
}
}
}

default
{
//integer i;
state_entry()
{
// numnotecards = llGetListLength(notecards);
initialize("";);
}

dataserver(key _query_id , string _data)
{
if (_query_id == notecardquery) {
// this is a line of our notecard
if (_data != EOF) {
// increment line count
templineslist += [_data];
//request a next line
notecardline++;
notecardquery = llGetNotecardLine(notecardname, notecardline);
} else {
//The notecard has been read
//notify end of read
notecardFinished(notecardname);
}
}
}
}

state start
{
state_entry()
{
llSay(0,"Done";);
}
}


// end code


I don't see a problem but it will not compile. if I remove the call to change states it works and reads the notecards placing the contents into 3 separate lists.

What am I missing?
Stephen Zenith
Registered User
Join date: 15 May 2006
Posts: 1,029
10-14-2007 08:23
Seem to be missing a { after "integer GetType(string var)"
_____________________
Tobler Ballinger
Registered User
Join date: 6 May 2007
Posts: 14
10-14-2007 15:29
From: Stephen Zenith
Seem to be missing a { after "integer GetType(string var)"



Thanks for pointing that out. I checked the code and the { IS there. I just missed it while posting the code here.
Tobler Ballinger
Registered User
Join date: 6 May 2007
Posts: 14
10-15-2007 16:44
FYI I figured out my state problem. I was calling it incorrectly. I changed the state call to read:

state("start";); and everything is working fine.

EDIT: This is actually an inconsistency between the SL Script Editor and LSLEditor :). LSLEditor also allows a state change in a global function whereas the SL Script Editor requires something along the lines of:

if ( 1==1 ) {
state start;
}

in order to to change state within a global function.
Gwylym Loon
Registered User
Join date: 6 Jun 2007
Posts: 81
01-24-2008 14:44
Anyone notice that this code as it stands will not do what is expected? First, templineslist is never used to load the information into the owners, admins or visitors lists. Also, the setting of "finished" happens at the wrong time so the notecard finished function is called too soon to set the owners, admins and visitors lists.

Is there a better example of this type of reading of notecards and making sure all of the notecards are read in before the script does any kind of processing?

Thanks.
Hewee Zetkin
Registered User
Join date: 20 Jul 2006
Posts: 2,702
01-24-2008 16:54
This hasn't been compiled and tested, but I've written tons and tons of them just like this, so it should be pretty close if it doesn't compile and work already.

CODE

string OWNER_NOTECARD = "owners";
string ADMIN_NOTECARD = "admins";
string VISITOR_NOTECARD = "visitors";

list owners = [];
integer nextOwnerLine = 0;
key ownerNoteLineQuery = NULL_KEY;

list admins = [];
integer nextAdminLine = 0;
key adminNoteLineQuery = NULL_KEY;

list visitors = [];
integer nextVisitorLine = 0;
key visitorNoteLineQuery = NULL_KEY;


state default
{
state_entry()
{
ownerNoteLineQuery = llGetNotecardLine(OWNER_NOTECARD, nextOwnerLine);
adminNoteLineQuery = llGetNotecardLine(ADMIN_NOTECARD, nextAdminLine);
visitorNoteLineQuery = llGetNotecardLine(VISITOR_NOTECARD, nextVisitorLine);
}

dataserver(key requestId, string data)
{
if (requestId == ownerNoteLineQuery)
{
if (data == EOF)
{
nextOwnerLine = -1;
ownerNoteLineQuery = NULL_KEY;
} else
{
owners = (owners=[])+owners+[ data ];
++nextOwnerLine;
ownerNoteLineQuery = llGetNotecardLine(OWNER_NOTECARD, nextOwnerLine);
}
} else if (requestId == adminNoteLineQuery)
{
if (data == EOF)
{
nextAdminLine = -1;
adminNoteLineQuery = NULL_KEY;
} else
{
admins = (admins=[])+admins+[ data ];
++nextAdminLine;
adminNoteLineQuery = llGetNotecardLine(ADMIN_NOTECARD, nextAdminLine);
}
} else if (requestId == visitorNoteLineQuery)
{
if (data == EOF)
{
nextVisitorLine = -1;
visitorNoteLineQuery = NULL_KEY;
} else
{
visitors = (visitors=[])+visitors+[ data ];
++nextVisitorLine;
visitorNoteLineQuery = llGetNotecardLine(VISITOR_NOTECARD, nextVisitorLine);
}
} else
{
return;
}

if (nextOwnerLine < 0 && nextAdminLine < 0 && nextVisitorLine < 0)
{
state configured;
}
}
}

state configured
{
state_entry()
{
// do stuff
}
}