Difference between revisions of "Category:LSL Key"

From Second Life Wiki
Jump to navigation Jump to search
(-1 >> ERR_GENERIC)
(source->syntaxhighlight, and added reminder that invalid keys are like NULL_KEY for purposes of filtering, though it seems to be mentioned in the relevant articles as well)
 
(8 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{LSL Header|ml=*}}{{LSLC|}}{{LSLC|Types}}
{{LSL Header|ml=*}}{{LSLC|}}{{LSLC|Types}}


A key is a unique identifier in Second Life for anything mostly, be it a prim, avatar, texture, etc.
== Intro: ==


You may see key referred to as [[UUID]], UID, "Asset UUID", or "asset-ID."
A key is a '''universal unique identifier''' in Second Life for anything mostly, be it a [[prim]], [[avatar]], [[:Category:LSL_Texture|texture]], etc.


The key itself is formed of hexidecimal characters (a-f and 0-9) and each section of the key is broken up by dashes (for a total amount of 36 characters).
You may see key referred to as [[UUID]], UID, "Asset UUID", or "asset-ID".


An example key:
The key itself is formed of {{Wikipedia|Hexidecimal|hexadecimal}} characters <code>[0-9a-f]</code> and each section of the key is broken up by dashes (for a total amount of 36 characters).
<pre>"a822ff2b-ff02-461d-b45d-dcd10a2de0c2"</pre>


<syntaxhighlight lang="lsl2">
    key whatever = "01234567-89ab-cdef-0123-456789abcdef";
</syntaxhighlight>


'''Getting a Key'''
'''Some keys''' in Second Life are a [http://en.wikipedia.org/wiki/UUID#Version_4_.28random.29 UUID-4] as defined in {{RFC|4122|target=section-4.1.3}}.


There are several ways to acquire the key of something:<br />
<syntaxhighlight lang="lsl2">
1) Having someone supply it to you;<br />
    key uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
2) Using a native LSL function such as [[llGetKey]], etc.<br />
3) In your inventory, right-clicking over something and choosing "Copy Asset UUID." Note this will only work on items that you have full permissions to.


//  where:
//      4 is 4
//      x is [0-9a-f]
//      y is [8-9a-b]
</syntaxhighlight>


'''Converting Keys'''
== Receiving keys: ==


When a key is supplied to you as a text string, you convert it to the key data type like this:
There are several ways to acquire the key of something:


<lsl>(key)"a822ff2b-ff02-461d-b45d-dcd10a2de0c2";</lsl>
# Having someone supply it to you;
# Using a built-in [[LSL_Portal|LSL]] [[:Category:LSL_Functions|function]] such as [[llGetKey]], [[llGetLinkKey]] etc.
# In your inventory, right-clicking over something and choosing <code>Copy Asset UUID</code>. Note this will only work on items that you have full permissions to.
 
== Generating keys: ==
 
Built-in [[LSL_Portal|LSL]] [[:Category:LSL_Functions|functions]]:
 
