Hi there, i'm a SL player and LSL scripter named
Christophe003 Carter (please, call me Carla).
Welcome to my page ^.^
I'm working on an open-source database scripted in LSL. Here's the current status: Last updated on 2009/03/29 (2)
// open-source database script by Christophe003 Carter
// This was never tested, so I'm not sure if it even works.
// requires mono compilation
// All included functions work fine.
// There's no multi-column search yet. Coming soon!
// list datatables: tablekey,tableName,NumberOfFields,fieldName1,fieldName2, ...
// list data: tablekey,datakey,fieldName,data,tablekey2,datakey2,fieldName2,data2
list datatables;
list data;
integer tablekeygen = 0;
integer datakeygen = 0;
// This function is finished!
list dataRequest(list search) // list search: [tablekey, fieldName, searchfordata]
// (required) (required) (optional,partial match)
// This is a query limited to searching one column (very limited)
{
list cdata = data;
list found;
@dataRequestLoop;
integer chk = llListFindList(cdata, [(key)llList2String( search, 0 )] );
if( chk == -1 )
{
jump dataRequestDone;
}
else
{
list tcdata = llList2List( cdata, chk, chk + 3 );
if( llList2String( data, chk + 2 ) == llList2String( search, 1 ) ) // Fieldname matches
{
if( llList2String( search, 2 ) == "" ) // no "searchfordata" input
{
found += llList2String( tcdata, chk + 3 );
}
else
{
if( llSubStringIndex( llList2String( tcdata, chk + 3 ) , llList2String( search, 2 ) ) != -1 )
{
found += llList2String( tcdata, chk + 3 );
}
}
}
llDeleteSubList(cdata, chk, chk + 3 ); // Delete the part searched this far
// SL's findlist would only return the first match in the list, otherwise
}
jump dataRequestLoop;
@dataRequestDone;
return found;
}
// This function is finished!
key tableKey(string tblName)
{
integer pos = llListFindList( datatables, [tblName] );
return llList2String( datatables, pos - 1 );
}
// This function isis finished!
integer dataInput(key tablekey, list data) // Boolean (TRUE if succeeded, FALSE if failed)
{
integer num = llListFindList( datatables, [(string)tablekey] );
if( num != -1 )
{
integer fieldamnt = (integer)llList2String( datatables, num + 2 );
list fieldnames = llList2List( datatables, num + 3, num + 2 + fieldamnt );
if( llGetListLength( data ) != fieldamnt )
{
errorMsg("Query invalid. The number of input fields doesn't match the number of table fields:\nQuery:\n" + llDumpList2String(data, ",") + "\nThe table has " + (string)fieldamnt + " of fields. Your query has " + (string)llGetListLength(data) + " amount of fields specified." );
return FALSE;
}
else
{
integer i;
for (i = 0; i < llGetListLength(data); i++)
{
data += [tablekey, (string)datakeygen, llList2String(fieldnames, i), llList2String(data, i)];
}
datakeygen++;
return TRUE;
}
}
else
{
errorMsg("Table with key doesn't exist:\n" + (string)tablekey );
return FALSE;
}
}
// This function is finished!
integer dataModify(key tablekey, key datakey, list newdata) // Boolean (TRUE if succeeded, fALSE if failed)
{
list cdata = data;
integer diff = 0;
@dataModifyLoop;
integer num = llListFindList(cdata,[(string)tablekey]);
if( num != -1 )
{
list tcdata = llList2List( cdata, num, num + 3 );
integer num2 = llListFindList(tcdata, [(string)datakey]);
if( num2 != -1 )
{
integer dbnum = llListFindList( datatables, [(string)tablekey] );
integer fieldamnt = (integer)llList2String( datatables, dbnum + 2 );
llListReplaceList( data, newdata, num + diff, num + diff );
jump dataModifyDone;
}
llDeleteSubList( cdata, num, num + 3 );
diff += 4;
jump dataModifyLoop;
}
else
{
errorMsg("Table with key doesn't exist or is empty:\n" + (string)tablekey + "\nOr data with key doesn't exist in that table:\n" + (string)datakey);
return FALSE;
}
@dataModifyDone;
return TRUE;
}
// This function is finished!
dataRemove(key tablekey, key datakey) // Can't return success anymore
{
list cdata = data;
integer missingindex = 0;
@dataRemoveLoop;
integer num = llListFindList(cdata,[(string)tablekey]);
if( num != -1 )
{
list tcdata = llList2List( cdata, num, num + 3 );
integer num2 = llListFindList(tcdata, [(string)datakey]);
if( num2 != -1 )
{
llDeleteSubList( data, num + missingindex, num + 3 + missingindex );
missingindex -= 4;
}
llDeleteSubList( cdata, num, num + 3 );
missingindex += 4;
}
else
{
jump dataRemoveDone; // prevent a permanent loop
}
jump dataRemoveLoop;
@dataRemoveDone;
}
// This function is finished!
integer createTable(string name, list fieldanddatatype) // Boolean (TRUE if succeeded, FALSE if failed)
// list fieldanddatatype: fieldName1, fieldName2, ...
{
if( llListFindList( datatables, [name] ) == -1 )
{
datatables += [(string)tablekeygen,name,llGetListLength(fieldanddatatype)] + fieldanddatatype;
tablekeygen++;
return TRUE;
}
else
{
errorMsg("A table with that name already exists:\n" + name);
return FALSE;
}
}
// This function is finished!
integer removeTable(key tablekey) // Boolean (TRUE if succeeded, FALSE if failed)
{
integer tablepos = llListFindList(datatables, [tablekey]);
if( tablepos != -1 )
{
integer numoffields = llList2Integer( datatables, tablepos + 2 );
llDeleteSubList( datatables, tablepos, tablepos + numoffields + 2 );
@removeTableLoop;
integer datanum = llListFindList( data, [tablekey] );
if( datanum == -1 )
{
jump removeTableDone;
}
else
{
llDeleteSubList( data, datanum, datanum + 3 );
}
jump removeTableLoop;
@removeTableDone;
return TRUE;
}
else
{
errorMsg("The table you're trying to remove doesn't exist:\n" + (string)tablekey);
return FALSE;
}
}
errorMsg(string error)
{
// Do whatever you want here, it's your errorhandling!
llWhisper( 0, error );
}
default
{
state_entry()
{
// Create your own way to communicate with the database.
}
}
A nice notecard reading script, an access list script for a remote controlled door or something.
//****************************************************************//
//****************************************************************//
//********************** ACCESS LIST SCRIPT **********************//
//****************************************************************//
//****************************************************************//
//*********** SCRIPT MADE BY CHRISTOPHE003 CARTER ****************//
//****** Script is provided as is, and has no warranty. **********//
//****************** We are not responsible for ******************//
//******** any damages done to your computer and/or avatar *******//
//******************** by use of this script. ********************//
//*********** These comments MUST remain in the script! **********//
//****************************************************************//
//****************************************************************//
// Read out a complete notecard from the object's inventory.
string gName; // name of a notecard in the object's inventory
integer gLine = 0; // current line number
key gQueryID;// id used to identify dataserver queries
string final;
float data2;
list users;
integer check;
float numlines; // alot of numbers used in calculations
float procent;
float linenum = 0;
float finalproc;
integer finalproc2;
key cQueryID; // key for the linecount
default // We only need the default state here.
{
state_entry() // Occurs on rezz and script reset
{
linenum = 0; // clear data
users = []; // clear data
gName = llGetInventoryName(INVENTORY_NOTECARD, 0); // select the first notecard in the object's inventory
if( gName != "" ) // make sure there is a notecard in the inventory
{
cQueryID = llGetNumberOfNotecardLines(gName); // Request how many lines the notecard has
gQueryID = llGetNotecardLine(gName, gLine); // request first line
}
}
changed(integer change)
{
if (change & CHANGED_INVENTORY) // makes sure that a change was made inside the inventory
{
llResetScript(); // Clear all memory, and re-read the notecard (hopefully prevents early stack-heap collision), goes to state_entry
}
}
dataserver(key query_id, string data)
{
if (query_id == cQueryID) // The dataserver provides us with the number of lines in the access list notecard
{
numlines = (integer)data; // Store the number of lines
procent = 100 / numlines; // calculate the percentages
llWhisper(0, "Reading access list, please wait..."); // Say that the access list reading has started
}
else if( query_id == gQueryID ) // We have been provided with a line of text from the notecard (or the end of it)
{
if (data != EOF) // Makes sure that we have not passed the end of the notecard
{
gLine++; // Add one (1) to the line count
linenum += 1; // same.
finalproc = linenum * procent;
finalproc2 = (integer)finalproc; // Calculating percentage to show.
users += [llToLower(data)]; // Add user to the list
llSetText("Loading Notecard\n" + (string)finalproc2 + " %", <1,1,0>, 1); // Set the text
gQueryID = llGetNotecardLine(gName, gLine); // Request next notecard line
}
else // We are at EOF (End Of File), we get no more data
{
llWhisper(0, "Done reading access list."); // We are done reading access list notecard.
llSetText("", <1,1,1>, 0); // Clear all text.
}
}
}
touch_start(integer num)
{
check = llListFindList(users, [llToLower( llDetectedName(0) )] ); // Store in what position the toucher is in the list
if( check != -1 ) // If it is not -1 then he is on the access list (-1 means not on access list)
{
// Example of what can happen
llSay(0, llDetectedName(0) + " is on the access list."); // Output that target is on access list
}
else // Target is not on access list
{
// Example of what can happen
llSay(0, llDetectedName(0) + " is not on the access list."); // Tell him he is not on access list.
}
}
}
A nice parcel monitor script for people who rent out land, to check for prim usage and things like that. Updated 2009/03/29
main script
Updated 2009/03/29
//****************************************************************//
//****************************************************************//
//******************** PARCEL MONITOR SCRIPT *********************//
//****************************************************************//
//****************************************************************//
//*********** SCRIPT MADE BY CHRISTOPHE003 CARTER ****************//
//****** Script is provided as is, and has no warranty. **********//
//****************** We are not responsible for ******************//
//******** any damages done to your computer and/or avatar *******//
//******************** by use of this script. ********************//
//*********** These comments MUST remain in the script! **********//
//****************************************************************//
//****************************************************************//
string HandleParcelName(string pname) // Splits parcel name to multiple lines when it's to long so
// it fits on the parcel monitor. It does this without breaking
// words up or stuff like that.
{
integer check = 1;
list parcelnamesplit = llParseString2List( pname, [], [" "] );
string finished;
string temp;
integer i;
for (i = 0; i < llGetListLength(parcelnamesplit); i++)
{
if( llStringLength(finished) + llStringLength( llList2String( parcelnamesplit, i ) ) > check * 25 )
{
finished += "\n";
check++;
}
finished += llList2String( parcelnamesplit, i );
}
return finished;
}
default
{
on_rez(integer param)
{
llResetScript();
}
state_entry()
{
llSetTimerEvent( 0.1 );
}
timer()
{
string extratext;
integer Parcel_Flags = llGetParcelFlags(llGetPos ());
if (PARCEL_FLAG_ALLOW_FLY & Parcel_Flags)
{
extratext += "Fly enabled\n";
}
else{extratext+="No fly\n";}
if (PARCEL_FLAG_ALLOW_SCRIPTS & Parcel_Flags)
{
extratext += "Outside Scripts on\n";
}
else{extratext+="No outside scripts\n";}
if( PARCEL_FLAG_ALLOW_LANDMARK & Parcel_Flags )
{
extratext += "Allows landmark creation\n";
}
else{extratext += "Disallow landmark creation\n";}
if (PARCEL_FLAG_ALLOW_TERRAFORM & Parcel_Flags)
{
extratext += "Terraforming Permitted\n";
}
else{extratext+="No terraforming\n";}
if (PARCEL_FLAG_ALLOW_DAMAGE & Parcel_Flags)
{
extratext += "Damage Enabled\n";
}
else{extratext+="No damage\n";}
if (PARCEL_FLAG_ALLOW_CREATE_OBJECTS & Parcel_Flags)
{
extratext += "Public rez on\n";
}
else{extratext+="Public rez off\n";}
if (PARCEL_FLAG_USE_ACCESS_GROUP & Parcel_Flags)
{
extratext += "Group Access on\n";
}
if (PARCEL_FLAG_USE_ACCESS_LIST & Parcel_Flags)
{
extratext += "Access List on\n";
}
else{extratext+="Public Access\n";}
if (PARCEL_FLAG_USE_BAN_LIST & Parcel_Flags)
{
extratext += "Banlist on\n";
}
else{extratext+="Banlist Disabled\n";}
extratext += "\n \n \n \n \n \n \n \n \n \n \n \n";
llMessageLinked( LINK_ALL_OTHERS, 0, extratext, "first" );
extratext = "";
if (PARCEL_FLAG_USE_LAND_PASS_LIST & Parcel_Flags)
{
extratext += "Passes for sale on.\n";
}
else{extratext+="No access passes for sale.\n";}
if (PARCEL_FLAG_LOCAL_SOUND_ONLY & Parcel_Flags)
{
extratext += "Parcel spatialised sound restricted.\n";
}
else{extratext+="Sound not restricted to parcel.\n";}
if (PARCEL_FLAG_ALLOW_GROUP_SCRIPTS & Parcel_Flags)
{
extratext += "Group scripts on.\n";
}
else{extratext+="No group scripts.\n";}
if (PARCEL_FLAG_ALLOW_CREATE_GROUP_OBJECTS & Parcel_Flags)
{
extratext += "Group members can rez here.\n";
}
else{extratext+="Group members cannot rez here.\n";}
if (PARCEL_FLAG_ALLOW_ALL_OBJECT_ENTRY & Parcel_Flags)
{
extratext += "All objects can enter.\n";
}
else{extratext+="Not all objects can enter.\n";}
if (PARCEL_FLAG_ALLOW_GROUP_OBJECT_ENTRY & Parcel_Flags)
{
extratext += "Group objects can enter.\n";
}
else{extratext+="Group objects cannot enter.\n";}
if (PARCEL_FLAG_RESTRICT_PUSHOBJECT & Parcel_Flags)
{
extratext += "Push is disabled.\n";
}
else{extratext+="Push enabled\n";}
extratext += " \n \n \n \n";
llMessageLinked( LINK_ALL_OTHERS, 0, extratext, "last" );
float basicperformance = llGetRegionTimeDilation() * 100;
float basicperformance2 = llGetRegionFPS() * 2.222222;
float basicperformance3 = basicperformance + basicperformance2;
float basicperformance4 = basicperformance3 / 2;
integer basicperformance5 = (integer)basicperformance4;
list parceldetails = llGetParcelDetails( llGetPos(), [PARCEL_DETAILS_NAME, PARCEL_DETAILS_DESC, PARCEL_DETAILS_AREA] );
integer primcount = llGetParcelPrimCount( llGetPos(), PARCEL_COUNT_TOTAL, FALSE );
string parcelname = llList2String( parceldetails, 0 );
string parceldesc = llList2String( parceldetails, 1 );
string parcelarea = llList2String( parceldetails, 2 );
llSetText( llGetRegionName() + "\nFPS: " + (string)llGetRegionFPS() + "\nTime Dilation: " + (string)llGetRegionTimeDilation() +
"\n \nSim Performance: " + (string)basicperformance5 + "%" + "\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n" + HandleParcelName(parcelname) + "\nParcel size: " + parcelarea + "sqm.\nPrims used: " + (string)primcount, llGetColor(ALL_SIDES), llGetAlpha( ALL_SIDES ) );
}
}
subscript 1
subscript 2
Feel free to leave ANY comments, criticize my scripting, correcting my scripts, suggestions, or just to say hi :)