<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Winter+Seale</id>
	<title>Second Life Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.secondlife.com/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Winter+Seale"/>
	<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/wiki/Special:Contributions/Winter_Seale"/>
	<updated>2026-07-28T04:57:09Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.42.1</generator>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:Json_usage_in_LSL&amp;diff=1187199</id>
		<title>Talk:Json usage in LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:Json_usage_in_LSL&amp;diff=1187199"/>
		<updated>2014-01-23T20:35:48Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Inconsistent behavior on types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am concerned because the JSON format specifies at json.org that you can use escape codes like \u0000 to represent Unicode byte values in strings. But LSL has the ugly habit of censoring and altering strings so that a character with byte value of 0x0000 is removed from the string, and some functions like llSHA1String are essentially broken since they also convert UTF-16 integers between \u0128–\u0255 into UTF-8 byte values starting with %c2 (which therefore have a different integer value due to the addition of the extraneous byte). Is LSL also going to mangle JSON strings&#039; byte values when it renders them into LSL strings? Won&#039;t this corrupt attempts at efficiently verifying the signatures of any incoming messages, and thwart attempts to generate proper signatures for some outgoing JSON-formatted requests? Or do the Lindens have plans to finally give us a proper suite of escape codes in LSL (or some other solution)?&lt;br /&gt;