{|{{Prettytable}}
|+
|-{{Hl2}}
!function
!purpose
|-
|| [[llGenerateKey]] || Generates a key using [http://en.wikipedia.org/wiki/UUID#Version_5_.28SHA-1_hash.29 Version 5 (SHA-1 hash)] [[UUID]] generation to create a unique key.
|}
 
User-defined functions:
{|{{Prettytable}}
|+
|-{{Hl2}}
!function
!purpose
|-
|| [[GenerateKey]] || Generates an MD5-based (version 3) type UUID. Useful for identifying link-messages and for other purposes.
|-
|| [[GenUUID]] || Generates a UUID based on PHP com_create_guid.
|}
 
== Converting Keys: ==
 
When a key is supplied to you as a text [[string]], you convert it to the key data-type like this:
 
<syntaxhighlight lang="lsl2">key whatever = (key)"01234567-89ab-cdef-0123-456789abcdef";</syntaxhighlight>


Implicit conversion will happen automatically when supplying a string where a key is required.
Implicit conversion will happen automatically when supplying a string where a key is required.


<lsl>key uuid = "a822ff2b-ff02-461d-b45d-dcd10a2de0c2";
<syntaxhighlight lang="lsl2">key uuid = "01234567-89ab-cdef-0123-456789abcdef";
llKey2Name("a822ff2b-ff02-461d-b45d-dcd10a2de0c2");</lsl>
llKey2Name("01234567-89ab-cdef-0123-456789abcdef");</syntaxhighlight>


However there is no implicit conversion with [[llListFindList]]. llListFindList requires not only the values to match but also the types. Tip: [[ERR_GENERIC]] has the integer value -1.
However there is no implicit conversion with [[llListFindList]]. [[llListFindList]] requires not only the values to match but also the types.  


<lsl>llListFindList(["a822ff2b-ff02-461d-b45d-dcd10a2de0c2"], [(key)"a822ff2b-ff02-461d-b45d-dcd10a2de0c2"]) == ERR_GENERIC;</lsl>
<syntaxhighlight lang="lsl2">llListFindList(["01234567-89ab-cdef-0123-456789abcdef"], [(key)"01234567-89ab-cdef-0123-456789abcdef"]) == -1;</syntaxhighlight>




'''Displaying avatar or group information'''
== Displaying avatar or group information: ==


If you know an avatar's key, you can display the avatar's name in the viewer window and chat history by using the following special URL:
If you know an avatar's key, you can display the avatar's name in the viewer window and chat history by using the following special URL:
<lsl>llOwnerSay("secondlife:///app/agent/" + (string)owner_key + "/about");</lsl>
<syntaxhighlight lang="lsl2">llOwnerSay("secondlife:///app/agent/" + (string)owner_key + "/about");</syntaxhighlight>


This displays both [[Display names|display name]] and [[Usernames|username]] as a clickable link that brings up an avatar profile window when clicked.  It is easier than using [[llRequestAgentData]] or [[llRequestUsername]] or [[llRequestDisplayName]], since there is no need to use a [[dataserver]] event.
This displays both [[Display names|display name]] and [[Usernames|username]] as a clickable link that brings up an avatar profile window when clicked.  It is easier than using [[llRequestAgentData]] or [[llRequestUsername]] or [[llRequestDisplayName]], since there is no need to use a [[dataserver]] event.


If you know a group key (as a result of calling [[llGetObjectDetails]] with [[OBJECT_GROUP]], or calling [[llGetParcelDetails]] with [[PARCEL_DETAILS_GROUP]]), you can display the group's name with the following special URL:
If you know a group key (as a result of calling <code>[[llGetObjectDetails]]([[key]] id, <nowiki>[</nowiki>[[OBJECT_GROUP]]<nowiki>]</nowiki>)</code>, or calling <code>[[llGetParcelDetails]]([[vector]] pos, <nowiki>[</nowiki>[[PARCEL_DETAILS_GROUP]]<nowiki>]</nowiki>)</code>), you can display the group's name with the following special URL:
<lsl>llOwnerSay("secondlife:///app/group/" + (string)group_key + "/about");</lsl>
<syntaxhighlight lang="lsl2">llOwnerSay("secondlife:///app/group/" + (string)group_key + "/about");</syntaxhighlight>


This displays the group name as a clickable link that brings up a group profile window when clicked.  This is especially useful since there is no other way to do this; there is no LSL function to print out a group's name.
This displays the group name as a clickable link that brings up a group profile window when clicked.  This is especially useful since there is no other way to do this; there is no LSL function to print out a group's name.


Finally, if you know a parcel key (as a result of calling [[llGetParcelDetails]] with [[PARCEL_DETAILS_ID]]), you can create a clickable link that brings up a place profile window when clicked, using the following special URL:
Finally, if you know a [[Land#Parcel|parcel]] key (as a result of calling <code>[[llGetParcelDetails]]([[vector]] pos, <nowiki>[</nowiki>[[PARCEL_DETAILS_ID]]<nowiki>]</nowiki>)</code>), you can create a clickable link that brings up a place profile window when clicked, using the following special URL:
<lsl>llOwnerSay("secondlife:///app/parcel/" + (string)parcel_key + "/about");</lsl>
<syntaxhighlight lang="lsl2">llOwnerSay("secondlife:///app/parcel/" + (string)parcel_key + "/about");</syntaxhighlight>
 


'''Testing for a valid key'''
== Testing for a valid key: ==


To test for a valid key, just do this:
To test for a valid key, just do this:


<lsl>if(uuid){
<syntaxhighlight lang="lsl2">if(uuid){
     //do something
     //do something
}</lsl>
}</syntaxhighlight>


<code>if(uuid)</code> will only return true if it is supplied a key that is both (A) valid, and (B) NOT a [[NULL_KEY]].
<code>if(uuid)</code> will only return true if it is supplied a key that is both (A) valid, and (B) NOT a [[NULL_KEY]].
Line 67: Line 104:
Here is an example of how to build a function around this:
Here is an example of how to build a function around this:


<lsl>
<syntaxhighlight lang="lsl2">
integer isKey(key in) {
// 2:        valid key, not NULL_KEY
     if(in) return 2;
// 1 (TRUE):  NULL_KEY
// 0 (FALSE): not a key
 
integer isKey(key in)
{
     if (in)
        return 2;
     return (in == NULL_KEY);
     return (in == NULL_KEY);
}
}
</lsl>
</syntaxhighlight>


'''Caveats'''
== Caveats: ==
 
* Assigning an arbitrary string to a key is allowed and the key variable retains the string value, but will be considered an invalid key unless it matches the correct key character pattern with hexadecimal digits and dashes. In most contexts invalid keys work like the NULL_KEY, e.g. if given to a function that can filter by UUID such as [[llListen]], no filtering will be performed.
* <code>if (uuid)</code> is a special case. Keys cannot be converted to integers, so logical operators such as <code>!</code>, <code>||</code> and <code>&&</code> cannot be used with keys. If you wish to do <code>if (!uuid) // Some action</code> then you can use a simple workaround like so: <code>if (uuid) {} else // Some action</code>. This is particularly useful if we wish to discard invalid string content (i.e - ensure that a key is actually a key) like so:<lsl>if (uuid) ; else uuid = NULL_KEY;</lsl>
* <syntaxhighlight lang="lsl2">if (uuid)</syntaxhighlight> is a special case. Keys cannot be converted to [[Integer|integers]], so logical [[LSL_Operators|operators]] such as <code>!</code>, <code>||</code> and <code>&&</code> cannot be used with keys. If you wish to do <syntaxhighlight lang="lsl2">if (!uuid) { /* wont work */ }</syntaxhighlight> then you can use a simple workaround like so: <syntaxhighlight lang="lsl2">if (uuid) { } else { /* will work */ }</syntaxhighlight> This is particularly useful if we wish to discard invalid string content (i.e - ensure that a key is actually a key) like so:<syntaxhighlight lang="lsl2">if (uuid) ; else uuid = NULL_KEY;</syntaxhighlight>
* Checking key validity with an if statement doesn't ensure the key actually refers to an asset, an avatar or anything at all, only that it has the correct structure.
* Be careful when adding key literals to lists, no implicit typecasting will take place. Failing to ensure that key literals are keys will cause problems with [[llListFindList]].
* Be careful when adding key literals to lists, no implicit typecasting will take place. Failing to ensure that key literals are keys will cause problems with [[llListFindList]].
 
* Furthermore, LSO and Mono do not work the same when it comes to typecasting strings to keys.
== Extended Key Operations ==
** There is a bug in LSO that LL has declined to fix, the reason given is that fixing it would break existing content.
These functions have been created and contributed by LSL users to perform operations not covered by built-in LSL functions.
 
 
{|{{Prettytable}}
|+
|-{{Hl2}}
!function
!purpose
|-
|| [[GenerateKey]] || Generates an MD5-based (version 3) type UUID. Useful for identifying link-messages and for other purposes.
|-
|| [[GenUUID]] || Generates a UUID based on PHP com_create_guid.
|}

Latest revision as of 12:33, 28 May 2024

Intro:

A key is a universal unique identifier in Second Life for anything mostly, be it a prim, avatar, texture, etc.

You may see key referred to as UUID, UID, "Asset UUID", or "asset-ID".

The key itself is formed of "Wikipedia logo"hexadecimal characters [0-9a-f] and each section of the key is broken up by dashes (for a total amount of 36 characters).

    key whatever = "01234567-89ab-cdef-0123-456789abcdef";

Some keys in Second Life are a UUID-4 as defined in RFC-4122.

    key uuid = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";

//  where:
//      4 is 4
//      x is [0-9a-f]
//      y is [8-9a-b]

Receiving keys:

There are several ways to acquire the key of something:

  1. Having someone supply it to you;
  2. Using a built-in LSL function such as llGetKey, llGetLinkKey etc.
  3. In your inventory, right-clicking over something and choosing Copy Asset UUID. Note this will only work on items that you have full permissions to.

Generating keys:

Built-in LSL functions:

function purpose
llGenerateKey Generates a key using Version 5 (SHA-1 hash) UUID generation to create a unique key.

User-defined functions:

function purpose
GenerateKey Generates an MD5-based (version 3) type UUID. Useful for identifying link-messages and for other purposes.
GenUUID Generates a UUID based on PHP com_create_guid.

Converting Keys:

When a key is supplied to you as a text string, you convert it to the key data-type like this:

key whatever = (key)"01234567-89ab-cdef-0123-456789abcdef";

Implicit conversion will happen automatically when supplying a string where a key is required.

key uuid = "01234567-89ab-cdef-0123-456789abcdef";
llKey2Name("01234567-89ab-cdef-0123-456789abcdef");

However there is no implicit conversion with llListFindList. llListFindList requires not only the values to match but also the types.

llListFindList(["01234567-89ab-cdef-0123-456789abcdef"], [(key)"01234567-89ab-cdef-0123-456789abcdef"]) == -1;


Displaying avatar or group information:

If you know an avatar's key, you can display the avatar's name in the viewer window and chat history by using the following special URL:

llOwnerSay("secondlife:///app/agent/" + (string)owner_key + "/about");

This displays both display name and username as a clickable link that brings up an avatar profile window when clicked. It is easier than using llRequestAgentData or llRequestUsername or llRequestDisplayName, since there is no need to use a dataserver event.

If you know a group key (as a result of calling llGetObjectDetails(key id, [OBJECT_GROUP]), or calling llGetParcelDetails(vector pos, [PARCEL_DETAILS_GROUP])), you can display the group's name with the following special URL:

llOwnerSay("secondlife:///app/group/" + (string)group_key + "/about");

This displays the group name as a clickable link that brings up a group profile window when clicked. This is especially useful since there is no other way to do this; there is no LSL function to print out a group's name.

Finally, if you know a parcel key (as a result of calling llGetParcelDetails(vector pos, [PARCEL_DETAILS_ID])), you can create a clickable link that brings up a place profile window when clicked, using the following special URL:

llOwnerSay("secondlife:///app/parcel/" + (string)parcel_key + "/about");

Testing for a valid key:

To test for a valid key, just do this:

if(uuid){
     //do something
}

if(uuid) will only return true if it is supplied a key that is both (A) valid, and (B) NOT a NULL_KEY.

Tip! In techy talk, this method is called "passing it as the parameter for a conditional"

Note! It is important for the above example that uuid be defined as a key. It can of course be typecast to be a key as well: if((key)uuid)

Here is an example of how to build a function around this:

// 2:         valid key, not NULL_KEY
// 1 (TRUE):  NULL_KEY
// 0 (FALSE): not a key

integer isKey(key in)
{
    if (in)
        return 2;
    return (in == NULL_KEY);
}

Caveats:

  • Assigning an arbitrary string to a key is allowed and the key variable retains the string value, but will be considered an invalid key unless it matches the correct key character pattern with hexadecimal digits and dashes. In most contexts invalid keys work like the NULL_KEY, e.g. if given to a function that can filter by UUID such as llListen, no filtering will be performed.
  • if (uuid)
    
    is a special case. Keys cannot be converted to integers, so logical operators such as !, || and && cannot be used with keys. If you wish to do
    if (!uuid) { /* wont work */ }
    
    then you can use a simple workaround like so:
    if (uuid) { } else { /* will work */ }
    
    This is particularly useful if we wish to discard invalid string content (i.e - ensure that a key is actually a key) like so:
    if (uuid) ; else uuid = NULL_KEY;
    
  • Checking key validity with an if statement doesn't ensure the key actually refers to an asset, an avatar or anything at all, only that it has the correct structure.
  • Be careful when adding key literals to lists, no implicit typecasting will take place. Failing to ensure that key literals are keys will cause problems with llListFindList.
  • Furthermore, LSO and Mono do not work the same when it comes to typecasting strings to keys.
    • There is a bug in LSO that LL has declined to fix, the reason given is that fixing it would break existing content.