Skip to content
lsl.devlsl.devLSL Dev

llLinksetDataFindKeys

function
Function syntax
list llLinksetDataFindKeys(
  1. string pattern,// A regular expression (regex) describing which keys to search for.
  2. integer start,// Zero-based start index of the matching keys to return.
  3. integer count// Maximum number of keys to return (or less than 1 to retrieve all matching keys).
);
Returns
list
Energy
10

The llLinksetDataFindKeys function returns a list of up to count keys from the datastore that match pattern, starting at the one indicated by start. If count is less than 1, then all keys between start and the end which match pattern are returned. If count minus start exceeds the number of matching keys, the returned list will be shorter than count, down to a zero-length list if start equals or exceeds the number of matching keys. The list is ordered alphabetically.

Returns a list of the keys in the datastore.

How to use
list result = llLinksetDataFindKeys("", 0, 0);

pattern is a Regular expression.

  • The maximum length for pattern seems to be 800 characters.
  • There seems to be a timing restriction. If the time limit is exceeded, the function fails silently.
  • Returns an empty list and the script continues execution.
  • To delete keys matching an expression, use the similar llLinksetDataDeleteFound.
When pattern matches multiple keys, start can be used to skip over some of the first matches.
11 collapsed lines
default
{
state_entry()
{
llLinksetDataWrite("ThingA_config", "value");
llLinksetDataWrite("ThingA_data", "value");
llLinksetDataWrite("ThingB_config", "value");
llLinksetDataWrite("ThingB_data", "value");
llLinksetDataWrite("ThingC_config", "value");
llLinksetDataWrite("ThingC_data", "value");
list keys;
// Return 1 key starting from the first match.
keys = llLinksetDataFindKeys("Thing", 0, 1);
llOwnerSay(llList2CSV(keys)); // ThingA_config
// Return 1 key after skipping the first 3 matches.
keys = llLinksetDataFindKeys("Thing", 3, 1);
llOwnerSay(llList2CSV(keys)); // ThingB_data
// Return up to 10 keys after skipping the first match.
keys = llLinksetDataFindKeys("_data", 1, 10);
llOwnerSay(llList2CSV(keys)); // ThingB_data, ThingC_data
}
}
The following regular expression code can be used to find UUID keys. (Such as those use to identify user UUID)
list keysFound = llLinksetDataFindKeys("(?i)^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$", 0, 0);
The following code can also be used to find UUID keys in LinksetData memory.
list keysFound = llLinksetDataFindKeys("^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$", 0, 0);
Warning: Keep track of how many UUIDs will be returned, as too many can overwhelm script memory and cause a stack-heap crash.

The script below uses llLinksetDataFindKeys for blacklist management.

79 collapsed lines
integer gDialogChannel;
integer gDialogHandle;
integer gManagingBlocks;
startDialog(key person)
{
gManagingBlocks = 0;
gDialogHandle = llListen(gDialogChannel, "", person, "");
llDialog(person, "\nSelect action", ["List blocks", "Add block", "Remove block"], gDialogChannel);
llSetTimerEvent(60);
}
stopDialog()
{
llSetTimerEvent(0);
llListenRemove(gDialogHandle);
}
default
{
on_rez(integer sp)
{
llResetScript();
}
state_entry()
{
gDialogChannel = (integer)(llFrand(-10000000)-10000000);
llListen(PUBLIC_CHANNEL, "", NULL_KEY, "");;
}
timer()
{
stopDialog();
}
touch_start(integer nd)
{
key toucherKey = llDetectedKey(0);
if (toucherKey == llGetOwner())
{
startDialog(toucherKey);
}
}
listen(integer channel, string name, key id, string message)
{
if (llGetAgentSize(id) == ZERO_VECTOR)
{
return;
}
if (channel == gDialogChannel)
{
stopDialog();
if (gManagingBlocks)
{
message = llStringTrim(message, STRING_TRIM);
if ((key)message)
{
if (gManagingBlocks == 1)
{
llOwnerSay("Addition request has been sent to the blacklist storage");
llLinksetDataWrite("blocklist:" + message, "1");
}
else
{
llOwnerSay("Removal request has been sent to the blacklist storage.");
llLinksetDataDelete("blocklist:" + message);
}
}
else
{
llOwnerSay("The UUID '" + message + "' appears to be invalid.");
}
startDialog(id);
}
else if (message == "List blocks")
{
list blocks = llLinksetDataFindKeys("^blocklist:", 0, 0);
integer listLength = llGetListLength(blocks);
llOwnerSay("Blacklist items: " + (string)listLength);
24 collapsed lines
integer i;
while (i < listLength)
{
string record = llGetSubString(llList2String(blocks, i), 10, -1);
llOwnerSay("- secondlife:///app/agent/" + record + "/about" + " - " + record);
++i;
}
blocks = [];
startDialog(id);
}
else if (message == "Add block" || message == "Remove block")
{
string label = "add to";
gManagingBlocks = 1;
if (message == "Remove block")
{
gManagingBlocks = 2;
label = "remove from";
}
gDialogHandle = llListen(gDialogChannel, "", id, "");
llTextBox(id, "\nPlease specify one single avatar UUID you'd like to " + label + " the blacklist storage.", gDialogChannel);
llSetTimerEvent(60);
}
return;
}
if (llGetListLength(llLinksetDataFindKeys("blocklist:" + (string)id, 0, 1)) > 0)
{
llRegionSayTo(id, 0, "You're blacklisted.");
return;
}
llRegionSayTo(id, 0, "Hello there, secondlife:///app/agent/" + (string)id + "/about - your message: " + message);
12 collapsed lines
}
linkset_data(integer action, string name, string value)
{
if (action == LINKSETDATA_RESET || action == LINKSETDATA_DELETE || action == LINKSETDATA_UPDATE)
{
llOwnerSay("Blacklist storage modified.");
}
}
}
Original wiki source

Some wiki templates and tables need their original context. View this article on the Second Life Wiki. Technical wording and examples are retained from the source; historical guidance may differ from current behavior.