--[[User:Gistya Eusebio|Gistya Eusebio]] 09:41, 30 May 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
Add to that the complete crash-and-burn if your string starts with a quote, generating invalid JSON. I really don&#039;t get why LL finds it advantageous to include magic switches which forces everybody to do workaround for normal use, and ensures that all future JSON implementations in SL must be hand-coded to keep backwards compatibility with the spec breaks currently implemented.&lt;br /&gt;
[[User:Tali Rosca|Tali Rosca]] 15:50, 19 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
:This sounds like a bug, you should report it. -- &#039;&#039;&#039;[[User:Strife_Onizuka|Strife]]&#039;&#039;&#039; &amp;lt;sup&amp;gt;&amp;lt;small&amp;gt;([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])&amp;lt;/small&amp;gt;&amp;lt;/sup&amp;gt; 21:49, 20 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
::nm I see that you did. {{jira|BUG-2594}} -- &#039;&#039;&#039;[[User:Strife_Onizuka|Strife]]&#039;&#039;&#039; &amp;lt;sup&amp;gt;&amp;lt;small&amp;gt;([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])&amp;lt;/small&amp;gt;&amp;lt;/sup&amp;gt; 21:50, 20 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
:::I&#039;ve been kicking and screaming about getting a robust JSON handling :-) 2594 got us some way, but we still have {{jira|BUG-2736}}, which I consider so exceedingly ill-advised as to be a bug, despite the insistence that it&#039;s a really awesome feature. [[User:Tali Rosca|Tali Rosca]] 16:39, 21 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
::::&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;The trailing quotation mark is the real nasty problem, not the leading one :D But yeah.. if they do add the capability to handle enquoted* text, how would that break anyone&#039;s scripts? Is anyone really relying on enquotation to invalidate their JSON strings on purpose? Besides when has breaking people&#039;s scripts stopped them from doing anything? I have tens of thousands of L$ worth of vehicles that are now worthless due to the Havok 4 update, but hey, life goes on. My copy of Microsoft Word 1.0 for Mac won&#039;t run on Mountain Lion either. I like backwards compatibility but we developers would be out of a job if software never had to be rewritten to work with the ever-evolving platforms that are out there :D &amp;lt;br&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;--[[User:Gistya Eusebio|Gistya Eusebio]] 07:58, 23 June 2013 (PDT) &amp;lt;br&amp;gt;* I know &amp;quot;enquoted&amp;quot; is not in the dictionary. However it is in the lexicon. :D&lt;br /&gt;
:::::A (somewhat kludgy) workaround for the mishandling of escaped characters can now be found [[User:LepreKhaun_Resident/Workaround4Escaped_Chars_within_JsonText|here]]. Hope someone finds this useful.[[User:LepreKhaun Resident|LepreKhaun Resident]] 23:41, 29 August 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I feel the paragraph within &amp;quot;Specifying Json Elements&amp;quot; that begins with &amp;quot;When JSON is presented in human-readable form,...&amp;quot; should be rewritten to show that the JSON string in its entirety is actually the root node of the structure, signified by an empty list used as &amp;quot;specifiers&amp;quot;. [[User:LepreKhaun Resident|LepreKhaun Resident]] 15:23, 6 July 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Unsure of major edit ==&lt;br /&gt;
&lt;br /&gt;
After making the edit on 16:04, 15 August 2013 to correct code examples that wouldn&#039;t compile, I&#039;ve come to realize that the given examples, as well as the surrounding text, is in error since json disallows empty values, as one might find in a &amp;quot;sparse&amp;quot; array.&lt;br /&gt;
&lt;br /&gt;
The author is pointing out &amp;quot;a rare exception&amp;quot; but then uses &amp;quot;{\&amp;quot;parent\&amp;quot;:,}&amp;quot; and &amp;quot;{\&amp;quot;parent\&amp;quot;:[ , ,  , , ]}&amp;quot; to illustrate. Neither of those can be arrived at with llList2Json(), since LSL doesn&#039;t allow empty list elements, but can only be obtained by hand coding to arrive at the non-compliant json strings.&lt;br /&gt;
&lt;br /&gt;
I feel that whole section should be rewritten to simply point out to the reader that they are advised to use llList2Json() in the formation of json strings and avoid hand coding, which may well result in mal-formed constructions that could lead to confusing results in later operations. &lt;br /&gt;
&lt;br /&gt;
However, doing so would excise a number of paragraphs and I&#039;m unsure how that would set with the original author and others. Guidance on this would be appreciated. [[User:LepreKhaun Resident|LepreKhaun Resident]] 05:25, 18 August 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
== JSON example ==&lt;br /&gt;
&lt;br /&gt;
I want to submit a simple, working example on LSL JSON, but I don&#039;t know the right place for it&lt;br /&gt;
:I hope Strife will and can place it, here it is:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// JSON array forum example by Dora Gustafson, Studio Dora 2013&lt;br /&gt;
// Building an 3 by 5 array in a JSON Object&lt;br /&gt;
// Rows are indexed by name and columns are indexed by number = 0,1,2,3,4&lt;br /&gt;
&lt;br /&gt;
string JSONVotes;&lt;br /&gt;
&lt;br /&gt;
tellVotes( string voter)&lt;br /&gt;
{&lt;br /&gt;
    string Js = llJsonGetValue( JSONVotes, [voter]);&lt;br /&gt;
    list Jl = llParseString2List( Js,[&amp;quot;,&amp;quot;,&amp;quot;[&amp;quot;,&amp;quot;]&amp;quot;,&amp;quot;\&amp;quot;&amp;quot;],[]);&lt;br /&gt;
    string output = llDumpList2String( Jl, &amp;quot;, &amp;quot;);&lt;br /&gt;
    llOwnerSay( &amp;quot;Votes from &amp;quot;+voter+&amp;quot; are: &amp;quot;+output);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {   // Building the JSON object&lt;br /&gt;
        string votes = llList2Json( JSON_ARRAY, [0, 0, 0, 0, 0]); // one row&lt;br /&gt;
        JSONVotes = llList2Json( JSON_OBJECT, [ &amp;quot;Betty&amp;quot;, votes, &amp;quot;Jerry&amp;quot;, votes, &amp;quot;Pierre&amp;quot;, votes]); // complete object&lt;br /&gt;
    }&lt;br /&gt;
    touch_end( integer num)&lt;br /&gt;
    {   // Testing the JSON object&lt;br /&gt;
        tellVotes( &amp;quot;Betty&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Jerry&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Pierre&amp;quot;);&lt;br /&gt;
        // saving some random votes&lt;br /&gt;
        JSONVotes = llJsonSetValue( JSONVotes, [&amp;quot;Betty&amp;quot;, 1], (string)llFrand( 100.0));&lt;br /&gt;
        JSONVotes = llJsonSetValue( JSONVotes, [&amp;quot;Jerry&amp;quot;, 4], (string)llFrand( 100.0));&lt;br /&gt;
        // testing&lt;br /&gt;
        tellVotes( &amp;quot;Betty&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Jerry&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Pierre&amp;quot;);&lt;br /&gt;
        // getting one vote, example&lt;br /&gt;
        string s = llJsonGetValue( JSONVotes, [&amp;quot;Betty&amp;quot;,1]);&lt;br /&gt;
        llOwnerSay( &amp;quot;Betty votes &amp;quot;+s+&amp;quot; in second column&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;[[User:Dora Gustafson|Dora Gustafson]] 06:23, 25 August 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Inconsistent behavior on types ==&lt;br /&gt;
&lt;br /&gt;
The documentation says: if the specifier list element is an integer, then the corresponding element in the json value must be an array and the list element is used as a zero-based index into the Json array.&lt;br /&gt;
&lt;br /&gt;
However, placing integers in a specifier used with a JSON_OBJECT and llJsonGetValue, they are automatically converted to strings.  llList2Json and llJsonSetValue do not automatically convert integers to strings.  Both will result in a JSON_INVALID if you try to put integers on the key side of a JSON_OBJECT.&lt;br /&gt;
&lt;br /&gt;
This example code, according to the documentation shouldn&#039;t even work (I&#039;d presume it&#039;s supposed to return a JSON_INVALID):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;string test = llList2Json(JSON_OBJECT, [&amp;quot;1&amp;quot;, &amp;quot;one&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;3&amp;quot;, &amp;quot;three&amp;quot;]);&lt;br /&gt;
llOwnerSay(llJsonGetValue(test, [3]));&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This little sniplet produces &amp;quot;three&amp;quot;.  Additionally, using llJsonValueType in place of llJsonGetValue in the above example will result in JSON_STRING.  Attempting something like &#039;llJsonSetValue(test, [3], &amp;quot;three&amp;quot;);&#039; results in JSON_INVALID.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[USER:Chetar Ruby|Chetar Ruby]] 09:15, 14 October 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
: Yes, that&#039;s because what you meant to say was &amp;lt;code&amp;gt;llJsonSetValue(test, [&amp;quot;3&amp;quot;], &amp;quot;three&amp;quot;)&amp;lt;/code&amp;gt;– objects in LSL JSON land are always keyed on STRINGS– you can&#039;t pass numbers even when the string looks like a number. -- [[User:Winter Seale|Winter Seale]] 12:35, 23 January 2014 (PST)&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:Json_usage_in_LSL&amp;diff=1187198</id>
		<title>Talk:Json usage in LSL</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:Json_usage_in_LSL&amp;diff=1187198"/>
		<updated>2014-01-23T20:35:03Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Inconsistent behavior on types */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I am concerned because the JSON format specifies at json.org that you can use escape codes like \u0000 to represent Unicode byte values in strings. But LSL has the ugly habit of censoring and altering strings so that a character with byte value of 0x0000 is removed from the string, and some functions like llSHA1String are essentially broken since they also convert UTF-16 integers between \u0128–\u0255 into UTF-8 byte values starting with %c2 (which therefore have a different integer value due to the addition of the extraneous byte). Is LSL also going to mangle JSON strings&#039; byte values when it renders them into LSL strings? Won&#039;t this corrupt attempts at efficiently verifying the signatures of any incoming messages, and thwart attempts to generate proper signatures for some outgoing JSON-formatted requests? Or do the Lindens have plans to finally give us a proper suite of escape codes in LSL (or some other solution)?&lt;br /&gt;
--[[User:Gistya Eusebio|Gistya Eusebio]] 09:41, 30 May 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
Add to that the complete crash-and-burn if your string starts with a quote, generating invalid JSON. I really don&#039;t get why LL finds it advantageous to include magic switches which forces everybody to do workaround for normal use, and ensures that all future JSON implementations in SL must be hand-coded to keep backwards compatibility with the spec breaks currently implemented.&lt;br /&gt;
[[User:Tali Rosca|Tali Rosca]] 15:50, 19 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
:This sounds like a bug, you should report it. -- &#039;&#039;&#039;[[User:Strife_Onizuka|Strife]]&#039;&#039;&#039; &amp;lt;sup&amp;gt;&amp;lt;small&amp;gt;([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])&amp;lt;/small&amp;gt;&amp;lt;/sup&amp;gt; 21:49, 20 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
::nm I see that you did. {{jira|BUG-2594}} -- &#039;&#039;&#039;[[User:Strife_Onizuka|Strife]]&#039;&#039;&#039; &amp;lt;sup&amp;gt;&amp;lt;small&amp;gt;([[User talk:Strife_Onizuka|talk]]|[[Special:Contributions/Strife_Onizuka|contribs]])&amp;lt;/small&amp;gt;&amp;lt;/sup&amp;gt; 21:50, 20 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
:::I&#039;ve been kicking and screaming about getting a robust JSON handling :-) 2594 got us some way, but we still have {{jira|BUG-2736}}, which I consider so exceedingly ill-advised as to be a bug, despite the insistence that it&#039;s a really awesome feature. [[User:Tali Rosca|Tali Rosca]] 16:39, 21 June 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
::::&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;The trailing quotation mark is the real nasty problem, not the leading one :D But yeah.. if they do add the capability to handle enquoted* text, how would that break anyone&#039;s scripts? Is anyone really relying on enquotation to invalidate their JSON strings on purpose? Besides when has breaking people&#039;s scripts stopped them from doing anything? I have tens of thousands of L$ worth of vehicles that are now worthless due to the Havok 4 update, but hey, life goes on. My copy of Microsoft Word 1.0 for Mac won&#039;t run on Mountain Lion either. I like backwards compatibility but we developers would be out of a job if software never had to be rewritten to work with the ever-evolving platforms that are out there :D &amp;lt;br&amp;gt;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;--[[User:Gistya Eusebio|Gistya Eusebio]] 07:58, 23 June 2013 (PDT) &amp;lt;br&amp;gt;* I know &amp;quot;enquoted&amp;quot; is not in the dictionary. However it is in the lexicon. :D&lt;br /&gt;
:::::A (somewhat kludgy) workaround for the mishandling of escaped characters can now be found [[User:LepreKhaun_Resident/Workaround4Escaped_Chars_within_JsonText|here]]. Hope someone finds this useful.[[User:LepreKhaun Resident|LepreKhaun Resident]] 23:41, 29 August 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I feel the paragraph within &amp;quot;Specifying Json Elements&amp;quot; that begins with &amp;quot;When JSON is presented in human-readable form,...&amp;quot; should be rewritten to show that the JSON string in its entirety is actually the root node of the structure, signified by an empty list used as &amp;quot;specifiers&amp;quot;. [[User:LepreKhaun Resident|LepreKhaun Resident]] 15:23, 6 July 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Unsure of major edit ==&lt;br /&gt;
&lt;br /&gt;
After making the edit on 16:04, 15 August 2013 to correct code examples that wouldn&#039;t compile, I&#039;ve come to realize that the given examples, as well as the surrounding text, is in error since json disallows empty values, as one might find in a &amp;quot;sparse&amp;quot; array.&lt;br /&gt;
&lt;br /&gt;
The author is pointing out &amp;quot;a rare exception&amp;quot; but then uses &amp;quot;{\&amp;quot;parent\&amp;quot;:,}&amp;quot; and &amp;quot;{\&amp;quot;parent\&amp;quot;:[ , ,  , , ]}&amp;quot; to illustrate. Neither of those can be arrived at with llList2Json(), since LSL doesn&#039;t allow empty list elements, but can only be obtained by hand coding to arrive at the non-compliant json strings.&lt;br /&gt;
&lt;br /&gt;
I feel that whole section should be rewritten to simply point out to the reader that they are advised to use llList2Json() in the formation of json strings and avoid hand coding, which may well result in mal-formed constructions that could lead to confusing results in later operations. &lt;br /&gt;
&lt;br /&gt;
However, doing so would excise a number of paragraphs and I&#039;m unsure how that would set with the original author and others. Guidance on this would be appreciated. [[User:LepreKhaun Resident|LepreKhaun Resident]] 05:25, 18 August 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
== JSON example ==&lt;br /&gt;
&lt;br /&gt;
I want to submit a simple, working example on LSL JSON, but I don&#039;t know the right place for it&lt;br /&gt;
:I hope Strife will and can place it, here it is:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
// JSON array forum example by Dora Gustafson, Studio Dora 2013&lt;br /&gt;
// Building an 3 by 5 array in a JSON Object&lt;br /&gt;
// Rows are indexed by name and columns are indexed by number = 0,1,2,3,4&lt;br /&gt;
&lt;br /&gt;
string JSONVotes;&lt;br /&gt;
&lt;br /&gt;
tellVotes( string voter)&lt;br /&gt;
{&lt;br /&gt;
    string Js = llJsonGetValue( JSONVotes, [voter]);&lt;br /&gt;
    list Jl = llParseString2List( Js,[&amp;quot;,&amp;quot;,&amp;quot;[&amp;quot;,&amp;quot;]&amp;quot;,&amp;quot;\&amp;quot;&amp;quot;],[]);&lt;br /&gt;
    string output = llDumpList2String( Jl, &amp;quot;, &amp;quot;);&lt;br /&gt;
    llOwnerSay( &amp;quot;Votes from &amp;quot;+voter+&amp;quot; are: &amp;quot;+output);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {   // Building the JSON object&lt;br /&gt;
        string votes = llList2Json( JSON_ARRAY, [0, 0, 0, 0, 0]); // one row&lt;br /&gt;
        JSONVotes = llList2Json( JSON_OBJECT, [ &amp;quot;Betty&amp;quot;, votes, &amp;quot;Jerry&amp;quot;, votes, &amp;quot;Pierre&amp;quot;, votes]); // complete object&lt;br /&gt;
    }&lt;br /&gt;
    touch_end( integer num)&lt;br /&gt;
    {   // Testing the JSON object&lt;br /&gt;
        tellVotes( &amp;quot;Betty&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Jerry&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Pierre&amp;quot;);&lt;br /&gt;
        // saving some random votes&lt;br /&gt;
        JSONVotes = llJsonSetValue( JSONVotes, [&amp;quot;Betty&amp;quot;, 1], (string)llFrand( 100.0));&lt;br /&gt;
        JSONVotes = llJsonSetValue( JSONVotes, [&amp;quot;Jerry&amp;quot;, 4], (string)llFrand( 100.0));&lt;br /&gt;
        // testing&lt;br /&gt;
        tellVotes( &amp;quot;Betty&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Jerry&amp;quot;);&lt;br /&gt;
        tellVotes( &amp;quot;Pierre&amp;quot;);&lt;br /&gt;
        // getting one vote, example&lt;br /&gt;
        string s = llJsonGetValue( JSONVotes, [&amp;quot;Betty&amp;quot;,1]);&lt;br /&gt;
        llOwnerSay( &amp;quot;Betty votes &amp;quot;+s+&amp;quot; in second column&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;[[User:Dora Gustafson|Dora Gustafson]] 06:23, 25 August 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
== Inconsistent behavior on types ==&lt;br /&gt;
&lt;br /&gt;
The documentation says: if the specifier list element is an integer, then the corresponding element in the json value must be an array and the list element is used as a zero-based index into the Json array.&lt;br /&gt;
&lt;br /&gt;
However, placing integers in a specifier used with a JSON_OBJECT and llJsonGetValue, they are automatically converted to strings.  llList2Json and llJsonSetValue do not automatically convert integers to strings.  Both will result in a JSON_INVALID if you try to put integers on the key side of a JSON_OBJECT.&lt;br /&gt;
&lt;br /&gt;
This example code, according to the documentation shouldn&#039;t even work (I&#039;d presume it&#039;s supposed to return a JSON_INVALID):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;string test = llList2Json(JSON_OBJECT, [&amp;quot;1&amp;quot;, &amp;quot;one&amp;quot;, &amp;quot;2&amp;quot;, &amp;quot;two&amp;quot;, &amp;quot;3&amp;quot;, &amp;quot;three&amp;quot;]);&lt;br /&gt;
llOwnerSay(llJsonGetValue(test, [3]));&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This little sniplet produces &amp;quot;three&amp;quot;.  Additionally, using llJsonValueType in place of llJsonGetValue in the above example will result in JSON_STRING.  Attempting something like &#039;llJsonSetValue(test, [3], &amp;quot;three&amp;quot;);&#039; results in JSON_INVALID.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
[[USER:Chetar Ruby|Chetar Ruby]] 09:15, 14 October 2013 (PDT)&lt;br /&gt;
&lt;br /&gt;
: Yes, that&#039;s because what you meant to say was &amp;lt;code&amp;gt;llJsonSetValue(test, [&amp;quot;3&amp;quot;], &amp;quot;three&amp;quot;)&amp;lt;/code&amp;gt;– objects are always keyed on STRINGS– you can&#039;t pass numbers even when the string looks like a number. -- [[User:Winter Seale|Winter Seale]] 12:35, 23 January 2014 (PST)&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149040</id>
		<title>User:Winter Seale</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149040"/>
		<updated>2011-07-20T04:19:49Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, I occasionally tweak LSL and related programming pages.  You can find me in world or:&lt;br /&gt;
&lt;br /&gt;
* On the web: [http://winterseale.com //winterseale.com]&lt;br /&gt;
* On twitter: [https://twitter.com/winterseale @winterseale]&lt;br /&gt;
* On Google Plus: [http://winterseale.com/g+ //winterseale.com/g+]&lt;br /&gt;
* On Diaspora: [http://winterseale.com/d* //winterseale.com/d*]&lt;br /&gt;
* Via email: [mailto:me@winterseale.com me@winterseale.com]&lt;br /&gt;
* Via Google Talk: winterseale@gmail.com&lt;br /&gt;
* Via AIM: winterseale&lt;br /&gt;
* Via Yahoo: winterseale&lt;br /&gt;
* Via MSN: msn@winterseale.com&lt;br /&gt;
&lt;br /&gt;
{{Tweeter}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149039</id>
		<title>User:Winter Seale</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149039"/>
		<updated>2011-07-20T04:19:28Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, I occasionally tweak LSL and related programming pages.  You can find me in world or:&lt;br /&gt;
&lt;br /&gt;
* On the web: [http://winterseale.com //winterseale.com]&lt;br /&gt;
* On twitter: [https://twitter.com/#!/winterseale @winterseale]&lt;br /&gt;
* On Google Plus: [http://winterseale.com/g+ //winterseale.com/g+]&lt;br /&gt;
* On Diaspora: [http://winterseale.com/d* //winterseale.com/d*]&lt;br /&gt;
* Via email: [mailto:me@winterseale.com me@winterseale.com]&lt;br /&gt;
* Via Google Talk: winterseale@gmail.com&lt;br /&gt;
* Via AIM: winterseale&lt;br /&gt;
* Via Yahoo: winterseale&lt;br /&gt;
* Via MSN: msn@winterseale.com&lt;br /&gt;
&lt;br /&gt;
{{Tweeter}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149038</id>
		<title>User:Winter Seale</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149038"/>
		<updated>2011-07-20T04:19:00Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, I occasionally tweak LSL and related programming pages.  You can find me in world or:&lt;br /&gt;
&lt;br /&gt;
* On the web: [http://winterseale.com //winterseale.com]&lt;br /&gt;
* On twitter: [https://twitter.com/#!/winterseale @winterseale]&lt;br /&gt;
* On Google Plus: [http://winterseale.com/g+ //winterseale.com/g+]&lt;br /&gt;
* On Diaspora: [http://winterseale.com/d* //winterseale.com/d*]&lt;br /&gt;
* Via email: me@winterseale.com&lt;br /&gt;
* Via Google Talk: winterseale@gmail.com&lt;br /&gt;
* Via AIM: winterseale&lt;br /&gt;
* Via Yahoo: winterseale&lt;br /&gt;
* Via MSN: msn@winterseale.com&lt;br /&gt;
&lt;br /&gt;
{{Tweeter}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149037</id>
		<title>User:Winter Seale</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1149037"/>
		<updated>2011-07-20T04:18:06Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, I occasionally tweak LSL and related programming pages.  You can find me in world or:&lt;br /&gt;
&lt;br /&gt;
* On the web: [http://winterseale.com //winterseale.com]&lt;br /&gt;
* On twitter: [https://twitter.com/#!/winterseale @winterseale]&lt;br /&gt;
* On Google Plus: http://winterseale.com/g+&lt;br /&gt;
* On Diaspora: http://winterseale.com/d*&lt;br /&gt;
* Via email: me@winterseale.com&lt;br /&gt;
* Via Google Talk: winterseale@gmail.com&lt;br /&gt;
* Via AIM: winterseale&lt;br /&gt;
* Via Yahoo: winterseale&lt;br /&gt;
* Via MSN: msn@winterseale.com&lt;br /&gt;
&lt;br /&gt;
{{Tweeter}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1145479</id>
		<title>User:Winter Seale</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=User:Winter_Seale&amp;diff=1145479"/>
		<updated>2011-06-06T16:52:48Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Created page with &amp;quot;Hi, I occasionally tweak LSL and related programming pages.  You can find me in world or:  * On the web: http://winterseale.com * On twitter: [https://twitter.com/#!/winterseale …&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Hi, I occasionally tweak LSL and related programming pages.  You can find me in world or:&lt;br /&gt;
&lt;br /&gt;
* On the web: http://winterseale.com&lt;br /&gt;
* On twitter: [https://twitter.com/#!/winterseale @winterseale]&lt;br /&gt;
* Via email: me@winterseale.com&lt;br /&gt;
* Via Google Talk: winterseale@gmail.com&lt;br /&gt;
* Via AIM: winterseale&lt;br /&gt;
* Via Yahoo: winterseale&lt;br /&gt;
* Via MSN: msn@winterseale.com&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145478</id>
		<title>LSL HTTP server/examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145478"/>
		<updated>2011-06-06T16:48:03Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header|ml=*}}&lt;br /&gt;
=== Utility Script ===&lt;br /&gt;
A script intended as a &#039;fill in the blank&#039; exercise for very, very simple HTTP servers is here: [[LSL_http_server/examples/utility_script | Utility Script]]&lt;br /&gt;
=== Hello World! ===&lt;br /&gt;
Classic example, the smallest http_request script possible.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
A slightly more robust version:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Echo World ===&lt;br /&gt;
&amp;quot;Echo World ([[User:Byrd Sciavo|Byrd Sciavo]] 04:19, 7 October 2009 (UTC))&amp;quot; is a slightly more useful &amp;quot;Hello World&amp;quot;, demonstrating a basic server that echos back dynamic data fed. Echo World shows how http_request receives GET variables. To receive this &amp;quot;dynamic echo&amp;quot;, append your cap url with a query string, such as https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry(){&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body){    &lt;br /&gt;
        if (method == URL_REQUEST_GRANTED) {&lt;br /&gt;
            url=body;llOwnerSay(url);&lt;br /&gt;
        }else if(method==&amp;quot;GET&amp;quot;){&lt;br /&gt;
              if(llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;)==&amp;quot;&amp;quot;) llHTTPResponse(id,200,&amp;quot;I ECHO when you append some GET variables to me, e.g., /?var=foo&amp;quot;);&lt;br /&gt;
              else llHTTPResponse(id,200,llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;));&lt;br /&gt;
        }        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visitor List ===&lt;br /&gt;
A list of residents within sensor range of the server.&lt;br /&gt;
&amp;lt;br&amp;gt;Notes:&lt;br /&gt;
* This includes a method for handling multiple requests while waiting for asynchronous data requests to come back.&lt;br /&gt;
&amp;lt;lsl&amp;gt;integer scanning = FALSE;&lt;br /&gt;
&lt;br /&gt;
list requests;&lt;br /&gt;
&lt;br /&gt;
send_response(string body)&lt;br /&gt;
{&lt;br /&gt;
    integer j;&lt;br /&gt;
    for (j = 0; j &amp;lt; llGetListLength(requests); ++j)&lt;br /&gt;
    {&lt;br /&gt;
        llHTTPResponse(llList2Key(requests,j), 200, body);&lt;br /&gt;
    }&lt;br /&gt;
    requests = [];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            if (!scanning)&lt;br /&gt;
            {&lt;br /&gt;
                llSensor(&amp;quot;&amp;quot;,NULL_KEY,AGENT,96,PI);&lt;br /&gt;
                scanning = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            requests += [id];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported method.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    no_sensor()&lt;br /&gt;
    {&lt;br /&gt;
        send_response(&amp;quot;There is no one here.&amp;quot;);&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    sensor(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        string output;&lt;br /&gt;
        if (n &amp;lt; 16) output = &amp;quot;There are &amp;quot; + (string)n + &amp;quot; avatars nearby:&amp;quot;;&lt;br /&gt;
        else output = &amp;quot;There are at least 16 avatars nearby:&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        for (i = 0;i&amp;lt;n;++i)&lt;br /&gt;
        {&lt;br /&gt;
            output += &amp;quot;\n\t&amp;quot; + llDetectedName(i);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        send_response(output);&lt;br /&gt;
&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Url Persistence / Visitor Counter ===&lt;br /&gt;
A more complete &#039;hello world&#039;, always has an url and keeps a visitor counter.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
integer hits;&lt;br /&gt;
&lt;br /&gt;
setup()&lt;br /&gt;
{&lt;br /&gt;
    llSetObjectName(&amp;quot;HTTP Server&amp;quot;);&lt;br /&gt;
    url = &amp;quot;&amp;quot;;&lt;br /&gt;
    llRequestURL();&lt;br /&gt;
    hits = (integer)llGetObjectDesc();&lt;br /&gt;
    llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry() { setup(); }&lt;br /&gt;
    on_rez(integer n) { setup(); }&lt;br /&gt;
    &lt;br /&gt;
    changed(integer c)&lt;br /&gt;
    {&lt;br /&gt;
        if (c &amp;amp; (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT) )&lt;br /&gt;
        {&lt;br /&gt;
            setup();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0,&amp;quot;My url is: &amp;quot; + url);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            url = body;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            ++hits;&lt;br /&gt;
            llSetObjectDesc((string)hits);&lt;br /&gt;
            llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello!  You are visitor &amp;quot; + (string)hits + &amp;quot;.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Method unsupported&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. The first script is the LSL code to receive the information on the grid. The second script is a Perl script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid.  ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL();     // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
     http_request(key id, string method, string body) {&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information from the outside: &amp;quot; + body);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Thank you for calling. All of our operators are busy.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Perl script to contact the prim on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
use LWP;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation) {&lt;br /&gt;
    my( $url, $params ) = @_;&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    id   =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    name =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
print $info,&amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Python code that does the same thing as the PERL code above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    # Set the parameters to be sent.&lt;br /&gt;
    encodedParams =  urllib.urlencode(parameters);&lt;br /&gt;
&lt;br /&gt;
    # Post the data.&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);&lt;br /&gt;
&lt;br /&gt;
    # return the result.&lt;br /&gt;
    return(net.read());&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;}&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST With Argument Parsing ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. In this example the scripts are adapted to handle the parsing of the arguments that are passed. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid. ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
// ###############################################&lt;br /&gt;
// Routine to parse a string sent through the &lt;br /&gt;
// http server via post.&lt;br /&gt;
//       parsePostData(theMessage)&lt;br /&gt;
// Returns a strided list with stride length 2.&lt;br /&gt;
// Each set has the key and then its value.&lt;br /&gt;
list parsePostData(string message) {&lt;br /&gt;
    list postData = [];         // The list with the data that was passed in.&lt;br /&gt;
    list parsedMessage = llParseString2List(message,[&amp;quot;&amp;amp;&amp;quot;],[]);    // The key/value pairs parsed into one list.&lt;br /&gt;
    integer len = ~llGetListLength(parsedMessage);&lt;br /&gt;
&lt;br /&gt;
    while(++len) {          &lt;br /&gt;
        string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string.&lt;br /&gt;
&lt;br /&gt;
        integer split = llSubStringIndex(currentField,&amp;quot;=&amp;quot;);     // Find the &amp;quot;=&amp;quot; sign&lt;br /&gt;
        if(split == -1) { // There is only one field in this part of the message.&lt;br /&gt;
            postData += [llUnescapeURL(currentField),&amp;quot;&amp;quot;];  &lt;br /&gt;
        } else {&lt;br /&gt;
            postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Return the strided list.&lt;br /&gt;
    return postData ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL(); // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_request(key id, string method, string body) {&lt;br /&gt;
         list incomingMessage;&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + &lt;br /&gt;
                       body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information form the outside: &amp;quot; + body);&lt;br /&gt;
            incomingMessage = parsePostData(body);&lt;br /&gt;
            llOwnerSay(llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;You passed the following:\n&amp;quot; + &lt;br /&gt;
                           llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has&lt;br /&gt;
            // not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding PERL script for contacting the LSL script on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
&lt;br /&gt;
use LWP;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation) {&lt;br /&gt;
    my( $url, $params ) = @_;&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    &#039;action&#039; =&amp;gt; &#039;send message&#039;,&lt;br /&gt;
    &#039;value&#039;  =&amp;gt; &#039;Hi there chief!&#039;,&lt;br /&gt;
    &#039;id&#039;     =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    &#039;name&#039;   =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
print($info,&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding Python script. It does the same thing as the Perl script above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    &lt;br /&gt;
#    encodedParams =  urllib.urlencode(parameters);  # encode the parameters&lt;br /&gt;
    encodedParams  = dictionary2URI(parameters);    # encode the parameters&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);        # Post the data.&lt;br /&gt;
    return(net.read());                             # return the result.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ################################################&lt;br /&gt;
# Routine to encode a dictionary without using &lt;br /&gt;
# &amp;quot;+&amp;quot; for spaces.&lt;br /&gt;
#       dictionary2URI(theDictionary)&lt;br /&gt;
def dictionary2URI(theDictionary) : &lt;br /&gt;
&lt;br /&gt;
    encoded = &#039;&#039;;           # Initialize the string to return&lt;br /&gt;
    for key, value in theDictionary.iteritems():&lt;br /&gt;
        # Encode each item in the dictionary.&lt;br /&gt;
        encoded += urllib.quote(key)+&amp;quot;=&amp;quot;+urllib.quote(value)+&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    remove = re.compile(&#039;&amp;amp;$&#039;)             # Remove the trailing ampersand.&lt;br /&gt;
    encoded = remove.sub(&#039;&#039;,encoded);&lt;br /&gt;
&lt;br /&gt;
    return(encoded);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;,&lt;br /&gt;
                  &#039;action&#039;:&#039;send message&#039;,&lt;br /&gt;
                  &#039;value&#039;:&#039;Hey there, hi there, ho there!&#039;};&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;lsl&amp;gt;&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple script for sending data to an LSL via PHP ===&lt;br /&gt;
This example by Simba Fuhr &#039;&#039;&#039;UPDATE April 16, 2011&#039;&#039;&#039;&lt;br /&gt;
{{Warning|Some hosting providers only allow fsockopen on the standard 80 and 443 ports.  This script will not work on those providers. If your provider is willing to open some ports for you, HTTP-in uses port 12046, and HTTPS-in uses port 12043.}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
To use SSL encrypted sockets, you need to have SSL activated on your server. If you run your own server, you need to import the ssl support to your server (apache =&amp;gt; apache.conf  +&amp;quot;LoadModule ssl_module modules/mod_ssl.so&amp;quot;)(normaly based on openssl).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Secure URL Request with LSL.&lt;br /&gt;
Script returns the URL to the chat. Please put the URL into the PHP below.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
 state_entry()&lt;br /&gt;
 {&lt;br /&gt;
  llRequestSecureURL();&lt;br /&gt;
 }&lt;br /&gt;
 http_request(key id, string method, string body)&lt;br /&gt;
 {&lt;br /&gt;
  if ((method == URL_REQUEST_GRANTED))&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
  }&lt;br /&gt;
  else if (method == &amp;quot;POST&amp;quot;)&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
   llHTTPResponse(id, 200, &amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the PHP.&lt;br /&gt;
A more advanced php function which supports complete url structures and automatical GET and POST types.&lt;br /&gt;
Just don&#039;t submit any post Data to make a GET request.&lt;br /&gt;
The Function supports any kind of url as secure and not secure (https and http).&lt;br /&gt;
If you dont submit a port in the url, the default port for http (80) and https (443) will be used.&lt;br /&gt;
(An example is shown on the top of the script.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo &amp;quot;LSL Script answered:&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
echo Advanced_HTTP_Request(&amp;quot;https://sim20557.agni.lindenlab.com:12043/cap/5851e666-b0c6-f0a0-758a-9e8156765215&amp;quot;, &amp;quot;Hello script, how are you ?&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
function Advanced_HTTP_Request($Host, $PostData = &amp;quot;&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
 $Method = &amp;quot;POST&amp;quot;;&lt;br /&gt;
 if (empty($PostData))&lt;br /&gt;
  {$Method = &amp;quot;GET&amp;quot;;}&lt;br /&gt;
 $Port = 80;&lt;br /&gt;
 if (strtolower(substr($Host, 0, 5)) == &amp;quot;https&amp;quot;)&lt;br /&gt;
  {$Port = 443;}&lt;br /&gt;
 $Host = explode(&amp;quot;//&amp;quot;, $Host, 2);&lt;br /&gt;
 if (count($Host) &amp;lt; 2)&lt;br /&gt;
  {$Host[1] = $Host[0];}&lt;br /&gt;
 $Host = explode(&amp;quot;/&amp;quot;, $Host[1], 2);&lt;br /&gt;
 if ($Port == 443)&lt;br /&gt;
  {$SSLAdd = &amp;quot;ssl://&amp;quot;;}&lt;br /&gt;
 $Host[0] = explode(&amp;quot;:&amp;quot;, $Host[0]);&lt;br /&gt;
 if (count($Host[0]) &amp;gt; 1)&lt;br /&gt;
 {&lt;br /&gt;
  $Port = $Host[0][1];&lt;br /&gt;
  $Host[0] = $Host[0][0];&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
  {$Host[0] = $Host[0][0];}&lt;br /&gt;
 $Socket = fsockopen($SSLAdd.$Host[0], $Port, $Dummy1, $Dummy2, 10);&lt;br /&gt;
 if ($Socket)&lt;br /&gt;
 {&lt;br /&gt;
  fputs($Socket, &amp;quot;$Method /$Host[1] HTTP/1.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Host: $Host[0]\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-type: application/x-www-form-urlencoded\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-length: &amp;quot;.strlen($PostData).&amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Connection: close\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 $PostData);&lt;br /&gt;
  $Tme = time();&lt;br /&gt;
  while(!feof($Socket) &amp;amp;&amp;amp; $Tme + 30 &amp;gt; time())&lt;br /&gt;
   {$Res = $Res.fgets($Socket, 256);}&lt;br /&gt;
  fclose($Socket);&lt;br /&gt;
 }&lt;br /&gt;
 $Res = explode(&amp;quot;\r\n\r\n&amp;quot;, $Res, 2);&lt;br /&gt;
 return $Res[1];&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kelly&#039;s Stupid Web Status Updater ===&lt;br /&gt;
Is actually on its own page: [[LSL_http_server/examples/kellys_stupid_web_status_updater | Kelly&#039;s Stupid Web Status Updater]]&amp;lt;br&amp;gt;&lt;br /&gt;
Kurai&#039;s mod from Kelly&#039;s stupid thing: [[LSL_http_server/examples/kurais_stupid_web_status_updater| Kurai&#039;s Stupid Web Status Updater Mod]]&lt;br /&gt;
{{LSLC|HTTP}}{{LSLC|Examples}}&lt;br /&gt;
&lt;br /&gt;
=== Web-based dynamic buildings ===&lt;br /&gt;
HTTP-in may be used to easily send commands from a web page to an in-world object, so that web users can control and interact with buildings. The interactive installation &#039;&#039;Chromutate&#039;&#039; is based upon this idea: see its [[User:Opensource_Obscure/Chromutate|documentation page]] for free scripts and more details.&lt;br /&gt;
&lt;br /&gt;
=== PHP/SQL Object DNS ===&lt;br /&gt;
Simple DNS server written in PHP to facilitate a DNS service for LSL scripts&lt;br /&gt;
[[LSL_http_server/examples/phpdns|PHPDNS]]&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145477</id>
		<title>LSL HTTP server/examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145477"/>
		<updated>2011-06-06T16:43:14Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Perl/Python Examples Using POST */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header|ml=*}}&lt;br /&gt;
=== Utility Script ===&lt;br /&gt;
A script intended as a &#039;fill in the blank&#039; exercise for very, very simple HTTP servers is here: [[LSL_http_server/examples/utility_script | Utility Script]]&lt;br /&gt;
=== Hello World! ===&lt;br /&gt;
Classic example, the smallest http_request script possible.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
A slightly more robust version:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Echo World ===&lt;br /&gt;
&amp;quot;Echo World ([[User:Byrd Sciavo|Byrd Sciavo]] 04:19, 7 October 2009 (UTC))&amp;quot; is a slightly more useful &amp;quot;Hello World&amp;quot;, demonstrating a basic server that echos back dynamic data fed. Echo World shows how http_request receives GET variables. To receive this &amp;quot;dynamic echo&amp;quot;, append your cap url with a query string, such as https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry(){&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body){    &lt;br /&gt;
        if (method == URL_REQUEST_GRANTED) {&lt;br /&gt;
            url=body;llOwnerSay(url);&lt;br /&gt;
        }else if(method==&amp;quot;GET&amp;quot;){&lt;br /&gt;
              if(llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;)==&amp;quot;&amp;quot;) llHTTPResponse(id,200,&amp;quot;I ECHO when you append some GET variables to me, e.g., /?var=foo&amp;quot;);&lt;br /&gt;
              else llHTTPResponse(id,200,llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;));&lt;br /&gt;
        }        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visitor List ===&lt;br /&gt;
A list of residents within sensor range of the server.&lt;br /&gt;
&amp;lt;br&amp;gt;Notes:&lt;br /&gt;
* This includes a method for handling multiple requests while waiting for asynchronous data requests to come back.&lt;br /&gt;
&amp;lt;lsl&amp;gt;integer scanning = FALSE;&lt;br /&gt;
&lt;br /&gt;
list requests;&lt;br /&gt;
&lt;br /&gt;
send_response(string body)&lt;br /&gt;
{&lt;br /&gt;
    integer j;&lt;br /&gt;
    for (j = 0; j &amp;lt; llGetListLength(requests); ++j)&lt;br /&gt;
    {&lt;br /&gt;
        llHTTPResponse(llList2Key(requests,j), 200, body);&lt;br /&gt;
    }&lt;br /&gt;
    requests = [];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            if (!scanning)&lt;br /&gt;
            {&lt;br /&gt;
                llSensor(&amp;quot;&amp;quot;,NULL_KEY,AGENT,96,PI);&lt;br /&gt;
                scanning = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            requests += [id];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported method.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    no_sensor()&lt;br /&gt;
    {&lt;br /&gt;
        send_response(&amp;quot;There is no one here.&amp;quot;);&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    sensor(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        string output;&lt;br /&gt;
        if (n &amp;lt; 16) output = &amp;quot;There are &amp;quot; + (string)n + &amp;quot; avatars nearby:&amp;quot;;&lt;br /&gt;
        else output = &amp;quot;There are at least 16 avatars nearby:&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        for (i = 0;i&amp;lt;n;++i)&lt;br /&gt;
        {&lt;br /&gt;
            output += &amp;quot;\n\t&amp;quot; + llDetectedName(i);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        send_response(output);&lt;br /&gt;
&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Url Persistence / Visitor Counter ===&lt;br /&gt;
A more complete &#039;hello world&#039;, always has an url and keeps a visitor counter.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
integer hits;&lt;br /&gt;
&lt;br /&gt;
setup()&lt;br /&gt;
{&lt;br /&gt;
    llSetObjectName(&amp;quot;HTTP Server&amp;quot;);&lt;br /&gt;
    url = &amp;quot;&amp;quot;;&lt;br /&gt;
    llRequestURL();&lt;br /&gt;
    hits = (integer)llGetObjectDesc();&lt;br /&gt;
    llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry() { setup(); }&lt;br /&gt;
    on_rez(integer n) { setup(); }&lt;br /&gt;
    &lt;br /&gt;
    changed(integer c)&lt;br /&gt;
    {&lt;br /&gt;
        if (c &amp;amp; (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT) )&lt;br /&gt;
        {&lt;br /&gt;
            setup();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0,&amp;quot;My url is: &amp;quot; + url);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            url = body;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            ++hits;&lt;br /&gt;
            llSetObjectDesc((string)hits);&lt;br /&gt;
            llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello!  You are visitor &amp;quot; + (string)hits + &amp;quot;.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Method unsupported&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. The first script is the LSL code to receive the information on the grid. The second script is a Perl script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid.  ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL();     // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
     http_request(key id, string method, string body) {&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information from the outside: &amp;quot; + body);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Thank you for calling. All of our operators are busy.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Perl script to contact the prim on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
use LWP;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation($url,$params) {&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    id   =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    name =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
print $info,&amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Python code that does the same thing as the PERL code above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    # Set the parameters to be sent.&lt;br /&gt;
    encodedParams =  urllib.urlencode(parameters);&lt;br /&gt;
&lt;br /&gt;
    # Post the data.&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);&lt;br /&gt;
&lt;br /&gt;
    # return the result.&lt;br /&gt;
    return(net.read());&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;}&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST With Argument Parsing ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. In this example the scripts are adapted to handle the parsing of the arguments that are passed. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid. ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
// ###############################################&lt;br /&gt;
// Routine to parse a string sent through the &lt;br /&gt;
// http server via post.&lt;br /&gt;
//       parsePostData(theMessage)&lt;br /&gt;
// Returns a strided list with stride length 2.&lt;br /&gt;
// Each set has the key and then its value.&lt;br /&gt;
list parsePostData(string message) {&lt;br /&gt;
    list postData = [];         // The list with the data that was passed in.&lt;br /&gt;
    list parsedMessage = llParseString2List(message,[&amp;quot;&amp;amp;&amp;quot;],[]);    // The key/value pairs parsed into one list.&lt;br /&gt;
    integer len = ~llGetListLength(parsedMessage);&lt;br /&gt;
&lt;br /&gt;
    while(++len) {          &lt;br /&gt;
        string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string.&lt;br /&gt;
&lt;br /&gt;
        integer split = llSubStringIndex(currentField,&amp;quot;=&amp;quot;);     // Find the &amp;quot;=&amp;quot; sign&lt;br /&gt;
        if(split == -1) { // There is only one field in this part of the message.&lt;br /&gt;
            postData += [llUnescapeURL(currentField),&amp;quot;&amp;quot;];  &lt;br /&gt;
        } else {&lt;br /&gt;
            postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Return the strided list.&lt;br /&gt;
    return postData ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL(); // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_request(key id, string method, string body) {&lt;br /&gt;
         list incomingMessage;&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + &lt;br /&gt;
                       body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information form the outside: &amp;quot; + body);&lt;br /&gt;
            incomingMessage = parsePostData(body);&lt;br /&gt;
            llOwnerSay(llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;You passed the following:\n&amp;quot; + &lt;br /&gt;
                           llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has&lt;br /&gt;
            // not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding PERL script for contacting the LSL script on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
&lt;br /&gt;
use LWP;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation($url,$params) {&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    &#039;action&#039; =&amp;gt; &#039;send message&#039;,&lt;br /&gt;
    &#039;value&#039;  =&amp;gt; &#039;Hi there chief!&#039;,&lt;br /&gt;
    &#039;id&#039;     =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    &#039;name&#039;   =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
print($info,&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding Python script. It does the same thing as the Perl script above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    &lt;br /&gt;
#    encodedParams =  urllib.urlencode(parameters);  # encode the parameters&lt;br /&gt;
    encodedParams  = dictionary2URI(parameters);    # encode the parameters&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);        # Post the data.&lt;br /&gt;
    return(net.read());                             # return the result.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ################################################&lt;br /&gt;
# Routine to encode a dictionary without using &lt;br /&gt;
# &amp;quot;+&amp;quot; for spaces.&lt;br /&gt;
#       dictionary2URI(theDictionary)&lt;br /&gt;
def dictionary2URI(theDictionary) : &lt;br /&gt;
&lt;br /&gt;
    encoded = &#039;&#039;;           # Initialize the string to return&lt;br /&gt;
    for key, value in theDictionary.iteritems():&lt;br /&gt;
        # Encode each item in the dictionary.&lt;br /&gt;
        encoded += urllib.quote(key)+&amp;quot;=&amp;quot;+urllib.quote(value)+&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    remove = re.compile(&#039;&amp;amp;$&#039;)             # Remove the trailing ampersand.&lt;br /&gt;
    encoded = remove.sub(&#039;&#039;,encoded);&lt;br /&gt;
&lt;br /&gt;
    return(encoded);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;,&lt;br /&gt;
                  &#039;action&#039;:&#039;send message&#039;,&lt;br /&gt;
                  &#039;value&#039;:&#039;Hey there, hi there, ho there!&#039;};&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;lsl&amp;gt;&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple script for sending data to an LSL via PHP ===&lt;br /&gt;
This example by Simba Fuhr &#039;&#039;&#039;UPDATE April 16, 2011&#039;&#039;&#039;&lt;br /&gt;
{{Warning|Some hosting providers only allow fsockopen on the standard 80 and 443 ports.  This script will not work on those providers. If your provider is willing to open some ports for you, HTTP-in uses port 12046, and HTTPS-in uses port 12043.}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
To use SSL encrypted sockets, you need to have SSL activated on your server. If you run your own server, you need to import the ssl support to your server (apache =&amp;gt; apache.conf  +&amp;quot;LoadModule ssl_module modules/mod_ssl.so&amp;quot;)(normaly based on openssl).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Secure URL Request with LSL.&lt;br /&gt;
Script returns the URL to the chat. Please put the URL into the PHP below.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
 state_entry()&lt;br /&gt;
 {&lt;br /&gt;
  llRequestSecureURL();&lt;br /&gt;
 }&lt;br /&gt;
 http_request(key id, string method, string body)&lt;br /&gt;
 {&lt;br /&gt;
  if ((method == URL_REQUEST_GRANTED))&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
  }&lt;br /&gt;
  else if (method == &amp;quot;POST&amp;quot;)&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
   llHTTPResponse(id, 200, &amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the PHP.&lt;br /&gt;
A more advanced php function which supports complete url structures and automatical GET and POST types.&lt;br /&gt;
Just don&#039;t submit any post Data to make a GET request.&lt;br /&gt;
The Function supports any kind of url as secure and not secure (https and http).&lt;br /&gt;
If you dont submit a port in the url, the default port for http (80) and https (443) will be used.&lt;br /&gt;
(An example is shown on the top of the script.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo &amp;quot;LSL Script answered:&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
echo Advanced_HTTP_Request(&amp;quot;https://sim20557.agni.lindenlab.com:12043/cap/5851e666-b0c6-f0a0-758a-9e8156765215&amp;quot;, &amp;quot;Hello script, how are you ?&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
function Advanced_HTTP_Request($Host, $PostData = &amp;quot;&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
 $Method = &amp;quot;POST&amp;quot;;&lt;br /&gt;
 if (empty($PostData))&lt;br /&gt;
  {$Method = &amp;quot;GET&amp;quot;;}&lt;br /&gt;
 $Port = 80;&lt;br /&gt;
 if (strtolower(substr($Host, 0, 5)) == &amp;quot;https&amp;quot;)&lt;br /&gt;
  {$Port = 443;}&lt;br /&gt;
 $Host = explode(&amp;quot;//&amp;quot;, $Host, 2);&lt;br /&gt;
 if (count($Host) &amp;lt; 2)&lt;br /&gt;
  {$Host[1] = $Host[0];}&lt;br /&gt;
 $Host = explode(&amp;quot;/&amp;quot;, $Host[1], 2);&lt;br /&gt;
 if ($Port == 443)&lt;br /&gt;
  {$SSLAdd = &amp;quot;ssl://&amp;quot;;}&lt;br /&gt;
 $Host[0] = explode(&amp;quot;:&amp;quot;, $Host[0]);&lt;br /&gt;
 if (count($Host[0]) &amp;gt; 1)&lt;br /&gt;
 {&lt;br /&gt;
  $Port = $Host[0][1];&lt;br /&gt;
  $Host[0] = $Host[0][0];&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
  {$Host[0] = $Host[0][0];}&lt;br /&gt;
 $Socket = fsockopen($SSLAdd.$Host[0], $Port, $Dummy1, $Dummy2, 10);&lt;br /&gt;
 if ($Socket)&lt;br /&gt;
 {&lt;br /&gt;
  fputs($Socket, &amp;quot;$Method /$Host[1] HTTP/1.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Host: $Host[0]\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-type: application/x-www-form-urlencoded\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-length: &amp;quot;.strlen($PostData).&amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Connection: close\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 $PostData);&lt;br /&gt;
  $Tme = time();&lt;br /&gt;
  while(!feof($Socket) &amp;amp;&amp;amp; $Tme + 30 &amp;gt; time())&lt;br /&gt;
   {$Res = $Res.fgets($Socket, 256);}&lt;br /&gt;
  fclose($Socket);&lt;br /&gt;
 }&lt;br /&gt;
 $Res = explode(&amp;quot;\r\n\r\n&amp;quot;, $Res, 2);&lt;br /&gt;
 return $Res[1];&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kelly&#039;s Stupid Web Status Updater ===&lt;br /&gt;
Is actually on its own page: [[LSL_http_server/examples/kellys_stupid_web_status_updater | Kelly&#039;s Stupid Web Status Updater]]&amp;lt;br&amp;gt;&lt;br /&gt;
Kurai&#039;s mod from Kelly&#039;s stupid thing: [[LSL_http_server/examples/kurais_stupid_web_status_updater| Kurai&#039;s Stupid Web Status Updater Mod]]&lt;br /&gt;
{{LSLC|HTTP}}{{LSLC|Examples}}&lt;br /&gt;
&lt;br /&gt;
=== Web-based dynamic buildings ===&lt;br /&gt;
HTTP-in may be used to easily send commands from a web page to an in-world object, so that web users can control and interact with buildings. The interactive installation &#039;&#039;Chromutate&#039;&#039; is based upon this idea: see its [[User:Opensource_Obscure/Chromutate|documentation page]] for free scripts and more details.&lt;br /&gt;
&lt;br /&gt;
=== PHP/SQL Object DNS ===&lt;br /&gt;
Simple DNS server written in PHP to facilitate a DNS service for LSL scripts&lt;br /&gt;
[[LSL_http_server/examples/phpdns|PHPDNS]]&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145476</id>
		<title>LSL HTTP server/examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145476"/>
		<updated>2011-06-06T16:42:36Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Perl/Python Examples Using POST With Argument Parsing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header|ml=*}}&lt;br /&gt;
=== Utility Script ===&lt;br /&gt;
A script intended as a &#039;fill in the blank&#039; exercise for very, very simple HTTP servers is here: [[LSL_http_server/examples/utility_script | Utility Script]]&lt;br /&gt;
=== Hello World! ===&lt;br /&gt;
Classic example, the smallest http_request script possible.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
A slightly more robust version:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Echo World ===&lt;br /&gt;
&amp;quot;Echo World ([[User:Byrd Sciavo|Byrd Sciavo]] 04:19, 7 October 2009 (UTC))&amp;quot; is a slightly more useful &amp;quot;Hello World&amp;quot;, demonstrating a basic server that echos back dynamic data fed. Echo World shows how http_request receives GET variables. To receive this &amp;quot;dynamic echo&amp;quot;, append your cap url with a query string, such as https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry(){&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body){    &lt;br /&gt;
        if (method == URL_REQUEST_GRANTED) {&lt;br /&gt;
            url=body;llOwnerSay(url);&lt;br /&gt;
        }else if(method==&amp;quot;GET&amp;quot;){&lt;br /&gt;
              if(llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;)==&amp;quot;&amp;quot;) llHTTPResponse(id,200,&amp;quot;I ECHO when you append some GET variables to me, e.g., /?var=foo&amp;quot;);&lt;br /&gt;
              else llHTTPResponse(id,200,llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;));&lt;br /&gt;
        }        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visitor List ===&lt;br /&gt;
A list of residents within sensor range of the server.&lt;br /&gt;
&amp;lt;br&amp;gt;Notes:&lt;br /&gt;
* This includes a method for handling multiple requests while waiting for asynchronous data requests to come back.&lt;br /&gt;
&amp;lt;lsl&amp;gt;integer scanning = FALSE;&lt;br /&gt;
&lt;br /&gt;
list requests;&lt;br /&gt;
&lt;br /&gt;
send_response(string body)&lt;br /&gt;
{&lt;br /&gt;
    integer j;&lt;br /&gt;
    for (j = 0; j &amp;lt; llGetListLength(requests); ++j)&lt;br /&gt;
    {&lt;br /&gt;
        llHTTPResponse(llList2Key(requests,j), 200, body);&lt;br /&gt;
    }&lt;br /&gt;
    requests = [];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            if (!scanning)&lt;br /&gt;
            {&lt;br /&gt;
                llSensor(&amp;quot;&amp;quot;,NULL_KEY,AGENT,96,PI);&lt;br /&gt;
                scanning = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            requests += [id];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported method.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    no_sensor()&lt;br /&gt;
    {&lt;br /&gt;
        send_response(&amp;quot;There is no one here.&amp;quot;);&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    sensor(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        string output;&lt;br /&gt;
        if (n &amp;lt; 16) output = &amp;quot;There are &amp;quot; + (string)n + &amp;quot; avatars nearby:&amp;quot;;&lt;br /&gt;
        else output = &amp;quot;There are at least 16 avatars nearby:&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        for (i = 0;i&amp;lt;n;++i)&lt;br /&gt;
        {&lt;br /&gt;
            output += &amp;quot;\n\t&amp;quot; + llDetectedName(i);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        send_response(output);&lt;br /&gt;
&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Url Persistence / Visitor Counter ===&lt;br /&gt;
A more complete &#039;hello world&#039;, always has an url and keeps a visitor counter.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
integer hits;&lt;br /&gt;
&lt;br /&gt;
setup()&lt;br /&gt;
{&lt;br /&gt;
    llSetObjectName(&amp;quot;HTTP Server&amp;quot;);&lt;br /&gt;
    url = &amp;quot;&amp;quot;;&lt;br /&gt;
    llRequestURL();&lt;br /&gt;
    hits = (integer)llGetObjectDesc();&lt;br /&gt;
    llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry() { setup(); }&lt;br /&gt;
    on_rez(integer n) { setup(); }&lt;br /&gt;
    &lt;br /&gt;
    changed(integer c)&lt;br /&gt;
    {&lt;br /&gt;
        if (c &amp;amp; (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT) )&lt;br /&gt;
        {&lt;br /&gt;
            setup();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0,&amp;quot;My url is: &amp;quot; + url);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            url = body;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            ++hits;&lt;br /&gt;
            llSetObjectDesc((string)hits);&lt;br /&gt;
            llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello!  You are visitor &amp;quot; + (string)hits + &amp;quot;.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Method unsupported&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. The first script is the LSL code to receive the information on the grid. The second script is a Perl script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid.  ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL();     // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
     http_request(key id, string method, string body) {&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information from the outside: &amp;quot; + body);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Thank you for calling. All of our operators are busy.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Perl script to contact the prim on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
&lt;br /&gt;
use LWP;&lt;br /&gt;
use strict;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation($url,$params) {&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    id   =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    name =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
print $info,&amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Python code that does the same thing as the PERL code above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    # Set the parameters to be sent.&lt;br /&gt;
    encodedParams =  urllib.urlencode(parameters);&lt;br /&gt;
&lt;br /&gt;
    # Post the data.&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);&lt;br /&gt;
&lt;br /&gt;
    # return the result.&lt;br /&gt;
    return(net.read());&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;}&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST With Argument Parsing ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. In this example the scripts are adapted to handle the parsing of the arguments that are passed. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid. ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
// ###############################################&lt;br /&gt;
// Routine to parse a string sent through the &lt;br /&gt;
// http server via post.&lt;br /&gt;
//       parsePostData(theMessage)&lt;br /&gt;
// Returns a strided list with stride length 2.&lt;br /&gt;
// Each set has the key and then its value.&lt;br /&gt;
list parsePostData(string message) {&lt;br /&gt;
    list postData = [];         // The list with the data that was passed in.&lt;br /&gt;
    list parsedMessage = llParseString2List(message,[&amp;quot;&amp;amp;&amp;quot;],[]);    // The key/value pairs parsed into one list.&lt;br /&gt;
    integer len = ~llGetListLength(parsedMessage);&lt;br /&gt;
&lt;br /&gt;
    while(++len) {          &lt;br /&gt;
        string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string.&lt;br /&gt;
&lt;br /&gt;
        integer split = llSubStringIndex(currentField,&amp;quot;=&amp;quot;);     // Find the &amp;quot;=&amp;quot; sign&lt;br /&gt;
        if(split == -1) { // There is only one field in this part of the message.&lt;br /&gt;
            postData += [llUnescapeURL(currentField),&amp;quot;&amp;quot;];  &lt;br /&gt;
        } else {&lt;br /&gt;
            postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Return the strided list.&lt;br /&gt;
    return postData ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL(); // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_request(key id, string method, string body) {&lt;br /&gt;
         list incomingMessage;&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + &lt;br /&gt;
                       body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information form the outside: &amp;quot; + body);&lt;br /&gt;
            incomingMessage = parsePostData(body);&lt;br /&gt;
            llOwnerSay(llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;You passed the following:\n&amp;quot; + &lt;br /&gt;
                           llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has&lt;br /&gt;
            // not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding PERL script for contacting the LSL script on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
use strict;&lt;br /&gt;
use warnings;&lt;br /&gt;
&lt;br /&gt;
use LWP;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation($url,$params) {&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    &#039;action&#039; =&amp;gt; &#039;send message&#039;,&lt;br /&gt;
    &#039;value&#039;  =&amp;gt; &#039;Hi there chief!&#039;,&lt;br /&gt;
    &#039;id&#039;     =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    &#039;name&#039;   =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
print($info,&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding Python script. It does the same thing as the Perl script above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    &lt;br /&gt;
#    encodedParams =  urllib.urlencode(parameters);  # encode the parameters&lt;br /&gt;
    encodedParams  = dictionary2URI(parameters);    # encode the parameters&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);        # Post the data.&lt;br /&gt;
    return(net.read());                             # return the result.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ################################################&lt;br /&gt;
# Routine to encode a dictionary without using &lt;br /&gt;
# &amp;quot;+&amp;quot; for spaces.&lt;br /&gt;
#       dictionary2URI(theDictionary)&lt;br /&gt;
def dictionary2URI(theDictionary) : &lt;br /&gt;
&lt;br /&gt;
    encoded = &#039;&#039;;           # Initialize the string to return&lt;br /&gt;
    for key, value in theDictionary.iteritems():&lt;br /&gt;
        # Encode each item in the dictionary.&lt;br /&gt;
        encoded += urllib.quote(key)+&amp;quot;=&amp;quot;+urllib.quote(value)+&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    remove = re.compile(&#039;&amp;amp;$&#039;)             # Remove the trailing ampersand.&lt;br /&gt;
    encoded = remove.sub(&#039;&#039;,encoded);&lt;br /&gt;
&lt;br /&gt;
    return(encoded);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;,&lt;br /&gt;
                  &#039;action&#039;:&#039;send message&#039;,&lt;br /&gt;
                  &#039;value&#039;:&#039;Hey there, hi there, ho there!&#039;};&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;lsl&amp;gt;&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Simple script for sending data to an LSL via PHP ===&lt;br /&gt;
This example by Simba Fuhr &#039;&#039;&#039;UPDATE April 16, 2011&#039;&#039;&#039;&lt;br /&gt;
{{Warning|Some hosting providers only allow fsockopen on the standard 80 and 443 ports.  This script will not work on those providers. If your provider is willing to open some ports for you, HTTP-in uses port 12046, and HTTPS-in uses port 12043.}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
To use SSL encrypted sockets, you need to have SSL activated on your server. If you run your own server, you need to import the ssl support to your server (apache =&amp;gt; apache.conf  +&amp;quot;LoadModule ssl_module modules/mod_ssl.so&amp;quot;)(normaly based on openssl).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Secure URL Request with LSL.&lt;br /&gt;
Script returns the URL to the chat. Please put the URL into the PHP below.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
 state_entry()&lt;br /&gt;
 {&lt;br /&gt;
  llRequestSecureURL();&lt;br /&gt;
 }&lt;br /&gt;
 http_request(key id, string method, string body)&lt;br /&gt;
 {&lt;br /&gt;
  if ((method == URL_REQUEST_GRANTED))&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
  }&lt;br /&gt;
  else if (method == &amp;quot;POST&amp;quot;)&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
   llHTTPResponse(id, 200, &amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the PHP.&lt;br /&gt;
A more advanced php function which supports complete url structures and automatical GET and POST types.&lt;br /&gt;
Just don&#039;t submit any post Data to make a GET request.&lt;br /&gt;
The Function supports any kind of url as secure and not secure (https and http).&lt;br /&gt;
If you dont submit a port in the url, the default port for http (80) and https (443) will be used.&lt;br /&gt;
(An example is shown on the top of the script.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo &amp;quot;LSL Script answered:&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
echo Advanced_HTTP_Request(&amp;quot;https://sim20557.agni.lindenlab.com:12043/cap/5851e666-b0c6-f0a0-758a-9e8156765215&amp;quot;, &amp;quot;Hello script, how are you ?&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
function Advanced_HTTP_Request($Host, $PostData = &amp;quot;&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
 $Method = &amp;quot;POST&amp;quot;;&lt;br /&gt;
 if (empty($PostData))&lt;br /&gt;
  {$Method = &amp;quot;GET&amp;quot;;}&lt;br /&gt;
 $Port = 80;&lt;br /&gt;
 if (strtolower(substr($Host, 0, 5)) == &amp;quot;https&amp;quot;)&lt;br /&gt;
  {$Port = 443;}&lt;br /&gt;
 $Host = explode(&amp;quot;//&amp;quot;, $Host, 2);&lt;br /&gt;
 if (count($Host) &amp;lt; 2)&lt;br /&gt;
  {$Host[1] = $Host[0];}&lt;br /&gt;
 $Host = explode(&amp;quot;/&amp;quot;, $Host[1], 2);&lt;br /&gt;
 if ($Port == 443)&lt;br /&gt;
  {$SSLAdd = &amp;quot;ssl://&amp;quot;;}&lt;br /&gt;
 $Host[0] = explode(&amp;quot;:&amp;quot;, $Host[0]);&lt;br /&gt;
 if (count($Host[0]) &amp;gt; 1)&lt;br /&gt;
 {&lt;br /&gt;
  $Port = $Host[0][1];&lt;br /&gt;
  $Host[0] = $Host[0][0];&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
  {$Host[0] = $Host[0][0];}&lt;br /&gt;
 $Socket = fsockopen($SSLAdd.$Host[0], $Port, $Dummy1, $Dummy2, 10);&lt;br /&gt;
 if ($Socket)&lt;br /&gt;
 {&lt;br /&gt;
  fputs($Socket, &amp;quot;$Method /$Host[1] HTTP/1.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Host: $Host[0]\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-type: application/x-www-form-urlencoded\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-length: &amp;quot;.strlen($PostData).&amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Connection: close\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 $PostData);&lt;br /&gt;
  $Tme = time();&lt;br /&gt;
  while(!feof($Socket) &amp;amp;&amp;amp; $Tme + 30 &amp;gt; time())&lt;br /&gt;
   {$Res = $Res.fgets($Socket, 256);}&lt;br /&gt;
  fclose($Socket);&lt;br /&gt;
 }&lt;br /&gt;
 $Res = explode(&amp;quot;\r\n\r\n&amp;quot;, $Res, 2);&lt;br /&gt;
 return $Res[1];&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kelly&#039;s Stupid Web Status Updater ===&lt;br /&gt;
Is actually on its own page: [[LSL_http_server/examples/kellys_stupid_web_status_updater | Kelly&#039;s Stupid Web Status Updater]]&amp;lt;br&amp;gt;&lt;br /&gt;
Kurai&#039;s mod from Kelly&#039;s stupid thing: [[LSL_http_server/examples/kurais_stupid_web_status_updater| Kurai&#039;s Stupid Web Status Updater Mod]]&lt;br /&gt;
{{LSLC|HTTP}}{{LSLC|Examples}}&lt;br /&gt;
&lt;br /&gt;
=== Web-based dynamic buildings ===&lt;br /&gt;
HTTP-in may be used to easily send commands from a web page to an in-world object, so that web users can control and interact with buildings. The interactive installation &#039;&#039;Chromutate&#039;&#039; is based upon this idea: see its [[User:Opensource_Obscure/Chromutate|documentation page]] for free scripts and more details.&lt;br /&gt;
&lt;br /&gt;
=== PHP/SQL Object DNS ===&lt;br /&gt;
Simple DNS server written in PHP to facilitate a DNS service for LSL scripts&lt;br /&gt;
[[LSL_http_server/examples/phpdns|PHPDNS]]&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145472</id>
		<title>LSL HTTP server/examples</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_HTTP_server/examples&amp;diff=1145472"/>
		<updated>2011-06-06T16:14:06Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Improved Perl, removing duplication of methods provided by the libraries already used, and vastly simplifying the result.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL Header|ml=*}}&lt;br /&gt;
=== Utility Script ===&lt;br /&gt;
A script intended as a &#039;fill in the blank&#039; exercise for very, very simple HTTP servers is here: [[LSL_http_server/examples/utility_script | Utility Script]]&lt;br /&gt;
=== Hello World! ===&lt;br /&gt;
Classic example, the smallest http_request script possible.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
A slightly more robust version:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello World!&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Echo World ===&lt;br /&gt;
&amp;quot;Echo World ([[User:Byrd Sciavo|Byrd Sciavo]] 04:19, 7 October 2009 (UTC))&amp;quot; is a slightly more useful &amp;quot;Hello World&amp;quot;, demonstrating a basic server that echos back dynamic data fed. Echo World shows how http_request receives GET variables. To receive this &amp;quot;dynamic echo&amp;quot;, append your cap url with a query string, such as https://sim3015.aditi.lindenlab.com:12043/cap/a7717681-2c04-e4ac-35e3-1f01c9861322/foo/bar?arg=gra&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry(){&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_request(key id, string method, string body){    &lt;br /&gt;
        if (method == URL_REQUEST_GRANTED) {&lt;br /&gt;
            url=body;llOwnerSay(url);&lt;br /&gt;
        }else if(method==&amp;quot;GET&amp;quot;){&lt;br /&gt;
              if(llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;)==&amp;quot;&amp;quot;) llHTTPResponse(id,200,&amp;quot;I ECHO when you append some GET variables to me, e.g., /?var=foo&amp;quot;);&lt;br /&gt;
              else llHTTPResponse(id,200,llGetHTTPHeader(id,&amp;quot;x-query-string&amp;quot;));&lt;br /&gt;
        }        &lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Visitor List ===&lt;br /&gt;
A list of residents within sensor range of the server.&lt;br /&gt;
&amp;lt;br&amp;gt;Notes:&lt;br /&gt;
* This includes a method for handling multiple requests while waiting for asynchronous data requests to come back.&lt;br /&gt;
&amp;lt;lsl&amp;gt;integer scanning = FALSE;&lt;br /&gt;
&lt;br /&gt;
list requests;&lt;br /&gt;
&lt;br /&gt;
send_response(string body)&lt;br /&gt;
{&lt;br /&gt;
    integer j;&lt;br /&gt;
    for (j = 0; j &amp;lt; llGetListLength(requests); ++j)&lt;br /&gt;
    {&lt;br /&gt;
        llHTTPResponse(llList2Key(requests,j), 200, body);&lt;br /&gt;
    }&lt;br /&gt;
    requests = [];&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        llRequestURL();&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0,&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            if (!scanning)&lt;br /&gt;
            {&lt;br /&gt;
                llSensor(&amp;quot;&amp;quot;,NULL_KEY,AGENT,96,PI);&lt;br /&gt;
                scanning = TRUE;&lt;br /&gt;
            }&lt;br /&gt;
            &lt;br /&gt;
            requests += [id];&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported method.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    no_sensor()&lt;br /&gt;
    {&lt;br /&gt;
        send_response(&amp;quot;There is no one here.&amp;quot;);&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    sensor(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        string output;&lt;br /&gt;
        if (n &amp;lt; 16) output = &amp;quot;There are &amp;quot; + (string)n + &amp;quot; avatars nearby:&amp;quot;;&lt;br /&gt;
        else output = &amp;quot;There are at least 16 avatars nearby:&amp;quot;;&lt;br /&gt;
        &lt;br /&gt;
        integer i;&lt;br /&gt;
        for (i = 0;i&amp;lt;n;++i)&lt;br /&gt;
        {&lt;br /&gt;
            output += &amp;quot;\n\t&amp;quot; + llDetectedName(i);&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        send_response(output);&lt;br /&gt;
&lt;br /&gt;
        scanning = FALSE;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Url Persistence / Visitor Counter ===&lt;br /&gt;
A more complete &#039;hello world&#039;, always has an url and keeps a visitor counter.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string url;&lt;br /&gt;
integer hits;&lt;br /&gt;
&lt;br /&gt;
setup()&lt;br /&gt;
{&lt;br /&gt;
    llSetObjectName(&amp;quot;HTTP Server&amp;quot;);&lt;br /&gt;
    url = &amp;quot;&amp;quot;;&lt;br /&gt;
    llRequestURL();&lt;br /&gt;
    hits = (integer)llGetObjectDesc();&lt;br /&gt;
    llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry() { setup(); }&lt;br /&gt;
    on_rez(integer n) { setup(); }&lt;br /&gt;
    &lt;br /&gt;
    changed(integer c)&lt;br /&gt;
    {&lt;br /&gt;
        if (c &amp;amp; (CHANGED_REGION | CHANGED_REGION_START | CHANGED_TELEPORT) )&lt;br /&gt;
        {&lt;br /&gt;
            setup();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    touch_start(integer n)&lt;br /&gt;
    {&lt;br /&gt;
        llSay(0,&amp;quot;My url is: &amp;quot; + url);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    http_request(key id, string method, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (method == URL_REQUEST_GRANTED)&lt;br /&gt;
        {&lt;br /&gt;
            url = body;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == URL_REQUEST_DENIED)&lt;br /&gt;
        {&lt;br /&gt;
            llSay(0, &amp;quot;Something went wrong, no url. &amp;quot; + body);&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;GET&amp;quot;)&lt;br /&gt;
        {&lt;br /&gt;
            ++hits;&lt;br /&gt;
            llSetObjectDesc((string)hits);&lt;br /&gt;
            llSetText((string)hits + &amp;quot; visitors.&amp;quot;,&amp;lt;1,1,0&amp;gt;,1);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Hello!  You are visitor &amp;quot; + (string)hits + &amp;quot;.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
        else&lt;br /&gt;
        {&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Method unsupported&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. The first script is the LSL code to receive the information on the grid. The second script is a Perl script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid.  ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL();     // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
     http_request(key id, string method, string body) {&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        &lt;br /&gt;
        &lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information from the outside: &amp;quot; + body);&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;Thank you for calling. All of our operators are busy.&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        &lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Perl script to contact the prim on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
&lt;br /&gt;
use LWP;&lt;br /&gt;
use strict;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation($url,$params) {&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    id   =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    name =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
} );&lt;br /&gt;
&lt;br /&gt;
print $info,&amp;quot;\n&amp;quot;;&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the Python code that does the same thing as the PERL code above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    # Set the parameters to be sent.&lt;br /&gt;
    encodedParams =  urllib.urlencode(parameters);&lt;br /&gt;
&lt;br /&gt;
    # Post the data.&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);&lt;br /&gt;
&lt;br /&gt;
    # return the result.&lt;br /&gt;
    return(net.read());&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/d57a7c8b-3ace-3186-730a-f22fde870d48&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;}&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Perl/Python Examples Using POST With Argument Parsing ===&lt;br /&gt;
Here are a set of scripts to provide another example using POST. In this example the scripts are adapted to handle the parsing of the arguments that are passed. The first script is the LSL code to receive the information on the grid. The second script is a PERL script that is used on the outside server to contact the code on the grid. The third script is a Python script that is also used on the outside server to contact the code on the grid. ([[User:Grandma Bates|Grandma Bates]] 12:42, 27 May 2009 (UTC))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
key requestURL;&lt;br /&gt;
&lt;br /&gt;
// ###############################################&lt;br /&gt;
// Routine to parse a string sent through the &lt;br /&gt;
// http server via post.&lt;br /&gt;
//       parsePostData(theMessage)&lt;br /&gt;
// Returns a strided list with stride length 2.&lt;br /&gt;
// Each set has the key and then its value.&lt;br /&gt;
list parsePostData(string message) {&lt;br /&gt;
    list postData = [];         // The list with the data that was passed in.&lt;br /&gt;
    list parsedMessage = llParseString2List(message,[&amp;quot;&amp;amp;&amp;quot;],[]);    // The key/value pairs parsed into one list.&lt;br /&gt;
    integer len = ~llGetListLength(parsedMessage);&lt;br /&gt;
&lt;br /&gt;
    while(++len) {          &lt;br /&gt;
        string currentField = llList2String(parsedMessage, len); // Current key/value pair as a string.&lt;br /&gt;
&lt;br /&gt;
        integer split = llSubStringIndex(currentField,&amp;quot;=&amp;quot;);     // Find the &amp;quot;=&amp;quot; sign&lt;br /&gt;
        if(split == -1) { // There is only one field in this part of the message.&lt;br /&gt;
            postData += [llUnescapeURL(currentField),&amp;quot;&amp;quot;];  &lt;br /&gt;
        } else {&lt;br /&gt;
            postData += [llUnescapeURL(llDeleteSubString(currentField,split,-1)), llUnescapeURL(llDeleteSubString(currentField,0,split))];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    // Return the strided list.&lt;br /&gt;
    return postData ;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
default {&lt;br /&gt;
&lt;br /&gt;
    state_entry() {&lt;br /&gt;
        requestURL = llRequestURL(); // Request that an URL be assigned to me.&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    http_request(key id, string method, string body) {&lt;br /&gt;
         list incomingMessage;&lt;br /&gt;
        &lt;br /&gt;
        if ((method == URL_REQUEST_GRANTED) &amp;amp;&amp;amp; (id == requestURL) ){&lt;br /&gt;
            // An URL has been assigned to me.&lt;br /&gt;
            llOwnerSay(&amp;quot;Obtained URL: &amp;quot; + body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if ((method == URL_REQUEST_DENIED) &amp;amp;&amp;amp; (id == requestURL)) {&lt;br /&gt;
            // I could not obtain a URL&lt;br /&gt;
            llOwnerSay(&amp;quot;There was a problem, and an URL was not assigned: &amp;quot; + &lt;br /&gt;
                       body);&lt;br /&gt;
            requestURL = NULL_KEY;&lt;br /&gt;
        }&lt;br /&gt;
        else if (method == &amp;quot;POST&amp;quot;) {&lt;br /&gt;
            // An incoming message was received.&lt;br /&gt;
            llOwnerSay(&amp;quot;Received information form the outside: &amp;quot; + body);&lt;br /&gt;
            incomingMessage = parsePostData(body);&lt;br /&gt;
            llOwnerSay(llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
            llHTTPResponse(id,200,&amp;quot;You passed the following:\n&amp;quot; + &lt;br /&gt;
                           llDumpList2String(incomingMessage,&amp;quot;\n&amp;quot;));&lt;br /&gt;
&lt;br /&gt;
        }&lt;br /&gt;
        else {&lt;br /&gt;
            // An incoming message has come in using a method that has&lt;br /&gt;
            // not been anticipated.&lt;br /&gt;
            llHTTPResponse(id,405,&amp;quot;Unsupported Method&amp;quot;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding PERL script for contacting the LSL script on the grid.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;perl&amp;gt;&lt;br /&gt;
#!/usr/bin/perl&lt;br /&gt;
# Routine to contact a script on the SL Grid using http server&lt;br /&gt;
&lt;br /&gt;
use LWP;&lt;br /&gt;
use strict;&lt;br /&gt;
&lt;br /&gt;
my $browser = LWP::UserAgent-&amp;gt;new;&lt;br /&gt;
&lt;br /&gt;
sub submitInformation($url,$params) {&lt;br /&gt;
    return $browser-&amp;gt;post( $url, $params )-&amp;gt;content;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
# Set the URL manually....&lt;br /&gt;
my $url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
my $info = submitInformation( $url, {&lt;br /&gt;
    &#039;action&#039; =&amp;gt; &#039;send message&#039;,&lt;br /&gt;
    &#039;value&#039;  =&amp;gt; &#039;Hi there chief!&#039;,&lt;br /&gt;
    &#039;id&#039;     =&amp;gt; &#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
    &#039;name&#039;   =&amp;gt; &#039;M Linden&#039;,&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
print($info,&amp;quot;\n&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/perl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is the coresponding Python script. It does the same thing as the Perl script above.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;python&amp;gt;&lt;br /&gt;
#!/usr/bin/python&lt;br /&gt;
&lt;br /&gt;
import urllib&lt;br /&gt;
import re&lt;br /&gt;
&lt;br /&gt;
# #################################################&lt;br /&gt;
# Routine to send the information to the prim&lt;br /&gt;
#     submitInformation(url,information)&lt;br /&gt;
#&lt;br /&gt;
def submitInformation(url,parameters) :&lt;br /&gt;
    &lt;br /&gt;
#    encodedParams =  urllib.urlencode(parameters);  # encode the parameters&lt;br /&gt;
    encodedParams  = dictionary2URI(parameters);    # encode the parameters&lt;br /&gt;
    net = urllib.urlopen(url,encodedParams);        # Post the data.&lt;br /&gt;
    return(net.read());                             # return the result.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# ################################################&lt;br /&gt;
# Routine to encode a dictionary without using &lt;br /&gt;
# &amp;quot;+&amp;quot; for spaces.&lt;br /&gt;
#       dictionary2URI(theDictionary)&lt;br /&gt;
def dictionary2URI(theDictionary) : &lt;br /&gt;
&lt;br /&gt;
    encoded = &#039;&#039;;           # Initialize the string to return&lt;br /&gt;
    for key, value in theDictionary.iteritems():&lt;br /&gt;
        # Encode each item in the dictionary.&lt;br /&gt;
        encoded += urllib.quote(key)+&amp;quot;=&amp;quot;+urllib.quote(value)+&amp;quot;&amp;amp;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
    remove = re.compile(&#039;&amp;amp;$&#039;)             # Remove the trailing ampersand.&lt;br /&gt;
    encoded = remove.sub(&#039;&#039;,encoded);&lt;br /&gt;
&lt;br /&gt;
    return(encoded);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
if __name__ == &amp;quot;__main__&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
    # Set the URL manually&lt;br /&gt;
    url = &#039;http://sim3015.aditi.lindenlab.com:12046/cap/5a1b89cd-e681-8110-7245-fb98969f32a0&#039;;&lt;br /&gt;
&lt;br /&gt;
    # Define the parameters&lt;br /&gt;
    parameters = {&#039;id&#039;:&#039;244195d6-c9b7-4fd6-9229-c3a8b2e60e81&#039;,&lt;br /&gt;
                  &#039;name&#039;:&#039;M Linden&#039;,&lt;br /&gt;
                  &#039;action&#039;:&#039;send message&#039;,&lt;br /&gt;
                  &#039;value&#039;:&#039;Hey there, hi there, ho there!&#039;};&lt;br /&gt;
&lt;br /&gt;
    # Pass the information along to the prim&lt;br /&gt;
    info = submitInformation(url,parameters);&lt;br /&gt;
    print(info);&lt;br /&gt;
&amp;lt;/python&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;lsl&amp;gt;&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Simple script for sending data to an LSL via PHP ===&lt;br /&gt;
This example by Simba Fuhr &#039;&#039;&#039;UPDATE April 16, 2011&#039;&#039;&#039;&lt;br /&gt;
{{Warning|Some hosting providers only allow fsockopen on the standard 80 and 443 ports.  This script will not work on those providers. If your provider is willing to open some ports for you, HTTP-in uses port 12046, and HTTPS-in uses port 12043.}}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
To use SSL encrypted sockets, you need to have SSL activated on your server. If you run your own server, you need to import the ssl support to your server (apache =&amp;gt; apache.conf  +&amp;quot;LoadModule ssl_module modules/mod_ssl.so&amp;quot;)(normaly based on openssl).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Secure URL Request with LSL.&lt;br /&gt;
Script returns the URL to the chat. Please put the URL into the PHP below.&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
 state_entry()&lt;br /&gt;
 {&lt;br /&gt;
  llRequestSecureURL();&lt;br /&gt;
 }&lt;br /&gt;
 http_request(key id, string method, string body)&lt;br /&gt;
 {&lt;br /&gt;
  if ((method == URL_REQUEST_GRANTED))&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;URL: &amp;quot; + body);&lt;br /&gt;
  }&lt;br /&gt;
  else if (method == &amp;quot;POST&amp;quot;)&lt;br /&gt;
  {&lt;br /&gt;
   llOwnerSay(&amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
   llHTTPResponse(id, 200, &amp;quot;PHP script sent: {&amp;quot; + body + &amp;quot;}&amp;quot;);&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here the PHP.&lt;br /&gt;
A more advanced php function which supports complete url structures and automatical GET and POST types.&lt;br /&gt;
Just don&#039;t submit any post Data to make a GET request.&lt;br /&gt;
The Function supports any kind of url as secure and not secure (https and http).&lt;br /&gt;
If you dont submit a port in the url, the default port for http (80) and https (443) will be used.&lt;br /&gt;
(An example is shown on the top of the script.)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
echo &amp;quot;LSL Script answered:&amp;lt;br&amp;gt;&amp;quot;;&lt;br /&gt;
echo Advanced_HTTP_Request(&amp;quot;https://sim20557.agni.lindenlab.com:12043/cap/5851e666-b0c6-f0a0-758a-9e8156765215&amp;quot;, &amp;quot;Hello script, how are you ?&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
function Advanced_HTTP_Request($Host, $PostData = &amp;quot;&amp;quot;)&lt;br /&gt;
{&lt;br /&gt;
 $Method = &amp;quot;POST&amp;quot;;&lt;br /&gt;
 if (empty($PostData))&lt;br /&gt;
  {$Method = &amp;quot;GET&amp;quot;;}&lt;br /&gt;
 $Port = 80;&lt;br /&gt;
 if (strtolower(substr($Host, 0, 5)) == &amp;quot;https&amp;quot;)&lt;br /&gt;
  {$Port = 443;}&lt;br /&gt;
 $Host = explode(&amp;quot;//&amp;quot;, $Host, 2);&lt;br /&gt;
 if (count($Host) &amp;lt; 2)&lt;br /&gt;
  {$Host[1] = $Host[0];}&lt;br /&gt;
 $Host = explode(&amp;quot;/&amp;quot;, $Host[1], 2);&lt;br /&gt;
 if ($Port == 443)&lt;br /&gt;
  {$SSLAdd = &amp;quot;ssl://&amp;quot;;}&lt;br /&gt;
 $Host[0] = explode(&amp;quot;:&amp;quot;, $Host[0]);&lt;br /&gt;
 if (count($Host[0]) &amp;gt; 1)&lt;br /&gt;
 {&lt;br /&gt;
  $Port = $Host[0][1];&lt;br /&gt;
  $Host[0] = $Host[0][0];&lt;br /&gt;
 }&lt;br /&gt;
 else&lt;br /&gt;
  {$Host[0] = $Host[0][0];}&lt;br /&gt;
 $Socket = fsockopen($SSLAdd.$Host[0], $Port, $Dummy1, $Dummy2, 10);&lt;br /&gt;
 if ($Socket)&lt;br /&gt;
 {&lt;br /&gt;
  fputs($Socket, &amp;quot;$Method /$Host[1] HTTP/1.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Host: $Host[0]\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-type: application/x-www-form-urlencoded\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;User-Agent: Opera/9.01 (Windows NT 5.1; U; en)\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Language: de-DE,de;q=0.9,en;q=0.8\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Accept-Charset: iso-8859-1, utf-8, utf-16, *;q=0.1\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Content-length: &amp;quot;.strlen($PostData).&amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;Connection: close\r\n&amp;quot;.&lt;br /&gt;
				 &amp;quot;\r\n&amp;quot;.&lt;br /&gt;
				 $PostData);&lt;br /&gt;
  $Tme = time();&lt;br /&gt;
  while(!feof($Socket) &amp;amp;&amp;amp; $Tme + 30 &amp;gt; time())&lt;br /&gt;
   {$Res = $Res.fgets($Socket, 256);}&lt;br /&gt;
  fclose($Socket);&lt;br /&gt;
 }&lt;br /&gt;
 $Res = explode(&amp;quot;\r\n\r\n&amp;quot;, $Res, 2);&lt;br /&gt;
 return $Res[1];&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Kelly&#039;s Stupid Web Status Updater ===&lt;br /&gt;
Is actually on its own page: [[LSL_http_server/examples/kellys_stupid_web_status_updater | Kelly&#039;s Stupid Web Status Updater]]&amp;lt;br&amp;gt;&lt;br /&gt;
Kurai&#039;s mod from Kelly&#039;s stupid thing: [[LSL_http_server/examples/kurais_stupid_web_status_updater| Kurai&#039;s Stupid Web Status Updater Mod]]&lt;br /&gt;
{{LSLC|HTTP}}{{LSLC|Examples}}&lt;br /&gt;
&lt;br /&gt;
=== Web-based dynamic buildings ===&lt;br /&gt;
HTTP-in may be used to easily send commands from a web page to an in-world object, so that web users can control and interact with buildings. The interactive installation &#039;&#039;Chromutate&#039;&#039; is based upon this idea: see its [[User:Opensource_Obscure/Chromutate|documentation page]] for free scripts and more details.&lt;br /&gt;
&lt;br /&gt;
=== PHP/SQL Object DNS ===&lt;br /&gt;
Simple DNS server written in PHP to facilitate a DNS service for LSL scripts&lt;br /&gt;
[[LSL_http_server/examples/phpdns|PHPDNS]]&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Http_response&amp;diff=1125963</id>
		<title>Http response</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Http_response&amp;diff=1125963"/>
		<updated>2010-12-11T16:39:03Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Split long preformated line.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL_Event|event_id=32|event_delay|event=http_response&lt;br /&gt;
|p1_type=key|p1_name=request_id|p1_desc=Matches return from [[llHTTPRequest]]&lt;br /&gt;
|p2_type=integer|p2_name=status|p2_desc=HTTP code (like 404 or 200)&lt;br /&gt;
|p3_type=list|p3_name=metadata|p3_desc=List of HTTP_* constants and attributes&lt;br /&gt;
|p4_type=string|p4_name=body|p4_desc&lt;br /&gt;
|event_desc=Triggered when task receives a response to one of its [[llHTTPRequest]]&amp;lt;nowiki&amp;gt;s&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|constants={{{!}}{{Prettytable|style=margin-top:0;}}&lt;br /&gt;
{{!}}-{{Hl2}}&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; {{!}} Constant&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} [[HTTP_BODY_TRUNCATED]]&lt;br /&gt;
{{!}} 0&lt;br /&gt;
{{!}} integer&lt;br /&gt;
{{!}} Truncation point in bytes&lt;br /&gt;
{{!}}}&lt;br /&gt;
|spec=&amp;lt;h3&amp;gt;Status 415 &amp;quot;Unsupported or unknown Content-Type&amp;quot;&amp;lt;/h3&amp;gt;&lt;br /&gt;
The remote server did reply to your request but the Content-Type of the reply (such as XML, JSON, Atom, RSS, PLS) is not recognised by the LL server and so is not passed back to the script. You can assume that 415 means the server heard your request and did reply.&lt;br /&gt;
&amp;lt;h3&amp;gt;Status 499&amp;lt;/h3&amp;gt;&lt;br /&gt;
Besides the usual HTTP status codes, SL implements a special &#039;&#039;&#039;status&#039;&#039;&#039; code 499.  This code isn&#039;t generated by the remote web server but by SL&#039;s servers, it can indicate:&lt;br /&gt;
*Request timeout (60 seconds)&lt;br /&gt;
*SSL failure&lt;br /&gt;
*A space was present in the url (escape your URL with [[llEscapeURL]]).&lt;br /&gt;
&amp;lt;h3&amp;gt;Status 502&amp;lt;/h3&amp;gt;&lt;br /&gt;
The proxy server received an invalid response from an upstream server. This error occurs when you send an llHTTPRequest to an object in-world, and it does not reply with an llHTTPResponse.&lt;br /&gt;
|caveats&lt;br /&gt;
|examples=&amp;lt;lsl&amp;gt;key http_request_id;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        http_request_id = llHTTPRequest(&amp;quot;url&amp;quot;, [], &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (request_id == http_request_id)&lt;br /&gt;
        {&lt;br /&gt;
            llSetText(body, &amp;lt;0,0,1&amp;gt;, 1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To parse POST content:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string get_post_value(string content, string returns){&lt;br /&gt;
    //This parses application/x-www-form-urlencoded POST data&lt;br /&gt;
    &lt;br /&gt;
    //For instance if the webserver posts &#039;data1=hi&amp;amp;data2=blah&#039; then &lt;br /&gt;
    //calling get_post_value(&amp;quot;data1=hi&amp;amp;data2=blah&amp;quot;,&amp;quot;data1&amp;quot;); would return &amp;quot;hi&amp;quot;&lt;br /&gt;
    //Written by MichaelRyan Allen, Unrevoked Clarity&lt;br /&gt;
&lt;br /&gt;
    list p =  llParseString2List(content,[&amp;quot;&amp;amp;&amp;quot;],[]);&lt;br /&gt;
    integer n = llGetListLength(p);&lt;br /&gt;
    integer i;&lt;br /&gt;
    list names;&lt;br /&gt;
    list values;&lt;br /&gt;
    for(i=0;i!=n;i++){&lt;br /&gt;
        list p2 =  llParseString2List(llList2String(p,i),[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
        names += llUnescapeURL(llList2String(p2,0));&lt;br /&gt;
        values += llUnescapeURL(llList2String(p2,1));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if(llListFindList(names,(list)returns) == -1){&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
        return llList2String(values,llListFindList(names,(list)returns));&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
|helpers&lt;br /&gt;
|also_header&lt;br /&gt;
|also_events&lt;br /&gt;
|also_functions={{LSL DefineRow||[[llHTTPRequest]]}}&lt;br /&gt;
|also_articles&lt;br /&gt;
|also_footer&lt;br /&gt;
|notes=&lt;br /&gt;
===Parsing Problems===&lt;br /&gt;
If for some reason while using [[llHTTPRequest]]/[[http_response]] you are unable to parse a known good RSS feed or some other form of web contents, you will need to work around it outside of SecondLife. This is unlikely to change in the near future since checking the headers requires more overhead at the simulator level.&lt;br /&gt;
&lt;br /&gt;
===Unicode===&lt;br /&gt;
&lt;br /&gt;
When serving content with UTF-8 characters be sure your server sets the outgoing &amp;quot;Content-Type&amp;quot; header so that it includes &amp;quot;charset=utf-8&amp;quot; otherwise it will be interpreted incorrectly. See [http://www.w3.org/International/O-HTTP-charset W3C:Setting the HTTP charset parameter] for further details.&lt;br /&gt;
&lt;br /&gt;
===Request Headers===&lt;br /&gt;
&lt;br /&gt;
{{LSL Constants/HTTP Headers}}&lt;br /&gt;
|mode&lt;br /&gt;
|deprecated&lt;br /&gt;
|cat1=HTTP&lt;br /&gt;
|cat2=XML-RPC&lt;br /&gt;
|cat3=HTTP/Client&lt;br /&gt;
|cat4&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Http_response&amp;diff=1125953</id>
		<title>Http response</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Http_response&amp;diff=1125953"/>
		<updated>2010-12-11T16:38:06Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Renamed &amp;quot;header&amp;quot; parser to match what it actually does (parsing urlencoded POST data) and added URL unescaping for keys and values.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL_Event|event_id=32|event_delay|event=http_response&lt;br /&gt;
|p1_type=key|p1_name=request_id|p1_desc=Matches return from [[llHTTPRequest]]&lt;br /&gt;
|p2_type=integer|p2_name=status|p2_desc=HTTP code (like 404 or 200)&lt;br /&gt;
|p3_type=list|p3_name=metadata|p3_desc=List of HTTP_* constants and attributes&lt;br /&gt;
|p4_type=string|p4_name=body|p4_desc&lt;br /&gt;
|event_desc=Triggered when task receives a response to one of its [[llHTTPRequest]]&amp;lt;nowiki&amp;gt;s&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|constants={{{!}}{{Prettytable|style=margin-top:0;}}&lt;br /&gt;
{{!}}-{{Hl2}}&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; {{!}} Constant&lt;br /&gt;
! Type&lt;br /&gt;
! Description&lt;br /&gt;
{{!}}-&lt;br /&gt;
{{!}} [[HTTP_BODY_TRUNCATED]]&lt;br /&gt;
{{!}} 0&lt;br /&gt;
{{!}} integer&lt;br /&gt;
{{!}} Truncation point in bytes&lt;br /&gt;
{{!}}}&lt;br /&gt;
|spec=&amp;lt;h3&amp;gt;Status 415 &amp;quot;Unsupported or unknown Content-Type&amp;quot;&amp;lt;/h3&amp;gt;&lt;br /&gt;
The remote server did reply to your request but the Content-Type of the reply (such as XML, JSON, Atom, RSS, PLS) is not recognised by the LL server and so is not passed back to the script. You can assume that 415 means the server heard your request and did reply.&lt;br /&gt;
&amp;lt;h3&amp;gt;Status 499&amp;lt;/h3&amp;gt;&lt;br /&gt;
Besides the usual HTTP status codes, SL implements a special &#039;&#039;&#039;status&#039;&#039;&#039; code 499.  This code isn&#039;t generated by the remote web server but by SL&#039;s servers, it can indicate:&lt;br /&gt;
*Request timeout (60 seconds)&lt;br /&gt;
*SSL failure&lt;br /&gt;
*A space was present in the url (escape your URL with [[llEscapeURL]]).&lt;br /&gt;
&amp;lt;h3&amp;gt;Status 502&amp;lt;/h3&amp;gt;&lt;br /&gt;
The proxy server received an invalid response from an upstream server. This error occurs when you send an llHTTPRequest to an object in-world, and it does not reply with an llHTTPResponse.&lt;br /&gt;
|caveats&lt;br /&gt;
|examples=&amp;lt;lsl&amp;gt;key http_request_id;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        http_request_id = llHTTPRequest(&amp;quot;url&amp;quot;, [], &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (request_id == http_request_id)&lt;br /&gt;
        {&lt;br /&gt;
            llSetText(body, &amp;lt;0,0,1&amp;gt;, 1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To parse POST content:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string get_post_value(string content, string returns){&lt;br /&gt;
    //This parses application/x-www-form-urlencoded POST data&lt;br /&gt;
    &lt;br /&gt;
    //For instance if the webserver posts &#039;data1=hi&amp;amp;data2=blah&#039; then calling get_post_value(&amp;quot;data1=hi&amp;amp;data2=blah&amp;quot;,&amp;quot;data1&amp;quot;); would return &amp;quot;hi&amp;quot;&lt;br /&gt;
    //Written by MichaelRyan Allen, Unrevoked Clarity&lt;br /&gt;
&lt;br /&gt;
    list p =  llParseString2List(content,[&amp;quot;&amp;amp;&amp;quot;],[]);&lt;br /&gt;
    integer n = llGetListLength(p);&lt;br /&gt;
    integer i;&lt;br /&gt;
    list names;&lt;br /&gt;
    list values;&lt;br /&gt;
    for(i=0;i!=n;i++){&lt;br /&gt;
        list p2 =  llParseString2List(llList2String(p,i),[&amp;quot;=&amp;quot;],[]);&lt;br /&gt;
        names += llUnescapeURL(llList2String(p2,0));&lt;br /&gt;
        values += llUnescapeURL(llList2String(p2,1));&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    if(llListFindList(names,(list)returns) == -1){&lt;br /&gt;
        return &amp;quot;&amp;quot;;&lt;br /&gt;
    }&lt;br /&gt;
    else{&lt;br /&gt;
        return llList2String(values,llListFindList(names,(list)returns));&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
|helpers&lt;br /&gt;
|also_header&lt;br /&gt;
|also_events&lt;br /&gt;
|also_functions={{LSL DefineRow||[[llHTTPRequest]]}}&lt;br /&gt;
|also_articles&lt;br /&gt;
|also_footer&lt;br /&gt;
|notes=&lt;br /&gt;
===Parsing Problems===&lt;br /&gt;
If for some reason while using [[llHTTPRequest]]/[[http_response]] you are unable to parse a known good RSS feed or some other form of web contents, you will need to work around it outside of SecondLife. This is unlikely to change in the near future since checking the headers requires more overhead at the simulator level.&lt;br /&gt;
&lt;br /&gt;
===Unicode===&lt;br /&gt;
&lt;br /&gt;
When serving content with UTF-8 characters be sure your server sets the outgoing &amp;quot;Content-Type&amp;quot; header so that it includes &amp;quot;charset=utf-8&amp;quot; otherwise it will be interpreted incorrectly. See [http://www.w3.org/International/O-HTTP-charset W3C:Setting the HTTP charset parameter] for further details.&lt;br /&gt;
&lt;br /&gt;
===Request Headers===&lt;br /&gt;
&lt;br /&gt;
{{LSL Constants/HTTP Headers}}&lt;br /&gt;
|mode&lt;br /&gt;
|deprecated&lt;br /&gt;
|cat1=HTTP&lt;br /&gt;
|cat2=XML-RPC&lt;br /&gt;
|cat3=HTTP/Client&lt;br /&gt;
|cat4&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/x-tensions&amp;diff=1070762</id>
		<title>LSL Protocol/Restrained Love Open Relay Group/x-tensions</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/x-tensions&amp;diff=1070762"/>
		<updated>2010-10-22T00:51:28Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: cleanup, moved follow to draft&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ ORG Restrained Life Relay Specs TOC }}&lt;br /&gt;
&lt;br /&gt;
== Full list of x-tensions ==&lt;br /&gt;
&lt;br /&gt;
At present, the list of x-tensions is short and it makes sense to list them all on a single page, In the future, it may make sense to separate the list into those that have group approval and those that do not, either because they are still under discussion or because they have been rejected by majority opinion.&lt;br /&gt;
&lt;br /&gt;
Proposed list of approval stages [[LSL Protocol/Restrained Life Open Relay Group/x-tensions Validation Process|here]].&lt;br /&gt;
&lt;br /&gt;
Feature table (including ORG x-tensions) of existing relays [[LSL_Protocol/Restrained_Love_Relay/Comparison|here]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;x-tensions&#039;&#039;&#039; that have been implemented or proposed are:&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;border-collapse: collapse; border-width: 1px; border-style: solid; border-color: #000&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! x-tension &lt;br /&gt;
! [[LSL Protocol/Restrained Love Open Relay Group/x-tensions Validation Process|status]]&lt;br /&gt;
! version &lt;br /&gt;
! description&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/who|who]]&#039;&#039;&#039;&#039;&#039; &lt;br /&gt;
| silver (?)&lt;br /&gt;
| 001 &lt;br /&gt;
| tells the relay the identity of the avatar operating the controlling device. Can be useful in playgrounds with bondage furnitures whose grabbing function is open to everybody.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/handover|handover]]&#039;&#039;&#039;&#039;&#039; &lt;br /&gt;
| bronze (?)&lt;br /&gt;
| 001&lt;br /&gt;
| hands over the control of the relay to another device, with no further auth required, and possiblity to keep all the previous restrictions.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/vision|vision]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| bronze (?)&lt;br /&gt;
| 001&lt;br /&gt;
| provide a means of obscuring the subjects vision &#039;&#039;&#039;WITHOUT&#039;&#039;&#039; having to muck about with extra wearables. Originally conceived as a &#039;&#039;&#039;MOUSELOOK ENFORCER/PUNISHER&#039;&#039;&#039; and &#039;&#039;&#039;REQUIRES&#039;&#039;&#039; a HUDstyle relay. (already implemented and available to use).&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;gender&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| proposal&lt;br /&gt;
| 000&lt;br /&gt;
| allow the users to set their defined sex, and be queried by a device &#039;&#039;&#039;AND SET BY THE DEVICE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;species&#039;&#039;&#039;&#039;&#039; &lt;br /&gt;
| proposal&lt;br /&gt;
| 000&lt;br /&gt;
| ditto for species.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;freeze&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| proposal&lt;br /&gt;
| 000&lt;br /&gt;
| stop the victim dead in their tracks. Effectively disables the arrow movement keys, jump and crouch. &lt;br /&gt;
::::Sure you can do it other ways, but this keeps down extra script/attachment counts and gives a &#039;standard interface&#039;. &lt;br /&gt;
::::Nice for &#039;&#039;area effects&#039;&#039; (prison lock-down perhaps), cages (hold them in place so you can open the cage and take out one specific captive.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/follow|follow]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| draft&lt;br /&gt;
| 001&lt;br /&gt;
| makes the victim follow a given object or avatar at the given distance. &lt;br /&gt;
::::This is exactly what current leashes already do, but without the particles. Useful for bringing the victim &lt;br /&gt;
::::from one place to another without using magic tricks like teleportation.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;control&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| proposal&lt;br /&gt;
| 000&lt;br /&gt;
| makes the victim move as if the control given in argument had been pressed. In conjunction with !x-freeze, this allows the device user to control the victim as if they controlled their own avatar.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/listen|listen]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| ?&lt;br /&gt;
| 001&lt;br /&gt;
| opens up a listener on the specified channel. Useful for cutting down the load on a sim by only having multiple listeners as needed.&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/channel|channel]]&#039;&#039;&#039;&#039;&#039; &lt;br /&gt;
| draft&lt;br /&gt;
| 000&lt;br /&gt;
| switches the control channel for the RLV relay communications to the specified channel to cut down on spam.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;s&amp;gt;&#039;&#039;&#039;&#039;&#039;(!x-)tensions&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| deprecated&lt;br /&gt;
| 000&lt;br /&gt;
| queries the relay for supported x-tensions.&amp;lt;/s&amp;gt; Deprecated by !x-orgversions, which is part of [[LSL_Protocol/Restrained_Love_Open_Relay_Group/ORG_Requirements|ORG core requirements]].&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;animate&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| proposal&lt;br /&gt;
| 000&lt;br /&gt;
| animates the victim with the given animation. The animation has to be a standard one, or an animation from a freebie set we would have to standardize and include in every relay that supports x-animate.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! &#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/email|email]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| draft&lt;br /&gt;
| 005&lt;br /&gt;
| initiates a gridwide email encapsulated protocol session.&lt;br /&gt;
::::The protocol itself is a work in progress now. A proof of concept is on its way in my relay and RLV remote. --[[User:Satomi Ahn|Satomi Ahn]] 10:03, 19 May 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/http-in|http-in]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| draft&lt;br /&gt;
| 002&lt;br /&gt;
| initiates a gridwide http encapsulated protocol session, using the new SL server http-in feature.&lt;br /&gt;
::::I see it as using exactly the same mechanisms as the email extension. It is likely that one of the two methods should eventually be deprecated as they would have the same use and one of the two has to be more efficient than the other! --[[User:Satomi Ahn|Satomi Ahn]] 10:03, 19 May 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;message&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| proposal&lt;br /&gt;
| 000&lt;br /&gt;
| Use the relay to send messages from the restraining device to the victim. &lt;br /&gt;
::::Mainly to negate the inconvenients of llInstantMessage as the only means for a restraining device to send a message only to the victim (Especially useful with multi line messages where the inherent script delay for llInstantMessage is more apparent). --[Regan Flasheart] 13:59, 26 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/custom|custom]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| proposal&lt;br /&gt;
| 001&lt;br /&gt;
| Asks the relay for a list of custom commands or sublists of such. The controlling device issuing this would display the list in a dialog to the device user. Items of the list could include simple actions like triggering animations, or blinding the relay wearer, or even display the menus of various compatible restraints worn by the relay wearer. The idea is to give the possibility for any relay maker to implement various custom extensions without having to wait for every furniture or remote maker to implement them in their menus.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! &#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/ack|ack]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| draft&lt;br /&gt;
| 002&lt;br /&gt;
| !x-ack/quiet tells the relay to stop sending &amp;quot;ok&amp;quot; and &amp;quot;ko&amp;quot; acknowledgements... until it receives !x-ack/verbose. This should help reduce spam on the relay channel.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Love Open Relay Group/delay|delay]]&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
| draft&lt;br /&gt;
| 001&lt;br /&gt;
| !x-delay/10 will delay the execution of the remaining subcommands by 10 seconds. This can be useful either for setting release timers or... making delayed surprises.&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note: x-tension names do not contain &amp;quot;!x-&amp;quot; or even &amp;quot;x-&amp;quot;. Only the meta-commands they define are prefixed that way. One x-tension can define several meta-commands, which must all be implemented if the x-tension is supported.&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1070752</id>
		<title>LSL Protocol/Restrained Love Open Relay Group/follow</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1070752"/>
		<updated>2010-10-22T00:47:56Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ ORG Restrained Life Relay Specs TOC }}&lt;br /&gt;
&lt;br /&gt;
==!x-follow==&lt;br /&gt;
STATUS: exists as a patch to Satomi&#039;s Multi-Relay&lt;br /&gt;
&lt;br /&gt;
VERSION: 001&lt;br /&gt;
&lt;br /&gt;
== Possible uses ==&lt;br /&gt;
!x-follow: Make the victim stay next to the issuer&lt;br /&gt;
&lt;br /&gt;
!x-follow/2c0df8cb-148b-4907-beb6-c01832321f3f/3: Make the victim follow Winter Seale at 3m&lt;br /&gt;
&lt;br /&gt;
!x-followclear: Allow the victim to move freely again&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Syntax and semantics ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!x-follow[/&#039;&#039;target_key&#039;&#039;[/&#039;&#039;distance&#039;&#039;[/&#039;&#039;tau&#039;&#039;]]]&#039;&#039;&#039;&lt;br /&gt;
:: target_key = defaults to the key of the object issuing the command&lt;br /&gt;
:: distance = how close you should stay to the target_key, defaults to 2 meters&lt;br /&gt;
:: tau = the tau that llMoveToTarget should be given, lower means you move faster. defaults to 1.5&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!x-followclear&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is essentially a leash with no particles, just the movement part.  Only one object may have an active follow at a time.  If multirelay receives a second x-follow while another one&#039;s still active, it should deny it.  If the key is not currently present, the relay should scan for it regularly (example: every 5 seconds) and continue moving toward it when it&#039;s found.&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068883</id>
		<title>Talk:LSL Protocol/Restrained Love Relay/Comparison</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068883"/>
		<updated>2010-10-21T10:37:37Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before we list 50 different relays and all their derivatives: on what basis should we decide to list a relay in this page?&lt;br /&gt;
&lt;br /&gt;
I am not too sure about listing my &amp;quot;Damn Fast Relay&amp;quot;... it is more something I made for fun &amp;quot;Let&#039;s script a relay in 5 minutes and less than 50 lines of LSL.&amp;quot; than anything else... although its lightweight approach and prioritization of performance before any other criterion are interesting.&lt;br /&gt;
&lt;br /&gt;
All the other listed relays (except Dahlia&#039;s) meet the criterion of being very popular. My own inquiries show they actually are the top 4 and cover more than 80% of the &amp;quot;market&amp;quot;. Other relays have less than 3% of market share... and most often than not are derivatives of either Maike&#039;s or my implementation.&lt;br /&gt;
&lt;br /&gt;
I added Dahlia&#039;s because it is one of the most feature complete relays and also another brand new implementation from scratch of RLVR and ORG standards. This can be useful to test the robustness of the specifications. For a short description, Dahlia&#039;s is very similar to mine, feature-wise and UI-wise, but it uses the multi-prim approach (like TkPBA).&lt;br /&gt;
&lt;br /&gt;
What other implementations should be mentioned? Relevant criteria on the positive side could be:&lt;br /&gt;
* popularity&lt;br /&gt;
* interesting new concept&lt;br /&gt;
* particularly good coverage of ORG&lt;br /&gt;
* new implementation derived on no other&lt;br /&gt;
* or if it is based on some other implementation, it has to have significant differences (for instance: OpenCollar&#039;s w.r.t. my MultiRelay: OpenCollar&#039;s focuses on collar integration and stability, whereas my HUD MultiRelay focuses on features).&lt;br /&gt;
&lt;br /&gt;
On the negative side:&lt;br /&gt;
* old implementations that are not supported by their authors anymore&lt;br /&gt;
&lt;br /&gt;
Other ideas?&lt;br /&gt;
&lt;br /&gt;
--[[User:Satomi Ahn|Satomi Ahn]] 09:01, 21 October 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
The initial list was &amp;quot;relays Winter has in her inventory at the moment&amp;quot;. =p  I was hesitant to include OpenCollar&#039;s but I felt it was different enough, while being very widely used, to warrant an entry.  My feeling is that a relay that meets any of the criteria would be good to include.  In that light, the Damn Fast relay would fall under the &amp;quot;new implementation&amp;quot; category.  The main thing to learn from it, I think, is that optimizing for scans can be valuable. (And also, that a minimal relay can be very very small.)&lt;br /&gt;
&lt;br /&gt;
On a related note, I think it&#039;d be useful to have a survey of relay use.  I&#039;ll likely start that as another page.&lt;br /&gt;
&lt;br /&gt;
[[User:Winter Seale|Winter Seale]] 10:37, 21 October 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068712</id>
		<title>LSL Protocol/Restrained Love Relay/Comparison</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068712"/>
		<updated>2010-10-21T01:10:34Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Restrained Love Relay Specs TOC}}&lt;br /&gt;
&lt;br /&gt;
This is not a place for editorializing, but just a table of features found in different relays currently available in Second Life.  More to give RLV furniture developers a sense of what&#039;s supported then to act as a guide to choosing a relay.&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;border-collapse: collapse; border-width: 1px; border-style: solid; border-color: #000&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Relay:&lt;br /&gt;
! Satomi&#039;s &amp;lt;br&amp;gt; Multi&lt;br /&gt;
! Susan&#039;s&lt;br /&gt;
! TKPBA&lt;br /&gt;
! Satomi&#039;s &amp;lt;br&amp;gt; Damn Fast&lt;br /&gt;
! OpenCollar&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Version:&lt;br /&gt;
| 1.02b&lt;br /&gt;
| 1.071&lt;br /&gt;
| 30i&lt;br /&gt;
| n/a&lt;br /&gt;
| 3.533&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! RLV Version:&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Max Controllers&lt;br /&gt;
| 5+ (Max is?)&lt;br /&gt;
| 1&lt;br /&gt;
| 5&lt;br /&gt;
| 1&lt;br /&gt;
| 5+ (Max is?)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-who:&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-handover:&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-vision:&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-follow&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-listen:&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-channel:&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-email&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-http-in&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-ack:&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! !x-delay:&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068692</id>
		<title>LSL Protocol/Restrained Love Relay/Comparison</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068692"/>
		<updated>2010-10-21T00:46:59Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: format fix up&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Restrained Love Relay Specs TOC}}&lt;br /&gt;
&lt;br /&gt;
This is not a place for editorializing, but just a table of features found in different relays currently available in Second Life.  More to give RLV furniture developers a sense of what&#039;s supported then to act as a guide to choosing a relay.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
! Relay:&lt;br /&gt;
! Satomi&#039;s Multi&lt;br /&gt;
! Susan&#039;s&lt;br /&gt;
! TKPBA&lt;br /&gt;
! Satomi&#039;s Damn Fast&lt;br /&gt;
! OpenCollar&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! Version&lt;br /&gt;
| 1.02b&lt;br /&gt;
| 1.071&lt;br /&gt;
| 30i&lt;br /&gt;
| n/a&lt;br /&gt;
| 3.533&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068682</id>
		<title>LSL Protocol/Restrained Love Relay/Comparison</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Relay/Comparison&amp;diff=1068682"/>
		<updated>2010-10-21T00:46:05Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: initial setup&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Restrained Love Relay Specs TOC}}&lt;br /&gt;
&lt;br /&gt;
This is not a place for editorializing, but just a table of features found in different relays currently available in Second Life.  More to give RLV furniture developers a sense of what&#039;s supported then to act as a guide to choosing a relay.&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
!! Relay:&lt;br /&gt;
!! Satomi&#039;s Multi&lt;br /&gt;
!! Susan&#039;s&lt;br /&gt;
!! TKPBA&lt;br /&gt;
!! Satomi&#039;s Damn Fast&lt;br /&gt;
!! OpenCollar&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
!! Version&lt;br /&gt;
!! 1.02b&lt;br /&gt;
!! 1.071&lt;br /&gt;
!! 30i&lt;br /&gt;
!! n/a&lt;br /&gt;
!! 3.533&lt;br /&gt;
&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1068673</id>
		<title>LSL Protocol/Restrained Love Open Relay Group/follow</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1068673"/>
		<updated>2010-10-21T00:34:21Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ ORG Restrained Life Relay Specs TOC }}&lt;br /&gt;
&lt;br /&gt;
==!x-follow==&lt;br /&gt;
STATUS: proposal&lt;br /&gt;
&lt;br /&gt;
VERSION: 001&lt;br /&gt;
&lt;br /&gt;
== Possible uses ==&lt;br /&gt;
!x-follow: Make the victim stay next to the issuer&lt;br /&gt;
&lt;br /&gt;
!x-follow/2c0df8cb-148b-4907-beb6-c01832321f3f/3: Make the victim follow Winter Seale at 3m&lt;br /&gt;
&lt;br /&gt;
!x-followclear: Allow the victim to move freely again&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Syntax and semantics ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!x-follow[/&#039;&#039;target_key&#039;&#039;[/&#039;&#039;distance&#039;&#039;[/&#039;&#039;tau&#039;&#039;]]]&#039;&#039;&#039;&lt;br /&gt;
:: target_key = defaults to the key of the object issuing the command&lt;br /&gt;
:: distance = how close you should stay to the target_key, defaults to 2 meters&lt;br /&gt;
:: tau = the tau that llMoveToTarget should be given, lower means you move faster. defaults to 1.5&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!x-followclear&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is essentially a leash with no particles, just the movement part.  Only one object may have an active follow at a time.  If multirelay receives a second x-follow while another one&#039;s still active, it should deny it.  If the key is not currently present, the relay should scan for it regularly (example: every 5 seconds) and continue moving toward it when it&#039;s found.&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1068663</id>
		<title>LSL Protocol/Restrained Love Open Relay Group/follow</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1068663"/>
		<updated>2010-10-21T00:33:24Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ ORG Restrained Life Relay Specs TOC }}&lt;br /&gt;
&lt;br /&gt;
==!x-follow==&lt;br /&gt;
STATUS: proposal&lt;br /&gt;
&lt;br /&gt;
VERSION: 001&lt;br /&gt;
&lt;br /&gt;
== Possible uses ==&lt;br /&gt;
!x-follow: Make the victim stay next to the issuer&lt;br /&gt;
!x-follow/2c0df8cb-148b-4907-beb6-c01832321f3f/3: Make the victim follow Winter Seale at 3m&lt;br /&gt;
!x-followclear: Allow the victim to move freely again&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Syntax and semantics ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!x-follow[/&#039;&#039;target_key&#039;&#039;[/&#039;&#039;distance&#039;&#039;[/&#039;&#039;tau&#039;&#039;]]]&#039;&#039;&#039;&lt;br /&gt;
:: target_key = defaults to the key of the object issuing the command&lt;br /&gt;
:: distance = how close you should stay to the target_key, defaults to 2 meters&lt;br /&gt;
:: tau = the tau that llMoveToTarget should be given, lower means you move faster. defaults to 1.5&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;!x-followclear&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is essentially a leash with no particles, just the movement part.  Only one object may have an active follow at a time.  If multirelay receives a second x-follow while another one&#039;s still active, it should deny it.  If the key is not currently present, the relay should scan for it regularly (example: every 5 seconds) and continue moving toward it when it&#039;s found.&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1068662</id>
		<title>LSL Protocol/Restrained Love Open Relay Group/follow</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/follow&amp;diff=1068662"/>
		<updated>2010-10-21T00:18:09Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Created page with &amp;#039;{{ ORG Restrained Life Relay Specs TOC }}  ==!x-follow==  ; Description : Command to open up a second communication channel to undocumented features of the object containing the ...&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ ORG Restrained Life Relay Specs TOC }}&lt;br /&gt;
&lt;br /&gt;
==!x-follow==&lt;br /&gt;
&lt;br /&gt;
; Description : Command to open up a second communication channel to undocumented features of the object containing the relay.&lt;br /&gt;
&lt;br /&gt;
; Implementation : Simply opens up a new listener on the given channel for the specified period of time (indefinitely if no time is specified)&lt;br /&gt;
&lt;br /&gt;
; Syntax : &#039;&#039;&#039;!x-follow[/(target_key)[/(distance)[/(tau)]]]&#039;&#039;&#039;&lt;br /&gt;
:: (target_key) = defaults to the key of the object issuing the command&lt;br /&gt;
:: (distance) = how close you should stay to the target_key, defaults to 2 meters&lt;br /&gt;
:: (tau) = the tau that llMoveToTarget should be given, lower means you move faster. defaults to 1.5&lt;br /&gt;
&lt;br /&gt;
; Syntax : &#039;&#039;&#039;!x-followclear&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; Examples&lt;br /&gt;
: Make the victim stay next to the issuer: &#039;!x-follow&#039;&lt;br /&gt;
: Make the victim follow Winter at 3m: &#039;!x-follow/2c0df8cb-148b-4907-beb6-c01832321f3f/3&#039;&lt;br /&gt;
: Clear the follow restriction: !x-followclear&lt;br /&gt;
&lt;br /&gt;
; Discussion&lt;br /&gt;
This is essentially a leash with no particles, just the movement part.  Only one object may have an active follow at a time.  If multirelay receives a second x-follow while another one&#039;s still active, it should deny it.&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/x-tensions&amp;diff=1068642</id>
		<title>LSL Protocol/Restrained Love Open Relay Group/x-tensions</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LSL_Protocol/Restrained_Love_Open_Relay_Group/x-tensions&amp;diff=1068642"/>
		<updated>2010-10-20T23:13:19Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Full list of x-tensions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ ORG Restrained Life Relay Specs TOC }}&lt;br /&gt;
&lt;br /&gt;
== Full list of x-tensions ==&lt;br /&gt;
&lt;br /&gt;
At present, the list of x-tensions is short and it makes sense to list them all on a single page, In the future, it may make sense to separate the list into those that have group approval and those that do not, either because they are still under discussion or because they have been rejected by majority opinion.&lt;br /&gt;
&lt;br /&gt;
Proposed list of approval stages [[LSL Protocol/Restrained Life Open Relay Group/x-tensions Validation Process|here]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;x-tensions&#039;&#039;&#039; that have been implemented or proposed are:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Open Relay Group/x-who|!x-who]]&#039;&#039;&#039;&#039;&#039; - tells the relay the identity of the avatar operating the controlling device. Can be useful in playgrounds with bondage furnitures whose grabbing function is open to everybody.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Open Relay Group/x-handover|!x-handover]]&#039;&#039;&#039;&#039;&#039; - hands over the control of the relay to another device, with no further auth required, and possiblity to keep all the previous restrictions.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Open Relay Group/x-vision|!x-vision]]&#039;&#039;&#039;&#039;&#039; - provide a means of obscuring the subjects vision &#039;&#039;&#039;WITHOUT&#039;&#039;&#039; having to muck about with extra wearables.&lt;br /&gt;
::::Originally conceived as a &#039;&#039;&#039;MOUSELOOK ENFORCER/PUNISHER&#039;&#039;&#039; and &#039;&#039;&#039;REQUIRES&#039;&#039;&#039; a HUDstyle relay. (already implemented and available to use).&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;!x-gender&#039;&#039;&#039;&#039;&#039; - allow the users to set their defined sex, and be queried by a device &#039;&#039;&#039;AND SET BY THE DEVICE&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;!x-species&#039;&#039;&#039;&#039;&#039; - ditto for species.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;!x-freeze&#039;&#039;&#039;&#039;&#039;  - stop the victim dead in their tracks. Effectively disables the arrow movement keys, jump and crouch. &lt;br /&gt;
::::Sure you can do it other ways, but this keeps down extra script/attachment counts and gives a &#039;standard interface&#039;. &lt;br /&gt;
::::Nice for &#039;&#039;area effects&#039;&#039; (prison lock-down perhaps), cages (hold them in place so you can open the cage and take out one specific captive.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Open Relay Group/x-follow|!x-follow]]&#039;&#039;&#039;&#039;&#039;  - makes the victim follow a given object or avatar at the given distance. &lt;br /&gt;
::::This is exactly what current leashes already do, but without the particles. Useful for bringing the victim &lt;br /&gt;
::::from one place to another without using magic tricks like teleportation.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;!x-control&#039;&#039;&#039;&#039;&#039;  - makes the victim move as if the control given in argument had been pressed. In conjunction with !x-freeze, this allows the device user to control the victim as if they controlled their own avatar.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Open Relay Group/x-listen|!x-listen]]&#039;&#039;&#039;&#039;&#039; - opens up a listener on the specified channel. Useful for cutting down the load on a sim by only having multiple listeners as needed.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Open Relay Group/x-channel|!x-channel]]&#039;&#039;&#039;&#039;&#039; - switches the control channel for the RLV relay communications to the specified channel to cut down on spam.&lt;br /&gt;
&lt;br /&gt;
::&amp;lt;s&amp;gt;&#039;&#039;&#039;&#039;&#039;!x-tensions&#039;&#039;&#039;&#039;&#039; - queries the relay for supported x-tensions.&amp;lt;/s&amp;gt; Deprecated by !x-orgversions, which is part of [[LSL_Protocol/Restrained_Life_Open_Relay_Group/ORG_Requirements|ORG core requirements]].&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;!x-animate&#039;&#039;&#039;&#039;&#039; - animates the victim with the given animation. The animation has to be a standard one, or an animation from a freebie set we would have to standardize and include in every relay that supports x-animate.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Relay/ORG email|!x-email]]&#039;&#039;&#039;&#039;&#039; - initiates a gridwide email encapsulated protocol session.&lt;br /&gt;
::::The protocol itself is a work in progress now. A proof of concept is on its way in my relay and RLV remote. --[[User:Satomi Ahn|Satomi Ahn]] 10:03, 19 May 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Relay/ORG http-in|!x-http-in]]&#039;&#039;&#039;&#039;&#039; - initiates a gridwide http encapsulated protocol session, using the new SL server http-in feature.&lt;br /&gt;
::::I see it as using exactly the same mechanisms as the email extension. It is likely that one of the two methods should eventually be deprecated as they would have the same use and one of the two has to be more efficient than the other! --[[User:Satomi Ahn|Satomi Ahn]] 10:03, 19 May 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;!x-message&#039;&#039;&#039;&#039;&#039;  - Use the relay to send messages from the restraining device to the victim. &lt;br /&gt;
::::Mainly to negate the inconvenients of llInstantMessage as the only means for a restraining device to send a message only to the victim (Especially useful with multi line messages where the inherent script delay for llInstantMessage is more apparent). --[Regan Flasheart] 13:59, 26 June 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Relay/ORG custom|!x-custom]]&#039;&#039;&#039;&#039;&#039; - Asks the relay for a list of custom commands or sublists of such. The controlling device issuing this would display the list in a dialog to the device user. Items of the list could include simple actions like triggering animations, or blinding the relay wearer, or even display the menus of various compatible restraints worn by the relay wearer. The idea is to give the possibility for any relay maker to implement various custom extensions without having to wait for every furniture or remote maker to implement them in their menus.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Relay/ORG ack|!x-ack]]&#039;&#039;&#039;&#039;&#039; - !x-ack/quiet tells the relay to stop sending &amp;quot;ok&amp;quot; and &amp;quot;ko&amp;quot; acknowledgements... until it receives !x-ack/verbose. This should help reduce spam on the relay channel.&lt;br /&gt;
&lt;br /&gt;
::&#039;&#039;&#039;&#039;&#039;[[LSL Protocol/Restrained Life Relay/ORG delay|!x-delay]]&#039;&#039;&#039;&#039;&#039; - !x-delay/10 will delay the execution of the remaining subcommands by 10 seconds. This can be useful either for setting release timers or... making delayed surprises.&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:Marketplace/Buying&amp;diff=1057632</id>
		<title>Talk:Marketplace/Buying</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:Marketplace/Buying&amp;diff=1057632"/>
		<updated>2010-10-09T04:01:39Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Boolean search syntax ==&lt;br /&gt;
&lt;br /&gt;
Hi, on the current version of the marketplace, the &amp;lt;code&amp;gt;&amp;quot;red shoes&amp;quot; -green&amp;lt;/code&amp;gt; example does not work to exclude &amp;quot;green&amp;quot; as described. That works the same as &amp;lt;code&amp;gt;&amp;quot;red shoes&amp;quot; green&amp;lt;/code&amp;gt;, in other words the - is ignored and it performs a logical AND.&lt;br /&gt;
&lt;br /&gt;
A syntax that &#039;&#039;does&#039;&#039; work is &amp;lt;code&amp;gt;&amp;quot;red shoes&amp;quot; NOT green&amp;lt;/code&amp;gt;. The NOT operator must be uppercase.&lt;br /&gt;
&lt;br /&gt;
--[[User:Cerise Sorbet|Cerise Sorbet]] 11:23, 5 October 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Slow ==&lt;br /&gt;
&lt;br /&gt;
Some explanation that the marketplace now takes 5-10 minutes to actually deliver goods should be included, as this is a dramatic change from every resident created site, which all respond instantly or nearly instantly.&lt;br /&gt;
&lt;br /&gt;
--[[User:Winter Seale|Winter Seale]] 04:01, 9 October 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlStartAnimation&amp;diff=949242</id>
		<title>LlStartAnimation</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlStartAnimation&amp;diff=949242"/>
		<updated>2010-06-26T21:53:48Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Cleanup the caveats (no future tense about something that happened a year ago =p)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL_Function/permission|PERMISSION_TRIGGER_ANIMATION}}{{LSL_Function/inventory|anim|uuid=false|type}}{{LSL_Function&lt;br /&gt;
|func_id=129|func_sleep=0.0|func_energy=10.0&lt;br /&gt;
|func=llStartAnimation|sort=StartAnimation&lt;br /&gt;
|p1_type=string|p1_name=anim|p1_desc=&amp;amp;#32;or [[Internal Animations|built-in animation]]&lt;br /&gt;
|func_footnote&lt;br /&gt;
|func_desc=Start animation &#039;&#039;&#039;anim&#039;&#039;&#039; for agent that granted [[PERMISSION_TRIGGER_ANIMATION]] if the permission has not been revoked.&lt;br /&gt;
|return_text&lt;br /&gt;
|spec&lt;br /&gt;
|caveats=* Only 30 animations can be played at a time.  (Prior to 1.25.4 the limit was 15 and prior to 1.25.3 there was no limit at all.)&lt;br /&gt;
|constants&lt;br /&gt;
|examples=&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    touch_start(integer detected)&lt;br /&gt;
    {&lt;br /&gt;
        llRequestPermissions(llDetectedKey(0), PERMISSION_TRIGGER_ANIMATION);&lt;br /&gt;
    }&lt;br /&gt;
    run_time_permissions(integer perm)&lt;br /&gt;
    {&lt;br /&gt;
        if (perm &amp;amp; PERMISSION_TRIGGER_ANIMATION)&lt;br /&gt;
        {&lt;br /&gt;
            llStartAnimation(&amp;quot;sit&amp;quot;);&lt;br /&gt;
            llOwnerSay(&amp;quot;animation will end in 5 seconds&amp;quot;);&lt;br /&gt;
            llSetTimerEvent(5.0);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    timer()&lt;br /&gt;
    {&lt;br /&gt;
        llSetTimerEvent(0.0);&lt;br /&gt;
        llStopAnimation(&amp;quot;sit&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
Add an animation or pose inside the same object as this script:&lt;br /&gt;
&amp;lt;lsl&amp;gt;&lt;br /&gt;
string animation; // the first animation in inventory will automatically be used&lt;br /&gt;
  // the animation name must be stored globally to be able to stop the animation when standing up&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        // set sit target, otherwise this will not work &lt;br /&gt;
        llSitTarget(&amp;lt;0.0, 0.0, 0.1&amp;gt;, ZERO_ROTATION);&lt;br /&gt;
    }&lt;br /&gt;
 &lt;br /&gt;
    changed(integer change)&lt;br /&gt;
    {&lt;br /&gt;
        if (change &amp;amp; CHANGED_LINK)&lt;br /&gt;
        {&lt;br /&gt;
            key av = llAvatarOnSitTarget();&lt;br /&gt;
            if (av) //evaluated as true if not NULL_KEY or invalid&lt;br /&gt;
                llRequestPermissions(av, PERMISSION_TRIGGER_ANIMATION);&lt;br /&gt;
            else // avatar is standing up&lt;br /&gt;
            {&lt;br /&gt;
                if (animation)&lt;br /&gt;
                    llStopAnimation(animation); // stop the started animation&lt;br /&gt;
                llResetScript(); // release the avatar animation permissions&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    run_time_permissions(integer perm)&lt;br /&gt;
    {&lt;br /&gt;
        if (perm &amp;amp; PERMISSION_TRIGGER_ANIMATION)&lt;br /&gt;
        {&lt;br /&gt;
            animation = llGetInventoryName(INVENTORY_ANIMATION,0); // get the first animation from inventory&lt;br /&gt;
            if (animation)&lt;br /&gt;
            {&lt;br /&gt;
                llStopAnimation(&amp;quot;sit&amp;quot;); // stop the default sit animation&lt;br /&gt;
                llStartAnimation(animation);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/lsl&amp;gt;&lt;br /&gt;
|helpers&lt;br /&gt;
|also_functions={{LSL DefineRow||[[llStopAnimation]]|}}&lt;br /&gt;
|also_tests&lt;br /&gt;
|also_events&lt;br /&gt;
|also_articles={{LSL DefineRow||[[Internal_Animations]]|lists internal Animations always available}}&lt;br /&gt;
|notes&lt;br /&gt;
|cat1=Animation&lt;br /&gt;
|cat2&lt;br /&gt;
|cat3&lt;br /&gt;
|cat4&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlHTTPRequest&amp;diff=930512</id>
		<title>LlHTTPRequest</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlHTTPRequest&amp;diff=930512"/>
		<updated>2010-05-28T07:41:25Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: added note about redirects only being followed for GETs&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL_Function&lt;br /&gt;
|func=llHTTPRequest&lt;br /&gt;
|func_id=230&lt;br /&gt;
|func_energy=10.0&lt;br /&gt;
|func_sleep=0.0&lt;br /&gt;
|func_desc=Sends an HTTP request to the specified URL with the body of the request and parameters. &lt;br /&gt;
|sort=HTTPRequest&lt;br /&gt;
|func_footnote=&lt;br /&gt;
|return_type=key&lt;br /&gt;
|return_text= that is a handle identifying the HTTP request made.&lt;br /&gt;
|p1_type=string|p1_name=url|p1_desc=A valid HTTP/HTTPS URL.&lt;br /&gt;
|p2_type=list|p2_name=parameters|p2_desc=configuration parameters, specified as HTTP_* flag-value pairs&lt;br /&gt;
[ parameter1, value1, parameter2, value2, . . . parameterN, valueN]&lt;br /&gt;
|p3_type=string|p3_name=body|p3_desc=Contents of the request.&lt;br /&gt;
|constants={{LSL_Constants_HTTP}}&lt;br /&gt;
{{LSL_Constants/HTTP_Headers}}&lt;br /&gt;
|spec&lt;br /&gt;
|caveats=&lt;br /&gt;
*If there is a space in &#039;&#039;&#039;url&#039;&#039;&#039;, the [[http_response]] status code will be 499.&lt;br /&gt;
*Requests must fully complete after 60 seconds, or else the response will be thrown away and the [[http_response]] status code will be 499.&lt;br /&gt;
*The response body is limited to 2048 bytes; if it is longer it will be truncated.&lt;br /&gt;
*Requests are throttled on a per [[object]] basis (not per prim).&lt;br /&gt;
**Requests are throttled to a maximum of 25 requests per 20 seconds.  This is to support a sustained rate of 1 per second or a burst of up to 25.&lt;br /&gt;
***See [http://forums-archive.secondlife.com/139/72/108960/1.html this thread] and [http://forums-archive.secondlife.com/139/2c/109571/1.html this thread] for more details.&lt;br /&gt;
*Cannot be used to load textures or images from the internet, for more information see [[Web Textures]].&lt;br /&gt;
*If the accessed site is relying on the LSL script to report L$ transactions, then it &#039;&#039;&#039;must&#039;&#039;&#039; check the X-SecondLife-Shard header to see if the script is running on the beta grid.&lt;br /&gt;
* Some servers will return a 405 error if you send POST to a file that can&#039;t accept metadata, such as a text or HTML file. Make sure you use the GET method to ensure success in any environment.&lt;br /&gt;
* While the HTTP status code from the server is provided to the script, redirect codes such as 302 will result in the redirect being automatically and transparently followed ONLY IF the HTTP_METHOD is GET, with the resulting response being returned.  If the HTTP_METHOD is anything other then GET then you&#039;ll get back an http_response with a status code of 302, but without any way to view the headers, you can&#039;t know where you were being redirected to unless that was also included in the body.&lt;br /&gt;
* The following applies when making a request to a script using HTTP-In:&lt;br /&gt;
** When appending a query string to a cap URL there MUST be a trailing slash between the cap guid and the query string token &#039;?&#039;. IE https://sim123.agni.lindenlab.com/cap/f23b4b94-012d-44f2-bd0c-16c328321221?arg=gra will return an HTTP 500, but https://sim123.agni.lindenlab.com/cap/f23b4b94-012d-44f2-bd0c-16c328321221/?arg=gra will succeed.&lt;br /&gt;
|examples=&amp;lt;lsl&amp;gt;key http_request_id;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        http_request_id = llHTTPRequest(&amp;quot;url&amp;quot;, [], &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (request_id == http_request_id)&lt;br /&gt;
        {&lt;br /&gt;
            llSetText(body, &amp;lt;0,0,1&amp;gt;, 1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example PHP test script:&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php header(&amp;quot;content-type: text/plain; charset=utf-8&amp;quot;); ?&amp;gt;&lt;br /&gt;
Headers received:&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Wouter Hobble&lt;br /&gt;
 * @copyright 2008&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
foreach ($_SERVER as $k =&amp;gt; $v)&lt;br /&gt;
{&lt;br /&gt;
	if( substr($k, 0, 5) == &#039;HTTP_&#039;)&lt;br /&gt;
	{&lt;br /&gt;
		print &amp;quot;\n&amp;quot;. $k. &amp;quot;\t&amp;quot;. $v;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
example wrapper script Both capturing apache headers and global methodes&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?PHP&lt;br /&gt;
	// Author Waster Skronski.&lt;br /&gt;
	// General Public License (GPL).&lt;br /&gt;
	// Mind that some headers are not included because they&#039;re either useless or unreliable.&lt;br /&gt;
	$USE_APACHE_HEADERS = TRUE; // switch to false if you need cgi methods&lt;br /&gt;
	if ($USE_APACHE_HEADERS)&lt;br /&gt;
	{&lt;br /&gt;
		$headers 	= apache_request_headers();&lt;br /&gt;
		$objectgrid 	= $headers[&amp;quot;X-SecondLife-Shard&amp;quot;];&lt;br /&gt;
		$objectname 	= $headers[&amp;quot;X-SecondLife-Object-Name&amp;quot;];&lt;br /&gt;
		$objectkey     	= $headers[&amp;quot;X-SecondLife-Object-Key&amp;quot;];&lt;br /&gt;
		$objectpos 	= $headers[&amp;quot;X-SecondLife-Local-Position&amp;quot;];&lt;br /&gt;
		$ownerkey     	= $headers[&amp;quot;X-SecondLife-Owner-Key&amp;quot;];&lt;br /&gt;
		$ownername 	= $headers[&amp;quot;X-SecondLife-Owner-Name&amp;quot;];&lt;br /&gt;
		$regiondata     = $headers[&amp;quot;X-SecondLife-Region&amp;quot;];&lt;br /&gt;
		$regiontmp 	= explode (&amp;quot;(&amp;quot;,$regiondata); // cut cords off &lt;br /&gt;
		$regionpos 	= explode (&amp;quot;)&amp;quot;,$regiontmp[1]); //&lt;br /&gt;
		$regionname 	= substr($regiontmp[0],0,-1); // cut last space from simname&lt;br /&gt;
	} else {&lt;br /&gt;
		$db = $GLOBALS;&lt;br /&gt;
		$headers 		= $db[&#039;HTTP_ENV_VARS&#039;];&lt;br /&gt;
		$objectgrid 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_SHARD&amp;quot;]; &lt;br /&gt;
		$objectname 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OBJECT_NAME&amp;quot;];&lt;br /&gt;
		$objectkey     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OBJECT_KEY&amp;quot;];&lt;br /&gt;
		$ownerkey     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OWNER_KEY&amp;quot;];&lt;br /&gt;
		$objectpos     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_LOCAL_POSITION&amp;quot;];&lt;br /&gt;
		$ownername 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OWNER_NAME&amp;quot;];&lt;br /&gt;
		$regiondata     = $headers[&amp;quot;HTTP_X_SECONDLIFE_REGION&amp;quot;];&lt;br /&gt;
		$regiontmp 	= explode (&amp;quot;(&amp;quot;,$regiondata); &lt;br /&gt;
		$regionpos 	= explode (&amp;quot;)&amp;quot;,$regiontmp[1]);&lt;br /&gt;
		$regionname 	= substr($regiontmp[0],0,-1);&lt;br /&gt;
	}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;lsl&amp;gt;&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
|helpers&lt;br /&gt;
|also_header&lt;br /&gt;
|also_events={{LSL DefineRow||[[http_response]]}}&lt;br /&gt;
|also_functions={{LSL DefineRow||[[llEscapeURL]]}}&lt;br /&gt;
{{LSL DefineRow||[[llUnescapeURL]]}}&lt;br /&gt;
|also_articles={{LSL DefineRow||[[Simulator IP Addresses]]}}&lt;br /&gt;
|also_footer&lt;br /&gt;
|notes=If for some reason while using llHTTPRequest/http_response you are unable to parse a known good RSS feed or some other form of web contents, you will need to work around it outside of SecondLife. This is unlikely to change in the near future since checking the headers requires more overhead at the simulator level.&lt;br /&gt;
&lt;br /&gt;
You may find that some web servers return either a null or a nonsensical result when llHTTPRequest is used, even though the same URL in a PC web browser returns the expected result. This may be due to the fact that the llHTTPRequest User Agent string is not recognised by some web servers as it does not contain &amp;quot;Mozilla&amp;quot;, which would identify it as a web browser instead of, for example, a Shoutcast or an RSS client. A workaround is to append &amp;quot; HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot; or similar to the URL string, which will kludge the HTTP request to look like it originates from a web browser.&lt;br /&gt;
&lt;br /&gt;
CGI environments may place the headers into variables by capitalizing the entire name, replacing dashes with underscores, and prefixing the name with &amp;quot;HTTP_&amp;quot;, e.g. &amp;quot;HTTP_X_SECONDLIFE_OBJECT_NAME&amp;quot;. PHP $_SERVER variables do this as well.&lt;br /&gt;
&lt;br /&gt;
Apache can include the headers in its logs, using the CustomLog and LogFormat directives.  See [http://httpd.apache.org/docs/2.0/mod/mod_log_config.html#formats the docs] for details on the syntax.&lt;br /&gt;
&lt;br /&gt;
|mode&lt;br /&gt;
|deprecated&lt;br /&gt;
|permission&lt;br /&gt;
|cat1=HTTP&lt;br /&gt;
|cat2=XML-RPC&lt;br /&gt;
|cat3=Communications&lt;br /&gt;
|cat4=HTTP/Client&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlHTTPRequest&amp;diff=930502</id>
		<title>LlHTTPRequest</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlHTTPRequest&amp;diff=930502"/>
		<updated>2010-05-28T07:18:43Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: fixed markup problem from adding note about timeouts&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL_Function&lt;br /&gt;
|func=llHTTPRequest&lt;br /&gt;
|func_id=230&lt;br /&gt;
|func_energy=10.0&lt;br /&gt;
|func_sleep=0.0&lt;br /&gt;
|func_desc=Sends an HTTP request to the specified URL with the body of the request and parameters. &lt;br /&gt;
|sort=HTTPRequest&lt;br /&gt;
|func_footnote=&lt;br /&gt;
|return_type=key&lt;br /&gt;
|return_text= that is a handle identifying the HTTP request made.&lt;br /&gt;
|p1_type=string|p1_name=url|p1_desc=A valid HTTP/HTTPS URL.&lt;br /&gt;
|p2_type=list|p2_name=parameters|p2_desc=configuration parameters, specified as HTTP_* flag-value pairs&lt;br /&gt;
[ parameter1, value1, parameter2, value2, . . . parameterN, valueN]&lt;br /&gt;
|p3_type=string|p3_name=body|p3_desc=Contents of the request.&lt;br /&gt;
|constants={{LSL_Constants_HTTP}}&lt;br /&gt;
{{LSL_Constants/HTTP_Headers}}&lt;br /&gt;
|spec&lt;br /&gt;
|caveats=&lt;br /&gt;
*If there is a space in &#039;&#039;&#039;url&#039;&#039;&#039;, the [[http_response]] status code will be 499.&lt;br /&gt;
*Requests must fully complete after 60 seconds, or else the response will be thrown away and the [[http_response]] status code will be 499.&lt;br /&gt;
*The response body is limited to 2048 bytes; if it is longer it will be truncated.&lt;br /&gt;
*Requests are throttled on a per [[object]] basis (not per prim).&lt;br /&gt;
**Requests are throttled to a maximum of 25 requests per 20 seconds.  This is to support a sustained rate of 1 per second or a burst of up to 25.&lt;br /&gt;
***See [http://forums-archive.secondlife.com/139/72/108960/1.html this thread] and [http://forums-archive.secondlife.com/139/2c/109571/1.html this thread] for more details.&lt;br /&gt;
*Cannot be used to load textures or images from the internet, for more information see [[Web Textures]].&lt;br /&gt;
*If the accessed site is relying on the LSL script to report L$ transactions, then it &#039;&#039;&#039;must&#039;&#039;&#039; check the X-SecondLife-Shard header to see if the script is running on the beta grid.&lt;br /&gt;
* Some servers will return a 405 error if you send POST to a file that can&#039;t accept metadata, such as a text or HTML file. Make sure you use the GET method to ensure success in any environment.&lt;br /&gt;
* While the HTTP status code from the server is provided to the script, redirect codes such as 302 will result in the redirect being automatically and transparently followed, with the resulting response being returned.&lt;br /&gt;
* The following applies when making a request to a script using HTTP-In:&lt;br /&gt;
** When appending a query string to a cap URL there MUST be a trailing slash between the cap guid and the query string token &#039;?&#039;. IE https://sim123.agni.lindenlab.com/cap/f23b4b94-012d-44f2-bd0c-16c328321221?arg=gra will return an HTTP 500, but https://sim123.agni.lindenlab.com/cap/f23b4b94-012d-44f2-bd0c-16c328321221/?arg=gra will succeed.&lt;br /&gt;
|examples=&amp;lt;lsl&amp;gt;key http_request_id;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        http_request_id = llHTTPRequest(&amp;quot;url&amp;quot;, [], &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (request_id == http_request_id)&lt;br /&gt;
        {&lt;br /&gt;
            llSetText(body, &amp;lt;0,0,1&amp;gt;, 1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example PHP test script:&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php header(&amp;quot;content-type: text/plain; charset=utf-8&amp;quot;); ?&amp;gt;&lt;br /&gt;
Headers received:&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Wouter Hobble&lt;br /&gt;
 * @copyright 2008&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
foreach ($_SERVER as $k =&amp;gt; $v)&lt;br /&gt;
{&lt;br /&gt;
	if( substr($k, 0, 5) == &#039;HTTP_&#039;)&lt;br /&gt;
	{&lt;br /&gt;
		print &amp;quot;\n&amp;quot;. $k. &amp;quot;\t&amp;quot;. $v;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
example wrapper script Both capturing apache headers and global methodes&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?PHP&lt;br /&gt;
	// Author Waster Skronski.&lt;br /&gt;
	// General Public License (GPL).&lt;br /&gt;
	// Mind that some headers are not included because they&#039;re either useless or unreliable.&lt;br /&gt;
	$USE_APACHE_HEADERS = TRUE; // switch to false if you need cgi methods&lt;br /&gt;
	if ($USE_APACHE_HEADERS)&lt;br /&gt;
	{&lt;br /&gt;
		$headers 	= apache_request_headers();&lt;br /&gt;
		$objectgrid 	= $headers[&amp;quot;X-SecondLife-Shard&amp;quot;];&lt;br /&gt;
		$objectname 	= $headers[&amp;quot;X-SecondLife-Object-Name&amp;quot;];&lt;br /&gt;
		$objectkey     	= $headers[&amp;quot;X-SecondLife-Object-Key&amp;quot;];&lt;br /&gt;
		$objectpos 	= $headers[&amp;quot;X-SecondLife-Local-Position&amp;quot;];&lt;br /&gt;
		$ownerkey     	= $headers[&amp;quot;X-SecondLife-Owner-Key&amp;quot;];&lt;br /&gt;
		$ownername 	= $headers[&amp;quot;X-SecondLife-Owner-Name&amp;quot;];&lt;br /&gt;
		$regiondata     = $headers[&amp;quot;X-SecondLife-Region&amp;quot;];&lt;br /&gt;
		$regiontmp 	= explode (&amp;quot;(&amp;quot;,$regiondata); // cut cords off &lt;br /&gt;
		$regionpos 	= explode (&amp;quot;)&amp;quot;,$regiontmp[1]); //&lt;br /&gt;
		$regionname 	= substr($regiontmp[0],0,-1); // cut last space from simname&lt;br /&gt;
	} else {&lt;br /&gt;
		$db = $GLOBALS;&lt;br /&gt;
		$headers 		= $db[&#039;HTTP_ENV_VARS&#039;];&lt;br /&gt;
		$objectgrid 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_SHARD&amp;quot;]; &lt;br /&gt;
		$objectname 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OBJECT_NAME&amp;quot;];&lt;br /&gt;
		$objectkey     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OBJECT_KEY&amp;quot;];&lt;br /&gt;
		$ownerkey     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OWNER_KEY&amp;quot;];&lt;br /&gt;
		$objectpos     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_LOCAL_POSITION&amp;quot;];&lt;br /&gt;
		$ownername 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OWNER_NAME&amp;quot;];&lt;br /&gt;
		$regiondata     = $headers[&amp;quot;HTTP_X_SECONDLIFE_REGION&amp;quot;];&lt;br /&gt;
		$regiontmp 	= explode (&amp;quot;(&amp;quot;,$regiondata); &lt;br /&gt;
		$regionpos 	= explode (&amp;quot;)&amp;quot;,$regiontmp[1]);&lt;br /&gt;
		$regionname 	= substr($regiontmp[0],0,-1);&lt;br /&gt;
	}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;lsl&amp;gt;&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
|helpers&lt;br /&gt;
|also_header&lt;br /&gt;
|also_events={{LSL DefineRow||[[http_response]]}}&lt;br /&gt;
|also_functions={{LSL DefineRow||[[llEscapeURL]]}}&lt;br /&gt;
{{LSL DefineRow||[[llUnescapeURL]]}}&lt;br /&gt;
|also_articles={{LSL DefineRow||[[Simulator IP Addresses]]}}&lt;br /&gt;
|also_footer&lt;br /&gt;
|notes=If for some reason while using llHTTPRequest/http_response you are unable to parse a known good RSS feed or some other form of web contents, you will need to work around it outside of SecondLife. This is unlikely to change in the near future since checking the headers requires more overhead at the simulator level.&lt;br /&gt;
&lt;br /&gt;
You may find that some web servers return either a null or a nonsensical result when llHTTPRequest is used, even though the same URL in a PC web browser returns the expected result. This may be due to the fact that the llHTTPRequest User Agent string is not recognised by some web servers as it does not contain &amp;quot;Mozilla&amp;quot;, which would identify it as a web browser instead of, for example, a Shoutcast or an RSS client. A workaround is to append &amp;quot; HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot; or similar to the URL string, which will kludge the HTTP request to look like it originates from a web browser.&lt;br /&gt;
&lt;br /&gt;
CGI environments may place the headers into variables by capitalizing the entire name, replacing dashes with underscores, and prefixing the name with &amp;quot;HTTP_&amp;quot;, e.g. &amp;quot;HTTP_X_SECONDLIFE_OBJECT_NAME&amp;quot;. PHP $_SERVER variables do this as well.&lt;br /&gt;
&lt;br /&gt;
Apache can include the headers in its logs, using the CustomLog and LogFormat directives.  See [http://httpd.apache.org/docs/2.0/mod/mod_log_config.html#formats the docs] for details on the syntax.&lt;br /&gt;
&lt;br /&gt;
|mode&lt;br /&gt;
|deprecated&lt;br /&gt;
|permission&lt;br /&gt;
|cat1=HTTP&lt;br /&gt;
|cat2=XML-RPC&lt;br /&gt;
|cat3=Communications&lt;br /&gt;
|cat4=HTTP/Client&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=LlHTTPRequest&amp;diff=930492</id>
		<title>LlHTTPRequest</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=LlHTTPRequest&amp;diff=930492"/>
		<updated>2010-05-28T07:06:30Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{LSL_Function&lt;br /&gt;
|func=llHTTPRequest&lt;br /&gt;
|func_id=230&lt;br /&gt;
|func_energy=10.0&lt;br /&gt;
|func_sleep=0.0&lt;br /&gt;
|func_desc=Sends an HTTP request to the specified URL with the body of the request and parameters. &lt;br /&gt;
|sort=HTTPRequest&lt;br /&gt;
|func_footnote=&lt;br /&gt;
|return_type=key&lt;br /&gt;
|return_text= that is a handle identifying the HTTP request made.&lt;br /&gt;
|p1_type=string|p1_name=url|p1_desc=A valid HTTP/HTTPS URL.&lt;br /&gt;
|p2_type=list|p2_name=parameters|p2_desc=configuration parameters, specified as HTTP_* flag-value pairs&lt;br /&gt;
[ parameter1, value1, parameter2, value2, . . . parameterN, valueN]&lt;br /&gt;
|p3_type=string|p3_name=body|p3_desc=Contents of the request.&lt;br /&gt;
|constants={{LSL_Constants_HTTP}}&lt;br /&gt;
{{LSL_Constants/HTTP_Headers}}&lt;br /&gt;
|spec&lt;br /&gt;
|caveats=&lt;br /&gt;
*If there is a space in &#039;&#039;&#039;url&#039;&#039;&#039;, the [[http_response]] status code will be 499.&lt;br /&gt;
*Requests must fully complete after 60 seconds, or else the response will be thrown away and the [http_response]] status code will be 499.&lt;br /&gt;
*The response body is limited to 2048 bytes; if it is longer it will be truncated.&lt;br /&gt;
*Requests are throttled on a per [[object]] basis (not per prim).&lt;br /&gt;
**Requests are throttled to a maximum of 25 requests per 20 seconds.  This is to support a sustained rate of 1 per second or a burst of up to 25.&lt;br /&gt;
***See [http://forums-archive.secondlife.com/139/72/108960/1.html this thread] and [http://forums-archive.secondlife.com/139/2c/109571/1.html this thread] for more details.&lt;br /&gt;
*Cannot be used to load textures or images from the internet, for more information see [[Web Textures]].&lt;br /&gt;
*If the accessed site is relying on the LSL script to report L$ transactions, then it &#039;&#039;&#039;must&#039;&#039;&#039; check the X-SecondLife-Shard header to see if the script is running on the beta grid.&lt;br /&gt;
* Some servers will return a 405 error if you send POST to a file that can&#039;t accept metadata, such as a text or HTML file. Make sure you use the GET method to ensure success in any environment.&lt;br /&gt;
* While the HTTP status code from the server is provided to the script, redirect codes such as 302 will result in the redirect being automatically and transparently followed, with the resulting response being returned.&lt;br /&gt;
* The following applies when making a request to a script using HTTP-In:&lt;br /&gt;
** When appending a query string to a cap URL there MUST be a trailing slash between the cap guid and the query string token &#039;?&#039;. IE https://sim123.agni.lindenlab.com/cap/f23b4b94-012d-44f2-bd0c-16c328321221?arg=gra will return an HTTP 500, but https://sim123.agni.lindenlab.com/cap/f23b4b94-012d-44f2-bd0c-16c328321221/?arg=gra will succeed.&lt;br /&gt;
|examples=&amp;lt;lsl&amp;gt;key http_request_id;&lt;br /&gt;
&lt;br /&gt;
default&lt;br /&gt;
{&lt;br /&gt;
    state_entry()&lt;br /&gt;
    {&lt;br /&gt;
        http_request_id = llHTTPRequest(&amp;quot;url&amp;quot;, [], &amp;quot;&amp;quot;);&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    http_response(key request_id, integer status, list metadata, string body)&lt;br /&gt;
    {&lt;br /&gt;
        if (request_id == http_request_id)&lt;br /&gt;
        {&lt;br /&gt;
            llSetText(body, &amp;lt;0,0,1&amp;gt;, 1);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&amp;lt;/lsl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example PHP test script:&lt;br /&gt;
&amp;lt;php&amp;gt;&amp;lt;?php header(&amp;quot;content-type: text/plain; charset=utf-8&amp;quot;); ?&amp;gt;&lt;br /&gt;
Headers received:&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * @author Wouter Hobble&lt;br /&gt;
 * @copyright 2008&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
foreach ($_SERVER as $k =&amp;gt; $v)&lt;br /&gt;
{&lt;br /&gt;
	if( substr($k, 0, 5) == &#039;HTTP_&#039;)&lt;br /&gt;
	{&lt;br /&gt;
		print &amp;quot;\n&amp;quot;. $k. &amp;quot;\t&amp;quot;. $v;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
?&amp;gt;&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
example wrapper script Both capturing apache headers and global methodes&lt;br /&gt;
&amp;lt;php&amp;gt;&lt;br /&gt;
&amp;lt;?PHP&lt;br /&gt;
	// Author Waster Skronski.&lt;br /&gt;
	// General Public License (GPL).&lt;br /&gt;
	// Mind that some headers are not included because they&#039;re either useless or unreliable.&lt;br /&gt;
	$USE_APACHE_HEADERS = TRUE; // switch to false if you need cgi methods&lt;br /&gt;
	if ($USE_APACHE_HEADERS)&lt;br /&gt;
	{&lt;br /&gt;
		$headers 	= apache_request_headers();&lt;br /&gt;
		$objectgrid 	= $headers[&amp;quot;X-SecondLife-Shard&amp;quot;];&lt;br /&gt;
		$objectname 	= $headers[&amp;quot;X-SecondLife-Object-Name&amp;quot;];&lt;br /&gt;
		$objectkey     	= $headers[&amp;quot;X-SecondLife-Object-Key&amp;quot;];&lt;br /&gt;
		$objectpos 	= $headers[&amp;quot;X-SecondLife-Local-Position&amp;quot;];&lt;br /&gt;
		$ownerkey     	= $headers[&amp;quot;X-SecondLife-Owner-Key&amp;quot;];&lt;br /&gt;
		$ownername 	= $headers[&amp;quot;X-SecondLife-Owner-Name&amp;quot;];&lt;br /&gt;
		$regiondata     = $headers[&amp;quot;X-SecondLife-Region&amp;quot;];&lt;br /&gt;
		$regiontmp 	= explode (&amp;quot;(&amp;quot;,$regiondata); // cut cords off &lt;br /&gt;
		$regionpos 	= explode (&amp;quot;)&amp;quot;,$regiontmp[1]); //&lt;br /&gt;
		$regionname 	= substr($regiontmp[0],0,-1); // cut last space from simname&lt;br /&gt;
	} else {&lt;br /&gt;
		$db = $GLOBALS;&lt;br /&gt;
		$headers 		= $db[&#039;HTTP_ENV_VARS&#039;];&lt;br /&gt;
		$objectgrid 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_SHARD&amp;quot;]; &lt;br /&gt;
		$objectname 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OBJECT_NAME&amp;quot;];&lt;br /&gt;
		$objectkey     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OBJECT_KEY&amp;quot;];&lt;br /&gt;
		$ownerkey     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OWNER_KEY&amp;quot;];&lt;br /&gt;
		$objectpos     	= $headers[&amp;quot;HTTP_X_SECONDLIFE_LOCAL_POSITION&amp;quot;];&lt;br /&gt;
		$ownername 	= $headers[&amp;quot;HTTP_X_SECONDLIFE_OWNER_NAME&amp;quot;];&lt;br /&gt;
		$regiondata     = $headers[&amp;quot;HTTP_X_SECONDLIFE_REGION&amp;quot;];&lt;br /&gt;
		$regiontmp 	= explode (&amp;quot;(&amp;quot;,$regiondata); &lt;br /&gt;
		$regionpos 	= explode (&amp;quot;)&amp;quot;,$regiontmp[1]);&lt;br /&gt;
		$regionname 	= substr($regiontmp[0],0,-1);&lt;br /&gt;
	}&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;display:none;&amp;quot;&amp;gt;&amp;lt;lsl&amp;gt;&amp;lt;/lsl&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
|helpers&lt;br /&gt;
|also_header&lt;br /&gt;
|also_events={{LSL DefineRow||[[http_response]]}}&lt;br /&gt;
|also_functions={{LSL DefineRow||[[llEscapeURL]]}}&lt;br /&gt;
{{LSL DefineRow||[[llUnescapeURL]]}}&lt;br /&gt;
|also_articles={{LSL DefineRow||[[Simulator IP Addresses]]}}&lt;br /&gt;
|also_footer&lt;br /&gt;
|notes=If for some reason while using llHTTPRequest/http_response you are unable to parse a known good RSS feed or some other form of web contents, you will need to work around it outside of SecondLife. This is unlikely to change in the near future since checking the headers requires more overhead at the simulator level.&lt;br /&gt;
&lt;br /&gt;
You may find that some web servers return either a null or a nonsensical result when llHTTPRequest is used, even though the same URL in a PC web browser returns the expected result. This may be due to the fact that the llHTTPRequest User Agent string is not recognised by some web servers as it does not contain &amp;quot;Mozilla&amp;quot;, which would identify it as a web browser instead of, for example, a Shoutcast or an RSS client. A workaround is to append &amp;quot; HTTP/1.0\nUser-Agent: LSL Script (Mozilla Compatible)\n\n&amp;quot; or similar to the URL string, which will kludge the HTTP request to look like it originates from a web browser.&lt;br /&gt;
&lt;br /&gt;
CGI environments may place the headers into variables by capitalizing the entire name, replacing dashes with underscores, and prefixing the name with &amp;quot;HTTP_&amp;quot;, e.g. &amp;quot;HTTP_X_SECONDLIFE_OBJECT_NAME&amp;quot;. PHP $_SERVER variables do this as well.&lt;br /&gt;
&lt;br /&gt;
Apache can include the headers in its logs, using the CustomLog and LogFormat directives.  See [http://httpd.apache.org/docs/2.0/mod/mod_log_config.html#formats the docs] for details on the syntax.&lt;br /&gt;
&lt;br /&gt;
|mode&lt;br /&gt;
|deprecated&lt;br /&gt;
|permission&lt;br /&gt;
|cat1=HTTP&lt;br /&gt;
|cat2=XML-RPC&lt;br /&gt;
|cat3=Communications&lt;br /&gt;
|cat4=HTTP/Client&lt;br /&gt;
}}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/RestrainedLoveAPI&amp;diff=797342</id>
		<title>Talk:LSL Protocol/RestrainedLoveAPI</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/RestrainedLoveAPI&amp;diff=797342"/>
		<updated>2010-03-11T00:19:36Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Feature suggestion: @emailsnapshot:=force */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Question regarding @remoutfit and teens===&lt;br /&gt;
&lt;br /&gt;
Thank you for putting up that API.&lt;br /&gt;
&lt;br /&gt;
But I got a question regarding the  &#039;&#039;@remoutfit[:&amp;lt;part&amp;gt;]=&amp;lt;y/n&amp;gt;&#039;&#039;-command:&lt;br /&gt;
It says&#039;&#039;(underpants and underwear are kept for teens)&#039;&#039;. What do you mean with that?&lt;br /&gt;
&lt;br /&gt;
Is removing underwear disabled only on teengrid? Is it disabled in PG Areas? Or just one of your nice jokes? :-)&lt;br /&gt;
&lt;br /&gt;
MK: No no this time it was not a joke, the standard viewer actually checks that you&#039;re not on the teen grid and if you are, discards removing underwear. I took care of not breaking that check when adding the remoutfit command :)&lt;br /&gt;
&lt;br /&gt;
== How to use for bondage furniture? ==&lt;br /&gt;
&lt;br /&gt;
Hi Marine,&lt;br /&gt;
&lt;br /&gt;
Good stuff, your viewer. I have a question on how to use the API in bondage furniture. &lt;br /&gt;
&lt;br /&gt;
As a test I did put the @remoutfit=force in the menuhandler of a bondage cross that I have. Now, when I use the menu while not sitting on the cross ... I am suddenly naked. Blush. Nice effect, but not what I expected. I expected the command to work on the AvatarOnSitTarget, if that person would use your viewer. &lt;br /&gt;
&lt;br /&gt;
Do I do something wrong, or is your viewer focused to impact the Owner of worn attachments? If the former, please let me know how to do it right. If the latter, it would be great if the viewer would work on Owner in case of attachments, and work on AvatarOnSitTarget in case of objects to sit on.&lt;br /&gt;
&lt;br /&gt;
Looking forward to your answer.&lt;br /&gt;
Ciao, Tam&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The answer came to me in world. Use the RealRestraint Relay&lt;br /&gt;
https://wiki.secondlife.com/wiki/LSL_Protocol/RestrainedLifeRelaySpecs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meaningless or App-Defined Rules ==&lt;br /&gt;
&lt;br /&gt;
I noticed (accidentially, due to a misspelling) that if you send a rule that doesn&#039;t exist, it has no effect, but it DOES remember the rule, and can be retrieved using @getstatus.  For example, you can llOwnerSay(&amp;quot;@randomtext=n&amp;quot;) and later when you call llOwnerSay(&amp;quot;@getstatus=x&amp;quot;) the rules in the response will include &amp;quot;randomtext&amp;quot; in the list.&lt;br /&gt;
&lt;br /&gt;
Is this a bug or a feature?  The reason I ask is, there are some good uses for this if the behavior can be depended upon, but if it&#039;s likely to disappear in a future version, then I&#039;ll steer clear of using it.  Thanks.&lt;br /&gt;
&lt;br /&gt;
--[[User:Galatea Gynoid|Galatea Gynoid]] 12:07, 17 August 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually there is no such thing as &amp;quot;a rule that does not exist&amp;quot;, the viewer takes whatever it is sent and puts it into its internal list for later. This is because I don&#039;t want to duplicate commands (I have to for some of them, for instance when checking whether the inventory is already open when issuing a @showinv). It&#039;s by design so it&#039;s easier to just poke at the code and add your own command without wondering whether you have to add it to a static table somewhere. So it&#039;s neither a bug nor a feature I would say.&lt;br /&gt;
&lt;br /&gt;
And to answer your actual question, it&#039;s very unlikely to change in the future, at least as long as I&#039;m in charge. Yes you&#039;re right, it could be a good way to store data in-world for the time of a unique session. However keep in mind that @getstatus gives a regular chat message, that is capped at 1023 characters.&lt;br /&gt;
&lt;br /&gt;
--[[User:Marine Kelley|Marine Kelley]] 01:47, 18 August 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== @sendchannel needs a bit of clarification ==&lt;br /&gt;
&lt;br /&gt;
The way it&#039;s worded, the explanation of sendchannel is a bit confusing.  I &#039;&#039;assume&#039;&#039; the way the restriction works is that the command @sendchannel=n would restrict all alt-channel chat, but the command @sendchannel:3=n would allow chat on that specific channel even if the global restriction is in place.  The way it&#039;s worded though, it seems like it could be that @sendchannel:3=n would restrict chat &#039;&#039;only&#039;&#039; on channel 3.  -- [[User:Felis Darwin|Felis Darwin]] 21:12, 7 December 2008 (UTC)&lt;br /&gt;
&lt;br /&gt;
Maybe it&#039;s poorly worded... @sendchannel:3=n does add an exception to the @sendchannel restriction, in other words you can speak on channel 3 when the former is applied.&lt;br /&gt;
&lt;br /&gt;
[[User:Marine Kelley|Marine Kelley]] 15:16, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== @acceptpermission &amp;amp; @denypermission ==&lt;br /&gt;
&lt;br /&gt;
Marine, your blog lists these new commands, but I don&#039;t see anything on usage in here. Were they overlooked? --[[User:Teyonas Miklos|Teyonas Miklos]] 07:19, 8 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
By the way, if @acceptpermission would also affect animation permission, that would be awesome! --[[User:Satomi Ahn|Satomi Ahn]] 16:42, 19 February 2009 (UTC)&lt;br /&gt;
:Oh it looks like the wiki has been completed now. Thanks Marine. But, may I ask, do @acceptpermission &amp;amp; @denypermission really work for animation permission now? Your blog says it is only for attachements and controls! --[[User:Satomi Ahn|Satomi Ahn]] 11:52, 31 March 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::Yes if I remember correctly it only accepts attach and controls permissions... I am really torn on the animation permission because it is automatically accepted if you&#039;re sitting on the prim that contains the animation (like furnitures), or wearing it (like restraints) but it proves to be a vulnerability for griefers to exploit. Granted, griefing with weird animations is lame (as is griefing in general), but it is griefing nonetheless. I should see how to accept animation permission requests from prims you are sitting on, regardless of whether they contain the animation or not. That should help for rezzable poseballs at least. [[User:Marine Kelley|Marine Kelley]] 15:13, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::: Is there a way to start an animation which is not in the prim? In case it is possible it would be interesting to extend the relay protocol to allow this. But I thought this was impossible? Another idea is to explicitly specify the key of the prim that should be allowed to start an animation: &amp;lt;code&amp;gt;@acceptpermission:7adf6218-ab26-8566-8387-660133840794=add&amp;lt;/code&amp;gt;. I am not sure if the viewer has this information in the permission query function. The scenario I have in mind is a Star Trek like force-field cell door that will give an electroshock on touch, assuming that the cell has an active relay session. Something else to keep in mind is that there is a pyramid scheme vampire game out there which sees accepting animation permission as accepting to be added to the database. --[[User:Maike Short|Maike Short]] 18:54, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::: Eh, you actually wrote this, on the wiki: &amp;quot;Force the viewer to automatically accept attach and &#039;animate&#039; permission requests : @acceptpermission=&amp;lt;rem/add&amp;gt; &amp;quot;. So I guess this is an error. By the way, Kitty might have pointed this to you, but there is actually a way to to get animation permissions by mean of RLV commands, exploiting a loophole in the logic you use for @acceptpermission. Basically, if this behavior is enabled, if you request permission to animate along with  either permission to attach or permission to take controls, then you are granted both. --[[User:Satomi Ahn|Satomi Ahn]] 20:35, 14 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== A shared root... and what about a protected root? ==&lt;br /&gt;
&lt;br /&gt;
I mean, if you are tired to put your tatoos back every time someone strips you... it would be great to be able to protect easily some clothes and attachments (hair, tail, ears,...).&lt;br /&gt;
You can already somehow do this for clothes with @remoutfit:xxxx=n, and for prims with @detach=n, but this requires scripting, and very often, you will forget to lock them.&lt;br /&gt;
&lt;br /&gt;
I believe this would be a lot easier if you could have a /#protected folder whose content cannot be force-detached by the mean of rlv commands.&lt;br /&gt;
Moreover, it would be even greater if RLV did not report items you are wearing and are in #protected: indeed some scripts will loop until they have successfully detached all they wanted to. If the viewer does not report those items are worn, then those scripts would be happy.&lt;br /&gt;
&lt;br /&gt;
--[[User:Satomi Ahn|Satomi Ahn]] 23:52, 19 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I like the idea of checking against some kind of viewer-side characteristic of the object, but I&#039;m not sure a folder would do... After all the user could want to protect-unprotect quickly, and moving a large chunk of inventory could reveal to be a hassle. I&#039;ll think about it.&lt;br /&gt;
&lt;br /&gt;
[[User:Marine Kelley|Marine Kelley]] 15:09, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just a note a posteriori: Kitty Barnett&#039;s &amp;quot;nostrip&amp;quot; flag works really well for what I wanted. It would be nice if Marine Kelley&#039;s RLV had this feature too. How does it work? Easy: if an item or folder has (nostrip) in its name, then it will be protected against @remoutfit:layer=force or @detach:attachpt=force commands. A lot better than my initial proposal as it is really fine-grained.&lt;br /&gt;
&lt;br /&gt;
--[[User:Satomi Ahn|Satomi Ahn]] 09:31, 27 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Third party extension @putinv and the SL permission system ==&lt;br /&gt;
&lt;br /&gt;
In my opinion the SL permission system has a serious) flaw. Objects owned by the land owner do have special rights without a permission dialog:&lt;br /&gt;
* manage the ban list&lt;br /&gt;
* change the media settings (can be used to get the ip-address of visitors)&lt;br /&gt;
* teraform (can be used to destroy the landscape and return rezzed objects to the lost and found folder, thous destroying a lovely place)&lt;br /&gt;
&lt;br /&gt;
While I think it is an issue that SL automatically grants these rights to objects owned by the land lord, I am concerned that the auto-accept and attach might be used to simplify attacks. So if you implement this inofficial extension (the official RLV viewer does not) please add a warning.&lt;br /&gt;
&lt;br /&gt;
PS: Oh, it just occured to me that it can be used to write a self replicating worm that jumps across avatars. This would surely have the potential to get the BDSM community some bad PR. --[[User:Maike Short|Maike Short]] 16:18, 8 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:Hm there&#039;s already a (way too) long discussion about this on the forums.&lt;br /&gt;
:Here: http://forums.secondlife.com/showthread.php?t=223796&amp;amp;page=30&amp;amp;pp=15&lt;br /&gt;
:And here: http://sldev.free.fr/forum/viewtopic.php?f=7&amp;amp;t=8&lt;br /&gt;
:I personnaly don&#039;t want to discuss the issue anymore, but I thought I had to point you to this ;-), as I basically share your concerns.&lt;br /&gt;
:--[[User:Satomi Ahn|Satomi Ahn]] 20:29, 14 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Protecting attachments against detach ==&lt;br /&gt;
&lt;br /&gt;
I&#039;m scripting a gizmo to prevent stripping of tattoos, piercings etc. It would be very useful to have a command similar to the &amp;quot;@remoutfit&amp;quot;, but for attachments. That way texture clothing and prim clothing can be treated the same way, instead of having to drop a script into each protected attachment.&lt;br /&gt;
&lt;br /&gt;
My question is: Would it be possible to include commands looking something like this?&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Allow/prevent wearing attachments&#039;&#039;&#039;&#039;&#039; : @addattach[:&amp;lt;attachpt&amp;gt;]=&amp;lt;y/n&amp;gt;&lt;br /&gt;
Where attachpt is :&lt;br /&gt;
 chest|skull|left shoulder|right shoulder|left hand|right hand|left foot|right foot|spine|&lt;br /&gt;
 pelvis|mouth|chin|left ear|right ear|left eyeball|right eyeball|nose|r upper arm|r forearm|&lt;br /&gt;
 l upper arm|l forearm|right hip|r upper leg|r lower leg|left hip|l upper leg|l lower leg|stomach|left pec|&lt;br /&gt;
 right pec|center 2|top right|top|top left|center|bottom left|bottom|bottom right&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Allow/prevent removing attachments&#039;&#039;&#039;&#039;&#039; : @remattach[:&amp;lt;attachpt&amp;gt;]=&amp;lt;y/n&amp;gt;&lt;br /&gt;
Where attachpt is :&lt;br /&gt;
 chest|skull|left shoulder|right shoulder|left hand|right hand|left foot|right foot|spine|&lt;br /&gt;
 pelvis|mouth|chin|left ear|right ear|left eyeball|right eyeball|nose|r upper arm|r forearm|&lt;br /&gt;
 l upper arm|l forearm|right hip|r upper leg|r lower leg|left hip|l upper leg|l lower leg|stomach|left pec|&lt;br /&gt;
 right pec|center 2|top right|top|top left|center|bottom left|bottom|bottom right&lt;br /&gt;
&lt;br /&gt;
Or is there already an easy way to do this which I&#039;ve overlooked? --[[User:Scarlett Flores|Scarlett Flores]] 13:58, 13 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:There is currently no way to do that in Marine&#039;s Viewer, but I can point you to Kitty&#039;s nostrip flag [http://rlva.catznip.com/blog/2009/07/feature-nostrip/] which would work well for what you want (currently in Emerald Greenlife Viewer only).&lt;br /&gt;
:However there is still a use case for @detach:attachpt=n that cannot be covered by nostrip: for locking an attachement against the wearer&#039;s will (but in that case, it is likely the attachment has already been made in the first place for the purpose of being locked, and is scripted with a llOwnerSay(&amp;quot;@detach=n&amp;quot;)). Still, in my opinion this remains an inconsistency in the current RLV API as @remoutfit:arg can be used both with =n and =force but @detach:arg can only be used with =force...&lt;br /&gt;
:--[[User:Satomi Ahn|Satomi Ahn]] 09:39, 27 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Loading a preset is laggy, but still better than loading each parameter by script? ==&lt;br /&gt;
&lt;br /&gt;
Loading WL presets is laggy, but is it less laggy than loading all parameters by script? Or would a script doing this not cause lag but just lag itself? --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 21:25, 16 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Version Changelog ==&lt;br /&gt;
&lt;br /&gt;
Can we have a little section on the API page that briefly lists the additions and changes? --[[User:Ninjafoo Ng|Ninjafoo Ng]] 07:47, 18 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== feature suggestion: forcechat and forceIM ==&lt;br /&gt;
&lt;br /&gt;
How about allowing scripts to make ther person say somthing, emote or otherwise? This woudl serve to, among other things, mind control situations, doing emoting without a choice (like flinching when zapped, blushing when groped etc), having a script send voice commands to another script that usually only obeys voice commands fromt he avatar etc&lt;br /&gt;
&lt;br /&gt;
ps: is there a better place to make feature suggestions?&lt;br /&gt;
&lt;br /&gt;
--[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 16:24, 19 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===force chat level (whisper, talk or shout) ===&lt;br /&gt;
the idea is to allow scripts to force the target (usually only the owner can be the target) to have all chat messages be either whisper, regular talk or shout, regardless of what keyboard shortcuts or gui buttons were pressed --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:24, 26 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
==Feature Suggestion: No-Fly/Fly zones ==&lt;br /&gt;
&lt;br /&gt;
a command to set a range of altitude where flying is allowed or forbidden, operates on top of @fly, defining a zone where the behavior is the opposite of what @fly defined.&lt;br /&gt;
&lt;br /&gt;
It would also be nice to be able to have both a fly and a no-fly zone defined at once, whatever is defined last will overwrite the other where they overlap (would allow for a zone that has a hole in the middle, a sandwich if you will) --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:13, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature sugestion: @Forcefly ==&lt;br /&gt;
&lt;br /&gt;
This command would force the avatar to start or stop flying, if flying is forbidden by the same object that now is running @Forcefly, the avatar would be unable to change their flying/no flying status --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:21, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature suggestion: @Forcepresskeys ==&lt;br /&gt;
&lt;br /&gt;
This command would result in the client behaving as if the user pressed the keys, including triggering control events in scripts.&lt;br /&gt;
&lt;br /&gt;
The parameter would be a list of key and time pairs (time as integer miliseconds), so a sequence of keypresses can be defined in single command. Zero, or an special keyword would indicate no key being pressed. Perhaps use two different separators, one to indicate the keys afterward must wait the last key to timeout and another to indicate they should start being pressed already.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If possible make all keys avaiable (perhaps except for dangerous ones, like delete, backspace, combinations like alt-F4, control-alt-del (this one isn&#039;t as bad as it used to be on Windows, but still better not allow), alt-tab, backspace etc), and for the keypresses must only work inside the client, if another window has focus or somthing, they keys would simply not work, or trigger client behavior event without the client window having focus.  --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:34, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature suggestion: @allowpay ==&lt;br /&gt;
&lt;br /&gt;
My goddess brought up a interesting concept of forcing slaves to not being able to spend lindens without the permission of the dom. So my idea is to have a api command to change the status of whether you are allowed to give money or not give money. I may write a patch for it in due time if this function wants to be considered. This would cover all abilities to debit funds from the current balance. [[User:Chibi Pedalo|Chibi Pedalo]] 17:24, 5 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature Suggestion: force paint ==&lt;br /&gt;
&lt;br /&gt;
(Inspired partially by an idea from a friend of mine)&lt;br /&gt;
&lt;br /&gt;
a command to have the client overlay a texture specified by UUID, over the baked texture, making that the new baked texture, alpha pixels and all&lt;br /&gt;
&lt;br /&gt;
this would allow scripts to make people get dirty, covered in slime sploches, darkyellow semi-transparent stain between the legs implying the person pissed on their pants, bloody gashes across the face etc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there should also be a command to do a clean rebake (a rebake that isntead of being the old rebake, perhaps composited with new textures, would actually do a regular rebake, reading the clothing info and generating the regular baked texture that woudl result form that.&lt;br /&gt;
&lt;br /&gt;
A copy of dirty baked textures would be kept on the client, when a rebake is done, either by the user request or during default functioning of the client, that saved temporary rebake would be what is sent to the server. Having the dirty rebaked textures be saved would allow for cumulative effects, since each time a new texture is applied the results are saved as the baked texture, each new one would be applied to whatever is there already, be it the normal baked texture, or one with dirt on it.&lt;br /&gt;
&lt;br /&gt;
There would also of course be a command to lock/unlock the current (re)baked texture, if it&#039;s dirty, prevent a clean rebake, and if it isn&#039;t prevent, though better would be separated locks, one for clean rebake, and one for getting any more dirty than how it already is&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 05:51, 8 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Curious behavior with exceptions and @sendim/@recvim ==&lt;br /&gt;
&lt;br /&gt;
So I was toying with a &amp;quot;Safety&amp;quot; plugin for my toy&#039;s collar, something I wrote after she was locked to something and was unable to tell me or get help from me.  I just wrote something simple that obtained the collar&#039;s owner, then set TP and IM restriction exceptions for that person on the wearer, thus ensuring that the owner would always be able to Teleport the wearer or Send/Receive IMs from them.  Initially this worked fine... I thought.  Every device we tested restricted everything covered except for SENDING IMs.&lt;br /&gt;
&lt;br /&gt;
When we finally were in a situation where a separate restraint (a gag) restricted her IM sending ability she wasn&#039;t able to IM me, despite an IM sending exception being set on her collar.  The same gag also restricted her ability to receive IMs, but the exception on the collar allowed me to IM her just fine.  The same was true for the teleport lure exception.  Bottom line, it seems that ONLY for the @sendIM restriction the exception MUST be set on the same object that sets the overall restriction.&lt;br /&gt;
&lt;br /&gt;
Apparently she is using RLV v1.17 (she said it was based on 1.22.11, so I think that&#039;s right), so I don&#039;t know if this is something which has been addressed in v1.19.  Am I right in assuming this is a glitch? -- [[User:Felis Darwin|Felis Darwin]] 06:06, 20 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature Suggestion: @logout=force ==&lt;br /&gt;
&lt;br /&gt;
Forces the wearer to log out of SL with a message explaining that such and such item as removed you from SL. Its a interesting idea to make a pet or slave leave SL for various reasons.&lt;br /&gt;
&lt;br /&gt;
== @clear, detachments and locked status ==&lt;br /&gt;
&lt;br /&gt;
If an attachment is not locked, sending @clear when dettaching should still be recommended since in that case the attachment won&#039;t be automaticly reattached and the permissions will have to be garbage collected. Only when the attachment is locked that the @clear should be omitted when it is detached --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:38, 2 October 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Moderate rewrite of Architecture section ==&lt;br /&gt;
&lt;br /&gt;
I just did a moderate rewrite of the Architecture section.  The main change was to give preference to the term &#039;command&#039; instead of &#039;behavior&#039;, because a) the next section is called &amp;quot;List of Commands&amp;quot; and uses that word in the introductory paragraph; and b) not all of these things are behaviors but they are all commands.  The other significant change was to just make more effective use of wiki formatting.   &lt;br /&gt;
&lt;br /&gt;
I hope that people will consider this an improvement, but I won&#039;t be offended by constructive criticism or even reverting to the original text (if accompanied by some reasoning).  &lt;br /&gt;
[[User:Kidd Krasner|Kidd Krasner]] 14:28, 17 December 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
== Feature suggestion: @getlocked[:attachpt]=&amp;lt;channel_number&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
A way to see which attachments are locked and not detachable or attachable.&lt;br /&gt;
There is, as far as I know, no way yet to see which attachmentpoints are locked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;discription:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Makes the viewer automatically answer the current lockstatus of attachment points as a list of 0s (unlocked) and 1s (locked) immediately on the chat channel number &amp;lt;channel_number&amp;gt; that the script can listen to. Always use a positive integer. Remember that regular viewers do not answer anything at all so remove the listener after a timeout. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The list of 0s and 1s corresponds to :&#039;&#039;&#039; &lt;br /&gt;
{{Box|none,chest,skull,left shoulder,right shoulder,left hand,right hand,left foot,right foot,spine,&lt;br /&gt;
pelvis,mouth,chin,left ear,right ear,left eyeball,right eyeball,nose,r upper arm,r forearm,&lt;br /&gt;
l upper arm,l forearm,right hip,r upper leg,r lower leg,left hip,l upper leg,l lower leg,stomach,left pec,&lt;br /&gt;
right pec,center 2,top right,top,top left,center,bottom left,bottom,bottom right}}&lt;br /&gt;
&lt;br /&gt;
in that order. &lt;br /&gt;
&lt;br /&gt;
If an attachment point is specified, answers a single 0 (unlocked) or 1 (locked) corresponding to the point.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A similiar feature would be very usefull for the clothing layers.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[User:Misty Wulluf|Misty Wulluf]] 12:37, 17 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Possible bug with respect to setdebug for scenegamma and renderresolutiondivisor ==&lt;br /&gt;
&lt;br /&gt;
While &#039;&#039;setenv_scenegamma&#039;&#039; and &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; could be seen to be useful commands, there is an issue of knowing what to do if multiple objects are issuing them. Right now it appears that the viewer is single-threaded, insofar as the last command entered wins. To make the case specific, assume I am wearing a blindfold that affects my vision using &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; and then accidentally step into a trap that sends a &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; change through a relay to my viewer. Now that command overrides the blindfold. On being freed from the trap (either by standing or safewording out from the relay) the value of &#039;&#039;renderresolutiondivisor&#039;&#039; will be set back to 1, thus negating the blindfold. It could be argued that using an appropriate &#039;&#039;@getdebug_renderresolutiondivisor&#039;&#039; before the trap operates, would allow the trap, when the avatar stands, to set the value back to the value it found before it operated. The problem is that if the order is: put on blindfold, sit on trap, take off blindfold, stand up from trap then the trap would set &#039;&#039;renderresolutiondivisor&#039;&#039; to the value as if the blindfold were on.&lt;br /&gt;
&lt;br /&gt;
Note that as a relay developer, I have the same problem, knowing what to do when safeword is called, since I have no obvious value to set for &#039;&#039;renderresolutiondivisor&#039;&#039; or &#039;&#039;scenegamma&#039;&#039;. I could set them to 1 and 1.0 respectively, but that is now an escape from other worn attachments. This seems to be something of a problem that it is hard, maybe even impossible to script your way out of, given the global nature of the debug values and the need to respond on a per-object basis.&lt;br /&gt;
&lt;br /&gt;
Should a relay just set the values back to 1.0 for &#039;&#039;scenegamma&#039;&#039; and 1 for &#039;&#039;renderresolutiondivisor&#039;&#039;?&lt;br /&gt;
&lt;br /&gt;
--[[User:Chloe1982 Constantine|Chloe1982 Constantine]] 21:06, 23 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
== Feature suggestion: @emailsnapshot:&amp;lt;emailaddr&amp;gt;=force ==&lt;br /&gt;
This would use the snapshot email feature to send a snapshot to &amp;lt;emailaddr&amp;gt;.  This would allow a range of products to be made that can&#039;t currently, particularly in conjunction with Shared Media.&lt;br /&gt;
&lt;br /&gt;
Due to privacy and spam concerns, the user should be asked for permission the first time an object tries to send to a specific address.  This permission (or rejection) should be kept on a per-object basis in the same way restrictions are (and so cleared when the object is derezed or the user relogs).  Something like:&lt;br /&gt;
&lt;br /&gt;
  +----------------------------------------+&lt;br /&gt;
  |                                        |&lt;br /&gt;
  |  May the object &#039;Shapshot Taker&#039; send  |&lt;br /&gt;
  |  snapshots to &#039;test@example.com&#039;?      |&lt;br /&gt;
  |                                        |&lt;br /&gt;
  |        [Yes]             [No]          |&lt;br /&gt;
  |                                        |&lt;br /&gt;
  +----------------------------------------+&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It might be desirable to set the resolution, in which case I would propose:&lt;br /&gt;
&lt;br /&gt;
  @emailsnapshot:&amp;lt;emailaddr&amp;gt;[;&amp;lt;width&amp;gt;x&amp;lt;height&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Although it would need to be limited to something reasonable.&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think it would be desirable to allow the interface to be included in the snapshot, due to privacy concerns, although perhaps that boat has already sailed.&lt;br /&gt;
&lt;br /&gt;
I would also say that HUD objects should only be shown in the snapshot if the HUD is locked (and so would be forced on for other snapshots).&lt;br /&gt;
&lt;br /&gt;
However, if these were to be configurable, I would propose:&lt;br /&gt;
&lt;br /&gt;
  @emailsnapshot:&amp;lt;emailaddr&amp;gt;[;&amp;lt;width&amp;gt;x&amp;lt;height&amp;gt;][;includehud][;includeinterface]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Edit: Hmm, actually there are further privacy concerns with this idea, as much as I would like it, it also would expose the email address you registered with (and that is not visible otherwise).  This seems like an unacceptable breech to me.  I do wish there were some other way to get this sort of feature.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[User:Winter Seale|Winter Seale]] 00:08, 11 March 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/RestrainedLoveAPI&amp;diff=797312</id>
		<title>Talk:LSL Protocol/RestrainedLoveAPI</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/RestrainedLoveAPI&amp;diff=797312"/>
		<updated>2010-03-11T00:14:11Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Feature suggestion: @emailsnapshot:=force */ Added concerns regarding email address being shared&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Question regarding @remoutfit and teens===&lt;br /&gt;
&lt;br /&gt;
Thank you for putting up that API.&lt;br /&gt;
&lt;br /&gt;
But I got a question regarding the  &#039;&#039;@remoutfit[:&amp;lt;part&amp;gt;]=&amp;lt;y/n&amp;gt;&#039;&#039;-command:&lt;br /&gt;
It says&#039;&#039;(underpants and underwear are kept for teens)&#039;&#039;. What do you mean with that?&lt;br /&gt;
&lt;br /&gt;
Is removing underwear disabled only on teengrid? Is it disabled in PG Areas? Or just one of your nice jokes? :-)&lt;br /&gt;
&lt;br /&gt;
MK: No no this time it was not a joke, the standard viewer actually checks that you&#039;re not on the teen grid and if you are, discards removing underwear. I took care of not breaking that check when adding the remoutfit command :)&lt;br /&gt;
&lt;br /&gt;
== How to use for bondage furniture? ==&lt;br /&gt;
&lt;br /&gt;
Hi Marine,&lt;br /&gt;
&lt;br /&gt;
Good stuff, your viewer. I have a question on how to use the API in bondage furniture. &lt;br /&gt;
&lt;br /&gt;
As a test I did put the @remoutfit=force in the menuhandler of a bondage cross that I have. Now, when I use the menu while not sitting on the cross ... I am suddenly naked. Blush. Nice effect, but not what I expected. I expected the command to work on the AvatarOnSitTarget, if that person would use your viewer. &lt;br /&gt;
&lt;br /&gt;
Do I do something wrong, or is your viewer focused to impact the Owner of worn attachments? If the former, please let me know how to do it right. If the latter, it would be great if the viewer would work on Owner in case of attachments, and work on AvatarOnSitTarget in case of objects to sit on.&lt;br /&gt;
&lt;br /&gt;
Looking forward to your answer.&lt;br /&gt;
Ciao, Tam&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The answer came to me in world. Use the RealRestraint Relay&lt;br /&gt;
https://wiki.secondlife.com/wiki/LSL_Protocol/RestrainedLifeRelaySpecs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meaningless or App-Defined Rules ==&lt;br /&gt;
&lt;br /&gt;
I noticed (accidentially, due to a misspelling) that if you send a rule that doesn&#039;t exist, it has no effect, but it DOES remember the rule, and can be retrieved using @getstatus.  For example, you can llOwnerSay(&amp;quot;@randomtext=n&amp;quot;) and later when you call llOwnerSay(&amp;quot;@getstatus=x&amp;quot;) the rules in the response will include &amp;quot;randomtext&amp;quot; in the list.&lt;br /&gt;
&lt;br /&gt;
Is this a bug or a feature?  The reason I ask is, there are some good uses for this if the behavior can be depended upon, but if it&#039;s likely to disappear in a future version, then I&#039;ll steer clear of using it.  Thanks.&lt;br /&gt;
&lt;br /&gt;
--[[User:Galatea Gynoid|Galatea Gynoid]] 12:07, 17 August 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually there is no such thing as &amp;quot;a rule that does not exist&amp;quot;, the viewer takes whatever it is sent and puts it into its internal list for later. This is because I don&#039;t want to duplicate commands (I have to for some of them, for instance when checking whether the inventory is already open when issuing a @showinv). It&#039;s by design so it&#039;s easier to just poke at the code and add your own command without wondering whether you have to add it to a static table somewhere. So it&#039;s neither a bug nor a feature I would say.&lt;br /&gt;
&lt;br /&gt;
And to answer your actual question, it&#039;s very unlikely to change in the future, at least as long as I&#039;m in charge. Yes you&#039;re right, it could be a good way to store data in-world for the time of a unique session. However keep in mind that @getstatus gives a regular chat message, that is capped at 1023 characters.&lt;br /&gt;
&lt;br /&gt;
--[[User:Marine Kelley|Marine Kelley]] 01:47, 18 August 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== @sendchannel needs a bit of clarification ==&lt;br /&gt;
&lt;br /&gt;
The way it&#039;s worded, the explanation of sendchannel is a bit confusing.  I &#039;&#039;assume&#039;&#039; the way the restriction works is that the command @sendchannel=n would restrict all alt-channel chat, but the command @sendchannel:3=n would allow chat on that specific channel even if the global restriction is in place.  The way it&#039;s worded though, it seems like it could be that @sendchannel:3=n would restrict chat &#039;&#039;only&#039;&#039; on channel 3.  -- [[User:Felis Darwin|Felis Darwin]] 21:12, 7 December 2008 (UTC)&lt;br /&gt;
&lt;br /&gt;
Maybe it&#039;s poorly worded... @sendchannel:3=n does add an exception to the @sendchannel restriction, in other words you can speak on channel 3 when the former is applied.&lt;br /&gt;
&lt;br /&gt;
[[User:Marine Kelley|Marine Kelley]] 15:16, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== @acceptpermission &amp;amp; @denypermission ==&lt;br /&gt;
&lt;br /&gt;
Marine, your blog lists these new commands, but I don&#039;t see anything on usage in here. Were they overlooked? --[[User:Teyonas Miklos|Teyonas Miklos]] 07:19, 8 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
By the way, if @acceptpermission would also affect animation permission, that would be awesome! --[[User:Satomi Ahn|Satomi Ahn]] 16:42, 19 February 2009 (UTC)&lt;br /&gt;
:Oh it looks like the wiki has been completed now. Thanks Marine. But, may I ask, do @acceptpermission &amp;amp; @denypermission really work for animation permission now? Your blog says it is only for attachements and controls! --[[User:Satomi Ahn|Satomi Ahn]] 11:52, 31 March 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::Yes if I remember correctly it only accepts attach and controls permissions... I am really torn on the animation permission because it is automatically accepted if you&#039;re sitting on the prim that contains the animation (like furnitures), or wearing it (like restraints) but it proves to be a vulnerability for griefers to exploit. Granted, griefing with weird animations is lame (as is griefing in general), but it is griefing nonetheless. I should see how to accept animation permission requests from prims you are sitting on, regardless of whether they contain the animation or not. That should help for rezzable poseballs at least. [[User:Marine Kelley|Marine Kelley]] 15:13, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::: Is there a way to start an animation which is not in the prim? In case it is possible it would be interesting to extend the relay protocol to allow this. But I thought this was impossible? Another idea is to explicitly specify the key of the prim that should be allowed to start an animation: &amp;lt;code&amp;gt;@acceptpermission:7adf6218-ab26-8566-8387-660133840794=add&amp;lt;/code&amp;gt;. I am not sure if the viewer has this information in the permission query function. The scenario I have in mind is a Star Trek like force-field cell door that will give an electroshock on touch, assuming that the cell has an active relay session. Something else to keep in mind is that there is a pyramid scheme vampire game out there which sees accepting animation permission as accepting to be added to the database. --[[User:Maike Short|Maike Short]] 18:54, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::: Eh, you actually wrote this, on the wiki: &amp;quot;Force the viewer to automatically accept attach and &#039;animate&#039; permission requests : @acceptpermission=&amp;lt;rem/add&amp;gt; &amp;quot;. So I guess this is an error. By the way, Kitty might have pointed this to you, but there is actually a way to to get animation permissions by mean of RLV commands, exploiting a loophole in the logic you use for @acceptpermission. Basically, if this behavior is enabled, if you request permission to animate along with  either permission to attach or permission to take controls, then you are granted both. --[[User:Satomi Ahn|Satomi Ahn]] 20:35, 14 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== A shared root... and what about a protected root? ==&lt;br /&gt;
&lt;br /&gt;
I mean, if you are tired to put your tatoos back every time someone strips you... it would be great to be able to protect easily some clothes and attachments (hair, tail, ears,...).&lt;br /&gt;
You can already somehow do this for clothes with @remoutfit:xxxx=n, and for prims with @detach=n, but this requires scripting, and very often, you will forget to lock them.&lt;br /&gt;
&lt;br /&gt;
I believe this would be a lot easier if you could have a /#protected folder whose content cannot be force-detached by the mean of rlv commands.&lt;br /&gt;
Moreover, it would be even greater if RLV did not report items you are wearing and are in #protected: indeed some scripts will loop until they have successfully detached all they wanted to. If the viewer does not report those items are worn, then those scripts would be happy.&lt;br /&gt;
&lt;br /&gt;
--[[User:Satomi Ahn|Satomi Ahn]] 23:52, 19 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I like the idea of checking against some kind of viewer-side characteristic of the object, but I&#039;m not sure a folder would do... After all the user could want to protect-unprotect quickly, and moving a large chunk of inventory could reveal to be a hassle. I&#039;ll think about it.&lt;br /&gt;
&lt;br /&gt;
[[User:Marine Kelley|Marine Kelley]] 15:09, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just a note a posteriori: Kitty Barnett&#039;s &amp;quot;nostrip&amp;quot; flag works really well for what I wanted. It would be nice if Marine Kelley&#039;s RLV had this feature too. How does it work? Easy: if an item or folder has (nostrip) in its name, then it will be protected against @remoutfit:layer=force or @detach:attachpt=force commands. A lot better than my initial proposal as it is really fine-grained.&lt;br /&gt;
&lt;br /&gt;
--[[User:Satomi Ahn|Satomi Ahn]] 09:31, 27 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Third party extension @putinv and the SL permission system ==&lt;br /&gt;
&lt;br /&gt;
In my opinion the SL permission system has a serious) flaw. Objects owned by the land owner do have special rights without a permission dialog:&lt;br /&gt;
* manage the ban list&lt;br /&gt;
* change the media settings (can be used to get the ip-address of visitors)&lt;br /&gt;
* teraform (can be used to destroy the landscape and return rezzed objects to the lost and found folder, thous destroying a lovely place)&lt;br /&gt;
&lt;br /&gt;
While I think it is an issue that SL automatically grants these rights to objects owned by the land lord, I am concerned that the auto-accept and attach might be used to simplify attacks. So if you implement this inofficial extension (the official RLV viewer does not) please add a warning.&lt;br /&gt;
&lt;br /&gt;
PS: Oh, it just occured to me that it can be used to write a self replicating worm that jumps across avatars. This would surely have the potential to get the BDSM community some bad PR. --[[User:Maike Short|Maike Short]] 16:18, 8 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:Hm there&#039;s already a (way too) long discussion about this on the forums.&lt;br /&gt;
:Here: http://forums.secondlife.com/showthread.php?t=223796&amp;amp;page=30&amp;amp;pp=15&lt;br /&gt;
:And here: http://sldev.free.fr/forum/viewtopic.php?f=7&amp;amp;t=8&lt;br /&gt;
:I personnaly don&#039;t want to discuss the issue anymore, but I thought I had to point you to this ;-), as I basically share your concerns.&lt;br /&gt;
:--[[User:Satomi Ahn|Satomi Ahn]] 20:29, 14 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Protecting attachments against detach ==&lt;br /&gt;
&lt;br /&gt;
I&#039;m scripting a gizmo to prevent stripping of tattoos, piercings etc. It would be very useful to have a command similar to the &amp;quot;@remoutfit&amp;quot;, but for attachments. That way texture clothing and prim clothing can be treated the same way, instead of having to drop a script into each protected attachment.&lt;br /&gt;
&lt;br /&gt;
My question is: Would it be possible to include commands looking something like this?&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Allow/prevent wearing attachments&#039;&#039;&#039;&#039;&#039; : @addattach[:&amp;lt;attachpt&amp;gt;]=&amp;lt;y/n&amp;gt;&lt;br /&gt;
Where attachpt is :&lt;br /&gt;
 chest|skull|left shoulder|right shoulder|left hand|right hand|left foot|right foot|spine|&lt;br /&gt;
 pelvis|mouth|chin|left ear|right ear|left eyeball|right eyeball|nose|r upper arm|r forearm|&lt;br /&gt;
 l upper arm|l forearm|right hip|r upper leg|r lower leg|left hip|l upper leg|l lower leg|stomach|left pec|&lt;br /&gt;
 right pec|center 2|top right|top|top left|center|bottom left|bottom|bottom right&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Allow/prevent removing attachments&#039;&#039;&#039;&#039;&#039; : @remattach[:&amp;lt;attachpt&amp;gt;]=&amp;lt;y/n&amp;gt;&lt;br /&gt;
Where attachpt is :&lt;br /&gt;
 chest|skull|left shoulder|right shoulder|left hand|right hand|left foot|right foot|spine|&lt;br /&gt;
 pelvis|mouth|chin|left ear|right ear|left eyeball|right eyeball|nose|r upper arm|r forearm|&lt;br /&gt;
 l upper arm|l forearm|right hip|r upper leg|r lower leg|left hip|l upper leg|l lower leg|stomach|left pec|&lt;br /&gt;
 right pec|center 2|top right|top|top left|center|bottom left|bottom|bottom right&lt;br /&gt;
&lt;br /&gt;
Or is there already an easy way to do this which I&#039;ve overlooked? --[[User:Scarlett Flores|Scarlett Flores]] 13:58, 13 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:There is currently no way to do that in Marine&#039;s Viewer, but I can point you to Kitty&#039;s nostrip flag [http://rlva.catznip.com/blog/2009/07/feature-nostrip/] which would work well for what you want (currently in Emerald Greenlife Viewer only).&lt;br /&gt;
:However there is still a use case for @detach:attachpt=n that cannot be covered by nostrip: for locking an attachement against the wearer&#039;s will (but in that case, it is likely the attachment has already been made in the first place for the purpose of being locked, and is scripted with a llOwnerSay(&amp;quot;@detach=n&amp;quot;)). Still, in my opinion this remains an inconsistency in the current RLV API as @remoutfit:arg can be used both with =n and =force but @detach:arg can only be used with =force...&lt;br /&gt;
:--[[User:Satomi Ahn|Satomi Ahn]] 09:39, 27 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Loading a preset is laggy, but still better than loading each parameter by script? ==&lt;br /&gt;
&lt;br /&gt;
Loading WL presets is laggy, but is it less laggy than loading all parameters by script? Or would a script doing this not cause lag but just lag itself? --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 21:25, 16 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Version Changelog ==&lt;br /&gt;
&lt;br /&gt;
Can we have a little section on the API page that briefly lists the additions and changes? --[[User:Ninjafoo Ng|Ninjafoo Ng]] 07:47, 18 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== feature suggestion: forcechat and forceIM ==&lt;br /&gt;
&lt;br /&gt;
How about allowing scripts to make ther person say somthing, emote or otherwise? This woudl serve to, among other things, mind control situations, doing emoting without a choice (like flinching when zapped, blushing when groped etc), having a script send voice commands to another script that usually only obeys voice commands fromt he avatar etc&lt;br /&gt;
&lt;br /&gt;
ps: is there a better place to make feature suggestions?&lt;br /&gt;
&lt;br /&gt;
--[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 16:24, 19 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===force chat level (whisper, talk or shout) ===&lt;br /&gt;
the idea is to allow scripts to force the target (usually only the owner can be the target) to have all chat messages be either whisper, regular talk or shout, regardless of what keyboard shortcuts or gui buttons were pressed --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:24, 26 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
==Feature Suggestion: No-Fly/Fly zones ==&lt;br /&gt;
&lt;br /&gt;
a command to set a range of altitude where flying is allowed or forbidden, operates on top of @fly, defining a zone where the behavior is the opposite of what @fly defined.&lt;br /&gt;
&lt;br /&gt;
It would also be nice to be able to have both a fly and a no-fly zone defined at once, whatever is defined last will overwrite the other where they overlap (would allow for a zone that has a hole in the middle, a sandwich if you will) --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:13, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature sugestion: @Forcefly ==&lt;br /&gt;
&lt;br /&gt;
This command would force the avatar to start or stop flying, if flying is forbidden by the same object that now is running @Forcefly, the avatar would be unable to change their flying/no flying status --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:21, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature suggestion: @Forcepresskeys ==&lt;br /&gt;
&lt;br /&gt;
This command would result in the client behaving as if the user pressed the keys, including triggering control events in scripts.&lt;br /&gt;
&lt;br /&gt;
The parameter would be a list of key and time pairs (time as integer miliseconds), so a sequence of keypresses can be defined in single command. Zero, or an special keyword would indicate no key being pressed. Perhaps use two different separators, one to indicate the keys afterward must wait the last key to timeout and another to indicate they should start being pressed already.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If possible make all keys avaiable (perhaps except for dangerous ones, like delete, backspace, combinations like alt-F4, control-alt-del (this one isn&#039;t as bad as it used to be on Windows, but still better not allow), alt-tab, backspace etc), and for the keypresses must only work inside the client, if another window has focus or somthing, they keys would simply not work, or trigger client behavior event without the client window having focus.  --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:34, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature suggestion: @allowpay ==&lt;br /&gt;
&lt;br /&gt;
My goddess brought up a interesting concept of forcing slaves to not being able to spend lindens without the permission of the dom. So my idea is to have a api command to change the status of whether you are allowed to give money or not give money. I may write a patch for it in due time if this function wants to be considered. This would cover all abilities to debit funds from the current balance. [[User:Chibi Pedalo|Chibi Pedalo]] 17:24, 5 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature Suggestion: force paint ==&lt;br /&gt;
&lt;br /&gt;
(Inspired partially by an idea from a friend of mine)&lt;br /&gt;
&lt;br /&gt;
a command to have the client overlay a texture specified by UUID, over the baked texture, making that the new baked texture, alpha pixels and all&lt;br /&gt;
&lt;br /&gt;
this would allow scripts to make people get dirty, covered in slime sploches, darkyellow semi-transparent stain between the legs implying the person pissed on their pants, bloody gashes across the face etc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there should also be a command to do a clean rebake (a rebake that isntead of being the old rebake, perhaps composited with new textures, would actually do a regular rebake, reading the clothing info and generating the regular baked texture that woudl result form that.&lt;br /&gt;
&lt;br /&gt;
A copy of dirty baked textures would be kept on the client, when a rebake is done, either by the user request or during default functioning of the client, that saved temporary rebake would be what is sent to the server. Having the dirty rebaked textures be saved would allow for cumulative effects, since each time a new texture is applied the results are saved as the baked texture, each new one would be applied to whatever is there already, be it the normal baked texture, or one with dirt on it.&lt;br /&gt;
&lt;br /&gt;
There would also of course be a command to lock/unlock the current (re)baked texture, if it&#039;s dirty, prevent a clean rebake, and if it isn&#039;t prevent, though better would be separated locks, one for clean rebake, and one for getting any more dirty than how it already is&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 05:51, 8 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Curious behavior with exceptions and @sendim/@recvim ==&lt;br /&gt;
&lt;br /&gt;
So I was toying with a &amp;quot;Safety&amp;quot; plugin for my toy&#039;s collar, something I wrote after she was locked to something and was unable to tell me or get help from me.  I just wrote something simple that obtained the collar&#039;s owner, then set TP and IM restriction exceptions for that person on the wearer, thus ensuring that the owner would always be able to Teleport the wearer or Send/Receive IMs from them.  Initially this worked fine... I thought.  Every device we tested restricted everything covered except for SENDING IMs.&lt;br /&gt;
&lt;br /&gt;
When we finally were in a situation where a separate restraint (a gag) restricted her IM sending ability she wasn&#039;t able to IM me, despite an IM sending exception being set on her collar.  The same gag also restricted her ability to receive IMs, but the exception on the collar allowed me to IM her just fine.  The same was true for the teleport lure exception.  Bottom line, it seems that ONLY for the @sendIM restriction the exception MUST be set on the same object that sets the overall restriction.&lt;br /&gt;
&lt;br /&gt;
Apparently she is using RLV v1.17 (she said it was based on 1.22.11, so I think that&#039;s right), so I don&#039;t know if this is something which has been addressed in v1.19.  Am I right in assuming this is a glitch? -- [[User:Felis Darwin|Felis Darwin]] 06:06, 20 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature Suggestion: @logout=force ==&lt;br /&gt;
&lt;br /&gt;
Forces the wearer to log out of SL with a message explaining that such and such item as removed you from SL. Its a interesting idea to make a pet or slave leave SL for various reasons.&lt;br /&gt;
&lt;br /&gt;
== @clear, detachments and locked status ==&lt;br /&gt;
&lt;br /&gt;
If an attachment is not locked, sending @clear when dettaching should still be recommended since in that case the attachment won&#039;t be automaticly reattached and the permissions will have to be garbage collected. Only when the attachment is locked that the @clear should be omitted when it is detached --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:38, 2 October 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Moderate rewrite of Architecture section ==&lt;br /&gt;
&lt;br /&gt;
I just did a moderate rewrite of the Architecture section.  The main change was to give preference to the term &#039;command&#039; instead of &#039;behavior&#039;, because a) the next section is called &amp;quot;List of Commands&amp;quot; and uses that word in the introductory paragraph; and b) not all of these things are behaviors but they are all commands.  The other significant change was to just make more effective use of wiki formatting.   &lt;br /&gt;
&lt;br /&gt;
I hope that people will consider this an improvement, but I won&#039;t be offended by constructive criticism or even reverting to the original text (if accompanied by some reasoning).  &lt;br /&gt;
[[User:Kidd Krasner|Kidd Krasner]] 14:28, 17 December 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
== Feature suggestion: @getlocked[:attachpt]=&amp;lt;channel_number&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
A way to see which attachments are locked and not detachable or attachable.&lt;br /&gt;
There is, as far as I know, no way yet to see which attachmentpoints are locked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;discription:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Makes the viewer automatically answer the current lockstatus of attachment points as a list of 0s (unlocked) and 1s (locked) immediately on the chat channel number &amp;lt;channel_number&amp;gt; that the script can listen to. Always use a positive integer. Remember that regular viewers do not answer anything at all so remove the listener after a timeout. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The list of 0s and 1s corresponds to :&#039;&#039;&#039; &lt;br /&gt;
{{Box|none,chest,skull,left shoulder,right shoulder,left hand,right hand,left foot,right foot,spine,&lt;br /&gt;
pelvis,mouth,chin,left ear,right ear,left eyeball,right eyeball,nose,r upper arm,r forearm,&lt;br /&gt;
l upper arm,l forearm,right hip,r upper leg,r lower leg,left hip,l upper leg,l lower leg,stomach,left pec,&lt;br /&gt;
right pec,center 2,top right,top,top left,center,bottom left,bottom,bottom right}}&lt;br /&gt;
&lt;br /&gt;
in that order. &lt;br /&gt;
&lt;br /&gt;
If an attachment point is specified, answers a single 0 (unlocked) or 1 (locked) corresponding to the point.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A similiar feature would be very usefull for the clothing layers.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[User:Misty Wulluf|Misty Wulluf]] 12:37, 17 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Possible bug with respect to setdebug for scenegamma and renderresolutiondivisor ==&lt;br /&gt;
&lt;br /&gt;
While &#039;&#039;setenv_scenegamma&#039;&#039; and &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; could be seen to be useful commands, there is an issue of knowing what to do if multiple objects are issuing them. Right now it appears that the viewer is single-threaded, insofar as the last command entered wins. To make the case specific, assume I am wearing a blindfold that affects my vision using &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; and then accidentally step into a trap that sends a &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; change through a relay to my viewer. Now that command overrides the blindfold. On being freed from the trap (either by standing or safewording out from the relay) the value of &#039;&#039;renderresolutiondivisor&#039;&#039; will be set back to 1, thus negating the blindfold. It could be argued that using an appropriate &#039;&#039;@getdebug_renderresolutiondivisor&#039;&#039; before the trap operates, would allow the trap, when the avatar stands, to set the value back to the value it found before it operated. The problem is that if the order is: put on blindfold, sit on trap, take off blindfold, stand up from trap then the trap would set &#039;&#039;renderresolutiondivisor&#039;&#039; to the value as if the blindfold were on.&lt;br /&gt;
&lt;br /&gt;
Note that as a relay developer, I have the same problem, knowing what to do when safeword is called, since I have no obvious value to set for &#039;&#039;renderresolutiondivisor&#039;&#039; or &#039;&#039;scenegamma&#039;&#039;. I could set them to 1 and 1.0 respectively, but that is now an escape from other worn attachments. This seems to be something of a problem that it is hard, maybe even impossible to script your way out of, given the global nature of the debug values and the need to respond on a per-object basis.&lt;br /&gt;
&lt;br /&gt;
Should a relay just set the values back to 1.0 for &#039;&#039;scenegamma&#039;&#039; and 1 for &#039;&#039;renderresolutiondivisor&#039;&#039;?&lt;br /&gt;
&lt;br /&gt;
--[[User:Chloe1982 Constantine|Chloe1982 Constantine]] 21:06, 23 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
== Feature suggestion: @emailsnapshot:&amp;lt;emailaddr&amp;gt;=force ==&lt;br /&gt;
This would use the snapshot email feature to send a snapshot to &amp;lt;emailaddr&amp;gt;.  This would allow a range of products to be made that can&#039;t currently, particularly in conjunction with Shared Media.&lt;br /&gt;
&lt;br /&gt;
Due to privacy and spam concerns, the user should be asked for permission the first time an object tries to send to a specific address.  This permission (or rejection) should be kept on a per-object basis in the same way restrictions are (and so cleared when the object is derezed or the user relogs).  Something like:&lt;br /&gt;
&lt;br /&gt;
  +----------------------------------------------------&lt;br /&gt;
  |&lt;br /&gt;
  |  May the object &#039;Shapshot Taker&#039; send&lt;br /&gt;
  |  snapshots to &#039;test@example.com&#039;?&lt;br /&gt;
  |&lt;br /&gt;
  |        [Yes]             [No]&lt;br /&gt;
  |&lt;br /&gt;
  +----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It might be desirable to set the resolution, in which case I would propose:&lt;br /&gt;
&lt;br /&gt;
  @emailsnapshot:&amp;lt;emailaddr&amp;gt;[;&amp;lt;width&amp;gt;x&amp;lt;height&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Although it would need to be limited to something reasonable.&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think it would be desirable to allow the interface to be included in the snapshot, due to privacy concerns, although perhaps that boat has already sailed.&lt;br /&gt;
&lt;br /&gt;
I would also say that HUD objects should only be shown in the snapshot if the HUD is locked (and so would be forced on for other snapshots).&lt;br /&gt;
&lt;br /&gt;
However, if these were to be configurable, I would propose:&lt;br /&gt;
&lt;br /&gt;
  @emailsnapshot:&amp;lt;emailaddr&amp;gt;[;&amp;lt;width&amp;gt;x&amp;lt;height&amp;gt;][;includehud][;includeinterface]&lt;br /&gt;
&lt;br /&gt;
Edit: Hmm, actually there are further privacy concerns with this idea, as much as I would like it, it also would expose the email address you registered with (and that is not visible otherwise).  This seems like an unacceptable breech to me.  I do wish there were some other way to get this sort of feature.&lt;br /&gt;
&lt;br /&gt;
[[User:Winter Seale|Winter Seale]] 00:08, 11 March 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/RestrainedLoveAPI&amp;diff=797302</id>
		<title>Talk:LSL Protocol/RestrainedLoveAPI</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:LSL_Protocol/RestrainedLoveAPI&amp;diff=797302"/>
		<updated>2010-03-11T00:08:23Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Added @emailsnapshot feature suggestion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Question regarding @remoutfit and teens===&lt;br /&gt;
&lt;br /&gt;
Thank you for putting up that API.&lt;br /&gt;
&lt;br /&gt;
But I got a question regarding the  &#039;&#039;@remoutfit[:&amp;lt;part&amp;gt;]=&amp;lt;y/n&amp;gt;&#039;&#039;-command:&lt;br /&gt;
It says&#039;&#039;(underpants and underwear are kept for teens)&#039;&#039;. What do you mean with that?&lt;br /&gt;
&lt;br /&gt;
Is removing underwear disabled only on teengrid? Is it disabled in PG Areas? Or just one of your nice jokes? :-)&lt;br /&gt;
&lt;br /&gt;
MK: No no this time it was not a joke, the standard viewer actually checks that you&#039;re not on the teen grid and if you are, discards removing underwear. I took care of not breaking that check when adding the remoutfit command :)&lt;br /&gt;
&lt;br /&gt;
== How to use for bondage furniture? ==&lt;br /&gt;
&lt;br /&gt;
Hi Marine,&lt;br /&gt;
&lt;br /&gt;
Good stuff, your viewer. I have a question on how to use the API in bondage furniture. &lt;br /&gt;
&lt;br /&gt;
As a test I did put the @remoutfit=force in the menuhandler of a bondage cross that I have. Now, when I use the menu while not sitting on the cross ... I am suddenly naked. Blush. Nice effect, but not what I expected. I expected the command to work on the AvatarOnSitTarget, if that person would use your viewer. &lt;br /&gt;
&lt;br /&gt;
Do I do something wrong, or is your viewer focused to impact the Owner of worn attachments? If the former, please let me know how to do it right. If the latter, it would be great if the viewer would work on Owner in case of attachments, and work on AvatarOnSitTarget in case of objects to sit on.&lt;br /&gt;
&lt;br /&gt;
Looking forward to your answer.&lt;br /&gt;
Ciao, Tam&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The answer came to me in world. Use the RealRestraint Relay&lt;br /&gt;
https://wiki.secondlife.com/wiki/LSL_Protocol/RestrainedLifeRelaySpecs&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Meaningless or App-Defined Rules ==&lt;br /&gt;
&lt;br /&gt;
I noticed (accidentially, due to a misspelling) that if you send a rule that doesn&#039;t exist, it has no effect, but it DOES remember the rule, and can be retrieved using @getstatus.  For example, you can llOwnerSay(&amp;quot;@randomtext=n&amp;quot;) and later when you call llOwnerSay(&amp;quot;@getstatus=x&amp;quot;) the rules in the response will include &amp;quot;randomtext&amp;quot; in the list.&lt;br /&gt;
&lt;br /&gt;
Is this a bug or a feature?  The reason I ask is, there are some good uses for this if the behavior can be depended upon, but if it&#039;s likely to disappear in a future version, then I&#039;ll steer clear of using it.  Thanks.&lt;br /&gt;
&lt;br /&gt;
--[[User:Galatea Gynoid|Galatea Gynoid]] 12:07, 17 August 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actually there is no such thing as &amp;quot;a rule that does not exist&amp;quot;, the viewer takes whatever it is sent and puts it into its internal list for later. This is because I don&#039;t want to duplicate commands (I have to for some of them, for instance when checking whether the inventory is already open when issuing a @showinv). It&#039;s by design so it&#039;s easier to just poke at the code and add your own command without wondering whether you have to add it to a static table somewhere. So it&#039;s neither a bug nor a feature I would say.&lt;br /&gt;
&lt;br /&gt;
And to answer your actual question, it&#039;s very unlikely to change in the future, at least as long as I&#039;m in charge. Yes you&#039;re right, it could be a good way to store data in-world for the time of a unique session. However keep in mind that @getstatus gives a regular chat message, that is capped at 1023 characters.&lt;br /&gt;
&lt;br /&gt;
--[[User:Marine Kelley|Marine Kelley]] 01:47, 18 August 2008 (PDT)&lt;br /&gt;
&lt;br /&gt;
== @sendchannel needs a bit of clarification ==&lt;br /&gt;
&lt;br /&gt;
The way it&#039;s worded, the explanation of sendchannel is a bit confusing.  I &#039;&#039;assume&#039;&#039; the way the restriction works is that the command @sendchannel=n would restrict all alt-channel chat, but the command @sendchannel:3=n would allow chat on that specific channel even if the global restriction is in place.  The way it&#039;s worded though, it seems like it could be that @sendchannel:3=n would restrict chat &#039;&#039;only&#039;&#039; on channel 3.  -- [[User:Felis Darwin|Felis Darwin]] 21:12, 7 December 2008 (UTC)&lt;br /&gt;
&lt;br /&gt;
Maybe it&#039;s poorly worded... @sendchannel:3=n does add an exception to the @sendchannel restriction, in other words you can speak on channel 3 when the former is applied.&lt;br /&gt;
&lt;br /&gt;
[[User:Marine Kelley|Marine Kelley]] 15:16, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== @acceptpermission &amp;amp; @denypermission ==&lt;br /&gt;
&lt;br /&gt;
Marine, your blog lists these new commands, but I don&#039;t see anything on usage in here. Were they overlooked? --[[User:Teyonas Miklos|Teyonas Miklos]] 07:19, 8 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
By the way, if @acceptpermission would also affect animation permission, that would be awesome! --[[User:Satomi Ahn|Satomi Ahn]] 16:42, 19 February 2009 (UTC)&lt;br /&gt;
:Oh it looks like the wiki has been completed now. Thanks Marine. But, may I ask, do @acceptpermission &amp;amp; @denypermission really work for animation permission now? Your blog says it is only for attachements and controls! --[[User:Satomi Ahn|Satomi Ahn]] 11:52, 31 March 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::Yes if I remember correctly it only accepts attach and controls permissions... I am really torn on the animation permission because it is automatically accepted if you&#039;re sitting on the prim that contains the animation (like furnitures), or wearing it (like restraints) but it proves to be a vulnerability for griefers to exploit. Granted, griefing with weird animations is lame (as is griefing in general), but it is griefing nonetheless. I should see how to accept animation permission requests from prims you are sitting on, regardless of whether they contain the animation or not. That should help for rezzable poseballs at least. [[User:Marine Kelley|Marine Kelley]] 15:13, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::: Is there a way to start an animation which is not in the prim? In case it is possible it would be interesting to extend the relay protocol to allow this. But I thought this was impossible? Another idea is to explicitly specify the key of the prim that should be allowed to start an animation: &amp;lt;code&amp;gt;@acceptpermission:7adf6218-ab26-8566-8387-660133840794=add&amp;lt;/code&amp;gt;. I am not sure if the viewer has this information in the permission query function. The scenario I have in mind is a Star Trek like force-field cell door that will give an electroshock on touch, assuming that the cell has an active relay session. Something else to keep in mind is that there is a pyramid scheme vampire game out there which sees accepting animation permission as accepting to be added to the database. --[[User:Maike Short|Maike Short]] 18:54, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
::: Eh, you actually wrote this, on the wiki: &amp;quot;Force the viewer to automatically accept attach and &#039;animate&#039; permission requests : @acceptpermission=&amp;lt;rem/add&amp;gt; &amp;quot;. So I guess this is an error. By the way, Kitty might have pointed this to you, but there is actually a way to to get animation permissions by mean of RLV commands, exploiting a loophole in the logic you use for @acceptpermission. Basically, if this behavior is enabled, if you request permission to animate along with  either permission to attach or permission to take controls, then you are granted both. --[[User:Satomi Ahn|Satomi Ahn]] 20:35, 14 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== A shared root... and what about a protected root? ==&lt;br /&gt;
&lt;br /&gt;
I mean, if you are tired to put your tatoos back every time someone strips you... it would be great to be able to protect easily some clothes and attachments (hair, tail, ears,...).&lt;br /&gt;
You can already somehow do this for clothes with @remoutfit:xxxx=n, and for prims with @detach=n, but this requires scripting, and very often, you will forget to lock them.&lt;br /&gt;
&lt;br /&gt;
I believe this would be a lot easier if you could have a /#protected folder whose content cannot be force-detached by the mean of rlv commands.&lt;br /&gt;
Moreover, it would be even greater if RLV did not report items you are wearing and are in #protected: indeed some scripts will loop until they have successfully detached all they wanted to. If the viewer does not report those items are worn, then those scripts would be happy.&lt;br /&gt;
&lt;br /&gt;
--[[User:Satomi Ahn|Satomi Ahn]] 23:52, 19 February 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
I like the idea of checking against some kind of viewer-side characteristic of the object, but I&#039;m not sure a folder would do... After all the user could want to protect-unprotect quickly, and moving a large chunk of inventory could reveal to be a hassle. I&#039;ll think about it.&lt;br /&gt;
&lt;br /&gt;
[[User:Marine Kelley|Marine Kelley]] 15:09, 4 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Just a note a posteriori: Kitty Barnett&#039;s &amp;quot;nostrip&amp;quot; flag works really well for what I wanted. It would be nice if Marine Kelley&#039;s RLV had this feature too. How does it work? Easy: if an item or folder has (nostrip) in its name, then it will be protected against @remoutfit:layer=force or @detach:attachpt=force commands. A lot better than my initial proposal as it is really fine-grained.&lt;br /&gt;
&lt;br /&gt;
--[[User:Satomi Ahn|Satomi Ahn]] 09:31, 27 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Third party extension @putinv and the SL permission system ==&lt;br /&gt;
&lt;br /&gt;
In my opinion the SL permission system has a serious) flaw. Objects owned by the land owner do have special rights without a permission dialog:&lt;br /&gt;
* manage the ban list&lt;br /&gt;
* change the media settings (can be used to get the ip-address of visitors)&lt;br /&gt;
* teraform (can be used to destroy the landscape and return rezzed objects to the lost and found folder, thous destroying a lovely place)&lt;br /&gt;
&lt;br /&gt;
While I think it is an issue that SL automatically grants these rights to objects owned by the land lord, I am concerned that the auto-accept and attach might be used to simplify attacks. So if you implement this inofficial extension (the official RLV viewer does not) please add a warning.&lt;br /&gt;
&lt;br /&gt;
PS: Oh, it just occured to me that it can be used to write a self replicating worm that jumps across avatars. This would surely have the potential to get the BDSM community some bad PR. --[[User:Maike Short|Maike Short]] 16:18, 8 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:Hm there&#039;s already a (way too) long discussion about this on the forums.&lt;br /&gt;
:Here: http://forums.secondlife.com/showthread.php?t=223796&amp;amp;page=30&amp;amp;pp=15&lt;br /&gt;
:And here: http://sldev.free.fr/forum/viewtopic.php?f=7&amp;amp;t=8&lt;br /&gt;
:I personnaly don&#039;t want to discuss the issue anymore, but I thought I had to point you to this ;-), as I basically share your concerns.&lt;br /&gt;
:--[[User:Satomi Ahn|Satomi Ahn]] 20:29, 14 April 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Protecting attachments against detach ==&lt;br /&gt;
&lt;br /&gt;
I&#039;m scripting a gizmo to prevent stripping of tattoos, piercings etc. It would be very useful to have a command similar to the &amp;quot;@remoutfit&amp;quot;, but for attachments. That way texture clothing and prim clothing can be treated the same way, instead of having to drop a script into each protected attachment.&lt;br /&gt;
&lt;br /&gt;
My question is: Would it be possible to include commands looking something like this?&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Allow/prevent wearing attachments&#039;&#039;&#039;&#039;&#039; : @addattach[:&amp;lt;attachpt&amp;gt;]=&amp;lt;y/n&amp;gt;&lt;br /&gt;
Where attachpt is :&lt;br /&gt;
 chest|skull|left shoulder|right shoulder|left hand|right hand|left foot|right foot|spine|&lt;br /&gt;
 pelvis|mouth|chin|left ear|right ear|left eyeball|right eyeball|nose|r upper arm|r forearm|&lt;br /&gt;
 l upper arm|l forearm|right hip|r upper leg|r lower leg|left hip|l upper leg|l lower leg|stomach|left pec|&lt;br /&gt;
 right pec|center 2|top right|top|top left|center|bottom left|bottom|bottom right&lt;br /&gt;
* &#039;&#039;&#039;&#039;&#039;Allow/prevent removing attachments&#039;&#039;&#039;&#039;&#039; : @remattach[:&amp;lt;attachpt&amp;gt;]=&amp;lt;y/n&amp;gt;&lt;br /&gt;
Where attachpt is :&lt;br /&gt;
 chest|skull|left shoulder|right shoulder|left hand|right hand|left foot|right foot|spine|&lt;br /&gt;
 pelvis|mouth|chin|left ear|right ear|left eyeball|right eyeball|nose|r upper arm|r forearm|&lt;br /&gt;
 l upper arm|l forearm|right hip|r upper leg|r lower leg|left hip|l upper leg|l lower leg|stomach|left pec|&lt;br /&gt;
 right pec|center 2|top right|top|top left|center|bottom left|bottom|bottom right&lt;br /&gt;
&lt;br /&gt;
Or is there already an easy way to do this which I&#039;ve overlooked? --[[User:Scarlett Flores|Scarlett Flores]] 13:58, 13 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
:There is currently no way to do that in Marine&#039;s Viewer, but I can point you to Kitty&#039;s nostrip flag [http://rlva.catznip.com/blog/2009/07/feature-nostrip/] which would work well for what you want (currently in Emerald Greenlife Viewer only).&lt;br /&gt;
:However there is still a use case for @detach:attachpt=n that cannot be covered by nostrip: for locking an attachement against the wearer&#039;s will (but in that case, it is likely the attachment has already been made in the first place for the purpose of being locked, and is scripted with a llOwnerSay(&amp;quot;@detach=n&amp;quot;)). Still, in my opinion this remains an inconsistency in the current RLV API as @remoutfit:arg can be used both with =n and =force but @detach:arg can only be used with =force...&lt;br /&gt;
:--[[User:Satomi Ahn|Satomi Ahn]] 09:39, 27 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Loading a preset is laggy, but still better than loading each parameter by script? ==&lt;br /&gt;
&lt;br /&gt;
Loading WL presets is laggy, but is it less laggy than loading all parameters by script? Or would a script doing this not cause lag but just lag itself? --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 21:25, 16 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Version Changelog ==&lt;br /&gt;
&lt;br /&gt;
Can we have a little section on the API page that briefly lists the additions and changes? --[[User:Ninjafoo Ng|Ninjafoo Ng]] 07:47, 18 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== feature suggestion: forcechat and forceIM ==&lt;br /&gt;
&lt;br /&gt;
How about allowing scripts to make ther person say somthing, emote or otherwise? This woudl serve to, among other things, mind control situations, doing emoting without a choice (like flinching when zapped, blushing when groped etc), having a script send voice commands to another script that usually only obeys voice commands fromt he avatar etc&lt;br /&gt;
&lt;br /&gt;
ps: is there a better place to make feature suggestions?&lt;br /&gt;
&lt;br /&gt;
--[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 16:24, 19 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===force chat level (whisper, talk or shout) ===&lt;br /&gt;
the idea is to allow scripts to force the target (usually only the owner can be the target) to have all chat messages be either whisper, regular talk or shout, regardless of what keyboard shortcuts or gui buttons were pressed --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:24, 26 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
==Feature Suggestion: No-Fly/Fly zones ==&lt;br /&gt;
&lt;br /&gt;
a command to set a range of altitude where flying is allowed or forbidden, operates on top of @fly, defining a zone where the behavior is the opposite of what @fly defined.&lt;br /&gt;
&lt;br /&gt;
It would also be nice to be able to have both a fly and a no-fly zone defined at once, whatever is defined last will overwrite the other where they overlap (would allow for a zone that has a hole in the middle, a sandwich if you will) --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:13, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature sugestion: @Forcefly ==&lt;br /&gt;
&lt;br /&gt;
This command would force the avatar to start or stop flying, if flying is forbidden by the same object that now is running @Forcefly, the avatar would be unable to change their flying/no flying status --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:21, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature suggestion: @Forcepresskeys ==&lt;br /&gt;
&lt;br /&gt;
This command would result in the client behaving as if the user pressed the keys, including triggering control events in scripts.&lt;br /&gt;
&lt;br /&gt;
The parameter would be a list of key and time pairs (time as integer miliseconds), so a sequence of keypresses can be defined in single command. Zero, or an special keyword would indicate no key being pressed. Perhaps use two different separators, one to indicate the keys afterward must wait the last key to timeout and another to indicate they should start being pressed already.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If possible make all keys avaiable (perhaps except for dangerous ones, like delete, backspace, combinations like alt-F4, control-alt-del (this one isn&#039;t as bad as it used to be on Windows, but still better not allow), alt-tab, backspace etc), and for the keypresses must only work inside the client, if another window has focus or somthing, they keys would simply not work, or trigger client behavior event without the client window having focus.  --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:34, 28 July 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature suggestion: @allowpay ==&lt;br /&gt;
&lt;br /&gt;
My goddess brought up a interesting concept of forcing slaves to not being able to spend lindens without the permission of the dom. So my idea is to have a api command to change the status of whether you are allowed to give money or not give money. I may write a patch for it in due time if this function wants to be considered. This would cover all abilities to debit funds from the current balance. [[User:Chibi Pedalo|Chibi Pedalo]] 17:24, 5 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature Suggestion: force paint ==&lt;br /&gt;
&lt;br /&gt;
(Inspired partially by an idea from a friend of mine)&lt;br /&gt;
&lt;br /&gt;
a command to have the client overlay a texture specified by UUID, over the baked texture, making that the new baked texture, alpha pixels and all&lt;br /&gt;
&lt;br /&gt;
this would allow scripts to make people get dirty, covered in slime sploches, darkyellow semi-transparent stain between the legs implying the person pissed on their pants, bloody gashes across the face etc&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
there should also be a command to do a clean rebake (a rebake that isntead of being the old rebake, perhaps composited with new textures, would actually do a regular rebake, reading the clothing info and generating the regular baked texture that woudl result form that.&lt;br /&gt;
&lt;br /&gt;
A copy of dirty baked textures would be kept on the client, when a rebake is done, either by the user request or during default functioning of the client, that saved temporary rebake would be what is sent to the server. Having the dirty rebaked textures be saved would allow for cumulative effects, since each time a new texture is applied the results are saved as the baked texture, each new one would be applied to whatever is there already, be it the normal baked texture, or one with dirt on it.&lt;br /&gt;
&lt;br /&gt;
There would also of course be a command to lock/unlock the current (re)baked texture, if it&#039;s dirty, prevent a clean rebake, and if it isn&#039;t prevent, though better would be separated locks, one for clean rebake, and one for getting any more dirty than how it already is&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 05:51, 8 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Curious behavior with exceptions and @sendim/@recvim ==&lt;br /&gt;
&lt;br /&gt;
So I was toying with a &amp;quot;Safety&amp;quot; plugin for my toy&#039;s collar, something I wrote after she was locked to something and was unable to tell me or get help from me.  I just wrote something simple that obtained the collar&#039;s owner, then set TP and IM restriction exceptions for that person on the wearer, thus ensuring that the owner would always be able to Teleport the wearer or Send/Receive IMs from them.  Initially this worked fine... I thought.  Every device we tested restricted everything covered except for SENDING IMs.&lt;br /&gt;
&lt;br /&gt;
When we finally were in a situation where a separate restraint (a gag) restricted her IM sending ability she wasn&#039;t able to IM me, despite an IM sending exception being set on her collar.  The same gag also restricted her ability to receive IMs, but the exception on the collar allowed me to IM her just fine.  The same was true for the teleport lure exception.  Bottom line, it seems that ONLY for the @sendIM restriction the exception MUST be set on the same object that sets the overall restriction.&lt;br /&gt;
&lt;br /&gt;
Apparently she is using RLV v1.17 (she said it was based on 1.22.11, so I think that&#039;s right), so I don&#039;t know if this is something which has been addressed in v1.19.  Am I right in assuming this is a glitch? -- [[User:Felis Darwin|Felis Darwin]] 06:06, 20 August 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Feature Suggestion: @logout=force ==&lt;br /&gt;
&lt;br /&gt;
Forces the wearer to log out of SL with a message explaining that such and such item as removed you from SL. Its a interesting idea to make a pet or slave leave SL for various reasons.&lt;br /&gt;
&lt;br /&gt;
== @clear, detachments and locked status ==&lt;br /&gt;
&lt;br /&gt;
If an attachment is not locked, sending @clear when dettaching should still be recommended since in that case the attachment won&#039;t be automaticly reattached and the permissions will have to be garbage collected. Only when the attachment is locked that the @clear should be omitted when it is detached --[[User:TigroSpottystripes Katsu|TigroSpottystripes Katsu]] 19:38, 2 October 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Moderate rewrite of Architecture section ==&lt;br /&gt;
&lt;br /&gt;
I just did a moderate rewrite of the Architecture section.  The main change was to give preference to the term &#039;command&#039; instead of &#039;behavior&#039;, because a) the next section is called &amp;quot;List of Commands&amp;quot; and uses that word in the introductory paragraph; and b) not all of these things are behaviors but they are all commands.  The other significant change was to just make more effective use of wiki formatting.   &lt;br /&gt;
&lt;br /&gt;
I hope that people will consider this an improvement, but I won&#039;t be offended by constructive criticism or even reverting to the original text (if accompanied by some reasoning).  &lt;br /&gt;
[[User:Kidd Krasner|Kidd Krasner]] 14:28, 17 December 2009 (UTC)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
== Feature suggestion: @getlocked[:attachpt]=&amp;lt;channel_number&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
A way to see which attachments are locked and not detachable or attachable.&lt;br /&gt;
There is, as far as I know, no way yet to see which attachmentpoints are locked.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;discription:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Makes the viewer automatically answer the current lockstatus of attachment points as a list of 0s (unlocked) and 1s (locked) immediately on the chat channel number &amp;lt;channel_number&amp;gt; that the script can listen to. Always use a positive integer. Remember that regular viewers do not answer anything at all so remove the listener after a timeout. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The list of 0s and 1s corresponds to :&#039;&#039;&#039; &lt;br /&gt;
{{Box|none,chest,skull,left shoulder,right shoulder,left hand,right hand,left foot,right foot,spine,&lt;br /&gt;
pelvis,mouth,chin,left ear,right ear,left eyeball,right eyeball,nose,r upper arm,r forearm,&lt;br /&gt;
l upper arm,l forearm,right hip,r upper leg,r lower leg,left hip,l upper leg,l lower leg,stomach,left pec,&lt;br /&gt;
right pec,center 2,top right,top,top left,center,bottom left,bottom,bottom right}}&lt;br /&gt;
&lt;br /&gt;
in that order. &lt;br /&gt;
&lt;br /&gt;
If an attachment point is specified, answers a single 0 (unlocked) or 1 (locked) corresponding to the point.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A similiar feature would be very usefull for the clothing layers.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[User:Misty Wulluf|Misty Wulluf]] 12:37, 17 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
== Possible bug with respect to setdebug for scenegamma and renderresolutiondivisor ==&lt;br /&gt;
&lt;br /&gt;
While &#039;&#039;setenv_scenegamma&#039;&#039; and &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; could be seen to be useful commands, there is an issue of knowing what to do if multiple objects are issuing them. Right now it appears that the viewer is single-threaded, insofar as the last command entered wins. To make the case specific, assume I am wearing a blindfold that affects my vision using &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; and then accidentally step into a trap that sends a &#039;&#039;setdebug_renderresolutiondivisor&#039;&#039; change through a relay to my viewer. Now that command overrides the blindfold. On being freed from the trap (either by standing or safewording out from the relay) the value of &#039;&#039;renderresolutiondivisor&#039;&#039; will be set back to 1, thus negating the blindfold. It could be argued that using an appropriate &#039;&#039;@getdebug_renderresolutiondivisor&#039;&#039; before the trap operates, would allow the trap, when the avatar stands, to set the value back to the value it found before it operated. The problem is that if the order is: put on blindfold, sit on trap, take off blindfold, stand up from trap then the trap would set &#039;&#039;renderresolutiondivisor&#039;&#039; to the value as if the blindfold were on.&lt;br /&gt;
&lt;br /&gt;
Note that as a relay developer, I have the same problem, knowing what to do when safeword is called, since I have no obvious value to set for &#039;&#039;renderresolutiondivisor&#039;&#039; or &#039;&#039;scenegamma&#039;&#039;. I could set them to 1 and 1.0 respectively, but that is now an escape from other worn attachments. This seems to be something of a problem that it is hard, maybe even impossible to script your way out of, given the global nature of the debug values and the need to respond on a per-object basis.&lt;br /&gt;
&lt;br /&gt;
Should a relay just set the values back to 1.0 for &#039;&#039;scenegamma&#039;&#039; and 1 for &#039;&#039;renderresolutiondivisor&#039;&#039;?&lt;br /&gt;
&lt;br /&gt;
--[[User:Chloe1982 Constantine|Chloe1982 Constantine]] 21:06, 23 February 2010 (UTC)&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
== Feature suggestion: @emailsnapshot:&amp;lt;emailaddr&amp;gt;=force ==&lt;br /&gt;
This would use the snapshot email feature to send a snapshot to &amp;lt;emailaddr&amp;gt;.  This would allow a range of products to be made that can&#039;t currently, particularly in conjunction with Shared Media.&lt;br /&gt;
&lt;br /&gt;
Due to privacy and spam concerns, the user should be asked for permission the first time an object tries to send to a specific address.  This permission (or rejection) should be kept on a per-object basis in the same way restrictions are (and so cleared when the object is derezed or the user relogs).  Something like:&lt;br /&gt;
&lt;br /&gt;
  +----------------------------------------------------&lt;br /&gt;
  |&lt;br /&gt;
  |  May the object &#039;Shapshot Taker&#039; send&lt;br /&gt;
  |  snapshots to &#039;test@example.com&#039;?&lt;br /&gt;
  |&lt;br /&gt;
  |        [Yes]             [No]&lt;br /&gt;
  |&lt;br /&gt;
  +----------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It might be desirable to set the resolution, in which case I would propose:&lt;br /&gt;
&lt;br /&gt;
  @emailsnapshot:&amp;lt;emailaddr&amp;gt;[;&amp;lt;width&amp;gt;x&amp;lt;height&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
Although it would need to be limited to something reasonable.&lt;br /&gt;
&lt;br /&gt;
I don&#039;t think it would be desirable to allow the interface to be included in the snapshot, due to privacy concerns, although perhaps that boat has already sailed.&lt;br /&gt;
&lt;br /&gt;
I would also say that HUD objects should only be shown in the snapshot if the HUD is locked (and so would be forced on for other snapshots).&lt;br /&gt;
&lt;br /&gt;
However, if these were to be configurable, I would propose:&lt;br /&gt;
&lt;br /&gt;
  @emailsnapshot:&amp;lt;emailaddr&amp;gt;[;&amp;lt;width&amp;gt;x&amp;lt;height&amp;gt;][;includehud][;includeinterface]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[User:Winter Seale|Winter Seale]] 00:08, 11 March 2010 (UTC)&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=297732</id>
		<title>Viewer URI Name Space</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Viewer_URI_Name_Space&amp;diff=297732"/>
		<updated>2009-03-30T18:18:54Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: Added documentation on /app/chat&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ProtocolNav}}&lt;br /&gt;
aka Viewer URL Namespace&lt;br /&gt;
&lt;br /&gt;
aka SLAPP URLs&lt;br /&gt;
&lt;br /&gt;
aka Application SLURL&lt;br /&gt;
&lt;br /&gt;
[[Category: Name Spaces]]&lt;br /&gt;
[[Category: Search]]&lt;br /&gt;
&lt;br /&gt;
The SL client supports links of the format secondlife://Region/123/45/67/, which have traditionally specified a region name and x/y/z location.  This means &amp;quot;open Second Life and show Region on the world map&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
The new URL scheme has 3 slashes, and allows direct control of the user interface and login.  For example, secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
Most secondlife:///app URLs only work from browser instances running inside Second Life because of a denial-of-service attack using secondlife:///app/teleport links to force repeated teleports.  SLURLs that work with external browsers include:&lt;br /&gt;
* secondlife://&amp;lt;region name&amp;gt;&lt;br /&gt;
* secondlife:///app/login&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;secondlife://&#039;&#039;&#039;&lt;br /&gt;
* &amp;lt;region_name&amp;gt; &#039;&#039;log in to this region or, if logged in, show information and offer teleport&#039;&#039;&lt;br /&gt;
** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
*** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* /app&lt;br /&gt;
** /agent&lt;br /&gt;
*** /&amp;lt;agent_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open agent&#039;s profile, with 2nd Life tab selected&#039;&#039;&lt;br /&gt;
** /login &#039;&#039;log in on launch. External and internal browsers.&#039;&#039;&lt;br /&gt;
*** see below for query parameters, of course, values are URL escaped&lt;br /&gt;
** /event&lt;br /&gt;
*** /&amp;lt;event_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing event&#039;&#039;&lt;br /&gt;
** /group&lt;br /&gt;
*** /&amp;lt;group_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing group&#039;&#039;&lt;br /&gt;
*** /create &#039;&#039;open the create group dialog, added in 1.20&#039;&#039;&lt;br /&gt;
*** /list&lt;br /&gt;
**** /show &#039;&#039;open the list of groups to which user belongs, added in 1.20&#039;&#039;&lt;br /&gt;
** /parcel&lt;br /&gt;
*** /&amp;lt;parcel_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing place&#039;&#039;&lt;br /&gt;
** /classified&lt;br /&gt;
*** /&amp;lt;classified_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;open floater describing classified&#039;&#039;&lt;br /&gt;
** /region&lt;br /&gt;
*** /&amp;lt;region_id&amp;gt;&lt;br /&gt;
**** /about &#039;&#039;information from database about that region?  list of parcels?  covenant?&#039;&#039;&lt;br /&gt;
** /teleport&lt;br /&gt;
*** /&amp;lt;region_name&amp;gt; &#039;&#039;teleport instantly to this region, no dialog&#039;&#039;&lt;br /&gt;
**** /&amp;lt;local_x&amp;gt; &#039;&#039;optional X position, defaults to 128&#039;&#039;&lt;br /&gt;
***** /&amp;lt;local_y&amp;gt; &#039;&#039;optional Y position, defaults to 128&#039;&#039;&lt;br /&gt;
****** /&amp;lt;local_z&amp;gt; &#039;&#039;optional Z position, defaults to 0&#039;&#039;&lt;br /&gt;
** /chat&lt;br /&gt;
*** /&amp;lt;channel&amp;gt; &#039;&#039;any channel number greater then or equal to 0&#039;&#039;&lt;br /&gt;
**** /&amp;lt;text&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This could be extended to things like:&lt;br /&gt;
* /app/event/&amp;lt;event_id&amp;gt;/subscribe to register for notifications&lt;br /&gt;
* /app/parcel/&amp;lt;parcel_id&amp;gt;/teleport to teleport to a specific location&lt;br /&gt;
* /app/agent/&amp;lt;agent_id&amp;gt;/im to start IM session&lt;br /&gt;
&lt;br /&gt;
== Login Query Parameters ==&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| first || the account first name&lt;br /&gt;
|-&lt;br /&gt;
| last || the account last name&lt;br /&gt;
|-&lt;br /&gt;
| session || the secure session id&lt;br /&gt;
|-&lt;br /&gt;
| location || login location, format TBD, optional&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
	<entry>
		<id>https://wiki.secondlife.com/w/index.php?title=Talk:LlListen&amp;diff=230163</id>
		<title>Talk:LlListen</title>
		<link rel="alternate" type="text/html" href="https://wiki.secondlife.com/w/index.php?title=Talk:LlListen&amp;diff=230163"/>
		<updated>2009-02-08T19:32:20Z</updated>

		<summary type="html">&lt;p&gt;Winter Seale: /* Performance and Sim impact of llListen */ added a post to the scripters ml from Kelly Linden describing how listens are processed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{QA&lt;br /&gt;
|Q=Has this function to be called in every state?&lt;br /&gt;
|A=Yes, it&#039;s a feature. [[User:Strife Onizuka|Strife Onizuka]]&lt;br /&gt;
}}&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=How can i send commands in chat that cannot be seen by others?&lt;br /&gt;
|A=&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=By other avatars?&lt;br /&gt;
|A=Use any channel other then 0 ([[PUBLIC_CHANNEL]]).&lt;br /&gt;
}}&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=By other scripts?&lt;br /&gt;
|A=Can&#039;t keep other scripts from hearing what scripts or avatars say. But you can write complicated channel hopping communications that span the entire range of 4 billion channels, reducing the probability of anyone capturing a complete message.&lt;br /&gt;
}}&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=What [happens] when i do configuration via public channel? There are some scripts that use commands like &#039;/99stop&#039; which cannot be seen in public channel by others&lt;br /&gt;
|A=They can be seen by other scripts, the number at the beginning indicates the channel. &#039;/99stop&#039; sends &#039;stop&#039; on channel 99. That can also be written as &#039;/99 stop&#039; and have the same effect. Any script just has to listen on channel 99 to receive the command.&lt;br /&gt;
}}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== general usage ==&lt;br /&gt;
&lt;br /&gt;
Please explain or show examples that explain what the arguments to llListen do.  specific questions: &lt;br /&gt;
&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=What does it mean to filter on name?  is that the name of the speaker?  does it have to be a full exact match, or can it match a substring of the character&#039;s name? (for example, can i filter by &amp;quot;Baroque&amp;quot; or &amp;quot;Ken&amp;quot; rather than &amp;quot;Kendown Baroque&amp;quot;?)&lt;br /&gt;
|A=If you filter by name, the name must match exactly to the speaker. If it does not match in any way then no listen event is raised. There is no support for partial filtering on any of the filters.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=similarly, I believe filtering by key means that the ID provided must be that of the speaker; is that correct? &lt;br /&gt;
|A=Correct.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=is the message filter case-sensitive?  for that matter, is the name filter?&lt;br /&gt;
|A=The message and name filters are case sensitive; the id filter is not.&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{QA&lt;br /&gt;
|Q=What happens if you create a llListen with the exact same filters as a previously set up (and still active) listener?  Does it ignore the second one?  Create two with the same filter?  Or error out?  For instance, I have a case where I set up a listener to listen to a reply to several different dialog commands.  Each command needs to make sure that the listener is open, but ideally, I could just set up the filter without checking to see if it already exists.&lt;br /&gt;
|A=Nothing bad will happen if you open two listens with the same filters or if the filters overlap; only one listen event will be raised. That said, there is a limit to the number of listens you can have open at any one time by a single script (65 per script) which means that opening multiple listens and not doing any form of tracking is very bad.}}&lt;br /&gt;
&lt;br /&gt;
== Performance and Sim impact of llListen ==&lt;br /&gt;
&lt;br /&gt;
I have heard some comments from sim owners that adding too many listens to a sim would either degrade performance, or there is a hard cap limit to the number that can be active. Is there any validity to this? There is also some discussion regarding filtered vs. unfiltered listens. Unfiltered is obviously an easy way to get aroung the 65 listener limit per script (and subsequently the number active on a sim), but may come with an overhead penalty. This seems somewhat counterintuitive as the filtering process should comsume more clock cycles than simply passing everything on a channel (or all channels?) to the script. -- {{User|Melany Lunasea}}&lt;br /&gt;
&lt;br /&gt;
:Listens do impact sim performance. It&#039;s better to have a single listen processing commands coming in on a single channel then it is to have multiple listens open all on the same channel. -- [[User:Strife Onizuka|Strife Onizuka]] 23:13, 8 March 2008 (PST)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Kelly Linden on 11/13/07 to Scripters mailing list:&lt;br /&gt;
&lt;br /&gt;
  You are pretty close.  The actual order of events is:&lt;br /&gt;
  1. Chat that is said gets added to a history.&lt;br /&gt;
  2. A script that is running and has a listen event will ask the history&lt;br /&gt;
  for a chat message during its slice of run time.&lt;br /&gt;
  3. When the script asks the history for a chat message the checks are&lt;br /&gt;
  done in this order:&lt;br /&gt;
   - channel&lt;br /&gt;
   - self chat (objects can&#039;t hear themselves)&lt;br /&gt;
   - distance/RegionSay&lt;br /&gt;
   - key&lt;br /&gt;
   - name&lt;br /&gt;
   - message&lt;br /&gt;
  4. If a message is found then a listen event is added to the event queue.&lt;br /&gt;
&lt;br /&gt;
  The key/name/message checks only happen at all if those are specified of&lt;br /&gt;
  course.&lt;br /&gt;
&lt;br /&gt;
  So, the most efficient way is llRegionSay on a rarely used channel.&lt;/div&gt;</summary>
		<author><name>Winter Seale</name></author>
	</entry>
</feed>